Browse Source

Merge pull request #321 from AlphaX-Projects/master

Bug fixes and new features
master
AlphaX-Projects 3 months ago committed by GitHub
parent
commit
5893d4de7d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      README.md
  2. BIN
      core/font/TwemojiCountryFlags.woff2
  3. 7
      core/font/material-icons.css
  4. 10
      core/language/de.json
  5. 10
      core/language/es.json
  6. 10
      core/language/et.json
  7. 10
      core/language/fi.json
  8. 10
      core/language/fr.json
  9. 10
      core/language/hindi.json
  10. 10
      core/language/hr.json
  11. 10
      core/language/hu.json
  12. 10
      core/language/it.json
  13. 10
      core/language/jp.json
  14. 10
      core/language/ko.json
  15. 10
      core/language/nl.json
  16. 10
      core/language/no.json
  17. 10
      core/language/pl.json
  18. 10
      core/language/pt.json
  19. 10
      core/language/ro.json
  20. 10
      core/language/rs.json
  21. 10
      core/language/ru.json
  22. 10
      core/language/us.json
  23. 10
      core/language/zhc.json
  24. 10
      core/language/zht.json
  25. 40
      core/src/components/login-view/login-section.js
  26. 8
      electron.js
  27. 115
      package-lock.json
  28. 11
      package.json
  29. 20
      plugins/plugins/core/components/ChatEmojiFlags.js
  30. 43
      plugins/plugins/core/components/ChatPage.js
  31. 271
      plugins/plugins/core/components/ChatRightPanelSettings.js
  32. 359
      plugins/plugins/core/components/ChatScroller.js
  33. 32
      plugins/plugins/core/components/ChatTestEmojiFlags.js
  34. 176
      plugins/plugins/core/components/plugins-css.js
  35. 2
      plugins/plugins/core/q-chat/index.html
  36. 14
      plugins/plugins/core/q-chat/q-chat.src.js

2
README.md

@ -26,7 +26,7 @@ Easiest way to install the lastest required packages on Linux is via nvm.
``` source ~/.profile ``` (For Debian based distro) <br/>
``` source ~/.bashrc ``` (For Fedora / CentOS) <br/>
``` nvm ls-remote ``` (Fetch list of available versions) <br/>
``` nvm install v20.14.0 ``` (LTS: Iron supported by Electron V31) <br/>
``` nvm install v18.20.3 ``` (Latest LTS: Hydrogen supported by Electron V31) <br/>
``` npm --location=global install [email protected] ``` <br/>
Adding via binary package mirror will only work if you have set the package path. You can do a node or java build via ports instead by downloading ports with portsnap fetch method.

BIN
core/font/TwemojiCountryFlags.woff2

Binary file not shown.

7
core/font/material-icons.css

@ -101,3 +101,10 @@
local('PaytoneOne'),
url(PaytoneOne.ttf) format('truetype');
}
@font-face {
font-family: 'Twemoji Country Flags';
src: url('TwemojiCountryFlags.woff2') format('woff2');
font-weight: normal;
font-style: normal;
}

10
core/language/de.json

@ -1319,5 +1319,15 @@
"tour20": "Blocks dahinter. Möchten Sie eine Aktualisierung (Bootstrap) durchführen, um den Synchronisierungsprozess zu beschleunigen?",
"tour21": "Verbleibende Blöcke.",
"tour22": "Aktualisierung (Bootstrap) angefordert. Bitte warten."
},
"chatsettings": {
"cs1": "Chat-Einstellungen",
"cs2": "Allgemeine Chat-Einstellungen",
"cs3": "Zeitstempel der Chat-Nachricht",
"cs4": "Vorherige Zeit",
"cs5": "Ortszeit",
"cs6": "Schriftgröße der Chat-Nachricht",
"cs7": "Standard",
"cs8": "px"
}
}

10
core/language/es.json

@ -1319,5 +1319,15 @@
"tour20": "bloques detrás. ¿Le gustaría actualizar (arrancar) para acelerar el proceso de sincronización?",
"tour21": "bloques restantes.",
"tour22": "Se solicitó actualización (arranque). Espere."
},
"chatsettings": {
"cs1": "Configuración de chat",
"cs2": "Configuración general del chat",
"cs3": "Marca de tiempo del mensaje de chat",
"cs4": "Hace tiempo",
"cs5": "Hora local",
"cs6": "Tamaño de fuente del mensaje de chat",
"cs7": "Estándar",
"cs8": "px"
}
}

10
core/language/et.json

@ -1319,5 +1319,15 @@
"tour20": "blokeerib taga. Kas soovite sünkroonimisprotsessi kiirendamiseks värskendada (bootstrap)?",
"tour21": "jäänud plokke.",
"tour22": "Taotleb värskendamist (bootstrap). Palun oodake."
},
"chatsettings": {
"cs1": "Vestluse seaded",
"cs2": "Üldised vestluse seaded",
"cs3": "Vestlussõnumi ajatempel",
"cs4": "Aeg tagasi",
"cs5": "Kohalik aeg",
"cs6": "Vestlussõnumi fondi suurus",
"cs7": "Standardne",
"cs8": "px"
}
}

10
core/language/fi.json

@ -1319,5 +1319,15 @@
"tour20": "blokkeja takana. Haluatko päivittää (bootstrap) nopeuttaaksesi synkronointiprosessia?",
"tour21": "jäljellä olevat lohkot.",
"tour22": "Pyydellään päivitystä (bootstrap). Odota."
},
"chatsettings": {
"cs1": "Pikaviestiasetukset",
"cs2": "Yleiset chat-asetukset",
"cs3": "Pikaviestin aikaleima",
"cs4": "Aika sitten",
"cs5": "Paikallinen aika",
"cs6": "Chat-viestin kirjasinkoko",
"cs7": "Vakio",
"cs8": "px"
}
}

10
core/language/fr.json

@ -1319,5 +1319,15 @@
"tour20": "blocs derrière. Souhaitez-vous actualiser (bootstrap) pour accélérer le processus de synchronisation ?",
"tour21": "blocs restants.",
"tour22": "Actualisation (bootstrap) demandée. Veuillez patienter."
},
"chatsettings": {
"cs1": "Paramètres de discussion",
"cs2": "Paramètres généraux de discussion",
"cs3": "Horodatage du message de discussion",
"cs4": "Il y a du temps",
"cs5": "Heure locale",
"cs6": "Taille de la police des messages de discussion",
"cs7": "Standard",
"cs8": "px"
}
}

10
core/language/hindi.json

@ -1319,5 +1319,15 @@
"tour20": "पक। क आप सििग परकिज करनिए रश (बटसप) करन?",
"tour21": "बक शष ह।",
"tour22": "रिश (बटसप) क अनध कि गय। कपयरत कर।"
},
"chatsettings": {
"cs1": "चट सिग",
"cs2": "सय चट सिग",
"cs3": "चट सश टइमसप",
"cs4": "समय पहल",
"cs5": "सय समय",
"cs6": "चट सश फट आकर",
"cs7": "मनक",
"cs8": "px"
}
}

10
core/language/hr.json

@ -1319,5 +1319,15 @@
"tour20": "blokovi iza. Želite li osvježiti (bootstrap) da ubrzate proces sinkronizacije?",
"tour21": "preostali blokovi.",
"tour22": "Zatraženo je osvježavanje (bootstrap). Molimo pričekajte."
},
"chatsettings": {
"cs1": "Postavke chata",
"cs2": "Opće postavke chata",
"cs3": "Vremenska oznaka poruke chata",
"cs4": "Prije vremena",
"cs5": "Lokalno vrijeme",
"cs6": "Veličina fonta poruke chata",
"cs7": "Standardno",
"cs8": "px"
}
}

10
core/language/hu.json

@ -1319,5 +1319,15 @@
"tour20": "blokkok mögött. Szeretne frissíteni (bootstrap) a szinkronizálási folyamat felgyorsítása érdekében?",
"tour21": "még blokkok.",
"tour22": "Frissítés (bootstrap) kérve. Kérjük, várjon."
},
"chatsettings": {
"cs1": "Csevegés beállításai",
"cs2": "Általános csevegési beállítások",
"cs3": "Csevegési üzenet időbélyege",
"cs4": "Idővel ezelőtt",
"cs5": "Helyi idő",
"cs6": "Csevegési üzenet betűmérete",
"cs7": "Normál",
"cs8": "px"
}
}

10
core/language/it.json

@ -1319,5 +1319,15 @@
"tour20": "blocchi dietro. Vuoi aggiornare (bootstrap) per accelerare il processo di sincronizzazione?",
"tour21": "blocchi rimanenti.",
"tour22": "Aggiornamento (bootstrap) richiesto. Attendi prego."
},
"chatsettings": {
"cs1": "Impostazioni chat",
"cs2": "Impostazioni generali della chat",
"cs3": "Timestamp del messaggio di chat",
"cs4": "Tempo fa",
"cs5": "Ora locale",
"cs6": "Dimensione carattere messaggio chat",
"cs7": "Standard",
"cs8": "px"
}
}

10
core/language/jp.json

