aboutsummaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp')
-rw-r--r--lisp/mastodon-search.el4
-rw-r--r--lisp/mastodon-tl.el330
-rw-r--r--lisp/mastodon-toot.el64
-rw-r--r--lisp/mastodon-views.el26
-rw-r--r--lisp/mastodon.el2
5 files changed, 269 insertions, 157 deletions
diff --git a/lisp/mastodon-search.el b/lisp/mastodon-search.el
index 9b3641b..8cfa3cb 100644
--- a/lisp/mastodon-search.el
+++ b/lisp/mastodon-search.el
@@ -191,7 +191,9 @@ user's profile note. This is also called by
`mastodon-tl--get-follow-suggestions' and
`mastodon-profile--insert-follow-requests'."
(mapc (lambda (acct)
- (insert (mastodon-search--propertize-user acct note)))
+ (insert (concat (mastodon-search--propertize-user acct note)
+ mastodon-tl--horiz-bar
+ "\n\n")))
json))
(defun mastodon-search--propertize-user (acct &optional note)
diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el
index e90be9a..b2b7d27 100644
--- a/lisp/mastodon-tl.el
+++ b/lisp/mastodon-tl.el
@@ -1090,117 +1090,6 @@ HELP-ECHO, DISPLAY, and FACE are the text properties to add."
(concat help-echo "\nC-RET: play " type " with mpv"))))
-;;; INSERT TOOTS
-
-(defun mastodon-tl--content (toot)
- "Retrieve text content from TOOT.
-Runs `mastodon-tl--render-text' and fetches poll or media."
- (let* ((content (mastodon-tl--field 'content toot))
- (reblog (alist-get 'reblog toot))
- (poll-p (if reblog
- (alist-get 'poll reblog)
- (alist-get 'poll toot))))
- (concat
- (mastodon-tl--render-text content toot)
- (when poll-p
- (mastodon-tl--get-poll toot))
- (mastodon-tl--media toot))))
-
-(defun mastodon-tl--insert-status (toot body author-byline action-byline
- &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.
-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-boosted'.
-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."
- (let ((start-pos (point)))
- (insert
- (propertize
- (concat "\n"
- body
- " \n"
- (mastodon-tl--byline toot author-byline action-byline detailed-p))
- 'toot-id (or id ; notification's own id
- (alist-get 'id toot)) ; toot id
- 'base-toot-id (mastodon-tl--toot-id
- ;; 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
- 'base-toot base-toot)
- "\n")
- (when mastodon-tl--display-media-p
- (mastodon-media--inline-images start-pos (point)))))
-
-;; from mastodon-alt.el:
-(defun mastodon-tl--toot-for-stats (&optional toot)
- "Return the TOOT on which we want to extract stats.
-If no TOOT is given, the one at point is considered."
- (let* ((original-toot (or toot (get-text-property (point) 'toot-json)))
- (toot (or (alist-get 'status original-toot)
- (when (alist-get 'type original-toot)
- original-toot)
- (alist-get 'reblog original-toot)
- original-toot))
- (type (alist-get 'type (or toot))))
- (unless (member type '("follow" "follow_request"))
- toot)))
-
-(defun mastodon-tl--toot-stats (toot)
- "Return a right aligned string (using display align-to).
-String is filled with TOOT statistics (boosts, favs, replies).
-When the TOOT is a reblog (boost), statistics from reblogged
-toots are returned.
-To disable showing the stats, customize
-`mastodon-tl--show-stats'."
- (when-let ((toot (mastodon-tl--toot-for-stats toot)))
- (let* ((favourites-count (alist-get 'favourites_count toot))
- (favourited (equal 't (alist-get 'favourited toot)))
- (faves-prop (propertize (format "%s" favourites-count)
- 'favourites-count favourites-count))
- (boosts-count (alist-get 'reblogs_count toot))
- (boosted (equal 't (alist-get 'reblogged toot)))
- (boosts-prop (propertize (format "%s" boosts-count)
- 'boosts-count boosts-count))
- (replies-count (alist-get 'replies_count toot))
- (favourites (format "%s %s" faves-prop ;favourites-count
- (mastodon-tl--symbol 'favourite)))
- (boosts (format "%s %s" boosts-prop ;boosts-count
- (mastodon-tl--symbol 'boost)))
- (replies (format "%s %s" replies-count (mastodon-tl--symbol 'reply)))
- (status (concat
- (propertize favourites
- 'favourited-p favourited
- 'favourites-field t
- 'face font-lock-comment-face)
- (propertize " | " 'face font-lock-comment-face)
- (propertize boosts
- 'boosted-p boosted
- 'boosts-field t
- 'face font-lock-comment-face)
- (propertize " | " 'face font-lock-comment-face)
- (propertize replies
- 'replies-field t
- 'replies-count replies-count
- 'face font-lock-comment-face)))
- (status (concat
- (propertize " " 'display `(space :align-to (- right ,(+ (length status) 7))))
- status)))
- status)))
-
-
;; POLLS
(defun mastodon-tl--get-poll (toot)
@@ -1359,7 +1248,115 @@ in which case play first video or gif from current toot."
(message "no moving image here?"))))
-;; INSERT TOOTS
+;;; INSERT TOOTS
+
+(defun mastodon-tl--content (toot)
+ "Retrieve text content from TOOT.
+Runs `mastodon-tl--render-text' and fetches poll or media."
+ (let* ((content (mastodon-tl--field 'content toot))
+ (reblog (alist-get 'reblog toot))
+ (poll-p (if reblog
+ (alist-get 'poll reblog)
+ (alist-get 'poll toot))))
+ (concat
+ (mastodon-tl--render-text content toot)
+ (when poll-p
+ (mastodon-tl--get-poll toot))
+ (mastodon-tl--media toot))))
+
+(defun mastodon-tl--insert-status (toot body author-byline action-byline
+ &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.
+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-boosted'.
+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."
+ (let ((start-pos (point)))
+ (insert
+ (propertize
+ (concat "\n"
+ body
+ " \n"
+ (mastodon-tl--byline toot author-byline action-byline detailed-p))
+ 'toot-id (or id ; notification's own id
+ (alist-get 'id toot)) ; toot id
+ 'base-toot-id (mastodon-tl--toot-id
+ ;; 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
+ 'base-toot base-toot)
+ "\n")
+ (when mastodon-tl--display-media-p
+ (mastodon-media--inline-images start-pos (point)))))
+
+;; from mastodon-alt.el:
+(defun mastodon-tl--toot-for-stats (&optional toot)
+ "Return the TOOT on which we want to extract stats.
+If no TOOT is given, the one at point is considered."
+ (let* ((original-toot (or toot (get-text-property (point) 'toot-json)))
+ (toot (or (alist-get 'status original-toot)
+ (when (alist-get 'type original-toot)
+ original-toot)
+ (alist-get 'reblog original-toot)
+ original-toot))
+ (type (alist-get 'type (or toot))))
+ (unless (member type '("follow" "follow_request"))
+ toot)))
+
+(defun mastodon-tl--toot-stats (toot)
+ "Return a right aligned string (using display align-to).
+String is filled with TOOT statistics (boosts, favs, replies).
+When the TOOT is a reblog (boost), statistics from reblogged
+toots are returned.
+To disable showing the stats, customize
+`mastodon-tl--show-stats'."
+ (when-let ((toot (mastodon-tl--toot-for-stats toot)))
+ (let* ((favourites-count (alist-get 'favourites_count toot))
+ (favourited (equal 't (alist-get 'favourited toot)))
+ (faves-prop (propertize (format "%s" favourites-count)
+ 'favourites-count favourites-count))
+ (boosts-count (alist-get 'reblogs_count toot))
+ (boosted (equal 't (alist-get 'reblogged toot)))
+ (boosts-prop (propertize (format "%s" boosts-count)
+ 'boosts-count boosts-count))
+ (replies-count (alist-get 'replies_count toot))
+ (favourites (format "%s %s" faves-prop ;favourites-count
+ (mastodon-tl--symbol 'favourite)))
+ (boosts (format "%s %s" boosts-prop ;boosts-count
+ (mastodon-tl--symbol 'boost)))
+ (replies (format "%s %s" replies-count (mastodon-tl--symbol 'reply)))
+ (status (concat
+ (propertize favourites
+ 'favourited-p favourited
+ 'favourites-field t
+ 'face font-lock-comment-face)
+ (propertize " | " 'face font-lock-comment-face)
+ (propertize boosts
+ 'boosted-p boosted
+ 'boosts-field t
+ 'face font-lock-comment-face)
+ (propertize " | " 'face font-lock-comment-face)
+ (propertize replies
+ 'replies-field t
+ 'replies-count replies-count
+ 'face font-lock-comment-face)))
+ (status (concat
+ (propertize " " 'display `(space :align-to (- right ,(+ (length status) 7))))
+ status)))
+ status)))
(defun mastodon-tl--is-reply (toot)
"Check if the TOOT is a reply to another one (and not boosted)."
@@ -1667,6 +1664,10 @@ webapp"
(reblog (alist-get 'reblog json)))
(if reblog (alist-get 'id reblog) id)))
+(defun mastodon-tl--toot-or-base (json)
+ "Return the base toot or just the toot from toot JSON."
+ (or (alist-get 'reblog json) json))
+
;;; THREADS
@@ -1719,8 +1720,7 @@ view all branches of a thread."
(mastodon-http--api (concat "statuses/" id))
nil
:silent))
- (context (mastodon-http--get-json url nil :silent))
- (marker (make-marker)))
+ (context (mastodon-http--get-json url nil :silent)))
(if (equal (caar toot) 'error)
(message "Error: %s" (cdar toot))
(when (member (alist-get 'type toot) '("reblog" "favourite"))
@@ -1731,7 +1731,8 @@ view all branches of a thread."
;; if we have a thread:
(progn
(with-current-buffer (get-buffer-create buffer)
- (let ((inhibit-read-only t))
+ (let ((inhibit-read-only t)
+ (marker (make-marker)))
(switch-to-buffer buffer)
(erase-buffer)
(mastodon-mode)
@@ -1743,10 +1744,10 @@ view all branches of a thread."
(move-marker marker (point))
;; print re-fetched toot:
(mastodon-tl--toot toot :detailed-p)
- (mastodon-tl--timeline (alist-get 'descendants context))))
- ;; put point at the toot:
- (goto-char (marker-position marker))
- (mastodon-tl--goto-next-toot))
+ (mastodon-tl--timeline (alist-get 'descendants context))
+ ;; put point at the toot:
+ (goto-char (marker-position marker))
+ (mastodon-tl--goto-next-toot))))
;; else just print the lone toot:
(mastodon-tl--single-toot id)))))))
@@ -2078,7 +2079,7 @@ If TAG is provided, unfollow it."
(defun mastodon-tl--list-followed-tags (&optional prefix)
"List followed tags. View timeline of tag user choses.
-Prefix is sent to `mastodon-tl--get-tag-timeline', which see."
+PREFIX is sent to `mastodon-tl--get-tag-timeline', which see."
(interactive "p")
(let* ((followed-tags-json (mastodon-tl--followed-tags))
(tags (mastodon-tl--map-alist 'name followed-tags-json))
@@ -2089,7 +2090,7 @@ Prefix is sent to `mastodon-tl--get-tag-timeline', which see."
(defun mastodon-tl--followed-tags-timeline (&optional prefix)
"Open a timeline of all your followed tags.
-Prefix is sent to `mastodon-tl--show-tag-timeline', which see."
+PREFIX is sent to `mastodon-tl--show-tag-timeline', which see."
(interactive "p")
(let* ((followed-tags-json (mastodon-tl--followed-tags))
(tags (mastodon-tl--map-alist 'name followed-tags-json)))
@@ -2107,6 +2108,93 @@ The suggestions are from followed tags, but any other tags are also allowed."
(mastodon-tl--show-tag-timeline prefix selection)))
+;;; REPORT TO MODERATORS
+
+(defun mastodon-tl--instance-rules ()
+ "Return the rules of the user's instance."
+ (let ((url (mastodon-http--api "instance/rules")))
+ (mastodon-http--get-json url nil :silent)))
+
+(defun mastodon-tl--report-params (account toot)
+ "Query user and return report params alist.
+ACCOUNT and TOOT are the data to use."
+ (let* ((account-id (mastodon-profile--account-field account 'id))
+ (comment (read-string "Add comment [optional]: "))
+ (toot-id (when (y-or-n-p "Also report status at point? ")
+ (mastodon-tl--toot-id toot))) ; base toot if poss
+ (forward-p (when (y-or-n-p "Forward to remote admin? ") "true"))
+ (rules (when (y-or-n-p "Cite a rule broken? ")
+ (mastodon-tl--read-rules-ids)))
+ (cat (unless rules (if (y-or-n-p "Spam? ") "spam" "other"))))
+ (mastodon-tl--report-build-params account-id comment toot-id
+ forward-p cat rules)))
+
+(defun mastodon-tl--report-build-params
+ (account-id comment toot-id forward-p cat &optional rules)
+ "Build the parameters alist based on user responses.
+ACCOUNT-ID, COMMENT, TOOT-ID, FORWARD-P, CAT, and RULES are all from
+`mastodon-tl--report-params', which see."
+ (let ((params `(("account_id" . ,account-id)
+ ,(when comment
+ `("comment" . ,comment))
+ ,(when toot-id
+ `("status_ids[]" . ,toot-id))
+ ,(when forward-p
+ `("forward" . ,forward-p))
+ ,(when cat
+ `("category" . ,cat)))))
+ (when rules
+ (let ((alist
+ (mastodon-http--build-array-params-alist "rule_ids[]" rules)))
+ (mapc (lambda (x)
+ (push x params))
+ alist)))
+ ;; FIXME: the above approach adds nils to your params.
+ (setq params (delete nil params))
+ params))
+
+(defun mastodon-tl--report-to-mods ()
+ "Report the author of the toot at point to your instance moderators.
+Optionally report the toot at point, add a comment, cite rules
+that have been broken, forward the report to the remove admin,
+report the account for spam."
+ (interactive)
+ (mastodon-tl--do-if-toot
+ (when (y-or-n-p "Report author of toot at point?")
+ (let* ((url (mastodon-http--api "reports"))
+ (toot (mastodon-tl--toot-or-base
+ (mastodon-tl--property 'toot-json :no-move)))
+ (account (alist-get 'account toot))
+ (handle (alist-get 'acct account))
+ (params (mastodon-tl--report-params account toot))
+ (response (mastodon-http--post url params)))
+ ;; (setq masto-report-response response)
+ (mastodon-http--triage response
+ (lambda ()
+ (message "User %s reported!" handle)))))))
+
+(defvar crm-separator)
+
+(defun mastodon-tl--map-rules-alist (rules)
+ "Return an alist of the text and id fields of RULES."
+ (mapcar (lambda (x)
+ (let-alist x
+ (cons .text .id)))
+ rules))
+
+(defun mastodon-tl--read-rules-ids ()
+ "Prompt for a list of instance rules and return a list of selected ids."
+ (let* ((rules (mastodon-tl--instance-rules))
+ (alist (mastodon-tl--map-rules-alist rules))
+ (crm-separator (replace-regexp-in-string "," "|" crm-separator))
+ (choices (completing-read-multiple
+ "rules [TAB for options, | to separate]: "
+ alist nil :match)))
+ (mapcar (lambda (x)
+ (alist-get x alist nil nil 'equal))
+ choices)))
+
+
;;; UPDATING, etc.
(defun mastodon-tl--more-json (endpoint id)
diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el
index 35e6eab..474337b 100644
--- a/lisp/mastodon-toot.el
+++ b/lisp/mastodon-toot.el
@@ -219,13 +219,20 @@ send.")
"\\([(\n\t ]\\|^\\)"
"\\(?2:@[0-9a-zA-Z._-]+" ; a handle
"\\(@[^ \n\t]*\\)?\\)" ; with poss domain, * = allow only @
- "\\b"))
+ "\\(\\b\\|'\\)")) ; boundary or ' char
(defvar mastodon-toot-tag-regex
(concat
;; preceding bracket, space or bol [boundary doesn't work with #]
"\\([(\n\t ]\\|^\\)"
"\\(?2:#[0-9a-zA-Z_]+\\)" ; tag
+ "\\(\\b\\|'\\)")) ; boundary or ' char
+
+(defvar mastodon-toot-url-regex
+ ;; adapted from ffap-url-regexp
+ (concat
+ "\\(?2:\\(news\\(post\\)?:\\|mailto:\\|file:\\|\\(ftp\\|https?\\|telnet\\|gopher\\|www\\|wais\\)://\\)" ; uri prefix
+ "[^ \n\t]*\\)" ; any old thing that's, i.e. we allow invalid/unwise chars
"\\b")) ; boundary
(defvar mastodon-toot-mode-map
@@ -764,6 +771,13 @@ to `emojify-user-emojis', and the emoji data is updated."
`(("poll[multiple]" . ,(symbol-name (plist-get mastodon-toot-poll :multi))))
`(("poll[hide_totals]" . ,(symbol-name (plist-get mastodon-toot-poll :hide))))))
+(defun mastodon-toot--read-cw-string ()
+ "Read a content warning from the minibuffer."
+ (when (and (not (mastodon-toot--empty-p))
+ mastodon-toot--content-warning)
+ (read-string "Warning: "
+ mastodon-toot--content-warning-from-reply-or-redraft)))
+
(defun mastodon-toot--send ()
"POST contents of new-toot buffer to Mastodon instance and kill buffer.
If media items have been attached and uploaded with
@@ -781,16 +795,13 @@ instance to edit a toot."
(mastodon-http--api (format "statuses/%s"
edit-id))
(mastodon-http--api "statuses")))
- (spoiler (when (and (not (mastodon-toot--empty-p))
- mastodon-toot--content-warning)
- (read-string "Warning: "
- mastodon-toot--content-warning-from-reply-or-redraft)))
+ (cw (mastodon-toot--read-cw-string))
(args-no-media (append `(("status" . ,toot)
("in_reply_to_id" . ,mastodon-toot--reply-to-id)
("visibility" . ,mastodon-toot--visibility)
("sensitive" . ,(when mastodon-toot--content-nsfw
(symbol-name t)))
- ("spoiler_text" . ,spoiler)
+ ("spoiler_text" . ,cw)
("language" . ,mastodon-toot--language))
;; Pleroma instances can't handle null-valued
;; scheduled_at args, so only add if non-nil
@@ -816,8 +827,8 @@ instance to edit a toot."
(length mastodon-toot--media-attachment-ids)))))
(message "Something is wrong with your uploads. Wait for them to complete or try again."))
((and mastodon-toot--max-toot-chars
- (> (mastodon-toot--count-toot-chars toot) mastodon-toot--max-toot-chars))
- (message "Looks like your toot is longer than that maximum allowed length."))
+ (> (mastodon-toot--count-toot-chars toot cw) mastodon-toot--max-toot-chars))
+ (message "Looks like your toot (inc. CW) is longer than that maximum allowed length."))
((mastodon-toot--empty-p)
(message "Empty toot. Cowardly refusing to post this."))
(t
@@ -944,7 +955,6 @@ eg. \"feduser@fed.social\" -> \"@feduser@fed.social\"."
The mentioned users look like this:
Local user (including the logged in): `username`.
Federated user: `username@host.co`."
- (interactive)
(let* ((boosted (mastodon-tl--field 'reblog status))
(mentions
(if boosted
@@ -1235,8 +1245,18 @@ MAX is the maximum number set by their instance."
(defun mastodon-toot--read-poll-options (count length)
"Read a list of options for poll with COUNT options.
LENGTH is the maximum character length allowed for a poll option."
- (cl-loop for x from 1 to count
- collect (read-string (format "Poll option [%s/%s] [max %s chars]: " x count length))))
+ (let* ((choices
+ (cl-loop for x from 1 to count
+ collect (read-string
+ (format "Poll option [%s/%s] [max %s chars]: "
+ x count length))))
+ (longest (cl-reduce #'max (mapcar #'length choices))))
+ (if (> longest length)
+ (progn
+ (message "looks like you went over the max length. Try again.")
+ (sleep-for 2)
+ (mastodon-toot--read-poll-options count length))
+ choices)))
(defun mastodon-toot--read-poll-expiry ()
"Prompt for a poll expiry time."
@@ -1434,12 +1454,14 @@ REPLY-TEXT is the text of the toot being replied to."
'read-only "Edit your message below."
'toot-post-header t)
(if reply-text
- (propertize (truncate-string-to-width
- (mastodon-tl--render-text reply-text)
- mastodon-toot-orig-in-reply-length)
- 'read-only "Edit your message below."
- 'toot-post-header t
- 'face '(variable-pitch :foreground "#7c6f64"))
+ (concat
+ (propertize (truncate-string-to-width
+ (mastodon-tl--render-text reply-text)
+ mastodon-toot-orig-in-reply-length)
+ 'read-only "Edit your message below."
+ 'toot-post-header t
+ 'face '(variable-pitch :foreground "#7c6f64"))
+ "\n")
"")
(propertize
(concat divider "\n")
@@ -1529,7 +1551,7 @@ REPLY-JSON is the full JSON of the toot being replied to."
(list 'invisible (not mastodon-toot--content-warning)
'face 'mastodon-cw-face)))))
-(defun mastodon-toot--count-toot-chars (toot-string)
+(defun mastodon-toot--count-toot-chars (toot-string &optional cw)
"Count the characters in TOOT-STRING.
URLs always = 23, and domain names of handles are not counted.
This is how mastodon does it."
@@ -1547,7 +1569,8 @@ This is how mastodon does it."
"\\b")
nil t)
(replace-match (match-string 2))) ; replace with handle only
- (length (buffer-substring (point-min) (point-max)))))
+ (+ (length cw)
+ (length (buffer-substring (point-min) (point-max))))))
(defun mastodon-toot--save-toot-text (&rest _args)
"Save the current toot text in `mastodon-toot-current-toot-text'.
@@ -1615,6 +1638,9 @@ Added to `after-change-functions'."
(cdr header-region))
(mastodon-toot--propertize-item mastodon-toot-handle-regex
'mastodon-display-name-face
+ (cdr header-region))
+ (mastodon-toot--propertize-item mastodon-toot-url-regex
+ 'link
(cdr header-region)))))
(defun mastodon-toot--propertize-item (regex face start)
diff --git a/lisp/mastodon-views.el b/lisp/mastodon-views.el
index de498f3..8064282 100644
--- a/lisp/mastodon-views.el
+++ b/lisp/mastodon-views.el
@@ -893,26 +893,20 @@ IND is the optional indentation level to print at."
(defun mastodon-views--print-instance-rules-or-fields (alist)
"Print ALIST of instance rules or contact account or emoji fields."
- (let ((key (cond ((alist-get 'id alist)
- 'id)
- ((alist-get 'name alist)
- 'name)
- ((alist-get 'shortcode alist)
- 'shortcode)))
- (value (cond ((alist-get 'id alist)
- 'text)
- ((alist-get 'value alist)
- 'value)
- ((alist-get 'url alist)
- 'url))))
+ (let ((key (or (alist-get 'id alist)
+ (alist-get 'name alist)
+ (alist-get 'shortcode alist)))
+ (value (or (alist-get 'text alist)
+ (alist-get 'value alist)
+ (alist-get 'url alist))))
(indent-to 4)
(insert
(format "%-5s: "
- (propertize (alist-get key alist)
- 'face '(:underline t)))
- (mastodon-views--newline-if-long (alist-get value alist))
+ (propertize key)
+ 'face '(:underline t))
+ (mastodon-views--newline-if-long value)
(format "%s" (mastodon-tl--render-text
- (alist-get value alist)))
+ value))
"\n")))
(defun mastodon-views--newline-if-long (el)
diff --git a/lisp/mastodon.el b/lisp/mastodon.el
index b384a87..980e31f 100644
--- a/lisp/mastodon.el
+++ b/lisp/mastodon.el
@@ -82,6 +82,7 @@
(autoload 'mastodon-tl--unblock-user "mastodon-tl")
(autoload 'mastodon-tl--unfollow-user "mastodon-tl")
(autoload 'mastodon-tl--unmute-user "mastodon-tl")
+(autoload 'mastodon-tl--report-to-mods "mastodon-tl")
(autoload 'mastodon-tl--update "mastodon-tl")
(autoload 'mastodon-toot--edit-toot-at-point "mastodon-toot")
(when (require 'lingva nil :no-error)
@@ -199,6 +200,7 @@ Use. e.g. \"%c\" for your locale's date and time format."
(define-key map (kbd "C-S-B") #'mastodon-tl--unblock-user)
(define-key map (kbd "M") #'mastodon-tl--mute-user)
(define-key map (kbd "C-S-M") #'mastodon-tl--unmute-user)
+ (define-key map (kbd "Z") #'mastodon-tl--report-to-mods)
;; own profile
(define-key map (kbd "O") #'mastodon-profile--my-profile)
(define-key map (kbd "U") #'mastodon-profile--update-user-profile-note)