Fixed view chat timestamp and reworked view chat dialog

This commit is contained in:
AlphaX-Qortal 2025-02-18 10:40:51 +01:00
parent 502952550c
commit 78f25607e2
3 changed files with 180 additions and 126 deletions

View File

@ -2600,12 +2600,17 @@ class ChatPage extends LitElement {
let getInitialMessages = [] let getInitialMessages = []
let count = 0 let count = 0
let isUnread = false let isUnread = false
let chatInfoTimestamp
const chatId = this.chatId const chatId = this.chatId
const findContent = this.chatHeads.find((item) => item.url === chatId) const findContent = this.chatHeads.find((item) => item.url === chatId)
const chatInfoTimestamp = findContent.timestamp || 0
const lastReadMessageTimestamp = this.lastReadMessageTimestamp const lastReadMessageTimestamp = this.lastReadMessageTimestamp
if (findContent === undefined) {
chatInfoTimestamp = 0
} else {
chatInfoTimestamp = findContent.timestamp || 0
}
if (lastReadMessageTimestamp && chatInfoTimestamp) { if (lastReadMessageTimestamp && chatInfoTimestamp) {
if (lastReadMessageTimestamp < chatInfoTimestamp) { if (lastReadMessageTimestamp < chatInfoTimestamp) {
@ -2721,13 +2726,18 @@ class ChatPage extends LitElement {
this.lastReadMessageTimestamp = await chatLastSeen.getItem(this.chatId) || 0 this.lastReadMessageTimestamp = await chatLastSeen.getItem(this.chatId) || 0
if (noInitial) return if (noInitial) return
let getInitialMessages = [] let getInitialMessages = []
const lastReadMessageTimestamp = this.lastReadMessageTimestamp
let isUnread = false let isUnread = false
let chatInfoTimestamp
const chatId = this.chatId const chatId = this.chatId
const findContent = this.chatHeads.find((item) => item.url === chatId) const findContent = this.chatHeads.find((item) => item.url === chatId)
const chatInfoTimestamp = findContent.timestamp || 0 const lastReadMessageTimestamp = this.lastReadMessageTimestamp
if (findContent === undefined) {
chatInfoTimestamp = 0
} else {
chatInfoTimestamp = findContent.timestamp || 0
}
if (lastReadMessageTimestamp && chatInfoTimestamp) { if (lastReadMessageTimestamp && chatInfoTimestamp) {
if (lastReadMessageTimestamp < chatInfoTimestamp) { if (lastReadMessageTimestamp < chatInfoTimestamp) {

View File

@ -7146,18 +7146,28 @@ export const qchatStyles = css`
* { * {
--mdc-theme-primary: rgb(3, 169, 244); --mdc-theme-primary: rgb(3, 169, 244);
--mdc-theme-secondary: var(--mdc-theme-primary); --mdc-theme-secondary: var(--mdc-theme-primary);
--paper-input-container-focus-color: var(--mdc-theme-primary);
--mdc-theme-surface: var(--white); --mdc-theme-surface: var(--white);
--mdc-dialog-content-ink-color: var(--black); --mdc-dialog-content-ink-color: var(--black);
--mdc-dialog-min-width: 750px;
--lumo-primary-text-color: rgb(0, 167, 245); --lumo-primary-text-color: rgb(0, 167, 245);
--lumo-primary-color-50pct: rgba(0, 167, 245, 0.5); --lumo-primary-color-50pct: rgba(0, 167, 245, 0.5);
--lumo-primary-color-10pct: rgba(0, 167, 245, 0.1); --lumo-primary-color-10pct: rgba(0, 167, 245, 0.1);
--lumo-primary-color: hsl(199, 100%, 48%); --lumo-primary-color: hsl(199, 100%, 48%);
--lumo-secondary-text-color: var(--sectxt);
--lumo-contrast-60pct: var(--vdicon);
--item-selected-color: var(--nav-selected-color);
--lumo-base-color: var(--white); --lumo-base-color: var(--white);
--lumo-body-text-color: var(--black); --lumo-body-text-color: var(--black);
--_lumo-grid-border-color: var(--border); --_lumo-grid-border-color: var(--border);
--_lumo-grid-secondary-border-color: var(--border2); --_lumo-grid-secondary-border-color: var(--border2);
--mdc-dialog-min-width: 750px; --item-selected-color-text: var(--nav-selected-color-text);
--item-color-active: var(--nav-color-active);
--item-color-hover: var(--nav-color-hover);
--item-text-color: var(--nav-text-color);
--item-icon-color: var(--nav-icon-color);
--item-border-color: var(--nav-border-color);
--item-border-selected-color: var(--nav-border-selected-color);
--paper-input-container-focus-color: var(--mdc-theme-primary);
} }
paper-spinner-lite { paper-spinner-lite {
@ -7655,109 +7665,108 @@ export const qchatStyles = css`
overflow: hidden; overflow: hidden;
} }
.check-roller { .view-grid {
display: inline-block; width: 120px;
position: relative; height: 120px;
width: 80px;
height: 80px;
}
.check-roller div {
animation: check-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
transform-origin: 40px 40px;
}
.check-roller div:after {
content: " ";
display: block;
position: absolute; position: absolute;
width: 7px; left: 50%;
height: 7px; top: 50%;
}
.view-grid div {
position: absolute;
width: 34px;
height: 34px;
border-radius: 50%; border-radius: 50%;
background: var(--black); background: #03a9f4;
margin: -4px 0 0 -4px; animation: view-grid 1.2s linear infinite;
} }
.check-roller div:nth-child(1) { .view-grid div:nth-child(1) {
animation-delay: -0.036s; top: 4px;
left: 4px;
animation-delay: 0s;
} }
.check-roller div:nth-child(1):after { .view-grid div:nth-child(2) {
top: 63px; top: 4px;
left: 63px;
}
.check-roller div:nth-child(2) {
animation-delay: -0.072s;
}
.check-roller div:nth-child(2):after {
top: 68px;
left: 56px;
}
.check-roller div:nth-child(3) {
animation-delay: -0.108s;
}
.check-roller div:nth-child(3):after {
top: 71px;
left: 48px; left: 48px;
animation-delay: -0.4s;
} }
.check-roller div:nth-child(4) { .view-grid div:nth-child(3) {
animation-delay: -0.144s; top: 4px;
left: 90px;
animation-delay: -0.8s;
} }
.check-roller div:nth-child(4):after { .view-grid div:nth-child(4) {
top: 72px; top: 50px;
left: 40px; left: 4px;
animation-delay: -0.4s;
} }
.check-roller div:nth-child(5) { .view-grid div:nth-child(5) {
animation-delay: -0.18s; top: 50px;
left: 48px;
animation-delay: -0.8s;
} }
.check-roller div:nth-child(5):after { .view-grid div:nth-child(6) {
top: 71px; top: 50px;
left: 32px; left: 90px;
animation-delay: -1.2s;
} }
.check-roller div:nth-child(6) { .view-grid div:nth-child(7) {
animation-delay: -0.216s; top: 95px;
left: 4px;
animation-delay: -0.8s;
} }
.check-roller div:nth-child(6):after { .view-grid div:nth-child(8) {
top: 68px; top: 95px;
left: 24px; left: 48px;
animation-delay: -1.2s;
} }
.check-roller div:nth-child(7) { .view-grid div:nth-child(9) {
animation-delay: -0.252s; top: 95px;
left: 90px;
animation-delay: -1.6s;
} }
.check-roller div:nth-child(7):after { @keyframes view-grid {
top: 63px;
left: 17px;
}
.check-roller div:nth-child(8) {
animation-delay: -0.288s;
}
.check-roller div:nth-child(8):after {
top: 56px;
left: 12px;
}
@keyframes check-roller {
0% {
transform: rotate(0deg);
}
0%,
100% { 100% {
transform: rotate(360deg); opacity: 1;
} }
50% {
opacity: 0.5;
}
}
paper-dialog.viewSettings {
min-width: 525px;
max-width: 525px;
min-height: auto;
max-height: 150px;
background-color: var(--white);
color: var(--black);
line-height: 1.6;
overflow: hidden;
border: 1px solid var(--black);
border-radius: 10px;
padding: 15px;
box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
}
.view {
display: inline;
width: 50%;
align-items: center;
} }
` `

View File

@ -39,6 +39,7 @@ import '@polymer/paper-icon-button/paper-icon-button.js'
import '@polymer/paper-spinner/paper-spinner-lite.js' import '@polymer/paper-spinner/paper-spinner-lite.js'
import '@vaadin/grid' import '@vaadin/grid'
import '@vaadin/tooltip' import '@vaadin/tooltip'
import '@vaadin/text-field'
// Multi language support // Multi language support
import { get, registerTranslateConfig, translate, use } from '../../../../core/translate' import { get, registerTranslateConfig, translate, use } from '../../../../core/translate'
@ -62,6 +63,7 @@ class Chat extends LitElement {
messages: { type: Array }, messages: { type: Array },
btnDisable: { type: Boolean }, btnDisable: { type: Boolean },
isLoading: { type: Boolean }, isLoading: { type: Boolean },
isViewOpen: { type: Boolean },
balance: { type: Number }, balance: { type: Number },
theme: { type: String, reflect: true }, theme: { type: String, reflect: true },
blockedUsers: { type: Array }, blockedUsers: { type: Array },
@ -69,6 +71,7 @@ class Chat extends LitElement {
privateMessagePlaceholder: { type: String }, privateMessagePlaceholder: { type: String },
imageFile: { type: Object }, imageFile: { type: Object },
activeChatHeadUrl: { type: String }, activeChatHeadUrl: { type: String },
switchChatHeadUrl: { type: String },
openPrivateMessage: { type: Boolean }, openPrivateMessage: { type: Boolean },
userFound: { type: Array }, userFound: { type: Array },
userFoundModalOpen: { type: Boolean }, userFoundModalOpen: { type: Boolean },
@ -102,6 +105,7 @@ class Chat extends LitElement {
this.messages = [] this.messages = []
this.btnDisable = false this.btnDisable = false
this.isLoading = false this.isLoading = false
this.isViewOpen = false
this.showNewMessageBar = this.showNewMessageBar.bind(this) this.showNewMessageBar = this.showNewMessageBar.bind(this)
this.hideNewMessageBar = this.hideNewMessageBar.bind(this) this.hideNewMessageBar = this.hideNewMessageBar.bind(this)
this.setOpenPrivateMessage = this.setOpenPrivateMessage.bind(this) this.setOpenPrivateMessage = this.setOpenPrivateMessage.bind(this)
@ -113,6 +117,7 @@ class Chat extends LitElement {
this.privateMessagePlaceholder = '' this.privateMessagePlaceholder = ''
this.imageFile = null this.imageFile = null
this.activeChatHeadUrl = '' this.activeChatHeadUrl = ''
this.switchChatHeadUrl = ''
this.openPrivateMessage = false this.openPrivateMessage = false
this.userFound = [] this.userFound = []
this.userFoundModalOpen = false this.userFoundModalOpen = false
@ -140,7 +145,7 @@ class Chat extends LitElement {
</vaadin-tooltip> </vaadin-tooltip>
</div> </div>
<div style="display:flex; align-items:center;gap:10px"> <div style="display:flex; align-items:center;gap:10px">
<div id="viewChat" class="create-chat" @click=${() => { this.shadowRoot.querySelector('#viewChatDialog').show() }}> <div id="viewChat" class="create-chat" @click=${() => { this.openView(this.activeChatHeadUrl) }}>
<mwc-icon style="color: var(--black);">pageview</mwc-icon> <mwc-icon style="color: var(--black);">pageview</mwc-icon>
<vaadin-tooltip <vaadin-tooltip
for="viewChat" for="viewChat"
@ -185,7 +190,11 @@ class Chat extends LitElement {
<span>${translate("chatpage.cchange5")} <mwc-icon style="font-size: 16px; vertical-align: bottom;">keyboard_arrow_down</mwc-icon></span> <span>${translate("chatpage.cchange5")} <mwc-icon style="font-size: 16px; vertical-align: bottom;">keyboard_arrow_down</mwc-icon></span>
</div> </div>
<div class="chat-history"> <div class="chat-history">
${this.activeChatHeadUrl ? html`${this.renderChatPage()}` : html`${this.renderChatWelcomePage()}`} ${this.activeChatHeadUrl ?
html`${this.renderChatPage()}`
: this.isViewOpen ? html`${this.renderChatViewPage()}`
: html`${this.renderChatWelcomePage()}`
}
</div> </div>
</div> </div>
<!-- Start Chatting Dialog --> <!-- Start Chatting Dialog -->
@ -315,43 +324,24 @@ class Chat extends LitElement {
</mwc-button> </mwc-button>
</mwc-dialog> </mwc-dialog>
<!-- View Chat Over ID --> <!-- View Chat Over ID -->
<mwc-dialog id="viewChatDialog"> <paper-dialog id="viewChatDialog" class="viewSettings" modal>
<div style="text-align: center;"> <div style="display: inline;">
<h1>${translate("modals.mpchange87")}</h1> <div class="view">
<hr> <vaadin-text-field
<br> style="width: 350px"
</div>
<div style="display: flex; align-items: center;">
<mwc-textfield
style="width: 100%;"
required
id="groupIdInput" id="groupIdInput"
label="${translate("managegroup.mg8")}" required
type="number" allowed-char-pattern="[0-9]"
auto-validate="false" placeholder="${translate("modals.mpchange87")}"
value="" value=""
@keydown="${this.viewKeyListener}"
clear-button-visible
> >
</mwc-textfield> </vaadin-text-field>
<paper-icon-button icon="icons:visibility" @click="${() => this.switchChatID()}" title="${translate("general.view")}"></paper-icon-button>
<paper-icon-button icon="icons:close" @click="${() => this.closeView()}" title="${translate("general.close")}"></paper-icon-button>
</div> </div>
<mwc-button slot="primaryAction" dialogAction="cancel" class="red">
${translate("general.close")}
</mwc-button>
<mwc-button slot="secondaryAction" class="green" @click=${this.switchChatID}>
${translate("general.view")}
</mwc-button>
</mwc-dialog>
<paper-dialog id="checkIdDialog" class="check" modal>
<div class="check-roller">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div> </div>
<h2>Checking</h2>
</paper-dialog> </paper-dialog>
</div> </div>
` `
@ -499,8 +489,6 @@ class Chat extends LitElement {
viewGroupID = this.shadowRoot.getElementById('groupIdInput').value viewGroupID = this.shadowRoot.getElementById('groupIdInput').value
this.shadowRoot.getElementById('checkIdDialog').open()
await parentEpml.request('apiCall', { await parentEpml.request('apiCall', {
url: `/groups/${viewGroupID}` url: `/groups/${viewGroupID}`
}).then(res => { }).then(res => {
@ -508,25 +496,55 @@ class Chat extends LitElement {
}) })
if (checkTheID.error) { if (checkTheID.error) {
this.shadowRoot.getElementById('checkIdDialog').close()
this.shadowRoot.getElementById('viewChatDialog').close() this.shadowRoot.getElementById('viewChatDialog').close()
this.shadowRoot.getElementById('groupIdInput').value = '' this.shadowRoot.getElementById('groupIdInput').value = ''
this.isViewOpen = false
this.activeChatHeadUrl = this.switchChatHeadUrl
this.switchChatHeadUrl = ''
this.resetChatEditor()
parentEpml.request('showSnackBar', `${notFound}`) parentEpml.request('showSnackBar', `${notFound}`)
} else if (checkTheID.groupId) { } else if (checkTheID.groupId) {
let switchToID = checkTheID.groupName let switchToID = checkTheID.groupName
this.shadowRoot.getElementById('checkIdDialog').close()
this.shadowRoot.getElementById('viewChatDialog').close() this.shadowRoot.getElementById('viewChatDialog').close()
this.shadowRoot.getElementById('groupIdInput').value = '' this.shadowRoot.getElementById('groupIdInput').value = ''
this.switchChatHeadUrl = ''
parentEpml.request('showSnackBar', `${switchToID}`) parentEpml.request('showSnackBar', `${switchToID}`)
this.processChatID(checkTheID.groupId) this.processChatID(checkTheID.groupId)
} else { } else {
this.shadowRoot.getElementById('checkIdDialog').close()
this.shadowRoot.getElementById('viewChatDialog').close() this.shadowRoot.getElementById('viewChatDialog').close()
this.shadowRoot.getElementById('groupIdInput').value = '' this.shadowRoot.getElementById('groupIdInput').value = ''
this.isViewOpen = false
this.activeChatHeadUrl = this.switchChatHeadUrl
this.switchChatHeadUrl = ''
this.resetChatEditor()
parentEpml.request('showSnackBar', `${wentWrong}`) parentEpml.request('showSnackBar', `${wentWrong}`)
} }
} }
openView(currentUrl) {
this.switchChatHeadUrl = currentUrl
this.activeChatHeadUrl = ''
this.isViewOpen = true
this.shadowRoot.getElementById('viewChatDialog').open()
this.shadowRoot.getElementById('groupIdInput').value = ''
this.resetChatEditor()
}
closeView() {
this.shadowRoot.getElementById('viewChatDialog').close()
this.shadowRoot.getElementById('groupIdInput').value = ''
this.isViewOpen = false
this.activeChatHeadUrl = this.switchChatHeadUrl
this.switchChatHeadUrl = ''
this.resetChatEditor()
}
viewKeyListener(e) {
if (e.key === 'Enter') {
this.switchChatID()
}
}
async processChatID(newID) { async processChatID(newID) {
let viewNewUrl = 'group/' + newID let viewNewUrl = 'group/' + newID
this.setActiveChatHeadUrl(viewNewUrl) this.setActiveChatHeadUrl(viewNewUrl)
@ -535,6 +553,7 @@ class Chat extends LitElement {
async setActiveChatHeadUrl(url) { async setActiveChatHeadUrl(url) {
await this.getSymKeyFile(url) await this.getSymKeyFile(url)
this.isViewOpen = false
} }
async getSymKeyFile(url) { async getSymKeyFile(url) {
@ -1153,6 +1172,22 @@ class Chat extends LitElement {
` `
} }
renderChatViewPage() {
return html`
<div class="view-grid">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
`
}
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>`