Browse Source

Merge remote-tracking branch 'justin/feature/implement-UI-edit-reply-messages' into feature/implement-logic-edit-reply-messages

q-apps
Phillip Lang Martinez 2 years ago
parent
commit
3f099258bd
  1. 6
      qortal-ui-core/font/switch-theme.css
  2. 6
      qortal-ui-core/src/styles/switch-theme.css
  3. 34
      qortal-ui-plugins/plugins/core/components/ChatPage.js
  4. 59
      qortal-ui-plugins/plugins/core/components/ChatScroller-css.js
  5. 153
      qortal-ui-plugins/plugins/core/components/ChatScroller.js
  6. 8
      qortal-ui-plugins/plugins/utils/cropAddress.js

6
qortal-ui-core/font/switch-theme.css

@ -7,7 +7,9 @@ html {
--border: #d0d6de; --border: #d0d6de;
--border2: #dde2e8; --border2: #dde2e8;
--copybutton: #707584; --copybutton: #707584;
--chat-bubble: #efefef73; --chat-bubble: #9f9f9f0a;
--chat-bubble-bg: #f3f3f3;
--chat-bubble-msg-color: #080808;
--sectxt: #576374; --sectxt: #576374;
--vdicon: #707b8a; --vdicon: #707b8a;
--tradehead: #6a6c75; --tradehead: #6a6c75;
@ -45,6 +47,8 @@ html[theme="dark"] {
--border2: #0b305e; --border2: #0b305e;
--copybutton: #d0d6de; --copybutton: #d0d6de;
--chat-bubble: #9694941a; --chat-bubble: #9694941a;
--chat-bubble-bg: #2d3749;
--chat-bubble-msg-color: #ffffff;
--sectxt: #bbc3cd; --sectxt: #bbc3cd;
--vdicon: #d0d6de; --vdicon: #d0d6de;
--tradehead: #008fd5; --tradehead: #008fd5;

6
qortal-ui-core/src/styles/switch-theme.css

@ -7,7 +7,9 @@ html {
--border: #d0d6de; --border: #d0d6de;
--border2: #dde2e8; --border2: #dde2e8;
--copybutton: #707584; --copybutton: #707584;
--chat-bubble: #efefef73; --chat-bubble: #9f9f9f0a;
--chat-bubble-bg: #f3f3f3;
--chat-bubble-msg-color: #080808;
--sectxt: #576374; --sectxt: #576374;
--vdicon: #707b8a; --vdicon: #707b8a;
--tradehead: #6a6c75; --tradehead: #6a6c75;
@ -44,6 +46,8 @@ html[theme="dark"] {
--border2: #0b305e; --border2: #0b305e;
--copybutton: #d0d6de; --copybutton: #d0d6de;
--chat-bubble: #9694941a; --chat-bubble: #9694941a;
--chat-bubble-bg: #2d3749;
--chat-bubble-msg-color: #ffffff;
--sectxt: #bbc3cd; --sectxt: #bbc3cd;
--vdicon: #d0d6de; --vdicon: #d0d6de;
--tradehead: #008fd5; --tradehead: #008fd5;

34
qortal-ui-plugins/plugins/core/components/ChatPage.js

@ -130,6 +130,7 @@ class ChatPage extends LitElement {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
justify-content: center;
gap: 15px; gap: 15px;
width: 100%; width: 100%;
} }
@ -138,7 +139,7 @@ class ChatPage extends LitElement {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 5px; gap: 5px;
width: 95%; width: 92%;
} }
@ -639,7 +640,6 @@ class ChatPage extends LitElement {
<p class="senderName">${this.repliedToMessageObj.senderName ? this.repliedToMessageObj.senderName : this.repliedToMessageObj.sender}</p> <p class="senderName">${this.repliedToMessageObj.senderName ? this.repliedToMessageObj.senderName : this.repliedToMessageObj.sender}</p>
<p class="original-message">${this.repliedToMessageObj.message}</p> <p class="original-message">${this.repliedToMessageObj.message}</p>
</div> </div>
</div>
<vaadin-icon <vaadin-icon
class="close-icon" class="close-icon"
icon="vaadin:close-big" icon="vaadin:close-big"
@ -647,6 +647,7 @@ class ChatPage extends LitElement {
@click=${() => this.closeRepliedToContainer()} @click=${() => this.closeRepliedToContainer()}
></vaadin-icon> ></vaadin-icon>
</div> </div>
</div>
`} `}
${this.editedMessageObj && html` ${this.editedMessageObj && html`
<div class="repliedTo-container"> <div class="repliedTo-container">
@ -656,7 +657,6 @@ class ChatPage extends LitElement {
<p class="senderName">${translate("chatpage.cchange25")}</p> <p class="senderName">${translate("chatpage.cchange25")}</p>
<p class="original-message">${this.editedMessageObj.message}</p> <p class="original-message">${this.editedMessageObj.message}</p>
</div> </div>
</div>
<vaadin-icon <vaadin-icon
class="close-icon" class="close-icon"
icon="vaadin:close-big" icon="vaadin:close-big"
@ -664,10 +664,13 @@ class ChatPage extends LitElement {
@click=${() => this.closeEditMessageContainer()} @click=${() => this.closeEditMessageContainer()}
></vaadin-icon> ></vaadin-icon>
</div> </div>
</div>
`} `}
<div class="chatbar" style="${this.chatMessageSize >= 750 && 'padding-bottom: 7px'}"> <div class="chatbar" style="${this.chatMessageSize >= 750 && 'padding-bottom: 7px'}">
<div class="chatbar-container" style="${this.chatMessageInput && this.chatMessageInput.contentDocument.body.scrollHeight > 60 ? 'align-items: flex-end' : "align-items: center"}" <div class="chatbar-container" style="${this.chatMessageInput && this.chatMessageInput.contentDocument.body.scrollHeight > 60 ? 'align-items: flex-end' : "align-items: center"}"
> >
${this.accountName && (
html`
<div class="file-picker-container"> <div class="file-picker-container">
<vaadin-icon <vaadin-icon
class="paperclip-icon" class="paperclip-icon"
@ -683,9 +686,11 @@ class ChatPage extends LitElement {
class="file-picker-input" type="file" name="myImage" accept="image/*" /> class="file-picker-input" type="file" name="myImage" accept="image/*" />
</div> </div>
</div> </div>
`
)}
<textarea style="color: var(--black);" tabindex='1' ?autofocus=${true} ?disabled=${this.isLoading || this.isLoadingMessages} id="messageBox" rows="1"></textarea> <textarea style="color: var(--black);" tabindex='1' ?autofocus=${true} ?disabled=${this.isLoading || this.isLoadingMessages} id="messageBox" rows="1"></textarea>
<iframe <iframe
}}" id="_chatEditorDOM" class="chat-editor" tabindex="-1" height=${this.iframeHeight}> id="_chatEditorDOM" class="chat-editor" tabindex="-1" height=${this.iframeHeight}>
</iframe> </iframe>
<button class="emoji-button" ?disabled=${this.isLoading || this.isLoadingMessages}> <button class="emoji-button" ?disabled=${this.isLoading || this.isLoadingMessages}>
${html`<img class="emoji" draggable="false" alt="😀" src="/emoji/svg/1f600.svg" />`} ${html`<img class="emoji" draggable="false" alt="😀" src="/emoji/svg/1f600.svg" />`}
@ -787,6 +792,7 @@ class ChatPage extends LitElement {
this.emojiPickerHandler = this.shadowRoot.querySelector('.emoji-button'); this.emojiPickerHandler = this.shadowRoot.querySelector('.emoji-button');
this.mirrorChatInput = this.shadowRoot.getElementById('messageBox'); this.mirrorChatInput = this.shadowRoot.getElementById('messageBox');
this.chatMessageInput = this.shadowRoot.getElementById('_chatEditorDOM'); this.chatMessageInput = this.shadowRoot.getElementById('_chatEditorDOM');
this.accountName = window.parent.reduxStore.getState().app.accountInfo.names[0];
document.addEventListener('keydown', (e) => { document.addEventListener('keydown', (e) => {
if (!this.chatEditor.content.body.matches(':focus')) { if (!this.chatEditor.content.body.matches(':focus')) {
// WARNING: Deprecated methods from KeyBoard Event // WARNING: Deprecated methods from KeyBoard Event
@ -1515,7 +1521,7 @@ class ChatPage extends LitElement {
} }
} }
if(outSideMsg && outSideMsg.type === 'delete'){ if (outSideMsg && outSideMsg.type === 'delete') {
this.isDeletingImage = true this.isDeletingImage = true
const userName = outSideMsg.name const userName = outSideMsg.name
const identifier = outSideMsg.identifier const identifier = outSideMsg.identifier
@ -1542,19 +1548,18 @@ class ChatPage extends LitElement {
return blob; return blob;
} }
const blob = b64toBlob(str, 'image/png'); const blob = b64toBlob(str, 'image/png');
await new Promise(resolve => { await new Promise(resolve => {
new Compressor( blob, { new Compressor(blob, {
quality: 0.6, quality: 0.6,
maxWidth: 500, maxWidth: 500,
success(result){ success(result) {
console.log({result}) console.log({result});
const file = new File([result], "name", { const file = new File([result], "name", {
type: 'image/png' type: 'image/png'
}); });
console.log({file}) console.log({file});
compressedFile = file compressedFile = file;
resolve() resolve();
}, },
error(err) { error(err) {
console.log(err.message); console.log(err.message);
@ -1617,7 +1622,7 @@ class ChatPage extends LitElement {
const identifier = `qchat_${id}`; const identifier = `qchat_${id}`;
let compressedFile = ''; let compressedFile = '';
await new Promise(resolve => { await new Promise(resolve => {
new Compressor( outSideMsg.imageFile, { new Compressor(outSideMsg.imageFile, {
quality: .6, quality: .6,
maxWidth: 500, maxWidth: 500,
success(result){ success(result){
@ -1632,7 +1637,6 @@ class ChatPage extends LitElement {
}, },
}) })
}) })
const fileSize = compressedFile.size; const fileSize = compressedFile.size;
if (fileSize > 5000000) { if (fileSize > 5000000) {
parentEpml.request('showSnackBar', get("chatpage.cchange26")); parentEpml.request('showSnackBar', get("chatpage.cchange26"));
@ -1844,8 +1848,6 @@ class ChatPage extends LitElement {
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

59
qortal-ui-plugins/plugins/core/components/ChatScroller-css.js

@ -82,8 +82,14 @@ export const chatStyles = css`
} }
.message-data-name { .message-data-name {
color: var(--black);
user-select: none; user-select: none;
color: #03a9f4;
margin-bottom: 5px;
}
.message-data-my-name {
color: #cf21e8;
text-shadow: 0 0 3px #cf21e8;
} }
.message-data-time { .message-data-time {
@ -109,21 +115,42 @@ export const chatStyles = css`
.message-container { .message-container {
position: relative; position: relative;
margin-bottom: 20px;
} }
.message-subcontainer { .message-subcontainer1 {
position: relative; position: relative;
display: flex; display: flex;
background-color: #f3f3f3; align-items: flex-end;
}
.message-subcontainer2 {
position: relative;
display: flex;
background-color: var(--chat-bubble-bg);
flex-grow: 0; flex-grow: 0;
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
justify-content: center; justify-content: center;
border-radius: 5px; border-radius: 5px;
padding: 10px 15px; padding: 12px 15px;
gap: 10px; width: fit-content;
margin-bottom: 10px; min-width: 150px;
}
.message-triangle {
position: relative;
}
.message-triangle:after {
content: "";
position: absolute;
bottom: 0px;
left: -9px;
width: 0;
height: 0;
border-style: solid;
border-width: 0px 0px 7px 9px;
border-color: transparent transparent var(--chat-bubble-bg) transparent;
} }
.message-reactions { .message-reactions {
@ -136,16 +163,14 @@ export const chatStyles = css`
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
color: black; color: var(--chat-bubble-msg-color);
line-height: 19px; line-height: 19px;
overflow-wrap: break-word;
user-select: text; user-select: text;
font-size: 13px; font-size: 15px;
width: 90%; width: 90%;
border-radius: 5px; border-radius: 5px;
background-color: rgba(232, 232, 232, 0.79);
padding: 8px 5px 8px 25px; padding: 8px 5px 8px 25px;
white-space: nowrap; margin-bottom: 10px;
} }
.original-message:before { .original-message:before {
@ -165,12 +190,14 @@ export const chatStyles = css`
.replied-message { .replied-message {
margin: 0; margin: 0;
white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
max-width: 300px;
} }
.message { .message {
color: black; color: var(--chat-bubble-msg-color);
line-height: 19px; line-height: 19px;
word-wrap: break-word; word-wrap: break-word;
-webkit-user-select: text; -webkit-user-select: text;
@ -178,12 +205,12 @@ export const chatStyles = css`
-ms-user-select: text; -ms-user-select: text;
user-select: text; user-select: text;
font-size: 16px; font-size: 16px;
width: 90%; width: 100%;
position: relative; position: relative;
} }
.message-data-avatar { .message-data-avatar {
margin: 0px 8px 3px 3px; margin: 0px 10px 0px 3px;
width: 42px; width: 42px;
height: 42px; height: 42px;
float: left; float: left;
@ -207,7 +234,7 @@ export const chatStyles = css`
.chat-hover { .chat-hover {
display: none; display: none;
position: absolute; position: absolute;
top: -38px; top: -25px;
right: 5px; right: 5px;
} }

153
qortal-ui-plugins/plugins/core/components/ChatScroller.js

@ -14,6 +14,7 @@ import '@material/mwc-button';
import '@material/mwc-dialog'; import '@material/mwc-dialog';
import '@material/mwc-icon'; import '@material/mwc-icon';
import { EmojiPicker } from 'emoji-picker-js'; import { EmojiPicker } from 'emoji-picker-js';
import {cropAddress} from "../../utils/cropAddress";
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
@ -75,9 +76,8 @@ class ChatScroller extends LitElement {
return html` return html`
<ul id="viewElement" class="chat-list clearfix"> <ul id="viewElement" class="chat-list clearfix">
<div id="upObserver"></div> <div id="upObserver"></div>
${formattedMessages.map((formattedMessage)=> { ${formattedMessages.map((formattedMessage) => {
return repeat(
return repeat(
formattedMessage.messages, formattedMessage.messages,
(message) => message.reference, (message) => message.reference,
(message, indexMessage) => html` (message, indexMessage) => html`
@ -90,13 +90,13 @@ return repeat(
.setEditedMessageObj=${this.setEditedMessageObj} .setEditedMessageObj=${this.setEditedMessageObj}
.focusChatEditor=${this.focusChatEditor} .focusChatEditor=${this.focusChatEditor}
.sendMessage=${this.sendMessage} .sendMessage=${this.sendMessage}
?isfirstmessage=${indexMessage === 0} ?isFirstMessage=${indexMessage === 0}
?isSingleMessageInGroup=${formattedMessage.messages.length > 1} ?isSingleMessageInGroup=${formattedMessage.messages.length > 1}
?isLastMessageInGroup=${indexMessage === formattedMessage.messages.length - 1}
> >
</message-template>` </message-template>`
) )
})} })}
<div id='downObserver'></div> <div id='downObserver'></div>
<div class='last-message-ref'> <div class='last-message-ref'>
<vaadin-icon class='arrow-down-icon' icon='vaadin:arrow-circle-down' slot='icon' @click=${() => { <vaadin-icon class='arrow-down-icon' icon='vaadin:arrow-circle-down' slot='icon' @click=${() => {
@ -195,10 +195,11 @@ class MessageTemplate extends LitElement {
setEditedMessageObj: { type: Function }, setEditedMessageObj: { type: Function },
focusChatEditor: { type: Function }, focusChatEditor: { type: Function },
sendMessage: { type: Function }, sendMessage: { type: Function },
openDialogImage: {type: Function}, openDialogImage: { type: Function },
isImageLoaded: {type: Boolean}, isImageLoaded: { type: Boolean },
isFirstMessage: {type: Boolean}, isFirstMessage: { type: Boolean },
isSingleMessageInGroup: {type: Boolean} isSingleMessageInGroup: { type: Boolean },
isLastMessageInGroup: { type: Boolean },
} }
} }
@ -214,6 +215,7 @@ class MessageTemplate extends LitElement {
this.isImageLoaded = false this.isImageLoaded = false
this.isFirstMessage = false this.isFirstMessage = false
this.isSingleMessageInGroup = false this.isSingleMessageInGroup = false
this.isLastMessageInGroup = false
} }
static styles = [chatStyles] static styles = [chatStyles]
@ -245,21 +247,22 @@ class MessageTemplate extends LitElement {
} }
} }
render() { render() {
const hidemsg = this.hideMessages const parsedMessageObj = JSON.parse(this.messageObj.decodedMessage);
let message = "" console.log({isFirstMessage: this.isFirstMessage, isSingleMessageInGroup: this.isSingleMessageInGroup, isLastMessageInGroup: this.isLastMessageInGroup, messageText: parsedMessageObj.messageText})
let reactions = [] const hidemsg = this.hideMessages;
let repliedToData = null let message = "";
let image = null let reactions = [];
let isImageDeleted = false let repliedToData = null;
let image = null;
let isImageDeleted = false;
try { try {
const parsedMessageObj = JSON.parse(this.messageObj.decodedMessage); const parsedMessageObj = JSON.parse(this.messageObj.decodedMessage);
message = parsedMessageObj.messageText; message = parsedMessageObj.messageText;
repliedToData = this.messageObj.repliedToData; repliedToData = this.messageObj.repliedToData;
isImageDeleted = parsedMessageObj.isImageDeleted; isImageDeleted = parsedMessageObj.isImageDeleted;
reactions = parsedMessageObj.reactions || []; reactions = parsedMessageObj.reactions || [];
if(parsedMessageObj.images && Array.isArray(parsedMessageObj.images) && parsedMessageObj.images.length > 0){ if (parsedMessageObj.images && Array.isArray(parsedMessageObj.images) && parsedMessageObj.images.length > 0) {
image = parsedMessageObj.images[0]; image = parsedMessageObj.images[0];
} }
} catch (error) { } catch (error) {
@ -284,19 +287,19 @@ class MessageTemplate extends LitElement {
avatarImg = html`<img src='/img/incognito.png' style="max-width:100%; max-height:100%;" onerror="this.onerror=null;" />` avatarImg = html`<img src='/img/incognito.png' style="max-width:100%; max-height:100%;" onerror="this.onerror=null;" />`
} }
const createImage=(imageUrl)=>{ const createImage = (imageUrl) => {
const imageHTMLRes = new Image(); const imageHTMLRes = new Image();
imageHTMLRes.src = imageUrl; imageHTMLRes.src = imageUrl;
imageHTMLRes.style= "max-width:45vh; max-height:40vh; border-radius: 5px; cursor: pointer"; imageHTMLRes.style= "max-width:45vh; max-height:40vh; border-radius: 5px; cursor: pointer";
imageHTMLRes.onclick= () => { imageHTMLRes.onclick= () => {
this.openDialogImage = true this.openDialogImage = true;
} }
imageHTMLRes.onload = ()=> { imageHTMLRes.onload = () => {
this.isImageLoaded = true this.isImageLoaded = true;
} }
imageHTMLRes.onerror = ()=> { imageHTMLRes.onerror = () => {
if (this.imageFetches < 4) { if (this.imageFetches < 4) {
setTimeout(()=> { setTimeout(() => {
this.imageFetches = this.imageFetches + 1; this.imageFetches = this.imageFetches + 1;
imageHTMLRes.src = imageUrl; imageHTMLRes.src = imageUrl;
}, 500); }, 500);
@ -321,11 +324,12 @@ class MessageTemplate extends LitElement {
imageHTMLDialog.style= "height: auto; max-height: 80vh; width: auto; max-width: 80vw; object-fit: contain; border-radius: 5px"; imageHTMLDialog.style= "height: auto; max-height: 80vh; width: auto; max-width: 80vw; object-fit: contain; border-radius: 5px";
} }
if (this.messageObj.sender === this.myAddress) { nameMenu = html`
nameMenu = html`<span style="color: #03a9f4;">${this.messageObj.senderName ? this.messageObj.senderName : this.messageObj.sender}</span>`; <span class="${this.messageObj.sender === this.myAddress && 'message-data-my-name'}">
} else { ${this.messageObj.senderName ? this.messageObj.senderName : cropAddress(this.messageObj.sender)}
nameMenu = html`<span>${this.messageObj.senderName ? this.messageObj.senderName : this.messageObj.sender}</span>`; </span>
} `;
if (repliedToData) { if (repliedToData) {
try { try {
const parsedMsg = JSON.parse(repliedToData.decodedMessage); const parsedMsg = JSON.parse(repliedToData.decodedMessage);
@ -338,21 +342,69 @@ class MessageTemplate extends LitElement {
const replacedMessage = escapedMessage.replace(new RegExp('\r?\n','g'), '<br />'); const replacedMessage = escapedMessage.replace(new RegExp('\r?\n','g'), '<br />');
return hideit ? html`<li class="clearfix"></li>` : html` return hideit ? html`<li class="clearfix"></li>` : html`
<li class="clearfix message-parent"> <li
class="clearfix message-parent"
style="${(this.isSingleMessageInGroup === true && this.isLastMessageInGroup === false && reactions.length === 0) ?
'padding-bottom: 0;'
: null}
${this.isFirstMessage && 'margin-top: 20px;'}">
${this.isFirstMessage ? (
html`
<div class="message-data ${this.messageObj.sender === this.myAddress ? "" : ""}"> <div class="message-data ${this.messageObj.sender === this.myAddress ? "" : ""}">
<span class="message-data-name">${nameMenu}</span>
<span class="message-data-level">${levelFounder}</span> <span class="message-data-level">${levelFounder}</span>
<span class="message-data-time"><message-time timestamp=${this.messageObj.timestamp}></message-time></span> <span class="message-data-time"><message-time timestamp=${this.messageObj.timestamp}></message-time></span>
</div> </div>
`
) : null}
<div>
<div
class="message-container"
style="${(this.isSingleMessageInGroup === true && this.isLastMessageInGroup === false) && 'margin-bottom: 0'}">
<div class="message-subcontainer1">
${(this.isSingleMessageInGroup === false ||
(this.isSingleMessageInGroup === true && this.isLastMessageInGroup === true))
? (
html`
<div class="message-data-avatar"> <div class="message-data-avatar">
${avatarImg} ${avatarImg}
</div> </div>
<div class="message-container"> `
<div class="message-subcontainer"> ) :
html`
<div class="message-data-avatar"></div>
`}
<div
class="${`message-subcontainer2
${((this.isFirstMessage === true && this.isSingleMessageInGroup === false) ||
(this.isSingleMessageInGroup === true && this.isLastMessageInGroup === true)) &&
'message-triangle'}`}"
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
? 'border-radius: 25px 25px 25px 0px;'
: null
}">
${this.isFirstMessage ?
html`
<span class="message-data-name">
${nameMenu}
</span>
`
: null
}
${repliedToData && html` ${repliedToData && html`
<div class="original-message"> <div class="original-message">
<p class="original-message-sender">${repliedToData.sendName ?? repliedToData.sender}</p> <p class="original-message-sender">
<p class="replied-message">${repliedToData.decodedMessage.messageText}</p> ${repliedToData.sendName ?? cropAddress(repliedToData.sender)}
</p>
<p class="replied-message">
${repliedToData.decodedMessage.messageText}
</p>
</div> </div>
`} `}
${image && !isImageDeleted ? html` ${image && !isImageDeleted ? html`
@ -371,24 +423,10 @@ class MessageTemplate extends LitElement {
${unsafeHTML(this.emojiPicker.parse(replacedMessage))} ${unsafeHTML(this.emojiPicker.parse(replacedMessage))}
</div> </div>
</div> </div>
<div class="message-reactions">
${reactions.map((reaction)=> {
return html`
<span
@click=${() => this.sendMessage({
type: 'reaction',
editedMessageObj: this.messageObj,
reaction: reaction.type,
})}
class="reactions-bg">
${reaction.type} ${reaction.qty}
</span>`
})}
</div>
<chat-menu <chat-menu
tabindex="0" tabindex="0"
class="chat-hover" class="chat-hover"
style=${this.showBlockAddressIcon && "display: block"} style="${this.showBlockAddressIcon ? 'display: block;' : null} ${this.isFirstMessage && 'top: -50px'}"
toblockaddress="${this.messageObj.sender}" toblockaddress="${this.messageObj.sender}"
.showPrivateMessageModal=${() => this.showPrivateMessageModal()} .showPrivateMessageModal=${() => this.showPrivateMessageModal()}
.showBlockUserModal=${() => this.showBlockUserModal()} .showBlockUserModal=${() => this.showBlockUserModal()}
@ -404,6 +442,23 @@ class MessageTemplate extends LitElement {
> >
</chat-menu> </chat-menu>
</div> </div>
<div class="message-reactions" style="${reactions.length > 0 &&
'margin-top: 10px; margin-bottom: 5px;'}">
${reactions.map((reaction)=> {
return html`
<span
@click=${() => this.sendMessage({
type: 'reaction',
editedMessageObj: this.messageObj,
reaction: reaction.type,
})}
class="reactions-bg">
${reaction.type} ${reaction.qty}
</span>`
})}
</div>
</div>
</div>
</div> </div>
</li> </li>
<chat-modals <chat-modals

8
qortal-ui-plugins/plugins/utils/cropAddress.js

@ -0,0 +1,8 @@
export function cropAddress(string = "", range = 5) {
const [start, end] = [
string?.substring(0, range),
string?.substring(string?.length - range, string?.length),
//
];
return start + "..." + end;
}
Loading…
Cancel
Save