4
1
mirror of https://github.com/Qortal/qortal-ui.git synced 2025-02-11 17:55:51 +00:00

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/>
``` nvm ls-remote ``` (Fetch list of available versions) <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.

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

View File

@ -5,6 +5,7 @@
"chinese1": "Chinesisch (vereinfacht)",
"chinese2": "Chinesisch (traditionell)",
"croatian": "Kroatisch",
"dutch": "Niederländisch",
"english": "Englisch",
"estonian": "Estnisch",
"french": "Französisch",
@ -153,11 +154,11 @@
"lp18": "Schlüsselteile ableiten",
"lp19": "Fehler, falscher Schlüssel. ",
"lp20": "Fehler, falsche Nonce",
"lp21": "Wichtige Teile kombinieren",
"lp21": "Schlüsselteile kombinieren",
"lp22": "Schlüssel ist bereit"
},
"logout": {
"logout": "AUSLOGGEN",
"logout": "ABMELDEN",
"confirmlogout": "Möchten Sie sich wirklich abmelden?"
},
"fragfile": {
@ -195,7 +196,7 @@
"export": "Knoten Exportieren",
"deletecustomnode": "Alle benutzerdefinierten Knoten entfernen",
"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",
"snack3": "Benutzerdefinierter Knoten erfolgreich hinzugefügt und gespeichert",
"snack4": "Knoten erfolgreich gespeichert als",
@ -387,7 +388,7 @@
"wchange45": "Sende alle",
"wchange46": "An diese Adresse verschicken",
"wchange47": "Adressbuch",
"wchange48": "Dieses Adressbuch ist leer !",
"wchange48": "Dieses Adressbuch ist leer!",
"wchange49": "Zum Adressbuch hinzufügen",
"wchange50": "Der Name darf nicht leer sein!",
"wchange51": "Adresse darf nicht leer sein!",
@ -621,7 +622,7 @@
"schange12": "Verfolgte Q-Tubes",
"schange13": "Du folgst keinen Q-Tubes",
"schange14": "Ihre blockierten Q-Tubes",
"schange15": "Blockierte Q-Röhren",
"schange15": "Blockierte Q-Tubes",
"schange16": "Sie haben keine Q-Tubes blockiert",
"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",
@ -727,7 +728,8 @@
"bchange45": "Verschlüsseln",
"bchange46": "Geben Sie dieser Anwendung die Erlaubnis, die folgende Datei zu speichern?",
"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": {
"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!",
"cchange43": "Tipp QORT an",
"cchange44": "NACHRICHT SENDEN",
"cchange45": "TIP BENUTZER",
"cchange45": "TIPP BENUTZER",
"cchange46": "Trinkgeldbetrag",
"cchange47": "Verfügbares Guthaben",
"cchange48": "QORT-Guthaben konnte nicht abgerufen werden. Versuchen Sie es erneut!",
@ -810,7 +812,7 @@
"cchange56": "Transaktion fehlgeschlagen!",
"cchange57": "Benutzerinfo",
"cchange58": "NACHRICHT SENDEN",
"cchange59": "TIP BENUTZER",
"cchange59": "TIPP BENUTZER",
"cchange60": "Gruppeneinladungen ausstehend",
"cchange61": "Fehler beim Abrufen von Gruppeneinladungen. Bitte versuchen Sie es erneut!",
"cchange62": "Falscher Benutzername und falsche Adresse eingegeben! Bitte versuchen Sie es erneut!",
@ -912,7 +914,7 @@
"gchange36": "Verlasse",
"gchange37": "Gruppe verlassen",
"gchange38": "Gruppenbesitzer verwalten:",
"gchange39": "Gruppenadministrator verwalten::",
"gchange39": "Gruppenadministrator verwalten:",
"gchange40": "Gruppe verwalten",
"gchange41": "Gruppenerstellung erfolgreich!",
"gchange42": "Ungültiger Gruppenname",
@ -960,9 +962,9 @@
"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.",
"nchange6": "Belohnungsschlüssel",
"nchange7": "Adding minting account",
"nchange7": "Minting-Konto hinzufügen",
"nchange8": "Hinzufügen",
"nchange9": "Minting-Konto hinzufügen",
"nchange9": "Minting-Konto",
"nchange10": "Empfängerkonto",
"nchange11": "Aktion",
"nchange12": "Entfernen",

View File

@ -5,6 +5,7 @@
"chinese1": "Chino (Simplificado)",
"chinese2": "Chino (Tradicional)",
"croatian": "Croata",
"dutch": "Holandés",
"english": "Inglés",
"estonian": "Estonio",
"french": "Francés",
@ -727,7 +728,8 @@
"bchange45": "Cifrar",
"bchange46": "¿Le das permiso a esta aplicación para guardar el siguiente archivo?",
"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": {
"dchange1": "Gestión de datos",

View File

@ -5,6 +5,7 @@
"chinese1": "Hiina (Lihtsustatud)",
"chinese2": "Hiina (Tradits.)",
"croatian": "Horvaatia",
"dutch": "Hollandi",
"english": "Inglise",
"estonian": "Eesti",
"french": "Prantsuse",
@ -727,7 +728,8 @@
"bchange45": "Krüpteeri",
"bchange46": "Kas annad sellele rakendusele loa salvestada järgnev fail",
"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": {
"dchange1": "Andmete haldamine",

View File

@ -5,6 +5,7 @@
"chinese1": "Chinois (Simplifié)",
"chinese2": "Chinois (Traditionnel)",
"croatian": "Croate",
"dutch": "Néerlandais",
"english": "Anglais",
"estonian": "Estonien",
"french": "Français",
@ -99,7 +100,7 @@
"upload": "Envoyer votre sauvegarde Qortal",
"howlogin": "Comment voulez-vous vous connecter ?",
"seed": "Phrase mnémonique",
"seedphrase": "Phrase mnémonique",
"seedphrase": "phrase mnémonique",
"saved": "Compte sauvegardé",
"qora": "Adresse de contrôle Qora",
"backup": "Sauvegarde du portefeuille Qortal",
@ -110,7 +111,7 @@
"error1": "La sauvegarde doit être un JSON valide",
"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.",
"createa": "A",
"createa": "Une",
"click": "Cliquez pour voir la phrase mnémonique",
"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.",
@ -148,7 +149,7 @@
"lp13": "Génération de la clé de déchiffrement",
"lp14": "Clé de vérification",
"lp15": "Mot de passe incorrect",
"lp16": "Décryptage",
"lp16": "Décryptage en cours",
"lp17": "En attente que les travailleurs soient prêts",
"lp18": "Dérivation des parties clés",
"lp19": "Erreur, clé incorrecte. ",
@ -727,7 +728,8 @@
"bchange45": "Crypter",
"bchange46": "Autorisez-vous cette application à enregistrer le fichier suivant",
"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": {
"dchange1": "Gestion de données",

View File

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

View File

@ -5,6 +5,7 @@
"chinese1": "Kineski (Pojednostavljeni)",
"chinese2": "Kineski (Traditionalni)",
"croatian": "Hrvatski",
"dutch": "Holandski",
"english": "Engleski",
"estonian": "Estonski",
"french": "Francuski",
@ -727,7 +728,8 @@
"bchange45": "Šifriraj",
"bchange46": "Dajete li ovoj aplikaciji dopuštenje za spremanje sljedeće datoteke",
"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": {
"dchange1": "Upravljanje podacima",

View File

@ -5,6 +5,7 @@
"chinese1": "Kínai (Egyszerűsített)",
"chinese2": "Kínai (Hagyományos)",
"croatian": "Horvát",
"dutch": "Németalföldi",
"english": "Angol",
"estonian": "Észt",
"french": "Francia",
@ -727,7 +728,8 @@
"bchange45": "Titkosítás",
"bchange46": "Engedélyezi ennek az alkalmazásnak a következő fájl mentését",
"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": {
"dchange1": "Adatkezelés",

View File

@ -5,6 +5,7 @@
"chinese1": "Cinese (semplificato)",
"chinese2": "Cinese (tradizionale)",
"croatian": "Croato",
"dutch": "Olandese",
"english": "Inglese",
"estonian": "Estone",
"french": "Francese",
@ -727,7 +728,8 @@
"bchange45": "Cripta",
"bchange46": "Concedi a questa applicazione il permesso di salvare il seguente file",
"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": {
"dchange1": "Gestione dati",

View File

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

View File

@ -5,6 +5,7 @@
"chinese1": "중국어(간체)",
"chinese2": "중국어(번체)",
"croatian": "크로아티아어",
"dutch": "네덜란드의",
"english": "영어",
"estonian": "에스토니아어",
"french": "프랑스어",
@ -727,7 +728,8 @@
"bchange45": "암호화",
"bchange46": "이 응용 프로그램에 다음 파일을 저장할 권한을 부여하시겠습니까?",
"bchange47": "즉시 게시 - 필요",
"bchange48": "이 애플리케이션에 알림을 보낼 수 있는 권한을 부여하시겠습니까?"
"bchange48": "이 애플리케이션에 알림을 보낼 수 있는 권한을 부여하시겠습니까?",
"bchange49": "이 애플리케이션에 지갑 정보를 얻을 수 있는 권한을 부여하시겠습니까?"
},
"datapage": {
"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)",
"chinese2": "Kinesisk (Tradisjonell)",
"croatian": "Kroatisk",
"dutch": "Nederlandsk",
"english": "Engelsk",
"estonian": "Estisk",
"french": "Fransk",
@ -727,7 +728,8 @@
"bchange45": "Krypter",
"bchange46": "Gir du dette programmet tillatelse til å lagre følgende fil",
"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": {
"dchange1": "Data-administrasjon",

View File

@ -5,6 +5,7 @@
"chinese1": "Chiński (uproszczony)",
"chinese2": "Chiński (tradycyjny)",
"croatian": "Chorwacki",
"dutch": "Holenderski",
"english": "Angielski",
"estonian": "Estoński",
"french": "Francuski",
@ -727,7 +728,8 @@
"bchange45": "Szyfruj",
"bchange46": "Czy zezwalasz tej aplikacji na zapisanie następującego pliku",
"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": {
"dchange1": "Zarządzanie danymi",

View File

@ -5,6 +5,7 @@
"chinese1": "Chinês Simplificado)",
"chinese2": "Chinês (Tradicional)",
"croatian": "Croata",
"dutch": "Holandês",
"english": "Inglês",
"estonian": "Estoniano",
"french": "Francês",
@ -727,7 +728,8 @@
"bchange45": "Criptografar",
"bchange46": "Você concede permissão a este aplicativo para salvar o seguinte arquivo",
"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": {
"dchange1": "Gerenciamento de Dados",

View File

@ -5,6 +5,7 @@
"chinese1": "Chineza (simplificata)",
"chinese2": "Chineza (traditionala)",
"croatian": "Croata",
"dutch": "Olandez",
"english": "Engleza",
"estonian": "Estonian",
"french": "Franceza",
@ -727,7 +728,8 @@
"bchange45": "Criptați",
"bchange46": "Dați această aplicație permisiunea de a salva următorul fișier",
"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": {
"dchange1": "Gestionare date",

View File

@ -5,6 +5,7 @@
"chinese1": "Kineski (pojednostavljeni)",
"chinese2": "Kineski (tradicionalni)",
"croatian": "Hrvatski",
"dutch": "Holandski",
"english": "Engleski",
"estonian": "Estonski",
"french": "Francuski",
@ -727,7 +728,8 @@
"bchange45": "Šifrovanje",
"bchange46": "Da li ovoj aplikaciji dajete dozvolu da sačuva sledeću datoteku",
"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": {
"dchange1": "Upravljanje podacima",

View File

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

View File

@ -5,6 +5,7 @@
"chinese1": "Chinese (Simplified)",
"chinese2": "Chinese (Traditional)",
"croatian": "Croatian",
"dutch": "Dutch",
"english": "English",
"estonian": "Estonian",
"french": "French",
@ -75,7 +76,7 @@
"tm29": "Reset Tab Menu",
"tm30": "Search Qortal Name",
"tm31": "My Followed Names",
"tm32": "This account not follow any user",
"tm32": "This account does not follow any user",
"tm33": "Import Tab Menu",
"tm34": "Export 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",
"tm38": "DEV MODE",
"tm39": "Add Custom Framework",
"tm40": "Add And Open",
"tm41": "Error: Invalid data please try again !",
"tm40": "Add and Open",
"tm41": "Error: Invalid data please try again!",
"tm42": "Qortal Lottery"
},
"login": {
@ -113,9 +114,9 @@
"createa": "A",
"click": "Click to view seedphrase",
"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.",
"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",
"pleaseenter": "Please enter a Password!",
"notmatch": "Passwords do not match!",
@ -134,11 +135,11 @@
"downloadbackup": "Download Wallet BackUp File",
"passwordhint": "A password must be at least 8 characters.",
"lp1": "Lock Screen",
"lp2": "No Lock Screen Password Is Set !",
"lp3": "Please Set One",
"lp2": "No screen lock password is set!",
"lp3": "Please set one",
"lp4": "No Thanks",
"lp5": "Set Password",
"lp6": "New screen lock password set successfully !",
"lp6": "New screen lock password set successfully!",
"lp7": "UNLOCK",
"lp8": "Error: Incorrect password",
"lp9": "IS",
@ -187,7 +188,7 @@
"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",
"addcustomnode": "Add Custom Node",
"addandsave": "Add And Save",
"addandsave": "Add and Save",
"protocol": "Protocol",
"domain": "Domain",
"port": "Port",
@ -730,7 +731,8 @@
"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?",
"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": {
"dchange1": "Data Management",
@ -934,7 +936,7 @@
"gchange55": "Search Private Group",
"gchange56": "Group Name To Search",
"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"
},
"puzzlepage": {
@ -961,7 +963,7 @@
"nchange2": "Node has been online for:",
"nchange3": "Node's minting accounts",
"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",
"nchange7": "Adding minting account",
"nchange8": "Add",
@ -1023,9 +1025,9 @@
"rewarddialog1": "Would you like to create a reward share transaction, sharing",
"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.",
"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:",
"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",
"deployAtdialog2": "On pressing confirm, the AT will be deployed!",
"deployAtdialog3": "Initial amount balance",
@ -1112,7 +1114,7 @@
"mg25": "Banned Members",
"mg26": "CANCEL BAN",
"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?",
"mg30": "On pressing confirm, the cancel ban request will be sent!",
"mg31": "Kick Member From Group",
@ -1152,7 +1154,7 @@
"inf2": "Close Trade Portal Info",
"inf3": "This is a market to BUY QORT with",
"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.",
"inf7": "Auto Buy Information",
"inf8": "Close Auto Buy Info",

View File

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

View File

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

View File

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

View File

@ -1,18 +1,13 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../store.js'
import { Epml } from '../epml.js'
import { addTradeBotRoutes } from '../tradebot/addTradeBotRoutes.js'
import { get, translate, translateUnsafeHTML } from 'lit-translate'
import {css, html, LitElement} from 'lit'
import {connect} from 'pwa-helpers'
import {store} from '../store.js'
import {Epml} from '../epml.js'
import {addTradeBotRoutes} from '../tradebot/addTradeBotRoutes.js'
import {get, translate} from 'lit-translate'
import localForage from 'localforage'
import { encryptData, decryptData } from '../lockScreen.js'
import { setChatLastSeen } from '../redux/app/app-actions.js'
import {decryptData, encryptData} from '../lockScreen.js'
import {setChatLastSeen} from '../redux/app/app-actions.js'
import isElectron from 'is-electron'
const chatLastSeen = localForage.createInstance({
name: "chat-last-seen",
})
import '@material/mwc-button'
import '@material/mwc-icon'
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/core-sync-status.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 })
class AppView extends connect(store)(LitElement) {
@ -57,7 +58,6 @@ class AppView extends connect(store)(LitElement) {
nodeType: { type: String, reflect: true },
theme: { type: String, reflect: true },
addressInfo: { type: Object },
getAllBalancesLoading: { type: Boolean },
botQortWallet: { type: String },
botBtcWallet: { type: String },
botLtcWallet: { type: String },
@ -231,13 +231,13 @@ class AppView extends connect(store)(LitElement) {
background-color: whitesmoke;
border-radius: 7px;
}
.sideBarMenu::-webkit-scrollbar {
width: 6px;
border-radius: 7px;
background-color: whitesmoke;
}
.sideBarMenu::-webkit-scrollbar-thumb {
background-color: rgb(180, 176, 176);
border-radius: 7px;
@ -364,7 +364,7 @@ class AppView extends connect(store)(LitElement) {
0%,100% { opacity: 0; }
50% { opacity: 10; }
}
.sideBarMenu::-webkit-scrollbar-thumb:hover {
background-color: rgb(148, 146, 146);
cursor: pointer;
@ -447,7 +447,6 @@ class AppView extends connect(store)(LitElement) {
this.urls = []
this.nodeType = ''
this.addressInfo = {}
this.getAllBalancesLoading = false
this.botQortWallet = ''
this.botBtcWallet = ''
this.botLtcWallet = ''
@ -553,24 +552,6 @@ class AppView extends connect(store)(LitElement) {
</side-menu>
</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>
</div>
</app-header-layout>
@ -599,6 +580,8 @@ class AppView extends connect(store)(LitElement) {
<div>&nbsp;&nbsp;</div>
<language-selector></language-selector>
<div>&nbsp;&nbsp;&nbsp;&nbsp;</div>
<core-sync-status></core-sync-status>
<div>&nbsp;&nbsp;</div>
<theme-toggle></theme-toggle>
<div>&nbsp;&nbsp;</div>
${this.renderLockButton()}
@ -677,7 +660,7 @@ class AppView extends connect(store)(LitElement) {
</div>
</paper-dialog>
<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.botArrrWallet = store.getState().app.selectedAddress.arrrWallet.address
await this.getAllBalances()
await this.botBtcTradebook()
await this.botLtcTradebook()
await this.botDogeTradebook()
@ -771,8 +752,6 @@ class AppView extends connect(store)(LitElement) {
this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]")
})
this.renderBalances()
const getOpenTradesBTC = async () => {
let timerBTC
@ -1803,15 +1782,6 @@ class AppView extends connect(store)(LitElement) {
}, 60000)
}
shBalanceTicker() {
const targetDiv = this.shadowRoot.getElementById("theTicker")
if (targetDiv.style.display !== "none") {
targetDiv.style.display = "none"
} else {
targetDiv.style.display = "inline"
}
}
clearTheCache() {
if (!isElectron()) {
} 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}>
<vaadin-icon icon="vaadin:thumbs-up" slot="icon"></vaadin-icon>
</side-menu-item>
<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>
</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() {
let qortAddress = store.getState().app.selectedAddress.address

View File

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

View File

@ -1,5 +1,5 @@
import { LitElement, html, css } from 'lit'
import { get, translate, translateUnsafeHTML } from 'lit-translate'
import {css, html, LitElement} from 'lit'
import {translate} from 'lit-translate'
import isElectron from 'is-electron'
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){
@ -39,7 +39,7 @@ const computePow = async (chatBytes, path, difficulty) => {
const hashAry = new Uint8Array(memory.buffer, hashPtr, 32);
hashAry.set(chatBytesHash);
const workBufferLength = 8 * 1024 * 1024;
const workBufferPtr = sbrk(workBufferLength, heap);
@ -72,11 +72,11 @@ loadWebAssembly(path)
}
resolve()
});
})
})
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 { render } from 'lit/html.js'
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
import {css, html, LitElement} from 'lit'
import {get} from 'lit-translate'
import '@material/mwc-icon'
import '@vaadin/tooltip';
@ -100,7 +99,7 @@ class ChatSideNavHeads extends LitElement {
imageHTMLRes.onload = () => {
this.isImageLoaded = true;
}
imageHTMLRes.onerror = () => {
imageHTMLRes.onerror = () => {
if (this.imageFetches < 4) {
setTimeout(() => {
this.imageFetches = this.imageFetches + 1;
@ -170,13 +169,13 @@ class ChatSideNavHeads extends LitElement {
</span>
</div>
</div>
</div>
<div style="display:flex; align-items: center">
${this.chatInfo.willFollow ? html`
<mwc-icon id="willFollowIcon" style="color: var(--black)">connect_without_contact</mwc-icon>
<vaadin-tooltip
for="willFollowIcon"
position="top"
hover-delay=${200}
@ -210,10 +209,10 @@ class ChatSideNavHeads extends LitElement {
if(changedProperties.has('isImageLoaded')){
return true
}
return false
}
getUrl(chatUrl) {
this.setActiveChatHeadUrl(chatUrl)
}

View File

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

View File

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

View File

@ -1,78 +1,160 @@
import { LitElement, html, css } from 'lit';
import '@material/mwc-icon';
import { store } from '../../store';
import { connect } from 'pwa-helpers';
import '@vaadin/tooltip';
import { get } from 'lit-translate';
import {css, html, LitElement} from 'lit'
import {store} from '../../store'
import {connect} from 'pwa-helpers'
import {translate} from 'lit-translate'
class CoreSyncStatus extends connect(store)(LitElement) {
static get properties() {
return {
nodeStatus: {type: Object}
};
nodeStatus: {type: Object},
coreInfos: { type: Array }
}
}
constructor() {
super();
this.nodeStatus = {
isMintingPossible:false,
isSynchronizing:true,
syncPercent:undefined,
numberOfConnections:undefined,
height:undefined,
}
super()
this.nodeStatus = {}
this.coreInfos = []
}
static styles = css`
.header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px;
border-bottom: 1px solid #e0e0e0;
.lineHeight {
line-height: 33%;
}
.content {
padding: 16px;
.tooltip {
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;
position: fixed;
z-index: -100;
right: -1000px;
opacity: 0;
transition: opacity 0.8s;
}
.parent-side-panel {
transform: translateX(100%); /* start from outside the right edge */
transition: transform 0.3s ease-in-out;
.tooltip:hover .bottom {
visibility: visible;
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) {
this.nodeStatus = state.app.nodeStatus
}
.tooltip .bottom i::after {
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() {
return html`
<mwc-icon id="icon" style="color: ${this.nodeStatus.syncPercent === 100 ? 'green': 'red'};user-select:none;margin-right:20px"
>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>
`;
${this.renderSyncStatusIcon()}
`
}
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 {
get,
translate,
} from 'lit-translate';
import {css, html, LitElement} from 'lit';
import {translate,} from 'lit-translate';
import axios from 'axios'
import '@material/mwc-menu';
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 { connect } from 'pwa-helpers';
import { store } from '../../store';
import { setNewTab } from '../../redux/app/app-actions';
import {connect} from 'pwa-helpers';
import {store} from '../../store';
import {setNewTab} from '../../redux/app/app-actions';
import ShortUniqueId from 'short-unique-id';
const requestQueue = new RequestQueueWithPromise(3);
@ -41,9 +38,9 @@ export class FeedItem extends connect(store)(LitElement) {
box-sizing: border-box;
}
img {
width:100%;
max-height:30vh;
border-radius: 5px;
width:100%;
max-height:30vh;
border-radius: 5px;
cursor: pointer;
position: relative;
}
@ -67,7 +64,7 @@ export class FeedItem extends connect(store)(LitElement) {
}
.defaultSize {
width: 100%;
width: 100%;
height: 160px;
}
.parent-feed-item {
@ -87,7 +84,7 @@ export class FeedItem extends connect(store)(LitElement) {
font-size: 16px;
}
.avatar {
width: 36px;
width: 36px;
height: 36px;
border-radius:50%;
overflow: hidden;
@ -95,7 +92,7 @@ export class FeedItem extends connect(store)(LitElement) {
align-items:center;
}
.avatarApp {
width: 30px;
width: 30px;
height: 30px;
border-radius:50%;
overflow: hidden;
@ -210,7 +207,7 @@ getMyNode(){
async fetchVideoUrl() {
this.fetchResource()
}
async getRawData(){
@ -228,7 +225,7 @@ getMyNode(){
// const responseData2 = await response2.json()
// return responseData2
}
updateDisplayWithPlaceholders(display, resource, rawdata) {
const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g;
@ -241,7 +238,7 @@ getMyNode(){
if (rawdata[dataKey] === undefined) {
console.error("rawdata key not found:", dataKey);
}
return rawdata[dataKey] || match;
return rawdata[dataKey] || match;
} else if (p1.startsWith('resource.')) {
const resourceKey = p1.split('.')[1];
if (resource[resourceKey] === undefined) {
@ -263,7 +260,7 @@ getMyNode(){
let timer = 24
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}`)
})
})
if(response && response.data && response.data.status === 'READY'){
const rawData = await this.getRawData()
const object = {
@ -272,13 +269,13 @@ getMyNode(){
this.updateDisplayWithPlaceholders(object, {},rawData.data)
this.feedItem = object
this.status = response.data
return
}
const intervalId = setInterval(async () => {
if (isCalling) return
isCalling = true
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}`)
});
@ -302,7 +299,7 @@ getMyNode(){
...res,
status: 'REFETCHING'
}
setTimeout(() => {
isCalling = false
this.fetchResource()
@ -311,7 +308,7 @@ getMyNode(){
}
percentLoaded = res.percentLoaded
}
this.status = res
if(this.status.status === 'DOWNLOADED'){
this.fetchResource()
@ -345,7 +342,7 @@ getMyNode(){
}
async goToFeedLink(){
try {
@ -386,7 +383,7 @@ getMyNode(){
console.log({error})
}
}
async extractComponents(url) {
@ -434,11 +431,11 @@ getMyNode(){
}
render() {
let avatarImg
@ -469,7 +466,7 @@ getMyNode(){
style=" box-sizing: border-box;"
>
${
this.status.status !== 'READY'
this.status.status !== 'READY'
? html`
<div
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>
`
}
}

View File

@ -1,11 +1,11 @@
// popover-component.js
import { LitElement, html, css } from 'lit';
import { createPopper } from '@popperjs/core';
import {css, html, LitElement} from 'lit';
import {createPopper} from '@popperjs/core';
import '@material/mwc-icon';
import { use, get, translate } from 'lit-translate';
import { store } from '../../store';
import { connect } from 'pwa-helpers';
import { setNewTab, setSideEffectAction } from '../../redux/app/app-actions';
import {translate} from 'lit-translate';
import {store} from '../../store';
import {connect} from 'pwa-helpers';
import {setNewTab, setSideEffectAction} from '../../redux/app/app-actions';
import ShortUniqueId from 'short-unique-id';
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 './friends-view'
import { friendsViewStyles } from './friends-view-css';
import { connect } from 'pwa-helpers';
import { store } from '../../store';
import {friendsViewStyles} from './friends-view-css';
import {connect} from 'pwa-helpers';
import {store} from '../../store';
import './feed-item'
import { translate } from 'lit-translate';
import {translate} from 'lit-translate';
import '@polymer/paper-spinner/paper-spinner-lite.js'
@ -31,7 +31,7 @@ class FriendsFeed extends connect(store)(LitElement) {
this.myNode = this.getMyNode();
this.endpoints = []
this.endpointOffsets = [] // Initialize offsets for each endpoint to 0
this.loadAndMergeData = this.loadAndMergeData.bind(this)
this.hasInitialFetch = false
this.observerHandler = this.observerHandler.bind(this);
@ -42,12 +42,12 @@ class FriendsFeed extends connect(store)(LitElement) {
this._updateFeeds = this._updateFeeds.bind(this)
}
static get styles() {
return [friendsViewStyles];
}
getNodeUrl() {
const myNode =
@ -109,7 +109,7 @@ class FriendsFeed extends connect(store)(LitElement) {
let interval = null;
let stop = false;
const getAnswer = async () => {
if (!stop) {
stop = true;
try {
@ -119,19 +119,19 @@ class FriendsFeed extends connect(store)(LitElement) {
}
};
interval = setInterval(getAnswer, 900000);
}
async getEndpoints(){
const dynamicVars = {
}
const schemas = await this.getSchemas()
const friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]")
const names = friendList.map(friend => `name=${friend.name}`).join('&');
if(names.length === 0){
this.endpoints= []
this.endpointOffsets = Array(this.endpoints.length).fill(0);
this.endpointOffsets = Array(this.endpoints.length).fill(0);
return
}
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.endpointOffsets = Array(this.endpoints.length).fill(0);
this.endpointOffsets = Array(this.endpoints.length).fill(0);
}
async firstUpdated(){
@ -159,8 +159,8 @@ class FriendsFeed extends connect(store)(LitElement) {
this.downObserverElement =
this.shadowRoot.getElementById('downObserver');
this.elementObserver();
try {
await new Promise((res)=> {
setTimeout(() => {
@ -172,7 +172,7 @@ class FriendsFeed extends connect(store)(LitElement) {
this.loadAndMergeData();
}
this.getFeedOnInterval()
} catch (error) {
@ -192,7 +192,7 @@ this.getFeedOnInterval()
await this.getEndpoints()
this.reFetchFeedData()
} catch (error) {
}
}
@ -236,17 +236,17 @@ this.getFeedOnInterval()
...i
}
})
}
async initialLoad() {
let results = [];
let totalFetched = 0;
let i = 0;
let madeProgress = true;
let exhaustedEndpoints = new Set();
while (totalFetched < totalDesiredCount && madeProgress) {
madeProgress = false;
this.isLoading = true
@ -254,32 +254,32 @@ this.getFeedOnInterval()
if (exhaustedEndpoints.has(i)) {
continue;
}
const remainingCount = totalDesiredCount - totalFetched;
// If we've already reached the desired count, break
if (remainingCount <= 0) {
break;
}
let fetchCount = Math.min(perEndpointCount, remainingCount);
let data = await this.fetchDataFromEndpoint(i, fetchCount);
// Increment the offset for this endpoint by the number of items fetched
this.endpointOffsets[i] += data.length;
if (data.length > 0) {
madeProgress = true;
}
if (data.length < fetchCount) {
exhaustedEndpoints.add(i);
}
results = results.concat(data);
totalFetched += data.length;
}
if (exhaustedEndpoints.size === this.endpoints.length) {
break;
}
@ -289,15 +289,15 @@ this.getFeedOnInterval()
// Trim the results if somehow they are over the totalDesiredCount
return results.slice(0, totalDesiredCount);
}
trimDataToLimit(data, limit) {
return data.slice(0, limit);
}
mergeData(newData, existingData) {
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));
@ -325,37 +325,37 @@ this.getFeedOnInterval()
const resource = newItem
let clickValue1 = newItem.schema.click;
const resolvedClickValue1 = replacePlaceholders(clickValue1, resource, newItem.schema.customParams);
newItem.link = resolvedClickValue1
newData.push(newItem)
}
}
return newData
}
async reFetchFeedData() {
// Resetting offsets to start fresh.
this.endpointOffsets = Array(this.endpoints.length).fill(0);
this.endpointOffsets = Array(this.endpoints.length).fill(0);
await this.getEndpoints()
const oldIdentifiers = new Set(this.feed.map(item => item.identifier));
const newData = await this.initialLoad();
// Filter out items that are already in the feed
const trulyNewData = newData.filter(item => !oldIdentifiers.has(item.identifier));
if (trulyNewData.length > 0) {
// Adding extra data and merging with old data
const enhancedNewData = await this.addExtraData(trulyNewData);
// Merge new data with old data immutably
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 = this.trimDataToLimit(this.feed, maxResultsInMemory); // Trim to the maximum allowed in memory
this.feedToRender = this.feed.slice(0, 20);
this.hasInitialFetch = true;
const created = trulyNewData[0].created;
let value = localStorage.getItem('lastSeenFeed');
if (((+value || 0) < created)) {
@ -363,9 +363,9 @@ this.getFeedOnInterval()
}
}
}
async loadAndMergeData() {
let allData = this.feed
const newData = await this.initialLoad();
@ -387,7 +387,7 @@ this.getFeedOnInterval()
render() {
return html`
@ -450,7 +450,7 @@ export function constructUrl(base, search, dynamicVars) {
export function replacePlaceholders(template, resource, customParams) {
const dataSource = { resource, customParams };
return template.replace(/\$\$\{(.*?)\}\$\$/g, (match, p1) => {
const keys = p1.split('.');
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 './friends-side-panel.js';
import '@vaadin/tooltip';
import { get } from 'lit-translate';
import {translate} from 'lit-translate';
class FriendsSidePanelParent extends LitElement {
@ -12,7 +12,7 @@ class FriendsSidePanelParent extends LitElement {
hasNewFeed: {type: Boolean}
};
}
constructor() {
super();
@ -68,10 +68,10 @@ class FriendsSidePanelParent extends LitElement {
position="bottom"
hover-delay=${400}
hide-delay=${1}
text=${get('friends.friend12')}>
text=${translate('friends.friend12')}>
</vaadin-tooltip>
<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 './friends-view'
import './friends-feed'
import { translate } from 'lit-translate';
import {translate} from 'lit-translate';
class FriendsSidePanel extends LitElement {
static get properties() {
return {
@ -19,7 +20,7 @@ class FriendsSidePanel extends LitElement {
this.selected = 'friends'
this.closeSidePanel = this.closeSidePanel.bind(this)
}
static styles = css`
:host {
display: block;
@ -98,14 +99,14 @@ class FriendsSidePanel extends LitElement {
position: absolute;
z-index: -50;
}
`;
refreshFeed(){
this.shadowRoot.querySelector('friends-feed').refresh()
}
closeSidePanel(){
@ -128,7 +129,7 @@ class FriendsSidePanel extends LitElement {
this.setIsOpen(false)
}}>close</mwc-icon>
</div>
</div>
<div class="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'}">
<friends-feed .setHasNewFeed=${(val)=> this.setHasNewFeed(val)}></friends-feed>
</div>
</div>
</div>

View File

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

View File

@ -1,6 +1,5 @@
import { LitElement, html, css } from 'lit';
import { render } from 'lit/html.js';
import { connect } from 'pwa-helpers';
import {html, LitElement} from 'lit';
import {connect} from 'pwa-helpers';
import '@material/mwc-button';
import '@material/mwc-dialog';
@ -14,16 +13,10 @@ import './ChatSideNavHeads';
import '../../../../plugins/plugins/core/components/ChatSearchResults'
import './add-friends-modal'
import {
use,
get,
translate,
translateUnsafeHTML,
registerTranslateConfig,
} from 'lit-translate';
import { store } from '../../store';
import { friendsViewStyles } from './friends-view-css';
import { parentEpml } from '../show-plugin';
import {translate,} from 'lit-translate';
import {store} from '../../store';
import {friendsViewStyles} from './friends-view-css';
import {parentEpml} from '../show-plugin';
class FriendsView extends connect(store)(LitElement) {
static get properties() {
@ -103,10 +96,10 @@ class FriendsView extends connect(store)(LitElement) {
this.elementObserver();
this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]")
this.friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]")
}
_updateFriends(event) {
@ -114,23 +107,20 @@ class FriendsView extends connect(store)(LitElement) {
this.friendList = detail
}
_updateFeed(event) {
console.log({event})
const detail = event.detail
console.log({detail})
this.mySelectedFeeds = detail
this.requestUpdate()
}
connectedCallback() {
super.connectedCallback()
console.log('callback')
window.addEventListener('friends-my-friend-list-event', this._updateFriends)
window.addEventListener('friends-my-selected-feeds-event', this._updateFeed)
window.addEventListener('friends-my-friend-list-event', this._updateFriends)
window.addEventListener('friends-my-selected-feeds-event', this._updateFeed)
}
disconnectedCallback() {
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()
}
@ -172,7 +162,7 @@ class FriendsView extends connect(store)(LitElement) {
}
try {
const url = `${this.nodeUrl}/names/${nameValue}`
const res = await fetch(url)
const res = await fetch(url)
const result = await res.json()
if (result.error === 401) {
this.userFound = []
@ -182,7 +172,7 @@ class FriendsView extends connect(store)(LitElement) {
];
}
this.userFoundModalOpen = true;
} catch (error) {
} catch (error) {
// let err4string = get("chatpage.cchange35");
// parentEpml.request('showSnackBar', `${err4string}`)
}
@ -199,7 +189,7 @@ class FriendsView extends connect(store)(LitElement) {
name
]
let namesJsonString = JSON.stringify({ "items": items })
let ret = await parentEpml.request('apiCall', {
url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
method: 'POST',
@ -208,8 +198,8 @@ class FriendsView extends connect(store)(LitElement) {
},
body: `${namesJsonString}`
})
return ret
}
@ -218,7 +208,7 @@ class FriendsView extends connect(store)(LitElement) {
name
]
let namesJsonString = JSON.stringify({ "items": items })
let ret = await parentEpml.request('apiCall', {
url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
method: 'DELETE',
@ -227,8 +217,8 @@ class FriendsView extends connect(store)(LitElement) {
},
body: `${namesJsonString}`
})
return ret
}
async addToFriendList(val, isRemove){
@ -242,9 +232,9 @@ class FriendsView extends connect(store)(LitElement) {
const copyList = [...this.friendList]
copyList[findFriend] = copyVal
this.friendList = copyList
}
} else {
this.friendList = [...this.friendList, copyVal]
}
@ -252,7 +242,7 @@ class FriendsView extends connect(store)(LitElement) {
this.unFollowName(copyVal.name)
} else if(copyVal.willFollow){
this.myFollowName(copyVal.name)
}
}
this.setMySelectedFeeds(val.mySelectedFeeds)
await new Promise((res)=> {
setTimeout(()=> {
@ -317,18 +307,17 @@ class FriendsView extends connect(store)(LitElement) {
}
render() {
console.log('rendered1')
return html`
<div class="container">
<div id="viewElement" class="container-body" style=${"position: relative"}>
<p class="group-name">My Friends</p>
<div class="search-field">
<input
<input
type="text"
class="name-input"
?disabled=${this.isLoading}
id="sendTo"
placeholder="${translate("friends.friend1")}"
class="name-input"
?disabled=${this.isLoading}
id="sendTo"
placeholder="${translate("friends.friend1")}"
value=${this.userSelected.name ? this.userSelected.name: ''}
@keypress=${(e) => {
if(e.key === 'Enter'){
@ -336,21 +325,21 @@ class FriendsView extends connect(store)(LitElement) {
}
}}
/>
<vaadin-icon
<vaadin-icon
@click=${this.userSearch}
slot="icon"
slot="icon"
icon="vaadin:search"
class="search-icon">
</vaadin-icon>
</div>
<div class="search-results-div">
<chat-search-results
<chat-search-results
.onClickFunc=${(result) => {
this.userSelected = result;
this.isOpenAddFriendsModal = true
this.userFound = [];
this.userFoundModalOpen = false;
}}
@ -363,13 +352,13 @@ class FriendsView extends connect(store)(LitElement) {
?loading=${this.isLoading}>
</chat-search-results>
</div>
${this.friendList.map((item) => {
return html`<chat-side-nav-heads
activeChatHeadUrl=""
.setActiveChatHeadUrl=${(val) => {
}}
.chatInfo=${item}
.openEditFriend=${(val)=> this.openEditFriend(val)}
@ -380,7 +369,7 @@ class FriendsView extends connect(store)(LitElement) {
</div>
</div>
<add-friends-modal
?isOpen=${this.isOpenAddFriendsModal}
?isOpen=${this.isOpenAddFriendsModal}
.setIsOpen=${(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 './friends-side-panel.js';
import { connect } from 'pwa-helpers';
@ -14,11 +14,10 @@ import {
encryptDataGroup,
objectToBase64,
uint8ArrayToBase64,
uint8ArrayToObject,
} from '../../../../plugins/plugins/core/components/qdn-action-encryption.js';
import { publishData } from '../../../../plugins/plugins/utils/publish-image.js';
import { parentEpml } from '../show-plugin.js';
import {publishData} from '../../../../plugins/plugins/utils/publish-image.js';
import {parentEpml} from '../show-plugin.js';
import '../notification-view/popover.js';
import { setNewTab } from '../../redux/app/app-actions.js';
@ -171,14 +170,14 @@ class SaveSettingsQdn extends connect(store)(LitElement) {
}
async getMyFollowedNames() {
let myFollowedNames = []
try {
myFollowedNames = await parentEpml.request('apiCall', {
url: `/lists/followedNames?apiKey=${this.myNode.apiKey}`
})
} catch (error) {
}
return myFollowedNames
@ -197,7 +196,7 @@ class SaveSettingsQdn extends connect(store)(LitElement) {
body: `${namesJsonString}`
})
return ret
}
@ -671,20 +670,20 @@ class SaveSettingsQdn extends connect(store)(LitElement) {
hover-delay=${300}
hide-delay=${1}
text=${this.error
? get('save.saving1')
? translate('save.saving1')
: Object.values(this.valuesToBeSavedOnQdn)
.length > 0 ||
this.resourceExists === false
? get('save.saving3')
: get('save.saving2')}
? translate('save.saving3')
: translate('save.saving2')}
>
</vaadin-tooltip>
<popover-component for="save-icon" message="">
<div style="margin-bottom:20px">
<p style="margin:10px 0px; font-size:16px">
${`${get('walletpage.wchange12')}: ${
${translate('walletpage.wchange12')}: ${
this.fee ? this.fee.feeToShow : ''
}`}
}
</p>
</div>
<div

View File

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

View File

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

View File

@ -1,8 +1,8 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../../store.js'
import { checkApiKey } from '../../apiKeyUtils.js'
import { translate, translateUnsafeHTML } from 'lit-translate'
import {css, html, LitElement} from 'lit'
import {connect} from 'pwa-helpers'
import {store} from '../../store.js'
import {checkApiKey} from '../../apiKeyUtils.js'
import {translate} from 'lit-translate'
import '@material/mwc-button'
import '@material/mwc-checkbox'
@ -18,9 +18,9 @@ import '@polymer/iron-collapse'
import '@polymer/paper-spinner/paper-spinner-lite.js'
import '@vaadin/text-field/vaadin-text-field.js'
import '@vaadin/password-field/vaadin-password-field.js'
import { doLogin, doSelectAddress } from '../../redux/app/app-actions.js'
import { doStoreWallet, doRemoveWallet } from '../../redux/user/user-actions.js'
import { createWallet } from '../../../../crypto/api/createWallet.js'
import {doLogin, doSelectAddress} from '../../redux/app/app-actions.js'
import {doRemoveWallet, doStoreWallet} from '../../redux/user/user-actions.js'
import {createWallet} from '../../../../crypto/api/createWallet.js'
import snackbar from '../../functional-components/snackbar.js'
import '../../custom-elements/frag-file-input.js'
import ripple from '../../functional-components/loading-ripple.js'
@ -195,7 +195,7 @@ class LoginSection extends connect(store)(LitElement) {
right: 5px;
top: 20px;
color: tomato;
--mdc-icon-size: 30px;
--mdc-icon-size: 30px;
}
.login-option {
@ -212,7 +212,7 @@ class LoginSection extends connect(store)(LitElement) {
color: var(--black);
}
*[hidden] {
*[hidden] {
display:none !important;
visibility: hidden;
}
@ -268,7 +268,7 @@ class LoginSection extends connect(store)(LitElement) {
cursor: pointer;
}
</style>
<div id="loginSection">
<div id="pagesContainer">
<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 { connect } from 'pwa-helpers'
import { store } from '../../store.js'
import { stateAwait } from '../../stateAwait.js'
import { translate, translateUnsafeHTML } from 'lit-translate'
import {css, html, LitElement} from 'lit'
import {connect} from 'pwa-helpers'
import {store} from '../../store.js'
import {stateAwait} from '../../stateAwait.js'
import {get} from 'lit-translate'
import '@material/mwc-button'
import '@material/mwc-icon'
@ -15,7 +15,20 @@ import './login-section.js'
import '../qort-theme-toggle.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.reduxAction = {
@ -122,7 +135,7 @@ class LoginView extends connect(store)(LitElement) {
display: block;
vertical-align: bottom;
}
.login-page {
background: var(--background);
background-repeat: no-repeat;
@ -137,6 +150,7 @@ class LoginView extends connect(store)(LitElement) {
left:0;
z-index:1;
}
.login-card-container {
max-width:1240px;
max-height:var(--window-height);
@ -144,6 +158,7 @@ class LoginView extends connect(store)(LitElement) {
margin-left: auto;
width: calc(100vw);
}
.qortal-logo {
margin-left: auto;
margin-right: auto;
@ -151,6 +166,7 @@ class LoginView extends connect(store)(LitElement) {
max-width:40%;
z-index:1;
}
.login-card-center-container {
max-width:100%;
max-height:var(--window-height);
@ -160,13 +176,16 @@ class LoginView extends connect(store)(LitElement) {
height: var(--window-height);
overflow:hidden;
}
#loginContainerPages {
display:inline;
}
#loginContainerPages [page] {
background: none;
padding:0;
}
.login-card {
min-width: 340px;
border-bottom: 2px solid var(--mdc-theme-primary);
@ -177,30 +196,49 @@ class LoginView extends connect(store)(LitElement) {
border: 0;
border-radius: 4px;
}
.login-card p {
margin-top: 0;
font-size: 1rem;
font-style: italic;
}
.login-card h1{
.login-card h1 {
margin-bottom:12px;
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 {
height:100%;
margin-top: -16px;
}
.backButton {
padding-top:18px;
text-align:center;
}
#login-pages-nav {
text-align: left;
/* padding-bottom:8px; */
padding: 12px 0 8px 0;
}
#nav-next {
float: right;
}
@media only screen and (min-width: ${getComputedStyle(document.body).getPropertyValue('--layout-breakpoint-tablet')}) {
/* Desktop/tablet */
.login-card {
@ -212,13 +250,14 @@ class LoginView extends connect(store)(LitElement) {
#loginContainerPages [page="welcome"] {
}
}
@media only screen and (max-width: ${getComputedStyle(document.body).getPropertyValue('--layout-breakpoint-tablet')}) {
/* Mobile */
.qortal-logo {
display:none;
visibility:hidden;
}
.login-card{
.login-card {
width:100%;
margin:0;
top:0;
@ -228,7 +267,14 @@ class LoginView extends connect(store)(LitElement) {
text-align: left;
padding-left:12px;
}
.login-card h5 {
margin-top: 0px;
margin-left: 0px;
font-size: 14px;
color: var(--black);
}
}
@keyframes fade {
from {
opacity: 0;
@ -239,6 +285,7 @@ class LoginView extends connect(store)(LitElement) {
transform: translateX(0);
}
}
@keyframes grow-up {
from {
overflow:hidden;
@ -249,16 +296,20 @@ class LoginView extends connect(store)(LitElement) {
max-height:var(--window-height);
}
}
iron-pages .animated, .animated {
animation-duration: ${animationDuration}s;
animation-name: grow-up;
}
div[page] > paper-icon-button {
margin:12px;
}
.corner-box {
border-color: var(--mdc-theme-primary) !important;
}
[hidden] {
visibility: hidden;
display: none;
@ -271,7 +322,8 @@ class LoginView extends connect(store)(LitElement) {
<div class="login-card-center-container">
<div class="login-card" id="login-card">
<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">
<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>
@ -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) {
this.selectedPage = newPage
}

View File

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

View File

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

View File

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

View File

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

View File

@ -1,13 +1,13 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import {css, html, LitElement} from 'lit'
import {connect} from 'pwa-helpers'
import '@vaadin/item'
import '@vaadin/list-box'
import '@polymer/paper-icon-button/paper-icon-button.js'
import '@polymer/iron-icons/iron-icons.js'
import { store } from '../../store.js'
import { setNewTab } from '../../redux/app/app-actions.js'
import { routes } from '../../plugins/routes.js'
import {store} from '../../store.js'
import {setNewTab} from '../../redux/app/app-actions.js'
import {routes} from '../../plugins/routes.js'
import '@material/mwc-icon';
import config from '../../notifications/config.js'
@ -61,7 +61,7 @@ class NotificationBell extends connect(store)(LitElement) {
0,
20
)}_${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, {
method: 'GET',
headers: {
@ -150,7 +150,7 @@ class NotificationBell extends connect(store)(LitElement) {
hide-delay=${1}
text="Q-Mail">
</vaadin-tooltip>
` : html`
<mwc-icon @click=${() => this._openTabQmail()} id="notification-mail-icon" style="color: var(--black); cursor:pointer;user-select:none"
>mail</mwc-icon
@ -162,7 +162,7 @@ class NotificationBell extends connect(store)(LitElement) {
hide-delay=${1}
text="Q-Mail">
</vaadin-tooltip>
`}
${this.notificationCount ? html`
@ -195,7 +195,7 @@ class NotificationBell extends connect(store)(LitElement) {
<p>Q-Mail</p>
<message-time timestamp=${notification.created} style="color:red;font-size:12px"></message-time>
</div>
<div>
<div>
<p>${notification.name}</p>
</div>
</div>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
import { css, html, LitElement } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../../store.js'
import { translate } from 'lit-translate'
import {css, html, LitElement} from 'lit'
import {connect} from 'pwa-helpers'
import {store} from '../../store.js'
import {translate} from 'lit-translate'
import '@material/mwc-textfield'
import '@material/mwc-icon'
@ -59,21 +59,21 @@ class QRLoginView extends connect(store)(LitElement) {
text-decoration: none;
transition: all .2s;
position: relative;
}
}
.q-button.outlined {
background: unset;
border: 1px solid #03a9f4;
}
:host([theme="light"]) .q-button.outlined {
color: #03a9f4;
}
#qr-toggle-button {
margin-left: 12px;
}
#login-qr-code {
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 id="qr-toggle-button" @click=${() => this.showQRCode()} class="q-button outlined"> ${translate(this.translateButtonKey)} </div>
</div>
<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>
</div>

View File

@ -1,8 +1,14 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../../store.js'
import { allowQAPPAutoAuth, removeQAPPAutoAuth, removeQAPPAutoLists, allowQAPPAutoLists, setIsOpenDevDialog } from '../../redux/app/app-actions.js'
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
import {css, html, LitElement} from 'lit'
import {connect} from 'pwa-helpers'
import {store} from '../../store.js'
import {
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 FileSaver from 'file-saver'
@ -75,7 +81,7 @@ class SecurityView extends connect(store)(LitElement) {
text-decoration: none;
transition: all .2s;
position: relative;
}
}
.add-dev-button {
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>
</div>
<div class="checkbox-row">
<button
<button
class="add-dev-button"
title="${translate('tabmenu.tm18')}"
@click=${this.openDevDialog}
>${translate('tabmenu.tm38')}</button>
</div>
</div>
`
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../store.js'
import { translate, translateUnsafeHTML } from 'lit-translate'
import {css, html, LitElement} from 'lit'
import {connect} from 'pwa-helpers'
import {store} from '../store.js'
import {translate} from 'lit-translate'
import '@polymer/paper-toast'
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-icon'
import { translate, translateUnsafeHTML } from 'lit-translate'
import {translate} from 'lit-translate'
class FragFileInput extends LitElement {
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(EpmlReadyPlugin)

View File

@ -1,9 +1,9 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../store.js'
import { get, translate, translateUnsafeHTML } from 'lit-translate'
import {css, html, LitElement} from 'lit'
import {connect} from 'pwa-helpers'
import {store} from '../store.js'
import {get, translate} from 'lit-translate'
import { listenForRequest } from '../transactionRequest.js'
import {listenForRequest} from '../transactionRequest.js'
import '@polymer/paper-dialog/paper-dialog.js'
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']
@ -99,7 +99,7 @@ class LoadingRipple extends LitElement {
opacity: 1;
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 '@polymer/paper-spinner/paper-spinner-lite.js';

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
import { css } from 'lit'
import {css} from 'lit'
export const sideMenuItemStyle = css`
: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-background-color: #ffffff;
--spacing: 4px;
font-family: var(--font-family);
@ -86,7 +86,7 @@ export const sideMenuItemStyle = css`
:host([expanded]){
background-color: var(--item-selected-color);
}
:host([hasSelectedChild]){
background-color: var(--item-selected-color);
}
@ -109,7 +109,7 @@ export const sideMenuItemStyle = css`
}
#collapse-button {
float: right;
float: right;
}
:host([compact]) #itemLink[level]:not([level="0"]) {
@ -143,7 +143,7 @@ export const sideMenuItemStyle = css`
z-index: 1;
animation: pop 200ms forwards;
}
@keyframes pop{
0% {
transform: translateX(-5px);

View File

@ -1,6 +1,6 @@
import { LitElement, html, css } from 'lit'
import { ifDefined } from 'lit/directives/if-defined.js'
import { sideMenuItemStyle } from './side-menu-item-style.js'
import {css, html, LitElement} from 'lit'
import {ifDefined} from 'lit/directives/if-defined.js'
import {sideMenuItemStyle} from './side-menu-item-style.js'
import '@vaadin/icon'
import '@vaadin/icons'
import '@polymer/paper-tooltip'
@ -50,8 +50,8 @@ export class SideMenuItem extends LitElement {
_itemLinkTemplate() {
return html`
<a id="itemLink"
level=${this._getLevel}
<a id="itemLink"
level=${this._getLevel}
href=${this.href || '#!'}
@click="${(e) => this._onClick(e)}"
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 {
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'
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 { doLoadConfigFromAPI } from './redux/config/config-actions.js'
import { doLoadNodeConfig, doInitWorkers } from './redux/app/app-actions.js'
import { doLoadNotificationConfig } from './redux/user/user-actions.js'
import {store} from './store.js'
import {doLoadConfigFromAPI} from './redux/config/config-actions.js'
import {doInitWorkers, doLoadNodeConfig} from './redux/app/app-actions.js'
import {doLoadNotificationConfig} from './redux/user/user-actions.js'
import './persistState.js'
import { initApi } from 'qortal-ui-crypto'
import {initApi} from 'qortal-ui-crypto'
initApi(store)

View File

@ -1,6 +1,6 @@
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) => {
const bytes = CryptoJS.AES.decrypt(ciphertext, salt)
try {
@ -8,4 +8,4 @@ export const decryptData = (ciphertext, salt) => {
} catch(err) {
return null
}
}
}

View File

@ -1,7 +1,7 @@
import config from './config'
import { dispatcher } from './dispatcher'
import {dispatcher} from './dispatcher'
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 _state
@ -44,7 +44,7 @@ const notificationCheck = function () {
export const doNewMessage = function (req) {
const newMessage = () => {
let data
if (req.type && req.type === 'qapp') {
data = req
@ -73,7 +73,7 @@ export const doNewMessage = function (req) {
} else {
_state = notificationState
}
}
}
const page = window.top.location.href
if(req.type && req.type === 'qapp-local-notification'){
try {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
import { store } from '../store.js'
import { EpmlStream } from 'epml'
import {store} from '../store.js'
import {EpmlStream} from 'epml'
const LOGIN_STREAM_NAME = 'logged_in'
const CONFIG_STREAM_NAME = 'config'
@ -10,6 +10,7 @@ const NODE_CONFIG_STREAM_NAME = 'node_config'
const CHAT_LAST_SEEN = 'chat_last_seen'
const SIDE_EFFECT_ACTION = 'side_effect_action'
const PROFILE_DATA_ACTION = 'profile_data_action'
const COIN_BALANCES_ACTION = 'coin_balances'
export const loggedInStream = new EpmlStream(LOGIN_STREAM_NAME, () => store.getState().app.loggedIn)
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 sideEffectActionStream = new EpmlStream(SIDE_EFFECT_ACTION, () => store.getState().app.sideEffectAction)
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){
profileDataActionStream.emit(state.app.profileData)
}
if (oldState.app.coinBalances !== state.app.coinBalances) {
coinBalancesActionStream.emit(state.app.coinBalances)
}
oldState = state
})

View File

@ -1,5 +1,27 @@
// 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) => {
return (dispatch, getState) => {
@ -163,4 +185,11 @@ export const setProfileData = (payload)=> {
type: SET_PROFILE_DATA,
payload
}
}
}
export const setCoinBalances = (payload)=> {
return {
type: SET_COIN_BALANCES,
payload
}
}

View File

@ -1,7 +1,8 @@
import { Epml } from '../../../epml.js'
import { EpmlWorkerPlugin } from 'epml'
import {Epml} from '../../../epml.js'
import {EpmlWorkerPlugin} from 'epml'
import {INIT_WORKERS} from '../app-action-types.js'
import { INIT_WORKERS } from '../app-action-types.js'
Epml.registerPlugin(EpmlWorkerPlugin)
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 => {
return (dispatch, getState) => {

View File

@ -1,6 +1,6 @@
// Node Config Actions here...
import { LOAD_NODE_CONFIG, SET_NODE, ADD_NODE, REMOVE_NODE, EDIT_NODE } from '../app-action-types.js'
import { UI_VERSION } from '../version.js'
import {ADD_NODE, EDIT_NODE, LOAD_NODE_CONFIG, REMOVE_NODE, SET_NODE} from '../app-action-types.js'
import {UI_VERSION} from '../version.js'
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) => {
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_SIDE_EFFECT= 'SET_SIDE_EFFECT'
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/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.
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 { initWorkersReducer } from './reducers/init-workers.js'
import { loginReducer } from './reducers/login-reducer.js'
import { setNode, addNode, removeNode, editNode } from './reducers/manage-node.js'
import {loadStateFromLocalStorage, saveStateToLocalStorage} from '../../localStorageHelpers.js'
import {
ACCOUNT_INFO,
ADD_AUTO_LOAD_IMAGES_CHAT,
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";
const chatLastSeen = localForage.createInstance({
name: "chat-last-seen",
});
@ -53,7 +91,8 @@ const INITIAL_STATE = {
isOpenDevDialog: false,
newNotification: null,
sideEffectAction: null,
profileData: null
profileData: null,
coinBalances: {}
}
export default (state = INITIAL_STATE, action) => {
@ -71,7 +110,7 @@ export default (state = INITIAL_STATE, action) => {
wallet: INITIAL_STATE.wallet,
selectedAddress: INITIAL_STATE.selectedAddress,
accountInfo: INITIAL_STATE.accountInfo
}
case ADD_PLUGIN:
return {
@ -300,6 +339,17 @@ export default (state = INITIAL_STATE, action) => {
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:
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.
// Initial state needs to be loaded from either the getConfig url or localstorage...NOT set via this
import { loadStateFromLocalStorage } from '../../localStorageHelpers'
import { LOAD_CONFIG_FROM_API } from './config-actions.js'
import { loadConfigFromAPI } from './reducers/load-config-from-api.js'
import {loadStateFromLocalStorage} from '../../localStorageHelpers'
import {LOAD_CONFIG_FROM_API} from './config-actions.js'
import {loadConfigFromAPI} from './reducers/load-config-from-api.js'
const DEFAULT_INITIAL_STATE = {
styles: {

View File

@ -1,4 +1,4 @@
import { combineReducers } from 'redux'
import {combineReducers} from 'redux'
import app from './app/app-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) => {
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'

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