window.onload = function () {
const user_name =
NAME_ARRAY[Math.round(Math.random() * NAME_ARRAY.length)];
document.getElementById("userName_profile").innerHTML = user_name;
document.getElementById("userName").innerHTML = user_name;
const btn = document.querySelector("#sendMessage");
const textfield = document.querySelector("#messageInput");
const log = document.querySelector("#messageArea");
// +++++++++++++++ For chat messaging system ++++++++++++
NAF.connection.subscribeToDataChannel(
"chat",
(senderId, dataType, data, targetId) => {
console.log("msg", data, "from", senderId, targetId);
messageArea.innerHTML += senderId + ": " + data.txt + "<br>";
}
);
btn.addEventListener("click", (evt) => {
NAF.clientId = user_name;
messageArea.innerHTML +=
NAF.clientId + ": " + textfield.value + "<br>";
NAF.connection.broadcastData("chat", { txt: textfield.value });
document.getElementById("messageInput").value = "";
// NAF.easy = user_name;
});
}
When I've made chat system and working fine. The only, issue is that I want a user name rather than a client id. Please, help with this.
Related
I have next.js project, on server side I generate Looker-sso url and on client side I use this url for embedded dashboard.
Here is how I generate SSO url at Next.js server side
function getLookerSsoUrl(embeddedUserParams: UserInfo, dashboardId: string) : string {
/** Returns Looker Embedded sso url. */
const url_data : LookerEmbeddedUrlOptions = {
"host": LOOKER_HOST,
"secret": LOOKER_SECRET,
"first_name": embeddedUserParams.firstName,
"last_name": embeddedUserParams.lastName,
"external_user_id": embeddedUserParams.firstName + " " + embeddedUserParams.lastName,
"external_group_id": embeddedUserParams.companyName + " group",
"group_ids": [1],
"access_filters": {},
"models": ['db_analytics'],
"permissions": [
'see_user_dashboards',
'see_lookml_dashboards',
'access_data',
'see_looks'],
"user_attributes": {
"name": embeddedUserParams.firstName + " " + embeddedUserParams.lastName,
"first_name": embeddedUserParams.firstName,
"last_name": embeddedUserParams.lastName,
"email": embeddedUserParams.email,
"company_id": embeddedUserParams.companyId,
"company_name": embeddedUserParams.companyName,
"id": embeddedUserParams.id
},
"session_length": 15 * 60,
"embed_url": `/embed/dashboards/${dashboardId}?embed_domain=http://localhost&company_id=${embeddedUserParams.companyId}`,
"force_logout_login": true
}
return "https://" + getSignedEmbedUrl(url_data)
}
function getSignedEmbedUrl(options : LookerEmbeddedUrlOptions) : string {
/** Build sso url with all Looker options and secret key and returns it. */
// looker options
const secret = options.secret
const host = options.host
// user options
const json_external_user_id = JSON.stringify(options.external_user_id)
const json_first_name = JSON.stringify(options.first_name)
const json_last_name = JSON.stringify(options.last_name)
const json_permissions = JSON.stringify(options.permissions)
const json_models = JSON.stringify(options.models)
const json_group_ids = JSON.stringify(options.group_ids)
const json_external_group_id = JSON.stringify(options.external_group_id || "")
const json_user_attributes = JSON.stringify(options.user_attributes || {})
const json_access_filters = JSON.stringify(options.access_filters)
// url/session specific options
const embed_path = '/login/embed/' + encodeURIComponent(options.embed_url)
const json_session_length = JSON.stringify(options.session_length)
const json_force_logout_login = JSON.stringify(options.force_logout_login)
// computed options
const json_time = JSON.stringify(Math.floor((new Date()).getTime() / 1000))
const json_nonce = JSON.stringify(getNonce(16))
// compute signature
let string_to_sign = ""
string_to_sign += host + "\n"
string_to_sign += embed_path + "\n"
string_to_sign += json_nonce + "\n"
string_to_sign += json_time + "\n"
string_to_sign += json_session_length + "\n"
string_to_sign += json_external_user_id + "\n"
string_to_sign += json_permissions + "\n"
string_to_sign += json_models + "\n"
string_to_sign += json_group_ids + "\n"
string_to_sign += json_external_group_id + "\n"
string_to_sign += json_user_attributes + "\n"
string_to_sign += json_access_filters
const signature = createHmac('sha1', secret).update(ForceUnicodeEncoding(string_to_sign)).digest('base64').trim()
// construct query string
const query_params = {
nonce: json_nonce,
time: json_time,
session_length: json_session_length,
external_user_id: json_external_user_id,
permissions: json_permissions,
models: json_models,
access_filters: json_access_filters,
first_name: json_first_name,
last_name: json_last_name,
group_ids: json_group_ids,
external_group_id: json_external_group_id,
user_attributes: json_user_attributes,
force_logout_login: json_force_logout_login,
signature: signature
}
const query_string = stringify(query_params)
return host + embed_path + '?' + query_string
}
function getNonce(len : number) : string {
/** Returns nonce characters. */
let text = ""
const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
for (let i = 0; i < len; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length))
return text
}
function ForceUnicodeEncoding(string : string) : string {
/** Decodes a URI component previously created by encodeURIComponent. */
return decodeURIComponent(encodeURIComponent(string))
}
Here is client side code:
import React, {useCallback} from "react"
import {LookerEmbedSDK} from "#looker/embed-sdk"
import {ENV_VAR} from "env"
type embeddedDashboardType = {
id : number
setError? : ((errorMsg : string) => void)
}
export const EmbeddedDashboard = ({id, setError} : embeddedDashboardType) => {
const canceller = (event : any) => {
return { cancel: !event.modal }
}
document.addEventListener("click", ()=>console.log("r"))
const embedCtrRef = useCallback((el) => {
const authUrl = "/api/looker-sso"
if (el) {
LookerEmbedSDK.init("...", authUrl)
LookerEmbedSDK.createDashboardWithId(id)
.withNext()
.appendTo(el)
.on("drillmenu:click", canceller)
.on("drillmodal:explore", canceller)
.on("dashboard:tile:explore", canceller)
.on("look:ready", ()=> console.log("ready"))
.on("explore:ready", ()=>console.log("ready"))
.on("dashboard:run:start", ()=>console.log("ready"))
.on("dashboard:tile:view", canceller)
.build()
.connect()
.catch((error) => {
console.error("Connection error", error)
if (setError){
setError(error)
}
})
}
}, [])
return <>
<style jsx>{`
:global(.container-dashboard) {
width: 100%;
height: 95vh;
}
:global(.container-dashboard > iframe) {
width: 100%;
height: 100%;
}
`}</style>
<div className="container-dashboard" ref={embedCtrRef} />
</>
}
The dashboard displays correctly, but I cant track events, that happen in Looker Iframe
I except, that I would see clicks, which are made on looker iframe
I'm facing some problem and I'm still new with this react native and SQLite thing but how do I delete a data from database if the create method is like this?
simpanCatatan = async () => {
const { navigation } = this.props
const date = new Date()
const dateNow = date.getDate() + " " + bulan[date.getMonth()] + " " + date.getFullYear()
await Catatan.create({
title: this.state.title,
value: this.state.catatan,
user_id: this.state.user_id,
video_id: this.state.idVideo,
video_name: this.state.namaVideo,
materi_id: this.state.idMateri,
created_at:dateNow
})
navigation.goBack()
navigation.state.params.getAllCatatan()
}
I've been struggling with this piece of code for a while and I'm reaching out for help. I have a array of dates and I"m trying to make http requests in order of the array and to write the return information, also in order.
Here is my code:
const dateArray = ['november-22-2019', 'november-25-2019', 'november-26-2019', 'november-27-2019', 'november-29-2019'];
async function loppThroughArray() {
for (const date of dateArray) {
const options = {
url: process.env.URL + date
};
await asyncRequest(options, date);
}
}
async function asyncRequest(options, date) {
request(options, function(error, response, html) {
if (error) {
return;
}
if (response.statusCode !== 200) {
return;
}
const $ = cheerio.load(html);
const content = $('.entry-content');
const formattedContent = content.text()
.split('\t').join('')
.split('\n\n\n').join('')
.split('\n\n').join('');
const dataToBeWritten = '### ' + date + '\n' + formattedContent + '\n\n';
fs.appendFileSync(`./WODs/${currentDate}.md`, dataToBeWritten, 'utf-8', {'flags':'a+'});
fs.appendFileSync(`./WODs/${currentDate}.txt`, dataToBeWritten, 'utf-8', {'flags':'a+'});
});
}
loppThroughArray();
I managed to solve this by using a version of 'request' that uses promises instead of callbacks. See code:
async function loppThroughArray() {
for (const date of dateArray) {
const options = {
url: process.env.URL + date
};
await asyncRequest(options, date);
console.log('fetching: ', date);
}
}
async function asyncRequest(options, date) {
await rp(options)
.then(function(html){
const $ = cheerio.load(html);
const content = $('.entry-content');
const formattedContent = content.text()
.split('\t').join('')
.split('\n\n\n').join('')
.split('\n\n').join('');
const dataToBeWritten = '### ' + date + '\n' + formattedContent + '\n\n';
fs.appendFileSync(`./WODs/${currentDate}.md`, dataToBeWritten, 'utf-8', {'flags':'a+'});
fs.appendFileSync(`./WODs/${currentDate}.txt`, dataToBeWritten, 'utf-8', {'flags':'a+'});
});
}
loppThroughArray();
I am using firebase realtime database for chat feature in my application, I just need to return an Obserable of type any or type Message from firebase query,
Here is my code:
getMessageHistory(farmerId) {
let chatMessages = [];
var chats;
firebase.database().ref('/' + this.chatUrl + '/' + farmerId + '/').once('value', function (snapshot) {
chats = snapshot.val();
if (chats != null) {
Object.keys(chats).forEach(element => {
let chat = chats[element.toString()];
var Message = {
fromId: chat.from,
toId: chat.to,
message: chat.message
}
let mockedHistory: Array<Message>;
mockedHistory.push(Message)
});
}
else {
}
});
}`
How do I return Observable from above method. I have tried angularfire2 but throwing an error while compiling (Angular Version 4)
Got the solution but I don't know is it recommended or not!
let mockedHistory: Array<Message> = [];
let totalRecords = this.db.list('/' + this.chatUrl + '/' + userId + '/');
return totalRecords.valueChanges<any>().map((chat)=>{
var newChat = chat.map((message) => {
let msg = new Message();
msg.fromId = message.from;
msg.toId= message.to,
msg.message= message.message
return msg;
});
return newChat;
}
)
I'm trying to take a photo with the Camera module of NativeScript, then upload it to Firebase, but it doesn't seem to work. imageTaken and fileLocation come up as false and undefined. Is there something wrong with my code? (Written in TypeScript)
import fs = require('file-system')
import frame = require('ui/frame')
import utils = require('utils/utils')
import observableModule = require('data/observable')
import imageSource = require("image-source")
import camera = require('camera')
import image = require('ui/image')
import {
ImageFormat
} from 'ui/enums'
import view = require("ui/core/view")
import firebase = require('nativescript-plugin-firebase')
var dialog = require('nativescript-dialog')
var pd = new observableModule.Observable()
var imageContainer
var imageTaken = false
var fileLocation
exports.loaded = args => {
var page = args.object
imageContainer = view.getViewById(page, "img")
pd.set('imageTaken', imageTaken)
page.bindingContext = pd
}
exports.takePhoto = args => {
const options = {
width: 300,
height: 300,
keepAspectRatio: true
}
camera.takePicture().then((picture) => {
console.log('Take Picture')
var image = new image.Image()
image.imageSource = picture
imageContainer.imageSource = picture
let savePath = fs.knownFolders.documents().path;
let fileName = 'img_' + new Date().getTime() + '_' + this.currentUserId.getValue() + '.' + ImageFormat.jpeg
let filePath = fs.path.join(savePath, fileName)
console.log(filePath)
picture.saveToFile(filePath, ImageFormat.jpeg)
fileLocation = filePath
imageTaken = true
})
}
exports.sendPhoto = args => {
console.log(imageTaken)
console.log(fileLocation)
imageTaken ? upload(Math.random() + '-' + Date.now()) : dialog.show({
title: "Error",
message: "Please take a photo first.",
okButtonText: "OK"
})
}
const upload = (remoteFileName) => {
firebase.uploadFile({
remoteFullPath: 'uploads/images/' + remoteFileName,
localFile: fs.File.fromPath(fileLocation),
localFullPath: fileLocation,
onProgress: function (status) {
console.log("Uploaded fraction: " + status.fractionCompleted)
console.log("Percentage complete: " + status.percentageCompleted)
}
}).then(
uploadedFile => {
console.log("File uploaded: " + JSON.stringify(uploadedFile))
},
error => {
console.log("File upload error: " + error)
}
)
}
The old camera module is obsolete. Use nativescript-camera instead. Note that for Android API23+ you will need to explicitly request permissions runtime. With nativescript-camera it is done with
import * as camera from "nativescript-camera";
camera.requestPermissions();
More about nativescript-camera plugin here