From 0e75fc74eebd142601d725cb814d7fe18b87c25e Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Tue, 29 Oct 2024 12:02:23 +0100 Subject: group-notifs custom (for servers without). #608. WIP. --- lisp/mastodon-notifications.el | 137 +++++++++++++++++++++++++++++++++++------ lisp/mastodon.el | 5 +- 2 files changed, 123 insertions(+), 19 deletions(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index f4615fb..4bf797d 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -85,6 +85,10 @@ make them unweildy." "Whether to display attached images in notifications." :type '(boolean)) +(defcustom mastodon-notifications--group-notifications t + "Whether to use grouped notifications." + :type '(boolean)) + (defvar mastodon-tl--buffer-spec) (defvar mastodon-tl--display-media-p) (defvar mastodon-mode-map) @@ -231,7 +235,101 @@ 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 of TYPE." + ;; FIXME: apply/refactor filtering as per/with `mastodon-tl--toot' + (let* ((id (alist-get 'id note)) + (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-notifications--profile-note-in-foll-reqs-max-length + (string-limit str mastodon-notifications--profile-note-in-foll-reqs-max-length) + str)))) + (status (mastodon-tl--field 'status note)) + (follower (alist-get 'username (alist-get 'account note))) + (toot (alist-get 'status note)) + (filtered (mastodon-tl--field 'filtered toot)) + (filters (when filtered + (mastodon-tl--current-filters filtered)))) + (if (and filtered (assoc "hide" filters)) + nil + (mastodon-tl--insert-status + ;; toot + (cond ((or (eq type 'follow) + (eq type 'follow-request)) + ;; Using reblog with an empty id will mark this as something + ;; non-boostable/non-favable. + (cons '(reblog (id . nil)) note)) + ;; reblogs/faves use 'note' to process their own json + ;; not the toot's. this ensures following etc. work on such notifs + ((or (eq type 'favourite) + (eq type 'boost)) + note) + (t + status)) + ;; body + (let ((body (if-let ((match (assoc "warn" filters))) + (mastodon-tl--spoiler toot (cadr match)) + (mastodon-tl--clean-tabs-and-nl + (if (mastodon-tl--has-spoiler status) + (mastodon-tl--spoiler status) + (if (eq 'follow-request type) + (mastodon-tl--render-text profile-note) + (mastodon-tl--content status))))))) + (cond ((or (eq type 'follow) + (eq type 'follow-request)) + (if (eq type 'follow) + (propertize "Congratulations, you have a new follower!" + 'face 'default) + (concat + (propertize + (format "You have a follow request from... %s" + follower) + 'face 'default) + (when mastodon-notifications--profile-note-in-foll-reqs + (concat + ":\n" + (mastodon-notifications--comment-note-text body)))))) + ((or (eq type 'favourite) + (eq type 'boost)) + (mastodon-notifications--comment-note-text body)) + (t body))) + ;; author-byline + (if (or (eq type 'follow) + (eq type 'follow-request) + (eq type 'mention)) + 'mastodon-tl--byline-author + (lambda (_status &rest _args) ; unbreak stuff + (mastodon-tl--byline-author note))) + ;; action-byline + (lambda (_status) + (mastodon-notifications--byline-concat + (cond ((eq type 'reblog) + "Boosted") + ((eq type 'favourite) + "Favourited") + ((eq type 'follow_request) + "Requested to follow") + ((eq type 'follow) + "Followed") + ((eq type 'mention) + "Mentioned") + ((eq type 'status) + "Posted") + ((eq type 'poll) + "Posted a poll") + ((eq type 'update) + "Edited")))) + id + ;; base toot + (when (or (eq type 'favourite) + (eq type 'boost)) + status))))) + +(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." @@ -420,30 +518,33 @@ When DOMAIN, force inclusion of user's domain in their handle." (cddr accounts) ;; not first two ", "))))))) -(defun mastodon-notifications--render (json) +(defun mastodon-notifications--render (json no-group) "Display grouped notifications in JSON." ;; (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-notifications--group-notifications)) (goto-char (point-min)))) (defun mastodon-notifications--get-mentions () diff --git a/lisp/mastodon.el b/lisp/mastodon.el index deee0c1..86810b7 100644 --- a/lisp/mastodon.el +++ b/lisp/mastodon.el @@ -372,7 +372,10 @@ MAX-ID is a request parameter for pagination." type (when max-id `(("max_id" . ,(mastodon-tl--buffer-property 'max-id)))) - nil nil nil "v2") + nil nil nil + (if (not mastodon-notifications--group-notifications) + "v1" + "v2")) (with-current-buffer (get-buffer-create buffer) (use-local-map mastodon-notifications--map)))) -- cgit v1.2.3 From 8446f239bb5cfe55511e43b8b3d938d67d6e1aa3 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Tue, 29 Oct 2024 16:59:03 +0100 Subject: working v1 notifications custom. #608 --- lisp/mastodon-notifications.el | 134 ++++++++++++++++++----------------------- lisp/mastodon-tl.el | 5 +- 2 files changed, 62 insertions(+), 77 deletions(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index 4bf797d..34aeb9d 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -236,12 +236,11 @@ JSON is a list of alists." .target_account))) (defun mastodon-notifications--format-note (note) - "Format for a NOTE of TYPE." - ;; FIXME: apply/refactor filtering as per/with `mastodon-tl--toot' + "Format for a NOTE, a non-grouped notification." (let* ((id (alist-get 'id note)) (type (intern (alist-get 'type note))) (profile-note - (when (eq 'follow-request type) + (when (eq 'follow_request type) (let ((str (mastodon-tl--field 'note (mastodon-tl--field 'account note)))) @@ -249,85 +248,69 @@ JSON is a list of alists." (string-limit str mastodon-notifications--profile-note-in-foll-reqs-max-length) str)))) (status (mastodon-tl--field 'status note)) - (follower (alist-get 'username (alist-get 'account note))) - (toot (alist-get 'status note)) - (filtered (mastodon-tl--field 'filtered toot)) + (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-tl--insert-status + (mastodon-notifications--insert-note ;; toot - (cond ((or (eq type 'follow) - (eq type 'follow-request)) - ;; Using reblog with an empty id will mark this as something - ;; non-boostable/non-favable. - (cons '(reblog (id . nil)) note)) - ;; reblogs/faves use 'note' to process their own json - ;; not the toot's. this ensures following etc. work on such notifs - ((or (eq type 'favourite) - (eq type 'boost)) - note) - (t - status)) + (if (member type '(follow follow_request)) + follower + status) ;; body - (let ((body (if-let ((match (assoc "warn" filters))) - (mastodon-tl--spoiler toot (cadr match)) - (mastodon-tl--clean-tabs-and-nl - (if (mastodon-tl--has-spoiler status) - (mastodon-tl--spoiler status) - (if (eq 'follow-request type) - (mastodon-tl--render-text profile-note) - (mastodon-tl--content status))))))) - (cond ((or (eq type 'follow) - (eq type 'follow-request)) - (if (eq type 'follow) - (propertize "Congratulations, you have a new follower!" - 'face 'default) - (concat - (propertize - (format "You have a follow request from... %s" - follower) - 'face 'default) - (when mastodon-notifications--profile-note-in-foll-reqs - (concat - ":\n" - (mastodon-notifications--comment-note-text body)))))) - ((or (eq type 'favourite) - (eq type 'boost)) - (mastodon-notifications--comment-note-text body)) - (t 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 '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-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 '(favourite reblog)) + (propertize + (mastodon-notifications--comment-note-text body))) + (t body))) ;; author-byline - (if (or (eq type 'follow) - (eq type 'follow-request) - (eq type 'mention)) - 'mastodon-tl--byline-author - (lambda (_status &rest _args) ; unbreak stuff - (mastodon-tl--byline-author note))) + #'mastodon-tl--byline-author ;; action-byline - (lambda (_status) - (mastodon-notifications--byline-concat - (cond ((eq type 'reblog) - "Boosted") - ((eq type 'favourite) - "Favourited") - ((eq type 'follow_request) - "Requested to follow") - ((eq type 'follow) - "Followed") - ((eq type 'mention) - "Mentioned") - ((eq type 'status) - "Posted") - ((eq type 'poll) - "Posted a poll") - ((eq type 'update) - "Edited")))) - id + (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 (alist-get 'account note)))) + ;; action symbol: + (unless (eq type 'mention) + (mastodon-tl--symbol type)) ;; base toot (when (or (eq type 'favourite) (eq type 'boost)) - status))))) + status) + nil nil nil type)))) (defun mastodon-notifications--format-group-note (group status accounts) "Format for a GROUP notification. @@ -407,7 +390,7 @@ ACCOUNTS is data of the accounts that have reacted to the notification." (defun mastodon-notifications--insert-note (toot body author-byline action-byline action-authors action-symbol - &optional base-toot unfolded group accounts) + &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 @@ -427,7 +410,9 @@ 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))) + (let* ((type (if type + (symbol-name type) + (alist-get 'type group))) (toot-foldable (and mastodon-tl--fold-toots-at-length (length> body mastodon-tl--fold-toots-at-length)))) @@ -452,7 +437,8 @@ ACCOUNTS is the notification accounts data." ;; types listed here use base item timestamp, else we use group's ;; latest timestamp: (when (not (member type '("favourite" "reblog" "edit" "poll"))) - (mastodon-tl--field 'latest_page_notification_at group)))) + (mastodon-tl--field 'latest_page_notification_at group)) + type)) 'item-type 'toot ;; for nav, actions, etc. 'item-id (or (alist-get 'page_max_id group) ;; newest notif (alist-get 'id toot)) ; toot id diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 5eb52e3..ab6951e 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -797,7 +797,7 @@ LETTER is a string, F for favourited, B for boosted, or K for bookmarked." (image-transforms-p))) (defun mastodon-tl--byline (toot author-byline &optional detailed-p - domain base-toot group account ts) + domain base-toot group account ts type) "Generate byline for TOOT. AUTHOR-BYLINE is a function for adding the author portion of the byline that takes one variable. @@ -811,7 +811,7 @@ BASE-TOOT is JSON for the base toot, if any. GROUP is the notification group if any. ACCOUNT is the notification account if any. TS is a timestamp from the server, if any." - (let* ((type (alist-get 'type group)) + (let* ((type (or type (alist-get 'type (or group toot)))) (created-time (or ts ;; mentions, statuses, folls/foll-reqs ;; bosts, faves, edits, polls in notifs view use base item @@ -826,7 +826,6 @@ TS is a timestamp from the server, if any." (boosted (eq t (mastodon-tl--field 'reblogged toot))) (bookmarked (eq t (mastodon-tl--field 'bookmarked toot))) (visibility (mastodon-tl--field 'visibility toot)) - (type (alist-get 'type (or group toot))) (base-toot-maybe (or base-toot ;; show edits for notifs (mastodon-tl--toot-or-base toot))) ;; for boosts (account (or account -- cgit v1.2.3 From f3602493dadeac6b19558c3655fbd5fbb1125107 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Tue, 29 Oct 2024 17:09:50 +0100 Subject: fix notifs custom group --- lisp/mastodon-notifications.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index 34aeb9d..fde57f5 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -64,7 +64,7 @@ (autoload 'mastodon-tl--symbol "mastodon-tl") (autoload 'mastodon-tl--display-or-uname "mastodon-tl") -(defgroup mastodon-tl nil +(defgroup mastodon-notifications nil "Nofications in mastodon.el." :prefix "mastodon-notifications-" :group 'mastodon) -- cgit v1.2.3 From 639745a8850dd01713437c2327610bdef9bd525c Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Tue, 29 Oct 2024 17:16:21 +0100 Subject: move notifs customizes into mastodon.el --- lisp/mastodon-notifications.el | 40 +++++++++------------------------------- lisp/mastodon-tl.el | 4 ++-- lisp/mastodon.el | 26 +++++++++++++++++++++++++- mastodon-index.org | 6 +++--- 4 files changed, 39 insertions(+), 37 deletions(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index fde57f5..f0657fb 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -64,30 +64,8 @@ (autoload 'mastodon-tl--symbol "mastodon-tl") (autoload 'mastodon-tl--display-or-uname "mastodon-tl") -(defgroup mastodon-notifications 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)) - -(defcustom mastodon-notifications--group-notifications t - "Whether to use grouped 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) @@ -244,8 +222,8 @@ JSON is a list of alists." (let ((str (mastodon-tl--field 'note (mastodon-tl--field 'account note)))) - (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)))) (status (mastodon-tl--field 'status note)) (follower (alist-get 'account note)) @@ -279,7 +257,7 @@ JSON is a list of alists." (propertize (format "You have a follow request from %s" follower-name) 'face 'default) - (when mastodon-notifications--profile-note-in-foll-reqs + (when mastodon-profile-note-in-foll-reqs (concat ":\n" (mastodon-notifications--comment-note-text body))))) @@ -323,8 +301,8 @@ ACCOUNTS is data of the accounts that have reacted to the notification." (profile-note (when (member type-sym '(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)) (car accounts))) @@ -356,7 +334,7 @@ ACCOUNTS is data of the accounts that have reacted to the notification." (propertize (format "You have a follow request from %s" follower-name) 'face 'default) - (when mastodon-notifications--profile-note-in-foll-reqs + (when mastodon-profile-note-in-foll-reqs (concat ":\n" (mastodon-notifications--comment-note-text body))))) @@ -530,7 +508,7 @@ When DOMAIN, force inclusion of user's domain in their handle." "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 (not mastodon-notifications--group-notifications)) + (mastodon-notifications--render json (not mastodon-group-notifications)) (goto-char (point-min)))) (defun mastodon-notifications--get-mentions () diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index ab6951e..4f77f92 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -97,7 +97,7 @@ (defvar mastodon-toot--visibility) (defvar mastodon-toot-mode) (defvar mastodon-active-user) -(defvar mastodon-notifications--images-in-notifs) +(defvar mastodon-images-in-notifs) (when (require 'mpv nil :no-error) (declare-function mpv-start "mpv")) @@ -1326,7 +1326,7 @@ SENSITIVE is a flag from the item's JSON data." ;; if in notifs, also check notifs images custom: (if (or (mastodon-tl--buffer-type-eq 'notifications) (mastodon-tl--buffer-type-eq 'mentions)) - mastodon-notifications--images-in-notifs + mastodon-images-in-notifs t)) (mastodon-media--get-media-link-rendering ; placeholder: "[img]" .preview_url remote-url ; for shr-browse-url diff --git a/lisp/mastodon.el b/lisp/mastodon.el index 86810b7..211a9bc 100644 --- a/lisp/mastodon.el +++ b/lisp/mastodon.el @@ -153,6 +153,30 @@ currently, it doesn't seem to have a way to handle custom emoji, while emojify,el has this feature and mastodon.el implements it." :type 'boolean) +;; notifications customizes +;; moved here because we can load notifs without first loading mastodon.el +;; or mastodon-notifications.el + +(defcustom mastodon-profile-note-in-foll-reqs t + "If non-nil, show a user's profile note in follow request notifications." + :type '(boolean)) + +(defcustom mastodon-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-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-images-in-notifs nil + "Whether to display attached images in notifications." + :type '(boolean)) + +(defcustom mastodon-group-notifications t + "Whether to use grouped notifications." + :type '(boolean)) + (defun mastodon-kill-window () "Quit window and delete helper." (interactive) @@ -373,7 +397,7 @@ MAX-ID is a request parameter for pagination." (when max-id `(("max_id" . ,(mastodon-tl--buffer-property 'max-id)))) nil nil nil - (if (not mastodon-notifications--group-notifications) + (if (not mastodon-group-notifications) "v1" "v2")) (with-current-buffer (get-buffer-create buffer) diff --git a/mastodon-index.org b/mastodon-index.org index b3d6af7..858c322 100644 --- a/mastodon-index.org +++ b/mastodon-index.org @@ -269,9 +269,9 @@ | mastodon-media--hide-sensitive-media | Whether media marked as sensitive should be hidden. | | mastodon-media--preview-max-height | Max height of any media attachment preview to be shown in timelines. | | mastodon-mode-hook | Hook run when entering Mastodon mode. | -| mastodon-notifications--images-in-notifs | Whether to display attached images in notifications. | -| mastodon-notifications--profile-note-in-foll-reqs | If non-nil, show a user's profile note in follow request notifications. | -| mastodon-notifications--profile-note-in-foll-reqs-max-length | The max character length for user profile note in follow requests. | +| mastodon-images-in-notifs | Whether to display attached images in notifications. | +| mastodon-profile-note-in-foll-reqs | If non-nil, show a user's profile note in follow request notifications. | +| mastodon-profile-note-in-foll-reqs-max-length | The max character length for user profile note in follow requests. | | mastodon-profile-mode-hook | Hook run after entering or leaving `mastodon-profile-mode'. | | mastodon-profile-update-mode-hook | Hook run after entering or leaving `mastodon-profile-update-mode'. | | mastodon-search-mode-hook | Hook run after entering or leaving `mastodon-search-mode'. | -- cgit v1.2.3 From 4505b4e8187a827a7908ecf75fa11866d82edfc7 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Tue, 29 Oct 2024 17:18:38 +0100 Subject: index --- mastodon-index.org | 96 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/mastodon-index.org b/mastodon-index.org index 858c322..7e5d2a7 100644 --- a/mastodon-index.org +++ b/mastodon-index.org @@ -200,6 +200,7 @@ | a | mastodon-toot--translate-toot-text | Translate text of toot at point. | | E | mastodon-toot--view-toot-edits | View editing history of the toot at point in a popup buffer. | | | mastodon-toot-mode | Minor mode for composing toots. | +| | mastodon-transient--choice-add | Add another poll choice if possible. | | | mastodon-update-profile-note | Update current user profile note. | | | mastodon-url-lookup | If a URL resembles a fediverse link, try to load in `mastodon.el'. | | | mastodon-url-lookup-force | Call `mastodon-url-lookup' without checking if URL is fedi-like. | @@ -259,50 +260,51 @@ #+end_src #+RESULTS: -| Custom variable | Description | -|--------------------------------------------------------------+-------------------------------------------------------------------------------| -| mastodon-active-user | Username of the active user. | -| mastodon-client--token-file | File path where Mastodon access tokens are stored. | -| mastodon-instance-url | Base URL for the fediverse instance you want to be active. | -| mastodon-media--avatar-height | Height of the user avatar images (if shown). | -| mastodon-media--enable-image-caching | Whether images should be cached. | -| mastodon-media--hide-sensitive-media | Whether media marked as sensitive should be hidden. | -| mastodon-media--preview-max-height | Max height of any media attachment preview to be shown in timelines. | -| mastodon-mode-hook | Hook run when entering Mastodon mode. | -| mastodon-images-in-notifs | Whether to display attached images in notifications. | -| mastodon-profile-note-in-foll-reqs | If non-nil, show a user's profile note in follow request notifications. | -| mastodon-profile-note-in-foll-reqs-max-length | The max character length for user profile note in follow requests. | -| mastodon-profile-mode-hook | Hook run after entering or leaving `mastodon-profile-mode'. | -| mastodon-profile-update-mode-hook | Hook run after entering or leaving `mastodon-profile-update-mode'. | -| mastodon-search-mode-hook | Hook run after entering or leaving `mastodon-search-mode'. | -| mastodon-tl--display-caption-not-url-when-no-media | Display an image's caption rather than URL. | -| mastodon-tl--display-media-p | A boolean value stating whether to show media in timelines. | -| mastodon-tl--enable-proportional-fonts | Nonnil to enable using proportional fonts when rendering HTML. | -| mastodon-tl--enable-relative-timestamps | Whether to show relative (to the current time) timestamps. | -| mastodon-tl--expand-content-warnings | Whether to expand content warnings by default. | -| mastodon-tl--fold-toots-at-length | Length, in characters, to fold a toot at. | -| mastodon-tl--hide-replies | Whether to hide replies from the timelines. | -| mastodon-tl--highlight-current-toot | Whether to highlight the toot at point. Uses `cursor-face' special property. | -| mastodon-tl--load-full-sized-images-in-emacs | Whether to load full-sized images inside Emacs. | -| mastodon-tl--no-fill-on-render | Non-nil to disable filling by shr.el while rendering toot body. | -| mastodon-tl--remote-local-domains | A list of domains to view the local timelines of. | -| mastodon-tl--show-avatars | Whether to enable display of user avatars in timelines. | -| mastodon-tl--show-stats | Whether to show toot stats (faves, boosts, replies counts). | -| mastodon-tl--symbols | A set of symbols (and fallback strings) to be used in timeline. | -| mastodon-tl--tag-timeline-tags | A list of up to four tags for use with `mastodon-tl--followed-tags-timeline'. | -| mastodon-tl--timeline-posts-count | Number of posts to display when loading a timeline. | -| mastodon-tl-position-after-update | Defines where `point' should be located after a timeline update. | -| mastodon-toot--attachment-height | Height of the attached images preview in the toot draft buffer. | -| mastodon-toot--completion-style-for-mentions | The company completion style to use for mentions. | -| mastodon-toot--default-media-directory | The default directory when prompting for a media file to upload. | -| mastodon-toot--default-reply-visibility | Default visibility settings when replying. | -| mastodon-toot--enable-completion | Whether to enable completion of mentions and hashtags. | -| mastodon-toot--enable-custom-instance-emoji | Whether to enable your instance's custom emoji by default. | -| mastodon-toot--proportional-fonts-compose | Nonnil to enable using proportional fonts in the compose buffer. | -| mastodon-toot--use-company-for-completion | Whether to enable company for completion. | -| mastodon-toot-display-orig-in-reply-buffer | Display a copy of the toot replied to in the compose buffer. | -| mastodon-toot-mode-hook | Hook run after entering or leaving `mastodon-toot-mode'. | -| mastodon-toot-orig-in-reply-length | Length to crop toot replied to in the compose buffer to. | -| mastodon-toot-poll-use-transient | Whether to use the transient menu to create a poll. | -| mastodon-toot-timestamp-format | Format to use for timestamps. | -| mastodon-use-emojify | Whether to use emojify.el to display emojis. | +| Custom variable | Description | +|----------------------------------------------------+-------------------------------------------------------------------------------| +| mastodon-active-user | Username of the active user. | +| mastodon-client--token-file | File path where Mastodon access tokens are stored. | +| mastodon-group-notifications | Whether to use grouped notifications. | +| mastodon-images-in-notifs | Whether to display attached images in notifications. | +| mastodon-instance-url | Base URL for the fediverse instance you want to be active. | +| mastodon-media--avatar-height | Height of the user avatar images (if shown). | +| mastodon-media--enable-image-caching | Whether images should be cached. | +| mastodon-media--hide-sensitive-media | Whether media marked as sensitive should be hidden. | +| mastodon-media--preview-max-height | Max height of any media attachment preview to be shown in timelines. | +| mastodon-mode-hook | Hook run when entering Mastodon mode. | +| mastodon-profile-mode-hook | Hook run after entering or leaving `mastodon-profile-mode'. | +| mastodon-profile-note-in-foll-reqs | If non-nil, show a user's profile note in follow request notifications. | +| mastodon-profile-note-in-foll-reqs-max-length | The max character length for user profile note in follow requests. | +| mastodon-profile-update-mode-hook | Hook run after entering or leaving `mastodon-profile-update-mode'. | +| mastodon-search-mode-hook | Hook run after entering or leaving `mastodon-search-mode'. | +| mastodon-tl--display-caption-not-url-when-no-media | Display an image's caption rather than URL. | +| mastodon-tl--display-media-p | A boolean value stating whether to show media in timelines. | +| mastodon-tl--enable-proportional-fonts | Nonnil to enable using proportional fonts when rendering HTML. | +| mastodon-tl--enable-relative-timestamps | Whether to show relative (to the current time) timestamps. | +| mastodon-tl--expand-content-warnings | Whether to expand content warnings by default. | +| mastodon-tl--fold-toots-at-length | Length, in characters, to fold a toot at. | +| mastodon-tl--hide-replies | Whether to hide replies from the timelines. | +| mastodon-tl--highlight-current-toot | Whether to highlight the toot at point. Uses `cursor-face' special property. | +| mastodon-tl--load-full-sized-images-in-emacs | Whether to load full-sized images inside Emacs. | +| mastodon-tl--no-fill-on-render | Non-nil to disable filling by shr.el while rendering toot body. | +| mastodon-tl--remote-local-domains | A list of domains to view the local timelines of. | +| mastodon-tl--show-avatars | Whether to enable display of user avatars in timelines. | +| mastodon-tl--show-stats | Whether to show toot stats (faves, boosts, replies counts). | +| mastodon-tl--symbols | A set of symbols (and fallback strings) to be used in timeline. | +| mastodon-tl--tag-timeline-tags | A list of up to four tags for use with `mastodon-tl--followed-tags-timeline'. | +| mastodon-tl--timeline-posts-count | Number of posts to display when loading a timeline. | +| mastodon-tl-position-after-update | Defines where `point' should be located after a timeline update. | +| mastodon-toot--attachment-height | Height of the attached images preview in the toot draft buffer. | +| mastodon-toot--completion-style-for-mentions | The company completion style to use for mentions. | +| mastodon-toot--default-media-directory | The default directory when prompting for a media file to upload. | +| mastodon-toot--default-reply-visibility | Default visibility settings when replying. | +| mastodon-toot--enable-completion | Whether to enable completion of mentions and hashtags. | +| mastodon-toot--enable-custom-instance-emoji | Whether to enable your instance's custom emoji by default. | +| mastodon-toot--proportional-fonts-compose | Nonnil to enable using proportional fonts in the compose buffer. | +| mastodon-toot--use-company-for-completion | Whether to enable company for completion. | +| mastodon-toot-display-orig-in-reply-buffer | Display a copy of the toot replied to in the compose buffer. | +| mastodon-toot-mode-hook | Hook run after entering or leaving `mastodon-toot-mode'. | +| mastodon-toot-orig-in-reply-length | Length to crop toot replied to in the compose buffer to. | +| mastodon-toot-poll-use-transient | Whether to use the transient menu to create a poll. | +| mastodon-toot-timestamp-format | Format to use for timestamps. | +| mastodon-use-emojify | Whether to use emojify.el to display emojis. | -- cgit v1.2.3 From b529690f96953cd9b0ab248b18d811b9e95d0890 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Tue, 29 Oct 2024 20:59:48 +0100 Subject: notifs: refactor some v1/v2 calling code, mastodon-notifiations--body-arg --- lisp/mastodon-notifications.el | 164 ++++++++++++++++++++++------------------- 1 file changed, 88 insertions(+), 76 deletions(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index f0657fb..97d0d80 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -72,6 +72,9 @@ (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" @@ -215,8 +218,7 @@ JSON is a list of alists." (defun mastodon-notifications--format-note (note) "Format for a NOTE, a non-grouped notification." - (let* ((id (alist-get 'id note)) - (type (intern (alist-get 'type note))) + (let* ((type (intern (alist-get 'type note))) (profile-note (when (eq 'follow_request type) (let ((str (mastodon-tl--field @@ -239,36 +241,38 @@ JSON is a list of alists." 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 '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-sym 'severed_relationships) - ;; (mastodon-notifications--severance-body group)) - ;; ((eq type-sym 'moderation_warning) - ;; (mastodon-notifications--mod-warning-body group)) - ((member type '(favourite reblog)) - (propertize - (mastodon-notifications--comment-note-text body))) - (t body))) + (mastodon-notifiations--body-arg + type filters status profile-note follower-name) + ;; (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))) ;; author-byline #'mastodon-tl--byline-author ;; action-byline @@ -297,14 +301,14 @@ 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-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)) @@ -313,59 +317,67 @@ 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-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))) + (mastodon-notifiations--body-arg + type filters status profile-note follower-name group) ;; author-byline #'mastodon-tl--byline-author ;; 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 type) @@ -389,7 +401,7 @@ foldable. GROUP is the notification group data. ACCOUNTS is the notification accounts data." (let* ((type (if type - (symbol-name type) + (symbol-name type) ;; non-group (alist-get 'type group))) (toot-foldable (and mastodon-tl--fold-toots-at-length @@ -403,9 +415,8 @@ 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 @@ -483,7 +494,8 @@ When DOMAIN, force inclusion of user's domain in their handle." ", "))))))) (defun mastodon-notifications--render (json no-group) - "Display grouped notifications in JSON." + "Display grouped notifications in JSON. +NO-GROUP means don't render grouped notifications." ;; (setq masto-grouped-notifs json) (if no-group (cl-loop for x in json -- cgit v1.2.3 From 7d61f38a6bbe8a329892c5e91d1627a3ab03ee66 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Wed, 30 Oct 2024 08:17:07 +0100 Subject: FIX #609. insert-status remove author-byline arg, its always the same function --- lisp/mastodon-notifications.el | 11 +++++------ lisp/mastodon-tl.el | 16 +++++++--------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index 97d0d80..6d6b339 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -273,8 +273,6 @@ JSON is a list of alists." ;; (propertize ;; (mastodon-notifications--comment-note-text body))) ;; (t body))) - ;; author-byline - #'mastodon-tl--byline-author ;; action-byline (unless (member type '(follow follow_request mention)) (downcase @@ -323,8 +321,6 @@ ACCOUNTS is data of the accounts that have reacted to the notification." ;; body (mastodon-notifiations--body-arg type filters status profile-note follower-name group) - ;; author-byline - #'mastodon-tl--byline-author ;; action-byline (unless (member type '(follow follow_request mention)) (downcase @@ -379,7 +375,7 @@ FILTERS STATUS PROFILE-NOTE FOLLOWER-NAME GROUP." (t body)))) (defun mastodon-notifications--insert-note - (toot body author-byline action-byline action-authors action-symbol + (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. @@ -420,7 +416,10 @@ ACCOUNTS is the notification accounts data." "\n" ;; actual byline: (mastodon-tl--byline - toot author-byline nil nil base-toot group + toot nil nil base-toot group + ;; FIXME: remove account arg (esp. if we have type). maybe we need + ;; type arg when we step from notifs (here); to tl--byline land + ;; (there): (when (member type '("follow" "follow_request")) toot) ;; account data! ;; types listed here use base item timestamp, else we use group's diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 4f77f92..61014ff 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -796,7 +796,7 @@ LETTER is a string, F for favourited, B for boosted, or K for bookmarked." (image-type-available-p 'imagemagick) (image-transforms-p))) -(defun mastodon-tl--byline (toot author-byline &optional detailed-p +(defun mastodon-tl--byline (toot &optional detailed-p domain base-toot group account ts type) "Generate byline for TOOT. AUTHOR-BYLINE is a function for adding the author portion of @@ -861,7 +861,7 @@ TS is a timestamp from the server, if any." ;; NB: action-byline (boost) is now added in insert-status, so no ;; longer part of the byline. ;; (base) author byline: - (funcall author-byline toot nil domain :base account) + (mastodon-tl--byline-author toot nil domain :base account) ;; visibility: (cond ((string= visibility "direct") (propertize (concat " " (mastodon-tl--symbol 'direct)) @@ -1654,7 +1654,7 @@ Runs `mastodon-tl--render-text' and fetches poll or media." (string= reply-to-id prev-id))) (defun mastodon-tl--insert-status - (toot body author-byline action-byline &optional id base-toot + (toot body action-byline &optional id base-toot detailed-p thread domain unfolded no-byline) "Display the content and byline of timeline element TOOT. BODY will form the section of the toot above the byline. @@ -1709,8 +1709,7 @@ NO-BYLINE means just insert toot body, used for folding." "\n" (if no-byline "" - (mastodon-tl--byline toot author-byline detailed-p - domain base-toot))) + (mastodon-tl--byline toot detailed-p domain base-toot))) 'item-type 'toot 'item-id (or id ; notification's own id (alist-get 'id toot)) ; toot id @@ -1792,10 +1791,9 @@ NO-BYLINE means just insert toot body, used for folding." (if (and filtered (assoc "hide" filters)) nil ;; no insert (mastodon-tl--insert-status - toot - (mastodon-tl--clean-tabs-and-nl spoiler-or-content) - #'mastodon-tl--byline-author #'mastodon-tl--byline-boost - nil nil detailed-p thread domain unfolded no-byline)))) + toot (mastodon-tl--clean-tabs-and-nl spoiler-or-content) + #'mastodon-tl--byline-boost nil nil detailed-p + thread domain unfolded no-byline)))) (defun mastodon-tl--timeline (toots &optional thread domain no-byline) "Display each toot in TOOTS. -- cgit v1.2.3 From 89f93a1316b229313dac36125a6ad439ed1e1ae1 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Wed, 30 Oct 2024 08:52:46 +0100 Subject: remove ACCOUNT and TYPE from our byline functions. to avoid them, for foll/reqs we send the full notif as TOOT arg, and fetch type/account from it as needed. muuuuuuuuch simpler, fingers crossed. fix grouped notifs new non-account arg byline code fix handle byline for grouped notifs --- lisp/mastodon-notifications.el | 18 ++++++------------ lisp/mastodon-tl.el | 41 +++++++++++++++++++---------------------- 2 files changed, 25 insertions(+), 34 deletions(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index 6d6b339..1b04699 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -238,7 +238,7 @@ JSON is a list of alists." (mastodon-notifications--insert-note ;; toot (if (member type '(follow follow_request)) - follower + note ;; full notif, not just follower acct? status) ;; body (mastodon-notifiations--body-arg @@ -281,8 +281,7 @@ JSON is a list of alists." ;; action authors (cond ((member type '(follow follow_request mention)) "") ;; mentions are normal statuses - (t (mastodon-tl--byline-username - note (alist-get 'account note)))) + (t (mastodon-tl--byline-username note))) ;; action symbol: (unless (eq type 'mention) (mastodon-tl--symbol type)) @@ -395,7 +394,8 @@ 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." +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))) @@ -417,16 +417,10 @@ ACCOUNTS is the notification accounts data." ;; actual byline: (mastodon-tl--byline toot nil nil base-toot group - ;; FIXME: remove account arg (esp. if we have type). maybe we need - ;; type arg when we step from notifs (here); to tl--byline land - ;; (there): - (when (member type '("follow" "follow_request")) - toot) ;; account data! ;; types listed here use base item timestamp, else we use group's ;; latest timestamp: (when (not (member type '("favourite" "reblog" "edit" "poll"))) - (mastodon-tl--field 'latest_page_notification_at group)) - type)) + (mastodon-tl--field 'latest_page_notification_at group)))) 'item-type 'toot ;; for nav, actions, etc. 'item-id (or (alist-get 'page_max_id group) ;; newest notif (alist-get 'id toot)) ; toot id @@ -478,7 +472,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 ", ") diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 61014ff..4846164 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -610,14 +610,12 @@ Do so if type of status at poins is not follow_request/follow." (string= type "follow")) ; no counts for these (message "%s" echo))))) -;; FIXME: now that this can also be used for non byline rendering, let's -;; remove the toot arg, and deal with attachments higher up (on real -;; author byline only) removing toot arg makes it easier to render notifs -;; that have no status (foll_reqs) -(defun mastodon-tl--byline-username (toot &optional account) +(defun mastodon-tl--byline-username (toot) "Format a byline username from account in TOOT. -ACCOUNT is optionally acccount data to use." - (let-alist (or account (alist-get 'account toot)) +TOOT may be account data, or toot data, in which case acount data +is extracted from it." + (let-alist (or (alist-get 'account toot) + toot) ;; grouped nofifs use account data directly (propertize (if (not (string-empty-p .display_name)) .display_name .username) @@ -635,7 +633,7 @@ ACCOUNT is optionally acccount data to use." (string-suffix-p "-following*" (buffer-name))) (mastodon-tl--format-byline-help-echo toot))))) -(defun mastodon-tl--byline-handle (toot &optional domain account string face) +(defun mastodon-tl--byline-handle (toot &optional domain string face) "Format a byline handle from account in TOOT. DOMAIN is optionally added to the handle. ACCOUNT is optionally acccount data to use. @@ -643,7 +641,8 @@ STRING is optionally the string to propertize. FACE is optionally the face to use. The last two args allow for display a username as a clickable handle." - (let-alist (or account (alist-get 'account toot)) + (let-alist (or (alist-get 'account toot) + toot) ;; grouped notifs (propertize (or string (concat "@" .acct (when domain @@ -653,19 +652,18 @@ handle." 'face (or face 'mastodon-handle-face) 'mouse-face 'highlight 'mastodon-tab-stop 'user-handle - 'account account 'shr-url .url 'keymap mastodon-tl--link-keymap 'mastodon-handle (concat "@" .acct) 'help-echo (concat "Browse user profile of @" .acct)))) -(defun mastodon-tl--byline-uname-+-handle (data &optional domain account) +(defun mastodon-tl--byline-uname-+-handle (data &optional domain) "Concatenate a byline username and handle. DATA is the (toot) data to use. DOMAIN is optionally a domain for the handle. ACCOUNT is optionally acccount data to use." - (concat (mastodon-tl--byline-username data account) - " (" (mastodon-tl--byline-handle data domain account) ")")) + (concat (mastodon-tl--byline-username data) + " (" (mastodon-tl--byline-handle data domain) ")")) (defun mastodon-tl--display-or-uname (account) "Return display name or username from ACCOUNT data." @@ -673,7 +671,7 @@ ACCOUNT is optionally acccount data to use." (alist-get 'display_name account) (alist-get 'username account))) -(defun mastodon-tl--byline-author (toot &optional avatar domain base account) +(defun mastodon-tl--byline-author (toot &optional avatar domain base) "Propertize author of TOOT. If TOOT contains a reblog, return author of reblogged item. With arg AVATAR, include the account's avatar image. @@ -684,7 +682,7 @@ ACCOUNT is optionally acccount data to use." (let* ((data (if base (mastodon-tl--toot-or-base toot) toot)) - (account (or account (alist-get 'account data))) + (account (alist-get 'account data)) (uname (mastodon-tl--display-or-uname account))) (concat ;; avatar insertion moved up to `mastodon-tl--byline' by default to @@ -701,11 +699,11 @@ ACCOUNT is optionally acccount data to use." " " ;; username as button: (mastodon-tl--byline-handle - data domain account + data domain ;; display uname not handle (for boosts): uname 'mastodon-display-name-face)) ;; normal combo author byline: - (mastodon-tl--byline-uname-+-handle data domain account))))) + (mastodon-tl--byline-uname-+-handle data domain))))) (defun mastodon-tl--format-byline-help-echo (toot) "Format a help-echo for byline of TOOT. @@ -797,7 +795,7 @@ LETTER is a string, F for favourited, B for boosted, or K for bookmarked." (image-transforms-p))) (defun mastodon-tl--byline (toot &optional detailed-p - domain base-toot group account ts type) + domain base-toot group ts) "Generate byline for TOOT. AUTHOR-BYLINE is a function for adding the author portion of the byline that takes one variable. @@ -811,7 +809,7 @@ BASE-TOOT is JSON for the base toot, if any. GROUP is the notification group if any. ACCOUNT is the notification account if any. TS is a timestamp from the server, if any." - (let* ((type (or type (alist-get 'type (or group toot)))) + (let* ((type (alist-get 'type (or group toot))) (created-time (or ts ;; mentions, statuses, folls/foll-reqs ;; bosts, faves, edits, polls in notifs view use base item @@ -828,8 +826,7 @@ TS is a timestamp from the server, if any." (visibility (mastodon-tl--field 'visibility toot)) (base-toot-maybe (or base-toot ;; show edits for notifs (mastodon-tl--toot-or-base toot))) ;; for boosts - (account (or account - (alist-get 'account base-toot-maybe))) + (account (alist-get 'account base-toot-maybe)) (avatar-url (alist-get 'avatar account)) (edited-time (alist-get 'edited_at base-toot-maybe)) (edited-parsed (when edited-time (date-to-time edited-time)))) @@ -861,7 +858,7 @@ TS is a timestamp from the server, if any." ;; NB: action-byline (boost) is now added in insert-status, so no ;; longer part of the byline. ;; (base) author byline: - (mastodon-tl--byline-author toot nil domain :base account) + (mastodon-tl--byline-author toot nil domain :base) ;; visibility: (cond ((string= visibility "direct") (propertize (concat " " (mastodon-tl--symbol 'direct)) -- cgit v1.2.3 From 521c87ea65ccd1976e76e70c7be0abc625fc61d5 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Wed, 30 Oct 2024 08:53:39 +0100 Subject: notifs: remove commented body-arg code from format-note --- lisp/mastodon-notifications.el | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index 1b04699..23bd1fa 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -243,36 +243,6 @@ JSON is a list of alists." ;; body (mastodon-notifiations--body-arg type filters status profile-note follower-name) - ;; (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))) ;; action-byline (unless (member type '(follow follow_request mention)) (downcase -- cgit v1.2.3 From bfb17cdf91845b4ba49c99d14d439a8c16003d53 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Wed, 30 Oct 2024 08:54:02 +0100 Subject: docstrings tl.el --- lisp/mastodon-tl.el | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 4846164..beb74f4 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -1796,7 +1796,8 @@ NO-BYLINE means just insert toot body, used for folding." "Display each toot in TOOTS. This function removes replies if user required. THREAD means the status will be displayed in a thread view. -When DOMAIN, force inclusion of user's domain in their handle." +When DOMAIN, force inclusion of user's domain in their handle. +NO-BYLINE means just insert toot body, used for folding." (let ((start-pos (point)) (toots ;; hack to *not* filter replies on profiles: (if (eq (mastodon-tl--get-buffer-type) 'profile-statuses) @@ -3257,7 +3258,8 @@ favourites and bookmarks. PARAMS is any parameters to send with the request. HIDE-REPLIES is a flag indicating if replies are hidden in the current buffer. INSTANCE is a string of another instance domain we are displaying -a timeline from." +a timeline from. +NO-BYLINE means just insert toot body, used for announcements." (let ((url (if instance (concat "https://" instance "/api/v1/" endpoint) (mastodon-http--api endpoint))) @@ -3277,7 +3279,8 @@ a timeline from." UPDATE-FUNCTION is used to recieve more toots. RESPONSE is the data returned from the server by `mastodon-http--process-json', with arg HEADERS a cons cell of -JSON and http headers, without it just the JSON." +JSON and http headers, without it just the JSON. +NO-BYLINE means just insert toot body, used for announcements." (let ((json (if headers (car response) response))) (cond ((not json) ; praying this is right here, else try "\n[]" ;; this means that whatever tl was inited won't load, which is not @@ -3349,7 +3352,8 @@ ENDPOINT-VERSION is a string, format Vx, e.g. V2." (defun mastodon-tl--do-init (json update-fun &optional domain no-byline) "Utility function for `mastodon-tl--init*' and `mastodon-tl--init-sync'. JSON is the data to call UPDATE-FUN on. -When DOMAIN, force inclusion of user's domain in their handle." +When DOMAIN, force inclusion of user's domain in their handle. +NO-BYLINE means just insert toot body, used for announcements." (remove-overlays) ; video overlays (cond (domain ;; maybe our update-fun doesn't always have 3 args...: (funcall update-fun json nil domain)) -- cgit v1.2.3 From 14e3fa36cb2e36a36e13005ac5b54cd2aed3f512 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Wed, 30 Oct 2024 09:15:12 +0100 Subject: start on pagination for v1 notifs. #610 --- lisp/mastodon-tl.el | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index beb74f4..6c043ac 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -98,6 +98,7 @@ (defvar mastodon-toot-mode) (defvar mastodon-active-user) (defvar mastodon-images-in-notifs) +(defvar mastodon-group-notifications) (when (require 'mpv nil :no-error) (declare-function mpv-start "mpv")) @@ -2240,8 +2241,9 @@ If we are in a notifications view, return `notifications-min-id'." (save-excursion (goto-char (point-max)) (mastodon-tl--property - (if (member (mastodon-tl--get-buffer-type) - '(mentions notifications)) + (if (and mastodon-group-notifications + (member (mastodon-tl--get-buffer-type) + '(mentions notifications))) 'notifications-min-id 'item-id) nil :backward))) @@ -2865,7 +2867,8 @@ the current view." (args (append args params)) (url (mastodon-http--api endpoint - (when (or (string= endpoint "notifications") + (when (or (and mastodon-group-notifications + (string= endpoint "notifications")) (string-suffix-p "search" endpoint)) "v2")))) (apply #'mastodon-http--get-json-async url args callback cbargs))) -- cgit v1.2.3 From 2b281fcc49957fc779c0bff0a1807c4beb2ef376 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Wed, 30 Oct 2024 14:57:51 +0100 Subject: byte-compile --- lisp/mastodon-toot.el | 2 +- lisp/mastodon-transient.el | 2 +- lisp/mastodon-widget.el | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index 4e116fa..82ebc90 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -1429,7 +1429,7 @@ MAX is the maximum number set by their instance." "Prompt for new poll options and return as a list." (interactive) (if mastodon-toot-poll-use-transient - (mastodon-create-poll) + (call-interactively #'mastodon-create-poll) (mastodon-toot--read-poll))) (defun mastodon-toot--read-poll () diff --git a/lisp/mastodon-transient.el b/lisp/mastodon-transient.el index bbfbfc9..c96e1d5 100644 --- a/lisp/mastodon-transient.el +++ b/lisp/mastodon-transient.el @@ -332,7 +332,7 @@ Do not add more than the server's maximum setting." (not (y-or-n-p "Need more than one option. Proceed? "))) (and (> opts-count (mastodon-transient-max-poll-opts)) (not (y-or-n-p "More options than server max. Proceed? ")))) - (mastodon-create-poll) + (call-interactively #'mastodon-create-poll) ;; if we are called with no poll data, do not set: (unless (not vals) (setq tp-transient-settings diff --git a/lisp/mastodon-widget.el b/lisp/mastodon-widget.el index a326800..a576672 100644 --- a/lisp/mastodon-widget.el +++ b/lisp/mastodon-widget.el @@ -45,7 +45,8 @@ Note that such modes will need to require wid-edit.") (defface mastodon-widget-face '((t :inherit font-lock-function-name-face :weight bold :underline t)) - "Face for widgets.") + "Face for widgets." + :group 'mastodon) (defun mastodon-widget--return-item-widgets (list) "Return a list of item widgets for each item, a string, in LIST." -- cgit v1.2.3 From 411e9f22e0f770b8a416ea587dc8be0260ca4d91 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Wed, 30 Oct 2024 19:25:19 +0100 Subject: grouped notifs: top byline create with account data, not toot. #612 half fixed. --- lisp/mastodon-notifications.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index 23bd1fa..d9f7114 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -442,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 + (mastodon-tl--byline-handle account nil uname 'mastodon-display-name-face)) ", "))) nil ", ") -- cgit v1.2.3 From 089eee64854ad6d8a880b0949fba7e2c1fb04cc6 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Wed, 30 Oct 2024 20:03:16 +0100 Subject: notifs: fix author action byline, top, for ungrouped. FIX #612 --- lisp/mastodon-notifications.el | 28 ++++++++++++---------------- lisp/mastodon-tl.el | 37 +++++++++++++++++++------------------ 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index d9f7114..862f2a2 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -56,7 +56,6 @@ (autoload 'mastodon-tl--render-text "mastodon-tl") (autoload 'mastodon-notifications-get "mastodon") (autoload 'mastodon-tl--byline-uname-+-handle "mastodon-tl") -(autoload 'mastodon-tl--byline-username "mastodon-tl") (autoload 'mastodon-tl--byline-handle "mastodon-tl") (autoload 'mastodon-http--get-json "mastodon-http") (autoload 'mastodon-media--get-avatar-rendering "mastodon-media") @@ -243,7 +242,7 @@ JSON is a list of alists." ;; body (mastodon-notifiations--body-arg type filters status profile-note follower-name) - ;; action-byline + ;; action-byline (top) (unless (member type '(follow follow_request mention)) (downcase (mastodon-notifications--byline-concat @@ -251,10 +250,9 @@ JSON is a list of alists." ;; 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)) + (t (mastodon-tl--byline-handle note nil + follower-name + 'mastodon-display-name-face))) ;; base toot (when (or (eq type 'favourite) (eq type 'boost)) @@ -300,9 +298,6 @@ ACCOUNTS is data of the accounts that have reacted to the notification." "") ;; mentions are normal statuses (t (mastodon-notifications--byline-accounts accounts status group))) - ;; action symbol: - (unless (eq type 'mention) - (mastodon-tl--symbol type)) ;; base toot (no need for update/poll/?) (when (member type '(favourite reblog)) status) @@ -344,7 +339,7 @@ FILTERS STATUS PROFILE-NOTE FOLLOWER-NAME GROUP." (t body)))) (defun mastodon-notifications--insert-note - (toot body action-byline action-authors action-symbol + (toot body action-byline action-authors &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. @@ -369,18 +364,19 @@ TYPE is notification type, used for non-group notifs." (let* ((type (if type (symbol-name type) ;; non-group (alist-get 'type group))) + (action-symbol (unless (eq type 'mention) + (mastodon-tl--symbol (intern type)))) (toot-foldable (and mastodon-tl--fold-toots-at-length (length> body mastodon-tl--fold-toots-at-length)))) (insert (propertize ;; top byline, body + byline: (concat - (propertize ;; top byline - (if (equal type "mention") - "" - (concat action-symbol " " action-authors - action-byline)) - 'byline-top t) + (if (equal type "mention") + "" + (propertize ;; top byline + (concat action-symbol " " action-authors action-byline) + 'byline-top t)) (propertize body ;; body only 'toot-body t) ;; includes newlines etc. for folding "\n" diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 3a7988e..6f510b3 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -615,24 +615,25 @@ Do so if type of status at poins is not follow_request/follow." "Format a byline username from account in TOOT. TOOT may be account data, or toot data, in which case acount data is extracted from it." - (let-alist (or (alist-get 'account toot) - toot) ;; grouped nofifs use account data directly - (propertize (if (not (string-empty-p .display_name)) - .display_name - .username) - 'face 'mastodon-display-name-face - ;; enable playing of videos when point is on byline: - ;; 'attachments (mastodon-tl--get-attachments-for-byline toot) - 'keymap mastodon-tl--byline-link-keymap - ;; echo faves count when point on post author name: - ;; which is where --goto-next-toot puts point. - 'help-echo - ;; but don't add it to "following"/"follows" on - ;; profile views: we don't have a tl--buffer-spec - ;; yet: - (unless (or (string-suffix-p "-followers*" (buffer-name)) - (string-suffix-p "-following*" (buffer-name))) - (mastodon-tl--format-byline-help-echo toot))))) + (let ((data (or (alist-get 'account toot) + toot))) ;; grouped nofifs use account data directly + (let-alist data + (propertize (if (not (string-empty-p .display_name)) + .display_name + .username) + 'face 'mastodon-display-name-face + ;; enable playing of videos when point is on byline: + ;; 'attachments (mastodon-tl--get-attachments-for-byline toot) + 'keymap mastodon-tl--byline-link-keymap + ;; echo faves count when point on post author name: + ;; which is where --goto-next-toot puts point. + 'help-echo + ;; but don't add it to "following"/"follows" on + ;; profile views: we don't have a tl--buffer-spec + ;; yet: + (unless (or (string-suffix-p "-followers*" (buffer-name)) + (string-suffix-p "-following*" (buffer-name))) + (mastodon-tl--format-byline-help-echo data)))))) (defun mastodon-tl--byline-handle (toot &optional domain string face) "Format a byline handle from account in TOOT. -- cgit v1.2.3 From 5cb2bf1c0409acb2a88f5ad45135fadb6d84db7a Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Wed, 30 Oct 2024 20:59:57 +0100 Subject: FIX #610 fix note/base toot in format-note/author byline. non-grouped notif pagination was broken because we were propertizing item-json and base-toot wrong. now we always hand insert-note the note data as toot, and the status notified about as base-toot. then we adjust our handling of this in tl--byline-author to display base item byline correctly. --- lisp/mastodon-notifications.el | 12 +++++------- lisp/mastodon-tl.el | 5 ++++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index 862f2a2..9ff8413 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -236,9 +236,9 @@ JSON is a list of alists." nil (mastodon-notifications--insert-note ;; toot - (if (member type '(follow follow_request)) - note ;; full notif, not just follower acct? - status) + ;; should always be note, otherwise notif data not avail + ;; later on: + note ;; body (mastodon-notifiations--body-arg type filters status profile-note follower-name) @@ -253,10 +253,8 @@ JSON is a list of alists." (t (mastodon-tl--byline-handle note nil follower-name 'mastodon-display-name-face))) - ;; base toot - (when (or (eq type 'favourite) - (eq type 'boost)) - status) + ;; base toot (always provide) + status nil nil nil type)))) (defun mastodon-notifications--format-group-note (group status accounts) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 6f510b3..7e37b00 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -860,7 +860,10 @@ TS is a timestamp from the server, if any." ;; NB: action-byline (boost) is now added in insert-status, so no ;; longer part of the byline. ;; (base) author byline: - (mastodon-tl--byline-author toot nil domain :base) + ;; we use base-toot if poss for fave/boost notifs that need to show + ;; base item in author byline + (mastodon-tl--byline-author (or base-toot toot) + nil domain :base) ;; visibility: (cond ((string= visibility "direct") (propertize (concat " " (mastodon-tl--symbol 'direct)) -- cgit v1.2.3 From 27e438a2a4bbd2ee35cb70c382980216e6710866 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Wed, 30 Oct 2024 21:47:06 +0100 Subject: fix author action byline non-grouped notifs: use display-name if poss --- lisp/mastodon-notifications.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index 9ff8413..c27ffef 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -228,7 +228,8 @@ JSON is a list of alists." str)))) (status (mastodon-tl--field 'status note)) (follower (alist-get 'account note)) - (follower-name (alist-get 'username follower)) + (follower-name (or (alist-get 'display_name follower) + (alist-get 'username follower))) (filtered (mastodon-tl--field 'filtered status)) (filters (when filtered (mastodon-tl--current-filters filtered)))) -- cgit v1.2.3 From 271308160538a2631869f3bb61e0dfdede2ad4d3 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Wed, 30 Oct 2024 22:25:40 +0100 Subject: notifs: byline-accounts: remove toot arg --- lisp/mastodon-notifications.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index c27ffef..384241d 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -414,8 +414,8 @@ TYPE is notification type, used for non-group notifs." ;; almost everything is .account.field anyway ;; but toot still needed also, for attachments, etc. (defun mastodon-notifications--byline-accounts - (accounts toot group &optional avatar) - "Propertize author byline ACCOUNTS for TOOT, the item responded to. + (accounts group &optional avatar) + "Propertize author byline ACCOUNTS. GROUP is the group notification data. When AVATAR, include the account's avatar image. When DOMAIN, force inclusion of user's domain in their handle." -- cgit v1.2.3 From d06ac674ef1690a7bbfda8d6c497c614ed9d1e83 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Wed, 30 Oct 2024 22:26:09 +0100 Subject: docs: remove old arg docstring --- lisp/mastodon-tl.el | 3 --- 1 file changed, 3 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 7e37b00..bae4f09 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -801,9 +801,6 @@ LETTER is a string, F for favourited, B for boosted, or K for bookmarked." "Generate byline for TOOT. AUTHOR-BYLINE is a function for adding the author portion of the byline that takes one variable. -ACTION-BYLINE is a function for adding an action, such as boosting, -favouriting and following to the byline. It also takes a single function. -By default it is `mastodon-tl--byline-author' DETAILED-P means display more detailed info. For now this just means displaying toot client. When DOMAIN, force inclusion of user's domain in their handle. -- cgit v1.2.3 From 464d2e463423f7c431f85497658531312c2ad448 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Thu, 31 Oct 2024 08:32:10 +0100 Subject: notifs: factor an action-byline fun (maybe move into insert-note) --- lisp/mastodon-notifications.el | 153 +++++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 74 deletions(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index 384241d..e5ad1ea 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -244,16 +244,8 @@ JSON is a list of alists." (mastodon-notifiations--body-arg type filters status profile-note follower-name) ;; action-byline (top) - (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-handle note nil - follower-name - 'mastodon-display-name-face))) + (mastodon-notifications--action-byline + type nil nil note follower-name) ;; base toot (always provide) status nil nil nil type)))) @@ -288,20 +280,36 @@ ACCOUNTS is data of the accounts that have reacted to the notification." (mastodon-notifiations--body-arg type filters status profile-note follower-name group) ;; 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-notifications--byline-accounts - accounts status group))) + (mastodon-notifications--action-byline + type accounts group) ;; base toot (no need for update/poll/?) (when (member type '(favourite reblog)) status) folded group accounts)))))) +(defun mastodon-notifications--action-byline + (type &optional accounts group note follower-name) + "TYPE ACCOUNTS GROUP NOTE FOLLOWER-NAME." + (let ((action-str + (unless (member type '(follow follow_request mention)) + (downcase + (mastodon-notifications--byline-concat + (alist-get type mastodon-notifications--action-alist))))) + (action-symbol (if (eq type 'mention) + "" + (mastodon-tl--symbol type))) + (action-authors + (if (member type '(follow follow_request mention)) + "" ;; mentions are normal statuses + (if group + (mastodon-notifications--byline-accounts accounts group) + (mastodon-tl--byline-handle note nil + follower-name + 'mastodon-display-name-face))))) + (propertize + (concat action-symbol " " action-authors action-str) + 'byline-top t))) + (defun mastodon-notifiations--body-arg (type &optional filters status profile-note follower-name group) "TYPE is a symbol, a member of `mastodon-notifiations--types'. @@ -338,9 +346,9 @@ FILTERS STATUS PROFILE-NOTE FOLLOWER-NAME GROUP." (t body)))) (defun mastodon-notifications--insert-note - (toot body action-byline action-authors + (toot body action-byline &optional base-toot unfolded group accounts type) - "Display the content and byline of timeline element TOOT. +"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 portion of the byline that takes one variable. By default it is @@ -360,59 +368,56 @@ foldable. GROUP is the notification group data. 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))) - (action-symbol (unless (eq type 'mention) - (mastodon-tl--symbol (intern type)))) - (toot-foldable - (and mastodon-tl--fold-toots-at-length - (length> body mastodon-tl--fold-toots-at-length)))) - (insert - (propertize ;; top byline, body + byline: - (concat - (if (equal type "mention") - "" - (propertize ;; top byline - (concat action-symbol " " action-authors action-byline) - 'byline-top t)) - (propertize body ;; body only - 'toot-body t) ;; includes newlines etc. for folding - "\n" - ;; actual byline: - (mastodon-tl--byline - 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"))) - (mastodon-tl--field 'latest_page_notification_at group)))) - 'item-type 'toot ;; for nav, actions, etc. - 'item-id (or (alist-get 'page_max_id group) ;; newest notif - (alist-get 'id toot)) ; toot id - 'base-item-id (mastodon-tl--item-id - ;; if status is a notif, get id from base-toot - ;; (-tl--item-id toot) will not work here: - (or base-toot - toot)) ; else normal toot with reblog check - 'item-json toot - 'base-toot base-toot - 'cursor-face 'mastodon-cursor-highlight-face - 'toot-foldable toot-foldable - 'toot-folded (and toot-foldable (not unfolded)) - ;; grouped notifs data: - 'notification-type type - 'notification-id (alist-get 'group_key group) - 'notification-group group - 'notification-accounts accounts - ;; for pagination: - 'notifications-min-id (alist-get 'page_min_id group) - 'notifications-max-id (alist-get 'page_max_id group)) - "\n"))) - -;; FIXME: REFACTOR with -tl--byline?: -;; we provide account directly, rather than let-alisting toot -;; almost everything is .account.field anyway -;; but toot still needed also, for attachments, etc. +(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))) + (follower (alist-get 'account toot)) + (follower-name (or (alist-get 'display_name follower) + (alist-get 'username follower)))) + (insert + (propertize ;; top byline, body + byline: + (concat + (if (equal type "mention") ;; top (action) byline + "" + action-byline) + ;; (mastodon-notifications--action-byline + ;; (intern type) accounts group toot follower-name)) + (propertize body ;; body only + 'toot-body t) ;; includes newlines etc. for folding + "\n" + ;; actual byline: + (mastodon-tl--byline + 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"))) + (mastodon-tl--field 'latest_page_notification_at group)))) + 'item-type 'toot ;; for nav, actions, etc. + 'item-id (or (alist-get 'page_max_id group) ;; newest notif + (alist-get 'id toot)) ; toot id + 'base-item-id (mastodon-tl--item-id + ;; if status is a notif, get id from base-toot + ;; (-tl--item-id toot) will not work here: + (or base-toot + toot)) ; else normal toot with reblog check + 'item-json toot + 'base-toot base-toot + 'cursor-face 'mastodon-cursor-highlight-face + 'toot-foldable toot-foldable + 'toot-folded (and toot-foldable (not unfolded)) + ;; grouped notifs data: + 'notification-type type + 'notification-id (alist-get 'group_key group) + 'notification-group group + 'notification-accounts accounts + ;; for pagination: + 'notifications-min-id (alist-get 'page_min_id group) + 'notifications-max-id (alist-get 'page_max_id group)) + "\n"))) + (defun mastodon-notifications--byline-accounts (accounts group &optional avatar) "Propertize author byline ACCOUNTS. -- cgit v1.2.3 From 8a8b13dc0a232f8018628953ce0f748bd303aaf1 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Thu, 31 Oct 2024 09:42:26 +0100 Subject: --byline: pull fave/boost/edit/visibility from base toot if present for non-grouped notifs, new implementation of note/base relationship --- lisp/mastodon-tl.el | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index bae4f09..bb00af5 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -819,15 +819,17 @@ TS is a timestamp from the server, if any." ;; (mastodon-tl--field auto fetches from reblogs if needed): (mastodon-tl--field 'created_at toot))) (parsed-time (when created-time (date-to-time created-time))) - (faved (eq t (mastodon-tl--field 'favourited toot))) - (boosted (eq t (mastodon-tl--field 'reblogged toot))) - (bookmarked (eq t (mastodon-tl--field 'bookmarked toot))) - (visibility (mastodon-tl--field 'visibility toot)) - (base-toot-maybe (or base-toot ;; show edits for notifs - (mastodon-tl--toot-or-base toot))) ;; for boosts - (account (alist-get 'account base-toot-maybe)) + ;; non-grouped notifs now need to pull the following data from + ;; base toot: + (base-maybe (or base-toot ;; show edits for notifs + (mastodon-tl--toot-or-base toot))) ;; for boosts + (faved (eq t (mastodon-tl--field 'favourited base-maybe))) + (boosted (eq t (mastodon-tl--field 'reblogged base-maybe))) + (bookmarked (eq t (mastodon-tl--field 'bookmarked base-maybe))) + (visibility (mastodon-tl--field 'visibility base-maybe)) + (account (alist-get 'account base-maybe)) (avatar-url (alist-get 'avatar account)) - (edited-time (alist-get 'edited_at base-toot-maybe)) + (edited-time (alist-get 'edited_at base-maybe)) (edited-parsed (when edited-time (date-to-time edited-time)))) (concat ;; Boosted/favourited markers are not technically part of the byline, so @@ -923,7 +925,7 @@ TS is a timestamp from the server, if any." 'edited edited-time 'edit-history (when edited-time (mastodon-toot--get-toot-edits - (alist-get 'id base-toot-maybe))) + (alist-get 'id base-maybe))) 'byline t)))) -- cgit v1.2.3 From 380c6be86f570854cc9b2a714f36301339e57c8b Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Thu, 31 Oct 2024 09:43:12 +0100 Subject: keep cleaning up notifs insert note --- lisp/mastodon-notifications.el | 99 +++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index e5ad1ea..99d9d89 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -348,7 +348,7 @@ FILTERS STATUS PROFILE-NOTE FOLLOWER-NAME GROUP." (defun mastodon-notifications--insert-note (toot body action-byline &optional base-toot unfolded group accounts type) -"Display the content and byline of timeline element TOOT. + "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 portion of the byline that takes one variable. By default it is @@ -368,55 +368,54 @@ foldable. GROUP is the notification group data. 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))) - (follower (alist-get 'account toot)) - (follower-name (or (alist-get 'display_name follower) - (alist-get 'username follower)))) - (insert - (propertize ;; top byline, body + byline: - (concat - (if (equal type "mention") ;; top (action) byline - "" - action-byline) - ;; (mastodon-notifications--action-byline - ;; (intern type) accounts group toot follower-name)) - (propertize body ;; body only - 'toot-body t) ;; includes newlines etc. for folding - "\n" - ;; actual byline: - (mastodon-tl--byline - 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"))) - (mastodon-tl--field 'latest_page_notification_at group)))) - 'item-type 'toot ;; for nav, actions, etc. - 'item-id (or (alist-get 'page_max_id group) ;; newest notif - (alist-get 'id toot)) ; toot id - 'base-item-id (mastodon-tl--item-id - ;; if status is a notif, get id from base-toot - ;; (-tl--item-id toot) will not work here: - (or base-toot - toot)) ; else normal toot with reblog check - 'item-json toot - 'base-toot base-toot - 'cursor-face 'mastodon-cursor-highlight-face - 'toot-foldable toot-foldable - 'toot-folded (and toot-foldable (not unfolded)) - ;; grouped notifs data: - 'notification-type type - 'notification-id (alist-get 'group_key group) - 'notification-group group - 'notification-accounts accounts - ;; for pagination: - 'notifications-min-id (alist-get 'page_min_id group) - 'notifications-max-id (alist-get 'page_max_id group)) - "\n"))) + (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))) + (follower (alist-get 'account toot)) + (follower-name (or (alist-get 'display_name follower) + (alist-get 'username follower))) + (ts ;; types listed here use base item timestamp, else we use + ;; group's latest timestamp: + (when (and group + (not + (member type '("favourite" "reblog" "edit" "poll")))) + (mastodon-tl--field 'latest_page_notification_at group)))) + (insert + (propertize ;; top byline, body + byline: + (concat + (if (equal type "mention") ;; top (action) byline + "" + action-byline) + (propertize body ;; body only + 'toot-body t) ;; includes newlines etc. for folding + "\n" + ;; actual byline: + (mastodon-tl--byline toot nil nil base-toot group ts)) + 'item-type 'toot ;; for nav, actions, etc. + 'item-id (or (alist-get 'page_max_id group) ;; newest notif + (alist-get 'id toot)) ; toot id + 'base-item-id (mastodon-tl--item-id + ;; if status is a notif, get id from base-toot + ;; (-tl--item-id toot) will not work here: + (or base-toot + toot)) ; else normal toot with reblog check + 'item-json toot + 'base-toot base-toot + 'cursor-face 'mastodon-cursor-highlight-face + 'toot-foldable toot-foldable + 'toot-folded (and toot-foldable (not unfolded)) + ;; grouped notifs data: + 'notification-type type + 'notification-id (alist-get 'group_key group) + 'notification-group group + 'notification-accounts accounts + ;; for pagination: + 'notifications-min-id (alist-get 'page_min_id group) + 'notifications-max-id (alist-get 'page_max_id group)) + "\n"))) (defun mastodon-notifications--byline-accounts (accounts group &optional avatar) -- cgit v1.2.3 From c4edecd145eafc7f6d7fd58106dbc0bca43ed861 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Thu, 31 Oct 2024 10:08:47 +0100 Subject: cask build cleanups --- lisp/mastodon-notifications.el | 3 --- lisp/mastodon-toot.el | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index 99d9d89..eed3d20 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -374,9 +374,6 @@ TYPE is notification type, used for non-group notifs." (toot-foldable (and mastodon-tl--fold-toots-at-length (length> body mastodon-tl--fold-toots-at-length))) - (follower (alist-get 'account toot)) - (follower-name (or (alist-get 'display_name follower) - (alist-get 'username follower))) (ts ;; types listed here use base item timestamp, else we use ;; group's latest timestamp: (when (and group diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index 82ebc90..fa5a955 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -36,14 +36,18 @@ (require 'emojify nil :noerror) (declare-function emojify-insert-emoji "emojify") (declare-function emojify-set-emoji-data "emojify") +(declare-function emojify-mode "emojify") +(declare-function emojify-emojis-each "emojify") (defvar emojify-emojis-dir) (defvar emojify-user-emojis) +(defvar emojify-emoji-styles) (require 'cl-lib) (require 'persist) (require 'mastodon-iso) (require 'facemenu) (require 'text-property-search) +(require 'ht) (eval-when-compile (require 'mastodon-tl)) -- cgit v1.2.3 From 198c7ae8c71bd6460122b34549c4e6c4b5393bc4 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Thu, 31 Oct 2024 08:36:05 +0100 Subject: bump tp version, bump version --- lisp/mastodon.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/mastodon.el b/lisp/mastodon.el index b544d5b..32cc671 100644 --- a/lisp/mastodon.el +++ b/lisp/mastodon.el @@ -6,8 +6,8 @@ ;; Author: Johnson Denen ;; Marty Hiatt ;; Maintainer: Marty Hiatt -;; Version: 1.1.3 -;; Package-Requires: ((emacs "28.1") (request "0.3.0") (persist "0.4") (tp "0.5")) +;; Version: 1.1.4 +;; Package-Requires: ((emacs "28.1") (request "0.3.0") (persist "0.4") (tp "0.6")) ;; Homepage: https://codeberg.org/martianh/mastodon.el ;; This file is not part of GNU Emacs. -- cgit v1.2.3 From 2bb6ad95f777f5f206ad203482e74f6eec0a64c1 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Thu, 31 Oct 2024 10:20:03 +0100 Subject: toot.el cask build cleanups --- lisp/mastodon-toot.el | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index 82ebc90..fa5a955 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -36,14 +36,18 @@ (require 'emojify nil :noerror) (declare-function emojify-insert-emoji "emojify") (declare-function emojify-set-emoji-data "emojify") +(declare-function emojify-mode "emojify") +(declare-function emojify-emojis-each "emojify") (defvar emojify-emojis-dir) (defvar emojify-user-emojis) +(defvar emojify-emoji-styles) (require 'cl-lib) (require 'persist) (require 'mastodon-iso) (require 'facemenu) (require 'text-property-search) +(require 'ht) (eval-when-compile (require 'mastodon-tl)) -- cgit v1.2.3 From c7a3ed75ab8d4b512676e939adc27e394f40d4b8 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Fri, 1 Nov 2024 15:05:15 +0100 Subject: fold-toot - respect CW state --- lisp/mastodon-tl.el | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index bb00af5..cfd9906 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -1771,15 +1771,18 @@ title, and context." (mastodon-tl--filter-by-context context filters-no-context))) (defun mastodon-tl--toot (toot &optional detailed-p thread domain - unfolded no-byline) + unfolded no-byline no-cw) "Format TOOT and insert it into the buffer. DETAILED-P means display more detailed info. For now this just means displaying toot client. THREAD means the status will be displayed in a thread view. When DOMAIN, force inclusion of user's domain in their handle. UNFOLDED is a boolean meaning whether to unfold or fold item if foldable. -NO-BYLINE means just insert toot body, used for folding." - (let* ((filtered (mastodon-tl--field 'filtered toot)) +NO-BYLINE means just insert toot body, used for folding. +NO-CW means treat content warnings as unfolded." + (let* ((mastodon-tl--expand-content-warnings + (or no-cw mastodon-tl--expand-content-warnings)) + (filtered (mastodon-tl--field 'filtered toot)) (filters (when filtered (mastodon-tl--current-filters filtered))) (spoiler-or-content (if-let ((match (assoc "warn" filters))) @@ -1825,9 +1828,14 @@ NO-BYLINE means just insert toot body, used for folding." (defun mastodon-tl--fold-body (body) "Fold toot BODY if it is very long. Folding decided by `mastodon-tl--fold-toots-at-length'." - (let* ((heading (mastodon-search--format-heading - (mastodon-tl--make-link "READ MORE" 'read-more) - nil :no-newline)) + (let* ((invis (get-text-property (1- (length body)) 'invisible body)) + (spoiler (get-text-property (1- (length body)) + 'mastodon-content-warning-body body)) + (heading (propertize (mastodon-search--format-heading + (mastodon-tl--make-link "READ MORE" 'read-more) + nil :no-newline) + 'mastodon-content-warning-body spoiler + 'invisible invis)) (display (concat (substring body 0 mastodon-tl--fold-toots-at-length) heading))) @@ -1847,6 +1855,10 @@ FOLD means to fold it instead." (let* ((inhibit-read-only t) (body-range (mastodon-tl--find-property-range 'toot-body (point) :backward)) + (cw-range (mastodon-tl--find-property-range + 'mastodon-content-warning-body + (point) :backward)) + (cw-invis (get-text-property (car cw-range) 'invisible)) (toot (mastodon-tl--property 'item-json :no-move)) ;; `replace-region-contents' is much too slow, our hack from ;; fedi.el is much simpler and much faster: @@ -1862,7 +1874,8 @@ FOLD means to fold it instead." (delete-region beg end) (delete-char 1) ;; prevent newlines accumulating ;; insert toot body: - (mastodon-tl--toot toot nil nil nil (not fold) :no-byline) + (mastodon-tl--toot toot nil nil nil (not fold) :no-byline + (unless cw-invis :no-cw)) ;; respect CW state ;; set toot-folded prop on entire toot (not just body): (let ((toot-range ;; post fold action range: (mastodon-tl--find-property-range 'item-json -- cgit v1.2.3 From b6676c180ba94002a3f03fa0b09931e886923f3d Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Fri, 1 Nov 2024 15:05:44 +0100 Subject: tl: improve ctrl flow in --spoiler + --toot --- lisp/mastodon-tl.el | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index cfd9906..a5bd2e0 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -1275,25 +1275,22 @@ FILTER is a string to use as a filter warning spoiler instead." (cw (mastodon-tl--set-face message 'mastodon-cw-face))) (concat cw - (propertize (mastodon-tl--content toot) - 'invisible - (if filter - t - (let ((cust mastodon-tl--expand-content-warnings)) - (cond ((eq t cust) - nil) - ((eq nil cust) - t) - ((eq 'server cust) - (unless (eq t - ;; If something goes wrong reading prefs, - ;; just return nil so CWs show by default. - (condition-case nil - (mastodon-profile--get-preferences-pref - 'reading:expand:spoilers) - (error nil))) - t))))) - 'mastodon-content-warning-body t)))) + (propertize + (mastodon-tl--content toot) + 'invisible + (or filter ;; filters = invis + (let ((cust mastodon-tl--expand-content-warnings)) + (if (not (eq 'server cust)) + (not cust) ;; opp to setting + ;; respect server setting: + (not + ;; If something goes wrong reading prefs, + ;; just return nil so CWs show by default. + (condition-case nil + (mastodon-profile--get-preferences-pref + 'reading:expand:spoilers) + (error nil)))))) + 'mastodon-content-warning-body t)))) ;;; MEDIA @@ -1792,8 +1789,7 @@ NO-CW means treat content warnings as unfolded." (mastodon-tl--content toot))))) ;; If any filters are "hide", then we hide, ;; even though item may also have a "warn" filter: - (if (and filtered (assoc "hide" filters)) - nil ;; no insert + (unless (and filtered (assoc "hide" filters)) ;; no insert (mastodon-tl--insert-status toot (mastodon-tl--clean-tabs-and-nl spoiler-or-content) #'mastodon-tl--byline-boost nil nil detailed-p -- cgit v1.2.3 From babb3a1adf7dbc2c458c65d841e758aafaabd298 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Fri, 1 Nov 2024 15:05:15 +0100 Subject: fold-toot - respect CW state --- lisp/mastodon-tl.el | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 5178a25..b655bec 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -1772,15 +1772,18 @@ title, and context." (mastodon-tl--filter-by-context context filters-no-context))) (defun mastodon-tl--toot (toot &optional detailed-p thread domain - unfolded no-byline) + unfolded no-byline no-cw) "Format TOOT and insert it into the buffer. DETAILED-P means display more detailed info. For now this just means displaying toot client. THREAD means the status will be displayed in a thread view. When DOMAIN, force inclusion of user's domain in their handle. UNFOLDED is a boolean meaning whether to unfold or fold item if foldable. -NO-BYLINE means just insert toot body, used for folding." - (let* ((filtered (mastodon-tl--field 'filtered toot)) +NO-BYLINE means just insert toot body, used for folding. +NO-CW means treat content warnings as unfolded." + (let* ((mastodon-tl--expand-content-warnings + (or no-cw mastodon-tl--expand-content-warnings)) + (filtered (mastodon-tl--field 'filtered toot)) (filters (when filtered (mastodon-tl--current-filters filtered))) (spoiler-or-content (if-let ((match (assoc "warn" filters))) @@ -1826,9 +1829,14 @@ When DOMAIN, force inclusion of user's domain in their handle." (defun mastodon-tl--fold-body (body) "Fold toot BODY if it is very long. Folding decided by `mastodon-tl--fold-toots-at-length'." - (let* ((heading (mastodon-search--format-heading - (mastodon-tl--make-link "READ MORE" 'read-more) - nil :no-newline)) + (let* ((invis (get-text-property (1- (length body)) 'invisible body)) + (spoiler (get-text-property (1- (length body)) + 'mastodon-content-warning-body body)) + (heading (propertize (mastodon-search--format-heading + (mastodon-tl--make-link "READ MORE" 'read-more) + nil :no-newline) + 'mastodon-content-warning-body spoiler + 'invisible invis)) (display (concat (substring body 0 mastodon-tl--fold-toots-at-length) heading))) @@ -1848,6 +1856,10 @@ FOLD means to fold it instead." (let* ((inhibit-read-only t) (body-range (mastodon-tl--find-property-range 'toot-body (point) :backward)) + (cw-range (mastodon-tl--find-property-range + 'mastodon-content-warning-body + (point) :backward)) + (cw-invis (get-text-property (car cw-range) 'invisible)) (toot (mastodon-tl--property 'item-json :no-move)) ;; `replace-region-contents' is much too slow, our hack from ;; fedi.el is much simpler and much faster: @@ -1863,7 +1875,8 @@ FOLD means to fold it instead." (delete-region beg end) (delete-char 1) ;; prevent newlines accumulating ;; insert toot body: - (mastodon-tl--toot toot nil nil nil (not fold) :no-byline) + (mastodon-tl--toot toot nil nil nil (not fold) :no-byline + (unless cw-invis :no-cw)) ;; respect CW state ;; set toot-folded prop on entire toot (not just body): (let ((toot-range ;; post fold action range: (mastodon-tl--find-property-range 'item-json -- cgit v1.2.3 From 1ba949586efbbcd50be9f341cfc3f8b9c591fb3b Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Fri, 1 Nov 2024 15:05:44 +0100 Subject: tl: improve ctrl flow in --spoiler + --toot. FIX #579 --- lisp/mastodon-tl.el | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index b655bec..595f0cf 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -1275,25 +1275,22 @@ FILTER is a string to use as a filter warning spoiler instead." (cw (mastodon-tl--set-face message 'mastodon-cw-face))) (concat cw - (propertize (mastodon-tl--content toot) - 'invisible - (if filter - t - (let ((cust mastodon-tl--expand-content-warnings)) - (cond ((eq t cust) - nil) - ((eq nil cust) - t) - ((eq 'server cust) - (unless (eq t - ;; If something goes wrong reading prefs, - ;; just return nil so CWs show by default. - (condition-case nil - (mastodon-profile--get-preferences-pref - 'reading:expand:spoilers) - (error nil))) - t))))) - 'mastodon-content-warning-body t)))) + (propertize + (mastodon-tl--content toot) + 'invisible + (or filter ;; filters = invis + (let ((cust mastodon-tl--expand-content-warnings)) + (if (not (eq 'server cust)) + (not cust) ;; opp to setting + ;; respect server setting: + (not + ;; If something goes wrong reading prefs, + ;; just return nil so CWs show by default. + (condition-case nil + (mastodon-profile--get-preferences-pref + 'reading:expand:spoilers) + (error nil)))))) + 'mastodon-content-warning-body t)))) ;;; MEDIA @@ -1793,8 +1790,7 @@ NO-CW means treat content warnings as unfolded." (mastodon-tl--content toot))))) ;; If any filters are "hide", then we hide, ;; even though item may also have a "warn" filter: - (if (and filtered (assoc "hide" filters)) - nil ;; no insert + (unless (and filtered (assoc "hide" filters)) ;; no insert (mastodon-tl--insert-status toot (mastodon-tl--clean-tabs-and-nl spoiler-or-content) -- cgit v1.2.3 From b05de5f9075813d9e56317fd011dcd809da905bc Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Fri, 1 Nov 2024 15:48:32 +0100 Subject: some ifs become whens --- lisp/mastodon-tl.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 595f0cf..2db7f34 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -3037,7 +3037,7 @@ MAX-ID is the pagination parameter, a string." (alist-get 'hashtags response)) ((string= "accounts" type) (alist-get 'accounts response)))))) - (headers (if headers (cdr response) nil)) + (headers (when headers (cdr response))) (link-header (mastodon-tl--get-link-header-from-response headers))) (goto-char (point-max)) @@ -3309,7 +3309,7 @@ JSON and http headers, without it just the JSON." ((eq (caar json) 'error) (user-error "Looks like the server bugged out: \"%s\"" (cdar json))) (t - (let* ((headers (if headers (cdr response) nil)) + (let* ((headers (when headers (cdr response))) (link-header (mastodon-tl--get-link-header-from-response headers))) (with-mastodon-buffer buffer #'mastodon-mode nil -- cgit v1.2.3 From 2c3f35c953574a046ef7e241494d5ee892c06ffb Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Fri, 1 Nov 2024 15:48:32 +0100 Subject: some ifs become whens --- lisp/mastodon-tl.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index a5bd2e0..b5dfa2b 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -3038,7 +3038,7 @@ MAX-ID is the pagination parameter, a string." (alist-get 'hashtags response)) ((string= "accounts" type) (alist-get 'accounts response)))))) - (headers (if headers (cdr response) nil)) + (headers (when headers (cdr response))) (link-header (mastodon-tl--get-link-header-from-response headers))) (goto-char (point-max)) @@ -3312,7 +3312,7 @@ NO-BYLINE means just insert toot body, used for announcements." ((eq (caar json) 'error) (user-error "Looks like the server bugged out: \"%s\"" (cdar json))) (t - (let* ((headers (if headers (cdr response) nil)) + (let* ((headers (when headers (cdr response))) (link-header (mastodon-tl--get-link-header-from-response headers))) (with-mastodon-buffer buffer #'mastodon-mode nil -- cgit v1.2.3 From 1bf73f2528e35c28d41d48548ea65ab00bd8f689 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Fri, 1 Nov 2024 16:06:38 +0100 Subject: remove elsa from Cask --- Cask | 1 - 1 file changed, 1 deletion(-) diff --git a/Cask b/Cask index 6d0179d..36f13df 100644 --- a/Cask +++ b/Cask @@ -9,5 +9,4 @@ (depends-on "el-mock") (depends-on "ecukes") (depends-on "package-lint") - (depends-on "elsa") (depends-on "async")) -- cgit v1.2.3 From add6bfceafeb115d4665706ca76f3c1e5105d531 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Fri, 1 Nov 2024 16:06:38 +0100 Subject: remove elsa from Cask --- Cask | 1 - 1 file changed, 1 deletion(-) diff --git a/Cask b/Cask index 6d0179d..36f13df 100644 --- a/Cask +++ b/Cask @@ -9,5 +9,4 @@ (depends-on "el-mock") (depends-on "ecukes") (depends-on "package-lint") - (depends-on "elsa") (depends-on "async")) -- cgit v1.2.3 From 6f9cb5c18f145f9b410812e967a2a018610860c9 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Fri, 1 Nov 2024 16:56:43 +0100 Subject: add mention symbol --- lisp/mastodon-tl.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index b5dfa2b..625b11b 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -163,6 +163,7 @@ nil." (verified . ("✓" . "V")) (locked . ("🔒" . "[locked]")) (private . ("🔒" . "[followers]")) + (mention . ("@" . "[mention]")) (direct . ("✉" . "[direct]")) (edited . ("✍" . "[edited]")) (update . ("✍" . "[edited]")) ;; server compat -- cgit v1.2.3 From c09935b100986a94e4265ca5f6c152d17fabd9e6 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Fri, 1 Nov 2024 17:15:27 +0100 Subject: tl: remove stale args to insert status, inc. action-byline arg (they were used when notifs didn't have its own insert fun.) more clean up tl--insert-status --- lisp/mastodon-tl.el | 33 +++++++-------------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 625b11b..f321e41 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -799,7 +799,7 @@ LETTER is a string, F for favourited, B for boosted, or K for bookmarked." (defun mastodon-tl--byline (toot &optional detailed-p domain base-toot group ts) - "Generate byline for TOOT. + "Generate (bottom) byline for TOOT. AUTHOR-BYLINE is a function for adding the author portion of the byline that takes one variable. DETAILED-P means display more detailed info. For now @@ -1653,21 +1653,9 @@ Runs `mastodon-tl--render-text' and fetches poll or media." (string= reply-to-id prev-id))) (defun mastodon-tl--insert-status - (toot body action-byline &optional id base-toot - detailed-p thread domain unfolded no-byline) + (toot body &optional detailed-p thread domain unfolded no-byline) "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 -portion of the byline that takes one variable. By default it is -`mastodon-tl--byline-author'. -ACTION-BYLINE is also an optional function for adding an action, -such as boosting favouriting and following to the byline. It also -takes a single function. By default it is -`mastodon-tl--byline-boost'. -ID is that of the status if it is a notification, which is -attached as a `item-id' property if provided. If the -status is a favourite or boost notification, BASE-TOOT is the -JSON of the toot responded to. DETAILED-P means display more detailed info. For now this just means displaying toot client. THREAD means the status will be displayed in a thread view. @@ -1688,7 +1676,7 @@ NO-BYLINE means just insert toot body, used for folding." (propertize ;; body only: (concat "\n" - (funcall action-byline toot) + (mastodon-tl--byline-boost toot) ;; top byline (boost) ;; relpy symbol: (when (and after-reply-status-p thread) (concat (mastodon-tl--symbol 'replied) @@ -1708,17 +1696,11 @@ NO-BYLINE means just insert toot body, used for folding." "\n" (if no-byline "" - (mastodon-tl--byline toot detailed-p domain base-toot))) + (mastodon-tl--byline toot detailed-p domain))) 'item-type 'toot - 'item-id (or id ; notification's own id - (alist-get 'id toot)) ; toot id - 'base-item-id (mastodon-tl--item-id - ;; if status is a notif, get id from base-toot - ;; (-tl--item-id toot) will not work here: - (or base-toot - toot)) ; else normal toot with reblog check + 'item-id (alist-get 'id toot) ; toot id + 'base-item-id (mastodon-tl--item-id toot) ; with reblog check 'item-json toot - 'base-toot base-toot 'cursor-face 'mastodon-cursor-highlight-face 'toot-foldable toot-foldable 'toot-folded (and toot-foldable (not unfolded))) @@ -1793,8 +1775,7 @@ NO-CW means treat content warnings as unfolded." (unless (and filtered (assoc "hide" filters)) ;; no insert (mastodon-tl--insert-status toot (mastodon-tl--clean-tabs-and-nl spoiler-or-content) - #'mastodon-tl--byline-boost nil nil detailed-p - thread domain unfolded no-byline)))) + detailed-p thread domain unfolded no-byline)))) (defun mastodon-tl--timeline (toots &optional thread domain no-byline) "Display each toot in TOOTS. -- cgit v1.2.3 From 94ea642a1a565f0a8c56d1ad541965b905411459 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Fri, 1 Nov 2024 17:16:14 +0100 Subject: notifs: improve byline docstrings for new byline logic --- lisp/mastodon-notifications.el | 21 ++++++++------------- lisp/mastodon-tl.el | 4 ++-- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index eed3d20..238feac 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -101,8 +101,8 @@ map) "Keymap for viewing notifications.") -(defun mastodon-notifications--byline-concat (message) - "Add byline for TOOT with MESSAGE." +(defun mastodon-notifications--byline-action-str (message) + "Return an action (top) byline string for TOOT with MESSAGE." (concat " " (propertize message 'face 'mastodon-boosted-face) " " (cdr (assoc message mastodon-notifications--response-alist)) @@ -289,11 +289,13 @@ ACCOUNTS is data of the accounts that have reacted to the notification." (defun mastodon-notifications--action-byline (type &optional accounts group note follower-name) - "TYPE ACCOUNTS GROUP NOTE FOLLOWER-NAME." + "Return an action (top) byline for notification of TYPE. +ACCOUNTS and GROUP group are used by grouped notifications. +NOTE and FOLLOWER-NAME are used for non-grouped notifs." (let ((action-str (unless (member type '(follow follow_request mention)) (downcase - (mastodon-notifications--byline-concat + (mastodon-notifications--byline-action-str (alist-get type mastodon-notifications--action-alist))))) (action-symbol (if (eq type 'mention) "" @@ -354,15 +356,8 @@ AUTHOR-BYLINE is an optional function for adding the author portion of the byline that takes one variable. By default it is `mastodon-tl--byline-author'. ACTION-BYLINE is a string, obtained by calling -`mastodon-notifications--byline-concat'. -ACTION-AUTHORS is a string of those who have responded to the -current item, obtained by calling -`mastodon-notifications--byline-accounts'. -ACTION-SYMBOL is a symbol indicating a favourite, boost, or edit. -ID is that of the status if it is a notification, which is -attached as a `item-id' property if provided. If the -status is a favourite or boost notification, BASE-TOOT is the -JSON of the toot responded to. +`mastodon-notifications--action-byline'. +BASE-TOOT is the 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. diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index f321e41..3e1d49f 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -640,7 +640,8 @@ is extracted from it." "Format a byline handle from account in TOOT. DOMAIN is optionally added to the handle. ACCOUNT is optionally acccount data to use. -STRING is optionally the string to propertize. +STRING is optionally the string to propertize, it is used to make +username rather than handle buttons. FACE is optionally the face to use. The last two args allow for display a username as a clickable handle." @@ -676,7 +677,6 @@ ACCOUNT is optionally acccount data to use." (defun mastodon-tl--byline-author (toot &optional avatar domain base) "Propertize author of TOOT. -If TOOT contains a reblog, return author of reblogged item. With arg AVATAR, include the account's avatar image. When DOMAIN, force inclusion of user's domain in their handle. BASE means to use data from the base item (reblog slot) if possible. -- cgit v1.2.3 From 16779f582042eb721905e7532ca02cbbeaeab24e Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Fri, 1 Nov 2024 17:50:35 +0100 Subject: readme for some of the new stuff --- README.org | 71 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/README.org b/README.org index 90222c7..b2f4964 100644 --- a/README.org +++ b/README.org @@ -171,6 +171,7 @@ For a full list of commands and variables, see [[file:mastodon-index.org][mastod | =K= | view bookmarked toots | | =X= | view/edit/create/delete lists | | =S= | view your scheduled toots | +| =S-:= | view profile/account settings transient menu | |----------------+---------------------------------------------------------------------------------| | | *Toot actions* | | =t= | Compose a new toot | @@ -192,7 +193,7 @@ For a full list of commands and variables, see [[file:mastodon-index.org][mastod |----------------+---------------------------------------------------------------------------------| | | *Profile view* | | =C-c C-c= | cycle between statuses, statuses without boosts, followers, and following | -| | =mastodon-profile--account-account-to-list= (see lists view) | +| | =mastodon-profile--add-account-to-list= (see lists view) | |----------------+---------------------------------------------------------------------------------| | | *Notifications view* | | =a=, =j= | accept/reject follow request | @@ -244,21 +245,22 @@ value of that hook is as follows: **** Keybindings -|----------+-------------------------------| -| Key | Action | -|----------+-------------------------------| -| =C-c C-c= | Send toot | -| =C-c C-k= | Cancel toot | -| =C-c C-w= | Add content warning | -| =C-c C-v= | Change toot visibility | -| =C-c C-n= | Add sensitive media/nsfw flag | -| =C-c C-a= | Upload attachment(s) | -| =C-c != | Remove all attachments | -| =C-c C-e= | Insert emoji | -| =C-c C-p= | Create a poll | -| =C-c C-l= | Set toot language | -| =-C-c C-s= | Schedule toot | -|----------+-------------------------------| +|---------+-------------------------------| +| Key | Action | +|---------+-------------------------------| +| =C-c C-c= | Send toot | +| =C-c C-k= | Cancel toot | +| =C-c C-w= | Add content warning | +| =C-c C-v= | Change toot visibility | +| =C-c C-n= | Add sensitive media/nsfw flag | +| =C-c C-a= | Upload attachment(s) | +| =C-c != | Remove all attachments | +| =C-c C-e= | Insert emoji | +| =C-c C-p= | Create a poll | +| =C-c C-o= | Cancel poll | +| =C-c C-l= | Set toot language | +| =C-c C-s= | Schedule toot | +|---------+-------------------------------| **** Autocompletion of mentions, tags and emoji @@ -301,7 +303,7 @@ work without first loading a =mastodon.el= buffer: - =mastodon-search--trending-tags=: View a list of trending hashtags on your instance. - =mastodon-search--trending-statuses=: View a list of trending statuses on your instance. - +- =mastodon-search--trending-links=: View a list of trending links on your instance (+ click through to a timeline of posts featuring a given link) - =mastodon-tl--add-toot-account-at-point-to-list=: Add the account of the toot at point to a list. @@ -330,21 +332,11 @@ work without first loading a =mastodon.el= buffer: - =mastodon-tl--remote-tag-timeline=: View a tag timeline on a remote instance. -- =mastodon-profile--update-display-name=: Update the display name for your - account. -- =mastodon-profile--update-user-profile-note=: Update your bio note. -- =mastodon-profile--update-meta-fields=: Update your metadata fields. -- =mastodon-profile--set-default-toot-visibility=: Set the default visibility - for your toots. -- =mastodon-profile--account-locked-toggle=: Toggle the locked status of your - account. Locked accounts have to manually approve follow requests. -- =mastodon-profile--account-discoverable-toggle=: Toggle the discoverable - status of your account. Non-discoverable accounts are not listed in the - profile directory. -- =mastodon-profile--account-bot-toggle=: Toggle whether your account is flagged - as a bot. -- =mastodon-profile--account-sensitive-toggle=: Toggle whether your posts are - marked as sensitive (nsfw) by default. +- =mastodon-user-settings=: Launch a transient menu to update various account settings. + +*** Notifications + +Mastodon from 4.3 supports grouped notifications. These are implemented by =mastodon.el=. If you are on an instance that doesn't implement grouped notifications, set =mastodon-group-notifications= to nil. *** Customization @@ -376,18 +368,24 @@ An index of all user-facing commands and custom variables is available here: [[f You can also hit =?= in any =mastodon.el= buffer to see the available bindings, or run =M-X= (upper-case =X=) to view all commands in the buffer with completion, and call one. -*** Alternative timeline layout +*** Packages related to =mastodon.el= + +**** Alternative timeline layout The incomparable Nicholas Rougier has written an alternative timeline layout for =mastodon.el=. The repo is at [[https://github.com/rougier/mastodon-alt][mastodon-alt]]. -*** mastodon hydra +**** Mastodon hydra -A user made a hydra for handling basic mastodon.el commands. It's available at +A user made a hydra for handling basic =mastodon.el= commands. It's available at https://holgerschurig.github.io/en/emacs-mastodon-hydra/. +**** Narrow to timeline item + +A simple code snippet to enable narrowing to current item in timelines: http://takeonrules.com/2024/10/31/hacking-on-mastodon-emacs-package-to-narrow-viewing/ + *** Live-updating timelines: =mastodon-async-mode= (code taken from [[https://github.com/alexjgriffith/mastodon-future.el][mastodon-future]].) @@ -433,6 +431,7 @@ to your translator function as its text argument. Here's what Hard dependencies (should all install with =mastodon.el=): - =request= (for uploading attachments), [[https://github.com/tkf/emacs-request][emacs-request]] - =persist= for storing some settings across sessions +- =tp.el= for transient menus Optional dependencies (install yourself, =mastodon.el= can use them): - =emojify= to use custom emoji (else we use builtin =emoji.el=) @@ -506,7 +505,7 @@ Some significant contributors are: - https://github.com/hdurer - https://codeberg.org/Red_Starfish -** screenshots +** Screenshots Here's a (federated) timeline: -- cgit v1.2.3 From f1bdef0b734fef63aeb4854b2a87503d442bd4ec Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sat, 2 Nov 2024 10:49:18 +0100 Subject: revert transient polls to use mastodon-toot-poll internally, the transients still use tp-transient-settings, but they fetch from mastodon-toot-poll, and set it when done. we also hack around so that the cancelling functions work ok. --- lisp/mastodon-toot.el | 45 ++++++++++++++++++++++----------------------- lisp/mastodon-transient.el | 14 ++++++++++---- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index fa5a955..14aa7de 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -57,7 +57,6 @@ (defvar mastodon-tl--enable-proportional-fonts) (defvar mastodon-profile-account-settings) (defvar mastodon-profile-acccount-preferences-data) -(defvar tp-transient-settings) (autoload 'iso8601-parse "iso8601") (autoload 'mastodon-auth--user-acct "mastodon-auth") @@ -780,7 +779,7 @@ TEXT-ONLY means don't check for attachments or polls." (and (if text-only t (and (not mastodon-toot--media-attachments) - (not (mastodon-toot-poll-var)))) + (not mastodon-toot-poll))) (string-empty-p (mastodon-tl--clean-tabs-and-nl (mastodon-toot--remove-docs))))) @@ -881,7 +880,7 @@ to `emojify-user-emojis', and the emoji data is updated." (defun mastodon-toot--build-poll-params () "Return an alist of parameters for POSTing a poll status." (if mastodon-toot-poll-use-transient - (let-alist tp-transient-settings + (let-alist mastodon-toot-poll (append (mastodon-http--build-array-params-alist "poll[options][]" @@ -930,13 +929,12 @@ instance to edit a toot." (mastodon-http--build-array-params-alist "media_ids[]" mastodon-toot--media-attachment-ids))) - (poll-var (mastodon-toot-poll-var)) - (args-poll (when poll-var + (args-poll (when mastodon-toot-poll (mastodon-toot--build-poll-params))) ;; media || polls: (args (if mastodon-toot--media-attachment-ids (append args-media args-no-media) - (if poll-var + (if mastodon-toot-poll (append args-no-media args-poll) args-no-media))) (prev-window-config mastodon-toot-previous-window-config)) @@ -951,7 +949,9 @@ instance to edit a toot." (> (mastodon-toot--count-toot-chars toot mastodon-toot--content-warning) mastodon-toot--max-toot-chars)) (user-error "Looks like your toot (inc. CW) is longer than that maximum allowed length")) - ((mastodon-toot--empty-p) + ;; polls must have text, so we use poll as flag for text-only + ;; check here: + ((mastodon-toot--empty-p mastodon-toot-poll) (user-error "Empty toot. Cowardly refusing to post this")) (t (let ((response (funcall (if edit-id ; we are sending an edit: @@ -964,7 +964,7 @@ instance to edit a toot." ;; kill buffer: (mastodon-toot--kill) ;; nil our poll var: - (set poll-var nil) + (setq mastodon-toot-poll nil) (message "Toot %s!" (if scheduled "scheduled" "toot")) ;; cancel scheduled toot if we were editing it: (when scheduled-id @@ -1395,12 +1395,6 @@ which is used to attach it to a toot when posting." ;;; POLL -(defun mastodon-toot-poll-var () - "Return the correct poll var." - (if mastodon-toot-poll-use-transient - 'tp-transient-settings - 'mastodon-toot-poll)) - (defun mastodon-toot--fetch-max-poll-options (instance) "Return the maximum number of poll options from JSON data INSTANCE." (mastodon-toot--fetch-poll-field 'max_options instance)) @@ -1492,14 +1486,20 @@ Return a cons of a human readable string, and a seconds-from-now string." ("14 days" . ,(number-to-string (* 60 60 24 14))) ("30 days" . ,(number-to-string (* 60 60 24 30))))) -(defun mastodon-toot--clear-poll () +(defun mastodon-toot--clear-poll (&optional transient) "Remove poll from toot compose buffer. -Sets `mastodon-toot-poll' to nil." +Sets `mastodon-toot-poll' to nil. +If TRANSIENT, we are called from a transient, so nil +`tp-transient-settings' too." (interactive) - (let ((var (mastodon-toot-poll-var))) - (if (not var) + (let ((var (if transient + 'tp-transient-settings + 'mastodon-toot-poll))) + (if (not (symbol-value var)) (user-error "No poll?") (set var nil) + (when transient + (setq mastodon-toot-poll nil)) (mastodon-toot--update-status-fields)))) (defun mastodon-toot--server-poll-to-local (json) @@ -1517,7 +1517,7 @@ Sets `mastodon-toot-poll' to nil." (options (mastodon-tl--map-alist 'title .options)) (multiple (if (eq :json-false .multiple) nil t))) (if mastodon-toot-poll-use-transient - (setq tp-transient-settings + (setq mastodon-toot-poll `((multi . ,multiple) (expiry . ,expiry-str) ;; (hide . ,hide) @@ -1805,8 +1805,7 @@ REPLY-REGION is a string to be injected into the buffer." (poll-region (mastodon-tl--find-property-range 'toot-post-poll-flag (point-min))) (toot-string (buffer-substring-no-properties (cdr header-region) - (point-max))) - (poll-var (mastodon-toot-poll-var))) + (point-max)))) (mastodon-toot--apply-fields-props count-region (format "%s/%s chars" @@ -1840,11 +1839,11 @@ REPLY-REGION is a string to be injected into the buffer." 'mastodon-cw-face) (mastodon-toot--apply-fields-props poll-region - (if (symbol-value poll-var) + (if mastodon-toot-poll "POLL" "") 'mastodon-cw-face - (prin1-to-string (symbol-value poll-var))) + (prin1-to-string mastodon-toot-poll)) (mastodon-toot--apply-fields-props cw-region (if (and mastodon-toot--content-warning diff --git a/lisp/mastodon-transient.el b/lisp/mastodon-transient.el index c96e1d5..6b1296f 100644 --- a/lisp/mastodon-transient.el +++ b/lisp/mastodon-transient.el @@ -268,8 +268,12 @@ Do not add more than the server's maximum setting." (transient-define-prefix mastodon-create-poll () "A transient for creating a poll." - ;; FIXME: handle existing polls when editing a toot - :value (lambda () tp-transient-settings) + :value (lambda () + ;; we set `tp-transient-settings' here to the poll value poss + ;; pulled from the server by + ;; `mastodon-toot--server-poll-to-local'. when we are done with + ;; the transient, we set `mastodon-toot-poll' again + (setq tp-transient-settings mastodon-toot-poll)) ["Create poll" (:info (lambda () (format "Max options: %s" @@ -305,7 +309,7 @@ Do not add more than the server's maximum setting." "Clear current poll data." :transient 'transient--do-stay (interactive) - (mastodon-toot--clear-poll) + (mastodon-toot--clear-poll :transient) (transient-reset)) (transient-define-suffix mastodon-create-poll-done (args) @@ -335,7 +339,9 @@ Do not add more than the server's maximum setting." (call-interactively #'mastodon-create-poll) ;; if we are called with no poll data, do not set: (unless (not vals) - (setq tp-transient-settings + ;; we set `mastodon-toot-poll' here not `tp-transient-settings' + ;; as that is our var outside of our transient: + (setq mastodon-toot-poll (tp-bools-to-strs args))) (mastodon-toot--update-status-fields)))) -- cgit v1.2.3 From ee25cb9b026a40c320570c09635a476509d81d67 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sat, 2 Nov 2024 10:57:33 +0100 Subject: update point after widget. FIX #615 --- lisp/mastodon-profile.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/mastodon-profile.el b/lisp/mastodon-profile.el index c16d88d..1ce8747 100644 --- a/lisp/mastodon-profile.el +++ b/lisp/mastodon-profile.el @@ -745,7 +745,6 @@ MAX-ID is a flag to include the max_id pagination parameter." "\n\n") 'success) "")))) ; for insert call - (setq mastodon-tl--update-point (point)) (mastodon-media--inline-images (point-min) (point)) ;; widget items description (mastodon-widget--create @@ -756,7 +755,8 @@ MAX-ID is a flag to include the max_id pagination parameter." (lambda (widget &rest _ignore) (let ((value (widget-value widget))) (mastodon-profile--view-fun-call value)))) - (insert "\n"))) + (insert "\n") + (setq mastodon-tl--update-point (point)))) ;; split insert of items from insert of profile: (with-current-buffer buffer (let* ((inhibit-read-only t)) -- cgit v1.2.3 From 7af46336f2dd2ed17b3aba7b0c58b029b49767cc Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sat, 2 Nov 2024 11:25:35 +0100 Subject: add read less button to unfolded long posts (read more). FIX #614 --- lisp/mastodon-tl.el | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 3e1d49f..87fd710 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -1143,7 +1143,8 @@ the toot)." LINK-TYPE is the type of link to produce." (let ((help-text (cond ((eq link-type 'content-warning) "Toggle hidden text") - ((eq link-type 'read-more) + ((or (eq link-type 'read-more) + (eq link-type 'read-less)) "Toggle full post") (t (error "Unknown link type %s" link-type))))) @@ -1187,6 +1188,8 @@ Used for hitting RET on a given link." (error "Unable to find account")))))))) ((eq link-type 'read-more) (mastodon-tl--unfold-post)) + ((eq link-type 'read-less) + (mastodon-tl--fold-post)) (t (error "Unknown link type %s" link-type))))) @@ -1653,7 +1656,8 @@ Runs `mastodon-tl--render-text' and fetches poll or media." (string= reply-to-id prev-id))) (defun mastodon-tl--insert-status - (toot body &optional detailed-p thread domain unfolded no-byline) + (toot body &optional detailed-p thread domain unfolded no-byline + cw-expanded) "Display the content and byline of timeline element TOOT. BODY will form the section of the toot above the byline. DETAILED-P means display more detailed info. For now @@ -1669,7 +1673,10 @@ NO-BYLINE means just insert toot body, used for folding." ;; (type (alist-get 'type toot)) (toot-foldable (and mastodon-tl--fold-toots-at-length - (length> body mastodon-tl--fold-toots-at-length)))) + (length> body mastodon-tl--fold-toots-at-length))) + (cw-p (not + (string-empty-p + (alist-get 'spoiler_text toot))))) (insert (propertize ;; body + byline: (concat @@ -1690,7 +1697,14 @@ NO-BYLINE means just insert toot body, used for folding." (propertize body 'line-prefix bar 'wrap-prefix bar) - body))) + body)) + (if (and toot-foldable unfolded cw-expanded) + (propertize (mastodon-search--format-heading + (mastodon-tl--make-link "READ LESS" 'read-less) + nil :no-newline) + 'mastodon-content-warning-body cw-p + 'invisible (not cw-expanded)) + "")) 'toot-body t) ;; includes newlines etc. for folding ;; byline: "\n" @@ -1751,7 +1765,7 @@ title, and context." (mastodon-tl--filter-by-context context filters-no-context))) (defun mastodon-tl--toot (toot &optional detailed-p thread domain - unfolded no-byline no-cw) + unfolded no-byline cw-expanded) "Format TOOT and insert it into the buffer. DETAILED-P means display more detailed info. For now this just means displaying toot client. @@ -1761,7 +1775,7 @@ UNFOLDED is a boolean meaning whether to unfold or fold item if foldable. NO-BYLINE means just insert toot body, used for folding. NO-CW means treat content warnings as unfolded." (let* ((mastodon-tl--expand-content-warnings - (or no-cw mastodon-tl--expand-content-warnings)) + (or cw-expanded mastodon-tl--expand-content-warnings)) (filtered (mastodon-tl--field 'filtered toot)) (filters (when filtered (mastodon-tl--current-filters filtered))) @@ -1775,7 +1789,7 @@ NO-CW means treat content warnings as unfolded." (unless (and filtered (assoc "hide" filters)) ;; no insert (mastodon-tl--insert-status toot (mastodon-tl--clean-tabs-and-nl spoiler-or-content) - detailed-p thread domain unfolded no-byline)))) + detailed-p thread domain unfolded no-byline cw-expanded)))) (defun mastodon-tl--timeline (toots &optional thread domain no-byline) "Display each toot in TOOTS. @@ -1853,7 +1867,7 @@ FOLD means to fold it instead." (delete-char 1) ;; prevent newlines accumulating ;; insert toot body: (mastodon-tl--toot toot nil nil nil (not fold) :no-byline - (unless cw-invis :no-cw)) ;; respect CW state + (unless cw-invis :cw-expanded)) ;; respect CW state ;; set toot-folded prop on entire toot (not just body): (let ((toot-range ;; post fold action range: (mastodon-tl--find-property-range 'item-json -- cgit v1.2.3 From ebab9b20a161d2ac1cb083f2d39de3bc1cda5faa Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sat, 2 Nov 2024 15:37:32 +0100 Subject: refactor a read-more-or-less heading --- lisp/mastodon-tl.el | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 87fd710..51abb6e 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -1699,11 +1699,8 @@ NO-BYLINE means just insert toot body, used for folding." 'wrap-prefix bar) body)) (if (and toot-foldable unfolded cw-expanded) - (propertize (mastodon-search--format-heading - (mastodon-tl--make-link "READ LESS" 'read-less) - nil :no-newline) - 'mastodon-content-warning-body cw-p - 'invisible (not cw-expanded)) + (mastodon-tl--read-more-or-less + "LESS" cw-p (not cw-expanded)) "")) 'toot-body t) ;; includes newlines etc. for folding ;; byline: @@ -1817,17 +1814,26 @@ NO-BYLINE means just insert toot body, used for folding." ;;; FOLDING +(defun mastodon-tl--read-more-or-less (str cw invis) + "Return a read more or read less heading. +The heading is a link to toggle the fold status of the toot. +CW and INVIS are boolean values for the properties invisible and +mastodon-content-warning-body." + (let ((type (if (string= str "MORE") 'read-more 'read-less))) + (propertize + (mastodon-search--format-heading + (mastodon-tl--make-link (format "READ %s" str) type) + nil :no-newline) + 'mastodon-content-warning-body cw + 'invisible invis))) + (defun mastodon-tl--fold-body (body) "Fold toot BODY if it is very long. Folding decided by `mastodon-tl--fold-toots-at-length'." (let* ((invis (get-text-property (1- (length body)) 'invisible body)) - (spoiler (get-text-property (1- (length body)) - 'mastodon-content-warning-body body)) - (heading (propertize (mastodon-search--format-heading - (mastodon-tl--make-link "READ MORE" 'read-more) - nil :no-newline) - 'mastodon-content-warning-body spoiler - 'invisible invis)) + (cw (get-text-property (1- (length body)) + 'mastodon-content-warning-body body)) + (heading (mastodon-tl--read-more-or-less "MORE" cw invis)) (display (concat (substring body 0 mastodon-tl--fold-toots-at-length) heading))) -- cgit v1.2.3 From bf82092dde3f062bee493b384436c7ccc038861b Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sat, 2 Nov 2024 15:39:47 +0100 Subject: autoload ht-get --- lisp/mastodon-toot.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index fa5a955..f90dd3c 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -47,7 +47,6 @@ (require 'mastodon-iso) (require 'facemenu) (require 'text-property-search) -(require 'ht) (eval-when-compile (require 'mastodon-tl)) @@ -60,6 +59,7 @@ (defvar tp-transient-settings) (autoload 'iso8601-parse "iso8601") +(autoload 'ht-get "ht") (autoload 'mastodon-auth--user-acct "mastodon-auth") (autoload 'mastodon-http--api "mastodon-http") (autoload 'mastodon-http--build-array-params-alist "mastodon-http") -- cgit v1.2.3 From 9eaf125207099ea78ec216b1622244930f14659d Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sat, 2 Nov 2024 15:45:37 +0100 Subject: docstring poll done --- lisp/mastodon-transient.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/mastodon-transient.el b/lisp/mastodon-transient.el index 6b1296f..3e8ba5f 100644 --- a/lisp/mastodon-transient.el +++ b/lisp/mastodon-transient.el @@ -313,7 +313,7 @@ Do not add more than the server's maximum setting." (transient-reset)) (transient-define-suffix mastodon-create-poll-done (args) - "Update current user profile fields." + "Finish setting poll details." :transient 'transient--do-exit (interactive (list (transient-args 'mastodon-create-poll))) (let* ((options (cl-member-if (lambda (x) -- cgit v1.2.3 From 6242db6028ef5646ead41e915dec6b8f014e33f8 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sat, 2 Nov 2024 17:33:58 +0100 Subject: bump --- lisp/mastodon.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/mastodon.el b/lisp/mastodon.el index 32cc671..c13c3ba 100644 --- a/lisp/mastodon.el +++ b/lisp/mastodon.el @@ -6,7 +6,7 @@ ;; Author: Johnson Denen ;; Marty Hiatt ;; Maintainer: Marty Hiatt -;; Version: 1.1.4 +;; Version: 1.1.5 ;; Package-Requires: ((emacs "28.1") (request "0.3.0") (persist "0.4") (tp "0.6")) ;; Homepage: https://codeberg.org/martianh/mastodon.el -- cgit v1.2.3