forked from Qortal/qortal-ui
Merge remote-tracking branch 'main/master' into feature/improve-q-chat-speed
This commit is contained in:
commit
657409a028
@ -27,7 +27,7 @@ Easiest way to install the lastest required packages on Linux is via nvm.
|
|||||||
``` source ~/.profile ``` (For Debian based distro) <br/>
|
``` source ~/.profile ``` (For Debian based distro) <br/>
|
||||||
``` source ~/.bashrc ``` (For Fedora / CentOS) <br/>
|
``` source ~/.bashrc ``` (For Fedora / CentOS) <br/>
|
||||||
``` nvm ls-remote ``` (Fetch list of available versions) <br/>
|
``` nvm ls-remote ``` (Fetch list of available versions) <br/>
|
||||||
``` nvm install v18.15.0 ``` (LTS: Hydrogen supported by Electron) <br/>
|
``` nvm install v18.16.1 ``` (LTS: Hydrogen supported by Electron) <br/>
|
||||||
``` npm --location=global install npm@9.8.1 ``` <br/>
|
``` npm --location=global install npm@9.8.1 ``` <br/>
|
||||||
|
|
||||||
Adding via binary package mirror will only work if you have set the package path. You can do a node or java build via ports instead by downloading ports with portsnap fetch method.
|
Adding via binary package mirror will only work if you have set the package path. You can do a node or java build via ports instead by downloading ports with portsnap fetch method.
|
||||||
|
@ -64,6 +64,7 @@ html {
|
|||||||
--app-background-2: #09c6f9;
|
--app-background-2: #09c6f9;
|
||||||
--app-icon: #ffffff;
|
--app-icon: #ffffff;
|
||||||
--app-hr: rgba(0, 0, 0, .3);
|
--app-hr: rgba(0, 0, 0, .3);
|
||||||
|
--code-block-text-color: #008fd5;
|
||||||
}
|
}
|
||||||
|
|
||||||
html[theme="dark"] {
|
html[theme="dark"] {
|
||||||
@ -132,4 +133,5 @@ html[theme="dark"] {
|
|||||||
--app-background-2: #0d324d;
|
--app-background-2: #0d324d;
|
||||||
--app-icon: #03a9f4;
|
--app-icon: #03a9f4;
|
||||||
--app-hr: rgba(255, 255, 255, .3);
|
--app-hr: rgba(255, 255, 255, .3);
|
||||||
|
--code-block-text-color: #008fd5;
|
||||||
}
|
}
|
@ -717,7 +717,8 @@
|
|||||||
"bchange43": "Erteilen Sie dieser Anwendung die Erlaubnis, diese Liste hinzuzufügen?",
|
"bchange43": "Erteilen Sie dieser Anwendung die Erlaubnis, diese Liste hinzuzufügen?",
|
||||||
"bchange44": "Erteilen Sie dieser Anwendung die Erlaubnis, sie von dieser Liste zu löschen?",
|
"bchange44": "Erteilen Sie dieser Anwendung die Erlaubnis, sie von dieser Liste zu löschen?",
|
||||||
"bchange45": "Verschlüsseln",
|
"bchange45": "Verschlüsseln",
|
||||||
"bchange46": "Geben Sie dieser Anwendung die Erlaubnis, die folgende Datei zu speichern?"
|
"bchange46": "Geben Sie dieser Anwendung die Erlaubnis, die folgende Datei zu speichern?",
|
||||||
|
"bchange47": "Sofortige Veröffentlichung – erforderlich"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Datenmanagement",
|
"dchange1": "Datenmanagement",
|
||||||
|
@ -717,7 +717,8 @@
|
|||||||
"bchange43": "¿Le das permiso a esta aplicación para agregar a esta lista?",
|
"bchange43": "¿Le das permiso a esta aplicación para agregar a esta lista?",
|
||||||
"bchange44": "¿Le das permiso a esta aplicación para eliminar de esta lista?",
|
"bchange44": "¿Le das permiso a esta aplicación para eliminar de esta lista?",
|
||||||
"bchange45": "Cifrar",
|
"bchange45": "Cifrar",
|
||||||
"bchange46": "¿Le das permiso a esta aplicación para guardar el siguiente archivo?"
|
"bchange46": "¿Le das permiso a esta aplicación para guardar el siguiente archivo?",
|
||||||
|
"bchange47": "Publicación instantánea - requiere"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Gestión de datos",
|
"dchange1": "Gestión de datos",
|
||||||
|
@ -717,7 +717,8 @@
|
|||||||
"bchange43": "Autorisez-vous cette application à ajouter à cette liste ?",
|
"bchange43": "Autorisez-vous cette application à ajouter à cette liste ?",
|
||||||
"bchange44": "Autorisez-vous cette application à supprimer de cette liste ?",
|
"bchange44": "Autorisez-vous cette application à supprimer de cette liste ?",
|
||||||
"bchange45": "Crypter",
|
"bchange45": "Crypter",
|
||||||
"bchange46": "Autorisez-vous cette application à enregistrer le fichier suivant"
|
"bchange46": "Autorisez-vous cette application à enregistrer le fichier suivant",
|
||||||
|
"bchange47": "Publication instantanée - nécessite"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Gestion de données",
|
"dchange1": "Gestion de données",
|
||||||
|
@ -718,7 +718,8 @@
|
|||||||
"bchange43": "क्या आप इस एप्लिकेशन को इस सूची में जोड़ने की अनुमति देते हैं?",
|
"bchange43": "क्या आप इस एप्लिकेशन को इस सूची में जोड़ने की अनुमति देते हैं?",
|
||||||
"bchange44": "क्या आप इस एप्लिकेशन को इस सूची से हटाने की अनुमति देते हैं?",
|
"bchange44": "क्या आप इस एप्लिकेशन को इस सूची से हटाने की अनुमति देते हैं?",
|
||||||
"bchange45": "एन्क्रिप्ट",
|
"bchange45": "एन्क्रिप्ट",
|
||||||
"bchange46": "क्या आप इस एप्लिकेशन को निम्न फ़ाइल सहेजने की अनुमति देते हैं"
|
"bchange46": "क्या आप इस एप्लिकेशन को निम्न फ़ाइल सहेजने की अनुमति देते हैं",
|
||||||
|
"bchange47": "तत्काल प्रकाशन - आवश्यक है"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "डाटा प्रबंधन",
|
"dchange1": "डाटा प्रबंधन",
|
||||||
|
@ -717,7 +717,8 @@
|
|||||||
"bchange43": "Dajete li ovoj aplikaciji dopuštenje za dodavanje na ovaj popis?",
|
"bchange43": "Dajete li ovoj aplikaciji dopuštenje za dodavanje na ovaj popis?",
|
||||||
"bchange44": "Dajete li ovoj aplikaciji dopuštenje za brisanje s ovog popisa?",
|
"bchange44": "Dajete li ovoj aplikaciji dopuštenje za brisanje s ovog popisa?",
|
||||||
"bchange45": "Šifriraj",
|
"bchange45": "Šifriraj",
|
||||||
"bchange46": "Dajete li ovoj aplikaciji dopuštenje za spremanje sljedeće datoteke"
|
"bchange46": "Dajete li ovoj aplikaciji dopuštenje za spremanje sljedeće datoteke",
|
||||||
|
"bchange47": "Trenutno objavljivanje - zahtijeva"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Upravljanje podacima",
|
"dchange1": "Upravljanje podacima",
|
||||||
|
@ -717,7 +717,8 @@
|
|||||||
"bchange43": "Engedélyt ad ennek az alkalmazásnak, hogy felvegye ezt a listát?",
|
"bchange43": "Engedélyt ad ennek az alkalmazásnak, hogy felvegye ezt a listát?",
|
||||||
"bchange44": "Engedélyezi ennek az alkalmazásnak, hogy töröljön erről a listáról?",
|
"bchange44": "Engedélyezi ennek az alkalmazásnak, hogy töröljön erről a listáról?",
|
||||||
"bchange45": "Titkosítás",
|
"bchange45": "Titkosítás",
|
||||||
"bchange46": "Engedélyezi ennek az alkalmazásnak a következő fájl mentését"
|
"bchange46": "Engedélyezi ennek az alkalmazásnak a következő fájl mentését",
|
||||||
|
"bchange47": "Azonnali közzététel – szükséges"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Adatkezelés",
|
"dchange1": "Adatkezelés",
|
||||||
|
@ -717,7 +717,8 @@
|
|||||||
"bchange43": "Concedi a questa applicazione il permesso di aggiungersi a questa lista?",
|
"bchange43": "Concedi a questa applicazione il permesso di aggiungersi a questa lista?",
|
||||||
"bchange44": "Concedi a questa applicazione il permesso di eliminare da questo elenco?",
|
"bchange44": "Concedi a questa applicazione il permesso di eliminare da questo elenco?",
|
||||||
"bchange45": "Cripta",
|
"bchange45": "Cripta",
|
||||||
"bchange46": "Concedi a questa applicazione il permesso di salvare il seguente file"
|
"bchange46": "Concedi a questa applicazione il permesso di salvare il seguente file",
|
||||||
|
"bchange47": "Pubblicazione istantanea - richiede"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Gestione dati",
|
"dchange1": "Gestione dati",
|
||||||
|
@ -720,7 +720,8 @@
|
|||||||
"bchange43": "このアプリケーションにこのリストに追加する事を許可しますか?",
|
"bchange43": "このアプリケーションにこのリストに追加する事を許可しますか?",
|
||||||
"bchange44": "このアプリケーションにこのリストから削除する事を許可しますか?",
|
"bchange44": "このアプリケーションにこのリストから削除する事を許可しますか?",
|
||||||
"bchange45": "暗号化",
|
"bchange45": "暗号化",
|
||||||
"bchange46": "このアプリケーションに次のファイルを保存する事を許可しますか?"
|
"bchange46": "このアプリケーションに次のファイルを保存する事を許可しますか?",
|
||||||
|
"bchange47": "インスタント公開 - が必要です"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "データ管理",
|
"dchange1": "データ管理",
|
||||||
|
@ -717,7 +717,8 @@
|
|||||||
"bchange43": "이 목록에 추가할 수 있는 권한을 이 응용 프로그램에 부여하시겠습니까?",
|
"bchange43": "이 목록에 추가할 수 있는 권한을 이 응용 프로그램에 부여하시겠습니까?",
|
||||||
"bchange44": "이 목록에서 삭제할 수 있는 권한을 이 애플리케이션에 부여하시겠습니까?",
|
"bchange44": "이 목록에서 삭제할 수 있는 권한을 이 애플리케이션에 부여하시겠습니까?",
|
||||||
"bchange45": "암호화",
|
"bchange45": "암호화",
|
||||||
"bchange46": "이 응용 프로그램에 다음 파일을 저장할 권한을 부여하시겠습니까?"
|
"bchange46": "이 응용 프로그램에 다음 파일을 저장할 권한을 부여하시겠습니까?",
|
||||||
|
"bchange47": "즉시 게시 - 필요"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "데이터 관리",
|
"dchange1": "데이터 관리",
|
||||||
|
@ -717,7 +717,8 @@
|
|||||||
"bchange43": "Gir du denne applikasjonen tillatelse til å legge til denne listen?",
|
"bchange43": "Gir du denne applikasjonen tillatelse til å legge til denne listen?",
|
||||||
"bchange44": "Gir du denne applikasjonen tillatelse til å slette fra denne listen?",
|
"bchange44": "Gir du denne applikasjonen tillatelse til å slette fra denne listen?",
|
||||||
"bchange45": "Krypter",
|
"bchange45": "Krypter",
|
||||||
"bchange46": "Gir du dette programmet tillatelse til å lagre følgende fil"
|
"bchange46": "Gir du dette programmet tillatelse til å lagre følgende fil",
|
||||||
|
"bchange47": "Øyeblikkelig publisering - krever"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Data-administrasjon",
|
"dchange1": "Data-administrasjon",
|
||||||
|
@ -717,7 +717,8 @@
|
|||||||
"bchange43": "Czy zezwalasz tej aplikacji na dodanie do tej listy?",
|
"bchange43": "Czy zezwalasz tej aplikacji na dodanie do tej listy?",
|
||||||
"bchange44": "Czy zezwalasz tej aplikacji na usunięcie z tej listy?",
|
"bchange44": "Czy zezwalasz tej aplikacji na usunięcie z tej listy?",
|
||||||
"bchange45": "Szyfruj",
|
"bchange45": "Szyfruj",
|
||||||
"bchange46": "Czy zezwalasz tej aplikacji na zapisanie następującego pliku"
|
"bchange46": "Czy zezwalasz tej aplikacji na zapisanie następującego pliku",
|
||||||
|
"bchange47": "Błyskawiczna publikacja - wymaga"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Zarządzanie danymi",
|
"dchange1": "Zarządzanie danymi",
|
||||||
|
@ -717,7 +717,8 @@
|
|||||||
"bchange43": "Você dá a este aplicativo permissão para adicionar a esta lista?",
|
"bchange43": "Você dá a este aplicativo permissão para adicionar a esta lista?",
|
||||||
"bchange44": "Você dá a este aplicativo permissão para deletar desta lista?",
|
"bchange44": "Você dá a este aplicativo permissão para deletar desta lista?",
|
||||||
"bchange45": "Criptografar",
|
"bchange45": "Criptografar",
|
||||||
"bchange46": "Você concede permissão a este aplicativo para salvar o seguinte arquivo"
|
"bchange46": "Você concede permissão a este aplicativo para salvar o seguinte arquivo",
|
||||||
|
"bchange47": "Publicação instantânea - requer"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Gerenciamento de Dados",
|
"dchange1": "Gerenciamento de Dados",
|
||||||
|
@ -717,7 +717,8 @@
|
|||||||
"bchange43": "Oferiți acestei aplicații permisiunea de a adăuga la această listă?",
|
"bchange43": "Oferiți acestei aplicații permisiunea de a adăuga la această listă?",
|
||||||
"bchange44": "Oferiți acestei aplicații permisiunea de a șterge din această listă?",
|
"bchange44": "Oferiți acestei aplicații permisiunea de a șterge din această listă?",
|
||||||
"bchange45": "Criptați",
|
"bchange45": "Criptați",
|
||||||
"bchange46": "Dați această aplicație permisiunea de a salva următorul fișier"
|
"bchange46": "Dați această aplicație permisiunea de a salva următorul fișier",
|
||||||
|
"bchange47": "Publicare instantanee - necesită"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Gestionare date",
|
"dchange1": "Gestionare date",
|
||||||
|
@ -717,7 +717,8 @@
|
|||||||
"bchange43": "Da li dajete ovoj aplikaciji dozvolu za dodavanje na ovu listu?",
|
"bchange43": "Da li dajete ovoj aplikaciji dozvolu za dodavanje na ovu listu?",
|
||||||
"bchange44": "Da li ovoj aplikaciji dajete dozvolu za brisanje sa ove liste?",
|
"bchange44": "Da li ovoj aplikaciji dajete dozvolu za brisanje sa ove liste?",
|
||||||
"bchange45": "Šifrovanje",
|
"bchange45": "Šifrovanje",
|
||||||
"bchange46": "Da li ovoj aplikaciji dajete dozvolu da sačuva sledeću datoteku"
|
"bchange46": "Da li ovoj aplikaciji dajete dozvolu da sačuva sledeću datoteku",
|
||||||
|
"bchange47": "Trenutno objavljivanje - zahteva"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Upravljanje podacima",
|
"dchange1": "Upravljanje podacima",
|
||||||
|
@ -717,7 +717,8 @@
|
|||||||
"bchange43": "Даете ли вы этому приложению разрешение на добавление в этот список?",
|
"bchange43": "Даете ли вы этому приложению разрешение на добавление в этот список?",
|
||||||
"bchange44": "Даете ли вы этому приложению разрешение на удаление из этого списка?",
|
"bchange44": "Даете ли вы этому приложению разрешение на удаление из этого списка?",
|
||||||
"bchange45": "Шифровать",
|
"bchange45": "Шифровать",
|
||||||
"bchange46": "Даете ли вы этому приложению разрешение на сохранение следующего файла?"
|
"bchange46": "Даете ли вы этому приложению разрешение на сохранение следующего файла?",
|
||||||
|
"bchange47": "Мгновенная публикация - требуется"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Управление данными",
|
"dchange1": "Управление данными",
|
||||||
|
@ -203,7 +203,8 @@
|
|||||||
"exp2": "Export Master Key",
|
"exp2": "Export Master Key",
|
||||||
"exp3": "Export",
|
"exp3": "Export",
|
||||||
"exp4": "Please choose a wallet to backup the private master key.",
|
"exp4": "Please choose a wallet to backup the private master key.",
|
||||||
"core": "Start Core Settings"
|
"core": "Start Core Settings",
|
||||||
|
"qappNotification1": "Q-App notifications"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
"blockheight": "Block Height",
|
"blockheight": "Block Height",
|
||||||
@ -719,7 +720,9 @@
|
|||||||
"bchange43": "Do you give this application permission to add to this list?",
|
"bchange43": "Do you give this application permission to add to this list?",
|
||||||
"bchange44": "Do you give this application permission to delete from this list?",
|
"bchange44": "Do you give this application permission to delete from this list?",
|
||||||
"bchange45": "Encrypt",
|
"bchange45": "Encrypt",
|
||||||
"bchange46": "Do you give this application permission to save the following file"
|
"bchange46": "Do you give this application permission to save the following file",
|
||||||
|
"bchange47": "Instant publish - requires",
|
||||||
|
"bchange48": "Do you give this application permission to send you notifications"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Data Management",
|
"dchange1": "Data Management",
|
||||||
@ -1007,7 +1010,10 @@
|
|||||||
"rewarddialog3": "If yes, you will need to save the key below in order to mint. It can be supplied to any node in order to allow it to mint on your behalf.",
|
"rewarddialog3": "If yes, you will need to save the key below in order to mint. It can be supplied to any node in order to allow it to mint on your behalf.",
|
||||||
"rewarddialog4": "On pressing confirm, the rewardshare will be created, but you will still need to supply the above key to a node in order to mint with the account.",
|
"rewarddialog4": "On pressing confirm, the rewardshare will be created, but you will still need to supply the above key to a node in order to mint with the account.",
|
||||||
"rewarddialog5": "You are removing a reward share transaction associated with account:",
|
"rewarddialog5": "You are removing a reward share transaction associated with account:",
|
||||||
"rewarddialog6": "On pressing confirm, the rewardshare will be removed and the minting key will become invalid."
|
"rewarddialog6": "On pressing confirm, the 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"
|
||||||
},
|
},
|
||||||
"sponsorshipspage": {
|
"sponsorshipspage": {
|
||||||
"schange1": "Active Sponsorships",
|
"schange1": "Active Sponsorships",
|
||||||
|
@ -717,7 +717,8 @@
|
|||||||
"bchange43": "您授予此应用程序添加到此列表的权限吗?",
|
"bchange43": "您授予此应用程序添加到此列表的权限吗?",
|
||||||
"bchange44": "您授予此应用程序从列表中删除的权限吗?",
|
"bchange44": "您授予此应用程序从列表中删除的权限吗?",
|
||||||
"bchange45": "加密",
|
"bchange45": "加密",
|
||||||
"bchange46": "您是否授予此应用程序保存以下文件的权限"
|
"bchange46": "您是否授予此应用程序保存以下文件的权限",
|
||||||
|
"bchange47": "即时发布 - 需要"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "资料管理",
|
"dchange1": "资料管理",
|
||||||
|
@ -717,7 +717,8 @@
|
|||||||
"bchange43": "您授予此應用程序添加到此列表的權限嗎?",
|
"bchange43": "您授予此應用程序添加到此列表的權限嗎?",
|
||||||
"bchange44": "您授予此應用程序從列表中刪除的權限嗎?",
|
"bchange44": "您授予此應用程序從列表中刪除的權限嗎?",
|
||||||
"bchange45": "加密",
|
"bchange45": "加密",
|
||||||
"bchange46": "您是否授予此應用程序保存以下文件的權限"
|
"bchange46": "您是否授予此應用程序保存以下文件的權限",
|
||||||
|
"bchange47": "即時發布 - 需要"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "資料管理",
|
"dchange1": "資料管理",
|
||||||
|
@ -119,11 +119,11 @@ class AppInfo extends connect(store)(LitElement) {
|
|||||||
this.setStorage()
|
this.setStorage()
|
||||||
this.getNodeInfo()
|
this.getNodeInfo()
|
||||||
this.getCoreInfo()
|
this.getCoreInfo()
|
||||||
try {
|
// try {
|
||||||
this.confirmPublicKeyOnChain(store.getState().app.selectedAddress.address)
|
// this.confirmPublicKeyOnChain(store.getState().app.selectedAddress.address)
|
||||||
} catch (error) {
|
// } catch (error) {
|
||||||
console.error(error)
|
// console.error(error)
|
||||||
}
|
// }
|
||||||
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
this.getNodeInfo()
|
this.getNodeInfo()
|
||||||
|
@ -3048,3 +3048,4 @@ class AppView extends connect(store)(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('app-view', AppView)
|
window.customElements.define('app-view', AppView)
|
||||||
|
|
||||||
|
@ -140,7 +140,9 @@ class NotificationBell extends connect(store)(LitElement) {
|
|||||||
${this.notificationCount ? html`
|
${this.notificationCount ? html`
|
||||||
<paper-icon-button style="color: green;" icon="icons:mail" @click=${() => this._toggleNotifications()} title="Q-Mail"></paper-icon-button>
|
<paper-icon-button style="color: green;" icon="icons:mail" @click=${() => this._toggleNotifications()} title="Q-Mail"></paper-icon-button>
|
||||||
` : html`
|
` : html`
|
||||||
<paper-icon-button icon="icons:mail" @click=${() => this._toggleNotifications()} title="Q-Mail"></paper-icon-button>
|
<paper-icon-button icon="icons:mail" @click=${() => {
|
||||||
|
this._openTabQmail()
|
||||||
|
}} title="Q-Mail"></paper-icon-button>
|
||||||
`}
|
`}
|
||||||
|
|
||||||
${this.notificationCount ? html`
|
${this.notificationCount ? html`
|
||||||
@ -188,6 +190,23 @@ class NotificationBell extends connect(store)(LitElement) {
|
|||||||
if (this.notifications.length === 0) return
|
if (this.notifications.length === 0) return
|
||||||
this.showNotifications = !this.showNotifications
|
this.showNotifications = !this.showNotifications
|
||||||
}
|
}
|
||||||
|
_openTabQmail() {
|
||||||
|
const query = `?service=APP&name=Q-Mail`
|
||||||
|
store.dispatch(setNewTab({
|
||||||
|
url: `qdn/browser/index.html${query}`,
|
||||||
|
id: 'q-mail-notification',
|
||||||
|
myPlugObj: {
|
||||||
|
"url": "qapps",
|
||||||
|
"domain": "core",
|
||||||
|
"page": `qdn/browser/index.html${query}`,
|
||||||
|
"title": "Q-Mail",
|
||||||
|
"icon": "vaadin:mailbox",
|
||||||
|
"mwcicon": "mail_outline",
|
||||||
|
"menus": [],
|
||||||
|
"parent": false
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
static styles = css`
|
static styles = css`
|
||||||
.layout {
|
.layout {
|
||||||
|
@ -14,7 +14,8 @@ class NotificationsView extends connect(store)(LitElement) {
|
|||||||
notificationConfig: { type: Object },
|
notificationConfig: { type: Object },
|
||||||
q_chatConfig: { type: Object },
|
q_chatConfig: { type: Object },
|
||||||
blockConfig: { type: Object },
|
blockConfig: { type: Object },
|
||||||
theme: { type: String, reflect: true }
|
theme: { type: String, reflect: true },
|
||||||
|
appNotificationList: {type: Array}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,6 +25,11 @@ class NotificationsView extends connect(store)(LitElement) {
|
|||||||
this.q_chatConfig = {}
|
this.q_chatConfig = {}
|
||||||
this.blockConfig = {}
|
this.blockConfig = {}
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
|
this.appNotificationList = [] // Fetch the list of apps from local storage
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated(){
|
||||||
|
this.appNotificationList = this.getAppsFromStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
@ -42,7 +48,7 @@ class NotificationsView extends connect(store)(LitElement) {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(min-width: 1150px) {
|
@media(min-width: 1400px) {
|
||||||
.notification-box {
|
.notification-box {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
@ -106,6 +112,18 @@ class NotificationsView extends connect(store)(LitElement) {
|
|||||||
transition: all .2s;
|
transition: all .2s;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.remove-button {
|
||||||
|
font-family: Roboto, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
color: var(--mdc-theme-primary);
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 8px 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: none;
|
||||||
|
transition: all 0.3s ease-in-out;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,6 +162,16 @@ class NotificationsView extends connect(store)(LitElement) {
|
|||||||
<mwc-checkbox indeterminate disabled id="blockShowNotification"></mwc-checkbox>
|
<mwc-checkbox indeterminate disabled id="blockShowNotification"></mwc-checkbox>
|
||||||
<label for="blockShowNotification">${translate("settings.shownotifications")}</label>
|
<label for="blockShowNotification">${translate("settings.shownotifications")}</label>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-box">
|
||||||
|
<h4>${translate("settings.qappNotification1")}</h4>
|
||||||
|
${this.appNotificationList.map((app)=> html`
|
||||||
|
<div style="display: flex; justify-content: space-between; margin-top: 10px;">
|
||||||
|
${app}
|
||||||
|
<button class="remove-button" @click=${() => this.removeApp(app)}>Remove</button>
|
||||||
|
</div>
|
||||||
|
`)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${this.renderSetCoreButton()}
|
${this.renderSetCoreButton()}
|
||||||
@ -151,6 +179,31 @@ class NotificationsView extends connect(store)(LitElement) {
|
|||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAppsFromStorage() {
|
||||||
|
// Your method to fetch the list of apps from local storage
|
||||||
|
// Example:
|
||||||
|
const address= store.getState().app.selectedAddress.address
|
||||||
|
const id = `appNotificationList-${address}`;
|
||||||
|
const data = localStorage.getItem(id);
|
||||||
|
return data ? Object.keys(JSON.parse(data)) : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
removeApp(appName) {
|
||||||
|
// Remove the app from local storage
|
||||||
|
this.removeAppFromStorage(appName);
|
||||||
|
// Update the apps list in the component
|
||||||
|
this.appNotificationList = this.appNotificationList.filter(app => app !== appName);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeAppFromStorage(appName) {
|
||||||
|
// Your method to remove the app from local storage
|
||||||
|
const address= store.getState().app.selectedAddress.address
|
||||||
|
const id = `appNotificationList-${address}`;
|
||||||
|
const data = JSON.parse(localStorage.getItem(id) || '{}');
|
||||||
|
delete data[appName];
|
||||||
|
localStorage.setItem(id, JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
renderSetCoreButton() {
|
renderSetCoreButton() {
|
||||||
if (!isElectron()) {
|
if (!isElectron()) {
|
||||||
return html``
|
return html``
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { LitElement, html, css } from 'lit'
|
import { LitElement, html, css } from 'lit'
|
||||||
import { connect } from 'pwa-helpers'
|
import { connect } from 'pwa-helpers'
|
||||||
import { store } from '../../store.js'
|
import { store } from '../../store.js'
|
||||||
import { allowQAPPAutoAuth, removeQAPPAutoAuth, removeQAPPAutoLists, allowQAPPAutoLists } from '../../redux/app/app-actions.js'
|
import { allowQAPPAutoAuth, removeQAPPAutoAuth, removeQAPPAutoLists, allowQAPPAutoLists, setIsOpenDevDialog } from '../../redux/app/app-actions.js'
|
||||||
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
|
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
|
||||||
import snackbar from '../../functional-components/snackbar.js'
|
import snackbar from '../../functional-components/snackbar.js'
|
||||||
import FileSaver from 'file-saver'
|
import FileSaver from 'file-saver'
|
||||||
@ -15,7 +15,8 @@ class SecurityView extends connect(store)(LitElement) {
|
|||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
theme: { type: String, reflect: true },
|
theme: { type: String, reflect: true },
|
||||||
backupErrorMessage: { type: String }
|
backupErrorMessage: { type: String },
|
||||||
|
closeSettings: {attribute: false}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +76,23 @@ class SecurityView extends connect(store)(LitElement) {
|
|||||||
transition: all .2s;
|
transition: all .2s;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.add-dev-button {
|
||||||
|
margin-top: 4px;
|
||||||
|
max-height: 28px;
|
||||||
|
padding: 5px 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
background-color: #03a9f4;
|
||||||
|
color: white;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-dev-button:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,6 +140,14 @@ class SecurityView extends connect(store)(LitElement) {
|
|||||||
</label>
|
</label>
|
||||||
<mwc-checkbox style="margin-right: -15px;" id="authButton" @click=${(e) => this.checkForLists(e)} ?checked=${store.getState().app.qAPPAutoLists}></mwc-checkbox>
|
<mwc-checkbox style="margin-right: -15px;" id="authButton" @click=${(e) => this.checkForLists(e)} ?checked=${store.getState().app.qAPPAutoLists}></mwc-checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="checkbox-row">
|
||||||
|
<button
|
||||||
|
class="add-dev-button"
|
||||||
|
title="${translate('tabmenu.tm18')}"
|
||||||
|
@click=${this.openDevDialog}
|
||||||
|
>${translate('tabmenu.tm38')}</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
@ -155,6 +181,11 @@ class SecurityView extends connect(store)(LitElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openDevDialog() {
|
||||||
|
this.closeSettings()
|
||||||
|
store.dispatch(setIsOpenDevDialog(true))
|
||||||
|
}
|
||||||
|
|
||||||
async downloadBackup() {
|
async downloadBackup() {
|
||||||
let backupname = ''
|
let backupname = ''
|
||||||
this.backupErrorMessage = ''
|
this.backupErrorMessage = ''
|
||||||
|
@ -157,7 +157,9 @@ class UserSettings extends connect(store)(LitElement) {
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
min-height: 460px;
|
min-height: 460px;
|
||||||
height: 60vh;
|
height: auto;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(max-width:700px) {
|
@media(max-width:700px) {
|
||||||
@ -252,7 +254,7 @@ class UserSettings extends connect(store)(LitElement) {
|
|||||||
if (selectedView.id === 'info') {
|
if (selectedView.id === 'info') {
|
||||||
return html`<account-view></account-view>`
|
return html`<account-view></account-view>`
|
||||||
} else if (selectedView.id === 'security') {
|
} else if (selectedView.id === 'security') {
|
||||||
return html`<security-view></security-view>`
|
return html`<security-view .closeSettings=${()=> this.closeSettings()}></security-view>`
|
||||||
} else if (selectedView.id === 'export') {
|
} else if (selectedView.id === 'export') {
|
||||||
return html`<export-keys></export-keys>`
|
return html`<export-keys></export-keys>`
|
||||||
} else if (selectedView.id === 'notification') {
|
} else if (selectedView.id === 'notification') {
|
||||||
|
@ -6,7 +6,7 @@ import { Epml } from '../epml.js'
|
|||||||
import { addPluginRoutes } from '../plugins/addPluginRoutes.js'
|
import { addPluginRoutes } from '../plugins/addPluginRoutes.js'
|
||||||
import { repeat } from 'lit/directives/repeat.js';
|
import { repeat } from 'lit/directives/repeat.js';
|
||||||
import ShortUniqueId from 'short-unique-id';
|
import ShortUniqueId from 'short-unique-id';
|
||||||
import { setNewTab } from '../redux/app/app-actions.js'
|
import { setIsOpenDevDialog, setNewTab } from '../redux/app/app-actions.js'
|
||||||
import localForage from 'localforage'
|
import localForage from 'localforage'
|
||||||
import FileSaver from 'file-saver'
|
import FileSaver from 'file-saver'
|
||||||
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
|
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
|
||||||
@ -46,7 +46,8 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
tabInfo: { type: Object },
|
tabInfo: { type: Object },
|
||||||
chatLastSeen: { type: Array },
|
chatLastSeen: { type: Array },
|
||||||
chatHeads: { type: Array },
|
chatHeads: { type: Array },
|
||||||
proxyPort: { type: Number }
|
proxyPort: { type: Number },
|
||||||
|
isOpenDevDialog: {type: Boolean}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,9 +335,11 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
this.chatLastSeen = []
|
this.chatLastSeen = []
|
||||||
this.chatHeads = []
|
this.chatHeads = []
|
||||||
this.proxyPort = 0
|
this.proxyPort = 0
|
||||||
|
this.isOpenDevDialog = false
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
const plugSrc = (myPlug) => {
|
const plugSrc = (myPlug) => {
|
||||||
return myPlug === undefined ? 'about:blank' : `${window.location.origin}/plugin/${myPlug.domain}/${myPlug.page}${this.linkParam}`
|
return myPlug === undefined ? 'about:blank' : `${window.location.origin}/plugin/${myPlug.domain}/${myPlug.page}${this.linkParam}`
|
||||||
}
|
}
|
||||||
@ -396,14 +399,15 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
icon = 'tab'
|
icon = 'tab'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tab.myPlugObj && (tab.myPlugObj.url === 'websites' || tab.myPlugObj.url === 'qapps') && this.tabInfo[tab.id]) {
|
if (tab.myPlugObj && (tab.myPlugObj.url === 'myapp') && this.tabInfo[tab.id]) {
|
||||||
title = this.tabInfo[tab.id].name
|
title = this.tabInfo[tab.id].name
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tab.myPlugObj && (tab.myPlugObj.url === 'websites' || tab.myPlugObj.url === 'qapps') && this.tabInfo[tab.id]) {
|
if (tab.myPlugObj && (tab.myPlugObj.url === 'myapp') && this.tabInfo[tab.id]) {
|
||||||
count = this.tabInfo[tab.id].count
|
count = this.tabInfo[tab.id].count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (tab.myPlugObj && tab.myPlugObj.url === 'q-chat') {
|
if (tab.myPlugObj && tab.myPlugObj.url === 'q-chat') {
|
||||||
for (const chat of this.chatHeads) {
|
for (const chat of this.chatHeads) {
|
||||||
|
|
||||||
@ -458,11 +462,6 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
this.currentTab = lengthOfTabs
|
this.currentTab = lengthOfTabs
|
||||||
}}
|
}}
|
||||||
>+</button>
|
>+</button>
|
||||||
<button
|
|
||||||
class="add-dev-button"
|
|
||||||
title="${translate('tabmenu.tm18')}"
|
|
||||||
@click=${this.openDevDialog}
|
|
||||||
>${translate('tabmenu.tm38')}</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
${repeat(this.tabs, (tab) => tab.id, (tab, index) => html`
|
${repeat(this.tabs, (tab) => tab.id, (tab, index) => html`
|
||||||
@ -484,7 +483,15 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
</nav-bar>
|
</nav-bar>
|
||||||
</div>
|
</div>
|
||||||
`)}
|
`)}
|
||||||
<mwc-dialog id="addDevDialog">
|
<mwc-dialog id="addDevDialog"
|
||||||
|
?open=${this.isOpenDevDialog}
|
||||||
|
@closed=${() => {
|
||||||
|
this.shadowRoot.getElementById('domainInput').value = ''
|
||||||
|
this.shadowRoot.getElementById('portInput').value = ''
|
||||||
|
this.isOpenDevDialog = false
|
||||||
|
store.dispatch(setIsOpenDevDialog(false))
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div style="text-align: center;">
|
<div style="text-align: center;">
|
||||||
<h2>${translate('tabmenu.tm39')}</h2>
|
<h2>${translate('tabmenu.tm39')}</h2>
|
||||||
<hr>
|
<hr>
|
||||||
@ -551,12 +558,6 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
openDevDialog() {
|
|
||||||
this.shadowRoot.getElementById('domainInput').value = ''
|
|
||||||
this.shadowRoot.getElementById('portInput').value = ''
|
|
||||||
this.shadowRoot.querySelector("#addDevDialog").show()
|
|
||||||
}
|
|
||||||
|
|
||||||
async getProxyPort() {
|
async getProxyPort() {
|
||||||
this.proxyPort = 0
|
this.proxyPort = 0
|
||||||
let framework = ''
|
let framework = ''
|
||||||
@ -733,11 +734,9 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
const myPlugObj = plugArr.find(pagePlug => {
|
const myPlugObj = plugArr.find(pagePlug => {
|
||||||
return pagePlug.url === this.url
|
return pagePlug.url === this.url
|
||||||
})
|
})
|
||||||
|
|
||||||
if (this.tabs.length === 0) {
|
if (this.tabs.length === 0) {
|
||||||
this.addTab({
|
this.addTab({
|
||||||
url: this.url,
|
url: "",
|
||||||
myPlugObj,
|
|
||||||
id: this.uid()
|
id: this.uid()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -780,7 +779,7 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (split[0] === '' && split[1] === 'app' && split[2] === undefined) {
|
if (split[0] === '' && split[1] === 'app' && split[2] === undefined) {
|
||||||
newUrl = 'wallet'
|
newUrl = ''
|
||||||
newLinkParam = ''
|
newLinkParam = ''
|
||||||
} else if (split.length === 5 && split[1] === 'app') {
|
} else if (split.length === 5 && split[1] === 'app') {
|
||||||
newUrl = split[2]
|
newUrl = split[2]
|
||||||
@ -792,7 +791,6 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
newUrl = '404'
|
newUrl = '404'
|
||||||
newLinkParam = ''
|
newLinkParam = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newUrl !== this.url) {
|
if (newUrl !== this.url) {
|
||||||
this.url = newUrl
|
this.url = newUrl
|
||||||
}
|
}
|
||||||
@ -838,6 +836,9 @@ class ShowPlugin extends connect(store)(LitElement) {
|
|||||||
//clear newTab
|
//clear newTab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(state.app.isOpenDevDialog){
|
||||||
|
this.isOpenDevDialog = state.app.isOpenDevDialog
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import config from './config'
|
import config from './config'
|
||||||
import { dispatcher } from './dispatcher'
|
import { dispatcher } from './dispatcher'
|
||||||
import snackbar from '../functional-components/snackbar.js'
|
import snackbar from '../functional-components/snackbar.js'
|
||||||
import { NEW_MESSAGE, NEW_MESSAGE_NOTIFICATION_QAPP } from './types'
|
import { NEW_MESSAGE, NEW_MESSAGE_NOTIFICATION_QAPP, NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL } from './types'
|
||||||
|
|
||||||
let initial = 0
|
let initial = 0
|
||||||
let _state
|
let _state
|
||||||
@ -43,8 +43,8 @@ const notificationCheck = function () {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export const doNewMessage = function (req) {
|
export const doNewMessage = function (req) {
|
||||||
|
|
||||||
const newMessage = () => {
|
const newMessage = () => {
|
||||||
|
|
||||||
let data
|
let data
|
||||||
if (req.type && req.type === 'qapp') {
|
if (req.type && req.type === 'qapp') {
|
||||||
data = req
|
data = req
|
||||||
@ -74,9 +74,15 @@ export const doNewMessage = function (req) {
|
|||||||
_state = notificationState
|
_state = notificationState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const page = window.top.location.href
|
const page = window.top.location.href
|
||||||
if (!document.hasFocus()) {
|
if(req.type && req.type === 'qapp-local-notification'){
|
||||||
|
try {
|
||||||
|
dispatcher({ type: NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL, data: req })
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log('error', error)
|
||||||
|
}
|
||||||
|
}else if (!document.hasFocus()) {
|
||||||
newMessage()
|
newMessage()
|
||||||
} else {
|
} else {
|
||||||
if (page.includes(req.url) === false) {
|
if (page.includes(req.url) === false) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { NEW_MESSAGE, NEW_MESSAGE_NOTIFICATION_QAPP } from './types'
|
import { NEW_MESSAGE, NEW_MESSAGE_NOTIFICATION_QAPP, NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL } from './types'
|
||||||
import { newMessage, newMessageNotificationQapp } from './notification-actions'
|
import { newMessage, newMessageNotificationQapp, newMessageNotificationQappLocal } from './notification-actions'
|
||||||
|
|
||||||
export const dispatcher = function (notificationState) {
|
export const dispatcher = function (notificationState) {
|
||||||
|
|
||||||
@ -8,6 +8,8 @@ export const dispatcher = function (notificationState) {
|
|||||||
return newMessage(notificationState.data)
|
return newMessage(notificationState.data)
|
||||||
case NEW_MESSAGE_NOTIFICATION_QAPP:
|
case NEW_MESSAGE_NOTIFICATION_QAPP:
|
||||||
return newMessageNotificationQapp(notificationState.data)
|
return newMessageNotificationQapp(notificationState.data)
|
||||||
|
case NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL:
|
||||||
|
return newMessageNotificationQappLocal(notificationState.data)
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
export { newMessage, newMessageNotificationQapp } from './new-message'
|
export { newMessage, newMessageNotificationQapp, newMessageNotificationQappLocal } from './new-message'
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import { store } from '../../store.js'
|
import { store } from '../../store.js'
|
||||||
import { doPageUrl, setNewTab } from '../../redux/app/app-actions.js'
|
import { doPageUrl, setNewTab } from '../../redux/app/app-actions.js'
|
||||||
import isElectron from 'is-electron'
|
import isElectron from 'is-electron'
|
||||||
|
import ShortUniqueId from 'short-unique-id';
|
||||||
|
|
||||||
|
const uid = new ShortUniqueId()
|
||||||
|
|
||||||
export const newMessage = (data) => {
|
export const newMessage = (data) => {
|
||||||
const alert = playSound(data.sound)
|
const alert = playSound(data.sound)
|
||||||
@ -101,6 +104,157 @@ export const newMessageNotificationQapp = (data) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const extractComponents= async (url)=> {
|
||||||
|
if (!url.startsWith("qortal://")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
url = url.replace(/^(qortal\:\/\/)/, "");
|
||||||
|
if (url.includes("/")) {
|
||||||
|
let parts = url.split("/");
|
||||||
|
const service = parts[0].toUpperCase();
|
||||||
|
parts.shift();
|
||||||
|
const name = parts[0];
|
||||||
|
parts.shift();
|
||||||
|
let identifier;
|
||||||
|
|
||||||
|
if (parts.length > 0) {
|
||||||
|
identifier = parts[0]; // Do not shift yet
|
||||||
|
// Check if a resource exists with this service, name and identifier combination
|
||||||
|
let responseObj = await parentEpml.request('apiCall', {
|
||||||
|
url: `/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${this.getApiKey()}`
|
||||||
|
})
|
||||||
|
|
||||||
|
if (responseObj.totalChunkCount > 0) {
|
||||||
|
// Identifier exists, so don't include it in the path
|
||||||
|
parts.shift();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
identifier = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const path = parts.join("/");
|
||||||
|
|
||||||
|
const components = {};
|
||||||
|
components["service"] = service;
|
||||||
|
components["name"] = name;
|
||||||
|
components["identifier"] = identifier;
|
||||||
|
components["path"] = path;
|
||||||
|
return components;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const newMessageNotificationQappLocal = (data) => {
|
||||||
|
const alert = playSound(data.sound)
|
||||||
|
|
||||||
|
// Should I show notification ?
|
||||||
|
if (store.getState().user.notifications.q_chat.showNotification) {
|
||||||
|
|
||||||
|
// Yes, I can but should I play sound ?
|
||||||
|
if (store.getState().user.notifications.q_chat.playSound) {
|
||||||
|
|
||||||
|
const notify = new Notification(data.title, data.options)
|
||||||
|
|
||||||
|
notify.onshow = (e) => {
|
||||||
|
alert.play()
|
||||||
|
}
|
||||||
|
|
||||||
|
notify.onclick = async(e) => {
|
||||||
|
const url = data?.url
|
||||||
|
const value = url
|
||||||
|
let newQuery = value;
|
||||||
|
if (newQuery.endsWith('/')) {
|
||||||
|
newQuery = newQuery.slice(0, -1);
|
||||||
|
}
|
||||||
|
const res = await extractComponents(newQuery)
|
||||||
|
if (!res) return
|
||||||
|
const { service, name, identifier, path } = res
|
||||||
|
let query = `?service=${service}`
|
||||||
|
if (name) {
|
||||||
|
query = query + `&name=${name}`
|
||||||
|
}
|
||||||
|
if (identifier) {
|
||||||
|
query = query + `&identifier=${identifier}`
|
||||||
|
}
|
||||||
|
if (path) {
|
||||||
|
query = query + `&path=${path}`
|
||||||
|
}
|
||||||
|
const tab = {
|
||||||
|
url: `qdn/browser/index.html${query}`,
|
||||||
|
id: uid(),
|
||||||
|
myPlugObj: {
|
||||||
|
"url": service === 'WEBSITE' ? "websites" : "qapps",
|
||||||
|
"domain": "core",
|
||||||
|
"page": `qdn/browser/index.html${query}`,
|
||||||
|
"title": name,
|
||||||
|
"icon": service === 'WEBSITE' ? 'vaadin:desktop' : 'vaadin:external-browser',
|
||||||
|
"mwcicon": service === 'WEBSITE' ? 'desktop_mac' : 'open_in_browser',
|
||||||
|
"menus": [],
|
||||||
|
"parent": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
store.dispatch(setNewTab(tab))
|
||||||
|
if (!isElectron()) {
|
||||||
|
window.focus();
|
||||||
|
} else {
|
||||||
|
window.electronAPI.focusApp()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const notify = new Notification(data.title, data.options)
|
||||||
|
|
||||||
|
notify.onclick = async(e) => {
|
||||||
|
const url = data?.url
|
||||||
|
const value = url
|
||||||
|
let newQuery = value;
|
||||||
|
if (newQuery.endsWith('/')) {
|
||||||
|
newQuery = newQuery.slice(0, -1);
|
||||||
|
}
|
||||||
|
const res = await extractComponents(newQuery)
|
||||||
|
if (!res) return
|
||||||
|
const { service, name, identifier, path } = res
|
||||||
|
let query = `?service=${service}`
|
||||||
|
if (name) {
|
||||||
|
query = query + `&name=${name}`
|
||||||
|
}
|
||||||
|
if (identifier) {
|
||||||
|
query = query + `&identifier=${identifier}`
|
||||||
|
}
|
||||||
|
if (path) {
|
||||||
|
query = query + `&path=${path}`
|
||||||
|
}
|
||||||
|
const tab = {
|
||||||
|
url: `qdn/browser/index.html${query}`,
|
||||||
|
id: uid(),
|
||||||
|
myPlugObj: {
|
||||||
|
"url": service === 'WEBSITE' ? "websites" : "qapps",
|
||||||
|
"domain": "core",
|
||||||
|
"page": `qdn/browser/index.html${query}`,
|
||||||
|
"title": name,
|
||||||
|
"icon": service === 'WEBSITE' ? 'vaadin:desktop' : 'vaadin:external-browser',
|
||||||
|
"mwcicon": service === 'WEBSITE' ? 'desktop_mac' : 'open_in_browser',
|
||||||
|
"menus": [],
|
||||||
|
"parent": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
store.dispatch(setNewTab(tab))
|
||||||
|
if (!isElectron()) {
|
||||||
|
window.focus();
|
||||||
|
} else {
|
||||||
|
window.electronAPI.focusApp()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const playSound = (soundUrl) => {
|
const playSound = (soundUrl) => {
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
export const NEW_MESSAGE = 'NEW_MESSAGE'
|
export const NEW_MESSAGE = 'NEW_MESSAGE'
|
||||||
export const NEW_MESSAGE_NOTIFICATION_QAPP = 'NEW_MESSAGE_NOTIFICATION_QAPP'
|
export const NEW_MESSAGE_NOTIFICATION_QAPP = 'NEW_MESSAGE_NOTIFICATION_QAPP'
|
||||||
|
export const NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL = 'NEW_MESSAGE_NOTIFICATION_QAPP_LOCAL'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Core App Actions here...
|
// Core App Actions here...
|
||||||
import { UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, CHAT_HEADS, ACCOUNT_INFO, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, ALLOW_QAPP_AUTO_AUTH, REMOVE_QAPP_AUTO_AUTH, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN, ALLOW_QAPP_AUTO_LISTS, REMOVE_QAPP_AUTO_LISTS, SET_NEW_TAB, ADD_TAB_INFO, SET_TAB_NOTIFICATIONS } from '../app-action-types.js'
|
import { UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, CHAT_HEADS, ACCOUNT_INFO, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, ALLOW_QAPP_AUTO_AUTH, REMOVE_QAPP_AUTO_AUTH, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN, ALLOW_QAPP_AUTO_LISTS, REMOVE_QAPP_AUTO_LISTS, SET_NEW_TAB, ADD_TAB_INFO, SET_TAB_NOTIFICATIONS, IS_OPEN_DEV_DIALOG } from '../app-action-types.js'
|
||||||
|
|
||||||
export const doUpdateBlockInfo = (blockObj) => {
|
export const doUpdateBlockInfo = (blockObj) => {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -126,7 +126,12 @@ export const setNewTab = (payload) => {
|
|||||||
payload
|
payload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export const setIsOpenDevDialog = (payload)=> {
|
||||||
|
return {
|
||||||
|
type: IS_OPEN_DEV_DIALOG,
|
||||||
|
payload
|
||||||
|
}
|
||||||
|
}
|
||||||
export const addTabInfo = (payload) => {
|
export const addTabInfo = (payload) => {
|
||||||
return {
|
return {
|
||||||
type: ADD_TAB_INFO,
|
type: ADD_TAB_INFO,
|
||||||
|
@ -28,3 +28,4 @@ export const ADD_CHAT_LAST_SEEN = 'ADD_CHAT_LAST_SEEN'
|
|||||||
export const SET_NEW_TAB = 'SET_NEW_TAB'
|
export const SET_NEW_TAB = 'SET_NEW_TAB'
|
||||||
export const ADD_TAB_INFO = 'ADD_TAB_INFO'
|
export const ADD_TAB_INFO = 'ADD_TAB_INFO'
|
||||||
export const SET_TAB_NOTIFICATIONS = 'SET_TAB_NOTIFICATIONS'
|
export const SET_TAB_NOTIFICATIONS = 'SET_TAB_NOTIFICATIONS'
|
||||||
|
export const IS_OPEN_DEV_DIALOG = 'IS_OPEN_DEV_DIALOG'
|
@ -1,6 +1,6 @@
|
|||||||
// Loading state, login state, isNavDrawOpen state etc. None of this needs to be saved to localstorage.
|
// Loading state, login state, isNavDrawOpen state etc. None of this needs to be saved to localstorage.
|
||||||
import { loadStateFromLocalStorage, saveStateToLocalStorage } from '../../localStorageHelpers.js'
|
import { loadStateFromLocalStorage, saveStateToLocalStorage } from '../../localStorageHelpers.js'
|
||||||
import { LOG_IN, LOG_OUT, NETWORK_CONNECTION_STATUS, INIT_WORKERS, ADD_PLUGIN_URL, ADD_PLUGIN, ADD_NEW_PLUGIN_URL, NAVIGATE, SELECT_ADDRESS, ACCOUNT_INFO, CHAT_HEADS, UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, LOAD_NODE_CONFIG, SET_NODE, ADD_NODE, PAGE_URL, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, ALLOW_QAPP_AUTO_AUTH, REMOVE_QAPP_AUTO_AUTH, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN, ALLOW_QAPP_AUTO_LISTS, REMOVE_QAPP_AUTO_LISTS, SET_NEW_TAB, ADD_TAB_INFO, SET_TAB_NOTIFICATIONS } from './app-action-types.js'
|
import { LOG_IN, LOG_OUT, NETWORK_CONNECTION_STATUS, INIT_WORKERS, ADD_PLUGIN_URL, ADD_PLUGIN, ADD_NEW_PLUGIN_URL, NAVIGATE, SELECT_ADDRESS, ACCOUNT_INFO, CHAT_HEADS, UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, LOAD_NODE_CONFIG, SET_NODE, ADD_NODE, PAGE_URL, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, ALLOW_QAPP_AUTO_AUTH, REMOVE_QAPP_AUTO_AUTH, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN, ALLOW_QAPP_AUTO_LISTS, REMOVE_QAPP_AUTO_LISTS, SET_NEW_TAB, ADD_TAB_INFO, SET_TAB_NOTIFICATIONS, IS_OPEN_DEV_DIALOG } from './app-action-types.js'
|
||||||
import { initWorkersReducer } from './reducers/init-workers.js'
|
import { initWorkersReducer } from './reducers/init-workers.js'
|
||||||
import { loginReducer } from './reducers/login-reducer.js'
|
import { loginReducer } from './reducers/login-reducer.js'
|
||||||
import { setNode, addNode } from './reducers/manage-node.js'
|
import { setNode, addNode } from './reducers/manage-node.js'
|
||||||
@ -49,7 +49,8 @@ const INITIAL_STATE = {
|
|||||||
qAPPAutoLists: loadStateFromLocalStorage('qAPPAutoLists') || false,
|
qAPPAutoLists: loadStateFromLocalStorage('qAPPAutoLists') || false,
|
||||||
chatLastSeen: [],
|
chatLastSeen: [],
|
||||||
newTab: null,
|
newTab: null,
|
||||||
tabInfo: {}
|
tabInfo: {},
|
||||||
|
isOpenDevDialog: false
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (state = INITIAL_STATE, action) => {
|
export default (state = INITIAL_STATE, action) => {
|
||||||
@ -231,6 +232,12 @@ export default (state = INITIAL_STATE, action) => {
|
|||||||
newTab: action.payload
|
newTab: action.payload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case IS_OPEN_DEV_DIALOG: {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isOpenDevDialog: action.payload
|
||||||
|
}
|
||||||
|
}
|
||||||
case ADD_TAB_INFO: {
|
case ADD_TAB_INFO: {
|
||||||
const newTabInfo = action.payload
|
const newTabInfo = action.payload
|
||||||
if (state.tabInfo[newTabInfo.id] && state.tabInfo[newTabInfo.id].name && newTabInfo.name === state.tabInfo[newTabInfo.id].name) break
|
if (state.tabInfo[newTabInfo.id] && state.tabInfo[newTabInfo.id].name && newTabInfo.name === state.tabInfo[newTabInfo.id].name) break
|
||||||
|
@ -1 +0,0 @@
|
|||||||
export const UI_VERSION = "4.0.4";
|
|
@ -161,6 +161,10 @@ const PROXY_URL = "/proxy/"
|
|||||||
// Chat reference timestamp
|
// Chat reference timestamp
|
||||||
const CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP = 1674316800000
|
const CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP = 1674316800000
|
||||||
|
|
||||||
|
// Dynamic fee timestamp
|
||||||
|
const DYNAMIC_FEE_TIMESTAMP = 1692118800000
|
||||||
|
|
||||||
|
|
||||||
// Used as a salt for all Qora addresses. Salts used for storing your private keys in local storage will be randomly generated
|
// Used as a salt for all Qora addresses. Salts used for storing your private keys in local storage will be randomly generated
|
||||||
const STATIC_SALT = new Uint8Array([54, 190, 201, 206, 65, 29, 123, 129, 147, 231, 180, 166, 171, 45, 95, 165, 78, 200, 208, 194, 44, 207, 221, 146, 45, 238, 68, 68, 69, 102, 62, 6])
|
const STATIC_SALT = new Uint8Array([54, 190, 201, 206, 65, 29, 123, 129, 147, 231, 180, 166, 171, 45, 95, 165, 78, 200, 208, 194, 44, 207, 221, 146, 45, 238, 68, 68, 69, 102, 62, 6])
|
||||||
const BCRYPT_ROUNDS = 10 // Remember that the total work spent on key derivation is BCRYPT_ROUNDS * KDF_THREADS
|
const BCRYPT_ROUNDS = 10 // Remember that the total work spent on key derivation is BCRYPT_ROUNDS * KDF_THREADS
|
||||||
@ -168,4 +172,4 @@ const BCRYPT_VERSION = "2a"
|
|||||||
const STATIC_BCRYPT_SALT = `$${BCRYPT_VERSION}$${BCRYPT_ROUNDS}$IxVE941tXVUD4cW0TNVm.O`
|
const STATIC_BCRYPT_SALT = `$${BCRYPT_VERSION}$${BCRYPT_ROUNDS}$IxVE941tXVUD4cW0TNVm.O`
|
||||||
const KDF_THREADS = 16
|
const KDF_THREADS = 16
|
||||||
|
|
||||||
export { TX_TYPES, ERROR_CODES, QORT_DECIMALS, PROXY_URL, STATIC_SALT, ADDRESS_VERSION, KDF_THREADS, STATIC_BCRYPT_SALT, CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP }
|
export { TX_TYPES, ERROR_CODES, QORT_DECIMALS, PROXY_URL, STATIC_SALT, ADDRESS_VERSION, KDF_THREADS, STATIC_BCRYPT_SALT, CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP, DYNAMIC_FEE_TIMESTAMP }
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
import TransactionBase from './TransactionBase.js'
|
import TransactionBase from './TransactionBase.js'
|
||||||
import { store } from '../../api.js'
|
import { store } from '../../api.js'
|
||||||
|
import { QORT_DECIMALS } from '../constants.js'
|
||||||
|
|
||||||
export default class DeployAtTransaction extends TransactionBase {
|
export default class DeployAtTransaction extends TransactionBase {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -8,17 +9,22 @@ export default class DeployAtTransaction extends TransactionBase {
|
|||||||
this.type = 16
|
this.type = 16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
render(html) {
|
render(html) {
|
||||||
return html`
|
return html`
|
||||||
${this._groupdialog5}
|
${this._atDeployDialog1}:
|
||||||
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
|
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
|
||||||
<div>${this._atDeployDialog1}: <span style="color: #000;">${this._rName}</span></div>
|
<span style="color: #000;">${this._rName}</span>
|
||||||
<br>
|
|
||||||
<div>${this.atDeployDialog2}: <span style="color: #000;">${this._rDescription}</span></div>
|
|
||||||
<br>
|
|
||||||
</div>
|
</div>
|
||||||
|
${this._atDeployDialog4}:
|
||||||
|
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
|
||||||
|
<span style="color: #000;">${this._feeToShow}</span>
|
||||||
</div>
|
</div>
|
||||||
${this._groupdialog6}
|
${this._atDeployDialog3}:
|
||||||
|
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
|
||||||
|
<span style="color: #000;">${this._amountToShow}</span>
|
||||||
|
</div>
|
||||||
|
${this._atDeployDialog2}
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,12 +34,20 @@ export default class DeployAtTransaction extends TransactionBase {
|
|||||||
set atDeployDialog2(atDeployDialog2) {
|
set atDeployDialog2(atDeployDialog2) {
|
||||||
this._atDeployDialog2 = atDeployDialog2
|
this._atDeployDialog2 = atDeployDialog2
|
||||||
}
|
}
|
||||||
|
set atDeployDialog3(atDeployDialog3) {
|
||||||
|
this._atDeployDialog3 = atDeployDialog3
|
||||||
|
}
|
||||||
|
set atDeployDialog4(atDeployDialog4) {
|
||||||
|
this._atDeployDialog4 = atDeployDialog4
|
||||||
|
}
|
||||||
|
|
||||||
set fee(fee) {
|
set fee(fee) {
|
||||||
this._fee = fee
|
this._feeToShow = fee
|
||||||
|
this._fee = fee * QORT_DECIMALS
|
||||||
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
|
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
|
||||||
}
|
}
|
||||||
set rAmount(rAmount) {
|
set rAmount(rAmount) {
|
||||||
|
this._amountToShow = rAmount
|
||||||
this._rAmount = Math.round(rAmount * store.getState().config.coin.decimals)
|
this._rAmount = Math.round(rAmount * store.getState().config.coin.decimals)
|
||||||
this._rAmountBytes = this.constructor.utils.int64ToBytes(this._rAmount)
|
this._rAmountBytes = this.constructor.utils.int64ToBytes(this._rAmount)
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import TransactionBase from '../TransactionBase.js'
|
import TransactionBase from '../TransactionBase.js'
|
||||||
import publicKeyToAddress from '../../wallet/publicKeyToAddress.js'
|
import publicKeyToAddress from '../../wallet/publicKeyToAddress.js'
|
||||||
import { Base58 } from '../../deps/deps.js'
|
import { Base58 } from '../../deps/deps.js'
|
||||||
|
import { DYNAMIC_FEE_TIMESTAMP } from '../../constants.js'
|
||||||
|
|
||||||
export default class RemoveRewardShareTransaction extends TransactionBase {
|
export default class RemoveRewardShareTransaction extends TransactionBase {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -34,8 +35,13 @@ export default class RemoveRewardShareTransaction extends TransactionBase {
|
|||||||
set recipient(recipient) {
|
set recipient(recipient) {
|
||||||
const _address = publicKeyToAddress(this._keyPair.publicKey)
|
const _address = publicKeyToAddress(this._keyPair.publicKey)
|
||||||
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
|
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
|
||||||
|
|
||||||
|
if (new Date(this._timestamp).getTime() >= DYNAMIC_FEE_TIMESTAMP) {
|
||||||
|
this.fee = _address === recipient ? 0 : 0.01
|
||||||
|
} else {
|
||||||
this.fee = _address === recipient ? 0 : 0.001
|
this.fee = _address === recipient ? 0 : 0.001
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
set percentageShare(share) {
|
set percentageShare(share) {
|
||||||
this._percentageShare = share * 100
|
this._percentageShare = share * 100
|
||||||
|
@ -4,6 +4,7 @@ import TransactionBase from "../TransactionBase.js"
|
|||||||
import nacl from '../../deps/nacl-fast.js'
|
import nacl from '../../deps/nacl-fast.js'
|
||||||
import ed2curve from '../../deps/ed2curve.js'
|
import ed2curve from '../../deps/ed2curve.js'
|
||||||
import { Sha256 } from 'asmcrypto.js'
|
import { Sha256 } from 'asmcrypto.js'
|
||||||
|
import { DYNAMIC_FEE_TIMESTAMP } from '../../constants.js'
|
||||||
|
|
||||||
export default class RewardShareTransaction extends TransactionBase {
|
export default class RewardShareTransaction extends TransactionBase {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -54,6 +55,12 @@ export default class RewardShareTransaction extends TransactionBase {
|
|||||||
this._base58RewardShareSeed = this.constructor.Base58.encode(this._rewardShareSeed)
|
this._base58RewardShareSeed = this.constructor.Base58.encode(this._rewardShareSeed)
|
||||||
|
|
||||||
this._rewardShareKeyPair = nacl.sign.keyPair.fromSeed(this._rewardShareSeed)
|
this._rewardShareKeyPair = nacl.sign.keyPair.fromSeed(this._rewardShareSeed)
|
||||||
|
|
||||||
|
if (new Date(this._timestamp).getTime() >= DYNAMIC_FEE_TIMESTAMP) {
|
||||||
|
this.fee = (recipientPublicKey === this.constructor.Base58.encode(this._keyPair.publicKey) ? 0 : 0.01)
|
||||||
|
} else {
|
||||||
|
this.fee = (recipientPublicKey === this.constructor.Base58.encode(this._keyPair.publicKey) ? 0 : 0.001)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set recipient(recipient) {
|
set recipient(recipient) {
|
||||||
|
@ -845,7 +845,7 @@ function createWindow() {
|
|||||||
})
|
})
|
||||||
myWindow.maximize()
|
myWindow.maximize()
|
||||||
myWindow.show()
|
myWindow.show()
|
||||||
myWindow.loadURL('http://localhost:12388/app/wallet')
|
myWindow.loadURL('http://localhost:12388/app')
|
||||||
myWindow.on('closed', function () {
|
myWindow.on('closed', function () {
|
||||||
myWindow = null
|
myWindow = null
|
||||||
})
|
})
|
||||||
@ -886,7 +886,7 @@ function createNewWindow() {
|
|||||||
show: false
|
show: false
|
||||||
})
|
})
|
||||||
newWindow.show()
|
newWindow.show()
|
||||||
newWindow.loadURL('http://localhost:12388/app/wallet')
|
newWindow.loadURL('http://localhost:12388/app')
|
||||||
newWindow.on('closed', function () {
|
newWindow.on('closed', function () {
|
||||||
newWindow = null
|
newWindow = null
|
||||||
})
|
})
|
||||||
|
810
package-lock.json
generated
810
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
38
package.json
38
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "qortal-ui",
|
"name": "qortal-ui",
|
||||||
"version": "4.3.0",
|
"version": "4.3.2",
|
||||||
"description": "Qortal Project - decentralize the world - Data storage, communications, web hosting, decentralized trading, complete infrastructure for the future blockchain-based Internet",
|
"description": "Qortal Project - decentralize the world - Data storage, communications, web hosting, decentralized trading, complete infrastructure for the future blockchain-based Internet",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"QORT",
|
"QORT",
|
||||||
@ -41,7 +41,7 @@
|
|||||||
"electron-store": "8.1.0",
|
"electron-store": "8.1.0",
|
||||||
"emoji-picker-js": "https://github.com/Qortal/emoji-picker-js",
|
"emoji-picker-js": "https://github.com/Qortal/emoji-picker-js",
|
||||||
"extract-zip": "2.0.1",
|
"extract-zip": "2.0.1",
|
||||||
"jssha": "3.3.0",
|
"jssha": "3.3.1",
|
||||||
"localforage": "1.10.0",
|
"localforage": "1.10.0",
|
||||||
"lodash": "4.17.21",
|
"lodash": "4.17.21",
|
||||||
"node-fetch": "2.6.9",
|
"node-fetch": "2.6.9",
|
||||||
@ -54,9 +54,9 @@
|
|||||||
"prosemirror-model": "1.19.3",
|
"prosemirror-model": "1.19.3",
|
||||||
"prosemirror-schema-list": "1.3.0",
|
"prosemirror-schema-list": "1.3.0",
|
||||||
"prosemirror-state": "1.4.3",
|
"prosemirror-state": "1.4.3",
|
||||||
"prosemirror-transform": "1.7.4",
|
"prosemirror-transform": "1.7.5",
|
||||||
"prosemirror-view": "1.31.7",
|
"prosemirror-view": "1.31.7",
|
||||||
"sass": "1.64.2",
|
"sass": "1.66.1",
|
||||||
"short-unique-id": "4.4.4",
|
"short-unique-id": "4.4.4",
|
||||||
"@hapi/hapi": "21.3.2",
|
"@hapi/hapi": "21.3.2",
|
||||||
"@hapi/inert": "7.1.0",
|
"@hapi/inert": "7.1.0",
|
||||||
@ -71,10 +71,10 @@
|
|||||||
"@tiptap/starter-kit": "2.0.4"
|
"@tiptap/starter-kit": "2.0.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"axios": "1.4.0",
|
"axios": "1.5.0",
|
||||||
"electron": "25.4.0",
|
"electron": "26.1.0",
|
||||||
"electron-builder": "24.6.3",
|
"electron-builder": "24.6.3",
|
||||||
"electron-packager": "17.1.1",
|
"electron-packager": "17.1.2",
|
||||||
"epml": "0.3.3",
|
"epml": "0.3.3",
|
||||||
"file-saver": "2.0.5",
|
"file-saver": "2.0.5",
|
||||||
"highcharts": "11.1.0",
|
"highcharts": "11.1.0",
|
||||||
@ -86,12 +86,12 @@
|
|||||||
"passive-events-support": "1.1.0",
|
"passive-events-support": "1.1.0",
|
||||||
"redux": "4.2.1",
|
"redux": "4.2.1",
|
||||||
"redux-thunk": "2.4.2",
|
"redux-thunk": "2.4.2",
|
||||||
"rollup": "3.27.2",
|
"rollup": "3.28.1",
|
||||||
"rollup-plugin-node-globals": "1.4.0",
|
"rollup-plugin-node-globals": "1.4.0",
|
||||||
"rollup-plugin-progress": "1.1.2",
|
"rollup-plugin-progress": "1.1.2",
|
||||||
"rollup-plugin-scss": "3.0.0",
|
"rollup-plugin-scss": "3.0.0",
|
||||||
"shelljs": "0.8.5",
|
"shelljs": "0.8.5",
|
||||||
"@babel/core": "7.22.9",
|
"@babel/core": "7.22.11",
|
||||||
"@material/mwc-button": "0.27.0",
|
"@material/mwc-button": "0.27.0",
|
||||||
"@material/mwc-checkbox": "0.27.0",
|
"@material/mwc-checkbox": "0.27.0",
|
||||||
"@material/mwc-dialog": "0.27.0",
|
"@material/mwc-dialog": "0.27.0",
|
||||||
@ -130,19 +130,19 @@
|
|||||||
"@qortal/rollup-plugin-web-worker-loader": "1.6.4",
|
"@qortal/rollup-plugin-web-worker-loader": "1.6.4",
|
||||||
"@rollup/plugin-alias": "5.0.0",
|
"@rollup/plugin-alias": "5.0.0",
|
||||||
"@rollup/plugin-babel": "6.0.3",
|
"@rollup/plugin-babel": "6.0.3",
|
||||||
"@rollup/plugin-commonjs": "25.0.3",
|
"@rollup/plugin-commonjs": "25.0.4",
|
||||||
"@rollup/plugin-node-resolve": "15.1.0",
|
"@rollup/plugin-node-resolve": "15.2.1",
|
||||||
"@rollup/plugin-replace": "5.0.2",
|
"@rollup/plugin-replace": "5.0.2",
|
||||||
"@rollup/plugin-terser": "0.4.3",
|
"@rollup/plugin-terser": "0.4.3",
|
||||||
"@vaadin/avatar": "24.1.4",
|
"@vaadin/avatar": "24.1.6",
|
||||||
"@vaadin/button": "24.1.4",
|
"@vaadin/button": "24.1.6",
|
||||||
"@vaadin/grid": "24.1.4",
|
"@vaadin/grid": "24.1.6",
|
||||||
"@vaadin/icons": "24.1.4",
|
"@vaadin/icons": "24.1.6",
|
||||||
"@vaadin/password-field": "24.1.4",
|
"@vaadin/password-field": "24.1.6",
|
||||||
"@vaadin/tooltip": "24.1.4",
|
"@vaadin/tooltip": "24.1.6",
|
||||||
"@zip.js/zip.js": "2.7.20"
|
"@zip.js/zip.js": "2.7.27"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.15.0"
|
"node": ">=18.16.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,14 +36,13 @@ import './ChatLeaveGroup.js'
|
|||||||
import './ChatGroupSettings.js'
|
import './ChatGroupSettings.js'
|
||||||
import './ChatRightPanel.js'
|
import './ChatRightPanel.js'
|
||||||
import './ChatSearchResults.js'
|
import './ChatSearchResults.js'
|
||||||
import './ChatGifs/ChatGifs.js'
|
|
||||||
|
|
||||||
import '@material/mwc-button'
|
import '@material/mwc-button'
|
||||||
import '@material/mwc-dialog'
|
import '@material/mwc-dialog'
|
||||||
import '@material/mwc-icon'
|
import '@material/mwc-icon'
|
||||||
import '@polymer/paper-dialog/paper-dialog.js'
|
import '@polymer/paper-dialog/paper-dialog.js'
|
||||||
import '@polymer/paper-spinner/paper-spinner-lite.js'
|
import '@polymer/paper-spinner/paper-spinner-lite.js'
|
||||||
import { RequestQueue } from '../../utils/queue.js'
|
import { RequestQueue } from '../../utils/queue.js'
|
||||||
|
import { modalHelper } from '../../utils/publish-modal.js'
|
||||||
|
|
||||||
const chatLastSeen = localForage.createInstance({
|
const chatLastSeen = localForage.createInstance({
|
||||||
name: "chat-last-seen",
|
name: "chat-last-seen",
|
||||||
@ -1449,8 +1448,6 @@ class ChatPage extends LitElement {
|
|||||||
<div style="position: fixed; top:${parseInt(this.isLoadingGoToRepliedMessage.top)}px;left: ${parseInt(this.isLoadingGoToRepliedMessage.left)}px" class=${`smallLoading marginLoader`}></div>
|
<div style="position: fixed; top:${parseInt(this.isLoadingGoToRepliedMessage.top)}px;left: ${parseInt(this.isLoadingGoToRepliedMessage.left)}px" class=${`smallLoading marginLoader`}></div>
|
||||||
` : ''}
|
` : ''}
|
||||||
<div class="chat-text-area" style="${`${(this.repliedToMessageObj || this.editedMessageObj) && "min-height: 120px"}`}">
|
<div class="chat-text-area" style="${`${(this.repliedToMessageObj || this.editedMessageObj) && "min-height: 120px"}`}">
|
||||||
<!-- gif div -->
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class='last-message-ref'
|
class='last-message-ref'
|
||||||
style=${(this.lastMessageRefVisible && !this.imageFile && !this.openGifModal) ? 'opacity: 1;' : 'opacity: 0;'}>
|
style=${(this.lastMessageRefVisible && !this.imageFile && !this.openGifModal) ? 'opacity: 1;' : 'opacity: 0;'}>
|
||||||
@ -1880,7 +1877,7 @@ class ChatPage extends LitElement {
|
|||||||
return memberItem
|
return memberItem
|
||||||
})
|
})
|
||||||
const membersWithName = await Promise.all(getMembersWithName)
|
const membersWithName = await Promise.all(getMembersWithName)
|
||||||
this.groupMembers = membersWithName
|
this.groupMembers = [...this.groupMembers, ...membersWithName]
|
||||||
this.pageNumber = this.pageNumber + 1
|
this.pageNumber = this.pageNumber + 1
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
}
|
}
|
||||||
@ -3177,6 +3174,7 @@ viewElement.scrollTop = originalScrollTop + heightDifference;
|
|||||||
}
|
}
|
||||||
|
|
||||||
async _sendMessage(outSideMsg, msg) {
|
async _sendMessage(outSideMsg, msg) {
|
||||||
|
try {
|
||||||
if (this.isReceipient) {
|
if (this.isReceipient) {
|
||||||
let hasPublicKey = true
|
let hasPublicKey = true
|
||||||
if (!this._publicKey.hasPubKey) {
|
if (!this._publicKey.hasPubKey) {
|
||||||
@ -3286,6 +3284,13 @@ viewElement.scrollTop = originalScrollTop + heightDifference;
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
const arbitraryFeeData = await modalHelper.getArbitraryFee()
|
||||||
|
const res = await modalHelper.showModalAndWaitPublish(
|
||||||
|
{
|
||||||
|
feeAmount: arbitraryFeeData.feeToShow
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.action !== 'accept') throw new Error('User declined publish')
|
||||||
try {
|
try {
|
||||||
await publishData({
|
await publishData({
|
||||||
registeredName: userName,
|
registeredName: userName,
|
||||||
@ -3296,7 +3301,9 @@ viewElement.scrollTop = originalScrollTop + heightDifference;
|
|||||||
metaData: undefined,
|
metaData: undefined,
|
||||||
uploadType: 'file',
|
uploadType: 'file',
|
||||||
selectedAddress: this.selectedAddress,
|
selectedAddress: this.selectedAddress,
|
||||||
worker: this.webWorkerFile
|
worker: this.webWorkerFile,
|
||||||
|
withFee: true,
|
||||||
|
feeAmount: arbitraryFeeData.fee
|
||||||
})
|
})
|
||||||
this.isDeletingImage = false
|
this.isDeletingImage = false
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -3374,7 +3381,13 @@ viewElement.scrollTop = originalScrollTop + heightDifference;
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
const arbitraryFeeData = await modalHelper.getArbitraryFee()
|
||||||
|
const res = await modalHelper.showModalAndWaitPublish(
|
||||||
|
{
|
||||||
|
feeAmount: arbitraryFeeData.feeToShow
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.action !== 'accept') throw new Error('User declined publish')
|
||||||
try {
|
try {
|
||||||
await publishData({
|
await publishData({
|
||||||
registeredName: userName,
|
registeredName: userName,
|
||||||
@ -3385,7 +3398,9 @@ viewElement.scrollTop = originalScrollTop + heightDifference;
|
|||||||
metaData: undefined,
|
metaData: undefined,
|
||||||
uploadType: 'file',
|
uploadType: 'file',
|
||||||
selectedAddress: this.selectedAddress,
|
selectedAddress: this.selectedAddress,
|
||||||
worker: this.webWorkerFile
|
worker: this.webWorkerFile,
|
||||||
|
withFee: true,
|
||||||
|
feeAmount: arbitraryFeeData.fee
|
||||||
})
|
})
|
||||||
this.isDeletingAttachment = false
|
this.isDeletingAttachment = false
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -3423,6 +3438,13 @@ viewElement.scrollTop = originalScrollTop + heightDifference;
|
|||||||
this.imageFile = null
|
this.imageFile = null
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const arbitraryFeeData = await modalHelper.getArbitraryFee()
|
||||||
|
const res = await modalHelper.showModalAndWaitPublish(
|
||||||
|
{
|
||||||
|
feeAmount: arbitraryFeeData.feeToShow
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.action !== 'accept') throw new Error('User declined publish')
|
||||||
|
|
||||||
if (this.webWorkerFile) {
|
if (this.webWorkerFile) {
|
||||||
this.webWorkerFile.terminate()
|
this.webWorkerFile.terminate()
|
||||||
@ -3457,7 +3479,9 @@ viewElement.scrollTop = originalScrollTop + heightDifference;
|
|||||||
this.isUploadingImage = false
|
this.isUploadingImage = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
await publishData({
|
await publishData({
|
||||||
registeredName: userName,
|
registeredName: userName,
|
||||||
file: compressedFile,
|
file: compressedFile,
|
||||||
@ -3467,7 +3491,9 @@ viewElement.scrollTop = originalScrollTop + heightDifference;
|
|||||||
metaData: undefined,
|
metaData: undefined,
|
||||||
uploadType: 'file',
|
uploadType: 'file',
|
||||||
selectedAddress: this.selectedAddress,
|
selectedAddress: this.selectedAddress,
|
||||||
worker: this.webWorkerFile
|
worker: this.webWorkerFile,
|
||||||
|
withFee: true,
|
||||||
|
feeAmount: arbitraryFeeData.fee
|
||||||
})
|
})
|
||||||
this.isUploadingImage = false
|
this.isUploadingImage = false
|
||||||
this.removeImage()
|
this.removeImage()
|
||||||
@ -3537,6 +3563,13 @@ viewElement.scrollTop = originalScrollTop + heightDifference;
|
|||||||
this.isUploadingAttachment = false
|
this.isUploadingAttachment = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const arbitraryFeeData = await modalHelper.getArbitraryFee()
|
||||||
|
const res = await modalHelper.showModalAndWaitPublish(
|
||||||
|
{
|
||||||
|
feeAmount: arbitraryFeeData.feeToShow
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.action !== 'accept') throw new Error('User declined publish')
|
||||||
try {
|
try {
|
||||||
await publishData({
|
await publishData({
|
||||||
registeredName: userName,
|
registeredName: userName,
|
||||||
@ -3547,7 +3580,9 @@ viewElement.scrollTop = originalScrollTop + heightDifference;
|
|||||||
metaData: undefined,
|
metaData: undefined,
|
||||||
uploadType: 'file',
|
uploadType: 'file',
|
||||||
selectedAddress: this.selectedAddress,
|
selectedAddress: this.selectedAddress,
|
||||||
worker: this.webWorkerFile
|
worker: this.webWorkerFile,
|
||||||
|
withFee: true,
|
||||||
|
feeAmount: arbitraryFeeData.fee
|
||||||
})
|
})
|
||||||
this.isUploadingAttachment = false
|
this.isUploadingAttachment = false
|
||||||
this.removeAttachment()
|
this.removeAttachment()
|
||||||
@ -3682,6 +3717,12 @@ viewElement.scrollTop = originalScrollTop + heightDifference;
|
|||||||
this.sendMessage(stringifyMessageObject, typeMessage)
|
this.sendMessage(stringifyMessageObject, typeMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.isLoading = false
|
||||||
|
this.isUploadingImage = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendMessage(messageText, typeMessage, chatReference, isForward) {
|
async sendMessage(messageText, typeMessage, chatReference, isForward) {
|
||||||
|
@ -225,7 +225,6 @@ class ChatRightPanel extends LitElement {
|
|||||||
if(this.groupMembers.length < 20){
|
if(this.groupMembers.length < 20){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.log('this.leaveGroupObjp', this.leaveGroupObj)
|
|
||||||
this.getMoreMembers(this.leaveGroupObj.groupId)
|
this.getMoreMembers(this.leaveGroupObj.groupId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,7 +251,6 @@ class ChatRightPanel extends LitElement {
|
|||||||
activeChatHeadUrl=""
|
activeChatHeadUrl=""
|
||||||
.setActiveChatHeadUrl=${(val) => {
|
.setActiveChatHeadUrl=${(val) => {
|
||||||
if (val.address === this.myAddress) return;
|
if (val.address === this.myAddress) return;
|
||||||
console.log({ val });
|
|
||||||
this.selectedHead = val;
|
this.selectedHead = val;
|
||||||
this.setOpenUserInfo(true);
|
this.setOpenUserInfo(true);
|
||||||
this.setUserName({
|
this.setUserName({
|
||||||
@ -269,7 +267,6 @@ class ChatRightPanel extends LitElement {
|
|||||||
activeChatHeadUrl=""
|
activeChatHeadUrl=""
|
||||||
.setActiveChatHeadUrl=${(val) => {
|
.setActiveChatHeadUrl=${(val) => {
|
||||||
if (val.address === this.myAddress) return;
|
if (val.address === this.myAddress) return;
|
||||||
console.log({ val });
|
|
||||||
this.selectedHead = val;
|
this.selectedHead = val;
|
||||||
this.setOpenUserInfo(true);
|
this.setOpenUserInfo(true);
|
||||||
this.setUserName({
|
this.setUserName({
|
||||||
@ -286,7 +283,6 @@ class ChatRightPanel extends LitElement {
|
|||||||
activeChatHeadUrl=""
|
activeChatHeadUrl=""
|
||||||
.setActiveChatHeadUrl=${(val) => {
|
.setActiveChatHeadUrl=${(val) => {
|
||||||
if (val.address === this.myAddress) return;
|
if (val.address === this.myAddress) return;
|
||||||
console.log({ val });
|
|
||||||
this.selectedHead = val;
|
this.selectedHead = val;
|
||||||
this.setOpenUserInfo(true);
|
this.setOpenUserInfo(true);
|
||||||
this.setUserName({
|
this.setUserName({
|
||||||
|
@ -101,7 +101,7 @@ function processText(input) {
|
|||||||
// Store the URL in a data attribute
|
// Store the URL in a data attribute
|
||||||
link.setAttribute('data-url', part)
|
link.setAttribute('data-url', part)
|
||||||
link.textContent = part
|
link.textContent = part
|
||||||
link.style.color = 'var(--nav-text-color)'
|
link.style.color = 'var(--code-block-text-color)'
|
||||||
link.style.textDecoration = 'underline'
|
link.style.textDecoration = 'underline'
|
||||||
link.style.cursor = 'pointer'
|
link.style.cursor = 'pointer'
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ function processText(input) {
|
|||||||
url: `qdn/browser/index.html${query}`,
|
url: `qdn/browser/index.html${query}`,
|
||||||
id: uid(),
|
id: uid(),
|
||||||
myPlugObj: {
|
myPlugObj: {
|
||||||
"url": service === 'WEBSITE' ? "websites" : "qapps",
|
"url": "myapp",
|
||||||
"domain": "core",
|
"domain": "core",
|
||||||
"page": `qdn/browser/index.html${query}`,
|
"page": `qdn/browser/index.html${query}`,
|
||||||
"title": name,
|
"title": name,
|
||||||
|
@ -506,21 +506,6 @@ mwc-checkbox::shadow .mdc-checkbox::after, mwc-checkbox::shadow .mdc-checkbox::b
|
|||||||
<button class="emoji-button" ?disabled=${this.isLoading || this.isLoadingMessages}>
|
<button class="emoji-button" ?disabled=${this.isLoading || this.isLoadingMessages}>
|
||||||
${html`<img class="emoji" draggable="false" alt="😀" src="/emoji/svg/1f600.svg" />`}
|
${html`<img class="emoji" draggable="false" alt="😀" src="/emoji/svg/1f600.svg" />`}
|
||||||
</button>
|
</button>
|
||||||
${this.setOpenGifModal ?
|
|
||||||
html`
|
|
||||||
<button
|
|
||||||
class="emoji-button"
|
|
||||||
@click=${()=> {
|
|
||||||
if (!this.userName) {
|
|
||||||
parentEpml.request('showSnackBar', get("gifs.gchange26"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setOpenGifModal(true)
|
|
||||||
}}>
|
|
||||||
<span style="font-size: 30px" class="material-symbols-outlined"></span>
|
|
||||||
</button>
|
|
||||||
`
|
|
||||||
: ''}
|
|
||||||
${this.editedMessageObj ? (
|
${this.editedMessageObj ? (
|
||||||
html`
|
html`
|
||||||
<div style="margin-bottom: 10px">
|
<div style="margin-bottom: 10px">
|
||||||
|
@ -19,6 +19,7 @@ export class TipUser extends LitElement {
|
|||||||
errorMessage: { type: String },
|
errorMessage: { type: String },
|
||||||
successMessage: { type: String },
|
successMessage: { type: String },
|
||||||
setOpenTipUser: { attribute: false },
|
setOpenTipUser: { attribute: false },
|
||||||
|
qortPaymentFee: { type: Number }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,12 +30,14 @@ export class TipUser extends LitElement {
|
|||||||
this.errorMessage = ""
|
this.errorMessage = ""
|
||||||
this.successMessage = ""
|
this.successMessage = ""
|
||||||
this.myAddress = window.parent.reduxStore.getState().app.selectedAddress
|
this.myAddress = window.parent.reduxStore.getState().app.selectedAddress
|
||||||
|
this.qortPaymentFee = 0.01
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = [tipUserStyles]
|
static styles = [tipUserStyles]
|
||||||
|
|
||||||
async firstUpdated() {
|
async firstUpdated() {
|
||||||
await this.fetchWalletDetails()
|
await this.fetchWalletDetails()
|
||||||
|
this.paymentFee()
|
||||||
}
|
}
|
||||||
|
|
||||||
updated(changedProperties) {
|
updated(changedProperties) {
|
||||||
@ -55,6 +58,28 @@ export class TipUser extends LitElement {
|
|||||||
return myRef
|
return myRef
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getSendQortFee() {
|
||||||
|
let sendFee = await parentEpml.request('apiCall', {
|
||||||
|
type: "api",
|
||||||
|
url: `/transactions/unitfee?txType=PAYMENT`
|
||||||
|
})
|
||||||
|
return (Number(sendFee) / 1e8).toFixed(8)
|
||||||
|
}
|
||||||
|
|
||||||
|
async paymentFee() {
|
||||||
|
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=PAYMENT`
|
||||||
|
await fetch(url).then((response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
return response.json()
|
||||||
|
}
|
||||||
|
return Promise.reject(response)
|
||||||
|
}).then((json) => {
|
||||||
|
this.qortPaymentFee = (Number(json) / 1e8).toFixed(8)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
renderSuccessText() {
|
renderSuccessText() {
|
||||||
return html`${translate("chatpage.cchange55")}`
|
return html`${translate("chatpage.cchange55")}`
|
||||||
}
|
}
|
||||||
@ -79,7 +104,7 @@ export class TipUser extends LitElement {
|
|||||||
this.sendMoneyLoading = true
|
this.sendMoneyLoading = true
|
||||||
this.btnDisable = true
|
this.btnDisable = true
|
||||||
|
|
||||||
if (parseFloat(amount) + parseFloat(0.001) > parseFloat(this.walletBalance)) {
|
if (parseFloat(amount) + parseFloat(0.011) > parseFloat(this.walletBalance)) {
|
||||||
this.sendMoneyLoading = false
|
this.sendMoneyLoading = false
|
||||||
this.btnDisable = false
|
this.btnDisable = false
|
||||||
let snack1string = get("chatpage.cchange51")
|
let snack1string = get("chatpage.cchange51")
|
||||||
@ -115,7 +140,7 @@ export class TipUser extends LitElement {
|
|||||||
} else {
|
} else {
|
||||||
myRes = myNameRes
|
myRes = myNameRes
|
||||||
}
|
}
|
||||||
return myRes;
|
return myRes
|
||||||
}
|
}
|
||||||
|
|
||||||
const validateAddress = async (receiverAddress) => {
|
const validateAddress = async (receiverAddress) => {
|
||||||
@ -125,6 +150,7 @@ export class TipUser extends LitElement {
|
|||||||
|
|
||||||
const validateReceiver = async (recipient) => {
|
const validateReceiver = async (recipient) => {
|
||||||
let lastRef = await this.getLastRef()
|
let lastRef = await this.getLastRef()
|
||||||
|
let theFee = await this.getSendQortFee()
|
||||||
let isAddress
|
let isAddress
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -134,7 +160,13 @@ export class TipUser extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isAddress) {
|
if (isAddress) {
|
||||||
let myTransaction = await makeTransactionRequest(recipient, lastRef)
|
let myTransaction = await makeTransactionRequest(recipient, lastRef, theFee)
|
||||||
|
getTxnRequestResponse(myTransaction)
|
||||||
|
} else {
|
||||||
|
let myNameRes = await validateName(recipient)
|
||||||
|
if (myNameRes !== false) {
|
||||||
|
let myNameAddress = myNameRes.owner
|
||||||
|
let myTransaction = await makeTransactionRequest(myNameAddress, lastRef, theFee)
|
||||||
getTxnRequestResponse(myTransaction)
|
getTxnRequestResponse(myTransaction)
|
||||||
} else {
|
} else {
|
||||||
let myNameRes = await validateName(recipient)
|
let myNameRes = await validateName(recipient)
|
||||||
@ -220,6 +252,59 @@ export class TipUser extends LitElement {
|
|||||||
validateReceiver(recipient)
|
validateReceiver(recipient)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const makeTransactionRequest = async (receiver, lastRef, theFee) => {
|
||||||
|
let myReceiver = receiver
|
||||||
|
let mylastRef = lastRef
|
||||||
|
let myFee = theFee
|
||||||
|
let dialogamount = get("transactions.amount")
|
||||||
|
let dialogAddress = get("login.address")
|
||||||
|
let dialogName = get("login.name")
|
||||||
|
let dialogto = get("transactions.to")
|
||||||
|
let recipientName = await getName(myReceiver)
|
||||||
|
let myTxnrequest = await parentEpml.request('transaction', {
|
||||||
|
type: 2,
|
||||||
|
nonce: this.myAddress.nonce,
|
||||||
|
params: {
|
||||||
|
recipient: myReceiver,
|
||||||
|
recipientName: recipientName,
|
||||||
|
amount: amount,
|
||||||
|
lastReference: mylastRef,
|
||||||
|
fee: myFee,
|
||||||
|
dialogamount: dialogamount,
|
||||||
|
dialogto: dialogto,
|
||||||
|
dialogAddress,
|
||||||
|
dialogName
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return myTxnrequest
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTxnRequestResponse = (txnResponse) => {
|
||||||
|
if (txnResponse.success === false && txnResponse.message) {
|
||||||
|
this.errorMessage = txnResponse.message
|
||||||
|
this.sendMoneyLoading = false
|
||||||
|
this.btnDisable = false
|
||||||
|
throw new Error(txnResponse)
|
||||||
|
} else if (txnResponse.success === true && !txnResponse.data.error) {
|
||||||
|
this.shadowRoot.getElementById('amountInput').value = ''
|
||||||
|
this.errorMessage = ''
|
||||||
|
this.successMessage = this.renderSuccessText()
|
||||||
|
this.sendMoneyLoading = false
|
||||||
|
this.btnDisable = false
|
||||||
|
setTimeout(() => {
|
||||||
|
this.setOpenTipUser(false)
|
||||||
|
this.successMessage = ""
|
||||||
|
}, 3000)
|
||||||
|
} else {
|
||||||
|
this.errorMessage = txnResponse.data.message
|
||||||
|
this.sendMoneyLoading = false
|
||||||
|
this.btnDisable = false
|
||||||
|
throw new Error(txnResponse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
validateReceiver(recipient)
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div class="tip-user-header">
|
<div class="tip-user-header">
|
||||||
@ -229,7 +314,7 @@ export class TipUser extends LitElement {
|
|||||||
<div class="tip-user-body">
|
<div class="tip-user-body">
|
||||||
<p class="tip-available">${translate("chatpage.cchange47")}: ${this.walletBalance} QORT</p>
|
<p class="tip-available">${translate("chatpage.cchange47")}: ${this.walletBalance} QORT</p>
|
||||||
<input id="amountInput" class="tip-input" type="number" placeholder="${translate("chatpage.cchange46")}" />
|
<input id="amountInput" class="tip-input" type="number" placeholder="${translate("chatpage.cchange46")}" />
|
||||||
<p class="tip-available">${translate("chatpage.cchange49")}: 0.001 QORT</p>
|
<p class="tip-available">${translate("chatpage.cchange49")}: ${this.qortPaymentFee} QORT</p>
|
||||||
${this.sendMoneyLoading ?
|
${this.sendMoneyLoading ?
|
||||||
html`
|
html`
|
||||||
<paper-progress indeterminate style="width: 100%; margin: 4px;">
|
<paper-progress indeterminate style="width: 100%; margin: 4px;">
|
||||||
|
@ -51,3 +51,12 @@ export const SAVE_FILE = 'SAVE_FILE'
|
|||||||
|
|
||||||
//SET_TAB_NOTIFICATIONS
|
//SET_TAB_NOTIFICATIONS
|
||||||
export const SET_TAB_NOTIFICATIONS = 'SET_TAB_NOTIFICATIONS'
|
export const SET_TAB_NOTIFICATIONS = 'SET_TAB_NOTIFICATIONS'
|
||||||
|
|
||||||
|
//OPEN_NEW_TAB
|
||||||
|
export const OPEN_NEW_TAB = 'OPEN_NEW_TAB'
|
||||||
|
|
||||||
|
//NOTIFICATIONS_PERMISSION
|
||||||
|
export const NOTIFICATIONS_PERMISSION = 'NOTIFICATIONS_PERMISSION'
|
||||||
|
|
||||||
|
//SEND_LOCAL_NOTIFICATION
|
||||||
|
export const SEND_LOCAL_NOTIFICATION = 'SEND_LOCAL_NOTIFICATION'
|
@ -30,7 +30,6 @@ import '@vaadin/grid'
|
|||||||
passiveSupport({ events: ['touchstart'] })
|
passiveSupport({ events: ['touchstart'] })
|
||||||
|
|
||||||
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
|
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
|
||||||
|
|
||||||
class Chat extends LitElement {
|
class Chat extends LitElement {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
|
@ -3,6 +3,7 @@ import { render } from 'lit/html.js'
|
|||||||
import { Epml } from '../../../../epml'
|
import { Epml } from '../../../../epml'
|
||||||
import isElectron from 'is-electron'
|
import isElectron from 'is-electron'
|
||||||
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
|
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
|
||||||
|
import ShortUniqueId from 'short-unique-id';
|
||||||
|
|
||||||
registerTranslateConfig({
|
registerTranslateConfig({
|
||||||
loader: (lang) => fetch(`/language/${lang}.json`).then((res) => res.json())
|
loader: (lang) => fetch(`/language/${lang}.json`).then((res) => res.json())
|
||||||
@ -131,6 +132,7 @@ class WebBrowser extends LitElement {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.url = 'about:blank';
|
this.url = 'about:blank';
|
||||||
|
this.uid = new ShortUniqueId()
|
||||||
this.myAddress = window.parent.reduxStore.getState().app.selectedAddress
|
this.myAddress = window.parent.reduxStore.getState().app.selectedAddress
|
||||||
this._publicKey = { key: '', hasPubKey: false }
|
this._publicKey = { key: '', hasPubKey: false }
|
||||||
const urlParams = new URLSearchParams(window.location.search)
|
const urlParams = new URLSearchParams(window.location.search)
|
||||||
@ -318,6 +320,44 @@ class WebBrowser extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async linkOpenNewTab(link) {
|
||||||
|
|
||||||
|
const value = link
|
||||||
|
let newQuery = value;
|
||||||
|
if (newQuery.endsWith('/')) {
|
||||||
|
newQuery = newQuery.slice(0, -1);
|
||||||
|
}
|
||||||
|
const res = await this.extractComponents(newQuery)
|
||||||
|
if (!res) return
|
||||||
|
const { service, name, identifier, path } = res
|
||||||
|
let query = `?service=${service}`
|
||||||
|
if (name) {
|
||||||
|
query = query + `&name=${name}`
|
||||||
|
}
|
||||||
|
if (identifier) {
|
||||||
|
query = query + `&identifier=${identifier}`
|
||||||
|
}
|
||||||
|
if (path) {
|
||||||
|
query = query + `&path=${path}`
|
||||||
|
}
|
||||||
|
|
||||||
|
window.parent.reduxStore.dispatch(window.parent.reduxAction.setNewTab({
|
||||||
|
url: `qdn/browser/index.html${query}`,
|
||||||
|
id: this.uid(),
|
||||||
|
myPlugObj: {
|
||||||
|
"url": service === 'WEBSITE' ? "websites" : "qapps",
|
||||||
|
"domain": "core",
|
||||||
|
"page": `qdn/browser/index.html${query}`,
|
||||||
|
"title": name,
|
||||||
|
"icon": service === 'WEBSITE' ? 'vaadin:desktop' : 'vaadin:external-browser',
|
||||||
|
"mwcicon": service === 'WEBSITE' ? 'desktop_mac' : 'open_in_browser',
|
||||||
|
"menus": [],
|
||||||
|
"parent": false
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
@ -424,6 +464,23 @@ class WebBrowser extends LitElement {
|
|||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
const joinFee = (Number(data) / 1e8).toFixed(8)
|
const joinFee = (Number(data) / 1e8).toFixed(8)
|
||||||
return joinFee
|
return joinFee
|
||||||
|
}
|
||||||
|
async getArbitraryFee (){
|
||||||
|
const timestamp = Date.now()
|
||||||
|
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=ARBITRARY×tamp=${timestamp}`
|
||||||
|
const response = await fetch(url)
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Error when fetching arbitrary fee');
|
||||||
|
}
|
||||||
|
const data = await response.json()
|
||||||
|
const arbitraryFee = (Number(data) / 1e8).toFixed(8)
|
||||||
|
return {
|
||||||
|
timestamp,
|
||||||
|
fee : Number(data),
|
||||||
|
feeToShow: arbitraryFee
|
||||||
|
}
|
||||||
}
|
}
|
||||||
async sendQortFee() {
|
async sendQortFee() {
|
||||||
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
||||||
@ -492,7 +549,7 @@ class WebBrowser extends LitElement {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _deployAt(name, description, tags, creationBytes, amount, assetId, fee, atType) {
|
async _deployAt(name, description, tags, creationBytes, amount, assetId, atType) {
|
||||||
const deployAtFee = await this.deployAtFee()
|
const deployAtFee = await this.deployAtFee()
|
||||||
const getLastRef = async () => {
|
const getLastRef = async () => {
|
||||||
let myRef = await parentEpml.request('apiCall', {
|
let myRef = await parentEpml.request('apiCall', {
|
||||||
@ -510,13 +567,15 @@ class WebBrowser extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const makeTransactionRequest = async (lastRef) => {
|
const makeTransactionRequest = async (lastRef) => {
|
||||||
let groupdialog1 = get("transactions.groupdialog1")
|
let deployAtdialog1 = get("transactions.deployAtdialog1")
|
||||||
let groupdialog2 = get("transactions.groupdialog2")
|
let deployAtdialog2 = get("transactions.deployAtdialog2")
|
||||||
|
let deployAtdialog3 = get("transactions.deployAtdialog3")
|
||||||
|
let deployAtdialog4 = get("walletpage.wchange12")
|
||||||
let myTxnrequest = await parentEpml.request('transaction', {
|
let myTxnrequest = await parentEpml.request('transaction', {
|
||||||
type: 16,
|
type: 16,
|
||||||
nonce: this.selectedAddress.nonce,
|
nonce: this.selectedAddress.nonce,
|
||||||
params: {
|
params: {
|
||||||
fee: fee || deployAtFee,
|
fee: deployAtFee,
|
||||||
rName: name,
|
rName: name,
|
||||||
rDescription: description,
|
rDescription: description,
|
||||||
rTags: tags,
|
rTags: tags,
|
||||||
@ -525,8 +584,10 @@ class WebBrowser extends LitElement {
|
|||||||
rCreationBytes: creationBytes,
|
rCreationBytes: creationBytes,
|
||||||
atType: atType,
|
atType: atType,
|
||||||
lastReference: lastRef,
|
lastReference: lastRef,
|
||||||
atDeployDialog1: groupdialog1,
|
atDeployDialog1: deployAtdialog1,
|
||||||
atDeployDialog2: groupdialog2
|
atDeployDialog2: deployAtdialog2,
|
||||||
|
atDeployDialog3: deployAtdialog3,
|
||||||
|
atDeployDialog4: deployAtdialog4
|
||||||
},
|
},
|
||||||
apiVersion: 2
|
apiVersion: 2
|
||||||
})
|
})
|
||||||
@ -975,6 +1036,7 @@ class WebBrowser extends LitElement {
|
|||||||
const tag3 = data.tag3;
|
const tag3 = data.tag3;
|
||||||
const tag4 = data.tag4;
|
const tag4 = data.tag4;
|
||||||
const tag5 = data.tag5;
|
const tag5 = data.tag5;
|
||||||
|
let feeAmount = null
|
||||||
if (data.identifier == null) {
|
if (data.identifier == null) {
|
||||||
identifier = 'default';
|
identifier = 'default';
|
||||||
}
|
}
|
||||||
@ -994,6 +1056,8 @@ class WebBrowser extends LitElement {
|
|||||||
if (data.file) {
|
if (data.file) {
|
||||||
data64 = await fileToBase64(data.file)
|
data64 = await fileToBase64(data.file)
|
||||||
}
|
}
|
||||||
|
const getArbitraryFee = await this.getArbitraryFee()
|
||||||
|
feeAmount = getArbitraryFee.fee
|
||||||
|
|
||||||
if (data.encrypt) {
|
if (data.encrypt) {
|
||||||
try {
|
try {
|
||||||
@ -1016,13 +1080,15 @@ class WebBrowser extends LitElement {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const res2 = await showModalAndWait(
|
const res2 = await showModalAndWait(
|
||||||
actions.PUBLISH_QDN_RESOURCE,
|
actions.PUBLISH_QDN_RESOURCE,
|
||||||
{
|
{
|
||||||
name,
|
name,
|
||||||
identifier,
|
identifier,
|
||||||
service,
|
service,
|
||||||
encrypt: data.encrypt
|
encrypt: data.encrypt,
|
||||||
|
feeAmount: getArbitraryFee.feeToShow
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
if (res2.action === 'accept') {
|
if (res2.action === 'accept') {
|
||||||
@ -1052,7 +1118,8 @@ class WebBrowser extends LitElement {
|
|||||||
tag4,
|
tag4,
|
||||||
tag5,
|
tag5,
|
||||||
apiVersion: 2,
|
apiVersion: 2,
|
||||||
withFee: res2.userData.isWithFee === true ? true : false
|
withFee: res2.userData.isWithFee === true ? true : false,
|
||||||
|
feeAmount: feeAmount
|
||||||
});
|
});
|
||||||
|
|
||||||
response = JSON.stringify(resPublish);
|
response = JSON.stringify(resPublish);
|
||||||
@ -1080,7 +1147,7 @@ class WebBrowser extends LitElement {
|
|||||||
case actions.PUBLISH_MULTIPLE_QDN_RESOURCES: {
|
case actions.PUBLISH_MULTIPLE_QDN_RESOURCES: {
|
||||||
const requiredFields = ['resources'];
|
const requiredFields = ['resources'];
|
||||||
const missingFields = [];
|
const missingFields = [];
|
||||||
|
let feeAmount = null
|
||||||
requiredFields.forEach((field) => {
|
requiredFields.forEach((field) => {
|
||||||
if (!data[field]) {
|
if (!data[field]) {
|
||||||
missingFields.push(field);
|
missingFields.push(field);
|
||||||
@ -1114,11 +1181,14 @@ class WebBrowser extends LitElement {
|
|||||||
response = JSON.stringify(data);
|
response = JSON.stringify(data);
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
const getArbitraryFee = await this.getArbitraryFee()
|
||||||
|
feeAmount = getArbitraryFee.fee
|
||||||
const res2 = await showModalAndWait(
|
const res2 = await showModalAndWait(
|
||||||
actions.PUBLISH_MULTIPLE_QDN_RESOURCES,
|
actions.PUBLISH_MULTIPLE_QDN_RESOURCES,
|
||||||
{
|
{
|
||||||
resources,
|
resources,
|
||||||
encrypt: data.encrypt
|
encrypt: data.encrypt,
|
||||||
|
feeAmount: getArbitraryFee.feeToShow
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1217,7 +1287,8 @@ class WebBrowser extends LitElement {
|
|||||||
tag4,
|
tag4,
|
||||||
tag5,
|
tag5,
|
||||||
apiVersion: 2,
|
apiVersion: 2,
|
||||||
withFee: res2.userData.isWithFee === true ? true : false
|
withFee: res2.userData.isWithFee === true ? true : false,
|
||||||
|
feeAmount: feeAmount
|
||||||
});
|
});
|
||||||
|
|
||||||
worker.terminate();
|
worker.terminate();
|
||||||
@ -1253,8 +1324,95 @@ class WebBrowser extends LitElement {
|
|||||||
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
|
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case actions.OPEN_NEW_TAB: {
|
||||||
|
if(!data.qortalLink){
|
||||||
|
const obj = {};
|
||||||
|
const errorMsg = 'Please enter a qortal link - qortal://...';
|
||||||
|
obj['error'] = errorMsg;
|
||||||
|
response = JSON.stringify(obj);
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.linkOpenNewTab(data.qortalLink)
|
||||||
|
response = true
|
||||||
|
break;
|
||||||
|
} catch (error) {
|
||||||
|
console.log('error', error)
|
||||||
|
const obj = {};
|
||||||
|
const errorMsg = "Invalid qortal link";
|
||||||
|
obj['error'] = errorMsg;
|
||||||
|
response = JSON.stringify(obj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
case actions.NOTIFICATIONS_PERMISSION: {
|
||||||
|
try {
|
||||||
|
|
||||||
|
const res = await showModalAndWait(
|
||||||
|
actions.NOTIFICATIONS_PERMISSION,
|
||||||
|
{
|
||||||
|
name: this.name
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.action === 'accept'){
|
||||||
|
this.addAppToNotificationList(this.name)
|
||||||
|
response = true
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
response = false
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
case actions.SEND_LOCAL_NOTIFICATION: {
|
||||||
|
const {title, url, icon, message} = data
|
||||||
|
try {
|
||||||
|
const id = `appNotificationList-${this.selectedAddress.address}`
|
||||||
|
const checkData = localStorage.getItem(id) ? JSON.parse(localStorage.getItem(id)) : null;
|
||||||
|
if(!checkData || !checkData[this.name]) throw new Error('App not on permission list')
|
||||||
|
const appInfo = checkData[this.name]
|
||||||
|
const lastNotification = appInfo.lastNotification
|
||||||
|
const interval = appInfo.interval
|
||||||
|
if (lastNotification && interval) {
|
||||||
|
const timeDifference = Date.now() - lastNotification;
|
||||||
|
|
||||||
|
if (timeDifference > interval) {
|
||||||
|
parentEpml.request('showNotification', {
|
||||||
|
title, type: "qapp-local-notification", sound: '', url, options: { body: message, icon, badge: icon }
|
||||||
|
})
|
||||||
|
response = true
|
||||||
|
this.updateLastNotification(id, this.name)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
throw new Error(`duration until another notification can be sent: ${interval - timeDifference}`)
|
||||||
|
}
|
||||||
|
} else if(!lastNotification){
|
||||||
|
parentEpml.request('showNotification', {
|
||||||
|
title, type: "qapp-local-notification", sound: '', url, options: { body: message, icon, badge: icon }
|
||||||
|
})
|
||||||
|
response = true
|
||||||
|
this.updateLastNotification(id)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
throw new Error(`invalid data`)
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
const obj = {};
|
||||||
|
const errorMsg = error.message || "error in pushing notification";
|
||||||
|
obj['error'] = errorMsg;
|
||||||
|
response = JSON.stringify(obj);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
case actions.SEND_CHAT_MESSAGE: {
|
case actions.SEND_CHAT_MESSAGE: {
|
||||||
const message = data.message;
|
const message = data.message;
|
||||||
const recipient = data.destinationAddress;
|
const recipient = data.destinationAddress;
|
||||||
@ -1618,41 +1776,41 @@ class WebBrowser extends LitElement {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// case 'DEPLOY_AT': {
|
case 'DEPLOY_AT': {
|
||||||
// const requiredFields = ['name', 'description', 'tags', 'creationBytes', 'amount', 'assetId', 'type'];
|
const requiredFields = ['name', 'description', 'tags', 'creationBytes', 'amount', 'assetId', 'type'];
|
||||||
// const missingFields = [];
|
const missingFields = [];
|
||||||
|
|
||||||
// requiredFields.forEach((field) => {
|
requiredFields.forEach((field) => {
|
||||||
// if (!data[field]) {
|
if (!data[field] && data[field] !== 0) {
|
||||||
// missingFields.push(field);
|
missingFields.push(field);
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
|
|
||||||
// if (missingFields.length > 0) {
|
if (missingFields.length > 0) {
|
||||||
// const missingFieldsString = missingFields.join(', ');
|
const missingFieldsString = missingFields.join(', ');
|
||||||
// const errorMsg = `Missing fields: ${missingFieldsString}`
|
const errorMsg = `Missing fields: ${missingFieldsString}`
|
||||||
// let data = {};
|
let data = {};
|
||||||
// data['error'] = errorMsg;
|
data['error'] = errorMsg;
|
||||||
// response = JSON.stringify(data);
|
response = JSON.stringify(data);
|
||||||
// break
|
break
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
|
||||||
// try {
|
try {
|
||||||
// this.loader.show();
|
this.loader.show();
|
||||||
// const fee = data.fee || undefined
|
|
||||||
// const resJoinGroup = await this._deployAt(data.name, data.description, data.tags, data.creationBytes, data.amount, data.assetId, fee, data.type)
|
const resDeployAt = await this._deployAt(data.name, data.description, data.tags, data.creationBytes, data.amount, data.assetId, data.type)
|
||||||
// response = JSON.stringify(resJoinGroup);
|
response = JSON.stringify(resDeployAt);
|
||||||
// } catch (error) {
|
} catch (error) {
|
||||||
// const obj = {};
|
const obj = {};
|
||||||
// const errorMsg = error.message || 'Failed to join the group.';
|
const errorMsg = error.message || 'Failed to join the group.';
|
||||||
// obj['error'] = errorMsg;
|
obj['error'] = errorMsg;
|
||||||
// response = JSON.stringify(obj);
|
response = JSON.stringify(obj);
|
||||||
// } finally {
|
} finally {
|
||||||
// this.loader.hide();
|
this.loader.hide();
|
||||||
// }
|
}
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
|
||||||
case actions.GET_WALLET_BALANCE: {
|
case actions.GET_WALLET_BALANCE: {
|
||||||
@ -2707,6 +2865,46 @@ class WebBrowser extends LitElement {
|
|||||||
use(checkLanguage);
|
use(checkLanguage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addAppToNotificationList(appName) {
|
||||||
|
if(!appName) throw new Error('unknown app name')
|
||||||
|
const id = `appNotificationList-${this.selectedAddress.address}`;
|
||||||
|
const checkData = localStorage.getItem(id) ? JSON.parse(localStorage.getItem(id)) : null;
|
||||||
|
|
||||||
|
if (!checkData) {
|
||||||
|
const newData = {
|
||||||
|
[appName]: {
|
||||||
|
interval: 900000, // 15mins in milliseconds
|
||||||
|
lastNotification: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
localStorage.setItem(id, JSON.stringify(newData));
|
||||||
|
} else {
|
||||||
|
const copyData = { ...checkData };
|
||||||
|
copyData[appName] = {
|
||||||
|
interval: 900000, // 15mins in milliseconds
|
||||||
|
lastNotification: null,
|
||||||
|
};
|
||||||
|
localStorage.setItem(id, JSON.stringify(copyData));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateLastNotification(id, appName) {
|
||||||
|
const checkData = localStorage.getItem(id) ? JSON.parse(localStorage.getItem(id)) : null;
|
||||||
|
|
||||||
|
if (checkData) {
|
||||||
|
const copyData = { ...checkData };
|
||||||
|
if (copyData[appName]) {
|
||||||
|
copyData[appName].lastNotification = Date.now(); // Make sure to use Date.now(), not date.now()
|
||||||
|
} else {
|
||||||
|
copyData[appName] = {
|
||||||
|
interval: 900000, // 15mins in milliseconds
|
||||||
|
lastNotification: Date.now(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
localStorage.setItem(id, JSON.stringify(copyData));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
renderFollowUnfollowButton() {
|
renderFollowUnfollowButton() {
|
||||||
// Only show the follow/unfollow button if we have permission to modify the list on this node
|
// Only show the follow/unfollow button if we have permission to modify the list on this node
|
||||||
@ -3000,10 +3198,7 @@ async function showModalAndWait(type, data) {
|
|||||||
`).join('')}
|
`).join('')}
|
||||||
</table>
|
</table>
|
||||||
<div class="checkbox-row">
|
<div class="checkbox-row">
|
||||||
<label for="isWithFee" id="isWithFeeLabel" style="color: var(--black);">
|
<p style="font-size: 16px;overflow-wrap: anywhere;" class="modal-paragraph">${get('browserpage.bchange47')} <span style="font-weight: bold">${data.resources.length * data.feeAmount} QORT fee</span></p>
|
||||||
${get('browserpage.bchange33')} ${data.resources.length * 0.001} QORT fee
|
|
||||||
</label>
|
|
||||||
<mwc-checkbox checked style="margin-right: -15px;" id="isWithFee"></mwc-checkbox>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
` : ''}
|
` : ''}
|
||||||
@ -3016,10 +3211,7 @@ async function showModalAndWait(type, data) {
|
|||||||
<p style="font-size: 16px;overflow-wrap: anywhere;" class="modal-paragraph"><span style="font-weight: bold">${get("browserpage.bchange32")}:</span> ${data.identifier}</p>
|
<p style="font-size: 16px;overflow-wrap: anywhere;" class="modal-paragraph"><span style="font-weight: bold">${get("browserpage.bchange32")}:</span> ${data.identifier}</p>
|
||||||
<p style="font-size: 16px;overflow-wrap: anywhere;" class="modal-paragraph"><span style="font-weight: bold">${get("browserpage.bchange45")}:</span> ${data.encrypt ? true : false}</p>
|
<p style="font-size: 16px;overflow-wrap: anywhere;" class="modal-paragraph"><span style="font-weight: bold">${get("browserpage.bchange45")}:</span> ${data.encrypt ? true : false}</p>
|
||||||
<div class="checkbox-row">
|
<div class="checkbox-row">
|
||||||
<label for="isWithFee" id="isWithFeeLabel" style="color: var(--black);">
|
<p style="font-size: 16px;overflow-wrap: anywhere;" class="modal-paragraph">${get('browserpage.bchange47')} <span style="font-weight: bold">${data.feeAmount} QORT fee</span></p>
|
||||||
${get('browserpage.bchange29')}
|
|
||||||
</label>
|
|
||||||
<mwc-checkbox checked style="margin-right: -15px;" id="isWithFee"></mwc-checkbox>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
` : ''}
|
` : ''}
|
||||||
@ -3064,6 +3256,11 @@ async function showModalAndWait(type, data) {
|
|||||||
<p class="modal-paragraph">${get("browserpage.bchange46")}: <span> ${data.filename}</span></p>
|
<p class="modal-paragraph">${get("browserpage.bchange46")}: <span> ${data.filename}</span></p>
|
||||||
</div>
|
</div>
|
||||||
` : ''}
|
` : ''}
|
||||||
|
${type === actions.NOTIFICATIONS_PERMISSION ? `
|
||||||
|
<div class="modal-subcontainer">
|
||||||
|
<p class="modal-paragraph">${get("browserpage.bchange48")}</p>
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
|
||||||
${type === actions.DELETE_LIST_ITEM ? `
|
${type === actions.DELETE_LIST_ITEM ? `
|
||||||
<div class="modal-subcontainer">
|
<div class="modal-subcontainer">
|
||||||
@ -3091,7 +3288,8 @@ async function showModalAndWait(type, data) {
|
|||||||
const userData = {};
|
const userData = {};
|
||||||
if (type === actions.PUBLISH_QDN_RESOURCE || type === actions.PUBLISH_MULTIPLE_QDN_RESOURCES) {
|
if (type === actions.PUBLISH_QDN_RESOURCE || type === actions.PUBLISH_MULTIPLE_QDN_RESOURCES) {
|
||||||
const isWithFeeCheckbox = modal.querySelector('#isWithFee');
|
const isWithFeeCheckbox = modal.querySelector('#isWithFee');
|
||||||
userData.isWithFee = isWithFeeCheckbox.checked;
|
// userData.isWithFee = isWithFeeCheckbox.checked;
|
||||||
|
userData.isWithFee = true
|
||||||
}
|
}
|
||||||
if (modal.parentNode === document.body) {
|
if (modal.parentNode === document.body) {
|
||||||
document.body.removeChild(modal);
|
document.body.removeChild(modal);
|
||||||
|
@ -14,6 +14,7 @@ import '@material/mwc-select'
|
|||||||
import '@material/mwc-dialog'
|
import '@material/mwc-dialog'
|
||||||
import '@material/mwc-list/mwc-list-item.js'
|
import '@material/mwc-list/mwc-list-item.js'
|
||||||
import '@polymer/paper-progress/paper-progress.js'
|
import '@polymer/paper-progress/paper-progress.js'
|
||||||
|
import { modalHelper } from '../../../utils/publish-modal'
|
||||||
|
|
||||||
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
|
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
|
||||||
|
|
||||||
@ -299,8 +300,10 @@ class PublishData extends LitElement {
|
|||||||
<p style="color: green; word-break: break-word;">${this.successMessage}</p>
|
<p style="color: green; word-break: break-word;">${this.successMessage}</p>
|
||||||
${this.loading ? html` <paper-progress indeterminate style="width:100%; margin:4px;"></paper-progress> ` : ''}
|
${this.loading ? html` <paper-progress indeterminate style="width:100%; margin:4px;"></paper-progress> ` : ''}
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<mwc-button ?disabled=${this.btnDisable} style="width:49%;" raised icon="science" @click=${(e) => this.doPublish(e, true, false)}> ${translate("appspage.schange40")}</mwc-button>
|
<mwc-button ?disabled=${this.btnDisable} style="width:49%;" raised icon="science" @click=${(e) => this.shadowRoot.querySelector('#publishWithFeeDialog').close()}> ${translate("appspage.schange40")}</mwc-button>
|
||||||
<mwc-button ?disabled=${this.btnDisable} style="width:49%;" raised icon="send" @click=${() => this.shadowRoot.querySelector('#publishWithFeeDialog').show()}> ${translate("publishpage.pchange11")}</mwc-button>
|
<mwc-button ?disabled=${this.btnDisable} style="width:49%;" raised icon="send" @click=${(e) => {
|
||||||
|
this.doPublish(e, false, true)
|
||||||
|
}}> ${translate("publishpage.pchange11")}</mwc-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -418,7 +421,7 @@ class PublishData extends LitElement {
|
|||||||
this.shadowRoot.querySelector('#publishWithFeeDialog').close()
|
this.shadowRoot.querySelector('#publishWithFeeDialog').close()
|
||||||
}
|
}
|
||||||
|
|
||||||
doPublish(e, preview, fee) {
|
async doPublish(e, preview, fee) {
|
||||||
let registeredName = this.shadowRoot.getElementById('registeredName').value
|
let registeredName = this.shadowRoot.getElementById('registeredName').value
|
||||||
let service = this.shadowRoot.getElementById('service').value
|
let service = this.shadowRoot.getElementById('service').value
|
||||||
let identifier = this.shadowRoot.getElementById('identifier').value
|
let identifier = this.shadowRoot.getElementById('identifier').value
|
||||||
@ -464,7 +467,22 @@ class PublishData extends LitElement {
|
|||||||
parentEpml.request('showSnackBar', `${err5string}`)
|
parentEpml.request('showSnackBar', `${err5string}`)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
try {
|
||||||
|
if(!preview){
|
||||||
|
const arbitraryFeeData = await modalHelper.getArbitraryFee()
|
||||||
|
const res = await modalHelper.showModalAndWaitPublish(
|
||||||
|
{
|
||||||
|
feeAmount: arbitraryFeeData.feeToShow
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.action !== 'accept') throw new Error('User declined publish')
|
||||||
|
}
|
||||||
|
|
||||||
this.publishData(registeredName, path, file, service, identifier, preview, fee)
|
this.publishData(registeredName, path, file, service, identifier, preview, fee)
|
||||||
|
} catch (error) {
|
||||||
|
this.shadowRoot.querySelector('#publishWithFeeDialog').close()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,6 +506,17 @@ class PublishData extends LitElement {
|
|||||||
this.successMessage = ''
|
this.successMessage = ''
|
||||||
console.error(errorMessage)
|
console.error(errorMessage)
|
||||||
}
|
}
|
||||||
|
const getArbitraryFee = async () => {
|
||||||
|
const timestamp = Date.now()
|
||||||
|
let fee = await parentEpml.request('apiCall', {
|
||||||
|
url: `/transactions/unitfee?txType=ARBITRARY×tamp=${timestamp}`
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
timestamp,
|
||||||
|
fee : Number(fee),
|
||||||
|
feeToShow: (Number(fee) / 1e8).toFixed(8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const validate = async () => {
|
const validate = async () => {
|
||||||
let validNameRes = await validateName(registeredName)
|
let validNameRes = await validateName(registeredName)
|
||||||
@ -501,8 +530,17 @@ class PublishData extends LitElement {
|
|||||||
this.generalMessage = `${err6string}`
|
this.generalMessage = `${err6string}`
|
||||||
let transactionBytes
|
let transactionBytes
|
||||||
let previewUrlPath
|
let previewUrlPath
|
||||||
|
let feeAmount = null
|
||||||
|
|
||||||
let uploadDataRes = await uploadData(registeredName, path, file, preview, fee)
|
if(fee){
|
||||||
|
const res = await getArbitraryFee()
|
||||||
|
if(res.fee){
|
||||||
|
feeAmount= res.fee
|
||||||
|
} else {
|
||||||
|
throw new Error('unable to get fee')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let uploadDataRes = await uploadData(registeredName, path, file, preview, fee, feeAmount)
|
||||||
|
|
||||||
if (uploadDataRes.error) {
|
if (uploadDataRes.error) {
|
||||||
let err7string = get("publishpage.pchange20")
|
let err7string = get("publishpage.pchange20")
|
||||||
@ -531,12 +569,13 @@ class PublishData extends LitElement {
|
|||||||
if (fee) {
|
if (fee) {
|
||||||
let err9string = get("publishpage.pchange26")
|
let err9string = get("publishpage.pchange26")
|
||||||
this.generalMessage = `${err9string}`
|
this.generalMessage = `${err9string}`
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
let err9string = get("publishpage.pchange22")
|
let err9string = get("publishpage.pchange22")
|
||||||
this.generalMessage = `${err9string}`
|
this.generalMessage = `${err9string}`
|
||||||
}
|
}
|
||||||
|
|
||||||
let signAndProcessRes = await signAndProcess(transactionBytes, fee)
|
let signAndProcessRes = await signAndProcess(transactionBytes, fee, feeAmount)
|
||||||
|
|
||||||
if (signAndProcessRes.error) {
|
if (signAndProcessRes.error) {
|
||||||
let err10string = get("publishpage.pchange20")
|
let err10string = get("publishpage.pchange20")
|
||||||
@ -554,7 +593,9 @@ class PublishData extends LitElement {
|
|||||||
this.successMessage = `${err11string}`
|
this.successMessage = `${err11string}`
|
||||||
}
|
}
|
||||||
|
|
||||||
const uploadData = async (registeredName, path, file, preview, fee) => {
|
|
||||||
|
|
||||||
|
const uploadData = async (registeredName, path, file, preview, fee, feeAmount) => {
|
||||||
let postBody = path
|
let postBody = path
|
||||||
let urlSuffix = ""
|
let urlSuffix = ""
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
@ -592,9 +633,9 @@ class PublishData extends LitElement {
|
|||||||
uploadDataUrl = `/arbitrary/${service}/${registeredName}/${this.identifier}${urlSuffix}?${metadataQueryString}&apiKey=${this.getApiKey()}&preview=${new Boolean(preview).toString()}`
|
uploadDataUrl = `/arbitrary/${service}/${registeredName}/${this.identifier}${urlSuffix}?${metadataQueryString}&apiKey=${this.getApiKey()}&preview=${new Boolean(preview).toString()}`
|
||||||
}
|
}
|
||||||
} else if (fee) {
|
} else if (fee) {
|
||||||
uploadDataUrl = `/arbitrary/${this.service}/${registeredName}${urlSuffix}?${metadataQueryString}&fee=100000&apiKey=${this.getApiKey()}`
|
uploadDataUrl = `/arbitrary/${this.service}/${registeredName}${urlSuffix}?${metadataQueryString}&fee=${feeAmount}&apiKey=${this.getApiKey()}`
|
||||||
if (identifier != null && identifier.trim().length > 0) {
|
if (identifier != null && identifier.trim().length > 0) {
|
||||||
uploadDataUrl = `/arbitrary/${service}/${registeredName}/${this.identifier}${urlSuffix}?${metadataQueryString}&fee=100000&apiKey=${this.getApiKey()}`
|
uploadDataUrl = `/arbitrary/${service}/${registeredName}/${this.identifier}${urlSuffix}?${metadataQueryString}&fee=${feeAmount}&apiKey=${this.getApiKey()}`
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uploadDataUrl = `/arbitrary/${this.service}/${registeredName}${urlSuffix}?${metadataQueryString}&apiKey=${this.getApiKey()}`
|
uploadDataUrl = `/arbitrary/${this.service}/${registeredName}${urlSuffix}?${metadataQueryString}&apiKey=${this.getApiKey()}`
|
||||||
|
@ -2104,6 +2104,7 @@ class TradeBotPortal extends LitElement {
|
|||||||
|
|
||||||
this.changeTheme()
|
this.changeTheme()
|
||||||
this.changeLanguage()
|
this.changeLanguage()
|
||||||
|
this.tradeFee()
|
||||||
|
|
||||||
this.autoHelperMessage = this.renderAutoHelperPass()
|
this.autoHelperMessage = this.renderAutoHelperPass()
|
||||||
|
|
||||||
@ -3736,6 +3737,20 @@ class TradeBotPortal extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async tradeFee() {
|
||||||
|
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=DEPLOY_AT`
|
||||||
|
await fetch(url).then((response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
return response.json()
|
||||||
|
}
|
||||||
|
return Promise.reject(response)
|
||||||
|
}).then((json) => {
|
||||||
|
this.listedCoins.get("QORTAL").tradeFee = (Number(json) + 100000) / 1e8
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
getApiKey() {
|
getApiKey() {
|
||||||
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node];
|
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node];
|
||||||
let apiKey = myNode.apiKey;
|
let apiKey = myNode.apiKey;
|
||||||
|
@ -708,7 +708,7 @@ class TradePortal extends LitElement {
|
|||||||
balance: "0",
|
balance: "0",
|
||||||
coinCode: "QORT",
|
coinCode: "QORT",
|
||||||
coinAmount: this.amountString,
|
coinAmount: this.amountString,
|
||||||
tradeFee: "0.002"
|
tradeFee: "0.02"
|
||||||
}
|
}
|
||||||
|
|
||||||
let bitcoin = {
|
let bitcoin = {
|
||||||
@ -1421,6 +1421,7 @@ class TradePortal extends LitElement {
|
|||||||
|
|
||||||
this.changeTheme()
|
this.changeTheme()
|
||||||
this.changeLanguage()
|
this.changeLanguage()
|
||||||
|
this.tradeFee()
|
||||||
|
|
||||||
this.tradeHelperMessage = this.renderTradeHelperPass()
|
this.tradeHelperMessage = this.renderTradeHelperPass()
|
||||||
|
|
||||||
@ -2698,6 +2699,7 @@ class TradePortal extends LitElement {
|
|||||||
async sellAction() {
|
async sellAction() {
|
||||||
this.isSellLoading = true
|
this.isSellLoading = true
|
||||||
this.sellBtnDisable = true
|
this.sellBtnDisable = true
|
||||||
|
await this.tradeFee()
|
||||||
const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value
|
const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value
|
||||||
const sellTotalInput = this.shadowRoot.getElementById('sellTotalInput').value
|
const sellTotalInput = this.shadowRoot.getElementById('sellTotalInput').value
|
||||||
const fundingQortAmount = this.round(parseFloat(sellAmountInput) + 0.001)
|
const fundingQortAmount = this.round(parseFloat(sellAmountInput) + 0.001)
|
||||||
@ -2732,7 +2734,7 @@ class TradePortal extends LitElement {
|
|||||||
fundingQortAmount: parseFloat(fundingQortAmount),
|
fundingQortAmount: parseFloat(fundingQortAmount),
|
||||||
foreignBlockchain: this.selectedCoin,
|
foreignBlockchain: this.selectedCoin,
|
||||||
foreignAmount: parseFloat(sellTotalInput),
|
foreignAmount: parseFloat(sellTotalInput),
|
||||||
tradeTimeout: 60,
|
tradeTimeout: 120,
|
||||||
receivingAddress: _receivingAddress,
|
receivingAddress: _receivingAddress,
|
||||||
})
|
})
|
||||||
return response
|
return response
|
||||||
@ -2758,7 +2760,7 @@ class TradePortal extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.round(parseFloat(fundingQortAmount) + parseFloat(0.002)) > parseFloat(this.listedCoins.get("QORTAL").balance)) {
|
if (this.round(parseFloat(fundingQortAmount) + parseFloat(this.listedCoins.get("QORTAL").tradeFee)) > parseFloat(this.listedCoins.get("QORTAL").balance)) {
|
||||||
this.isSellLoading = false
|
this.isSellLoading = false
|
||||||
this.sellBtnDisable = false
|
this.sellBtnDisable = false
|
||||||
let snack4string = get("tradepage.tchange22")
|
let snack4string = get("tradepage.tchange22")
|
||||||
@ -3021,6 +3023,21 @@ class TradePortal extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async tradeFee() {
|
||||||
|
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=DEPLOY_AT`
|
||||||
|
await fetch(url).then((response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
return response.json()
|
||||||
|
}
|
||||||
|
return Promise.reject(response)
|
||||||
|
}).then((json) => {
|
||||||
|
this.listedCoins.get("QORTAL").tradeFee = (Number(json) * 2) / 1e8
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
getApiKey() {
|
getApiKey() {
|
||||||
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node];
|
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node];
|
||||||
let apiKey = myNode.apiKey;
|
let apiKey = myNode.apiKey;
|
||||||
|
@ -75,6 +75,7 @@ class MultiWallet extends LitElement {
|
|||||||
isValidAmount: { type: Boolean },
|
isValidAmount: { type: Boolean },
|
||||||
balance: { type: Number },
|
balance: { type: Number },
|
||||||
balanceString: { type: String },
|
balanceString: { type: String },
|
||||||
|
qortPaymentFee: { type: Number },
|
||||||
btcFeePerByte: { type: Number },
|
btcFeePerByte: { type: Number },
|
||||||
ltcFeePerByte: { type: Number },
|
ltcFeePerByte: { type: Number },
|
||||||
dogeFeePerByte: { type: Number },
|
dogeFeePerByte: { type: Number },
|
||||||
@ -795,6 +796,7 @@ class MultiWallet extends LitElement {
|
|||||||
this.dgbAmount = 0
|
this.dgbAmount = 0
|
||||||
this.rvnAmount = 0
|
this.rvnAmount = 0
|
||||||
this.arrrAmount = 0
|
this.arrrAmount = 0
|
||||||
|
this.qortPaymentFee = 0.001
|
||||||
this.btcFeePerByte = 100
|
this.btcFeePerByte = 100
|
||||||
this.btcSatMinFee = 20
|
this.btcSatMinFee = 20
|
||||||
this.btcSatMaxFee = 150
|
this.btcSatMaxFee = 150
|
||||||
@ -1352,7 +1354,7 @@ class MultiWallet extends LitElement {
|
|||||||
</mwc-textfield>
|
</mwc-textfield>
|
||||||
</p>
|
</p>
|
||||||
<div style="margin-bottom: 10px;">
|
<div style="margin-bottom: 10px;">
|
||||||
<p style="margin-bottom: 0;">${translate("walletpage.wchange21")} <span style="font-weight: bold;">0.001 QORT<span></p>
|
<p style="margin-bottom: 0;">${translate("walletpage.wchange21")} <span style="font-weight: bold;">${this.qortPaymentFee} QORT<span></p>
|
||||||
</div>
|
</div>
|
||||||
${this.renderClearSuccess()}
|
${this.renderClearSuccess()}
|
||||||
${this.renderClearError()}
|
${this.renderClearError()}
|
||||||
@ -2821,6 +2823,7 @@ class MultiWallet extends LitElement {
|
|||||||
firstUpdated() {
|
firstUpdated() {
|
||||||
this.changeTheme()
|
this.changeTheme()
|
||||||
this.changeLanguage()
|
this.changeLanguage()
|
||||||
|
this.paymentFee()
|
||||||
|
|
||||||
this.bookQortalAddress = window.parent.reduxStore.getState().app.selectedAddress.address
|
this.bookQortalAddress = window.parent.reduxStore.getState().app.selectedAddress.address
|
||||||
this.bookBitcoinAddress = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address
|
this.bookBitcoinAddress = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address
|
||||||
@ -2906,6 +2909,23 @@ class MultiWallet extends LitElement {
|
|||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
this.clearConsole()
|
this.clearConsole()
|
||||||
}, 60000)
|
}, 60000)
|
||||||
|
setInterval(() => {
|
||||||
|
this.paymentFee()
|
||||||
|
}, 600000)
|
||||||
|
}
|
||||||
|
|
||||||
|
async paymentFee() {
|
||||||
|
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=PAYMENT`
|
||||||
|
await fetch(url).then((response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
return response.json()
|
||||||
|
}
|
||||||
|
return Promise.reject(response)
|
||||||
|
}).then((json) => {
|
||||||
|
this.qortPaymentFee = (Number(json) / 1e8).toFixed(8)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
clearConsole() {
|
clearConsole() {
|
||||||
@ -4048,11 +4068,11 @@ class MultiWallet extends LitElement {
|
|||||||
calculateQortAll() {
|
calculateQortAll() {
|
||||||
this.amount = 0
|
this.amount = 0
|
||||||
this.shadowRoot.getElementById('amountInput').value = this.amount
|
this.shadowRoot.getElementById('amountInput').value = this.amount
|
||||||
if (this.balance < 0.00110000) {
|
if (this.balance < 0.01100000) {
|
||||||
let not_enough_string = get("walletpage.wchange26")
|
let not_enough_string = get("walletpage.wchange26")
|
||||||
parentEpml.request('showSnackBar', `${not_enough_string}`)
|
parentEpml.request('showSnackBar', `${not_enough_string}`)
|
||||||
} else {
|
} else {
|
||||||
this.amount = (this.balance - 0.00110000).toFixed(8)
|
this.amount = (this.balance - 0.01100000).toFixed(8)
|
||||||
this.shadowRoot.getElementById('amountInput').value = this.amount
|
this.shadowRoot.getElementById('amountInput').value = this.amount
|
||||||
this.shadowRoot.getElementById('amountInput').blur()
|
this.shadowRoot.getElementById('amountInput').blur()
|
||||||
this.shadowRoot.getElementById('amountInput').focus()
|
this.shadowRoot.getElementById('amountInput').focus()
|
||||||
@ -4238,7 +4258,7 @@ class MultiWallet extends LitElement {
|
|||||||
} else {
|
} else {
|
||||||
const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value
|
const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value
|
||||||
const checkQortAmount = this.round(parseFloat(checkQortAmountInput))
|
const checkQortAmount = this.round(parseFloat(checkQortAmountInput))
|
||||||
const myFunds = this.round(parseFloat(this.balance - 0.00110000))
|
const myFunds = this.round(parseFloat(this.balance - 0.01100000))
|
||||||
if (Number(myFunds) >= Number(checkQortAmount)) {
|
if (Number(myFunds) >= Number(checkQortAmount)) {
|
||||||
this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput
|
this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput
|
||||||
this.btnDisable = false
|
this.btnDisable = false
|
||||||
@ -4269,7 +4289,7 @@ class MultiWallet extends LitElement {
|
|||||||
} else {
|
} else {
|
||||||
const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value
|
const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value
|
||||||
const checkQortAmount = this.round(parseFloat(checkQortAmountInput))
|
const checkQortAmount = this.round(parseFloat(checkQortAmountInput))
|
||||||
const myFunds = this.round(parseFloat(this.balance - 0.00110000))
|
const myFunds = this.round(parseFloat(this.balance - 0.01100000))
|
||||||
if (Number(myFunds) >= Number(checkQortAmount)) {
|
if (Number(myFunds) >= Number(checkQortAmount)) {
|
||||||
this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput
|
this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput
|
||||||
this.btnDisable = false
|
this.btnDisable = false
|
||||||
@ -4287,7 +4307,7 @@ class MultiWallet extends LitElement {
|
|||||||
} else {
|
} else {
|
||||||
const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value
|
const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value
|
||||||
const checkQortAmount = this.round(parseFloat(checkQortAmountInput))
|
const checkQortAmount = this.round(parseFloat(checkQortAmountInput))
|
||||||
const myFunds = this.round(parseFloat(this.balance - 0.00110000))
|
const myFunds = this.round(parseFloat(this.balance - 0.01100000))
|
||||||
if (Number(myFunds) >= Number(checkQortAmount)) {
|
if (Number(myFunds) >= Number(checkQortAmount)) {
|
||||||
this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput
|
this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput
|
||||||
this.btnDisable = false
|
this.btnDisable = false
|
||||||
@ -4302,6 +4322,7 @@ class MultiWallet extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async sendQort() {
|
async sendQort() {
|
||||||
|
const sendFee = this.qortPaymentFee
|
||||||
const amount = this.shadowRoot.getElementById('amountInput').value
|
const amount = this.shadowRoot.getElementById('amountInput').value
|
||||||
let recipient = this.shadowRoot.getElementById('recipient').value
|
let recipient = this.shadowRoot.getElementById('recipient').value
|
||||||
|
|
||||||
@ -4390,7 +4411,6 @@ class MultiWallet extends LitElement {
|
|||||||
|
|
||||||
const getName = async (recipient)=> {
|
const getName = async (recipient)=> {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
const getNames = await parentEpml.request("apiCall", {
|
const getNames = await parentEpml.request("apiCall", {
|
||||||
type: "api",
|
type: "api",
|
||||||
url: `/names/address/${recipient}`,
|
url: `/names/address/${recipient}`,
|
||||||
@ -4421,7 +4441,7 @@ class MultiWallet extends LitElement {
|
|||||||
recipientName: recipientName,
|
recipientName: recipientName,
|
||||||
amount: amount,
|
amount: amount,
|
||||||
lastReference: mylastRef,
|
lastReference: mylastRef,
|
||||||
fee: 0.001,
|
fee: sendFee,
|
||||||
dialogamount: dialogamount,
|
dialogamount: dialogamount,
|
||||||
dialogto: dialogto,
|
dialogto: dialogto,
|
||||||
dialogAddress,
|
dialogAddress,
|
||||||
|
@ -28,7 +28,8 @@ export const publishData = async ({
|
|||||||
tag2,
|
tag2,
|
||||||
tag3,
|
tag3,
|
||||||
tag4,
|
tag4,
|
||||||
tag5
|
tag5,
|
||||||
|
feeAmount
|
||||||
}) => {
|
}) => {
|
||||||
const validateName = async (receiverName) => {
|
const validateName = async (receiverName) => {
|
||||||
let nameRes = await parentEpml.request("apiCall", {
|
let nameRes = await parentEpml.request("apiCall", {
|
||||||
@ -48,6 +49,17 @@ export const publishData = async ({
|
|||||||
})
|
})
|
||||||
return convertedBytes
|
return convertedBytes
|
||||||
}
|
}
|
||||||
|
const getArbitraryFee = async () => {
|
||||||
|
const timestamp = Date.now()
|
||||||
|
let fee = await parentEpml.request('apiCall', {
|
||||||
|
url: `/transactions/unitfee?txType=ARBITRARY×tamp=${timestamp}`
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
timestamp,
|
||||||
|
fee : Number(fee),
|
||||||
|
feeToShow: (Number(fee) / 1e8).toFixed(8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const signAndProcess = async (transactionBytesBase58) => {
|
const signAndProcess = async (transactionBytesBase58) => {
|
||||||
let convertedBytesBase58 = await convertBytesForSigning(
|
let convertedBytesBase58 = await convertBytesForSigning(
|
||||||
@ -125,7 +137,18 @@ export const publishData = async ({
|
|||||||
if (validNameRes.error) {
|
if (validNameRes.error) {
|
||||||
throw new Error('Name not found');
|
throw new Error('Name not found');
|
||||||
}
|
}
|
||||||
let transactionBytes = await uploadData(registeredName, path, file)
|
let fee = null
|
||||||
|
if(withFee && feeAmount){
|
||||||
|
fee= feeAmount
|
||||||
|
} else if(withFee){
|
||||||
|
const res = await getArbitraryFee()
|
||||||
|
if(res.fee){
|
||||||
|
fee= res.fee
|
||||||
|
} else {
|
||||||
|
throw new Error('unable to get fee')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let transactionBytes = await uploadData(registeredName, path, file, fee)
|
||||||
if (transactionBytes.error) {
|
if (transactionBytes.error) {
|
||||||
throw new Error(transactionBytes.message || 'Error when uploading');
|
throw new Error(transactionBytes.message || 'Error when uploading');
|
||||||
} else if (
|
} else if (
|
||||||
@ -149,7 +172,7 @@ export const publishData = async ({
|
|||||||
return signAndProcessRes
|
return signAndProcessRes
|
||||||
}
|
}
|
||||||
|
|
||||||
const uploadData = async (registeredName, path, file) => {
|
const uploadData = async (registeredName, path, file, fee) => {
|
||||||
if (identifier != null && identifier.trim().length > 0) {
|
if (identifier != null && identifier.trim().length > 0) {
|
||||||
let postBody = path
|
let postBody = path
|
||||||
let urlSuffix = ""
|
let urlSuffix = ""
|
||||||
@ -181,7 +204,7 @@ export const publishData = async ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(withFee){
|
if(withFee){
|
||||||
uploadDataUrl = uploadDataUrl + '&fee=100000'
|
uploadDataUrl = uploadDataUrl + `&fee=${fee}`
|
||||||
}
|
}
|
||||||
|
|
||||||
if(filename != null && filename != "undefined"){
|
if(filename != null && filename != "undefined"){
|
||||||
|
147
plugins/plugins/utils/publish-modal.css
Normal file
147
plugins/plugins/utils/publish-modal.css
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
.backdrop {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgb(186 186 186 / 26%);
|
||||||
|
overflow: hidden;
|
||||||
|
animation: backdrop_blur cubic-bezier(0.22, 1, 0.36, 1) 1s forwards;
|
||||||
|
z-index: 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes backdrop_blur {
|
||||||
|
0% {
|
||||||
|
backdrop-filter: blur(0px);
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
background: rgb(186 186 186 / 26%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes modal_transition {
|
||||||
|
0% {
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
animation: 1s cubic-bezier(0.22, 1, 0.36, 1) 0s 1 normal forwards running modal_transition;
|
||||||
|
z-index: 1000001;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes modal_transition {
|
||||||
|
0% {
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
background-color: var(--white);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||||
|
max-width: 80%;
|
||||||
|
min-width: 300px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-subcontainer {
|
||||||
|
color: var(--black);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-subcontainer-error {
|
||||||
|
color: var(--black);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-paragraph-error {
|
||||||
|
font-family: Roboto, sans-serif;
|
||||||
|
font-size: 20px;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--black);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-paragraph {
|
||||||
|
font-family: Roboto, sans-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
font-weight: 300;
|
||||||
|
color: var(--black);
|
||||||
|
margin: 0;
|
||||||
|
word-wrap: break-word;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.capitalize-first {
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-family: Montserrat, sans-serif;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--black);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-buttons button {
|
||||||
|
background-color: #4caf50;
|
||||||
|
border: none;
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-buttons button:hover {
|
||||||
|
background-color: #3e8e41;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cancel-button {
|
||||||
|
background-color: #f44336;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cancel-button:hover {
|
||||||
|
background-color: #d32f2f;
|
||||||
|
}
|
270
plugins/plugins/utils/publish-modal.js
Normal file
270
plugins/plugins/utils/publish-modal.js
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
import { get } from 'lit-translate';
|
||||||
|
|
||||||
|
export class ModalHelper {
|
||||||
|
constructor() {
|
||||||
|
this.initializeStyles();
|
||||||
|
}
|
||||||
|
|
||||||
|
async getArbitraryFee() {
|
||||||
|
const timestamp = Date.now();
|
||||||
|
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=ARBITRARY×tamp=${timestamp}`;
|
||||||
|
const response = await fetch(url);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Error when fetching arbitrary fee');
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
const arbitraryFee = (Number(data) / 1e8).toFixed(8);
|
||||||
|
return {
|
||||||
|
timestamp,
|
||||||
|
fee: Number(data),
|
||||||
|
feeToShow: arbitraryFee
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async showModalAndWaitPublish(data) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const modal = this.createModal(data);
|
||||||
|
document.body.appendChild(modal);
|
||||||
|
this.addModalEventListeners(modal, resolve);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
createModal(data) {
|
||||||
|
const modal = document.createElement('div');
|
||||||
|
modal.id = "backdrop";
|
||||||
|
modal.classList.add("backdrop");
|
||||||
|
modal.innerHTML = `
|
||||||
|
<div class="modal my-modal-class">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="modal-subcontainer">
|
||||||
|
<div class="checkbox-row">
|
||||||
|
<p style="font-size: 16px;overflow-wrap: anywhere;" class="modal-paragraph">${get('browserpage.bchange47')} <span style="font-weight: bold">${data.feeAmount} QORT fee</span></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-buttons">
|
||||||
|
<button id="cancel-button">${get("browserpage.bchange27")}</button>
|
||||||
|
<button id="ok-button">${get("browserpage.bchange28")}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
return modal;
|
||||||
|
}
|
||||||
|
|
||||||
|
addModalEventListeners(modal, resolve) {
|
||||||
|
// Event listener for the 'OK' button
|
||||||
|
const okButton = modal.querySelector('#ok-button');
|
||||||
|
okButton.addEventListener('click', () => {
|
||||||
|
const userData = { isWithFee: true };
|
||||||
|
if (modal.parentNode === document.body) {
|
||||||
|
document.body.removeChild(modal);
|
||||||
|
}
|
||||||
|
resolve({ action: 'accept', userData });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Prevent modal content from closing the modal
|
||||||
|
const modalContent = modal.querySelector('.modal-content');
|
||||||
|
modalContent.addEventListener('click', e => {
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Event listeners for backdrop and 'Cancel' button
|
||||||
|
const backdropClick = document.getElementById('backdrop');
|
||||||
|
backdropClick.addEventListener('click', () => {
|
||||||
|
if (modal.parentNode === document.body) {
|
||||||
|
document.body.removeChild(modal);
|
||||||
|
}
|
||||||
|
resolve({ action: 'reject' });
|
||||||
|
});
|
||||||
|
|
||||||
|
const cancelButton = modal.querySelector('#cancel-button');
|
||||||
|
cancelButton.addEventListener('click', () => {
|
||||||
|
if (modal.parentNode === document.body) {
|
||||||
|
document.body.removeChild(modal);
|
||||||
|
}
|
||||||
|
resolve({ action: 'reject' });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
initializeStyles() {
|
||||||
|
const styles = `
|
||||||
|
* {
|
||||||
|
--mdc-theme-primary: rgb(3, 169, 244);
|
||||||
|
--mdc-theme-secondary: var(--mdc-theme-primary);
|
||||||
|
--paper-input-container-focus-color: var(--mdc-theme-primary);
|
||||||
|
--mdc-checkbox-unchecked-color: var(--black);
|
||||||
|
--mdc-theme-on-surface: var(--black);
|
||||||
|
--mdc-checkbox-disabled-color: var(--black);
|
||||||
|
--mdc-checkbox-ink-color: var(--black);
|
||||||
|
}
|
||||||
|
|
||||||
|
.backdrop {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgb(186 186 186 / 26%);
|
||||||
|
overflow: hidden;
|
||||||
|
animation: backdrop_blur cubic-bezier(0.22, 1, 0.36, 1) 0.1s forwards;
|
||||||
|
z-index: 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes backdrop_blur {
|
||||||
|
0% {
|
||||||
|
backdrop-filter: blur(0px);
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
background: rgb(186 186 186 / 26%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes modal_transition {
|
||||||
|
0% {
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
animation: 0.1s cubic-bezier(0.22, 1, 0.36, 1) 0s 1 normal forwards running modal_transition;
|
||||||
|
z-index: 1000001;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes modal_transition {
|
||||||
|
0% {
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
background-color: var(--white);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||||
|
max-width: 80%;
|
||||||
|
min-width: 300px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-subcontainer {
|
||||||
|
color: var(--black);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-subcontainer-error {
|
||||||
|
color: var(--black);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-paragraph-error {
|
||||||
|
font-family: Roboto, sans-serif;
|
||||||
|
font-size: 20px;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--black);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-paragraph {
|
||||||
|
font-family: Roboto, sans-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
font-weight: 300;
|
||||||
|
color: var(--black);
|
||||||
|
margin: 0;
|
||||||
|
word-wrap: break-word;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.capitalize-first {
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-family: Montserrat, sans-serif;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--black);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-buttons button {
|
||||||
|
background-color: #4caf50;
|
||||||
|
border: none;
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-buttons button:hover {
|
||||||
|
background-color: #3e8e41;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cancel-button {
|
||||||
|
background-color: #f44336;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cancel-button:hover {
|
||||||
|
background-color: #d32f2f;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const styleSheet = new CSSStyleSheet();
|
||||||
|
styleSheet.replaceSync(styles);
|
||||||
|
|
||||||
|
document.adoptedStyleSheets = [styleSheet];
|
||||||
|
}
|
||||||
|
|
||||||
|
static getInstance() {
|
||||||
|
if (!ModalHelper.instance) {
|
||||||
|
ModalHelper.instance = new ModalHelper();
|
||||||
|
}
|
||||||
|
return ModalHelper.instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const modalHelper = ModalHelper.getInstance();
|
Loading…
x
Reference in New Issue
Block a user