diff options
Diffstat (limited to 'lisp/mastodon-notifications.el')
-rw-r--r-- | lisp/mastodon-notifications.el | 226 |
1 files changed, 133 insertions, 93 deletions
diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index f4615fb..23bd1fa 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -64,32 +64,17 @@ (autoload 'mastodon-tl--symbol "mastodon-tl") (autoload 'mastodon-tl--display-or-uname "mastodon-tl") -(defgroup mastodon-tl nil - "Nofications in mastodon.el." - :prefix "mastodon-notifications-" - :group 'mastodon) - -(defcustom mastodon-notifications--profile-note-in-foll-reqs t - "If non-nil, show a user's profile note in follow request notifications." - :type '(boolean)) - -(defcustom mastodon-notifications--profile-note-in-foll-reqs-max-length nil - "The max character length for user profile note in follow requests. -Profile notes are only displayed if -`mastodon-notifications--profile-note-in-foll-reqs' is non-nil. -If unset, profile notes of any size will be displayed, which may -make them unweildy." - :type '(integer)) - -(defcustom mastodon-notifications--images-in-notifs nil - "Whether to display attached images in notifications." - :type '(boolean)) +;; notifications defcustoms moved into mastodon.el +;; as some need to be available without loading this file (defvar mastodon-tl--buffer-spec) (defvar mastodon-tl--display-media-p) (defvar mastodon-mode-map) (defvar mastodon-tl--fold-toots-at-length) (defvar mastodon-tl--show-avatars) +(defvar mastodon-profile-note-in-foll-reqs) +(defvar mastodon-profile-note-in-foll-reqs-max-length) +(defvar mastodon-group-notifications) (defvar mastodon-notifications--types '("favourite" "reblog" "mention" "poll" @@ -231,21 +216,66 @@ JSON is a list of alists." "\nfor account: " .target_account))) -(defun mastodon-notifications--format-note (group status accounts) +(defun mastodon-notifications--format-note (note) + "Format for a NOTE, a non-grouped notification." + (let* ((type (intern (alist-get 'type note))) + (profile-note + (when (eq 'follow_request type) + (let ((str (mastodon-tl--field + 'note + (mastodon-tl--field 'account note)))) + (if mastodon-profile-note-in-foll-reqs-max-length + (string-limit str mastodon-profile-note-in-foll-reqs-max-length) + str)))) + (status (mastodon-tl--field 'status note)) + (follower (alist-get 'account note)) + (follower-name (alist-get 'username follower)) + (filtered (mastodon-tl--field 'filtered status)) + (filters (when filtered + (mastodon-tl--current-filters filtered)))) + (if (and filtered (assoc "hide" filters)) + nil + (mastodon-notifications--insert-note + ;; toot + (if (member type '(follow follow_request)) + note ;; full notif, not just follower acct? + status) + ;; body + (mastodon-notifiations--body-arg + type filters status profile-note follower-name) + ;; action-byline + (unless (member type '(follow follow_request mention)) + (downcase + (mastodon-notifications--byline-concat + (alist-get type mastodon-notifications--action-alist)))) + ;; action authors + (cond ((member type '(follow follow_request mention)) + "") ;; mentions are normal statuses + (t (mastodon-tl--byline-username note))) + ;; action symbol: + (unless (eq type 'mention) + (mastodon-tl--symbol type)) + ;; base toot + (when (or (eq type 'favourite) + (eq type 'boost)) + status) + nil nil nil type)))) + +(defun mastodon-notifications--format-group-note (group status accounts) "Format for a GROUP notification. STATUS is the status's JSON. ACCOUNTS is data of the accounts that have reacted to the notification." (let ((folded nil)) ;; FIXME: apply/refactor filtering as per/with `mastodon-tl--toot' (let-alist group - (let* ((type-sym (intern .type)) + (let* ((type (intern .type)) (profile-note - (when (member type-sym '(follow_request)) + (when (member type '(follow_request)) (let ((str (mastodon-tl--field 'note (car accounts)))) - (if mastodon-notifications--profile-note-in-foll-reqs-max-length - (string-limit str mastodon-notifications--profile-note-in-foll-reqs-max-length) + (if mastodon-profile-note-in-foll-reqs-max-length + (string-limit str mastodon-profile-note-in-foll-reqs-max-length) str)))) - (follower (when (member type-sym '(follow follow_request)) + (follower (when (member type '(follow follow_request)) (car accounts))) (follower-name (mastodon-tl--field 'username follower)) (filtered (mastodon-tl--field 'filtered status)) @@ -254,62 +284,68 @@ ACCOUNTS is data of the accounts that have reacted to the notification." (unless (and filtered (assoc "hide" filters)) (mastodon-notifications--insert-note ;; toot - (if (member type-sym '(follow follow_request)) + (if (member type '(follow follow_request)) follower status) ;; body - (let ((body (if-let ((match (assoc "warn" filters))) - (mastodon-tl--spoiler status (cadr match)) - (mastodon-tl--clean-tabs-and-nl - (cond ((mastodon-tl--has-spoiler status) - (mastodon-tl--spoiler status)) - ((eq type-sym 'follow_request) - (mastodon-tl--render-text profile-note)) - (t (mastodon-tl--content status))))))) - (cond - ((eq type-sym 'follow) - (propertize "Congratulations, you have a new follower!" - 'face 'default)) - ((eq type-sym 'follow_request) - (concat - (propertize (format "You have a follow request from %s" - follower-name) - 'face 'default) - (when mastodon-notifications--profile-note-in-foll-reqs - (concat - ":\n" - (mastodon-notifications--comment-note-text body))))) - ((eq type-sym 'severed_relationships) - (mastodon-notifications--severance-body group)) - ((eq type-sym 'moderation_warning) - (mastodon-notifications--mod-warning-body group)) - ((member type-sym '(favourite reblog)) - (propertize - (mastodon-notifications--comment-note-text body))) - (t body))) - ;; author-byline - #'mastodon-tl--byline-author + (mastodon-notifiations--body-arg + type filters status profile-note follower-name group) ;; action-byline - (unless (member type-sym '(follow follow_request mention)) + (unless (member type '(follow follow_request mention)) (downcase (mastodon-notifications--byline-concat - (alist-get type-sym mastodon-notifications--action-alist)))) + (alist-get type mastodon-notifications--action-alist)))) ;; action authors - (cond ((member type-sym '(follow follow_request mention)) + (cond ((member type '(follow follow_request mention)) "") ;; mentions are normal statuses (t (mastodon-notifications--byline-accounts accounts status group))) ;; action symbol: - (unless (eq type-sym 'mention) - (mastodon-tl--symbol type-sym)) + (unless (eq type 'mention) + (mastodon-tl--symbol type)) ;; base toot (no need for update/poll/?) - (when (member type-sym '(favourite reblog)) + (when (member type '(favourite reblog)) status) folded group accounts)))))) +(defun mastodon-notifiations--body-arg + (type &optional filters status profile-note follower-name group) + "TYPE is a symbol, a member of `mastodon-notifiations--types'. +FILTERS STATUS PROFILE-NOTE FOLLOWER-NAME GROUP." + (let ((body + (if-let ((match (assoc "warn" filters))) + (mastodon-tl--spoiler status (cadr match)) + (mastodon-tl--clean-tabs-and-nl + (cond ((mastodon-tl--has-spoiler status) + (mastodon-tl--spoiler status)) + ((eq type 'follow_request) + (mastodon-tl--render-text profile-note)) + (t (mastodon-tl--content status))))))) + (cond + ((eq type 'follow) + (propertize "Congratulations, you have a new follower!" + 'face 'default)) + ((eq type 'follow_request) + (concat + (propertize (format "You have a follow request from %s" + follower-name) + 'face 'default) + (when mastodon-profile-note-in-foll-reqs + (concat + ":\n" + (mastodon-notifications--comment-note-text body))))) + ((eq type 'severed_relationships) + (mastodon-notifications--severance-body group)) + ((eq type 'moderation_warning) + (mastodon-notifications--mod-warning-body group)) + ((member type '(favourite reblog)) + (propertize + (mastodon-notifications--comment-note-text body))) + (t body)))) + (defun mastodon-notifications--insert-note - (toot body author-byline action-byline action-authors action-symbol - &optional base-toot unfolded group accounts) + (toot body action-byline action-authors action-symbol + &optional base-toot unfolded group accounts type) "Display the content and byline of timeline element TOOT. BODY will form the section of the toot above the byline. AUTHOR-BYLINE is an optional function for adding the author @@ -328,8 +364,11 @@ JSON of the toot responded to. UNFOLDED is a boolean meaning whether to unfold or fold item if foldable. GROUP is the notification group data. -ACCOUNTS is the notification accounts data." - (let* ((type (alist-get 'type (or group toot))) +ACCOUNTS is the notification accounts data. +TYPE is notification type, used for non-group notifs." + (let* ((type (if type + (symbol-name type) ;; non-group + (alist-get 'type group))) (toot-foldable (and mastodon-tl--fold-toots-at-length (length> body mastodon-tl--fold-toots-at-length)))) @@ -342,15 +381,12 @@ ACCOUNTS is the notification accounts data." (concat action-symbol " " action-authors action-byline)) 'byline-top t) - (propertize ;; body only - body - 'toot-body t) ;; includes newlines etc. for folding + (propertize body ;; body only + 'toot-body t) ;; includes newlines etc. for folding "\n" ;; actual byline: (mastodon-tl--byline - toot author-byline nil nil base-toot group - (when (member type '("follow" "follow_request")) - toot) ;; account data! + toot nil nil base-toot group ;; types listed here use base item timestamp, else we use group's ;; latest timestamp: (when (not (member type '("favourite" "reblog" "edit" "poll"))) @@ -406,7 +442,7 @@ When DOMAIN, force inclusion of user's domain in their handle." (mastodon-tl--image-trans-check)) (mastodon-media--get-avatar-rendering .avatar)) (let ((uname (mastodon-tl--display-or-uname account))) - (mastodon-tl--byline-handle toot nil account + (mastodon-tl--byline-handle toot nil uname 'mastodon-display-name-face)) ", "))) nil ", ") @@ -420,30 +456,34 @@ When DOMAIN, force inclusion of user's domain in their handle." (cddr accounts) ;; not first two ", "))))))) -(defun mastodon-notifications--render (json) - "Display grouped notifications in JSON." +(defun mastodon-notifications--render (json no-group) + "Display grouped notifications in JSON. +NO-GROUP means don't render grouped notifications." ;; (setq masto-grouped-notifs json) - (let ((groups (alist-get 'notification_groups json))) - (cl-loop - for g in groups - for start-pos = (point) - for accounts = (mastodon-notifications--group-accounts - (alist-get 'sample_account_ids g) - (alist-get 'accounts json)) - for status = (mastodon-notifications--alist-by-value - (alist-get 'status_id g) 'id - (alist-get 'statuses json)) - do (mastodon-notifications--format-note g status accounts) - (when mastodon-tl--display-media-p - ;; images-in-notifs custom is handeld in - ;; `mastodon-tl--media-attachment', not here - (mastodon-media--inline-images start-pos (point)))))) + (if no-group + (cl-loop for x in json + do (mastodon-notifications--format-note x)) + (let ((groups (alist-get 'notification_groups json))) + (cl-loop + for g in groups + for start-pos = (point) + for accounts = (mastodon-notifications--group-accounts + (alist-get 'sample_account_ids g) + (alist-get 'accounts json)) + for status = (mastodon-notifications--alist-by-value + (alist-get 'status_id g) 'id + (alist-get 'statuses json)) + do (mastodon-notifications--format-group-note g status accounts) + (when mastodon-tl--display-media-p + ;; images-in-notifs custom is handeld in + ;; `mastodon-tl--media-attachment', not here + (mastodon-media--inline-images start-pos (point))))))) (defun mastodon-notifications--timeline (json) "Format JSON in Emacs buffer." (if (seq-empty-p json) (user-error "Looks like you have no (more) notifications for now") - (mastodon-notifications--render json) + (mastodon-notifications--render json (not mastodon-group-notifications)) (goto-char (point-min)))) (defun mastodon-notifications--get-mentions () |