emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/ement 176b6dd2a1 2/3: Add: (ement-room-notification-sta


From: ELPA Syncer
Subject: [elpa] externals/ement 176b6dd2a1 2/3: Add: (ement-room-notification-state)
Date: Thu, 6 Oct 2022 20:57:35 -0400 (EDT)

branch: externals/ement
commit 176b6dd2a1ea3796f984c8a21dba7842b645c887
Author: Adam Porter <adam@alphapapa.net>
Commit: Adam Porter <adam@alphapapa.net>

    Add: (ement-room-notification-state)
---
 README.org    |  1 +
 ement-lib.el  | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 ement-room.el | 25 ++++++++++++++++++++++++-
 3 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/README.org b/README.org
index 1bf9fc9285..1a82b03fbd 100644
--- a/README.org
+++ b/README.org
@@ -292,6 +292,7 @@ Note that, while ~matrix-client~ remains usable, and 
probably will for some time
 *Additions*
 + Option ~ement-room-unread-only-counts-notifications~, now enabled by 
default, causes rooms' unread status to be determined only by their 
notification counts (which are set by the server and depend on rooms' 
notification settings).
 + Command ~ement-room-set-notification-state~ sets a room's notification state 
(imitating Element's user-friendly presets).
++ Room buffers' Transient menus show the room's notification state (imitating 
Element's user-friendly presets).
 
 *Changes*
 + When a room's read receipt is updated, the room's buffer is also marked as 
unmodified.  (In concert with the new option, this makes rooms' unread status 
more intuitive.)
diff --git a/ement-lib.el b/ement-lib.el
index 0b0981bb41..cb0ac0df1b 100644
--- a/ement-lib.el
+++ b/ement-lib.el
@@ -427,6 +427,57 @@ If DELETE (interactively, with prefix), delete it."
 ;; slightly different.  This implementation will follow Element's initially, 
because the
 ;; spec is not simple, and imitating Element's requests will make it easier.
 
+(defun ement-room-notification-state (room session)
+  "Return notification state for ROOM on SESSION.
+Returns one of nil (meaning default rules are used), `all-loud',
+`all', `mentions-and-keywords', or `none'."
+  ;; Following the implementation of getRoomNotifsState() in RoomNotifs.ts in 
matrix-react-sdk.
+
+  ;; TODO: Guest support (in which case the state should be `all').
+  ;; TODO: Store account data as a hash table of event types.
+  (let ((push-rules (cl-find-if (lambda (alist)
+                                  (equal "m.push_rules" (alist-get 'type 
alist)))
+                                (ement-session-account-data session))))
+    (cl-labels ((override-mute-rule-for-room-p
+                 ;; Following findOverrideMuteRule() in RoomNotifs.ts.
+                 (room) (when-let ((overrides (map-nested-elt push-rules 
'(content global override))))
+                          (cl-loop for rule in overrides
+                                   when (and (alist-get 'enabled rule)
+                                             (rule-for-room-p rule room))
+                                   return rule)))
+                (rule-for-room-p
+                 ;; Following isRuleForRoom() in RoomNotifs.ts.
+                 (rule room) (and (/= 1 (length (alist-get 'conditions rule)))
+                                  (pcase-let* ((condition (elt (alist-get 
'conditions rule) 0))
+                                               ((map kind key pattern) 
condition))
+                                    (and (equal "event_match" kind)
+                                         (equal "room_id" key)
+                                         (equal (ement-room-id room) 
pattern)))))
+                (mute-rule-p
+                 (rule) (and (= 1 (length (alist-get 'actions rule)))
+                             (equal "dont_notify" (elt (alist-get 'actions 
rule) 0))))
+                (tweak-rule-p
+                 (type rule) (pcase-let (((map ('actions `[,action ,alist])) 
rule))
+                               (and (equal "notify" action)
+                                    (equal type (alist-get 'set_tweak 
alist))))))
+      ;; If none of these match, nil is returned, meaning that the default 
rule is used
+      ;; for the room.
+      (if (override-mute-rule-for-room-p room)
+          'none
+        (when-let ((room-rule (cl-find-if (lambda (rule)
+                                            (equal (ement-room-id room) 
(alist-get 'rule_id rule)))
+                                          (map-nested-elt push-rules '(content 
global room)))))
+          (cond ((not (alist-get 'enabled room-rule))
+                 ;; NOTE: According to comment in getRoomNotifsState(), this 
assumes that
+                 ;; the default is to notify for all messages, which "will be 
'wrong' for
+                 ;; one to one rooms because they will notify loudly for all 
messages."
+                 'all)
+                ((mute-rule-p room-rule)
+                 ;; According to comment, a room-level mute still allows 
mentions to
+                 ;; notify.
+                 'mentions-and-keywords)
+                ((tweak-rule-p "sound" room-rule) 'all-loud)))))))
+
 (defun ement-room-set-notification-state (state room session)
   "Set notification STATE for ROOM on SESSION.
 STATE may be nil to set the rules to default, `all',
diff --git a/ement-room.el b/ement-room.el
index 65fbfd2a35..c5f5b7936a 100644
--- a/ement-room.el
+++ b/ement-room.el
@@ -4149,7 +4149,30 @@ For use in `completion-at-point-functions'."
               ("r m" "List members" ement-list-members)
               ("r t" "Set topic" ement-room-set-topic)
               ("r f" "Set message format" ement-room-set-message-format)
-              ("r n" "Set notification state" 
ement-room-set-notification-state)
+              ("r n" "Set notification state" ement-room-set-notification-state
+               :description (lambda ()
+                              (let ((state (ement-room-notification-state 
ement-room ement-session)))
+                                (format "Notifications (%s/%s/%s/%s/%s)"
+                                        (propertize "default"
+                                                    'face (pcase state
+                                                            (`nil 
'transient-value)
+                                                            (_ 
'transient-inactive-value)))
+                                        (propertize "all-loud"
+                                                    'face (pcase state
+                                                            ('all-loud 
'transient-value)
+                                                            (_ 
'transient-inactive-value)))
+                                        (propertize "all"
+                                                    'face (pcase state
+                                                            ('all 
'transient-value)
+                                                            (_ 
'transient-inactive-value)))
+                                        (propertize "mentions-and-keywords"
+                                                    'face (pcase state
+                                                            
('mentions-and-keywords 'transient-value)
+                                                            (_ 
'transient-inactive-value)))
+                                        (propertize "none"
+                                                    'face (pcase state
+                                                            ('none 
'transient-value)
+                                                            (_ 
'transient-inactive-value)))))))
               ("r T" "Tag/untag room" ement-tag-room
                :description (lambda ()
                               (format "Tag/untag room (%s/%s)"



reply via email to

[Prev in Thread] Current Thread [Next in Thread]