From e3c2c780c82fcbe22b9edc5b984736e8611f1fed Mon Sep 17 00:00:00 2001 From: koplenov Date: Fri, 8 May 2026 01:02:37 +0300 Subject: [PATCH] added pooling --- xmpp.view.ts | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/xmpp.view.ts b/xmpp.view.ts index 362313c..740e022 100644 --- a/xmpp.view.ts +++ b/xmpp.view.ts @@ -617,6 +617,8 @@ private _handle_message(el: Element) { private _scroll_setup = new Set() // scroll listener installed private _rooms = new Map() private _oldest_time = new Map() // room_jid → oldest msg timestamp + private _poll_timer: number | null = null + private _poll_count: number = 0 private _ver = 0 private _toast_container: HTMLDivElement | null = null @@ -1129,6 +1131,7 @@ private _handle_message(el: Element) { this.my_jid(bound_jid) this.status('connected') this._connect_at = Date.now() + this._start_polling() void this._load_persisted() } conn.on_bookmarks = bookmarks => { @@ -1264,6 +1267,7 @@ private _handle_message(el: Element) { this._rooms.clear() this.rooms([]) this._oldest_time.clear() + this._stop_polling() this.messages_ver(0) this.$.$mol_state_arg.value('chat', null) } @@ -1891,6 +1895,53 @@ private _handle_message(el: Element) { this._last_displayed_sent.set(jid, newest.time) } + // Periodically poll for new messages in loaded chats to recover from connection issues. + private _start_polling() { + if (this._poll_timer) clearInterval(this._poll_timer) + this._poll_count = 0 + this._poll_timer = setInterval(() => { + if (!this._conn) return + this._poll_count++ + const current_chat = this.$.$mol_state_arg.value('chat') + const is_full_poll = this._poll_count % 6 === 0 // every 30 seconds + + // Always poll current chat if open + if (current_chat) { + if (this._history_loaded.has(current_chat) && !this._loading_more.has(current_chat)) { + this._conn.request_mam(current_chat, 5) + } else if (this._rooms.has(current_chat) && !this._loading_more.has(current_chat)) { + this._conn.request_mam_room(current_chat, 5) + } + } + + // Poll all others every 30 seconds + if (is_full_poll) { + // Poll 1:1 chats that have history loaded (except current) + for (const peer of this._history_loaded) { + if (peer === current_chat) continue + if (!this._loading_more.has(peer)) { + this._conn.request_mam(peer, 5) + } + } + // Poll rooms that are joined (except current) + for (const room of this._rooms.values()) { + if (room.jid === current_chat) continue + if (!this._loading_more.has(room.jid)) { + this._conn.request_mam_room(room.jid, 5) + } + } + } + }, 5000) // every 5 seconds + } + + private _stop_polling() { + if (this._poll_timer) { + clearInterval(this._poll_timer) + this._poll_timer = null + this._poll_count = 0 + } + } + private async _upload_and_send(jid: string, file: File): Promise { if (!this._conn) throw new Error('Not connected') const { put, get } = await this._conn.request_slot(file.name, file.size, file.type)