This commit is contained in:
AlphaX-Projects 2023-07-24 19:32:13 +02:00
parent b086d2ddc1
commit 34f5be0d03

View File

@ -1,38 +1,38 @@
import { LitElement, html, css } from 'lit'; import { LitElement, html, css } from 'lit'
import { render } from 'lit/html.js'; import { render } from 'lit/html.js'
import { passiveSupport } from 'passive-events-support/src/utils' import { passiveSupport } from 'passive-events-support/src/utils'
passiveSupport({ import { Epml } from '../../../../epml.js'
events: ['touchstart'] import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
})
import { Epml } from '../../../../epml.js';
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate';
import { qchatStyles } from './q-chat-css.src.js' import { qchatStyles } from './q-chat-css.src.js'
import WebWorker from 'web-worker:./computePowWorker.src.js'; import { repeat } from 'lit/directives/repeat.js'
import {repeat} from 'lit/directives/repeat.js'; import { Editor, Extension } from '@tiptap/core'
import isElectron from 'is-electron' import isElectron from 'is-electron'
import WebWorker from 'web-worker:./computePowWorker.src.js'
import StarterKit from '@tiptap/starter-kit'
import Underline from '@tiptap/extension-underline';
import Placeholder from '@tiptap/extension-placeholder'
import Highlight from '@tiptap/extension-highlight'
import snackbar from '../../components/snackbar.js'
import '../../components/ChatWelcomePage.js'
import '../../components/ChatHead.js'
import '../../components/ChatPage.js'
import '../../components/WrapperModal.js'
import '../../components/ChatSeachResults.js'
import '@material/mwc-button'
import '@material/mwc-dialog'
import '@material/mwc-icon'
import '@material/mwc-snackbar'
import '@polymer/paper-spinner/paper-spinner-lite.js'
import '@vaadin/grid'
registerTranslateConfig({ registerTranslateConfig({
loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
}) })
import '../../components/ChatWelcomePage.js' passiveSupport({ events: ['touchstart'] })
import '../../components/ChatHead.js'
import '../../components/ChatPage.js'
import '../../components/WrapperModal.js';
import '../../components/ChatSeachResults.js';
import snackbar from '../../components/snackbar.js'
import '@polymer/paper-spinner/paper-spinner-lite.js'
import '@material/mwc-button'
import '@material/mwc-dialog'
import '@material/mwc-icon'
import '@material/mwc-snackbar'
import '@vaadin/grid'
import StarterKit from '@tiptap/starter-kit'
import Underline from '@tiptap/extension-underline';
import Placeholder from '@tiptap/extension-placeholder'
import Highlight from '@tiptap/extension-highlight'
import { Editor, Extension } from '@tiptap/core'
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
class Chat extends LitElement { class Chat extends LitElement {
@ -58,7 +58,7 @@ class Chat extends LitElement {
userFoundModalOpen: { type: Boolean }, userFoundModalOpen: { type: Boolean },
userSelected: { type: Object }, userSelected: { type: Object },
editor: {type: Object}, editor: {type: Object},
groupInvites: { type: Array }, groupInvites: { type: Array }
} }
} }
@ -70,7 +70,6 @@ class Chat extends LitElement {
this.config = { this.config = {
user: { user: {
node: { node: {
} }
} }
} }
@ -107,23 +106,21 @@ class Chat extends LitElement {
} }
resetChatEditor(){ resetChatEditor(){
this.editor.commands.setContent('') this.editor.commands.setContent('')
} }
async getUpdateCompleteTextEditor() { async getUpdateCompleteTextEditor() {
await super.getUpdateComplete(); await super.getUpdateComplete()
const marginElements = Array.from(this.shadowRoot.querySelectorAll('chat-text-editor')); const marginElements = Array.from(this.shadowRoot.querySelectorAll('chat-text-editor'))
await Promise.all(marginElements.map(el => el.updateComplete)); await Promise.all(marginElements.map(el => el.updateComplete))
const marginElements2 = Array.from(this.shadowRoot.querySelectorAll('wrapper-modal')); const marginElements2 = Array.from(this.shadowRoot.querySelectorAll('wrapper-modal'))
await Promise.all(marginElements2.map(el => el.updateComplete)); await Promise.all(marginElements2.map(el => el.updateComplete))
return true; return true
} }
async connectedCallback() { async connectedCallback() {
super.connectedCallback()
super.connectedCallback(); await this.getUpdateCompleteTextEditor()
await this.getUpdateCompleteTextEditor();
const elementChatId = this.shadowRoot.getElementById('messageBox').shadowRoot.getElementById('privateMessage') const elementChatId = this.shadowRoot.getElementById('messageBox').shadowRoot.getElementById('privateMessage')
this.editor = new Editor({ this.editor = new Editor({
@ -155,33 +152,29 @@ class Chat extends LitElement {
this.unsubscribeStore = window.parent.reduxStore.subscribe(() => { this.unsubscribeStore = window.parent.reduxStore.subscribe(() => {
try { try {
if(window.parent.location && window.parent.location.search) {
if(window.parent.location && window.parent.location.search){ const queryString = window.parent.location.search
const queryString = window.parent.location.search; const params = new URLSearchParams(queryString)
const params = new URLSearchParams(queryString);
const chat = params.get("chat") const chat = params.get("chat")
if(chat && chat !== this.activeChatHeadUrl){ if(chat && chat !== this.activeChatHeadUrl){
let url = window.parent.location.href; let url = window.parent.location.href
let newUrl = url.split("?")[0]; let newUrl = url.split("?")[0]
window.parent.history.pushState({}, "", newUrl); window.parent.history.pushState({}, "", newUrl)
this.setActiveChatHeadUrl(chat) this.setActiveChatHeadUrl(chat)
} }
} }
} catch (error) { } catch (error) {
console.error(error)
} }
})
});
} }
disconnectedCallback() { disconnectedCallback() {
super.disconnectedCallback(); super.disconnectedCallback()
this.editor.destroy(); this.editor.destroy()
this.unsubscribeStore(); this.unsubscribeStore()
} }
updatePlaceholder(editor, text) {
updatePlaceholder(editor, text){
editor.extensionManager.extensions.forEach((extension) => { editor.extensionManager.extensions.forEach((extension) => {
if (extension.name === "placeholder") { if (extension.name === "placeholder") {
@ -196,9 +189,8 @@ class Chat extends LitElement {
<div class="container clearfix"> <div class="container clearfix">
<div class="people-list" id="people-list"> <div class="people-list" id="people-list">
<div class="search"> <div class="search">
<div class="create-chat" @click=${() => { <div class="create-chat" @click=${() => { this.openPrivateMessage = true }}>
this.openPrivateMessage = true; ${translate("chatpage.cchange1")}
}}>${translate("chatpage.cchange1")}
</div> </div>
</div> </div>
<ul class="list"> <ul class="list">
@ -207,9 +199,7 @@ class Chat extends LitElement {
<div class="blockedusers"> <div class="blockedusers">
<!-- <div class="groups-button-container"> <!-- <div class="groups-button-container">
<button <button
@click=${() => { @click=${() => { this.redirectToGroups() }}
this.redirectToGroups();
}}
class="groups-button"> class="groups-button">
<mwc-icon>groups</mwc-icon> <mwc-icon>groups</mwc-icon>
${translate("sidemenu.groupmanagement")} ${translate("sidemenu.groupmanagement")}
@ -246,11 +236,11 @@ class Chat extends LitElement {
<!-- Start Chatting Dialog --> <!-- Start Chatting Dialog -->
<wrapper-modal <wrapper-modal
.onClickFunc=${() => { .onClickFunc=${() => {
this.resetChatEditor(); this.resetChatEditor()
this.openPrivateMessage = false; this.openPrivateMessage = false
this.shadowRoot.getElementById('sendTo').value = ""; this.shadowRoot.getElementById('sendTo').value = ""
this.userFoundModalOpen = false; this.userFoundModalOpen = false;
this.userFound = []; this.userFound = []
} } } }
style=${this.openPrivateMessage ? "visibility:visible;z-index:50" : "visibility: hidden;z-index:-100;position: relative"}> style=${this.openPrivateMessage ? "visibility:visible;z-index:50" : "visibility: hidden;z-index:-100;position: relative"}>
<div style=${"position: relative"}> <div style=${"position: relative"}>
@ -269,8 +259,8 @@ class Chat extends LitElement {
placeholder="${translate("chatpage.cchange7")}" placeholder="${translate("chatpage.cchange7")}"
value=${this.userSelected.name ? this.userSelected.name: ''} value=${this.userSelected.name ? this.userSelected.name: ''}
@keypress=${() => { @keypress=${() => {
this.userSelected = {}; this.userSelected = {}
this.requestUpdate(); this.requestUpdate()
}} }}
/> />
${this.userSelected.name ? ( ${this.userSelected.name ? (
@ -323,8 +313,6 @@ class Chat extends LitElement {
const chatTextEditor = this.shadowRoot.getElementById('messageBox') const chatTextEditor = this.shadowRoot.getElementById('messageBox')
chatTextEditor.sendMessageFunc({ chatTextEditor.sendMessageFunc({
}) })
}} }}
?disabled="${this.isLoading}"> ?disabled="${this.isLoading}">
${this.isLoading === false ${this.isLoading === false
@ -364,9 +352,9 @@ class Chat extends LitElement {
<vaadin-grid theme="compact" id="blockedGrid" ?hidden="${this.isEmptyArray(this.blockedUserList)}" aria-label="Blocked List" .items="${this.blockedUserList}" all-rows-visible> <vaadin-grid theme="compact" id="blockedGrid" ?hidden="${this.isEmptyArray(this.blockedUserList)}" aria-label="Blocked List" .items="${this.blockedUserList}" all-rows-visible>
<vaadin-grid-column auto-width header="${translate("chatpage.cchange11")}" .renderer=${(root, column, data) => { <vaadin-grid-column auto-width header="${translate("chatpage.cchange11")}" .renderer=${(root, column, data) => {
if (data.item.name === "No registered name") { if (data.item.name === "No registered name") {
render(html`${translate("chatpage.cchange15")}`, root); render(html`${translate("chatpage.cchange15")}`, root)
} else { } else {
render(html`${data.item.name}`, root); render(html`${data.item.name}`, root)
} }
}}> }}>
</vaadin-grid-column> </vaadin-grid-column>
@ -392,14 +380,12 @@ class Chat extends LitElement {
` `
} }
async firstUpdated() { async firstUpdated() {
this.changeLanguage(); this.changeLanguage()
this.changeTheme(); this.changeTheme()
this.getChatBlockedList(); this.getChatBlockedList()
this.getLocalBlockedList(); this.getLocalBlockedList()
// await this.getPendingGroupInvites(); // await this.getPendingGroupInvites()
const getBlockedUsers = async () => { const getBlockedUsers = async () => {
let blockedUsers = await parentEpml.request('apiCall', { let blockedUsers = await parentEpml.request('apiCall', {
@ -410,15 +396,15 @@ class Chat extends LitElement {
} }
const stopKeyEventPropagation = (e) => { const stopKeyEventPropagation = (e) => {
e.stopPropagation(); e.stopPropagation()
return false; return false
} }
const nameInput = this.shadowRoot.getElementById('sendTo'); const nameInput = this.shadowRoot.getElementById('sendTo')
nameInput.addEventListener('keydown', stopKeyEventPropagation); nameInput.addEventListener('keydown', stopKeyEventPropagation)
this.shadowRoot.getElementById('messageBox').addEventListener('keydown', stopKeyEventPropagation); this.shadowRoot.getElementById('messageBox').addEventListener('keydown', stopKeyEventPropagation)
const runFunctionsAfterPageLoad = () => { const runFunctionsAfterPageLoad = () => {
// Functions to exec after render while waiting for page info... // Functions to exec after render while waiting for page info...
@ -440,7 +426,7 @@ class Chat extends LitElement {
} }
} }
let runFunctionsAfterPageLoadInterval = setInterval(runFunctionsAfterPageLoad, 100); let runFunctionsAfterPageLoadInterval = setInterval(runFunctionsAfterPageLoad, 100)
window.addEventListener('storage', () => { window.addEventListener('storage', () => {
const checkLanguage = localStorage.getItem('qortalLanguage') const checkLanguage = localStorage.getItem('qortalLanguage')
@ -491,7 +477,6 @@ class Chat extends LitElement {
}) })
}) })
parentEpml.imReady() parentEpml.imReady()
} }
setOpenPrivateMessage(props) { setOpenPrivateMessage(props) {
@ -500,10 +485,10 @@ class Chat extends LitElement {
} }
async userSearch() { async userSearch() {
const nameValue = this.shadowRoot.getElementById('sendTo').value; const nameValue = this.shadowRoot.getElementById('sendTo').value
if(!nameValue) { if(!nameValue) {
this.userFound = []; this.userFound = []
this.userFoundModalOpen = true; this.userFoundModalOpen = true
return; return;
} }
try { try {
@ -512,7 +497,7 @@ class Chat extends LitElement {
url: `/names/${nameValue}` url: `/names/${nameValue}`
}) })
if (result.error === 401) { if (result.error === 401) {
this.userFound = []; this.userFound = []
} else { } else {
this.userFound = [ this.userFound = [
...this.userFound, ...this.userFound,
@ -535,7 +520,7 @@ class Chat extends LitElement {
const trimmedMessage = msg const trimmedMessage = msg
if (/^\s*$/.test(trimmedMessage)) { if (/^\s*$/.test(trimmedMessage)) {
this.isLoading = false; this.isLoading = false
} else { } else {
const messageObject = { const messageObject = {
messageText: trimmedMessage, messageText: trimmedMessage,
@ -544,19 +529,19 @@ class Chat extends LitElement {
version: 3 version: 3
} }
const stringifyMessageObject = JSON.stringify(messageObject) const stringifyMessageObject = JSON.stringify(messageObject)
this.sendMessage(stringifyMessageObject); this.sendMessage(stringifyMessageObject)
} }
} }
async sendMessage(messageText) { async sendMessage(messageText) {
this.isLoading = true; this.isLoading = true
const _recipient = this.shadowRoot.getElementById('sendTo').value; const _recipient = this.shadowRoot.getElementById('sendTo').value
let recipient; let recipient
const validateName = async (receiverName) => { const validateName = async (receiverName) => {
let myRes; let myRes
try { try {
let myNameRes = await parentEpml.request('apiCall', { let myNameRes = await parentEpml.request('apiCall', {
type: 'api', type: 'api',
@ -565,19 +550,19 @@ class Chat extends LitElement {
if (myNameRes.error === 401) { if (myNameRes.error === 401) {
myRes = false; myRes = false;
} else { } else {
myRes = myNameRes; myRes = myNameRes
} }
return myRes; return myRes;
} catch (error) { } catch (error) {
return ""; return ""
} }
}; };
const myNameRes = await validateName(_recipient); const myNameRes = await validateName(_recipient)
if (!myNameRes) { if (!myNameRes) {
recipient = _recipient; recipient = _recipient
} else { } else {
recipient = myNameRes.owner; recipient = myNameRes.owner
}; };
const getAddressPublicKey = async () => { const getAddressPublicKey = async () => {
@ -590,23 +575,23 @@ class Chat extends LitElement {
}) })
if (addressPublicKey.error === 102) { if (addressPublicKey.error === 102) {
_publicKey = false; _publicKey = false
let err4string = get("chatpage.cchange19"); let err4string = get("chatpage.cchange19")
parentEpml.request('showSnackBar', `${err4string}`); parentEpml.request('showSnackBar', `${err4string}`)
this.isLoading = false; this.isLoading = false
} else if (addressPublicKey !== false) { } else if (addressPublicKey !== false) {
isEncrypted = 1; isEncrypted = 1
_publicKey = addressPublicKey; _publicKey = addressPublicKey
sendMessageRequest(isEncrypted, _publicKey); sendMessageRequest(isEncrypted, _publicKey)
} else { } else {
let err4string = get("chatpage.cchange39"); let err4string = get("chatpage.cchange39")
parentEpml.request('showSnackBar', `${err4string}`); parentEpml.request('showSnackBar', `${err4string}`)
this.isLoading = false; this.isLoading = false
} }
}; };
let _reference = new Uint8Array(64); let _reference = new Uint8Array(64)
window.crypto.getRandomValues(_reference); window.crypto.getRandomValues(_reference);
let reference = window.parent.Base58.encode(_reference); let reference = window.parent.Base58.encode(_reference)
const sendMessageRequest = async (isEncrypted, _publicKey) => { const sendMessageRequest = async (isEncrypted, _publicKey) => {
let chatResponse = await parentEpml.request('chat', { let chatResponse = await parentEpml.request('chat', {
type: 18, type: 18,
@ -622,26 +607,26 @@ class Chat extends LitElement {
isEncrypted: 1, isEncrypted: 1,
isText: 1 isText: 1
} }
}); })
_computePow(chatResponse); _computePow(chatResponse);
}; };
const _computePow = async (chatBytes) => { const _computePow = async (chatBytes) => {
const difficulty = this.balance < 4 ? 18 : 8 const difficulty = this.balance < 4 ? 18 : 8
const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full'; const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full'
const worker = new WebWorker(); const worker = new WebWorker()
let nonce = null; let nonce = null
let chatBytesArray = null; let chatBytesArray = null;
await new Promise((res, rej) => { await new Promise((res, rej) => {
worker.postMessage({chatBytes, path, difficulty}); worker.postMessage({chatBytes, path, difficulty})
worker.onmessage = e => { worker.onmessage = e => {
worker.terminate(); worker.terminate()
chatBytesArray = e.data.chatBytesArray; chatBytesArray = e.data.chatBytesArray
nonce = e.data.nonce; nonce = e.data.nonce
res(); res()
} }
}); })
let _response = await parentEpml.request('sign_chat', { let _response = await parentEpml.request('sign_chat', {
nonce: this.selectedAddress.nonce, nonce: this.selectedAddress.nonce,
@ -649,36 +634,36 @@ class Chat extends LitElement {
chatNonce: nonce chatNonce: nonce
}); });
getSendChatResponse(_response); getSendChatResponse(_response)
}; };
const getSendChatResponse = (response) => { const getSendChatResponse = (response) => {
if (response === true) { if (response === true) {
this.setActiveChatHeadUrl(`direct/${recipient}`); this.setActiveChatHeadUrl(`direct/${recipient}`)
this.shadowRoot.getElementById('sendTo').value = ""; this.shadowRoot.getElementById('sendTo').value = ""
this.openPrivateMessage = false; this.openPrivateMessage = false
this.resetChatEditor(); this.resetChatEditor();
} else if (response.error) { } else if (response.error) {
parentEpml.request('showSnackBar', response.message); parentEpml.request('showSnackBar', response.message)
} else { } else {
let err2string = get("chatpage.cchange21"); let err2string = get("chatpage.cchange21")
parentEpml.request('showSnackBar', `${err2string}`); parentEpml.request('showSnackBar', `${err2string}`)
} }
this.isLoading = false; this.isLoading = false
}; }
// Exec.. // Exec..
getAddressPublicKey(); getAddressPublicKey()
} }
insertImage(file) { insertImage(file) {
if (file.type.includes('image')) { if (file.type.includes('image')) {
this.imageFile = file; this.imageFile = file
return; return
} }
parentEpml.request('showSnackBar', get("chatpage.cchange28")); parentEpml.request('showSnackBar', get("chatpage.cchange28"))
} }
renderLoadingText() { renderLoadingText() {
@ -724,7 +709,7 @@ class Chat extends LitElement {
localStorage.removeItem("ChatBlockedAddresses") localStorage.removeItem("ChatBlockedAddresses")
var obj = []; var obj = []
fetch(blockedAddressesUrl).then(response => { fetch(blockedAddressesUrl).then(response => {
return response.json() return response.json()
@ -810,11 +795,11 @@ class Chat extends LitElement {
changeTheme() { changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme') const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') { if (checkTheme === 'dark') {
this.theme = 'dark'; this.theme = 'dark'
} else { } else {
this.theme = 'light'; this.theme = 'light'
} }
document.querySelector('html').setAttribute('theme', this.theme); document.querySelector('html').setAttribute('theme', this.theme)
} }
changeLanguage() { changeLanguage() {
@ -832,20 +817,18 @@ class Chat extends LitElement {
return html` return html`
<chat-welcome-page <chat-welcome-page
myAddress=${JSON.stringify(this.selectedAddress)} myAddress=${JSON.stringify(this.selectedAddress)}
.setOpenPrivateMessage=${(val) => this.setOpenPrivateMessage(val)}> .setOpenPrivateMessage=${(val) => this.setOpenPrivateMessage(val)}
>
</chat-welcome-page>` </chat-welcome-page>`
} }
renderChatHead(chatHeadArr) { renderChatHead(chatHeadArr) {
return chatHeadArr.map(eachChatHead => { return chatHeadArr.map(eachChatHead => {
return html`<chat-head activeChatHeadUrl=${this.activeChatHeadUrl} .setActiveChatHeadUrl=${(val)=> this.setActiveChatHeadUrl(val)} chatInfo=${JSON.stringify(eachChatHead)}></chat-head>` return html`<chat-head activeChatHeadUrl=${this.activeChatHeadUrl} .setActiveChatHeadUrl=${(val)=> this.setActiveChatHeadUrl(val)} chatInfo=${JSON.stringify(eachChatHead)}></chat-head>`
}) })
} }
renderChatPage() { renderChatPage() {
// Check for the chat ID from and render chat messages // Check for the chat ID from and render chat messages
// Else render Welcome to Q-CHat // Else render Welcome to Q-CHat
@ -858,43 +841,51 @@ class Chat extends LitElement {
myAddress=${window.parent.reduxStore.getState().app.selectedAddress.address} myAddress=${window.parent.reduxStore.getState().app.selectedAddress.address}
chatId=${this.activeChatHeadUrl} chatId=${this.activeChatHeadUrl}
.setOpenPrivateMessage=${(val) => this.setOpenPrivateMessage(val)} .setOpenPrivateMessage=${(val) => this.setOpenPrivateMessage(val)}
.setActiveChatHeadUrl=${(val)=> this.setActiveChatHeadUrl(val)}> .setActiveChatHeadUrl=${(val)=> this.setActiveChatHeadUrl(val)}
>
</chat-page> </chat-page>
` `
} }
setChatHeads(chatObj) { setChatHeads(chatObj) {
const chatObjGroups = Array.isArray(chatObj.groups) ? chatObj.groups : []; const chatObjGroups = Array.isArray(chatObj.groups) ? chatObj.groups : []
const chatObjDirect = Array.isArray(chatObj.direct) ? chatObj.direct : []; const chatObjDirect = Array.isArray(chatObj.direct) ? chatObj.direct : []
let groupList = chatObjGroups.map(group => group.groupId === 0 ? { groupId: group.groupId, url: `group/${group.groupId}`, groupName: "Qortal General Chat", timestamp: group.timestamp === undefined ? 2 : group.timestamp, sender: group.sender } : { ...group, timestamp: group.timestamp === undefined ? 1 : group.timestamp, url: `group/${group.groupId}` })
let groupList = chatObjGroups.map(group => group.groupId === 0 ? {
groupId: group.groupId, url: `group/${group.groupId}`,
groupName: "Qortal General Chat",
timestamp: group.timestamp === undefined ? 2 : group.timestamp,
sender: group.sender } : { ...group, timestamp: group.timestamp === undefined ? 1 : group.timestamp, url: `group/${group.groupId}`
})
let directList = chatObjDirect.map(dc => { let directList = chatObjDirect.map(dc => {
return { ...dc, url: `direct/${dc.address}` } return { ...dc, url: `direct/${dc.address}` }
}) })
const compareNames = (a, b) => { const compareNames = (a, b) => {
return a.groupName.localeCompare(b.groupName) return a.groupName.localeCompare(b.groupName)
} }
groupList.sort(compareNames) groupList.sort(compareNames)
let chatHeadMasterList = [...groupList, ...directList] let chatHeadMasterList = [...groupList, ...directList]
const compareArgs = (a, b) => { const compareArgs = (a, b) => {
return b.timestamp - a.timestamp return b.timestamp - a.timestamp
} }
this.chatHeads = chatHeadMasterList.sort(compareArgs) this.chatHeads = chatHeadMasterList.sort(compareArgs)
} }
getChatHeadFromState(chatObj) { getChatHeadFromState(chatObj) {
if (chatObj === undefined) { if (chatObj === undefined) {
return return
} else { } else {
this.chatHeadsObj = chatObj this.chatHeadsObj = chatObj
this.setChatHeads(chatObj) this.setChatHeads(chatObj)
} }
} }
_textArea(e) { _textArea(e) {
if (e.keyCode === 13 && !e.shiftKey) this._sendMessage() if (e.keyCode === 13 && !e.shiftKey) this._sendMessage()
} }
@ -908,13 +899,13 @@ class Chat extends LitElement {
} }
getApiKey() { getApiKey() {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
let apiKey = myNode.apiKey; let apiKey = myNode.apiKey
return apiKey; return apiKey
} }
scrollToBottom() { scrollToBottom() {
const viewElement = this.shadowRoot.querySelector('chat-page').shadowRoot.querySelector('chat-scroller').shadowRoot.getElementById('viewElement'); const viewElement = this.shadowRoot.querySelector('chat-page').shadowRoot.querySelector('chat-scroller').shadowRoot.getElementById('viewElement')
viewElement.scroll({ top: viewElement.scrollHeight, left: 0, behavior: 'smooth' }) viewElement.scroll({ top: viewElement.scrollHeight, left: 0, behavior: 'smooth' })
} }