@ -1319,5 +1319,15 @@
"tour20": "ブロックが遅れています。同期プロセスを高速化するために更新 (ブートストラップ) しますか?",
"tour21": "残りのブロック。",
"tour22": "更新 (ブートストラップ) が要求されました。お待ちください。"
},
"chatsettings": {
"cs1": "チャット設定",
"cs2": "一般チャット設定",
"cs3": "チャットメッセージのタイムスタンプ",
"cs4": "過去時間",
"cs5": "現地時間",
"cs6": "チャットメッセージのフォントサイズ",
"cs7": "標準",
"cs8": "px"
}
}

10
core/language/ko.json

@ -1319,5 +1319,15 @@
"tour20": "뒤에 차단되어 있습니다. 동기화 프로세스 속도를 높이기 위해 새로 고치시겠습니까(부트스트랩)?",
"tour21": "남은 블록입니다.",
"tour22": "새로 고침(부트스트랩)이 요청되었습니다. 잠시 기다려 주십시오."
},
"chatsettings": {
"cs1": "채팅 설정",
"cs2": "일반 채팅 설정",
"cs3": "채팅 메시지 타임스탬프",
"cs4": "옛날",
"cs5": "현지 시간",
"cs6": "채팅 메시지 글꼴 크기",
"cs7": "표준",
"cs8": "px"
}
}

10
core/language/nl.json

@ -1319,5 +1319,15 @@
"tour20": "blokken achterstand. Wenst U te herladen ('bootstrap') om het synchronisatie-proces te versnellen?",
"tour21": "blokken te gaan.",
"tour22": "Herladen ('bootstrap') werd aangevraagd. Gelive te wachten."
},
"chatsettings": {
"cs1": "Chatinstellingen",
"cs2": "Algemene chatinstellingen",
"cs3": "Tijdstempel van chatbericht",
"cs4": "Tijd geleden",
"cs5": "Lokale tijd",
"cs6": "Lettergrootte chatbericht",
"cs7": "Standaard",
"cs8": "px"
}
}

10
core/language/no.json

@ -1319,5 +1319,15 @@
"tour20": "blokker bak. Vil du oppdatere (bootstrap) for å fremskynde synkroniseringsprosessen?",
"tour21": "blokker igjen.",
"tour22": "Oppdater (bootstrap) forespurt. Vennligst vent."
},
"chatsettings": {
"cs1": "Chatinnstillinger",
"cs2": "Generelle chatinnstillinger",
"cs3": "Tidsstempel for chatmelding",
"cs4": "For tid siden",
"cs5": "Lokal tid",
"cs6": "Skriftstørrelse for chatmelding",
"cs7": "Standard",
"cs8": "px"
}
}

10
core/language/pl.json

@ -1319,5 +1319,15 @@
"tour20": "bloki za sobą. Czy chcesz odświeżyć (bootstrap), aby przyspieszyć proces synchronizacji?",
"tour21": "pozostałe bloki.",
"tour22": "Zażądano odświeżenia (bootstrap). Proszę czekać."
},
"chatsettings": {
"cs1": "Ustawienia czatu",
"cs2": "Ogólne ustawienia czatu",
"cs3": "Sygnatura czasowa wiadomości czatu",
"cs4": "Czas temu",
"cs5": "Czas lokalny",
"cs6": "Rozmiar czcionki wiadomości czatu",
"cs7": "Standardowy",
"cs8": "px"
}
}

10
core/language/pt.json

@ -1319,5 +1319,15 @@
"tour20": "blocos atrás. Gostaria de atualizar (inicializar) para acelerar o processo de sincronização?",
"tour21": "blocos restantes.",
"tour22": "Atualização (bootstrap) solicitada. Aguarde."
},
"chatsettings": {
"cs1": "Configurações de bate-papo",
"cs2": "Configurações gerais de bate-papo",
"cs3": "Data e hora da mensagem de bate-papo",
"cs4": "Tempo atrás",
"cs5": "Hora Local",
"cs6": "Tamanho da fonte da mensagem de bate-papo",
"cs7": "Padrão",
"cs8": "px"
}
}

10
core/language/ro.json

@ -1319,5 +1319,15 @@
"tour20": "se blochează în urmă. Doriți să reîmprospătați (bootstrap) pentru a accelera procesul de sincronizare?",
"tour21": "blocuri rămase.",
"tour22": "Reîmprospătare (bootstrap) solicitată. Vă rugăm să așteptați."
},
"chatsettings": {
"cs1": "Setări chat",
"cs2": "Setări generale de chat",
"cs3": "Marca temporală a mesajului de chat",
"cs4": "Timp în urmă",
"cs5": "Ora locală",
"cs6": "Dimensiunea fontului mesajului de chat",
"cs7": "Standard",
"cs8": "px"
}
}

10
core/language/rs.json

@ -1319,5 +1319,15 @@
"tour20": "blokovi iza. Da li želite da osvežite (bootstrap) da biste ubrzali proces sinhronizacije?",
"tour21": "preostali blokovi.",
"tour22": "Zatraženo je osvežavanje (bootstrap). Molimo sačekajte."
},
"chatsettings": {
"cs1": "Podešavanja ćaskanja",
"cs2": "Opšta podešavanja ćaskanja",
"cs3": "Vremenska oznaka poruke ćaskanja",
"cs4": "pre vremena",
"cs5": "Lokalno vreme",
"cs6": "Veličina fonta poruke ćaskanja",
"cs7": "Standard",
"cs8": "pk"
}
}

10
core/language/ru.json

@ -1319,5 +1319,15 @@
"tour20": "блоки позади. Хотите обновить (загрузочную загрузку), чтобы ускорить процесс синхронизации?",
"tour21": "осталось блоков.",
"tour22": "Запрошено обновление (загрузочная загрузка). Пожалуйста, подождите."
},
"chatsettings": {
"cs1": "Настройки чата",
"cs2": "Общие настройки чата",
"cs3": "Временная метка сообщения чата",
"cs4": "Время назад",
"cs5": "Местное время",
"cs6": "Размер шрифта сообщения чата",
"cs7": "Стандартный",
"cs8": "px"
}
}

10
core/language/us.json

@ -1319,5 +1319,15 @@
"tour20": "blocks behind. Would you like to refresh (bootstrap) to speed up the syncing process?",
"tour21": "blocks remaining.",
"tour22": "Refresh (bootstrap) requested. Please wait."
},
"chatsettings": {
"cs1": "Chat Settings",
"cs2": "General Chat Settings",
"cs3": "Chat Message Timestamp",
"cs4": "Time Ago",
"cs5": "Local Time",
"cs6": "Chat Message Font Size",
"cs7": "Standard",
"cs8": "px"
}
}

10
core/language/zhc.json

@ -1319,5 +1319,15 @@
"tour20": "落后了。您想刷新(引导)以加快同步过程吗?",
"tour21": "剩余块数。",
"tour22": "已请求刷新(引导)。请稍候。"
},
"chatsettings": {
"cs1": "聊天设置",
"cs2": "常规聊天设置",
"cs3": "聊天消息时间戳",
"cs4": "时间前",
"cs5": "当地时间",
"cs6": "聊天消息字体大小",
"cs7": "标准",
"cs8": "px"
}
}

10
core/language/zht.json

@ -1319,5 +1319,15 @@
"tour20": "落後了。您想刷新(引導)以加快同步過程嗎?",
"tour21": "剩餘塊數。",
"tour22": "已要求刷新(引導)。請稍候。"
},
"chatsettings": {
"cs1": "聊天設定",
"cs2": "常規聊天設定",
"cs3": "聊天訊息時間戳",
"cs4": "很久以前",
"cs5": "當地時間",
"cs6": "聊天訊息字體大小",
"cs7": "標準",
"cs8": "px"
}
}

40
core/src/components/login-view/login-section.js

