From 9d09bf23c5b59120497744954ae1521449d5d0bb Mon Sep 17 00:00:00 2001 From: koplenov Date: Sun, 10 May 2026 13:49:04 +0300 Subject: [PATCH] fix unread message indicator --- xmpp.view.ts | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/xmpp.view.ts b/xmpp.view.ts index 03e5018..c3bb8cb 100644 --- a/xmpp.view.ts +++ b/xmpp.view.ts @@ -22,7 +22,8 @@ media_size?: number media_hash?: string media_hash_algo?: string - } + read?: boolean + } type Xmpp_room = { jid: string @@ -53,6 +54,7 @@ media_size?: number media_hash?: string media_hash_algo?: string + read?: boolean } Indexes: {} } @@ -1300,6 +1302,7 @@ private _handle_message(el: Element) { } conn.on_message = msg => { if (this._msg_by_id.has(msg.id)) return // ← FIX: skip duplicates + msg.read = false this._add_message(msg) const bare = this.my_jid().split('/')[0] const peer = msg.from === bare ? msg.to : msg.from @@ -1313,6 +1316,7 @@ private _handle_message(el: Element) { } conn.on_groupchat_message = msg => { if (this._msg_by_id.has(msg.id)) return + msg.read = false this._add_message(msg) this._scroll_to_bottom(msg.from) const room = this._rooms.get(msg.from) @@ -1515,7 +1519,7 @@ private _handle_message(el: Element) { .filter(m => m.from === jid || m.to === jid || (m.from === bare && m.to === jid) || (m.from === jid && m.to === bare)) - return msgs.length > 0 + return msgs.some(m => m.from !== bare && !m.read) } @ $mol_mem_key @@ -1523,7 +1527,26 @@ private _handle_message(el: Element) { return this.unread_indicator(jid) ? '●' : '' } - open_chat(jid: string) { this.$.$mol_state_arg.value('chat', jid) } + open_chat(jid: string) { + this.$.$mol_state_arg.value('chat', jid) + this._mark_last_read(jid) + } + + private _mark_last_read(jid: string) { + const bare = this.my_jid().split('/')[0] + const msgs = this._msgs + .filter(m => m.from === jid || m.to === jid + || (m.from === bare && m.to === jid) + || (m.from === jid && m.to === bare)) + const unread_msgs = msgs.filter(m => m.from !== bare && !m.read) + for (const msg of unread_msgs) { + msg.read = true + void this._persist_msg(msg) + } + if (unread_msgs.length > 0) { + this.messages_ver(Date.now()) + } + } do_new_chat() { const jid = this.new_chat_jid().trim() @@ -1711,13 +1734,13 @@ private _handle_message(el: Element) { this.compose(jid, '') const id = `l${ Date.now() }_${ Math.random().toString(36).slice(2) }` this._conn.send_groupchat(jid, text, id) - this._add_message({ id, from: this.my_jid().split('/')[0], to: jid, body: text, time: Date.now() }) + this._add_message({ id, from: this.my_jid().split('/')[0], to: jid, body: text, time: Date.now(), read: true }) } this.compose(jid, '') const id = `l${ Date.now() }_${ Math.random().toString(36).slice(2) }` this._conn.send_message(jid, text, id) - this._add_message({ id, from: this.my_jid().split('/')[0], to: jid, body: text, time: Date.now() }) + this._add_message({ id, from: this.my_jid().split('/')[0], to: jid, body: text, time: Date.now(), read: true }) this._scroll_to_bottom(jid) } @@ -2037,6 +2060,7 @@ private _handle_message(el: Element) { ...(msg.media_hash !== undefined ? { media_hash: msg.media_hash } : {}), ...(msg.media_hash_algo !== undefined ? { media_hash_algo: msg.media_hash_algo } : {}), ...(msg.mam_id !== undefined ? { mam_id: msg.mam_id } : {}), + read: msg.read ?? false, } await Messages.put(doc, [account, msg.id]) } catch (e) { console.warn('[xmpp] persist failed', e) } @@ -2065,6 +2089,7 @@ private _handle_message(el: Element) { ...(doc.media_hash !== undefined ? { media_hash: doc.media_hash } : {}), ...(doc.media_hash_algo !== undefined ? { media_hash_algo: doc.media_hash_algo } : {}), ...(doc.mam_id !== undefined ? { mam_id: doc.mam_id } : {}), + read: doc.read ?? true, } this._add_message(msg) if (msg.mam_id) { @@ -2182,6 +2207,7 @@ private _handle_message(el: Element) { media_size: file.size, media_hash: hash, media_hash_algo: 'sha-256', + read: true, }) this._scroll_to_bottom(jid) }