aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lisp/mastodon-notifications.el6
-rw-r--r--lisp/mastodon-tl.el78
-rw-r--r--lisp/mastodon-toot.el45
3 files changed, 67 insertions, 62 deletions
diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el
index 1ecdbfb..7c5d40b 100644
--- a/lisp/mastodon-notifications.el
+++ b/lisp/mastodon-notifications.el
@@ -221,7 +221,7 @@ Status notifications are given when
(defun mastodon-notifications--insert-status (toot body
author-byline action-byline id
- &optional parent-toot)
+ &optional base-toot)
"Display the content and byline of timeline element TOOT.
BODY will form the section of the toot above the byline.
@@ -236,10 +236,10 @@ takes a single function. By default it is
`mastodon-tl--byline-boosted'.
ID is the notification's own id, which is attached as a property.
-If the status is a favourite or a boost, PARENT-TOOT is the JSON
+If the status is a favourite or a boost, BASE-TOOT is the JSON
of the toot responded to."
(when toot ; handle rare blank notif server bug
- (mastodon-tl--insert-status toot body author-byline action-byline id parent-toot)))
+ (mastodon-tl--insert-status toot body author-byline action-byline id base-toot)))
(defun mastodon-notifications--by-type (note)
"Filters NOTE for those listed in `mastodon-notifications--types-alist'."
diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el
index b352c6d..86a7b56 100644
--- a/lisp/mastodon-tl.el
+++ b/lisp/mastodon-tl.el
@@ -106,12 +106,6 @@ width fonts when rendering HTML text"))
:group 'mastodon-tl
:type '(boolean :tag "Whether to display user avatars in timelines"))
-;; (defvar mastodon-tl--show-avatars nil
-;; (if (version< emacs-version "27.1")
-;; (image-type-available-p 'imagemagick)
-;; (image-transforms-p))
-;; "A boolean value stating whether to show avatars in timelines.")
-
(defvar-local mastodon-tl--update-point nil
"When updating a mastodon buffer this is where new toots will be inserted.
@@ -953,7 +947,7 @@ Runs `mastodon-tl--render-text' and fetches poll or media."
(mastodon-tl--media toot))))
(defun mastodon-tl--insert-status (toot body author-byline action-byline
- &optional id parent-toot detailed-p)
+ &optional id base-toot detailed-p)
"Display the content and byline of timeline element TOOT.
BODY will form the section of the toot above the byline.
@@ -965,9 +959,10 @@ such as boosting favouriting and following to the byline. It also
takes a single function. By default it is
`mastodon-tl--byline-boosted'.
-ID is that of the toot, which is attached as a property if it is
-a notification. If the status is a favourite or a boost,
-PARENT-TOOT is the JSON of the toot responded to.
+ID is that of the status if it is a notification, which is
+attached as a `toot-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."
@@ -978,13 +973,16 @@ this just means displaying toot client."
body
" \n"
(mastodon-tl--byline toot author-byline action-byline detailed-p))
- 'toot-id (or id ; for notifications
- (alist-get 'id toot))
+ 'toot-id (or id ; notification's own id
+ (alist-get 'id toot)) ; toot id
'base-toot-id (mastodon-tl--toot-id
- ;; if a favourite/boost notif, get ID of toot responded to:
- (or parent-toot toot))
+ ;; if status is a notif, get id from base-toot
+ ;; (-tl--toot-id toot) will not work here:
+ (or base-toot
+ ;; else normal toot with reblog check:
+ toot))
'toot-json toot
- 'parent-toot parent-toot)
+ 'base-toot base-toot)
"\n")
(when mastodon-tl--display-media-p
(mastodon-media--inline-images start-pos (point)))))
@@ -1283,20 +1281,11 @@ webapp"
(reblog (alist-get 'reblog json)))
(if reblog (alist-get 'id reblog) id)))
-(defun mastodon-tl--single-toot (&optional id)
+(defun mastodon-tl--single-toot (id)
"View toot at point in separate buffer.
ID is that of the toot to view."
(interactive)
- (let* ((id
- (or id
- (if (equal (mastodon-tl--get-endpoint) "notifications")
- ;; for boosts/faves:
- (if (mastodon-tl--property 'parent-toot)
- (mastodon-tl--as-string (mastodon-tl--toot-id
- (mastodon-tl--property 'parent-toot)))
- (mastodon-tl--property 'base-toot-id))
- (mastodon-tl--property 'base-toot-id))))
- (buffer (format "*mastodon-toot-%s*" id))
+ (let* ((buffer (format "*mastodon-toot-%s*" id))
(toot (mastodon-http--get-json
(mastodon-http--api (concat "statuses/" id)))))
(if (equal (caar toot) 'error)
@@ -1312,17 +1301,12 @@ ID is that of the toot to view."
(defun mastodon-tl--thread (&optional id)
"Open thread buffer for toot at point or with ID."
+ ;; NB: this is called by `mastodon-url-lookup', which means it must work
+ ;; without `mastodon-tl--buffer-spec' being set!
+ ;; so avoid calls to `mastodon-tl--property' and friends
(interactive)
- (let* ((id
- (or id
- (if (equal (mastodon-tl--get-endpoint) "notifications")
- ;; for boosts/faves:
- (if (mastodon-tl--property 'parent-toot)
- (mastodon-tl--as-string (mastodon-tl--toot-id
- (mastodon-tl--property 'parent-toot)))
- (mastodon-tl--property 'base-toot-id))
- (mastodon-tl--property 'base-toot-id))))
- (type (mastodon-tl--field 'type (mastodon-tl--property 'toot-json))))
+ (let* ((id (or id (get-text-property (point) 'base-toot-id)))
+ (type (mastodon-tl--field 'type (get-text-property (point) 'toot-json))))
(if (or (string= type "follow_request")
(string= type "follow")) ; no can thread these
(error "No thread")
@@ -1509,16 +1493,28 @@ BRIEF means to show fewer details.
INSTANCE is an instance domain name."
(interactive)
(mastodon-tl--do-if-toot
- (let* ((toot (mastodon-tl--property 'toot-json))
+ (let* ((profile-p (get-text-property (point) 'profile-json))
+ (toot (if profile-p
+ (mastodon-tl--property 'profile-json) ; profile may have 0 toots
+ (mastodon-tl--property 'toot-json)))
(reblog (alist-get 'reblog toot))
(account (or (alist-get 'account reblog)
(alist-get 'account toot)))
- (url (alist-get 'url account))
- (username (alist-get 'username account))
+ (url (if profile-p
+ (alist-get 'url toot) ; profile
+ (alist-get 'url account)))
+ (username (if profile-p
+ (alist-get 'username toot) ;; profile
+ (alist-get 'username account)))
(instance (if instance
(concat "https://" instance)
- (string-remove-suffix (concat "/@" username)
- url)))
+ ;; pleroma URL is https://instance.com/users/username
+ (if (string-suffix-p "users/" (url-basepath url))
+ (string-remove-suffix "/users/"
+ (url-basepath url))
+ ;; mastodon:
+ (string-remove-suffix (concat "/@" username)
+ url))))
(response (mastodon-http--get-json
(if user
(mastodon-http--api "instance")
diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el
index 95eac31..438e887 100644
--- a/lisp/mastodon-toot.el
+++ b/lisp/mastodon-toot.el
@@ -820,16 +820,15 @@ Customize `mastodon-toot-display-orig-in-reply-buffer' to display
text of the toot being replied to in the compose buffer."
(interactive)
(let* ((toot (mastodon-tl--property 'toot-json))
- ;; NB: we cannot use mastodon-tl--property for 'parent-toot
+ ;; NB: we cannot use mastodon-tl--property for 'base-toot
;; because if it doesn't have one, it is fetched from next toot!
;; we also cannot use --field because we need to get a different property first
- (parent (get-text-property (point) 'parent-toot)) ; for new notifs handling
- (id (mastodon-tl--as-string
- (mastodon-tl--field 'id (or parent toot))))
+ (base-toot (get-text-property (point) 'base-toot)) ; for new notifs handling
+ (id (mastodon-tl--as-string (mastodon-tl--field 'id (or base-toot toot))))
(account (mastodon-tl--field 'account toot))
(user (alist-get 'acct account))
- (mentions (mastodon-toot--mentions (or parent toot)))
- (boosted (mastodon-tl--field 'reblog (or parent toot)))
+ (mentions (mastodon-toot--mentions (or base-toot toot)))
+ (boosted (mastodon-tl--field 'reblog (or base-toot toot)))
(booster (when boosted
(alist-get 'acct
(alist-get 'account toot)))))
@@ -857,7 +856,7 @@ text of the toot being replied to in the compose buffer."
;; user in mentions already:
mentions)))
id
- (or parent toot))))
+ (or base-toot toot))))
(defun mastodon-toot--toggle-warning ()
"Toggle `mastodon-toot--content-warning'."
@@ -968,9 +967,18 @@ which is used to attach it to a toot when posting."
collect `(,key . ,o))))
(defun mastodon-toot--fetch-max-poll-options ()
- "Return the maximum number of poll options from the user's instance. "
+ "Return the maximum number of poll options."
+ (mastodon-toot--fetch-poll-field 'max_options))
+
+(defun mastodon-toot--fetch-max-poll-option-chars ()
+ "Return the maximum number of characters a poll option may have."
+ (or (mastodon-toot--fetch-poll-field 'max_characters_per_option)
+ 50)) ; masto default
+
+(defun mastodon-toot--fetch-poll-field (field)
+ "Return FIELD from the poll settings from the user's instance. "
(let* ((instance (mastodon-http--get-json (mastodon-http--api "instance"))))
- (alist-get 'max_options
+ (alist-get field
(alist-get 'polls
(alist-get 'configuration instance)
instance))))
@@ -989,19 +997,20 @@ MAX is the maximum number set by their instance."
(interactive)
;; re length, API docs show a poll 9 options.
(let* ((max-options (mastodon-toot--fetch-max-poll-options))
- (length (mastodon-toot--read-poll-options-count max-options))
+ (count (mastodon-toot--read-poll-options-count max-options))
+ (length (mastodon-toot--fetch-max-poll-option-chars))
(multiple-p (y-or-n-p "Multiple choice? "))
- (options (mastodon-toot--read-poll-options length))
+ (options (mastodon-toot--read-poll-options count length))
(hide-totals (y-or-n-p "Hide votes until poll ends? "))
(expiry (mastodon-toot--get-poll-expiry)))
(setq mastodon-toot-poll
`(:options ,options :length ,length :multi ,multiple-p :hide ,hide-totals :expiry ,expiry))
(message "poll created!")))
-(defun mastodon-toot--read-poll-options (length)
+(defun mastodon-toot--read-poll-options (count length)
"Read a list of options for poll of LENGTH options."
- (cl-loop for x from 1 to length
- collect (read-string (format "Poll option [%s/%s]: " x length))))
+ (cl-loop for x from 1 to count
+ collect (read-string (format "Poll option [%s/%s] [max %s chars]: " x count length))))
(defun mastodon-toot--get-poll-expiry ()
"Prompt for a poll expiry time."
@@ -1253,10 +1262,10 @@ Added to `after-change-functions'."
;; stops all text after a handle or mention being propertized:
(set-text-properties (cdr header-region) (point-max) nil)
;; TODO: confirm allowed hashtag/handle characters:
- (mastodon-toot--propertize-item "#[1-9a-zA-Z_]+"
+ (mastodon-toot--propertize-item "[\n\t ]\\(?2:#[1-9a-zA-Z_]+\\)[\n\t ]"
'success
(cdr header-region))
- (mastodon-toot--propertize-item "@[1-9a-zA-Z._-]+"
+ (mastodon-toot--propertize-item "[\n\t ]\\(?2:@[1-9a-zA-Z._-]+\\)[\n\t ]"
'mastodon-display-name-face
(cdr header-region)))))
@@ -1265,8 +1274,8 @@ Added to `after-change-functions'."
(save-excursion
(goto-char start)
(cl-loop while (search-forward-regexp regex nil :noerror)
- do (add-text-properties (match-beginning 0)
- (match-end 0)
+ do (add-text-properties (match-beginning 2)
+ (match-end 2)
`(face ,face)))))
(defun mastodon-toot-compose-buffer-p ()