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

Merge remote-tracking branch 'main/master' into feature/friends-list

This commit is contained in:
PhilReact 2023-10-21 14:56:34 +03:00
commit dfb7d234e8
32 changed files with 2274 additions and 1447 deletions

View File

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

@ -207,7 +207,8 @@
"exp3": "Exportieren",
"exp4": "Bitte wählen Sie eine Brieftasche aus, um den privaten Hauptschlüssel zu sichern.",
"core": "Core-Einstellungen starten",
"qappNotification1": "Q-App Benachrichtigungen"
"qappNotification1": "Q-App Benachrichtigungen",
"selectnode": "Bitte wählen Sie eine Option"
},
"appinfo": {
"blockheight": "Blockhöhe",
@ -1019,12 +1020,18 @@
"rewarddialog1": "Möchten Sie eine Reward-Share-Transaktion erstellen und",
"rewarddialog2": "Ihrer Prägeprämien teilen mit",
"rewarddialog3": "Wenn ja, müssen Sie den Schlüssel unten speichern, um zu prägen. Es kann an jeden Knoten geliefert werden, damit es in Ihrem Namen prägen kann.",
"rewarddialog4": "Wenn Sie auf Bestätigen drücken, wird der Belohnungsanteil erstellt, aber Sie müssen den oben genannten Schlüssel trotzdem an einen Knoten übermitteln, um mit dem Konto zu prägen.",
"rewarddialog4": "Wenn Sie auf Bestätigen drücken, wird der Belohnungsanteil erstellt, aber Sie müssen den oben genannten Schlüssel trotzdem an einen Knoten übermitteln, um mit dem Konto zu prägen.",
"rewarddialog5": "Sie entfernen eine Prämienaktientransaktion, die mit dem Konto verknüpft ist:",
"rewarddialog6": "Wenn Sie auf „Bestätigen“ klicken, wird die Prämie entfernt und der Prägeschlüssel wird ungültig.",
"rewarddialog6": "Wenn Sie auf Bestätigen drücken, wird die Prämie entfernt und der Prägeschlüssel wird ungültig.",
"deployAtdialog1": "Sie stellen das AT bereit",
"deployAtdialog2": "Wenn Sie auf 'Bestätigen' klicken, wird das AT bereitgestellt!",
"deployAtdialog3": "Anfänglicher Betragssaldo"
"deployAtdialog2": "Wenn Sie auf Bestätigen drücken, wird das AT bereitgestellt!",
"deployAtdialog3": "Anfänglicher Betragssaldo",
"votedialog1": "Sie beantragen, bei der folgenden Umfrage abzustimmen:",
"votedialog2": "Wenn Sie auf Bestätigen drücken, wird die Abstimmungsanfrage gesendet!",
"votedialog3": "Sie beantragen die Erstellung der folgenden Umfrage:",
"votedialog4": "Umfragebeschreibung",
"votedialog5": "Optionen",
"votedialog6": "Wenn Sie auf Bestätigen drücken, wird die Umfrage erstellt!"
},
"sponsorshipspage": {
"schange1": "Aktive Patenschaften",

View File

@ -207,7 +207,8 @@
"exp3": "Exportar",
"exp4": "Elija una billetera para hacer una copia de seguridad de la clave maestra privada.",
"core": "Iniciar configuración básica",
"qappNotification1": "Notificaciones de Q-App"
"qappNotification1": "Notificaciones de Q-App",
"selectnode": "Por favor seleccione una opción"
},
"appinfo": {
"blockheight": "Altura del Bloque",
@ -1024,7 +1025,13 @@
"rewarddialog6": "Al presionar confirmar, se eliminará la recompensa compartida y la clave de acuñación dejará de ser válida.",
"deployAtdialog1": "Estás implementando el AT",
"deployAtdialog2": "¡Al presionar confirmar, el AT será implementado!",
"deployAtdialog3": "Saldo del importe inicial"
"deployAtdialog3": "Saldo del importe inicial",
"votedialog1": "Estás solicitando votar en la siguiente encuesta:",
"votedialog2": "¡Al presionar confirmar, se enviará la solicitud de voto!",
"votedialog3": "Estás solicitando crear la encuesta a continuación:",
"votedialog4": "Descripción de la encuesta",
"votedialog5": "Opciones",
"votedialog6": "¡Al presionar confirmar, se creará la encuesta!"
},
"sponsorshipspage": {
"schange1": "Patrocinios Activos",

File diff suppressed because it is too large Load Diff

View File

@ -207,7 +207,8 @@
"exp3": "Exporter",
"exp4": "Veuillez choisir un portefeuille pour sauvegarder la clé principale privée.",
"core": "Démarrer les paramètres du noyau",
"qappNotification1": "Notifications Q-App"
"qappNotification1": "Notifications Q-App",
"selectnode": "Veuillez sélectionner une option"
},
"appinfo": {
"blockheight": "Hauteur de bloc",
@ -1024,7 +1025,13 @@
"rewarddialog6": "En appuyant sur confirmer, le partage de récompense sera supprimé et la clé de frappe deviendra invalide.",
"deployAtdialog1": "Vous déployez l'AT",
"deployAtdialog2": "En appuyant sur confirmer, l'AT sera déployé !",
"deployAtdialog3": "Solde du montant initial"
"deployAtdialog3": "Solde du montant initial",
"votedialog1": "Vous demandez à voter sur le sondage ci-dessous :",
"votedialog2": "En appuyant sur confirmer, la demande de vote sera envoyée !",
"votedialog3": "Vous demandez la création du sondage ci-dessous :",
"votedialog4": "Description du sondage",
"votedialog5": "Options",
"votedialog6": "En appuyant sur confirmer, le sondage sera créé !"
},
"sponsorshipspage": {
"schange1": "Parrainages actifs",

View File

@ -207,7 +207,8 @@
"exp3": "निर्यात",
"exp4": "निजी मास्टर कुंजी का बैकअप लेने के लिए कृपया एक वॉलेट चुनें।",
"core": "कोर सेटिंग प्रारंभ करें",
"qappNotification1": "क्यू-ऐप अधिसूचनाएँ"
"qappNotification1": "क्यू-ऐप अधिसूचनाएँ",
"selectnode": "कृपया एक विकल्प चुनें"
},
"appinfo": {
"blockheight": "ब्लॉक ऊँचाई",
@ -1024,7 +1025,13 @@
"rewarddialog6": "कन्फर्म दबाने पर, रिवॉर्डशेयर हटा दिया जाएगा और मिंटिंग की अमान्य हो जाएगी।",
"deployAtdialog1": "आप एटी तैनात कर रहे हैं",
"deployAtdialog2": "पुष्टि बटन दबाने पर, AT तैनात हो जाएगा!",
"deployAtdialog3": "प्रारंभिक राशि शेष"
"deployAtdialog3": "प्रारंभिक राशि शेष",
"votedialog1": "आप नीचे दिए गए मतदान पर मतदान करने का अनुरोध कर रहे हैं:",
"votedialog2": "कन्फ़र्म बटन दबाने पर वोट अनुरोध भेज दिया जाएगा!",
"votedialog3": "आप नीचे पोल बनाने का अनुरोध कर रहे हैं:",
"votedialog4": "मतदान विवरण",
"votedialog5": "विकल्प",
"votedialog6": "कन्फर्म दबाने पर पोल क्रिएट हो जाएगा!"
},
"sponsorshipspage": {
"schange1": "सक्रिय प्रायोजन",

View File

@ -207,7 +207,8 @@
"exp3": "Izvoz",
"exp4": "Odaberite novčanik za sigurnosnu kopiju privatnog glavnog ključa.",
"core": "Pokreni osnovne postavke",
"qappNotification1": "Obavijesti Q-App"
"qappNotification1": "Obavijesti Q-App",
"selectnode": "Molimo odaberite opciju"
},
"appinfo": {
"blockheight": "Visina bloka",
@ -1024,7 +1025,13 @@
"rewarddialog6": "Pritiskom na potvrdu, dijeljenje nagrade bit će uklonjeno, a ključ za kovanje postat će nevažeći.",
"deployAtdialog1": "Uvodite AT",
"deployAtdialog2": "Pritiskom na potvrdu, AT će biti postavljen!",
"deployAtdialog3": "Početni iznos stanja"
"deployAtdialog3": "Početni iznos stanja",
"votedialog1": "Tražite da glasate u anketi ispod:",
"votedialog2": "Pritiskom na potvrdu, zahtjev za glasovanje bit će poslan!",
"votedialog3": "Tražite izradu ankete ispod:",
"votedialog4": "Opis ankete",
"votedialog5": "Mogućnosti",
"votedialog6": "Pritiskom na potvrdu, anketa će biti kreirana!"
},
"sponsorshipspage": {
"schange1": "Aktivna sponzorstva",

View File

@ -207,7 +207,8 @@
"exp3": "Exportálás",
"exp4": "Kérjük, válasszon egy tárcát a privát főkulcs biztonsági mentéséhez.",
"core": "Alapbeállítások indítása",
"qappNotification1": "Q-App értesítések"
"qappNotification1": "Q-App értesítések",
"selectnode": "Kérjük, válasszon egy lehetőséget"
},
"appinfo": {
"blockheight": "Blokk Magassága",
@ -1024,7 +1025,13 @@
"rewarddialog6": "A megerősítés megnyomására a jutalommegosztás törlődik, és a pénzverési kulcs érvénytelenné válik.",
"deployAtdialog1": "Ön telepíti az AT-t",
"deployAtdialog2": "A megerősítés megnyomására az AT telepítésre kerül!",
"deployAtdialog3": "Kezdő összeg egyenleg"
"deployAtdialog3": "Kezdő összeg egyenleg",
"votedialog1": "Az alábbi szavazásra kérsz szavazást:",
"votedialog2": "A megerősítés megnyomására a szavazás elküldésre kerül!",
"votedialog3": "Az alábbi szavazás létrehozását kéri:",
"votedialog4": "Szavazás leírása",
"votedialog5": "Lehetőségek",
"votedialog6": "A megerősítés megnyomására a szavazás létrejön!"
},
"sponsorshipspage": {
"schange1": "Aktív szponzorálás",

View File

@ -207,7 +207,8 @@
"exp3": "Esporta",
"exp4": "Scegli un portafoglio per il backup della chiave master privata.",
"core": "Avvia impostazioni principali",
"qappNotification1": "Notifiche Q-App"
"qappNotification1": "Notifiche Q-App",
"selectnode": "Seleziona un'opzione"
},
"appinfo": {
"blockheight": "Altezza blocco",
@ -1024,7 +1025,13 @@
"rewarddialog6": "Premendo conferma, la condivisione del premio verrà rimossa e la chiave di conio non sarà più valida.",
"deployAtdialog1": "Stai distribuendo l'AT",
"deployAtdialog2": "Premendo conferma, l'AT verrà schierato!",
"deployAtdialog3": "Saldo importo iniziale"
"deployAtdialog3": "Saldo importo iniziale",
"votedialog1": "Stai richiedendo di votare per il sondaggio qui sotto:",
"votedialog2": "Premendo conferma, la richiesta di voto verrà inviata!",
"votedialog3": "Stai richiedendo di creare il sondaggio qui sotto:",
"votedialog4": "Descrizione sondaggio",
"votedialog5": "Opzioni",
"votedialog6": "Premendo conferma, il sondaggio verrà creato!"
},
"sponsorshipspage": {
"schange1": "Sponsorizzazioni attive",

View File

@ -207,7 +207,8 @@
"exp3": "エクスポート",
"exp4": "秘密マスターキーをバックアップするウォレットを選択してください。",
"core": "Core設定を開始",
"qappNotification1": "Q-App 通知"
"qappNotification1": "Q-App 通知",
"selectnode": "オプションを選択してください"
},
"appinfo": {
"blockheight": "ブロック高",
@ -1024,7 +1025,13 @@
"rewarddialog6": "確認を押すと、報酬シェアが削除され、ミントキーが無効になります。",
"deployAtdialog1": "AT を展開しています",
"deployAtdialog2": "確認を押すと、AT が展開されます!",
"deployAtdialog3": "初期金額残高"
"deployAtdialog3": "初期金額残高",
"votedialog1": "以下のアンケートへの投票をリクエストしています。",
"votedialog2": "確認を押すと、投票リクエストが送信されます。",
"votedialog3": "以下の投票の作成をリクエストしています:",
"votedialog4": "投票の説明",
"votedialog5": "オプション",
"votedialog6": "確認を押すと投票が作成されます。"
},
"sponsorshipspage": {
"schange1": "アクティブなスポンサーシップ",

View File

@ -207,7 +207,8 @@
"exp3": "내보내기",
"exp4": "개인 마스터 키를 백업할 지갑을 선택하세요.",
"core": "코어 설정 시작",
"qappNotification1": "Q-App 알림"
"qappNotification1": "Q-App 알림",
"selectnode": "옵션을 선택하세요"
},
"appinfo": {
"blockheight": "블록 높이",
@ -1024,7 +1025,13 @@
"rewarddialog6": "확인을 누르면 보상 공유가 제거되고 조폐 키가 유효하지 않게 됩니다.",
"deployAtdialog1": "AT를 배치하고 있습니다",
"deployAtdialog2": "확인을 누르면 AT가 배치됩니다!",
"deployAtdialog3": "초기 잔액"
"deployAtdialog3": "초기 잔액",
"votedialog1": "아래 설문조사에 투표를 요청합니다:",
"votedialog2": "확인을 누르면 투표 요청이 전송됩니다!",
"votedialog3": "아래 설문조사 생성을 요청하고 있습니다.",
"votedialog4": "설문조사 설명",
"votedialog5": "옵션",
"votedialog6": "확인을 누르면 설문조사가 생성됩니다!"
},
"sponsorshipspage": {
"schange1": "적극적인 후원",

View File

@ -207,7 +207,8 @@
"exp3": "Eksporter",
"exp4": "Velg en lommebok for å sikkerhetskopiere den private hovednøkkelen.",
"core": "Start kjerneinnstillinger",
"qappNotification1": "Q-App varsler"
"qappNotification1": "Q-App varsler",
"selectnode": "Vennligst velg et alternativ"
},
"appinfo": {
"blockheight": "Blokkhøyde",
@ -1024,7 +1025,13 @@
"rewarddialog6": "Ved å trykke på Bekreft, vil belønningsdelen bli fjernet og mintnøkkelen blir ugyldig.",
"deployAtdialog1": "Du distribuerer AT",
"deployAtdialog2": "Når du trykker på bekreftelse, vil AT bli distribuert!",
"deployAtdialog3": "Startbeløpssaldo"
"deployAtdialog3": "Startbeløpssaldo",
"votedialog1": "Du ber om å stemme på avstemningen nedenfor:",
"votedialog2": "Ved å trykke bekreft vil stemmeforespørselen bli sendt!",
"votedialog3": "Du ber om å lage avstemningen nedenfor:",
"votedialog4": "Avstemningsbeskrivelse",
"votedialog5": "Alternativer",
"votedialog6": "Når du trykker på bekreft, blir avstemningen opprettet!"
},
"sponsorshipspage": {
"schange1": "Aktive sponsorer",

View File

@ -207,7 +207,8 @@
"exp3": "Eksportuj",
"exp4": "Wybierz portfel do wykonania kopii zapasowej prywatnego klucza głównego.",
"core": "Uruchom podstawowe ustawienia",
"qappNotification1": "Powiadomienia Q-App"
"qappNotification1": "Powiadomienia Q-App",
"selectnode": "Proszę wybrać opcję"
},
"appinfo": {
"blockheight": "Wysokość bloku",
@ -1024,7 +1025,13 @@
"rewarddialog6": "Po naciśnięciu przycisku Potwierdź udział w nagrodach zostanie usunięty, a klucz bicia stanie się nieważny.",
"deployAtdialog1": "Wdrażasz terminal AT",
"deployAtdialog2": "Po naciśnięciu przycisku potwierdzenia terminal AT zostanie wdrożony!",
"deployAtdialog3": "Saldo kwoty początkowej"
"deployAtdialog3": "Saldo kwoty początkowej",
"votedialog1": "Prosimy o oddanie głosu w poniższej ankiecie:",
"votedialog2": "Po naciśnięciu potwierdzenia zostanie wysłana prośba o głos!",
"votedialog3": "Prosisz o utworzenie poniższej ankiety:",
"votedialog4": "Opis ankiety",
"votedialog5": "Opcje",
"votedialog6": "Po naciśnięciu potwierdzenia ankieta zostanie utworzona!"
},
"sponsorshipspage": {
"schange1": "Aktywny Sponsoring",

View File

@ -207,7 +207,8 @@
"exp3": "Exportar",
"exp4": "Por favor, escolha uma carteira para fazer backup da chave mestra privada.",
"core": "Iniciar configurações do núcleo",
"qappNotification1": "Notificações de Q-App"
"qappNotification1": "Notificações de Q-App",
"selectnode": "Por favor selecione uma opção"
},
"appinfo": {
"blockheight": "Altura do Bloco",
@ -1024,7 +1025,13 @@
"rewarddialog6": "Ao pressionar confirmar, o rewardshare será removido e a chave de cunhagem se tornará inválida.",
"deployAtdialog1": "Você está implantando o AT",
"deployAtdialog2": "Ao pressionar confirmar, o AT será implantado!",
"deployAtdialog3": "Saldo do valor inicial"
"deployAtdialog3": "Saldo do valor inicial",
"votedialog1": "Você está solicitando votar na enquete abaixo:",
"votedialog2": "Ao pressionar confirmar, o pedido de voto será enviado!",
"votedialog3": "Você está solicitando a criação da enquete abaixo:",
"votedialog4": "Descrição da enquete",
"votedialog5": "Opções",
"votedialog6": "Ao pressionar confirmar, a enquete será criada!"
},
"sponsorshipspage": {
"schange1": "Patrocínios Ativos",

View File

@ -207,7 +207,8 @@
"exp3": "Export",
"exp4": "Vă rugăm să alegeți un portofel pentru a face backup cheii master private.",
"core": "Porniți setările de bază",
"qappNotification1": "Notificări Q-App"
"qappNotification1": "Notificări Q-App",
"selectnode": "Vă rugăm să selectați o opțiune"
},
"appinfo": {
"blockheight": "Dimensiunea blocului",
@ -1024,7 +1025,13 @@
"rewarddialog6": "La apasarea butonului de confirmare, recompensa va fi eliminata, iar cheia de obtinere de recompensa (minting) va deveni invalida.",
"deployAtdialog1": "Implementați AT",
"deployAtdialog2": "La apăsarea confirmării, AT va fi implementat!",
"deployAtdialog3": "Soldul sumei inițiale"
"deployAtdialog3": "Soldul sumei inițiale",
"votedialog1": "Soliciți să votați la sondajul de mai jos:",
"votedialog2": "La apăsarea confirmării, cererea de vot va fi trimisă!",
"votedialog3": "Soliciți să creezi sondajul de mai jos:",
"votedialog4": "Descrierea sondajului",
"votedialog5": "Opțiuni",
"votedialog6": "La apăsarea confirmării, sondajul va fi creat!"
},
"sponsorshipspage": {
"schange1": "Sponsorizari active",

View File

@ -207,7 +207,8 @@
"exp3": "Izvoz",
"exp4": "Molimo izaberite novčanik za rezervnu kopiju privatnog glavnog ključa.",
"core": "Pokreni podešavanja jezgra",
"qappNotification1": "Obaveštenja o Q-App"
"qappNotification1": "Obaveštenja o Q-App",
"selectnode": "Izaberite opciju"
},
"appinfo": {
"blockheight": "Visina Bloka",
@ -1024,7 +1025,13 @@
"rewarddialog6": "Pritiskom na potvrdu, udeo nagrade će biti uklonjen i ključ za kovanje će postati nevažeći.",
"deployAtdialog1": "Postavljate AT",
"deployAtdialog2": "Pritiskom na potvrdi, AT će biti raspoređen!",
"deployAtdialog3": "Početni saldo iznosa"
"deployAtdialog3": "Početni saldo iznosa",
"votedialog1": "Tražite da glasate u anketi ispod:",
"votedialog2": "Pritiskom na potvrdi, zahtev za glasanje će biti poslat!",
"votedialog3": "Zahtevate da napravite anketu ispod:",
"votedialog4": "Opis ankete",
"votedialog5": "Opcije",
"votedialog6": "Pritiskom na potvrdi, anketa će biti kreirana!"
},
"sponsorshipspage": {
"schange1": "Aktivna sponzorstva",

View File

@ -207,7 +207,8 @@
"exp3": "Экспорт",
"exp4": "Пожалуйста, выберите кошелек для резервного копирования приватного главного ключа.",
"core": "Начать основные настройки",
"qappNotification1": "Уведомления Q-App"
"qappNotification1": "Уведомления Q-App",
"selectnode": "Пожалуйста, выберите вариант"
},
"appinfo": {
"blockheight": "Высота блока",
@ -1024,7 +1025,13 @@
"rewarddialog6": "При нажатии кнопки подтверждения доля вознаграждения будет удалена, а ключ чеканки станет недействительным.",
"deployAtdialog1": "Вы развертываете AT",
"deployAtdialog2": "При нажатии подтверждения AT будет развернут!",
"deployAtdialog3": "Начальный баланс суммы"
"deployAtdialog3": "Начальный баланс суммы",
"votedialog1": "Вы просите проголосовать в опросе ниже:",
"votedialog2": "При нажатии на подтверждение запрос на голосование будет отправлен!",
"votedialog3": "Вы просите создать опрос ниже:",
"votedialog4": "Описание опроса",
"votedialog5": "Параметры",
"votedialog6": "При нажатии на подтверждение опрос будет создан!"
},
"sponsorshipspage": {
"schange1": "Активное спонсорство",

View File

@ -207,7 +207,8 @@
"exp3": "Export",
"exp4": "Please choose a wallet to backup the private master key.",
"core": "Start Core Settings",
"qappNotification1": "Q-App Notifications"
"qappNotification1": "Q-App Notifications",
"selectnode": "Please select an option"
},
"appinfo": {
"blockheight": "Block Height",
@ -1024,7 +1025,13 @@
"rewarddialog6": "On pressing confirm, the rewardshare 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"
"deployAtdialog3": "Initial amount balance",
"votedialog1": "You are requesting to vote on the poll below:",
"votedialog2": "On pressing confirm, the vote request will be sent!",
"votedialog3": "You are requesting to create the poll below:",
"votedialog4": "Poll Description",
"votedialog5": "Options",
"votedialog6": "On pressing confirm, the poll will be created!"
},
"sponsorshipspage": {
"schange1": "Active Sponsorships",

View File

@ -207,7 +207,8 @@
"exp3": "导出",
"exp4": "请选择一个钱包来备份私钥。",
"core": "开始核心设置",
"qappNotification1": "Q-App 通知"
"qappNotification1": "Q-App 通知",
"selectnode": "请选择一个选项"
},
"appinfo": {
"blockheight": "区块高度",
@ -1024,7 +1025,13 @@
"rewarddialog6": "点击确认后,铸币密钥将被移除并失效。",
"deployAtdialog1": "您正在部署 AT",
"deployAtdialog2": "按下确认键后AT 将被部署!",
"deployAtdialog3": "初始金额余额"
"deployAtdialog3": "初始金额余额",
"votedialog1": "您请求对以下民意调查进行投票:",
"votedialog2": "按下确认后,投票请求将被发送!",
"votedialog3": "您请求创建以下投票:",
"votedialog4": "投票说明",
"votedialog5": "选项",
"votedialog6": "按确认后,将创建投票!"
},
"sponsorshipspage": {
"schange1": "目前有效的赞助记录",

View File

@ -207,7 +207,8 @@
"exp3": "導出",
"exp4": "請選擇一個錢包來備份私鑰。",
"core": "開始核心設置",
"qappNotification1": "Q-App 通知"
"qappNotification1": "Q-App 通知",
"selectnode": "請選擇一個選項"
},
"appinfo": {
"blockheight": "區塊高度",
@ -1024,7 +1025,13 @@
"rewarddialog6": "點擊確認後,鑄幣密鑰將被移除並失效。",
"deployAtdialog1": "您正在部署 AT",
"deployAtdialog2": "按下確認鍵後AT 將被部署!",
"deployAtdialog3": "初始金額餘額"
"deployAtdialog3": "初始金額餘額",
"votedialog1": "您要求對以下民意調查進行投票:",
"votedialog2": "按下確認後,投票請求將被發送!",
"votedialog3": "您請求建立以下投票:",
"votedialog4": "投票說明",
"votedialog5": "選項",
"votedialog6": "按確認後,將創建投票!"
},
"sponsorshipspage": {
"schange1": "目前有效的贊助記錄",

View File

@ -73,11 +73,23 @@ class AppView extends connect(store)(LitElement) {
rvnWalletBalance: { type: Number },
arrrWalletBalance: { type: Number },
tradesOpenBtcQortal: { type: Array },
tradesFailedBtcQortal: { type: Array },
tradesOpenBtcQortalCleaned: { type: Array },
tradesOpenLtcQortal: { type: Array },
tradesFailedLtcQortal: { type: Array },
tradesOpenLtcQortalCleaned: { type: Array },
tradesOpenDogeQortal: { type: Array },
tradesFailedDogeQortal: { type: Array },
tradesOpenDogeQortalCleaned: { type: Array },
tradesOpenDgbQortal: { type: Array },
tradesFailedDgbQortal: { type: Array },
tradesOpenDgbQortalCleaned: { type: Array },
tradesOpenRvnQortal: { type: Array },
tradesFailedRvnQortal: { type: Array },
tradesOpenRvnQortalCleaned: { type: Array },
tradesOpenArrrQortal: { type: Array },
tradesFailedArrrQortal: { type: Array },
tradesOpenArrrQortalCleaned: { type: Array },
tradeBotBtcBook: { type: Array },
tradeBotLtcBook: { type: Array },
tradeBotDogeBook: { type: Array },
@ -451,11 +463,23 @@ class AppView extends connect(store)(LitElement) {
this.rvnWalletBalance = 0
this.arrrWalletBalance = 0
this.tradesOpenBtcQortal = []
this.tradesFailedBtcQortal = []
this.tradesOpenBtcQortalCleaned = []
this.tradesOpenLtcQortal = []
this.tradesFailedLtcQortal = []
this.tradesOpenLtcQortalCleaned = []
this.tradesOpenDogeQortal = []
this.tradesFailedDogeQortal = []
this.tradesOpenDogeQortalCleaned = []
this.tradesOpenDgbQortal = []
this.tradesFailedDgbQortal = []
this.tradesOpenDgbQortalCleaned = []
this.tradesOpenRvnQortal = []
this.tradesFailedRvnQortal = []
this.tradesOpenRvnQortalCleaned = []
this.tradesOpenArrrQortal = []
this.tradesFailedArrrQortal = []
this.tradesOpenArrrQortalCleaned = []
this.tradeBotBtcBook = []
this.tradeBotLtcBook = []
this.tradeBotDogeBook = []
@ -773,11 +797,36 @@ class AppView extends connect(store)(LitElement) {
price: roundedPrice,
foreignAmount: item.expectedForeignAmount,
qortalCreator: item.qortalCreator,
qortalAtAddress: item.qortalAtAddress
qortalAtAddress: item.qortalAtAddress,
qortalCreatorTradeAddress: item.qortalCreatorTradeAddress
}
}
}).filter(item => !!item)
const tradesFailedBtcQortalUrl = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true`
const tradesFailedBtcQortal = await fetch(tradesFailedBtcQortalUrl).then(response => {
return response.json()
})
this.tradesFailedBtcQortal = tradesFailedBtcQortal.map(item => {
const messageTimeDiff = Date.now() - item.timestamp
const oneHour = 60 * 60 * 1000
if (Number(messageTimeDiff) > Number(oneHour)) {
return {
timestamp: item.timestamp,
recipient: item.recipient
}
}
}).filter(item => !!item)
this.tradesFailedBtcQortal.map(item => {
const recipientToRemove = item.recipient
this.tradesOpenBtcQortalCleaned = this.tradesOpenBtcQortal.filter(obj => {
return obj.qortalCreatorTradeAddress !== recipientToRemove
})
})
await appDelay(1000)
filterMyBotPriceTradesBTC()
setTimeout(getOpenTradesBTC, 150000)
@ -795,7 +844,7 @@ class AppView extends connect(store)(LitElement) {
await appDelay(1000)
this.tradeBotAvailableBtcQortal = this.tradesOpenBtcQortal.map(item => {
this.tradeBotAvailableBtcQortal = this.tradesOpenBtcQortalCleaned.map(item => {
const listprice = parseFloat(item.price)
const listamount = parseFloat(item.qortAmount)
const checkprice = parseFloat(this.tradeBotBtcBook[0].botBtcPrice)
@ -806,7 +855,8 @@ class AppView extends connect(store)(LitElement) {
price: item.price,
foreignAmount: item.foreignAmount,
qortalCreator: item.qortalCreator,
qortalAtAddress: item.qortalAtAddress
qortalAtAddress: item.qortalAtAddress,
qortalCreatorTradeAddress: item.qortalCreatorTradeAddress
}
}
}).filter(item => !!item)
@ -914,11 +964,36 @@ class AppView extends connect(store)(LitElement) {
price: roundedPrice,
foreignAmount: item.expectedForeignAmount,
qortalCreator: item.qortalCreator,
qortalAtAddress: item.qortalAtAddress
qortalAtAddress: item.qortalAtAddress,
qortalCreatorTradeAddress: item.qortalCreatorTradeAddress
}
}
}).filter(item => !!item)
const tradesFailedLtcQortalUrl = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true`
const tradesFailedLtcQortal = await fetch(tradesFailedLtcQortalUrl).then(response => {
return response.json()
})
this.tradesFailedLtcQortal = tradesFailedLtcQortal.map(item => {
const messageTimeDiff = Date.now() - item.timestamp
const oneHour = 60 * 60 * 1000
if (Number(messageTimeDiff) > Number(oneHour)) {
return {
timestamp: item.timestamp,
recipient: item.recipient
}
}
}).filter(item => !!item)
this.tradesFailedLtcQortal.map(item => {
const recipientToRemove = item.recipient
this.tradesOpenLtcQortalCleaned = this.tradesOpenLtcQortal.filter(obj => {
return obj.qortalCreatorTradeAddress !== recipientToRemove
})
})
await appDelay(1000)
filterMyBotPriceTradesLTC()
setTimeout(getOpenTradesLTC, 150000)
@ -936,7 +1011,7 @@ class AppView extends connect(store)(LitElement) {
await appDelay(1000)
this.tradeBotAvailableLtcQortal = this.tradesOpenLtcQortal.map(item => {
this.tradeBotAvailableLtcQortal = this.tradesOpenLtcQortalCleaned.map(item => {
const listprice = parseFloat(item.price)
const listamount = parseFloat(item.qortAmount)
const checkprice = parseFloat(this.tradeBotLtcBook[0].botLtcPrice)
@ -947,7 +1022,8 @@ class AppView extends connect(store)(LitElement) {
price: item.price,
foreignAmount: item.foreignAmount,
qortalCreator: item.qortalCreator,
qortalAtAddress: item.qortalAtAddress
qortalAtAddress: item.qortalAtAddress,
qortalCreatorTradeAddress: item.qortalCreatorTradeAddress
}
}
}).filter(item => !!item)
@ -1055,11 +1131,36 @@ class AppView extends connect(store)(LitElement) {
price: roundedPrice,
foreignAmount: item.expectedForeignAmount,
qortalCreator: item.qortalCreator,
qortalAtAddress: item.qortalAtAddress
qortalAtAddress: item.qortalAtAddress,
qortalCreatorTradeAddress: item.qortalCreatorTradeAddress
}
}
}).filter(item => !!item)
const tradesFailedDogeQortalUrl = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true`
const tradesFailedDogeQortal = await fetch(tradesFailedDogeQortalUrl).then(response => {
return response.json()
})
this.tradesFailedDogeQortal = tradesFailedDogeQortal.map(item => {
const messageTimeDiff = Date.now() - item.timestamp
const oneHour = 60 * 60 * 1000
if (Number(messageTimeDiff) > Number(oneHour)) {
return {
timestamp: item.timestamp,
recipient: item.recipient
}
}
}).filter(item => !!item)
this.tradesFailedDogeQortal.map(item => {
const recipientToRemove = item.recipient
this.tradesOpenDogeQortalCleaned = this.tradesOpenDogeQortal.filter(obj => {
return obj.qortalCreatorTradeAddress !== recipientToRemove
})
})
await appDelay(1000)
filterMyBotPriceTradesDOGE()
setTimeout(getOpenTradesDOGE, 150000)
@ -1077,7 +1178,7 @@ class AppView extends connect(store)(LitElement) {
await appDelay(1000)
this.tradeBotAvailableDogeQortal = this.tradesOpenDogeQortal.map(item => {
this.tradeBotAvailableDogeQortal = this.tradesOpenDogeQortalCleaned.map(item => {
const listprice = parseFloat(item.price)
const listamount = parseFloat(item.qortAmount)
const checkprice = parseFloat(this.tradeBotDogeBook[0].botDogePrice)
@ -1088,7 +1189,8 @@ class AppView extends connect(store)(LitElement) {
price: item.price,
foreignAmount: item.foreignAmount,
qortalCreator: item.qortalCreator,
qortalAtAddress: item.qortalAtAddress
qortalAtAddress: item.qortalAtAddress,
qortalCreatorTradeAddress: item.qortalCreatorTradeAddress
}
}
}).filter(item => !!item)
@ -1196,11 +1298,36 @@ class AppView extends connect(store)(LitElement) {
price: roundedPrice,
foreignAmount: item.expectedForeignAmount,
qortalCreator: item.qortalCreator,
qortalAtAddress: item.qortalAtAddress
qortalAtAddress: item.qortalAtAddress,
qortalCreatorTradeAddress: item.qortalCreatorTradeAddress
}
}
}).filter(item => !!item)
const tradesFailedDgbQortalUrl = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true`
const tradesFailedDgbQortal = await fetch(tradesFailedDgbQortalUrl).then(response => {
return response.json()
})
this.tradesFailedDgbQortal = tradesFailedDgbQortal.map(item => {
const messageTimeDiff = Date.now() - item.timestamp
const oneHour = 60 * 60 * 1000
if (Number(messageTimeDiff) > Number(oneHour)) {
return {
timestamp: item.timestamp,
recipient: item.recipient
}
}
}).filter(item => !!item)
this.tradesFailedDgbQortal.map(item => {
const recipientToRemove = item.recipient
this.tradesOpenDgbQortalCleaned = this.tradesOpenDgbQortal.filter(obj => {
return obj.qortalCreatorTradeAddress !== recipientToRemove
})
})
await appDelay(1000)
filterMyBotPriceTradesDGB()
setTimeout(getOpenTradesDGB, 150000)
@ -1218,7 +1345,7 @@ class AppView extends connect(store)(LitElement) {
await appDelay(1000)
this.tradeBotAvailableDgbQortal = this.tradesOpenDgbQortal.map(item => {
this.tradeBotAvailableDgbQortal = this.tradesOpenDgbQortalCleaned.map(item => {
const listprice = parseFloat(item.price)
const listamount = parseFloat(item.qortAmount)
const checkprice = parseFloat(this.tradeBotDgbBook[0].botDgbPrice)
@ -1229,7 +1356,8 @@ class AppView extends connect(store)(LitElement) {
price: item.price,
foreignAmount: item.foreignAmount,
qortalCreator: item.qortalCreator,
qortalAtAddress: item.qortalAtAddress
qortalAtAddress: item.qortalAtAddress,
qortalCreatorTradeAddress: item.qortalCreatorTradeAddress
}
}
}).filter(item => !!item)
@ -1337,11 +1465,36 @@ class AppView extends connect(store)(LitElement) {
price: roundedPrice,
foreignAmount: item.expectedForeignAmount,
qortalCreator: item.qortalCreator,
qortalAtAddress: item.qortalAtAddress
qortalAtAddress: item.qortalAtAddress,
qortalCreatorTradeAddress: item.qortalCreatorTradeAddress
}
}
}).filter(item => !!item)
const tradesFailedRvnQortalUrl = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true`
const tradesFailedRvnQortal = await fetch(tradesFailedRvnQortalUrl).then(response => {
return response.json()
})
this.tradesFailedRvnQortal = tradesFailedRvnQortal.map(item => {
const messageTimeDiff = Date.now() - item.timestamp
const oneHour = 60 * 60 * 1000
if (Number(messageTimeDiff) > Number(oneHour)) {
return {
timestamp: item.timestamp,
recipient: item.recipient
}
}
}).filter(item => !!item)
this.tradesFailedRvnQortal.map(item => {
const recipientToRemove = item.recipient
this.tradesOpenRvnQortalCleaned = this.tradesOpenRvnQortal.filter(obj => {
return obj.qortalCreatorTradeAddress !== recipientToRemove
})
})
await appDelay(1000)
filterMyBotPriceTradesRVN()
setTimeout(getOpenTradesRVN, 150000)
@ -1359,7 +1512,7 @@ class AppView extends connect(store)(LitElement) {
await appDelay(1000)
this.tradeBotAvailableRvnQortal = this.tradesOpenRvnQortal.map(item => {
this.tradeBotAvailableRvnQortal = this.tradesOpenRvnQortalCleaned.map(item => {
const listprice = parseFloat(item.price)
const listamount = parseFloat(item.qortAmount)
const checkprice = parseFloat(this.tradeBotRvnBook[0].botRvnPrice)
@ -1370,7 +1523,8 @@ class AppView extends connect(store)(LitElement) {
price: item.price,
foreignAmount: item.foreignAmount,
qortalCreator: item.qortalCreator,
qortalAtAddress: item.qortalAtAddress
qortalAtAddress: item.qortalAtAddress,
qortalCreatorTradeAddress: item.qortalCreatorTradeAddress
}
}
}).filter(item => !!item)
@ -1478,11 +1632,36 @@ class AppView extends connect(store)(LitElement) {
price: roundedPrice,
foreignAmount: item.expectedForeignAmount,
qortalCreator: item.qortalCreator,
qortalAtAddress: item.qortalAtAddress
qortalAtAddress: item.qortalAtAddress,
qortalCreatorTradeAddress: item.qortalCreatorTradeAddress
}
}
}).filter(item => !!item)
const tradesFailedArrrQortalUrl = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true`
const tradesFailedArrrQortal = await fetch(tradesFailedArrrQortalUrl).then(response => {
return response.json()
})
this.tradesFailedArrrQortal = tradesFailedArrrQortal.map(item => {
const messageTimeDiff = Date.now() - item.timestamp
const oneHour = 60 * 60 * 1000
if (Number(messageTimeDiff) > Number(oneHour)) {
return {
timestamp: item.timestamp,
recipient: item.recipient
}
}
}).filter(item => !!item)
this.tradesFailedArrrQortal.map(item => {
const recipientToRemove = item.recipient
this.tradesOpenArrrQortalCleaned = this.tradesOpenArrrQortal.filter(obj => {
return obj.qortalCreatorTradeAddress !== recipientToRemove
})
})
await appDelay(1000)
filterMyBotPriceTradesARRR()
setTimeout(getOpenTradesARRR, 150000)
@ -1500,7 +1679,7 @@ class AppView extends connect(store)(LitElement) {
await appDelay(1000)
this.tradeBotAvailableArrrQortal = this.tradesOpenArrrQortal.map(item => {
this.tradeBotAvailableArrrQortal = this.tradesOpenArrrQortalCleaned.map(item => {
const listprice = parseFloat(item.price)
const listamount = parseFloat(item.qortAmount)
const checkprice = parseFloat(this.tradeBotArrrBook[0].botArrrPrice)
@ -1511,7 +1690,8 @@ class AppView extends connect(store)(LitElement) {
price: item.price,
foreignAmount: item.foreignAmount,
qortalCreator: item.qortalCreator,
qortalAtAddress: item.qortalAtAddress
qortalAtAddress: item.qortalAtAddress,
qortalCreatorTradeAddress: item.qortalCreatorTradeAddress
}
}
}).filter(item => !!item)

View File

@ -179,6 +179,30 @@ class StartMinting extends connect(store)(LitElement) {
this.openDialogRewardShare = false;
this.status = 0;
this.privateRewardShareKey = "";
this.address = this.getAddress();
this.nonce = this.getNonce();
this.base58PublicKey = this.getBase58PublicKey()
}
getBase58PublicKey(){
const appState = window.parent.reduxStore.getState().app;
const selectedAddress = appState && appState.selectedAddress;
const base58PublicKey = selectedAddress && selectedAddress.base58PublicKey;
return base58PublicKey || ""
}
getAddress(){
const appState = window.parent.reduxStore.getState().app;
const selectedAddress = appState && appState.selectedAddress;
const address = selectedAddress && selectedAddress.address;
return address || ""
}
getNonce(){
const appState = window.parent.reduxStore.getState().app;
const selectedAddress = appState && appState.selectedAddress;
const nonce = selectedAddress && selectedAddress.nonce;
return nonce || ""
}
render() {
@ -223,7 +247,7 @@ class StartMinting extends connect(store)(LitElement) {
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node];
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
this.status = value
const address = window.parent.reduxStore.getState().app?.selectedAddress?.address;
const address = this.address
// Check to see if a sponsorship key on a newly-level 1 minter exists. If it does, remove it.
const findMintingAccountFromOtherUser = this.mintingAccountData.find((ma) => ma.recipientAccount === address && ma.mintingAccount !== address);
@ -247,12 +271,14 @@ class StartMinting extends connect(store)(LitElement) {
try {
if (
findMintingAccountFromOtherUser &&
findMintingAccountFromOtherUser?.publicKey[0]
findMintingAccountFromOtherUser.publicKey &&
findMintingAccountFromOtherUser.publicKey[0]
) {
await removeMintingAccount(
findMintingAccountFromOtherUser?.publicKey[0]
findMintingAccountFromOtherUser.publicKey[0]
);
}
} catch (error) {
this.errorMsg = this.renderErrorMsg2();
return;
@ -292,7 +318,7 @@ class StartMinting extends connect(store)(LitElement) {
if (!stop) {
stop = true;
try {
const address = window.parent.reduxStore.getState().app?.selectedAddress?.address;
const address = this.address
const myRewardShareArray = await rewardShares(address);
if (myRewardShareArray.length > 0) {
clearInterval(interval)
@ -313,12 +339,12 @@ class StartMinting extends connect(store)(LitElement) {
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
const mintingAccountData = this.mintingAccountData;
const addressInfo = window.parent.reduxStore.getState().app.accountInfo.addressInfo
const address = window.parent.reduxStore.getState().app?.selectedAddress?.address;
const nonce = window.parent.reduxStore.getState().app?.selectedAddress?.nonce;
const publicAddress = window.parent.reduxStore.getState().app?.selectedAddress ?.base58PublicKey;
const address = this.address
const nonce = this.nonce
const publicAddress = this.base58PublicKey
const findMintingAccount = mintingAccountData.find((ma) => ma.mintingAccount === address);
const isMinterButKeyMintingKeyNotAssigned = addressInfo?.error !== 124 && addressInfo?.level >= 1 && !findMintingAccount;
const isMinterButKeyMintingKeyNotAssigned = addressInfo && addressInfo.error !== 124 && addressInfo.level >= 1 && !findMintingAccount;
const makeTransactionRequest = async (lastRef) => {
let mylastRef = lastRef;
let rewarddialog1 = get('transactions.rewarddialog1');
@ -347,31 +373,33 @@ class StartMinting extends connect(store)(LitElement) {
const getTxnRequestResponse = (txnResponse) => {
let err6string = get('rewardsharepage.rchange21');
if (txnResponse?.extraData?.rewardSharePrivateKey && (txnResponse?.data?.message?.includes('multiple') || txnResponse?.data?.message?.includes('SELF_SHARE_EXISTS'))) {
return err6string
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.error
) {
throw txnResponse;
} else if (txnResponse.success === true && txnResponse.data && !txnResponse.data.error) {
return err6string;
} else {
throw (txnResponse);
throw txnResponse;
}
};
const createSponsorshipKey = async () => {
this.status = 1
this.status = 1;
let lastRef = await getLastRef();
let myTransaction = await makeTransactionRequest(lastRef);
getTxnRequestResponse(myTransaction);
return myTransaction?.extraData?.rewardSharePrivateKey
if (myTransaction && myTransaction.extraData) {
return myTransaction.extraData.rewardSharePrivateKey;
}
};
const getLastRef = async () => {
const url = `${nodeUrl}/addresses/lastreference/${address}`;
@ -383,7 +411,7 @@ class StartMinting extends connect(store)(LitElement) {
const startMinting = async () => {
this.openDialogRewardShare = true
this.errorMsg = '';
const address = window.parent.reduxStore.getState().app?.selectedAddress?.address;
const address = this.address
const findMintingAccountsFromUser = this.mintingAccountData.filter((ma) => ma.recipientAccount === address && ma.mintingAccount === address);
@ -397,7 +425,7 @@ class StartMinting extends connect(store)(LitElement) {
this.confirmRelationship(publicAddress)
} catch (error) {
console.log({ error })
this.errorMsg = error?.data?.message || this.renderErrorMsg4();
this.errorMsg = (error && error.data && error.data.message) ? error.data.message : this.renderErrorMsg4();
return;
}
};

View File

@ -1,46 +1,34 @@
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 snackbar from './snackbar.js';
import '../components/language-selector.js';
import '../custom-elements/frag-file-input.js';
import FileSaver from 'file-saver';
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 snackbar from './snackbar.js'
import '../components/language-selector.js'
import '../custom-elements/frag-file-input.js'
import FileSaver from 'file-saver'
import '@material/mwc-dialog';
import '@material/mwc-button';
import '@material/mwc-select';
import '@material/mwc-textfield';
import '@material/mwc-icon';
import '@material/mwc-list/mwc-list-item.js';
import '@material/mwc-dialog'
import '@material/mwc-button'
import '@material/mwc-select'
import '@material/mwc-textfield'
import '@material/mwc-icon'
import '@material/mwc-list/mwc-list-item.js'
registerTranslateConfig({
loader: (lang) => fetch(`/language/${lang}.json`).then((res) => res.json()),
});
loader: (lang) => fetch(`/language/${lang}.json`).then((res) => res.json())
})
const checkLanguage = localStorage.getItem('qortalLanguage');
const checkLanguage = localStorage.getItem('qortalLanguage')
if (checkLanguage === null || checkLanguage.length === 0) {
localStorage.setItem('qortalLanguage', 'us');
use('us');
localStorage.setItem('qortalLanguage', 'us')
use('us')
} else {
use(checkLanguage);
use(checkLanguage)
}
let settingsDialog;
let settingsDialog
class SettingsPage extends connect(store)(LitElement) {
static get properties() {
@ -50,8 +38,8 @@ class SettingsPage extends connect(store)(LitElement) {
theme: { type: String, reflect: true },
nodeIndex: { type: Number },
isBeingEdited: { type: Boolean },
dropdownOpen: { type: Boolean },
};
dropdownOpen: { type: Boolean }
}
}
static get styles() {
@ -98,9 +86,11 @@ class SettingsPage extends connect(store)(LitElement) {
.buttongreen {
color: #03c851;
}
.buttonBlue {
color: #03a9f4;
}
.buttonBlue {
color: #03a9f4;
}
.floatleft {
float: left;
}
@ -108,24 +98,26 @@ class SettingsPage extends connect(store)(LitElement) {
.floatright {
float: right;
}
.list-parent {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
}
#customSelect {
position: relative;
border: 1px solid #ccc;
cursor: pointer;
background: var(--plugback);
background: var(--plugback);
}
#customSelect .selected {
padding: 10px;
display: flex;
align-items: center;
justify-content: space-between;
display: flex;
align-items: center;
justify-content: space-between;
}
#customSelect ul {
@ -149,32 +141,32 @@ class SettingsPage extends connect(store)(LitElement) {
#customSelect ul li {
padding: 10px;
transition: 0.2s all;
transition: 0.2s all;
}
#customSelect ul li:hover {
background-color: var(--graylight);
}
.selected-left-side{
display: flex;
align-items: center;
}
`;
.selected-left-side {
display: flex;
align-items: center;
}
`
}
constructor() {
super();
this.nodeConfig = {};
this.nodeIndex = localStorage.getItem('mySelectedNode');
this.theme = localStorage.getItem('qortalTheme')
? localStorage.getItem('qortalTheme')
: 'light';
this.isBeingEdited = false;
this.isBeingEditedIndex = null;
this.dropdownOpen = false;
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;">
@ -182,129 +174,58 @@ class SettingsPage extends connect(store)(LitElement) {
<hr />
</div>
<br />
<div
style="min-height: 250px; min-width: 500px; box-sizing: border-box; position: relative;"
>
<div id="customSelect" @click="${this.toggleDropdown}" @blur="${
this.handleBlur
}" tabindex="0">
<div style="min-height: 250px; min-width: 500px; box-sizing: border-box; position: relative;">
<div id="customSelect" @click="${this.toggleDropdown}" @blur="${this.handleBlur}" tabindex="0">
<div class="selected">
<div class="selected-left-side">
<mwc-icon style="margin-right: 10px"
>link</mwc-icon
>
${
this.selectedItem
? html`
<div>
<span class="name"
>${this.selectedItem
.name}</span
>
<span
>${this.selectedItem
.protocol +
'://' +
this.selectedItem.domain +
':' +
this.selectedItem
.port}</span
>
</div>
`
: 'Please select an option'
<div class="selected-left-side">
<mwc-icon style="margin-right: 10px">link</mwc-icon>
${this.selectedItem ? html
`
<div>
<span class="name">${this.selectedItem.name}</span>
<span>${this.selectedItem.protocol + '://' + this.selectedItem.domain + ':' + this.selectedItem.port}</span>
</div>
` : html`${translate('settings.selectnode')}`
}
</div>
<mwc-icon
>expand_more</mwc-icon
>
</div>
<mwc-icon>expand_more</mwc-icon>
</div>
<ul class="${this.dropdownOpen ? 'open' : ''}">
${this.nodeConfig.knownNodes.map(
(n, index) => html`
<li
@click="${(e) =>
this.handleSelection(e, n, index)}"
>
<li @click="${(e) => this.handleSelection(e, n, index)}">
<div class="list-parent">
<div>
<span class="name"
>${n.name}</span
>
<span
>${n.protocol +
'://' +
n.domain +
':' +
n.port}</span
>
<span class="name">${n.name}</span>
<span>${n.protocol + '://' + n.domain + ':' + n.port}</span>
</div>
<div>
<mwc-button
outlined
@click="${(e) => {
e.stopPropagation();
const currentValues =
this.nodeConfig
.knownNodes[
index
];
const dialog =
this.shadowRoot.querySelector(
'#addNodeDialog'
);
const currentValues = this.nodeConfig.knownNodes[index]
const dialog = this.shadowRoot.querySelector('#addNodeDialog')
// Set the value for mwc-textfield elements
dialog.querySelector(
'#nameInput'
).value =
currentValues.name;
dialog.querySelector(
'#domainInput'
).value =
currentValues.domain;
dialog.querySelector(
'#portInput'
).value =
currentValues.port;
dialog.querySelector('#nameInput').value = currentValues.name
dialog.querySelector('#domainInput').value = currentValues.domain
dialog.querySelector('#portInput').value = currentValues.port
// Set the selected value for mwc-select
const protocolList =
dialog.querySelector(
'#protocolList'
);
const desiredProtocol =
currentValues.protocol;
protocolList.value =
desiredProtocol;
this.isBeingEdited = true;
this.isBeingEditedIndex =
index;
this.shadowRoot
.querySelector(
'#addNodeDialog'
)
.show();
const protocolList = dialog.querySelector('#protocolList')
const desiredProtocol = currentValues.protocol
protocolList.value = desiredProtocol
this.isBeingEdited = true
this.isBeingEditedIndex = index
this.shadowRoot.querySelector('#addNodeDialog').show()
}}"
><mwc-icon class="buttonBlue"
>edit</mwc-icon
></mwc-button
>
<mwc-button
outlined
@click="${(e) =>
this.removeNode(
e,
index
)}"
><mwc-icon class="buttonred"
>remove</mwc-icon
></mwc-button
>
<mwc-icon class="buttonBlue">edit</mwc-icon>
</mwc-button>
<mwc-button outlined @click="${(e) => this.removeNode(e, index)}">
<mwc-icon class="buttonred">remove</mwc-icon>
</mwc-button>
</div>
</div>
</li>
@ -312,9 +233,6 @@ class SettingsPage extends connect(store)(LitElement) {
)}
</ul>
</div>
<p style="margin-top: 30px; text-align: center;">
${translate('settings.nodehint')}
</p>
@ -323,14 +241,15 @@ class SettingsPage extends connect(store)(LitElement) {
outlined
@click="${() => this.shadowRoot.querySelector('#addNodeDialog').show()}"
><mwc-icon class="buttongreen">add</mwc-icon
>${translate('settings.addcustomnode')}</mwc-button
>
${translate('settings.addcustomnode')}
</mwc-button>
</center>
<center>
<mwc-button outlined @click="${() => this.removeList()}"
><mwc-icon class="buttonred">remove</mwc-icon
>${translate('settings.deletecustomnode')}</mwc-button
>
<mwc-button outlined @click="${() => this.removeList()}">
<mwc-icon class="buttonred">remove</mwc-icon>
${translate('settings.deletecustomnode')}
</mwc-button>
</center>
<br />
<div class="floatleft">
@ -341,9 +260,7 @@ class SettingsPage extends connect(store)(LitElement) {
</div>
<br /><br />
</div>
<div
style="min-height:100px; min-width: 300px; box-sizing: border-box; position: relative;"
>
<div style="min-height:100px; min-width: 300px; box-sizing: border-box; position: relative;">
<hr />
<br />
<center>
@ -353,11 +270,7 @@ class SettingsPage extends connect(store)(LitElement) {
</div>
</center>
</div>
<mwc-button
slot="primaryAction"
dialogAction="close"
class="red"
>
<mwc-button slot="primaryAction" dialogAction="close" class="red">
${translate('general.close')}
</mwc-button>
</mwc-dialog>
@ -368,36 +281,16 @@ class SettingsPage extends connect(store)(LitElement) {
<hr />
</div>
<br />
<mwc-textfield
id="nameInput"
style="width:100%;"
label="${translate('login.name')}"
></mwc-textfield>
<mwc-textfield id="nameInput" style="width:100%;" label="${translate('login.name')}"></mwc-textfield>
<br />
<mwc-select
id="protocolList"
style="width:100%;"
label="${translate('settings.protocol')}"
>
<mwc-select id="protocolList" style="width:100%;" label="${translate('settings.protocol')}">
<mwc-list-item value="http">http</mwc-list-item>
<mwc-list-item value="https">https</mwc-list-item>
</mwc-select>
<br />
<mwc-textfield
id="domainInput"
style="width:100%;"
label="${translate('settings.domain')}"
></mwc-textfield>
<mwc-textfield
id="portInput"
style="width:100%;"
label="${translate('settings.port')}"
></mwc-textfield>
<mwc-button
slot="secondaryAction"
dialogAction="close"
class="red"
>
<mwc-textfield id="domainInput" style="width:100%;" label="${translate('settings.domain')}"></mwc-textfield>
<mwc-textfield id="portInput" style="width:100%;" label="${translate('settings.port')}"></mwc-textfield>
<mwc-button slot="secondaryAction" dialogAction="close" class="red">
${translate('general.close')}
</mwc-button>
<mwc-button slot="primaryAction" @click="${this.addNode}">
@ -411,17 +304,16 @@ class SettingsPage extends connect(store)(LitElement) {
<hr />
<br />
</div>
<div
style="min-height: 150px; min-width: 500px; box-sizing: border-box; position: relative;"
>
<frag-file-input
accept=".nodes"handleBlur(event) {
if (!this.shadowRoot.querySelector("#customSelect").contains(event.relatedTarget)) {
this.dropdownOpen = false;
}
}
<div style="min-height: 150px; min-width: 500px; box-sizing: border-box; position: relative;">
<frag-file-input accept=".nodes"handleBlur(event)
{
if (!this.shadowRoot.querySelector("#customSelect").contains(event.relatedTarget)) {
this.dropdownOpen = false
}
}
@file-read-success="${(e) => this.importQortalNodesList(e.detail.result)}"
></frag-file-input>
>
</frag-file-input>
<h4 style="color: #F44336; text-align: center;">
${translate('walletpage.wchange56')}
</h4>
@ -429,255 +321,257 @@ class SettingsPage extends connect(store)(LitElement) {
${translate('settings.warning')}
</h5>
</div>
<mwc-button
slot="primaryAction"
dialogAction="cancel"
class="red"
>
<mwc-button slot="primaryAction" dialogAction="cancel" class="red">
${translate('general.close')}
</mwc-button>
</mwc-dialog>
`;
`
}
firstUpdated() {
const checkNode = localStorage.getItem('mySelectedNode');
const checkNode = localStorage.getItem('mySelectedNode')
if (checkNode === null || checkNode.length === 0) {
localStorage.setItem('mySelectedNode', 0);
} else {
this.handleSelectionOnNewStart(checkNode)
}
}
handleSelectionOnNewStart(index) {
this.localSavedNodes = JSON.parse(localStorage.getItem('myQortalNodes'))
this.dropdownOpen = false
this.selectedItem = this.localSavedNodes[index]
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;
this.dropdownOpen = !this.dropdownOpen
}
handleBlur(event) {
if (
!this.shadowRoot
.querySelector('#customSelect')
.contains(event.relatedTarget)
) {
this.dropdownOpen = false;
if (!this.shadowRoot.querySelector('#customSelect').contains(event.relatedTarget)) {
this.dropdownOpen = false
}
}
focusOnCustomSelect() {
const customSelect = this.shadowRoot.querySelector('#customSelect');
const customSelect = this.shadowRoot.querySelector('#customSelect')
if (customSelect) {
customSelect.focus();
customSelect.focus()
}
}
handleSelection(event, node, index) {
event.stopPropagation();
event.stopPropagation()
this.selectedItem = node;
this.dropdownOpen = false;
this.requestUpdate();
this.nodeSelected(index);
this.selectedItem = node
this.dropdownOpen = false
this.requestUpdate()
this.nodeSelected(index)
localStorage.setItem('mySelectedNode', index)
}
show() {
this.shadowRoot.getElementById('settingsDialog').show();
this.shadowRoot.getElementById('settingsDialog').show()
}
close() {
this.shadowRoot.getElementById('settingsDialog').close();
this.shadowRoot.getElementById('settingsDialog').close()
}
removeList() {
localStorage.removeItem('myQortalNodes');
localStorage.removeItem('myQortalNodes')
const obj1 = {
name: 'Local Node',
protocol: 'http',
domain: '127.0.0.1',
port: 12391,
enableManagement: true,
};
enableManagement: true
}
const obj2 = {
name: 'Local Testnet',
protocol: 'http',
domain: '127.0.0.1',
port: 62391,
enableManagement: true,
};
enableManagement: true
}
var renewNodes = [];
renewNodes.push(obj1, obj2);
localStorage.setItem('myQortalNodes', JSON.stringify(renewNodes));
var renewNodes = []
renewNodes.push(obj1, obj2)
localStorage.setItem('myQortalNodes', JSON.stringify(renewNodes))
let snack1string = get('settings.snack1');
let snack1string = get('settings.snack1')
snackbar.add({
labelText: `${snack1string}`,
dismiss: true,
});
dismiss: true
})
localStorage.removeItem('mySelectedNode');
localStorage.setItem('mySelectedNode', 0);
localStorage.removeItem('mySelectedNode')
localStorage.setItem('mySelectedNode', 0)
store.dispatch(doLoadNodeConfig());
store.dispatch(doLoadNodeConfig())
}
nodeSelected(selectedNodeIndex) {
const selectedNode = this.nodeConfig.knownNodes[selectedNodeIndex];
const selectedNodeUrl = `${
selectedNode.protocol +
'://' +
selectedNode.domain +
':' +
selectedNode.port
}`;
const selectedNode = this.nodeConfig.knownNodes[selectedNodeIndex]
const selectedName = `${selectedNode.name}`
const selectedNodeUrl = `${selectedNode.protocol + '://' + selectedNode.domain +':' + selectedNode.port}`
const index = parseInt(selectedNodeIndex);
if (isNaN(index)) return;
const index = parseInt(selectedNodeIndex)
if (isNaN(index)) return
store.dispatch(doSetNode(selectedNodeIndex));
store.dispatch(doSetNode(selectedNodeIndex))
localStorage.removeItem('mySelectedNode');
localStorage.setItem('mySelectedNode', selectedNodeIndex);
localStorage.setItem('mySelectedNode', selectedNodeIndex)
let snack2string = get('settings.snack2');
let snack2string = get('settings.snack2')
snackbar.add({
labelText: `${snack2string} : ${selectedNodeUrl}`,
dismiss: true,
});
// this.shadowRoot.querySelector('#settingsDialog').close();
labelText: `${snack2string} : ${selectedName} ${selectedNodeUrl}`,
dismiss: true
})
}
addNode(e) {
e.stopPropagation();
e.stopPropagation()
if (this.isBeingEdited) {
this.editNode(this.isBeingEditedIndex);
return;
this.editNode(this.isBeingEditedIndex)
return
}
const nameInput = this.shadowRoot.getElementById('nameInput').value;
const protocolList =
this.shadowRoot.getElementById('protocolList').value;
const domainInput = this.shadowRoot.getElementById('domainInput').value;
const portInput = this.shadowRoot.getElementById('portInput').value;
if (
protocolList.length >= 4 &&
domainInput.length >= 3 &&
portInput.length >= 2
) {
const nameInput = this.shadowRoot.getElementById('nameInput').value
const protocolList = this.shadowRoot.getElementById('protocolList').value
const domainInput = this.shadowRoot.getElementById('domainInput').value
const portInput = this.shadowRoot.getElementById('portInput').value
if (protocolList.length >= 4 && domainInput.length >= 3 && portInput.length >= 2) {
const nodeObject = {
name: nameInput,
protocol: protocolList,
domain: domainInput,
port: portInput,
enableManagement: true,
};
enableManagement: true
}
store.dispatch(doAddNode(nodeObject));
store.dispatch(doAddNode(nodeObject))
const haveNodes = JSON.parse(localStorage.getItem('myQortalNodes'));
const haveNodes = JSON.parse(localStorage.getItem('myQortalNodes'))
if (haveNodes === null || haveNodes.length === 0) {
var savedNodes = [];
savedNodes.push(nodeObject);
localStorage.setItem(
'myQortalNodes',
JSON.stringify(savedNodes)
);
var savedNodes = []
savedNodes.push(nodeObject)
localStorage.setItem('myQortalNodes', JSON.stringify(savedNodes))
let snack3string = get('settings.snack3');
let snack3string = get('settings.snack3')
snackbar.add({
labelText: `${snack3string}`,
dismiss: true,
});
dismiss: true
})
this.shadowRoot.getElementById('nameInput').value = '';
this.shadowRoot.getElementById('protocolList').value = '';
this.shadowRoot.getElementById('domainInput').value = '';
this.shadowRoot.getElementById('portInput').value = '';
this.shadowRoot.getElementById('nameInput').value = ''
this.shadowRoot.getElementById('protocolList').value = ''
this.shadowRoot.getElementById('domainInput').value = ''
this.shadowRoot.getElementById('portInput').value = ''
this.shadowRoot.querySelector('#addNodeDialog').close();
this.shadowRoot.querySelector('#addNodeDialog').close()
} else {
var stored = JSON.parse(localStorage.getItem('myQortalNodes'));
stored.push(nodeObject);
localStorage.setItem('myQortalNodes', JSON.stringify(stored));
var stored = JSON.parse(localStorage.getItem('myQortalNodes'))
stored.push(nodeObject)
localStorage.setItem('myQortalNodes', JSON.stringify(stored))
let snack3string = get('settings.snack3');
snackbar.add({
labelText: `${snack3string}`,
dismiss: true,
});
dismiss: true
})
this.shadowRoot.getElementById('nameInput').value = '';
this.shadowRoot.getElementById('protocolList').value = '';
this.shadowRoot.getElementById('domainInput').value = '';
this.shadowRoot.getElementById('portInput').value = '';
this.shadowRoot.getElementById('nameInput').value = ''
this.shadowRoot.getElementById('protocolList').value = ''
this.shadowRoot.getElementById('domainInput').value = ''
this.shadowRoot.getElementById('portInput').value = ''
this.shadowRoot.querySelector('#addNodeDialog').close();
this.shadowRoot.querySelector('#addNodeDialog').close()
}
}
}
removeNode(event, index) {
event.stopPropagation();
let stored = JSON.parse(localStorage.getItem('myQortalNodes'));
stored.splice(index, 1);
localStorage.setItem('myQortalNodes', JSON.stringify(stored));
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');
let snack3string = get('settings.snack6')
snackbar.add({
labelText: `${snack3string}`,
dismiss: true,
});
dismiss: true
})
this.shadowRoot.querySelector('#addNodeDialog').close();
this.shadowRoot.querySelector('#addNodeDialog').close()
}
editNode(index) {
const nameInput = this.shadowRoot.getElementById('nameInput').value;
const protocolList =
this.shadowRoot.getElementById('protocolList').value;
const domainInput = this.shadowRoot.getElementById('domainInput').value;
const portInput = this.shadowRoot.getElementById('portInput').value;
if (
protocolList.length >= 4 &&
domainInput.length >= 3 &&
portInput.length >= 2
) {
editNode(index) {
const nameInput = this.shadowRoot.getElementById('nameInput').value
const protocolList = this.shadowRoot.getElementById('protocolList').value
const domainInput = this.shadowRoot.getElementById('domainInput').value
const portInput = this.shadowRoot.getElementById('portInput').value
if (protocolList.length >= 4 && domainInput.length >= 3 && portInput.length >= 2) {
const nodeObject = {
name: nameInput,
protocol: protocolList,
domain: domainInput,
port: portInput,
enableManagement: true,
};
}
let stored = JSON.parse(localStorage.getItem('myQortalNodes'));
const copyStored = [...stored];
copyStored[index] = nodeObject;
localStorage.setItem('myQortalNodes', JSON.stringify(copyStored));
store.dispatch(doEditNode(index, nodeObject));
let snack3string = get('settings.snack7');
let stored = JSON.parse(localStorage.getItem('myQortalNodes'))
const copyStored = [...stored]
copyStored[index] = nodeObject
localStorage.setItem('myQortalNodes', JSON.stringify(copyStored))
store.dispatch(doEditNode(index, nodeObject))
let snack3string = get('settings.snack7')
snackbar.add({
labelText: `${snack3string}`,
dismiss: true,
});
this.shadowRoot.getElementById('nameInput').value = '';
this.shadowRoot.getElementById('protocolList').value = '';
this.shadowRoot.getElementById('domainInput').value = '';
this.shadowRoot.getElementById('portInput').value = '';
this.isBeingEdited = false;
this.isBeingEditedIndex = null;
dismiss: true
})
this.shadowRoot.getElementById('nameInput').value = ''
this.shadowRoot.getElementById('protocolList').value = ''
this.shadowRoot.getElementById('domainInput').value = ''
this.shadowRoot.getElementById('portInput').value = ''
this.isBeingEdited = false
this.isBeingEditedIndex = null
this.shadowRoot.querySelector('#addNodeDialog').close();
this.shadowRoot.querySelector('#addNodeDialog').close()
}
}
openImportNodesDialog() {
this.shadowRoot.querySelector('#importQortalNodesListDialog').show();
this.shadowRoot.querySelector('#importQortalNodesListDialog').show()
}
closeImportNodesDialog() {
this.shadowRoot.querySelector('#importQortalNodesListDialog').close();
this.shadowRoot.querySelector('#importQortalNodesListDialog').close()
}
renderExportNodesListButton() {
@ -687,8 +581,9 @@ class SettingsPage extends connect(store)(LitElement) {
unelevated
label="${translate('settings.export')}"
@click="${() => this.exportQortalNodesList()}"
></mwc-button>
`;
>
</mwc-button>
`
}
exportQortalNodesList() {
@ -696,40 +591,38 @@ class SettingsPage extends connect(store)(LitElement) {
const qortalNodesList = JSON.stringify(
localStorage.getItem('myQortalNodes')
);
const qortalNodesListSave = JSON.parse(qortalNodesList || '[]');
const qortalNodesListSave = JSON.parse(qortalNodesList || '[]')
const blob = new Blob([qortalNodesListSave], {
type: 'text/plain;charset=utf-8',
});
nodelist = 'qortal.nodes';
this.saveFileToDisk(blob, nodelist);
nodelist = 'qortal.nodes'
this.saveFileToDisk(blob, nodelist)
}
async saveFileToDisk(blob, fileName) {
try {
const fileHandle = await self.showSaveFilePicker({
suggestedName: fileName,
types: [
{
description: 'File',
},
],
});
types: [{
description: 'File'
}],
})
const writeFile = async (fileHandle, contents) => {
const writable = await fileHandle.createWritable();
await writable.write(contents);
await writable.close();
const writable = await fileHandle.createWritable()
await writable.write(contents)
await writable.close()
};
writeFile(fileHandle, blob).then(() => console.log('FILE SAVED'));
let snack4string = get('settings.snack4');
let snack4string = get('settings.snack4')
snackbar.add({
labelText: `${snack4string} qortal.nodes`,
dismiss: true,
});
dismiss: true
})
} catch (error) {
if (error.name === 'AbortError') {
return;
return
}
FileSaver.saveAs(blob, fileName);
FileSaver.saveAs(blob, fileName)
}
}
@ -741,25 +634,25 @@ class SettingsPage extends connect(store)(LitElement) {
label="${translate('settings.import')}"
@click="${() => this.openImportNodesDialog()}"
></mwc-button>
`;
`
}
async importQortalNodesList(file) {
localStorage.removeItem('myQortalNodes');
const newItems = JSON.parse(file || '[]');
localStorage.setItem('myQortalNodes', JSON.stringify(newItems));
this.shadowRoot.querySelector('#importQortalNodesListDialog').close();
localStorage.removeItem('myQortalNodes')
const newItems = JSON.parse(file || '[]')
localStorage.setItem('myQortalNodes', JSON.stringify(newItems))
this.shadowRoot.querySelector('#importQortalNodesListDialog').close()
let snack5string = get('settings.snack5');
let snack5string = get('settings.snack5')
snackbar.add({
labelText: `${snack5string}`,
dismiss: true,
});
localStorage.removeItem('mySelectedNode');
localStorage.setItem('mySelectedNode', 0);
localStorage.removeItem('mySelectedNode')
localStorage.setItem('mySelectedNode', 0)
store.dispatch(doLoadNodeConfig());
store.dispatch(doLoadNodeConfig())
}
stateChanged(state) {
@ -768,9 +661,9 @@ class SettingsPage extends connect(store)(LitElement) {
}
}
window.customElements.define('settings-page', SettingsPage);
window.customElements.define('settings-page', SettingsPage)
const settings = document.createElement('settings-page');
settingsDialog = document.body.appendChild(settings);
const settings = document.createElement('settings-page')
settingsDialog = document.body.appendChild(settings)
export default settingsDialog;
export default settingsDialog

View File

@ -0,0 +1,111 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class CreatePollTransaction extends TransactionBase {
constructor() {
super()
this.type = 8
this._options = []
}
render(html) {
return html`
${this._votedialog3}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this._rPollName}</span>
</div>
${this._votedialog4}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this._rPollDesc}</span>
</div>
${this._votedialog5}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this._pollOptions.join(', ')}</span>
</div>
${this._votedialog6}
<div style="margin-top: 10px; font-weight: bold">
${this._feeDialog}: ${this._feeDisplay}
</div>
`
}
addOption(option) {
const optionBytes = this.constructor.utils.stringtoUTF8Array(option);
const optionLength = this.constructor.utils.int32ToBytes(optionBytes.length);
this._options.push({ length: optionLength, bytes: optionBytes });
}
set feeDialog(feeDialog){
this._feeDialog = feeDialog
}
set votedialog3(votedialog3) {
this._votedialog3 = votedialog3
}
set votedialog4(votedialog4) {
this._votedialog4 = votedialog4
}
set votedialog5(votedialog5) {
this._votedialog5 = votedialog5
}
set votedialog6(votedialog6) {
this._votedialog6 = votedialog6
}
set fee(fee) {
this._feeDisplay = fee
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set ownerAddress(ownerAddress) {
this._ownerAddress = ownerAddress instanceof Uint8Array ? ownerAddress : this.constructor.Base58.decode(ownerAddress)
}
set rPollName(rPollName) {
this._rPollName = rPollName
this._rPollNameBytes = this.constructor.utils.stringtoUTF8Array(this._rPollName)
this._rPollNameLength = this.constructor.utils.int32ToBytes(this._rPollNameBytes.length);
}
set rPollDesc(rPollDesc) {
this._rPollDesc = rPollDesc
this._rPollDescBytes = this.constructor.utils.stringtoUTF8Array(this._rPollDesc.toLocaleLowerCase())
this._rPollDescLength = this.constructor.utils.int32ToBytes(this._rPollDescBytes.length)
}
set rOptions(rOptions) {
const optionsArray = rOptions[0].split(', ').map(opt => opt.trim());
this._pollOptions = optionsArray
for (let i = 0; i < optionsArray.length; i++) {
this.addOption(optionsArray[i]);
}
this._rNumberOfOptionsBytes = this.constructor.utils.int32ToBytes(optionsArray.length);
}
get params() {
const params = super.params
params.push(
this._ownerAddress,
this._rPollNameLength,
this._rPollNameBytes,
this._rPollDescLength,
this._rPollDescBytes,
this._rNumberOfOptionsBytes
)
// Push the dynamic options
console.log('this._options', this._options)
for (let i = 0; i < this._options.length; i++) {
params.push(this._options[i].length, this._options[i].bytes);
}
params.push(this._feeBytes);
return params
}
}

View File

@ -0,0 +1,65 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class VoteOnPollTransaction extends TransactionBase {
constructor() {
super()
this.type = 9
}
render(html) {
return html`
${this._votedialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this._rPollName}</span>
</div>
${this._votedialog2}
<div style="margin-top: 10px; font-weight: bold">
${this._feeDialog}: ${this._feeDisplay}
</div>
`
}
set feeDialog(feeDialog){
this._feeDialog = feeDialog
}
set votedialog1(votedialog1) {
this._votedialog1 = votedialog1
}
set votedialog2(votedialog2) {
this._votedialog2 = votedialog2
}
set fee(fee) {
this._feeDisplay = fee
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set rPollName(rPollName) {
this._rPollName = rPollName
this._rPollNameBytes = this.constructor.utils.stringtoUTF8Array(this._rPollName)
this._rPollNameLength = this.constructor.utils.int32ToBytes(this._rPollNameBytes.length)
}
set rOptionIndex(rOptionIndex) {
this._rOptionIndex = rOptionIndex
this._rOptionIndexBytes = this.constructor.utils.int32ToBytes(this._rOptionIndex)
}
get params() {
const params = super.params
params.push(
this._rPollNameLength,
this._rPollNameBytes,
this._rOptionIndexBytes,
this._feeBytes
)
return params
}
}

View File

@ -23,6 +23,8 @@ import RewardShareTransaction from './reward-share/RewardShareTransaction.js'
import RemoveRewardShareTransaction from './reward-share/RemoveRewardShareTransaction.js'
import TransferPrivsTransaction from './TransferPrivsTransaction.js'
import DeployAtTransaction from './DeployAtTransaction.js'
import VoteOnPollTransaction from './polls/VoteOnPollTransaction.js'
import CreatePollTransaction from './polls/CreatePollTransaction.js'
export const transactionTypes = {
2: PaymentTransaction,
@ -31,6 +33,8 @@ export const transactionTypes = {
5: SellNameTransacion,
6: CancelSellNameTransacion,
7: BuyNameTransacion,
8: CreatePollTransaction,
9: VoteOnPollTransaction,
16: DeployAtTransaction,
17: MessageTransaction,
18: ChatTransaction,

View File

@ -1,39 +1,39 @@
{
"__locale_name__": "Estonian",
"electron_translate_1": "Näita Qortal KL-st",
"electron_translate_2": "Lahku",
"electron_translate_3": "Uuendus saadaval",
"electron_translate_4": "Uus Qortal KL versioon saadaval. Kas soovid alla laadida ?",
"electron_translate_5": "PAIGALDA NÜÜD",
"electron_translate_6": "EHK HILJEM",
"electron_translate_7": "Uuendus valmis paigaldamiseks",
"electron_translate_8": "Uus Qortal KL versioon on alla laetud.",
"electron_translate_9": "Klõpsa PAIGALDA NÜÜD uuendamaks, EHK HILJEM et mitte KL-st uuendada.",
"electron_translate_10": "Ajutine uuendamise tõrge. Proovin hiljem uuesti.",
"electron_translate_1": "Näita Qortal UI-d",
"electron_translate_2": "Sulge",
"electron_translate_3": "Uuendus on saadaval",
"electron_translate_4": "Uus Qortal UI versioon on saadaval. Kas soovid selle alla laadida?",
"electron_translate_5": "PAIGALDA KOHE",
"electron_translate_6": "HILJEM",
"electron_translate_7": "Uuendus on paigaldamiseks valmis",
"electron_translate_8": "Uus Qortali kasutajaliidese versioon on alla laetud.",
"electron_translate_9": "Vali PAIGALDA NÜÜD, et uuendada UI versioon või HILJEM, kui ei soovi praegu uuendada.",
"electron_translate_10": "Ajutine uuendamise tõrge. Proovime hiljem uuesti.",
"electron_translate_11": "LAE UUENDUS ALLA",
"electron_translate_12": "See laaditakse taustal alla ⌛️!",
"electron_translate_13": "KÄIVITA QORTAL TUUM",
"electron_translate_12": "Allalaadimine toimub nüüd taustal ⌛️!",
"electron_translate_13": "KÄIVITA QORTALI TUUM",
"electron_translate_14": "TÄNAN EI",
"electron_translate_15": "Qortal Tuum EI tööta selles süsteemis",
"electron_translate_16": "Qortal KL on tuvastanud, et Qortal Tuum EI tööta selles süsteemis",
"electron_translate_17": "Klõpsake selles süsteemis Qortal Tuuma käivitamiseks nuppu KÄIVITA QORTAL TUUM VÕI klõpsake nuppu Tänan EI, et selles süsteemis käivitamine vahele jätta",
"electron_translate_18": "Laadi alla QORTAL TUUM",
"electron_translate_15": "Qortali Tuum pole käivitatud",
"electron_translate_16": "Qortal UI tuvastas, et Qortali Tuum ei tööta hetkel",
"electron_translate_17": "Klõpsa Tuuma käivitamiseks KÄIVITA QORTALI TUUM või vali TÄNAN EI, kui ei soovi seda hetkel teha",
"electron_translate_18": "LAADI ALLA QORTALI TUUM",
"electron_translate_19": "TÄNAN EI",
"electron_translate_20": "Qortal Tuuma EI tuvastata",
"electron_translate_21": "Qortali kasutajaliides tuvastas, et Qortal Tuum EI ole sellesse süsteemi installitud (vaikeasukohas).",
"electron_translate_22": "Tuuma allalaadimiseks ja installimiseks (vaikeasukohta) klõpsake nuppu LAADI ALLA QORTAL TUUM VÕI klõpsake allalaadimise ja installimise vahelejätmiseks nuppu TÄNAN EI.",
"electron_translate_23": "Laadi alla JAVA",
"electron_translate_20": "Qortal Tuuma ei leidu",
"electron_translate_21": "Qortali kasutajaliides (UI) tuvastas, et Qortali Tuuma programmi faile pole arvutisse paigaldatud, vähemalt mitte tüüpilisse Qortali kausta.",
"electron_translate_22": "Tuuma failide allalaadimiseks ja vastavasse Qortali kausta paigaldamiseks vali LAADI ALLA QORTAL TUUM. Muul juhul vali TÄNAN EI.",
"electron_translate_23": "LAADI ALLA JAVA",
"electron_translate_24": "TÄNAN EI",
"electron_translate_25": "Java pole paigaldatud.",
"electron_translate_26": "Qortali kasutajaliides tuvastas, et Java pole teie süsteemi installitud.",
"electron_translate_27": "Java allalaadimiseks ja installimiseks klõpsake nuppu Laadi alla JAVA või TÄNAN EI, kui soovite seda alla laadida ja installida.",
"electron_translate_28": "Ära küsi enam kunagi",
"electron_translate_29": "MUUDA SEADET",
"electron_translate_26": "Qortali kasutajaliides (UI) tuvastas, et Java pole teie arvutisse paigaldatud. Aga seda on vaja.",
"electron_translate_27": "Java allalaadimiseks ja automaatseks paigaldamiseks klõpsa nuppu LAADI ALLA JAVA.",
"electron_translate_28": "Ära küsi rohkem Tuuma oleku kohta",
"electron_translate_29": "SALVESTA",
"electron_translate_30": "TÜHISTA",
"electron_translate_31": "Käivitage tuumikseaded",
"electron_translate_32": "Muutke tuuma käivitamise küsimise praegust olekut, kui see ei tööta",
"electron_translate_33": "(Märkige või tühjendage märkeruut, ära küsi enam mitte kunagi)",
"electron_translate_31": "Tuuma käivitamise säte",
"electron_translate_32": "Siit saad muuta sätet selle osas, et kas tahad UI käivitamisel saad Tuuma käivitamise kohta märguande-küsimuse, juhul kui Tuum ei tööta",
"electron_translate_33": "(Märgi linnuke kasti, kui ei taha edaspidi saada küsimust Tuuma kohta)",
"electron_translate_34": "Seaded",
"electron_translate_35": "Kopeeri",
"electron_translate_36": "Aseta",
@ -41,8 +41,6 @@
"electron_translate_38": "Suurenda",
"electron_translate_39": "Vähenda",
"electron_translate_40": "Tegelik suurus",
"electron_translate_41": "Lülitage täisekraan sisse",
"electron_translate_42": "Uus KL eksemplar",
"electron_translate_43": "Värskenduste otsimine!",
"electron_translate_44": "KL kontrollib taustal, kas uus versioon on saadaval, ja laadib selle alla."
}
"electron_translate_41": "Lülita täisekraanile",
"electron_translate_42": "Uus UI versioon"
}

1283
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@
"@hapi/hapi": "21.3.2",
"@hapi/inert": "7.1.0",
"@lit-labs/motion": "1.0.4",
"@popperjs/core": "^2.11.8",
"@popperjs/core": "2.11.8",
"@tiptap/core": "2.0.4",
"@tiptap/extension-highlight": "2.0.4",
"@tiptap/extension-image": "2.0.4",
@ -48,7 +48,7 @@
"buffer": "6.0.3",
"compressorjs": "1.2.1",
"crypto-js": "4.1.1",
"electron-dl": "3.5.0",
"electron-dl": "3.5.1",
"electron-log": "4.4.8",
"electron-store": "8.1.0",
"electron-updater": "6.1.4",
@ -67,12 +67,12 @@
"prosemirror-schema-list": "1.3.0",
"prosemirror-state": "1.4.3",
"prosemirror-transform": "1.8.0",
"prosemirror-view": "1.32.0",
"sass": "1.68.0",
"prosemirror-view": "1.32.1",
"sass": "1.69.4",
"short-unique-id": "5.0.3"
},
"devDependencies": {
"@babel/core": "7.23.0",
"@babel/core": "7.23.2",
"@material/mwc-button": "0.27.0",
"@material/mwc-checkbox": "0.27.0",
"@material/mwc-dialog": "0.27.0",
@ -108,28 +108,28 @@
"@polymer/paper-spinner": "3.0.2",
"@polymer/paper-toast": "3.0.1",
"@polymer/paper-tooltip": "3.0.1",
"@qortal/rollup-plugin-web-worker-loader": "1.6.4",
"@rollup/plugin-alias": "5.0.0",
"@rollup/plugin-babel": "6.0.3",
"@rollup/plugin-commonjs": "25.0.4",
"@rollup/plugin-node-resolve": "15.2.1",
"@rollup/plugin-replace": "5.0.2",
"@rollup/plugin-terser": "0.4.3",
"@vaadin/avatar": "24.1.9",
"@vaadin/button": "24.1.9",
"@vaadin/grid": "24.1.9",
"@vaadin/icons": "24.1.9",
"@vaadin/password-field": "24.1.9",
"@vaadin/tooltip": "24.1.10",
"@zip.js/zip.js": "2.7.29",
"@qortal/rollup-plugin-web-worker-loader": "1.6.5",
"@rollup/plugin-alias": "5.0.1",
"@rollup/plugin-babel": "6.0.4",
"@rollup/plugin-commonjs": "25.0.7",
"@rollup/plugin-node-resolve": "15.2.3",
"@rollup/plugin-replace": "5.0.4",
"@rollup/plugin-terser": "0.4.4",
"@vaadin/avatar": "24.2.0",
"@vaadin/button": "24.2.0",
"@vaadin/grid": "24.2.0",
"@vaadin/icons": "24.2.0",
"@vaadin/password-field": "24.2.0",
"@vaadin/tooltip": "24.2.0",
"@zip.js/zip.js": "2.7.30",
"axios": "1.5.1",
"electron": "26.2.4",
"electron": "27.0.2",
"electron-builder": "24.6.4",
"electron-packager": "17.1.2",
"epml": "0.3.3",
"eslint": "^8.50.0",
"eslint-plugin-lit": "^1.9.1",
"eslint-plugin-wc": "^2.0.3",
"eslint": "8.52.0",
"eslint-plugin-lit": "1.9.1",
"eslint-plugin-wc": "2.0.4",
"file-saver": "2.0.5",
"highcharts": "11.1.0",
"html-escaper": "3.0.3",
@ -140,13 +140,13 @@
"pwa-helpers": "0.9.1",
"redux": "4.2.1",
"redux-thunk": "2.4.2",
"rollup": "3.29.4",
"rollup": "4.1.4",
"rollup-plugin-node-globals": "1.4.0",
"rollup-plugin-progress": "1.1.2",
"rollup-plugin-scss": "3.0.0",
"shelljs": "0.8.5"
},
"engines": {
"node": ">=18.16.1"
"node": ">=18.17.1"
}
}

View File

@ -59,4 +59,10 @@ export const OPEN_NEW_TAB = 'OPEN_NEW_TAB'
export const NOTIFICATIONS_PERMISSION = 'NOTIFICATIONS_PERMISSION'
//SEND_LOCAL_NOTIFICATION
export const SEND_LOCAL_NOTIFICATION = 'SEND_LOCAL_NOTIFICATION'
export const SEND_LOCAL_NOTIFICATION = 'SEND_LOCAL_NOTIFICATION'
//VOTE_ON_POLL
export const VOTE_ON_POLL= 'VOTE_ON_POLL'
//CREATE_POLL
export const CREATE_POLL= 'CREATE_POLL'

View File

@ -493,6 +493,33 @@ class WebBrowser extends LitElement {
return qortFee
}
async unitVoteFee() {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
const url = `${nodeUrl}/transactions/unitfee?txType=VOTE_ON_POLL`
const response = await fetch(url)
if (!response.ok) {
throw new Error('Error when fetching vote fee');
}
const data = await response.json()
const joinFee = (Number(data) / 1e8).toFixed(8)
return joinFee
}
async unitCreatePollFee() {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
const url = `${nodeUrl}/transactions/unitfee?txType=CREATE_POLL`
const response = await fetch(url)
if (!response.ok) {
throw new Error('Error when fetching vote fee');
}
const data = await response.json()
const joinFee = (Number(data) / 1e8).toFixed(8)
return joinFee
}
async _joinGroup(groupId, groupName) {
const joinFeeInput = await this.unitJoinFee()
const getLastRef = async () => {
@ -607,6 +634,122 @@ class WebBrowser extends LitElement {
}
async _voteOnPoll(pollName, optionIndex) {
const voteFeeInput = await this.unitVoteFee()
const getLastRef = async () => {
let myRef = await parentEpml.request('apiCall', {
type: 'api',
url: `/addresses/lastreference/${this.selectedAddress.address}`
})
return myRef
};
const validateReceiver = async () => {
let lastRef = await getLastRef();
let myTransaction = await makeTransactionRequest(lastRef)
const res = getTxnRequestResponse(myTransaction)
return res
}
const makeTransactionRequest = async (lastRef) => {
let votedialog1 = get("transactions.votedialog1")
let votedialog2 = get("transactions.votedialog2")
let feeDialog = get("walletpage.wchange12")
let myTxnrequest = await parentEpml.request('transaction', {
type: 9,
nonce: this.selectedAddress.nonce,
params: {
fee: voteFeeInput,
voterAddress: this.selectedAddress.address,
rPollName: pollName,
rOptionIndex: optionIndex,
lastReference: lastRef,
votedialog1: votedialog1,
votedialog2: votedialog2,
feeDialog
},
apiVersion: 2
})
return myTxnrequest
}
const getTxnRequestResponse = (txnResponse) => {
if (txnResponse.success === false && txnResponse.message) {
throw new Error(txnResponse.message)
} else if (txnResponse.success === true && !txnResponse.data.error) {
return txnResponse.data
} else if (txnResponse.data && txnResponse.data.message) {
throw new Error(txnResponse.data.message)
} else {
throw new Error('Server error. Could not perform action.')
}
}
const voteRes = await validateReceiver()
return voteRes
}
async _createPoll(pollName, pollDescription, options, pollOwnerAddress) {
const voteFeeInput = await this.unitCreatePollFee()
const getLastRef = async () => {
let myRef = await parentEpml.request('apiCall', {
type: 'api',
url: `/addresses/lastreference/${this.selectedAddress.address}`
})
return myRef
};
const validateReceiver = async () => {
let lastRef = await getLastRef();
let myTransaction = await makeTransactionRequest(lastRef)
const res = getTxnRequestResponse(myTransaction)
return res
}
const makeTransactionRequest = async (lastRef) => {
let votedialog3 = get("transactions.votedialog3")
let votedialog4 = get("transactions.votedialog4")
let votedialog5 = get("transactions.votedialog5")
let votedialog6 = get("transactions.votedialog6")
let feeDialog = get("walletpage.wchange12")
let myTxnrequest = await parentEpml.request('transaction', {
type: 8,
nonce: this.selectedAddress.nonce,
params: {
fee: voteFeeInput,
ownerAddress: pollOwnerAddress,
rPollName: pollName,
rPollDesc: pollDescription,
rOptions: options,
lastReference: lastRef,
votedialog3: votedialog3,
votedialog4: votedialog4,
votedialog5: votedialog5,
votedialog6: votedialog6,
feeDialog
},
apiVersion: 2
})
return myTxnrequest
}
const getTxnRequestResponse = (txnResponse) => {
if (txnResponse.success === false && txnResponse.message) {
throw new Error(txnResponse.message)
} else if (txnResponse.success === true && !txnResponse.data.error) {
return txnResponse.data
} else if (txnResponse.data && txnResponse.data.message) {
throw new Error(txnResponse.data.message)
} else {
throw new Error('Server error. Could not perform action.')
}
}
const voteRes = await validateReceiver()
return voteRes
}
firstUpdated() {
this.changeTheme();
this.changeLanguage();
@ -1321,6 +1464,103 @@ class WebBrowser extends LitElement {
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
break;
}
case actions.VOTE_ON_POLL: {
const requiredFields = ['pollName', 'optionIndex'];
const missingFields = [];
requiredFields.forEach((field) => {
if (!data[field]) {
missingFields.push(field);
}
});
if (missingFields.length > 0) {
const missingFieldsString = missingFields.join(', ');
const errorMsg = `Missing fields: ${missingFieldsString}`
let data = {};
data['error'] = errorMsg;
response = JSON.stringify(data);
break
}
const pollName = data.pollName;
const optionIndex = data.optionIndex;
let pollInfo = null
try {
pollInfo = await parentEpml.request("apiCall", {
type: "api",
url: `/polls/${pollName}`,
});
} catch (error) {
const errorMsg = (error && error.message) || 'Poll not found';
let obj = {};
obj['error'] = errorMsg;
response = JSON.stringify(obj);
break
}
if (!pollInfo || pollInfo.error) {
const errorMsg = (pollInfo && pollInfo.message) || 'Poll not found';
let obj = {};
obj['error'] = errorMsg;
response = JSON.stringify(obj);
break
}
try {
this.loader.show();
const resVoteOnPoll = await this._voteOnPoll(pollName, optionIndex)
response = JSON.stringify(resVoteOnPoll);
} catch (error) {
const obj = {};
const errorMsg = error.message || 'Failed to vote on the poll.';
obj['error'] = errorMsg;
response = JSON.stringify(obj);
} finally {
this.loader.hide();
}
break;
}
case actions.CREATE_POLL: {
const requiredFields = ['pollName', 'pollDescription', 'pollOptions', 'pollOwnerAddress'];
const missingFields = [];
requiredFields.forEach((field) => {
if (!data[field]) {
missingFields.push(field);
}
});
if (missingFields.length > 0) {
const missingFieldsString = missingFields.join(', ');
const errorMsg = `Missing fields: ${missingFieldsString}`
let data = {};
data['error'] = errorMsg;
response = JSON.stringify(data);
break
}
const pollName = data.pollName;
const pollDescription = data.pollDescription
const pollOptions = data.pollOptions
const pollOwnerAddress = data.pollOwnerAddress
try {
this.loader.show();
const resCreatePoll = await this._createPoll(pollName, pollDescription, pollOptions, pollOwnerAddress)
response = JSON.stringify(resCreatePoll);
} catch (error) {
const obj = {};
const errorMsg = error.message || 'Failed to created poll.';
obj['error'] = errorMsg;
response = JSON.stringify(obj);
} finally {
this.loader.hide();
}
break;
}
case actions.OPEN_NEW_TAB: {
if(!data.qortalLink){
const obj = {};

View File

@ -100,17 +100,17 @@ class TradePortal extends LitElement {
--mdc-theme-primary: rgb(3, 169, 244);
--mdc-theme-secondary: var(--mdc-theme-primary);
--mdc-theme-error: rgb(255, 89, 89);
--mdc-text-field-outlined-idle-border-color: var(--txtfieldborder);
--mdc-text-field-outlined-idle-border-color: var(--txtfieldborder);
--mdc-text-field-outlined-hover-border-color: var(--txtfieldhoverborder);
--mdc-text-field-label-ink-color: var(--black);
--mdc-text-field-ink-color: var(--black);
--mdc-select-outlined-idle-border-color: var(--txtfieldborder);
--mdc-select-outlined-idle-border-color: var(--txtfieldborder);
--mdc-select-outlined-hover-border-color: var(--txtfieldhoverborder);
--mdc-select-label-ink-color: var(--black);
--mdc-select-ink-color: var(--black);
--mdc-theme-surface: var(--white);
--mdc-dialog-content-ink-color: var(--black);
--mdc-dialog-shape-radius: 25px;
--mdc-dialog-shape-radius: 25px;
--paper-input-container-focus-color: var(--mdc-theme-primary);
--lumo-primary-text-color: rgb(0, 167, 245);
--lumo-primary-color-50pct: rgba(0, 167, 245, 0.5);
@ -1580,7 +1580,7 @@ class TradePortal extends LitElement {
this.selectedAddress = selectedAddress
this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address
this.ltcWwallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address
this.ltcWallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address
this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address
this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address
this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address