feature addition, bug fixes and code refactoring

--Added support for eth chat merging
This commit is contained in:
sairaj mote 2023-10-17 03:26:57 +05:30
parent 5e4b9e9803
commit a5a0e4ef8f
6 changed files with 155 additions and 118 deletions

View File

@ -1788,12 +1788,14 @@ sm-chip .badge {
position: -webkit-sticky; position: -webkit-sticky;
position: sticky; position: sticky;
top: 0; top: 0;
z-index: 1; z-index: 2;
background-color: rgba(var(--background-color), 0.9); background-color: rgba(var(--foreground-color), 1);
border: solid thin rgba(var(--text-color), 0.2); border: solid thin rgba(var(--text-color), 0.2);
color: rgba(var(--text-color), 0.8);
margin: 1.5rem auto; margin: 1.5rem auto;
-webkit-backdrop-filter: blur(1rem); -webkit-backdrop-filter: blur(1rem);
backdrop-filter: blur(1rem); backdrop-filter: blur(1rem);
box-shadow: 0 1rem 1.5rem rgba(0, 0, 0, 0.1);
} }
.message { .message {
@ -2139,11 +2141,6 @@ sm-chip .badge {
padding-bottom: 6rem; padding-bottom: 6rem;
} }
.has-bg-image .received,
.has-bg-image .group-event-card,
.has-bg-image .date-card {
background: rgba(var(--foreground-color), 1);
}
.has-bg-image .received::after { .has-bg-image .received::after {
border-color: transparent rgba(var(--foreground-color), 0.6) transparent transparent; border-color: transparent rgba(var(--foreground-color), 0.6) transparent transparent;
} }

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -1835,11 +1835,13 @@ sm-chip {
#transaction_details { #transaction_details {
position: sticky; position: sticky;
top: 0; top: 0;
z-index: 1; z-index: 2;
background-color: rgba(var(--background-color), 0.9); background-color: rgba(var(--foreground-color), 1);
border: solid thin rgba(var(--text-color), 0.2); border: solid thin rgba(var(--text-color), 0.2);
color: rgba(var(--text-color), 0.8);
margin: 1.5rem auto; margin: 1.5rem auto;
backdrop-filter: blur(1rem); backdrop-filter: blur(1rem);
box-shadow: 0 1rem 1.5rem rgba(0 0 0 / 0.1);
} }
.message { .message {
@ -2189,12 +2191,6 @@ sm-chip {
} }
.has-bg-image { .has-bg-image {
.received,
.group-event-card,
.date-card {
background: rgba(var(--foreground-color), 1);
}
.received::after { .received::after {
border-color: transparent rgba(var(--foreground-color), 0.6) transparent border-color: transparent rgba(var(--foreground-color), 0.6) transparent
transparent; transparent;

View File

@ -254,7 +254,7 @@
<div id="chat_sections"> <div id="chat_sections">
<div class="flex flex-direction-column gap-0-5" style="overflow: hidden;"> <div class="flex flex-direction-column gap-0-5" style="overflow: hidden;">
<div class="flex align-center gap-0-5" style="padding: 0 1rem;"> <div class="flex align-center gap-0-5" style="padding: 0 1rem;">
<sm-input id="search_chats" type="search" placeholder="Search FLO/BTC address or name"> <sm-input id="search_chats" type="search" placeholder="FLO/BTC/ETH address or name">
<svg slot="icon" class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" <svg slot="icon" class="icon" xmlns="http://www.w3.org/2000/svg" height="24px"
viewBox="0 0 24 24" width="24px" fill="#000000"> viewBox="0 0 24 24" width="24px" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" /> <path d="M0 0h24v24H0V0z" fill="none" />
@ -691,8 +691,8 @@
<h4>Add contact</h4> <h4>Add contact</h4>
</header> </header>
<sm-form> <sm-form>
<sm-input id="add_contact_floID" data-flo-address placeholder="FLO/BTC address" error-text="Invalid address" <sm-input id="add_contact_floID" data-flo-address placeholder="FLO/BTC/ETH address"
animate autofocus required></sm-input> error-text="Invalid address" animate autofocus required></sm-input>
<sm-input id="add_contact_name" placeholder="Name" animate required></sm-input> <sm-input id="add_contact_name" placeholder="Name" animate required></sm-input>
<button class="button button--primary" id="add_contact_button" type="submit" disabled>Add</button> <button class="button button--primary" id="add_contact_button" type="submit" disabled>Add</button>
</sm-form> </sm-form>
@ -799,7 +799,7 @@
<div id="contacts_container" class="observe-empty-state"></div> <div id="contacts_container" class="observe-empty-state"></div>
<div class="empty-state"> <div class="empty-state">
<h4 class="margin-bottom-0-5">No saved contacts</h4> <h4 class="margin-bottom-0-5">No saved contacts</h4>
<p>Use 'Add contact' to add new FLO/BTC address as a contact.</p> <p>Use 'Add contact' to add new FLO/BTC/ETH address as a contact.</p>
</div> </div>
</div> </div>
</div> </div>
@ -839,7 +839,7 @@
<div id="select_contacts_container" class="observe-empty-state"></div> <div id="select_contacts_container" class="observe-empty-state"></div>
<div class="empty-state"> <div class="empty-state">
<h4 class="margin-bottom-0-5">No saved contacts.</h4> <h4 class="margin-bottom-0-5">No saved contacts.</h4>
<p class="margin-bottom-1">Use 'Add contact' to add new FLO/BTC address as a contact.</p> <p class="margin-bottom-1">Use 'Add contact' to add new FLO/BTC/ETH address as a contact.</p>
<button class="button interactive" onclick="openPopup('add_contact_popup')"> <button class="button interactive" onclick="openPopup('add_contact_popup')">
<svg class="icon margin-right-0-5" xmlns="http://www.w3.org/2000/svg" <svg class="icon margin-right-0-5" xmlns="http://www.w3.org/2000/svg"
enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px"
@ -1194,7 +1194,7 @@
popupStack.peek().popup.hide(options) popupStack.peek().popup.hide(options)
} }
function getFloIdType(floID) { function getAddressType(floID) {
if (messenger.groups.hasOwnProperty(floID)) if (messenger.groups.hasOwnProperty(floID))
return 'group'; return 'group';
else if (messenger.pipeline.hasOwnProperty(floID)) else if (messenger.pipeline.hasOwnProperty(floID))
@ -1209,7 +1209,7 @@
switch (e.target.id) { switch (e.target.id) {
case 'contact_details_popup': case 'contact_details_popup':
const chatAddress = floGlobals.viewingDetailsOfAddress; const chatAddress = floGlobals.viewingDetailsOfAddress;
const addressType = getFloIdType(chatAddress); const addressType = getAddressType(chatAddress);
let isAdmin = false; let isAdmin = false;
let contactInitial = ''; let contactInitial = '';
let disableContactName = false; let disableContactName = false;
@ -1310,7 +1310,7 @@
console.error(e) console.error(e)
} }
} else { } else {
contactFloAddress = validateEthAddress(chatAddress) ? floCrypto.getFloID(floGlobals.pubKeys[chatAddress]) : floCrypto.toFloID(chatAddress); contactFloAddress = validateEthAddress(chatAddress) ? floCrypto.getFloID(floGlobals.pubKeys[chatAddress] || getEthPubKey(chatAddress)) : floCrypto.toFloID(chatAddress);
} }
if (addressType === 'plain') { if (addressType === 'plain') {
if (contactFloAddress) if (contactFloAddress)
@ -1580,7 +1580,7 @@
break; break;
case 'error': case 'error':
icon = `<svg class="icon icon--error" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-7v2h2v-2h-2zm0-8v6h2V7h-2z"/></svg>` icon = `<svg class="icon icon--error" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-7v2h2v-2h-2zm0-8v6h2V7h-2z"/></svg>`
options.pinned = true options.timeout = 15000
break; break;
} }
if (mode === 'error') { if (mode === 'error') {
@ -1785,6 +1785,12 @@
targetChatCard.classList.add('active') targetChatCard.classList.add('active')
} }
await viewConversation(params.address) await viewConversation(params.address)
setTimeout(() => {
if (!chatScrollInfo.isScrolledUp) {
console.log('scrolling to bottom')
scrollToBottom()
}
}, 0);
getRef('messages_container').animate([ getRef('messages_container').animate([
{ opacity: 0 }, { opacity: 0 },
{ opacity: 1 }, { opacity: 1 },
@ -2089,6 +2095,7 @@
} }
this.lazyContainer.innerHTML = ``; this.lazyContainer.innerHTML = ``;
} }
this.updateStartIndex = Math.max(this.updateStartIndex, 0)
this.lastScrollHeight = this.lazyContainer.scrollHeight this.lastScrollHeight = this.lazyContainer.scrollHeight
this.lastScrollTop = this.lazyContainer.scrollTop this.lastScrollTop = this.lazyContainer.scrollTop
this.arrayOfElements.slice(this.updateStartIndex, this.updateEndIndex).forEach((element, index) => { this.arrayOfElements.slice(this.updateStartIndex, this.updateEndIndex).forEach((element, index) => {
@ -2827,12 +2834,19 @@
function getLastMessage(floID) { function getLastMessage(floID) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let chatGetter
let type let type
if (messenger.chats[floID]) if (messenger.chats[floID]) {
type = 'chat' type = 'chat'
else if (messenger.groups[floID]) chatGetter = getMergedChat
type = 'group' } else {
messenger.getChat(floID).then(chat => { if (messenger.groups[floID])
type = 'group'
if (messenger.pipeline[floID])
type = 'pipeline'
chatGetter = messenger.getChat
}
chatGetter(floID).then(chat => {
let lastMessage = Object.values(chat).reverse().find(({ message }) => message) || { message: '', time: 0 } let lastMessage = Object.values(chat).reverse().find(({ message }) => message) || { message: '', time: 0 }
let { message, time, sender, category } = lastMessage let { message, time, sender, category } = lastMessage
if (type === 'group' && time === 0) if (type === 'group' && time === 0)
@ -2885,6 +2899,16 @@
return false return false
} }
} }
const ethPubKeyLookup = new Map()
function getEthPubKey(ethAddress) {
if (ethPubKeyLookup.has(ethAddress)) return ethPubKeyLookup.get(ethAddress)
for (const address in floGlobals.pubKeys) {
if (floEthereum.ethAddressFromCompressedPublicKey(floGlobals.pubKeys[address]) === ethAddress) {
ethPubKeyLookup.set(address, floGlobals.pubKeys[address])
return floGlobals.pubKeys[address]
}
}
}
function addNotificationBadge(elem, text, { replace = false } = {}) { function addNotificationBadge(elem, text, { replace = false } = {}) {
const animOptions = { const animOptions = {
duration: 200, duration: 200,
@ -3028,10 +3052,9 @@
} }
for (let messageId in messagesData) { for (let messageId in messagesData) {
const { category, floID, time, message, sender, groupID, admin, name, pipeID, unconfirmed, type } = messagesData[messageId] const { category, floID, time, message, sender, groupID, admin, name, pipeID, unconfirmed, type } = messagesData[messageId]
console.log(messagesData[messageId])
const chatAddress = floID || groupID || pipeID const chatAddress = floID || groupID || pipeID
// code to run if a chat is opened // code to run if a chat is opened
if (activeChat && floCrypto.isSameAddr(activeChat.address, chatAddress)) { if (activeChat && floCrypto.isSameAddr(activeChat.address, chatAddress) || floCrypto.isSameAddr(floCrypto.getFloID(getEthPubKey(activeChat.address)), chatAddress)) {
if (sentByMe || type === 'TRANSACTION' || !sender || !floCrypto.isSameAddr(sender, floDapps.user.id)) { if (sentByMe || type === 'TRANSACTION' || !sender || !floCrypto.isSameAddr(sender, floDapps.user.id)) {
const messageBody = render.messageBubble(messagesData[messageId]); const messageBody = render.messageBubble(messagesData[messageId]);
getRef('messages_container').append(messageBody); getRef('messages_container').append(messageBody);
@ -3040,7 +3063,7 @@
scrollToBottom() scrollToBottom()
} }
// remove encryption badge if it exists // remove encryption badge if it exists
if (!groupID && floDapps.user.get_pubKey(activeChat.address) && floID !== floDapps.user.id) { if (!groupID && (floDapps.user.get_pubKey(activeChat.address) || getEthPubKey(activeChat.address)) && floID !== floDapps.user.id) {
if (getRef('warn_no_encryption')) { if (getRef('warn_no_encryption')) {
getRef('warn_no_encryption').after( getRef('warn_no_encryption').after(
html.node` html.node`
@ -3062,7 +3085,7 @@
} }
// move chat card to top if it is not already there // move chat card to top if it is not already there
const topChatCard = getRef('chats_list').children[0] const topChatCard = getRef('chats_list').children[0]
if (!floCrypto.isSameAddr(chatAddress, topChatCard.dataset.address)) { if (!floCrypto.isSameAddr(chatAddress, topChatCard.dataset.address) && !floCrypto.isSameAddr(floCrypto.getFloID(getEthPubKey(chatAddress)), topChatCard.dataset.address)) {
const cloneContact = chatCard.cloneNode(true) const cloneContact = chatCard.cloneNode(true)
chatCard.remove() chatCard.remove()
getRef('chats_list').prepend(cloneContact) getRef('chats_list').prepend(cloneContact)
@ -3108,7 +3131,7 @@
if (chatCard.querySelector('.time')) if (chatCard.querySelector('.time'))
chatCard.querySelector('.time').textContent = getFormattedTime(time, 'relative') chatCard.querySelector('.time').textContent = getFormattedTime(time, 'relative')
if (activeChat.address === chatAddress) { if (floCrypto.isSameAddr(activeChat.address, chatAddress) || floCrypto.isSameAddr(floCrypto.getFloID(getEthPubKey(activeChat.address)), chatAddress)) {
if (chatScrollInfo.isScrolledUp) if (chatScrollInfo.isScrolledUp)
getRef('scroll_to_bottom').classList.add('new-message') getRef('scroll_to_bottom').classList.add('new-message')
else { else {
@ -3752,8 +3775,8 @@
function addContact() { function addContact() {
let addressToSave = getRef('add_contact_floID').value.trim(); let addressToSave = getRef('add_contact_floID').value.trim();
let name = getRef('add_contact_name').value.trim(); let name = getRef('add_contact_name').value.trim();
if (floCrypto.isSameAddr(addressToSave, floDapps.user.id)) { if (floCrypto.isSameAddr(addressToSave, floDapps.user.id) || floCrypto.myEthID === addressToSave) {
notify(`you can't add your own FLO/BTC address as contact`, 'error') notify(`you can't add your own FLO/BTC/ETH address as contact`, 'error')
return return
} }
if (floGlobals.contacts.hasOwnProperty(addressToSave)) { if (floGlobals.contacts.hasOwnProperty(addressToSave)) {
@ -3784,7 +3807,7 @@
if (popupStack.items.find(elem => elem.popup.id === 'new_message_popup')) { if (popupStack.items.find(elem => elem.popup.id === 'new_message_popup')) {
renderContactList() renderContactList()
} }
if (activeChat.address === addressToSave) if (floCrypto.isSameAddr(activeChat.address, addressToSave))
updateChatHeaderName(name) updateChatHeaderName(name)
}).catch(error => notify(error, "error")); }).catch(error => notify(error, "error"));
} }
@ -3806,7 +3829,7 @@
skipSendingRequest.add(sentRequests[key].floID) skipSendingRequest.add(sentRequests[key].floID)
} }
for (const floID in floGlobals.contacts) { for (const floID in floGlobals.contacts) {
if (getFloIdType(floID) !== 'plain') continue; if (getAddressType(floID) !== 'plain') continue;
if (floDapps.user.get_pubKey(floID)) { if (floDapps.user.get_pubKey(floID)) {
contacts.push(render.selectableContact(floID)) contacts.push(render.selectableContact(floID))
} else { } else {
@ -3826,19 +3849,26 @@
return mergedChatOrder.push(address) return mergedChatOrder.push(address)
if (messenger.pipeline.hasOwnProperty(address)) if (messenger.pipeline.hasOwnProperty(address))
return mergedChatOrder.push(address) return mergedChatOrder.push(address)
let priorityAddress = address; let priorityAddress;
const addressPubKey = floGlobals.pubKeys[address]; let equivalentFloAddress;
const addrInFlo = validateEthAddress(address) ? (floCrypto.getFloID(addressPubKey) || floCrypto.toFloID(address)) : floCrypto.toFloID(address); let equivalentBtcAddress;
const addrInBtc = btcOperator.convert.legacy2bech(addrInFlo); let equivalentEthAddress;
const addrInEth = addressPubKey ? floEthereum.ethAddressFromCompressedPublicKey(addressPubKey) : null; const addressPubKey = floGlobals.pubKeys[address] || getEthPubKey(address);
if (floGlobals.contacts.hasOwnProperty(addrInFlo)) { //if address id ethereuem address get equivalent flo address from pubKey if available
priorityAddress = addrInFlo; equivalentFloAddress = validateEthAddress(address) ? floCrypto.getFloID(addressPubKey) : floCrypto.toFloID(address); //
} else if (floGlobals.contacts.hasOwnProperty(addrInBtc)) { if (equivalentFloAddress)
priorityAddress = addrInBtc; equivalentBtcAddress = btcOperator.convert.legacy2bech(equivalentFloAddress);
} else if (addrInEth && floGlobals.contacts.hasOwnProperty(addrInEth)) { equivalentEthAddress = addressPubKey ? floEthereum.ethAddressFromCompressedPublicKey(addressPubKey) : null;
priorityAddress = addrInEth; if (equivalentFloAddress && floGlobals.contacts.hasOwnProperty(equivalentFloAddress)) {
priorityAddress = equivalentFloAddress;
} else if (equivalentBtcAddress && floGlobals.contacts.hasOwnProperty(equivalentBtcAddress)) {
priorityAddress = equivalentBtcAddress;
} else if (equivalentEthAddress && floGlobals.contacts.hasOwnProperty(equivalentEthAddress)) {
priorityAddress = equivalentEthAddress;
} else {
priorityAddress = address;
} }
if (!chatOrderLookup.has(addrInFlo) && !chatOrderLookup.has(addrInBtc) && !chatOrderLookup.has(addrInEth)) { if (!chatOrderLookup.has(equivalentFloAddress) && !chatOrderLookup.has(equivalentBtcAddress) && !chatOrderLookup.has(equivalentEthAddress)) {
mergedChatOrder.push(priorityAddress) mergedChatOrder.push(priorityAddress)
chatOrderLookup.add(priorityAddress) chatOrderLookup.add(priorityAddress)
} }
@ -3927,68 +3957,80 @@
} }
} }
let chatLazyLoader function getMergedChat(address) {
function renderMessages(address) { return new Promise((resolve, reject) => {
return new Promise(async (resolve, reject) => { let floChatAddress
let floChatID = validateEthAddress(address) ? floCrypto.getFloID(floGlobals.pubKeys[address]) || floCrypto.toFloID(address) : floCrypto.toFloID(address); let btcChatAddress
let btcChatID = btcOperator.convert.legacy2bech(floChatID); const promises = []
const promises = [messenger.getChat(floChatID), messenger.getChat(btcChatID)] floChatAddress = validateEthAddress(address) ? floCrypto.getFloID(floGlobals.pubKeys[address] || getEthPubKey(address)) : floCrypto.toFloID(address);
if (floChatAddress) {
btcChatAddress = btcOperator.convert.legacy2bech(floChatAddress);
promises.push(messenger.getChat(floChatAddress), messenger.getChat(btcChatAddress))
}
if (validateEthAddress(address)) if (validateEthAddress(address))
promises.push(messenger.getChat(address)) promises.push(messenger.getChat(address))
Promise.all(promises) Promise.all(promises)
.then(([floChat, btcChat, ethChat = []]) => { .then((chats) => {
const floBtcMerged = mergeSortedArrays(Object.values(floChat), Object.values(btcChat), 'time') // recursively merge chats using mergeSortedArrays
const floBtcEthMerged = mergeSortedArrays(floBtcMerged, Object.values(ethChat), 'time') const mergedChat = chats.reduce((acc, chat) => mergeSortedArrays(acc, Object.values(chat), 'time'), [])
let chat = floBtcEthMerged resolve(mergedChat)
console.log(chat)
if (chatLazyLoader) {
chatLazyLoader.update(chat)
} else {
chatLazyLoader = new LazyLoader('#messages_container', chat, render.messageBubble, {
bottomFirst: true,
batchSize: 20,
onEnd: () => {
if (activeChat.type === 'plain') {
if (floDapps.user.get_pubKey(activeChat.address)) {
getRef('messages_container').prepend(html.node`<strong class="event-card flex align-center">
<svg class="icon margin-right-0-5" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g fill="none"><path d="M0 0h24v24H0V0z"/><path d="M0 0h24v24H0V0z" opacity=".87"/></g><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM9 6c0-1.66 1.34-3 3-3s3 1.34 3 3v2H9V6zm9 14H6V10h12v10zm-6-3c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z"/></svg>
Conversation is encrypted
</strong>`)
} else {
getRef('messages_container').prepend(html.node`<strong id="warn_no_encryption" class="event-card">Conversation is not encrypted until receiver replies</strong>`)
}
}
}
});
}
chatLazyLoader.init()
if (getFloIdType(address) === 'pipeline') {
if (!floGlobals.pipeSigns[address])
floGlobals.pipeSigns[address] = new Set()
for (const key in chat) {
const { type, sender, tx_hex, txid } = chat[key]
switch (type) {
case 'TRANSACTION':
floGlobals.pipeSigns[address].add(sender)
if (tx_hex)
floGlobals.pipelineTxHex = tx_hex
break;
case 'BROADCAST':
if (txid) {
floGlobals.pipelineTxID = txid
}
break;
}
}
}
resolve()
}).catch(error => { }).catch(error => {
console.error(error)
reject(error) reject(error)
}) })
}) })
} }
let chatLazyLoader
function renderMessages(address) {
return new Promise(async (resolve, reject) => {
(getAddressType(address) === 'plain' ? getMergedChat(address) : messenger.getChat).then(chat => {
if (chatLazyLoader) {
chatLazyLoader.update(chat)
} else {
chatLazyLoader = new LazyLoader('#messages_container', chat, render.messageBubble, {
bottomFirst: true,
batchSize: 20,
onEnd: () => {
if (activeChat.type === 'plain') {
if (floDapps.user.get_pubKey(activeChat.address) || getEthPubKey(activeChat.address)) {
getRef('messages_container').prepend(html.node`<strong class="event-card flex align-center">
<svg class="icon margin-right-0-5" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g fill="none"><path d="M0 0h24v24H0V0z"/><path d="M0 0h24v24H0V0z" opacity=".87"/></g><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM9 6c0-1.66 1.34-3 3-3s3 1.34 3 3v2H9V6zm9 14H6V10h12v10zm-6-3c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z"/></svg>
Conversation is encrypted
</strong>`)
} else {
getRef('messages_container').prepend(html.node`<strong id="warn_no_encryption" class="event-card">Conversation is not encrypted until receiver replies</strong>`)
}
}
}
});
}
chatLazyLoader.init()
if (getAddressType(address) === 'pipeline') {
if (!floGlobals.pipeSigns[address])
floGlobals.pipeSigns[address] = new Set()
for (const key in chat) {
const { type, sender, tx_hex, txid } = chat[key]
switch (type) {
case 'TRANSACTION':
floGlobals.pipeSigns[address].add(sender)
if (tx_hex)
floGlobals.pipelineTxHex = tx_hex
break;
case 'BROADCAST':
if (txid) {
floGlobals.pipelineTxID = txid
}
break;
}
}
}
resolve()
}).catch(error => {
reject(error)
})
})
}
floGlobals.typedMessages = {} floGlobals.typedMessages = {}
floGlobals.pipeSigns = {} floGlobals.pipeSigns = {}
function viewConversation(floID) { function viewConversation(floID) {
@ -4004,7 +4046,7 @@
// restore typed message if any // restore typed message if any
getRef('type_message').value = floGlobals.typedMessages[floID] || '' getRef('type_message').value = floGlobals.typedMessages[floID] || ''
activeChat.address = floID activeChat.address = floID
activeChat.type = getFloIdType(floID) activeChat.type = getAddressType(floID)
updateChatHeaderName(getContactName(floID)); updateChatHeaderName(getContactName(floID));
const chatCard = getChatCard(floID); const chatCard = getChatCard(floID);
if (chatCard) { if (chatCard) {
@ -4027,7 +4069,7 @@
chatScrollInfo['isScrolledUp'] = false chatScrollInfo['isScrolledUp'] = false
getRef('scroll_to_bottom').classList.remove('no-transformations') getRef('scroll_to_bottom').classList.remove('no-transformations')
} }
const floIdType = getFloIdType(floID) const floIdType = getAddressType(floID)
if (floIdType === 'pipeline' && messenger.pipeline[floID].disabled) { if (floIdType === 'pipeline' && messenger.pipeline[floID].disabled) {
getRef('chat_footer').classList.add('hidden') getRef('chat_footer').classList.add('hidden')
} else { } else {
@ -4035,7 +4077,6 @@
} }
lastSender = '' lastSender = ''
renderMessages(floID).then(async () => { renderMessages(floID).then(async () => {
scrollToBottom()
if (activeChat.type === 'pipeline') { if (activeChat.type === 'pipeline') {
if (!messenger.pipeline[floID].disabled && floGlobals.pipeSigns[floID] && !floGlobals.pipeSigns[floID].has(floDapps.user.id)) { if (!messenger.pipeline[floID].disabled && floGlobals.pipeSigns[floID] && !floGlobals.pipeSigns[floID].has(floDapps.user.id)) {
getRef('messages_container').append(html.node` getRef('messages_container').append(html.node`
@ -4106,7 +4147,7 @@
} }
} }
getRef('messages_container').prepend(html.node` getRef('messages_container').prepend(html.node`
<details id="transaction_details" class="grid gap-1 card" open> <details id="transaction_details" class="grid gap-1 card">
<summary> <summary>
${pendingSigns === 0 ? html` ${pendingSigns === 0 ? html`
<h4>Required signatures are done</h4> <h4>Required signatures are done</h4>
@ -4356,7 +4397,7 @@
async function changeContactName(name) { async function changeContactName(name) {
const floID = floGlobals.viewingDetailsOfAddress const floID = floGlobals.viewingDetailsOfAddress
const type = getFloIdType(floID) const type = getAddressType(floID)
if (type === 'group') { if (type === 'group') {
messenger.changeGroupName(floID, name).then(res => { messenger.changeGroupName(floID, name).then(res => {
updateChatCards({ name, floID }) updateChatCards({ name, floID })
@ -4373,13 +4414,13 @@
} }
function updateChatCards({ name, floID }) { function updateChatCards({ name, floID }) {
const type = getFloIdType(floID) const type = getAddressType(floID)
if (activeChat.address && activeChat.address === clickedContact.address) { if (activeChat.address && floCrypto.isSameAddr(activeChat.address, clickedContact.address)) {
updateChatHeaderName(name) updateChatHeaderName(name)
} }
if (type === 'plain') { if (type === 'plain') {
getRef('contact_initial').textContent = name.charAt(0) getRef('contact_initial').textContent = name.charAt(0)
if (activeChat.address && activeChat.address === clickedContact.address) { if (activeChat.address && floCrypto.isSameAddr(activeChat.address, clickedContact.address)) {
getRef('receiver_initial').textContent = name.charAt(0) getRef('receiver_initial').textContent = name.charAt(0)
} }
document.querySelectorAll(`.contact[data-address="${floID}"]`).forEach(contact => { document.querySelectorAll(`.contact[data-address="${floID}"]`).forEach(contact => {
@ -4390,11 +4431,15 @@
} }
function getChatCard(address) { function getChatCard(address) {
const addressPubKey = floGlobals.pubKeys[address]; let floAddress
const floID = validateEthAddress(address) ? (floCrypto.getFloID(addressPubKey) || floCrypto.toFloID(address)) : floCrypto.toFloID(address); let btcAddress
const btcID = btcOperator.convert.legacy2bech(floID) let ethAddress
const ethID = addressPubKey ? floEthereum.ethAddressFromCompressedPublicKey(addressPubKey) : address const addressPubKey = floGlobals.pubKeys[address] || getEthPubKey(address);
return getRef('chats_list').querySelector(`[data-address="${floID}"], [data-address="${btcID}"], [data-address="${ethID}"]`) floAddress = validateEthAddress(address) ? floCrypto.getFloID(addressPubKey) : floCrypto.toFloID(address)
if (floAddress)
btcAddress = btcOperator.convert.legacy2bech(floAddress)
ethAddress = addressPubKey ? floEthereum.ethAddressFromCompressedPublicKey(addressPubKey) : null;
return getRef('chats_list').querySelector(`[data-address="${floAddress}"], [data-address="${btcAddress}"], [data-address="${ethAddress}"], [data-address="${address}"]`)
} }
function addAsContact() { function addAsContact() {

View File

@ -324,7 +324,6 @@
if (unparsed.message instanceof Object && "secret" in unparsed.message) if (unparsed.message instanceof Object && "secret" in unparsed.message)
unparsed.message = floDapps.user.decrypt(unparsed.message); unparsed.message = floDapps.user.decrypt(unparsed.message);
let vc = unparsed.vectorClock; let vc = unparsed.vectorClock;
console.debug(unparsed);
switch (unparsed.type) { switch (unparsed.type) {
case "MESSAGE": { //process as message case "MESSAGE": { //process as message
let dm = { let dm = {

File diff suppressed because one or more lines are too long