Merge remote-tracking branch 'origin/master' into feature/profile

This commit is contained in:
PhilReact 2023-11-06 14:50:07 +02:00
commit e6165f910d
273 changed files with 5524 additions and 3610 deletions

View File

@ -28,7 +28,7 @@ Easiest way to install the lastest required packages on Linux is via nvm.
``` source ~/.bashrc ``` (For Fedora / CentOS) <br/> ``` source ~/.bashrc ``` (For Fedora / CentOS) <br/>
``` nvm ls-remote ``` (Fetch list of available versions) <br/> ``` nvm ls-remote ``` (Fetch list of available versions) <br/>
``` nvm install v18.17.1 ``` (LTS: Hydrogen supported by Electron) <br/> ``` nvm install v18.17.1 ``` (LTS: Hydrogen supported by Electron) <br/>
``` npm --location=global install npm@10.2.0 ``` <br/> ``` npm --location=global install npm@10.2.1 ``` <br/>
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. 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.

View File

@ -1,4 +1,4 @@
import { html } from 'lit' import {html} from 'lit'
export const svgSun = html`<svg height="64px" style="shape-rendering:geometricPrecision;text-rendering:geometricPrecision;image-rendering:optimizeQuality;fill-rule:evenodd;clip-rule:evenodd;width: 32px;" version="1.1" viewBox="0 0 64 64" width="64px" xml:space="preserve"><defs><style type="text/css">.str0 {stroke:#FFC106;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:22.9256} .fil1 {fill:none} .fil0 {fill:#FFC106}</style></defs><g id="Layer_x0020_1"><g id="_866321920"><circle class="fil0" r="22.97" transform="matrix(0.543121 0.145529 -0.145529 0.543121 32.0002 31.9993)"/><path class="fil1 str0" d="M32 12.4c0,1.52 0,2 0,2m-9.8 0.63c0.76,1.32 1,1.73 1,1.73m-8.17 5.44c1.32,0.76 1.73,1 1.73,1m-4.36 8.8c1.53,0 2,0 2,0m0.63 9.8c1.32,-0.76 1.73,-1 1.73,-1m5.44 8.17c0.76,-1.32 1,-1.73 1,-1.73m8.8 4.36c0,-1.53 0,-2 0,-2m9.8 -0.63c-0.76,-1.32 -1,-1.73 -1,-1.73m8.17 -5.44c-1.32,-0.76 -1.73,-1 -1.73,-1m4.36 -8.8c-1.53,0 -2,0 -2,0m-0.63 -9.8c-1.32,0.76 -1.73,1 -1.73,1m-5.44 -8.17c-0.76,1.32 -1,1.73 -1,1.73"/></g></g></svg>`; export const svgSun = html`<svg height="64px" style="shape-rendering:geometricPrecision;text-rendering:geometricPrecision;image-rendering:optimizeQuality;fill-rule:evenodd;clip-rule:evenodd;width: 32px;" version="1.1" viewBox="0 0 64 64" width="64px" xml:space="preserve"><defs><style type="text/css">.str0 {stroke:#FFC106;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:22.9256} .fil1 {fill:none} .fil0 {fill:#FFC106}</style></defs><g id="Layer_x0020_1"><g id="_866321920"><circle class="fil0" r="22.97" transform="matrix(0.543121 0.145529 -0.145529 0.543121 32.0002 31.9993)"/><path class="fil1 str0" d="M32 12.4c0,1.52 0,2 0,2m-9.8 0.63c0.76,1.32 1,1.73 1,1.73m-8.17 5.44c1.32,0.76 1.73,1 1.73,1m-4.36 8.8c1.53,0 2,0 2,0m0.63 9.8c1.32,-0.76 1.73,-1 1.73,-1m5.44 8.17c0.76,-1.32 1,-1.73 1,-1.73m8.8 4.36c0,-1.53 0,-2 0,-2m9.8 -0.63c-0.76,-1.32 -1,-1.73 -1,-1.73m8.17 -5.44c-1.32,-0.76 -1.73,-1 -1.73,-1m4.36 -8.8c-1.53,0 -2,0 -2,0m-0.63 -9.8c-1.32,0.76 -1.73,1 -1.73,1m-5.44 -8.17c-0.76,1.32 -1,1.73 -1,1.73"/></g></g></svg>`;
export const svgMoon = html `<svg height="32px" style="enable-background:new 0 0 32 32;" version="1.1" viewBox="0 0 32 32" width="32px" xml:space="preserve"><g id="Layer_1"/><g id="moon_x5F_fill"><g><path d="M24.633,22.184c-8.188,0-14.82-6.637-14.82-14.82c0-2.695,0.773-5.188,2.031-7.363 C5.02,1.969,0,8.188,0,15.645C0,24.676,7.32,32,16.352,32c7.457,0,13.68-5.023,15.648-11.844 C29.82,21.41,27.328,22.184,24.633,22.184z" style="fill:#4E4E50;"/></g></g></svg>`; export const svgMoon = html `<svg height="32px" style="enable-background:new 0 0 32 32;" version="1.1" viewBox="0 0 32 32" width="32px" xml:space="preserve"><g id="Layer_1"/><g id="moon_x5F_fill"><g><path d="M24.633,22.184c-8.188,0-14.82-6.637-14.82-14.82c0-2.695,0.773-5.188,2.031-7.363 C5.02,1.969,0,8.188,0,15.645C0,24.676,7.32,32,16.352,32c7.457,0,13.68-5.023,15.648-11.844 C29.82,21.41,27.328,22.184,24.633,22.184z" style="fill:#4E4E50;"/></g></g></svg>`;

View File

