diff --git a/README.md b/README.md
index bee983ae..f39fd5b3 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@ Easiest way to install the lastest required packages on Linux is via nvm.
``` source ~/.bashrc ``` (For Fedora / CentOS)
``` nvm ls-remote ``` (Fetch list of available versions)
``` nvm install v20.11.1 ``` (LTS: Iron supported by Electron V30)
-``` npm --location=global install npm@10.8.0 ```
+``` npm --location=global install npm@10.8.1 ```
Adding via binary package mirror will only work if you have set the package path. You can do a node or java build via ports instead by downloading ports with portsnap fetch method.
diff --git a/core/language/de.json b/core/language/de.json
index 9e6bf97f..a3bd5663 100644
--- a/core/language/de.json
+++ b/core/language/de.json
@@ -973,7 +973,10 @@
"gchange65": "Ersetzen Sie diese Adresse durch EIGENTUM der Gruppe übertragen!",
"gchange66": "Ungültige Besitzer-/neue Besitzeradresse",
"gchange67": "Gruppen-UPDATE erfolgreich!",
- "gchange68": "Gruppen-Avatar festlegen"
+ "gchange68": "Gruppen-Avatar festlegen",
+ "gchange69": "Nachrichten",
+ "gchange70": "Keine Nachrichten in den letzten 24 Stunden!",
+ "gchange71": "Du bist dieser Gruppe bereits beigetreten!"
},
"puzzlepage": {
"pchange1": "Rätsel",
diff --git a/core/language/es.json b/core/language/es.json
index 41e8af96..3935defc 100644
--- a/core/language/es.json
+++ b/core/language/es.json
@@ -973,8 +973,10 @@
"gchange65": "¡Reemplace esta dirección para TRANSFERIR LA PROPIEDAD del grupo!",
"gchange66": "Propietario no válido / Dirección de nuevo propietario",
"gchange67": "¡Éxito de la ACTUALIZACIÓN del grupo!",
- "gchange68": "Establecer avatar de grupo"
-
+ "gchange68": "Establecer avatar de grupo",
+ "gchange69": "Mensajes",
+ "gchange70": "¡No hay mensajes en las últimas 24 horas!",
+ "gchange71": "¡Ya te uniste a este grupo!"
},
"puzzlepage": {
"pchange1": "Rompecabezas",
diff --git a/core/language/et.json b/core/language/et.json
index 667124be..f2a159bd 100644
--- a/core/language/et.json
+++ b/core/language/et.json
@@ -973,7 +973,10 @@
"gchange65": "Asendage see aadress grupi omandiõiguse üleandmiseks!",
"gchange66": "Kehtetu omanik / uue omaniku aadress",
"gchange67": "Grupi UUENDAMINE edukas!",
- "gchange68": "Rühma avatari määramine"
+ "gchange68": "Rühma avatari määramine",
+ "gchange69": "Sõnumid",
+ "gchange70": "Viimase 24 tunni jooksul pole ühtegi sõnumit!",
+ "gchange71": "Olete selle grupiga juba liitunud!"
},
"puzzlepage": {
"pchange1": "Puzzled",
diff --git a/core/language/fi.json b/core/language/fi.json
index fbcbad11..b5fb6553 100644
--- a/core/language/fi.json
+++ b/core/language/fi.json
@@ -973,7 +973,10 @@
"gchange65": "Korvaa tämä osoite muotoon SIIRRÄ RYHMÄN OMISTAJUUS!",
"gchange66": "Virheellinen omistaja / uuden omistajan osoite",
"gchange67": "Ryhmän päivitys onnistui!",
- "gchange68": "Aseta ryhmän avatar"
+ "gchange68": "Aseta ryhmän avatar",
+ "gchange69": "Viestit",
+ "gchange70": "Ei viestejä viimeisen 24 tunnin aikana!",
+ "gchange71": "Olet jo liittynyt tähän ryhmään!"
},
"puzzlepage": {
"pchange1": "Palapelit",
diff --git a/core/language/fr.json b/core/language/fr.json
index 3f18fe61..dab0a7c3 100644
--- a/core/language/fr.json
+++ b/core/language/fr.json
@@ -973,7 +973,10 @@
"gchange65": "Remplacez cette adresse par TRANSFERT DE PROPRIÉTÉ du groupe !",
"gchange66": "Invalid Owner / New Owner Address",
"gchange67": "MISE À JOUR DE GROUPE réussie !",
- "gchange68": "Définir l'avatar de groupe"
+ "gchange68": "Définir l'avatar de groupe",
+ "gchange69": "Messages",
+ "gchange70": "Aucun message ces dernières 24 heures !",
+ "gchange71": "Vous avez déjà rejoint ce groupe !"
},
"puzzlepage": {
"pchange1": "Puzzles",
diff --git a/core/language/hindi.json b/core/language/hindi.json
index aa3190d1..3263ec7f 100644
--- a/core/language/hindi.json
+++ b/core/language/hindi.json
@@ -973,7 +973,10 @@
"gchange65": "इस पते को समूह के स्थानांतरण स्वामित्व में बदलें!",
"gchange66": "अमान्य मालिक/नए मालिक का पता",
"gchange67": "समूह अद्यतन सफल!",
- "gchange68": "समूह अवतार सेट करें"
+ "gchange68": "समूह अवतार सेट करें",
+ "gchange69": "संदेश",
+ "gchange70": "पिछले 24 घंटों में कोई संदेश नहीं!",
+ "gchange71": "आप पहले ही इस समूह में शामिल हो चुके हैं!"
},
"puzzlepage": {
"pchange1": "पहेलि",
diff --git a/core/language/hr.json b/core/language/hr.json
index 3babe225..f557b346 100644
--- a/core/language/hr.json
+++ b/core/language/hr.json
@@ -973,7 +973,10 @@
"gchange65": "Zamijenite ovu adresu u PRIJENOS VLASNIŠTVA grupe!",
"gchange66": "Vlasnik / nova adresa vlasnika nisu valjani",
"gchange67": "Grupa UPDATE Uspješna!",
- "gchange68": "Postavi grupni avatar"
+ "gchange68": "Postavi grupni avatar",
+ "gchange69": "Poruke",
+ "gchange70": "Nema poruka u zadnja 24 sata!",
+ "gchange71": "Već ste se pridružili ovoj grupi!"
},
"puzzlepage": {
"pchange1": "Zagonetke",
diff --git a/core/language/hu.json b/core/language/hu.json
index 16054238..e5528c0b 100644
--- a/core/language/hu.json
+++ b/core/language/hu.json
@@ -973,7 +973,10 @@
"gchange65": "Cserélje ki ezt a címet erre: A CSOPORT TULAJDONJOGÁNAK ÁTRUHÁZÁSA!",
"gchange66": "Érvénytelen tulajdonos / új tulajdonos címe",
"gchange67": "Csoportos FRISSÍTÉS sikeres!",
- "gchange68": "Csoportavatar beállítása"
+ "gchange68": "Csoportavatar beállítása",
+ "gchange69": "Üzenetek",
+ "gchange70": "Nincs üzenet az elmúlt 24 órában!",
+ "gchange71": "Már csatlakoztál ehhez a csoporthoz!"
},
"puzzlepage": {
"pchange1": "Rejtvények",
diff --git a/core/language/it.json b/core/language/it.json
index 56920f36..5566f078 100644
--- a/core/language/it.json
+++ b/core/language/it.json
@@ -973,7 +973,10 @@
"gchange65": "Sostituisci questo indirizzo per TRASFERIRE LA PROPRIETA' del gruppo!",
"gchange66": "Indirizzo del proprietario non valido/nuovo proprietario",
"gchange67": "AGGIORNAMENTO di gruppo riuscito!",
- "gchange68": "Imposta avatar di gruppo"
+ "gchange68": "Imposta avatar di gruppo",
+ "gchange69": "Messaggi",
+ "gchange70": "Nessun messaggio nelle ultime 24 ore!",
+ "gchange71": "Ti sei già unito a questo gruppo!"
},
"puzzlepage": {
"pchange1": "Puzzle",
diff --git a/core/language/jp.json b/core/language/jp.json
index a3b677c6..cad3bdcc 100644
--- a/core/language/jp.json
+++ b/core/language/jp.json
@@ -973,7 +973,10 @@
"gchange65": "このアドレスをグループの所有権の譲渡に置き換えてください。",
"gchange66": "無効な所有者/新しい所有者のアドレス",
"gchange67": "グループ UPDATE 成功しました!",
- "gchange68": "グループアバターの設定"
+ "gchange68": "グループアバターの設定",
+ "gchange69": "メッセージ",
+ "gchange70": "過去 24 時間以内にメッセージはありません。",
+ "gchange71": "このグループにはすでに参加しています。"
},
"puzzlepage": {
"pchange1": "パズル",
diff --git a/core/language/ko.json b/core/language/ko.json
index 78a746f6..a8936506 100644
--- a/core/language/ko.json
+++ b/core/language/ko.json
@@ -973,7 +973,10 @@
"gchange65": "이 주소를 그룹의 소유권 이전으로 바꾸십시오!",
"gchange66": "잘못된 소유자/새 소유자 주소",
"gchange67": "그룹 업데이트 성공!",
- "gchange68": "그룹 아바타 설정"
+ "gchange68": "그룹 아바타 설정",
+ "gchange69": "메시지",
+ "gchange70": "지난 24시간 동안 메시지가 없습니다!",
+ "gchange71": "당신은 이미 이 그룹에 가입했습니다!"
},
"puzzlepage": {
"pchange1": "퍼즐",
diff --git a/core/language/nl.json b/core/language/nl.json
index 4946716f..a10b8ad3 100644
--- a/core/language/nl.json
+++ b/core/language/nl.json
@@ -973,7 +973,10 @@
"gchange65": "Vervang dit adres enkel als U de EIGENDOM van de groep wenst OVER TE DRAGEN!",
"gchange66": "Ongeldig adres van huidige of nieuwe eigenaar",
"gchange67": "Groep UPDATE succesvol uitgevoerd!",
- "gchange68": "Groepsavatar instellen"
+ "gchange68": "Groepsavatar instellen",
+ "gchange69": "Berichten",
+ "gchange70": "Geen berichten in de afgelopen 24 uur!",
+ "gchange71": "Je bent al lid van deze groep!"
},
"puzzlepage": {
"pchange1": "Puzzels",
diff --git a/core/language/no.json b/core/language/no.json
index 68d670b0..6e934a0a 100644
--- a/core/language/no.json
+++ b/core/language/no.json
@@ -973,7 +973,10 @@
"gchange65": "Erstatt denne adressen til OVERFØR EIERSKAP av gruppen!",
"gchange66": "Ugyldig eier / ny eieradresse",
"gchange67": "Gruppeoppdatering vellykket!",
- "gchange68": "Angi gruppeavatar"
+ "gchange68": "Angi gruppeavatar",
+ "gchange69": "Meldinger",
+ "gchange70": "Ingen meldinger de siste 24 timene!",
+ "gchange71": "Du har allerede blitt med i denne gruppen!"
},
"puzzlepage": {
"pchange1": "Puzzles",
diff --git a/core/language/pl.json b/core/language/pl.json
index 34dd56ad..5b9d3097 100644
--- a/core/language/pl.json
+++ b/core/language/pl.json
@@ -973,7 +973,10 @@
"gchange65": "Zamień ten adres na PRZENIESIENIE WŁASNOŚCI grupy!",
"gchange66": "Nieprawidłowy właściciel / nowy adres właściciela",
"gchange67": "AKTUALIZACJA grupy powiodła się!",
- "gchange68": "Ustaw awatar grupy"
+ "gchange68": "Ustaw awatar grupy",
+ "gchange69": "Wiadomości",
+ "gchange70": "Brak wiadomości w ciągu ostatnich 24 godzin!",
+ "gchange71": "Już dołączyłeś do tej grupy!"
},
"puzzlepage": {
"pchange1": "Zagadki",
diff --git a/core/language/pt.json b/core/language/pt.json
index 1c12c47a..5f42ae85 100644
--- a/core/language/pt.json
+++ b/core/language/pt.json
@@ -973,7 +973,10 @@
"gchange65": "Substitua este endereço para TRANSFERIR PROPRIEDADE do grupo!",
"gchange66": "Endereço de proprietário / novo proprietário inválido",
"gchange67": "ATUALIZAÇÃO DO Grupo bem-sucedida!",
- "gchange68": "Definir avatar do grupo"
+ "gchange68": "Definir avatar do grupo",
+ "gchange69": "Mensagens",
+ "gchange70": "Nenhuma mensagem nas últimas 24 horas!",
+ "gchange71": "Você já entrou neste grupo!"
},
"puzzlepage": {
"pchange1": "Enigmas",
diff --git a/core/language/ro.json b/core/language/ro.json
index 951fe336..dc1ab009 100644
--- a/core/language/ro.json
+++ b/core/language/ro.json
@@ -973,7 +973,10 @@
"gchange65": "Înlocuiți această adresă la TRANSFERAȚI PROPRIETATEA grupului!",
"gchange66": "Adresa proprietarului / proprietarului nou nevalidă",
"gchange67": "UPDATE de grup Reușit!",
- "gchange68": "Set Avatar grup"
+ "gchange68": "Set Avatar grup",
+ "gchange69": "Mesaje",
+ "gchange70": "Niciun mesaj în ultimele 24 de ore!",
+ "gchange71": "Te-ai alaturat deja acestui grup!"
},
"puzzlepage": {
"pchange1": "Puzzle-uri",
diff --git a/core/language/rs.json b/core/language/rs.json
index eede9f52..12e97877 100644
--- a/core/language/rs.json
+++ b/core/language/rs.json
@@ -973,7 +973,10 @@
"gchange65": "Zameni ovu adresu NA PRENOS VLASNIŠTVA GRUPE!",
"gchange66": "Nevažeći vlasnik / adresa novog vlasnika",
"gchange67": "Grupni UPDATE je uspešan!",
- "gchange68": "Postavi grupni avatar"
+ "gchange68": "Postavi grupni avatar",
+ "gchange69": "Poruke",
+ "gchange70": "Nema poruka u poslednja 24 sata!",
+ "gchange71": "Već ste se pridružili ovoj grupi!"
},
"puzzlepage": {
"pchange1": "Slagalice",
diff --git a/core/language/ru.json b/core/language/ru.json
index f5b228ad..a6bdc1e0 100644
--- a/core/language/ru.json
+++ b/core/language/ru.json
@@ -973,7 +973,10 @@
"gchange65": "Замените этот адрес на TRANSFER OWNERSHIP of group!",
"gchange66": "Неверный адрес владельца / нового владельца",
"gchange67": "Групповое ОБНОВЛЕНИЕ выполнено успешно!",
- "gchange68": "Установить групповой аватар"
+ "gchange68": "Установить групповой аватар",
+ "gchange69": "Сообщения",
+ "gchange70": "За последние 24 часа нет сообщений!",
+ "gchange71": "Вы уже присоединились к этой группе!"
},
"puzzlepage": {
"pchange1": "Головоломки",
diff --git a/core/language/us.json b/core/language/us.json
index fc14e419..ae3b1353 100644
--- a/core/language/us.json
+++ b/core/language/us.json
@@ -973,7 +973,10 @@
"gchange65": "Only replace this address if you want to transfer the group!",
"gchange66": "Invalid Owner / New Owner Address",
"gchange67": "Group Update Successful!",
- "gchange68": "Set Group Avatar"
+ "gchange68": "Set Group Avatar",
+ "gchange69": "Messages",
+ "gchange70": "No messages in the last 24 hours!",
+ "gchange71": "You have already joined this group!"
},
"puzzlepage": {
"pchange1": "Puzzles",
diff --git a/core/language/zhc.json b/core/language/zhc.json
index 6635f5ea..dea8a0b4 100644
--- a/core/language/zhc.json
+++ b/core/language/zhc.json
@@ -973,7 +973,10 @@
"gchange65": "将此地址替换为组的 TRANSFER OWNERSHIP!",
"gchange66": "无效的所有者/新所有者地址",
"gchange67": "组更新成功!",
- "gchange68": "设置组头像"
+ "gchange68": "设置组头像",
+ "gchange69": "消息",
+ "gchange70": "过去 24 小时内没有消息!",
+ "gchange71": "您已经加入此群组!"
},
"puzzlepage": {
"pchange1": "益智游戏",
diff --git a/core/language/zht.json b/core/language/zht.json
index ca5cfbbc..7150f4b4 100644
--- a/core/language/zht.json
+++ b/core/language/zht.json
@@ -973,7 +973,10 @@
"gchange65": "將此位址替換為組的 TRANSFER OWNERSHIP!",
"gchange66": "無效的擁有者/新擁有者位址",
"gchange67": "組更新成功!",
- "gchange68": "設置組頭像"
+ "gchange68": "設置組頭像",
+ "gchange69": "訊息",
+ "gchange70": "過去 24 小時內沒有訊息!",
+ "gchange71": "你已經加入這個群組了!"
},
"puzzlepage": {
"pchange1": "益智游戲",
diff --git a/img/img-loading.png b/img/img-loading.png
new file mode 100644
index 00000000..9f4c1373
Binary files /dev/null and b/img/img-loading.png differ
diff --git a/package-lock.json b/package-lock.json
index 2596704b..d2da21bf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -28,9 +28,9 @@
"crypto-js": "4.2.0",
"driver.js": "1.3.1",
"electron-dl": "3.5.2",
- "electron-log": "5.1.4",
+ "electron-log": "5.1.5",
"electron-store": "8.2.0",
- "electron-updater": "6.1.8",
+ "electron-updater": "6.2.1",
"emoji-picker-js": "https://github.com/Qortal/emoji-picker-js",
"extract-zip": "2.0.1",
"jssha": "3.3.1",
@@ -42,17 +42,17 @@
"prosemirror-gapcursor": "1.3.2",
"prosemirror-history": "1.4.0",
"prosemirror-keymap": "1.2.2",
- "prosemirror-model": "1.21.0",
- "prosemirror-schema-list": "1.3.0",
+ "prosemirror-model": "1.21.1",
+ "prosemirror-schema-list": "1.4.0",
"prosemirror-state": "1.4.3",
"prosemirror-transform": "1.9.0",
- "prosemirror-view": "1.33.6",
- "sass": "1.77.2",
+ "prosemirror-view": "1.33.7",
+ "sass": "1.77.4",
"short-unique-id": "5.2.0",
"xhr2": "0.2.1"
},
"devDependencies": {
- "@babel/core": "7.24.6",
+ "@babel/core": "7.24.7",
"@electron/packager": "18.3.2",
"@material/mwc-button": "0.27.0",
"@material/mwc-checkbox": "0.27.0",
@@ -92,9 +92,9 @@
"@qortal/rollup-plugin-web-worker-loader": "1.6.5",
"@rollup/plugin-alias": "5.1.0",
"@rollup/plugin-babel": "6.0.4",
- "@rollup/plugin-commonjs": "25.0.8",
+ "@rollup/plugin-commonjs": "26.0.1",
"@rollup/plugin-node-resolve": "15.2.3",
- "@rollup/plugin-replace": "5.0.5",
+ "@rollup/plugin-replace": "5.0.7",
"@rollup/plugin-terser": "0.4.4",
"@vaadin/avatar": "24.2.9",
"@vaadin/button": "24.2.9",
@@ -105,13 +105,13 @@
"@vaadin/tabs": "24.2.9",
"@vaadin/tabsheet": "24.2.9",
"@vaadin/tooltip": "24.2.9",
- "@zip.js/zip.js": "2.7.44",
+ "@zip.js/zip.js": "2.7.45",
"axios": "1.7.2",
- "electron": "30.0.8",
+ "electron": "30.1.0",
"electron-builder": "24.13.3",
"epml": "0.3.3",
"eslint": "8.57.0",
- "eslint-plugin-lit": "1.13.0",
+ "eslint-plugin-lit": "1.14.0",
"eslint-plugin-wc": "2.1.0",
"file-saver": "2.0.5",
"highcharts": "11.1.0",
@@ -147,13 +147,13 @@
}
},
"node_modules/@babel/code-frame": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.6.tgz",
- "integrity": "sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
+ "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/highlight": "^7.24.6",
+ "@babel/highlight": "^7.24.7",
"picocolors": "^1.0.0"
},
"engines": {
@@ -161,9 +161,9 @@
}
},
"node_modules/@babel/compat-data": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.6.tgz",
- "integrity": "sha512-aC2DGhBq5eEdyXWqrDInSqQjO0k8xtPRf5YylULqx8MCd6jBtzqfta/3ETMRpuKIc5hyswfO80ObyA1MvkCcUQ==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz",
+ "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -171,22 +171,22 @@
}
},
"node_modules/@babel/core": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.6.tgz",
- "integrity": "sha512-qAHSfAdVyFmIvl0VHELib8xar7ONuSHrE2hLnsaWkYNTI68dmi1x8GYDhJjMI/e7XWal9QBlZkwbOnkcw7Z8gQ==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz",
+ "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.24.6",
- "@babel/generator": "^7.24.6",
- "@babel/helper-compilation-targets": "^7.24.6",
- "@babel/helper-module-transforms": "^7.24.6",
- "@babel/helpers": "^7.24.6",
- "@babel/parser": "^7.24.6",
- "@babel/template": "^7.24.6",
- "@babel/traverse": "^7.24.6",
- "@babel/types": "^7.24.6",
+ "@babel/code-frame": "^7.24.7",
+ "@babel/generator": "^7.24.7",
+ "@babel/helper-compilation-targets": "^7.24.7",
+ "@babel/helper-module-transforms": "^7.24.7",
+ "@babel/helpers": "^7.24.7",
+ "@babel/parser": "^7.24.7",
+ "@babel/template": "^7.24.7",
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -202,13 +202,13 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.6.tgz",
- "integrity": "sha512-S7m4eNa6YAPJRHmKsLHIDJhNAGNKoWNiWefz1MBbpnt8g9lvMDl1hir4P9bo/57bQEmuwEhnRU/AMWsD0G/Fbg==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz",
+ "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.24.6",
+ "@babel/types": "^7.24.7",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^2.5.1"
@@ -218,14 +218,14 @@
}
},
"node_modules/@babel/helper-compilation-targets": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.6.tgz",
- "integrity": "sha512-VZQ57UsDGlX/5fFA7GkVPplZhHsVc+vuErWgdOiysI9Ksnw0Pbbd6pnPiR/mmJyKHgyIW0c7KT32gmhiF+cirg==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz",
+ "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/compat-data": "^7.24.6",
- "@babel/helper-validator-option": "^7.24.6",
+ "@babel/compat-data": "^7.24.7",
+ "@babel/helper-validator-option": "^7.24.7",
"browserslist": "^4.22.2",
"lru-cache": "^5.1.1",
"semver": "^6.3.1"
@@ -235,67 +235,71 @@
}
},
"node_modules/@babel/helper-environment-visitor": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.6.tgz",
- "integrity": "sha512-Y50Cg3k0LKLMjxdPjIl40SdJgMB85iXn27Vk/qbHZCFx/o5XO3PSnpi675h1KEmmDb6OFArfd5SCQEQ5Q4H88g==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz",
+ "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.24.7"
+ },
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-function-name": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.6.tgz",
- "integrity": "sha512-xpeLqeeRkbxhnYimfr2PC+iA0Q7ljX/d1eZ9/inYbmfG2jpl8Lu3DyXvpOAnrS5kxkfOWJjioIMQsaMBXFI05w==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz",
+ "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/template": "^7.24.6",
- "@babel/types": "^7.24.6"
+ "@babel/template": "^7.24.7",
+ "@babel/types": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-hoist-variables": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.6.tgz",
- "integrity": "sha512-SF/EMrC3OD7dSta1bLJIlrsVxwtd0UpjRJqLno6125epQMJ/kyFmpTT4pbvPbdQHzCHg+biQ7Syo8lnDtbR+uA==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz",
+ "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.24.6"
+ "@babel/types": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-imports": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.6.tgz",
- "integrity": "sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
+ "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.24.6"
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-transforms": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.6.tgz",
- "integrity": "sha512-Y/YMPm83mV2HJTbX1Qh2sjgjqcacvOlhbzdCCsSlblOKjSYmQqEbO6rUniWQyRo9ncyfjT8hnUjlG06RXDEmcA==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz",
+ "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-environment-visitor": "^7.24.6",
- "@babel/helper-module-imports": "^7.24.6",
- "@babel/helper-simple-access": "^7.24.6",
- "@babel/helper-split-export-declaration": "^7.24.6",
- "@babel/helper-validator-identifier": "^7.24.6"
+ "@babel/helper-environment-visitor": "^7.24.7",
+ "@babel/helper-module-imports": "^7.24.7",
+ "@babel/helper-simple-access": "^7.24.7",
+ "@babel/helper-split-export-declaration": "^7.24.7",
+ "@babel/helper-validator-identifier": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -305,35 +309,36 @@
}
},
"node_modules/@babel/helper-simple-access": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.6.tgz",
- "integrity": "sha512-nZzcMMD4ZhmB35MOOzQuiGO5RzL6tJbsT37Zx8M5L/i9KSrukGXWTjLe1knIbb/RmxoJE9GON9soq0c0VEMM5g==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
+ "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.24.6"
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-split-export-declaration": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.6.tgz",
- "integrity": "sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz",
+ "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.24.6"
+ "@babel/types": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.6.tgz",
- "integrity": "sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz",
+ "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -341,9 +346,9 @@
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.6.tgz",
- "integrity": "sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
+ "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
"dev": true,
"license": "MIT",
"engines": {
@@ -351,9 +356,9 @@
}
},
"node_modules/@babel/helper-validator-option": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.6.tgz",
- "integrity": "sha512-Jktc8KkF3zIkePb48QO+IapbXlSapOW9S+ogZZkcO6bABgYAxtZcjZ/O005111YLf+j4M84uEgwYoidDkXbCkQ==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz",
+ "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -361,27 +366,27 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.6.tgz",
- "integrity": "sha512-V2PI+NqnyFu1i0GyTd/O/cTpxzQCYioSkUIRmgo7gFEHKKCg5w46+r/A6WeUR1+P3TeQ49dspGPNd/E3n9AnnA==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz",
+ "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/template": "^7.24.6",
- "@babel/types": "^7.24.6"
+ "@babel/template": "^7.24.7",
+ "@babel/types": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/highlight": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.6.tgz",
- "integrity": "sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
+ "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.24.6",
+ "@babel/helper-validator-identifier": "^7.24.7",
"chalk": "^2.4.2",
"js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
@@ -391,9 +396,9 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.6.tgz",
- "integrity": "sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz",
+ "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==",
"dev": true,
"license": "MIT",
"bin": {
@@ -404,35 +409,35 @@
}
},
"node_modules/@babel/template": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.6.tgz",
- "integrity": "sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz",
+ "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.24.6",
- "@babel/parser": "^7.24.6",
- "@babel/types": "^7.24.6"
+ "@babel/code-frame": "^7.24.7",
+ "@babel/parser": "^7.24.7",
+ "@babel/types": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.6.tgz",
- "integrity": "sha512-OsNjaJwT9Zn8ozxcfoBc+RaHdj3gFmCmYoQLUII1o6ZrUwku0BMg80FoOTPx+Gi6XhcQxAYE4xyjPTo4SxEQqw==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz",
+ "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.24.6",
- "@babel/generator": "^7.24.6",
- "@babel/helper-environment-visitor": "^7.24.6",
- "@babel/helper-function-name": "^7.24.6",
- "@babel/helper-hoist-variables": "^7.24.6",
- "@babel/helper-split-export-declaration": "^7.24.6",
- "@babel/parser": "^7.24.6",
- "@babel/types": "^7.24.6",
+ "@babel/code-frame": "^7.24.7",
+ "@babel/generator": "^7.24.7",
+ "@babel/helper-environment-visitor": "^7.24.7",
+ "@babel/helper-function-name": "^7.24.7",
+ "@babel/helper-hoist-variables": "^7.24.7",
+ "@babel/helper-split-export-declaration": "^7.24.7",
+ "@babel/parser": "^7.24.7",
+ "@babel/types": "^7.24.7",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -441,14 +446,14 @@
}
},
"node_modules/@babel/types": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.6.tgz",
- "integrity": "sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz",
+ "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-string-parser": "^7.24.6",
- "@babel/helper-validator-identifier": "^7.24.6",
+ "@babel/helper-string-parser": "^7.24.7",
+ "@babel/helper-validator-identifier": "^7.24.7",
"to-fast-properties": "^2.0.0"
},
"engines": {
@@ -3095,21 +3100,21 @@
}
},
"node_modules/@rollup/plugin-commonjs": {
- "version": "25.0.8",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.8.tgz",
- "integrity": "sha512-ZEZWTK5n6Qde0to4vS9Mr5x/0UZoqCxPVR9KRUjU4kA2sO7GEUn1fop0DAwpO6z0Nw/kJON9bDmSxdWxO/TT1A==",
+ "version": "26.0.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-26.0.1.tgz",
+ "integrity": "sha512-UnsKoZK6/aGIH6AdkptXhNvhaqftcjq3zZdT+LY5Ftms6JR06nADcDsYp5hTU9E2lbJUEOhdlY5J4DNTneM+jQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@rollup/pluginutils": "^5.0.1",
"commondir": "^1.0.1",
"estree-walker": "^2.0.2",
- "glob": "^8.0.3",
+ "glob": "^10.4.1",
"is-reference": "1.2.1",
"magic-string": "^0.30.3"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=16.0.0 || 14 >= 14.17"
},
"peerDependencies": {
"rollup": "^2.68.0||^3.0.0||^4.0.0"
@@ -3131,36 +3136,52 @@
}
},
"node_modules/@rollup/plugin-commonjs/node_modules/glob": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
- "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "version": "10.4.1",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz",
+ "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==",
"dev": true,
"license": "ISC",
"dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^5.0.1",
- "once": "^1.3.0"
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
},
"engines": {
- "node": ">=12"
+ "node": ">=16 || 14 >=14.18"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@rollup/plugin-commonjs/node_modules/minimatch": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
- "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "version": "9.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
+ "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
- "node": ">=10"
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@rollup/plugin-commonjs/node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
}
},
"node_modules/@rollup/plugin-node-resolve": {
@@ -3190,9 +3211,9 @@
}
},
"node_modules/@rollup/plugin-replace": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.5.tgz",
- "integrity": "sha512-rYO4fOi8lMaTg/z5Jb+hKnrHHVn8j2lwkqwyS4kTRhKyWOLf2wST2sWXr4WzWiTcoHTp2sTjqUbqIj2E39slKQ==",
+ "version": "5.0.7",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.7.tgz",
+ "integrity": "sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4422,9 +4443,9 @@
}
},
"node_modules/@zip.js/zip.js": {
- "version": "2.7.44",
- "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.44.tgz",
- "integrity": "sha512-ZzMhAcAyRAYi1FZELsvKaw8I4ADxNTqbiVIjyo/syBe4HGWop9+OADnuBnHpm2TxgXPogxxhhPffOhDD40jUdA==",
+ "version": "2.7.45",
+ "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.45.tgz",
+ "integrity": "sha512-Mm2EXF33DJQ/3GWWEWeP1UCqzpQ5+fiMvT3QWspsXY05DyqqxWu7a9awSzU4/spHMHVFrTjani1PR0vprgZpow==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
@@ -5177,9 +5198,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.23.0",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
- "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
+ "version": "4.23.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz",
+ "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==",
"dev": true,
"funding": [
{
@@ -5197,10 +5218,10 @@
],
"license": "MIT",
"dependencies": {
- "caniuse-lite": "^1.0.30001587",
- "electron-to-chromium": "^1.4.668",
+ "caniuse-lite": "^1.0.30001629",
+ "electron-to-chromium": "^1.4.796",
"node-releases": "^2.0.14",
- "update-browserslist-db": "^1.0.13"
+ "update-browserslist-db": "^1.0.16"
},
"bin": {
"browserslist": "cli.js"
@@ -5298,7 +5319,6 @@
"version": "9.2.4",
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz",
"integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.3.4",
@@ -5452,9 +5472,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001621",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001621.tgz",
- "integrity": "sha512-+NLXZiviFFKX0fk8Piwv3PfLPGtRqJeq2TiNoUff/qB5KJgwecJTvCXDpmlyP/eCI/GUEmp/h/y5j0yckiiZrA==",
+ "version": "1.0.30001632",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001632.tgz",
+ "integrity": "sha512-udx3o7yHJfUxMLkGohMlVHCvFvWmirKh9JAH/d7WOLPetlH+LTL5cocMZ0t7oZx/mdlOWXti97xLZWc8uURRHg==",
"dev": true,
"funding": [
{
@@ -6236,9 +6256,9 @@
}
},
"node_modules/electron": {
- "version": "30.0.8",
- "resolved": "https://registry.npmjs.org/electron/-/electron-30.0.8.tgz",
- "integrity": "sha512-ivzXJJ/9gdb4oOw+5SDuaZpSInz8C+Z021dKZfFLMltKbDa4sSqt5cRBiUg7J36Z2kdus+Jai0bdHWutYE9wAA==",
+ "version": "30.1.0",
+ "resolved": "https://registry.npmjs.org/electron/-/electron-30.1.0.tgz",
+ "integrity": "sha512-9O8m7kinjwMH5Df0hpXbwUaqI6pk3aJm1sKQUkQGCF7NDbNkGhu2BXgqaicPU6oe26zQPc5vtwWnHmiKlh1hYA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -6420,9 +6440,9 @@
}
},
"node_modules/electron-log": {
- "version": "5.1.4",
- "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-5.1.4.tgz",
- "integrity": "sha512-P0RSXnwT3z+e89Z5uAcZDeN85/QjIgv764a93kqCi+wh2Jm22CCbc3AGDt4S8rsxAHWHB4Q0PGsQl3fw1AN0kQ==",
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-5.1.5.tgz",
+ "integrity": "sha512-vuq10faUAxRbILgQx7yHoMObKZDEfj7hMSZrJPsVrDNeCpV/HN11dU7QuY4UDUe055pzBxhSCB3m0+6D3Aktjw==",
"license": "MIT",
"engines": {
"node": ">= 14"
@@ -6549,19 +6569,19 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.783",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.783.tgz",
- "integrity": "sha512-bT0jEz/Xz1fahQpbZ1D7LgmPYZ3iHVY39NcWWro1+hA2IvjiPeaXtfSqrQ+nXjApMvQRE2ASt1itSLRrebHMRQ==",
+ "version": "1.4.796",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.796.tgz",
+ "integrity": "sha512-NglN/xprcM+SHD2XCli4oC6bWe6kHoytcyLKCWXmRL854F0qhPhaYgUswUsglnPxYaNQIg2uMY4BvaomIf3kLA==",
"dev": true,
"license": "ISC"
},
"node_modules/electron-updater": {
- "version": "6.1.8",
- "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.1.8.tgz",
- "integrity": "sha512-hhOTfaFAd6wRHAfUaBhnAOYc+ymSGCWJLtFkw4xJqOvtpHmIdNHnXDV9m1MHC+A6q08Abx4Ykgyz/R5DGKNAMQ==",
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.2.1.tgz",
+ "integrity": "sha512-83eKIPW14qwZqUUM6wdsIRwVKZyjmHxQ4/8G+1C6iS5PdDt7b1umYQyj1/qPpH510GmHEQe4q0kCPe3qmb3a0Q==",
"license": "MIT",
"dependencies": {
- "builder-util-runtime": "9.2.3",
+ "builder-util-runtime": "9.2.4",
"fs-extra": "^10.1.0",
"js-yaml": "^4.1.0",
"lazy-val": "^1.0.5",
@@ -6571,19 +6591,6 @@
"tiny-typed-emitter": "^2.1.0"
}
},
- "node_modules/electron-updater/node_modules/builder-util-runtime": {
- "version": "9.2.3",
- "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.3.tgz",
- "integrity": "sha512-FGhkqXdFFZ5dNC4C+yuQB9ak311rpGAw+/ASz8ZdxwODCv1GGMWgLDeofRkdi0F3VCHQEWy/aXcJQozx2nOPiw==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.4",
- "sax": "^1.2.4"
- },
- "engines": {
- "node": ">=12.0.0"
- }
- },
"node_modules/electron-updater/node_modules/fs-extra": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
@@ -6863,9 +6870,9 @@
}
},
"node_modules/eslint-plugin-lit": {
- "version": "1.13.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-lit/-/eslint-plugin-lit-1.13.0.tgz",
- "integrity": "sha512-vKc67q6YQ+naYO1QuFpqMoTs3535yp8+0WB/8bzZRLr5NSOb4C6vZrD4se7S9XZtym5TxSVlIqa9QTWYISykQg==",
+ "version": "1.14.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-lit/-/eslint-plugin-lit-1.14.0.tgz",
+ "integrity": "sha512-J4w+CgO31621GreLFCdTUbTr5yeV2/RJ/M0myw0dykD5p9FGGIRLityQiNa6SG+JpVbmeQTQPJy4pNFmiurJ/w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -9815,9 +9822,9 @@
}
},
"node_modules/prosemirror-model": {
- "version": "1.21.0",
- "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.21.0.tgz",
- "integrity": "sha512-zLpS1mVCZLA7VTp82P+BfMiYVPcX1/z0Mf3gsjKZtzMWubwn2pN7CceMV0DycjlgE5JeXPR7UF4hJPbBV98oWA==",
+ "version": "1.21.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.21.1.tgz",
+ "integrity": "sha512-IVBAuMqOfltTr7yPypwpfdGT+6rGAteVOw2FO6GEvCGGa1ZwxLseqC1Eax/EChDvG/xGquB2d/hLdgh3THpsYg==",
"license": "MIT",
"dependencies": {
"orderedmap": "^2.0.0"
@@ -9833,9 +9840,9 @@
}
},
"node_modules/prosemirror-schema-list": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.3.0.tgz",
- "integrity": "sha512-Hz/7gM4skaaYfRPNgr421CU4GSwotmEwBVvJh5ltGiffUJwm7C8GfN/Bc6DR1EKEp5pDKhODmdXXyi9uIsZl5A==",
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.4.0.tgz",
+ "integrity": "sha512-nZOIq/AkBSzCENxUyLm5ltWE53e2PLk65ghMN8qLQptOmDVixZlPqtMeQdiNw0odL9vNpalEjl3upgRkuJ/Jyw==",
"license": "MIT",
"dependencies": {
"prosemirror-model": "^1.0.0",
@@ -9904,9 +9911,9 @@
}
},
"node_modules/prosemirror-view": {
- "version": "1.33.6",
- "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.6.tgz",
- "integrity": "sha512-zRLUNgLIQfd8IfGprsXxWTjdA8xEAFJe8cDNrOptj6Mop9sj+BMeVbJvceyAYCm5G2dOdT2prctH7K9dfnpIMw==",
+ "version": "1.33.7",
+ "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.7.tgz",
+ "integrity": "sha512-jo6eMQCtPRwcrA2jISBCnm0Dd2B+szS08BU1Ay+XGiozHo5EZMHfLQE8R5nO4vb1spTH2RW1woZIYXRiQsuP8g==",
"license": "MIT",
"dependencies": {
"prosemirror-model": "^1.20.0",
@@ -10563,9 +10570,9 @@
}
},
"node_modules/sass": {
- "version": "1.77.2",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.2.tgz",
- "integrity": "sha512-eb4GZt1C3avsX3heBNlrc7I09nyT00IUuo4eFhAbeXWU2fvA7oXI53SxODVAA+zgZCk9aunAZgO+losjR3fAwA==",
+ "version": "1.77.4",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.4.tgz",
+ "integrity": "sha512-vcF3Ckow6g939GMA4PeU7b2K/9FALXk2KF9J87txdHzXbUF9XRQRwSxcAs/fGaTnJeBFd7UoV22j3lzMLdM0Pw==",
"license": "MIT",
"dependencies": {
"chokidar": ">=3.0.0 <4.0.0",
diff --git a/package.json b/package.json
index 28a12522..a83424a4 100644
--- a/package.json
+++ b/package.json
@@ -50,9 +50,9 @@
"crypto-js": "4.2.0",
"driver.js": "1.3.1",
"electron-dl": "3.5.2",
- "electron-log": "5.1.4",
+ "electron-log": "5.1.5",
"electron-store": "8.2.0",
- "electron-updater": "6.1.8",
+ "electron-updater": "6.2.1",
"emoji-picker-js": "https://github.com/Qortal/emoji-picker-js",
"extract-zip": "2.0.1",
"jssha": "3.3.1",
@@ -64,17 +64,17 @@
"prosemirror-gapcursor": "1.3.2",
"prosemirror-history": "1.4.0",
"prosemirror-keymap": "1.2.2",
- "prosemirror-model": "1.21.0",
- "prosemirror-schema-list": "1.3.0",
+ "prosemirror-model": "1.21.1",
+ "prosemirror-schema-list": "1.4.0",
"prosemirror-state": "1.4.3",
"prosemirror-transform": "1.9.0",
- "prosemirror-view": "1.33.6",
- "sass": "1.77.2",
+ "prosemirror-view": "1.33.7",
+ "sass": "1.77.4",
"short-unique-id": "5.2.0",
"xhr2": "0.2.1"
},
"devDependencies": {
- "@babel/core": "7.24.6",
+ "@babel/core": "7.24.7",
"@electron/packager": "18.3.2",
"@material/mwc-button": "0.27.0",
"@material/mwc-checkbox": "0.27.0",
@@ -114,9 +114,9 @@
"@qortal/rollup-plugin-web-worker-loader": "1.6.5",
"@rollup/plugin-alias": "5.1.0",
"@rollup/plugin-babel": "6.0.4",
- "@rollup/plugin-commonjs": "25.0.8",
+ "@rollup/plugin-commonjs": "26.0.1",
"@rollup/plugin-node-resolve": "15.2.3",
- "@rollup/plugin-replace": "5.0.5",
+ "@rollup/plugin-replace": "5.0.7",
"@rollup/plugin-terser": "0.4.4",
"@vaadin/avatar": "24.2.9",
"@vaadin/button": "24.2.9",
@@ -127,13 +127,13 @@
"@vaadin/tabs": "24.2.9",
"@vaadin/tabsheet": "24.2.9",
"@vaadin/tooltip": "24.2.9",
- "@zip.js/zip.js": "2.7.44",
+ "@zip.js/zip.js": "2.7.45",
"axios": "1.7.2",
- "electron": "30.0.8",
+ "electron": "30.1.0",
"electron-builder": "24.13.3",
"epml": "0.3.3",
"eslint": "8.57.0",
- "eslint-plugin-lit": "1.13.0",
+ "eslint-plugin-lit": "1.14.0",
"eslint-plugin-wc": "2.1.0",
"file-saver": "2.0.5",
"highcharts": "11.1.0",
diff --git a/plugins/plugins/core/components/ChatPage.js b/plugins/plugins/core/components/ChatPage.js
index b6047770..37ddece1 100644
--- a/plugins/plugins/core/components/ChatPage.js
+++ b/plugins/plugins/core/components/ChatPage.js
@@ -1045,7 +1045,7 @@ class ChatPage extends LitElement {
}
},
- "Shift-Enter": () => {
+ 'Shift-Enter': () => {
if (this.isEnabledChatEnter) {
this.editor.commands.first(() => [
this.editor.commands.newlineInCode()
@@ -1079,6 +1079,13 @@ class ChatPage extends LitElement {
type: 'image'
})
return true
+ },
+ 'Shift-Enter': () => {
+ if (this.isEnabledChatEnter) {
+ this.editor.commands.first(() => [
+ this.editor.commands.newlineInCode()
+ ])
+ }
}
}
}
@@ -1107,6 +1114,13 @@ class ChatPage extends LitElement {
type: 'gif'
})
return true
+ },
+ 'Shift-Enter': () => {
+ if (this.isEnabledChatEnter) {
+ this.editor.commands.first(() => [
+ this.editor.commands.newlineInCode()
+ ])
+ }
}
}
}
@@ -1135,6 +1149,13 @@ class ChatPage extends LitElement {
type: 'attachment'
})
return true
+ },
+ 'Shift-Enter': () => {
+ if (this.isEnabledChatEnter) {
+ this.editor.commands.first(() => [
+ this.editor.commands.newlineInCode()
+ ])
+ }
}
}
}
@@ -1163,6 +1184,13 @@ class ChatPage extends LitElement {
type: 'file'
})
return true
+ },
+ 'Shift-Enter': () => {
+ if (this.isEnabledChatEnter) {
+ this.editor.commands.first(() => [
+ this.editor.commands.newlineInCode()
+ ])
+ }
}
}
}
@@ -1312,7 +1340,6 @@ class ChatPage extends LitElement {
}
}
}
-
}
async goToRepliedMessage(message, clickedOnMessage) {
diff --git a/plugins/plugins/core/components/ChatTextEditor.js b/plugins/plugins/core/components/ChatTextEditor.js
index 805fdd99..ad50baf0 100644
--- a/plugins/plugins/core/components/ChatTextEditor.js
+++ b/plugins/plugins/core/components/ChatTextEditor.js
@@ -167,7 +167,13 @@ class ChatTextEditor extends LitElement {
}
` : html`
-
+
${this.isLoading === false
? html`
![send-icon](/img/qchat-send-message-icon.svg)
{this.sendMessageFunc(this.messageQueue)}}>
diff --git a/plugins/plugins/core/components/plugins-css.js b/plugins/plugins/core/components/plugins-css.js
index b5c570db..9de78759 100644
--- a/plugins/plugins/core/components/plugins-css.js
+++ b/plugins/plugins/core/components/plugins-css.js
@@ -3818,12 +3818,6 @@ export const chatTextEditorStyles = css`
cursor: pointer;
}
- .ProseMirror {
- word-wrap: break-word;
- white-space: pre-wrap;
- white-space: break-spaces;
- }
-
.ProseMirror:focus {
outline: none;
}
@@ -7744,6 +7738,14 @@ export const groupManagementStyles = css`
margin: 12px 0 -6px 0;
}
+ .actions-chat {
+ display: flex;
+ justify-content: space-between;
+ padding: 0 1em;
+ margin: 12px 0 -6px 0;
+ position: fixed;
+ }
+
.card-container {
background-color: var(--white);
border-radius: 5px;
@@ -7774,6 +7776,16 @@ export const groupManagementStyles = css`
opacity: .6;
}
+ .close-icon-chat {
+ font-size: 36px;
+ margin-top: -8px;
+ }
+
+ .close-icon-chat:hover {
+ cursor: pointer;
+ opacity: .6;
+ }
+
.buttons {
text-align: right;
}
@@ -8039,6 +8051,460 @@ export const groupManagementStyles = css`
margin: auto;
align-items: center;
}
+
+ .message-container {
+ position: relative;
+ }
+
+ .message-subcontainer1 {
+ position: relative;
+ display: flex;
+ align-items: flex-end;
+ margin-top: 10px;
+ }
+
+ .message-subcontainer2 {
+ position: relative;
+ display: flex;
+ background-color: var(--chat-bubble-bg);
+ flex-grow: 0;
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: center;
+ border-radius: 5px;
+ padding: 12px 15px 4px 15px;
+ width: fit-content;
+ min-width: 150px;
+ }
+
+ .message-subcontainer2-mybg {
+ position: relative;
+ display: flex;
+ background-color: var(--chat-bubble-myBg);
+ flex-grow: 0;
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: center;
+ border-radius: 5px;
+ padding: 12px 15px 4px 15px;
+ width: fit-content;
+ min-width: 150px;
+ }
+
+ .message-triangle {
+ position: relative;
+ }
+
+ .message-triangle:after {
+ content: "";
+ position: absolute;
+ bottom: 0px;
+ left: -9px;
+ width: 0;
+ height: 0;
+ border-style: solid;
+ border-width: 0px 0px 7px 9px;
+ border-color: transparent transparent var(--chat-bubble-bg) transparent;
+ }
+
+ .message-triangle-mybg {
+ position: relative;
+ }
+
+ .message-triangle-mybg:after {
+ content: "";
+ position: absolute;
+ bottom: 0px;
+ left: -9px;
+ width: 0;
+ height: 0;
+ border-style: solid;
+ border-width: 0px 0px 7px 9px;
+ border-color: transparent transparent var(--chat-bubble-myBg) transparent;
+ }
+
+ .message-user-info {
+ display: flex;
+ justify-content: space-between;
+ width: 100%;
+ gap: 10px;
+ }
+
+ .message-data-name {
+ user-select: none;
+ color: var(--qchat-name);
+ margin-bottom: 5px;
+ }
+
+ .message-data-my-name {
+ user-select: none;
+ color: var(--qchat-my-name);
+ margin-bottom: 5px;
+ }
+
+ .message-avatar {
+ margin: 0px 5px 0px 0px;
+ width: 42px;
+ height: 42px;
+ border-radius: 25%;
+ float: left;
+ }
+
+ .message {
+ display: flex;
+ flex-direction: column;
+ color: var(--chat-bubble-msg-color);
+ line-height: 19px;
+ overflow-wrap: anywhere;
+ margin-top: 5px;
+ -webkit-user-select: text;
+ -moz-user-select: text;
+ -ms-user-select: text;
+ user-select: text;
+ font-size: 16px;
+ width: 100%;
+ position: relative;
+ }
+
+ .message p {
+ margin: 0px;
+ padding: 0px;
+ }
+
+ .original-message {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ color: var(--chat-bubble-msg-color);
+ line-height: 19px;
+ user-select: text;
+ font-size: 15px;
+ width: 90%;
+ border-radius: 5px;
+ padding: 8px 5px 8px 25px;
+ margin-bottom: 10px;
+ cursor: pointer;
+ }
+
+ .original-message:before {
+ content: "";
+ position: absolute;
+ top: 5px;
+ left: 10px;
+ height: 75%;
+ width: 2.6px;
+ background-color: var(--mdc-theme-primary);
+ }
+
+ .original-message-sender {
+ color: var(--mdc-theme-primary);
+ }
+
+ .original-message-sender-wasme {
+ color: var(--qchat-my-name);
+ }
+
+ .replied-message {
+ margin: 0;
+ padding: 0;
+ }
+
+ .replied-message p {
+ margin: 0;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 500px;
+ max-height: 40px;
+ margin: 0;
+ padding: 0;
+ }
+
+ .image-container {
+ display: flex;
+ }
+
+ .chat-img {
+ max-width: 45vh;
+ max-height: 40vh;
+ border-radius: 5px;
+ position: relative;
+ }
+
+ .chat-replied-img {
+ max-width: 30vh;
+ max-height: 25vh;
+ border-radius: 5px;
+ position: relative;
+ }
+
+ .defaultSize {
+ width: 45vh;
+ height: 40vh;
+ }
+
+ .attachment-container {
+ display: flex;
+ align-items: center;
+ justify-content: space-evenly;
+ padding: 5px 0 10px 0;
+ gap: 20px;
+ }
+
+ .attachment-icon-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ height: 52px;
+ width: 52px;
+ border-radius: 50%;
+ border: none;
+ background-color: var(--mdc-theme-primary);
+ }
+
+ .attachment-icon {
+ height: 42px;
+ width: 42px;
+ }
+
+ .file-container {
+ display: flex;
+ align-items: center;
+ justify-content: space-evenly;
+ padding: 5px 0 10px 0;
+ gap: 20px;
+ }
+
+ .file-icon-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ height: 52px;
+ width: 52px;
+ border-radius: 50%;
+ border: none;
+ background-color: transparent;
+ }
+
+ .file-icon {
+ height: 52px;
+ width: 52px;
+ }
+
+ .attachment-info {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+ }
+
+ .attachment-name {
+ font-family: Work Sans, sans-serif;
+ font-size: 16px;
+ color: var(--chat-bubble-msg-color);
+ margin: 0;
+ letter-spacing: 0.3px;
+ padding: 5px 0;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ .attachment-deleted {
+ font-family: Work Sans, sans-serif;
+ font-style: italic;
+ font-size: 16px;
+ color: var(--chat-bubble-msg-color);
+ margin: 0;
+ letter-spacing: 0.4px;
+ padding: 5px 0;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ .attachment-size {
+ font-family: Work Sans, sans-serif;
+ font-style: italic;
+ font-size: 16px;
+ color: var(--chat-bubble-msg-color);
+ margin: 0;
+ letter-spacing: 0.3px;
+ font-weight: 300;
+ }
+
+ .message-data-time {
+ color: #888888;
+ font-size: 13px;
+ user-select: none;
+ display: flex;
+ justify-content: flex-end;
+ width: 100%;
+ padding-top: 2px;
+ }
+
+ .message-data-time-edited {
+ color: #888888;
+ font-size: 13px;
+ user-select: none;
+ display: flex;
+ justify-content: space-between;
+ width: 100%;
+ padding-top: 2px;
+ }
+
+ .message-data-forward {
+ user-select: none;
+ color: var(--general-color-blue);
+ margin-bottom: 5px;
+ font-size: 12px;
+ }
+
+ .message-data-edited {
+ font-family: "Work Sans", sans-serif;
+ font-style: italic;
+ font-size: 13px;
+ visibility: visible;
+ }
+
+ .no-messages {
+ color: var(--black);
+ font-weight: 500;
+ font-size: 32px;
+ text-align: center;
+ margin: 0;
+ }
+
+ paper-dialog.info {
+ width: 100%;
+ max-width: 75vw;
+ height: 100%;
+ max-height: 75vh;
+ background-color: var(--white);
+ color: var(--black);
+ border: 1px solid var(--black);
+ border-radius: 15px;
+ overflow: hidden;
+ }
+
+ paper-dialog.progress {
+ width: auto;
+ max-width: 50vw;
+ height: auto;
+ max-height: 30vh;
+ background-color: var(--white);
+ color: var(--black);
+ border: 1px solid var(--black);
+ border-radius: 15px;
+ text-align: center;
+ padding: 15px;
+ line-height: 1.6;
+ overflow: hidden;
+ }
+
+ .lds-roller {
+ display: inline-block;
+ position: relative;
+ width: 80px;
+ height: 80px;
+ }
+
+ .lds-roller div {
+ animation: lds-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
+ transform-origin: 40px 40px;
+ }
+
+ .lds-roller div:after {
+ content: " ";
+ display: block;
+ position: absolute;
+ width: 7px;
+ height: 7px;
+ border-radius: 50%;
+ background: var(--black);
+ margin: -4px 0 0 -4px;
+ }
+
+ .lds-roller div:nth-child(1) {
+ animation-delay: -0.036s;
+ }
+
+ .lds-roller div:nth-child(1):after {
+ top: 63px;
+ left: 63px;
+ }
+
+ .lds-roller div:nth-child(2) {
+ animation-delay: -0.072s;
+ }
+
+ .lds-roller div:nth-child(2):after {
+ top: 68px;
+ left: 56px;
+ }
+
+ .lds-roller div:nth-child(3) {
+ animation-delay: -0.108s;
+ }
+
+ .lds-roller div:nth-child(3):after {
+ top: 71px;
+ left: 48px;
+ }
+
+ .lds-roller div:nth-child(4) {
+ animation-delay: -0.144s;
+ }
+
+ .lds-roller div:nth-child(4):after {
+ top: 72px;
+ left: 40px;
+ }
+
+ .lds-roller div:nth-child(5) {
+ animation-delay: -0.18s;
+ }
+
+ .lds-roller div:nth-child(5):after {
+ top: 71px;
+ left: 32px;
+ }
+
+ .lds-roller div:nth-child(6) {
+ animation-delay: -0.216s;
+ }
+
+ .lds-roller div:nth-child(6):after {
+ top: 68px;
+ left: 24px;
+ }
+
+ .lds-roller div:nth-child(7) {
+ animation-delay: -0.252s;
+ }
+
+ .lds-roller div:nth-child(7):after {
+ top: 63px;
+ left: 17px;
+ }
+
+ .lds-roller div:nth-child(8) {
+ animation-delay: -0.288s;
+ }
+
+ .lds-roller div:nth-child(8):after {
+ top: 56px;
+ left: 12px;
+ }
+
+ @keyframes lds-roller {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
`
export const mintingInfoStyles = css`
diff --git a/plugins/plugins/core/group-management/group-management.src.js b/plugins/plugins/core/group-management/group-management.src.js
index fe313238..85ea515e 100644
--- a/plugins/plugins/core/group-management/group-management.src.js
+++ b/plugins/plugins/core/group-management/group-management.src.js
@@ -1,8 +1,15 @@
import { html, LitElement } from 'lit'
import { render } from 'lit/html.js'
+import { unsafeHTML } from 'lit/directives/unsafe-html.js'
import { Epml } from '../../../epml'
+import { generateHTML } from '@tiptap/core'
+import { roundToNearestDecimal } from '../../utils/functions'
import { groupManagementStyles } from '../components/plugins-css'
import isElectron from 'is-electron'
+import Highlight from '@tiptap/extension-highlight'
+import ShortUniqueId from 'short-unique-id'
+import StarterKit from '@tiptap/starter-kit'
+import Underline from '@tiptap/extension-underline'
import '../components/time-elements/index'
import '@material/mwc-button'
import '@material/mwc-dialog'
@@ -93,7 +100,11 @@ class GroupManagement extends LitElement {
haveName: { type: Boolean },
myName: { type: String },
haveGoName: { type: Boolean },
- goName: { type: String }
+ goName: { type: String },
+ chatMessageArray: { type: Array },
+ chatInfoName: { type: String },
+ chatInfoId: { type: String },
+ chatInfoMembers: { type: String }
}
}
@@ -159,6 +170,10 @@ class GroupManagement extends LitElement {
this.myName = ''
this.haveGoName = false
this.goName = ''
+ this.chatMessageArray = []
+ this.chatInfoName = ''
+ this.chatInfoId = ''
+ this.chatInfoMembers = ''
this.selectedView = { id: 'group-members', name: 'Group Members' }
}
@@ -167,11 +182,16 @@ class GroupManagement extends LitElement {
${translate("grouppage.gchange1")}
-
- this.shadowRoot.querySelector('#createGroupDialog').show()}>
- add
- ${translate("grouppage.gchange2")}
-
+
+ this.shadowRoot.querySelector('#createGroupDialog').show()}>
+ add
+ ${translate("grouppage.gchange2")}
+
+ this.openPreviewGeneral()}>
+ pageview
+ ${translate("general.view")} Qortal General Chat
+
+
${translate("grouppage.gchange55")}
@@ -197,6 +217,10 @@ class GroupManagement extends LitElement {
+ {
+ await this.getChatMessageCount(data.item)
+ render(html`${this.countArray.length}`, root)
+ }}>
{
if (data.item.isOpen === true) {
@@ -207,7 +231,7 @@ class GroupManagement extends LitElement {
}}>
- {
+ {
render(html`
this.openJoinGroup(data.item)}>
queue
@@ -215,20 +239,40 @@ class GroupManagement extends LitElement {
`, root)
}}>
+ {
+ render(html`
+ this.openPreviewChat(data.item)}>
+ pageview
+ ${translate("general.view")}
+
+ `, root)
+ }}>
${translate("grouppage.gchange3")}
+ {
+ await this.getChatMessageCount(data.item)
+ render(html`${this.countArray.length}`, root)
+ }}>
{
render(html`${this.renderRole(data.item)}`, root)
}}>
- {
+ {
render(html`${this.renderManageButton(data.item)}`, root)
}}>
+ {
+ render(html`
+ this.openPreviewChat(data.item)}>
+ pageview
+ ${translate("general.view")}
+
+ `, root)
+ }}>
${this.isEmptyArray(this.joinedGroups) ? html`
@@ -240,6 +284,10 @@ class GroupManagement extends LitElement {
${translate("managegroup.mg36")}
+ {
+ await this.getChatMessageCount(data.item)
+ render(html`${this.countArray.length}`, root)
+ }}>
{
if (data.item.isOpen === true) {
@@ -252,7 +300,7 @@ class GroupManagement extends LitElement {
const expiryString = new Date(data.item.expiry).toLocaleString()
render(html`${expiryString}`, root)
}}>
- {
+ {
render(html`
this.openJoinGroup(data.item)}>
queue
@@ -260,6 +308,14 @@ class GroupManagement extends LitElement {
`, root)
}}>
+ {
+ render(html`
+ this.openPreviewChat(data.item)}>
+ pageview
+ ${translate("general.view")}
+
+ `, root)
+ }}>
${this.isEmptyArray(this.groupInvites) ? html`
@@ -287,7 +343,7 @@ class GroupManagement extends LitElement {
- {
+ {
render(html`
this.openJoinGroup(data.item)}>
queue
@@ -295,6 +351,14 @@ class GroupManagement extends LitElement {
`, root)
}}>
+ {
+ render(html`
+ this.openPreviewChat(data.item)}>
+ pageview
+ ${translate("general.view")}
+
+ `, root)
+ }}>
${this.isEmptyArray(this.publicGroups) ? html`
${translate("grouppage.gchange11")}
@@ -607,6 +671,52 @@ class GroupManagement extends LitElement {
+
+
+
+
${translate("grouppage.gchange4")}: ${this.chatInfoName} / ${translate("managegroup.mg8")}: ${this.chatInfoId} / ${translate("grouppage.gchange54")}: ${this.chatInfoMembers}
+
+ this.shadowRoot.getElementById('chat-container').scrollIntoView({
+ block: 'end',
+ behavior: 'smooth'
+ })}
+ title="${translate("managegroup.mg5")}"
+ >
+ arrow_circle_down
+
+ this.shadowRoot.getElementById('chat-container').scrollIntoView({
+ block: 'start',
+ behavior: 'smooth'
+ })}
+ title="${translate("managegroup.mg5")}"
+ >
+ arrow_circle_up
+
+ this.closePreviewChat()} title="${translate("managegroup.mg5")}">highlight_off
+
+
+
+
+
+
+
+ ${translate("chatpage.cchange2")}
+
`
}
@@ -744,7 +854,7 @@ class GroupManagement extends LitElement {
if (sideEffectAction && sideEffectAction.type === 'openJoinGroupModal') {
const res = await getGroupInfo(sideEffectAction.data)
if (res && res.groupId) {
- this.joinGroup(res)
+ this.openJoinGroup(res)
}
window.parent.reduxStore.dispatch(
window.parent.reduxAction.setSideEffectAction(null)
@@ -2495,21 +2605,22 @@ class GroupManagement extends LitElement {
}
async getNewGroupInvitesList(theGroup) {
- let callGroupID = theGroup
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
+ let callGroupID = theGroup
let inviteObj = []
this.groupInviteMembers = []
+ this.newGroupInvitesList = []
await parentEpml.request('apiCall', {
url: `/groups/invites/group/${callGroupID}`
}).then(res => {
- this.groupInviteMembers = res
+ this.groupInviteMembers = res.filter((item) => item.expiry > Date.now())
})
- if (this.groupInviteMembers.length === 0) {
-
+ if (this.isEmptyArray(this.groupInviteMembers)) {
+ // Nothing to do because no open invites
} else {
this.groupInviteMembers.map(a => {
let callTheInviteMember = a.invitee
@@ -2593,8 +2704,14 @@ class GroupManagement extends LitElement {
}
closeManageGroupOwnerDialog() {
- this.resetDefaultSettings()
+ this.manageGroupId = ''
+ this.theGroupOwner = ''
+ this.manageGroupName = ''
+ this.manageGroupCount = ''
+ this.manageGroupType = ''
this.shadowRoot.getElementById('manageGroupOwnerDialog').close()
+ this.resetDefaultSettings()
+
window.location.reload()
}
@@ -2605,13 +2722,17 @@ class GroupManagement extends LitElement {
}
async manageGroupOwner(groupObj) {
+ this.shadowRoot.getElementById('downloadProgressDialog').open()
+ const manageGroupDelay = ms => new Promise(res => setTimeout(res, ms))
+
+ let intervalInvites
+
this.manageGroupId = ''
this.theGroupOwner = ''
this.manageGroupName = ''
this.manageGroupCount = ''
this.manageGroupType = ''
this.manageGroupDescription = ''
- const manageGroupDelay = ms => new Promise(res => setTimeout(res, ms))
this.manageGroupObj = groupObj
this.manageGroupId = groupObj.groupId
this.theGroupOwner = groupObj.owner
@@ -2619,40 +2740,71 @@ class GroupManagement extends LitElement {
this.manageGroupCount = groupObj.memberCount
this.manageGroupType = groupObj.isOpen
this.manageGroupDescription = groupObj.description
+
await this.getNewMemberList(groupObj.groupId)
await this.getNewBannedList(groupObj.groupId)
await this.getNewGroupInvitesList(groupObj.groupId)
await this.getNewGroupJoinList(groupObj.groupId)
await this.getGoName(groupObj.owner)
await manageGroupDelay(1000)
+
this.shadowRoot.getElementById('manageGroupOwnerDialog').open()
+ this.shadowRoot.getElementById('downloadProgressDialog').close()
+
+ intervalInvites = setInterval(() => { this.getNewGroupInvitesList(this.manageGroupId) }, 300000)
}
async manageGroupAdmin(groupObj) {
+ this.shadowRoot.getElementById('downloadProgressDialog').open()
+ const manageGroupDelay = ms => new Promise(res => setTimeout(res, ms))
+
+ let intervalInvites
+
this.manageGroupId = ''
this.theGroupOwner = ''
this.manageGroupName = ''
this.manageGroupCount = ''
this.manageGroupType = ''
- const manageGroupDelay = ms => new Promise(res => setTimeout(res, ms))
this.manageGroupObj = groupObj
this.manageGroupId = groupObj.groupId
this.theGroupOwner = groupObj.owner
this.manageGroupName = groupObj.groupName
this.manageGroupCount = groupObj.memberCount
this.manageGroupType = groupObj.isOpen
+
await this.getNewMemberList(groupObj.groupId)
await this.getNewBannedList(groupObj.groupId)
await this.getNewGroupInvitesList(groupObj.groupId)
await this.getGoName(groupObj.owner)
await manageGroupDelay(1000)
+
this.shadowRoot.getElementById('manageGroupOwnerDialog').open()
+ this.shadowRoot.getElementById('downloadProgressDialog').close()
+
+ intervalInvites = setInterval(() => { this.getNewGroupInvitesList(this.manageGroupId) }, 300000)
}
- openJoinGroup(groupObj) {
- this.resetDefaultSettings()
- this.joinGroupObj = groupObj
- this.shadowRoot.querySelector('#joinDialog').show()
+ async openJoinGroup(groupObj) {
+ this.joinGroupObj = {}
+ let joinedHroups = []
+ let requestJoin
+
+ let resJoinedGroups = await parentEpml.request('apiCall', {
+ url: `/groups/member/${this.selectedAddress.address}`
+ })
+
+ joinedHroups = resJoinedGroups
+ requestJoin = groupObj.groupId
+
+ if (joinedHroups.find(item => item.groupId === requestJoin)) {
+ this.resetDefaultSettings()
+ let allreadyJoindedString = get('grouppage.gchange71')
+ parentEpml.request('showSnackBar', `${allreadyJoindedString}`)
+ } else {
+ this.resetDefaultSettings()
+ this.joinGroupObj = groupObj
+ this.shadowRoot.querySelector('#joinDialog').show()
+ }
}
openLeaveGroup(groupObj) {
@@ -2661,6 +2813,1124 @@ class GroupManagement extends LitElement {
this.shadowRoot.querySelector('#leaveDialog').show()
}
+ async openPreviewChat(groupObj) {
+ this.chatInfoName = groupObj.groupName
+ this.chatInfoId = groupObj.groupId
+ this.chatInfoMembers = groupObj.memberCount
+ this.shadowRoot.getElementById('downloadProgressDialog').open()
+ await this.getChatContent(groupObj.groupId)
+ }
+
+ async openPreviewGeneral() {
+ this.chatInfoName = 'Qortal General Chat'
+ this.chatInfoId = 0
+ this.chatInfoMembers = 'Everyone'
+ this.shadowRoot.getElementById('downloadProgressDialog').open()
+ await this.getChatContent(0)
+ }
+
+ closePreviewChat() {
+ this.shadowRoot.getElementById('chatInfoDialog').close()
+ this.chatInfoName = ''
+ this.chatInfoId = ''
+ this.chatInfoMembers = ''
+ this.chatMessageArray = []
+ this.shadowRoot.getElementById('chat-container').innerHTML = ''
+
+ if (this.webSocket) {
+ this.webSocket.close(1000, 'closed preview')
+ this.webSocket = ''
+ }
+ }
+
+ async getChatMessageCount(groupObj) {
+ this.countArray = []
+
+ let retChatArr = await parentEpml.request('apiCall', {
+ url: `/chat/messages?txGroupId=${groupObj.groupId}&haschatreference=false&encoding=BASE64&limit=0&reverse=false`
+ })
+
+ this.countArray = retChatArr
+ }
+
+ decodeMessage(string) {
+ const binaryString = atob(string)
+ const binaryLength = binaryString.length
+ const bytes = new Uint8Array(binaryLength)
+
+ for (let i = 0; i < binaryLength; i++) {
+ bytes[i] = binaryString.charCodeAt(i)
+ }
+
+ const decoder = new TextDecoder()
+ const decodedString = decoder.decode(bytes)
+ return decodedString
+ }
+
+ async getChatContent(involved) {
+ let chatArray = []
+ let decodedArray = []
+ this.chatMessageArray = []
+ this.firstMessageTimestamp = 0
+ const chatDelay = ms => new Promise(res => setTimeout(res, ms))
+
+ // Call the chat messages without chatreference ( without chatreference are messages in original )
+ let retChat = await parentEpml.request('apiCall', {
+ url: `/chat/messages?txGroupId=${involved}&haschatreference=false&encoding=BASE64&limit=0&reverse=false`
+ })
+
+ chatArray = retChat
+
+ // Decode the BASE64 Messagge and add to new array
+ chatArray.forEach(item => {
+ let decodedMessageObj = {}
+ let decodedMessage = this.decodeMessage(item.data)
+
+ const messageObj = {
+ timestamp: item.timestamp,
+ txGroupId: item.txGroupId,
+ reference: item.reference,
+ senderPublicKey: item.senderPublicKey,
+ sender: item.sender,
+ senderName: item.senderName,
+ encoding: item.encoding,
+ isText: item.isText,
+ isEncrypted: item.isEncrypted,
+ signature: item.signature
+ }
+
+ decodedMessageObj = { ...messageObj, decodedMessage }
+
+ decodedArray.push(decodedMessageObj)
+ })
+
+ // Set decoded array to new array
+ this.chatMessageArray = decodedArray
+
+ let chaEditedArray = []
+
+ // Call the chat messages with chatreference ( with chatreference means a message got edited )
+ let getEditedArray = await parentEpml.request('apiCall', {
+ url: `/chat/messages?txGroupId=${involved}&haschatreference=true&encoding=BASE64&limit=0&reverse=false`
+ })
+
+ chaEditedArray = getEditedArray
+
+ // Replace messages which got edited in the chatMessageArray
+ chaEditedArray.forEach(item => {
+ let editedDecodedMessage = ''
+ let editedSignature = ''
+
+ editedDecodedMessage = this.decodeMessage(item.data)
+ editedSignature = item.chatReference
+
+ const found = this.chatMessageArray.some(el => el.signature === editedSignature)
+
+ if (found) {
+ this.chatMessageArray.find(v => v.signature === editedSignature).decodedMessage = editedDecodedMessage
+ }
+ })
+
+ this.shadowRoot.getElementById('downloadProgressDialog').close()
+ this.shadowRoot.getElementById('chatInfoDialog').open()
+ this.shadowRoot.getElementById('chat-container').innerHTML = ''
+
+ // Render the chat messages from chatMessageArray
+ await this.renderChatMessagesGrid(this.chatMessageArray, false)
+ await chatDelay(250)
+
+ this.shadowRoot.getElementById('chat-container').scrollIntoView({
+ block: 'end',
+ behavior: 'smooth'
+ })
+
+ // Start the websocket for new messages
+ this.fetchChatMessages(involved)
+ }
+
+ async scrollChatToEnd() {
+ const scrollDelay = ms => new Promise(res => setTimeout(res, ms))
+
+ await scrollDelay(100)
+
+ this.shadowRoot.getElementById('chat-container').scrollIntoView({
+ block: 'end',
+ behavior: 'smooth'
+ })
+ }
+
+ renderChatMessagesGrid(renderArray, scroll) {
+ 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 chatGridContainer = this.shadowRoot.getElementById('chat-container')
+
+ let noMessagesString = get('grouppage.gchange70')
+ let forwardedString = get('blockpage.bcchange17')
+ let editedString = get('chatpage.cchange68')
+ let imageDeletedString = get('chatpage.cchange80')
+ let gifDeletedString = get('chatpage.cchange107')
+ let attachmentDeletedString = get('chatpage.cchange82')
+ let fileDeletedString = get('chatpage.cchange102')
+ let sizeString = get('websitespage.schange27')
+
+ if (this.shadowRoot.getElementById('chat-container').innerHTML === '') {
+ this.shadowRoot.getElementById('chat-container').innerHTML = ''
+ }
+
+ if (this.isEmptyArray(renderArray)) {
+ const chatEmpty = document.createElement('div')
+ chatEmpty.classList.add('no-messages')
+ chatEmpty.textContent = noMessagesString
+
+ chatGridContainer.appendChild(chatEmpty)
+ } else {
+ renderArray.forEach(item => {
+ const parsedMessageObj = JSON.parse(item.decodedMessage)
+
+ let chatID = ''
+ let messageID = ''
+ let messageTimeID = ''
+ let messageEditedID = ''
+ let messageImageID = ''
+ let messageGifID = ''
+ let messageAttachmentID = ''
+ let messageFileID = ''
+ let repliedID = ''
+ let repliedImageID = ''
+ let repliedGifID = ''
+ let repliedAttachmentID = ''
+ let repliedFileID = ''
+ let subcontainer1ID = ''
+ let subcontainer2ID = ''
+ let name = ''
+ let repliedName = ''
+ let messageAddress = ''
+ let repliedMessageAddress = ''
+ let repliedMessage = ''
+ let messageContent = ''
+ let imageLink = ''
+ let gifLink = ''
+ let attachmentLink = ''
+ let fileLink = ''
+ let attachmentName = ''
+ let fileName = ''
+ let attachmentSize = ''
+ let fileSize = ''
+ let repliedImageLink = ''
+ let repliedGifLink = ''
+ let repliedAttachmentLink = ''
+ let repliedFileLink = ''
+ let repliedAttachmentName = ''
+ let repliedFileName = ''
+ let repliedAttachmentSize = ''
+ let repliedFileSize = ''
+ let messageTimeString = ''
+ let haveImage = false
+ let haveGif = false
+ let haveAttachment = false
+ let haveFile = false
+ let haveRepliedImage = false
+ let haveRepliedGif = false
+ let haveRepliedAttachment = false
+ let haveRepliedFile = false
+ let hasImageDeleted = false
+ let hasGifDeleted = false
+ let hasAttachmentDeleted = false
+ let hasFileDeleted = false
+ let hasRepliedImageDeleted = false
+ let hasRepliedGifDeleted = false
+ let hasRepliedAttachmentDeleted = false
+ let hasRepliedFileDeleted = false
+ let isForwarded = false
+ let isEdited = false
+ let avatarFetches = 0
+ let imageFetches = 0
+ let repliedImageFetches = 0
+
+ messageTimeString = new Date(item.timestamp).toLocaleString()
+
+ if (item.senderName) {
+ name = item.senderName
+ messageAddress = item.sender
+ } else {
+ name = item.sender
+ messageAddress = item.sender
+ }
+
+ chatID = item.reference
+ messageID = item.signature
+ messageTimeID = 'time-' + item.signature
+ messageEditedID = 'edited-' + item.signature
+ messageImageID = 'image-' + item.signature
+ messageGifID = 'gif-' + item.signature
+ messageAttachmentID = 'attachment-' + item.signature
+ messageFileID = 'file-' + item.signature
+ subcontainer1ID = 'subcontainer1-' + item.signature
+ subcontainer2ID = 'subcontainer2-' + item.signature
+ isForwarded = parsedMessageObj.type === 'forward'
+ isEdited = parsedMessageObj.isEdited
+
+ if (parsedMessageObj.version > 1 && parsedMessageObj.messageText) {
+ messageContent = generateHTML(parsedMessageObj.messageText, [StarterKit, Underline, Highlight])
+ }
+
+ if (parsedMessageObj.repliedTo) {
+ let replied = this.chatMessageArray.filter(obj => {
+ return obj.signature === parsedMessageObj.repliedTo
+ })
+
+ replied.forEach(item => {
+ const parsedRepliedMessageObj = JSON.parse(item.decodedMessage)
+
+ if (item.senderName) {
+ repliedName = item.senderName
+ repliedMessageAddress = item.sender
+ } else {
+ repliedName = item.sender
+ repliedMessageAddress = item.sender
+ }
+
+ repliedID = item.reference
+ repliedImageID = 'repimage-' + item.signature
+ repliedGifID = 'repgif-' + item.signature
+ repliedAttachmentID = 'repattachment-' + item.signature
+ repliedFileID = 'repfile-' + item.signature
+
+ if (parsedRepliedMessageObj.isImageDeleted === false) {
+ haveRepliedImage = true
+ hasRepliedImageDeleted = false
+
+ parsedRepliedMessageObj.images.forEach(item => {
+ if (item.name) {
+ repliedImageLink = item.service + '/' + item.name + '/' + item.identifier
+ }
+ })
+ } else if (parsedRepliedMessageObj.isImageDeleted === true) {
+ haveRepliedImage = true
+ hasRepliedImageDeleted = true
+ }
+
+ if (parsedRepliedMessageObj.isGifDeleted === false) {
+ haveRepliedGif = true
+ hasRepliedGifDeleted = false
+
+ parsedRepliedMessageObj.gifs.forEach(item => {
+ if (item.name) {
+ repliedGifLink = item.service + '/' + item.name + '/' + item.identifier
+ }
+ })
+ } else if (parsedRepliedMessageObj.isGifDeleted === true) {
+ haveRepliedGif = true
+ hasRepliedGifDeleted = true
+ }
+
+ if (parsedRepliedMessageObj.isAttachmentDeleted === false) {
+ haveRepliedAttachment = true
+ hasRepliedAttachmentDeleted = false
+
+ parsedRepliedMessageObj.attachments.forEach(item => {
+ if (item.name) {
+ repliedAttachmentLink = item.service + '/' + item.name + '/' + item.identifier
+ repliedAttachmentName = item.attachmentName
+ let repliedAttachmentSizeMb = roundToNearestDecimal(item.attachmentSize)
+ repliedAttachmentSize = sizeString + ': ' + repliedAttachmentSizeMb + ' mb'
+ }
+ })
+ } else if (parsedRepliedMessageObj.isAttachmentDeleted === true) {
+ haveRepliedAttachment = true
+ hasRepliedAttachmentDeleted = true
+ }
+
+ if (parsedRepliedMessageObj.isFileDeleted === false) {
+ haveRepliedFile = true
+ hasRepliedFileDeleted = false
+
+ parsedRepliedMessageObj.files.forEach(item => {
+ if (item.name) {
+ repliedFileLink = item.service + '/' + item.name + '/' + item.identifier
+ repliedFileName = item.appFileName
+ let repliedFileSizeMb = roundToNearestDecimal(item.appFileSize)
+ repliedFileSize = sizeString + ': ' + repliedFileSizeMb + ' mb'
+ }
+ })
+ } else if (parsedRepliedMessageObj.isFileDeleted === true) {
+ haveRepliedFile = true
+ hasRepliedFileDeleted = true
+ }
+
+ if (parsedRepliedMessageObj.version > 1 && parsedRepliedMessageObj.messageText) {
+ repliedMessage = generateHTML(parsedRepliedMessageObj.messageText, [StarterKit, Underline, Highlight])
+ }
+ })
+ }
+
+ if (parsedMessageObj.isImageDeleted === false) {
+ haveImage = true
+ hasImageDeleted = false
+
+ parsedMessageObj.images.forEach(item => {
+ if (item.name) {
+ imageLink = item.service + '/' + item.name + '/' + item.identifier
+ }
+ })
+ } else if (parsedMessageObj.isImageDeleted === true) {
+ haveImage = true
+ hasImageDeleted = true
+ }
+
+ if (parsedMessageObj.isGifDeleted === false) {
+ haveGif = true
+ hasGifDeleted = false
+
+ parsedMessageObj.gifs.forEach(item => {
+ if (item.name) {
+ gifLink = item.service + '/' + item.name + '/' + item.identifier
+ }
+ })
+ } else if (parsedMessageObj.isGifDeleted === true) {
+ haveGif = true
+ hasGifDeleted = true
+ }
+
+ if (parsedMessageObj.isAttachmentDeleted === false) {
+ haveAttachment = true
+ hasAttachmentDeleted = false
+
+ parsedMessageObj.attachments.forEach(item => {
+ if (item.name) {
+ attachmentLink = item.service + '/' + item.name + '/' + item.identifier
+ attachmentName = item.attachmentName
+ let attachmentSizeMb = roundToNearestDecimal(item.attachmentSize)
+ attachmentSize = sizeString + ': ' + attachmentSizeMb + ' mb'
+ }
+ })
+ } else if (parsedMessageObj.isAttachmentDeleted === true) {
+ haveAttachment = true
+ hasAttachmentDeleted = true
+ }
+
+ if (parsedMessageObj.isFileDeleted === false) {
+ haveFile = true
+ hasFileDeleted = false
+
+ parsedMessageObj.files.forEach(item => {
+ if (item.name) {
+ fileLink = item.service + '/' + item.name + '/' + item.identifier
+ fileName = item.appFileName
+ let fileSizeMb = roundToNearestDecimal(item.appFileSize)
+ fileSize = sizeString + ': ' + fileSizeMb + ' mb'
+ }
+ })
+ } else if (parsedMessageObj.isFileDeleted === true) {
+ haveFile = true
+ hasFileDeleted = true
+ }
+
+ const chatElement = document.createElement('div')
+ chatElement.setAttribute('id', chatID)
+ chatElement.classList.add('message-container')
+
+ const forwarded = document.createElement('span')
+ forwarded.classList.add('message-data-forward')
+ forwarded.textContent = forwardedString
+
+ const subcontainer1 = document.createElement('div')
+ subcontainer1.setAttribute('id', subcontainer1ID)
+ subcontainer1.classList.add('message-subcontainer1')
+
+ const subcontainer2 = document.createElement('div')
+ subcontainer2.setAttribute('id', subcontainer2ID)
+ if (this.selectedAddress.address === messageAddress) {
+ subcontainer2.classList.add('message-subcontainer2-mybg', 'message-triangle-mybg')
+ } else {
+ subcontainer2.classList.add('message-subcontainer2', 'message-triangle')
+ }
+
+ const avatarContainer = document.createElement('div')
+ avatarContainer.classList.add('message-avatar')
+
+ const userinfo = document.createElement('div')
+ userinfo.classList.add('message-user-info')
+
+ const username = document.createElement('span')
+ if (this.selectedAddress.address === messageAddress) {
+ username.classList.add('message-data-my-name')
+ } else {
+ username.classList.add('message-data-name')
+ }
+ username.textContent = name
+
+ if (isForwarded) {
+ userinfo.appendChild(username)
+ userinfo.appendChild(forwarded)
+ } else {
+ userinfo.appendChild(username)
+ }
+
+ const messageContainer = document.createElement('div')
+ messageContainer.setAttribute('id', messageID)
+ messageContainer.classList.add('message')
+ messageContainer.innerHTML = messageContent
+
+ const messageTimeContainer = document.createElement('div')
+ messageTimeContainer.setAttribute('id', messageTimeID)
+
+ const messageOrgTimeString = document.createElement('span')
+ messageOrgTimeString.classList.add('message-data-edited')
+ messageOrgTimeString.textContent = messageTimeString
+
+ const messageEditedString = document.createElement('span')
+ messageEditedString.setAttribute('id', messageEditedID)
+ messageEditedString.classList.add('message-data-edited')
+ messageEditedString.textContent = editedString
+
+ if (!isEdited) {
+ messageTimeContainer.classList.add('message-data-time')
+ messageTimeContainer.appendChild(messageOrgTimeString)
+ } else if (isEdited) {
+ messageTimeContainer.classList.add('message-data-time-edited')
+ messageTimeContainer.appendChild(messageEditedString)
+ messageTimeContainer.appendChild(messageOrgTimeString)
+ }
+
+ const avatarUrl = `${nodeUrl}/arbitrary/THUMBNAIL/${name}/qortal_avatar?async=true`
+ const avatarImage = document.createElement('img')
+ avatarImage.src = `${avatarUrl}`
+ avatarImage.onerror = () => {
+ if (avatarFetches < 4) {
+ setTimeout(() => {
+ avatarFetches = avatarFetches + 1
+ avatarImage.src = `${avatarUrl}`
+ }, 750)
+ } else {
+ avatarImage.src = '/img/incognito.png'
+ }
+ }
+ avatarContainer.appendChild(avatarImage)
+
+ const contentDeltedContainer = document.createElement('div')
+ contentDeltedContainer.classList.add('attachment-container')
+
+ const contentDeltedInfo = document.createElement('div')
+ contentDeltedInfo.classList.add('attachment-info')
+
+ const contentDeltedText = document.createElement('p')
+ contentDeltedText.classList.add('attachment-deleted')
+
+ const repliedtodata = document.createElement('div')
+ repliedtodata.classList.add('original-message')
+ repliedtodata.onclick = () => {
+ this.shadowRoot.getElementById(repliedID).scrollIntoView({
+ behavior: 'smooth'
+ })
+ }
+
+ const repliedtoname = document.createElement('p')
+ if (this.selectedAddress.address === repliedMessageAddress) {
+ repliedtoname.classList.add('original-message-sender-wasme')
+ } else {
+ repliedtoname.classList.add('original-message-sender')
+ }
+ repliedtoname.textContent = repliedName
+
+ const repliedtomessage = document.createElement('p')
+ repliedtomessage.classList.add('replied-message')
+ repliedtomessage.innerHTML = repliedMessage
+
+ const attachmentContainer = document.createElement('div')
+ attachmentContainer.setAttribute('id', messageAttachmentID)
+ attachmentContainer.classList.add('attachment-container')
+
+ const attachmentIconContainer = document.createElement('div')
+ attachmentIconContainer.classList.add('attachment-icon-container')
+
+ const attachmentIconUrl = `/img/attachment-icon.png`
+ const attachmentIcon = document.createElement('img')
+ attachmentIcon.classList.add('attachment-icon')
+ attachmentIcon.src = `${attachmentIconUrl}`
+
+ attachmentIconContainer.appendChild(attachmentIcon)
+
+ const attachmentInfoContainer = document.createElement('div')
+ attachmentInfoContainer.classList.add('attachment-info')
+
+ const attachmentNameContainer = document.createElement('p')
+ attachmentNameContainer.classList.add('attachment-name')
+ attachmentNameContainer.textContent = attachmentName
+
+ const attachmentSizeContainer = document.createElement('p')
+ attachmentSizeContainer.classList.add('attachment-size')
+ attachmentSizeContainer.textContent = attachmentSize
+
+ attachmentInfoContainer.appendChild(attachmentNameContainer)
+ attachmentInfoContainer.appendChild(attachmentSizeContainer)
+
+ attachmentContainer.appendChild(attachmentIconContainer)
+ attachmentContainer.appendChild(attachmentInfoContainer)
+
+ const repliedAttachmentContainer = document.createElement('div')
+ repliedAttachmentContainer.setAttribute('id', repliedAttachmentID)
+ repliedAttachmentContainer.classList.add('attachment-container')
+
+ const repliedAttachmentIconContainer = document.createElement('div')
+ repliedAttachmentIconContainer.classList.add('attachment-icon-container')
+
+ const repliedAttachmentIconUrl = `/img/attachment-icon.png`
+ const repliedAttachmentIcon = document.createElement('img')
+ repliedAttachmentIcon.classList.add('attachment-icon')
+ repliedAttachmentIcon.src = `${repliedAttachmentIconUrl}`
+
+ repliedAttachmentIconContainer.appendChild(repliedAttachmentIcon)
+
+ const repliedAttachmentInfoContainer = document.createElement('div')
+ repliedAttachmentInfoContainer.classList.add('attachment-info')
+
+ const repliedAttachmentNameContainer = document.createElement('p')
+ repliedAttachmentNameContainer.classList.add('attachment-name')
+ repliedAttachmentNameContainer.textContent = repliedAttachmentName
+
+ const repliedAttachmentSizeContainer = document.createElement('p')
+ repliedAttachmentSizeContainer.classList.add('attachment-size')
+ repliedAttachmentSizeContainer.textContent = repliedAttachmentSize
+
+ repliedAttachmentInfoContainer.appendChild(repliedAttachmentNameContainer)
+ repliedAttachmentInfoContainer.appendChild(repliedAttachmentSizeContainer)
+
+ repliedAttachmentContainer.appendChild(repliedAttachmentIconContainer)
+ repliedAttachmentContainer.appendChild(repliedAttachmentInfoContainer)
+
+ const fileContainer = document.createElement('div')
+ fileContainer.setAttribute('id', messageFileID)
+ fileContainer.classList.add('file-container')
+
+ const fileIconContainer = document.createElement('div')
+ fileIconContainer.classList.add('file-icon-container')
+
+ const fileIconUrl = `/img/file-icon.png`
+ const fileIcon = document.createElement('img')
+ fileIcon.classList.add('file-icon')
+ fileIcon.src = `${fileIconUrl}`
+
+ fileIconContainer.appendChild(fileIcon)
+
+ const fileInfoContainer = document.createElement('div')
+ fileInfoContainer.classList.add('attachment-info')
+
+ const fileNameContainer = document.createElement('p')
+ fileNameContainer.classList.add('attachment-name')
+ fileNameContainer.textContent = fileName
+
+ const fileSizeContainer = document.createElement('p')
+ fileSizeContainer.classList.add('attachment-size')
+ fileSizeContainer.textContent = fileSize
+
+ fileInfoContainer.appendChild(fileNameContainer)
+ fileInfoContainer.appendChild(fileSizeContainer)
+
+ fileContainer.appendChild(fileIconContainer)
+ fileContainer.appendChild(fileInfoContainer)
+
+ const repliedFileContainer = document.createElement('div')
+ repliedFileContainer.setAttribute('id', repliedFileID)
+ repliedFileContainer.classList.add('file-container')
+
+ const repliedFileIconContainer = document.createElement('div')
+ repliedFileIconContainer.classList.add('file-icon-container')
+
+ const repliedFileIconUrl = `/img/file-icon.png`
+ const repliedFileIcon = document.createElement('img')
+ repliedFileIcon.classList.add('file-icon')
+ repliedFileIcon.src = `${repliedFileIconUrl}`
+
+ repliedFileIconContainer.appendChild(repliedFileIcon)
+
+ const repliedFileInfoContainer = document.createElement('div')
+ repliedFileInfoContainer.classList.add('attachment-info')
+
+ const repliedFileNameContainer = document.createElement('p')
+ repliedFileNameContainer.classList.add('attachment-name')
+ repliedFileNameContainer.textContent = repliedFileName
+
+ const repliedFileSizeContainer = document.createElement('p')
+ repliedFileSizeContainer.classList.add('attachment-size')
+ repliedFileSizeContainer.textContent = repliedFileSize
+
+ repliedFileInfoContainer.appendChild(repliedFileNameContainer)
+ repliedFileInfoContainer.appendChild(repliedFileSizeContainer)
+
+ repliedFileContainer.appendChild(repliedFileIconContainer)
+ repliedFileContainer.appendChild(repliedFileInfoContainer)
+
+ if (repliedMessage
+ && !haveRepliedImage
+ && !hasRepliedImageDeleted
+ && !haveRepliedGif
+ && !hasRepliedGifDeleted
+ && !haveRepliedAttachment
+ && !hasRepliedAttachmentDeleted
+ && !haveRepliedFile
+ && !hasRepliedFileDeleted
+ ) {
+ repliedtodata.appendChild(repliedtoname)
+ repliedtodata.appendChild(repliedtomessage)
+
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(repliedtodata)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (repliedMessage
+ && haveRepliedImage
+ && !hasRepliedImageDeleted
+ && !haveRepliedGif
+ && !hasRepliedGifDeleted
+ && !haveRepliedAttachment
+ && !hasRepliedAttachmentDeleted
+ && !haveRepliedFile
+ && !hasRepliedFileDeleted
+ ) {
+ const repliedImageContainer = document.createElement('div')
+ repliedImageContainer.setAttribute('id', repliedImageID)
+ repliedImageContainer.classList.add('image-container')
+
+ const repliedImageUrl = `${nodeUrl}/arbitrary/${repliedImageLink}?async=true`
+
+ const chatRepliedImage = document.createElement('img')
+ chatRepliedImage.classList.add('chat-replied-img')
+ chatRepliedImage.src = `${repliedImageUrl}`
+ chatRepliedImage.onerror = () => {
+ chatRepliedImage.src = '/img/img-loading.png'
+ if (repliedImageFetches < 400) {
+ setTimeout(() => {
+ repliedImageFetches = repliedImageFetches + 1
+ chatRepliedImage.src = `${repliedImageUrl}`
+ }, 750)
+ } else {
+ chatRepliedImage.src = '/img/chain.png'
+ }
+ }
+
+ repliedImageContainer.appendChild(chatRepliedImage)
+
+ repliedtodata.appendChild(repliedtoname)
+ repliedtodata.appendChild(repliedImageContainer)
+ repliedtodata.appendChild(repliedtomessage)
+
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(repliedtodata)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (repliedMessage
+ && haveRepliedImage
+ && hasRepliedImageDeleted
+ && !haveRepliedGif
+ && !hasRepliedGifDeleted
+ && !haveRepliedAttachment
+ && !hasRepliedAttachmentDeleted
+ && !haveRepliedFile
+ && !hasRepliedFileDeleted
+ ) {
+ contentDeltedText.textContent = imageDeletedString
+
+ contentDeltedInfo.appendChild(contentDeltedText)
+ contentDeltedContainer.appendChild(contentDeltedInfo)
+
+ repliedtodata.appendChild(repliedtoname)
+ repliedtodata.appendChild(contentDeltedContainer)
+ repliedtodata.appendChild(repliedtomessage)
+
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(repliedtodata)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (repliedMessage
+ && !haveRepliedImage
+ && !hasRepliedImageDeleted
+ && haveRepliedGif
+ && !hasRepliedGifDeleted
+ && !haveRepliedAttachment
+ && !hasRepliedAttachmentDeleted
+ && !haveRepliedFile
+ && !hasRepliedFileDeleted
+ ) {
+ const repliedImageContainer = document.createElement('div')
+ repliedImageContainer.setAttribute('id', repliedGifID)
+ repliedImageContainer.classList.add('image-container')
+
+ const repliedGifUrl = `${nodeUrl}/arbitrary/${repliedGifLink}?async=true`
+
+ const chatRepliedImage = document.createElement('img')
+ chatRepliedImage.classList.add('chat-replied-img')
+ chatRepliedImage.src = `${repliedGifUrl}`
+ chatRepliedImage.onerror = () => {
+ chatRepliedImage.src = '/img/img-loading.png'
+ if (repliedImageFetches < 400) {
+ setTimeout(() => {
+ repliedImageFetches = repliedImageFetches + 1
+ chatRepliedImage.src = `${repliedGifUrl}`
+ }, 750)
+ } else {
+ chatRepliedImage.src = '/img/chain.png'
+ }
+ }
+
+ repliedImageContainer.appendChild(chatRepliedImage)
+
+ repliedtodata.appendChild(repliedtoname)
+ repliedtodata.appendChild(repliedImageContainer)
+ repliedtodata.appendChild(repliedtomessage)
+
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(repliedtodata)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (repliedMessage
+ && !haveRepliedImage
+ && !hasRepliedImageDeleted
+ && haveRepliedGif
+ && hasRepliedGifDeleted
+ && !haveRepliedAttachment
+ && !hasRepliedAttachmentDeleted
+ && !haveRepliedFile
+ && !hasRepliedFileDeleted
+ ) {
+ contentDeltedText.textContent = gifDeletedString
+
+ contentDeltedInfo.appendChild(contentDeltedText)
+ contentDeltedContainer.appendChild(contentDeltedInfo)
+
+ repliedtodata.appendChild(repliedtoname)
+ repliedtodata.appendChild(contentDeltedContainer)
+ repliedtodata.appendChild(repliedtomessage)
+
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(repliedtodata)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (repliedMessage
+ && !haveRepliedImage
+ && !hasRepliedImageDeleted
+ && !haveRepliedGif
+ && !hasRepliedGifDeleted
+ && haveRepliedAttachment
+ && !hasRepliedAttachmentDeleted
+ && !haveRepliedFile
+ && !hasRepliedFileDeleted
+ ) {
+ repliedtodata.appendChild(repliedtoname)
+ repliedtodata.appendChild(repliedAttachmentContainer)
+ repliedtodata.appendChild(repliedtomessage)
+
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(repliedtodata)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (repliedMessage
+ && !haveRepliedImage
+ && !hasRepliedImageDeleted
+ && !haveRepliedGif
+ && !hasRepliedGifDeleted
+ && haveRepliedAttachment
+ && hasRepliedAttachmentDeleted
+ && !haveRepliedFile
+ && !hasRepliedFileDeleted
+ ) {
+ contentDeltedText.textContent = attachmentDeletedString
+
+ contentDeltedInfo.appendChild(contentDeltedText)
+ contentDeltedContainer.appendChild(contentDeltedInfo)
+
+ repliedtodata.appendChild(repliedtoname)
+ repliedtodata.appendChild(contentDeltedContainer)
+ repliedtodata.appendChild(repliedtomessage)
+
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(repliedtodata)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (repliedMessage
+ && !haveRepliedImage
+ && !hasRepliedImageDeleted
+ && !haveRepliedGif
+ && !hasRepliedGifDeleted
+ && !haveRepliedAttachment
+ && !hasRepliedAttachmentDeleted
+ && haveRepliedFile
+ && !hasRepliedFileDeleted
+ ) {
+ repliedtodata.appendChild(repliedtoname)
+ repliedtodata.appendChild(repliedFileContainer)
+ repliedtodata.appendChild(repliedtomessage)
+
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(repliedtodata)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (repliedMessage
+ && !haveRepliedImage
+ && !hasRepliedImageDeleted
+ && !haveRepliedGif
+ && !hasRepliedGifDeleted
+ && !haveRepliedAttachment
+ && !hasRepliedAttachmentDeleted
+ && haveRepliedFile
+ && hasRepliedFileDeleted
+ ) {
+ contentDeltedText.textContent = fileDeletedString
+
+ contentDeltedInfo.appendChild(contentDeltedText)
+ contentDeltedContainer.appendChild(contentDeltedInfo)
+
+ repliedtodata.appendChild(repliedtoname)
+ repliedtodata.appendChild(contentDeltedContainer)
+ repliedtodata.appendChild(repliedtomessage)
+
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(repliedtodata)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (haveImage && !hasImageDeleted) {
+ const imageContainer = document.createElement('div')
+ imageContainer.setAttribute('id', messageImageID)
+ imageContainer.classList.add('image-container')
+
+ const imageUrl = `${nodeUrl}/arbitrary/${imageLink}?async=true`
+ const chatImage = document.createElement('img')
+ chatImage.classList.add('chat-img')
+ chatImage.src = `${imageUrl}`
+ chatImage.onerror = () => {
+ chatImage.src = '/img/img-loading.png'
+ if (imageFetches < 400) {
+ setTimeout(() => {
+ imageFetches = imageFetches + 1
+ chatImage.src = `${imageUrl}`
+ }, 750)
+ } else {
+ chatImage.src = '/img/chain.png'
+ }
+ }
+
+ imageContainer.appendChild(chatImage)
+
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(imageContainer)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (haveImage && hasImageDeleted) {
+ contentDeltedText.textContent = imageDeletedString
+
+ contentDeltedInfo.appendChild(contentDeltedText)
+ contentDeltedContainer.appendChild(contentDeltedInfo)
+
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(contentDeltedContainer)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (haveGif && !hasGifDeleted) {
+ const imageContainer = document.createElement('div')
+ imageContainer.setAttribute('id', messageGifID)
+ imageContainer.classList.add('image-container')
+
+ const gifUrl = `${nodeUrl}/arbitrary/${gifLink}?async=true`
+ const chatImage = document.createElement('img')
+ chatImage.classList.add('chat-img')
+ chatImage.src = `${gifUrl}`
+ chatImage.onerror = () => {
+ chatImage.src = '/img/img-loading.png'
+ if (imageFetches < 400) {
+ setTimeout(() => {
+ imageFetches = imageFetches + 1
+ chatImage.src = `${gifUrl}`
+ }, 750)
+ } else {
+ chatImage.src = '/img/chain.png'
+ }
+ }
+
+ imageContainer.appendChild(chatImage)
+
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(imageContainer)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (haveGif && hasGifDeleted) {
+ contentDeltedText.textContent = gifDeletedString
+
+ contentDeltedInfo.appendChild(contentDeltedText)
+ contentDeltedContainer.appendChild(contentDeltedInfo)
+
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(contentDeltedContainer)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (haveAttachment && !hasAttachmentDeleted) {
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(attachmentContainer)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (haveAttachment && hasAttachmentDeleted) {
+ contentDeltedText.textContent = attachmentDeletedString
+
+ contentDeltedInfo.appendChild(contentDeltedText)
+ contentDeltedContainer.appendChild(contentDeltedInfo)
+
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(contentDeltedContainer)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (haveFile && !hasFileDeleted) {
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(fileContainer)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else if (haveFile && hasFileDeleted) {
+ contentDeltedText.textContent = fileDeletedString
+
+ contentDeltedInfo.appendChild(contentDeltedText)
+ contentDeltedContainer.appendChild(contentDeltedInfo)
+
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(contentDeltedContainer)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ } else {
+ subcontainer2.appendChild(userinfo)
+ subcontainer2.appendChild(messageContainer)
+ subcontainer2.appendChild(messageTimeContainer)
+
+ subcontainer1.appendChild(avatarContainer)
+ subcontainer1.appendChild(subcontainer2)
+
+ chatElement.appendChild(subcontainer1)
+
+ chatGridContainer.appendChild(chatElement)
+ }
+ })
+
+ if (scroll) {
+ this.scrollChatToEnd()
+ }
+ }
+ }
+
timeIsoString(timestamp) {
let myTimestamp = timestamp === undefined ? 1587560082346 : timestamp
let time = new Date(myTimestamp)
@@ -3053,6 +4323,17 @@ class GroupManagement extends LitElement {
}
async joinGroup(groupId, groupName) {
+ let nGroupId = ''
+ let nGroupName = ''
+
+ if (typeof groupId === 'object' && groupId !== null) {
+ nGroupId = groupId.groupId
+ nGroupName = groupId.groupName
+ } else {
+ nGroupId = groupId
+ nGroupName = groupName
+ }
+
await this.unitJoinGroupFee()
this.resetDefaultSettings()
@@ -3083,8 +4364,8 @@ class GroupManagement extends LitElement {
params: {
fee: joinFeeInput,
registrantAddress: this.selectedAddress.address,
- rGroupName: groupName,
- rGroupId: groupId,
+ rGroupName: nGroupName,
+ rGroupId: nGroupId,
lastReference: lastRef,
groupdialog1: groupdialog1,
groupdialog2: groupdialog2
@@ -4046,6 +5327,288 @@ class GroupManagement extends LitElement {
round(number) {
return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8)
}
+
+ async fetchChatMessages(chatId) {
+ const restartGroupWebSocket = () => {
+ let groupChatId = Number(chatId)
+ setTimeout(() => initGroup(groupChatId, 50))
+ }
+
+ const initGroup = (gId) => {
+ let timeoutId
+ let groupId = Number(gId)
+ let groupSocketTimeout
+ let groupSocketLink
+ let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
+ let nodeUrl = myNode.domain + ":" + myNode.port
+
+ if (window.parent.location.protocol === "https:") {
+ // WSS is over https
+ groupSocketLink = `wss://${nodeUrl}/websockets/chat/messages?txGroupId=${groupId}&encoding=BASE64&limit=1`
+ } else {
+ // WSS is over http
+ groupSocketLink = `ws://${nodeUrl}/websockets/chat/messages?txGroupId=${groupId}&encoding=BASE64&limit=1`
+ }
+
+ // Set the websocket
+ this.webSocket = new WebSocket(groupSocketLink)
+
+ // When websocket is open ping every 50ms
+ this.webSocket.onopen = () => {
+ setTimeout(pingGroupSocket, 50)
+ }
+
+ // Websocket message Event
+ this.webSocket.onmessage = async (e) => {
+ if (e.data === 'pong') {
+ clearTimeout(timeoutId)
+ groupSocketTimeout = setTimeout(pingGroupSocket, 45000)
+ return
+ }
+
+ try {
+ if (e.data) {
+ let newMessage = []
+ let newDecodedArray = []
+
+ newMessage = JSON.parse(e.data)
+
+ // Check if message is new one (as first call is last message from before created array)
+ if (newMessage[0].timestamp > this.chatMessageArray[this.chatMessageArray.length - 1].timestamp) {
+ newMessage.forEach(item => {
+ let newDecodedMessageObj = {}
+ let decodedMessage = this.decodeMessage(item.data)
+ let checkEdited = JSON.parse(decodedMessage)
+ let editedString = get('chatpage.cchange68')
+ let imageDeletedString = get('chatpage.cchange80')
+ let gifDeletedString = get('chatpage.cchange107')
+ let attachmentDeletedString = get('chatpage.cchange82')
+ let fileDeletedString = get('chatpage.cchange102')
+
+ // Check if message got edited
+ if (checkEdited.isEdited) {
+ let refSignature = ''
+ let refTimeSignature = ''
+ let refEditedMessage = ''
+ let messageEditedID = ''
+
+ refSignature = item.chatReference
+ refTimeSignature = 'time-' + item.chatReference
+ refEditedMessage = generateHTML(checkEdited.messageText, [StarterKit, Underline, Highlight])
+ messageEditedID = 'edited-' + item.chatReference
+
+ const messageEditedString = document.createElement('span')
+ messageEditedString.setAttribute('id', messageEditedID)
+ messageEditedString.classList.add('message-data-edited')
+ messageEditedString.textContent = editedString
+
+ this.shadowRoot.getElementById(refSignature).innerHTML = refEditedMessage
+ this.shadowRoot.getElementById(refTimeSignature).classList.remove('message-data-time-edited')
+ this.shadowRoot.getElementById(refTimeSignature).classList.remove('message-data-time')
+ this.shadowRoot.getElementById(refTimeSignature).classList.add('message-data-time-edited')
+
+ if (this.shadowRoot.getElementById(refTimeSignature).childNodes.length > 1) {
+ this.shadowRoot.getElementById(refTimeSignature).removeChild(messageEditedString)
+ }
+
+ this.shadowRoot.getElementById(refTimeSignature).insertBefore(messageEditedString, this.shadowRoot.getElementById(refTimeSignature).firstChild)
+
+ this.chatMessageArray.find(v => v.signature === refSignature).decodedMessage = decodedMessage
+ } else if (checkEdited.isImageDeleted) {
+ let refSignature = ''
+ let refImageSignature = ''
+ let repImageSignature = ''
+
+ refSignature = item.chatReference
+ refImageSignature = 'image-' + item.chatReference
+ repImageSignature = 'repimage-' + item.chatReference
+
+ const contentDeltedInfo = document.createElement('div')
+ contentDeltedInfo.classList.add('attachment-info')
+
+ const contentDeltedText = document.createElement('p')
+ contentDeltedText.classList.add('attachment-deleted')
+ contentDeltedText.textContent = imageDeletedString
+
+ contentDeltedInfo.appendChild(contentDeltedText)
+
+ if (this.shadowRoot.getElementById(refImageSignature)) {
+ this.shadowRoot.getElementById(refImageSignature).innerHTML = ''
+ this.shadowRoot.getElementById(refImageSignature).classList.remove('image-container')
+ this.shadowRoot.getElementById(refImageSignature).classList.add('attachment-container')
+ this.shadowRoot.getElementById(refImageSignature).appendChild(contentDeltedInfo)
+ }
+
+ if (this.shadowRoot.getElementById(repImageSignature)) {
+ this.shadowRoot.getElementById(repImageSignature).innerHTML = ''
+ this.shadowRoot.getElementById(repImageSignature).classList.remove('image-container')
+ this.shadowRoot.getElementById(repImageSignature).classList.add('attachment-container')
+ this.shadowRoot.getElementById(repImageSignature).appendChild(contentDeltedInfo)
+ }
+
+ this.chatMessageArray.find(v => v.signature === refSignature).decodedMessage = decodedMessage
+ } else if (checkEdited.isGifDeleted) {
+ let refSignature = ''
+ let refGifSignature = ''
+ let repGifSignature = ''
+
+ refSignature = item.chatReference
+ refGifSignature = 'gif-' + item.chatReference
+ repGifSignature = 'repgif-' + item.chatReference
+
+ const contentDeltedInfo = document.createElement('div')
+ contentDeltedInfo.classList.add('attachment-info')
+
+ const contentDeltedText = document.createElement('p')
+ contentDeltedText.classList.add('attachment-deleted')
+ contentDeltedText.textContent = gifDeletedString
+
+ contentDeltedInfo.appendChild(contentDeltedText)
+
+ if (this.shadowRoot.getElementById(refGifSignature)) {
+ this.shadowRoot.getElementById(refGifSignature).innerHTML = ''
+ this.shadowRoot.getElementById(refGifSignature).classList.remove('image-container')
+ this.shadowRoot.getElementById(refGifSignature).classList.add('attachment-container')
+ this.shadowRoot.getElementById(refGifSignature).appendChild(contentDeltedInfo)
+ }
+
+ if (this.shadowRoot.getElementById(repGifSignature)) {
+ this.shadowRoot.getElementById(repGifSignature).innerHTML = ''
+ this.shadowRoot.getElementById(repGifSignature).classList.remove('image-container')
+ this.shadowRoot.getElementById(repGifSignature).classList.add('attachment-container')
+ this.shadowRoot.getElementById(repGifSignature).appendChild(contentDeltedInfo)
+ }
+
+ this.chatMessageArray.find(v => v.signature === refSignature).decodedMessage = decodedMessage
+ } else if (checkEdited.isAttachmentDeleted) {
+ let refSignature = ''
+ let refAttachmentSignature = ''
+ let repAttachmentSignature = ''
+
+ refSignature = item.chatReference
+ refAttachmentSignature = 'attachment-' + item.chatReference
+ repAttachmentSignature = 'repattachment-' + item.chatReference
+
+ const contentDeltedInfo = document.createElement('div')
+ contentDeltedInfo.classList.add('attachment-info')
+
+ const contentDeltedText = document.createElement('p')
+ contentDeltedText.classList.add('attachment-deleted')
+ contentDeltedText.textContent = attachmentDeletedString
+
+ contentDeltedInfo.appendChild(contentDeltedText)
+
+ if (this.shadowRoot.getElementById(refAttachmentSignature)) {
+ this.shadowRoot.getElementById(refAttachmentSignature).innerHTML = ''
+ this.shadowRoot.getElementById(refAttachmentSignature).appendChild(contentDeltedInfo)
+ }
+
+ if (this.shadowRoot.getElementById(repAttachmentSignature)) {
+ this.shadowRoot.getElementById(repAttachmentSignature).innerHTML = ''
+ this.shadowRoot.getElementById(repAttachmentSignature).appendChild(contentDeltedInfo)
+ }
+
+ this.chatMessageArray.find(v => v.signature === refSignature).decodedMessage = decodedMessage
+ } else if (checkEdited.isFileDeleted) {
+ let refSignature = ''
+ let refFileSignature = ''
+ let repFileSignature = ''
+
+ refSignature = item.chatReference
+ refFileSignature = 'file-' + item.chatReference
+ repFileSignature = 'repfile-' + item.chatReference
+
+ const contentDeltedInfo = document.createElement('div')
+ contentDeltedInfo.classList.add('attachment-info')
+
+ const contentDeltedText = document.createElement('p')
+ contentDeltedText.classList.add('attachment-deleted')
+ contentDeltedText.textContent = fileDeletedString
+
+ contentDeltedInfo.appendChild(contentDeltedText)
+
+ const contentDeltedInfoRep = document.createElement('div')
+ contentDeltedInfoRep.classList.add('attachment-info')
+
+ const contentDeltedTextRep = document.createElement('p')
+ contentDeltedTextRep.classList.add('attachment-deleted')
+ contentDeltedTextRep.textContent = fileDeletedString
+
+ contentDeltedInfoRep.appendChild(contentDeltedTextRep)
+
+ if (this.shadowRoot.getElementById(refFileSignature)) {
+ this.shadowRoot.getElementById(refFileSignature).innerHTML = ''
+ this.shadowRoot.getElementById(refFileSignature).classList.remove('file-container')
+ this.shadowRoot.getElementById(refFileSignature).classList.add('attachment-container')
+ this.shadowRoot.getElementById(refFileSignature).appendChild(contentDeltedInfo)
+ }
+
+ if (this.shadowRoot.getElementById(repFileSignature)) {
+ this.shadowRoot.getElementById(repFileSignature).innerHTML = ''
+ this.shadowRoot.getElementById(repFileSignature).classList.remove('file-container')
+ this.shadowRoot.getElementById(repFileSignature).classList.add('attachment-container')
+ this.shadowRoot.getElementById(repFileSignature).appendChild(contentDeltedInfoRep)
+ }
+
+ this.chatMessageArray.find(v => v.signature === refSignature).decodedMessage = decodedMessage
+ } else {
+ const newMessageObj = {
+ timestamp: item.timestamp,
+ txGroupId: item.txGroupId,
+ reference: item.reference,
+ senderPublicKey: item.senderPublicKey,
+ sender: item.sender,
+ senderName: item.senderName,
+ encoding: item.encoding,
+ isText: item.isText,
+ isEncrypted: item.isEncrypted,
+ signature: item.signature
+ }
+
+ newDecodedMessageObj = { ...newMessageObj, decodedMessage }
+
+ newDecodedArray.push(newDecodedMessageObj)
+
+ this.chatMessageArray.push(newDecodedMessageObj)
+ this.renderChatMessagesGrid(newDecodedArray, true)
+ }
+ })
+ }
+ }
+ } catch (error) { /* empty */ }
+ }
+
+ // Websocket close event
+ this.webSocket.onclose = (e) => {
+ clearTimeout(groupSocketTimeout)
+ if (e.reason === 'closed preview') return
+ restartGroupWebSocket()
+ }
+
+ // Websocket error event
+ this.webSocket.onerror = () => {
+ clearTimeout(groupSocketTimeout)
+ this.webSocket.close()
+ }
+
+ // Close the WebSocket connection if no pong message is received within 5 seconds.
+ const pingGroupSocket = () => {
+ this.webSocket.send('ping')
+ timeoutId = setTimeout(() => {
+ this.webSocket.close()
+ clearTimeout(groupSocketTimeout)
+ }, 5000)
+ }
+ }
+
+ // Init the websocket
+ if (chatId !== undefined) {
+ let groupChatId = Number(chatId)
+ initGroup(groupChatId)
+ } else {
+ // ... Websocket not started
+ }
+ }
}
window.customElements.define('group-management', GroupManagement)
\ No newline at end of file