mirror of
https://github.com/Qortal/qortal-ui.git
synced 2025-04-17 16:45:54 +00:00
Merge pull request #191 from Philreact/feature/notification-and-other-fixes
Feature/notification and other fixes
This commit is contained in:
commit
738de26a24
@ -64,6 +64,7 @@ html {
|
|||||||
--app-background-2: #09c6f9;
|
--app-background-2: #09c6f9;
|
||||||
--app-icon: #ffffff;
|
--app-icon: #ffffff;
|
||||||
--app-hr: rgba(0, 0, 0, .3);
|
--app-hr: rgba(0, 0, 0, .3);
|
||||||
|
--code-block-text-color: #008fd5;
|
||||||
}
|
}
|
||||||
|
|
||||||
html[theme="dark"] {
|
html[theme="dark"] {
|
||||||
@ -132,4 +133,5 @@ html[theme="dark"] {
|
|||||||
--app-background-2: #0d324d;
|
--app-background-2: #0d324d;
|
||||||
--app-icon: #03a9f4;
|
--app-icon: #03a9f4;
|
||||||
--app-hr: rgba(255, 255, 255, .3);
|
--app-hr: rgba(255, 255, 255, .3);
|
||||||
|
--code-block-text-color: #008fd5;
|
||||||
}
|
}
|
@ -203,7 +203,8 @@
|
|||||||
"exp2": "Export Master Key",
|
"exp2": "Export Master Key",
|
||||||
"exp3": "Export",
|
"exp3": "Export",
|
||||||
"exp4": "Please choose a wallet to backup the private master key.",
|
"exp4": "Please choose a wallet to backup the private master key.",
|
||||||
"core": "Start Core Settings"
|
"core": "Start Core Settings",
|
||||||
|
"qappNotification1": "Q-App notifications"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
"blockheight": "Block Height",
|
"blockheight": "Block Height",
|
||||||
@ -720,7 +721,8 @@
|
|||||||
"bchange44": "Do you give this application permission to delete from this list?",
|
"bchange44": "Do you give this application permission to delete from this list?",
|
||||||
"bchange45": "Encrypt",
|
"bchange45": "Encrypt",
|
||||||
"bchange46": "Do you give this application permission to save the following file",
|
"bchange46": "Do you give this application permission to save the following file",
|
||||||
"bchange47": "Instant publish - requires"
|
"bchange47": "Instant publish - requires",
|
||||||
|
"bchange48": "Do you give this application permission to send you notifications"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Data Management",
|
"dchange1": "Data Management",
|
||||||
|
@ -140,7 +140,9 @@ class NotificationBell extends connect(store)(LitElement) {
|
|||||||
${this.notificationCount ? html`
|
${this.notificationCount ? html`
|
||||||
<paper-icon-button style="color: green;" icon="icons:mail" @click=${() => this._toggleNotifications()} title="Q-Mail"></paper-icon-button>
|
<paper-icon-button style="color: green;" icon="icons:mail" @click=${() => this._toggleNotifications()} title="Q-Mail"></paper-icon-button>
|
||||||
` : html`
|
` : html`
|
||||||
<paper-icon-button icon="icons:mail" @click=${() => this._toggleNotifications()} title="Q-Mail"></paper-icon-button>
|
<paper-icon-button icon="icons:mail" @click=${() => {
|
||||||
|
this._openTabQmail()
|
||||||
|
}} title="Q-Mail"></paper-icon-button>
|
||||||
`}
|
`}
|
||||||
|
|
||||||
${this.notificationCount ? html`
|
${this.notificationCount ? html`
|
||||||
@ -188,6 +190,23 @@ class NotificationBell extends connect(store)(LitElement) {
|
|||||||
if (this.notifications.length === 0) return
|
if (this.notifications.length === 0) return
|
||||||
this.showNotifications = !this.showNotifications
|
this.showNotifications = !this.showNotifications
|
||||||
}
|
}
|
||||||
|
_openTabQmail() {
|
||||||
|
const query = `?service=APP&name=Q-Mail`
|
||||||
|
store.dispatch(setNewTab({
|
||||||
|
url: `qdn/browser/index.html${query}`,
|
||||||
|
id: 'q-mail-notification',
|
||||||
|
myPlugObj: {
|
||||||
|
"url": "qapps",
|
||||||
|
"domain": "core",
|
||||||
|
"page": `qdn/browser/index.html${query}`,
|
||||||
|
"title": "Q-Mail",
|
||||||
|
"icon": "vaadin:mailbox",
|
||||||
|
"mwcicon": "mail_outline",
|
||||||
|
"menus": [],
|
||||||
|
"parent": false
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
static styles = css`
|
static styles = css`
|
||||||
.layout {
|
.layout {
|
||||||
|
@ -14,7 +14,8 @@ class NotificationsView extends connect(store)(LitElement) {
|
|||||||
notificationConfig: { type: Object },
|
notificationConfig: { type: Object },
|
||||||
q_chatConfig: { type: Object },
|
q_chatConfig: { type: Object },
|
||||||
blockConfig: { type: Object },
|
blockConfig: { type: Object },
|
||||||
theme: { type: String, reflect: true }
|
theme: { type: String, reflect: true },
|
||||||
|
appNotificationList: {type: Array}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,6 +25,11 @@ class NotificationsView extends connect(store)(LitElement) {
|
|||||||
this.q_chatConfig = {}
|
this.q_chatConfig = {}
|
||||||
this.blockConfig = {}
|
this.blockConfig = {}
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
|
this.appNotificationList = [] // Fetch the list of apps from local storage
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated(){
|
||||||
|
this.appNotificationList = this.getAppsFromStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
@ -42,7 +48,7 @@ class NotificationsView extends connect(store)(LitElement) {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(min-width: 1150px) {
|
@media(min-width: 1400px) {
|
||||||
.notification-box {
|
.notification-box {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
@ -106,6 +112,18 @@ class NotificationsView extends connect(store)(LitElement) {
|
|||||||
transition: all .2s;
|
transition: all .2s;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.remove-button {
|
||||||
|
font-family: Roboto, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
color: var(--mdc-theme-primary);
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 8px 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: none;
|
||||||
|
transition: all 0.3s ease-in-out;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,12 +163,47 @@ class NotificationsView extends connect(store)(LitElement) {
|
|||||||
<label for="blockShowNotification">${translate("settings.shownotifications")}</label>
|
<label for="blockShowNotification">${translate("settings.shownotifications")}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="content-box">
|
||||||
|
<h4>${translate("settings.qappNotification1")}</h4>
|
||||||
|
${this.appNotificationList.map((app)=> html`
|
||||||
|
<div style="display: flex; justify-content: space-between; margin-top: 10px;">
|
||||||
|
${app}
|
||||||
|
<button class="remove-button" @click=${() => this.removeApp(app)}>Remove</button>
|
||||||
|
</div>
|
||||||
|
`)}
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${this.renderSetCoreButton()}
|
${this.renderSetCoreButton()}
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAppsFromStorage() {
|
||||||
|
// Your method to fetch the list of apps from local storage
|
||||||
|
// Example:
|
||||||
|
const address= store.getState().app.selectedAddress.address
|
||||||
|
const id = `appNotificationList-${address}`;
|
||||||
|
const data = localStorage.getItem(id);
|
||||||
|
return data ? Object.keys(JSON.parse(data)) : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
removeApp(appName) {
|
||||||
|
// Remove the app from local storage
|
||||||
|
this.removeAppFromStorage(appName);
|
||||||
|
// Update the apps list in the component
|
||||||
|
this.appNotificationList = this.appNotificationList.filter(app => app !== appName);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeAppFromStorage(appName) {
|
||||||
|
// Your method to remove the app from local storage
|
||||||
|
const address= store.getState().app.selectedAddress.address
|
||||||
|
const id = `appNotificationList-${address}`;
|
||||||
|
const data = JSON.parse(localStorage.getItem(id) || '{}');
|
||||||
|
delete data[appName];
|
||||||
|
localStorage.setItem(id, JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
renderSetCoreButton() {
|
renderSetCoreButton() {
|
||||||
if (!isElectron()) {
|
if (!isElectron()) {
|
||||||
return html``
|
return html``
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { LitElement, html, css } from 'lit'
|
import { LitElement, html, css } from 'lit'
|
||||||
import { connect } from 'pwa-helpers'
|
import { connect } from 'pwa-helpers'
|
||||||
import { store } from '../../store.js'
|
import { store } from '../../store.js'
|
||||||
import { allowQAPPAutoAuth, removeQAPPAutoAuth, removeQAPPAutoLists, allowQAPPAutoLists } from '../../redux/app/app-actions.js'
|
import { allowQAPPAutoAuth, removeQAPPAutoAuth, removeQAPPAutoLists, allowQAPPAutoLists, setIsOpenDevDialog } from '../../redux/app/app-actions.js'
|
||||||
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
|
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
|
||||||
import snackbar from '../../functional-components/snackbar.js'
|
import snackbar from '../../functional-components/snackbar.js'
|
||||||
import FileSaver from 'file-saver'
|
import FileSaver from 'file-saver'
|
||||||
@ -15,7 +15,8 @@ class SecurityView extends connect(store)(LitElement) {
|
|||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
theme: { type: String, reflect: true },
|
theme: { type: String, reflect: true },
|
||||||
backupErrorMessage: { type: String }
|
backupErrorMessage: { type: String },
|
||||||
|
closeSettings: {attribute: false}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +76,23 @@ class SecurityView extends connect(store)(LitElement) {
|
|||||||
transition: all .2s;
|
transition: all .2s;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.add-dev-button {
|
||||||
|
margin-top: 4px;
|
||||||
|
max-height: 28px;
|
||||||
|
padding: 5px 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
background-color: #03a9f4;
|
||||||
|
color: white;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-dev-button:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,6 +140,14 @@ class SecurityView extends connect(store)(LitElement) {
|
|||||||
</label>
|
</label>
|
||||||
<mwc-checkbox style="margin-right: -15px;" id="authButton" @click=${(e) => this.checkForLists(e)} ?checked=${store.getState().app.qAPPAutoLists}></mwc-checkbox>
|
<mwc-checkbox style="margin-right: -15px;" id="authButton" @click=${(e) => this.checkForLists(e)} ?checked=${store.getState().app.qAPPAutoLists}></mwc-checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="checkbox-row">
|
||||||
|
<button
|
||||||
|
class="add-dev-button"
|
||||||
|
title="${translate('tabmenu.tm18')}"
|
||||||
|
@click=${this.openDevDialog}
|
||||||
|
>${translate('tabmenu.tm38')}</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
@ -155,6 +181,11 @@ class SecurityView extends connect(store)(LitElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openDevDialog() {
|
||||||
|
this.closeSettings()
|
||||||
|
store.dispatch(setIsOpenDevDialog(true))
|
||||||
|
}
|
||||||
|
|
||||||
async downloadBackup() {
|
async downloadBackup() {
|
||||||
let backupname = ''
|
let backupname = ''
|
||||||
this.backupErrorMessage = ''
|
this.backupErrorMessage = ''
|
||||||
|
@ -157,7 +157,9 @@ class UserSettings extends connect(store)(LitElement) {
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
min-height: 460px;
|
min-height: 460px;
|
||||||
height: 60vh;
|
height: auto;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(max-width:700px) {
|
@media(max-width:700px) {
|
||||||
@ -252,7 +254,7 @@ class UserSettings extends connect(store)(LitElement) {
|
|||||||
if (selectedView.id === 'info') {
|
if (selectedView.id === 'info') {
|
||||||
return html`<account-view></account-view>`
|
return html`<account-view></account-view>`
|
||||||
} else if (selectedView.id === 'security') {
|
} else if (selectedView.id === 'security') {
|
||||||
return html`<security-view></security-view>`
|
return html`<security-view .closeSettings=${()=> this.closeSettings()}></security-view>`
|
||||||
} else if (selectedView.id === 'export') {
|
} else if (selectedView.id === 'export') {
|
||||||
return html`<export-keys></export-keys>`
|
return html`<export-keys></export-keys>`
|
||||||
} else if (selectedView.id === 'notification') {
|
} else if (selectedView.id === 'notification') {
|
||||||
|
@ -6,7 +6,7 @@ import { Epml } from '../epml.js'
|
|||||||
import { addPluginRoutes } from '../plugins/addPluginRoutes.js'
|
import { addPluginRoutes } from '../plugins/addPluginRoutes.js'
|
||||||
import { repeat } from 'lit/directives/repeat.js';
|
import { repeat } from 'lit/directives/repeat.js';
|
||||||
import ShortUniqueId from 'short-unique-id';
|
import ShortUniqueId from 'short-unique-id';
|
||||||
import { setNewTab } from '../redux/app/app-actions.js'
|
import { setIsOpenDevDialog, setNewTab } from '../redux/app/app-actions.js'
|
||||||
import localForage from 'localforage'
|
import localForage from 'localforage'
|
||||||
import FileSaver from 'file-saver'
|
import FileSaver from 'file-saver'
|
||||||
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
|
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
|
||||||
@ -46,7 +46,8 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
tabInfo: { type: Object },
|
tabInfo: { type: Object },
|
||||||
chatLastSeen: { type: Array },
|
chatLastSeen: { type: Array },
|
||||||
chatHeads: { type: Array },
|
chatHeads: { type: Array },
|
||||||
proxyPort: { type: Number }
|
proxyPort: { type: Number },
|
||||||
|
isOpenDevDialog: {type: Boolean}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,9 +335,11 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
this.chatLastSeen = []
|
this.chatLastSeen = []
|
||||||
this.chatHeads = []
|
this.chatHeads = []
|
||||||
this.proxyPort = 0
|
this.proxyPort = 0
|
||||||
|
this.isOpenDevDialog = false
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
const plugSrc = (myPlug) => {
|
const plugSrc = (myPlug) => {
|
||||||
return myPlug === undefined ? 'about:blank' : `${window.location.origin}/plugin/${myPlug.domain}/${myPlug.page}${this.linkParam}`
|
return myPlug === undefined ? 'about:blank' : `${window.location.origin}/plugin/${myPlug.domain}/${myPlug.page}${this.linkParam}`
|
||||||
}
|
}
|
||||||
@ -396,14 +399,15 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
icon = 'tab'
|
icon = 'tab'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tab.myPlugObj && (tab.myPlugObj.url === 'websites' || tab.myPlugObj.url === 'qapps') && this.tabInfo[tab.id]) {
|
if (tab.myPlugObj && (tab.myPlugObj.url === 'myapp') && this.tabInfo[tab.id]) {
|
||||||
title = this.tabInfo[tab.id].name
|
title = this.tabInfo[tab.id].name
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tab.myPlugObj && (tab.myPlugObj.url === 'websites' || tab.myPlugObj.url === 'qapps') && this.tabInfo[tab.id]) {
|
if (tab.myPlugObj && (tab.myPlugObj.url === 'myapp') && this.tabInfo[tab.id]) {
|
||||||
count = this.tabInfo[tab.id].count
|
count = this.tabInfo[tab.id].count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (tab.myPlugObj && tab.myPlugObj.url === 'q-chat') {
|
if (tab.myPlugObj && tab.myPlugObj.url === 'q-chat') {
|
||||||
for (const chat of this.chatHeads) {
|
for (const chat of this.chatHeads) {
|
||||||
|
|
||||||
@ -458,11 +462,6 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
this.currentTab = lengthOfTabs
|
this.currentTab = lengthOfTabs
|
||||||
}}
|
}}
|
||||||
>+</button>
|
>+</button>
|
||||||
<button
|
|
||||||
class="add-dev-button"
|
|
||||||
title="${translate('tabmenu.tm18')}"
|
|
||||||
@click=${this.openDevDialog}
|
|
||||||
>${translate('tabmenu.tm38')}</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
${repeat(this.tabs, (tab) => tab.id, (tab, index) => html`
|
${repeat(this.tabs, (tab) => tab.id, (tab, index) => html`
|
||||||
@ -484,7 +483,15 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
</nav-bar>
|
</nav-bar>
|
||||||
</div>
|
</div>
|
||||||
`)}
|
`)}
|
||||||
<mwc-dialog id="addDevDialog">
|
<mwc-dialog id="addDevDialog"
|
||||||
|
?open=${this.isOpenDevDialog}
|
||||||
|
@closed=${() => {
|
||||||
|
this.shadowRoot.getElementById('domainInput').value = ''
|
||||||
|
this.shadowRoot.getElementById('portInput').value = ''
|
||||||
|
this.isOpenDevDialog = false
|
||||||
|
store.dispatch(setIsOpenDevDialog(false))
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div style="text-align: center;">
|
<div style="text-align: center;">
|
||||||
<h2>${translate('tabmenu.tm39')}</h2>
|
<h2>${translate('tabmenu.tm39')}</h2>
|
||||||
<hr>
|
<hr>
|
||||||
@ -551,12 +558,6 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
openDevDialog() {
|
|
||||||
this.shadowRoot.getElementById('domainInput').value = ''
|
|
||||||
this.shadowRoot.getElementById('portInput').value = ''
|
|
||||||
this.shadowRoot.querySelector("#addDevDialog").show()
|
|
||||||
}
|
|
||||||
|
|
||||||
async getProxyPort() {
|
async getProxyPort() {
|
||||||
this.proxyPort = 0
|
this.proxyPort = 0
|
||||||
let framework = ''
|
let framework = ''
|
||||||
@ -733,11 +734,9 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
const myPlugObj = plugArr.find(pagePlug => {
|
const myPlugObj = plugArr.find(pagePlug => {
|
||||||
return pagePlug.url === this.url
|
return pagePlug.url === this.url
|
||||||
})
|
})
|
||||||
|
|
||||||
if (this.tabs.length === 0) {
|
if (this.tabs.length === 0) {
|
||||||
this.addTab({
|
this.addTab({
|
||||||
url: this.url,
|
url: "",
|
||||||
myPlugObj,
|
|
||||||
id: this.uid()
|
id: this.uid()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -780,7 +779,7 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (split[0] === '' && split[1] === 'app' && split[2] === undefined) {
|
if (split[0] === '' && split[1] === 'app' && split[2] === undefined) {
|
||||||
newUrl = 'wallet'
|
newUrl = ''
|
||||||
newLinkParam = ''
|
newLinkParam = ''
|
||||||
} else if (split.length === 5 && split[1] === 'app') {
|
} else if (split.length === 5 && split[1] === 'app') {
|
||||||
newUrl = split[2]
|
newUrl = split[2]
|
||||||
@ -792,7 +791,6 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
newUrl = '404'
|
newUrl = '404'
|
||||||
newLinkParam = ''
|
newLinkParam = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newUrl !== this.url) {
|
if (newUrl !== this.url) {
|
||||||
this.url = newUrl
|
this.url = newUrl
|
||||||
}
|
}
|
||||||
@ -838,6 +836,9 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
//clear newTab
|
//clear newTab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(state.app.isOpenDevDialog){
|
||||||
|
this.isOpenDevDialog = state.app.isOpenDevDialog
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import config from './config'
|
import config from './config'
|
||||||
import { dispatcher } from './dispatcher'
|
import { dispatcher } from './dispatcher'
|
||||||
import snackbar from '../functional-components/snackbar.js'
|
import snackbar from '../functional-components/snackbar.js'
|
||||||
import { NEW_MESSAGE, NEW_MESSAGE_NOTIFICATION_QAPP } from './types'
|
import { NEW_MESSAGE, NEW_MESSAGE_NOTIFICATION_QAPP, NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL } from './types'
|
||||||
|
|
||||||
let initial = 0
|
let initial = 0
|
||||||
let _state
|
let _state
|
||||||
@ -43,8 +43,8 @@ const notificationCheck = function () {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export const doNewMessage = function (req) {
|
export const doNewMessage = function (req) {
|
||||||
|
|
||||||
const newMessage = () => {
|
const newMessage = () => {
|
||||||
|
|
||||||
let data
|
let data
|
||||||
if (req.type && req.type === 'qapp') {
|
if (req.type && req.type === 'qapp') {
|
||||||
data = req
|
data = req
|
||||||
@ -73,10 +73,16 @@ export const doNewMessage = function (req) {
|
|||||||
} else {
|
} else {
|
||||||
_state = notificationState
|
_state = notificationState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const page = window.top.location.href
|
const page = window.top.location.href
|
||||||
if (!document.hasFocus()) {
|
if(req.type && req.type === 'qapp-local-notification'){
|
||||||
|
try {
|
||||||
|
dispatcher({ type: NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL, data: req })
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log('error', error)
|
||||||
|
}
|
||||||
|
}else if (!document.hasFocus()) {
|
||||||
newMessage()
|
newMessage()
|
||||||
} else {
|
} else {
|
||||||
if (page.includes(req.url) === false) {
|
if (page.includes(req.url) === false) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { NEW_MESSAGE, NEW_MESSAGE_NOTIFICATION_QAPP } from './types'
|
import { NEW_MESSAGE, NEW_MESSAGE_NOTIFICATION_QAPP, NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL } from './types'
|
||||||
import { newMessage, newMessageNotificationQapp } from './notification-actions'
|
import { newMessage, newMessageNotificationQapp, newMessageNotificationQappLocal } from './notification-actions'
|
||||||
|
|
||||||
export const dispatcher = function (notificationState) {
|
export const dispatcher = function (notificationState) {
|
||||||
|
|
||||||
@ -8,6 +8,8 @@ export const dispatcher = function (notificationState) {
|
|||||||
return newMessage(notificationState.data)
|
return newMessage(notificationState.data)
|
||||||
case NEW_MESSAGE_NOTIFICATION_QAPP:
|
case NEW_MESSAGE_NOTIFICATION_QAPP:
|
||||||
return newMessageNotificationQapp(notificationState.data)
|
return newMessageNotificationQapp(notificationState.data)
|
||||||
|
case NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL:
|
||||||
|
return newMessageNotificationQappLocal(notificationState.data)
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
export { newMessage, newMessageNotificationQapp } from './new-message'
|
export { newMessage, newMessageNotificationQapp, newMessageNotificationQappLocal } from './new-message'
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import { store } from '../../store.js'
|
import { store } from '../../store.js'
|
||||||
import { doPageUrl, setNewTab } from '../../redux/app/app-actions.js'
|
import { doPageUrl, setNewTab } from '../../redux/app/app-actions.js'
|
||||||
import isElectron from 'is-electron'
|
import isElectron from 'is-electron'
|
||||||
|
import ShortUniqueId from 'short-unique-id';
|
||||||
|
|
||||||
|
const uid = new ShortUniqueId()
|
||||||
|
|
||||||
export const newMessage = (data) => {
|
export const newMessage = (data) => {
|
||||||
const alert = playSound(data.sound)
|
const alert = playSound(data.sound)
|
||||||
@ -101,6 +104,157 @@ export const newMessageNotificationQapp = (data) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const extractComponents= async (url)=> {
|
||||||
|
if (!url.startsWith("qortal://")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
url = url.replace(/^(qortal\:\/\/)/, "");
|
||||||
|
if (url.includes("/")) {
|
||||||
|
let parts = url.split("/");
|
||||||
|
const service = parts[0].toUpperCase();
|
||||||
|
parts.shift();
|
||||||
|
const name = parts[0];
|
||||||
|
parts.shift();
|
||||||
|
let identifier;
|
||||||
|
|
||||||
|
if (parts.length > 0) {
|
||||||
|
identifier = parts[0]; // Do not shift yet
|
||||||
|
// Check if a resource exists with this service, name and identifier combination
|
||||||
|
let responseObj = await parentEpml.request('apiCall', {
|
||||||
|
url: `/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${this.getApiKey()}`
|
||||||
|
})
|
||||||
|
|
||||||
|
if (responseObj.totalChunkCount > 0) {
|
||||||
|
// Identifier exists, so don't include it in the path
|
||||||
|
parts.shift();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
identifier = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const path = parts.join("/");
|
||||||
|
|
||||||
|
const components = {};
|
||||||
|
components["service"] = service;
|
||||||
|
components["name"] = name;
|
||||||
|
components["identifier"] = identifier;
|
||||||
|
components["path"] = path;
|
||||||
|
return components;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const newMessageNotificationQappLocal = (data) => {
|
||||||
|
const alert = playSound(data.sound)
|
||||||
|
|
||||||
|
// Should I show notification ?
|
||||||
|
if (store.getState().user.notifications.q_chat.showNotification) {
|
||||||
|
|
||||||
|
// Yes, I can but should I play sound ?
|
||||||
|
if (store.getState().user.notifications.q_chat.playSound) {
|
||||||
|
|
||||||
|
const notify = new Notification(data.title, data.options)
|
||||||
|
|
||||||
|
notify.onshow = (e) => {
|
||||||
|
alert.play()
|
||||||
|
}
|
||||||
|
|
||||||
|
notify.onclick = async(e) => {
|
||||||
|
const url = data?.url
|
||||||
|
const value = url
|
||||||
|
let newQuery = value;
|
||||||
|
if (newQuery.endsWith('/')) {
|
||||||
|
newQuery = newQuery.slice(0, -1);
|
||||||
|
}
|
||||||
|
const res = await 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}`
|
||||||
|
}
|
||||||
|
const tab = {
|
||||||
|
url: `qdn/browser/index.html${query}`,
|
||||||
|
id: uid(),
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
store.dispatch(setNewTab(tab))
|
||||||
|
if (!isElectron()) {
|
||||||
|
window.focus();
|
||||||
|
} else {
|
||||||
|
window.electronAPI.focusApp()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const notify = new Notification(data.title, data.options)
|
||||||
|
|
||||||
|
notify.onclick = async(e) => {
|
||||||
|
const url = data?.url
|
||||||
|
const value = url
|
||||||
|
let newQuery = value;
|
||||||
|
if (newQuery.endsWith('/')) {
|
||||||
|
newQuery = newQuery.slice(0, -1);
|
||||||
|
}
|
||||||
|
const res = await 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}`
|
||||||
|
}
|
||||||
|
const tab = {
|
||||||
|
url: `qdn/browser/index.html${query}`,
|
||||||
|
id: uid(),
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
store.dispatch(setNewTab(tab))
|
||||||
|
if (!isElectron()) {
|
||||||
|
window.focus();
|
||||||
|
} else {
|
||||||
|
window.electronAPI.focusApp()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const playSound = (soundUrl) => {
|
const playSound = (soundUrl) => {
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
export const NEW_MESSAGE = 'NEW_MESSAGE'
|
export const NEW_MESSAGE = 'NEW_MESSAGE'
|
||||||
export const NEW_MESSAGE_NOTIFICATION_QAPP = 'NEW_MESSAGE_NOTIFICATION_QAPP'
|
export const NEW_MESSAGE_NOTIFICATION_QAPP = 'NEW_MESSAGE_NOTIFICATION_QAPP'
|
||||||
|
export const NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL = 'NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Core App Actions here...
|
// 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 } 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 } from '../app-action-types.js'
|
||||||
|
|
||||||
export const doUpdateBlockInfo = (blockObj) => {
|
export const doUpdateBlockInfo = (blockObj) => {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -126,7 +126,12 @@ export const setNewTab = (payload) => {
|
|||||||
payload
|
payload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export const setIsOpenDevDialog = (payload)=> {
|
||||||
|
return {
|
||||||
|
type: IS_OPEN_DEV_DIALOG,
|
||||||
|
payload
|
||||||
|
}
|
||||||
|
}
|
||||||
export const addTabInfo = (payload) => {
|
export const addTabInfo = (payload) => {
|
||||||
return {
|
return {
|
||||||
type: ADD_TAB_INFO,
|
type: ADD_TAB_INFO,
|
||||||
|
@ -27,4 +27,5 @@ export const SET_CHAT_LAST_SEEN = 'SET_CHAT_LAST_SEEN'
|
|||||||
export const ADD_CHAT_LAST_SEEN = 'ADD_CHAT_LAST_SEEN'
|
export const ADD_CHAT_LAST_SEEN = 'ADD_CHAT_LAST_SEEN'
|
||||||
export const SET_NEW_TAB = 'SET_NEW_TAB'
|
export const SET_NEW_TAB = 'SET_NEW_TAB'
|
||||||
export const ADD_TAB_INFO = 'ADD_TAB_INFO'
|
export const ADD_TAB_INFO = 'ADD_TAB_INFO'
|
||||||
export const SET_TAB_NOTIFICATIONS = 'SET_TAB_NOTIFICATIONS'
|
export const SET_TAB_NOTIFICATIONS = 'SET_TAB_NOTIFICATIONS'
|
||||||
|
export const IS_OPEN_DEV_DIALOG = 'IS_OPEN_DEV_DIALOG'
|
@ -1,6 +1,6 @@
|
|||||||
// Loading state, login state, isNavDrawOpen state etc. None of this needs to be saved to localstorage.
|
// Loading state, login state, isNavDrawOpen state etc. None of this needs to be saved to localstorage.
|
||||||
import { loadStateFromLocalStorage, saveStateToLocalStorage } from '../../localStorageHelpers.js'
|
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 } 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 } from './app-action-types.js'
|
||||||
import { initWorkersReducer } from './reducers/init-workers.js'
|
import { initWorkersReducer } from './reducers/init-workers.js'
|
||||||
import { loginReducer } from './reducers/login-reducer.js'
|
import { loginReducer } from './reducers/login-reducer.js'
|
||||||
import { setNode, addNode } from './reducers/manage-node.js'
|
import { setNode, addNode } from './reducers/manage-node.js'
|
||||||
@ -49,7 +49,8 @@ const INITIAL_STATE = {
|
|||||||
qAPPAutoLists: loadStateFromLocalStorage('qAPPAutoLists') || false,
|
qAPPAutoLists: loadStateFromLocalStorage('qAPPAutoLists') || false,
|
||||||
chatLastSeen: [],
|
chatLastSeen: [],
|
||||||
newTab: null,
|
newTab: null,
|
||||||
tabInfo: {}
|
tabInfo: {},
|
||||||
|
isOpenDevDialog: false
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (state = INITIAL_STATE, action) => {
|
export default (state = INITIAL_STATE, action) => {
|
||||||
@ -231,6 +232,12 @@ export default (state = INITIAL_STATE, action) => {
|
|||||||
newTab: action.payload
|
newTab: action.payload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case IS_OPEN_DEV_DIALOG: {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isOpenDevDialog: action.payload
|
||||||
|
}
|
||||||
|
}
|
||||||
case ADD_TAB_INFO: {
|
case ADD_TAB_INFO: {
|
||||||
const newTabInfo = action.payload
|
const newTabInfo = action.payload
|
||||||
if (state.tabInfo[newTabInfo.id] && state.tabInfo[newTabInfo.id].name && newTabInfo.name === state.tabInfo[newTabInfo.id].name) break
|
if (state.tabInfo[newTabInfo.id] && state.tabInfo[newTabInfo.id].name && newTabInfo.name === state.tabInfo[newTabInfo.id].name) break
|
||||||
|
@ -1 +1 @@
|
|||||||
export const UI_VERSION = "4.0.4";
|
export const UI_VERSION = "4.3.0";
|
||||||
|
@ -845,7 +845,7 @@ function createWindow() {
|
|||||||
})
|
})
|
||||||
myWindow.maximize()
|
myWindow.maximize()
|
||||||
myWindow.show()
|
myWindow.show()
|
||||||
myWindow.loadURL('http://localhost:12388/app/wallet')
|
myWindow.loadURL('http://localhost:12388/app')
|
||||||
myWindow.on('closed', function () {
|
myWindow.on('closed', function () {
|
||||||
myWindow = null
|
myWindow = null
|
||||||
})
|
})
|
||||||
@ -886,7 +886,7 @@ function createNewWindow() {
|
|||||||
show: false
|
show: false
|
||||||
})
|
})
|
||||||
newWindow.show()
|
newWindow.show()
|
||||||
newWindow.loadURL('http://localhost:12388/app/wallet')
|
newWindow.loadURL('http://localhost:12388/app')
|
||||||
newWindow.on('closed', function () {
|
newWindow.on('closed', function () {
|
||||||
newWindow = null
|
newWindow = null
|
||||||
})
|
})
|
||||||
|
@ -1870,7 +1870,7 @@ class ChatPage extends LitElement {
|
|||||||
return memberItem
|
return memberItem
|
||||||
})
|
})
|
||||||
const membersWithName = await Promise.all(getMembersWithName)
|
const membersWithName = await Promise.all(getMembersWithName)
|
||||||
this.groupMembers = membersWithName
|
this.groupMembers = [...this.groupMembers, ...membersWithName]
|
||||||
this.pageNumber = this.pageNumber + 1
|
this.pageNumber = this.pageNumber + 1
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
}
|
}
|
||||||
|
@ -225,7 +225,6 @@ class ChatRightPanel extends LitElement {
|
|||||||
if(this.groupMembers.length < 20){
|
if(this.groupMembers.length < 20){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.log('this.leaveGroupObjp', this.leaveGroupObj)
|
|
||||||
this.getMoreMembers(this.leaveGroupObj.groupId)
|
this.getMoreMembers(this.leaveGroupObj.groupId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,7 +251,6 @@ class ChatRightPanel extends LitElement {
|
|||||||
activeChatHeadUrl=""
|
activeChatHeadUrl=""
|
||||||
.setActiveChatHeadUrl=${(val) => {
|
.setActiveChatHeadUrl=${(val) => {
|
||||||
if (val.address === this.myAddress) return;
|
if (val.address === this.myAddress) return;
|
||||||
console.log({ val });
|
|
||||||
this.selectedHead = val;
|
this.selectedHead = val;
|
||||||
this.setOpenUserInfo(true);
|
this.setOpenUserInfo(true);
|
||||||
this.setUserName({
|
this.setUserName({
|
||||||
@ -269,7 +267,6 @@ class ChatRightPanel extends LitElement {
|
|||||||
activeChatHeadUrl=""
|
activeChatHeadUrl=""
|
||||||
.setActiveChatHeadUrl=${(val) => {
|
.setActiveChatHeadUrl=${(val) => {
|
||||||
if (val.address === this.myAddress) return;
|
if (val.address === this.myAddress) return;
|
||||||
console.log({ val });
|
|
||||||
this.selectedHead = val;
|
this.selectedHead = val;
|
||||||
this.setOpenUserInfo(true);
|
this.setOpenUserInfo(true);
|
||||||
this.setUserName({
|
this.setUserName({
|
||||||
@ -286,7 +283,6 @@ class ChatRightPanel extends LitElement {
|
|||||||
activeChatHeadUrl=""
|
activeChatHeadUrl=""
|
||||||
.setActiveChatHeadUrl=${(val) => {
|
.setActiveChatHeadUrl=${(val) => {
|
||||||
if (val.address === this.myAddress) return;
|
if (val.address === this.myAddress) return;
|
||||||
console.log({ val });
|
|
||||||
this.selectedHead = val;
|
this.selectedHead = val;
|
||||||
this.setOpenUserInfo(true);
|
this.setOpenUserInfo(true);
|
||||||
this.setUserName({
|
this.setUserName({
|
||||||
|
@ -101,7 +101,7 @@ function processText(input) {
|
|||||||
// Store the URL in a data attribute
|
// Store the URL in a data attribute
|
||||||
link.setAttribute('data-url', part)
|
link.setAttribute('data-url', part)
|
||||||
link.textContent = part
|
link.textContent = part
|
||||||
link.style.color = 'var(--nav-text-color)'
|
link.style.color = 'var(--code-block-text-color)'
|
||||||
link.style.textDecoration = 'underline'
|
link.style.textDecoration = 'underline'
|
||||||
link.style.cursor = 'pointer'
|
link.style.cursor = 'pointer'
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ function processText(input) {
|
|||||||
url: `qdn/browser/index.html${query}`,
|
url: `qdn/browser/index.html${query}`,
|
||||||
id: uid(),
|
id: uid(),
|
||||||
myPlugObj: {
|
myPlugObj: {
|
||||||
"url": service === 'WEBSITE' ? "websites" : "qapps",
|
"url": "myapp",
|
||||||
"domain": "core",
|
"domain": "core",
|
||||||
"page": `qdn/browser/index.html${query}`,
|
"page": `qdn/browser/index.html${query}`,
|
||||||
"title": name,
|
"title": name,
|
||||||
|
@ -50,4 +50,13 @@ export const DECRYPT_DATA_GROUP = 'DECRYPT_DATA_GROUP'
|
|||||||
export const SAVE_FILE = 'SAVE_FILE'
|
export const SAVE_FILE = 'SAVE_FILE'
|
||||||
|
|
||||||
//SET_TAB_NOTIFICATIONS
|
//SET_TAB_NOTIFICATIONS
|
||||||
export const SET_TAB_NOTIFICATIONS = 'SET_TAB_NOTIFICATIONS'
|
export const SET_TAB_NOTIFICATIONS = 'SET_TAB_NOTIFICATIONS'
|
||||||
|
|
||||||
|
//OPEN_NEW_TAB
|
||||||
|
export const OPEN_NEW_TAB = 'OPEN_NEW_TAB'
|
||||||
|
|
||||||
|
//NOTIFICATIONS_PERMISSION
|
||||||
|
export const NOTIFICATIONS_PERMISSION = 'NOTIFICATIONS_PERMISSION'
|
||||||
|
|
||||||
|
//SEND_LOCAL_NOTIFICATION
|
||||||
|
export const SEND_LOCAL_NOTIFICATION = 'SEND_LOCAL_NOTIFICATION'
|
@ -3,6 +3,7 @@ import { render } from 'lit/html.js'
|
|||||||
import { Epml } from '../../../../epml'
|
import { Epml } from '../../../../epml'
|
||||||
import isElectron from 'is-electron'
|
import isElectron from 'is-electron'
|
||||||
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
|
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
|
||||||
|
import ShortUniqueId from 'short-unique-id';
|
||||||
|
|
||||||
registerTranslateConfig({
|
registerTranslateConfig({
|
||||||
loader: (lang) => fetch(`/language/${lang}.json`).then((res) => res.json())
|
loader: (lang) => fetch(`/language/${lang}.json`).then((res) => res.json())
|
||||||
@ -131,6 +132,7 @@ class WebBrowser extends LitElement {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.url = 'about:blank';
|
this.url = 'about:blank';
|
||||||
|
this.uid = new ShortUniqueId()
|
||||||
this.myAddress = window.parent.reduxStore.getState().app.selectedAddress
|
this.myAddress = window.parent.reduxStore.getState().app.selectedAddress
|
||||||
this._publicKey = { key: '', hasPubKey: false }
|
this._publicKey = { key: '', hasPubKey: false }
|
||||||
const urlParams = new URLSearchParams(window.location.search)
|
const urlParams = new URLSearchParams(window.location.search)
|
||||||
@ -318,6 +320,44 @@ class WebBrowser extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async linkOpenNewTab(link) {
|
||||||
|
|
||||||
|
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(),
|
||||||
|
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() {
|
render() {
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
@ -1280,8 +1320,95 @@ class WebBrowser extends LitElement {
|
|||||||
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
|
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case actions.OPEN_NEW_TAB: {
|
||||||
|
if(!data.qortalLink){
|
||||||
|
const obj = {};
|
||||||
|
const errorMsg = 'Please enter a qortal link - qortal://...';
|
||||||
|
obj['error'] = errorMsg;
|
||||||
|
response = JSON.stringify(obj);
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.linkOpenNewTab(data.qortalLink)
|
||||||
|
response = true
|
||||||
|
break;
|
||||||
|
} catch (error) {
|
||||||
|
console.log('error', error)
|
||||||
|
const obj = {};
|
||||||
|
const errorMsg = "Invalid qortal link";
|
||||||
|
obj['error'] = errorMsg;
|
||||||
|
response = JSON.stringify(obj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
case actions.NOTIFICATIONS_PERMISSION: {
|
||||||
|
try {
|
||||||
|
|
||||||
|
const res = await showModalAndWait(
|
||||||
|
actions.NOTIFICATIONS_PERMISSION,
|
||||||
|
{
|
||||||
|
name: this.name
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.action === 'accept'){
|
||||||
|
this.addAppToNotificationList(this.name)
|
||||||
|
response = true
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
response = false
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
case actions.SEND_LOCAL_NOTIFICATION: {
|
||||||
|
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) {
|
||||||
|
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)
|
||||||
|
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: {
|
case actions.SEND_CHAT_MESSAGE: {
|
||||||
const message = data.message;
|
const message = data.message;
|
||||||
const recipient = data.destinationAddress;
|
const recipient = data.destinationAddress;
|
||||||
@ -2734,6 +2861,46 @@ class WebBrowser extends LitElement {
|
|||||||
use(checkLanguage);
|
use(checkLanguage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addAppToNotificationList(appName) {
|
||||||
|
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(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
localStorage.setItem(id, JSON.stringify(copyData));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
renderFollowUnfollowButton() {
|
renderFollowUnfollowButton() {
|
||||||
// Only show the follow/unfollow button if we have permission to modify the list on this node
|
// Only show the follow/unfollow button if we have permission to modify the list on this node
|
||||||
@ -3085,7 +3252,12 @@ async function showModalAndWait(type, data) {
|
|||||||
<p class="modal-paragraph">${get("browserpage.bchange46")}: <span> ${data.filename}</span></p>
|
<p class="modal-paragraph">${get("browserpage.bchange46")}: <span> ${data.filename}</span></p>
|
||||||
</div>
|
</div>
|
||||||
` : ''}
|
` : ''}
|
||||||
|
${type === actions.NOTIFICATIONS_PERMISSION ? `
|
||||||
|
<div class="modal-subcontainer">
|
||||||
|
<p class="modal-paragraph">${get("browserpage.bchange48")}</p>
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
|
||||||
${type === actions.DELETE_LIST_ITEM ? `
|
${type === actions.DELETE_LIST_ITEM ? `
|
||||||
<div class="modal-subcontainer">
|
<div class="modal-subcontainer">
|
||||||
<p class="modal-paragraph">${get("browserpage.bchange44")}</p>
|
<p class="modal-paragraph">${get("browserpage.bchange44")}</p>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user