@ -65,6 +65,7 @@ html {
--app-icon: #ffffff; --app-icon: #ffffff;
--app-hr: rgba(0, 0, 0, .3); --app-hr: rgba(0, 0, 0, .3);
--code-block-text-color: #008fd5; --code-block-text-color: #008fd5;
--noavatar: url("/img/noavatar_light.png");
} }
html[theme="dark"] { html[theme="dark"] {
@ -134,4 +135,5 @@ html[theme="dark"] {
--app-icon: #03a9f4; --app-icon: #03a9f4;
--app-hr: rgba(255, 255, 255, .3); --app-hr: rgba(255, 255, 255, .3);
--code-block-text-color: #008fd5; --code-block-text-color: #008fd5;
--noavatar: url("/img/noavatar_dark.png");
} }

View File

@ -5,6 +5,7 @@
"chinese1": "Chinesisch (vereinfacht)", "chinese1": "Chinesisch (vereinfacht)",
"chinese2": "Chinesisch (traditionell)", "chinese2": "Chinesisch (traditionell)",
"croatian": "Kroatisch", "croatian": "Kroatisch",
"dutch": "Niederländisch",
"english": "Englisch", "english": "Englisch",
"estonian": "Estnisch", "estonian": "Estnisch",
"french": "Französisch", "french": "Französisch",
@ -153,11 +154,11 @@
"lp18": "Schlüsselteile ableiten", "lp18": "Schlüsselteile ableiten",
"lp19": "Fehler, falscher Schlüssel. ", "lp19": "Fehler, falscher Schlüssel. ",
"lp20": "Fehler, falsche Nonce", "lp20": "Fehler, falsche Nonce",
"lp21": "Wichtige Teile kombinieren", "lp21": "Schlüsselteile kombinieren",
"lp22": "Schlüssel ist bereit" "lp22": "Schlüssel ist bereit"
}, },
"logout": { "logout": {
"logout": "AUSLOGGEN", "logout": "ABMELDEN",
"confirmlogout": "Möchten Sie sich wirklich abmelden?" "confirmlogout": "Möchten Sie sich wirklich abmelden?"
}, },
"fragfile": { "fragfile": {
@ -195,7 +196,7 @@
"export": "Knoten Exportieren", "export": "Knoten Exportieren",
"deletecustomnode": "Alle benutzerdefinierten Knoten entfernen", "deletecustomnode": "Alle benutzerdefinierten Knoten entfernen",
"warning": "Ihre bestehenden Knoten werden gelöscht und aus dem Backup neu erstellt.", "warning": "Ihre bestehenden Knoten werden gelöscht und aus dem Backup neu erstellt.",
"snack1": "Standardknoten erfolgreich gelöscht und hinzugefügt", "snack1": "Benutzerdefinierten Knoten erfolgreich gelöscht und Standardknoten hinzugefügt",
"snack2": "UI mit Knoten verbunden", "snack2": "UI mit Knoten verbunden",
"snack3": "Benutzerdefinierter Knoten erfolgreich hinzugefügt und gespeichert", "snack3": "Benutzerdefinierter Knoten erfolgreich hinzugefügt und gespeichert",
"snack4": "Knoten erfolgreich gespeichert als", "snack4": "Knoten erfolgreich gespeichert als",
@ -387,7 +388,7 @@
"wchange45": "Sende alle", "wchange45": "Sende alle",
"wchange46": "An diese Adresse verschicken", "wchange46": "An diese Adresse verschicken",
"wchange47": "Adressbuch", "wchange47": "Adressbuch",
"wchange48": "Dieses Adressbuch ist leer !", "wchange48": "Dieses Adressbuch ist leer!",
"wchange49": "Zum Adressbuch hinzufügen", "wchange49": "Zum Adressbuch hinzufügen",
"wchange50": "Der Name darf nicht leer sein!", "wchange50": "Der Name darf nicht leer sein!",
"wchange51": "Adresse darf nicht leer sein!", "wchange51": "Adresse darf nicht leer sein!",
@ -621,7 +622,7 @@
"schange12": "Verfolgte Q-Tubes", "schange12": "Verfolgte Q-Tubes",
"schange13": "Du folgst keinen Q-Tubes", "schange13": "Du folgst keinen Q-Tubes",
"schange14": "Ihre blockierten Q-Tubes", "schange14": "Ihre blockierten Q-Tubes",
"schange15": "Blockierte Q-Röhren", "schange15": "Blockierte Q-Tubes",
"schange16": "Sie haben keine Q-Tubes blockiert", "schange16": "Sie haben keine Q-Tubes blockiert",
"schange17": "Name nicht gefunden!", "schange17": "Name nicht gefunden!",
"schange18": "Relaismodus ist aktiviert. Das bedeutet, dass Ihr Knoten dabei hilft, verschlüsselte Daten durch das Netzwerk zu transportieren, wenn ein Peer dies anfordert. Sie können sich durch Einstellung abmelden", "schange18": "Relaismodus ist aktiviert. Das bedeutet, dass Ihr Knoten dabei hilft, verschlüsselte Daten durch das Netzwerk zu transportieren, wenn ein Peer dies anfordert. Sie können sich durch Einstellung abmelden",
@ -727,7 +728,8 @@
"bchange45": "Verschlüsseln", "bchange45": "Verschlüsseln",
"bchange46": "Geben Sie dieser Anwendung die Erlaubnis, die folgende Datei zu speichern?", "bchange46": "Geben Sie dieser Anwendung die Erlaubnis, die folgende Datei zu speichern?",
"bchange47": "Sofortige Veröffentlichung erforderlich", "bchange47": "Sofortige Veröffentlichung erforderlich",
"bchange48": "Erteilen Sie dieser Anwendung die Berechtigung, Ihnen Benachrichtigungen zu senden?" "bchange48": "Erteilen Sie dieser Anwendung die Berechtigung, Ihnen Benachrichtigungen zu senden?",
"bchange49": "Erteilen Sie dieser Anwendung die Erlaubnis, Ihr Wallet-Informationen abzurufen?"
}, },
"datapage": { "datapage": {
"dchange1": "Datenmanagement", "dchange1": "Datenmanagement",
@ -796,7 +798,7 @@
"cchange42": "Aus Gründen der Spam-Bekämpfung benötigen Konten mit einem Qort-Guthaben von weniger als 4 viel Zeit, um Nachrichten in Q-Chat zu SENDEN. Wenn Sie die Sendegeschwindigkeit für Q-Chat-Nachrichten sofort erhöhen möchten, besorgen Sie sich über 4 QORT an Ihre Adresse. Dies kann mit Trades im Handelsportal oder über einen anderen Qortian erfolgen, der Ihnen die QORT gibt. Sobald Sie über 4 QORT in Ihrem Konto haben, werden Q-Chat-Nachrichten sofort gesendet und dieser Dialog wird nicht mehr angezeigt Show. Vielen Dank für Ihr Verständnis für diese notwendige Spam-Präventionsmethode, und wir hoffen, dass Ihnen Qortal gefällt!", "cchange42": "Aus Gründen der Spam-Bekämpfung benötigen Konten mit einem Qort-Guthaben von weniger als 4 viel Zeit, um Nachrichten in Q-Chat zu SENDEN. Wenn Sie die Sendegeschwindigkeit für Q-Chat-Nachrichten sofort erhöhen möchten, besorgen Sie sich über 4 QORT an Ihre Adresse. Dies kann mit Trades im Handelsportal oder über einen anderen Qortian erfolgen, der Ihnen die QORT gibt. Sobald Sie über 4 QORT in Ihrem Konto haben, werden Q-Chat-Nachrichten sofort gesendet und dieser Dialog wird nicht mehr angezeigt Show. Vielen Dank für Ihr Verständnis für diese notwendige Spam-Präventionsmethode, und wir hoffen, dass Ihnen Qortal gefällt!",
"cchange43": "Tipp QORT an", "cchange43": "Tipp QORT an",
"cchange44": "NACHRICHT SENDEN", "cchange44": "NACHRICHT SENDEN",
"cchange45": "TIP BENUTZER", "cchange45": "TIPP BENUTZER",
"cchange46": "Trinkgeldbetrag", "cchange46": "Trinkgeldbetrag",
"cchange47": "Verfügbares Guthaben", "cchange47": "Verfügbares Guthaben",
"cchange48": "QORT-Guthaben konnte nicht abgerufen werden. Versuchen Sie es erneut!", "cchange48": "QORT-Guthaben konnte nicht abgerufen werden. Versuchen Sie es erneut!",
@ -810,7 +812,7 @@
"cchange56": "Transaktion fehlgeschlagen!", "cchange56": "Transaktion fehlgeschlagen!",
"cchange57": "Benutzerinfo", "cchange57": "Benutzerinfo",
"cchange58": "NACHRICHT SENDEN", "cchange58": "NACHRICHT SENDEN",
"cchange59": "TIP BENUTZER", "cchange59": "TIPP BENUTZER",
"cchange60": "Gruppeneinladungen ausstehend", "cchange60": "Gruppeneinladungen ausstehend",
"cchange61": "Fehler beim Abrufen von Gruppeneinladungen. Bitte versuchen Sie es erneut!", "cchange61": "Fehler beim Abrufen von Gruppeneinladungen. Bitte versuchen Sie es erneut!",
"cchange62": "Falscher Benutzername und falsche Adresse eingegeben! Bitte versuchen Sie es erneut!", "cchange62": "Falscher Benutzername und falsche Adresse eingegeben! Bitte versuchen Sie es erneut!",
@ -912,7 +914,7 @@
"gchange36": "Verlasse", "gchange36": "Verlasse",
"gchange37": "Gruppe verlassen", "gchange37": "Gruppe verlassen",
"gchange38": "Gruppenbesitzer verwalten:", "gchange38": "Gruppenbesitzer verwalten:",
"gchange39": "Gruppenadministrator verwalten::", "gchange39": "Gruppenadministrator verwalten:",
"gchange40": "Gruppe verwalten", "gchange40": "Gruppe verwalten",
"gchange41": "Gruppenerstellung erfolgreich!", "gchange41": "Gruppenerstellung erfolgreich!",
"gchange42": "Ungültiger Gruppenname", "gchange42": "Ungültiger Gruppenname",
@ -960,9 +962,9 @@
"nchange4": "Prägekonto hinzufügen", "nchange4": "Prägekonto hinzufügen",
"nchange5": "Wenn Sie mit Ihrem eigenen Konto prägen möchten, müssen Sie eine Rewardshare-Transaktion für sich selbst erstellen (wobei der Rewardshare-Prozentsatz auf 0 gesetzt ist) und dann mit dem Rewardshare-Schlüssel prägen, den Ihnen zugeteilt wird.", "nchange5": "Wenn Sie mit Ihrem eigenen Konto prägen möchten, müssen Sie eine Rewardshare-Transaktion für sich selbst erstellen (wobei der Rewardshare-Prozentsatz auf 0 gesetzt ist) und dann mit dem Rewardshare-Schlüssel prägen, den Ihnen zugeteilt wird.",
"nchange6": "Belohnungsschlüssel", "nchange6": "Belohnungsschlüssel",
"nchange7": "Adding minting account", "nchange7": "Minting-Konto hinzufügen",
"nchange8": "Hinzufügen", "nchange8": "Hinzufügen",
"nchange9": "Minting-Konto hinzufügen", "nchange9": "Minting-Konto",
"nchange10": "Empfängerkonto", "nchange10": "Empfängerkonto",
"nchange11": "Aktion", "nchange11": "Aktion",
"nchange12": "Entfernen", "nchange12": "Entfernen",

View File

@ -5,6 +5,7 @@
"chinese1": "Chino (Simplificado)", "chinese1": "Chino (Simplificado)",
"chinese2": "Chino (Tradicional)", "chinese2": "Chino (Tradicional)",
"croatian": "Croata", "croatian": "Croata",
"dutch": "Holandés",
"english": "Inglés", "english": "Inglés",
"estonian": "Estonio", "estonian": "Estonio",
"french": "Francés", "french": "Francés",
@ -727,7 +728,8 @@
"bchange45": "Cifrar", "bchange45": "Cifrar",
"bchange46": "¿Le das permiso a esta aplicación para guardar el siguiente archivo?", "bchange46": "¿Le das permiso a esta aplicación para guardar el siguiente archivo?",
"bchange47": "Publicación instantánea - requiere", "bchange47": "Publicación instantánea - requiere",
"bchange48": "¿Le das permiso a esta aplicación para enviarte notificaciones?" "bchange48": "¿Le das permiso a esta aplicación para enviarte notificaciones?",
"bchange49": "¿Le das permiso a esta aplicación para obtener la información de tu billetera?"
}, },
"datapage": { "datapage": {
"dchange1": "Gestión de datos", "dchange1": "Gestión de datos",

View File

@ -5,6 +5,7 @@
"chinese1": "Hiina (Lihtsustatud)", "chinese1": "Hiina (Lihtsustatud)",
"chinese2": "Hiina (Tradits.)", "chinese2": "Hiina (Tradits.)",
"croatian": "Horvaatia", "croatian": "Horvaatia",
"dutch": "Hollandi",
"english": "Inglise", "english": "Inglise",
"estonian": "Eesti", "estonian": "Eesti",
"french": "Prantsuse", "french": "Prantsuse",
@ -727,7 +728,8 @@
"bchange45": "Krüpteeri", "bchange45": "Krüpteeri",
"bchange46": "Kas annad sellele rakendusele loa salvestada järgnev fail", "bchange46": "Kas annad sellele rakendusele loa salvestada järgnev fail",
"bchange47": "Kiire avaldamine - nõuab", "bchange47": "Kiire avaldamine - nõuab",
"bchange48": "Kas annate sellele rakendusele loa teile teateid saata" "bchange48": "Kas annate sellele rakendusele loa teile teateid saata",
"bchange49": "Kas annad sellele rakendusele loa näha oma rahakoti teabe?"
}, },
"datapage": { "datapage": {
"dchange1": "Andmete haldamine", "dchange1": "Andmete haldamine",

View File

@ -5,6 +5,7 @@
"chinese1": "Chinois (Simplifié)", "chinese1": "Chinois (Simplifié)",
"chinese2": "Chinois (Traditionnel)", "chinese2": "Chinois (Traditionnel)",
"croatian": "Croate", "croatian": "Croate",
"dutch": "Néerlandais",
"english": "Anglais", "english": "Anglais",
"estonian": "Estonien", "estonian": "Estonien",
"french": "Français", "french": "Français",
@ -99,7 +100,7 @@
"upload": "Envoyer votre sauvegarde Qortal", "upload": "Envoyer votre sauvegarde Qortal",
"howlogin": "Comment voulez-vous vous connecter ?", "howlogin": "Comment voulez-vous vous connecter ?",
"seed": "Phrase mnémonique", "seed": "Phrase mnémonique",
"seedphrase": "Phrase mnémonique", "seedphrase": "phrase mnémonique",
"saved": "Compte sauvegardé", "saved": "Compte sauvegardé",
"qora": "Adresse de contrôle Qora", "qora": "Adresse de contrôle Qora",
"backup": "Sauvegarde du portefeuille Qortal", "backup": "Sauvegarde du portefeuille Qortal",
@ -110,7 +111,7 @@
"error1": "La sauvegarde doit être un JSON valide", "error1": "La sauvegarde doit être un JSON valide",
"error2": "Option de connexion non sélectionnée", "error2": "Option de connexion non sélectionnée",
"createwelcome": "Bienvenue dans Qortal, vous trouverez des similitudes avec un jeu de rôle, où, vous, en tant que frappeur dans le réseau Qortal (si vous choisissez d'en devenir un), aurez la chance d'augmenter votre niveau, vous donnant à la fois une plus grande partie de la récompense de bloc QORT et une plus grande influence sur le réseau en termes de vote sur les décisions pour la plate-forme.", "createwelcome": "Bienvenue dans Qortal, vous trouverez des similitudes avec un jeu de rôle, où, vous, en tant que frappeur dans le réseau Qortal (si vous choisissez d'en devenir un), aurez la chance d'augmenter votre niveau, vous donnant à la fois une plus grande partie de la récompense de bloc QORT et une plus grande influence sur le réseau en termes de vote sur les décisions pour la plate-forme.",
"createa": "A", "createa": "Une",
"click": "Cliquez pour voir la phrase mnémonique", "click": "Cliquez pour voir la phrase mnémonique",
"confirmpass": "Confirmez votre mot de passe", "confirmpass": "Confirmez votre mot de passe",
"willbe": "sera généré au hasard en arrière-plan. Il sera utilisé comme votre générateur de clé privée pour votre compte blockchain dans Qortal.", "willbe": "sera généré au hasard en arrière-plan. Il sera utilisé comme votre générateur de clé privée pour votre compte blockchain dans Qortal.",
@ -148,7 +149,7 @@
"lp13": "Génération de la clé de déchiffrement", "lp13": "Génération de la clé de déchiffrement",
"lp14": "Clé de vérification", "lp14": "Clé de vérification",
"lp15": "Mot de passe incorrect", "lp15": "Mot de passe incorrect",
"lp16": "Décryptage", "lp16": "Décryptage en cours",
"lp17": "En attente que les travailleurs soient prêts", "lp17": "En attente que les travailleurs soient prêts",
"lp18": "Dérivation des parties clés", "lp18": "Dérivation des parties clés",
"lp19": "Erreur, clé incorrecte. ", "lp19": "Erreur, clé incorrecte. ",
@ -727,7 +728,8 @@
"bchange45": "Crypter", "bchange45": "Crypter",
"bchange46": "Autorisez-vous cette application à enregistrer le fichier suivant", "bchange46": "Autorisez-vous cette application à enregistrer le fichier suivant",
"bchange47": "Publication instantanée - nécessite", "bchange47": "Publication instantanée - nécessite",
"bchange48": "Autorisez-vous cette application à vous envoyer des notifications" "bchange48": "Autorisez-vous cette application à vous envoyer des notifications",
"bchange49": "Autorisez-vous cette application à récupérer les informations de votre portefeuille ?"
}, },
"datapage": { "datapage": {
"dchange1": "Gestion de données", "dchange1": "Gestion de données",

View File

@ -5,6 +5,7 @@
"chinese1": "चीनी (सरलीकृत)", "chinese1": "चीनी (सरलीकृत)",
"chinese2": "चीनी (परंपरागत)", "chinese2": "चीनी (परंपरागत)",
"croatian": "क्रोएशियाई", "croatian": "क्रोएशियाई",
"dutch": "ओलंदेज़",
"english": "अंग्रेज़ी", "english": "अंग्रेज़ी",
"estonian": "एस्टोनियाई", "estonian": "एस्टोनियाई",
"french": "फ्रेंच", "french": "फ्रेंच",
@ -727,7 +728,8 @@
"bchange45": "एन्क्रिप्ट", "bchange45": "एन्क्रिप्ट",
"bchange46": "क्या आप इस एप्लिकेशन को निम्न फ़ाइल सहेजने की अनुमति देते हैं", "bchange46": "क्या आप इस एप्लिकेशन को निम्न फ़ाइल सहेजने की अनुमति देते हैं",
"bchange47": "तत्काल प्रकाशन - आवश्यक है", "bchange47": "तत्काल प्रकाशन - आवश्यक है",
"bchange48": "क्या आप इस एप्लिकेशन को आपको सूचनाएं भेजने की अनुमति देते हैं" "bchange48": "क्या आप इस एप्लिकेशन को आपको सूचनाएं भेजने की अनुमति देते हैं",
"bchange49": "क्या आप इस एप्लिकेशन को अपने वॉलेट की जानकारी प्राप्त करने की अनुमति देते हैं?"
}, },
"datapage": { "datapage": {
"dchange1": "डाटा प्रबंधन", "dchange1": "डाटा प्रबंधन",

View File

@ -5,6 +5,7 @@
"chinese1": "Kineski (Pojednostavljeni)", "chinese1": "Kineski (Pojednostavljeni)",
"chinese2": "Kineski (Traditionalni)", "chinese2": "Kineski (Traditionalni)",
"croatian": "Hrvatski", "croatian": "Hrvatski",
"dutch": "Holandski",
"english": "Engleski", "english": "Engleski",
"estonian": "Estonski", "estonian": "Estonski",
"french": "Francuski", "french": "Francuski",
@ -727,7 +728,8 @@
"bchange45": "Šifriraj", "bchange45": "Šifriraj",
"bchange46": "Dajete li ovoj aplikaciji dopuštenje za spremanje sljedeće datoteke", "bchange46": "Dajete li ovoj aplikaciji dopuštenje za spremanje sljedeće datoteke",
"bchange47": "Trenutno objavljivanje - zahtijeva", "bchange47": "Trenutno objavljivanje - zahtijeva",
"bchange48": "Dajete li ovoj aplikaciji dopuštenje da vam šalje obavijesti" "bchange48": "Dajete li ovoj aplikaciji dopuštenje da vam šalje obavijesti",
"bchange49": "Dajete li ovoj aplikaciji dopuštenje da dobije podatke o vašem novčaniku?"
}, },
"datapage": { "datapage": {
"dchange1": "Upravljanje podacima", "dchange1": "Upravljanje podacima",

View File

@ -5,6 +5,7 @@
"chinese1": "Kínai (Egyszerűsített)", "chinese1": "Kínai (Egyszerűsített)",
"chinese2": "Kínai (Hagyományos)", "chinese2": "Kínai (Hagyományos)",
"croatian": "Horvát", "croatian": "Horvát",
"dutch": "Németalföldi",
"english": "Angol", "english": "Angol",
"estonian": "Észt", "estonian": "Észt",
"french": "Francia", "french": "Francia",
@ -727,7 +728,8 @@
"bchange45": "Titkosítás", "bchange45": "Titkosítás",
"bchange46": "Engedélyezi ennek az alkalmazásnak a következő fájl mentését", "bchange46": "Engedélyezi ennek az alkalmazásnak a következő fájl mentését",
"bchange47": "Azonnali közzététel szükséges", "bchange47": "Azonnali közzététel szükséges",
"bchange48": "Engedélyezi ennek az alkalmazásnak, hogy értesítéseket küldjön Önnek" "bchange48": "Engedélyezi ennek az alkalmazásnak, hogy értesítéseket küldjön Önnek",
"bchange49": "Engedélyt ad ennek az alkalmazásnak, hogy megszerezze a pénztárca adatait?"
}, },
"datapage": { "datapage": {
"dchange1": "Adatkezelés", "dchange1": "Adatkezelés",

View File

@ -5,6 +5,7 @@
"chinese1": "Cinese (semplificato)", "chinese1": "Cinese (semplificato)",
"chinese2": "Cinese (tradizionale)", "chinese2": "Cinese (tradizionale)",
"croatian": "Croato", "croatian": "Croato",
"dutch": "Olandese",
"english": "Inglese", "english": "Inglese",
"estonian": "Estone", "estonian": "Estone",
"french": "Francese", "french": "Francese",
@ -727,7 +728,8 @@
"bchange45": "Cripta", "bchange45": "Cripta",
"bchange46": "Concedi a questa applicazione il permesso di salvare il seguente file", "bchange46": "Concedi a questa applicazione il permesso di salvare il seguente file",
"bchange47": "Pubblicazione istantanea - richiede", "bchange47": "Pubblicazione istantanea - richiede",
"bchange48": "Concedi a questa applicazione il permesso di inviarti notifiche" "bchange48": "Concedi a questa applicazione il permesso di inviarti notifiche",
"bchange49": "Concedi a questa applicazione il permesso di ottenere informazioni sul tuo portafoglio?"
}, },
"datapage": { "datapage": {
"dchange1": "Gestione dati", "dchange1": "Gestione dati",

View File

@ -5,6 +5,7 @@
"chinese1": "中国語 (簡体字)", "chinese1": "中国語 (簡体字)",
"chinese2": "中国語 (繁体字)", "chinese2": "中国語 (繁体字)",
"croatian": "クロアチア語", "croatian": "クロアチア語",
"dutch": "オランダの",
"english": "英語", "english": "英語",
"estonian": "エストニア語", "estonian": "エストニア語",
"french": "フランス語", "french": "フランス語",
@ -727,7 +728,8 @@
"bchange45": "暗号化", "bchange45": "暗号化",
"bchange46": "このアプリケーションに次のファイルを保存する事を許可しますか?", "bchange46": "このアプリケーションに次のファイルを保存する事を許可しますか?",
"bchange47": "インスタント公開 - が必要です", "bchange47": "インスタント公開 - が必要です",
"bchange48": "このアプリケーションに通知を送信する権限を与えますか?" "bchange48": "このアプリケーションに通知を送信する権限を与えますか?",
"bchange49": "ウォレット情報を取得する許可をこのアプリケーションに与えますか?"
}, },
"datapage": { "datapage": {
"dchange1": "データ管理", "dchange1": "データ管理",

View File

@ -5,6 +5,7 @@
"chinese1": "중국어(간체)", "chinese1": "중국어(간체)",
"chinese2": "중국어(번체)", "chinese2": "중국어(번체)",
"croatian": "크로아티아어", "croatian": "크로아티아어",
"dutch": "네덜란드의",
"english": "영어", "english": "영어",
"estonian": "에스토니아어", "estonian": "에스토니아어",
"french": "프랑스어", "french": "프랑스어",
@ -727,7 +728,8 @@
"bchange45": "암호화", "bchange45": "암호화",
"bchange46": "이 응용 프로그램에 다음 파일을 저장할 권한을 부여하시겠습니까?", "bchange46": "이 응용 프로그램에 다음 파일을 저장할 권한을 부여하시겠습니까?",
"bchange47": "즉시 게시 - 필요", "bchange47": "즉시 게시 - 필요",
"bchange48": "이 애플리케이션에 알림을 보낼 수 있는 권한을 부여하시겠습니까?" "bchange48": "이 애플리케이션에 알림을 보낼 수 있는 권한을 부여하시겠습니까?",
"bchange49": "이 애플리케이션에 지갑 정보를 얻을 수 있는 권한을 부여하시겠습니까?"
}, },
"datapage": { "datapage": {
"dchange1": "데이터 관리", "dchange1": "데이터 관리",

1218
core/language/nl.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@
"chinese1": "Kinesisk (Forenklet)", "chinese1": "Kinesisk (Forenklet)",
"chinese2": "Kinesisk (Tradisjonell)", "chinese2": "Kinesisk (Tradisjonell)",
"croatian": "Kroatisk", "croatian": "Kroatisk",
"dutch": "Nederlandsk",
"english": "Engelsk", "english": "Engelsk",
"estonian": "Estisk", "estonian": "Estisk",
"french": "Fransk", "french": "Fransk",
@ -727,7 +728,8 @@
"bchange45": "Krypter", "bchange45": "Krypter",
"bchange46": "Gir du dette programmet tillatelse til å lagre følgende fil", "bchange46": "Gir du dette programmet tillatelse til å lagre følgende fil",
"bchange47": "Øyeblikkelig publisering - krever", "bchange47": "Øyeblikkelig publisering - krever",
"bchange48": "Gir du denne applikasjonen tillatelse til å sende deg varsler" "bchange48": "Gir du denne applikasjonen tillatelse til å sende deg varsler",
"bchange49": "Gir du dette programmet tillatelse til å få lommebokinformasjonen din?"
}, },
"datapage": { "datapage": {
"dchange1": "Data-administrasjon", "dchange1": "Data-administrasjon",

View File

@ -5,6 +5,7 @@
"chinese1": "Chiński (uproszczony)", "chinese1": "Chiński (uproszczony)",
"chinese2": "Chiński (tradycyjny)", "chinese2": "Chiński (tradycyjny)",
"croatian": "Chorwacki", "croatian": "Chorwacki",
"dutch": "Holenderski",
"english": "Angielski", "english": "Angielski",
"estonian": "Estoński", "estonian": "Estoński",
"french": "Francuski", "french": "Francuski",
@ -727,7 +728,8 @@
"bchange45": "Szyfruj", "bchange45": "Szyfruj",
"bchange46": "Czy zezwalasz tej aplikacji na zapisanie następującego pliku", "bchange46": "Czy zezwalasz tej aplikacji na zapisanie następującego pliku",
"bchange47": "Błyskawiczna publikacja - wymaga", "bchange47": "Błyskawiczna publikacja - wymaga",
"bchange48": "Czy dajesz tej aplikacji pozwolenie na wysyłanie Ci powiadomień" "bchange48": "Czy dajesz tej aplikacji pozwolenie na wysyłanie Ci powiadomień",
"bchange49": "Czy dajesz tej aplikacji pozwolenie na uzyskanie informacji o Twoim portfelu?"
}, },
"datapage": { "datapage": {
"dchange1": "Zarządzanie danymi", "dchange1": "Zarządzanie danymi",

View File

@ -5,6 +5,7 @@
"chinese1": "Chinês Simplificado)", "chinese1": "Chinês Simplificado)",
"chinese2": "Chinês (Tradicional)", "chinese2": "Chinês (Tradicional)",
"croatian": "Croata", "croatian": "Croata",
"dutch": "Holandês",
"english": "Inglês", "english": "Inglês",
"estonian": "Estoniano", "estonian": "Estoniano",
"french": "Francês", "french": "Francês",
@ -727,7 +728,8 @@
"bchange45": "Criptografar", "bchange45": "Criptografar",
"bchange46": "Você concede permissão a este aplicativo para salvar o seguinte arquivo", "bchange46": "Você concede permissão a este aplicativo para salvar o seguinte arquivo",
"bchange47": "Publicação instantânea - requer", "bchange47": "Publicação instantânea - requer",
"bchange48": "Você dá permissão a este aplicativo para enviar notificações para você?" "bchange48": "Você dá permissão a este aplicativo para enviar notificações para você?",
"bchange49": "Você dá permissão a este aplicativo para obter informações da sua carteira?"
}, },
"datapage": { "datapage": {
"dchange1": "Gerenciamento de Dados", "dchange1": "Gerenciamento de Dados",

View File

@ -5,6 +5,7 @@
"chinese1": "Chineza (simplificata)", "chinese1": "Chineza (simplificata)",
"chinese2": "Chineza (traditionala)", "chinese2": "Chineza (traditionala)",
"croatian": "Croata", "croatian": "Croata",
"dutch": "Olandez",
"english": "Engleza", "english": "Engleza",
"estonian": "Estonian", "estonian": "Estonian",
"french": "Franceza", "french": "Franceza",
@ -727,7 +728,8 @@
"bchange45": "Criptați", "bchange45": "Criptați",
"bchange46": "Dați această aplicație permisiunea de a salva următorul fișier", "bchange46": "Dați această aplicație permisiunea de a salva următorul fișier",
"bchange47": "Publicare instantanee - necesită", "bchange47": "Publicare instantanee - necesită",
"bchange48": "Acordați acestei aplicații permisiunea de a vă trimite notificări" "bchange48": "Acordați acestei aplicații permisiunea de a vă trimite notificări",
"bchange49": "Oferiți acestei aplicații permisiunea de a obține informațiile despre portofel?"
}, },
"datapage": { "datapage": {
"dchange1": "Gestionare date", "dchange1": "Gestionare date",

View File

@ -5,6 +5,7 @@
"chinese1": "Kineski (pojednostavljeni)", "chinese1": "Kineski (pojednostavljeni)",
"chinese2": "Kineski (tradicionalni)", "chinese2": "Kineski (tradicionalni)",
"croatian": "Hrvatski", "croatian": "Hrvatski",
"dutch": "Holandski",
"english": "Engleski", "english": "Engleski",
"estonian": "Estonski", "estonian": "Estonski",
"french": "Francuski", "french": "Francuski",
@ -727,7 +728,8 @@
"bchange45": "Šifrovanje", "bchange45": "Šifrovanje",
"bchange46": "Da li ovoj aplikaciji dajete dozvolu da sačuva sledeću datoteku", "bchange46": "Da li ovoj aplikaciji dajete dozvolu da sačuva sledeću datoteku",
"bchange47": "Trenutno objavljivanje - zahteva", "bchange47": "Trenutno objavljivanje - zahteva",
"bchange48": "Da li ovoj aplikaciji dajete dozvolu da vam šalje obaveštenja" "bchange48": "Da li ovoj aplikaciji dajete dozvolu da vam šalje obaveštenja",
"bchange49": "Da li ovoj aplikaciji dajete dozvolu da dobije informacije o vašem novčaniku?"
}, },
"datapage": { "datapage": {
"dchange1": "Upravljanje podacima", "dchange1": "Upravljanje podacima",

View File

@ -5,6 +5,7 @@
"chinese1": "Китайский (упрощенный)", "chinese1": "Китайский (упрощенный)",
"chinese2": "Китайский (традиционный)", "chinese2": "Китайский (традиционный)",
"croatian": "Хорватский", "croatian": "Хорватский",
"dutch": "Голландский",
"english": "Английский", "english": "Английский",
"estonian": "Эстонский", "estonian": "Эстонский",
"french": "Французкий", "french": "Французкий",
@ -727,7 +728,8 @@
"bchange45": "Шифровать", "bchange45": "Шифровать",
"bchange46": "Даете ли вы этому приложению разрешение на сохранение следующего файла?", "bchange46": "Даете ли вы этому приложению разрешение на сохранение следующего файла?",
"bchange47": "Мгновенная публикация - требуется", "bchange47": "Мгновенная публикация - требуется",
"bchange48": "Разрешаете ли вы этому приложению отправлять вам уведомления?" "bchange48": "Разрешаете ли вы этому приложению отправлять вам уведомления?",
"bchange49": "Разрешаете ли вы этому приложению получать информацию о вашем кошельке?"
}, },
"datapage": { "datapage": {
"dchange1": "Управление данными", "dchange1": "Управление данными",

View File

@ -5,6 +5,7 @@
"chinese1": "Chinese (Simplified)", "chinese1": "Chinese (Simplified)",
"chinese2": "Chinese (Traditional)", "chinese2": "Chinese (Traditional)",
"croatian": "Croatian", "croatian": "Croatian",
"dutch": "Dutch",
"english": "English", "english": "English",
"estonian": "Estonian", "estonian": "Estonian",
"french": "French", "french": "French",
@ -75,7 +76,7 @@
"tm29": "Reset Tab Menu", "tm29": "Reset Tab Menu",
"tm30": "Search Qortal Name", "tm30": "Search Qortal Name",
"tm31": "My Followed Names", "tm31": "My Followed Names",
"tm32": "This account not follow any user", "tm32": "This account does not follow any user",
"tm33": "Import Tab Menu", "tm33": "Import Tab Menu",
"tm34": "Export Tab Menu", "tm34": "Export Tab Menu",
"tm35": "Your existing tab menu will be deleted and set to uploaded tab menu.", "tm35": "Your existing tab menu will be deleted and set to uploaded tab menu.",
@ -83,8 +84,8 @@
"tm37": "Tab Menu Successfully Saved As", "tm37": "Tab Menu Successfully Saved As",
"tm38": "DEV MODE", "tm38": "DEV MODE",
"tm39": "Add Custom Framework", "tm39": "Add Custom Framework",
"tm40": "Add And Open", "tm40": "Add and Open",
"tm41": "Error: Invalid data please try again !", "tm41": "Error: Invalid data please try again!",
"tm42": "Qortal Lottery" "tm42": "Qortal Lottery"
}, },
"login": { "login": {
@ -113,9 +114,9 @@
"createa": "A", "createa": "A",
"click": "Click to view seedphrase", "click": "Click to view seedphrase",
"confirmpass": "Confirm Password", "confirmpass": "Confirm Password",
"willbe": "will be randomly generated in background. This is used as your private key generator for your blockchain account in Qortal.", "willbe": "will be randomly generated in the background. This is used as your private key generator for your blockchain account in Qortal.",
"clicknext": "Create your Qortal account by clicking NEXT below.", "clicknext": "Create your Qortal account by clicking NEXT below.",
"ready": "Your account is now ready to be created. It will be saved in this browser. If you do not want your new account to be saved in your browser, you can uncheck the box below. You will still be able to log in with your new account(after logging out), using your wallet backup file that you MUST download once you create your account.", "ready": "Your account is now ready to be created. It will be saved in this browser. If you do not want your new account to be saved in your browser, you can uncheck the box below. You will still be able to log in with your new account (after logging out), using your wallet backup file that you MUST download once you create your account.",
"welmessage": "Welcome to Qortal", "welmessage": "Welcome to Qortal",
"pleaseenter": "Please enter a Password!", "pleaseenter": "Please enter a Password!",
"notmatch": "Passwords do not match!", "notmatch": "Passwords do not match!",
@ -134,11 +135,11 @@
"downloadbackup": "Download Wallet BackUp File", "downloadbackup": "Download Wallet BackUp File",
"passwordhint": "A password must be at least 8 characters.", "passwordhint": "A password must be at least 8 characters.",
"lp1": "Lock Screen", "lp1": "Lock Screen",
"lp2": "No Lock Screen Password Is Set !", "lp2": "No screen lock password is set!",
"lp3": "Please Set One", "lp3": "Please set one",
"lp4": "No Thanks", "lp4": "No Thanks",
"lp5": "Set Password", "lp5": "Set Password",
"lp6": "New screen lock password set successfully !", "lp6": "New screen lock password set successfully!",
"lp7": "UNLOCK", "lp7": "UNLOCK",
"lp8": "Error: Incorrect password", "lp8": "Error: Incorrect password",
"lp9": "IS", "lp9": "IS",
@ -187,7 +188,7 @@
"nodeurl": "Node Url", "nodeurl": "Node Url",
"nodehint": "Select a node from the default list of nodes above or add a custom node to the list above by clicking on the button below", "nodehint": "Select a node from the default list of nodes above or add a custom node to the list above by clicking on the button below",
"addcustomnode": "Add Custom Node", "addcustomnode": "Add Custom Node",
"addandsave": "Add And Save", "addandsave": "Add and Save",
"protocol": "Protocol", "protocol": "Protocol",
"domain": "Domain", "domain": "Domain",
"port": "Port", "port": "Port",
@ -730,7 +731,8 @@
"bchange48": "Do you give this application permission to send you notifications", "bchange48": "Do you give this application permission to send you notifications",
"bchange49": "Do you grant this application permission to access the following private information from your profile?", "bchange49": "Do you grant this application permission to access the following private information from your profile?",
"bchange50": "This app has requested a change to your public profile. Property: ", "bchange50": "This app has requested a change to your public profile. Property: ",
"bchange51": "To submit the changes don't forget to click on 'Update profile'" "bchange51": "To submit the changes don't forget to click on 'Update profile'",
"bchange52": "Do you give this application permission to get your wallet information?"
}, },
"datapage": { "datapage": {
"dchange1": "Data Management", "dchange1": "Data Management",
@ -934,7 +936,7 @@
"gchange55": "Search Private Group", "gchange55": "Search Private Group",
"gchange56": "Group Name To Search", "gchange56": "Group Name To Search",
"gchange57": "Private Group Name Not Found", "gchange57": "Private Group Name Not Found",
"gchange58": "Note that group name must exact match.", "gchange58": "Note that group name must be an exact match.",
"gchange59": "Show / Hide Ticker" "gchange59": "Show / Hide Ticker"
}, },
"puzzlepage": { "puzzlepage": {
@ -961,7 +963,7 @@
"nchange2": "Node has been online for:", "nchange2": "Node has been online for:",
"nchange3": "Node's minting accounts", "nchange3": "Node's minting accounts",
"nchange4": "Add minting account", "nchange4": "Add minting account",
"nchange5": "If you would like to mint with your own account you will need to create a rewardshare transaction to yourself (with rewardshare percent set to 0), and then mint with the rewardshare key it gives you.", "nchange5": "If you would like to mint with your own account you will need to create a reward share transaction to yourself (with reward share percent set to 0), and then mint with the reward share key it gives you.",
"nchange6": "Rewardshare key", "nchange6": "Rewardshare key",
"nchange7": "Adding minting account", "nchange7": "Adding minting account",
"nchange8": "Add", "nchange8": "Add",
@ -1023,9 +1025,9 @@
"rewarddialog1": "Would you like to create a reward share transaction, sharing", "rewarddialog1": "Would you like to create a reward share transaction, sharing",
"rewarddialog2": "of your minting rewards with", "rewarddialog2": "of your minting rewards with",
"rewarddialog3": "If yes, you will need to save the key below in order to mint. It can be supplied to any node in order to allow it to mint on your behalf.", "rewarddialog3": "If yes, you will need to save the key below in order to mint. It can be supplied to any node in order to allow it to mint on your behalf.",
"rewarddialog4": "On pressing confirm, the rewardshare will be created, but you will still need to supply the above key to a node in order to mint with the account.", "rewarddialog4": "On pressing confirm, the reward share will be created, but you will still need to supply the above key to a node in order to mint with the account.",
"rewarddialog5": "You are removing a reward share transaction associated with account:", "rewarddialog5": "You are removing a reward share transaction associated with account:",
"rewarddialog6": "On pressing confirm, the rewardshare will be removed and the minting key will become invalid.", "rewarddialog6": "On pressing confirm, the reward share will be removed and the minting key will become invalid.",
"deployAtdialog1": "You are deploying the AT", "deployAtdialog1": "You are deploying the AT",
"deployAtdialog2": "On pressing confirm, the AT will be deployed!", "deployAtdialog2": "On pressing confirm, the AT will be deployed!",
"deployAtdialog3": "Initial amount balance", "deployAtdialog3": "Initial amount balance",
@ -1112,7 +1114,7 @@
"mg25": "Banned Members", "mg25": "Banned Members",
"mg26": "CANCEL BAN", "mg26": "CANCEL BAN",
"mg27": "Ban Expiry", "mg27": "Ban Expiry",
"mg28": "Cancel Ban Member From Group", "mg28": "Cancel Ban for Member From Group",
"mg29": "Are you sure to cancel the ban for this member from the group?", "mg29": "Are you sure to cancel the ban for this member from the group?",
"mg30": "On pressing confirm, the cancel ban request will be sent!", "mg30": "On pressing confirm, the cancel ban request will be sent!",
"mg31": "Kick Member From Group", "mg31": "Kick Member From Group",
@ -1152,7 +1154,7 @@
"inf2": "Close Trade Portal Info", "inf2": "Close Trade Portal Info",
"inf3": "This is a market to BUY QORT with", "inf3": "This is a market to BUY QORT with",
"inf4": "- 'open market sells' are QORT SELL ORDERS.", "inf4": "- 'open market sells' are QORT SELL ORDERS.",
"inf5": "You can only buy ONE order at a time simply click an order that you wish to buy with", "inf5": "You can only buy ONE order at a time. Simply click an order that you wish to buy with",
"inf6": "and it will populate the 'BUY QORT' box with the details, then click BUY.", "inf6": "and it will populate the 'BUY QORT' box with the details, then click BUY.",
"inf7": "Auto Buy Information", "inf7": "Auto Buy Information",
"inf8": "Close Auto Buy Info", "inf8": "Close Auto Buy Info",

View File

@ -5,6 +5,7 @@
"chinese1": "简体中文", "chinese1": "简体中文",
"chinese2": "繁体中文", "chinese2": "繁体中文",
"croatian": "克罗地亚文", "croatian": "克罗地亚文",
"dutch": "荷兰语",
"english": "英文", "english": "英文",
"estonian": "爱沙尼亚文", "estonian": "爱沙尼亚文",
"french": "法文", "french": "法文",
@ -727,7 +728,8 @@
"bchange45": "加密", "bchange45": "加密",
"bchange46": "您是否授予此应用程序保存以下文件的权限", "bchange46": "您是否授予此应用程序保存以下文件的权限",
"bchange47": "即时发布 - 需要", "bchange47": "即时发布 - 需要",
"bchange48": "您是否授予此应用程序向您发送通知的权限" "bchange48": "您是否授予此应用程序向您发送通知的权限",
"bchange49": "您是否授予此应用程序获取您的钱包信息的权限?"
}, },
"datapage": { "datapage": {
"dchange1": "资料管理", "dchange1": "资料管理",

View File

@ -5,6 +5,7 @@
"chinese1": "簡體中文", "chinese1": "簡體中文",
"chinese2": "繁體中文", "chinese2": "繁體中文",
"croatian": "克羅地亞文", "croatian": "克羅地亞文",
"dutch": "荷蘭語",
"english": "英文", "english": "英文",
"estonian": "愛沙尼亞文", "estonian": "愛沙尼亞文",
"french": "法文", "french": "法文",
@ -727,7 +728,8 @@
"bchange45": "加密", "bchange45": "加密",
"bchange46": "您是否授予此應用程序保存以下文件的權限", "bchange46": "您是否授予此應用程序保存以下文件的權限",
"bchange47": "即時發布 - 需要", "bchange47": "即時發布 - 需要",
"bchange48": "您是否授予此應用程式向您發送通知的權限" "bchange48": "您是否授予此應用程式向您發送通知的權限",
"bchange49": "您是否授予此應用程式以取得您的錢包資訊的權限?"
}, },
"datapage": { "datapage": {
"dchange1": "資料管理", "dchange1": "資料管理",

View File

@ -1,10 +1,10 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../store.js' import {store} from '../store.js'
import { doPageUrl } from '../redux/app/app-actions.js' import {doPageUrl} from '../redux/app/app-actions.js'
import { translate, translateUnsafeHTML } from 'lit-translate' import {translate} from 'lit-translate'
import WebWorker from 'web-worker:./computePowWorker.js'; import WebWorker from 'web-worker:./computePowWorker.js';
import { routes } from '../plugins/routes.js'; import {routes} from '../plugins/routes.js';
import '@material/mwc-icon' import '@material/mwc-icon'
import '@material/mwc-button' import '@material/mwc-button'
@ -124,7 +124,7 @@ class AppInfo extends connect(store)(LitElement) {
// } catch (error) { // } catch (error) {
// console.error(error) // console.error(error)
// } // }
setInterval(() => { setInterval(() => {
this.getNodeInfo() this.getNodeInfo()
this.getCoreInfo() this.getCoreInfo()
@ -198,13 +198,13 @@ class AppInfo extends connect(store)(LitElement) {
lastReference: reference, lastReference: reference,
proofOfWorkNonce: 0, proofOfWorkNonce: 0,
fee: 0, fee: 0,
timestamp: Date.now(), timestamp: Date.now(),
}, },
disableModal: true disableModal: true
}, },
disableModal: true, disableModal: true,
}); });
try { try {
const powRes = await _computePow2(chatRes) const powRes = await _computePow2(chatRes)
if(powRes === true) { if(powRes === true) {
@ -216,7 +216,7 @@ class AppInfo extends connect(store)(LitElement) {
console.error(error) console.error(error)
} }
} }
if (!data.error && data !== 'false' && data) { if (!data.error && data !== 'false' && data) {
clearInterval(this.interval) clearInterval(this.interval)
localStorage.removeItem(this.publicizeAddress) localStorage.removeItem(this.publicizeAddress)

View File

@ -1,18 +1,13 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../store.js' import {store} from '../store.js'
import { Epml } from '../epml.js' import {Epml} from '../epml.js'
import { addTradeBotRoutes } from '../tradebot/addTradeBotRoutes.js' import {addTradeBotRoutes} from '../tradebot/addTradeBotRoutes.js'
import { get, translate, translateUnsafeHTML } from 'lit-translate' import {get, translate} from 'lit-translate'
import localForage from 'localforage' import localForage from 'localforage'
import { encryptData, decryptData } from '../lockScreen.js' import {decryptData, encryptData} from '../lockScreen.js'
import { setChatLastSeen } from '../redux/app/app-actions.js' import {setChatLastSeen} from '../redux/app/app-actions.js'
import isElectron from 'is-electron' import isElectron from 'is-electron'
const chatLastSeen = localForage.createInstance({
name: "chat-last-seen",
})
import '@material/mwc-button' import '@material/mwc-button'
import '@material/mwc-icon' import '@material/mwc-icon'
import '@polymer/paper-icon-button/paper-icon-button.js' import '@polymer/paper-icon-button/paper-icon-button.js'
@ -47,6 +42,12 @@ import './friends-view/friends-side-panel-parent.js'
import './friends-view/save-settings-qdn.js' import './friends-view/save-settings-qdn.js'
import './friends-view/core-sync-status.js' import './friends-view/core-sync-status.js'
import './friends-view/profile.js' import './friends-view/profile.js'
import './controllers/coin-balances-controller.js'
const chatLastSeen = localForage.createInstance({
name: "chat-last-seen",
})
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
class AppView extends connect(store)(LitElement) { class AppView extends connect(store)(LitElement) {
@ -57,7 +58,6 @@ class AppView extends connect(store)(LitElement) {
nodeType: { type: String, reflect: true }, nodeType: { type: String, reflect: true },
theme: { type: String, reflect: true }, theme: { type: String, reflect: true },
addressInfo: { type: Object }, addressInfo: { type: Object },
getAllBalancesLoading: { type: Boolean },
botQortWallet: { type: String }, botQortWallet: { type: String },
botBtcWallet: { type: String }, botBtcWallet: { type: String },
botLtcWallet: { type: String }, botLtcWallet: { type: String },
@ -231,13 +231,13 @@ class AppView extends connect(store)(LitElement) {
background-color: whitesmoke; background-color: whitesmoke;
border-radius: 7px; border-radius: 7px;
} }
.sideBarMenu::-webkit-scrollbar { .sideBarMenu::-webkit-scrollbar {
width: 6px; width: 6px;
border-radius: 7px; border-radius: 7px;
background-color: whitesmoke; background-color: whitesmoke;
} }
.sideBarMenu::-webkit-scrollbar-thumb { .sideBarMenu::-webkit-scrollbar-thumb {
background-color: rgb(180, 176, 176); background-color: rgb(180, 176, 176);
border-radius: 7px; border-radius: 7px;
@ -364,7 +364,7 @@ class AppView extends connect(store)(LitElement) {
0%,100% { opacity: 0; } 0%,100% { opacity: 0; }
50% { opacity: 10; } 50% { opacity: 10; }
} }
.sideBarMenu::-webkit-scrollbar-thumb:hover { .sideBarMenu::-webkit-scrollbar-thumb:hover {
background-color: rgb(148, 146, 146); background-color: rgb(148, 146, 146);
cursor: pointer; cursor: pointer;
@ -447,7 +447,6 @@ class AppView extends connect(store)(LitElement) {
this.urls = [] this.urls = []
this.nodeType = '' this.nodeType = ''
this.addressInfo = {} this.addressInfo = {}
this.getAllBalancesLoading = false
this.botQortWallet = '' this.botQortWallet = ''
this.botBtcWallet = '' this.botBtcWallet = ''
this.botLtcWallet = '' this.botLtcWallet = ''
@ -553,24 +552,6 @@ class AppView extends connect(store)(LitElement) {
</side-menu> </side-menu>
</div> </div>
</div> </div>
<button class="balanceButton" @click="${() => this.shBalanceTicker()}">${translate("grouppage.gchange59")}</button>
<div id="theTicker" style="display: none; margin-bottom: 20px;">
<div id="balanceheader">
<span class="balanceheadertext">
${this.getAllBalancesLoading ? html`
${translate("general.update")}
` : html`
${translate("general.balances")}
<vaadin-button theme="icon" id="reload" @click="${() => this.getAllBalances()}">
<vaadin-icon icon="vaadin:refresh"></vaadin-icon>
</vaadin-button>
<vaadin-tooltip text="${translate("general.update")}" for="reload" position="top"></vaadin-tooltip>
`}
</span>
</div>
${this.getAllBalancesLoading ? html`<paper-progress indeterminate style="width: 100%; margin: 4px;"></paper-progress>` : ''}
${this.balanceTicker}
</div>
<app-info></app-info> <app-info></app-info>
</div> </div>
</app-header-layout> </app-header-layout>
@ -599,6 +580,8 @@ class AppView extends connect(store)(LitElement) {
<div>&nbsp;&nbsp;</div> <div>&nbsp;&nbsp;</div>
<language-selector></language-selector> <language-selector></language-selector>
<div>&nbsp;&nbsp;&nbsp;&nbsp;</div> <div>&nbsp;&nbsp;&nbsp;&nbsp;</div>
<core-sync-status></core-sync-status>
<div>&nbsp;&nbsp;</div>
<theme-toggle></theme-toggle> <theme-toggle></theme-toggle>
<div>&nbsp;&nbsp;</div> <div>&nbsp;&nbsp;</div>
${this.renderLockButton()} ${this.renderLockButton()}
@ -677,7 +660,7 @@ class AppView extends connect(store)(LitElement) {
</div> </div>
</paper-dialog> </paper-dialog>
<div id="portal-target"></div> <div id="portal-target"></div>
<coin-balances-controller></coin-balances-controller>
` `
} }
@ -753,8 +736,6 @@ class AppView extends connect(store)(LitElement) {
this.botRvnWallet = store.getState().app.selectedAddress.rvnWallet.address this.botRvnWallet = store.getState().app.selectedAddress.rvnWallet.address
this.botArrrWallet = store.getState().app.selectedAddress.arrrWallet.address this.botArrrWallet = store.getState().app.selectedAddress.arrrWallet.address
await this.getAllBalances()
await this.botBtcTradebook() await this.botBtcTradebook()
await this.botLtcTradebook() await this.botLtcTradebook()
await this.botDogeTradebook() await this.botDogeTradebook()
@ -771,8 +752,6 @@ class AppView extends connect(store)(LitElement) {
this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]")
}) })
this.renderBalances()
const getOpenTradesBTC = async () => { const getOpenTradesBTC = async () => {
let timerBTC let timerBTC
@ -1803,15 +1782,6 @@ class AppView extends connect(store)(LitElement) {
}, 60000) }, 60000)
} }
shBalanceTicker() {
const targetDiv = this.shadowRoot.getElementById("theTicker")
if (targetDiv.style.display !== "none") {
targetDiv.style.display = "none"
} else {
targetDiv.style.display = "inline"
}
}
clearTheCache() { clearTheCache() {
if (!isElectron()) { if (!isElectron()) {
} else { } else {
@ -1869,7 +1839,7 @@ class AppView extends connect(store)(LitElement) {
<side-menu-item id="qbminter" label="${translate('sidemenu.becomeAMinter')}" href="/app/become-minter" ?hide=${isMinter}> <side-menu-item id="qbminter" label="${translate('sidemenu.becomeAMinter')}" href="/app/become-minter" ?hide=${isMinter}>
<vaadin-icon icon="vaadin:thumbs-up" slot="icon"></vaadin-icon> <vaadin-icon icon="vaadin:thumbs-up" slot="icon"></vaadin-icon>
</side-menu-item> </side-menu-item>
<side-menu-item id="qiminter" label="${translate('mintingpage.mchange35')}" href="/app/sponsorship-list" ?hide=${!isSponsor}> <side-menu-item id="qiminter" label="${translate('mintingpage.mchange35')}" href="/app/sponsorship-list" ?hide=${!isSponsor}>
<vaadin-icon icon="vaadin:list-ol" slot="icon"></vaadin-icon> <vaadin-icon icon="vaadin:list-ol" slot="icon"></vaadin-icon>
</side-menu-item> </side-menu-item>
@ -2094,55 +2064,6 @@ class AppView extends connect(store)(LitElement) {
} }
} }
async getAllBalances() {
this.getAllBalancesLoading = true
await this.updateQortWalletBalance()
await this.updateBtcWalletBalance()
await this.updateLtcWalletBalance()
await this.updateDogeWalletBalance()
await this.updateDgbWalletBalance()
await this.updateRvnWalletBalance()
await this.fetchArrrWalletAddress()
await this.updateArrrWalletBalance()
this.getAllBalancesLoading = false
}
async renderBalances() {
const tickerTime = ms => new Promise(res => setTimeout(res, ms))
clearTimeout(this.updateBalancesTimeout)
this.balanceTicker = html`
<div id="balances">
<div class="balancelist"></div>
</div>
`
await tickerTime(1000)
this.balanceTicker = html`
<div id="balances">
<div class="balancelist">
<span class="balanceinfo qort">QORT ${translate("general.balance")}: ${this.qortWalletBalance}</span>
<span class="balanceinfo btc">BTC ${translate("general.balance")}: ${this.btcWalletBalance}</span>
<span class="balanceinfo ltc">LTC ${translate("general.balance")}: ${this.ltcWalletBalance}</span>
<span class="balanceinfo doge">DOGE ${translate("general.balance")}: ${this.dogeWalletBalance}</span>
<span class="balanceinfo dgb">DGB ${translate("general.balance")}: ${this.dgbWalletBalance}</span>
<span class="balanceinfo rvn">RVN ${translate("general.balance")}: ${this.rvnWalletBalance}</span>
<span class="balanceinfo arrr">ARRR ${translate("general.balance")}: ${this.arrrWalletBalance}</span>
</div>
</div>
`
this.updateBalancesTimeout = setTimeout(() => this.renderBalances(), 45000)
}
async fetchArrrWalletAddress() {
let res = await parentEpml.request('apiCall', {
url: `/crosschain/arrr/walletaddress?apiKey=${this.getApiKey()}`,
method: 'POST',
body: `${store.getState().app.selectedAddress.arrrWallet.seed58}`,
})
if (res != null && res.error != 1201) {
this.arrrWalletAddress = res
}
}
async updateQortWalletBalance() { async updateQortWalletBalance() {
let qortAddress = store.getState().app.selectedAddress.address let qortAddress = store.getState().app.selectedAddress.address

View File

@ -1,6 +1,6 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../store.js' import {store} from '../store.js'
class MyElement extends connect(store)(LitElement) { class MyElement extends connect(store)(LitElement) {
static get properties () { static get properties () {

View File

@ -1,5 +1,5 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { get, translate, translateUnsafeHTML } from 'lit-translate' import {translate} from 'lit-translate'
import isElectron from 'is-electron' import isElectron from 'is-electron'
import '@polymer/paper-icon-button/paper-icon-button.js' import '@polymer/paper-icon-button/paper-icon-button.js'

View File

@ -1,4 +1,4 @@
import { Sha256 } from 'asmcrypto.js' import {Sha256} from 'asmcrypto.js'
function sbrk(size, heap){ function sbrk(size, heap){
@ -39,7 +39,7 @@ const computePow = async (chatBytes, path, difficulty) => {
const hashAry = new Uint8Array(memory.buffer, hashPtr, 32); const hashAry = new Uint8Array(memory.buffer, hashPtr, 32);
hashAry.set(chatBytesHash); hashAry.set(chatBytesHash);
const workBufferLength = 8 * 1024 * 1024; const workBufferLength = 8 * 1024 * 1024;
const workBufferPtr = sbrk(workBufferLength, heap); const workBufferPtr = sbrk(workBufferLength, heap);
@ -72,11 +72,11 @@ loadWebAssembly(path)
} }
resolve() resolve()
}); });
}) })
return response return response
} }

View File

@ -0,0 +1,325 @@
import {html, LitElement} from 'lit';
import '@material/mwc-icon';
import {store} from '../../store';
import {connect} from 'pwa-helpers';
import '@vaadin/tooltip';
import {parentEpml} from '../show-plugin';
import {setCoinBalances} from '../../redux/app/app-actions';
class CoinBalancesController extends connect(store)(LitElement) {
static get properties() {
return {
coinList: { type: Object },
};
}
constructor() {
super();
this.coinList = {}
this.nodeUrl = this.getNodeUrl();
this.myNode = this.getMyNode();
this.fetchBalance = this.fetchBalance.bind(this)
this._updateCoinList = this._updateCoinList.bind(this)
this.stop = false
}
getNodeUrl() {
const myNode =
store.getState().app.nodeConfig.knownNodes[
store.getState().app.nodeConfig.node
];
const nodeUrl =
myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
return nodeUrl;
}
getMyNode() {
const myNode =
store.getState().app.nodeConfig.knownNodes[
store.getState().app.nodeConfig.node
];
return myNode;
}
async updateArrrWalletBalance() {
let _url = `/crosschain/arrr/walletbalance?apiKey=${this.myNode.apiKey}`
let _body = store.getState().app.selectedAddress.arrrWallet.seed58
await parentEpml.request('apiCall', {
url: _url,
method: 'POST',
body: _body,
}).then((res) => {
if (isNaN(Number(res))) {
//...
} else {
this.arrrWalletBalance = (Number(res) / 1e8).toFixed(8)
store.dispatch(
setCoinBalances({
type: 'arrr',
fullValue: Number(res)
})
);
}
}).catch(()=> {
console.log('error')
})
}
async updateQortWalletBalance() {
let qortAddress = store.getState().app.selectedAddress.address
await parentEpml.request('apiCall', {
url: `/addresses/balance/${qortAddress}?apiKey=${this.myNode.apiKey}`,
}).then((res) => {
this.qortWalletBalance = res
store.dispatch(
setCoinBalances({
type: 'qort',
fullValue: Number(res)
})
);
}).catch(()=> {
console.log('error')
})
}
async updateRvnWalletBalance() {
let _url = `/crosschain/rvn/walletbalance?apiKey=${this.myNode.apiKey}`
let _body = store.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey
await parentEpml.request('apiCall', {
url: _url,
method: 'POST',
body: _body,
}).then((res) => {
if (isNaN(Number(res))) {
//...
} else {
this.rvnWalletBalance = (Number(res) / 1e8).toFixed(8)
store.dispatch(
setCoinBalances({
type: 'rvn',
fullValue: Number(res)
})
);
}
}).catch(()=> {
console.log('error')
})
}
async updateDgbWalletBalance() {
let _url = `/crosschain/dgb/walletbalance?apiKey=${this.myNode.apiKey}`
let _body = store.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey
await parentEpml.request('apiCall', {
url: _url,
method: 'POST',
body: _body,
}).then((res) => {
if (isNaN(Number(res))) {
//...
} else {
this.dgbWalletBalance = (Number(res) / 1e8).toFixed(8)
store.dispatch(
setCoinBalances({
type: 'dgb',
fullValue: Number(res)
})
);
}
}).catch(()=> {
console.log('error')
})
}
async updateDogeWalletBalance() {
let _url = `/crosschain/doge/walletbalance?apiKey=${this.myNode.apiKey}`
let _body = store.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey
await parentEpml.request('apiCall', {
url: _url,
method: 'POST',
body: _body,
}).then((res) => {
if (isNaN(Number(res))) {
//...
} else {
this.dogeWalletBalance = (Number(res) / 1e8).toFixed(8)
store.dispatch(
setCoinBalances({
type: 'doge',
fullValue: Number(res)
})
);
}
}).catch(()=> {
console.log('error')
})
}
async updateBtcWalletBalance() {
let _url = `/crosschain/btc/walletbalance?apiKey=${this.myNode.apiKey}`
let _body = store.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey
await parentEpml.request('apiCall', {
url: _url,
method: 'POST',
body: _body,
}).then((res) => {
if (isNaN(Number(res))) {
//...
} else {
this.btcWalletBalance = (Number(res) / 1e8).toFixed(8)
store.dispatch(
setCoinBalances({
type: 'btc',
fullValue: Number(res)
})
);
}
}).catch(()=> {
console.log('error')
})
}
async updateLtcWalletBalance() {
let _url = `/crosschain/ltc/walletbalance?apiKey=${this.myNode.apiKey}`
let _body = store.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey
await parentEpml.request('apiCall', {
url: _url,
method: 'POST',
body: _body,
}).then((res) => {
if (isNaN(Number(res))) {
//...
} else {
this.ltcWalletBalance = (Number(res) / 1e8).toFixed(8)
store.dispatch(
setCoinBalances({
type: 'ltc',
fullValue: Number(res)
})
);
}
}).catch(()=> {
console.log('error')
})
}
_updateCoinList(event) {
const copyCoinList = {...this.coinList}
const coin = event.detail
if(!copyCoinList[coin]){
try {
if(coin === 'ltc'){
this.updateLtcWalletBalance()
} else if(coin === 'qort'){
this.updateQortWalletBalance()
} else if(coin === 'doge'){
this.updateDogeWalletBalance()
} else if(coin === 'btc'){
this.updateBtcWalletBalance()
} else if(coin === 'dgb'){
this.updateDgbWalletBalance()
} else if(coin === 'rvn'){
this.updateRvnWalletBalance()
}else if(coin === 'arrr'){
this.updateArrrWalletBalance()
}
} catch (error) {
}
}
copyCoinList[coin] = Date.now() + 120000;
this.coinList = copyCoinList
this.requestUpdate()
}
async fetchCoins(arrayOfCoins){
const getCoinBalances = (arrayOfCoins || []).map(
async (coin) => {
if(coin === 'ltc'){
await this.updateLtcWalletBalance()
} else if(coin === 'qort'){
await this.updateQortWalletBalance()
} else if(coin === 'doge'){
await this.updateDogeWalletBalance()
} else if(coin === 'btc'){
await this.updateBtcWalletBalance()
} else if(coin === 'dgb'){
await this.updateDgbWalletBalance()
} else if(coin === 'rvn'){
await this.updateRvnWalletBalance()
}else if(coin === 'arrr'){
await this.updateArrrWalletBalance()
}
})
await Promise.all(getCoinBalances);
}
async fetchBalance(){
try {
let arrayOfCoins = []
const copyObject = {...this.coinList}
const currentDate = Date.now()
const array = Object.keys(this.coinList)
for (const key of array) {
const item = this.coinList[key]
if(item < currentDate){
delete copyObject[key]
} else {
arrayOfCoins.push(key)
}
}
if(!this.stop){
this.stop = true
await this.fetchCoins(arrayOfCoins)
this.stop = false
}
this.coinList = copyObject
} catch (error) {
this.stop = false
}
}
connectedCallback() {
super.connectedCallback();
this.intervalID = setInterval(this.fetchBalance, 45000);
window.addEventListener(
'ping-coin-controller-with-coin',
this._updateCoinList
);
}
disconnectedCallback() {
super.disconnectedCallback();
window.removeEventListener(
'ping-coin-controller-with-coin',
this._updateCoinList
);
if(this.intervalID){
clearInterval(this.intervalID);
}
}
render() {
return html``;
}
}
customElements.define('coin-balances-controller', CoinBalancesController);

View File

@ -1,6 +1,5 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { render } from 'lit/html.js' import {get} from 'lit-translate'
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
import '@material/mwc-icon' import '@material/mwc-icon'
import '@vaadin/tooltip'; import '@vaadin/tooltip';
@ -100,7 +99,7 @@ class ChatSideNavHeads extends LitElement {
imageHTMLRes.onload = () => { imageHTMLRes.onload = () => {
this.isImageLoaded = true; this.isImageLoaded = true;
} }
imageHTMLRes.onerror = () => { imageHTMLRes.onerror = () => {
if (this.imageFetches < 4) { if (this.imageFetches < 4) {
setTimeout(() => { setTimeout(() => {
this.imageFetches = this.imageFetches + 1; this.imageFetches = this.imageFetches + 1;
@ -170,13 +169,13 @@ class ChatSideNavHeads extends LitElement {
</span> </span>
</div> </div>
</div> </div>
</div> </div>
<div style="display:flex; align-items: center"> <div style="display:flex; align-items: center">
${this.chatInfo.willFollow ? html` ${this.chatInfo.willFollow ? html`
<mwc-icon id="willFollowIcon" style="color: var(--black)">connect_without_contact</mwc-icon> <mwc-icon id="willFollowIcon" style="color: var(--black)">connect_without_contact</mwc-icon>
<vaadin-tooltip <vaadin-tooltip
for="willFollowIcon" for="willFollowIcon"
position="top" position="top"
hover-delay=${200} hover-delay=${200}
@ -210,10 +209,10 @@ class ChatSideNavHeads extends LitElement {
if(changedProperties.has('isImageLoaded')){ if(changedProperties.has('isImageLoaded')){
return true return true
} }
return false return false
} }
getUrl(chatUrl) { getUrl(chatUrl) {
this.setActiveChatHeadUrl(chatUrl) this.setActiveChatHeadUrl(chatUrl)
} }

View File

@ -1,17 +1,10 @@
import { LitElement, html, css } from 'lit'; import {css, html, LitElement} from 'lit';
import { render } from 'lit/html.js'; import {translate,} from 'lit-translate';
import {
use,
get,
translate,
translateUnsafeHTML,
registerTranslateConfig,
} from 'lit-translate';
import '@material/mwc-button'; import '@material/mwc-button';
import '@material/mwc-dialog'; import '@material/mwc-dialog';
import '@material/mwc-checkbox'; import '@material/mwc-checkbox';
import { connect } from 'pwa-helpers'; import {connect} from 'pwa-helpers';
import { store } from '../../store'; import {store} from '../../store';
import '@polymer/paper-spinner/paper-spinner-lite.js' import '@polymer/paper-spinner/paper-spinner-lite.js'
class AddFriendsModal extends connect(store)(LitElement) { class AddFriendsModal extends connect(store)(LitElement) {
@ -235,7 +228,7 @@ class AddFriendsModal extends connect(store)(LitElement) {
notes: this.notes, notes: this.notes,
willFollow: this.willFollow, willFollow: this.willFollow,
mySelectedFeeds: this.mySelectedFeeds mySelectedFeeds: this.mySelectedFeeds
}); });
this.clearFields(); this.clearFields();
this.onClose(); this.onClose();
@ -303,7 +296,7 @@ class AddFriendsModal extends connect(store)(LitElement) {
render() { render() {
return html` return html`
<div class="modal-overlay ${this.isOpen ? '' : 'hidden'}"> <div class="modal-overlay ${this.isOpen ? '' : 'hidden'}">
<div class="modal-content"> <div class="modal-content">
<div class="inner-content"> <div class="inner-content">
<div style="text-align:center"> <div style="text-align:center">
@ -321,7 +314,7 @@ class AddFriendsModal extends connect(store)(LitElement) {
id="willFollowLabel" id="willFollowLabel"
style="color: var(--black);" style="color: var(--black);"
> >
${get('friends.friend5')} ${translate('friends.friend5')}
</label> </label>
<mwc-checkbox <mwc-checkbox
style="margin-right: -15px;" style="margin-right: -15px;"
@ -339,7 +332,7 @@ class AddFriendsModal extends connect(store)(LitElement) {
id="nameLabel" id="nameLabel"
style="color: var(--black);" style="color: var(--black);"
> >
${get('login.name')} ${translate('login.name')}
</label> </label>
<input <input
id="name" id="name"
@ -357,7 +350,7 @@ class AddFriendsModal extends connect(store)(LitElement) {
id="aliasLabel" id="aliasLabel"
style="color: var(--black);" style="color: var(--black);"
> >
${get('friends.friend6')} ${translate('friends.friend6')}
</label> </label>
<input <input
id="alias" id="alias"

View File

@ -1,5 +1,4 @@
import { Sha256 } from 'asmcrypto.js' import {Sha256} from 'asmcrypto.js'
function sbrk(size, heap){ function sbrk(size, heap){
@ -19,7 +18,7 @@ function sbrk(size, heap){
self.addEventListener('message', async e => { self.addEventListener('message', async e => {
const response = await computePow(e.data.convertedBytes, e.data.path) const response = await computePow(e.data.convertedBytes, e.data.path)
postMessage(response) postMessage(response)
}) })
@ -79,14 +78,14 @@ loadWebAssembly(path)
.then(wasmModule => { .then(wasmModule => {
response = { response = {
nonce : wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), nonce : wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty),
} }
resolve() resolve()
}); });
}) })
return response return response
} }

View File

@ -1,78 +1,160 @@
import { LitElement, html, css } from 'lit'; import {css, html, LitElement} from 'lit'
import '@material/mwc-icon'; import {store} from '../../store'
import { store } from '../../store'; import {connect} from 'pwa-helpers'
import { connect } from 'pwa-helpers'; import {translate} from 'lit-translate'
import '@vaadin/tooltip';
import { get } from 'lit-translate';
class CoreSyncStatus extends connect(store)(LitElement) { class CoreSyncStatus extends connect(store)(LitElement) {
static get properties() { static get properties() {
return { return {
nodeStatus: {type: Object} nodeStatus: {type: Object},
}; coreInfos: { type: Array }
}
} }
constructor() { constructor() {
super(); super()
this.nodeStatus = { this.nodeStatus = {}
isMintingPossible:false, this.coreInfos = []
isSynchronizing:true,
syncPercent:undefined,
numberOfConnections:undefined,
height:undefined,
}
} }
static styles = css` static styles = css`
.header { .lineHeight {
display: flex; line-height: 33%;
align-items: center;
justify-content: space-between;
padding: 16px;
border-bottom: 1px solid #e0e0e0;
} }
.content { .tooltip {
padding: 16px; display: inline-block;
position: relative;
text-align: left;
} }
.close {
.tooltip .bottom {
min-width: 200px;
max-width: 250px;
top: 35px;
left: 50%;
transform: translate(-50%, 0);
padding: 10px 10px;
color: var(--black);
background-color: var(--white);
font-weight: normal;
font-size: 13px;
border-radius: 8px;
position: absolute;
z-index: 99999999;
box-sizing: border-box;
box-shadow: 0 1px 8px rgba(0,0,0,0.5);
border: 1px solid var(--black);
visibility: hidden; visibility: hidden;
position: fixed; opacity: 0;
z-index: -100; transition: opacity 0.8s;
right: -1000px;
} }
.parent-side-panel { .tooltip:hover .bottom {
transform: translateX(100%); /* start from outside the right edge */ visibility: visible;
transition: transform 0.3s ease-in-out; opacity: 1;
} }
.parent-side-panel.open {
transform: translateX(0); /* slide in to its original position */
.tooltip .bottom i {
position: absolute;
bottom: 100%;
left: 50%;
margin-left: -12px;
width: 24px;
height: 12px;
overflow: hidden;
} }
`;
stateChanged(state) { .tooltip .bottom i::after {
this.nodeStatus = state.app.nodeStatus content: '';
} position: absolute;
width: 12px;
height: 12px;
left: 50%;
transform: translate(-50%,50%) rotate(45deg);
background-color: var(--white);
border: 1px solid var(--black);
box-shadow: 0 1px 8px rgba(0,0,0,0.5);
}
`
render() { render() {
return html` return html`
<mwc-icon id="icon" style="color: ${this.nodeStatus.syncPercent === 100 ? 'green': 'red'};user-select:none;margin-right:20px" ${this.renderSyncStatusIcon()}
>lightbulb</mwc-icon `
>
<vaadin-tooltip
for="icon"
position="bottom"
hover-delay=${400}
hide-delay=${1}
text=${this.nodeStatus.syncPercent === 100 ? get('notifications.status1'): get('notifications.status2')}>
</vaadin-tooltip>
`;
} }
firstUpdated() {
this.getCoreInfos()
setInterval(() => {
this.getCoreInfos()
}, 60000)
}
async getCoreInfos() {
const corInfo = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
const coreInfoUrl = corInfo.protocol + '://' + corInfo.domain + ':' + corInfo.port
const infoUrl = `${coreInfoUrl}/admin/info`
await fetch(infoUrl).then(response => {
return response.json()
}).then(data => {
this.coreInfos = data
}).catch(err => {
})
}
renderSyncStatusIcon() {
if (this.nodeStatus.isSynchronizing === true) {
return html`
<div class="tooltip" style="display: inline;">
<span><img src="/img/syncing.png" style="height: 24px; width: 24px; padding-top: 4px;"></span>
<div class="bottom">
<h3>${translate("walletprofile.wp3")}</h3>
<h4 class="lineHeight">${translate("appinfo.coreversion")}: <span style="color: #03a9f4">${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}</span></h4>
<h4 class="lineHeight">${translate("appinfo.synchronizing")}... <span style="color: #03a9f4">${this.nodeStatus.syncPercent !== undefined ? this.nodeStatus.syncPercent + '%' : ''}</span></h4>
<h4 class="lineHeight">${translate("appinfo.blockheight")}: <span style="color: #03a9f4">${this.nodeStatus.height ? this.nodeStatus.height : ''}</span></h4>
<h4 class="lineHeight">${translate("appinfo.peers")}: <span style="color: #03a9f4">${this.nodeStatus.numberOfConnections ? this.nodeStatus.numberOfConnections : ''}</span></h4>
<i></i>
</div>
</div>
`
} else if (this.nodeStatus.isSynchronizing === false && this.nodeStatus.isMintingPossible === false) {
return html`
<div class="tooltip" style="display: inline;">
<span><img src="/img/synced.png" style="height: 24px; width: 24px; padding-top: 4px;"></span>
<div class="bottom">
<h3>${translate("walletprofile.wp3")}</h3>
<h4 class="lineHeight">${translate("appinfo.coreversion")}: <span style="color: #03a9f4">${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}</span></h4>
<h4 class="lineHeight">${translate("walletprofile.wp4")} ${translate("walletprofile.wp2")}</h4>
<h4 class="lineHeight">${translate("appinfo.blockheight")}: <span style="color: #03a9f4">${this.nodeStatus.height ? this.nodeStatus.height : ''}</span></h4>
<h4 class="lineHeight">${translate("appinfo.peers")}: <span style="color: #03a9f4">${this.nodeStatus.numberOfConnections ? this.nodeStatus.numberOfConnections : ''}</span></h4>
<i></i>
</div>
</div>
`
} else if (this.nodeStatus.isSynchronizing === false && this.nodeStatus.isMintingPossible === true) {
return html`
<div class="tooltip" style="display: inline;">
<span><img src="/img/synced_minting.png" style="height: 24px; width: 24px; padding-top: 4px;"></span>
<div class="bottom">
<h3>${translate("walletprofile.wp3")}</h3>
<h4 class="lineHeight">${translate("appinfo.coreversion")}: <span style="color: #03a9f4">${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}</span></h4>
<h4 class="lineHeight">${translate("walletprofile.wp4")} <span style="color: #03a9f4">( ${translate("walletprofile.wp1")} )</span></h4>
<h4 class="lineHeight">${translate("appinfo.blockheight")}: <span style="color: #03a9f4">${this.nodeStatus.height ? this.nodeStatus.height : ''}</span></h4>
<h4 class="lineHeight">${translate("appinfo.peers")}: <span style="color: #03a9f4">${this.nodeStatus.numberOfConnections ? this.nodeStatus.numberOfConnections : ''}</span></h4>
<i></i>
</div>
</div>
`
}
}
stateChanged(state) {
this.nodeStatus = state.app.nodeStatus
}
} }
customElements.define('core-sync-status', CoreSyncStatus); customElements.define('core-sync-status', CoreSyncStatus)

View File

@ -1,16 +1,13 @@
import { LitElement, html, css } from 'lit'; import {css, html, LitElement} from 'lit';
import { import {translate,} from 'lit-translate';
get,
translate,
} from 'lit-translate';
import axios from 'axios' import axios from 'axios'
import '@material/mwc-menu'; import '@material/mwc-menu';
import '@material/mwc-list/mwc-list-item.js' import '@material/mwc-list/mwc-list-item.js'
import { RequestQueueWithPromise } from '../../../../plugins/plugins/utils/queue'; import {RequestQueueWithPromise} from '../../../../plugins/plugins/utils/queue';
import '../../../../plugins/plugins/core/components/TimeAgo' import '../../../../plugins/plugins/core/components/TimeAgo'
import { connect } from 'pwa-helpers'; import {connect} from 'pwa-helpers';
import { store } from '../../store'; import {store} from '../../store';
import { setNewTab } from '../../redux/app/app-actions'; import {setNewTab} from '../../redux/app/app-actions';
import ShortUniqueId from 'short-unique-id'; import ShortUniqueId from 'short-unique-id';
const requestQueue = new RequestQueueWithPromise(3); const requestQueue = new RequestQueueWithPromise(3);
@ -41,9 +38,9 @@ export class FeedItem extends connect(store)(LitElement) {
box-sizing: border-box; box-sizing: border-box;
} }
img { img {
width:100%; width:100%;
max-height:30vh; max-height:30vh;
border-radius: 5px; border-radius: 5px;
cursor: pointer; cursor: pointer;
position: relative; position: relative;
} }
@ -67,7 +64,7 @@ export class FeedItem extends connect(store)(LitElement) {
} }
.defaultSize { .defaultSize {
width: 100%; width: 100%;
height: 160px; height: 160px;
} }
.parent-feed-item { .parent-feed-item {
@ -87,7 +84,7 @@ export class FeedItem extends connect(store)(LitElement) {
font-size: 16px; font-size: 16px;
} }
.avatar { .avatar {
width: 36px; width: 36px;
height: 36px; height: 36px;
border-radius:50%; border-radius:50%;
overflow: hidden; overflow: hidden;
@ -95,7 +92,7 @@ export class FeedItem extends connect(store)(LitElement) {
align-items:center; align-items:center;
} }
.avatarApp { .avatarApp {
width: 30px; width: 30px;
height: 30px; height: 30px;
border-radius:50%; border-radius:50%;
overflow: hidden; overflow: hidden;
@ -210,7 +207,7 @@ getMyNode(){
async fetchVideoUrl() { async fetchVideoUrl() {
this.fetchResource() this.fetchResource()
} }
async getRawData(){ async getRawData(){
@ -228,7 +225,7 @@ getMyNode(){
// const responseData2 = await response2.json() // const responseData2 = await response2.json()
// return responseData2 // return responseData2
} }
updateDisplayWithPlaceholders(display, resource, rawdata) { updateDisplayWithPlaceholders(display, resource, rawdata) {
const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g; const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g;
@ -241,7 +238,7 @@ getMyNode(){
if (rawdata[dataKey] === undefined) { if (rawdata[dataKey] === undefined) {
console.error("rawdata key not found:", dataKey); console.error("rawdata key not found:", dataKey);
} }
return rawdata[dataKey] || match; return rawdata[dataKey] || match;
} else if (p1.startsWith('resource.')) { } else if (p1.startsWith('resource.')) {
const resourceKey = p1.split('.')[1]; const resourceKey = p1.split('.')[1];
if (resource[resourceKey] === undefined) { if (resource[resourceKey] === undefined) {
@ -263,7 +260,7 @@ getMyNode(){
let timer = 24 let timer = 24
const response = await requestQueueStatus.enqueue(()=> { const response = await requestQueueStatus.enqueue(()=> {
return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`) return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`)
}) })
if(response && response.data && response.data.status === 'READY'){ if(response && response.data && response.data.status === 'READY'){
const rawData = await this.getRawData() const rawData = await this.getRawData()
const object = { const object = {
@ -272,13 +269,13 @@ getMyNode(){
this.updateDisplayWithPlaceholders(object, {},rawData.data) this.updateDisplayWithPlaceholders(object, {},rawData.data)
this.feedItem = object this.feedItem = object
this.status = response.data this.status = response.data
return return
} }
const intervalId = setInterval(async () => { const intervalId = setInterval(async () => {
if (isCalling) return if (isCalling) return
isCalling = true isCalling = true
const data = await requestQueue.enqueue(() => { const data = await requestQueue.enqueue(() => {
return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`) return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`)
}); });
@ -302,7 +299,7 @@ getMyNode(){
...res, ...res,
status: 'REFETCHING' status: 'REFETCHING'
} }
setTimeout(() => { setTimeout(() => {
isCalling = false isCalling = false
this.fetchResource() this.fetchResource()
@ -311,7 +308,7 @@ getMyNode(){
} }
percentLoaded = res.percentLoaded percentLoaded = res.percentLoaded
} }
this.status = res this.status = res
if(this.status.status === 'DOWNLOADED'){ if(this.status.status === 'DOWNLOADED'){
this.fetchResource() this.fetchResource()
@ -345,7 +342,7 @@ getMyNode(){
} }
async goToFeedLink(){ async goToFeedLink(){
try { try {
@ -386,7 +383,7 @@ getMyNode(){
console.log({error}) console.log({error})
} }
} }
async extractComponents(url) { async extractComponents(url) {
@ -434,11 +431,11 @@ getMyNode(){
} }
render() { render() {
let avatarImg let avatarImg
@ -469,7 +466,7 @@ getMyNode(){
style=" box-sizing: border-box;" style=" box-sizing: border-box;"
> >
${ ${
this.status.status !== 'READY' this.status.status !== 'READY'
? html` ? html`
<div <div
style="display:flex;flex-direction:column;width:100%;height:100%;justify-content:center;align-items:center; box-sizing: border-box;" style="display:flex;flex-direction:column;width:100%;height:100%;justify-content:center;align-items:center; box-sizing: border-box;"
@ -506,10 +503,10 @@ getMyNode(){
` : ''} ` : ''}
</div> </div>
` `
} }
} }

View File

@ -1,11 +1,11 @@
// popover-component.js // popover-component.js
import { LitElement, html, css } from 'lit'; import {css, html, LitElement} from 'lit';
import { createPopper } from '@popperjs/core'; import {createPopper} from '@popperjs/core';
import '@material/mwc-icon'; import '@material/mwc-icon';
import { use, get, translate } from 'lit-translate'; import {translate} from 'lit-translate';
import { store } from '../../store'; import {store} from '../../store';
import { connect } from 'pwa-helpers'; import {connect} from 'pwa-helpers';
import { setNewTab, setSideEffectAction } from '../../redux/app/app-actions'; import {setNewTab, setSideEffectAction} from '../../redux/app/app-actions';
import ShortUniqueId from 'short-unique-id'; import ShortUniqueId from 'short-unique-id';
export class FriendItemActions extends connect(store)(LitElement) { export class FriendItemActions extends connect(store)(LitElement) {

View File

@ -1,11 +1,11 @@
import { LitElement, html, css } from 'lit'; import {html, LitElement} from 'lit';
import '@material/mwc-icon'; import '@material/mwc-icon';
import './friends-view' import './friends-view'
import { friendsViewStyles } from './friends-view-css'; import {friendsViewStyles} from './friends-view-css';
import { connect } from 'pwa-helpers'; import {connect} from 'pwa-helpers';
import { store } from '../../store'; import {store} from '../../store';
import './feed-item' import './feed-item'
import { translate } from 'lit-translate'; import {translate} from 'lit-translate';
import '@polymer/paper-spinner/paper-spinner-lite.js' import '@polymer/paper-spinner/paper-spinner-lite.js'
@ -31,7 +31,7 @@ class FriendsFeed extends connect(store)(LitElement) {
this.myNode = this.getMyNode(); this.myNode = this.getMyNode();
this.endpoints = [] this.endpoints = []
this.endpointOffsets = [] // Initialize offsets for each endpoint to 0 this.endpointOffsets = [] // Initialize offsets for each endpoint to 0
this.loadAndMergeData = this.loadAndMergeData.bind(this) this.loadAndMergeData = this.loadAndMergeData.bind(this)
this.hasInitialFetch = false this.hasInitialFetch = false
this.observerHandler = this.observerHandler.bind(this); this.observerHandler = this.observerHandler.bind(this);
@ -42,12 +42,12 @@ class FriendsFeed extends connect(store)(LitElement) {
this._updateFeeds = this._updateFeeds.bind(this) this._updateFeeds = this._updateFeeds.bind(this)
} }
static get styles() { static get styles() {
return [friendsViewStyles]; return [friendsViewStyles];
} }
getNodeUrl() { getNodeUrl() {
const myNode = const myNode =
@ -109,7 +109,7 @@ class FriendsFeed extends connect(store)(LitElement) {
let interval = null; let interval = null;
let stop = false; let stop = false;
const getAnswer = async () => { const getAnswer = async () => {
if (!stop) { if (!stop) {
stop = true; stop = true;
try { try {
@ -119,19 +119,19 @@ class FriendsFeed extends connect(store)(LitElement) {
} }
}; };
interval = setInterval(getAnswer, 900000); interval = setInterval(getAnswer, 900000);
} }
async getEndpoints(){ async getEndpoints(){
const dynamicVars = { const dynamicVars = {
} }
const schemas = await this.getSchemas() const schemas = await this.getSchemas()
const friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]") const friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]")
const names = friendList.map(friend => `name=${friend.name}`).join('&'); const names = friendList.map(friend => `name=${friend.name}`).join('&');
if(names.length === 0){ if(names.length === 0){
this.endpoints= [] this.endpoints= []
this.endpointOffsets = Array(this.endpoints.length).fill(0); this.endpointOffsets = Array(this.endpoints.length).fill(0);
return return
} }
const baseurl = `${this.nodeUrl}/arbitrary/resources/search?reverse=true&exactmatchnames=true&${names}` const baseurl = `${this.nodeUrl}/arbitrary/resources/search?reverse=true&exactmatchnames=true&${names}`
@ -147,11 +147,11 @@ class FriendsFeed extends connect(store)(LitElement) {
}) })
} }
} }
}) })
this.endpoints= formEndpoints this.endpoints= formEndpoints
this.endpointOffsets = Array(this.endpoints.length).fill(0); this.endpointOffsets = Array(this.endpoints.length).fill(0);
} }
async firstUpdated(){ async firstUpdated(){
@ -159,8 +159,8 @@ class FriendsFeed extends connect(store)(LitElement) {
this.downObserverElement = this.downObserverElement =
this.shadowRoot.getElementById('downObserver'); this.shadowRoot.getElementById('downObserver');
this.elementObserver(); this.elementObserver();
try { try {
await new Promise((res)=> { await new Promise((res)=> {
setTimeout(() => { setTimeout(() => {
@ -172,7 +172,7 @@ class FriendsFeed extends connect(store)(LitElement) {
this.loadAndMergeData(); this.loadAndMergeData();
} }
this.getFeedOnInterval() this.getFeedOnInterval()
} catch (error) { } catch (error) {
@ -192,7 +192,7 @@ this.getFeedOnInterval()
await this.getEndpoints() await this.getEndpoints()
this.reFetchFeedData() this.reFetchFeedData()
} catch (error) { } catch (error) {
} }
} }
@ -236,17 +236,17 @@ this.getFeedOnInterval()
...i ...i
} }
}) })
} }
async initialLoad() { async initialLoad() {
let results = []; let results = [];
let totalFetched = 0; let totalFetched = 0;
let i = 0; let i = 0;
let madeProgress = true; let madeProgress = true;
let exhaustedEndpoints = new Set(); let exhaustedEndpoints = new Set();
while (totalFetched < totalDesiredCount && madeProgress) { while (totalFetched < totalDesiredCount && madeProgress) {
madeProgress = false; madeProgress = false;
this.isLoading = true this.isLoading = true
@ -254,32 +254,32 @@ this.getFeedOnInterval()
if (exhaustedEndpoints.has(i)) { if (exhaustedEndpoints.has(i)) {
continue; continue;
} }
const remainingCount = totalDesiredCount - totalFetched; const remainingCount = totalDesiredCount - totalFetched;
// If we've already reached the desired count, break // If we've already reached the desired count, break
if (remainingCount <= 0) { if (remainingCount <= 0) {
break; break;
} }
let fetchCount = Math.min(perEndpointCount, remainingCount); let fetchCount = Math.min(perEndpointCount, remainingCount);
let data = await this.fetchDataFromEndpoint(i, fetchCount); let data = await this.fetchDataFromEndpoint(i, fetchCount);
// Increment the offset for this endpoint by the number of items fetched // Increment the offset for this endpoint by the number of items fetched
this.endpointOffsets[i] += data.length; this.endpointOffsets[i] += data.length;
if (data.length > 0) { if (data.length > 0) {
madeProgress = true; madeProgress = true;
} }
if (data.length < fetchCount) { if (data.length < fetchCount) {
exhaustedEndpoints.add(i); exhaustedEndpoints.add(i);
} }
results = results.concat(data); results = results.concat(data);
totalFetched += data.length; totalFetched += data.length;
} }
if (exhaustedEndpoints.size === this.endpoints.length) { if (exhaustedEndpoints.size === this.endpoints.length) {
break; break;
} }
@ -289,15 +289,15 @@ this.getFeedOnInterval()
// Trim the results if somehow they are over the totalDesiredCount // Trim the results if somehow they are over the totalDesiredCount
return results.slice(0, totalDesiredCount); return results.slice(0, totalDesiredCount);
} }
trimDataToLimit(data, limit) { trimDataToLimit(data, limit) {
return data.slice(0, limit); return data.slice(0, limit);
} }
mergeData(newData, existingData) { mergeData(newData, existingData) {
const existingIds = new Set(existingData.map(item => item.identifier)); // Assume each item has a unique 'id' const existingIds = new Set(existingData.map(item => item.identifier)); // Assume each item has a unique 'id'
const uniqueNewData = newData.filter(item => !existingIds.has(item.identifier)); const uniqueNewData = newData.filter(item => !existingIds.has(item.identifier));
@ -325,37 +325,37 @@ this.getFeedOnInterval()
const resource = newItem const resource = newItem
let clickValue1 = newItem.schema.click; let clickValue1 = newItem.schema.click;
const resolvedClickValue1 = replacePlaceholders(clickValue1, resource, newItem.schema.customParams); const resolvedClickValue1 = replacePlaceholders(clickValue1, resource, newItem.schema.customParams);
newItem.link = resolvedClickValue1 newItem.link = resolvedClickValue1
newData.push(newItem) newData.push(newItem)
} }
} }
return newData return newData
} }
async reFetchFeedData() { async reFetchFeedData() {
// Resetting offsets to start fresh. // Resetting offsets to start fresh.
this.endpointOffsets = Array(this.endpoints.length).fill(0); this.endpointOffsets = Array(this.endpoints.length).fill(0);
await this.getEndpoints() await this.getEndpoints()
const oldIdentifiers = new Set(this.feed.map(item => item.identifier)); const oldIdentifiers = new Set(this.feed.map(item => item.identifier));
const newData = await this.initialLoad(); const newData = await this.initialLoad();
// Filter out items that are already in the feed // Filter out items that are already in the feed
const trulyNewData = newData.filter(item => !oldIdentifiers.has(item.identifier)); const trulyNewData = newData.filter(item => !oldIdentifiers.has(item.identifier));
if (trulyNewData.length > 0) { if (trulyNewData.length > 0) {
// Adding extra data and merging with old data // Adding extra data and merging with old data
const enhancedNewData = await this.addExtraData(trulyNewData); const enhancedNewData = await this.addExtraData(trulyNewData);
// Merge new data with old data immutably // Merge new data with old data immutably
this.feed = [...enhancedNewData, ...this.feed]; this.feed = [...enhancedNewData, ...this.feed];
this.feed.sort((a, b) => new Date(b.created) - new Date(a.created)); // Sort by timestamp, most recent first this.feed.sort((a, b) => new Date(b.created) - new Date(a.created)); // Sort by timestamp, most recent first
this.feed = this.trimDataToLimit(this.feed, maxResultsInMemory); // Trim to the maximum allowed in memory this.feed = this.trimDataToLimit(this.feed, maxResultsInMemory); // Trim to the maximum allowed in memory
this.feedToRender = this.feed.slice(0, 20); this.feedToRender = this.feed.slice(0, 20);
this.hasInitialFetch = true; this.hasInitialFetch = true;
const created = trulyNewData[0].created; const created = trulyNewData[0].created;
let value = localStorage.getItem('lastSeenFeed'); let value = localStorage.getItem('lastSeenFeed');
if (((+value || 0) < created)) { if (((+value || 0) < created)) {
@ -363,9 +363,9 @@ this.getFeedOnInterval()
} }
} }
} }
async loadAndMergeData() { async loadAndMergeData() {
let allData = this.feed let allData = this.feed
const newData = await this.initialLoad(); const newData = await this.initialLoad();
@ -387,7 +387,7 @@ this.getFeedOnInterval()
render() { render() {
return html` return html`
@ -450,7 +450,7 @@ export function constructUrl(base, search, dynamicVars) {
export function replacePlaceholders(template, resource, customParams) { export function replacePlaceholders(template, resource, customParams) {
const dataSource = { resource, customParams }; const dataSource = { resource, customParams };
return template.replace(/\$\$\{(.*?)\}\$\$/g, (match, p1) => { return template.replace(/\$\$\{(.*?)\}\$\$/g, (match, p1) => {
const keys = p1.split('.'); const keys = p1.split('.');
let value = dataSource; let value = dataSource;

View File

@ -1,8 +1,8 @@
import { LitElement, html, css } from 'lit'; import {css, html, LitElement} from 'lit';
import '@material/mwc-icon'; import '@material/mwc-icon';
import './friends-side-panel.js'; import './friends-side-panel.js';
import '@vaadin/tooltip'; import '@vaadin/tooltip';
import { get } from 'lit-translate'; import {translate} from 'lit-translate';
class FriendsSidePanelParent extends LitElement { class FriendsSidePanelParent extends LitElement {
@ -12,7 +12,7 @@ class FriendsSidePanelParent extends LitElement {
hasNewFeed: {type: Boolean} hasNewFeed: {type: Boolean}
}; };
} }
constructor() { constructor() {
super(); super();
@ -68,10 +68,10 @@ class FriendsSidePanelParent extends LitElement {
position="bottom" position="bottom"
hover-delay=${400} hover-delay=${400}
hide-delay=${1} hide-delay=${1}
text=${get('friends.friend12')}> text=${translate('friends.friend12')}>
</vaadin-tooltip> </vaadin-tooltip>
<friends-side-panel .setHasNewFeed=${(val)=> this.setHasNewFeed(val)} ?isOpen=${this.isOpen} .setIsOpen=${(val)=> this.isOpen = val}></friends-side-panel> <friends-side-panel .setHasNewFeed=${(val)=> this.setHasNewFeed(val)} ?isOpen=${this.isOpen} .setIsOpen=${(val)=> this.isOpen = val}></friends-side-panel>
`; `;
} }

View File

@ -1,8 +1,9 @@
import { LitElement, html, css } from 'lit'; import {css, html, LitElement} from 'lit';
import '@material/mwc-icon'; import '@material/mwc-icon';
import './friends-view' import './friends-view'
import './friends-feed' import './friends-feed'
import { translate } from 'lit-translate'; import {translate} from 'lit-translate';
class FriendsSidePanel extends LitElement { class FriendsSidePanel extends LitElement {
static get properties() { static get properties() {
return { return {
@ -19,7 +20,7 @@ class FriendsSidePanel extends LitElement {
this.selected = 'friends' this.selected = 'friends'
this.closeSidePanel = this.closeSidePanel.bind(this) this.closeSidePanel = this.closeSidePanel.bind(this)
} }
static styles = css` static styles = css`
:host { :host {
display: block; display: block;
@ -98,14 +99,14 @@ class FriendsSidePanel extends LitElement {
position: absolute; position: absolute;
z-index: -50; z-index: -50;
} }
`; `;
refreshFeed(){ refreshFeed(){
this.shadowRoot.querySelector('friends-feed').refresh() this.shadowRoot.querySelector('friends-feed').refresh()
} }
closeSidePanel(){ closeSidePanel(){
@ -128,7 +129,7 @@ class FriendsSidePanel extends LitElement {
this.setIsOpen(false) this.setIsOpen(false)
}}>close</mwc-icon> }}>close</mwc-icon>
</div> </div>
</div> </div>
<div class="content"> <div class="content">
<div class="${this.selected === 'friends' ? 'active-content' : 'default-content'}"> <div class="${this.selected === 'friends' ? 'active-content' : 'default-content'}">
@ -137,8 +138,8 @@ class FriendsSidePanel extends LitElement {
<div class="${this.selected === 'feed' ? 'active-content' : 'default-content'}"> <div class="${this.selected === 'feed' ? 'active-content' : 'default-content'}">
<friends-feed .setHasNewFeed=${(val)=> this.setHasNewFeed(val)}></friends-feed> <friends-feed .setHasNewFeed=${(val)=> this.setHasNewFeed(val)}></friends-feed>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,4 +1,4 @@
import { css } from 'lit' import {css} from 'lit'
export const friendsViewStyles = css` export const friendsViewStyles = css`
* { * {
@ -37,9 +37,9 @@ export const friendsViewStyles = css`
.container-body { .container-body {
width: 100%; width: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex-grow: 1; flex-grow: 1;
margin-top: 5px; margin-top: 5px;
padding: 0px 6px; padding: 0px 6px;
box-sizing: border-box; box-sizing: border-box;
@ -51,13 +51,13 @@ export const friendsViewStyles = css`
background-color: whitesmoke; background-color: whitesmoke;
border-radius: 7px; border-radius: 7px;
} }
.container-body::-webkit-scrollbar { .container-body::-webkit-scrollbar {
width: 6px; width: 6px;
border-radius: 7px; border-radius: 7px;
background-color: whitesmoke; background-color: whitesmoke;
} }
.container-body::-webkit-scrollbar-thumb { .container-body::-webkit-scrollbar-thumb {
background-color: rgb(180, 176, 176); background-color: rgb(180, 176, 176);
border-radius: 7px; border-radius: 7px;
@ -67,7 +67,7 @@ export const friendsViewStyles = css`
.container-body::-webkit-scrollbar-thumb:hover { .container-body::-webkit-scrollbar-thumb:hover {
background-color: rgb(148, 146, 146); background-color: rgb(148, 146, 146);
cursor: pointer; cursor: pointer;
} }
p { p {
color: var(--black); color: var(--black);

View File

@ -1,6 +1,5 @@
import { LitElement, html, css } from 'lit'; import {html, LitElement} from 'lit';
import { render } from 'lit/html.js'; import {connect} from 'pwa-helpers';
import { connect } from 'pwa-helpers';
import '@material/mwc-button'; import '@material/mwc-button';
import '@material/mwc-dialog'; import '@material/mwc-dialog';
@ -14,16 +13,10 @@ import './ChatSideNavHeads';
import '../../../../plugins/plugins/core/components/ChatSearchResults' import '../../../../plugins/plugins/core/components/ChatSearchResults'
import './add-friends-modal' import './add-friends-modal'
import { import {translate,} from 'lit-translate';
use, import {store} from '../../store';
get, import {friendsViewStyles} from './friends-view-css';
translate, import {parentEpml} from '../show-plugin';
translateUnsafeHTML,
registerTranslateConfig,
} from 'lit-translate';
import { store } from '../../store';
import { friendsViewStyles } from './friends-view-css';
import { parentEpml } from '../show-plugin';
class FriendsView extends connect(store)(LitElement) { class FriendsView extends connect(store)(LitElement) {
static get properties() { static get properties() {
@ -103,10 +96,10 @@ class FriendsView extends connect(store)(LitElement) {
this.elementObserver(); this.elementObserver();
this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]") this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]")
this.friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]") this.friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]")
} }
_updateFriends(event) { _updateFriends(event) {
@ -114,23 +107,20 @@ class FriendsView extends connect(store)(LitElement) {
this.friendList = detail this.friendList = detail
} }
_updateFeed(event) { _updateFeed(event) {
console.log({event})
const detail = event.detail const detail = event.detail
console.log({detail})
this.mySelectedFeeds = detail this.mySelectedFeeds = detail
this.requestUpdate() this.requestUpdate()
} }
connectedCallback() { connectedCallback() {
super.connectedCallback() super.connectedCallback()
console.log('callback') window.addEventListener('friends-my-friend-list-event', this._updateFriends)
window.addEventListener('friends-my-friend-list-event', this._updateFriends) window.addEventListener('friends-my-selected-feeds-event', this._updateFeed)
window.addEventListener('friends-my-selected-feeds-event', this._updateFeed)
} }
disconnectedCallback() { disconnectedCallback() {
window.removeEventListener('friends-my-friend-list-event', this._updateFriends) window.removeEventListener('friends-my-friend-list-event', this._updateFriends)
window.addEventListener('friends-my-selected-feeds-event', this._updateFeed) window.addEventListener('friends-my-selected-feeds-event', this._updateFeed)
super.disconnectedCallback() super.disconnectedCallback()
} }
@ -172,7 +162,7 @@ class FriendsView extends connect(store)(LitElement) {
} }
try { try {
const url = `${this.nodeUrl}/names/${nameValue}` const url = `${this.nodeUrl}/names/${nameValue}`
const res = await fetch(url) const res = await fetch(url)
const result = await res.json() const result = await res.json()
if (result.error === 401) { if (result.error === 401) {
this.userFound = [] this.userFound = []
@ -182,7 +172,7 @@ class FriendsView extends connect(store)(LitElement) {
]; ];
} }
this.userFoundModalOpen = true; this.userFoundModalOpen = true;
} catch (error) { } catch (error) {
// let err4string = get("chatpage.cchange35"); // let err4string = get("chatpage.cchange35");
// parentEpml.request('showSnackBar', `${err4string}`) // parentEpml.request('showSnackBar', `${err4string}`)
} }
@ -199,7 +189,7 @@ class FriendsView extends connect(store)(LitElement) {
name name
] ]
let namesJsonString = JSON.stringify({ "items": items }) let namesJsonString = JSON.stringify({ "items": items })
let ret = await parentEpml.request('apiCall', { let ret = await parentEpml.request('apiCall', {
url: `/lists/followedNames?apiKey=${this.getApiKey()}`, url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
method: 'POST', method: 'POST',
@ -208,8 +198,8 @@ class FriendsView extends connect(store)(LitElement) {
}, },
body: `${namesJsonString}` body: `${namesJsonString}`
}) })
return ret return ret
} }
@ -218,7 +208,7 @@ class FriendsView extends connect(store)(LitElement) {
name name
] ]
let namesJsonString = JSON.stringify({ "items": items }) let namesJsonString = JSON.stringify({ "items": items })
let ret = await parentEpml.request('apiCall', { let ret = await parentEpml.request('apiCall', {
url: `/lists/followedNames?apiKey=${this.getApiKey()}`, url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
method: 'DELETE', method: 'DELETE',
@ -227,8 +217,8 @@ class FriendsView extends connect(store)(LitElement) {
}, },
body: `${namesJsonString}` body: `${namesJsonString}`
}) })
return ret return ret
} }
async addToFriendList(val, isRemove){ async addToFriendList(val, isRemove){
@ -242,9 +232,9 @@ class FriendsView extends connect(store)(LitElement) {
const copyList = [...this.friendList] const copyList = [...this.friendList]
copyList[findFriend] = copyVal copyList[findFriend] = copyVal
this.friendList = copyList this.friendList = copyList
} }
} else { } else {
this.friendList = [...this.friendList, copyVal] this.friendList = [...this.friendList, copyVal]
} }
@ -252,7 +242,7 @@ class FriendsView extends connect(store)(LitElement) {
this.unFollowName(copyVal.name) this.unFollowName(copyVal.name)
} else if(copyVal.willFollow){ } else if(copyVal.willFollow){
this.myFollowName(copyVal.name) this.myFollowName(copyVal.name)
} }
this.setMySelectedFeeds(val.mySelectedFeeds) this.setMySelectedFeeds(val.mySelectedFeeds)
await new Promise((res)=> { await new Promise((res)=> {
setTimeout(()=> { setTimeout(()=> {
@ -317,18 +307,17 @@ class FriendsView extends connect(store)(LitElement) {
} }
render() { render() {
console.log('rendered1')
return html` return html`
<div class="container"> <div class="container">
<div id="viewElement" class="container-body" style=${"position: relative"}> <div id="viewElement" class="container-body" style=${"position: relative"}>
<p class="group-name">My Friends</p> <p class="group-name">My Friends</p>
<div class="search-field"> <div class="search-field">
<input <input
type="text" type="text"
class="name-input" class="name-input"
?disabled=${this.isLoading} ?disabled=${this.isLoading}
id="sendTo" id="sendTo"
placeholder="${translate("friends.friend1")}" placeholder="${translate("friends.friend1")}"
value=${this.userSelected.name ? this.userSelected.name: ''} value=${this.userSelected.name ? this.userSelected.name: ''}
@keypress=${(e) => { @keypress=${(e) => {
if(e.key === 'Enter'){ if(e.key === 'Enter'){
@ -336,21 +325,21 @@ class FriendsView extends connect(store)(LitElement) {
} }
}} }}
/> />
<vaadin-icon <vaadin-icon
@click=${this.userSearch} @click=${this.userSearch}
slot="icon" slot="icon"
icon="vaadin:search" icon="vaadin:search"
class="search-icon"> class="search-icon">
</vaadin-icon> </vaadin-icon>
</div> </div>
<div class="search-results-div"> <div class="search-results-div">
<chat-search-results <chat-search-results
.onClickFunc=${(result) => { .onClickFunc=${(result) => {
this.userSelected = result; this.userSelected = result;
this.isOpenAddFriendsModal = true this.isOpenAddFriendsModal = true
this.userFound = []; this.userFound = [];
this.userFoundModalOpen = false; this.userFoundModalOpen = false;
}} }}
@ -363,13 +352,13 @@ class FriendsView extends connect(store)(LitElement) {
?loading=${this.isLoading}> ?loading=${this.isLoading}>
</chat-search-results> </chat-search-results>
</div> </div>
${this.friendList.map((item) => { ${this.friendList.map((item) => {
return html`<chat-side-nav-heads return html`<chat-side-nav-heads
activeChatHeadUrl="" activeChatHeadUrl=""
.setActiveChatHeadUrl=${(val) => { .setActiveChatHeadUrl=${(val) => {
}} }}
.chatInfo=${item} .chatInfo=${item}
.openEditFriend=${(val)=> this.openEditFriend(val)} .openEditFriend=${(val)=> this.openEditFriend(val)}
@ -380,7 +369,7 @@ class FriendsView extends connect(store)(LitElement) {
</div> </div>
</div> </div>
<add-friends-modal <add-friends-modal
?isOpen=${this.isOpenAddFriendsModal} ?isOpen=${this.isOpenAddFriendsModal}
.setIsOpen=${(val)=> { .setIsOpen=${(val)=> {
this.isOpenAddFriendsModal = val this.isOpenAddFriendsModal = val
}} }}

View File

@ -1,4 +1,4 @@
import { LitElement, html, css } from 'lit'; import {css, html, LitElement} from 'lit';
import '@material/mwc-icon'; import '@material/mwc-icon';
import './friends-side-panel.js'; import './friends-side-panel.js';
import { connect } from 'pwa-helpers'; import { connect } from 'pwa-helpers';
@ -14,11 +14,10 @@ import {
encryptDataGroup, encryptDataGroup,
objectToBase64, objectToBase64,
uint8ArrayToBase64,
uint8ArrayToObject, uint8ArrayToObject,
} from '../../../../plugins/plugins/core/components/qdn-action-encryption.js'; } from '../../../../plugins/plugins/core/components/qdn-action-encryption.js';
import { publishData } from '../../../../plugins/plugins/utils/publish-image.js'; import {publishData} from '../../../../plugins/plugins/utils/publish-image.js';
import { parentEpml } from '../show-plugin.js'; import {parentEpml} from '../show-plugin.js';
import '../notification-view/popover.js'; import '../notification-view/popover.js';
import { setNewTab } from '../../redux/app/app-actions.js'; import { setNewTab } from '../../redux/app/app-actions.js';
@ -171,14 +170,14 @@ class SaveSettingsQdn extends connect(store)(LitElement) {
} }
async getMyFollowedNames() { async getMyFollowedNames() {
let myFollowedNames = [] let myFollowedNames = []
try { try {
myFollowedNames = await parentEpml.request('apiCall', { myFollowedNames = await parentEpml.request('apiCall', {
url: `/lists/followedNames?apiKey=${this.myNode.apiKey}` url: `/lists/followedNames?apiKey=${this.myNode.apiKey}`
}) })
} catch (error) { } catch (error) {
} }
return myFollowedNames return myFollowedNames
@ -197,7 +196,7 @@ class SaveSettingsQdn extends connect(store)(LitElement) {
body: `${namesJsonString}` body: `${namesJsonString}`
}) })
return ret return ret
} }
@ -671,20 +670,20 @@ class SaveSettingsQdn extends connect(store)(LitElement) {
hover-delay=${300} hover-delay=${300}
hide-delay=${1} hide-delay=${1}
text=${this.error text=${this.error
? get('save.saving1') ? translate('save.saving1')
: Object.values(this.valuesToBeSavedOnQdn) : Object.values(this.valuesToBeSavedOnQdn)
.length > 0 || .length > 0 ||
this.resourceExists === false this.resourceExists === false
? get('save.saving3') ? translate('save.saving3')
: get('save.saving2')} : translate('save.saving2')}
> >
</vaadin-tooltip> </vaadin-tooltip>
<popover-component for="save-icon" message=""> <popover-component for="save-icon" message="">
<div style="margin-bottom:20px"> <div style="margin-bottom:20px">
<p style="margin:10px 0px; font-size:16px"> <p style="margin:10px 0px; font-size:16px">
${`${get('walletpage.wchange12')}: ${ ${translate('walletpage.wchange12')}: ${
this.fee ? this.fee.feeToShow : '' this.fee ? this.fee.feeToShow : ''
}`} }
</p> </p>
</div> </div>
<div <div

View File

@ -1,5 +1,5 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { use, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate' import {registerTranslateConfig, translate, use} from 'lit-translate'
registerTranslateConfig({ registerTranslateConfig({
loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
@ -56,7 +56,7 @@ class LanguageSelector extends LitElement {
outline: none; outline: none;
} }
select option { select option {
color: var(--black); color: var(--black);
background: var(--white); background: var(--white);
line-height: 34px; line-height: 34px;
@ -85,6 +85,7 @@ class LanguageSelector extends LitElement {
<option value="it">IT - ${translate("selectmenu.italian")}</option> <option value="it">IT - ${translate("selectmenu.italian")}</option>
<option value="jp">JP - ${translate("selectmenu.japanese")}</option> <option value="jp">JP - ${translate("selectmenu.japanese")}</option>
<option value="ko">KO - ${translate("selectmenu.korean")}</option> <option value="ko">KO - ${translate("selectmenu.korean")}</option>
<option value="nl">NL - ${translate("selectmenu.dutch")}</option>
<option value="no">NO - ${translate("selectmenu.norwegian")}</option> <option value="no">NO - ${translate("selectmenu.norwegian")}</option>
<option value="pl">PL - ${translate("selectmenu.polish")}</option> <option value="pl">PL - ${translate("selectmenu.polish")}</option>
<option value="pt">PT - ${translate("selectmenu.portuguese")}</option> <option value="pt">PT - ${translate("selectmenu.portuguese")}</option>

View File

@ -1,12 +1,12 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../../store.js' import {store} from '../../store.js'
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate' import {get, translate} from 'lit-translate'
import { createWallet } from '../../../../crypto/api/createWallet.js' import {createWallet} from '../../../../crypto/api/createWallet.js'
import { doLogin, doLogout, doSelectAddress } from '../../redux/app/app-actions.js' import {doLogin, doLogout, doSelectAddress} from '../../redux/app/app-actions.js'
import { doStoreWallet } from '../../redux/user/user-actions.js' import {doStoreWallet} from '../../redux/user/user-actions.js'
import { checkApiKey } from '../../apiKeyUtils.js' import {checkApiKey} from '../../apiKeyUtils.js'
import FileSaver from 'file-saver' import FileSaver from 'file-saver'
import ripple from '../../functional-components/loading-ripple.js' import ripple from '../../functional-components/loading-ripple.js'
import snackbar from '../../functional-components/snackbar.js' import snackbar from '../../functional-components/snackbar.js'
@ -252,7 +252,7 @@ class CreateAccountSection extends connect(store)(LitElement) {
return html` return html`
<style> <style>
div[hidden] { div[hidden] {
display:none !important; display:none !important;
} }
.flex { .flex {
@ -360,7 +360,7 @@ class CreateAccountSection extends connect(store)(LitElement) {
padding: 0; padding: 0;
} }
</style> </style>
<div id="createAccountSection" class="flex column"> <div id="createAccountSection" class="flex column">
<iron-pages selected="${this.selectedPage}" attr-for-selected="page" id="createAccountPages"> <iron-pages selected="${this.selectedPage}" attr-for-selected="page" id="createAccountPages">
<div page="info"> <div page="info">

View File

@ -1,8 +1,8 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../../store.js' import {store} from '../../store.js'
import { checkApiKey } from '../../apiKeyUtils.js' import {checkApiKey} from '../../apiKeyUtils.js'
import { translate, translateUnsafeHTML } from 'lit-translate' import {translate} from 'lit-translate'
import '@material/mwc-button' import '@material/mwc-button'
import '@material/mwc-checkbox' import '@material/mwc-checkbox'
@ -18,9 +18,9 @@ import '@polymer/iron-collapse'
import '@polymer/paper-spinner/paper-spinner-lite.js' import '@polymer/paper-spinner/paper-spinner-lite.js'
import '@vaadin/text-field/vaadin-text-field.js' import '@vaadin/text-field/vaadin-text-field.js'
import '@vaadin/password-field/vaadin-password-field.js' import '@vaadin/password-field/vaadin-password-field.js'
import { doLogin, doSelectAddress } from '../../redux/app/app-actions.js' import {doLogin, doSelectAddress} from '../../redux/app/app-actions.js'
import { doStoreWallet, doRemoveWallet } from '../../redux/user/user-actions.js' import {doRemoveWallet, doStoreWallet} from '../../redux/user/user-actions.js'
import { createWallet } from '../../../../crypto/api/createWallet.js' import {createWallet} from '../../../../crypto/api/createWallet.js'
import snackbar from '../../functional-components/snackbar.js' import snackbar from '../../functional-components/snackbar.js'
import '../../custom-elements/frag-file-input.js' import '../../custom-elements/frag-file-input.js'
import ripple from '../../functional-components/loading-ripple.js' import ripple from '../../functional-components/loading-ripple.js'
@ -195,7 +195,7 @@ class LoginSection extends connect(store)(LitElement) {
right: 5px; right: 5px;
top: 20px; top: 20px;
color: tomato; color: tomato;
--mdc-icon-size: 30px; --mdc-icon-size: 30px;
} }
.login-option { .login-option {
@ -212,7 +212,7 @@ class LoginSection extends connect(store)(LitElement) {
color: var(--black); color: var(--black);
} }
*[hidden] { *[hidden] {
display:none !important; display:none !important;
visibility: hidden; visibility: hidden;
} }
@ -268,7 +268,7 @@ class LoginSection extends connect(store)(LitElement) {
cursor: pointer; cursor: pointer;
} }
</style> </style>
<div id="loginSection"> <div id="loginSection">
<div id="pagesContainer"> <div id="pagesContainer">
<iron-pages style="padding: 0;" selected="${this.selectedPage}" attr-for-selected="page" id="loginPages"> <iron-pages style="padding: 0;" selected="${this.selectedPage}" attr-for-selected="page" id="loginPages">

View File

@ -1,8 +1,8 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../../store.js' import {store} from '../../store.js'
import { stateAwait } from '../../stateAwait.js' import {stateAwait} from '../../stateAwait.js'
import { translate, translateUnsafeHTML } from 'lit-translate' import {get} from 'lit-translate'
import '@material/mwc-button' import '@material/mwc-button'
import '@material/mwc-icon' import '@material/mwc-icon'
@ -15,7 +15,20 @@ import './login-section.js'
import '../qort-theme-toggle.js' import '../qort-theme-toggle.js'
import settings from '../../functional-components/settings-page.js' import settings from '../../functional-components/settings-page.js'
import { addAutoLoadImageChat, removeAutoLoadImageChat, addChatLastSeen, allowQAPPAutoAuth, removeQAPPAutoAuth, removeQAPPAutoLists, allowQAPPAutoLists, addTabInfo, setTabNotifications, setNewTab, setNewNotification, setSideEffectAction } from '../../redux/app/app-actions.js' import {
addAutoLoadImageChat,
addChatLastSeen,
addTabInfo,
allowQAPPAutoAuth,
allowQAPPAutoLists,
removeAutoLoadImageChat,
removeQAPPAutoAuth,
removeQAPPAutoLists,
setNewNotification,
setNewTab,
setSideEffectAction,
setTabNotifications
} from '../../redux/app/app-actions.js'
window.reduxStore = store window.reduxStore = store
window.reduxAction = { window.reduxAction = {
@ -122,7 +135,7 @@ class LoginView extends connect(store)(LitElement) {
display: block; display: block;
vertical-align: bottom; vertical-align: bottom;
} }
.login-page { .login-page {
background: var(--background); background: var(--background);
background-repeat: no-repeat; background-repeat: no-repeat;
@ -137,6 +150,7 @@ class LoginView extends connect(store)(LitElement) {
left:0; left:0;
z-index:1; z-index:1;
} }
.login-card-container { .login-card-container {
max-width:1240px; max-width:1240px;
max-height:var(--window-height); max-height:var(--window-height);
@ -144,6 +158,7 @@ class LoginView extends connect(store)(LitElement) {
margin-left: auto; margin-left: auto;
width: calc(100vw); width: calc(100vw);
} }
.qortal-logo { .qortal-logo {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
@ -151,6 +166,7 @@ class LoginView extends connect(store)(LitElement) {
max-width:40%; max-width:40%;
z-index:1; z-index:1;
} }
.login-card-center-container { .login-card-center-container {
max-width:100%; max-width:100%;
max-height:var(--window-height); max-height:var(--window-height);
@ -160,13 +176,16 @@ class LoginView extends connect(store)(LitElement) {
height: var(--window-height); height: var(--window-height);
overflow:hidden; overflow:hidden;
} }
#loginContainerPages { #loginContainerPages {
display:inline; display:inline;
} }
#loginContainerPages [page] { #loginContainerPages [page] {
background: none; background: none;
padding:0; padding:0;
} }
.login-card { .login-card {
min-width: 340px; min-width: 340px;
border-bottom: 2px solid var(--mdc-theme-primary); border-bottom: 2px solid var(--mdc-theme-primary);
@ -177,30 +196,49 @@ class LoginView extends connect(store)(LitElement) {
border: 0; border: 0;
border-radius: 4px; border-radius: 4px;
} }
.login-card p { .login-card p {
margin-top: 0; margin-top: 0;
font-size: 1rem; font-size: 1rem;
font-style: italic; font-style: italic;
} }
.login-card h1{
.login-card h1 {
margin-bottom:12px; margin-bottom:12px;
font-size:64px; font-size:64px;
} }
.login-card h5 {
margin-top: -16px;
margin-left: 100px;
font-size: 14px;
color: var(--black);
}
.login-card h6 {
font-size: 12px;
color: var(--mdc-theme-primary);
}
.login-card iron-pages { .login-card iron-pages {
height:100%; height:100%;
margin-top: -16px;
} }
.backButton { .backButton {
padding-top:18px; padding-top:18px;
text-align:center; text-align:center;
} }
#login-pages-nav { #login-pages-nav {
text-align: left; text-align: left;
/* padding-bottom:8px; */
padding: 12px 0 8px 0; padding: 12px 0 8px 0;
} }
#nav-next { #nav-next {
float: right; float: right;
} }
@media only screen and (min-width: ${getComputedStyle(document.body).getPropertyValue('--layout-breakpoint-tablet')}) { @media only screen and (min-width: ${getComputedStyle(document.body).getPropertyValue('--layout-breakpoint-tablet')}) {
/* Desktop/tablet */ /* Desktop/tablet */
.login-card { .login-card {
@ -212,13 +250,14 @@ class LoginView extends connect(store)(LitElement) {
#loginContainerPages [page="welcome"] { #loginContainerPages [page="welcome"] {
} }
} }
@media only screen and (max-width: ${getComputedStyle(document.body).getPropertyValue('--layout-breakpoint-tablet')}) { @media only screen and (max-width: ${getComputedStyle(document.body).getPropertyValue('--layout-breakpoint-tablet')}) {
/* Mobile */ /* Mobile */
.qortal-logo { .qortal-logo {
display:none; display:none;
visibility:hidden; visibility:hidden;
} }
.login-card{ .login-card {
width:100%; width:100%;
margin:0; margin:0;
top:0; top:0;
@ -228,7 +267,14 @@ class LoginView extends connect(store)(LitElement) {
text-align: left; text-align: left;
padding-left:12px; padding-left:12px;
} }
.login-card h5 {
margin-top: 0px;
margin-left: 0px;
font-size: 14px;
color: var(--black);
}
} }
@keyframes fade { @keyframes fade {
from { from {
opacity: 0; opacity: 0;
@ -239,6 +285,7 @@ class LoginView extends connect(store)(LitElement) {
transform: translateX(0); transform: translateX(0);
} }
} }
@keyframes grow-up { @keyframes grow-up {
from { from {
overflow:hidden; overflow:hidden;
@ -249,16 +296,20 @@ class LoginView extends connect(store)(LitElement) {
max-height:var(--window-height); max-height:var(--window-height);
} }
} }
iron-pages .animated, .animated { iron-pages .animated, .animated {
animation-duration: ${animationDuration}s; animation-duration: ${animationDuration}s;
animation-name: grow-up; animation-name: grow-up;
} }
div[page] > paper-icon-button { div[page] > paper-icon-button {
margin:12px; margin:12px;
} }
.corner-box { .corner-box {
border-color: var(--mdc-theme-primary) !important; border-color: var(--mdc-theme-primary) !important;
} }
[hidden] { [hidden] {
visibility: hidden; visibility: hidden;
display: none; display: none;
@ -271,7 +322,8 @@ class LoginView extends connect(store)(LitElement) {
<div class="login-card-center-container"> <div class="login-card-center-container">
<div class="login-card" id="login-card"> <div class="login-card" id="login-card">
<img class="qortal-logo" src="${this.config.coin.logo}"> <img class="qortal-logo" src="${this.config.coin.logo}">
<h5 style="color:var(--mdc-theme-primary)" ?hidden="${this.selectedPage != "welcome"}">${translate("appinfo.uiversion")}: ${this.nodeConfig.version ? this.nodeConfig.version : ''}</h5> <h5 ?hidden="${this.selectedPage != "welcome"}">UI: v${this.nodeConfig.version ? this.nodeConfig.version : ''}</h5>
${this.renderSelectedNodeOnStart()}
<iron-pages selected="${this.selectedPage}" attr-for-selected="page" id="loginContainerPages"> <iron-pages selected="${this.selectedPage}" attr-for-selected="page" id="loginContainerPages">
<welcome-page @next=${e => this.selectedPageElement.next(e)} page="welcome"></welcome-page> <welcome-page @next=${e => this.selectedPageElement.next(e)} page="welcome"></welcome-page>
<create-account-section @next=${e => this.selectedPageElement.next(e)} page="create-account"></create-account-section> <create-account-section @next=${e => this.selectedPageElement.next(e)} page="create-account"></create-account-section>
@ -292,6 +344,18 @@ class LoginView extends connect(store)(LitElement) {
` `
} }
renderSelectedNodeOnStart() {
const selectedNodeIndexOnStart = localStorage.getItem('mySelectedNode')
const catchSavedNodes = JSON.parse(localStorage.getItem('myQortalNodes'))
const selectedNodeOnStart = catchSavedNodes[selectedNodeIndexOnStart]
const selectedNameOnStart = `${selectedNodeOnStart.name}`
const selectedNodeUrlOnStart = `${selectedNodeOnStart.protocol + '://' + selectedNodeOnStart.domain +':' + selectedNodeOnStart.port}`
let connectString = get('settings.snack2')
return html`<h6>${connectString} : ${selectedNameOnStart} ${selectedNodeUrlOnStart}</h6>`
}
selectPage(newPage) { selectPage(newPage) {
this.selectedPage = newPage this.selectedPage = newPage
} }

View File

@ -1,5 +1,5 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { translate, translateUnsafeHTML } from 'lit-translate' import {translate} from 'lit-translate'
import '@material/mwc-button' import '@material/mwc-button'

View File

@ -1,8 +1,8 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../../store.js' import {store} from '../../store.js'
import { doLogout } from '../../redux/app/app-actions.js' import {doLogout} from '../../redux/app/app-actions.js'
import { translate, translateUnsafeHTML } from 'lit-translate' import {translate} from 'lit-translate'
import '@polymer/paper-dialog/paper-dialog.js' import '@polymer/paper-dialog/paper-dialog.js'
import '@material/mwc-button' import '@material/mwc-button'

View File

@ -1,12 +1,12 @@
import { LitElement, html } from 'lit' import {html, LitElement} from 'lit'
import { installRouter } from 'pwa-helpers/router.js' import {installRouter} from 'pwa-helpers/router.js'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../store.js' import {store} from '../store.js'
import { doNavigate } from '../redux/app/app-actions.js' import {doNavigate} from '../redux/app/app-actions.js'
import isElectron from 'is-electron' import isElectron from 'is-electron'
import '../plugins/streams.js' import '../plugins/streams.js'
import { loadPlugins } from '../plugins/load-plugins.js' import {loadPlugins} from '../plugins/load-plugins.js'
import '../styles/app-styles.js' import '../styles/app-styles.js'
import './login-view/login-view.js' import './login-view/login-view.js'
@ -31,8 +31,8 @@ class MainApp extends connect(store)(LitElement) {
} }
/** /**
* Dynamic renderViews method to introduce conditional rendering of views based on user's logged in state. * Dynamic renderViews method to introduce conditional rendering of views based on user's logged in state.
* @param {Boolean} isLoggedIn * @param {Boolean} isLoggedIn
*/ */
renderViews(isLoggedIn) { renderViews(isLoggedIn) {

View File

@ -1,24 +1,19 @@
import { LitElement, html, css } from 'lit'; import {css, html, LitElement} from 'lit';
import { connect } from 'pwa-helpers'; import {connect} from 'pwa-helpers';
import '@vaadin/item'; import '@vaadin/item';
import '@vaadin/list-box'; import '@vaadin/list-box';
import '@polymer/paper-icon-button/paper-icon-button.js'; import '@polymer/paper-icon-button/paper-icon-button.js';
import '@polymer/iron-icons/iron-icons.js'; import '@polymer/iron-icons/iron-icons.js';
import { store } from '../../store.js'; import {store} from '../../store.js';
import { setNewNotification, setNewTab } from '../../redux/app/app-actions.js'; import {setNewNotification} from '../../redux/app/app-actions.js';
import { routes } from '../../plugins/routes.js';
import '@material/mwc-icon'; import '@material/mwc-icon';
import { translate, get } from 'lit-translate'; import {get, translate} from 'lit-translate';
import { repeat } from 'lit/directives/repeat.js'; import {repeat} from 'lit/directives/repeat.js';
import config from '../../notifications/config.js';
import '../../../../plugins/plugins/core/components/TimeAgo.js'; import '../../../../plugins/plugins/core/components/TimeAgo.js';
import './popover.js'; import './popover.js';
class NotificationBellGeneral extends connect(store)(LitElement) { class NotificationBellGeneral extends connect(store)(LitElement) {
static properties = { static properties = {
notifications: { type: Array }, notifications: { type: Array },
@ -91,7 +86,7 @@ class NotificationBellGeneral extends connect(store)(LitElement) {
status: statusTx, status: statusTx,
}; };
this.notifications = copyNotifications; this.notifications = copyNotifications;
} }
} }

View File

@ -1,13 +1,13 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import '@vaadin/item' import '@vaadin/item'
import '@vaadin/list-box' import '@vaadin/list-box'
import '@polymer/paper-icon-button/paper-icon-button.js' import '@polymer/paper-icon-button/paper-icon-button.js'
import '@polymer/iron-icons/iron-icons.js' import '@polymer/iron-icons/iron-icons.js'
import { store } from '../../store.js' import {store} from '../../store.js'
import { setNewTab } from '../../redux/app/app-actions.js' import {setNewTab} from '../../redux/app/app-actions.js'
import { routes } from '../../plugins/routes.js' import {routes} from '../../plugins/routes.js'
import '@material/mwc-icon'; import '@material/mwc-icon';
import config from '../../notifications/config.js' import config from '../../notifications/config.js'
@ -61,7 +61,7 @@ class NotificationBell extends connect(store)(LitElement) {
0, 0,
20 20
)}_${recipientAddress.slice(-6)}_mail_` )}_${recipientAddress.slice(-6)}_mail_`
const url = `${nodeUrl}/arbitrary/resources/search?service=MAIL_PRIVATE&query=${query}&limit=10&includemetadata=true&offset=0&reverse=true&excludeblocked=true` const url = `${nodeUrl}/arbitrary/resources/search?service=MAIL_PRIVATE&query=${query}&limit=10&includemetadata=false&offset=0&reverse=true&excludeblocked=true`
const response = await fetch(url, { const response = await fetch(url, {
method: 'GET', method: 'GET',
headers: { headers: {
@ -150,7 +150,7 @@ class NotificationBell extends connect(store)(LitElement) {
hide-delay=${1} hide-delay=${1}
text="Q-Mail"> text="Q-Mail">
</vaadin-tooltip> </vaadin-tooltip>
` : html` ` : html`
<mwc-icon @click=${() => this._openTabQmail()} id="notification-mail-icon" style="color: var(--black); cursor:pointer;user-select:none" <mwc-icon @click=${() => this._openTabQmail()} id="notification-mail-icon" style="color: var(--black); cursor:pointer;user-select:none"
>mail</mwc-icon >mail</mwc-icon
@ -162,7 +162,7 @@ class NotificationBell extends connect(store)(LitElement) {
hide-delay=${1} hide-delay=${1}
text="Q-Mail"> text="Q-Mail">
</vaadin-tooltip> </vaadin-tooltip>
`} `}
${this.notificationCount ? html` ${this.notificationCount ? html`
@ -195,7 +195,7 @@ class NotificationBell extends connect(store)(LitElement) {
<p>Q-Mail</p> <p>Q-Mail</p>
<message-time timestamp=${notification.created} style="color:red;font-size:12px"></message-time> <message-time timestamp=${notification.created} style="color:red;font-size:12px"></message-time>
</div> </div>
<div> <div>
<p>${notification.name}</p> <p>${notification.name}</p>
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
// popover-component.js // popover-component.js
import { LitElement, html, css } from 'lit'; import {css, html, LitElement} from 'lit';
import { createPopper } from '@popperjs/core'; import {createPopper} from '@popperjs/core';
import '@material/mwc-icon' import '@material/mwc-icon'
export class PopoverComponent extends LitElement { export class PopoverComponent extends LitElement {
@ -24,7 +24,7 @@ export class PopoverComponent extends LitElement {
color: var(--black) color: var(--black)
} }
`; `;
static properties = { static properties = {

View File

@ -1,5 +1,5 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { svgSun, svgMoon } from '../../assets/js/svg.js' import {svgMoon, svgSun} from '../../assets/js/svg.js'
class QortThemeToggle extends LitElement { class QortThemeToggle extends LitElement {
static get properties() { static get properties() {

View File

@ -1,5 +1,5 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { get, translate, translateUnsafeHTML } from 'lit-translate' import {get, translate} from 'lit-translate'
import snackbar from '../functional-components/snackbar.js' import snackbar from '../functional-components/snackbar.js'
import '@polymer/paper-icon-button/paper-icon-button.js' import '@polymer/paper-icon-button/paper-icon-button.js'
@ -129,4 +129,4 @@ class SearchModal extends LitElement {
} }
} }
window.customElements.define('search-modal', SearchModal) window.customElements.define('search-modal', SearchModal)

View File

@ -1,13 +1,14 @@
import { LitElement, html, css } from 'lit'; import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers'; import {connect} from 'pwa-helpers'
import { store } from '../../store.js'; import {store} from '../../store.js'
import { translate, translateUnsafeHTML } from 'lit-translate' import {translate} from 'lit-translate'
class AccountView extends connect(store)(LitElement) { class AccountView extends connect(store)(LitElement) {
static get properties() { static get properties() {
return { return {
accountInfo: { type: Object }, accountInfo: { type: Object },
theme: { type: String, reflect: true } theme: { type: String, reflect: true },
switchAvatar: { type: String }
} }
} }
@ -66,6 +67,7 @@ class AccountView extends connect(store)(LitElement) {
super() super()
this.accountInfo = { names: [], addressInfo: {} } this.accountInfo = { names: [], addressInfo: {} }
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
this.switchAvatar = ''
} }
render() { render() {
@ -88,26 +90,46 @@ class AccountView extends connect(store)(LitElement) {
` `
} }
stateChanged(state) { firstUpdated() {
this.accountInfo = state.app.accountInfo this.getSwitchAvatar()
setInterval(() => {
this.getSwitchAvatar()
}, 2000)
} }
getAvatar() { getAvatar() {
let numberBlocks = (this.accountInfo.addressInfo.blocksMinted + this.accountInfo.addressInfo.blocksMintedAdjustment); const avatarNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
if (Number.isNaN(numberBlocks) || numberBlocks == "" || numberBlocks === null) { const avatarUrl = avatarNode.protocol + '://' + avatarNode.domain + ':' + avatarNode.port
return html`<img src="/img/noavatar.png" style="width:150px; height:150px; border-radius: 50%;">` const url = `${avatarUrl}/arbitrary/THUMBNAIL/${this.accountInfo.names[0].name}/qortal_avatar?async=true&apiKey=${this.getApiKey()}`
} else { const numberBlocks = (this.accountInfo.addressInfo.blocksMinted + this.accountInfo.addressInfo.blocksMintedAdjustment)
const avatarNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
const avatarUrl = avatarNode.protocol + '://' + avatarNode.domain + ':' + avatarNode.port if (this.switchAvatar === 'light') {
const url = `${avatarUrl}/arbitrary/THUMBNAIL/${this.accountInfo.names[0].name}/qortal_avatar?async=true&apiKey=${this.getApiKey()}` if (Number.isNaN(numberBlocks) || numberBlocks == "" || numberBlocks === null) {
return html`<img src="${url}" style="width:150px; height:150px; border-radius: 50%;" onerror="this.src='/img/noavatar.png';">` return html`<img src="/img/noavatar_light.png" style="width:150px; height:150px; border-radius: 25%;">`
} else {
return html`<img src="${url}" style="width:150px; height:150px; border-radius: 25%;" onerror="this.src='/img/noavatar_light.png';">`
}
} else if (this.switchAvatar === 'dark') {
if (Number.isNaN(numberBlocks) || numberBlocks == "" || numberBlocks === null) {
return html`<img src="/img/noavatar_dark.png" style="width:150px; height:150px; border-radius: 25%;">`
} else {
return html`<img src="${url}" style="width:150px; height:150px; border-radius: 25%;" onerror="this.src='/img/noavatar_dark.png';">`
}
} }
} }
getSwitchAvatar() {
this.switchAvatar = localStorage.getItem('qortalTheme')
}
getApiKey() { getApiKey() {
const apiNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]; const apiNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
let apiKey = apiNode.apiKey; let apiKey = apiNode.apiKey
return apiKey; return apiKey
}
stateChanged(state) {
this.accountInfo = state.app.accountInfo
} }
} }

View File

@ -1,7 +1,7 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../../store.js' import {store} from '../../store.js'
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate' import {get, translate} from 'lit-translate'
import snackbar from '../../functional-components/snackbar.js' import snackbar from '../../functional-components/snackbar.js'
import FileSaver from 'file-saver' import FileSaver from 'file-saver'

View File

@ -1,8 +1,8 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../../store.js' import {store} from '../../store.js'
import { doSetQChatNotificationConfig } from '../../redux/user/user-actions.js' import {doSetQChatNotificationConfig} from '../../redux/user/user-actions.js'
import { translate, translateUnsafeHTML } from 'lit-translate' import {translate} from 'lit-translate'
import isElectron from 'is-electron' import isElectron from 'is-electron'
import '@material/mwc-checkbox' import '@material/mwc-checkbox'
@ -111,7 +111,7 @@ class NotificationsView extends connect(store)(LitElement) {
text-decoration: none; text-decoration: none;
transition: all .2s; transition: all .2s;
position: relative; position: relative;
} }
.remove-button { .remove-button {
font-family: Roboto, sans-serif; font-family: Roboto, sans-serif;
@ -171,7 +171,7 @@ class NotificationsView extends connect(store)(LitElement) {
<button class="remove-button" @click=${() => this.removeApp(app)}>Remove</button> <button class="remove-button" @click=${() => this.removeApp(app)}>Remove</button>
</div> </div>
`)} `)}
</div> </div>
</div> </div>
${this.renderSetCoreButton()} ${this.renderSetCoreButton()}
@ -194,7 +194,7 @@ class NotificationsView extends connect(store)(LitElement) {
// Update the apps list in the component // Update the apps list in the component
this.appNotificationList = this.appNotificationList.filter(app => app !== appName); this.appNotificationList = this.appNotificationList.filter(app => app !== appName);
} }
removeAppFromStorage(appName) { removeAppFromStorage(appName) {
// Your method to remove the app from local storage // Your method to remove the app from local storage
const address= store.getState().app.selectedAddress.address const address= store.getState().app.selectedAddress.address

View File

@ -1,7 +1,7 @@
import { css, html, LitElement } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../../store.js' import {store} from '../../store.js'
import { translate } from 'lit-translate' import {translate} from 'lit-translate'
import '@material/mwc-textfield' import '@material/mwc-textfield'
import '@material/mwc-icon' import '@material/mwc-icon'
@ -59,21 +59,21 @@ class QRLoginView extends connect(store)(LitElement) {
text-decoration: none; text-decoration: none;
transition: all .2s; transition: all .2s;
position: relative; position: relative;
} }
.q-button.outlined { .q-button.outlined {
background: unset; background: unset;
border: 1px solid #03a9f4; border: 1px solid #03a9f4;
} }
:host([theme="light"]) .q-button.outlined { :host([theme="light"]) .q-button.outlined {
color: #03a9f4; color: #03a9f4;
} }
#qr-toggle-button { #qr-toggle-button {
margin-left: 12px; margin-left: 12px;
} }
#login-qr-code { #login-qr-code {
margin: auto; margin: auto;
} }
@ -101,7 +101,7 @@ class QRLoginView extends connect(store)(LitElement) {
<div style="max-width: 600px; display: flex; justify-content: center; margin: auto;"> <div style="max-width: 600px; display: flex; justify-content: center; margin: auto;">
<div id="qr-toggle-button" @click=${() => this.showQRCode()} class="q-button outlined"> ${translate(this.translateButtonKey)} </div> <div id="qr-toggle-button" @click=${() => this.showQRCode()} class="q-button outlined"> ${translate(this.translateButtonKey)} </div>
</div> </div>
<div id="login-qr-code" style="display: none;"> <div id="login-qr-code" style="display: none;">
<qortal-qrcode-generator id="login-qr-code" data="${this.savedWalletDataJson}" mode="octet" format="html" auto></qortal-qrcode-generator> <qortal-qrcode-generator id="login-qr-code" data="${this.savedWalletDataJson}" mode="octet" format="html" auto></qortal-qrcode-generator>
</div> </div>

View File

@ -1,8 +1,14 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../../store.js' import {store} from '../../store.js'
import { allowQAPPAutoAuth, removeQAPPAutoAuth, removeQAPPAutoLists, allowQAPPAutoLists, setIsOpenDevDialog } from '../../redux/app/app-actions.js' import {
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate' allowQAPPAutoAuth,
allowQAPPAutoLists,
removeQAPPAutoAuth,
removeQAPPAutoLists,
setIsOpenDevDialog
} from '../../redux/app/app-actions.js'
import {get, translate} from 'lit-translate'
import snackbar from '../../functional-components/snackbar.js' import snackbar from '../../functional-components/snackbar.js'
import FileSaver from 'file-saver' import FileSaver from 'file-saver'
@ -75,7 +81,7 @@ class SecurityView extends connect(store)(LitElement) {
text-decoration: none; text-decoration: none;
transition: all .2s; transition: all .2s;
position: relative; position: relative;
} }
.add-dev-button { .add-dev-button {
margin-top: 4px; margin-top: 4px;
@ -141,13 +147,13 @@ class SecurityView extends connect(store)(LitElement) {
<mwc-checkbox style="margin-right: -15px;" id="authButton" @click=${(e) => this.checkForLists(e)} ?checked=${store.getState().app.qAPPAutoLists}></mwc-checkbox> <mwc-checkbox style="margin-right: -15px;" id="authButton" @click=${(e) => this.checkForLists(e)} ?checked=${store.getState().app.qAPPAutoLists}></mwc-checkbox>
</div> </div>
<div class="checkbox-row"> <div class="checkbox-row">
<button <button
class="add-dev-button" class="add-dev-button"
title="${translate('tabmenu.tm18')}" title="${translate('tabmenu.tm18')}"
@click=${this.openDevDialog} @click=${this.openDevDialog}
>${translate('tabmenu.tm38')}</button> >${translate('tabmenu.tm38')}</button>
</div> </div>
</div> </div>
` `
} }

View File

@ -1,7 +1,7 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../../store.js' import {store} from '../../store.js'
import { translate, translateUnsafeHTML } from 'lit-translate' import {translate} from 'lit-translate'
import '@polymer/paper-dialog/paper-dialog.js' import '@polymer/paper-dialog/paper-dialog.js'
import '@material/mwc-button' import '@material/mwc-button'
@ -12,8 +12,6 @@ import './notifications-view.js'
import './qr-login-view.js' import './qr-login-view.js'
import './export-keys.js' import './export-keys.js'
import { doLogout } from '../../redux/app/app-actions.js'
class UserSettings extends connect(store)(LitElement) { class UserSettings extends connect(store)(LitElement) {
static get properties() { static get properties() {
return { return {

View File

@ -1,20 +1,14 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { render } from 'lit/html.js' import {render} from 'lit/html.js'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../store.js' import {store} from '../store.js'
import { Epml } from '../epml.js' import {Epml} from '../epml.js'
import { addPluginRoutes } from '../plugins/addPluginRoutes.js' import {addPluginRoutes} from '../plugins/addPluginRoutes.js'
import { repeat } from 'lit/directives/repeat.js'; import {repeat} from 'lit/directives/repeat.js';
import ShortUniqueId from 'short-unique-id'; import ShortUniqueId from 'short-unique-id';
import { setIsOpenDevDialog, setNewTab } from '../redux/app/app-actions.js' import {setIsOpenDevDialog, setNewTab} from '../redux/app/app-actions.js'
import localForage from 'localforage'
import FileSaver from 'file-saver' import FileSaver from 'file-saver'
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate' import {get, registerTranslateConfig, translate, use} from 'lit-translate'
registerTranslateConfig({
loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
})
import '@material/mwc-button' import '@material/mwc-button'
import '@material/mwc-dialog' import '@material/mwc-dialog'
import '@material/mwc-icon' import '@material/mwc-icon'
@ -26,6 +20,9 @@ import '@vaadin/grid'
import '@vaadin/text-field' import '@vaadin/text-field'
import '../custom-elements/frag-file-input.js' import '../custom-elements/frag-file-input.js'
registerTranslateConfig({
loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
})
export const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) export const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
@ -91,7 +88,7 @@ class ShowPlugin extends connect(store)(LitElement) {
border-radius: 6px; border-radius: 6px;
border: 3px solid var(--scrollbarBG); border: 3px solid var(--scrollbarBG);
} }
.hideIframe { .hideIframe {
display: none; display: none;
position: absolute; position: absolute;
@ -436,7 +433,7 @@ class ShowPlugin extends connect(store)(LitElement) {
}}" }}"
@mousedown="${(event) => { @mousedown="${(event) => {
if (event.button === 1) { if (event.button === 1) {
event.preventDefault(); event.preventDefault();
this.removeTab(index, tab.id); this.removeTab(index, tab.id);
} }
}}" }}"
@ -447,8 +444,8 @@ class ShowPlugin extends connect(store)(LitElement) {
` : html` ` : html`
<mwc-icon>${icon}</mwc-icon> <mwc-icon>${icon}</mwc-icon>
`} `}
</div> </div>
<div class="tabCard"> <div class="tabCard">
${count ? html` ${count ? html`
@ -456,7 +453,7 @@ class ShowPlugin extends connect(store)(LitElement) {
<span class="count ml-5">${count}</span> <span class="count ml-5">${count}</span>
<span class="show ml-25"><mwc-icon class="close" @click=${(event) => { <span class="show ml-25"><mwc-icon class="close" @click=${(event) => {
event.stopPropagation(); this.removeTab(index, tab.id) event.stopPropagation(); this.removeTab(index, tab.id)
}}>close</mwc-icon></span> }}>close</mwc-icon></span>
` : html` ` : html`
<span class="tabTitle ml-30">${title}</span> <span class="tabTitle ml-30">${title}</span>
@ -466,7 +463,7 @@ class ShowPlugin extends connect(store)(LitElement) {
</div> </div>
` `
})} })}
<button <button
class="add-tab-button" class="add-tab-button"
title="${translate('tabmenu.tm18')}" title="${translate('tabmenu.tm18')}"
@click=${() => { @click=${() => {
@ -476,7 +473,7 @@ class ShowPlugin extends connect(store)(LitElement) {
id: this.uid.rnd() id: this.uid.rnd()
}) })
this.currentTab = lengthOfTabs this.currentTab = lengthOfTabs
}} }}
>+</button> >+</button>
</div> </div>
@ -500,8 +497,8 @@ class ShowPlugin extends connect(store)(LitElement) {
</nav-bar> </nav-bar>
</div> </div>
`)} `)}
<mwc-dialog id="addDevDialog" <mwc-dialog id="addDevDialog"
?open=${this.isOpenDevDialog} ?open=${this.isOpenDevDialog}
@closed=${() => { @closed=${() => {
this.shadowRoot.getElementById('domainInput').value = '' this.shadowRoot.getElementById('domainInput').value = ''
this.shadowRoot.getElementById('portInput').value = '' this.shadowRoot.getElementById('portInput').value = ''
@ -532,7 +529,7 @@ class ShowPlugin extends connect(store)(LitElement) {
> >
${translate('tabmenu.tm40')} ${translate('tabmenu.tm40')}
</mwc-button> </mwc-button>
</mwc-dialog> </mwc-dialog>
` `
} }
@ -1019,22 +1016,22 @@ class NavBar extends connect(store)(LitElement) {
--mdc-icon-size: 64px; --mdc-icon-size: 64px;
cursor: pointer; cursor: pointer;
} }
.menuIconPos { .menuIconPos {
right: -2px; right: -2px;
} }
.removeIconPos { .removeIconPos {
position: absolute; position: absolute;
top: -10px; top: -10px;
right: -10px; right: -10px;
z-index: 1; z-index: 1;
} }
.menuIconPos:hover .removeIcon { .menuIconPos:hover .removeIcon {
display: inline; display: inline;
} }
.removeIcon { .removeIcon {
display: none; display: none;
color: var(--black); color: var(--black);
@ -1043,7 +1040,7 @@ class NavBar extends connect(store)(LitElement) {
position: relative; position: relative;
z-index: 1; z-index: 1;
} }
.removeIcon:hover { .removeIcon:hover {
color: #C6011F; color: #C6011F;
font-weight: bold; font-weight: bold;
@ -1480,7 +1477,7 @@ class NavBar extends connect(store)(LitElement) {
const addressInfo = this.addressInfo const addressInfo = this.addressInfo
const isMinter = addressInfo?.error !== 124 && +addressInfo?.level > 0 const isMinter = addressInfo?.error !== 124 && +addressInfo?.level > 0
const isSponsor = +addressInfo?.level >= 5 const isSponsor = +addressInfo?.level >= 5
if (!isMinter) { if (!isMinter) {
this.newMenuList = this.myMenuPlugins.filter((minter) => { this.newMenuList = this.myMenuPlugins.filter((minter) => {
@ -1499,7 +1496,7 @@ class NavBar extends connect(store)(LitElement) {
} else { } else {
this.myMenuList = this.newMenuList this.myMenuList = this.newMenuList
} }
this.requestUpdate() this.requestUpdate()
} }
@ -2209,7 +2206,7 @@ class NavBar extends connect(store)(LitElement) {
renderRemoveIcon(appurl, appicon, appname, appid, appplugin) { renderRemoveIcon(appurl, appicon, appname, appid, appplugin) {
return html` return html`
<div class="menuIconPos" @click="${() => this.changePage(appplugin)}"> <div class="menuIconPos" @click="${() => this.changePage(appplugin)}">
<div class="removeIconPos" title="${translate('tabmenu.tm22')}" @click="${(event) => { <div class="removeIconPos" title="${translate('tabmenu.tm22')}" @click="${(event) => {
event.stopPropagation(); event.stopPropagation();
@ -2453,14 +2450,14 @@ class AppAvatar extends LitElement {
constructor() { constructor() {
super() super()
this.hasAvatar = false this.hasAvatar = false
this.isImageLoaded = false this.isImageLoaded = false
this.imageFetches = 0 this.imageFetches = 0
} }
static get styles() { static get styles() {
return css` return css`
:host { :host {
position: absolute; position: absolute;
@ -2478,16 +2475,16 @@ class AppAvatar extends LitElement {
` `
} }
createImage(imageUrl) { createImage(imageUrl) {
const imageHTMLRes = new Image(); const imageHTMLRes = new Image();
imageHTMLRes.src = imageUrl; imageHTMLRes.src = imageUrl;
imageHTMLRes.style= "border-radius:10px; font-size:14px; object-fit: fill;height:60px;width:60px"; imageHTMLRes.style= "border-radius:10px; font-size:14px; object-fit: fill;height:60px;width:60px";
imageHTMLRes.onload = () => { imageHTMLRes.onload = () => {
this.isImageLoaded = true; this.isImageLoaded = true;
} }
imageHTMLRes.onerror = () => { imageHTMLRes.onerror = () => {
if (this.imageFetches < 1) { if (this.imageFetches < 1) {
setTimeout(() => { setTimeout(() => {
this.imageFetches = this.imageFetches + 1; this.imageFetches = this.imageFetches + 1;
@ -2534,23 +2531,23 @@ class TabAvatar extends LitElement {
constructor() { constructor() {
super() super()
this.hasAvatar = false this.hasAvatar = false
this.isImageLoaded = false this.isImageLoaded = false
this.imageFetches = 0 this.imageFetches = 0
} }
createImage(imageUrl) { createImage(imageUrl) {
const imageHTMLRes = new Image(); const imageHTMLRes = new Image();
imageHTMLRes.src = imageUrl; imageHTMLRes.src = imageUrl;
imageHTMLRes.style= "border-radius:4px; font-size:14px; object-fit: fill;height:24px;width:24px"; imageHTMLRes.style= "border-radius:4px; font-size:14px; object-fit: fill;height:24px;width:24px";
imageHTMLRes.onload = () => { imageHTMLRes.onload = () => {
this.isImageLoaded = true; this.isImageLoaded = true;
} }
imageHTMLRes.onerror = () => { imageHTMLRes.onerror = () => {
if (this.imageFetches < 1) { if (this.imageFetches < 1) {
setTimeout(() => { setTimeout(() => {
this.imageFetches = this.imageFetches + 1; this.imageFetches = this.imageFetches + 1;

View File

@ -1,11 +1,11 @@
import { LitElement, html, css } from 'lit'; import {css, html, LitElement} from 'lit';
import { connect } from 'pwa-helpers'; import {connect} from 'pwa-helpers';
import { store } from '../store.js'; import {store} from '../store.js';
import { translate, get } from 'lit-translate'; import {get, translate} from 'lit-translate';
import { asyncReplace } from 'lit/directives/async-replace.js'; import {asyncReplace} from 'lit/directives/async-replace.js';
import '../functional-components/my-button.js'; import '../functional-components/my-button.js';
import { routes } from '../plugins/routes.js'; import {routes} from '../plugins/routes.js';
import "@material/mwc-button" import "@material/mwc-button"
import '@material/mwc-dialog' import '@material/mwc-dialog'
@ -278,7 +278,7 @@ const nonce = selectedAddress && selectedAddress.nonce;
findMintingAccountFromOtherUser.publicKey[0] findMintingAccountFromOtherUser.publicKey[0]
); );
} }
} catch (error) { } catch (error) {
this.errorMsg = this.renderErrorMsg2(); this.errorMsg = this.renderErrorMsg2();
return; return;
@ -344,7 +344,7 @@ const nonce = selectedAddress && selectedAddress.nonce;
const publicAddress = this.base58PublicKey const publicAddress = this.base58PublicKey
const findMintingAccount = mintingAccountData.find((ma) => ma.mintingAccount === address); const findMintingAccount = mintingAccountData.find((ma) => ma.mintingAccount === address);
const isMinterButKeyMintingKeyNotAssigned = addressInfo && addressInfo.error !== 124 && addressInfo.level >= 1 && !findMintingAccount; const isMinterButKeyMintingKeyNotAssigned = addressInfo && addressInfo.error !== 124 && addressInfo.level >= 1 && !findMintingAccount;
const makeTransactionRequest = async (lastRef) => { const makeTransactionRequest = async (lastRef) => {
let mylastRef = lastRef; let mylastRef = lastRef;
let rewarddialog1 = get('transactions.rewarddialog1'); let rewarddialog1 = get('transactions.rewarddialog1');
@ -373,12 +373,12 @@ const nonce = selectedAddress && selectedAddress.nonce;
const getTxnRequestResponse = (txnResponse) => { const getTxnRequestResponse = (txnResponse) => {
let err6string = get('rewardsharepage.rchange21'); let err6string = get('rewardsharepage.rchange21');
if (txnResponse && txnResponse.extraData && txnResponse.extraData.rewardSharePrivateKey && if (txnResponse && txnResponse.extraData && txnResponse.extraData.rewardSharePrivateKey &&
txnResponse.data && (txnResponse.data.message && (txnResponse.data.message.includes('multiple') || txnResponse.data.message.includes('SELF_SHARE_EXISTS')))) { txnResponse.data && (txnResponse.data.message && (txnResponse.data.message.includes('multiple') || txnResponse.data.message.includes('SELF_SHARE_EXISTS')))) {
return err6string; return err6string;
} }
if (txnResponse.success === false && txnResponse.message) { if (txnResponse.success === false && txnResponse.message) {
throw txnResponse; throw txnResponse;
} else if (txnResponse.success === true && txnResponse.data && !txnResponse.data.error) { } else if (txnResponse.success === true && txnResponse.data && !txnResponse.data.error) {
@ -387,19 +387,19 @@ const nonce = selectedAddress && selectedAddress.nonce;
throw txnResponse; throw txnResponse;
} }
}; };
const createSponsorshipKey = async () => { const createSponsorshipKey = async () => {
this.status = 1; this.status = 1;
let lastRef = await getLastRef(); let lastRef = await getLastRef();
let myTransaction = await makeTransactionRequest(lastRef); let myTransaction = await makeTransactionRequest(lastRef);
getTxnRequestResponse(myTransaction); getTxnRequestResponse(myTransaction);
if (myTransaction && myTransaction.extraData) { if (myTransaction && myTransaction.extraData) {
return myTransaction.extraData.rewardSharePrivateKey; return myTransaction.extraData.rewardSharePrivateKey;
} }
}; };
const getLastRef = async () => { const getLastRef = async () => {
const url = `${nodeUrl}/addresses/lastreference/${address}`; const url = `${nodeUrl}/addresses/lastreference/${address}`;
@ -448,7 +448,7 @@ const nonce = selectedAddress && selectedAddress.nonce;
</div> </div>
<!-- Dialog for tracking the progress of starting minting --> <!-- Dialog for tracking the progress of starting minting -->
${this.openDialogRewardShare ? html` ${this.openDialogRewardShare ? html`
<div class="dialogCustom"> <div class="dialogCustom">
<div class="dialogCustomInner"> <div class="dialogCustomInner">
@ -502,7 +502,7 @@ const nonce = selectedAddress && selectedAddress.nonce;
Warning: do not close the Qortal UI until completion! Warning: do not close the Qortal UI until completion!
</p> </p>
<p class="message-error">${this.errorMsg}</p> <p class="message-error">${this.errorMsg}</p>
</div> </div>
</div> </div>
<div class="modalFooter"> <div class="modalFooter">
${this.errorMsg || this.status === 5 ? html` ${this.errorMsg || this.status === 5 ? html`
@ -520,8 +520,8 @@ const nonce = selectedAddress && selectedAddress.nonce;
</div> </div>
</div> </div>
</div> </div>
` : ""} ` : ""}
` : ''} ` : ''}
`; `;
} }

View File

@ -1,5 +1,5 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { get, translate, translateUnsafeHTML } from 'lit-translate' import {translate} from 'lit-translate'
import '@polymer/paper-icon-button/paper-icon-button.js' import '@polymer/paper-icon-button/paper-icon-button.js'
import '@polymer/iron-icons/image-icons.js' import '@polymer/iron-icons/image-icons.js'
import '@polymer/iron-icons/iron-icons.js' import '@polymer/iron-icons/iron-icons.js'

View File

@ -1,8 +1,8 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { render } from 'lit/html.js' import {render} from 'lit/html.js'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../../store.js' import {store} from '../../store.js'
import { get, translate, translateUnsafeHTML } from 'lit-translate' import {get, translate} from 'lit-translate'
import '@polymer/paper-dialog/paper-dialog.js' import '@polymer/paper-dialog/paper-dialog.js'
import '@material/mwc-button' import '@material/mwc-button'
@ -50,11 +50,8 @@ class UserInfoView extends connect(store)(LitElement) {
slicedArray: { type: Array }, slicedArray: { type: Array },
allReceivedPayments: { type: Array }, allReceivedPayments: { type: Array },
allSendPayments: { type: Array }, allSendPayments: { type: Array },
actualBlockheight: { type: Number },
reduceBlockheight: { type: Number },
startMintBlockheight: { type: Number },
startMintTime: { type: String }, startMintTime: { type: String },
startMintBlock: { type: Array }, startMinting: { type: Array },
totalSent: { type: Number }, totalSent: { type: Number },
totalReceived: { type: Number }, totalReceived: { type: Number },
txtimestamp: { type: String }, txtimestamp: { type: String },
@ -357,7 +354,7 @@ class UserInfoView extends connect(store)(LitElement) {
.border-wrapper { .border-wrapper {
border: 1px var(--tradeborder) solid; border: 1px var(--tradeborder) solid;
overflow: hidden; overflow: hidden;
} }
@ -507,11 +504,8 @@ class UserInfoView extends connect(store)(LitElement) {
this.slicedArray = [] this.slicedArray = []
this.allReceivedPayments = [] this.allReceivedPayments = []
this.allSendPayments = [] this.allSendPayments = []
this.actualBlockheight = 0
this.reduceBlockheight = 0
this.startMintBlockheight = 0
this.startMintTime = '' this.startMintTime = ''
this.startMintBlock = [] this.startMinting = []
this.totalSent = 0 this.totalSent = 0
this.totalReceived = 0 this.totalReceived = 0
this.txtimestamp = '' this.txtimestamp = ''
@ -1397,7 +1391,7 @@ class UserInfoView extends connect(store)(LitElement) {
this.displayLevel = this.addressResult.level this.displayLevel = this.addressResult.level
this.isLoadingCompleteInfo = true this.isLoadingCompleteInfo = true
this.shadowRoot.getElementById('userFullInfoDialog').open() this.shadowRoot.getElementById('userFullInfoDialog').open()
await this.getStartMint() await this.getStartMint(myAddress)
await this.getPaymentsGridItems() await this.getPaymentsGridItems()
this.isLoadingCompleteInfo = false this.isLoadingCompleteInfo = false
} }
@ -1449,12 +1443,9 @@ class UserInfoView extends connect(store)(LitElement) {
this.displayBalance = qortalBalanceInfo.toFixed(4) this.displayBalance = qortalBalanceInfo.toFixed(4)
} }
async getStartMint() { async getStartMint(mintAddress) {
this.actualBlockheight = 0
this.reduceBlockheight = 0
this.startMintBlockheight = 0
this.startMintTime = '' this.startMintTime = ''
this.startMintBlock = [] this.startMinting = []
const checkBlocks = this.addressResult.blocksMinted + this.addressResult.blocksMintedAdjustment const checkBlocks = this.addressResult.blocksMinted + this.addressResult.blocksMintedAdjustment
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
@ -1463,24 +1454,15 @@ class UserInfoView extends connect(store)(LitElement) {
let noMinterString = get("explorerpage.exp16") let noMinterString = get("explorerpage.exp16")
this.startMintTime = noMinterString this.startMintTime = noMinterString
} else { } else {
const blockheightUrl = `${nodeUrl}/blocks/height` const rewardshareUrl = `${nodeUrl}/transactions/search?txType=REWARD_SHARE&address=${mintAddress}&confirmationStatus=CONFIRMED&limit=1&reverse=false`
const currentBlockheight = await fetch(blockheightUrl).then(response => { const startMinting = await fetch(rewardshareUrl).then(response => {
return response.json() return response.json()
}) })
this.actualBlockheight = currentBlockheight this.startMinting = startMinting
this.reduceBlockheight = this.addressResult.blocksMinted + this.addressResult.blocksMintedAdjustment
this.startMintBlockheight = (this.actualBlockheight - this.reduceBlockheight)
const startMintUrl = `${nodeUrl}/blocks/byheight/${this.startMintBlockheight}?includeOnlineSignatures=false`
const startMintBlock = await fetch(startMintUrl).then(response => { const mintString = new Date(this.startMinting[0].timestamp).toLocaleDateString()
return response.json()
})
this.startMintBlock = startMintBlock
const mintString = new Date(this.startMintBlock.timestamp).toLocaleDateString()
this.startMintTime = mintString this.startMintTime = mintString
} }
} }
@ -1549,7 +1531,7 @@ class UserInfoView extends connect(store)(LitElement) {
creatorAddress: item.creatorAddress, creatorAddress: item.creatorAddress,
recipient: item.recipient, recipient: item.recipient,
amount: item.amount amount: item.amount
} }
} }
}).filter(item => !!item) }).filter(item => !!item)
@ -1566,7 +1548,7 @@ class UserInfoView extends connect(store)(LitElement) {
creatorAddress: item.creatorAddress, creatorAddress: item.creatorAddress,
recipient: item.recipient, recipient: item.recipient,
amount: item.amount amount: item.amount
} }
} }
}).filter(item => !!item) }).filter(item => !!item)
@ -1612,7 +1594,7 @@ class UserInfoView extends connect(store)(LitElement) {
return { return {
timestamp: item.tradeTimestamp, timestamp: item.tradeTimestamp,
foreignAmount: item.foreignAmount, foreignAmount: item.foreignAmount,
qortAmount: item.qortAmount qortAmount: item.qortAmount
} }
} }
}).filter(item => !!item) }).filter(item => !!item)
@ -1634,7 +1616,7 @@ class UserInfoView extends connect(store)(LitElement) {
return { return {
timestamp: item.tradeTimestamp, timestamp: item.tradeTimestamp,
foreignAmount: item.foreignAmount, foreignAmount: item.foreignAmount,
qortAmount: item.qortAmount qortAmount: item.qortAmount
} }
} }
}).filter(item => !!item) }).filter(item => !!item)
@ -1656,7 +1638,7 @@ class UserInfoView extends connect(store)(LitElement) {
return { return {
timestamp: item.tradeTimestamp, timestamp: item.tradeTimestamp,
foreignAmount: item.foreignAmount, foreignAmount: item.foreignAmount,
qortAmount: item.qortAmount qortAmount: item.qortAmount
} }
} }
}).filter(item => !!item) }).filter(item => !!item)
@ -1678,7 +1660,7 @@ class UserInfoView extends connect(store)(LitElement) {
return { return {
timestamp: item.tradeTimestamp, timestamp: item.tradeTimestamp,
foreignAmount: item.foreignAmount, foreignAmount: item.foreignAmount,
qortAmount: item.qortAmount qortAmount: item.qortAmount
} }
} }
}).filter(item => !!item) }).filter(item => !!item)
@ -1700,7 +1682,7 @@ class UserInfoView extends connect(store)(LitElement) {
return { return {
timestamp: item.tradeTimestamp, timestamp: item.tradeTimestamp,
foreignAmount: item.foreignAmount, foreignAmount: item.foreignAmount,
qortAmount: item.qortAmount qortAmount: item.qortAmount
} }
} }
}).filter(item => !!item) }).filter(item => !!item)
@ -1722,7 +1704,7 @@ class UserInfoView extends connect(store)(LitElement) {
return { return {
timestamp: item.tradeTimestamp, timestamp: item.tradeTimestamp,
foreignAmount: item.foreignAmount, foreignAmount: item.foreignAmount,
qortAmount: item.qortAmount qortAmount: item.qortAmount
} }
} }
}).filter(item => !!item) }).filter(item => !!item)
@ -1744,7 +1726,7 @@ class UserInfoView extends connect(store)(LitElement) {
return { return {
timestamp: item.tradeTimestamp, timestamp: item.tradeTimestamp,
foreignAmount: item.foreignAmount, foreignAmount: item.foreignAmount,
qortAmount: item.qortAmount qortAmount: item.qortAmount
} }
} }
}).filter(item => !!item) }).filter(item => !!item)
@ -1766,7 +1748,7 @@ class UserInfoView extends connect(store)(LitElement) {
return { return {
timestamp: item.tradeTimestamp, timestamp: item.tradeTimestamp,
foreignAmount: item.foreignAmount, foreignAmount: item.foreignAmount,
qortAmount: item.qortAmount qortAmount: item.qortAmount
} }
} }
}).filter(item => !!item) }).filter(item => !!item)
@ -1788,7 +1770,7 @@ class UserInfoView extends connect(store)(LitElement) {
return { return {
timestamp: item.tradeTimestamp, timestamp: item.tradeTimestamp,
foreignAmount: item.foreignAmount, foreignAmount: item.foreignAmount,
qortAmount: item.qortAmount qortAmount: item.qortAmount
} }
} }
}).filter(item => !!item) }).filter(item => !!item)
@ -1810,7 +1792,7 @@ class UserInfoView extends connect(store)(LitElement) {
return { return {
timestamp: item.tradeTimestamp, timestamp: item.tradeTimestamp,
foreignAmount: item.foreignAmount, foreignAmount: item.foreignAmount,
qortAmount: item.qortAmount qortAmount: item.qortAmount
} }
} }
}).filter(item => !!item) }).filter(item => !!item)
@ -1832,7 +1814,7 @@ class UserInfoView extends connect(store)(LitElement) {
return { return {
timestamp: item.tradeTimestamp, timestamp: item.tradeTimestamp,
foreignAmount: item.foreignAmount, foreignAmount: item.foreignAmount,
qortAmount: item.qortAmount qortAmount: item.qortAmount
} }
} }
}).filter(item => !!item) }).filter(item => !!item)
@ -1854,7 +1836,7 @@ class UserInfoView extends connect(store)(LitElement) {
return { return {
timestamp: item.tradeTimestamp, timestamp: item.tradeTimestamp,
foreignAmount: item.foreignAmount, foreignAmount: item.foreignAmount,
qortAmount: item.qortAmount qortAmount: item.qortAmount
} }
} }
}).filter(item => !!item) }).filter(item => !!item)

View File

@ -1,7 +1,7 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../store.js' import {store} from '../store.js'
import { translate, translateUnsafeHTML } from 'lit-translate' import {translate} from 'lit-translate'
import '@polymer/paper-toast' import '@polymer/paper-toast'
import '@material/mwc-icon-button' import '@material/mwc-icon-button'

View File

@ -1,9 +1,9 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import '@material/mwc-button' import '@material/mwc-button'
import '@material/mwc-icon' import '@material/mwc-icon'
import { translate, translateUnsafeHTML } from 'lit-translate' import {translate} from 'lit-translate'
class FragFileInput extends LitElement { class FragFileInput extends LitElement {
static get properties () { static get properties () {

View File

@ -1,4 +1,12 @@
import { Epml, EpmlReadyPlugin, RequestPlugin, ContentWindow as EpmlContentWindowPlugin, EpmlStreamPlugin, EpmlProxyPlugin, EpmlStream } from 'epml' import {
ContentWindow as EpmlContentWindowPlugin,
Epml,
EpmlProxyPlugin,
EpmlReadyPlugin,
EpmlStream,
EpmlStreamPlugin,
RequestPlugin
} from 'epml'
Epml.registerPlugin(RequestPlugin) Epml.registerPlugin(RequestPlugin)
Epml.registerPlugin(EpmlReadyPlugin) Epml.registerPlugin(EpmlReadyPlugin)

View File

@ -1,9 +1,9 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../store.js' import {store} from '../store.js'
import { get, translate, translateUnsafeHTML } from 'lit-translate' import {get, translate} from 'lit-translate'
import { listenForRequest } from '../transactionRequest.js' import {listenForRequest} from '../transactionRequest.js'
import '@polymer/paper-dialog/paper-dialog.js' import '@polymer/paper-dialog/paper-dialog.js'
import '@material/mwc-button' import '@material/mwc-button'

View File

@ -1,4 +1,4 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
const TRANSITION_EVENT_NAMES = ['transitionend', 'webkitTransitionEnd', 'oTransitionEnd', 'MSTransitionEnd'] const TRANSITION_EVENT_NAMES = ['transitionend', 'webkitTransitionEnd', 'oTransitionEnd', 'MSTransitionEnd']
@ -99,7 +99,7 @@ class LoadingRipple extends LitElement {
opacity: 1; opacity: 1;
transition: var(--ripple-activating-transition); transition: var(--ripple-activating-transition);
} }
` `
} }

View File

@ -1,4 +1,4 @@
import { LitElement, html, css } from 'lit'; import {css, html, LitElement} from 'lit';
import '@vaadin/button'; import '@vaadin/button';
import '@polymer/paper-spinner/paper-spinner-lite.js'; import '@polymer/paper-spinner/paper-spinner-lite.js';

View File

@ -1,8 +1,8 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../store.js' import {store} from '../store.js'
import { testApiKey } from '../apiKeyUtils.js' import {testApiKey} from '../apiKeyUtils.js'
import { get, translate, translateUnsafeHTML } from 'lit-translate' import {get, translate} from 'lit-translate'
import '@material/mwc-dialog' import '@material/mwc-dialog'
import '@material/mwc-button' import '@material/mwc-button'

View File

@ -1,7 +1,7 @@
// Author: irontiga <irontiga@gmail.com> // Author: irontiga <irontiga@gmail.com>
'use strict' 'use strict'
import { LitElement, html, css } from 'lit' import {html, LitElement} from 'lit'
import * as WORDLISTS from './wordlists.js' import * as WORDLISTS from './wordlists.js'
class RandomSentenceGenerator extends LitElement { class RandomSentenceGenerator extends LitElement {

View File

@ -1,8 +1,8 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { connect } from 'pwa-helpers' import {connect} from 'pwa-helpers'
import { store } from '../store.js' import {store} from '../store.js'
import { doAddNode, doSetNode, doLoadNodeConfig, doRemoveNode, doEditNode } from '../redux/app/app-actions.js' import {doAddNode, doEditNode, doLoadNodeConfig, doRemoveNode, doSetNode} from '../redux/app/app-actions.js'
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate' import {get, registerTranslateConfig, translate, use} from 'lit-translate'
import snackbar from './snackbar.js' import snackbar from './snackbar.js'
import '../components/language-selector.js' import '../components/language-selector.js'
import '../custom-elements/frag-file-input.js' import '../custom-elements/frag-file-input.js'
@ -36,7 +36,6 @@ class SettingsPage extends connect(store)(LitElement) {
lastSelected: { type: Number }, lastSelected: { type: Number },
nodeConfig: { type: Object }, nodeConfig: { type: Object },
theme: { type: String, reflect: true }, theme: { type: String, reflect: true },
nodeIndex: { type: Number },
isBeingEdited: { type: Boolean }, isBeingEdited: { type: Boolean },
dropdownOpen: { type: Boolean } dropdownOpen: { type: Boolean }
} }
@ -159,14 +158,12 @@ class SettingsPage extends connect(store)(LitElement) {
super() super()
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
this.nodeConfig = {} this.nodeConfig = {}
this.nodeIndex = localStorage.getItem('mySelectedNode')
this.isBeingEdited = false this.isBeingEdited = false
this.isBeingEditedIndex = null this.isBeingEditedIndex = null
this.dropdownOpen = false this.dropdownOpen = false
} }
render() { render() {
this.nodeSelectedOnNewStart()
return html` return html`
<mwc-dialog id="settingsDialog" opened="false"> <mwc-dialog id="settingsDialog" opened="false">
<div style="display: inline; text-align: center;"> <div style="display: inline; text-align: center;">
@ -331,7 +328,7 @@ class SettingsPage extends connect(store)(LitElement) {
firstUpdated() { firstUpdated() {
const checkNode = localStorage.getItem('mySelectedNode') const checkNode = localStorage.getItem('mySelectedNode')
if (checkNode === null || checkNode.length === 0) { if (checkNode === null || checkNode.length === 0) {
localStorage.setItem('mySelectedNode', 0); localStorage.setItem('mySelectedNode', 0)
} else { } else {
this.handleSelectionOnNewStart(checkNode) this.handleSelectionOnNewStart(checkNode)
} }
@ -344,24 +341,6 @@ class SettingsPage extends connect(store)(LitElement) {
this.requestUpdate() this.requestUpdate()
} }
nodeSelectedOnNewStart() {
const selectedNodeIndexOnNewStart = localStorage.getItem('mySelectedNode')
this.catchSavedNodes = JSON.parse(localStorage.getItem('myQortalNodes'))
const selectedNodeOnNewStart = this.catchSavedNodes[selectedNodeIndexOnNewStart]
const selectedNameOnNewStart = `${selectedNodeOnNewStart.name}`
const selectedNodeUrlOnNewStart = `${selectedNodeOnNewStart.protocol + '://' + selectedNodeOnNewStart.domain +':' + selectedNodeOnNewStart.port}`
const index = parseInt(selectedNodeIndexOnNewStart)
if (isNaN(index)) return
const snack0string = get('settings.snack2')
snackbar.add({
labelText: `${snack0string} : ${selectedNameOnNewStart} ${selectedNodeUrlOnNewStart}`,
dismiss: true
})
}
toggleDropdown() { toggleDropdown() {
this.dropdownOpen = !this.dropdownOpen this.dropdownOpen = !this.dropdownOpen
} }
@ -387,6 +366,19 @@ class SettingsPage extends connect(store)(LitElement) {
this.requestUpdate() this.requestUpdate()
this.nodeSelected(index) this.nodeSelected(index)
localStorage.setItem('mySelectedNode', index) localStorage.setItem('mySelectedNode', index)
const selectedNodeIndexOnNewStart = localStorage.getItem('mySelectedNode')
const catchSavedNodes = JSON.parse(localStorage.getItem('myQortalNodes'))
const selectedNodeOnNewStart = catchSavedNodes[selectedNodeIndexOnNewStart]
const selectedNameOnNewStart = `${selectedNodeOnNewStart.name}`
const selectedNodeUrlOnNewStart = `${selectedNodeOnNewStart.protocol + '://' + selectedNodeOnNewStart.domain +':' + selectedNodeOnNewStart.port}`
let snack2string = get('settings.snack2')
snackbar.add({
labelText: `${snack2string} : ${selectedNameOnNewStart} ${selectedNodeUrlOnNewStart}`,
dismiss: true
})
} }
show() { show() {
@ -444,16 +436,11 @@ class SettingsPage extends connect(store)(LitElement) {
localStorage.removeItem('mySelectedNode'); localStorage.removeItem('mySelectedNode');
localStorage.setItem('mySelectedNode', selectedNodeIndex) localStorage.setItem('mySelectedNode', selectedNodeIndex)
let snack2string = get('settings.snack2')
snackbar.add({
labelText: `${snack2string} : ${selectedName} ${selectedNodeUrl}`,
dismiss: true
})
} }
addNode(e) { addNode(e) {
e.stopPropagation() e.stopPropagation()
if (this.isBeingEdited) { if (this.isBeingEdited) {
this.editNode(this.isBeingEditedIndex) this.editNode(this.isBeingEditedIndex)
return return
@ -517,13 +504,15 @@ class SettingsPage extends connect(store)(LitElement) {
removeNode(event, index) { removeNode(event, index) {
event.stopPropagation() event.stopPropagation()
let stored = JSON.parse(localStorage.getItem('myQortalNodes')) let stored = JSON.parse(localStorage.getItem('myQortalNodes'))
stored.splice(index, 1) stored.splice(index, 1)
localStorage.setItem('myQortalNodes', JSON.stringify(stored)) localStorage.setItem('myQortalNodes', JSON.stringify(stored))
store.dispatch(doRemoveNode(index)); store.dispatch(doRemoveNode(index))
let snack3string = get('settings.snack6')
let snack6string = get('settings.snack6')
snackbar.add({ snackbar.add({
labelText: `${snack3string}`, labelText: `${snack6string}`,
dismiss: true dismiss: true
}) })
@ -550,11 +539,13 @@ class SettingsPage extends connect(store)(LitElement) {
copyStored[index] = nodeObject copyStored[index] = nodeObject
localStorage.setItem('myQortalNodes', JSON.stringify(copyStored)) localStorage.setItem('myQortalNodes', JSON.stringify(copyStored))
store.dispatch(doEditNode(index, nodeObject)) store.dispatch(doEditNode(index, nodeObject))
let snack3string = get('settings.snack7')
let snack7string = get('settings.snack7')
snackbar.add({ snackbar.add({
labelText: `${snack3string}`, labelText: `${snack7string}`,
dismiss: true dismiss: true
}) })
this.shadowRoot.getElementById('nameInput').value = '' this.shadowRoot.getElementById('nameInput').value = ''
this.shadowRoot.getElementById('protocolList').value = '' this.shadowRoot.getElementById('protocolList').value = ''
this.shadowRoot.getElementById('domainInput').value = '' this.shadowRoot.getElementById('domainInput').value = ''
@ -587,14 +578,14 @@ class SettingsPage extends connect(store)(LitElement) {
} }
exportQortalNodesList() { exportQortalNodesList() {
let nodelist = ''; let nodelist = ''
const qortalNodesList = JSON.stringify( const qortalNodesList = JSON.stringify(
localStorage.getItem('myQortalNodes') localStorage.getItem('myQortalNodes')
); );
const qortalNodesListSave = JSON.parse(qortalNodesList || '[]') const qortalNodesListSave = JSON.parse(qortalNodesList || '[]')
const blob = new Blob([qortalNodesListSave], { const blob = new Blob([qortalNodesListSave], {
type: 'text/plain;charset=utf-8', type: 'text/plain;charset=utf-8',
}); })
nodelist = 'qortal.nodes' nodelist = 'qortal.nodes'
this.saveFileToDisk(blob, nodelist) this.saveFileToDisk(blob, nodelist)
} }
@ -611,8 +602,9 @@ class SettingsPage extends connect(store)(LitElement) {
const writable = await fileHandle.createWritable() const writable = await fileHandle.createWritable()
await writable.write(contents) await writable.write(contents)
await writable.close() await writable.close()
}; }
writeFile(fileHandle, blob).then(() => console.log('FILE SAVED')); writeFile(fileHandle, blob).then(() => console.log('FILE SAVED'))
let snack4string = get('settings.snack4') let snack4string = get('settings.snack4')
snackbar.add({ snackbar.add({
labelText: `${snack4string} qortal.nodes`, labelText: `${snack4string} qortal.nodes`,
@ -633,7 +625,8 @@ class SettingsPage extends connect(store)(LitElement) {
unelevated unelevated
label="${translate('settings.import')}" label="${translate('settings.import')}"
@click="${() => this.openImportNodesDialog()}" @click="${() => this.openImportNodesDialog()}"
></mwc-button> >
</mwc-button>
` `
} }
@ -647,7 +640,7 @@ class SettingsPage extends connect(store)(LitElement) {
snackbar.add({ snackbar.add({
labelText: `${snack5string}`, labelText: `${snack5string}`,
dismiss: true, dismiss: true,
}); })
localStorage.removeItem('mySelectedNode') localStorage.removeItem('mySelectedNode')
localStorage.setItem('mySelectedNode', 0) localStorage.setItem('mySelectedNode', 0)
@ -656,8 +649,8 @@ class SettingsPage extends connect(store)(LitElement) {
} }
stateChanged(state) { stateChanged(state) {
this.config = state.config; this.config = state.config
this.nodeConfig = state.app.nodeConfig; this.nodeConfig = state.app.nodeConfig
} }
} }

View File

@ -1,4 +1,4 @@
import { css } from 'lit' import {css} from 'lit'
export const sideMenuItemStyle = css` export const sideMenuItemStyle = css`
:host { :host {
@ -21,7 +21,7 @@ export const sideMenuItemStyle = css`
--overlay-box-shadow: 0 2px 4px -1px hsla(214, 53%, 23%, 0.16), 0 3px 12px -1px hsla(214, 50%, 22%, 0.26); --overlay-box-shadow: 0 2px 4px -1px hsla(214, 53%, 23%, 0.16), 0 3px 12px -1px hsla(214, 50%, 22%, 0.26);
--overlay-background-color: #ffffff; --overlay-background-color: #ffffff;
--spacing: 4px; --spacing: 4px;
font-family: var(--font-family); font-family: var(--font-family);
@ -86,7 +86,7 @@ export const sideMenuItemStyle = css`
:host([expanded]){ :host([expanded]){
background-color: var(--item-selected-color); background-color: var(--item-selected-color);
} }
:host([hasSelectedChild]){ :host([hasSelectedChild]){
background-color: var(--item-selected-color); background-color: var(--item-selected-color);
} }
@ -109,7 +109,7 @@ export const sideMenuItemStyle = css`
} }
#collapse-button { #collapse-button {
float: right; float: right;
} }
:host([compact]) #itemLink[level]:not([level="0"]) { :host([compact]) #itemLink[level]:not([level="0"]) {
@ -143,7 +143,7 @@ export const sideMenuItemStyle = css`
z-index: 1; z-index: 1;
animation: pop 200ms forwards; animation: pop 200ms forwards;
} }
@keyframes pop{ @keyframes pop{
0% { 0% {
transform: translateX(-5px); transform: translateX(-5px);

View File

@ -1,6 +1,6 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import { ifDefined } from 'lit/directives/if-defined.js' import {ifDefined} from 'lit/directives/if-defined.js'
import { sideMenuItemStyle } from './side-menu-item-style.js' import {sideMenuItemStyle} from './side-menu-item-style.js'
import '@vaadin/icon' import '@vaadin/icon'
import '@vaadin/icons' import '@vaadin/icons'
import '@polymer/paper-tooltip' import '@polymer/paper-tooltip'
@ -50,8 +50,8 @@ export class SideMenuItem extends LitElement {
_itemLinkTemplate() { _itemLinkTemplate() {
return html` return html`
<a id="itemLink" <a id="itemLink"
level=${this._getLevel} level=${this._getLevel}
href=${this.href || '#!'} href=${this.href || '#!'}
@click="${(e) => this._onClick(e)}" @click="${(e) => this._onClick(e)}"
target=${ifDefined(this.target)} target=${ifDefined(this.target)}

View File

@ -1,4 +1,4 @@
import {LitElement, html, css} from 'lit' import {css, html, LitElement} from 'lit'
class SideMenu extends LitElement { class SideMenu extends LitElement {
static get properties() { static get properties() {

View File

@ -1,4 +1,4 @@
import { LitElement, html, css } from 'lit' import {css, html, LitElement} from 'lit'
import '@material/mwc-snackbar' import '@material/mwc-snackbar'
let queueElement let queueElement

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,11 @@
import { store } from './store.js' import {store} from './store.js'
import { doLoadConfigFromAPI } from './redux/config/config-actions.js' import {doLoadConfigFromAPI} from './redux/config/config-actions.js'
import { doLoadNodeConfig, doInitWorkers } from './redux/app/app-actions.js' import {doInitWorkers, doLoadNodeConfig} from './redux/app/app-actions.js'
import { doLoadNotificationConfig } from './redux/user/user-actions.js' import {doLoadNotificationConfig} from './redux/user/user-actions.js'
import './persistState.js' import './persistState.js'
import { initApi } from 'qortal-ui-crypto' import {initApi} from 'qortal-ui-crypto'
initApi(store) initApi(store)

View File

@ -1,6 +1,6 @@
import CryptoJS from 'crypto-js' import CryptoJS from 'crypto-js'
export const encryptData = (data, salt) => CryptoJS.AES.encrypt(JSON.stringify(data), salt).toString() export const encryptData = (data, salt) => CryptoJS.AES.encrypt(JSON.stringify(data), salt).toString()
export const decryptData = (ciphertext, salt) => { export const decryptData = (ciphertext, salt) => {
const bytes = CryptoJS.AES.decrypt(ciphertext, salt) const bytes = CryptoJS.AES.decrypt(ciphertext, salt)
try { try {
@ -8,4 +8,4 @@ export const decryptData = (ciphertext, salt) => {
} catch(err) { } catch(err) {
return null return null
} }
} }

View File

@ -1,7 +1,7 @@
import config from './config' import config from './config'
import { dispatcher } from './dispatcher' import {dispatcher} from './dispatcher'
import snackbar from '../functional-components/snackbar.js' import snackbar from '../functional-components/snackbar.js'
import { NEW_MESSAGE, NEW_MESSAGE_NOTIFICATION_QAPP, NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL } from './types' import {NEW_MESSAGE, NEW_MESSAGE_NOTIFICATION_QAPP, NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL} from './types'
let initial = 0 let initial = 0
let _state let _state
@ -44,7 +44,7 @@ const notificationCheck = function () {
export const doNewMessage = function (req) { export const doNewMessage = function (req) {
const newMessage = () => { const newMessage = () => {
let data let data
if (req.type && req.type === 'qapp') { if (req.type && req.type === 'qapp') {
data = req data = req
@ -73,7 +73,7 @@ export const doNewMessage = function (req) {
} else { } else {
_state = notificationState _state = notificationState
} }
} }
const page = window.top.location.href const page = window.top.location.href
if(req.type && req.type === 'qapp-local-notification'){ if(req.type && req.type === 'qapp-local-notification'){
try { try {

View File

@ -1,5 +1,5 @@
import { NEW_MESSAGE, NEW_MESSAGE_NOTIFICATION_QAPP, NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL } from './types' import {NEW_MESSAGE, NEW_MESSAGE_NOTIFICATION_QAPP, NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL} from './types'
import { newMessage, newMessageNotificationQapp, newMessageNotificationQappLocal } from './notification-actions' import {newMessage, newMessageNotificationQapp, newMessageNotificationQappLocal} from './notification-actions'
export const dispatcher = function (notificationState) { export const dispatcher = function (notificationState) {

View File

@ -1,5 +1,5 @@
import { store } from '../../store.js' import {store} from '../../store.js'
import { doPageUrl, setNewTab } from '../../redux/app/app-actions.js' import {doPageUrl, setNewTab} from '../../redux/app/app-actions.js'
import isElectron from 'is-electron' import isElectron from 'is-electron'
import ShortUniqueId from 'short-unique-id'; import ShortUniqueId from 'short-unique-id';

View File

@ -1,5 +1,5 @@
import { store } from './store.js' import {store} from './store.js'
import { saveStateToLocalStorage } from './localStorageHelpers.js' import {saveStateToLocalStorage} from './localStorageHelpers.js'
const keys = [ const keys = [
'config', 'config',

View File

@ -1,4 +1,4 @@
import { routes } from './routes.js' import {routes} from './routes.js'
export const addPluginRoutes = epmlInstance => { export const addPluginRoutes = epmlInstance => {
Object.entries(routes).forEach(([route, handler]) => { Object.entries(routes).forEach(([route, handler]) => {

View File

@ -1,7 +1,7 @@
import { store } from '../store.js' import {store} from '../store.js'
import { Epml } from '../epml.js' import {Epml} from '../epml.js'
import { addPluginRoutes } from './addPluginRoutes' import {addPluginRoutes} from './addPluginRoutes'
import { doAddPlugin } from '../redux/app/app-actions.js' import {doAddPlugin} from '../redux/app/app-actions.js'
let retryLoadPluginsInterval = 0 let retryLoadPluginsInterval = 0
export const loadPlugins = () => fetch('/getPlugins') export const loadPlugins = () => fetch('/getPlugins')

View File

@ -1,5 +1,5 @@
'use strict' 'use strict'
import { Epml, EpmlStream } from '../epml.js' import {Epml, EpmlStream} from '../epml.js'
window.Epml = Epml window.Epml = Epml
window.EpmlStream = EpmlStream window.EpmlStream = EpmlStream

View File

@ -1,22 +1,19 @@
import { store } from '../store.js' import {store} from '../store.js'
import { import {
doAddPluginUrl, doAddPluginUrl,
doUpdateBlockInfo,
doUpdateNodeStatus,
doUpdateNodeInfo,
doSetNode,
doPageUrl, doPageUrl,
doSetChatHeads, doSetChatHeads,
doSetNode,
doUpdateAccountInfo, doUpdateAccountInfo,
doUpdateBlockInfo,
doUpdateNodeInfo,
doUpdateNodeStatus,
} from '../redux/app/app-actions.js' } from '../redux/app/app-actions.js'
import * as api from 'qortal-ui-crypto' import * as api from 'qortal-ui-crypto'
import { requestTransactionDialog } from '../functional-components/confirm-transaction-dialog.js' import {requestTransactionDialog} from '../functional-components/confirm-transaction-dialog.js'
import { doNewMessage } from '../notifications/controller.js' import {doNewMessage} from '../notifications/controller.js'
import snackbar from '../functional-components/snackbar.js' import snackbar from '../functional-components/snackbar.js'
import { import {loadStateFromLocalStorage, saveStateToLocalStorage,} from '../localStorageHelpers.js'
loadStateFromLocalStorage,
saveStateToLocalStorage,
} from '../localStorageHelpers.js'
const createTransaction = api.createTransaction const createTransaction = api.createTransaction
const processTransaction = api.processTransaction const processTransaction = api.processTransaction
@ -128,13 +125,13 @@ export const routes = {
if(!req.data.apiVersion){ if(!req.data.apiVersion){
res = await processTransaction(tx.signedBytes) res = await processTransaction(tx.signedBytes)
} }
let extraData = {} let extraData = {}
if(req.data.type === 38 && tx && tx._rewardShareKeyPair && tx._rewardShareKeyPair.secretKey){ if(req.data.type === 38 && tx && tx._rewardShareKeyPair && tx._rewardShareKeyPair.secretKey){
extraData.rewardSharePrivateKey = Base58.encode(tx._rewardShareKeyPair.secretKey) extraData.rewardSharePrivateKey = Base58.encode(tx._rewardShareKeyPair.secretKey)
} }
response = { response = {
success: true, success: true,
data: res, data: res,
@ -182,8 +179,8 @@ export const routes = {
if(!req.data.apiVersion){ if(!req.data.apiVersion){
res = await processTransaction(tx.signedBytes) res = await processTransaction(tx.signedBytes)
} }
response = { response = {
success: true, success: true,
data: res, data: res,
@ -234,7 +231,7 @@ export const routes = {
req.data.chatNonce, req.data.chatNonce,
store.getState().app.wallet._addresses[req.data.nonce].keyPair store.getState().app.wallet._addresses[req.data.nonce].keyPair
) )
let res let res
if(req.data.apiVersion && req.data.apiVersion === 2){ if(req.data.apiVersion && req.data.apiVersion === 2){
@ -243,7 +240,7 @@ export const routes = {
if(!req.data.apiVersion){ if(!req.data.apiVersion){
res = await processTransaction(signedChatBytes) res = await processTransaction(signedChatBytes)
} }
response = res response = res
} catch (e) { } catch (e) {
console.error(e) console.error(e)
@ -270,7 +267,7 @@ export const routes = {
if(!req.data.apiVersion){ if(!req.data.apiVersion){
res = await processTransaction(signedArbitraryBytes) res = await processTransaction(signedArbitraryBytes)
} }
response = res response = res
} catch (e) { } catch (e) {
console.error(e) console.error(e)
@ -296,7 +293,7 @@ export const routes = {
if(!req.data.apiVersion){ if(!req.data.apiVersion){
res = await processTransaction(signedArbitraryBytes) res = await processTransaction(signedArbitraryBytes)
} }
response = res response = res
} catch (e) { } catch (e) {
console.error(e) console.error(e)
@ -366,7 +363,7 @@ export const routes = {
unsignedTxn, unsignedTxn,
store.getState().app.selectedAddress.keyPair store.getState().app.selectedAddress.keyPair
) )
let res let res
if(req.data.apiVersion && req.data.apiVersion === 2){ if(req.data.apiVersion && req.data.apiVersion === 2){

View File

@ -1,5 +1,5 @@
import { store } from '../store.js' import {store} from '../store.js'
import { EpmlStream } from 'epml' import {EpmlStream} from 'epml'
const LOGIN_STREAM_NAME = 'logged_in' const LOGIN_STREAM_NAME = 'logged_in'
const CONFIG_STREAM_NAME = 'config' const CONFIG_STREAM_NAME = 'config'
@ -10,6 +10,7 @@ const NODE_CONFIG_STREAM_NAME = 'node_config'
const CHAT_LAST_SEEN = 'chat_last_seen' const CHAT_LAST_SEEN = 'chat_last_seen'
const SIDE_EFFECT_ACTION = 'side_effect_action' const SIDE_EFFECT_ACTION = 'side_effect_action'
const PROFILE_DATA_ACTION = 'profile_data_action' const PROFILE_DATA_ACTION = 'profile_data_action'
const COIN_BALANCES_ACTION = 'coin_balances'
export const loggedInStream = new EpmlStream(LOGIN_STREAM_NAME, () => store.getState().app.loggedIn) export const loggedInStream = new EpmlStream(LOGIN_STREAM_NAME, () => store.getState().app.loggedIn)
export const configStream = new EpmlStream(CONFIG_STREAM_NAME, () => store.getState().config) export const configStream = new EpmlStream(CONFIG_STREAM_NAME, () => store.getState().config)
@ -20,6 +21,8 @@ export const nodeConfigStream = new EpmlStream(NODE_CONFIG_STREAM_NAME, () => st
export const chatLastSeenStream = new EpmlStream(CHAT_LAST_SEEN, () => store.getState().app.chatLastSeen) export const chatLastSeenStream = new EpmlStream(CHAT_LAST_SEEN, () => store.getState().app.chatLastSeen)
export const sideEffectActionStream = new EpmlStream(SIDE_EFFECT_ACTION, () => store.getState().app.sideEffectAction) export const sideEffectActionStream = new EpmlStream(SIDE_EFFECT_ACTION, () => store.getState().app.sideEffectAction)
export const profileDataActionStream = new EpmlStream(SIDE_EFFECT_ACTION, () => store.getState().app.profileData) export const profileDataActionStream = new EpmlStream(SIDE_EFFECT_ACTION, () => store.getState().app.profileData)
export const coinBalancesActionStream = new EpmlStream(COIN_BALANCES_ACTION, () => store.getState().app.coinBalances)
@ -67,6 +70,10 @@ store.subscribe(() => {
if(oldState.app.profileDataActionStream !== state.app.profileDataActionStream){ if(oldState.app.profileDataActionStream !== state.app.profileDataActionStream){
profileDataActionStream.emit(state.app.profileData) profileDataActionStream.emit(state.app.profileData)
} }
if (oldState.app.coinBalances !== state.app.coinBalances) {
coinBalancesActionStream.emit(state.app.coinBalances)
}
oldState = state oldState = state
}) })

View File

@ -1,5 +1,27 @@
// Core App Actions here... // Core App Actions here...
import { UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, CHAT_HEADS, ACCOUNT_INFO, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, ALLOW_QAPP_AUTO_AUTH, REMOVE_QAPP_AUTO_AUTH, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN, ALLOW_QAPP_AUTO_LISTS, REMOVE_QAPP_AUTO_LISTS, SET_NEW_TAB, ADD_TAB_INFO, SET_TAB_NOTIFICATIONS, IS_OPEN_DEV_DIALOG, SET_NEW_NOTIFICATION, SET_SIDE_EFFECT, SET_PROFILE_DATA } from '../app-action-types.js' import {
ACCOUNT_INFO,
ADD_AUTO_LOAD_IMAGES_CHAT,
ADD_CHAT_LAST_SEEN,
ADD_TAB_INFO,
ALLOW_QAPP_AUTO_AUTH,
ALLOW_QAPP_AUTO_LISTS,
CHAT_HEADS,
IS_OPEN_DEV_DIALOG,
REMOVE_AUTO_LOAD_IMAGES_CHAT,
REMOVE_QAPP_AUTO_AUTH,
REMOVE_QAPP_AUTO_LISTS,
SET_CHAT_LAST_SEEN,
SET_COIN_BALANCES,
SET_NEW_NOTIFICATION,
SET_NEW_TAB,
SET_SIDE_EFFECT,
SET_TAB_NOTIFICATIONS,
UPDATE_BLOCK_INFO,
UPDATE_NODE_INFO,
UPDATE_NODE_STATUS,
SET_PROFILE_DATA
} from '../app-action-types.js'
export const doUpdateBlockInfo = (blockObj) => { export const doUpdateBlockInfo = (blockObj) => {
return (dispatch, getState) => { return (dispatch, getState) => {
@ -163,4 +185,11 @@ export const setProfileData = (payload)=> {
type: SET_PROFILE_DATA, type: SET_PROFILE_DATA,
payload payload
} }
} }
export const setCoinBalances = (payload)=> {
return {
type: SET_COIN_BALANCES,
payload
}
}

View File

@ -1,7 +1,8 @@
import { Epml } from '../../../epml.js' import {Epml} from '../../../epml.js'
import { EpmlWorkerPlugin } from 'epml' import {EpmlWorkerPlugin} from 'epml'
import {INIT_WORKERS} from '../app-action-types.js'
import { INIT_WORKERS } from '../app-action-types.js'
Epml.registerPlugin(EpmlWorkerPlugin) Epml.registerPlugin(EpmlWorkerPlugin)
export const doInitWorkers = (numberOfWorkers, workerURL) => { export const doInitWorkers = (numberOfWorkers, workerURL) => {

View File

@ -1,4 +1,4 @@
import { LOG_IN, LOG_OUT, SELECT_ADDRESS } from '../app-action-types.js' import {LOG_IN, LOG_OUT, SELECT_ADDRESS} from '../app-action-types.js'
export const doSelectAddress = address => { export const doSelectAddress = address => {
return (dispatch, getState) => { return (dispatch, getState) => {

View File

@ -1,6 +1,6 @@
// Node Config Actions here... // Node Config Actions here...
import { LOAD_NODE_CONFIG, SET_NODE, ADD_NODE, REMOVE_NODE, EDIT_NODE } from '../app-action-types.js' import {ADD_NODE, EDIT_NODE, LOAD_NODE_CONFIG, REMOVE_NODE, SET_NODE} from '../app-action-types.js'
import { UI_VERSION } from '../version.js' import {UI_VERSION} from '../version.js'
const nodeConfigUrl = '/getConfig' const nodeConfigUrl = '/getConfig'

View File

@ -1,4 +1,4 @@
import { ADD_PLUGIN, ADD_PLUGIN_URL, PAGE_URL } from '../app-action-types.js' import {ADD_PLUGIN, ADD_PLUGIN_URL, PAGE_URL} from '../app-action-types.js'
export const doAddPluginUrl = (pluginUrlsConf) => { export const doAddPluginUrl = (pluginUrlsConf) => {
return (dispatch, getState) => { return (dispatch, getState) => {

View File

@ -34,3 +34,4 @@ export const IS_OPEN_DEV_DIALOG = 'IS_OPEN_DEV_DIALOG'
export const SET_NEW_NOTIFICATION = 'SET_NEW_NOTIFICATION' export const SET_NEW_NOTIFICATION = 'SET_NEW_NOTIFICATION'
export const SET_SIDE_EFFECT= 'SET_SIDE_EFFECT' export const SET_SIDE_EFFECT= 'SET_SIDE_EFFECT'
export const SET_PROFILE_DATA = 'SET_PROFILE_DATA' export const SET_PROFILE_DATA = 'SET_PROFILE_DATA'
export const SET_COIN_BALANCES= 'SET_COIN_BALANCES'

View File

@ -1,4 +1,4 @@
import { NAVIGATE, NETWORK_CONNECTION_STATUS } from './app-action-types.js' import {NAVIGATE, NETWORK_CONNECTION_STATUS} from './app-action-types.js'
export * from './actions/login.js' export * from './actions/login.js'
export * from './actions/init-worker.js' export * from './actions/init-worker.js'

View File

@ -1,10 +1,48 @@
// Loading state, login state, isNavDrawOpen state etc. None of this needs to be saved to localstorage. // Loading state, login state, isNavDrawOpen state etc. None of this needs to be saved to localstorage.
import { loadStateFromLocalStorage, saveStateToLocalStorage } from '../../localStorageHelpers.js' import {loadStateFromLocalStorage, saveStateToLocalStorage} from '../../localStorageHelpers.js'
import { LOG_IN, LOG_OUT, NETWORK_CONNECTION_STATUS, INIT_WORKERS, ADD_PLUGIN_URL, ADD_PLUGIN, ADD_NEW_PLUGIN_URL, NAVIGATE, SELECT_ADDRESS, ACCOUNT_INFO, CHAT_HEADS, UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, LOAD_NODE_CONFIG, SET_NODE, ADD_NODE, PAGE_URL, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, ALLOW_QAPP_AUTO_AUTH, REMOVE_QAPP_AUTO_AUTH, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN, ALLOW_QAPP_AUTO_LISTS, REMOVE_QAPP_AUTO_LISTS, SET_NEW_TAB, ADD_TAB_INFO, SET_TAB_NOTIFICATIONS, IS_OPEN_DEV_DIALOG, REMOVE_NODE, EDIT_NODE, SET_NEW_NOTIFICATION, SET_SIDE_EFFECT, SET_PROFILE_DATA } from './app-action-types.js' import {
import { initWorkersReducer } from './reducers/init-workers.js' ACCOUNT_INFO,
import { loginReducer } from './reducers/login-reducer.js' ADD_AUTO_LOAD_IMAGES_CHAT,
import { setNode, addNode, removeNode, editNode } from './reducers/manage-node.js' ADD_CHAT_LAST_SEEN,
ADD_NEW_PLUGIN_URL,
ADD_NODE,
ADD_PLUGIN,
ADD_PLUGIN_URL,
ADD_TAB_INFO,
ALLOW_QAPP_AUTO_AUTH,
ALLOW_QAPP_AUTO_LISTS,
CHAT_HEADS,
EDIT_NODE,
INIT_WORKERS,
IS_OPEN_DEV_DIALOG,
LOAD_NODE_CONFIG,
LOG_IN,
LOG_OUT,
NAVIGATE,
NETWORK_CONNECTION_STATUS,
PAGE_URL,
REMOVE_AUTO_LOAD_IMAGES_CHAT,
REMOVE_NODE,
REMOVE_QAPP_AUTO_AUTH,
REMOVE_QAPP_AUTO_LISTS,
SELECT_ADDRESS,
SET_CHAT_LAST_SEEN,
SET_COIN_BALANCES,
SET_NEW_NOTIFICATION,
SET_NEW_TAB,
SET_NODE,
SET_SIDE_EFFECT,
SET_TAB_NOTIFICATIONS,
UPDATE_BLOCK_INFO,
UPDATE_NODE_INFO,
UPDATE_NODE_STATUS,
SET_PROFILE_DATA
} from './app-action-types.js'
import {initWorkersReducer} from './reducers/init-workers.js'
import {loginReducer} from './reducers/login-reducer.js'
import {addNode, editNode, removeNode, setNode} from './reducers/manage-node.js'
import localForage from "localforage"; import localForage from "localforage";
const chatLastSeen = localForage.createInstance({ const chatLastSeen = localForage.createInstance({
name: "chat-last-seen", name: "chat-last-seen",
}); });
@ -53,7 +91,8 @@ const INITIAL_STATE = {
isOpenDevDialog: false, isOpenDevDialog: false,
newNotification: null, newNotification: null,
sideEffectAction: null, sideEffectAction: null,
profileData: null profileData: null,
coinBalances: {}
} }
export default (state = INITIAL_STATE, action) => { export default (state = INITIAL_STATE, action) => {
@ -71,7 +110,7 @@ export default (state = INITIAL_STATE, action) => {
wallet: INITIAL_STATE.wallet, wallet: INITIAL_STATE.wallet,
selectedAddress: INITIAL_STATE.selectedAddress, selectedAddress: INITIAL_STATE.selectedAddress,
accountInfo: INITIAL_STATE.accountInfo accountInfo: INITIAL_STATE.accountInfo
} }
case ADD_PLUGIN: case ADD_PLUGIN:
return { return {
@ -300,6 +339,17 @@ export default (state = INITIAL_STATE, action) => {
profileData: action.payload profileData: action.payload
} }
} }
case SET_COIN_BALANCES: {
const copyBalances = {...state.coinBalances}
copyBalances[action.payload.type] = {
value: action.payload.value,
fullValue: action.payload.fullValue
}
return {
...state,
coinBalances: copyBalances
}
}
default: default:
return state return state

View File

@ -1,8 +1,8 @@
// Must be saved to localstorage. Will storage things such as saved addresses and themes (day/night mode) etc. // Must be saved to localstorage. Will storage things such as saved addresses and themes (day/night mode) etc.
// Initial state needs to be loaded from either the getConfig url or localstorage...NOT set via this // Initial state needs to be loaded from either the getConfig url or localstorage...NOT set via this
import { loadStateFromLocalStorage } from '../../localStorageHelpers' import {loadStateFromLocalStorage} from '../../localStorageHelpers'
import { LOAD_CONFIG_FROM_API } from './config-actions.js' import {LOAD_CONFIG_FROM_API} from './config-actions.js'
import { loadConfigFromAPI } from './reducers/load-config-from-api.js' import {loadConfigFromAPI} from './reducers/load-config-from-api.js'
const DEFAULT_INITIAL_STATE = { const DEFAULT_INITIAL_STATE = {
styles: { styles: {

View File

@ -1,4 +1,4 @@
import { combineReducers } from 'redux' import {combineReducers} from 'redux'
import app from './app/app-reducer.js' import app from './app/app-reducer.js'
import config from './config/config-reducer.js' import config from './config/config-reducer.js'

View File

@ -1,4 +1,4 @@
import { CLAIM_AIRDROP } from '../user-action-types.js' import {CLAIM_AIRDROP} from '../user-action-types.js'
export const doClaimAirdrop = (address) => { export const doClaimAirdrop = (address) => {
return (dispatch, getState) => { return (dispatch, getState) => {

View File

@ -1,5 +1,4 @@
import {LOAD_NOTIFICATION_CONFIG, SET_QCHAT_NOTIFICATION_CONFIG} from '../user-action-types.js'
import { LOAD_NOTIFICATION_CONFIG, SET_QCHAT_NOTIFICATION_CONFIG } from '../user-action-types.js'
const configUrl = '/getConfig' const configUrl = '/getConfig'

Some files were not shown because too many files have changed in this diff Show More