4
1
mirror of https://github.com/Qortal/qortal-ui.git synced 2025-02-12 18:25:50 +00:00

Started private message with chat-text-editor

This commit is contained in:
Justin Ferrari 2022-12-12 21:50:55 -05:00
parent faeaa330cf
commit c34cf0fda8
3 changed files with 176 additions and 175 deletions

View File

@ -1554,35 +1554,31 @@ class ChatPage extends LitElement {
users: [this.selectedAddress.address] users: [this.selectedAddress.address]
}] }]
} }
const messageObject = { const messageObject = {
...message, ...message,
reactions reactions
} }
const stringifyMessageObject = JSON.stringify(messageObject) const stringifyMessageObject = JSON.stringify(messageObject)
this.sendMessage(stringifyMessageObject, typeMessage, chatReference); this.sendMessage(stringifyMessageObject, typeMessage, chatReference);
} else if (/^\s*$/.test(trimmedMessage)) { } else if (/^\s*$/.test(trimmedMessage)) {
this.isLoading = false; this.isLoading = false;
this.chatEditor.enable(); this.chatEditor.enable();
this.chatEditorNewChat.enable() this.chatEditorNewChat.enable();
} }
else if (this.repliedToMessageObj) { else if (this.repliedToMessageObj) {
let chatReference = this.repliedToMessageObj.reference let chatReference = this.repliedToMessageObj.reference;
if(this.repliedToMessageObj.chatReference){ if(this.repliedToMessageObj.chatReference){
chatReference = this.repliedToMessageObj.chatReference chatReference = this.repliedToMessageObj.chatReference;
} }
typeMessage = 'reply' typeMessage = 'reply';
const messageObject = { const messageObject = {
messageText: trimmedMessage, messageText: trimmedMessage,
images: [''], images: [''],
repliedTo: chatReference, repliedTo: chatReference,
version: 1 version: 1
} }
const stringifyMessageObject = JSON.stringify(messageObject) const stringifyMessageObject = JSON.stringify(messageObject);
this.sendMessage(stringifyMessageObject, typeMessage ); this.sendMessage(stringifyMessageObject, typeMessage);
} else if (this.editedMessageObj) { } else if (this.editedMessageObj) {
typeMessage = 'edit' typeMessage = 'edit'
let chatReference = this.editedMessageObj.reference let chatReference = this.editedMessageObj.reference

View File

@ -223,7 +223,13 @@ class ChatTextEditor extends LitElement {
` `
) : ) :
html` html`
<div style="${ scrollHeightBool ? 'margin-bottom: 5px;' : "margin-bottom: 0;"} ${this.iframeId === 'newChat' ? 'display: none;' : 'display: flex;'}"> <div
style="${scrollHeightBool
? 'margin-bottom: 5px;'
: "margin-bottom: 0;"}
${this.iframeId === 'newChat'
? 'display: none;'
: 'display: flex;'}">
${this.isLoading === false ? html` ${this.isLoading === false ? html`
<img <img
src="/img/qchat-send-message-icon.svg" src="/img/qchat-send-message-icon.svg"
@ -354,13 +360,13 @@ class ChatTextEditor extends LitElement {
return true return true
} }
sendMessageFunc(props) { sendMessageFunc() {
if (this.chatMessageSize > 1000 ) { if (this.chatMessageSize > 1000 ) {
parentEpml.request('showSnackBar', get("chatpage.cchange29")); parentEpml.request('showSnackBar', get("chatpage.cchange29"));
return; return;
}; };
this.chatMessageSize = 0; this.chatMessageSize = 0;
this._sendMessage(props); this._sendMessage();
} }
getMessageSize(message){ getMessageSize(message){

View File

@ -2,6 +2,7 @@ import { LitElement, html, css } from 'lit'
import { render } from 'lit/html.js' import { render } from 'lit/html.js'
import { Epml } from '../../../../epml.js' import { Epml } from '../../../../epml.js'
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate' import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
import WebWorker from 'web-worker:../../components/computePowWorker.js';
registerTranslateConfig({ registerTranslateConfig({
loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
@ -324,6 +325,7 @@ class Chat extends LitElement {
this.isLoading = false this.isLoading = false
this.showNewMesssageBar = this.showNewMesssageBar.bind(this) this.showNewMesssageBar = this.showNewMesssageBar.bind(this)
this.hideNewMesssageBar = this.hideNewMesssageBar.bind(this) this.hideNewMesssageBar = this.hideNewMesssageBar.bind(this)
this._sendMessage = this._sendMessage.bind(this)
this.insertImage = this.insertImage.bind(this) this.insertImage = this.insertImage.bind(this)
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
this.blockedUsers = [] this.blockedUsers = []
@ -381,10 +383,10 @@ class Chat extends LitElement {
iframeId="privateMessage" iframeId="privateMessage"
?hasGlobalEvents=${true} ?hasGlobalEvents=${true}
placeholder="${translate("chatpage.cchange8")}" placeholder="${translate("chatpage.cchange8")}"
_sendMessage=${this._sendMessage}
.setChatEditor=${(editor)=> this.setChatEditor(editor)} .setChatEditor=${(editor)=> this.setChatEditor(editor)}
.chatEditor=${this.chatEditor} .chatEditor=${this.chatEditor}
.imageFile=${this.imageFile} .imageFile=${this.imageFile}.
._sendMessage=${this._sendMessage}
.insertImage=${this.insertImage} .insertImage=${this.insertImage}
?isLoading=${this.isLoading}> ?isLoading=${this.isLoading}>
</chat-text-editor> </chat-text-editor>
@ -392,7 +394,7 @@ class Chat extends LitElement {
<mwc-button <mwc-button
?disabled="${this.isLoading}" ?disabled="${this.isLoading}"
slot="primaryAction" slot="primaryAction"
@click=${this._sendMessage} @click=${this.sendMessageFunc}
> >
${this.isLoading === false ? this.renderSendText() : html`<paper-spinner-lite active></paper-spinner-lite>`} ${this.isLoading === false ? this.renderSendText() : html`<paper-spinner-lite active></paper-spinner-lite>`}
</mwc-button> </mwc-button>
@ -544,7 +546,6 @@ class Chat extends LitElement {
this.config = JSON.parse(c) this.config = JSON.parse(c)
}) })
parentEpml.subscribe('chat_heads', chatHeads => { parentEpml.subscribe('chat_heads', chatHeads => {
console.log("here51");
chatHeads = JSON.parse(chatHeads) chatHeads = JSON.parse(chatHeads)
this.getChatHeadFromState(chatHeads) this.getChatHeadFromState(chatHeads)
}) })
@ -568,6 +569,162 @@ class Chat extends LitElement {
this.chatEditor = editor; this.chatEditor = editor;
} }
async _sendMessage() {
console.log("here1");
this.isLoading = true;
this.chatEditor.disable();
const messageText = this.chatEditor.mirror.value;
// Format and Sanitize Message
const sanitizedMessage = messageText.replace(/&nbsp;/gi, ' ').replace(/<br\s*[\/]?>/gi, '\n');
const trimmedMessage = sanitizedMessage.trim();
if (/^\s*$/.test(trimmedMessage)) {
this.isLoading = false;
this.chatEditor.enable();
} else {
const messageObject = {
messageText: trimmedMessage,
images: [''],
repliedTo: '',
version: 1
}
const stringifyMessageObject = JSON.stringify(messageObject)
this.sendMessage(stringifyMessageObject);
}
console.log("here2");
}
async sendMessage(messageText) {
console.log("here3");
this.isLoading = true;
const _recipient = this.shadowRoot.getElementById('sendTo').value;
let recipient;
const validateName = async (receiverName) => {
let myRes;
try {
let myNameRes = await parentEpml.request('apiCall', {
type: 'api',
url: `/names/${receiverName}`
});
if (myNameRes.error === 401) {
myRes = false;
} else {
myRes = myNameRes;
}
return myRes;
} catch (error) {
return "";
}
};
const myNameRes = await validateName(_recipient);
if (!myNameRes) {
recipient = _recipient;
} else {
recipient = myNameRes.owner;
};
const getAddressPublicKey = async () => {
let isEncrypted;
let _publicKey;
let addressPublicKey = await parentEpml.request('apiCall', {
type: 'api',
url: `/addresses/publickey/${recipient}`
})
if (addressPublicKey.error === 102) {
_publicKey = false;
let err4string = get("chatpage.cchange19");
parentEpml.request('showSnackBar', `${err4string}`);
this.isLoading = false;
} else if (addressPublicKey !== false) {
isEncrypted = 1;
_publicKey = addressPublicKey;
sendMessageRequest(isEncrypted, _publicKey);
} else {
isEncrypted = 0;
_publicKey = this.selectedAddress.address;
sendMessageRequest(isEncrypted, _publicKey);
}
};
let _reference = new Uint8Array(64);
window.crypto.getRandomValues(_reference);
let reference = window.parent.Base58.encode(_reference);
const sendMessageRequest = async (isEncrypted, _publicKey) => {
let chatResponse = await parentEpml.request('chat', {
type: 18,
nonce: this.selectedAddress.nonce,
params: {
timestamp: Date.now(),
recipient: recipient,
recipientPublicKey: _publicKey,
hasChatReference: 0,
message: messageText,
lastReference: reference,
proofOfWorkNonce: 0,
isEncrypted: isEncrypted,
isText: 1
}
});
console.log({chatResponse});
_computePow(chatResponse);
};
const _computePow = async (chatBytes) => {
const difficulty = this.balance === 0 ? 12 : 8;
const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full';
console.log("here4");
const worker = new WebWorker();
console.log("here5");
let nonce = null;
let chatBytesArray = null;
await new Promise((res, rej) => {
console.log(chatBytes, "chatBytes");
console.log(path, "path");
console.log(difficulty, "difficulty");
worker.postMessage({chatBytes, path, difficulty});
worker.onmessage = e => {
worker.terminate();
chatBytesArray = e.data.chatBytesArray;
nonce = e.data.nonce;
res();
}
});
let _response = await parentEpml.request('sign_chat', {
nonce: this.selectedAddress.nonce,
chatBytesArray: chatBytesArray,
chatNonce: nonce
});
getSendChatResponse(_response);
};
const getSendChatResponse = (response) => {
if (response === true) {
this.chatEditor.resetValue();
} else if (response.error) {
parentEpml.request('showSnackBar', response.message);
} else {
let err2string = get("chatpage.cchange21");
parentEpml.request('showSnackBar', `${err2string}`);
}
this.isLoading = false;
this.chatEditor.enable();
};
// Exec..
getAddressPublicKey();
}
insertImage(file) { insertImage(file) {
if (file.type.includes('image')) { if (file.type.includes('image')) {
this.imageFile = file; this.imageFile = file;
@ -747,7 +904,6 @@ class Chat extends LitElement {
const compareArgs = (a, b) => { const compareArgs = (a, b) => {
return b.timestamp - a.timestamp return b.timestamp - a.timestamp
} }
console.log({chatHeadMasterList});
this.chatHeads = chatHeadMasterList.sort(compareArgs) this.chatHeads = chatHeadMasterList.sort(compareArgs)
} }
@ -762,163 +918,6 @@ class Chat extends LitElement {
} }
} }
_sendMessage() {
this.isLoading = true
const recipient = this.shadowRoot.getElementById('sendTo').value
const messageBox = this.shadowRoot.getElementById('messageBox')
const messageText = messageBox.value
if (recipient.length === 0) {
this.isLoading = false
} else if (messageText.length === 0) {
this.isLoading = false
} else {
this.sendMessage()
}
}
async sendMessage(e) {
this.isLoading = true
const _recipient = this.shadowRoot.getElementById('sendTo').value
const messageBox = this.shadowRoot.getElementById('messageBox')
const messageText = messageBox.value
let recipient
const validateName = async (receiverName) => {
let myRes
let myNameRes = await parentEpml.request('apiCall', {
type: 'api',
url: `/names/${receiverName}`
})
if (myNameRes.error === 401) {
myRes = false
} else {
myRes = myNameRes
}
return myRes
}
const myNameRes = await validateName(_recipient)
if (!myNameRes) {
recipient = _recipient
} else {
recipient = myNameRes.owner
}
let _reference = new Uint8Array(64);
window.crypto.getRandomValues(_reference);
let sendTimestamp = Date.now()
let reference = window.parent.Base58.encode(_reference)
const getAddressPublicKey = async () => {
let isEncrypted
let _publicKey
let addressPublicKey = await parentEpml.request('apiCall', {
type: 'api',
url: `/addresses/publickey/${recipient}`
})
if (addressPublicKey.error === 102) {
_publicKey = false
let err4string = get("chatpage.cchange19")
parentEpml.request('showSnackBar', `${err4string}`)
this.isLoading = false
} else if (addressPublicKey !== false) {
isEncrypted = 1
_publicKey = addressPublicKey
sendMessageRequest(isEncrypted, _publicKey)
} else {
isEncrypted = 0
_publicKey = this.selectedAddress.address
sendMessageRequest(isEncrypted, _publicKey)
}
};
const sendMessageRequest = async (isEncrypted, _publicKey) => {
const messageObject = {
messageText,
images: [''],
repliedTo: '',
version: 1
}
const stringifyMessageObject = JSON.stringify(messageObject)
let chatResponse = await parentEpml.request('chat', {
type: 18,
nonce: this.selectedAddress.nonce,
params: {
timestamp: sendTimestamp,
recipient: recipient,
recipientPublicKey: _publicKey,
hasChatReference: 0,
message: stringifyMessageObject,
lastReference: reference,
proofOfWorkNonce: 0,
isEncrypted: isEncrypted,
isText: 1
}
})
_computePow(chatResponse)
}
const _computePow = async (chatBytes) => {
const _chatBytesArray = Object.keys(chatBytes).map(function (key) { return chatBytes[key]; });
const chatBytesArray = new Uint8Array(_chatBytesArray)
const chatBytesHash = new window.parent.Sha256().process(chatBytesArray).finish().result
const hashPtr = window.parent.sbrk(32, window.parent.heap);
const hashAry = new Uint8Array(window.parent.memory.buffer, hashPtr, 32)
hashAry.set(chatBytesHash);
const difficulty = this.balance === 0 ? 12 : 8
const workBufferLength = 8 * 1024 * 1024;
const workBufferPtr = window.parent.sbrk(workBufferLength, window.parent.heap)
let nonce = window.parent.computePow(hashPtr, workBufferPtr, workBufferLength, difficulty)
let _response = await parentEpml.request('sign_chat', {
nonce: this.selectedAddress.nonce,
chatBytesArray: chatBytesArray,
chatNonce: nonce
})
getSendChatResponse(_response)
}
const getSendChatResponse = (response) => {
if (response === true) {
messageBox.value = ""
let err5string = get("chatpage.cchange20")
parentEpml.request('showSnackBar', `${err5string}`)
this.isLoading = false
} else if (response.error) {
parentEpml.request('showSnackBar', response.message)
this.isLoading = false
} else {
let err6string = get("chatpage.cchange21")
parentEpml.request('showSnackBar', `${err6string}`)
this.isLoading = false
}
}
// Exec..
getAddressPublicKey()
}
_textMenu(event) { _textMenu(event) {
const getSelectedText = () => { const getSelectedText = () => {