From 7bf9d25de2ae4b1157ae61badddbdee32a51575b Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Mon, 28 Oct 2024 15:48:46 +0100 Subject: add inspect prefix --- lisp/mastodon-transient.el | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'lisp') diff --git a/lisp/mastodon-transient.el b/lisp/mastodon-transient.el index 67ea667..ceea384 100644 --- a/lisp/mastodon-transient.el +++ b/lisp/mastodon-transient.el @@ -48,6 +48,20 @@ ;;; UTILS +(transient-define-suffix mastodon-transient--prefix-inspect () + "Inspect a transient prefix's arguments and scope." + (interactive) + :transient 'transient--do-return + (let ((args (transient-args (oref transient-current-prefix command))) + (scope (oref transient-current-prefix scope))) + (message "prefix's scope: %s \ntransient-args: %s\n last: %s" + scope args + (length + (cl-member-if + (lambda (x) + (equal (car x) 'one)) + args))))) + ;; some JSON fields that are returned under the "source" field need to be ;; sent back in the format source[key], while some others are sent kust as ;; key: -- cgit v1.2.3 From 5d3b80d6a85a036aabcf690bd07cef92b502c33d Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Mon, 28 Oct 2024 15:49:10 +0100 Subject: poll transient: add another option interactively --- lisp/mastodon-transient.el | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'lisp') diff --git a/lisp/mastodon-transient.el b/lisp/mastodon-transient.el index ceea384..68d8b24 100644 --- a/lisp/mastodon-transient.el +++ b/lisp/mastodon-transient.el @@ -233,6 +233,37 @@ the format fields.X.keyname." (let ((instance (mastodon-instance-data))) (mastodon-toot--fetch-max-poll-option-chars instance))) +(transient-define-suffix mastodon-transient--choice-add () + "docstring" + (interactive) + :transient 'transient--do-stay + (let* ((args (transient-args (oref transient-current-prefix command))) + (choice-count (length + (cl-member-if + (lambda (x) + (equal (car x) 'one)) + args))) + (inc (1+ choice-count)) + (next (number-to-string inc)) + (next-symbol (pcase inc + (5 'five) + (6 'six) + (7 'seven) + (8 'eight) + (9 'nine)))) + (if (or ;(>= choice-count (mastodon-transient-max-poll-opts)) + (= choice-count 9)) + ;; FIXME when we hit '10', we get a binding clash with '1'. :/ + (message "Max choices reached") + (transient-append-suffix + 'mastodon-create-poll + '(2 -1) + `(,next "" ,next + :class mastodon-transient-poll-choice + :alist-key ,next-symbol + :transient t)))) + (transient-setup 'mastodon-create-poll)) + (transient-define-prefix mastodon-create-poll () "A transient for creating a poll." ;; FIXME: handle existing polls when editing a toot @@ -260,6 +291,7 @@ the format fields.X.keyname." ["Update" ("C-c C-c" "Save and done" mastodon-create-poll-done) ("C-c C-k" "Delete all" mastodon-clear-poll) + ("C-c C-s" "Add another poll choice" mastodon-transient--choice-add) ("C-x C-k" :info "Revert all")] (interactive) (if (not mastodon-active-user) -- cgit v1.2.3 From c69917a12ece246a18720f4b7ecc40f739cd011e Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Tue, 29 Oct 2024 08:45:33 +0100 Subject: fix timestamp logic in notifs v2 (use base item when necessary) --- lisp/mastodon-notifications.el | 12 ++++++++---- lisp/mastodon-tl.el | 25 +++++++++++++------------ 2 files changed, 21 insertions(+), 16 deletions(-) (limited to 'lisp') diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index 3ef8869..06bbca7 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -346,10 +346,14 @@ ACCOUNTS is the notification accounts data." 'toot-body t) ;; includes newlines etc. for folding "\n" ;; actual byline: - (mastodon-tl--byline toot author-byline nil nil - base-toot group - (if (member type '("follow" "follow_request")) - toot))) ;; account data! + (mastodon-tl--byline + toot author-byline nil nil base-toot group + (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)))) '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 5bd1ec1..5eb52e3 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) + domain base-toot group account ts) "Generate byline for TOOT. AUTHOR-BYLINE is a function for adding the author portion of the byline that takes one variable. @@ -809,17 +809,18 @@ this just means displaying toot client. When DOMAIN, force inclusion of user's domain in their handle. BASE-TOOT is JSON for the base toot, if any. GROUP is the notification group if any. -ACCOUNT is the notification account if any." - (let* ((created-time - (if group - (mastodon-tl--field 'latest_page_notification_at group) - ;; bosts and faves in notifs view - ;; (makes timestamps be for the original toot not the boost/fave): - (or (mastodon-tl--field 'created_at - (mastodon-tl--field 'status toot)) - ;; all other toots, inc. boosts/faves in timelines: - ;; (mastodon-tl--field auto fetches from reblogs if needed): - (mastodon-tl--field 'created_at toot)))) +ACCOUNT is the notification account if any. +TS is a timestamp from the server, if any." + (let* ((type (alist-get 'type group)) + (created-time + (or ts ;; mentions, statuses, folls/foll-reqs + ;; bosts, faves, edits, polls in notifs view use base item + ;; timestamp: + (mastodon-tl--field 'created_at + (mastodon-tl--field 'status toot)) + ;; all other toots, inc. boosts/faves in timelines: + ;; (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))) -- cgit v1.2.3 From c55233b45cbbe0d465f3928f185e5d41be5f078f Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Tue, 29 Oct 2024 09:44:53 +0100 Subject: poll transient: checks for expiry, max opts, max length, > 1 opt --- lisp/mastodon-transient.el | 79 +++++++++++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 22 deletions(-) (limited to 'lisp') diff --git a/lisp/mastodon-transient.el b/lisp/mastodon-transient.el index 68d8b24..4d6fb2c 100644 --- a/lisp/mastodon-transient.el +++ b/lisp/mastodon-transient.el @@ -289,10 +289,10 @@ the format fields.X.keyname." ("4" "" "4" :alist-key four :class mastodon-transient-poll-choice)] ;; TODO: display the max number of options or add options cmd ["Update" - ("C-c C-c" "Save and done" mastodon-create-poll-done) - ("C-c C-k" "Delete all" mastodon-clear-poll) ("C-c C-s" "Add another poll choice" mastodon-transient--choice-add) - ("C-x C-k" :info "Revert all")] + ("C-c C-c" "Save and done" mastodon-create-poll-done) + ("C-x C-k" :info "Revert all") + ("C-c C-k" "Delete all" mastodon-clear-poll)] (interactive) (if (not mastodon-active-user) (user-error "User not set") @@ -309,13 +309,32 @@ the format fields.X.keyname." "Update current user profile fields." :transient 'transient--do-exit (interactive (list (transient-args 'mastodon-create-poll))) - ;; FIXME: if - ;; - no options filled in - ;; - no expiry - ;; then offer to cancel or warn / return to transient - (setq tp-transient-settings - (tp-bools-to-strs args)) - (mastodon-toot--update-status-fields)) + (let* ((options (cl-member-if (lambda (x) + (eq (car x) 'one)) + args)) + (opt-vals (cl-loop for x in options + collect (cdr x))) + (lengths (mapcar #'length opt-vals)) + (vals (cl-remove 'nil + (cl-loop for x in args + collect (cdr x)))) + (opts-count (length (cl-remove 'nil opt-vals)))) + ;; this way of checking gets annoying if we want to just cancel out of + ;; the poll (but to actually cancel user should C-g, not C-c C-c): + (if (or (and (< 50 (apply #'max lengths)) + (not (y-or-n-p "Options longer than server max. Proceed? "))) + (and (not (alist-get 'expiry args)) + (not (y-or-n-p "No expiry. Proceed? "))) + (and (not (< 1 opts-count)) + (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) + ;; if we are called with no poll data, do not set: + (unless (not vals) + (setq tp-transient-settings + (tp-bools-to-strs args))) + (mastodon-toot--update-status-fields)))) ;;; CLASSES @@ -324,18 +343,6 @@ the format fields.X.keyname." "An infix option class for our options. We always read.") -(defclass mastodon-transient-opt (tp-option tp-option-var) - (())) - -(defclass mastodon-transient-poll-bool (tp-bool tp-option-var) - ()) - -(defclass mastodon-transient-poll-choice (tp-option-str tp-option-var) - ()) - -(defclass mastodon-transient-expiry (tp-option tp-option-var) - ()) - (cl-defmethod transient-init-value ((obj mastodon-transient-field)) "Initialize value of OBJ." (let* ((prefix-val (oref transient--prefix value))) @@ -365,6 +372,34 @@ CONS is a cons of the form \"(fields.1.name . val)\"." (not (equal (cdr cons) (alist-get server-key server-elt nil nil #'string=))))) +(defclass mastodon-transient-opt (tp-option tp-option-var) + (())) + +(defclass mastodon-transient-poll-bool (tp-bool tp-option-var) + ()) + +(defclass mastodon-transient-poll-choice (tp-option-str tp-option-var) + ()) + +(cl-defmethod transient-infix-read ((obj mastodon-transient-poll-choice)) + "Reader function for OBJ, a poll expiry." + (let* ((value (transient-infix-value obj)) + (prompt (transient-prompt obj)) + (str (read-string prompt (cdr value))) + (max (mastodon-transient-max-poll-opt-chars))) + (if (not (> (length str) max)) + str + (if (not + (y-or-n-p + (format "Poll option too long for server (%s/%s chars), retry?" + (length str) max))) + str + (oset obj value str) + (transient-infix-read obj))))) + +(defclass mastodon-transient-expiry (tp-option tp-option-var) + ()) + (cl-defmethod transient-infix-read ((_obj mastodon-transient-expiry)) "Reader function for OBJ, a poll expiry." (cdr (mastodon-toot--read-poll-expiry))) -- cgit v1.2.3 From 1679216a14ba33ac7b5e16b9784d968da6bd63fe Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Tue, 29 Oct 2024 10:09:02 +0100 Subject: poll: choice add: uncomment max poll opts check --- lisp/mastodon-transient.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lisp') diff --git a/lisp/mastodon-transient.el b/lisp/mastodon-transient.el index 4d6fb2c..bb92f56 100644 --- a/lisp/mastodon-transient.el +++ b/lisp/mastodon-transient.el @@ -251,8 +251,8 @@ the format fields.X.keyname." (7 'seven) (8 'eight) (9 'nine)))) - (if (or ;(>= choice-count (mastodon-transient-max-poll-opts)) - (= choice-count 9)) + (if (or (>= choice-count (mastodon-transient-max-poll-opts)) + (= choice-count 9)) ;; FIXME when we hit '10', we get a binding clash with '1'. :/ (message "Max choices reached") (transient-append-suffix -- cgit v1.2.3 From 409a7b1bddf80ca155a3d75afb8bb204341c086d Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Tue, 29 Oct 2024 10:11:25 +0100 Subject: poll transient: display predicate for add choice --- lisp/mastodon-transient.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lisp') diff --git a/lisp/mastodon-transient.el b/lisp/mastodon-transient.el index bb92f56..00d9acf 100644 --- a/lisp/mastodon-transient.el +++ b/lisp/mastodon-transient.el @@ -289,7 +289,8 @@ the format fields.X.keyname." ("4" "" "4" :alist-key four :class mastodon-transient-poll-choice)] ;; TODO: display the max number of options or add options cmd ["Update" - ("C-c C-s" "Add another poll choice" mastodon-transient--choice-add) + ("C-c C-s" "Add another poll choice" mastodon-transient--choice-add + :if (lambda () (< 4 (mastodon-transient-max-poll-opts)))) ("C-c C-c" "Save and done" mastodon-create-poll-done) ("C-x C-k" :info "Revert all") ("C-c C-k" "Delete all" mastodon-clear-poll)] -- cgit v1.2.3