From 9ac74bcf8d9ccfeee64645254cad73b8db7c8307 Mon Sep 17 00:00:00 2001 From: PhilReact Date: Tue, 31 Oct 2023 02:02:08 +0200 Subject: [PATCH] qortalrequest for fetching profile data --- core/language/us.json | 3 +- .../friends-view/profile-modal-update.js | 12 +- core/src/components/friends-view/profile.js | 14 +- core/src/plugins/streams.js | 6 +- core/src/redux/app/actions/app-core.js | 8 +- core/src/redux/app/app-action-types.js | 1 + core/src/redux/app/app-reducer.js | 11 +- .../core/components/qdn-action-types.js | 5 +- .../plugins/core/qdn/browser/browser.src.js | 404 ++++++++++++------ 9 files changed, 325 insertions(+), 139 deletions(-) diff --git a/core/language/us.json b/core/language/us.json index 80b7bf2d..5daf3012 100644 --- a/core/language/us.json +++ b/core/language/us.json @@ -727,7 +727,8 @@ "bchange45": "Encrypt", "bchange46": "Do you give this application permission to save the following file", "bchange47": "Instant publish - requires", - "bchange48": "Do you give this application permission to send you notifications" + "bchange48": "Do you give this application permission to send you notifications", + "bchange49": "Do you grant this application permission to access the following private information from your profile?" }, "datapage": { "dchange1": "Data Management", diff --git a/core/src/components/friends-view/profile-modal-update.js b/core/src/components/friends-view/profile-modal-update.js index 485236be..f38d8851 100644 --- a/core/src/components/friends-view/profile-modal-update.js +++ b/core/src/components/friends-view/profile-modal-update.js @@ -467,9 +467,7 @@ class ProfileModalUpdate extends connect(store)(LitElement) { > { @@ -591,9 +589,9 @@ class ProfileModalUpdate extends connect(store)(LitElement) { > { @@ -623,7 +621,7 @@ class ProfileModalUpdate extends connect(store)(LitElement) { { @@ -649,7 +647,7 @@ class ProfileModalUpdate extends connect(store)(LitElement) {
{ diff --git a/core/src/components/friends-view/profile.js b/core/src/components/friends-view/profile.js index d214fd3c..fae70f53 100644 --- a/core/src/components/friends-view/profile.js +++ b/core/src/components/friends-view/profile.js @@ -20,7 +20,7 @@ import { publishData } from '../../../../plugins/plugins/utils/publish-image.js' import { parentEpml } from '../show-plugin.js'; import '../notification-view/popover.js'; import './avatar.js'; -import { setNewTab } from '../../redux/app/app-actions.js'; +import { setNewTab, setProfileData } from '../../redux/app/app-actions.js'; import './profile-modal-update.js'; class ProfileQdn extends connect(store)(LitElement) { @@ -220,12 +220,16 @@ class ProfileQdn extends connect(store)(LitElement) { console.log({error}) } - } + } else { + customData[key] = data.customData[key]; + } } this.profileData = { ...response, customData } + + store.dispatch(setProfileData(this.profileData)) } } @@ -352,10 +356,10 @@ class ProfileQdn extends connect(store)(LitElement) { }); newObject['customData'][key] = encryptedData; } else { - newObject['customData'][key] = data[key]; + newObject['customData'][key] = newObject.customData[key]; } } - + console.log({newObject}) const newObjectToBase64 = await objectToBase64(newObject); // const encryptedData = encryptDataGroup({ // data64: newObjectToBase64, @@ -382,6 +386,8 @@ class ProfileQdn extends connect(store)(LitElement) { this.resourceExists = true; this.profileData = data + store.dispatch(setProfileData(data)) + // this.setValues(newObject, { // updated: Date.now(), // }); diff --git a/core/src/plugins/streams.js b/core/src/plugins/streams.js index bc4bae3a..6a0bdd08 100644 --- a/core/src/plugins/streams.js +++ b/core/src/plugins/streams.js @@ -9,6 +9,7 @@ const CHAT_HEADS_STREAM_NAME = 'chat_heads' const NODE_CONFIG_STREAM_NAME = 'node_config' const CHAT_LAST_SEEN = 'chat_last_seen' const SIDE_EFFECT_ACTION = 'side_effect_action' +const PROFILE_DATA_ACTION = 'profile_data_action' export const loggedInStream = new EpmlStream(LOGIN_STREAM_NAME, () => store.getState().app.loggedIn) export const configStream = new EpmlStream(CONFIG_STREAM_NAME, () => store.getState().config) @@ -18,6 +19,7 @@ export const chatHeadsStateStream = new EpmlStream(CHAT_HEADS_STREAM_NAME, () => export const nodeConfigStream = new EpmlStream(NODE_CONFIG_STREAM_NAME, () => store.getState().app.nodeConfig) export const chatLastSeenStream = new EpmlStream(CHAT_LAST_SEEN, () => store.getState().app.chatLastSeen) export const sideEffectActionStream = new EpmlStream(SIDE_EFFECT_ACTION, () => store.getState().app.sideEffectAction) +export const profileDataActionStream = new EpmlStream(SIDE_EFFECT_ACTION, () => store.getState().app.profileData) @@ -62,7 +64,9 @@ store.subscribe(() => { if (oldState.app.sideEffectAction !== state.app.sideEffectAction) { sideEffectActionStream.emit(state.app.sideEffectAction) } - + if(oldState.app.profileDataActionStream !== state.app.profileDataActionStream){ + profileDataActionStream.emit(state.app.profileData) + } oldState = state }) diff --git a/core/src/redux/app/actions/app-core.js b/core/src/redux/app/actions/app-core.js index fa2e8380..adcbc32c 100644 --- a/core/src/redux/app/actions/app-core.js +++ b/core/src/redux/app/actions/app-core.js @@ -1,5 +1,5 @@ // Core App Actions here... -import { UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, CHAT_HEADS, ACCOUNT_INFO, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, ALLOW_QAPP_AUTO_AUTH, REMOVE_QAPP_AUTO_AUTH, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN, ALLOW_QAPP_AUTO_LISTS, REMOVE_QAPP_AUTO_LISTS, SET_NEW_TAB, ADD_TAB_INFO, SET_TAB_NOTIFICATIONS, IS_OPEN_DEV_DIALOG, SET_NEW_NOTIFICATION, SET_SIDE_EFFECT } from '../app-action-types.js' +import { UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, CHAT_HEADS, ACCOUNT_INFO, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, ALLOW_QAPP_AUTO_AUTH, REMOVE_QAPP_AUTO_AUTH, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN, ALLOW_QAPP_AUTO_LISTS, REMOVE_QAPP_AUTO_LISTS, SET_NEW_TAB, ADD_TAB_INFO, SET_TAB_NOTIFICATIONS, IS_OPEN_DEV_DIALOG, SET_NEW_NOTIFICATION, SET_SIDE_EFFECT, SET_PROFILE_DATA } from '../app-action-types.js' export const doUpdateBlockInfo = (blockObj) => { return (dispatch, getState) => { @@ -157,4 +157,10 @@ export const setSideEffectAction = (payload)=> { type: SET_SIDE_EFFECT, payload } +} +export const setProfileData = (payload)=> { + return { + type: SET_PROFILE_DATA, + payload + } } \ No newline at end of file diff --git a/core/src/redux/app/app-action-types.js b/core/src/redux/app/app-action-types.js index fd5e06f7..48979158 100644 --- a/core/src/redux/app/app-action-types.js +++ b/core/src/redux/app/app-action-types.js @@ -33,3 +33,4 @@ export const SET_TAB_NOTIFICATIONS = 'SET_TAB_NOTIFICATIONS' export const IS_OPEN_DEV_DIALOG = 'IS_OPEN_DEV_DIALOG' export const SET_NEW_NOTIFICATION = 'SET_NEW_NOTIFICATION' export const SET_SIDE_EFFECT= 'SET_SIDE_EFFECT' +export const SET_PROFILE_DATA = 'SET_PROFILE_DATA' diff --git a/core/src/redux/app/app-reducer.js b/core/src/redux/app/app-reducer.js index f7ce35a2..bb6287f9 100644 --- a/core/src/redux/app/app-reducer.js +++ b/core/src/redux/app/app-reducer.js @@ -1,6 +1,6 @@ // Loading state, login state, isNavDrawOpen state etc. None of this needs to be saved to localstorage. import { loadStateFromLocalStorage, saveStateToLocalStorage } from '../../localStorageHelpers.js' -import { LOG_IN, LOG_OUT, NETWORK_CONNECTION_STATUS, INIT_WORKERS, ADD_PLUGIN_URL, ADD_PLUGIN, ADD_NEW_PLUGIN_URL, NAVIGATE, SELECT_ADDRESS, ACCOUNT_INFO, CHAT_HEADS, UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, LOAD_NODE_CONFIG, SET_NODE, ADD_NODE, PAGE_URL, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, ALLOW_QAPP_AUTO_AUTH, REMOVE_QAPP_AUTO_AUTH, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN, ALLOW_QAPP_AUTO_LISTS, REMOVE_QAPP_AUTO_LISTS, SET_NEW_TAB, ADD_TAB_INFO, SET_TAB_NOTIFICATIONS, IS_OPEN_DEV_DIALOG, REMOVE_NODE, EDIT_NODE, SET_NEW_NOTIFICATION, SET_SIDE_EFFECT } from './app-action-types.js' +import { LOG_IN, LOG_OUT, NETWORK_CONNECTION_STATUS, INIT_WORKERS, ADD_PLUGIN_URL, ADD_PLUGIN, ADD_NEW_PLUGIN_URL, NAVIGATE, SELECT_ADDRESS, ACCOUNT_INFO, CHAT_HEADS, UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, LOAD_NODE_CONFIG, SET_NODE, ADD_NODE, PAGE_URL, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, ALLOW_QAPP_AUTO_AUTH, REMOVE_QAPP_AUTO_AUTH, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN, ALLOW_QAPP_AUTO_LISTS, REMOVE_QAPP_AUTO_LISTS, SET_NEW_TAB, ADD_TAB_INFO, SET_TAB_NOTIFICATIONS, IS_OPEN_DEV_DIALOG, REMOVE_NODE, EDIT_NODE, SET_NEW_NOTIFICATION, SET_SIDE_EFFECT, SET_PROFILE_DATA } from './app-action-types.js' import { initWorkersReducer } from './reducers/init-workers.js' import { loginReducer } from './reducers/login-reducer.js' import { setNode, addNode, removeNode, editNode } from './reducers/manage-node.js' @@ -52,7 +52,8 @@ const INITIAL_STATE = { tabInfo: {}, isOpenDevDialog: false, newNotification: null, - sideEffectAction: null + sideEffectAction: null, + profileData: null } export default (state = INITIAL_STATE, action) => { @@ -293,6 +294,12 @@ export default (state = INITIAL_STATE, action) => { sideEffectAction: action.payload } } + case SET_PROFILE_DATA: { + return { + ...state, + profileData: action.payload + } + } default: return state diff --git a/plugins/plugins/core/components/qdn-action-types.js b/plugins/plugins/core/components/qdn-action-types.js index 496aba42..91c7488e 100644 --- a/plugins/plugins/core/components/qdn-action-types.js +++ b/plugins/plugins/core/components/qdn-action-types.js @@ -65,4 +65,7 @@ export const SEND_LOCAL_NOTIFICATION = 'SEND_LOCAL_NOTIFICATION' export const VOTE_ON_POLL= 'VOTE_ON_POLL' //CREATE_POLL -export const CREATE_POLL= 'CREATE_POLL' \ No newline at end of file +export const CREATE_POLL= 'CREATE_POLL' + +//GET_PROFILE_DATA +export const GET_PROFILE_DATA = 'GET_PROFILE_DATA' \ No newline at end of file diff --git a/plugins/plugins/core/qdn/browser/browser.src.js b/plugins/plugins/core/qdn/browser/browser.src.js index 3225f33e..9bf6f8f4 100644 --- a/plugins/plugins/core/qdn/browser/browser.src.js +++ b/plugins/plugins/core/qdn/browser/browser.src.js @@ -281,7 +281,7 @@ class WebBrowser extends LitElement { else { identifier = null; } - }extractComponents + } extractComponents const components = {}; components["service"] = service; components["name"] = name; @@ -318,41 +318,41 @@ class WebBrowser extends LitElement { } async linkOpenNewTab(link) { - - const value = link - let newQuery = value; - if (newQuery.endsWith('/')) { - newQuery = newQuery.slice(0, -1); + + const value = link + let newQuery = value; + if (newQuery.endsWith('/')) { + newQuery = newQuery.slice(0, -1); + } + const res = await this.extractComponents(newQuery) + if (!res) return + const { service, name, identifier, path } = res + let query = `?service=${service}` + if (name) { + query = query + `&name=${name}` + } + if (identifier) { + query = query + `&identifier=${identifier}` + } + if (path) { + query = query + `&path=${path}` + } + + window.parent.reduxStore.dispatch(window.parent.reduxAction.setNewTab({ + url: `qdn/browser/index.html${query}`, + id: this.uid.rnd(), + myPlugObj: { + "url": service === 'WEBSITE' ? "websites" : "qapps", + "domain": "core", + "page": `qdn/browser/index.html${query}`, + "title": name, + "icon": service === 'WEBSITE' ? 'vaadin:desktop' : 'vaadin:external-browser', + "mwcicon": service === 'WEBSITE' ? 'desktop_mac' : 'open_in_browser', + "menus": [], + "parent": false } - const res = await this.extractComponents(newQuery) - if (!res) return - const { service, name, identifier, path } = res - let query = `?service=${service}` - if (name) { - query = query + `&name=${name}` - } - if (identifier) { - query = query + `&identifier=${identifier}` - } - if (path) { - query = query + `&path=${path}` - } - - window.parent.reduxStore.dispatch(window.parent.reduxAction.setNewTab({ - url: `qdn/browser/index.html${query}`, - id: this.uid.rnd(), - myPlugObj: { - "url": service === 'WEBSITE' ? "websites" : "qapps", - "domain": "core", - "page": `qdn/browser/index.html${query}`, - "title": name, - "icon": service === 'WEBSITE' ? 'vaadin:desktop' : 'vaadin:external-browser', - "mwcicon": service === 'WEBSITE' ? 'desktop_mac' : 'open_in_browser', - "menus": [], - "parent": false - } - })) - + })) + } render() { @@ -462,7 +462,7 @@ class WebBrowser extends LitElement { const joinFee = (Number(data) / 1e8).toFixed(8) return joinFee } - async getArbitraryFee (){ + async getArbitraryFee() { const timestamp = Date.now() const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port @@ -475,10 +475,10 @@ class WebBrowser extends LitElement { const arbitraryFee = (Number(data) / 1e8).toFixed(8) return { timestamp, - fee : Number(data), + fee: Number(data), feeToShow: arbitraryFee } - } + } async sendQortFee() { const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port @@ -652,9 +652,9 @@ class WebBrowser extends LitElement { } const makeTransactionRequest = async (lastRef) => { - let votedialog1 = get("transactions.votedialog1") - let votedialog2 = get("transactions.votedialog2") - let feeDialog = get("walletpage.wchange12") + let votedialog1 = get("transactions.votedialog1") + let votedialog2 = get("transactions.votedialog2") + let feeDialog = get("walletpage.wchange12") let myTxnrequest = await parentEpml.request('transaction', { type: 9, @@ -707,12 +707,12 @@ class WebBrowser extends LitElement { } const makeTransactionRequest = async (lastRef) => { - let votedialog3 = get("transactions.votedialog3") - let votedialog4 = get("transactions.votedialog4") - let votedialog5 = get("transactions.votedialog5") - let votedialog6 = get("transactions.votedialog6") - let feeDialog = get("walletpage.wchange12") - + let votedialog3 = get("transactions.votedialog3") + let votedialog4 = get("transactions.votedialog4") + let votedialog5 = get("transactions.votedialog5") + let votedialog6 = get("transactions.votedialog6") + let feeDialog = get("walletpage.wchange12") + let myTxnrequest = await parentEpml.request('transaction', { type: 8, nonce: this.selectedAddress.nonce, @@ -1218,7 +1218,7 @@ class WebBrowser extends LitElement { } - + const res2 = await showModalAndWait( @@ -1484,7 +1484,7 @@ class WebBrowser extends LitElement { } const pollName = data.pollName; const optionIndex = data.optionIndex; - + let pollInfo = null try { @@ -1542,10 +1542,10 @@ class WebBrowser extends LitElement { break } const pollName = data.pollName; - const pollDescription = data.pollDescription + const pollDescription = data.pollDescription const pollOptions = data.pollOptions - const pollOwnerAddress = data.pollOwnerAddress - + const pollOwnerAddress = data.pollOwnerAddress + try { this.loader.show(); const resCreatePoll = await this._createPoll(pollName, pollDescription, pollOptions, pollOwnerAddress) @@ -1562,7 +1562,7 @@ class WebBrowser extends LitElement { break; } case actions.OPEN_NEW_TAB: { - if(!data.qortalLink){ + if (!data.qortalLink) { const obj = {}; const errorMsg = 'Please enter a qortal link - qortal://...'; obj['error'] = errorMsg; @@ -1582,7 +1582,7 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj); break; } - + } case actions.NOTIFICATIONS_PERMISSION: { try { @@ -1593,62 +1593,62 @@ class WebBrowser extends LitElement { name: this.name } ); - if (res.action === 'accept'){ + if (res.action === 'accept') { this.addAppToNotificationList(this.name) - response = true - break; + response = true + break; } else { response = false break; } - + } catch (error) { break; } - + } case actions.SEND_LOCAL_NOTIFICATION: { - const {title, url, icon, message} = data + const { title, url, icon, message } = data try { const id = `appNotificationList-${this.selectedAddress.address}` const checkData = localStorage.getItem(id) ? JSON.parse(localStorage.getItem(id)) : null; - if(!checkData || !checkData[this.name]) throw new Error('App not on permission list') - const appInfo = checkData[this.name] - const lastNotification = appInfo.lastNotification - const interval = appInfo.interval - if (lastNotification && interval) { - const timeDifference = Date.now() - lastNotification; - - if (timeDifference > interval) { + if (!checkData || !checkData[this.name]) throw new Error('App not on permission list') + const appInfo = checkData[this.name] + const lastNotification = appInfo.lastNotification + const interval = appInfo.interval + if (lastNotification && interval) { + const timeDifference = Date.now() - lastNotification; + + if (timeDifference > interval) { + parentEpml.request('showNotification', { + title, type: "qapp-local-notification", sound: '', url, options: { body: message, icon, badge: icon } + }) + response = true + this.updateLastNotification(id, this.name) + break; + } else { + throw new Error(`duration until another notification can be sent: ${interval - timeDifference}`) + } + } else if (!lastNotification) { parentEpml.request('showNotification', { - title, type: "qapp-local-notification", sound: '', url, options: { body: message, icon, badge: icon } - }) - response = true - this.updateLastNotification(id, this.name) - break; + title, type: "qapp-local-notification", sound: '', url, options: { body: message, icon, badge: icon } + }) + response = true + this.updateLastNotification(id) + break; } else { - throw new Error(`duration until another notification can be sent: ${interval - timeDifference}`) + throw new Error(`invalid data`) } - } else if(!lastNotification){ - parentEpml.request('showNotification', { - title, type: "qapp-local-notification", sound: '', url, options: { body: message, icon, badge: icon } - }) - response = true - this.updateLastNotification(id) - break; - } else { - throw new Error(`invalid data`) - } - + } catch (error) { const obj = {}; const errorMsg = error.message || "error in pushing notification"; obj['error'] = errorMsg; response = JSON.stringify(obj); break; - + } - + } case actions.SEND_CHAT_MESSAGE: { const message = data.message; @@ -2035,7 +2035,7 @@ class WebBrowser extends LitElement { try { this.loader.show(); - + const resDeployAt = await this._deployAt(data.name, data.description, data.tags, data.creationBytes, data.amount, data.assetId, data.type) response = JSON.stringify(resDeployAt); } catch (error) { @@ -2049,6 +2049,161 @@ class WebBrowser extends LitElement { break; } + case 'GET_PROFILE_DATA': { + const defaultProperties = ['tagline', 'bio', 'wallets'] + const requiredFields = ['property']; + const missingFields = []; + + requiredFields.forEach((field) => { + if (!data[field] && data[field] !== 0) { + missingFields.push(field); + } + }); + + if (missingFields.length > 0) { + const missingFieldsString = missingFields.join(', '); + const errorMsg = `Missing fields: ${missingFieldsString}` + let data = {}; + data['error'] = errorMsg; + response = JSON.stringify(data); + break + } + + + try { + const profileData = window.parent.reduxStore.getState().app.profileData + if (!profileData) { + throw new Error('User does not have a profile') + } + const property = data.property + const propertyIndex = defaultProperties.indexOf(property) + if (propertyIndex !== -1) { + const requestedData = profileData[property] + if (requestedData) { + response = JSON.stringify(requestedData); + break + } else { + throw new Error('Cannot find requested data') + } + } + + if (property.includes('-private')) { + const resPrivateProperty = await showModalAndWait( + actions.GET_PROFILE_DATA, { + property + } + ); + + if (resPrivateProperty.action === 'accept') { + + const requestedData = profileData.customData[property] + if (requestedData) { + response = JSON.stringify(requestedData); + break + } else { + throw new Error('Cannot find requested data') + } + } else { + throw new Error('User denied permission for private property') + } + } else { + const requestedData = profileData.customData[property] + if (requestedData) { + response = JSON.stringify(requestedData); + break + } else { + throw new Error('Cannot find requested data') + } + } + + } catch (error) { + const obj = {}; + const errorMsg = error.message || 'Failed to join the group.'; + obj['error'] = errorMsg; + response = JSON.stringify(obj); + } finally { + this.loader.hide(); + } + break; + } + case 'SET_PROFILE_DATA': { + const defaultProperties = ['tagline', 'bio', 'wallets'] + const requiredFields = ['property', 'data']; + const missingFields = []; + + requiredFields.forEach((field) => { + if (!data[field] && data[field] !== 0) { + missingFields.push(field); + } + }); + + if (missingFields.length > 0) { + const missingFieldsString = missingFields.join(', '); + const errorMsg = `Missing fields: ${missingFieldsString}` + let data = {}; + data['error'] = errorMsg; + response = JSON.stringify(data); + break + } + + + try { + const profileData = window.parent.reduxStore.getState().app.profileData + if (!profileData) { + throw new Error('User does not have a profile') + } + const property = data.property + const propertyIndex = defaultProperties.indexOf(property) + if (propertyIndex !== -1) { + const requestedData = profileData[property] + if (requestedData) { + response = JSON.stringify(requestedData); + break + } else { + throw new Error('Cannot find requested data') + } + } + + if (property.includes('-private')) { + const resPrivateProperty = await showModalAndWait( + actions.GET_PROFILE_DATA, { + property + } + ); + + if (resPrivateProperty.action === 'accept') { + + const requestedData = profileData.customData[property] + if (requestedData) { + response = JSON.stringify(requestedData); + break + } else { + throw new Error('Cannot find requested data') + } + } else { + throw new Error('User denied permission for private property') + } + } else { + const requestedData = profileData.customData[property] + if (requestedData) { + response = JSON.stringify(requestedData); + break + } else { + throw new Error('Cannot find requested data') + } + } + + } catch (error) { + const obj = {}; + const errorMsg = error.message || 'Failed to join the group.'; + obj['error'] = errorMsg; + response = JSON.stringify(obj); + } finally { + this.loader.hide(); + } + break; + } + case actions.GET_WALLET_BALANCE: { const requiredFields = ['coin']; @@ -3103,45 +3258,45 @@ class WebBrowser extends LitElement { } } addAppToNotificationList(appName) { - if(!appName) throw new Error('unknown app name') + if (!appName) throw new Error('unknown app name') const id = `appNotificationList-${this.selectedAddress.address}`; const checkData = localStorage.getItem(id) ? JSON.parse(localStorage.getItem(id)) : null; - - if (!checkData) { - const newData = { - [appName]: { - interval: 900000, // 15mins in milliseconds - lastNotification: null, - }, - }; - localStorage.setItem(id, JSON.stringify(newData)); - } else { - const copyData = { ...checkData }; - copyData[appName] = { - interval: 900000, // 15mins in milliseconds - lastNotification: null, - }; - localStorage.setItem(id, JSON.stringify(copyData)); - } - } - updateLastNotification(id, appName) { - const checkData = localStorage.getItem(id) ? JSON.parse(localStorage.getItem(id)) : null; - - if (checkData) { - const copyData = { ...checkData }; - if (copyData[appName]) { - copyData[appName].lastNotification = Date.now(); // Make sure to use Date.now(), not date.now() - } else { - copyData[appName] = { - interval: 900000, // 15mins in milliseconds - lastNotification: Date.now(), + if (!checkData) { + const newData = { + [appName]: { + interval: 900000, // 15mins in milliseconds + lastNotification: null, + }, }; - } - localStorage.setItem(id, JSON.stringify(copyData)); + localStorage.setItem(id, JSON.stringify(newData)); + } else { + const copyData = { ...checkData }; + copyData[appName] = { + interval: 900000, // 15mins in milliseconds + lastNotification: null, + }; + localStorage.setItem(id, JSON.stringify(copyData)); } - } - + } + + updateLastNotification(id, appName) { + const checkData = localStorage.getItem(id) ? JSON.parse(localStorage.getItem(id)) : null; + + if (checkData) { + const copyData = { ...checkData }; + if (copyData[appName]) { + copyData[appName].lastNotification = Date.now(); // Make sure to use Date.now(), not date.now() + } else { + copyData[appName] = { + interval: 900000, // 15mins in milliseconds + lastNotification: Date.now(), + }; + } + localStorage.setItem(id, JSON.stringify(copyData)); + } + } + renderFollowUnfollowButton() { // Only show the follow/unfollow button if we have permission to modify the list on this node @@ -3493,6 +3648,11 @@ async function showModalAndWait(type, data) {
` : ''} + ${type === actions.GET_PROFILE_DATA ? ` + + ` : ''} ${type === actions.NOTIFICATIONS_PERMISSION ? `