aboutsummaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authormarty hiatt <martianhiatus@riseup.net>2024-05-27 19:51:51 +0200
committermarty hiatt <martianhiatus@riseup.net>2024-05-27 19:51:51 +0200
commit476268af7d78d3136d6d6bf11856d0c0d6fd1c7a (patch)
treeb4c4eace33d293f5f511280ee0a11005a80c4980 /lisp
parent49def07b3d9b6f0718ef9402a3808ca01557245e (diff)
parent4c3bdb30b8d0238e8b5900a42938d865e7dc407f (diff)
Merge branch 'develop'
Diffstat (limited to 'lisp')
-rw-r--r--lisp/mastodon-http.el7
-rw-r--r--lisp/mastodon-notifications.el58
-rw-r--r--lisp/mastodon-tl.el132
-rw-r--r--lisp/mastodon-toot.el12
-rw-r--r--lisp/mastodon-views.el2
-rw-r--r--lisp/mastodon.el2
6 files changed, 160 insertions, 53 deletions
diff --git a/lisp/mastodon-http.el b/lisp/mastodon-http.el
index 49c94a4..7ef6f77 100644
--- a/lisp/mastodon-http.el
+++ b/lisp/mastodon-http.el
@@ -47,10 +47,11 @@
(defconst mastodon-http--timeout 15
"HTTP request timeout, in seconds. Has no effect on Emacs < 26.1.")
-(defun mastodon-http--api (endpoint)
- "Return Mastodon API URL for ENDPOINT."
+(defun mastodon-http--api (endpoint &optional version)
+ "Return Mastodon API URL for ENDPOINT.
+Optionally specify VERSION in format vX."
(concat mastodon-instance-url "/api/"
- mastodon-http--api-version "/" endpoint))
+ (or version mastodon-http--api-version) "/" endpoint))
(defun mastodon-http--api-search ()
"Return Mastodon API url for the /search endpoint (v2)."
diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el
index 0e367c9..9b40861 100644
--- a/lisp/mastodon-notifications.el
+++ b/lisp/mastodon-notifications.el
@@ -53,6 +53,25 @@
(autoload 'mastodon-tl--update "mastodon-tl")
(autoload 'mastodon-views--view-follow-requests "mastodon-views")
+(defgroup mastodon-tl nil
+ "Nofications in mastodon.el."
+ :prefix "mastodon-notifications-"
+ :group 'mastodon)
+
+(defcustom mastodon-notifications--profile-note-in-foll-reqs t
+ "When non-nil, show some of a user's profile note in follow
+request notifications."
+ :type '(boolean))
+
+(defcustom mastodon-notifications--profile-note-in-foll-reqs-max-length nil
+ "The maximum character length for display of 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))
+
(defvar mastodon-tl--buffer-spec)
(defvar mastodon-tl--display-media-p)
@@ -186,9 +205,17 @@ Status notifications are given when
(defun mastodon-notifications--format-note (note type)
"Format for a NOTE of TYPE."
- (let ((id (alist-get 'id note))
- (status (mastodon-tl--field 'status note))
- (follower (alist-get 'username (alist-get 'account note))))
+ (let* ((id (alist-get 'id note))
+ (profile-note
+ (when (equal '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))))
(mastodon-notifications--insert-status
;; toot
(cond ((or (equal type 'follow)
@@ -207,14 +234,25 @@ Status notifications are given when
(let ((body (mastodon-tl--clean-tabs-and-nl
(if (mastodon-tl--has-spoiler status)
(mastodon-tl--spoiler status)
- (mastodon-tl--content status)))))
+ (if (equal 'follow-request type)
+ (mastodon-tl--render-text profile-note)
+ (mastodon-tl--content status))))))
(cond ((or (eq type 'follow)
(eq type 'follow-request))
- (propertize (if (equal type 'follow)
- "Congratulations, you have a new follower!"
- (format "You have a follow request from... %s"
- follower))
- 'face 'default))
+ (propertize
+ (if (equal 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
@@ -225,7 +263,7 @@ Status notifications are given when
(equal type 'follow-request)
(equal type 'mention))
'mastodon-tl--byline-author
- (lambda (_status)
+ (lambda (_status &rest args) ; unbreak stuff
(mastodon-tl--byline-author note)))
;; action-byline
(lambda (_status)
diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el
index 6c444d4..db923a4 100644
--- a/lisp/mastodon-tl.el
+++ b/lisp/mastodon-tl.el
@@ -212,6 +212,10 @@ If nil, mastodon.el will instead call `shr-browse-image', which
respects the user's `browse-url' settings."
:type '(boolean))
+(defcustom mastodon-tl--remote-local-domains nil
+ "A list of domains to view the local timelines of using `mastodon-tl--get-remote-local-timeline'."
+ :type '(repeat string))
+
;;; VARIABLES
@@ -463,6 +467,35 @@ With a single prefix ARG, hide replies."
`(("limit" . ,mastodon-tl--timeline-posts-count))
(when (eq arg 4) t)))
+(defun mastodon-tl--get-remote-local-timeline ()
+ "Prompt for an instance domain and try to display its local timeline.
+You can enter any working instance domain. Domains that you want
+to regularly load can be stored in
+`mastodon-tl--remote-local-domains' for easy access with completion.
+Note that some instances do not make their local timelines public, in
+which case this will not work."
+ (interactive)
+ (let* ((domain (completing-read "Domain for remote local tl: "
+ mastodon-tl--remote-local-domains))
+ (params `(("limit" . ,mastodon-tl--timeline-posts-count)
+ ("local" . "true")))
+ (buf (concat "remote-local-" domain))
+ (known (member domain
+ (mastodon-http--get-json
+ (mastodon-http--api "instance/peers")))))
+ ;; condition-case doesn't work here, so i added basic error handling to
+ ;; `mastodon-tl--init*' instead
+ (if (not known)
+ (when (y-or-n-p
+ "Domain appears unknown to your instance. Proceed?")
+ ;; TODO: refactor these calls:
+ (mastodon-tl--init buf
+ "timelines/public" 'mastodon-tl--timeline nil
+ params nil domain))
+ (mastodon-tl--init buf
+ "timelines/public" 'mastodon-tl--timeline nil
+ params nil domain))))
+
(defun mastodon-tl--get-local-timeline (&optional prefix)
"Open local timeline.
With a single PREFIX arg, hide-replies.
@@ -520,9 +553,10 @@ Do so if type of status at poins is not follow_request/follow."
(string= type "follow")) ; no counts for these
(message "%s" (mastodon-tl--property 'help-echo :no-move))))))
-(defun mastodon-tl--byline-author (toot &optional avatar)
+(defun mastodon-tl--byline-author (toot &optional avatar domain)
"Propertize author of TOOT.
-With arg AVATAR, include the account's avatar image."
+With arg AVATAR, include the account's avatar image.
+When DOMAIN, force inclusion of user's domain in their handle."
(let-alist toot
(concat
;; avatar insertion moved up to `mastodon-tl--byline' by default to be
@@ -534,6 +568,7 @@ With arg AVATAR, include the account's avatar image."
(image-type-available-p 'imagemagick)
(image-transforms-p)))
(mastodon-media--get-avatar-rendering .account.avatar))
+ ;; username:
(propertize (if (not (string-empty-p .account.display_name))
.account.display_name
.account.username)
@@ -549,8 +584,14 @@ With arg AVATAR, include the account's avatar image."
(unless (or (string-suffix-p "-followers*" (buffer-name))
(string-suffix-p "-following*" (buffer-name)))
(mastodon-tl--format-byline-help-echo toot)))
+ ;; handle:
" ("
- (propertize (concat "@" .account.acct)
+ (propertize (concat "@" .account.acct
+ (if domain
+ (concat "@"
+ (url-host
+ (url-generic-parse-url .account.url)))
+ ""))
'face 'mastodon-handle-face
'mouse-face 'highlight
'mastodon-tab-stop 'user-handle
@@ -629,7 +670,7 @@ LETTER is a string, F for favourited, B for boosted, or K for bookmarked."
'help-echo (format "You have %s this status."
help-string)))))
-(defun mastodon-tl--byline (toot author-byline action-byline &optional detailed-p)
+(defun mastodon-tl--byline (toot author-byline action-byline &optional detailed-p domain)
"Generate byline for TOOT.
AUTHOR-BYLINE is a function for adding the author portion of
the byline that takes one variable.
@@ -637,7 +678,8 @@ 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-boosted'.
DETAILED-P means display more detailed info. For now
-this just means displaying toot client."
+this just means displaying toot client.
+When DOMAIN, force inclusion of user's domain in their handle."
(let* ((created-time
;; bosts and faves in notifs view
;; (makes timestamps be for the original toot not the boost/fave):
@@ -685,7 +727,7 @@ this just means displaying toot client."
(concat
;; we propertize help-echo format faves for author name
;; in `mastodon-tl--byline-author'
- (funcall author-byline toot)
+ (funcall author-byline toot nil domain)
;; visibility:
(cond ((equal visibility "direct")
(propertize (concat " " (mastodon-tl--symbol 'direct))
@@ -1413,7 +1455,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 detailed-p thread)
+ &optional id base-toot detailed-p thread domain)
"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
@@ -1429,13 +1471,15 @@ 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."
+THREAD means the status will be displayed in a thread view.
+When DOMAIN, force inclusion of user's domain in their handle."
(let* ((start-pos (point))
(reply-to-id (alist-get 'in_reply_to_id toot))
(after-reply-status-p
(when (and thread reply-to-id)
(mastodon-tl--after-reply-status reply-to-id)))
(type (alist-get 'type toot)))
+ ;; body:
(insert
(propertize
(concat
@@ -1451,7 +1495,8 @@ THREAD means the status will be displayed in a thread view."
'wrap-prefix bar))
body)
" \n"
- (mastodon-tl--byline toot author-byline action-byline detailed-p))
+ ;; byline:
+ (mastodon-tl--byline toot author-byline action-byline detailed-p domain))
'item-type 'toot
'item-id (or id ; notification's own id
(alist-get 'id toot)) ; toot id
@@ -1528,25 +1573,27 @@ To disable showing the stats, customize
(and (null (mastodon-tl--field 'in_reply_to_id toot))
(not (mastodon-tl--field 'rebloged toot))))
-(defun mastodon-tl--toot (toot &optional detailed-p thread)
+(defun mastodon-tl--toot (toot &optional detailed-p thread domain)
"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."
+THREAD means the status will be displayed in a thread view.
+When DOMAIN, force inclusion of user's domain in their handle."
(mastodon-tl--insert-status
toot
(mastodon-tl--clean-tabs-and-nl (if (mastodon-tl--has-spoiler toot)
(mastodon-tl--spoiler toot)
(mastodon-tl--content toot)))
'mastodon-tl--byline-author 'mastodon-tl--byline-boosted
- nil nil detailed-p thread))
+ nil nil detailed-p thread domain))
-(defun mastodon-tl--timeline (toots &optional thread)
+(defun mastodon-tl--timeline (toots &optional thread domain)
"Display each toot in TOOTS.
This function removes replies if user required.
-THREAD means the status will be displayed in a thread view."
+THREAD means the status will be displayed in a thread view.
+When DOMAIN, force inclusion of user's domain in their handle."
(mapc (lambda (toot)
- (mastodon-tl--toot toot nil thread))
+ (mastodon-tl--toot toot nil thread domain))
;; hack to *not* filter replies on profiles:
(if (eq (mastodon-tl--get-buffer-type) 'profile-statuses)
toots
@@ -1679,6 +1726,8 @@ call this function after it is set or use something else."
'profile-statuses-no-replies)
((string-suffix-p "only-media*" buffer-name)
'profile-statuses-only-media)
+ ((string-match-p "-tagged-" buffer-name)
+ 'profile-statuses-tagged)
((mastodon-tl--endpoint-str-= "statuses" :suffix)
'profile-statuses)
;; profile followers
@@ -2788,14 +2837,19 @@ This location is defined by a non-nil value of
;;; LOADING TIMELINES
(defun mastodon-tl--init (buffer-name endpoint update-function
- &optional headers params hide-replies)
+ &optional headers params hide-replies
+ instance)
"Initialize BUFFER-NAME with timeline targeted by ENDPOINT asynchronously.
UPDATE-FUNCTION is used to recieve more toots.
HEADERS means to also collect the response headers. Used for paginating
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."
- (let ((url (mastodon-http--api endpoint))
+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."
+ (let ((url (if instance
+ (concat "https://" instance "/api/v1/" endpoint)
+ (mastodon-http--api endpoint)))
(buffer (concat "*mastodon-" buffer-name "*")))
(if headers
(mastodon-http--get-response-async
@@ -2803,29 +2857,32 @@ HIDE-REPLIES is a flag indicating if replies are hidden in the current buffer."
buffer endpoint update-function headers params hide-replies)
(mastodon-http--get-json-async
url params 'mastodon-tl--init*
- buffer endpoint update-function nil params hide-replies))))
+ buffer endpoint update-function nil params hide-replies instance))))
(defun mastodon-tl--init* (response buffer endpoint update-function
- &optional headers update-params hide-replies)
+ &optional headers update-params hide-replies instance)
"Initialize BUFFER with timeline targeted by ENDPOINT.
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."
(let ((json (if headers (car response) response)))
- (if (not json) ; praying this is right here, else try "\n[]"
- (message "Looks like nothing returned from endpoint: %s" endpoint)
- (let* ((headers (if headers (cdr response) nil))
- (link-header (mastodon-tl--get-link-header-from-response headers)))
- (with-mastodon-buffer buffer #'mastodon-mode nil
- (mastodon-tl--set-buffer-spec buffer endpoint update-function
- link-header update-params hide-replies)
- (mastodon-tl--do-init json update-function))))))
-
-(defun mastodon-tl--init-sync
- (buffer-name endpoint update-function
- &optional note-type params headers view-name binding-str)
- "Initialize BUFFER-NAME with timeline targeted by ENDPOINT.
+ (cond ((not json) ; praying this is right here, else try "\n[]"
+ (message "Looks like nothing returned from endpoint: %s" endpoint))
+ ((eq (caar json) 'error)
+ (user-error "Looks like the server bugged out: \"%s\"" (cdar json)))
+ (t
+ (let* ((headers (if headers (cdr response) nil))
+ (link-header (mastodon-tl--get-link-header-from-response headers)))
+ (with-mastodon-buffer buffer #'mastodon-mode nil
+ (mastodon-tl--set-buffer-spec buffer endpoint update-function
+ link-header update-params hide-replies)
+ (mastodon-tl--do-init json update-function instance)))))))
+
+ (defun mastodon-tl--init-sync
+ (buffer-name endpoint update-function
+ &optional note-type params headers view-name binding-str)
+ "Initialize BUFFER-NAME with timeline targeted by ENDPOINT.
UPDATE-FUNCTION is used to receive more toots.
Runs synchronously.
Optional arg NOTE-TYPE means only get that type of notification.
@@ -2859,11 +2916,14 @@ BINDING-STR is a string explaining any bindins in the view."
(mastodon-tl--do-init json update-function)
buffer)))
-(defun mastodon-tl--do-init (json update-fun)
+(defun mastodon-tl--do-init (json update-fun &optional domain)
"Utility function for `mastodon-tl--init*' and `mastodon-tl--init-sync'.
-JSON is the data to call UPDATE-FUN on."
+JSON is the data to call UPDATE-FUN on.
+When DOMAIN, force inclusion of user's domain in their handle."
(remove-overlays) ; video overlays
- (funcall update-fun json)
+ (if domain
+ (funcall update-fun json nil domain)
+ (funcall update-fun json))
(setq
;; Initialize with a minimal interval; we re-scan at least once
;; every 5 minutes to catch any timestamps we may have missed
diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el
index aff201d..864d767 100644
--- a/lisp/mastodon-toot.el
+++ b/lisp/mastodon-toot.el
@@ -912,7 +912,15 @@ instance to edit a toot."
(mastodon-views--cancel-scheduled-toot
scheduled-id :no-confirm))
(mastodon-toot--restore-previous-window-config prev-window-config)
- (when edit-id
+ ;; reload previous view in certain cases:
+ ;; we reload: - when we have been editing
+ ;; - when we are in thread view
+ ;; - ?
+ ;; (we don't necessarily want to reload in every posting case
+ ;; as it can sometimes be slow and we may still lose our place
+ ;; in a timeline.)
+ (when (or edit-id
+ (equal 'thread (mastodon-tl--get-buffer-type)))
(let ((pos (marker-position (cadr prev-window-config))))
(mastodon-tl--reload-timeline-or-profile pos))))))))))
@@ -1133,7 +1141,7 @@ arg, a candidate."
(cadr (assoc candidate mastodon-toot-completions)))
(defun mastodon-toot--emoji-annotation-fun (candidate)
- "."
+ "CANDIDATE."
;; TODO: emoji image as annot
(cdr (assoc candidate mastodon-toot-completions)))
diff --git a/lisp/mastodon-views.el b/lisp/mastodon-views.el
index e9e89c0..775b96b 100644
--- a/lisp/mastodon-views.el
+++ b/lisp/mastodon-views.el
@@ -748,7 +748,7 @@ MISSKEY means the instance is a Misskey or derived server."
(interactive)
(if user
(let ((response (mastodon-http--get-json
- (mastodon-http--api "instance") nil nil :vector)))
+ (mastodon-http--api "instance" "v2") nil nil :vector)))
(mastodon-views--instance-response-fun response brief instance))
(mastodon-tl--do-if-item
(let* ((toot (if (mastodon-tl--profile-buffer-p)
diff --git a/lisp/mastodon.el b/lisp/mastodon.el
index 3504ef3..6eac3d8 100644
--- a/lisp/mastodon.el
+++ b/lisp/mastodon.el
@@ -6,7 +6,7 @@
;; Author: Johnson Denen <johnson.denen@gmail.com>
;; Marty Hiatt <martianhiatus@riseup.net>
;; Maintainer: Marty Hiatt <martianhiatus@riseup.net>
-;; Version: 1.0.21
+;; Version: 1.0.22
;; Package-Requires: ((emacs "27.1") (request "0.3.0") (persist "0.4"))
;; Homepage: https://codeberg.org/martianh/mastodon.el