@ -48,6 +48,8 @@ class LoginSection extends connect(store)(LitElement) {
backedUpWalletJSON: { type: Object },
backedUpSeedLoading: { type: Boolean },
nodeConfig: { type: Object },
names: { type: Array },
namesAvatar: { type: String },
theme: { type: String, reflect: true }
}
}
@ -66,6 +68,8 @@ class LoginSection extends connect(store)(LitElement) {
this.selectedWallet = {}
this.loginErrorMessage = ''
this.saveInBrowser = false
this.names = []
this.namesAvatar = ''
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
this.loginOptions = [
@ -311,7 +315,7 @@ class LoginSection extends connect(store)(LitElement) {
</div>
<div page="unlockStored" id="unlockStoredPage">
<div style="text-align:center;">
<mwc-icon id='accountIcon' style="padding-bottom: 24px; color: var(--black);">account_circle</mwc-icon>
${this.namesAvatar}
<br>
<span style="font-size:14px; font-weight: 100; font-family: 'Roboto Mono', monospace; color: var(--black);">${this.selectedWallet.address0}</span>
</div>
@ -417,9 +421,38 @@ class LoginSection extends connect(store)(LitElement) {
return html`${translate("login.lp8")}`
}
renderLoginAvatar(renderAddress) {
const avatarNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
const avatarUrl = avatarNode.protocol + '://' + avatarNode.domain + ':' + avatarNode.port
const namesUrl = `${avatarUrl}/names/address/${renderAddress}?limit=0&reverse=true`
this.namesAvatar = ''
if (this.isEmptyArray(this.names)) {
fetch(namesUrl).then(response => {
return response.json()
}).then(data => {
this.names = data
if (this.isEmptyArray(this.names)) {
this.namesAvatar = html`<mwc-icon id='accountIcon' style="padding-bottom: 24px; color: var(--black);">account_circle</mwc-icon>`
} else {
const url = `${avatarUrl}/arbitrary/THUMBNAIL/${this.names[0].name}/qortal_avatar?async=true`
this.namesAvatar = html`
<img style="width: 48px; height: 48px; border-radius: 25%; padding-bottom: 16px;" src="${url}" onerror="this.src='/img/incognito.png';" />
<br>
<span style="font-size:16px; font-weight: 400; font-family: 'Roboto Mono', monospace; color: var(--black);">${this.names[0].name}</span>
<br>
`
}
})
}
}
selectWallet(wallet) {
this.selectedWallet = wallet
this.selectedPage = 'unlockStored'
this.names = []
this.renderLoginAvatar(this.selectedWallet.address0)
}
toDeleteWallet(deleteAddress) {
@ -668,6 +701,11 @@ class LoginSection extends connect(store)(LitElement) {
this.selectedPage = this.hasStoredWallets ? 'storedWallet' : 'loginOptions'
this.shadowRoot.querySelector('#deleteWalletDialog').close()
}
isEmptyArray(arr) {
if (!arr) { return true }
return arr.length === 0
}
}
window.customElements.define('login-section', LoginSection)

8
electron.js

@ -38,16 +38,16 @@ crashReporter.start({
})
if (myMemory > 16000000000) {
app.commandLine.appendSwitch('js-flags', '--max-old-space-size=8192')
app.commandLine.appendSwitch('js-flags', '--max-executable-size=192', '--max-old-space-size=8192', '--max-semi-space-size=2')
log.info("Memory Size Is 16GB Using JS Memory Heap Size 8GB")
} else if (myMemory > 12000000000) {
app.commandLine.appendSwitch('js-flags', '--max-old-space-size=6144')
app.commandLine.appendSwitch('js-flags', '--max-executable-size=192', '--max-old-space-size=6144', '--max-semi-space-size=2')
log.info("Memory Size Is 12GB Using JS Memory Heap Size 6GB")
} else if (myMemory > 7000000000) {
app.commandLine.appendSwitch('js-flags', '--max-old-space-size=4096')
app.commandLine.appendSwitch('js-flags', '--max-executable-size=192', '--max-old-space-size=4096', '--max-semi-space-size=2')
log.info("Memory Size Is 8GB Using JS Memory Heap Size 4GB")
} else {
app.commandLine.appendSwitch('js-flags', '--max-old-space-size=2048')
app.commandLine.appendSwitch('js-flags', '--max-executable-size=192', '--max-old-space-size=2048', '--max-semi-space-size=2')
log.info("Memory Size Is 4GB Using JS Memory Heap Size 2GB")
}

115
package-lock.json generated

@ -42,18 +42,18 @@
"prosemirror-gapcursor": "1.3.2",
"prosemirror-history": "1.4.0",
"prosemirror-keymap": "1.2.2",
"prosemirror-model": "1.21.1",
"prosemirror-model": "1.21.3",
"prosemirror-schema-list": "1.4.0",
"prosemirror-state": "1.4.3",
"prosemirror-transform": "1.9.0",
"prosemirror-view": "1.33.8",
"sass": "1.77.5",
"sass": "1.77.6",
"short-unique-id": "5.2.0",
"xhr2": "0.2.1"
},
"devDependencies": {
"@babel/core": "7.24.7",
"@electron/packager": "18.3.2",
"@electron/packager": "18.3.3",
"@material/mwc-button": "0.27.0",
"@material/mwc-checkbox": "0.27.0",
"@material/mwc-dialog": "0.27.0",
@ -101,13 +101,12 @@
"@vaadin/grid": "24.2.9",
"@vaadin/icons": "24.2.9",
"@vaadin/password-field": "24.2.9",
"@vaadin/scroller": "24.2.9",
"@vaadin/tabs": "24.2.9",
"@vaadin/tabsheet": "24.2.9",
"@vaadin/tooltip": "24.2.9",
"@zip.js/zip.js": "2.7.45",
"axios": "1.7.2",
"electron": "31.0.1",
"electron": "31.1.0",
"electron-builder": "24.13.3",
"epml": "0.3.3",
"file-saver": "2.0.5",
@ -126,7 +125,7 @@
"shelljs": "0.8.5"
},
"engines": {
"node": ">=20.14.0"
"node": ">=18.20.3"
}
},
"node_modules/@ampproject/remapping": {
@ -619,9 +618,9 @@
}
},
"node_modules/@electron/packager": {
"version": "18.3.2",
"resolved": "https://registry.npmjs.org/@electron/packager/-/packager-18.3.2.tgz",
"integrity": "sha512-orjylavppgIh24qkNpWm2B/LQUpCS/YLOoKoU+eMK/hJgIhShLDsusPIQzgUGVwNCichu8/zPAGfdQZXHG0gtw==",
"version": "18.3.3",
"resolved": "https://registry.npmjs.org/@electron/packager/-/packager-18.3.3.tgz",
"integrity": "sha512-hGXzwbUdxv49XvlYwlVPC6W6j6WaXUAzKkYyyTeiwdhxvHFMfQSEJxVHsQpqMFzZZ7wrr7iqiokOFZ/qkgEzUQ==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@ -698,9 +697,9 @@
}
},
"node_modules/@electron/universal/node_modules/minimatch": {
"version": "9.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
"integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"license": "ISC",
"dependencies": {
@ -2970,9 +2969,9 @@
}
},
"node_modules/@rollup/plugin-commonjs/node_modules/glob": {
"version": "10.4.1",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz",
"integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==",
"version": "10.4.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz",
"integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==",
"dev": true,
"license": "ISC",
"dependencies": {
@ -2980,6 +2979,7 @@
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
@ -2993,9 +2993,9 @@
}
},
"node_modules/@rollup/plugin-commonjs/node_modules/minimatch": {
"version": "9.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
"integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"license": "ISC",
"dependencies": {
@ -3823,9 +3823,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "20.14.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz",
"integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==",
"version": "20.14.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz",
"integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==",
"devOptional": true,
"license": "MIT",
"dependencies": {
@ -5279,9 +5279,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001634",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001634.tgz",
"integrity": "sha512-fbBYXQ9q3+yp1q1gBk86tOFs4pyn/yxFm5ZNP18OXJDfA3txImOY9PhfxVggZ4vRHDqoU8NrKU81eN0OtzOgRA==",
"version": "1.0.30001638",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001638.tgz",
"integrity": "sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ==",
"dev": true,
"funding": [
{
@ -5588,9 +5588,9 @@
}
},
"node_modules/config-file-ts/node_modules/glob": {
"version": "10.4.1",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz",
"integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==",
"version": "10.4.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz",
"integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==",
"dev": true,
"license": "ISC",
"dependencies": {
@ -5598,6 +5598,7 @@
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
@ -5611,9 +5612,9 @@
}
},
"node_modules/config-file-ts/node_modules/minimatch": {
"version": "9.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
"integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"license": "ISC",
"dependencies": {
@ -6031,9 +6032,9 @@
}
},
"node_modules/electron": {
"version": "31.0.1",
"resolved": "https://registry.npmjs.org/electron/-/electron-31.0.1.tgz",
"integrity": "sha512-2eBcp4iqLkTsml6mMq+iqrS5u3kJ/2mpOLP7Mj7lo0uNK3OyfNqRS9z1ArsHjBF2/HV250Te/O9nKrwQRTX/+g==",
"version": "31.1.0",
"resolved": "https://registry.npmjs.org/electron/-/electron-31.1.0.tgz",
"integrity": "sha512-TBOwqLxSxnx6+pH6GMri7R3JPH2AkuGJHfWZS0p1HsmN+Qr1T9b0IRJnnehSd/3NZAmAre4ft9Ljec7zjyKFJA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@ -6344,9 +6345,9 @@
}
},
"node_modules/electron-to-chromium": {
"version": "1.4.802",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.802.tgz",
"integrity": "sha512-TnTMUATbgNdPXVSHsxvNVSG0uEd6cSZsANjm8c9HbvflZVVn1yTRcmVXYT1Ma95/ssB/Dcd30AHweH2TE+dNpA==",
"version": "1.4.812",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.812.tgz",
"integrity": "sha512-7L8fC2Ey/b6SePDFKR2zHAy4mbdp1/38Yk5TsARO66W3hC5KEaeKMMHoxwtuH+jcu2AYLSn9QX04i95t6Fl1Hg==",
"dev": true,
"license": "ISC"
},
@ -6848,9 +6849,9 @@
}
},
"node_modules/foreground-child": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.0.tgz",
"integrity": "sha512-CrWQNaEl1/6WeZoarcM9LHupTo3RpZO2Pdk1vktwzPiQTsJnAKJmm3TACKeG5UZbWDfaH2AbvYxzP96y0MT7fA==",
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz",
"integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==",
"dev": true,
"license": "ISC",
"dependencies": {
@ -7581,13 +7582,16 @@
}
},
"node_modules/is-core-module": {
"version": "2.13.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
"integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz",
"integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==",
"dev": true,
"license": "MIT",
"dependencies": {
"hasown": "^2.0.0"
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@ -8659,6 +8663,13 @@
"node": ">=6"
}
},
"node_modules/package-json-from-dist": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
"integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==",
"dev": true,
"license": "BlueOak-1.0.0"
},
"node_modules/parse-author": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz",
@ -9016,9 +9027,9 @@
}
},
"node_modules/prosemirror-model": {
"version": "1.21.1",
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.21.1.tgz",
"integrity": "sha512-IVBAuMqOfltTr7yPypwpfdGT+6rGAteVOw2FO6GEvCGGa1ZwxLseqC1Eax/EChDvG/xGquB2d/hLdgh3THpsYg==",
"version": "1.21.3",
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.21.3.tgz",
"integrity": "sha512-nt2Xs/RNGepD9hrrkzXvtCm1mpGJoQfFSPktGa0BF/aav6XsnmVGZ9sTXNWRLupAz5SCLa3EyKlFeK7zJWROKg==",
"license": "MIT",
"dependencies": {
"orderedmap": "^2.0.0"
@ -9649,9 +9660,9 @@
}
},
"node_modules/sass": {
"version": "1.77.5",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.77.5.tgz",
"integrity": "sha512-oDfX1mukIlxacPdQqNb6mV2tVCrnE+P3nVYioy72V5tlk56CPNcO4TCuFcaCRKKfJ1M3lH95CleRS+dVKL2qMg==",
"version": "1.77.6",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz",
"integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==",
"license": "MIT",
"dependencies": {
"chokidar": ">=3.0.0 <4.0.0",
@ -10418,9 +10429,9 @@
}
},
"node_modules/typescript": {
"version": "5.4.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
"version": "5.5.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz",
"integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==",
"dev": true,
"license": "Apache-2.0",
"bin": {

11
package.json

@ -63,18 +63,18 @@
"prosemirror-gapcursor": "1.3.2",
"prosemirror-history": "1.4.0",
"prosemirror-keymap": "1.2.2",
"prosemirror-model": "1.21.1",
"prosemirror-model": "1.21.3",
"prosemirror-schema-list": "1.4.0",
"prosemirror-state": "1.4.3",
"prosemirror-transform": "1.9.0",
"prosemirror-view": "1.33.8",
"sass": "1.77.5",
"sass": "1.77.6",
"short-unique-id": "5.2.0",
"xhr2": "0.2.1"
},
"devDependencies": {
"@babel/core": "7.24.7",
"@electron/packager": "18.3.2",
"@electron/packager": "18.3.3",
"@material/mwc-button": "0.27.0",
"@material/mwc-checkbox": "0.27.0",
"@material/mwc-dialog": "0.27.0",
@ -122,13 +122,12 @@
"@vaadin/grid": "24.2.9",
"@vaadin/icons": "24.2.9",
"@vaadin/password-field": "24.2.9",
"@vaadin/scroller": "24.2.9",
"@vaadin/tabs": "24.2.9",
"@vaadin/tabsheet": "24.2.9",
"@vaadin/tooltip": "24.2.9",
"@zip.js/zip.js": "2.7.45",
"axios": "1.7.2",
"electron": "31.0.1",
"electron": "31.1.0",
"electron-builder": "24.13.3",
"epml": "0.3.3",
"file-saver": "2.0.5",
@ -147,6 +146,6 @@
"shelljs": "0.8.5"
},
"engines": {
"node": ">=20.14.0"
"node": ">=18.20.3"
}
}

