branch: elpa/jabber
commit 5a90b151c0c80d86b4fc72027a04a11fcf077985
Author: Thanos Apollo <[email protected]>
Commit: Thanos Apollo <[email protected]>
muc: Separate room state
---
lisp/jabber-alert.el | 3 +-
lisp/jabber-bookmarks.el | 3 +-
lisp/jabber-chat.el | 3 +-
lisp/jabber-chatstates.el | 2 +-
lisp/jabber-db.el | 2 +-
lisp/jabber-httpupload.el | 2 +-
lisp/jabber-mam.el | 2 +-
lisp/jabber-muc-nick-completion.el | 2 +-
lisp/jabber-muc-state.el | 86 ++++++++++++++++++++++++++++++++++++++
lisp/jabber-muc.el | 74 +-------------------------------
lisp/jabber-omemo.el | 2 +-
lisp/jabber-presence.el | 7 +---
lisp/jabber-reactions.el | 2 +-
lisp/jabber-roster.el | 3 +-
lisp/jabber-util.el | 1 -
15 files changed, 100 insertions(+), 94 deletions(-)
diff --git a/lisp/jabber-alert.el b/lisp/jabber-alert.el
index 4e3f318a84..b61d9fdbb6 100644
--- a/lisp/jabber-alert.el
+++ b/lisp/jabber-alert.el
@@ -30,6 +30,7 @@
(require 'cl-lib)
(require 'jabber-util)
(require 'jabber-xml)
+(require 'jabber-muc-state)
(defgroup jabber-alerts nil
"Auditory and visual alerts for Jabber events."
@@ -242,8 +243,6 @@ files."
(declare-function jabber-chat-send "jabber-chat.el"
(jc body &optional extra-elements))
(declare-function jabber-muc-sender-p "jabber-muc.el" (jid))
-(declare-function jabber-muc-nickname "jabber-muc.el" (group &optional jc))
-(declare-function jabber-muc-our-nick-p "jabber-muc.el" (group nick))
(defvar jabber-presence-strings) ; jabber.el
(defvar jabber-xml-data) ; jabber.el
(defvar jabber-buffer-connection) ; jabber-chatbuffer.el
diff --git a/lisp/jabber-bookmarks.el b/lisp/jabber-bookmarks.el
index c2ff67e3cb..bb44f5a2c0 100644
--- a/lisp/jabber-bookmarks.el
+++ b/lisp/jabber-bookmarks.el
@@ -31,6 +31,7 @@
(require 'jabber-private)
(require 'jabber-pubsub)
+(require 'jabber-muc-state)
(require 'keymap-popup)
(defconst jabber-bookmarks-xmlns "storage:bookmarks"
@@ -59,8 +60,6 @@
(declare-function jabber-disco-get-info "jabber-disco.el"
(jc jid node callback closure-data &optional force))
-(declare-function jabber-muc-joined-p "jabber-muc" (group &optional jc))
-(declare-function jabber-muc-nickname "jabber-muc" (group &optional jc))
(declare-function jabber-muc-join "jabber-muc" (jc group nickname &optional
popup))
(declare-function jabber-muc-leave "jabber-muc" (jc group))
(declare-function jabber-muc-get-buffer "jabber-muc" (group &optional jc))
diff --git a/lisp/jabber-chat.el b/lisp/jabber-chat.el
index c26ebf54f7..ae12b60a5f 100644
--- a/lisp/jabber-chat.el
+++ b/lisp/jabber-chat.el
@@ -39,6 +39,7 @@
(require 'url-queue)
(require 'hex-util)
(require 'jabber-image)
+(require 'jabber-muc-state)
;; For the `image-property' setf-expander (not preloaded on emacs-nox).
(require 'image)
@@ -273,8 +274,6 @@ holding state for the next composed message stay inert."
(declare-function jabber-muc-message-p "jabber-muc.el"(message))
(declare-function jabber-muc-sender-p "jabber-muc.el" (jid))
(declare-function jabber-muc-private-message-p "jabber-muc.el" (message))
-(declare-function jabber-muc-nickname "jabber-muc.el" (group &optional jc))
-(declare-function jabber-muc-our-nick-p "jabber-muc.el" (group nick))
(defvar jabber-muc-xmlns-user)
(declare-function jabber-omemo-aesgcm-decrypt "jabber-omemo"
(key iv ciphertext-with-tag))
diff --git a/lisp/jabber-chatstates.el b/lisp/jabber-chatstates.el
index 33e2b4a5ff..68b9d3c119 100644
--- a/lisp/jabber-chatstates.el
+++ b/lisp/jabber-chatstates.el
@@ -36,6 +36,7 @@
(require 'jabber-chat)
(require 'jabber-chatbuffer)
(require 'jabber-disco)
+(require 'jabber-muc-state)
(require 'jabber-xml)
@@ -43,7 +44,6 @@
(defvar jabber-chatting-with) ; jabber-chat.el
(declare-function jabber-muc-find-buffer "jabber-muc" (group))
-(declare-function jabber-muc-nickname "jabber-muc" (group &optional jc))
(declare-function jabber-reactions--reaction-only-p "jabber-reactions"
(xml-data))
(defgroup jabber-chatstates nil
diff --git a/lisp/jabber-db.el b/lisp/jabber-db.el
index 79b71436f7..696c0e6ec9 100644
--- a/lisp/jabber-db.el
+++ b/lisp/jabber-db.el
@@ -38,11 +38,11 @@
(require 'subr-x)
(require 'jabber-util)
(require 'jabber-xml)
+(require 'jabber-muc-state)
(eval-when-compile
(require 'cl-lib)
(require 'seq))
-(declare-function jabber-muc-joined-p "jabber-muc" (group &optional jc))
(declare-function jabber-muc-sender-p "jabber-muc" (jid))
(defvar jabber-chatting-with) ; jabber-chat.el
(defvar jabber-chat-send-hooks) ; jabber-chat.el
diff --git a/lisp/jabber-httpupload.el b/lisp/jabber-httpupload.el
index 63e996c3ea..b3f9b481d2 100644
--- a/lisp/jabber-httpupload.el
+++ b/lisp/jabber-httpupload.el
@@ -43,11 +43,11 @@
(require 'mailcap)
(require 'subr-x)
(require 'jabber)
+(require 'jabber-muc-state)
(declare-function jabber-chat-send "jabber-chat.el"
(jc body &optional extra-elements))
(declare-function jabber-chat-create-buffer "jabber-chat.el" (jc chat-with))
-(declare-function jabber-muc-joined-p "jabber-muc.el" (group &optional jc))
(defvar jabber-oob-xmlns) ; jabber-xml.el
(defconst jabber-httpupload-xmlns "urn:xmpp:http:upload:0"
diff --git a/lisp/jabber-mam.el b/lisp/jabber-mam.el
index 84f89a4815..10e2f68bd3 100644
--- a/lisp/jabber-mam.el
+++ b/lisp/jabber-mam.el
@@ -39,6 +39,7 @@
(require 'jabber-disco)
(require 'jabber-iq)
(require 'jabber-message-correct)
+(require 'jabber-muc-state)
(eval-when-compile (require 'cl-lib))
@@ -388,7 +389,6 @@ comparing with the account username to handle nick changes."
(string= nick my-nick))
(string= nick (plist-get (fsm-get-state-data jc) :username))))
-(declare-function jabber-muc-nickname "jabber-muc" (group &optional jc))
(defun jabber-mam--mark-dirty (peer type)
"Record that PEER's buffer needs redisplay after sync.
diff --git a/lisp/jabber-muc-nick-completion.el
b/lisp/jabber-muc-nick-completion.el
index cab0d0ebeb..ba51ff21af 100644
--- a/lisp/jabber-muc-nick-completion.el
+++ b/lisp/jabber-muc-nick-completion.el
@@ -34,6 +34,7 @@
(require 'cl-lib)
(require 'jabber-chatbuffer)
+(require 'jabber-muc-state)
;;; User customizations here:
(defcustom jabber-muc-completion-delimiter ": "
@@ -65,7 +66,6 @@ Note that \":\" or alike not needed (it appended in other
string)"
;; Global reference declarations
-(declare-function jabber-muc-nickname "jabber-muc.el" (group &optional jc))
(defvar jabber-group) ; jabber-muc.el
(defvar jabber-muc-default-nicknames) ; jabber-muc.el
(defvar jabber-muc-participants) ; jabber-muc.el
diff --git a/lisp/jabber-muc-state.el b/lisp/jabber-muc-state.el
new file mode 100644
index 0000000000..5de039f2b5
--- /dev/null
+++ b/lisp/jabber-muc-state.el
@@ -0,0 +1,86 @@
+;;; jabber-muc-state.el --- Multi-user chat state -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2026 Thanos Apollo
+
+;; Maintainer: Thanos Apollo <[email protected]>
+
+;; This file is a part of jabber.el.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+
+;;; Commentary:
+
+;; Track joined rooms independently from MUC protocol handling and buffers.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'subr-x)
+
+(defvar jabber-muc--rooms (make-hash-table :test #'equal)
+ "Map room JIDs to lists of connection and nickname pairs.")
+
+(defvar jabber-muc--generation 0
+ "Generation counter incremented after every room-state change.")
+
+(defun jabber-muc-nickname (group &optional jc)
+ "Return our nickname in GROUP, optionally restricted to JC."
+ (let ((entries (gethash group jabber-muc--rooms)))
+ (if jc
+ (alist-get jc entries)
+ (cdar entries))))
+
+(defun jabber-muc-connection (group)
+ "Return the first connection joined to GROUP, or nil."
+ (caar (gethash group jabber-muc--rooms)))
+
+(defun jabber-muc-joined-p (group &optional jc)
+ "Return non-nil when GROUP is joined, optionally through JC."
+ (let ((entries (gethash group jabber-muc--rooms)))
+ (if jc
+ (and (assq jc entries) t)
+ (and entries t))))
+
+(defun jabber-muc-our-nick-p (group nick)
+ "Return non-nil when NICK belongs to us in GROUP."
+ (cl-some (lambda (entry) (string= nick (cdr entry)))
+ (gethash group jabber-muc--rooms)))
+
+(defun jabber-muc-room-entries (group)
+ "Return connection and nickname pairs for GROUP."
+ (gethash group jabber-muc--rooms))
+
+(defun jabber-muc-active-rooms ()
+ "Return the JIDs of all joined rooms."
+ (hash-table-keys jabber-muc--rooms))
+
+(defun jabber-muc-join-set (group jc nickname)
+ "Record that JC joined GROUP as NICKNAME."
+ (let ((entries (gethash group jabber-muc--rooms)))
+ (if-let* ((existing (assq jc entries)))
+ (setcdr existing nickname)
+ (push (cons jc nickname) entries))
+ (puthash group entries jabber-muc--rooms))
+ (cl-incf jabber-muc--generation))
+
+(defun jabber-muc-leave-remove (group &optional jc)
+ "Remove GROUP state, or only the entry associated with JC."
+ (if jc
+ (let ((entries (assq-delete-all
+ jc (gethash group jabber-muc--rooms))))
+ (if entries
+ (puthash group entries jabber-muc--rooms)
+ (remhash group jabber-muc--rooms)))
+ (remhash group jabber-muc--rooms))
+ (cl-incf jabber-muc--generation))
+
+(defun jabber-muc-generation ()
+ "Return the room-state generation counter."
+ jabber-muc--generation)
+
+(provide 'jabber-muc-state)
+
+;;; jabber-muc-state.el ends here
diff --git a/lisp/jabber-muc.el b/lisp/jabber-muc.el
index bdc7417dc4..1186159784 100644
--- a/lisp/jabber-muc.el
+++ b/lisp/jabber-muc.el
@@ -33,6 +33,7 @@
(require 'ewoc)
(require 'jabber-widget)
(require 'jabber-disco)
+(require 'jabber-muc-state)
(require 'jabber-bookmarks)
(require 'jabber-chat)
(require 'jabber-db)
@@ -53,79 +54,6 @@
(defconst jabber-muc-xmlns-direct-invite "jabber:x:conference"
"XEP-0249 Direct MUC Invitations namespace.")
-(defvar jabber-muc--rooms (make-hash-table :test #'equal)
- "Internal hash table of active MUC rooms.
-Keys are group JID strings; values are lists of (JC . NICKNAME)
-cons cells, one per connection that has joined the room. This
-allows multiple accounts to be in the same room simultaneously.")
-
-(defvar jabber-muc--generation 0
- "Generation counter for `jabber-muc--rooms'.
-Incremented on every join/leave, enabling cheap change detection
-without copying the room list.")
-
-(defun jabber-muc-nickname (group &optional jc)
- "Return our nickname in GROUP, or nil.
-If JC is given, return the nickname for that specific connection.
-Otherwise return the nickname from the first entry."
- (let ((entries (gethash group jabber-muc--rooms)))
- (if jc
- (alist-get jc entries)
- (cdar entries))))
-
-(defun jabber-muc-connection (group)
- "Return a connection object for GROUP, or nil.
-When multiple accounts are in the same room, returns the first."
- (caar (gethash group jabber-muc--rooms)))
-
-(defun jabber-muc-joined-p (group &optional jc)
- "Return non-nil if we are in GROUP.
-If JC is given, check whether that specific connection is in GROUP."
- (let ((entries (gethash group jabber-muc--rooms)))
- (if jc
- (and (assq jc entries) t)
- (and entries t))))
-
-(defun jabber-muc-our-nick-p (group nick)
- "Return non-nil if NICK is our nickname in GROUP on any connection."
- (let ((entries (gethash group jabber-muc--rooms)))
- (cl-some (lambda (entry) (string= nick (cdr entry))) entries)))
-
-(defun jabber-muc-room-entries (group)
- "Return list of (JC . NICKNAME) entries for GROUP."
- (gethash group jabber-muc--rooms))
-
-(defun jabber-muc-active-rooms ()
- "Return list of joined room JIDs."
- (hash-table-keys jabber-muc--rooms))
-
-(defun jabber-muc-join-set (group jc nickname)
- "Record that we joined GROUP via JC with NICKNAME."
- (let ((entries (gethash group jabber-muc--rooms)))
- (if-let* ((existing (assq jc entries)))
- (setcdr existing nickname)
- (push (cons jc nickname) entries))
- (puthash group entries jabber-muc--rooms))
- (cl-incf jabber-muc--generation))
-
-(defun jabber-muc-leave-remove (group &optional jc)
- "Remove GROUP from active rooms.
-If JC is given, only remove that connection's entry; the room
-stays tracked if other connections remain in it."
- (if jc
- (let ((entries (gethash group jabber-muc--rooms)))
- (setq entries (assq-delete-all jc entries))
- (if entries
- (puthash group entries jabber-muc--rooms)
- (remhash group jabber-muc--rooms)))
- (remhash group jabber-muc--rooms))
- (cl-incf jabber-muc--generation))
-
-(defun jabber-muc-generation ()
- "Return current generation counter for change detection."
- jabber-muc--generation)
-
-
(defvar jabber-pending-groupchats (make-hash-table)
"Hash table of groupchats and nicknames.
Keys are JID symbols; values are strings.
diff --git a/lisp/jabber-omemo.el b/lisp/jabber-omemo.el
index 52f3c243ae..e743175adc 100644
--- a/lisp/jabber-omemo.el
+++ b/lisp/jabber-omemo.el
@@ -40,12 +40,12 @@
(require 'jabber-eme)
(require 'jabber-chat)
(require 'jabber-db)
+(require 'jabber-muc-state)
(declare-function jabber-muc-modify-participant "jabber-muc"
(group nickname new-plist))
(declare-function jabber-muc-participant-plist "jabber-muc"
(group nickname))
-(declare-function jabber-muc-joined-p "jabber-muc" (group &optional jc))
(declare-function jabber-muc-create-buffer "jabber-muc" (jc group))
(declare-function jabber-disco-advertise-feature "jabber-disco")
(declare-function jabber-send-iq "jabber-iq")
diff --git a/lisp/jabber-presence.el b/lisp/jabber-presence.el
index cd1f5f4236..981cf29550 100644
--- a/lisp/jabber-presence.el
+++ b/lisp/jabber-presence.el
@@ -31,6 +31,7 @@
(require 'jabber-iq)
(require 'jabber-alert)
(require 'jabber-util)
+(require 'jabber-muc-state)
(require 'ewoc)
(defconst jabber-presence-show-alist
@@ -64,10 +65,6 @@ stanza.")
(declare-function jabber-muc-get-buffer "jabber-muc.el" (group &optional jc))
(declare-function jabber-muc-process-presence "jabber-muc.el" (jc presence))
(declare-function jabber-muc-presence-p "jabber-muc.el" (presence))
-(declare-function jabber-muc-active-rooms "jabber-muc.el" ())
-(declare-function jabber-muc-connection "jabber-muc.el" (group))
-(declare-function jabber-muc-nickname "jabber-muc.el" (group &optional jc))
-(declare-function jabber-muc-room-entries "jabber-muc.el" (group))
(defvar jabber-chatting-with) ; jabber-chat.el
(defvar jabber-buffer-connection) ; jabber-chatbuffer.el
(defvar jabber-chat-ewoc) ; jabber-chatbuffer.el
@@ -634,4 +631,4 @@ JC is the Jabber connection."
(provide 'jabber-presence)
-;;; jabber-presence.el ends here
\ No newline at end of file
+;;; jabber-presence.el ends here
diff --git a/lisp/jabber-reactions.el b/lisp/jabber-reactions.el
index 846b936946..8f9a7b3e01 100644
--- a/lisp/jabber-reactions.el
+++ b/lisp/jabber-reactions.el
@@ -32,6 +32,7 @@
(require 'jabber-db)
(require 'jabber-disco)
(require 'jabber-util)
+(require 'jabber-muc-state)
(defconst jabber-reactions-xmlns "urn:xmpp:reactions:0"
"XEP-0444 Message Reactions namespace.")
@@ -71,7 +72,6 @@ are not filtered against it."
(declare-function jabber-chat-ewoc-invalidate "jabber-chatbuffer" (node))
(declare-function jabber-chat-find-buffer "jabber-chat" (chat-with))
(declare-function jabber-muc-find-buffer "jabber-muc" (group))
-(declare-function jabber-muc-nickname "jabber-muc" (group &optional jc))
;;; Pure helpers
diff --git a/lisp/jabber-roster.el b/lisp/jabber-roster.el
index 7455d4511d..e586e1feb2 100644
--- a/lisp/jabber-roster.el
+++ b/lisp/jabber-roster.el
@@ -34,6 +34,7 @@
(require 'jabber-private)
(require 'jabber-presence)
(require 'jabber-carbons)
+(require 'jabber-muc-state)
(require 'keymap-popup)
(defgroup jabber-roster nil "Roster options."
@@ -115,8 +116,6 @@ Trailing newlines are always removed, regardless of this
variable."
(declare-function jabber-get-conference-data "jabber-bookmarks.el"
(jc conference-jid cont &optional key))
(declare-function jabber-get-version "jabber-version.el" (jc to))
-(declare-function jabber-muc-active-rooms "jabber-muc.el" ())
-(declare-function jabber-muc-connection "jabber-muc.el" (group))
(declare-function jabber-muc-join "jabber-muc.el"
(jc group nickname &optional popup))
(declare-function jabber-muc-switch-to "jabber-muc.el" (group))
diff --git a/lisp/jabber-util.el b/lisp/jabber-util.el
index 78d6eb4929..08eae7fb4b 100644
--- a/lisp/jabber-util.el
+++ b/lisp/jabber-util.el
@@ -301,7 +301,6 @@ Candidates display sorted by availability, then name."
(t
(complete-with-action action table string pred))))))
-(declare-function jabber-muc-joined-p "jabber-muc.el" (group &optional jc))
(defun jabber-read-jid-completing (prompt &optional subset require-match
default resource fulljids)
"Read a JID out of the current roster from the minibuffer, with PROMPT.
If SUBSET is non-nil, it should be a list of symbols from which