From 595d16af86ab74a93f5bbd11e490d2368cc2467f Mon Sep 17 00:00:00 2001
From: Phillip
Date: Sat, 29 Apr 2023 05:47:30 +0300
Subject: [PATCH] switch receiving chat message to base64 and added qortal://
protocol to be recognized as links in the chat
---
qortal-ui-crypto/api.js | 5 +-
qortal-ui-crypto/api/deps/Base64.js | 24 +++
.../transactions/chat/decryptChatMessage.js | 31 ++++
.../plugins/core/components/ChatPage.js | 56 +++---
.../plugins/core/components/ChatScroller.js | 174 ++++++++++++++++--
.../plugins/core/qdn/browser/browser.src.js | 9 +-
.../plugins/utils/replace-messages-edited.js | 8 +-
7 files changed, 253 insertions(+), 54 deletions(-)
create mode 100644 qortal-ui-crypto/api/deps/Base64.js
diff --git a/qortal-ui-crypto/api.js b/qortal-ui-crypto/api.js
index cc81dc9e..543d875d 100644
--- a/qortal-ui-crypto/api.js
+++ b/qortal-ui-crypto/api.js
@@ -1,16 +1,19 @@
import { Sha256 } from 'asmcrypto.js'
import Base58 from './api/deps/Base58'
+import Base64 from './api/deps/Base64'
import { base58PublicKeyToAddress } from './api/wallet/base58PublicKeyToAddress'
import { validateAddress } from './api/wallet/validateAddress'
-import { decryptChatMessage } from './api/transactions/chat/decryptChatMessage'
+import { decryptChatMessage, decryptChatMessageBase64 } from './api/transactions/chat/decryptChatMessage'
import _ from 'lodash'
window.Sha256 = Sha256
window.Base58 = Base58
+window.Base64 = Base64
window._ = _
window.base58PublicKeyToAddress = base58PublicKeyToAddress
window.validateAddress = validateAddress
window.decryptChatMessage = decryptChatMessage
+window.decryptChatMessageBase64 = decryptChatMessageBase64
export { initApi, store } from './api_deps.js'
export * from './api/deps/deps.js'
diff --git a/qortal-ui-crypto/api/deps/Base64.js b/qortal-ui-crypto/api/deps/Base64.js
new file mode 100644
index 00000000..82bc5847
--- /dev/null
+++ b/qortal-ui-crypto/api/deps/Base64.js
@@ -0,0 +1,24 @@
+
+const Base64 = {};
+
+
+
+Base64.decode = function (string) {
+
+ const binaryString = atob(string);
+ const binaryLength = binaryString.length;
+ const bytes = new Uint8Array(binaryLength);
+
+ for (let i = 0; i < binaryLength; i++) {
+ bytes[i] = binaryString.charCodeAt(i);
+ }
+
+ const decoder = new TextDecoder();
+ const decodedString = decoder.decode(bytes);
+ return decodedString;
+};
+
+
+
+
+export default Base64;
\ No newline at end of file
diff --git a/qortal-ui-crypto/api/transactions/chat/decryptChatMessage.js b/qortal-ui-crypto/api/transactions/chat/decryptChatMessage.js
index 038db155..e6f8bcd1 100644
--- a/qortal-ui-crypto/api/transactions/chat/decryptChatMessage.js
+++ b/qortal-ui-crypto/api/transactions/chat/decryptChatMessage.js
@@ -24,3 +24,34 @@ export const decryptChatMessage = (encryptedMessage, privateKey, recipientPublic
_decryptedMessage === false ? decryptedMessage : decryptedMessage = new TextDecoder('utf-8').decode(_decryptedMessage)
return decryptedMessage
}
+
+export const decryptChatMessageBase64 = (encryptedMessage, privateKey, recipientPublicKey, lastReference) => {
+ let _encryptedMessage = atob(encryptedMessage);
+ const binaryLength = _encryptedMessage.length;
+ const bytes = new Uint8Array(binaryLength);
+
+ for (let i = 0; i < binaryLength; i++) {
+ bytes[i] = _encryptedMessage.charCodeAt(i);
+ }
+
+ const _base58RecipientPublicKey = recipientPublicKey instanceof Uint8Array ? Base58.encode(recipientPublicKey) : recipientPublicKey
+ const _recipientPublicKey = Base58.decode(_base58RecipientPublicKey)
+
+ const _lastReference = lastReference instanceof Uint8Array ? lastReference : Base58.decode(lastReference)
+
+ const convertedPrivateKey = ed2curve.convertSecretKey(privateKey)
+ const convertedPublicKey = ed2curve.convertPublicKey(_recipientPublicKey)
+ const sharedSecret = new Uint8Array(32);
+ nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey)
+
+ const _chatEncryptionSeed = new Sha256().process(sharedSecret).finish().result
+ const _decryptedMessage = nacl.secretbox.open(bytes, _lastReference.slice(0, 24), _chatEncryptionSeed)
+
+
+ if (_decryptedMessage === false) {
+ return _decryptedMessage
+ }
+ return new TextDecoder('utf-8').decode(_decryptedMessage)
+
+
+}
\ No newline at end of file
diff --git a/qortal-ui-plugins/plugins/core/components/ChatPage.js b/qortal-ui-plugins/plugins/core/components/ChatPage.js
index 3e405f4f..b9da91f2 100644
--- a/qortal-ui-plugins/plugins/core/components/ChatPage.js
+++ b/qortal-ui-plugins/plugins/core/components/ChatPage.js
@@ -2514,7 +2514,7 @@ class ChatPage extends LitElement {
if (this.isReceipient) {
const getInitialMessages = await parentEpml.request('apiCall', {
type: 'api',
- url: `/chat/messages?involving=${window.parent.reduxStore.getState().app.selectedAddress.address}&involving=${this._chatId}&limit=${limit}&reverse=true&before=${before}&after=${after}&haschatreference=false`,
+ url: `/chat/messages?involving=${window.parent.reduxStore.getState().app.selectedAddress.address}&involving=${this._chatId}&limit=${limit}&reverse=true&before=${before}&after=${after}&haschatreference=false&encoding=BASE64`,
});
const decodeMsgs = getInitialMessages.map((eachMessage) => {
@@ -2548,7 +2548,7 @@ class ChatPage extends LitElement {
} else {
const getInitialMessages = await parentEpml.request('apiCall', {
type: 'api',
- url: `/chat/messages?txGroupId=${Number(this._chatId)}&limit=${limit}&reverse=true&before=${before}&after=${after}&haschatreference=false`,
+ url: `/chat/messages?txGroupId=${Number(this._chatId)}&limit=${limit}&reverse=true&before=${before}&after=${after}&haschatreference=false&encoding=BASE64`,
});
@@ -2589,7 +2589,7 @@ class ChatPage extends LitElement {
if (this.isReceipient) {
const getInitialMessages = await parentEpml.request('apiCall', {
type: 'api',
- url: `/chat/messages?involving=${window.parent.reduxStore.getState().app.selectedAddress.address}&involving=${this._chatId}&limit=20&reverse=true&before=${scrollElement.messageObj.timestamp}&haschatreference=false`,
+ url: `/chat/messages?involving=${window.parent.reduxStore.getState().app.selectedAddress.address}&involving=${this._chatId}&limit=20&reverse=true&before=${scrollElement.messageObj.timestamp}&haschatreference=false&encoding=BASE64`,
});
const decodeMsgs = getInitialMessages.map((eachMessage) => {
@@ -2622,7 +2622,7 @@ class ChatPage extends LitElement {
} else {
const getInitialMessages = await parentEpml.request('apiCall', {
type: 'api',
- url: `/chat/messages?txGroupId=${Number(this._chatId)}&limit=20&reverse=true&before=${scrollElement.messageObj.timestamp}&haschatreference=false`,
+ url: `/chat/messages?txGroupId=${Number(this._chatId)}&limit=20&reverse=true&before=${scrollElement.messageObj.timestamp}&haschatreference=false&encoding=BASE64`,
});
@@ -2660,7 +2660,7 @@ class ChatPage extends LitElement {
if (this.isReceipient) {
const getInitialMessages = await parentEpml.request('apiCall', {
type: 'api',
- url: `/chat/messages?involving=${window.parent.reduxStore.getState().app.selectedAddress.address}&involving=${this._chatId}&limit=20&reverse=true&afer=${scrollElement.messageObj.timestamp}&haschatreference=false`,
+ url: `/chat/messages?involving=${window.parent.reduxStore.getState().app.selectedAddress.address}&involving=${this._chatId}&limit=20&reverse=true&afer=${scrollElement.messageObj.timestamp}&haschatreference=false&encoding=BASE64`,
});
const decodeMsgs = getInitialMessages.map((eachMessage) => {
@@ -2693,7 +2693,7 @@ class ChatPage extends LitElement {
} else {
const getInitialMessages = await parentEpml.request('apiCall', {
type: 'api',
- url: `/chat/messages?txGroupId=${Number(this._chatId)}&limit=20&reverse=true&after=${scrollElement.messageObj.timestamp}&haschatreference=false`,
+ url: `/chat/messages?txGroupId=${Number(this._chatId)}&limit=20&reverse=true&after=${scrollElement.messageObj.timestamp}&haschatreference=false&encoding=BASE64`,
});
@@ -2739,8 +2739,7 @@ class ChatPage extends LitElement {
let _eachMessage = this.decodeMessage(eachMessage)
return _eachMessage
}
- })
-
+ })
if (isInitial) {
this.chatEditorPlaceholder = await this.renderPlaceholder();
const replacedMessages = await replaceMessagesEdited({
@@ -2759,6 +2758,7 @@ class ChatPage extends LitElement {
// TODO: Determine number of initial messages by screen height...
this.messagesRendered = this._messages;
this.isLoadingMessages = false;
+
setTimeout(() => this.downElementObserver(), 500);
} else {
const replacedMessages = await replaceMessagesEdited({
@@ -2885,11 +2885,10 @@ class ChatPage extends LitElement {
if (isReceipientVar === true) {
// direct chat
if (encodedMessageObj.isEncrypted === true && _publicKeyVar.hasPubKey === true && encodedMessageObj.data) {
- let decodedMessage = window.parent.decryptChatMessage(encodedMessageObj.data, window.parent.reduxStore.getState().app.selectedAddress.keyPair.privateKey, _publicKeyVar.key, encodedMessageObj.reference);
+ let decodedMessage = window.parent.decryptChatMessageBase64(encodedMessageObj.data, window.parent.reduxStore.getState().app.selectedAddress.keyPair.privateKey, _publicKeyVar.key, encodedMessageObj.reference);
decodedMessageObj = { ...encodedMessageObj, decodedMessage };
} else if (encodedMessageObj.isEncrypted === false && encodedMessageObj.data) {
- let bytesArray = window.parent.Base58.decode(encodedMessageObj.data);
- let decodedMessage = new TextDecoder('utf-8').decode(bytesArray);
+ let decodedMessage = window.parent.Base64.decode(encodedMessageObj.data);
decodedMessageObj = { ...encodedMessageObj, decodedMessage };
} else {
decodedMessageObj = { ...encodedMessageObj, decodedMessage: "Cannot Decrypt Message!" };
@@ -2897,8 +2896,7 @@ class ChatPage extends LitElement {
} else {
// group chat
- let bytesArray = window.parent.Base58.decode(encodedMessageObj.data);
- let decodedMessage = new TextDecoder('utf-8').decode(bytesArray);
+ let decodedMessage = window.parent.Base64.decode(encodedMessageObj.data);
decodedMessageObj = { ...encodedMessageObj, decodedMessage };
}
@@ -2919,11 +2917,11 @@ class ChatPage extends LitElement {
if (window.parent.location.protocol === "https:") {
- directSocketLink = `wss://${nodeUrl}/websockets/chat/messages?involving=${window.parent.reduxStore.getState().app.selectedAddress.address}&involving=${cid}`;
+ directSocketLink = `wss://${nodeUrl}/websockets/chat/messages?involving=${window.parent.reduxStore.getState().app.selectedAddress.address}&involving=${cid}&encoding=BASE64`;
} else {
// Fallback to http
- directSocketLink = `ws://${nodeUrl}/websockets/chat/messages?involving=${window.parent.reduxStore.getState().app.selectedAddress.address}&involving=${cid}`;
+ directSocketLink = `ws://${nodeUrl}/websockets/chat/messages?involving=${window.parent.reduxStore.getState().app.selectedAddress.address}&involving=${cid}&encoding=BASE64`;
}
this.webSocket = new WebSocket(directSocketLink);
@@ -2942,13 +2940,13 @@ class ChatPage extends LitElement {
const lastMessage = cachedData[cachedData.length - 1]
const newMessages = await parentEpml.request('apiCall', {
type: 'api',
- url: `/chat/messages?involving=${window.parent.reduxStore.getState().app.selectedAddress.address}&involving=${cid}&limit=20&reverse=true&after=${lastMessage.timestamp}&haschatreference=false`,
+ url: `/chat/messages?involving=${window.parent.reduxStore.getState().app.selectedAddress.address}&involving=${cid}&limit=20&reverse=true&after=${lastMessage.timestamp}&haschatreference=false&encoding=BASE64`,
});
getInitialMessages = [...cachedData, ...newMessages].slice(-20)
} else {
getInitialMessages = await parentEpml.request('apiCall', {
type: 'api',
- url: `/chat/messages?involving=${window.parent.reduxStore.getState().app.selectedAddress.address}&involving=${cid}&limit=20&reverse=true&haschatreference=false`,
+ url: `/chat/messages?involving=${window.parent.reduxStore.getState().app.selectedAddress.address}&involving=${cid}&limit=20&reverse=true&haschatreference=false&encoding=BASE64`,
});
@@ -2959,9 +2957,14 @@ class ChatPage extends LitElement {
initial = initial + 1
} else {
+ try {
if(e.data){
this.processMessages(JSON.parse(e.data), false)
}
+ } catch (error) {
+
+ }
+
}
}
@@ -3009,11 +3012,11 @@ class ChatPage extends LitElement {
if (window.parent.location.protocol === "https:") {
- groupSocketLink = `wss://${nodeUrl}/websockets/chat/messages?txGroupId=${groupId}`;
+ groupSocketLink = `wss://${nodeUrl}/websockets/chat/messages?txGroupId=${groupId}&encoding=BASE64`;
} else {
// Fallback to http
- groupSocketLink = `ws://${nodeUrl}/websockets/chat/messages?txGroupId=${groupId}`;
+ groupSocketLink = `ws://${nodeUrl}/websockets/chat/messages?txGroupId=${groupId}&encoding=BASE64`;
}
this.webSocket = new WebSocket(groupSocketLink);
@@ -3037,17 +3040,15 @@ class ChatPage extends LitElement {
const newMessages = await parentEpml.request('apiCall', {
type: 'api',
- url: `/chat/messages?txGroupId=${groupId}&limit=20&reverse=true&after=${lastMessage.timestamp}&haschatreference=false`,
+ url: `/chat/messages?txGroupId=${groupId}&limit=20&reverse=true&after=${lastMessage.timestamp}&haschatreference=false&encoding=BASE64`,
});
-
getInitialMessages = [...cachedData, ...newMessages].slice(-20)
} else {
getInitialMessages = await parentEpml.request('apiCall', {
type: 'api',
- url: `/chat/messages?txGroupId=${groupId}&limit=20&reverse=true&haschatreference=false`,
+ url: `/chat/messages?txGroupId=${groupId}&limit=20&reverse=true&haschatreference=false&encoding=BASE64`,
});
-
}
@@ -3055,9 +3056,14 @@ class ChatPage extends LitElement {
initial = initial + 1
} else {
- if(e.data){
- this.processMessages(JSON.parse(e.data), false)
+ try {
+ if (e.data) {
+ this.processMessages(JSON.parse(e.data), false)
+ }
+ } catch (error) {
+
}
+
}
}
diff --git a/qortal-ui-plugins/plugins/core/components/ChatScroller.js b/qortal-ui-plugins/plugins/core/components/ChatScroller.js
index 382a8114..598ea10c 100644
--- a/qortal-ui-plugins/plugins/core/components/ChatScroller.js
+++ b/qortal-ui-plugins/plugins/core/components/ChatScroller.js
@@ -28,6 +28,112 @@ import Highlight from '@tiptap/extension-highlight'
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
let toggledMessage = {}
+
+const getApiKey = () => {
+ const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node];
+ let apiKey = myNode.apiKey;
+ return apiKey;
+}
+
+const extractComponents = async (url) => {
+ if (!url.startsWith("qortal://")) {
+ return null;
+ }
+
+ url = url.replace(/^(qortal\:\/\/)/, "");
+ if (url.includes("/")) {
+ let parts = url.split("/");
+ const service = parts[0].toUpperCase();
+ parts.shift();
+ const name = parts[0];
+ parts.shift();
+ let identifier;
+
+ if (parts.length > 0) {
+ identifier = parts[0]; // Do not shift yet
+ // Check if a resource exists with this service, name and identifier combination
+ let responseObj = await parentEpml.request('apiCall', {
+ url: `/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${getApiKey()}`
+ })
+
+ if (responseObj.totalChunkCount > 0) {
+ // Identifier exists, so don't include it in the path
+ parts.shift();
+ }
+ else {
+ identifier = null;
+ }
+ }
+
+ const path = parts.join("/");
+
+ const components = {};
+ components["service"] = service;
+ components["name"] = name;
+ components["identifier"] = identifier;
+ components["path"] = path;
+ return components;
+ }
+
+ return null;
+}
+
+function processText(input) {
+ const linkRegex = /(qortal:\/\/\S+)/g;
+
+ function processNode(node) {
+ if (node.nodeType === Node.TEXT_NODE) {
+ const parts = node.textContent.split(linkRegex);
+
+ if (parts.length > 1) {
+ const fragment = document.createDocumentFragment();
+
+ parts.forEach((part) => {
+ if (part.startsWith('qortal://')) {
+ const link = document.createElement('span');
+ // Store the URL in a data attribute
+ link.setAttribute('data-url', part);
+ link.textContent = part;
+ link.style.color = 'var(--nav-text-color)';
+ link.style.textDecoration = 'underline';
+ link.style.cursor = 'pointer'
+
+ link.addEventListener('click', async (e) => {
+ e.preventDefault();
+ try {
+ const res = await extractComponents(part)
+ if (!res) return
+ const { service, name, identifier, path } = res
+ window.location = `../../qdn/browser/index.html?service=${service}&name=${name}&identifier=${identifier}&path=${path}`
+ } catch (error) {
+ console.log({ error })
+ }
+
+ });
+
+ fragment.appendChild(link);
+ } else {
+ const textNode = document.createTextNode(part);
+ fragment.appendChild(textNode);
+ }
+ });
+
+ node.replaceWith(fragment);
+ }
+ } else {
+ for (const childNode of Array.from(node.childNodes)) {
+ processNode(childNode);
+ }
+ }
+ }
+
+ const wrapper = document.createElement('div');
+ wrapper.innerHTML = input;
+
+ processNode(wrapper);
+
+ return wrapper
+}
class ChatScroller extends LitElement {
static get properties() {
return {
@@ -61,7 +167,9 @@ class ChatScroller extends LitElement {
}
}
- static styles = [chatStyles]
+ static get styles() {
+ return [chatStyles];
+ }
constructor() {
super()
@@ -103,7 +211,10 @@ class ChatScroller extends LitElement {
const isSameGroup = Math.abs(timestamp - message.timestamp) < 600000 && sender === message.sender && !repliedToData;
if (isSameGroup) {
- messageArray[messageArray.length - 1].messages = [...(messageArray[messageArray.length - 1]?.messages || []), message];
+ messageArray[messageArray.length - 1].messages = [
+ ...(messageArray[messageArray.length - 1].messages || []),
+ message
+ ];
} else {
messageArray.push({
messages: [message],
@@ -324,7 +435,10 @@ class MessageTemplate extends LitElement {
this.viewImage = false
}
- static styles = [chatStyles]
+ static get styles() {
+ return [chatStyles];
+ }
+
// Open & Close Private Message Chat Modal
showPrivateMessageModal() {
@@ -369,7 +483,7 @@ class MessageTemplate extends LitElement {
}
}
firstUpdated(){
- const autoSeeChatList = window.parent.reduxStore.getState().app?.autoLoadImageChats
+ const autoSeeChatList = window.parent.reduxStore.getState().app.autoLoadImageChats
if(autoSeeChatList.includes(this.chatId) || this.listSeenMessages.includes(this.messageObj.signature)){
this.viewImage = true
}
@@ -386,6 +500,7 @@ class MessageTemplate extends LitElement {
const hidemsg = this.hideMessages;
let message = "";
let messageVersion2 = ""
+ let messageVersion2WithLink = null
let reactions = [];
let repliedToData = null;
let image = null;
@@ -405,6 +520,8 @@ class MessageTemplate extends LitElement {
Highlight
// other extensions …
])
+ messageVersion2WithLink = processText(messageVersion2)
+
}
message = parsedMessageObj.messageText;
repliedToData = this.messageObj.repliedToData;
@@ -424,7 +541,6 @@ class MessageTemplate extends LitElement {
gif = parsedMessageObj.gifs[0];
}
} catch (error) {
- console.error(error);
message = this.messageObj.decodedMessage;
}
let avatarImg = '';
@@ -550,8 +666,28 @@ class MessageTemplate extends LitElement {
}
}
- const escapedMessage = this.escapeHTML(message)
- const replacedMessage = escapedMessage.replace(new RegExp('\r?\n','g'), '
');
+ let repliedToMessageText = ''
+ if (repliedToData && repliedToData.decodedMessage && repliedToData.decodedMessage.messageText) {
+ try {
+ repliedToMessageText = generateHTML(repliedToData.decodedMessage.messageText, [
+ StarterKit,
+ Underline,
+ Highlight
+ // other extensions …
+ ])
+ } catch (error) {
+
+ }
+ }
+ let replacedMessage = ''
+ if (message && +version < 2) {
+ const escapedMessage = this.escapeHTML(message)
+ if (escapedMessage) {
+ replacedMessage = escapedMessage.replace(new RegExp('\r?\n', 'g'), '
');
+ }
+
+ }
+
return hideit ? html`` : html`
- ${repliedToData.senderName ?? cropAddress(repliedToData.sender)}
+ ${repliedToData.senderName ? cropAddress(repliedToData.sender) : ''}
- ${version.toString() === '1' ? html`
+ ${version && version.toString() === '1' ? html`
${repliedToData.decodedMessage.messageText}
` : ''}
- ${+version > 1 ? html`
- ${unsafeHTML(generateHTML(repliedToData.decodedMessage.messageText, [
- StarterKit,
- Underline,
- Highlight
- // other extensions …
- ]))}
+ ${+version > 1 && repliedToMessageText ? html`
+ ${unsafeHTML(repliedToMessageText)}
`
: ''}
@@ -764,13 +895,14 @@ class MessageTemplate extends LitElement {
id="messageContent"
class="message"
style=${(image && replacedMessage !== "") &&"margin-top: 15px;"}>
- ${+version > 1 ? html`
+ ${+version > 1 ? messageVersion2WithLink ? html`${messageVersion2WithLink}` : html`
${unsafeHTML(messageVersion2)}
` : ''}
- ${version.toString() === '1' ? html`
+
+ ${version && version.toString() === '1' ? html`
${unsafeHTML(this.emojiPicker.parse(replacedMessage))}
` : ''}
- ${version.toString() === '0' ? html`
+ ${version && version.toString() === '0' ? html`
${unsafeHTML(this.emojiPicker.parse(replacedMessage))}
` : ''}
{};
}
- static styles = [chatStyles]
+ static get styles() {
+ return [chatStyles];
+ }
// Copy address to clipboard
async copyToClipboard(text) {
diff --git a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
index 455cc1ac..003b2a76 100644
--- a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
+++ b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
@@ -146,15 +146,15 @@ class WebBrowser extends LitElement {
// Build initial display URL
let displayUrl = 'qortal://' + this.service + '/' + this.name;
if (
- this.identifier != null &&
- data.identifier != '' &&
+ this.identifier && this.identifier != 'null' &&
this.identifier != 'default'
)
+ {
displayUrl = displayUrl.concat('/' + this.identifier);
+ }
if (this.path != null && this.path != '/')
displayUrl = displayUrl.concat(this.path);
this.displayUrl = displayUrl;
-
const getFollowedNames = async () => {
let followedNames = await parentEpml.request('apiCall', {
url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
@@ -193,8 +193,9 @@ class WebBrowser extends LitElement {
}
else {
// Normal mode
+
this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : ''
- }?theme=${this.theme}&identifier=${this.identifier != null ? this.identifier : ''
+ }?theme=${this.theme}&identifier=${(this.identifier != null && this.identifier != 'null') ? this.identifier : ''
}`
}
}
diff --git a/qortal-ui-plugins/plugins/utils/replace-messages-edited.js b/qortal-ui-plugins/plugins/utils/replace-messages-edited.js
index a7e459a7..ad815fe8 100644
--- a/qortal-ui-plugins/plugins/utils/replace-messages-edited.js
+++ b/qortal-ui-plugins/plugins/utils/replace-messages-edited.js
@@ -14,7 +14,7 @@ export const replaceMessagesEdited = async ({
}
const response = await parentEpml.request("apiCall", {
type: "api",
- url: `/chat/messages?chatreference=${msg.signature}&reverse=true${msgQuery}&limit=1&sender=${msg.sender}`,
+ url: `/chat/messages?chatreference=${msg.signature}&reverse=true${msgQuery}&limit=1&sender=${msg.sender}&encoding=BASE64`,
})
if (response && Array.isArray(response) && response.length !== 0) {
@@ -54,13 +54,13 @@ export const replaceMessagesEdited = async ({
if(+parsedMessageObj.version > 2){
originalReply = await parentEpml.request("apiCall", {
type: "api",
- url: `/chat/message/${parsedMessageObj.repliedTo}`,
+ url: `/chat/message/${parsedMessageObj.repliedTo}?encoding=BASE64`,
})
}
if(+parsedMessageObj.version < 3){
originalReply = await parentEpml.request("apiCall", {
type: "api",
- url: `/chat/messages?reference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}`,
+ url: `/chat/messages?reference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}&encoding=BASE64`,
})
}
@@ -71,7 +71,7 @@ export const replaceMessagesEdited = async ({
const response = await parentEpml.request("apiCall", {
type: "api",
- url: `/chat/messages?chatreference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}&limit=1&sender=${originalReplyMessage.sender}`,
+ url: `/chat/messages?chatreference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}&limit=1&sender=${originalReplyMessage.sender}&encoding=BASE64`,
})
if (