20
plugins/plugins/core/components/ChatEmojiFlags.js

@ -0,0 +1,20 @@
import { supportsEmojiFlags } from './ChatTestEmojiFlags'
export function supportCountryFlagEmojis(fontName = "Twemoji Country Flags", fontUrl = "/font/TwemojiCountryFlags.woff2") {
if (typeof window !== "undefined" && supportsEmojiFlags("😊") && !supportsEmojiFlags("🇨🇭")) {
const style = document.createElement("style")
style.textContent = `@font-face {
font-family: "${fontName}";
unicode-range: U+1F1E6-1F1FF, U+1F3F4, U+E0062-E0063, U+E0065, U+E0067, U+E006C, U+E006E, U+E0073-E0074, U+E0077, U+E007F;
src: url('${fontUrl}') format('woff2');
font-display: swap;
}`
document.head.appendChild(style)
return true
}
return false
}

43
plugins/plugins/core/components/ChatPage.js

@ -34,12 +34,14 @@ import './ChatLeaveGroup'
import './ChatGroupSettings'
import './ChatRightPanel'
import './ChatRightPanelResources'
import './ChatRightPanelSettings'
import './ChatSearchResults'
import '@material/mwc-button'
import '@material/mwc-dialog'
import '@material/mwc-icon'
import '@polymer/paper-dialog/paper-dialog.js'
import '@polymer/paper-spinner/paper-spinner-lite.js'
import '@vaadin/tooltip'
// Multi language support
import { get, translate } from '../../../../core/translate'
@ -108,6 +110,7 @@ class ChatPage extends LitElement {
groupMembers: { type: Array },
shifted: { type: Boolean },
shiftedResources: { type: Boolean },
shiftedSettings: { type: Boolean },
groupInfo: { type: Object },
setActiveChatHeadUrl: { attribute: false },
userFound: { type: Array },
@ -200,6 +203,7 @@ class ChatPage extends LitElement {
this.groupMembers = []
this.shifted = false
this.shiftedResources = false
this.shiftedSettings = false
this.groupInfo = {}
this.pageNumber = 1
this.userFoundModalOpen = false
@ -258,6 +262,8 @@ class ChatPage extends LitElement {
}
</div>
<div style="display: flex; height: 100%; align-items: center">
<mwc-icon id="chatsettings" class="top-bar-icon" @click=${this._toggleSettings} style="margin: 0px 10px">settings</mwc-icon>
<vaadin-tooltip for="chatsettings" text=${translate("chatsettings.cs1")} position="start"></vaadin-tooltip>
${(!this.isReceipient && +this._chatId !== 0) ?
html`
<mwc-icon class="top-bar-icon" @click=${this.copyJoinGroupLinkToClipboard} style="margin: 0px 10px">link</mwc-icon>
@ -661,7 +667,12 @@ class ChatPage extends LitElement {
}}
>
${this.forwardActiveChatHeadUrl.selected ?
(html`<div class="user-verified"><p >${translate("chatpage.cchange38")}</p><vaadin-icon icon="vaadin:check-circle-o" slot="icon"></vaadin-icon></div>`)
(html`
<div class="user-verified">
<p>${translate("chatpage.cchange38")}</p>
<vaadin-icon icon="vaadin:check-circle-o" slot="icon"></vaadin-icon>
</div>
`)
: (html`<vaadin-icon @click=${this.userSearch} slot="icon" icon="vaadin:open-book" class="search-icon"></vaadin-icon>`)
}
</div>
@ -695,7 +706,9 @@ class ChatPage extends LitElement {
return html`
<chat-select
activeChatHeadUrl=${this.forwardActiveChatHeadUrl.url}
.setActiveChatHeadUrl=${(val) => {this.forwardActiveChatHeadUrl = {...this.forwardActiveChatHeadUrl, url: val}; this.userFound = [];}}
.setActiveChatHeadUrl=${
(val) => {this.forwardActiveChatHeadUrl = {...this.forwardActiveChatHeadUrl, url: val}; this.userFound = [];}
}
chatInfo=${JSON.stringify(item)}
>
</chat-select>
@ -780,6 +793,12 @@ class ChatPage extends LitElement {
>
</chat-right-panel-resources>
</div>
<div class="chat-right-panel ${this.shiftedSettings ? "movedin" : "movedout"}" ${animate()}>
<chat-right-panel-settings
.toggle=${(val) => this._toggleSettings(val)}
>
</chat-right-panel-settings>
</div>
</div>
`
}
@ -787,6 +806,14 @@ class ChatPage extends LitElement {
async firstUpdated() {
this.changeTheme()
if (localStorage.getItem('timestampForChats') === null) {
localStorage.setItem('timestampForChats', 'ago')
}
if (localStorage.getItem('fontsizeForChats') === null) {
localStorage.setItem('fontsizeForChats', 'font16')
}
window.addEventListener('storage', () => {
const checkLanguage = localStorage.getItem('qortalLanguage')
const checkTheme = localStorage.getItem('qortalTheme')
@ -838,6 +865,11 @@ class ChatPage extends LitElement {
this.requestUpdate()
}
_toggleSettings(value) {
this.shiftedSettings = value === (false || true) ? value : !this.shiftedSettings
this.requestUpdate()
}
setOpenTipUser(props) {
this.openTipUser = props
}
@ -1376,7 +1408,12 @@ class ChatPage extends LitElement {
await this.getUpdateComplete()
const marginElements = Array.from(this.shadowRoot.querySelector('chat-scroller').shadowRoot.querySelectorAll('message-template'))
const findMessage2 = marginElements.find((item) => item.messageObj.signature === message.signature) || marginElements.find((item) => item.messageObj.originalSignature === message.signature) || marginElements.find((item) => item.messageObj.signature === message.originalSignature) || marginElements.find((item) => item.messageObj.originalSignature === message.originalSignature)
const findMessage2 = marginElements.find((item) =>
item.messageObj.signature === message.signature) || marginElements.find(
(item) => item.messageObj.originalSignature === message.signature
)
|| marginElements.find((item) => item.messageObj.signature === message.originalSignature)
|| marginElements.find((item) => item.messageObj.originalSignature === message.originalSignature)
if (findMessage2) {
findMessage2.scrollIntoView({ block: 'center' })
}

271
plugins/plugins/core/components/ChatRightPanelSettings.js

@ -0,0 +1,271 @@
import { html, LitElement } from 'lit'
import { Epml } from '../../../epml'
import { chatRightPanelSettingsStyles } from './plugins-css'
import './WrapperModal'
import '@material/mwc-button'
import '@material/mwc-icon'
import '@vaadin/button'
// Multi language support
import { translate } from '../../../../core/translate'
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
class ChatRightPanelSettings extends LitElement {
static get properties() {
return {
toggle: { attribute: false },
agoTime: { type: Boolean },
isoTime: { type: Boolean },
bothTime: { type: Boolean },
currentFontSize16: { type: Boolean },
currentFontSize18: { type: Boolean },
currentFontSize20: { type: Boolean },
currentFontSize22: { type: Boolean } }
}
static get styles() {
return [chatRightPanelSettingsStyles]
}
constructor() {
super()
this.agoTime = false
this.isoTime = false
this.bothTime = false
this.currentFontSize16 = false
this.currentFontSize18 = false
this.currentFontSize20 = false
this.currentFontSize22 = false
}
render() {
return html`
<div class="container">
<div class="close-row" style="margin-top: 15px">
<vaadin-icon class="top-bar-icon" @click=${() => this.toggle(false)} style="margin: 0px 10px" icon="vaadin:close" slot="icon"></vaadin-icon>
</div>
<div class="container-body">
<div style="margin-top: 5px;">
<p class="group-name">${translate("chatsettings.cs2")}</p>
<hr style="color: var(--black);">
</div>
<div class="group-info">
<p class="group-description">${translate("chatsettings.cs3")}</p>
<div class="checkbox-row">
<label for="agoButton" id="agoButtonLabel" style="color: var(--black);">${translate("chatsettings.cs4")}</label>
<mwc-checkbox
style="margin-right: -15px;"
id="agoButton"
@click=${(e) => this.setAgo(e)}
?checked=${this.agoTime}
></mwc-checkbox>
</div>
<div class="checkbox-row" style="margin-top: -20px;">
<label for="isoButton" id="isoButtonLabel" style="color: var(--black);">${translate("chatsettings.cs5")}</label>
<mwc-checkbox
style="margin-right: -15px;"
id="agoButton"
@click=${(e) => this.setIso(e)}
?checked=${this.isoTime}
></mwc-checkbox>
</div>
<div class="checkbox-row" style="margin-top: -20px;">
<label for="bothButton" id="bothButtonLabel" style="color: var(--black);">${translate("chatsettings.cs5")} + ${translate("chatsettings.cs4")}</label>
<mwc-checkbox
style="margin-right: -15px;"
id="agoButton"
@click=${(e) => this.setBoth(e)}
?checked=${this.bothTime}
></mwc-checkbox>
</div>
</div>
<div><hr style="color: var(--black);"></div>
<div class="group-info">
<p class="group-description">${translate("chatsettings.cs6")}</p>
<div class="checkbox-row">
<label for="font16Button" id="font16ButtonLabel" style="color: var(--black);">${translate("chatsettings.cs7")} 16${translate("chatsettings.cs8")}</label>
<mwc-checkbox
style="margin-right: -15px;"
id="font16Button"
@click=${(e) => this.setFont16(e)}
?checked=${this.currentFontSize16}
></mwc-checkbox>
</div>
<div class="checkbox-row" style="margin-top: -20px;">
<label for="font18Button" id="font18ButtonLabel" style="color: var(--black);">18${translate("chatsettings.cs8")}</label>
<mwc-checkbox
style="margin-right: -15px;"
id="font18Button"
@click=${(e) => this.setFont18(e)}
?checked=${this.currentFontSize18}
></mwc-checkbox>
<span style="color: var(--black)">&nbsp;&nbsp;|&nbsp;&nbsp;</span>
<label for="font24Button" id="font20ButtonLabel" style="color: var(--black);">20${translate("chatsettings.cs8")}</label>
<mwc-checkbox
style="margin-right: -15px;"
id="font20Button"
@click=${(e) => this.setFont20(e)}
?checked=${this.currentFontSize20}
></mwc-checkbox>
<span style="color: var(--black)">&nbsp;&nbsp;|&nbsp;&nbsp;</span>
<label for="font22Button" id="font22ButtonLabel" style="color: var(--black);">22${translate("chatsettings.cs8")}</label>
<mwc-checkbox
style="margin-right: -15px;"
id="font22Button"
@click=${(e) => this.setFont22(e)}
?checked=${this.currentFontSize22}
></mwc-checkbox>
</div>
</div>
</div>
</div>
`
}
firstUpdated() {
this.setTimeFormat()
this.setFontFormat()
}
setTimeFormat() {
if (localStorage.getItem('timestampForChats') === 'ago') {
this.agoTime = true
this.isoTime = false
this.bothTime = false
} else if (localStorage.getItem('timestampForChats') === 'iso') {
this.agoTime = false
this.isoTime = true
this.bothTime = false
} else if (localStorage.getItem('timestampForChats') === 'both') {
this.agoTime = false
this.isoTime = false
this.bothTime = true
}
}
setAgo(e) {
if (!e.target.checked) {
window.localStorage.setItem('timestampForChats', 'ago')
window.dispatchEvent( new Event('storage') )
this.setTimeFormat()
} else {
window.localStorage.setItem('timestampForChats', 'ago')
window.dispatchEvent( new Event('storage') )
this.setTimeFormat()
}
}
setIso(e) {
if (!e.target.checked) {
window.localStorage.setItem('timestampForChats', 'iso')
window.dispatchEvent( new Event('storage') )
this.setTimeFormat()
} else {
window.localStorage.setItem('timestampForChats', 'ago')
window.dispatchEvent( new Event('storage') )
this.setTimeFormat()
}
}
setBoth(e) {
if (!e.target.checked) {
window.localStorage.setItem('timestampForChats', 'both')
window.dispatchEvent( new Event('storage') )
this.setTimeFormat()
} else {
window.localStorage.setItem('timestampForChats', 'ago')
window.dispatchEvent( new Event('storage') )
this.setTimeFormat()
}
}
setFontFormat() {
if (localStorage.getItem('fontsizeForChats') === 'font16') {
this.currentFontSize16 = true
this.currentFontSize18 = false
this.currentFontSize20 = false
this.currentFontSize22 = false
} else if (localStorage.getItem('fontsizeForChats') === 'font18') {
this.currentFontSize16 = false
this.currentFontSize18 = true
this.currentFontSize20 = false
this.currentFontSize22 = false
} else if (localStorage.getItem('fontsizeForChats') === 'font20') {
this.currentFontSize16 = false
this.currentFontSize18 = false
this.currentFontSize20 = true
this.currentFontSize22 = false
} else if (localStorage.getItem('fontsizeForChats') === 'font22') {
this.currentFontSize16 = false
this.currentFontSize18 = false
this.currentFontSize20 = false
this.currentFontSize22 = true
}
}
setFont16(e) {
if (!e.target.checked) {
window.localStorage.setItem('fontsizeForChats', 'font16')
window.dispatchEvent( new Event('storage') )
this.setFontFormat()
} else {
window.localStorage.setItem('fontsizeForChats', 'font16')
window.dispatchEvent( new Event('storage') )
this.setFontFormat()
}
}
setFont18(e) {
if (!e.target.checked) {
window.localStorage.setItem('fontsizeForChats', 'font18')
window.dispatchEvent( new Event('storage') )
this.setFontFormat()
} else {
window.localStorage.setItem('fontsizeForChats', 'font16')
window.dispatchEvent( new Event('storage') )
this.setFontFormat()
}
}
setFont20(e) {
if (!e.target.checked) {
window.localStorage.setItem('fontsizeForChats', 'font20')
window.dispatchEvent( new Event('storage') )
this.setFontFormat()
} else {
window.localStorage.setItem('fontsizeForChats', 'font16')
window.dispatchEvent( new Event('storage') )
this.setFontFormat()
}
}
setFont22(e) {
if (!e.target.checked) {
window.localStorage.setItem('fontsizeForChats', 'font22')
window.dispatchEvent( new Event('storage') )
this.setFontFormat()
} else {
window.localStorage.setItem('fontsizeForChats', 'font16')
window.dispatchEvent( new Event('storage') )
this.setFontFormat()
}
}
// Standard functions
getApiKey() {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return myNode.apiKey
}
isEmptyArray(arr) {
if (!arr) { return true }
return arr.length === 0
}
round(number) {
return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8)
}
}
window.customElements.define('chat-right-panel-settings', ChatRightPanelSettings)

359
plugins/plugins/core/components/ChatScroller.js

@ -241,8 +241,7 @@ class ChatScroller extends LitElement {
isLoadingAfter: { type: Boolean },
messageQueue: { type: Array },
loggedInUserName: { type: String },
loggedInUserAddress: { type: String }
}
loggedInUserAddress: { type: String } }
}
static get styles() {
@ -384,6 +383,7 @@ class ChatScroller extends LitElement {
async firstUpdated() {
this.changeTheme()
window.addEventListener('storage', () => {
const checkTheme = localStorage.getItem('qortalTheme')
@ -1015,7 +1015,14 @@ class MessageTemplate extends LitElement {
addSeenMessage: { attribute: false },
chatId: { type: String },
isInProgress: { type: Boolean },
id: { type: String }
id: { type: String },
timeId: { type: String },
isAgo: { type: Boolean },
isIso: { type: Boolean },
isBoth: { type: Boolean },
fontSize: { type: String },
messageFontSize: { type: String },
replyFontSize: { type: String }
}
}
@ -1045,6 +1052,13 @@ class MessageTemplate extends LitElement {
this.openDeleteGif = false
this.openDeleteAttachment = false
this.openDeleteFile = false
this.timeId = localStorage.getItem('timestampForChats') ? localStorage.getItem('timestampForChats') : 'ago'
this.isAgo = false
this.isIso = false
this.isBoth = false
this.fontSize = localStorage.getItem('fontsizeForChats') ? localStorage.getItem('fontsizeForChats') : 'font16'
this.messageFontSize = ''
this.replyFontSize = ''
}
render() {
@ -1067,6 +1081,7 @@ class MessageTemplate extends LitElement {
let isForwarded = false
let isEdited = false
try {
const parsedMessageObj = JSON.parse(this.messageObj.decodedMessage)
@ -1182,11 +1197,54 @@ class MessageTemplate extends LitElement {
}
}
nameMenu = html`<span class="${this.messageObj.sender === this.myAddress && 'message-data-my-name'}">${this.messageObj.senderName ? this.messageObj.senderName : cropAddress(this.messageObj.sender)}</span>`
nameMenu = html`
<div id="namesize" style=${this.messageFontSize}>
<span class="${this.messageObj.sender === this.myAddress && 'message-data-my-name'}">
${this.messageObj.senderName ? this.messageObj.senderName : cropAddress(this.messageObj.sender)}
</span>
</div>
`
forwarded = html`<span class="${this.messageObj.sender === this.myAddress && 'message-data-forward'}">${translate('blockpage.bcchange17')}</span>`
forwarded = html`
<span class="${this.messageObj.sender === this.myAddress && 'message-data-forward'}">
${translate('blockpage.bcchange17')}
</span>
`
edited = html`<span class="edited-message-style">${translate('chatpage.cchange68')} <message-time timestamp=${(this.messageObj.editedTimestamp === undefined ? Date.now() : this.messageObj.editedTimestamp)}></message-time></span>`
if (this.timeId === 'ago') {
this.isAgo = true
this.isIso = false
this.isBoth = false
} else if (this.timeId === 'iso') {
this.isAgo = false
this.isIso = true
this.isBoth = false
} else if (this.timeId === 'both') {
this.isAgo = false
this.isIso = false
this.isBoth = true
}
if (this.fontSize === 'font16') {
this.messageFontSize = "font-size: 16px"
this.replyFontSize = "font-size: 14px"
} else if (this.fontSize === 'font18') {
this.messageFontSize = "font-size: 18px"
this.replyFontSize = "font-size: 16px"
} else if (this.fontSize === 'font20') {
this.messageFontSize = "font-size: 20px"
this.replyFontSize = "font-size: 18px"
} else if (this.fontSize === 'font22') {
this.messageFontSize = "font-size: 22px"
this.replyFontSize = "font-size: 20px"
}
edited = html`
<span class="edited-message-style">
${translate('chatpage.cchange68')}
<message-time timestamp=${(this.messageObj.editedTimestamp === undefined ? Date.now() : this.messageObj.editedTimestamp)}></message-time>
</span>
`
if (repliedToData) {
try {
@ -1212,7 +1270,16 @@ class MessageTemplate extends LitElement {
}
return hideit ? html`<li class="clearfix"></li>` : html`
<li class="clearfix message-parent" style="${ this.isSingleMessageInGroup === true && this.isLastMessageInGroup === false && reactions.length === 0 ? 'padding-bottom: 0;' : null} ${this.isFirstMessage && 'margin-top: 20px;'}">
<li
class="clearfix message-parent"
style="${
this.isSingleMessageInGroup === true
&& this.isLastMessageInGroup === false
&& reactions.length === 0 ?
'padding-bottom: 0;' : null
}
${this.isFirstMessage && 'margin-top: 20px;'}"
>
<div>
<div class="message-container" style="${this.isSingleMessageInGroup === true && this.isLastMessageInGroup === false && 'margin-bottom: 0'}">
<div class=${`message-subcontainer1 ${this.isInProgress ? 'message-sending' : ''}`}>
@ -1238,20 +1305,46 @@ class MessageTemplate extends LitElement {
message-subcontainer2
${this.myAddress === this.messageObj.sender && 'message-myBg'}
${
((this.isFirstMessage === true && this.isSingleMessageInGroup === false) || (this.isSingleMessageInGroup === true && this.isLastMessageInGroup === true)) && this.myAddress !== this.messageObj.sender ? 'message-triangle'
: ((this.isFirstMessage === true && this.isSingleMessageInGroup === false) || (this.isSingleMessageInGroup === true && this.isLastMessageInGroup === true)) && this.myAddress === this.messageObj.sender ? 'message-myTriangle'
(
(this.isFirstMessage === true && this.isSingleMessageInGroup === false)
|| (this.isSingleMessageInGroup === true && this.isLastMessageInGroup === true)
) && this.myAddress !== this.messageObj.sender ?
'message-triangle'
: (
(this.isFirstMessage === true && this.isSingleMessageInGroup === false)
|| (this.isSingleMessageInGroup === true && this.isLastMessageInGroup === true)
) && this.myAddress === this.messageObj.sender ?
'message-myTriangle'
: null
}
`}"
style="${
this.isSingleMessageInGroup === true && this.isLastMessageInGroup === false ? 'margin-bottom: 0;' : null}
style="
${
this.isSingleMessageInGroup === true
&& this.isLastMessageInGroup === false ?
'margin-bottom: 0;'
: null
}
${
this.isFirstMessage === false && this.isSingleMessageInGroup === true && this.isLastMessageInGroup === false ? 'border-radius: 8px 25px 25px 8px;'
: this.isFirstMessage === true && this.isSingleMessageInGroup === true && this.isLastMessageInGroup === false ? 'border-radius: 27px 25px 25px 12px;'
: this.isFirstMessage === false && this.isSingleMessageInGroup === true && this.isLastMessageInGroup === true ? 'border-radius: 10px 25px 25px 0;'
: this.isFirstMessage === true && this.isSingleMessageInGroup === false && this.isLastMessageInGroup === true ? 'border-radius: 25px 25px 25px 0px;'
this.isFirstMessage === false
&& this.isSingleMessageInGroup === true
&& this.isLastMessageInGroup === false ?
'border-radius: 8px 25px 25px 8px;'
: this.isFirstMessage === true
&& this.isSingleMessageInGroup === true
&& this.isLastMessageInGroup === false ?
'border-radius: 27px 25px 25px 12px;'
: this.isFirstMessage === false
&& this.isSingleMessageInGroup === true
&& this.isLastMessageInGroup === true ?
'border-radius: 10px 25px 25px 0;'
: this.isFirstMessage === true
&& this.isSingleMessageInGroup === false
&& this.isLastMessageInGroup === true ?
'border-radius: 25px 25px 25px 0px;'
: null
}"
}
"
>
<div class="message-user-info">
${this.isFirstMessage ?
@ -1285,20 +1378,35 @@ class MessageTemplate extends LitElement {
</div>
${repliedToData &&
html`
<div class="original-message" @click=${() => {this.goToRepliedMessage(repliedToData, this.messageObj);}}>
<p style=${'cursor: pointer; margin: 0 0 5px 0;'} class=${this.myAddress !== repliedToData.sender ? 'original-message-sender' : 'message-data-my-name'}>
<div
id="replyNameSize"
class="original-message"
style=${this.replyFontSize}
@click=${() => {this.goToRepliedMessage(repliedToData, this.messageObj);}}
>
<p
style=${'cursor: pointer; margin: 0 0 5px 0;'}
class=${
this.myAddress !== repliedToData.sender ?
'original-message-sender' : 'message-data-my-name'
}
>
${repliedToData.senderName ? repliedToData.senderName : cropAddress(repliedToData.sender)}
</p>
<p class="replied-message">
${version && version.toString() === '1' ?
html`
${repliedToData.decodedMessage.messageText}
<div id="replyFontSize" style=${this.replyFontSize}>
${repliedToData.decodedMessage.messageText}
</div>
`
: ''
}
${+version > 1 && repliedToMessageText ?
html`
${unsafeHTML(repliedToMessageText)}
<div id="replyFontSize" style=${this.replyFontSize}>
${unsafeHTML(repliedToMessageText)}
</div>
`
: ''
}
@ -1313,7 +1421,17 @@ class MessageTemplate extends LitElement {
class=${[`image-container`, !this.isImageLoaded ? 'defaultSize' : '',].join(' ')}
style=${this.isFirstMessage && 'margin-top: 10px;'}
>
<div style="display: flex; width: 100%; height: 100%; justify-content: center; align-items: center; cursor: pointer; color: var(--black);">
<div
style="
display: flex;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
cursor: pointer;
color: var(--black);
"
>
${translate('chatpage.cchange40')}
</div>
</div>
@ -1356,7 +1474,17 @@ class MessageTemplate extends LitElement {
class=${[`image-container`, !this.isGifoaded ? 'defaultSize' : '', ].join(' ')}
style=${this.isFirstMessage && 'margin-top: 10px;'}
>
<div style="display: flex; width: 100%; height: 100%; justify-content: center; align-items: center; cursor: pointer; color: var(--black);">
<div
style="
display: flex;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
cursor: pointer;
color: var(--black);
"
>
${translate('gifs.gchange25')}
</div>
</div>
@ -1365,7 +1493,12 @@ class MessageTemplate extends LitElement {
}
${gif && !isGifDeleted && (this.viewImage || this.myAddress === this.messageObj.sender) ?
html`
<div class=${[`image-container`, !this.isGifLoaded ? 'defaultSize' : '',].join(' ')} style=${this.isFirstMessage && 'margin-top: 10px;'}>
<div
class=${
[`image-container`, !this.isGifLoaded ? 'defaultSize' : '',].join(' ')
}
style=${this.isFirstMessage && 'margin-top: 10px;'}
>
${gifHTML}
${this.myAddress === this.messageObj.sender ?
html`
@ -1486,16 +1619,22 @@ class MessageTemplate extends LitElement {
<div id="messageContent" class="message" style=${image && replacedMessage !== '' && 'margin-top: 15px;'}>
${+version > 1 ? messageVersion2WithLink ?
html`
${messageVersion2WithLink}
<div id="fontsize" style=${this.messageFontSize}>
${messageVersion2WithLink}
<div>
`
: html`
${unsafeHTML(messageVersion2)}
<div id="fontsize" style=${this.messageFontSize}>
${unsafeHTML(messageVersion2)}
<div>
`
: ''
}
${version && version.toString() === '1' ?
html`
${unsafeHTML(this.emojiPicker.parse(replacedMessage))}
<div id="fontsize" style=${this.messageFontSize}>
${unsafeHTML(this.emojiPicker.parse(replacedMessage))}
<div>
`
: ''
}
@ -1508,12 +1647,40 @@ class MessageTemplate extends LitElement {
<div
style=${isEdited ? 'justify-content: space-between;' : 'justify-content: flex-end;'}
class="${
(this.isFirstMessage === false && this .isSingleMessageInGroup === true && this.isLastMessageInGroup === true) ||
(this.isFirstMessage === true && this.isSingleMessageInGroup === false && this.isLastMessageInGroup === true) ? 'message-data-time' : 'message-data-time-hidden'
(this.isFirstMessage === false
&& this .isSingleMessageInGroup === true
&& this.isLastMessageInGroup === true
) ||
(this.isFirstMessage === true
&& this.isSingleMessageInGroup === false
&& this.isLastMessageInGroup === true
) ? 'message-data-time' : 'message-data-time-hidden'
}"
>
${isEdited ? html`<span>${edited}</span>` : ''}
${this.isInProgress ? html`<p>${translate('chatpage.cchange91')}</p>` : html`${new Date(this.messageObj.timestamp).toLocaleString()}`}
${this.isInProgress ? html`
<p>${translate('chatpage.cchange91')}</p>
` : this.isAgo ? html`
<div id="timeformat">
<span>
<message-time timestamp=${this.messageObj.timestamp}></message-time>
</span>
</div>
` : this.isIso ? html`
<div id="timeformat">
<span>
${new Date(this.messageObj.timestamp).toLocaleString()}
</span>
</div>
` : this.isBoth ? html`
<div id="timeformat">
<span>
${new Date(this.messageObj.timestamp).toLocaleString()}
( <message-time timestamp=${this.messageObj.timestamp}></message-time> )
</span>
</div>
` : ''
}
</div>
</div>
</div>
@ -1719,6 +1886,140 @@ class MessageTemplate extends LitElement {
}
firstUpdated() {
window.addEventListener('storage', () => {
if (localStorage.getItem('timestampForChats') !== this.timeId) {
this.timeId = localStorage.getItem('timestampForChats')
if (this.timeId === 'ago') {
this.isAgo = true
this.isIso = false
this.isBoth = false
const setTimeFormatAgo = this.shadowRoot.querySelectorAll('#timeformat')
setTimeFormatAgo.forEach((replaceToAgo) => {
replaceToAgo.innerHTML = `
<span>
<message-time timestamp=${this.messageObj.timestamp}></message-time>
</span>
`
})
} else if (this.timeId === 'iso') {
this.isAgo = false
this.isIso = true
this.isBoth = false
const setTimeFormatIso = this.shadowRoot.querySelectorAll('#timeformat')
setTimeFormatIso.forEach((replaceToIso) => {
replaceToIso.innerHTML = `
<span>
${new Date(this.messageObj.timestamp).toLocaleString()}
</span>
`
})
} else if (this.timeId === 'both') {
this.isAgo = false
this.isIso = false
this.isBoth = true
const setTimeFormatBoth = this.shadowRoot.querySelectorAll('#timeformat')
setTimeFormatBoth.forEach((replaceToBoth) => {
replaceToBoth.innerHTML = `
<span>
${new Date(this.messageObj.timestamp).toLocaleString()}
( <message-time timestamp=${this.messageObj.timestamp}></message-time> )
</span>
`
})
}
}
if (localStorage.getItem('fontsizeForChats') !== this.messageFontSize) {
this.messageFontSize = localStorage.getItem('fontsizeForChats')
if (this.messageFontSize === 'font16') {
const setFontSize16 = this.shadowRoot.querySelectorAll('#fontsize')
setFontSize16.forEach((replaceFontSizeTo16) => {
replaceFontSizeTo16.removeAttribute("style")
replaceFontSizeTo16.setAttribute("style", "font-size: 16px;")
})
const setNameSize16 = this.shadowRoot.querySelectorAll('#namesize')
setNameSize16.forEach((replaceNameSizeTo16) => {
replaceNameSizeTo16.removeAttribute("style")
replaceNameSizeTo16.setAttribute("style", "font-size: 16px;")
})
const setReplyFontSize16 = this.shadowRoot.querySelectorAll('#replyFontSize')
setReplyFontSize16.forEach((replaceReplayFontSizeTo16) => {
replaceReplayFontSizeTo16.removeAttribute("style")
replaceReplayFontSizeTo16.setAttribute("style", "font-size: 14px;")
})
const setReplyNameSize16 = this.shadowRoot.querySelectorAll('#replyNameSize')
setReplyNameSize16.forEach((replaceReplayNameSizeTo16) => {
replaceReplayNameSizeTo16.removeAttribute("style")
replaceReplayNameSizeTo16.setAttribute("style", "font-size: 14px;")
})
} else if (this.messageFontSize === 'font18') {
const setFontSize18 = this.shadowRoot.querySelectorAll('#fontsize')
setFontSize18.forEach((replaceFontSizeTo18) => {
replaceFontSizeTo18.removeAttribute("style")
replaceFontSizeTo18.setAttribute("style", "font-size: 18px;")
})
const setNameSize18 = this.shadowRoot.querySelectorAll('#namesize')
setNameSize18.forEach((replaceNameSizeTo18) => {
replaceNameSizeTo18.removeAttribute("style")
replaceNameSizeTo18.setAttribute("style", "font-size: 18px;")
})
const setReplyFontSize18 = this.shadowRoot.querySelectorAll('#replyFontSize')
setReplyFontSize18.forEach((replaceReplayFontSizeTo18) => {
replaceReplayFontSizeTo18.removeAttribute("style")
replaceReplayFontSizeTo18.setAttribute("style", "font-size: 16px;")
})
const setReplyNameSize18 = this.shadowRoot.querySelectorAll('#replyNameSize')
setReplyNameSize18.forEach((replaceReplayNameSizeTo18) => {
replaceReplayNameSizeTo18.removeAttribute("style")
replaceReplayNameSizeTo18.setAttribute("style", "font-size: 16px;")
})
} else if (this.messageFontSize === 'font20') {
const setFontSize20 = this.shadowRoot.querySelectorAll('#fontsize')
setFontSize20.forEach((replaceFontSizeTo20) => {
replaceFontSizeTo20.removeAttribute("style")
replaceFontSizeTo20.setAttribute("style", "font-size: 20px;")
})
const setNameSize20 = this.shadowRoot.querySelectorAll('#namesize')
setNameSize20.forEach((replaceNameSizeTo20) => {
replaceNameSizeTo20.removeAttribute("style")
replaceNameSizeTo20.setAttribute("style", "font-size: 20px;")
})
const setReplyFontSize20 = this.shadowRoot.querySelectorAll('#replyFontSize')
setReplyFontSize20.forEach((replaceReplayFontSizeTo20) => {
replaceReplayFontSizeTo20.removeAttribute("style")
replaceReplayFontSizeTo20.setAttribute("style", "font-size: 18px;")
})
const setReplyNameSize20 = this.shadowRoot.querySelectorAll('#replyNameSize')
setReplyNameSize20.forEach((replaceReplayNameSizeTo20) => {
replaceReplayNameSizeTo20.removeAttribute("style")
replaceReplayNameSizeTo20.setAttribute("style", "font-size: 18px;")
})
} else if (this.messageFontSize === 'font22') {
const setFontSize22 = this.shadowRoot.querySelectorAll('#fontsize')
setFontSize22.forEach((replaceFontSizeTo22) => {
replaceFontSizeTo22.removeAttribute("style")
replaceFontSizeTo22.setAttribute("style", "font-size: 22px;")
})
const setNameSize22 = this.shadowRoot.querySelectorAll('#namesize')
setNameSize22.forEach((replaceNameSizeTo22) => {
replaceNameSizeTo22.removeAttribute("style")
replaceNameSizeTo22.setAttribute("style", "font-size: 22px;")
})
const setReplyFontSize22 = this.shadowRoot.querySelectorAll('#replyFontSize')
setReplyFontSize22.forEach((replaceReplayFontSizeTo22) => {
replaceReplayFontSizeTo22.removeAttribute("style")
replaceReplayFontSizeTo22.setAttribute("style", "font-size: 20px;")
})
const setReplyNameSize22 = this.shadowRoot.querySelectorAll('#replyNameSize')
setReplyNameSize22.forEach((replaceReplayNameSizeTo22) => {
replaceReplayNameSizeTo22.removeAttribute("style")
replaceReplayNameSizeTo22.setAttribute("style", "font-size: 20px;")
})
}
}
})
const autoSeeChatList = window.parent.reduxStore.getState().app.autoLoadImageChats
if (autoSeeChatList.includes(this.chatId) || this.listSeenMessages.includes(this.messageObj.signature)) {

32
plugins/plugins/core/components/ChatTestEmojiFlags.js

@ -0,0 +1,32 @@
const FONT_FAMILY = '"Twemoji Mozilla","Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji","EmojiOne Color","Android Emoji",sans-serif'
function makeCtx() {
const canvas = document.createElement("canvas")
canvas.width = canvas.height = 1
const ctx = canvas.getContext("2d", { willReadFrequently: true })
ctx.textBaseline = "top"
ctx.font = `100px ${FONT_FAMILY}`
ctx.scale(0.01, 0.01)
return ctx
}
function getColor(ctx, text, color) {
ctx.clearRect(0, 0, 100, 100)
ctx.fillStyle = color
ctx.fillText(text, 0, 0)
const bytes = ctx.getImageData(0, 0, 1, 1).data
return bytes.join(",")
}
export function supportsEmojiFlags(text) {
const ctx = makeCtx()
const white = getColor(ctx, text, "#fff")
const black = getColor(ctx, text, "#000")
return black === white && !black.startsWith("0,0,0,")
}

176
plugins/plugins/core/components/plugins-css.js

@ -2755,6 +2755,178 @@ export const levelFounderStyles = css`
}
`
export const chatRightPanelSettingsStyles = css`
.top-bar-icon {
cursor: pointer;
height: 18px;
width: 18px;
color: var(--black);
transition: 0.2s all;
}
.top-bar-icon:hover {
color: #F44336;
}
.red {
color: #F44336;
}
.green {
color: #198754;
}
.modal-button {
font-family: Roboto, sans-serif;
font-size: 16px;
color: var(--mdc-theme-primary);
background-color: transparent;
padding: 8px 10px;
border-radius: 5px;
border: none;
transition: all 0.3s ease-in-out;
}
.close-row {
width: 100%;
display: flex;
justify-content: flex-end;
height: 50px;
flex: 0;
align-items: center;
}
.container-body {
width: 100%;
display: flex;
flex-direction: column;
flex-grow: 1;
overflow: auto;
margin-top: 5px;
padding: 0px 6px;
box-sizing: border-box;
}
.container-body::-webkit-scrollbar-track {
background-color: whitesmoke;
border-radius: 7px;
}
.container-body::-webkit-scrollbar {
width: 6px;
border-radius: 7px;
background-color: whitesmoke;
}
.container-body::-webkit-scrollbar-thumb {
background-color: rgb(180, 176, 176);
border-radius: 7px;
transition: all 0.3s ease-in-out;
}
.container-body::-webkit-scrollbar-thumb:hover {
background-color: rgb(148, 146, 146);
cursor: pointer;
}
p {
color: var(--black);
margin: 0px;
padding: 0px;
word-break: break-all;
}
.container {
display: flex;
width: 100%;
flex-direction: column;
height: 100%;
}
.chat-right-panel-label {
font-family: Montserrat, sans-serif;
color: var(--group-header);
padding: 5px;
font-size: 13px;
user-select: none;
}
.group-info {
display: flex;
flex-direction: column;
justify-content: flex-start;
gap: 10px;
}
.group-name {
font-family: Raleway, sans-serif;
font-size: 20px;
color: var(--chat-bubble-msg-color);
text-align: center;
user-select: none;
}
.group-description {
font-family: Roboto, sans-serif;
color: var(--chat-bubble-msg-color);
letter-spacing: 0.3px;
font-weight: 500;
font-size: 16px;
margin-top: 15px;
word-break: break-word;
user-select: none;
}
.group-subheader {
font-family: Montserrat, sans-serif;
font-size: 14px;
color: var(--chat-bubble-msg-color);
}
.group-data {
font-family: Roboto, sans-serif;
letter-spacing: 0.3px;
font-weight: 300;
font-size: 14px;
color: var(--chat-bubble-msg-color);
}
.message-myBg {
background-color: var(--chat-bubble-myBg) !important;
margin-bottom: 15px;
border-radius: 5px;
padding: 5px;
}
.message-data-name {
user-select: none;
color: #03a9f4;
margin-bottom: 5px;
}
.message-user-info {
display: flex;
justify-content: space-between;
width: 100%;
gap: 10px;
}
.hideImg {
visibility: hidden;
}
.checkbox-row {
position: relative;
display: flex;
align-items: center;
align-content: center;
font-family: Montserrat, sans-serif;
font-weight: 600;
color: var(--black);
padding-left: 5px;
}
`
export const chatRightPanelResourcesStyles = css`
.top-bar-icon {
cursor: pointer;
@ -14031,8 +14203,10 @@ export const multiWalletStyles = css`
}
.qrcode-pos {
margin-top: -175px;
margin-top: -190px;
margin-right: 20px;
float: right;
border: 1px solid var(--black);
}
.send-pos {

2
plugins/plugins/core/q-chat/index.html

@ -41,7 +41,7 @@
html,
body {
margin: 0;
font-family: "Roboto", sans-serif;
font-family: "Twemoji Country Flags", "Roboto", sans-serif;
background: var(--plugback);
overflow: hidden;
}

14
plugins/plugins/core/q-chat/q-chat.src.js

@ -3,6 +3,7 @@ import { render } from 'lit/html.js'
import { Epml } from '../../../epml'
import { passiveSupport } from 'passive-events-support/src/utils'
import { Editor, Extension } from '@tiptap/core'
import { supportCountryFlagEmojis } from '../components/ChatEmojiFlags'
import { qchatStyles } from '../components/plugins-css'
import isElectron from 'is-electron'
import WebWorker from 'web-worker:./computePowWorker'
@ -24,7 +25,6 @@ import '@material/mwc-icon'
import '@material/mwc-snackbar'
import '@polymer/paper-spinner/paper-spinner-lite.js'
import '@vaadin/grid'
import '@vaadin/scroller'
import '@vaadin/tooltip'
// Multi language support
@ -36,6 +36,7 @@ registerTranslateConfig({
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
passiveSupport({ events: ['touchstart'] })
supportCountryFlagEmojis()
class Chat extends LitElement {
static get properties() {
@ -150,14 +151,9 @@ class Chat extends LitElement {
</div>
</div>
</div>
<vaadin-scroller
scroll-direction="vertical"
style="border-bottom: 1px solid var(--lumo-contrast-20pct); padding: var(--lumo-space-s);"
>
<ul class="list">
${this.isEmptyArray(this.chatHeads) ? this.renderLoadingText() : this.renderChatHead(this.chatHeads)}
</ul>
</vaadin-scroller>
<ul>
${this.isEmptyArray(this.chatHeads) ? this.renderLoadingText() : this.renderChatHead(this.chatHeads)}
</ul>
</div>
<div class="chat">
<div id="newMessageBar" class="new-message-bar hide-new-message-bar clearfix" @click=${() => this.scrollToBottom()}>

Loading…
Cancel
Save