diff --git a/README.md b/README.md index 2449f9cf..6af149dc 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Easiest way to install the lastest required packages on Linux is via nvm. ``` source ~/.profile ``` (For Debian based distro)
``` source ~/.bashrc ``` (For Fedora / CentOS)
``` nvm ls-remote ``` (Fetch list of available versions)
-``` nvm install v20.9.0 ``` (LTS: Iron supported by Electron)
+``` nvm install v18.17.1 ``` (LTS: Hydrogen supported by Electron V27)
``` npm --location=global install npm@10.5.0 ```
Adding via binary package mirror will only work if you have set the package path. You can do a node or java build via ports instead by downloading ports with portsnap fetch method. diff --git a/core/src/components/app-info.js b/core/src/components/app-info.js index c3cc86da..c5d4aa95 100644 --- a/core/src/components/app-info.js +++ b/core/src/components/app-info.js @@ -1,105 +1,70 @@ import {css, html, LitElement} from 'lit' import {connect} from 'pwa-helpers' import {store} from '../store.js' -import {doPageUrl} from '../redux/app/app-actions.js' -import {translate} from '../../translate/index.js' -import WebWorker from 'web-worker:./computePowWorker.js'; -import {routes} from '../plugins/routes.js'; - -import '@material/mwc-icon' -import '@material/mwc-button' +import {translate} from '../../translate' class AppInfo extends connect(store)(LitElement) { static get properties() { return { - blockInfo: { type: Object }, - nodeStatus: { type: Object }, nodeInfo: { type: Array }, coreInfo: { type: Array }, nodeConfig: { type: Object }, - pageUrl: { type: String }, - publicizeAddress: { type: String }, theme: { type: String, reflect: true } } } static get styles() { - return [ - css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --paper-input-container-focus-color: var(--mdc-theme-primary); - } - .normal { - --mdc-theme-primary: rgb(3, 169, 244); - } + return css` + * { + --mdc-theme-primary: rgb(3, 169, 244); + --paper-input-container-focus-color: var(--mdc-theme-primary); + } - .normal-button { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-on-primary: white; - } + .normal { + --mdc-theme-primary: rgb(3, 169, 244); + } - mwc-button.normal-button { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-on-primary: white; - } - .test-net { - --mdc-theme-primary: black; - } + #profileInMenu { + flex: 0 0 100px; + padding:12px; + border-top: 1px solid var(--border); + background: var(--sidetopbar); + } - .test-net-button { - --mdc-theme-primary: black; - --mdc-theme-on-primary: white; - } + .info { + margin: 0; + font-size: 14px; + font-weight: 100; + display: inline-block; + width: 100%; + padding-bottom: 8px; + color: var(--black); + } - mwc-button.test-net-button { - --mdc-theme-primary: black; - --mdc-theme-on-primary: white; - } - #profileInMenu { - flex: 0 0 100px; - padding:12px; - border-top: 1px solid var(--border); - background: var(--sidetopbar); - } - .info { - margin: 0; - font-size: 14px; - font-weight:100; - display: inline-block; - width:100%; - padding-bottom:8px; - color: var(--black); - } - .blue { - color: #03a9f4; - margin: 0; - font-size: 14px; - font-weight:200; - display: inline; - } - .black { - color: var(--black); - margin: 0; - font-size: 14px; - font-weight:200; - display: inline; - } - ` - ] + .blue { + color: #03a9f4; + margin: 0; + font-size: 14px; + font-weight: 200; + display: inline; + } + + .black { + color: var(--black); + margin: 0; + font-size: 14px; + font-weight: 200; + display: inline; + } + ` } constructor() { super() - this.blockInfo = {} this.nodeInfo = [] this.coreInfo = [] this.nodeStatus = {} - this.pageUrl = '' - this.publicizeAddress = '' this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' - this.publicKeyisOnChainConfirmation = false - this.interval } render() { @@ -115,133 +80,25 @@ class AppInfo extends connect(store)(LitElement) { } firstUpdated() { - this.publicizeAddress = store.getState().app.selectedAddress.address + '_publicize' - this.setStorage() this.getNodeInfo() this.getCoreInfo() - // try { - // this.confirmPublicKeyOnChain(store.getState().app.selectedAddress.address) - // } catch (error) { - // console.error(error) - // } setInterval(() => { this.getNodeInfo() this.getCoreInfo() - }, 30000) - } - - setStorage() { - if (localStorage.getItem(this.publicizeAddress) === null) { - localStorage.setItem(this.publicizeAddress, 'false') - } - } - - async confirmPublicKeyOnChain(address) { - const _computePow2 = async (chatBytes) => { - const difficulty = 14 - const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full' - const worker = new WebWorker(); - let nonce = null - let chatBytesArray = null - await new Promise((res, rej) => { - worker.postMessage({chatBytes, path, difficulty}) - - worker.onmessage = e => { - worker.terminate() - chatBytesArray = e.data.chatBytesArray - nonce = e.data.nonce - res() - } - }) - - let _response = await routes.sign_chat({ - data: { - nonce: store.getState().app.selectedAddress.nonce, - chatBytesArray: chatBytesArray, - chatNonce: nonce - }, - }) - return _response - } - - let stop = false - const checkPublicKey = async () => { - if (!stop) { - stop = true - try { - if(localStorage.getItem(this.publicizeAddress) === 'true') { - clearInterval(this.interval) - return - } - const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/addresses/publickey/${address}` - const res = await fetch(url) - let data = '' - try { - data = await res.text() - } catch (error) { - data = { - error: 'error' - } - } - if(data === 'false' && this.nodeInfo.isSynchronizing !== true) { - let _reference = new Uint8Array(64) - window.crypto.getRandomValues(_reference) - let reference = window.parent.Base58.encode(_reference) - const chatRes = await routes.chat({ - data: { - type: 19, - nonce: store.getState().app.selectedAddress.nonce, - params: { - lastReference: reference, - proofOfWorkNonce: 0, - fee: 0, - timestamp: Date.now(), - }, - disableModal: true - }, - disableModal: true, - }); - - try { - const powRes = await _computePow2(chatRes) - if(powRes === true) { - clearInterval(this.interval) - localStorage.removeItem(this.publicizeAddress) - localStorage.setItem(this.publicizeAddress, 'true') - } - } catch (error) { - console.error(error) - } - } - - if (!data.error && data !== 'false' && data) { - clearInterval(this.interval) - localStorage.removeItem(this.publicizeAddress) - localStorage.setItem(this.publicizeAddress, 'true') - } - - } catch (error) { - } - stop = false - } - } - this.interval = setInterval(checkPublicKey, 5000); + }, 60000) } async getNodeInfo() { const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port const url = `${appinfoUrl}/admin/status` + await fetch(url).then(response => { return response.json() - }) - .then(data => { + }).then(data => { this.nodeInfo = data - }) - .catch(err => { + }).catch(err => { console.error('Request failed', err) }) } @@ -250,13 +107,12 @@ class AppInfo extends connect(store)(LitElement) { const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port const url = `${appinfoUrl}/admin/info` + await fetch(url).then(response => { return response.json() - }) - .then(data => { + }).then(data => { this.coreInfo = data - }) - .catch(err => { + }).catch(err => { console.error('Request failed', err) }) } @@ -283,21 +139,8 @@ class AppInfo extends connect(store)(LitElement) { return html`${translate("appinfo.coreversion")}: ${this.coreInfo.buildVersion ? this.coreInfo.buildVersion : ''}` } - gotoPage(url) { - const myLink = this.shadowRoot.querySelector('#pageLink') - myLink.href = url - myLink.click() - store.dispatch(doPageUrl('')) - } - stateChanged(state) { - this.blockInfo = state.app.blockInfo - this.nodeStatus = state.app.nodeStatus this.nodeConfig = state.app.nodeConfig - this.pageUrl = state.app.pageUrl - if (this.pageUrl.length > 5) { - this.gotoPage(this.pageUrl) - } } } diff --git a/core/src/components/wallet-profile.js b/core/src/components/wallet-profile.js index 83e8c01d..33d92282 100644 --- a/core/src/components/wallet-profile.js +++ b/core/src/components/wallet-profile.js @@ -1,10 +1,7 @@ import {css, html, LitElement} from 'lit' import {connect} from 'pwa-helpers' import {store} from '../store.js' -import {translate} from '../../translate/index.js' - -import '@polymer/paper-toast' -import '@material/mwc-icon-button' +import {translate} from '../../translate' class WalletProfile extends connect(store)(LitElement) { static get properties() { @@ -12,82 +9,76 @@ class WalletProfile extends connect(store)(LitElement) { wallet: { type: Object }, nodeConfig: { type: Object }, accountInfo: { type: Object }, - imageUrl: { type: String }, theme: { type: String, reflect: true } } } static get styles() { - return [ - css` - ` - ] + return css` + #profileInMenu { + padding: 12px; + border-top: var(--border); + background: var(--sidetopbar); + color: var(--black); + } + + #accountName { + margin: 0; + font-size: 18px; + font-weight: 500; + width: 100%; + padding-bottom: 8px; + display: flex; + } + + #blocksMinted { + margin:0; + margin-top: 0; + font-size: 12px; + color: #03a9f4; + } + + #address { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin:0; + margin-top: 8px; + font-size: 11px; + } + + .round-fullinfo { + position: relative; + width: 68px; + height: 68px; + border-radius: 50%; + } + + .full-info-logo { + width: 68px; + height: 68px; + border-radius: 50%; + } + + .inline-block-child { + flex: 1; + } + ` } constructor() { super() + this.wallet = {} this.nodeConfig = {} this.accountInfo = { names: [], addressInfo: {} } - this.imageUrl = '' this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' } render() { return html` -
@@ -102,26 +93,10 @@ class WalletProfile extends connect(store)(LitElement) {

${this.wallet.addresses[0].address}

- ` } - firstUpdated() { - - const container = document.body.querySelector('main-app').shadowRoot.querySelector('app-view').shadowRoot; - const toast = this.shadowRoot.getElementById('toast') - const isMobile = window.matchMedia(`(max-width: ${getComputedStyle(document.body).getPropertyValue('--layout-breakpoint-tablet')})`).matches - - if (isMobile) { - toast.verticalAlign = 'bottom' - toast.verticalOffset = 0 - } - this.toast = container.appendChild(toast) - } - - async getAllWithAddress(myAddress) { - await this.getAddressUserAvatar(myAddress) - } + firstUpdated() {} getAvatar() { if (this.accountInfo.names.length === 0) { @@ -135,9 +110,9 @@ class WalletProfile extends connect(store)(LitElement) { } getApiKey() { - const apiNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]; - let apiKey = apiNode.apiKey; - return apiKey; + const apiNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + let apiKey = apiNode.apiKey + return apiKey } stateChanged(state) { diff --git a/electron.js b/electron.js index 01ad0b93..782c59ef 100644 --- a/electron.js +++ b/electron.js @@ -2,16 +2,12 @@ const { app, BrowserWindow, ipcMain, - ipcRenderer, Menu, Notification, Tray, - nativeImage, dialog, - webContents, nativeTheme, - crashReporter, - webFrame + crashReporter } = require('electron') const { autoUpdater } = require('electron-updater') @@ -42,16 +38,16 @@ crashReporter.start({ }) if (myMemory > 16000000000) { - app.commandLine.appendSwitch('js-flags', '--max-executable-size=192', '--max-old-space-size=8192', '--max-semi-space-size=2') + app.commandLine.appendSwitch('js-flags', '--max-executable-size=192 --max-old-space-size=8192 --max-semi-space-size=2') log.info("Memory Size Is 16GB Using JS Memory Heap Size 8GB") } else if (myMemory > 12000000000) { - app.commandLine.appendSwitch('js-flags', '--max-executable-size=192', '--max-old-space-size=6144', '--max-semi-space-size=2') + app.commandLine.appendSwitch('js-flags', '--max-executable-size=192 --max-old-space-size=6144 --max-semi-space-size=2') log.info("Memory Size Is 12GB Using JS Memory Heap Size 6GB") } else if (myMemory > 7000000000) { - app.commandLine.appendSwitch('js-flags', '--max-executable-size=192', '--max-old-space-size=4096', '--max-semi-space-size=2') + app.commandLine.appendSwitch('js-flags', '--max-executable-size=192 --max-old-space-size=4096 --max-semi-space-size=2') log.info("Memory Size Is 8GB Using JS Memory Heap Size 4GB") } else { - app.commandLine.appendSwitch('js-flags', '--max-executable-size=192', '--max-old-space-size=2048', '--max-semi-space-size=2') + app.commandLine.appendSwitch('js-flags', '--max-executable-size=192 --max-old-space-size=2048 --max-semi-space-size=2') log.info("Memory Size Is 4GB Using JS Memory Heap Size 2GB") } @@ -168,10 +164,10 @@ const isRunning = (query, cb) => { } function doesFileExist(urlToJavaFile) { - var xhr = new XMLHttpRequest() + const xhr = new XMLHttpRequest(); xhr.open('HEAD', urlToJavaFile, true) xhr.send() - + if (xhr.status == "404") { return false } else { @@ -227,7 +223,7 @@ async function checkWin() { async function checkOsPlatform() { if (process.platform === 'win32') { - startElectronWin() + await startElectronWin() } else if (process.platform === 'linux' || process.platform === 'darwin') { startElectronUnix() } else { @@ -298,7 +294,7 @@ async function downloadWindows() { alwaysOnTop: true, show: false }) - winLoader.loadFile(path.join(__dirname + '/splash/download.html')) + await winLoader.loadFile(path.join(__dirname + '/splash/download.html')) winLoader.show() await electronDl.download(myWindow, winurl, { @@ -329,7 +325,7 @@ async function removeQortalExe() { log.info('renove error', err) } - checkWin() + await checkWin() } async function checkPort() { @@ -353,7 +349,7 @@ async function checkResponseStatus(res) { } async function javaversion() { - var stderrChunks = [] + let stderrChunks = []; let checkJava = await spawn('java', ['-version'], { shell: true }) if (process.platform === 'linux') { if (process.arch === 'x64') { @@ -387,7 +383,7 @@ async function javaversion() { checkJava.stderr.on('end', () => { datres = Buffer.concat(stderrChunks).toString().split('\n')[0] - var javaVersion = new RegExp('(java|openjdk) version').test(datres) ? datres.split(' ')[2].replace(/"/g, '') : false + const javaVersion = new RegExp('(java|openjdk) version').test(datres) ? datres.split(' ')[2].replace(/"/g, '') : false; log.info("Java Version", javaVersion) if (javaVersion != false) { checkQortal() @@ -419,7 +415,7 @@ async function installJava() { alwaysOnTop: true, show: false }) - splashLoader.loadFile(path.join(__dirname + '/splash/download.html')) + await splashLoader.loadFile(path.join(__dirname + '/splash/download.html')) if (process.platform === 'linux') { if (process.arch === 'x64') { @@ -435,7 +431,7 @@ async function installJava() { log.info('Download JAVA error', err) } splashLoader.destroy() - unzipJavaX64Linux() + await unzipJavaX64Linux() } else { try { splashLoader.show() @@ -448,7 +444,7 @@ async function installJava() { log.info('Download JAVA error', err) } splashLoader.destroy() - unzipJavaX64Linux() + await unzipJavaX64Linux() } } else if (process.arch === 'arm64') { if (doesFileExist(linjavaarm64url) == true) { @@ -463,7 +459,7 @@ async function installJava() { log.info('Download JAVA error', err) } splashLoader.destroy() - unzipJavaArm64Linux() + await unzipJavaArm64Linux() } else { try { splashLoader.show() @@ -476,7 +472,7 @@ async function installJava() { log.info('Download JAVA error', err) } splashLoader.destroy() - unzipJavaArm64Linux() + await unzipJavaArm64Linux() } } else if (process.arch === 'arm') { if (doesFileExist(linjavaarmurl) == true) { @@ -491,7 +487,7 @@ async function installJava() { log.info('Download JAVA error', err) } splashLoader.destroy() - unzipJavaArmLinux() + await unzipJavaArmLinux() } else { try { splashLoader.show() @@ -504,7 +500,7 @@ async function installJava() { log.info('Download JAVA error', err) } splashLoader.destroy() - unzipJavaArmLinux() + await unzipJavaArmLinux() } } } else if (process.platform === 'darwin') { @@ -521,7 +517,7 @@ async function installJava() { log.info('Download JAVA error', err) } splashLoader.destroy() - unzipJavaX64Mac() + await unzipJavaX64Mac() } else { try { splashLoader.show() @@ -534,7 +530,7 @@ async function installJava() { log.info('Download JAVA error', err) } splashLoader.destroy() - unzipJavaX64Mac() + await unzipJavaX64Mac() } } else { if (doesFileExist(macjavaaarch64url) == true) { @@ -549,7 +545,7 @@ async function installJava() { log.info('Download JAVA error', err) } splashLoader.destroy() - unzipJavaAarch64Mac() + await unzipJavaAarch64Mac() } else { try { splashLoader.show() @@ -562,7 +558,7 @@ async function installJava() { log.info('Download JAVA error', err) } splashLoader.destroy() - unzipJavaAarch64Mac() + await unzipJavaAarch64Mac() } } } @@ -575,7 +571,7 @@ async function unzipJavaX64Linux() { } catch (err) { log.info('Unzip Java error', err) } - chmodJava() + await chmodJava() } async function unzipJavaArm64Linux() { @@ -585,7 +581,7 @@ async function unzipJavaArm64Linux() { } catch (err) { log.info('Unzip Java error', err) } - chmodJava() + await chmodJava() } async function unzipJavaArmLinux() { @@ -595,7 +591,7 @@ async function unzipJavaArmLinux() { } catch (err) { log.info('Unzip Java error', err) } - chmodJava() + await chmodJava() } async function unzipJavaX64Mac() { @@ -605,7 +601,7 @@ async function unzipJavaX64Mac() { } catch (err) { log.info('Unzip Java error', err) } - chmodJava() + await chmodJava() } async function unzipJavaAarch64Mac() { @@ -615,7 +611,7 @@ async function unzipJavaAarch64Mac() { } catch (err) { log.info('Unzip Java error', err) } - chmodJava() + await chmodJava() } async function chmodJava() { @@ -627,7 +623,7 @@ async function chmodJava() { } catch (err) { log.info('chmod error', err) } - removeJavaZip() + await removeJavaZip() } async function removeJavaZip() { @@ -743,7 +739,7 @@ async function downloadQortal() { alwaysOnTop: true, show: false }) - qortalLoader.loadFile(path.join(__dirname + '/splash/download.html')) + await qortalLoader.loadFile(path.join(__dirname + '/splash/download.html')) try { qortalLoader.show() @@ -756,7 +752,7 @@ async function downloadQortal() { log.info('Download Qortal error', err) } qortalLoader.destroy() - unzipQortal() + await unzipQortal() } async function unzipQortal() { @@ -766,7 +762,7 @@ async function unzipQortal() { } catch (err) { log.info('Unzip Qortal error', err) } - chmodQortal() + await chmodQortal() } async function chmodQortal() { @@ -778,7 +774,7 @@ async function chmodQortal() { } catch (err) { log.info('chmod error', err) } - removeQortalZip() + await removeQortalZip() } async function removeQortalZip() { @@ -790,7 +786,7 @@ async function removeQortalZip() { } catch (err) { log.info('rm error', err) } - checkAndStart() + await checkAndStart() } async function checkAndStart() { @@ -1208,8 +1204,10 @@ if (!isLock) { app.whenReady().then(async () => { createWindow() createTray() - await checkAll() - autoUpdater.checkForUpdatesAndNotify() + if (!store.get('askingCore')) { + await checkAll() + } + await autoUpdater.checkForUpdatesAndNotify() setInterval(() => { autoUpdater.checkForUpdatesAndNotify() }, 1000 * 60 * 720) diff --git a/package-lock.json b/package-lock.json index 7adc6f21..083cc2e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "4.5.1", "license": "GPL-3.0", "dependencies": { - "@hapi/hapi": "21.3.3", + "@hapi/hapi": "21.3.6", "@hapi/inert": "7.1.0", "@lit-labs/motion": "1.0.6", "@popperjs/core": "2.11.8", @@ -47,7 +47,7 @@ "prosemirror-state": "1.4.3", "prosemirror-transform": "1.8.0", "prosemirror-view": "1.33.1", - "sass": "1.71.1", + "sass": "1.72.0", "short-unique-id": "5.0.3", "xhr2": "0.2.1" }, @@ -96,15 +96,15 @@ "@rollup/plugin-node-resolve": "15.2.3", "@rollup/plugin-replace": "5.0.5", "@rollup/plugin-terser": "0.4.4", - "@vaadin/avatar": "24.2.8", - "@vaadin/button": "24.2.8", - "@vaadin/grid": "24.2.8", - "@vaadin/icons": "24.2.8", - "@vaadin/password-field": "24.2.8", - "@vaadin/tooltip": "24.2.8", + "@vaadin/avatar": "24.2.9", + "@vaadin/button": "24.2.9", + "@vaadin/grid": "24.2.9", + "@vaadin/icons": "24.2.9", + "@vaadin/password-field": "24.2.9", + "@vaadin/tooltip": "24.2.9", "@zip.js/zip.js": "2.7.40", - "axios": "1.6.7", - "electron": "29.1.1", + "axios": "1.6.8", + "electron": "27.3.6", "electron-builder": "24.13.3", "epml": "0.3.3", "eslint": "8.57.0", @@ -119,14 +119,14 @@ "pwa-helpers": "0.9.1", "redux": "5.0.1", "redux-thunk": "3.1.0", - "rollup": "4.12.1", + "rollup": "4.13.0", "rollup-plugin-node-globals": "1.4.0", "rollup-plugin-progress": "1.1.2", "rollup-plugin-scss": "3.0.0", "shelljs": "0.8.5" }, "engines": { - "node": ">=20.9.0" + "node": ">=18.17.1" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -950,9 +950,9 @@ "integrity": "sha512-w+lKW+yRrLhJu620jT3y+5g2mHqnKfepreykvdOcl9/6up8GrQQn+l3FRTsjHTKbkbfQFkuksHpdv2EcpKcJ4Q==" }, "node_modules/@hapi/hapi": { - "version": "21.3.3", - "resolved": "https://registry.npmjs.org/@hapi/hapi/-/hapi-21.3.3.tgz", - "integrity": "sha512-6pgwWVl/aSKSNVn86n+mWa06jRqCAKi2adZp/Hti19A0u5x3/6eiKz8UTBPMzfrdGf9WcrYbFBYzWr/qd2s28g==", + "version": "21.3.6", + "resolved": "https://registry.npmjs.org/@hapi/hapi/-/hapi-21.3.6.tgz", + "integrity": "sha512-fbJ7QYQZl7Ixe6fmKjJbVO3zUrDa5aY+4xn7xBvJFXw6be76B4d28qknrD2la1aXo6GIhTUsJnqzU2awqmG0Sg==", "dependencies": { "@hapi/accept": "^6.0.1", "@hapi/ammo": "^6.0.1", @@ -1319,13 +1319,13 @@ } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/sourcemap-codec": { @@ -3039,9 +3039,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.1.tgz", - "integrity": "sha512-iU2Sya8hNn1LhsYyf0N+L4Gf9Qc+9eBTJJJsaOGUp+7x4n2M9dxTt8UvhJl3oeftSjblSlpCfvjA/IfP3g5VjQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", + "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", "cpu": [ "arm" ], @@ -3052,9 +3052,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.1.tgz", - "integrity": "sha512-wlzcWiH2Ir7rdMELxFE5vuM7D6TsOcJ2Yw0c3vaBR3VOsJFVTx9xvwnAvhgU5Ii8Gd6+I11qNHwndDscIm0HXg==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz", + "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", "cpu": [ "arm64" ], @@ -3065,9 +3065,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.1.tgz", - "integrity": "sha512-YRXa1+aZIFN5BaImK+84B3uNK8C6+ynKLPgvn29X9s0LTVCByp54TB7tdSMHDR7GTV39bz1lOmlLDuedgTwwHg==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz", + "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", "cpu": [ "arm64" ], @@ -3078,9 +3078,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.1.tgz", - "integrity": "sha512-opjWJ4MevxeA8FhlngQWPBOvVWYNPFkq6/25rGgG+KOy0r8clYwL1CFd+PGwRqqMFVQ4/Qd3sQu5t7ucP7C/Uw==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz", + "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", "cpu": [ "x64" ], @@ -3091,9 +3091,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.1.tgz", - "integrity": "sha512-uBkwaI+gBUlIe+EfbNnY5xNyXuhZbDSx2nzzW8tRMjUmpScd6lCQYKY2V9BATHtv5Ef2OBq6SChEP8h+/cxifQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz", + "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", "cpu": [ "arm" ], @@ -3104,9 +3104,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.1.tgz", - "integrity": "sha512-0bK9aG1kIg0Su7OcFTlexkVeNZ5IzEsnz1ept87a0TUgZ6HplSgkJAnFpEVRW7GRcikT4GlPV0pbtVedOaXHQQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz", + "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", "cpu": [ "arm64" ], @@ -3117,9 +3117,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.1.tgz", - "integrity": "sha512-qB6AFRXuP8bdkBI4D7UPUbE7OQf7u5OL+R94JE42Z2Qjmyj74FtDdLGeriRyBDhm4rQSvqAGCGC01b8Fu2LthQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz", + "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", "cpu": [ "arm64" ], @@ -3130,9 +3130,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.1.tgz", - "integrity": "sha512-sHig3LaGlpNgDj5o8uPEoGs98RII8HpNIqFtAI8/pYABO8i0nb1QzT0JDoXF/pxzqO+FkxvwkHZo9k0NJYDedg==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz", + "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", "cpu": [ "riscv64" ], @@ -3143,9 +3143,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.1.tgz", - "integrity": "sha512-nD3YcUv6jBJbBNFvSbp0IV66+ba/1teuBcu+fBBPZ33sidxitc6ErhON3JNavaH8HlswhWMC3s5rgZpM4MtPqQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz", + "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", "cpu": [ "x64" ], @@ -3156,9 +3156,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.1.tgz", - "integrity": "sha512-7/XVZqgBby2qp/cO0TQ8uJK+9xnSdJ9ct6gSDdEr4MfABrjTyrW6Bau7HQ73a2a5tPB7hno49A0y1jhWGDN9OQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz", + "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", "cpu": [ "x64" ], @@ -3169,9 +3169,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.1.tgz", - "integrity": "sha512-CYc64bnICG42UPL7TrhIwsJW4QcKkIt9gGlj21gq3VV0LL6XNb1yAdHVp1pIi9gkts9gGcT3OfUYHjGP7ETAiw==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz", + "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", "cpu": [ "arm64" ], @@ -3182,9 +3182,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.1.tgz", - "integrity": "sha512-LN+vnlZ9g0qlHGlS920GR4zFCqAwbv2lULrR29yGaWP9u7wF5L7GqWu9Ah6/kFZPXPUkpdZwd//TNR+9XC9hvA==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz", + "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", "cpu": [ "ia32" ], @@ -3195,9 +3195,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.1.tgz", - "integrity": "sha512-n+vkrSyphvmU0qkQ6QBNXCGr2mKjhP08mPRM/Xp5Ck2FV4NrHU+y6axzDeixUrCBHVUS51TZhjqrKBBsHLKb2Q==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", + "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", "cpu": [ "x64" ], @@ -3658,9 +3658,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.11.25", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz", - "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==", + "version": "18.19.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.24.tgz", + "integrity": "sha512-eghAz3gnbQbvnHqB+mgB2ZR3aH6RhdEmHGS48BnV75KceQPHqabkxKI0BbUSsqhqy2Ddhc2xD/VAR9ySZd57Lw==", "devOptional": true, "dependencies": { "undici-types": "~5.26.4" @@ -3720,72 +3720,72 @@ "dev": true }, "node_modules/@vaadin/a11y-base": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/a11y-base/-/a11y-base-24.2.8.tgz", - "integrity": "sha512-fImkvOP1ctdOJViFX+2af1JgrO5LS5SZTs6+fb6E8PeXC3C0xnoCuP/Q62ANILLTk9OCpxM1x9H2zfPF7Tl2Tw==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/a11y-base/-/a11y-base-24.2.9.tgz", + "integrity": "sha512-8YR6HS+U49UOOinVm60i1SGfWobZWQHhQv+5irvQqCUVCLwYYDAjsgRtXXW83M3MQXJMvBaisGHzCKQdzuKCpw==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/component-base": "~24.2.8", + "@vaadin/component-base": "~24.2.9", "lit": "^2.0.0" } }, "node_modules/@vaadin/avatar": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/avatar/-/avatar-24.2.8.tgz", - "integrity": "sha512-GILsjiXsYGxjkRqt1RfT06uOe3OHbb0FtCz2qA44bIASLJc8xFcOcqeb7ibbgQYnI0cxxlrbrhJ+Fjb9kolQyQ==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/avatar/-/avatar-24.2.9.tgz", + "integrity": "sha512-J1JHcEmrUyX2a/VM9Xa702GXC18SoCfzj1dTxxOtWI3XE+A2sEvBp4/3PDnRasjIPTzG4DBtapeXVkjzdaPL1g==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.2.8", - "@vaadin/component-base": "~24.2.8", - "@vaadin/item": "~24.2.8", - "@vaadin/list-box": "~24.2.8", - "@vaadin/overlay": "~24.2.8", - "@vaadin/tooltip": "~24.2.8", - "@vaadin/vaadin-lumo-styles": "~24.2.8", - "@vaadin/vaadin-material-styles": "~24.2.8", - "@vaadin/vaadin-themable-mixin": "~24.2.8" + "@vaadin/a11y-base": "~24.2.9", + "@vaadin/component-base": "~24.2.9", + "@vaadin/item": "~24.2.9", + "@vaadin/list-box": "~24.2.9", + "@vaadin/overlay": "~24.2.9", + "@vaadin/tooltip": "~24.2.9", + "@vaadin/vaadin-lumo-styles": "~24.2.9", + "@vaadin/vaadin-material-styles": "~24.2.9", + "@vaadin/vaadin-themable-mixin": "~24.2.9" } }, "node_modules/@vaadin/button": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/button/-/button-24.2.8.tgz", - "integrity": "sha512-LK/hh+AU4lj1BKuTWGhiBgWru0p75fP0iY5od3RAGoe/ds08lEt0kbq45ZWGtBdVdi0ia10I1uRXUQ/pWJoflQ==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/button/-/button-24.2.9.tgz", + "integrity": "sha512-qCWTBXVNklcKO8fY0r9zK4AtMLdyUvkFacfoP6qPVw2hEmM2SZkzZQ7zlMO2S842bqCQuKB9aMgUDbX0rqgcPw==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.2.8", - "@vaadin/component-base": "~24.2.8", - "@vaadin/vaadin-lumo-styles": "~24.2.8", - "@vaadin/vaadin-material-styles": "~24.2.8", - "@vaadin/vaadin-themable-mixin": "~24.2.8", + "@vaadin/a11y-base": "~24.2.9", + "@vaadin/component-base": "~24.2.9", + "@vaadin/vaadin-lumo-styles": "~24.2.9", + "@vaadin/vaadin-material-styles": "~24.2.9", + "@vaadin/vaadin-themable-mixin": "~24.2.9", "lit": "^2.0.0" } }, "node_modules/@vaadin/checkbox": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/checkbox/-/checkbox-24.2.8.tgz", - "integrity": "sha512-APMQHOCqS5eYKCurVCPGEBCPYUX/H56Y+apGInFa6qI2ms6nuetVhwplzRsTi8GDjGphP4Ayd6ibQOZtuM43ig==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/checkbox/-/checkbox-24.2.9.tgz", + "integrity": "sha512-IXwqepF/mVb/x11VPE7dmUe1+yZXYwg+yATkMZl9BUnyeZNmXhkSw5vyj9ueDUq5v9FYJYJF8IhWoP0R2apMvw==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.2.8", - "@vaadin/component-base": "~24.2.8", - "@vaadin/field-base": "~24.2.8", - "@vaadin/vaadin-lumo-styles": "~24.2.8", - "@vaadin/vaadin-material-styles": "~24.2.8", - "@vaadin/vaadin-themable-mixin": "~24.2.8", + "@vaadin/a11y-base": "~24.2.9", + "@vaadin/component-base": "~24.2.9", + "@vaadin/field-base": "~24.2.9", + "@vaadin/vaadin-lumo-styles": "~24.2.9", + "@vaadin/vaadin-material-styles": "~24.2.9", + "@vaadin/vaadin-themable-mixin": "~24.2.9", "lit": "^2.0.0" } }, "node_modules/@vaadin/component-base": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/component-base/-/component-base-24.2.8.tgz", - "integrity": "sha512-j/4wW+GtEtZYSEO+CDhmHqNgsSD1QWOYKaVzvE7pXJ8nflY4eEelaCO45sEo5L2H2YKgZpZePiaPbcG4gcZi5w==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/component-base/-/component-base-24.2.9.tgz", + "integrity": "sha512-REyjFlNa84vNfus/xxq+KtRR6Ijsjx3BknwPXDB9ks4YpSO125TkNluLa/otVtrJkK1YS4Vty1VLwTspcIzYxg==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", @@ -3796,173 +3796,173 @@ } }, "node_modules/@vaadin/field-base": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/field-base/-/field-base-24.2.8.tgz", - "integrity": "sha512-/t5VWgfVRkanIFbGrLP1ZJh1z67E/Pdyuiv81byGAdBoqxOQeI5qC9tXyP4svcHd3BJuaQoxS2qChyOTxTv/ww==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/field-base/-/field-base-24.2.9.tgz", + "integrity": "sha512-WPcJaQakjVtTYnGS0jv7FUz60PCqF3HNpp+QzmAoJIe1ezBEX173niU8B0L0pe64IcBs2BD8H5gkO+iIGHzMPA==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.2.8", - "@vaadin/component-base": "~24.2.8", + "@vaadin/a11y-base": "~24.2.9", + "@vaadin/component-base": "~24.2.9", "lit": "^2.0.0" } }, "node_modules/@vaadin/grid": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/grid/-/grid-24.2.8.tgz", - "integrity": "sha512-gRCd6nsvHz8crRjXnxhh9xclH5/CB+kUbfCK+6+vO2j5FQaH9nDugwJLSuixsX98KtlYCo6nuJc7QG19guCKZA==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/grid/-/grid-24.2.9.tgz", + "integrity": "sha512-/OiUgO/GTLDsXxyhlt13mGTBbC9DwJQt1Y6FrJz+M+te5EjHG2X3ZGot2KPpLeesDUuvrw+WGx/siie0Jm0NVg==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.2.8", - "@vaadin/checkbox": "~24.2.8", - "@vaadin/component-base": "~24.2.8", - "@vaadin/lit-renderer": "~24.2.8", - "@vaadin/text-field": "~24.2.8", - "@vaadin/vaadin-lumo-styles": "~24.2.8", - "@vaadin/vaadin-material-styles": "~24.2.8", - "@vaadin/vaadin-themable-mixin": "~24.2.8" + "@vaadin/a11y-base": "~24.2.9", + "@vaadin/checkbox": "~24.2.9", + "@vaadin/component-base": "~24.2.9", + "@vaadin/lit-renderer": "~24.2.9", + "@vaadin/text-field": "~24.2.9", + "@vaadin/vaadin-lumo-styles": "~24.2.9", + "@vaadin/vaadin-material-styles": "~24.2.9", + "@vaadin/vaadin-themable-mixin": "~24.2.9" } }, "node_modules/@vaadin/icon": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/icon/-/icon-24.2.8.tgz", - "integrity": "sha512-Lh7V+ZgLOIFBKDo3R9k7C61rP4lWe+pVqfglEbR1pghPyEvsX5WswnOEy7uvCJXDc1XkQ5AU1QTLSpbh2KkE3w==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/icon/-/icon-24.2.9.tgz", + "integrity": "sha512-wuGOB9wAaZrHx15k6pNKszUjiDb+6OJFd6YPLTT5OigkjRU3gfL/RowmV4jdIr4z7bQmsF5/811FMDG+fz1qJA==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/component-base": "~24.2.8", - "@vaadin/vaadin-lumo-styles": "~24.2.8", - "@vaadin/vaadin-themable-mixin": "~24.2.8", + "@vaadin/component-base": "~24.2.9", + "@vaadin/vaadin-lumo-styles": "~24.2.9", + "@vaadin/vaadin-themable-mixin": "~24.2.9", "lit": "^2.0.0" } }, "node_modules/@vaadin/icons": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/icons/-/icons-24.2.8.tgz", - "integrity": "sha512-aByOEPyJis5HX8Y8dYCAfsGeCBis9RvuAgTu7J3MQY53xJ6S2fLl9aG9+CznEBCn5He8svZcDNR80y3K9T0uaA==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/icons/-/icons-24.2.9.tgz", + "integrity": "sha512-6N0eR5j6uEaPtmS4WajRhFvAqVx8P201mOY1xg7U/GXDI2sH+aGySnW2ivZXLXDbZNbqzZP5G0kQ11oEdbjfxw==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/icon": "~24.2.8" + "@vaadin/icon": "~24.2.9" } }, "node_modules/@vaadin/input-container": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/input-container/-/input-container-24.2.8.tgz", - "integrity": "sha512-CsmIuztWoUEHUj4GkE3GSu0q3qWYxgOTZ+PtwMi2Ecw4N3Udw9v6hNywANEmxnqXtXlvrKdWKW84KrSEFOgpgQ==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/input-container/-/input-container-24.2.9.tgz", + "integrity": "sha512-eFr6M2ns5YyuErYNX2IHpnUa2SeG8BfM7/79RGcbEQlhZa0VKFJ2UATFN2bRZXZDSCG5WTVnkjxFWxeSo3m0Uw==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/component-base": "~24.2.8", - "@vaadin/vaadin-lumo-styles": "~24.2.8", - "@vaadin/vaadin-material-styles": "~24.2.8", - "@vaadin/vaadin-themable-mixin": "~24.2.8" + "@vaadin/component-base": "~24.2.9", + "@vaadin/vaadin-lumo-styles": "~24.2.9", + "@vaadin/vaadin-material-styles": "~24.2.9", + "@vaadin/vaadin-themable-mixin": "~24.2.9" } }, "node_modules/@vaadin/item": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/item/-/item-24.2.8.tgz", - "integrity": "sha512-gu2lemQGAuBN/E+NpnuGe2cfKcOnU4Fs3q99Ki5Mq47dF2y7ABu6MHakXrhRixOC5lCH+EoBxoAVyLlHNKem/A==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/item/-/item-24.2.9.tgz", + "integrity": "sha512-xH5okZ4QDdGAeIe9/JUiUvgYF30DXnt2M0ZxhDfgHzmybyAXthcVgauqa42Rgs+jpVF0jI0gQN4eq5vpaUyz2Q==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.2.8", - "@vaadin/component-base": "~24.2.8", - "@vaadin/vaadin-lumo-styles": "~24.2.8", - "@vaadin/vaadin-material-styles": "~24.2.8", - "@vaadin/vaadin-themable-mixin": "~24.2.8" + "@vaadin/a11y-base": "~24.2.9", + "@vaadin/component-base": "~24.2.9", + "@vaadin/vaadin-lumo-styles": "~24.2.9", + "@vaadin/vaadin-material-styles": "~24.2.9", + "@vaadin/vaadin-themable-mixin": "~24.2.9" } }, "node_modules/@vaadin/list-box": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/list-box/-/list-box-24.2.8.tgz", - "integrity": "sha512-GVNuXCb92VfuyEDmg0Ee73OFswVCJuizS4MJqWEXhnaPLWcVKmlmftG4fIm4UFWNqVbdk7Wukz3dIN226IH11g==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/list-box/-/list-box-24.2.9.tgz", + "integrity": "sha512-GlxdaNt51iQE445SfoihW/izUVdsFaYS6d0nka81jkCn86BOqjEqfXKlWDliDq72WksQHNAHrU5ipj8CIx3udA==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.2.8", - "@vaadin/component-base": "~24.2.8", - "@vaadin/item": "~24.2.8", - "@vaadin/vaadin-lumo-styles": "~24.2.8", - "@vaadin/vaadin-material-styles": "~24.2.8", - "@vaadin/vaadin-themable-mixin": "~24.2.8" + "@vaadin/a11y-base": "~24.2.9", + "@vaadin/component-base": "~24.2.9", + "@vaadin/item": "~24.2.9", + "@vaadin/vaadin-lumo-styles": "~24.2.9", + "@vaadin/vaadin-material-styles": "~24.2.9", + "@vaadin/vaadin-themable-mixin": "~24.2.9" } }, "node_modules/@vaadin/lit-renderer": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/lit-renderer/-/lit-renderer-24.2.8.tgz", - "integrity": "sha512-Fvcsl2yYiVrwLwZHCucuP2Kiz1ispOVeydlY97P4Vjs4irtJz5kF9Vl9esdK15spnfDXOdfiggEmjlSqDrRhhg==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/lit-renderer/-/lit-renderer-24.2.9.tgz", + "integrity": "sha512-A5VWnRRwrMHE/e20pIYwYNBeO7/bZUacCCdNLMsAML3Mgz8WXvj9iGK3gCoQc7fMwfMdBKRq8mkOSDUXyEEIWA==", "dev": true, "dependencies": { "lit": "^2.0.0" } }, "node_modules/@vaadin/overlay": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/overlay/-/overlay-24.2.8.tgz", - "integrity": "sha512-o8+oJuxwBDRN5xo2BYOUi8kcB6ZrAxiR8mkxxXa//ucCPn5IzePvPqDeTpNe0+By5zjfB663aGKPXe0ArTJfFQ==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/overlay/-/overlay-24.2.9.tgz", + "integrity": "sha512-0gF9C2JGrP5neZHvoE6/uc4qF5izbPldEqNIL5t91D+AVKRNwIxUNqlarbA+aV1G4G+EBZaYrpLxj/APd1lcxw==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.2.8", - "@vaadin/component-base": "~24.2.8", - "@vaadin/vaadin-lumo-styles": "~24.2.8", - "@vaadin/vaadin-material-styles": "~24.2.8", - "@vaadin/vaadin-themable-mixin": "~24.2.8" + "@vaadin/a11y-base": "~24.2.9", + "@vaadin/component-base": "~24.2.9", + "@vaadin/vaadin-lumo-styles": "~24.2.9", + "@vaadin/vaadin-material-styles": "~24.2.9", + "@vaadin/vaadin-themable-mixin": "~24.2.9" } }, "node_modules/@vaadin/password-field": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/password-field/-/password-field-24.2.8.tgz", - "integrity": "sha512-nxQ9Gd/eRwloVYvvHO9Yc4VeyJ8SJVh0RiGjZetNugyKdYhVy0S4eQYr6GWXhHLJoMUD4xMuH+0uEbJMror4EQ==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/password-field/-/password-field-24.2.9.tgz", + "integrity": "sha512-drXbEbfGBEHzu8qUXVeioYUjvnnSP9wY22Hy5Pz6OS8gi5S66BADCNe4mZxWBTIs4tsiOQqslM90jpsxVcC8ug==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/button": "~24.2.8", - "@vaadin/component-base": "~24.2.8", - "@vaadin/text-field": "~24.2.8", - "@vaadin/vaadin-lumo-styles": "~24.2.8", - "@vaadin/vaadin-material-styles": "~24.2.8", - "@vaadin/vaadin-themable-mixin": "~24.2.8" + "@vaadin/button": "~24.2.9", + "@vaadin/component-base": "~24.2.9", + "@vaadin/text-field": "~24.2.9", + "@vaadin/vaadin-lumo-styles": "~24.2.9", + "@vaadin/vaadin-material-styles": "~24.2.9", + "@vaadin/vaadin-themable-mixin": "~24.2.9" } }, "node_modules/@vaadin/text-field": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/text-field/-/text-field-24.2.8.tgz", - "integrity": "sha512-7srn01dF9YlCGxcDzcQ4Il4ey2MIsP2icsXdVUn+oJ+scPmU/5hnBMa834nSGXWJmt5DCM2zK4UYkmKsReNBcg==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/text-field/-/text-field-24.2.9.tgz", + "integrity": "sha512-CE/Gk1h+Y+u2bVceF8bhjfCVapTcWWe9kkSbvsdOXdKqFi7+tRq14obWeHbPQ2l2lhwTJygw3GEB6WXZ96NEvA==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.2.8", - "@vaadin/component-base": "~24.2.8", - "@vaadin/field-base": "~24.2.8", - "@vaadin/input-container": "~24.2.8", - "@vaadin/vaadin-lumo-styles": "~24.2.8", - "@vaadin/vaadin-material-styles": "~24.2.8", - "@vaadin/vaadin-themable-mixin": "~24.2.8", + "@vaadin/a11y-base": "~24.2.9", + "@vaadin/component-base": "~24.2.9", + "@vaadin/field-base": "~24.2.9", + "@vaadin/input-container": "~24.2.9", + "@vaadin/vaadin-lumo-styles": "~24.2.9", + "@vaadin/vaadin-material-styles": "~24.2.9", + "@vaadin/vaadin-themable-mixin": "~24.2.9", "lit": "^2.0.0" } }, "node_modules/@vaadin/tooltip": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/tooltip/-/tooltip-24.2.8.tgz", - "integrity": "sha512-3f0qu4IPyDaaPnaDjK6E9s61sTK2ddzLUc6Fbo4orha+b9KxmCvFy66GzvXgQFGfy3Zy9r+NSUU70cNAAl7T4g==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/tooltip/-/tooltip-24.2.9.tgz", + "integrity": "sha512-yyQ50hR1In5SXkh+uNRwmhFiSQpZ/3sVZZAh3z8VJsLS5PDtrNEAJ2S3IwwDKe5GpawN/LrjzmJTRZBANzTbEQ==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/a11y-base": "~24.2.8", - "@vaadin/component-base": "~24.2.8", - "@vaadin/overlay": "~24.2.8", - "@vaadin/vaadin-lumo-styles": "~24.2.8", - "@vaadin/vaadin-material-styles": "~24.2.8", - "@vaadin/vaadin-themable-mixin": "~24.2.8" + "@vaadin/a11y-base": "~24.2.9", + "@vaadin/component-base": "~24.2.9", + "@vaadin/overlay": "~24.2.9", + "@vaadin/vaadin-lumo-styles": "~24.2.9", + "@vaadin/vaadin-material-styles": "~24.2.9", + "@vaadin/vaadin-themable-mixin": "~24.2.9" } }, "node_modules/@vaadin/vaadin-development-mode-detector": { @@ -3972,32 +3972,32 @@ "dev": true }, "node_modules/@vaadin/vaadin-lumo-styles": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/vaadin-lumo-styles/-/vaadin-lumo-styles-24.2.8.tgz", - "integrity": "sha512-Yo2eEGbdUAUO4ZPc5KRjzeh/+/ZdrSuzoedhNKrwYZ6zftDAODZCacoomUHUIKEOpIKwRxtiEHs3l7Im9YKjAg==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/vaadin-lumo-styles/-/vaadin-lumo-styles-24.2.9.tgz", + "integrity": "sha512-buBnferJEBWolUT1hLPDwcdUI/iMvxzHGxvDy6gpZi6RLEGnsBZJzvB8F6B8LTifmZTuDVfF1BWUOW8HStPH1Q==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/component-base": "~24.2.8", - "@vaadin/icon": "~24.2.8", - "@vaadin/vaadin-themable-mixin": "~24.2.8" + "@vaadin/component-base": "~24.2.9", + "@vaadin/icon": "~24.2.9", + "@vaadin/vaadin-themable-mixin": "~24.2.9" } }, "node_modules/@vaadin/vaadin-material-styles": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/vaadin-material-styles/-/vaadin-material-styles-24.2.8.tgz", - "integrity": "sha512-rqHzycAjvU8PwVfYQ1FYP282EIw8tteRA6MljXari3Sd1xrEoJkjk6/nAAvXKbRjJtqSFPuYIKS2esQ35Nju3A==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/vaadin-material-styles/-/vaadin-material-styles-24.2.9.tgz", + "integrity": "sha512-l8lY05AND39jdnn6d6A7MJJjDg57UAr9nrYLHPymQUm+Q8KO4sg95R14cLR9No3d1o4sCgJCCIrM3JH4xRrW/g==", "dev": true, "dependencies": { "@polymer/polymer": "^3.0.0", - "@vaadin/component-base": "~24.2.8", - "@vaadin/vaadin-themable-mixin": "~24.2.8" + "@vaadin/component-base": "~24.2.9", + "@vaadin/vaadin-themable-mixin": "~24.2.9" } }, "node_modules/@vaadin/vaadin-themable-mixin": { - "version": "24.2.8", - "resolved": "https://registry.npmjs.org/@vaadin/vaadin-themable-mixin/-/vaadin-themable-mixin-24.2.8.tgz", - "integrity": "sha512-3y3CYMglwb/2UoQU7fovI2L53IKG50A2n7Jgc1lsVj6vAOUWi8ra8SifhFRNFjm0yxoD6xbaMo9V+VJwdEiCfw==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@vaadin/vaadin-themable-mixin/-/vaadin-themable-mixin-24.2.9.tgz", + "integrity": "sha512-aL89R7Pkg+KKEVL/taEd+1a2tcxDgXNw5r7Govp9MRKwtHZCV8mnGt8wRp2Vwd5CYu7mX5pBFHkPMJwGTuNNyQ==", "dev": true, "dependencies": { "@open-wc/dedupe-mixin": "^1.3.0", @@ -4574,12 +4574,12 @@ } }, "node_modules/axios": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", - "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", "dev": true, "dependencies": { - "follow-redirects": "^1.15.4", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -4615,11 +4615,14 @@ "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/bl": { @@ -4970,9 +4973,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001597", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz", - "integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==", + "version": "1.0.30001598", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001598.tgz", + "integrity": "sha512-j8mQRDziG94uoBfeFuqsJUNECW37DXpnvhcMJMdlH2u3MRkq1sAI0LJcXP1i/Py0KbSIC4UDj8YHPrTn5YsL+Q==", "dev": true, "funding": [ { @@ -5749,14 +5752,14 @@ } }, "node_modules/electron": { - "version": "29.1.1", - "resolved": "https://registry.npmjs.org/electron/-/electron-29.1.1.tgz", - "integrity": "sha512-cXN15NgCi7MkzGo5/23ZQbii+0UfhmUiDjACunmzcUofYCjF42XhFbL7JZnwgI0qtBCCeJU8qZNZt9lU91gUFw==", + "version": "27.3.6", + "resolved": "https://registry.npmjs.org/electron/-/electron-27.3.6.tgz", + "integrity": "sha512-oLk99Euqa9EQKWJsPxi4rYV32OYmlbasHUZdvLGNzTn5S3U+jLlfhvca/9Tg1xUyIv2U/gyRnwjR37Ne9n4orA==", "dev": true, "hasInstallScript": true, "dependencies": { "@electron/get": "^2.0.0", - "@types/node": "^20.9.0", + "@types/node": "^18.11.18", "extract-zip": "^2.0.1" }, "bin": { @@ -6040,9 +6043,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.699", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.699.tgz", - "integrity": "sha512-I7q3BbQi6e4tJJN5CRcyvxhK0iJb34TV8eJQcgh+fR2fQ8miMgZcEInckCo1U9exDHbfz7DLDnFn8oqH/VcRKw==", + "version": "1.4.708", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.708.tgz", + "integrity": "sha512-iWgEEvREL4GTXXHKohhh33+6Y8XkPI5eHihDmm8zUk5Zo7HICEW+wI/j5kJ2tbuNUCXJ/sNXa03ajW635DiJXA==", "dev": true }, "node_modules/electron-updater": { @@ -6845,9 +6848,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true, "funding": [ { @@ -9589,9 +9592,9 @@ } }, "node_modules/rollup": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.1.tgz", - "integrity": "sha512-ggqQKvx/PsB0FaWXhIvVkSWh7a/PCLQAsMjBc+nA2M8Rv2/HG0X6zvixAB7KyZBRtifBUhy5k8voQX/mRnABPg==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", + "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -9604,19 +9607,19 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.12.1", - "@rollup/rollup-android-arm64": "4.12.1", - "@rollup/rollup-darwin-arm64": "4.12.1", - "@rollup/rollup-darwin-x64": "4.12.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.12.1", - "@rollup/rollup-linux-arm64-gnu": "4.12.1", - "@rollup/rollup-linux-arm64-musl": "4.12.1", - "@rollup/rollup-linux-riscv64-gnu": "4.12.1", - "@rollup/rollup-linux-x64-gnu": "4.12.1", - "@rollup/rollup-linux-x64-musl": "4.12.1", - "@rollup/rollup-win32-arm64-msvc": "4.12.1", - "@rollup/rollup-win32-ia32-msvc": "4.12.1", - "@rollup/rollup-win32-x64-msvc": "4.12.1", + "@rollup/rollup-android-arm-eabi": "4.13.0", + "@rollup/rollup-android-arm64": "4.13.0", + "@rollup/rollup-darwin-arm64": "4.13.0", + "@rollup/rollup-darwin-x64": "4.13.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.13.0", + "@rollup/rollup-linux-arm64-gnu": "4.13.0", + "@rollup/rollup-linux-arm64-musl": "4.13.0", + "@rollup/rollup-linux-riscv64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-musl": "4.13.0", + "@rollup/rollup-win32-arm64-msvc": "4.13.0", + "@rollup/rollup-win32-ia32-msvc": "4.13.0", + "@rollup/rollup-win32-x64-msvc": "4.13.0", "fsevents": "~2.3.2" } }, @@ -9758,9 +9761,9 @@ } }, "node_modules/sass": { - "version": "1.71.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.1.tgz", - "integrity": "sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==", + "version": "1.72.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.72.0.tgz", + "integrity": "sha512-Gpczt3WA56Ly0Mn8Sl21Vj94s1axi9hDIzDFn9Ph9x3C3p4nNyvsqJoQyVXKou6cBlfFWEgRW4rT8Tb4i3XnVA==", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -10315,9 +10318,9 @@ } }, "node_modules/terser": { - "version": "5.29.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.1.tgz", - "integrity": "sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ==", + "version": "5.29.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.2.tgz", + "integrity": "sha512-ZiGkhUBIM+7LwkNjXYJq8svgkd+QK3UUr0wJqY4MieaezBSAIPgbSPZyIx0idM6XWK5CMzSWa8MJIzmRcB8Caw==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", diff --git a/package.json b/package.json index 0517bd7d..f0097e9c 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "lint": "eslint './**/*.{js,mjs}'" }, "dependencies": { - "@hapi/hapi": "21.3.3", + "@hapi/hapi": "21.3.6", "@hapi/inert": "7.1.0", "@lit-labs/motion": "1.0.6", "@popperjs/core": "2.11.8", @@ -69,7 +69,7 @@ "prosemirror-state": "1.4.3", "prosemirror-transform": "1.8.0", "prosemirror-view": "1.33.1", - "sass": "1.71.1", + "sass": "1.72.0", "short-unique-id": "5.0.3", "xhr2": "0.2.1" }, @@ -118,15 +118,15 @@ "@rollup/plugin-node-resolve": "15.2.3", "@rollup/plugin-replace": "5.0.5", "@rollup/plugin-terser": "0.4.4", - "@vaadin/avatar": "24.2.8", - "@vaadin/button": "24.2.8", - "@vaadin/grid": "24.2.8", - "@vaadin/icons": "24.2.8", - "@vaadin/password-field": "24.2.8", - "@vaadin/tooltip": "24.2.8", + "@vaadin/avatar": "24.2.9", + "@vaadin/button": "24.2.9", + "@vaadin/grid": "24.2.9", + "@vaadin/icons": "24.2.9", + "@vaadin/password-field": "24.2.9", + "@vaadin/tooltip": "24.2.9", "@zip.js/zip.js": "2.7.40", - "axios": "1.6.7", - "electron": "29.1.1", + "axios": "1.6.8", + "electron": "27.3.6", "electron-builder": "24.13.3", "epml": "0.3.3", "eslint": "8.57.0", @@ -141,13 +141,13 @@ "pwa-helpers": "0.9.1", "redux": "5.0.1", "redux-thunk": "3.1.0", - "rollup": "4.12.1", + "rollup": "4.13.0", "rollup-plugin-node-globals": "1.4.0", "rollup-plugin-progress": "1.1.2", "rollup-plugin-scss": "3.0.0", "shelljs": "0.8.5" }, "engines": { - "node": ">=20.9.0" + "node": ">=18.17.1" } -} \ No newline at end of file +} diff --git a/plugins/plugins/core/components/ChatHead.js b/plugins/plugins/core/components/ChatHead.js index 32a33416..398690b4 100644 --- a/plugins/plugins/core/components/ChatHead.js +++ b/plugins/plugins/core/components/ChatHead.js @@ -1,7 +1,8 @@ import {css, html, LitElement} from 'lit' import {Epml} from '../../../epml.js' import localForage from "localforage" -import {translate} from '../../../../core/translate/index.js' +import {translate} from '../../../../core/translate' + import '@material/mwc-icon' const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) @@ -28,15 +29,12 @@ class ChatHead extends LitElement { static get styles() { return css` li { - width: 100%; padding: 10px 5px 10px 5px; cursor: pointer; - width: 100%; box-sizing: border-box; display: flex; align-items: flex-start; - } li:hover { @@ -59,7 +57,7 @@ class ChatHead extends LitElement { align-items: center; justify-content: space-between; width: 100%; - margin: 0px; + margin: 0; } .inner-container { display: flex; @@ -135,7 +133,6 @@ class ChatHead extends LitElement { render() { let avatarImg = '' - let backupAvatarImg = '' let isUnread = false if(this.chatInfo.name){ @@ -160,26 +157,25 @@ class ChatHead extends LitElement { } return html`
  • this.getUrl(this.chatInfo.url)} class="clearfix ${this.activeChatHeadUrl === this.chatInfo.url ? 'active' : ''}"> - ${this.isImageLoaded ? html`${avatarImg}` : html`` } + ${this.isImageLoaded ? html`${avatarImg}` : html`` } ${!this.isImageLoaded && !this.chatInfo.name && !this.chatInfo.groupName ? html`account_circle` : html`` } ${!this.isImageLoaded && this.chatInfo.name ? html`
    ${this.chatInfo.name.charAt(0)}
    `: ''} ${!this.isImageLoaded && this.chatInfo.groupName ? html`
    ${this.chatInfo.groupName.charAt(0)}
    `: ''} -
    -
    -
    ${this.chatInfo.groupName ? this.chatInfo.groupName : this.chatInfo.name !== undefined ? this.chatInfo.name : this.chatInfo.address.substr(0, 15)} ${this.chatInfo.groupId !== undefined ? 'lock_open' : 'lock'}
    -
    -
    -
    -
    -
    - - ${translate('chatpage.cchange90')} -
    -
    -
    -
    - -
  • +
    +
    +
    ${this.chatInfo.groupName ? this.chatInfo.groupName : this.chatInfo.name !== undefined ? this.chatInfo.name : this.chatInfo.address.substr(0, 15)} ${this.chatInfo.groupId !== undefined ? 'lock_open' : 'lock'}
    +
    +
    +
    +
    +
    + + ${translate('chatpage.cchange90')} +
    +
    +
    +
    + ` } @@ -266,4 +262,4 @@ class ChatHead extends LitElement { } } -window.customElements.define('chat-head', ChatHead) +window.customElements.define('chat-head', ChatHead) \ No newline at end of file diff --git a/plugins/plugins/core/messaging/q-chat/q-chat-css.src.js b/plugins/plugins/core/messaging/q-chat/q-chat-css.src.js index 08408ca2..95c8afb9 100644 --- a/plugins/plugins/core/messaging/q-chat/q-chat-css.src.js +++ b/plugins/plugins/core/messaging/q-chat/q-chat-css.src.js @@ -1,483 +1,479 @@ import {css} from 'lit' -export const qchatStyles = css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --paper-input-container-focus-color: var(--mdc-theme-primary); - --mdc-theme-surface: var(--white); - --mdc-dialog-content-ink-color: var(--black); - --lumo-primary-text-color: rgb(0, 167, 245); - --lumo-primary-color-50pct: rgba(0, 167, 245, 0.5); - --lumo-primary-color-10pct: rgba(0, 167, 245, 0.1); - --lumo-primary-color: hsl(199, 100%, 48%); - --lumo-base-color: var(--white); - --lumo-body-text-color: var(--black); - --_lumo-grid-border-color: var(--border); - --_lumo-grid-secondary-border-color: var(--border2); - --mdc-dialog-min-width: 750px; - } +export const qchatStyles = css` + * { + --mdc-theme-primary: rgb(3, 169, 244); + --mdc-theme-secondary: var(--mdc-theme-primary); + --paper-input-container-focus-color: var(--mdc-theme-primary); + --mdc-theme-surface: var(--white); + --mdc-dialog-content-ink-color: var(--black); + --lumo-primary-text-color: rgb(0, 167, 245); + --lumo-primary-color-50pct: rgba(0, 167, 245, 0.5); + --lumo-primary-color-10pct: rgba(0, 167, 245, 0.1); + --lumo-primary-color: hsl(199, 100%, 48%); + --lumo-base-color: var(--white); + --lumo-body-text-color: var(--black); + --_lumo-grid-border-color: var(--border); + --_lumo-grid-secondary-border-color: var(--border2); + --mdc-dialog-min-width: 750px; + scrollbar-width: thin; + scrollbar-color: #6a6c75 #a1a1a1; + } + + paper-spinner-lite { + height: 24px; + width: 24px; + --paper-spinner-color: var(--mdc-theme-primary); + --paper-spinner-stroke-width: 2px; + } + + *, + *:before, + *:after { + box-sizing: border-box; + } + + ul { + list-style: none; + padding: 0; + } + + .container { + margin: 0 auto; + width: 100%; + background: var(--white); + } + + .people-list { + width: 20vw; + float: left; + height: 100vh; + overflow-y: hidden; + border-right: 3px #ddd solid; + } + + .people-list .blockedusers { + z-index: 1; + position: absolute; + bottom: 0; + width: 20vw; + background: var(--white); + border-right: 3px #ddd solid; + display: flex; + justify-content: space-between; + gap: 15px; + flex-direction: column; + padding: 5px 30px 0 30px; + } + + .groups-button-container { + position: relative; + } + + .groups-button { + width: 100%; + background-color: rgb(116, 69, 240); + border: none; + color: white; + font-weight: bold; + font-family: Roboto, sans-serif; + letter-spacing: 0.8px; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + border-radius: 5px; + gap: 10px; + padding: 5px 8px; + transition: all 0.1s ease-in-out; + } + + .groups-button-notif { + position: absolute; + top: -10px; + right: -8px; + width: 25px; + border-radius: 50%; + height: 25px; + font-weight: bold; + display: flex; + align-items: center; + justify-content: center; + font-family: Montserrat, sans-serif; + font-size: 16px; + color: black; + background-color: rgb(51, 213, 0); + user-select: none; + transition: all 0.3s ease-in-out 0s; + } + + .groups-button-notif:hover { + cursor: auto; + box-shadow: rgba(99, 99, 99, 0.2) 0 2px 8px 0; + } + + .groups-button-notif:hover + .groups-button-notif-number { + display: block; + opacity: 1; + animation: fadeIn 0.6s; + } + + @keyframes fadeIn { + from { + opacity: 0; + top: -10px; + } + + to { + opacity: 1; + top: -60px; + } + } + + .groups-button-notif-number { + position: absolute; + transform: translateX(-50%); + left: 50%; + width: 150px; + text-align: center; + border-radius: 3px; + padding: 5px 10px; + background-color: white; + color: black; + font-family: Roboto, sans-serif; + letter-spacing: 0.3px; + font-weight: 300; + display: none; + opacity: 0; + top: -60px; + box-shadow: rgb(216 216 216 / 25%) 0 6px 12px -2px, rgb(0 0 0 / 30%) 0 3px 7px -3px; + } + + .groups-button:hover { + cursor: pointer; + filter: brightness(120%); + } + + .people-list .search { + padding-top: 20px; + padding-left: 20px; + padding-right: 20px; + display: flex; + align-items: center; + gap: 10px; + justify-content: space-between; + } + + .center { + margin: 0; + position: absolute; + padding-top: 12px; + left: 50%; + -ms-transform: translateX(-50%); + transform: translateX(-50%); + } + + .people-list .create-chat { + border-radius: 5px; + border: none; + color: #fff; + width: 100%; + font-size: 15px; + text-align: center; + cursor: pointer; + display: flex; + flex: 0; + } + + .people-list .create-chat:hover { + opacity: .8; + box-shadow: 0 3px 5px rgba(0, 0, 0, .2); + } + + .people-list ul { + padding: 0 0 60px 0; + height: 85vh; + overflow-y: auto; + overflow-x: hidden; + } - paper-spinner-lite { - height: 24px; - width: 24px; - --paper-spinner-color: var(--mdc-theme-primary); - --paper-spinner-stroke-width: 2px; - } - - *, - *:before, - *:after { - box-sizing: border-box; - } - - ul { - list-style: none; - padding: 0; - } - - .container { - margin: 0 auto; - width: 100%; - background: var(--white); - } - - .people-list { - width: 20vw; - float: left; - height: 100vh; - overflow-y: hidden; - border-right: 3px #ddd solid; - } - - .people-list .blockedusers { - z-index: 1; - position: absolute; - bottom: 0; - width: 20vw; - background: var(--white); - border-right: 3px #ddd solid; - display: flex; - justify-content: space-between; - gap: 15px; - flex-direction: column; - padding: 5px 30px 0 30px; - } - - .groups-button-container { - position: relative; - } - - .groups-button { - width: 100%; - background-color: rgb(116, 69, 240); - border: none; - color: white; - font-weight: bold; - font-family: 'Roboto'; - letter-spacing: 0.8px; - height: 100%; - display: flex; - align-items: center; - justify-content: center; - border-radius: 5px; - gap: 10px; - padding: 5px 8px; - transition: all 0.1s ease-in-out; - } - - .groups-button-notif { - position: absolute; - top: -10px; - right: -8px; - width: 25px; - border-radius: 50%; - height: 25px; - font-weight: bold; - display: flex; - align-items: center; - justify-content: center; - font-family: Montserrat, sans-serif; - font-size: 16px; - font-weight: bold; - color: black; - background-color: rgb(51, 213, 0); - user-select: none; - transition: all 0.3s ease-in-out 0s; - } - - .groups-button-notif:hover { - cursor: auto; - box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px; - } - - .groups-button-notif:hover + .groups-button-notif-number { - display: block; - opacity: 1; - animation: fadeIn 0.6s; -} - -@keyframes fadeIn { - from { - opacity: 0; - top: -10px; - } - - to { - opacity: 1; - top: -60px; - } -} - - .groups-button-notif-number { - position: absolute; - transform: translateX(-50%); - left: 50%; - width: 150px; - text-align: center; - border-radius: 3px; - padding: 5px 10px; - background-color: white; - color: black; - font-family: Roboto, sans-serif; - letter-spacing: 0.3px; - font-weight: 300; - display: none; - opacity: 0; - top: -60px; - box-shadow: rgb(216 216 216 / 25%) 0px 6px 12px -2px, rgb(0 0 0 / 30%) 0px 3px 7px -3px; - } - - .groups-button:hover { - cursor: pointer; - filter: brightness(120%); - } - - .people-list .search { - padding-top: 20px; - padding-left: 20px; - padding-right: 20px; - display: flex; - align-items: center; - gap: 10px; - justify-content: space-between; - } - - .center { - margin: 0; - position: absolute; - padding-top: 12px; - left: 50%; - -ms-transform: translateX(-50%); - transform: translateX(-50%); - } - - .people-list .create-chat { - border-radius: 5px; - border: none; - display: inline-block; - color: #fff; - width: 100%; - font-size: 15px; - text-align: center; - cursor: pointer; - display: flex; - flex: 0; - } - - .people-list .create-chat:hover { - opacity: .8; - box-shadow: 0 3px 5px rgba(0, 0, 0, .2); - } - - .people-list ul { - padding: 0px 0px 60px 0px; - height: 85vh; - overflow-y: auto; - overflow-x: hidden; - } - - .people-list ul::-webkit-scrollbar-track { - background-color: whitesmoke; - border-radius: 7px; + .people-list ul::-webkit-scrollbar-track { + background: #a1a1a1; } .people-list ul::-webkit-scrollbar { - width: 6px; - border-radius: 7px; - background-color: whitesmoke; + width: 11px; } .people-list ul::-webkit-scrollbar-thumb { - background-color: rgb(180, 176, 176); - border-radius: 7px; - transition: all 0.3s ease-in-out; + background-color: #6a6c75; + border-radius: 6px; + border: 3px solid #a1a1a1; } - .chat { - width: 80vw; - height: 100vh; - float: left; - background: var(--white); - border-top-right-radius: 5px; - border-bottom-right-radius: 5px; - color: #434651; - box-sizing: border-box; - } + .chat { + width: 80vw; + height: 100vh; + float: left; + background: var(--white); + border-top-right-radius: 5px; + border-bottom-right-radius: 5px; + color: #434651; + box-sizing: border-box; + } - .chat .new-message-bar { - display: flex; - flex: 0 1 auto; - align-items: center; - justify-content: space-between; - padding: 0px 25px; - font-size: 14px; - font-weight: 500; - top: 0; - position: absolute; - left: 20vw; - right: 0; - z-index: 5; - background: var(--tradehead); - color: var(--white); - border-radius: 0 0 8px 8px; - min-height: 25px; - transition: opacity .15s; - text-transform: capitalize; - opacity: .85; - cursor: pointer; - } - - .chat .new-message-bar:hover { - opacity: .75; - transform: translateY(-1px); - box-shadow: 0 3px 7px rgba(0, 0, 0, .2); - } - - .hide-new-message-bar { - display: none !important; - } - - .chat .chat-history { - position: absolute; - top: 0; - right: 0; - bottom: 100%; - left: 20vw; - border-bottom: 2px solid var(--white); - overflow-y: hidden; - height: 100vh; - box-sizing: border-box; - } - - .chat .chat-message { - padding: 10px; - height: 10%; - display: inline-block; - width: 100%; - background-color: #eee; - } - - .chat .chat-message textarea { - width: 90%; - border: none; - font-size: 16px; - padding: 10px 20px; - border-radius: 5px; - resize: none; - } - - .chat .chat-message button { - float: right; - color: #94c2ed; - font-size: 16px; - text-transform: uppercase; - border: none; - cursor: pointer; - font-weight: bold; - background: #f2f5f8; - padding: 10px; - margin-top: 4px; - margin-right: 4px; - } - - .chat .chat-message button:hover { - color: #75b1e8; - } - - .online, - .offline, - .me { - margin-right: 3px; - font-size: 10px; - } - - .clearfix:after { - visibility: hidden; - display: block; - font-size: 0; - content: " "; - clear: both; - height: 0; - } - - .red { - --mdc-theme-primary: red; - } - - h2 { - margin:0; - } - - h2, h3, h4, h5 { - color: var(--black); - font-weight: 400; - } - - [hidden] { - display: hidden !important; - visibility: none !important; - } - - .details { - display: flex; - font-size: 18px; - } - - .title { - font-weight:600; - font-size:12px; - line-height: 32px; - opacity: 0.66; - } - - .textarea { - width: 100%; - border: none; - display: inline-block; - font-size: 16px; - padding: 10px 20px; - border-radius: 5px; - height: 120px; - resize: none; - background: #eee; - } - - .dialog-container { - position: relative; - display: flex; - align-items: center; - flex-direction: column; - padding: 0 10px; - gap: 10px; - height: 100%; - } - - .dialog-header { - color: var(--chat-bubble-msg-color); - } - - .dialog-subheader { - color: var(--chat-bubble-msg-color); - } - - .modal-button-row { - display: flex; - align-items: center; - justify-content: space-between; - width: 100%; - } - - .modal-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; - } - - .modal-button-red { - font-family: Roboto, sans-serif; - font-size: 16px; - color: #F44336; - background-color: transparent; - padding: 8px 10px; - border-radius: 5px; - border: none; - transition: all 0.3s ease-in-out; - } - - .modal-button-red:hover { - cursor: pointer; - background-color: #f4433663; - } - - .modal-button:hover { - cursor: pointer; - background-color: #03a8f475; - } - - .name-input { - width: 100%; - outline: 0; - border-width: 0 0 2px; - border-color: var(--mdc-theme-primary); - background-color: transparent; - padding: 10px; - font-family: Roboto, sans-serif; - font-size: 15px; - color: var(--chat-bubble-msg-color); - box-sizing: border-box; - } - - .name-input::selection { + .chat .new-message-bar { + display: flex; + flex: 0 1 auto; + align-items: center; + justify-content: space-between; + padding: 0 25px; + font-size: 14px; + font-weight: 500; + top: 0; + position: absolute; + left: 20vw; + right: 0; + z-index: 5; + background: var(--tradehead); + color: var(--white); + border-radius: 0 0 8px 8px; + min-height: 25px; + transition: opacity .15s; + text-transform: capitalize; + opacity: .85; + cursor: pointer; + } + + .chat .new-message-bar:hover { + opacity: .75; + transform: translateY(-1px); + box-shadow: 0 3px 7px rgba(0, 0, 0, .2); + } + + .hide-new-message-bar { + display: none !important; + } + + .chat .chat-history { + position: absolute; + top: 0; + right: 0; + bottom: 100%; + left: 20vw; + border-bottom: 2px solid var(--white); + overflow-y: hidden; + height: 100vh; + box-sizing: border-box; + } + + .chat .chat-message { + padding: 10px; + height: 10%; + display: inline-block; + width: 100%; + background-color: #eee; + } + + .chat .chat-message textarea { + width: 90%; + border: none; + font-size: 16px; + padding: 10px 20px; + border-radius: 5px; + resize: none; + } + + .chat .chat-message button { + float: right; + color: #94c2ed; + font-size: 16px; + text-transform: uppercase; + border: none; + cursor: pointer; + font-weight: bold; + background: #f2f5f8; + padding: 10px; + margin-top: 4px; + margin-right: 4px; + } + + .chat .chat-message button:hover { + color: #75b1e8; + } + + .online, + .offline, + .me { + margin-right: 3px; + font-size: 10px; + } + + .clearfix:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; + } + + .red { + --mdc-theme-primary: red; + } + + h2 { + margin:0; + } + + h2, h3, h4, h5 { + color: var(--black); + font-weight: 400; + } + + [hidden] { + display: hidden !important; + visibility: none !important; + } + + .details { + display: flex; + font-size: 18px; + } + + .title { + font-weight:600; + font-size:12px; + line-height: 32px; + opacity: 0.66; + } + + .textarea { + width: 100%; + border: none; + display: inline-block; + font-size: 16px; + padding: 10px 20px; + border-radius: 5px; + height: 120px; + resize: none; + background: #eee; + } + + .dialog-container { + position: relative; + display: flex; + align-items: center; + flex-direction: column; + padding: 0 10px; + gap: 10px; + height: 100%; + } + + .dialog-header { + color: var(--chat-bubble-msg-color); + } + + .dialog-subheader { + color: var(--chat-bubble-msg-color); + } + + .modal-button-row { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + } + + .modal-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; + } + + .modal-button-red { + font-family: Roboto, sans-serif; + font-size: 16px; + color: #F44336; + background-color: transparent; + padding: 8px 10px; + border-radius: 5px; + border: none; + transition: all 0.3s ease-in-out; + } + + .modal-button-red:hover { + cursor: pointer; + background-color: #f4433663; + } + + .modal-button:hover { + cursor: pointer; + background-color: #03a8f475; + } + + .name-input { + width: 100%; + outline: 0; + border-width: 0 0 2px; + border-color: var(--mdc-theme-primary); + background-color: transparent; + padding: 10px; + font-family: Roboto, sans-serif; + font-size: 15px; + color: var(--chat-bubble-msg-color); + box-sizing: border-box; + } + + .name-input::selection { background-color: var(--mdc-theme-primary); color: white; - } - - .name-input::placeholder { - opacity: 0.9; - color: var(--black); - } - - .search-field { - width: 100%; - position: relative; - } - - .search-icon { - position: absolute; - right: 3px; - color: var(--chat-bubble-msg-color); - transition: all 0.3s ease-in-out; - background: none; - border-radius: 50%; - padding: 6px 3px; - font-size: 21px; - } - - .search-icon:hover { - cursor: pointer; - background: #d7d7d75c; - } - - .search-results-div { - position: absolute; - top: 25px; - right: 25px; - } - - .user-verified { - position: absolute; - top: 0; - right: 5px; - display: flex; - align-items: center; - gap: 10px; - color: #04aa2e; - font-size: 13px; - } -` + } + + .name-input::placeholder { + opacity: 0.9; + color: var(--black); + } + + .search-field { + width: 100%; + position: relative; + } + + .search-icon { + position: absolute; + right: 3px; + color: var(--chat-bubble-msg-color); + transition: all 0.3s ease-in-out; + background: none; + border-radius: 50%; + padding: 6px 3px; + font-size: 21px; + } + + .search-icon:hover { + cursor: pointer; + background: #d7d7d75c; + } + + .search-results-div { + position: absolute; + top: 25px; + right: 25px; + } + .user-verified { + position: absolute; + top: 0; + right: 5px; + display: flex; + align-items: center; + gap: 10px; + color: #04aa2e; + font-size: 13px; + } +` \ No newline at end of file diff --git a/plugins/plugins/core/messaging/q-chat/q-chat.src.js b/plugins/plugins/core/messaging/q-chat/q-chat.src.js index 6dc84422..86f956d4 100644 --- a/plugins/plugins/core/messaging/q-chat/q-chat.src.js +++ b/plugins/plugins/core/messaging/q-chat/q-chat.src.js @@ -2,7 +2,7 @@ import {html, LitElement} from 'lit' import {render} from 'lit/html.js' import {passiveSupport} from 'passive-events-support/src/utils' import {Epml} from '../../../../epml.js' -import {get, translate} from '../../../../../core/translate/index.js' +import {get, translate} from '../../../../../core/translate' import {qchatStyles} from './q-chat-css.src.js' import {Editor, Extension} from '@tiptap/core' import isElectron from 'is-electron' @@ -12,7 +12,7 @@ import Underline from '@tiptap/extension-underline'; import Placeholder from '@tiptap/extension-placeholder' import Highlight from '@tiptap/extension-highlight' import snackbar from '../../components/snackbar.js' -import ShortUniqueId from 'short-unique-id'; +import ShortUniqueId from 'short-unique-id' import '../../components/ChatWelcomePage.js' import '../../components/ChatHead.js' @@ -26,977 +26,964 @@ import '@material/mwc-icon' import '@material/mwc-snackbar' import '@polymer/paper-spinner/paper-spinner-lite.js' import '@vaadin/grid' -import '@vaadin/tooltip'; - +import '@vaadin/tooltip' passiveSupport({ events: ['touchstart'] }) const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) class Chat extends LitElement { - static get properties() { - return { - selectedAddress: { type: Object }, - chatTitle: { type: String }, - chatHeads: { type: Array }, - chatHeadsObj: { type: Object }, - chatId: { type: String }, - messages: { type: Array }, - btnDisable: { type: Boolean }, - isLoading: { type: Boolean }, - balance: { type: Number }, - theme: { type: String, reflect: true }, - blockedUsers: { type: Array }, - blockedUserList: { type: Array }, - privateMessagePlaceholder: { type: String}, - imageFile: { type: Object }, - activeChatHeadUrl: { type: String }, - openPrivateMessage: { type: Boolean }, - userFound: { type: Array}, - userFoundModalOpen: { type: Boolean }, - userSelected: { type: Object }, - editor: {type: Object}, - groupInvites: { type: Array }, - loggedInUserName: {type: String}, - loggedInUserAddress: {type: String}, - openDialogGroupsModal: {type: Boolean} - } - } + static get properties() { + return { + selectedAddress: { type: Object }, + chatTitle: { type: String }, + chatHeads: { type: Array }, + chatHeadsObj: { type: Object }, + chatId: { type: String }, + messages: { type: Array }, + btnDisable: { type: Boolean }, + isLoading: { type: Boolean }, + balance: { type: Number }, + theme: { type: String, reflect: true }, + blockedUsers: { type: Array }, + blockedUserList: { type: Array }, + privateMessagePlaceholder: { type: String}, + imageFile: { type: Object }, + activeChatHeadUrl: { type: String }, + openPrivateMessage: { type: Boolean }, + userFound: { type: Array}, + userFoundModalOpen: { type: Boolean }, + userSelected: { type: Object }, + editor: {type: Object}, + groupInvites: { type: Array }, + loggedInUserName: {type: String}, + loggedInUserAddress: {type: String}, + openDialogGroupsModal: {type: Boolean} + } + } - static get styles() { + static get styles() { return [qchatStyles]; } - constructor() { - super() - this.selectedAddress = window.parent.reduxStore.getState().app.selectedAddress - this.config = { - user: { - node: { - } - } - } - this.chatTitle = "" - this.chatHeads = [] - this.chatHeadsObj = {} - this.chatId = '' - this.balance = 1 - this.messages = [] - this.btnDisable = false - this.isLoading = false - this.showNewMessageBar = this.showNewMessageBar.bind(this) - this.hideNewMessageBar = this.hideNewMessageBar.bind(this) - this.setOpenPrivateMessage = this.setOpenPrivateMessage.bind(this) - this._sendMessage = this._sendMessage.bind(this) - this.insertImage = this.insertImage.bind(this) - this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' - this.blockedUsers = [] - this.blockedUserList = [] - this.privateMessagePlaceholder = "" - this.imageFile = null - this.activeChatHeadUrl = '' - this.openPrivateMessage = false - this.userFound = [] - this.userFoundModalOpen = false - this.userSelected = {} - this.groupInvites = [] - this.loggedInUserName = "" - this.openDialogGroupsModal = false - this.uid = new ShortUniqueId(); - - } - - async setActiveChatHeadUrl(url) { - this.activeChatHeadUrl = url - this.requestUpdate() - } - - resetChatEditor(){ - this.editor.commands.setContent('') - } - - async getUpdateCompleteTextEditor() { - await super.getUpdateComplete() - const marginElements = Array.from(this.shadowRoot.querySelectorAll('chat-text-editor')) - await Promise.all(marginElements.map(el => el.updateComplete)) - const marginElements2 = Array.from(this.shadowRoot.querySelectorAll('wrapper-modal')) - await Promise.all(marginElements2.map(el => el.updateComplete)) - return true - } - - async connectedCallback() { - super.connectedCallback() - await this.getUpdateCompleteTextEditor() - - const elementChatId = this.shadowRoot.getElementById('messageBox').shadowRoot.getElementById('privateMessage') - this.editor = new Editor({ - onUpdate: ()=> { - this.shadowRoot.getElementById('messageBox').getMessageSize(this.editor.getJSON()) - }, - element: elementChatId, - extensions: [ - StarterKit, - Underline, - Highlight, - Placeholder.configure({ - placeholder: 'Write something …', - }), - Extension.create({ - addKeyboardShortcuts:()=> { - return { - 'Enter': ()=> { - const chatTextEditor = this.shadowRoot.getElementById('messageBox') - chatTextEditor.sendMessageFunc({ - }) - return true - } - } - }}) - ] - }) - - this.unsubscribeStore = window.parent.reduxStore.subscribe(() => { - try { - const currentState = window.parent.reduxStore.getState(); - - if(window.parent.location && window.parent.location.search) { - const queryString = window.parent.location.search - const params = new URLSearchParams(queryString) - const chat = params.get("chat") - if(chat && chat !== this.activeChatHeadUrl){ - let url = window.parent.location.href - let newUrl = url.split("?")[0] - window.parent.history.pushState({}, "", newUrl) - this.setActiveChatHeadUrl(chat) - } - } - if(currentState.app.accountInfo && currentState.app.accountInfo.names && currentState.app.accountInfo.names.length > 0 && this.loggedInUserName !== currentState.app.accountInfo.names[0].name){ - this.loggedInUserName = currentState.app.accountInfo.names[0].name - } - if(currentState.app.accountInfo && currentState.app.accountInfo.addressInfo && currentState.app.accountInfo.addressInfo.address && this.loggedInUserAddress !== currentState.app.accountInfo.addressInfo.address){ - this.loggedInUserAddress = currentState.app.accountInfo.addressInfo.address - } - } catch (error) { /* empty */ } - }) - } - - disconnectedCallback() { - super.disconnectedCallback() - this.editor.destroy() - this.unsubscribeStore() - } - - updatePlaceholder(editor, text) { - editor.extensionManager.extensions.forEach((extension) => { - if (extension.name === "placeholder") { - - extension.options["placeholder"] = text - editor.commands.focus('end') - } - }) - } - - setOpenDialogGroupsModal(val){ - this.openDialogGroupsModal = val - } - - openTabToGroupManagement(){ - window.parent.reduxStore.dispatch( - window.parent.reduxAction.setNewTab({ - url: `group-management`, - id: this.uid.rnd(), - myPlugObj: { - "url": "group-management", - "domain": "core", - "page": "group-management/index.html", - "title": "Group Management", - "icon": "vaadin:group", - "mwcicon": "group", - "pluginNumber": "plugin-fJZNpyLGTl", - "menus": [], - "parent": false - }, - openExisting: true - }) - ); - } - - render() { - return html` -
    -
    - -
      - ${this.isEmptyArray(this.chatHeads) ? this.renderLoadingText() : this.renderChatHead(this.chatHeads)} -
    - -
    -
    -
    this.scrollToBottom()}> - ${translate("chatpage.cchange4")} - ${translate("chatpage.cchange5")} keyboard_arrow_down -
    -
    - - ${this.activeChatHeadUrl ? html`${this.renderChatPage()}` : html`${this.renderChatWelcomePage()}`} -
    -
    - - { - this.resetChatEditor() - this.openPrivateMessage = false - this.shadowRoot.getElementById('sendTo').value = "" - this.userFoundModalOpen = false; - this.userFound = [] - } } - style=${this.openPrivateMessage ? "visibility:visible;z-index:50" : "visibility: hidden;z-index:-100;position: relative"}> -
    -
    -
    -

    ${translate("chatpage.cchange1")}

    -
    -
    -

    ${translate("chatpage.cchange6")}

    -
    - { - this.userSelected = {} - this.requestUpdate() - }} - /> - ${this.userSelected.name ? ( - html` -
    -

    ${translate("chatpage.cchange38")}

    - -
    - ` - ) : ( - html` - - - ` - )} -
    - - this.updatePlaceholder(editor, value)} - > - - -
    -
    - { - this.userSelected = result; - this.userFound = []; - this.userFoundModalOpen = false; - }} - .closeFunc=${() => { - this.userFoundModalOpen = false; - this.userFound = []; - }} - .searchResults=${this.userFound} - ?isOpen=${this.userFoundModalOpen} - ?loading=${this.isLoading}> - -
    -
    -
    - - - -
    -

    ${translate("chatpage.cchange10")}

    -
    -
    -
    - - { - if (data.item.name === "No registered name") { - render(html`${translate("chatpage.cchange15")}`, root) - } else { - render(html`${data.item.name}`, root) - } - }}> - - - { - render(html`${this.renderUnblockButton(data.item)}`, root); - }}> - - - ${this.isEmptyArray(this.blockedUserList) ? html` - ${translate("chatpage.cchange14")} - `: ''} - - ${translate("general.close")} - -
    -
    - - ` - } - - async firstUpdated() { - this.changeTheme() - this.getChatBlockedList() - this.getLocalBlockedList() - // await this.getPendingGroupInvites() - - const getBlockedUsers = async () => { - let blockedUsers = await parentEpml.request('apiCall', { - url: `/lists/blockedAddresses?apiKey=${this.getApiKey()}` - }) - this.blockedUsers = blockedUsers - setTimeout(getBlockedUsers, 60000) - } - - const stopKeyEventPropagation = (e) => { - e.stopPropagation() - return false - } - - const nameInput = this.shadowRoot.getElementById('sendTo') - - nameInput.addEventListener('keydown', stopKeyEventPropagation) - - this.shadowRoot.getElementById('messageBox').addEventListener('keydown', stopKeyEventPropagation) - - const runFunctionsAfterPageLoad = () => { - // Functions to exec after render while waiting for page info... - // getDataFromURL() - - try { - let key = `${window.parent.reduxStore.getState().app.selectedAddress.address.substr(0, 10)}_chat-heads` - let localChatHeads = localStorage.getItem(key) - this.setChatHeads(JSON.parse(localChatHeads)) - } catch (e) { - // TODO: Could add error handling in case there's a weird one... (-_-) - return - } - - // Clear Interval... - if (this.selectedAddress.address !== undefined) { - clearInterval(runFunctionsAfterPageLoadInterval) - return - } - } - - let runFunctionsAfterPageLoadInterval = setInterval(runFunctionsAfterPageLoad, 100) - - window.addEventListener('storage', () => { - const checkTheme = localStorage.getItem('qortalTheme') - - if (checkTheme === 'dark') { - this.theme = 'dark' - } else { - this.theme = 'light' - } - document.querySelector('html').setAttribute('theme', this.theme) - }) - - if (!isElectron()) { /* empty */ } else { - window.addEventListener('contextmenu', (event) => { - // Check if the clicked element has the class - let target = event.target; - while (target !== null) { - if (target.classList && target.classList.contains('customContextMenuDiv')) { - // Your custom context menu logic - this.showContextMenu(event); - return; - } - target = target.parentNode; - } - - // If it doesn't, show the default Electron context menu - event.preventDefault(); - window.parent.electronAPI.showMyMenu(); - }); - - - - } - - let configLoaded = false - - parentEpml.ready().then(() => { - - parentEpml.subscribe('config', c => { - if (!configLoaded) { - setTimeout(getBlockedUsers, 1) - configLoaded = true - } - this.config = JSON.parse(c) - }) - parentEpml.subscribe('chat_heads', chatHeads => { - chatHeads = JSON.parse(chatHeads) - this.getChatHeadFromState(chatHeads) - }) - parentEpml.subscribe('side_effect_action', async sideEffectActionParam => { - const sideEffectAction = JSON.parse(sideEffectActionParam) - - if(sideEffectAction && sideEffectAction.type === 'openPrivateChat'){ - const name = sideEffectAction.data.name - const address = sideEffectAction.data.address - if(this.chatHeadsObj.direct && this.chatHeadsObj.direct.find(item=> item.address === address)){ - this.setActiveChatHeadUrl(`direct/${address}`) - window.parent.reduxStore.dispatch( - window.parent.reduxAction.setSideEffectAction(null)) - } else { - this.setOpenPrivateMessage({ - open: true, - name: name - }) - window.parent.reduxStore.dispatch( - window.parent.reduxAction.setSideEffectAction(null)) - } - - } - }) - parentEpml.request('apiCall', { - url: `/addresses/balance/${window.parent.reduxStore.getState().app.selectedAddress.address}` - }).then(res => { - this.balance = res - this.requestUpdate() - }) - }) - parentEpml.imReady() - this.clearConsole() - setInterval(() => { - this.clearConsole() - }, 60000) - } - - - - clearConsole() { - if (!isElectron()) { /* empty */ } else { - console.clear() - window.parent.electronAPI.clearCache() - } - } - - setOpenPrivateMessage(props) { - this.openPrivateMessage = props.open; - this.shadowRoot.getElementById("sendTo").value = props.name - } - - async userSearch() { - const nameValue = this.shadowRoot.getElementById('sendTo').value - if(!nameValue) { - this.userFound = [] - this.userFoundModalOpen = true - return; - } - try { - const result = await parentEpml.request('apiCall', { - type: 'api', - url: `/names/${nameValue}` - }) - if (result.error === 401) { - this.userFound = [] - } else { - this.userFound = [ - ...this.userFound, - result, - ]; - } - this.userFoundModalOpen = true; - } catch (error) { - let err4string = get("chatpage.cchange35"); - parentEpml.request('showSnackBar', `${err4string}`) - } - } - - redirectToGroups() { - window.location.href = `../../group-management/index.html` - } - - async _sendMessage(outSideMsg, msg) { - this.isLoading = true; - - const trimmedMessage = msg - if (/^\s*$/.test(trimmedMessage)) { - this.isLoading = false - } else { - const messageObject = { - messageText: trimmedMessage, - images: [''], - repliedTo: '', - version: 3 - } - const stringifyMessageObject = JSON.stringify(messageObject) - this.sendMessage(stringifyMessageObject) - } - } - - async sendMessage(messageText) { - this.isLoading = true - - const _recipient = this.shadowRoot.getElementById('sendTo').value - - let recipient - - const validateName = async (receiverName) => { - let myRes - try { - let myNameRes = await parentEpml.request('apiCall', { - type: 'api', - url: `/names/${receiverName}` - }); - if (myNameRes.error === 401) { - myRes = false; - } else { - myRes = myNameRes - } - return myRes; - } catch (error) { - return "" - } - }; - - const myNameRes = await validateName(_recipient) - if (!myNameRes) { - recipient = _recipient - } else { - recipient = myNameRes.owner - } - - const getAddressPublicKey = async () => { - let isEncrypted; - let _publicKey; - - let addressPublicKey = await parentEpml.request('apiCall', { - type: 'api', - url: `/addresses/publickey/${recipient}` - }) - - if (addressPublicKey.error === 102) { - _publicKey = false - let err4string = get("chatpage.cchange19") - parentEpml.request('showSnackBar', `${err4string}`) - this.isLoading = false - } else if (addressPublicKey !== false) { - isEncrypted = 1 - _publicKey = addressPublicKey - sendMessageRequest(isEncrypted, _publicKey) - } else { - let err4string = get("chatpage.cchange39") - parentEpml.request('showSnackBar', `${err4string}`) - this.isLoading = false - } - }; - let _reference = new Uint8Array(64) - window.crypto.getRandomValues(_reference); - let reference = window.parent.Base58.encode(_reference) - const sendMessageRequest = async (isEncrypted, _publicKey) => { - let chatResponse = await parentEpml.request('chat', { - type: 18, - nonce: this.selectedAddress.nonce, - params: { - timestamp: Date.now(), - recipient: recipient, - recipientPublicKey: _publicKey, - hasChatReference: 0, - message: messageText, - lastReference: reference, - proofOfWorkNonce: 0, - isEncrypted: 1, - isText: 1 - } - }) - - _computePow(chatResponse); - }; - - const _computePow = async (chatBytes) => { - const difficulty = this.balance < 4 ? 18 : 8 - const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full' - const worker = new WebWorker() - let nonce = null - let chatBytesArray = null; - await new Promise((res) => { - worker.postMessage({chatBytes, path, difficulty}) - worker.onmessage = e => { - worker.terminate() - chatBytesArray = e.data.chatBytesArray - nonce = e.data.nonce - res() - } - }) - - let _response = await parentEpml.request('sign_chat', { - nonce: this.selectedAddress.nonce, - chatBytesArray: chatBytesArray, - chatNonce: nonce - }); - - getSendChatResponse(_response) - }; - - const getSendChatResponse = (response) => { - if (response === true) { - this.setActiveChatHeadUrl(`direct/${recipient}`) - this.shadowRoot.getElementById('sendTo').value = "" - this.openPrivateMessage = false - this.resetChatEditor(); - } else if (response.error) { - parentEpml.request('showSnackBar', response.message) - } else { - let err2string = get("chatpage.cchange21") - parentEpml.request('showSnackBar', `${err2string}`) - } - - this.isLoading = false - } - - // Exec.. - getAddressPublicKey() - - } - - insertImage(file) { - if (file.type.includes('image')) { - this.imageFile = file - return - } - parentEpml.request('showSnackBar', get("chatpage.cchange28")) - } - - renderLoadingText() { - return html`
    ` - } - - renderSendText() { - return html`${translate("chatpage.cchange9")}` - } - - relMessages() { - setTimeout(() => { - window.location.href = window.location.href.split( '#' )[0] - }, 500) - } - - getLocalBlockedList() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const blockedAddressesUrl = `${nodeUrl}/lists/blockedAddresses?apiKey=${this.getApiKey()}` - - localStorage.removeItem("MessageBlockedAddresses") - - var hidelist = [] - - fetch(blockedAddressesUrl).then(response => { - return response.json() - }).then(data => { - data.map(item => { - hidelist.push(item) - }) - localStorage.setItem("MessageBlockedAddresses", JSON.stringify(hidelist)) - - this.blockedUserList = hidelist - }) - } - - getChatBlockedList() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const blockedAddressesUrl = `${nodeUrl}/lists/blockedAddresses?apiKey=${this.getApiKey()}` - const err1string = 'No registered name' - - localStorage.removeItem("ChatBlockedAddresses") - - var obj = [] - - fetch(blockedAddressesUrl).then(response => { - return response.json() - }).then(data => { - return data.map(item => { - const noName = { - name: err1string, - owner: item - } - fetch(`${nodeUrl}/names/address/${item}?limit=0&reverse=true`).then(res => { - return res.json() - }).then(jsonRes => { - if(jsonRes.length) { - jsonRes.map (item => { - obj.push(item) - }) - } else { - obj.push(noName) - } - localStorage.setItem("ChatBlockedAddresses", JSON.stringify(obj)) - this.blockedUserList = JSON.parse(localStorage.getItem("ChatBlockedAddresses") || "[]") - }) - }) - }) - } - - async getPendingGroupInvites() { - const myAddress = window.parent.reduxStore.getState().app.selectedAddress.address - try { - let pendingGroupInvites = await parentEpml.request('apiCall', { - url: `/groups/invites/${myAddress}` - }) - this.groupInvites = pendingGroupInvites; - } catch (error) { - let err4string = get("chatpage.cchange61"); - parentEpml.request('showSnackBar', `${err4string}`) - } - } - - async unblockUser(websiteObj) { - let owner = websiteObj.owner - - let items = [ - owner - ] - - let ownersJsonString = JSON.stringify({ "items": items }) - - let ret = await parentEpml.request('apiCall', { - url: `/lists/blockedAddresses?apiKey=${this.getApiKey()}`, - method: 'DELETE', - headers: { - 'Content-Type': 'application/json' - }, - body: `${ownersJsonString}` - }) - - if (ret === true) { - this.blockedUsers = this.blockedUsers.filter(item => item != owner) - this.getChatBlockedList() - this.blockedUserList = JSON.parse(localStorage.getItem("ChatBlockedAddresses") || "[]") - let err2string = get("chatpage.cchange16") - snackbar.add({ - labelText: `${err2string}`, - dismiss: true - }) - this.relMessages() - } - else { - let err3string = get("chatpage.cchange17") - snackbar.add({ - labelText: `${err3string}`, - dismiss: true - }) - } - return ret - } - - renderUnblockButton(websiteObj) { - return html`` - } - - changeTheme() { - const checkTheme = localStorage.getItem('qortalTheme') - if (checkTheme === 'dark') { - this.theme = 'dark' - } else { - this.theme = 'light' - } - document.querySelector('html').setAttribute('theme', this.theme) - } - - renderChatWelcomePage() { - return html` - this.setOpenPrivateMessage(val)} - > - ` - } - - renderChatHead(chatHeadArr) { - return chatHeadArr.map(eachChatHead => { - return html` this.setActiveChatHeadUrl(val)} chatInfo=${JSON.stringify(eachChatHead)}>` - }) - } - - renderChatPage() { - // Check for the chat ID from and render chat messages - // Else render Welcome to Q-CHat - - // TODO: DONE: Do the above in the ChatPage - return html` - this.setOpenPrivateMessage(val)} - .setActiveChatHeadUrl=${(val)=> this.setActiveChatHeadUrl(val)} - balance=${this.balance} - loggedInUserName=${this.loggedInUserName} - loggedInUserAddress=${this.loggedInUserAddress} - > - - ` - } - - setChatHeads(chatObj) { - const chatObjGroups = Array.isArray(chatObj.groups) ? chatObj.groups : [] - const chatObjDirect = Array.isArray(chatObj.direct) ? chatObj.direct : [] - - let groupList = chatObjGroups.map(group => group.groupId === 0 ? { - groupId: group.groupId, url: `group/${group.groupId}`, - groupName: "Qortal General Chat", - timestamp: group.timestamp === undefined ? 2 : group.timestamp, - sender: group.sender } : { ...group, timestamp: group.timestamp === undefined ? 1 : group.timestamp, url: `group/${group.groupId}` - }) - - let directList = chatObjDirect.map(dc => { - return { ...dc, url: `direct/${dc.address}` } - }) - - const compareNames = (a, b) => { - return a.groupName.localeCompare(b.groupName) - } - - groupList.sort(compareNames) - let chatHeadMasterList = [...groupList, ...directList] - - const compareArgs = (a, b) => { - return b.timestamp - a.timestamp - } - - this.chatHeads = chatHeadMasterList.sort(compareArgs) - } - - getChatHeadFromState(chatObj) { - if (chatObj === undefined) { - return - } else { - this.chatHeadsObj = chatObj - this.setChatHeads(chatObj) - } - } - - _textArea(e) { - if (e.keyCode === 13 && !e.shiftKey) this._sendMessage() - } - - onPageNavigation(pageUrl) { - parentEpml.request('setPageUrl', pageUrl) - } - - isEmptyArray(arr) { - if (!arr) { return true } - return arr.length === 0 - } - - getApiKey() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - let apiKey = myNode.apiKey - return apiKey - } - - scrollToBottom() { - const viewElement = this.shadowRoot.querySelector('chat-page').shadowRoot.querySelector('chat-scroller').shadowRoot.getElementById('viewElement') - - const chatScrollerElement = this.shadowRoot.querySelector('chat-page').shadowRoot.querySelector('chat-scroller') - if (chatScrollerElement && chatScrollerElement.disableAddingNewMessages) { - const chatPageElement = this.shadowRoot.querySelector('chat-page') - if(chatPageElement && chatPageElement.getLastestMessages) - chatPageElement.getLastestMessages() - } else { - viewElement.scroll({ top: viewElement.scrollHeight, left: 0, behavior: 'smooth' }) - } - } - - showNewMessageBar() { - this.shadowRoot.getElementById('newMessageBar').classList.remove('hide-new-message-bar') - } - - hideNewMessageBar() { - this.shadowRoot.getElementById('newMessageBar').classList.add('hide-new-message-bar') - } + constructor() { + super() + this.selectedAddress = window.parent.reduxStore.getState().app.selectedAddress + this.config = { + user: { + node: { + } + } + } + this.chatTitle = "" + this.chatHeads = [] + this.chatHeadsObj = {} + this.chatId = '' + this.balance = 1 + this.messages = [] + this.btnDisable = false + this.isLoading = false + this.showNewMessageBar = this.showNewMessageBar.bind(this) + this.hideNewMessageBar = this.hideNewMessageBar.bind(this) + this.setOpenPrivateMessage = this.setOpenPrivateMessage.bind(this) + this._sendMessage = this._sendMessage.bind(this) + this.insertImage = this.insertImage.bind(this) + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + this.blockedUsers = [] + this.blockedUserList = [] + this.privateMessagePlaceholder = "" + this.imageFile = null + this.activeChatHeadUrl = '' + this.openPrivateMessage = false + this.userFound = [] + this.userFoundModalOpen = false + this.userSelected = {} + this.groupInvites = [] + this.loggedInUserName = "" + this.openDialogGroupsModal = false + this.uid = new ShortUniqueId() + + } + + async setActiveChatHeadUrl(url) { + this.activeChatHeadUrl = url + this.requestUpdate() + } + + resetChatEditor(){ + this.editor.commands.setContent('') + } + + async getUpdateCompleteTextEditor() { + await super.getUpdateComplete() + const marginElements = Array.from(this.shadowRoot.querySelectorAll('chat-text-editor')) + await Promise.all(marginElements.map(el => el.updateComplete)) + const marginElements2 = Array.from(this.shadowRoot.querySelectorAll('wrapper-modal')) + await Promise.all(marginElements2.map(el => el.updateComplete)) + return true + } + + async connectedCallback() { + super.connectedCallback() + await this.getUpdateCompleteTextEditor() + + const elementChatId = this.shadowRoot.getElementById('messageBox').shadowRoot.getElementById('privateMessage') + this.editor = new Editor({ + onUpdate: ()=> { + this.shadowRoot.getElementById('messageBox').getMessageSize(this.editor.getJSON()) + }, + element: elementChatId, + extensions: [ + StarterKit, + Underline, + Highlight, + Placeholder.configure({ + placeholder: 'Write something …', + }), + Extension.create({ + addKeyboardShortcuts:()=> { + return { + 'Enter': ()=> { + const chatTextEditor = this.shadowRoot.getElementById('messageBox') + chatTextEditor.sendMessageFunc({ + }) + return true + } + } + } + }) + ] + }) + + this.unsubscribeStore = window.parent.reduxStore.subscribe(() => { + try { + const currentState = window.parent.reduxStore.getState() + + if(window.parent.location && window.parent.location.search) { + const queryString = window.parent.location.search + const params = new URLSearchParams(queryString) + const chat = params.get("chat") + if(chat && chat !== this.activeChatHeadUrl){ + let url = window.parent.location.href + let newUrl = url.split("?")[0] + window.parent.history.pushState({}, "", newUrl) + this.setActiveChatHeadUrl(chat) + } + } + if(currentState.app.accountInfo && currentState.app.accountInfo.names && currentState.app.accountInfo.names.length > 0 && this.loggedInUserName !== currentState.app.accountInfo.names[0].name){ + this.loggedInUserName = currentState.app.accountInfo.names[0].name + } + if(currentState.app.accountInfo && currentState.app.accountInfo.addressInfo && currentState.app.accountInfo.addressInfo.address && this.loggedInUserAddress !== currentState.app.accountInfo.addressInfo.address){ + this.loggedInUserAddress = currentState.app.accountInfo.addressInfo.address + } + } catch (error) { /* empty */ } + }) + } + + disconnectedCallback() { + super.disconnectedCallback() + this.editor.destroy() + this.unsubscribeStore() + } + + updatePlaceholder(editor, text) { + editor.extensionManager.extensions.forEach((extension) => { + if (extension.name === "placeholder") { + + extension.options["placeholder"] = text + editor.commands.focus('end') + } + }) + } + + setOpenDialogGroupsModal(val){ + this.openDialogGroupsModal = val + } + + openTabToGroupManagement(){ + window.parent.reduxStore.dispatch( + window.parent.reduxAction.setNewTab({ + url: `group-management`, + id: this.uid.rnd(), + myPlugObj: { + "url": "group-management", + "domain": "core", + "page": "group-management/index.html", + "title": "Group Management", + "icon": "vaadin:group", + "mwcicon": "group", + "pluginNumber": "plugin-fJZNpyLGTl", + "menus": [], + "parent": false + }, + openExisting: true + }) + ); + } + + render() { + return html` +
    +
    + +
      + ${this.isEmptyArray(this.chatHeads) ? this.renderLoadingText() : this.renderChatHead(this.chatHeads)} +
    +
    +
    +
    this.scrollToBottom()}> + ${translate("chatpage.cchange4")} + ${translate("chatpage.cchange5")} keyboard_arrow_down +
    +
    + ${this.activeChatHeadUrl ? html`${this.renderChatPage()}` : html`${this.renderChatWelcomePage()}`} +
    +
    + + { + this.resetChatEditor() + this.openPrivateMessage = false + this.shadowRoot.getElementById('sendTo').value = "" + this.userFoundModalOpen = false; + this.userFound = [] + }} + style=${this.openPrivateMessage ? "visibility:visible;z-index:50" : "visibility: hidden;z-index:-100;position: relative"}> +
    +
    +
    +

    ${translate("chatpage.cchange1")}

    +
    +
    +

    ${translate("chatpage.cchange6")}

    +
    + { + this.userSelected = {} + this.requestUpdate() + }} + /> + ${this.userSelected.name ? ( + html` +
    +

    ${translate("chatpage.cchange38")}

    + +
    + ` + ) : ( + html` + + + ` + )} +
    + + this.updatePlaceholder(editor, value)} + > + + + +
    +
    + { + this.userSelected = result + this.userFound = []; + this.userFoundModalOpen = false + }} + .closeFunc=${() => { + this.userFoundModalOpen = false + this.userFound = [] + }} + .searchResults=${this.userFound} + ?isOpen=${this.userFoundModalOpen} + ?loading=${this.isLoading} + > + +
    +
    +
    + + + +
    +

    ${translate("chatpage.cchange10")}

    +
    +
    +
    + + { + if (data.item.name === "No registered name") { + render(html`${translate("chatpage.cchange15")}`, root) + } else { + render(html`${data.item.name}`, root) + } + }}> + + + { + render(html`${this.renderUnblockButton(data.item)}`, root) + }}> + + + ${this.isEmptyArray(this.blockedUserList) ? html` + ${translate("chatpage.cchange14")} + `: ''} + + ${translate("general.close")} + +
    +
    + ` + } + + async firstUpdated() { + this.changeTheme() + this.getChatBlockedList() + this.getLocalBlockedList() + + const getBlockedUsers = async () => { + let blockedUsers = await parentEpml.request('apiCall', { + url: `/lists/blockedAddresses?apiKey=${this.getApiKey()}` + }) + this.blockedUsers = blockedUsers + setTimeout(getBlockedUsers, 60000) + } + + const stopKeyEventPropagation = (e) => { + e.stopPropagation() + return false + } + + const nameInput = this.shadowRoot.getElementById('sendTo') + + nameInput.addEventListener('keydown', stopKeyEventPropagation) + + this.shadowRoot.getElementById('messageBox').addEventListener('keydown', stopKeyEventPropagation) + + const runFunctionsAfterPageLoad = () => { + // Functions to exec after render while waiting for page info... + // getDataFromURL() + + try { + let key = `${window.parent.reduxStore.getState().app.selectedAddress.address.substr(0, 10)}_chat-heads` + let localChatHeads = localStorage.getItem(key) + this.setChatHeads(JSON.parse(localChatHeads)) + } catch (e) { + // TODO: Could add error handling in case there's a weird one... (-_-) + return + } + + // Clear Interval... + if (this.selectedAddress.address !== undefined) { + clearInterval(runFunctionsAfterPageLoadInterval) + } + } + + let runFunctionsAfterPageLoadInterval = setInterval(runFunctionsAfterPageLoad, 100) + + window.addEventListener('storage', () => { + const checkTheme = localStorage.getItem('qortalTheme') + + if (checkTheme === 'dark') { + this.theme = 'dark' + } else { + this.theme = 'light' + } + document.querySelector('html').setAttribute('theme', this.theme) + }) + + if (!isElectron()) { /* empty */ } else { + window.addEventListener('contextmenu', (event) => { + // Check if the clicked element has the class + let target = event.target + while (target !== null) { + if (target.classList && target.classList.contains('customContextMenuDiv')) { + // Your custom context menu logic + this.showContextMenu(event) + return + } + target = target.parentNode + } + + // If it doesn't, show the default Electron context menu + event.preventDefault() + window.parent.electronAPI.showMyMenu() + }) + } + + let configLoaded = false + + parentEpml.ready().then(() => { + + parentEpml.subscribe('config', c => { + if (!configLoaded) { + setTimeout(getBlockedUsers, 1) + configLoaded = true + } + this.config = JSON.parse(c) + }) + parentEpml.subscribe('chat_heads', chatHeads => { + chatHeads = JSON.parse(chatHeads) + this.getChatHeadFromState(chatHeads) + }) + parentEpml.subscribe('side_effect_action', async sideEffectActionParam => { + const sideEffectAction = JSON.parse(sideEffectActionParam) + + if(sideEffectAction && sideEffectAction.type === 'openPrivateChat') { + const name = sideEffectAction.data.name + const address = sideEffectAction.data.address + if(this.chatHeadsObj.direct && this.chatHeadsObj.direct.find(item=> item.address === address)){ + this.setActiveChatHeadUrl(`direct/${address}`) + window.parent.reduxStore.dispatch( + window.parent.reduxAction.setSideEffectAction(null)) + } else { + this.setOpenPrivateMessage({ + open: true, + name: name + }) + window.parent.reduxStore.dispatch( + window.parent.reduxAction.setSideEffectAction(null)) + } + + } + }) + parentEpml.request('apiCall', { + url: `/addresses/balance/${window.parent.reduxStore.getState().app.selectedAddress.address}` + }).then(res => { + this.balance = res + this.requestUpdate() + }) + }) + parentEpml.imReady() + this.clearConsole() + setInterval(() => { + this.clearConsole() + }, 60000) + } + + clearConsole() { + if (!isElectron()) { /* empty */ } else { + console.clear() + window.parent.electronAPI.clearCache() + } + } + + setOpenPrivateMessage(props) { + this.openPrivateMessage = props.open; + this.shadowRoot.getElementById("sendTo").value = props.name + } + + async userSearch() { + const nameValue = this.shadowRoot.getElementById('sendTo').value + if(!nameValue) { + this.userFound = [] + this.userFoundModalOpen = true + return + } + try { + const result = await parentEpml.request('apiCall', { + type: 'api', + url: `/names/${nameValue}` + }) + if (result.error === 401) { + this.userFound = [] + } else { + this.userFound = [ + ...this.userFound, + result, + ]; + } + this.userFoundModalOpen = true; + } catch (error) { + let err4string = get("chatpage.cchange35"); + parentEpml.request('showSnackBar', `${err4string}`) + } + } + + redirectToGroups() { + window.location.href = `../../group-management/index.html` + } + + async _sendMessage(outSideMsg, msg) { + this.isLoading = true; + + const trimmedMessage = msg + if (/^\s*$/.test(trimmedMessage)) { + this.isLoading = false + } else { + const messageObject = { + messageText: trimmedMessage, + images: [''], + repliedTo: '', + version: 3 + } + const stringifyMessageObject = JSON.stringify(messageObject) + this.sendMessage(stringifyMessageObject) + } + } + + async sendMessage(messageText) { + this.isLoading = true + + const _recipient = this.shadowRoot.getElementById('sendTo').value + + let recipient + + const validateName = async (receiverName) => { + let myRes + try { + let myNameRes = await parentEpml.request('apiCall', { + type: 'api', + url: `/names/${receiverName}` + }); + if (myNameRes.error === 401) { + myRes = false; + } else { + myRes = myNameRes + } + return myRes; + } catch (error) { + return "" + } + } + + const myNameRes = await validateName(_recipient) + if (!myNameRes) { + recipient = _recipient + } else { + recipient = myNameRes.owner + } + + const getAddressPublicKey = async () => { + let isEncrypted; + let _publicKey; + + let addressPublicKey = await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/publickey/${recipient}` + }) + + if (addressPublicKey.error === 102) { + _publicKey = false + let err4string = get("chatpage.cchange19") + parentEpml.request('showSnackBar', `${err4string}`) + this.isLoading = false + } else if (addressPublicKey !== false) { + isEncrypted = 1 + _publicKey = addressPublicKey + sendMessageRequest(isEncrypted, _publicKey) + } else { + let err4string = get("chatpage.cchange39") + parentEpml.request('showSnackBar', `${err4string}`) + this.isLoading = false + } + } + let _reference = new Uint8Array(64) + window.crypto.getRandomValues(_reference); + let reference = window.parent.Base58.encode(_reference) + const sendMessageRequest = async (isEncrypted, _publicKey) => { + let chatResponse = await parentEpml.request('chat', { + type: 18, + nonce: this.selectedAddress.nonce, + params: { + timestamp: Date.now(), + recipient: recipient, + recipientPublicKey: _publicKey, + hasChatReference: 0, + message: messageText, + lastReference: reference, + proofOfWorkNonce: 0, + isEncrypted: 1, + isText: 1 + } + }) + _computePow(chatResponse) + } + + const _computePow = async (chatBytes) => { + const difficulty = this.balance < 4 ? 18 : 8 + const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full' + const worker = new WebWorker() + let nonce = null + let chatBytesArray = null + await new Promise((res) => { + worker.postMessage({chatBytes, path, difficulty}) + worker.onmessage = e => { + worker.terminate() + chatBytesArray = e.data.chatBytesArray + nonce = e.data.nonce + res() + } + }) + + let _response = await parentEpml.request('sign_chat', { + nonce: this.selectedAddress.nonce, + chatBytesArray: chatBytesArray, + chatNonce: nonce + }) + getSendChatResponse(_response) + } + + const getSendChatResponse = (response) => { + if (response === true) { + this.setActiveChatHeadUrl(`direct/${recipient}`) + this.shadowRoot.getElementById('sendTo').value = "" + this.openPrivateMessage = false + this.resetChatEditor(); + } else if (response.error) { + parentEpml.request('showSnackBar', response.message) + } else { + let err2string = get("chatpage.cchange21") + parentEpml.request('showSnackBar', `${err2string}`) + } + + this.isLoading = false + } + // Exec.. + getAddressPublicKey() + } + + insertImage(file) { + if (file.type.includes('image')) { + this.imageFile = file + return + } + parentEpml.request('showSnackBar', get("chatpage.cchange28")) + } + + renderLoadingText() { + return html`
    ` + } + + renderSendText() { + return html`${translate("chatpage.cchange9")}` + } + + relMessages() { + setTimeout(() => { + window.location.href = window.location.href.split( '#' )[0] + }, 500) + } + + getLocalBlockedList() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const blockedAddressesUrl = `${nodeUrl}/lists/blockedAddresses?apiKey=${this.getApiKey()}` + + localStorage.removeItem("MessageBlockedAddresses") + + var hidelist = [] + + fetch(blockedAddressesUrl).then(response => { + return response.json() + }).then(data => { + data.map(item => { + hidelist.push(item) + }) + localStorage.setItem("MessageBlockedAddresses", JSON.stringify(hidelist)) + + this.blockedUserList = hidelist + }) + } + + getChatBlockedList() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const blockedAddressesUrl = `${nodeUrl}/lists/blockedAddresses?apiKey=${this.getApiKey()}` + const err1string = 'No registered name' + + localStorage.removeItem("ChatBlockedAddresses") + + var obj = [] + + fetch(blockedAddressesUrl).then(response => { + return response.json() + }).then(data => { + return data.map(item => { + const noName = { + name: err1string, + owner: item + } + fetch(`${nodeUrl}/names/address/${item}?limit=0&reverse=true`).then(res => { + return res.json() + }).then(jsonRes => { + if(jsonRes.length) { + jsonRes.map (item => { + obj.push(item) + }) + } else { + obj.push(noName) + } + localStorage.setItem("ChatBlockedAddresses", JSON.stringify(obj)) + this.blockedUserList = JSON.parse(localStorage.getItem("ChatBlockedAddresses") || "[]") + }) + }) + }) + } + + async getPendingGroupInvites() { + const myAddress = window.parent.reduxStore.getState().app.selectedAddress.address + try { + let pendingGroupInvites = await parentEpml.request('apiCall', { + url: `/groups/invites/${myAddress}` + }) + this.groupInvites = pendingGroupInvites; + } catch (error) { + let err4string = get("chatpage.cchange61"); + parentEpml.request('showSnackBar', `${err4string}`) + } + } + + async unblockUser(websiteObj) { + let owner = websiteObj.owner + + let items = [ + owner + ] + + let ownersJsonString = JSON.stringify({ "items": items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/blockedAddresses?apiKey=${this.getApiKey()}`, + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + }, + body: `${ownersJsonString}` + }) + + if (ret === true) { + this.blockedUsers = this.blockedUsers.filter(item => item != owner) + this.getChatBlockedList() + this.blockedUserList = JSON.parse(localStorage.getItem("ChatBlockedAddresses") || "[]") + let err2string = get("chatpage.cchange16") + snackbar.add({ + labelText: `${err2string}`, + dismiss: true + }) + this.relMessages() + } + else { + let err3string = get("chatpage.cchange17") + snackbar.add({ + labelText: `${err3string}`, + dismiss: true + }) + } + return ret + } + + renderUnblockButton(websiteObj) { + return html`` + } + + changeTheme() { + const checkTheme = localStorage.getItem('qortalTheme') + if (checkTheme === 'dark') { + this.theme = 'dark' + } else { + this.theme = 'light' + } + document.querySelector('html').setAttribute('theme', this.theme) + } + + renderChatWelcomePage() { + return html` + this.setOpenPrivateMessage(val)} + > + ` + } + + renderChatHead(chatHeadArr) { + return chatHeadArr.map(eachChatHead => { + return html` this.setActiveChatHeadUrl(val)} chatInfo=${JSON.stringify(eachChatHead)}>` + }) + } + + renderChatPage() { + // Check for the chat ID from and render chat messages + // Else render Welcome to Q-CHat + + // TODO: DONE: Do the above in the ChatPage + return html` + this.setOpenPrivateMessage(val)} + .setActiveChatHeadUrl=${(val)=> this.setActiveChatHeadUrl(val)} + balance=${this.balance} + loggedInUserName=${this.loggedInUserName} + loggedInUserAddress=${this.loggedInUserAddress} + > + + ` + } + + setChatHeads(chatObj) { + const chatObjGroups = Array.isArray(chatObj.groups) ? chatObj.groups : [] + const chatObjDirect = Array.isArray(chatObj.direct) ? chatObj.direct : [] + + let groupList = chatObjGroups.map(group => group.groupId === 0 ? { + groupId: group.groupId, url: `group/${group.groupId}`, + groupName: "Qortal General Chat", + timestamp: group.timestamp === undefined ? 2 : group.timestamp, + sender: group.sender } : { ...group, timestamp: group.timestamp === undefined ? 1 : group.timestamp, url: `group/${group.groupId}` + }) + + let directList = chatObjDirect.map(dc => { + return { ...dc, url: `direct/${dc.address}` } + }) + + const compareNames = (a, b) => { + return a.groupName.localeCompare(b.groupName) + } + + groupList.sort(compareNames) + let chatHeadMasterList = [...groupList, ...directList] + + const compareArgs = (a, b) => { + return b.timestamp - a.timestamp + } + + this.chatHeads = chatHeadMasterList.sort(compareArgs) + } + + getChatHeadFromState(chatObj) { + if (chatObj === undefined) { + return + } else { + this.chatHeadsObj = chatObj + this.setChatHeads(chatObj) + } + } + + _textArea(e) { + if (e.keyCode === 13 && !e.shiftKey) this._sendMessage() + } + + onPageNavigation(pageUrl) { + parentEpml.request('setPageUrl', pageUrl) + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let apiKey = myNode.apiKey + return apiKey + } + + scrollToBottom() { + const viewElement = this.shadowRoot.querySelector('chat-page').shadowRoot.querySelector('chat-scroller').shadowRoot.getElementById('viewElement') + + const chatScrollerElement = this.shadowRoot.querySelector('chat-page').shadowRoot.querySelector('chat-scroller') + if (chatScrollerElement && chatScrollerElement.disableAddingNewMessages) { + const chatPageElement = this.shadowRoot.querySelector('chat-page') + if(chatPageElement && chatPageElement.getLastestMessages) + chatPageElement.getLastestMessages() + } else { + viewElement.scroll({ top: viewElement.scrollHeight, left: 0, behavior: 'smooth' }) + } + } + + showNewMessageBar() { + this.shadowRoot.getElementById('newMessageBar').classList.remove('hide-new-message-bar') + } + + hideNewMessageBar() { + this.shadowRoot.getElementById('newMessageBar').classList.add('hide-new-message-bar') + } } -window.customElements.define('q-chat', Chat) +window.customElements.define('q-chat', Chat) \ No newline at end of file