mirror of
https://github.com/Qortal/qortal-ui.git
synced 2025-04-24 20:07:51 +00:00
Merge branch 'feature/implement-logic-edit-reply-messages' of https://github.com/PhillipLangMartinez/qortal-ui into feature/implement-UI-edit-reply-messages
This commit is contained in:
commit
ddf8a740f9
@ -518,7 +518,11 @@
|
||||
"bcchange10": "More",
|
||||
"bcchange11": "Reply",
|
||||
"bcchange12": "Edit",
|
||||
"bcchange13": "Reaction"
|
||||
"bcchange13": "Reaction",
|
||||
"bcchange14": "Forward",
|
||||
"bcchange15": "Message Forwarded",
|
||||
"bcchange16": "Choose recipient",
|
||||
"bcchange17": "FORWARDED"
|
||||
},
|
||||
"grouppage": {
|
||||
"gchange1": "Qortal Groups",
|
||||
|
@ -14,6 +14,7 @@ class ChatHead extends LitElement {
|
||||
iconName: { type: String },
|
||||
activeChatHeadUrl: { type: String },
|
||||
isImageLoaded: { type: Boolean },
|
||||
setActiveChatHeadUrl: {attribute: false}
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,8 +117,6 @@ class ChatHead extends LitElement {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return html`
|
||||
<li @click=${() => this.getUrl(this.chatInfo.url)} class="clearfix ${this.activeChatHeadUrl === this.chatInfo.url ? 'active' : ''}">
|
||||
${this.isImageLoaded ? html`${avatarImg}` : html`` }
|
||||
@ -150,8 +149,19 @@ class ChatHead extends LitElement {
|
||||
parentEpml.imReady()
|
||||
}
|
||||
|
||||
shouldUpdate(changedProperties) {
|
||||
if(changedProperties.has('activeChatHeadUrl')){
|
||||
return true
|
||||
}
|
||||
if(changedProperties.has('chatInfo')){
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
getUrl(chatUrl) {
|
||||
this.onPageNavigation(`/app/q-chat/${chatUrl}`)
|
||||
this.setActiveChatHeadUrl(chatUrl)
|
||||
}
|
||||
|
||||
onPageNavigation(pageUrl) {
|
||||
|
@ -16,6 +16,7 @@ import './NameMenu.js';
|
||||
import './TimeAgo.js';
|
||||
import './ChatTextEditor';
|
||||
import './WrapperModal';
|
||||
import './ChatSelect.js'
|
||||
import '@polymer/paper-spinner/paper-spinner-lite.js';
|
||||
import '@material/mwc-button';
|
||||
import '@material/mwc-dialog';
|
||||
@ -67,7 +68,11 @@ class ChatPage extends LitElement {
|
||||
userLanguage: { type: String },
|
||||
lastMessageRefVisible: { type: Boolean },
|
||||
isLoadingOldMessages: {type: Boolean},
|
||||
isEditMessageOpen: { type: Boolean }
|
||||
isEditMessageOpen: { type: Boolean },
|
||||
webSocket: {attribute: false},
|
||||
chatHeads: {type: Array},
|
||||
forwardActiveChatHeadUrl: {type: String},
|
||||
openForwardOpen: {type: Boolean}
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,6 +82,15 @@ class ChatPage extends LitElement {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
.chat-head-container {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
flex-direction: column;
|
||||
height: 50vh;
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.chat-container {
|
||||
display: grid;
|
||||
grid-template-rows: minmax(6%, 92vh) minmax(40px, auto);
|
||||
@ -428,6 +442,11 @@ class ChatPage extends LitElement {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.dialog-container-title {
|
||||
color: var(--black);
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.dialog-container-loader {
|
||||
position: relative;
|
||||
display: flex;
|
||||
@ -549,8 +568,11 @@ class ChatPage extends LitElement {
|
||||
position: 'top-start',
|
||||
boxShadow: 'rgba(4, 4, 5, 0.15) 0px 0px 0px 1px, rgba(0, 0, 0, 0.24) 0px 8px 16px 0px'
|
||||
});
|
||||
this.openForwardOpen = false
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="chat-container">
|
||||
@ -701,11 +723,105 @@ class ChatPage extends LitElement {
|
||||
</div>
|
||||
</div>
|
||||
</wrapper-modal>
|
||||
<wrapper-modal
|
||||
.removeImage=${() => {
|
||||
this.openForwardOpen = false
|
||||
this.forwardActiveChatHeadUrl = ""
|
||||
} }
|
||||
style=${this.openForwardOpen ? "display: block" : "display: none"}>
|
||||
<div>
|
||||
<div class="dialog-container">
|
||||
<div>
|
||||
<p class="dialog-container-title">${translate("blockpage.bcchange16")}</p>
|
||||
</div>
|
||||
<div class="chat-head-container">
|
||||
${this.chatHeads.map((item)=> {
|
||||
return html`<chat-select activeChatHeadUrl=${this.forwardActiveChatHeadUrl} .setActiveChatHeadUrl=${(val)=> {
|
||||
this.forwardActiveChatHeadUrl = val
|
||||
}} chatInfo=${JSON.stringify(item)}></chat-select>`
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div class="modal-button-row">
|
||||
<button class="modal-button-red" @click=${() => {
|
||||
this.openForwardOpen = false
|
||||
this.forwardActiveChatHeadUrl = ""
|
||||
}}>
|
||||
${translate("chatpage.cchange33")}
|
||||
</button>
|
||||
<button
|
||||
?disabled=${!this.forwardActiveChatHeadUrl}
|
||||
class="modal-button"
|
||||
@click=${()=> {
|
||||
this.sendForwardMessage()
|
||||
}}
|
||||
>
|
||||
${translate("blockpage.bcchange14")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</wrapper-modal>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
setForwardProperties(forwardedMessage){
|
||||
this.openForwardOpen = true
|
||||
this.forwardedMessage = forwardedMessage
|
||||
}
|
||||
|
||||
async sendForwardMessage(){
|
||||
let parsedMessageObj = {}
|
||||
let publicKey = {
|
||||
hasPubKey: false,
|
||||
key: ''
|
||||
}
|
||||
try {
|
||||
parsedMessageObj = JSON.parse(this.forwardedMessage);
|
||||
|
||||
} catch (error) {
|
||||
parsedMessageObj = {}
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await parentEpml.request('apiCall', {
|
||||
type: 'api',
|
||||
url: `/addresses/publickey/${this.forwardChatId}`
|
||||
})
|
||||
if (res.error === 102) {
|
||||
publicKey.key = ''
|
||||
publicKey.hasPubKey = false
|
||||
} else if (res !== false) {
|
||||
publicKey.key = res
|
||||
publicKey.hasPubKey = true
|
||||
} else {
|
||||
publicKey.key = ''
|
||||
publicKey.hasPubKey = false
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
const message = {
|
||||
...parsedMessageObj,
|
||||
type: 'forward'
|
||||
}
|
||||
delete message.reactions
|
||||
const stringifyMessageObject = JSON.stringify(message)
|
||||
this.sendMessage(stringifyMessageObject, undefined, '', true, {
|
||||
isReceipient: true,
|
||||
chatId: 'Qdxha59Cm1Ty4QkKMBWPnKrNigcDCDk6eq',
|
||||
publicKey: {
|
||||
hasPubKey: false,
|
||||
key: ''
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.log({error})
|
||||
}
|
||||
}
|
||||
|
||||
showLastMessageRefScroller(props) {
|
||||
this.lastMessageRefVisible = props;
|
||||
@ -733,13 +849,18 @@ class ChatPage extends LitElement {
|
||||
this.chatEditor.enable();
|
||||
}
|
||||
|
||||
async firstUpdated() {
|
||||
window.addEventListener('storage', () => {
|
||||
const checkLanguage = localStorage.getItem('qortalLanguage');
|
||||
use(checkLanguage);
|
||||
this.userLanguage = checkLanguage;
|
||||
})
|
||||
changeMsgInput(id) {
|
||||
|
||||
this.chatEditor.remove()
|
||||
this.chatMessageInput = this.shadowRoot.getElementById(id);
|
||||
this.initChatEditor();
|
||||
}
|
||||
|
||||
async initUpdate(){
|
||||
if(this.webSocket){
|
||||
this.webSocket.close()
|
||||
this.webSocket= ''
|
||||
}
|
||||
const getAddressPublicKey = () => {
|
||||
|
||||
parentEpml.request('apiCall', {
|
||||
@ -781,6 +902,16 @@ class ChatPage extends LitElement {
|
||||
// this.initChatEditor();
|
||||
}, 100)
|
||||
|
||||
|
||||
}
|
||||
|
||||
async firstUpdated() {
|
||||
window.addEventListener('storage', () => {
|
||||
const checkLanguage = localStorage.getItem('qortalLanguage');
|
||||
use(checkLanguage);
|
||||
this.userLanguage = checkLanguage;
|
||||
})
|
||||
|
||||
parentEpml.ready().then(() => {
|
||||
parentEpml.subscribe('selected_address', async selectedAddress => {
|
||||
this.selectedAddress = {}
|
||||
@ -804,10 +935,11 @@ class ChatPage extends LitElement {
|
||||
})
|
||||
})
|
||||
parentEpml.imReady();
|
||||
|
||||
await this.initUpdate()
|
||||
}
|
||||
|
||||
async updated(changedProperties) {
|
||||
|
||||
if (changedProperties && changedProperties.has('userLanguage')) {
|
||||
const userLang = changedProperties.get('userLanguage')
|
||||
|
||||
@ -817,6 +949,10 @@ class ChatPage extends LitElement {
|
||||
}
|
||||
|
||||
}
|
||||
if (changedProperties && changedProperties.has('chatId') && changedProperties.get('chatId')) {
|
||||
await this.initUpdate()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async renderPlaceholder() {
|
||||
@ -849,6 +985,7 @@ class ChatPage extends LitElement {
|
||||
renderChatScroller() {
|
||||
return html`
|
||||
<chat-scroller
|
||||
chatId=${this.chatId}
|
||||
.messages=${this.messagesRendered}
|
||||
.escapeHTML=${escape}
|
||||
.getOldMessage=${this.getOldMessage}
|
||||
@ -856,10 +993,12 @@ class ChatPage extends LitElement {
|
||||
.setEditedMessageObj=${(val) => this.setEditedMessageObj(val)}
|
||||
.focusChatEditor=${() => this.focusChatEditor()}
|
||||
.sendMessage=${(val) => this._sendMessage(val)}
|
||||
.sendMessageForward=${(messageText, typeMessage, chatReference, isForward, forwardParams)=> this.sendMessage(messageText, typeMessage, chatReference, isForward, forwardParams)}
|
||||
.showLastMessageRefScroller=${(val) => this.showLastMessageRefScroller(val)}
|
||||
.emojiPicker=${this.emojiPicker}
|
||||
?isLoadingMessages=${this.isLoadingOldMessages}
|
||||
.setIsLoadingMessages=${(val) => this.setIsLoadingMessages(val)}
|
||||
.setForwardProperties=${(forwardedMessage)=> this.setForwardProperties(forwardedMessage)}
|
||||
>
|
||||
</chat-scroller>
|
||||
`
|
||||
@ -1119,7 +1258,6 @@ class ChatPage extends LitElement {
|
||||
async fetchChatMessages(chatId) {
|
||||
|
||||
const initDirect = async (cid) => {
|
||||
|
||||
let initial = 0
|
||||
|
||||
let directSocketTimeout
|
||||
@ -1138,22 +1276,22 @@ class ChatPage extends LitElement {
|
||||
directSocketLink = `ws://${nodeUrl}/websockets/chat/messages?involving=${window.parent.reduxStore.getState().app.selectedAddress.address}&involving=${cid}`;
|
||||
}
|
||||
|
||||
const directSocket = new WebSocket(directSocketLink);
|
||||
this.webSocket = new WebSocket(directSocketLink);
|
||||
|
||||
// Open Connection
|
||||
directSocket.onopen = () => {
|
||||
this.webSocket.onopen = () => {
|
||||
|
||||
setTimeout(pingDirectSocket, 50)
|
||||
}
|
||||
|
||||
// Message Event
|
||||
directSocket.onmessage = async (e) => {
|
||||
this.webSocket.onmessage = async (e) => {
|
||||
if (initial === 0) {
|
||||
const isReceipient = this.chatId.includes('direct')
|
||||
|
||||
|
||||
const chatReference1 = isReceipient ? 'direct' : 'group';
|
||||
const chatReference2 = this.chatId.split('/')[1];
|
||||
// commented out code= localstorage persistance
|
||||
// const chatReference1 = isReceipient ? 'direct' : 'group';
|
||||
// const chatReference2 = this.chatId.split('/')[1];
|
||||
// const cachedData = await messagesCache.getItem(`${chatReference1}-${chatReference2}`);
|
||||
const cachedData = null
|
||||
let getInitialMessages = []
|
||||
@ -1186,17 +1324,17 @@ class ChatPage extends LitElement {
|
||||
}
|
||||
|
||||
// Closed Event
|
||||
directSocket.onclose = () => {
|
||||
this.webSocket.onclose = () => {
|
||||
clearTimeout(directSocketTimeout)
|
||||
}
|
||||
|
||||
// Error Event
|
||||
directSocket.onerror = (e) => {
|
||||
this.webSocket.onerror = (e) => {
|
||||
clearTimeout(directSocketTimeout)
|
||||
}
|
||||
|
||||
const pingDirectSocket = () => {
|
||||
directSocket.send('ping')
|
||||
this.webSocket.send('ping')
|
||||
|
||||
directSocketTimeout = setTimeout(pingDirectSocket, 295000)
|
||||
}
|
||||
@ -1224,16 +1362,16 @@ class ChatPage extends LitElement {
|
||||
groupSocketLink = `ws://${nodeUrl}/websockets/chat/messages?txGroupId=${groupId}`;
|
||||
}
|
||||
|
||||
const groupSocket = new WebSocket(groupSocketLink);
|
||||
this.webSocket = new WebSocket(groupSocketLink);
|
||||
|
||||
// Open Connection
|
||||
groupSocket.onopen = () => {
|
||||
this.webSocket.onopen = () => {
|
||||
|
||||
setTimeout(pingGroupSocket, 50)
|
||||
}
|
||||
|
||||
// Message Event
|
||||
groupSocket.onmessage = async (e) => {
|
||||
this.webSocket.onmessage = async (e) => {
|
||||
|
||||
if (initial === 0) {
|
||||
const isGroup = this.chatId.includes('group')
|
||||
@ -1275,17 +1413,17 @@ class ChatPage extends LitElement {
|
||||
}
|
||||
|
||||
// Closed Event
|
||||
groupSocket.onclose = () => {
|
||||
this.webSocket.onclose = () => {
|
||||
clearTimeout(groupSocketTimeout)
|
||||
}
|
||||
|
||||
// Error Event
|
||||
groupSocket.onerror = (e) => {
|
||||
this.webSocket.onerror = (e) => {
|
||||
clearTimeout(groupSocketTimeout)
|
||||
}
|
||||
|
||||
const pingGroupSocket = () => {
|
||||
groupSocket.send('ping')
|
||||
this.webSocket.send('ping')
|
||||
|
||||
groupSocketTimeout = setTimeout(pingGroupSocket, 295000)
|
||||
}
|
||||
@ -1533,7 +1671,7 @@ class ChatPage extends LitElement {
|
||||
const findEmojiIndex = reactions.findIndex((reaction)=> reaction.type === outSideMsg.reaction)
|
||||
if(findEmojiIndex !== -1){
|
||||
let users = reactions[findEmojiIndex].users || []
|
||||
const findUserIndex = users.find((user)=> user === this.selectedAddress.address )
|
||||
const findUserIndex = users.findIndex((user)=> user === this.selectedAddress.address )
|
||||
if(findUserIndex !== -1){
|
||||
users.splice(findUserIndex, 1)
|
||||
} else {
|
||||
@ -1614,8 +1752,7 @@ class ChatPage extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
async sendMessage(messageText, typeMessage, chatReference) {
|
||||
|
||||
async sendMessage(messageText, typeMessage, chatReference, isForward, forwardParams) {
|
||||
this.isLoading = true;
|
||||
|
||||
let _reference = new Uint8Array(64);
|
||||
@ -1663,7 +1800,55 @@ class ChatPage extends LitElement {
|
||||
}
|
||||
};
|
||||
|
||||
const _computePow = async (chatBytes) => {
|
||||
const sendForwardRequest = async () => {
|
||||
const { publicKey } = forwardParams
|
||||
|
||||
const isRecipient = this.forwardActiveChatHeadUrl.includes('direct') === true ? true : false;
|
||||
|
||||
const chatId = this.forwardActiveChatHeadUrl.split('/')[1];
|
||||
this.openForwardOpen = false
|
||||
if (isRecipient === true) {
|
||||
let chatResponse = await parentEpml.request('chat', {
|
||||
type: 18,
|
||||
nonce: this.selectedAddress.nonce,
|
||||
params: {
|
||||
timestamp: Date.now(),
|
||||
recipient: chatId,
|
||||
recipientPublicKey: publicKey.key,
|
||||
hasChatReference: 0,
|
||||
chatReference: "",
|
||||
message: messageText,
|
||||
lastReference: reference,
|
||||
proofOfWorkNonce: 0,
|
||||
isEncrypted: publicKey.hasPubKey === false ? 0 : 1,
|
||||
isText: 1
|
||||
}
|
||||
});
|
||||
|
||||
_computePow(chatResponse, true)
|
||||
} else {
|
||||
let groupResponse = await parentEpml.request('chat', {
|
||||
type: 181,
|
||||
nonce: this.selectedAddress.nonce,
|
||||
params: {
|
||||
timestamp: Date.now(),
|
||||
groupID: Number(chatId),
|
||||
hasReceipient: 0,
|
||||
hasChatReference: 0,
|
||||
chatReference: chatReference,
|
||||
message: messageText,
|
||||
lastReference: reference,
|
||||
proofOfWorkNonce: 0,
|
||||
isEncrypted: 0, // Set default to not encrypted for groups
|
||||
isText: 1
|
||||
}
|
||||
});
|
||||
|
||||
_computePow(groupResponse, true)
|
||||
}
|
||||
};
|
||||
|
||||
const _computePow = async (chatBytes, isForward) => {
|
||||
const difficulty = this.balance === 0 ? 12 : 8;
|
||||
const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full'
|
||||
const worker = new WebWorker();
|
||||
@ -1688,13 +1873,17 @@ class ChatPage extends LitElement {
|
||||
});
|
||||
|
||||
|
||||
getSendChatResponse(_response);
|
||||
getSendChatResponse(_response, isForward);
|
||||
};
|
||||
|
||||
const getSendChatResponse = (response) => {
|
||||
const getSendChatResponse = (response, isForward) => {
|
||||
if (response === true) {
|
||||
this.chatEditor.resetValue();
|
||||
this.chatEditorNewChat.resetValue()
|
||||
if(isForward){
|
||||
let successString = get("blockpage.bcchange15");
|
||||
parentEpml.request('showSnackBar', `${successString}`);
|
||||
}
|
||||
} else if (response.error) {
|
||||
parentEpml.request('showSnackBar', response.message);
|
||||
} else {
|
||||
@ -1707,9 +1896,14 @@ class ChatPage extends LitElement {
|
||||
this.chatEditorNewChat.enable()
|
||||
this.closeEditMessageContainer()
|
||||
this.closeRepliedToContainer()
|
||||
this.openForwardOpen = false
|
||||
this.forwardActiveChatHeadUrl = ""
|
||||
};
|
||||
|
||||
// Exec..
|
||||
if(isForward){
|
||||
sendForwardRequest();
|
||||
return
|
||||
}
|
||||
sendMessageRequest();
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,12 @@ export const chatStyles = css`
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.message-data-forward {
|
||||
user-select: none;
|
||||
color: var(--mainmenutext);
|
||||
margin-bottom: 5px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.message-data-my-name {
|
||||
color: #cf21e8;
|
||||
text-shadow: 0 0 3px #cf21e8;
|
||||
|
@ -30,10 +30,13 @@ class ChatScroller extends LitElement {
|
||||
setEditedMessageObj: {attribute: false},
|
||||
focusChatEditor: {attribute: false},
|
||||
sendMessage: {attribute: false},
|
||||
sendMessageForward: {attribute: false},
|
||||
showLastMessageRefScroller: { type: Function },
|
||||
emojiPicker: { attribute: false },
|
||||
isLoadingMessages: { type: Boolean},
|
||||
setIsLoadingMessages: {attribute: false}
|
||||
setIsLoadingMessages: {attribute: false},
|
||||
chatId: { type: String },
|
||||
setForwardProperties: {attribute: false},
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,6 +53,7 @@ class ChatScroller extends LitElement {
|
||||
|
||||
|
||||
render() {
|
||||
console.log({messages: this.messages})
|
||||
let formattedMessages = this.messages.reduce((messageArray, message) => {
|
||||
const lastGroupedMessage = messageArray[messageArray.length - 1];
|
||||
let timestamp;
|
||||
@ -95,10 +99,12 @@ class ChatScroller extends LitElement {
|
||||
.setEditedMessageObj=${this.setEditedMessageObj}
|
||||
.focusChatEditor=${this.focusChatEditor}
|
||||
.sendMessage=${this.sendMessage}
|
||||
.sendMessageForward=${this.sendMessageForward}
|
||||
?isFirstMessage=${indexMessage === 0}
|
||||
?isSingleMessageInGroup=${formattedMessage.messages.length > 1}
|
||||
?isLastMessageInGroup=${indexMessage === formattedMessage.messages.length - 1}
|
||||
.setToggledMessage=${this.setToggledMessage}
|
||||
.setForwardProperties=${this.setForwardProperties}
|
||||
>
|
||||
</message-template>`
|
||||
)
|
||||
@ -112,6 +118,9 @@ class ChatScroller extends LitElement {
|
||||
if(changedProperties.has('isLoadingMessages')){
|
||||
return true
|
||||
}
|
||||
if(changedProperties.has('chatId') && changedProperties.get('chatId')){
|
||||
return true
|
||||
}
|
||||
// Only update element if prop1 changed.
|
||||
return changedProperties.has('messages');
|
||||
}
|
||||
@ -215,12 +224,14 @@ class MessageTemplate extends LitElement {
|
||||
setEditedMessageObj: {attribute: false},
|
||||
focusChatEditor: {attribute: false},
|
||||
sendMessage: {attribute: false},
|
||||
sendMessageForward: {attribute: false},
|
||||
openDialogImage: {attribute: false},
|
||||
isImageLoaded: { type: Boolean },
|
||||
isFirstMessage: { type: Boolean },
|
||||
isSingleMessageInGroup: { type: Boolean },
|
||||
isLastMessageInGroup: { type: Boolean },
|
||||
setToggledMessage: {attribute: false}
|
||||
setToggledMessage: {attribute: false},
|
||||
setForwardProperties: {attribute: false},
|
||||
}
|
||||
}
|
||||
|
||||
@ -275,6 +286,7 @@ class MessageTemplate extends LitElement {
|
||||
let image = null;
|
||||
let isImageDeleted = false;
|
||||
let version = 0;
|
||||
let isForwarded = false
|
||||
try {
|
||||
const parsedMessageObj = JSON.parse(this.messageObj.decodedMessage);
|
||||
message = parsedMessageObj.messageText;
|
||||
@ -282,6 +294,7 @@ class MessageTemplate extends LitElement {
|
||||
isImageDeleted = parsedMessageObj.isImageDeleted;
|
||||
reactions = parsedMessageObj.reactions || [];
|
||||
version = parsedMessageObj.version
|
||||
isForwarded = parsedMessageObj.type === 'forward'
|
||||
if (parsedMessageObj.images && Array.isArray(parsedMessageObj.images) && parsedMessageObj.images.length > 0) {
|
||||
image = parsedMessageObj.images[0];
|
||||
}
|
||||
@ -295,6 +308,7 @@ class MessageTemplate extends LitElement {
|
||||
let nameMenu = '';
|
||||
let levelFounder = '';
|
||||
let hideit = hidemsg.includes(this.messageObj.sender);
|
||||
let forwarded = ''
|
||||
|
||||
levelFounder = html`<level-founder checkleveladdress="${this.messageObj.sender}"></level-founder>`;
|
||||
if (this.messageObj.senderName) {
|
||||
@ -348,6 +362,11 @@ class MessageTemplate extends LitElement {
|
||||
${this.messageObj.senderName ? this.messageObj.senderName : cropAddress(this.messageObj.sender)}
|
||||
</span>
|
||||
`;
|
||||
forwarded = html`
|
||||
<span class="${this.messageObj.sender === this.myAddress && 'message-data-forward'}">
|
||||
${translate("blockpage.bcchange17")}
|
||||
</span>
|
||||
`;
|
||||
|
||||
if (repliedToData) {
|
||||
try {
|
||||
@ -410,6 +429,14 @@ class MessageTemplate extends LitElement {
|
||||
`
|
||||
: null
|
||||
}
|
||||
${isForwarded ?
|
||||
html`
|
||||
<span class="message-data-name">
|
||||
${forwarded}
|
||||
</span>
|
||||
`
|
||||
: null
|
||||
}
|
||||
${this.isFirstMessage ? (
|
||||
html`
|
||||
<span class="message-data-level">${levelFounder}</span>
|
||||
@ -476,9 +503,11 @@ class MessageTemplate extends LitElement {
|
||||
.myAddress=${this.myAddress}
|
||||
@blur=${() => this.showBlockIconFunc(false)}
|
||||
.sendMessage=${this.sendMessage}
|
||||
.sendMessageForward=${this.sendMessageForward}
|
||||
version=${version}
|
||||
.emojiPicker=${this.emojiPicker}
|
||||
.setToggledMessage=${this.setToggledMessage}
|
||||
.setForwardProperties=${this.setForwardProperties}
|
||||
>
|
||||
</chat-menu>
|
||||
</div>
|
||||
@ -555,7 +584,9 @@ class ChatMenu extends LitElement {
|
||||
emojiPicker: { attribute: false },
|
||||
sendMessage: {attribute: false},
|
||||
version: {type: String},
|
||||
setToggledMessage: {attribute: false}
|
||||
setToggledMessage: {attribute: false},
|
||||
sendMessageForward: {attribute: false},
|
||||
setForwardProperties: {attribute: false}
|
||||
}
|
||||
}
|
||||
|
||||
@ -585,6 +616,51 @@ class ChatMenu extends LitElement {
|
||||
parentEpml.request('showSnackBar', `${errorMsg}`)
|
||||
}
|
||||
|
||||
async messageForwardFunc(){
|
||||
let parsedMessageObj = {}
|
||||
let publicKey = {
|
||||
hasPubKey: false,
|
||||
key: ''
|
||||
}
|
||||
try {
|
||||
parsedMessageObj = JSON.parse(this.originalMessage.decodedMessage);
|
||||
|
||||
} catch (error) {
|
||||
parsedMessageObj = {}
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await parentEpml.request('apiCall', {
|
||||
type: 'api',
|
||||
url: `/addresses/publickey/${this._chatId}`
|
||||
})
|
||||
if (res.error === 102) {
|
||||
publicKey.key = ''
|
||||
publicKey.hasPubKey = false
|
||||
} else if (res !== false) {
|
||||
publicKey.key = res
|
||||
publicKey.hasPubKey = true
|
||||
} else {
|
||||
publicKey.key = ''
|
||||
publicKey.hasPubKey = false
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
const message = {
|
||||
...parsedMessageObj,
|
||||
type: 'forward'
|
||||
}
|
||||
const stringifyMessageObject = JSON.stringify(message)
|
||||
this.setForwardProperties(stringifyMessageObject)
|
||||
|
||||
} catch (error) {
|
||||
console.log({error})
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="container">
|
||||
@ -607,6 +683,14 @@ class ChatMenu extends LitElement {
|
||||
>
|
||||
<vaadin-icon icon="vaadin:smiley-o" slot="icon"></vaadin-icon>
|
||||
</div>
|
||||
<div
|
||||
class="menu-icon tooltip"
|
||||
data-text="${translate("blockpage.bcchange14")}"
|
||||
@click="${() => {
|
||||
this.messageForwardFunc()
|
||||
}}">
|
||||
<vaadin-icon icon="vaadin:arrow-forward" slot="icon"></vaadin-icon>
|
||||
</div>
|
||||
<div class="menu-icon tooltip" data-text="${translate("blockpage.bcchange9")}" @click="${() => this.showPrivateMessageModal()}">
|
||||
<vaadin-icon icon="vaadin:paperplane" slot="icon"></vaadin-icon>
|
||||
</div>
|
||||
|
176
qortal-ui-plugins/plugins/core/components/ChatSelect.js
Normal file
176
qortal-ui-plugins/plugins/core/components/ChatSelect.js
Normal file
@ -0,0 +1,176 @@
|
||||
import { LitElement, html, css } from 'lit'
|
||||
import { Epml } from '../../../epml.js'
|
||||
|
||||
import '@material/mwc-icon'
|
||||
|
||||
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
|
||||
|
||||
class ChatSelect extends LitElement {
|
||||
static get properties() {
|
||||
return {
|
||||
selectedAddress: { type: Object },
|
||||
config: { type: Object },
|
||||
chatInfo: { type: Object },
|
||||
iconName: { type: String },
|
||||
activeChatHeadUrl: { type: String },
|
||||
isImageLoaded: { type: Boolean },
|
||||
setActiveChatHeadUrl: {attribute: false}
|
||||
}
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
ul {
|
||||
list-style-type: none;
|
||||
}
|
||||
li {
|
||||
padding: 10px 2px 20px 5px;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
li:hover {
|
||||
background-color: var(--menuhover);
|
||||
}
|
||||
|
||||
.active {
|
||||
background: var(--menuactive);
|
||||
border-left: 4px solid #3498db;
|
||||
}
|
||||
|
||||
.img-icon {
|
||||
font-size:40px;
|
||||
color: var(--chat-group);
|
||||
}
|
||||
|
||||
.about {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.about {
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.status {
|
||||
color: #92959e;
|
||||
}
|
||||
|
||||
.clearfix:after {
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
font-size: 0;
|
||||
content: " ";
|
||||
clear: both;
|
||||
height: 0;
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.selectedAddress = {}
|
||||
this.config = {
|
||||
user: {
|
||||
node: {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
this.chatInfo = {}
|
||||
this.iconName = ''
|
||||
this.activeChatHeadUrl = ''
|
||||
this.isImageLoaded = false
|
||||
this.imageFetches = 0
|
||||
}
|
||||
|
||||
createImage(imageUrl) {
|
||||
const imageHTMLRes = new Image();
|
||||
imageHTMLRes.src = imageUrl;
|
||||
imageHTMLRes.style= "width:40px; height:40px; float: left; border-radius:50%";
|
||||
imageHTMLRes.onclick= () => {
|
||||
this.openDialogImage = true;
|
||||
}
|
||||
imageHTMLRes.onload = () => {
|
||||
this.isImageLoaded = true;
|
||||
}
|
||||
imageHTMLRes.onerror = () => {
|
||||
if (this.imageFetches < 4) {
|
||||
setTimeout(() => {
|
||||
this.imageFetches = this.imageFetches + 1;
|
||||
imageHTMLRes.src = imageUrl;
|
||||
}, 500);
|
||||
} else {
|
||||
|
||||
|
||||
this.isImageLoaded = false
|
||||
}
|
||||
};
|
||||
return imageHTMLRes;
|
||||
}
|
||||
|
||||
render() {
|
||||
let avatarImg = '';
|
||||
let backupAvatarImg = ''
|
||||
if(this.chatInfo.name){
|
||||
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node];
|
||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
|
||||
const avatarUrl = `${nodeUrl}/arbitrary/THUMBNAIL/${this.chatInfo.name}/qortal_avatar?async=true&apiKey=${myNode.apiKey}`;
|
||||
avatarImg= this.createImage(avatarUrl)
|
||||
|
||||
}
|
||||
|
||||
return html`
|
||||
<li @click=${() => this.getUrl(this.chatInfo.url)} class="clearfix ${this.activeChatHeadUrl === this.chatInfo.url ? 'active' : ''}">
|
||||
${this.isImageLoaded ? html`${avatarImg}` : html`` }
|
||||
${!this.isImageLoaded && !this.chatInfo.name && !this.chatInfo.groupName ? html`<mwc-icon class="img-icon">account_circle</mwc-icon>` : html`` }
|
||||
${!this.isImageLoaded && this.chatInfo.name ? html`<div style="width:40px; height:40px; float: left; border-radius:50%; background: ${this.activeChatHeadUrl === this.chatInfo.url ? 'var(--chatHeadBgActive)' : 'var(--chatHeadBg)' }; color: ${this.activeChatHeadUrl === this.chatInfo.url ? 'var(--chatHeadTextActive)' : 'var(--chatHeadText)' }; font-weight:bold; display: flex; justify-content: center; align-items: center; text-transform: capitalize">${this.chatInfo.name.charAt(0)}</div>`: ''}
|
||||
${!this.isImageLoaded && this.chatInfo.groupName ? html`<div style="width:40px; height:40px; float: left; border-radius:50%; background: ${this.activeChatHeadUrl === this.chatInfo.url ? 'var(--chatHeadBgActive)' : 'var(--chatHeadBg)' }; color: ${this.activeChatHeadUrl === this.chatInfo.url ? 'var(--chatHeadTextActive)' : 'var(--chatHeadText)' }; font-weight:bold; display: flex; justify-content: center; align-items: center; text-transform: capitalize">${this.chatInfo.groupName.charAt(0)}</div>`: ''}
|
||||
<div class="about">
|
||||
<div class="name"><span style="float:left; padding-left: 8px; color: var(--chat-group);">${this.chatInfo.groupName ? this.chatInfo.groupName : this.chatInfo.name !== undefined ? this.chatInfo.name : this.chatInfo.address.substr(0, 15)} </span> </div>
|
||||
</div>
|
||||
</li>
|
||||
`
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
let configLoaded = false
|
||||
parentEpml.ready().then(() => {
|
||||
parentEpml.subscribe('selected_address', async selectedAddress => {
|
||||
this.selectedAddress = {}
|
||||
selectedAddress = JSON.parse(selectedAddress)
|
||||
if (!selectedAddress || Object.entries(selectedAddress).length === 0) return
|
||||
this.selectedAddress = selectedAddress
|
||||
})
|
||||
parentEpml.subscribe('config', c => {
|
||||
if (!configLoaded) {
|
||||
configLoaded = true
|
||||
}
|
||||
this.config = JSON.parse(c)
|
||||
})
|
||||
})
|
||||
parentEpml.imReady()
|
||||
}
|
||||
|
||||
shouldUpdate(changedProperties) {
|
||||
if(changedProperties.has('activeChatHeadUrl')){
|
||||
return true
|
||||
}
|
||||
if(changedProperties.has('chatInfo')){
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
getUrl(chatUrl) {
|
||||
this.setActiveChatHeadUrl(chatUrl)
|
||||
}
|
||||
|
||||
onPageNavigation(pageUrl) {
|
||||
parentEpml.request('setPageUrl', pageUrl)
|
||||
}
|
||||
}
|
||||
|
||||
window.customElements.define('chat-select', ChatSelect)
|
@ -15,7 +15,6 @@ function sbrk(size, heap){
|
||||
|
||||
|
||||
self.addEventListener('message', async e => {
|
||||
console.log({data: e.data})
|
||||
const response = await computePow(e.data.chatBytes, e.data.path, e.data.difficulty)
|
||||
postMessage(response)
|
||||
|
||||
|
@ -17,7 +17,6 @@ function sbrk(size, heap){
|
||||
|
||||
|
||||
self.addEventListener('message', async e => {
|
||||
console.log({data: e.data})
|
||||
const response = await computePow(e.data.convertedBytes, e.data.path)
|
||||
postMessage(response)
|
||||
|
||||
@ -75,7 +74,7 @@ const workBufferPtr = sbrk(
|
||||
});
|
||||
}
|
||||
|
||||
console.log({path})
|
||||
|
||||
loadWebAssembly(path)
|
||||
.then(wasmModule => {
|
||||
response = {
|
||||
|
@ -38,7 +38,8 @@ class Chat extends LitElement {
|
||||
blockedUserList: { type: Array },
|
||||
privateMessagePlaceholder: { type: String},
|
||||
chatEditor: { type: Object },
|
||||
imageFile: { type: Object }
|
||||
imageFile: { type: Object },
|
||||
activeChatHeadUrl: {type: String}
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,6 +333,13 @@ class Chat extends LitElement {
|
||||
this.blockedUserList = []
|
||||
this.privateMessagePlaceholder = ""
|
||||
this.imageFile = null
|
||||
this.activeChatHeadUrl = ''
|
||||
}
|
||||
|
||||
async setActiveChatHeadUrl(url) {
|
||||
this.activeChatHeadUrl = ''
|
||||
await this.updateComplete;
|
||||
this.activeChatHeadUrl = url
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -357,7 +365,8 @@ class Chat extends LitElement {
|
||||
<span>${translate("chatpage.cchange5")} <mwc-icon style="font-size: 16px; vertical-align: bottom;">keyboard_arrow_down</mwc-icon></span>
|
||||
</div>
|
||||
<div class="chat-history">
|
||||
${window.parent.location.pathname !== "/app/q-chat" ? html`${this.renderChatPage(this.chatId)}` : html`${this.renderChatWelcomePage()}`}
|
||||
|
||||
${window.parent.location.pathname !== "/app/q-chat" || this.activeChatHeadUrl ? html`${this.renderChatPage(this.chatId)}` : html`${this.renderChatWelcomePage()}`}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -445,15 +454,10 @@ class Chat extends LitElement {
|
||||
this.getChatBlockedList()
|
||||
this.getLocalBlockedList()
|
||||
|
||||
setInterval(() => {
|
||||
this.blockedUserList = JSON.parse(localStorage.getItem("ChatBlockedAddresses") || "[]")
|
||||
}, 1000)
|
||||
|
||||
const getBlockedUsers = async () => {
|
||||
let blockedUsers = await parentEpml.request('apiCall', {
|
||||
url: `/lists/blockedAddresses?apiKey=${this.getApiKey()}`
|
||||
})
|
||||
|
||||
this.blockedUsers = blockedUsers
|
||||
setTimeout(getBlockedUsers, 60000)
|
||||
}
|
||||
@ -478,7 +482,7 @@ class Chat extends LitElement {
|
||||
|
||||
const runFunctionsAfterPageLoad = () => {
|
||||
// Functions to exec after render while waiting for page info...
|
||||
getDataFromURL()
|
||||
// getDataFromURL()
|
||||
|
||||
try {
|
||||
let key = `${window.parent.reduxStore.getState().app.selectedAddress.address.substr(0, 10)}_chat-heads`
|
||||
@ -764,6 +768,8 @@ class Chat extends LitElement {
|
||||
hidelist.push(item)
|
||||
})
|
||||
localStorage.setItem("MessageBlockedAddresses", JSON.stringify(hidelist))
|
||||
|
||||
this.blockedUserList = hidelist
|
||||
})
|
||||
}
|
||||
|
||||
@ -796,6 +802,7 @@ class Chat extends LitElement {
|
||||
obj.push(noName)
|
||||
}
|
||||
localStorage.setItem("ChatBlockedAddresses", JSON.stringify(obj))
|
||||
this.blockedUserList = JSON.parse(localStorage.getItem("ChatBlockedAddresses") || "[]")
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -873,20 +880,20 @@ class Chat extends LitElement {
|
||||
|
||||
let tempUrl = document.location.href
|
||||
let splitedUrl = decodeURI(tempUrl).split('?')
|
||||
let activeChatHeadUrl = splitedUrl[1] === undefined ? '' : splitedUrl[1]
|
||||
// let activeChatHeadUrl = splitedUrl[1] === undefined ? '' : splitedUrl[1]
|
||||
|
||||
return chatHeadArr.map(eachChatHead => {
|
||||
return html`<chat-head activeChatHeadUrl=${activeChatHeadUrl} 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(chatId) {
|
||||
|
||||
// Check for the chat ID from and render chat messages
|
||||
// Else render Welcome to Q-CHat
|
||||
|
||||
// TODO: DONE: Do the above in the ChatPage
|
||||
|
||||
return html`<chat-page .hideNewMesssageBar=${this.hideNewMesssageBar} .showNewMesssageBar=${this.showNewMesssageBar} myAddress=${window.parent.reduxStore.getState().app.selectedAddress.address} chatId=${chatId}></chat-page>`
|
||||
return html`<chat-page .chatHeads=${this.chatHeads} .hideNewMesssageBar=${this.hideNewMesssageBar} .showNewMesssageBar=${this.showNewMesssageBar} myAddress=${window.parent.reduxStore.getState().app.selectedAddress.address} chatId=${this.activeChatHeadUrl}></chat-page>`
|
||||
}
|
||||
|
||||
setChatHeads(chatObj) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user