diff options
-rw-r--r-- | lisp/mastodon-http.el | 1 | ||||
-rw-r--r-- | lisp/mastodon-notifications.el | 213 | ||||
-rw-r--r-- | lisp/mastodon-profile.el | 46 | ||||
-rw-r--r-- | lisp/mastodon-tl.el | 26 | ||||
-rw-r--r-- | lisp/mastodon-toot.el | 10 | ||||
-rw-r--r-- | lisp/mastodon.el | 8 |
6 files changed, 118 insertions, 186 deletions
diff --git a/lisp/mastodon-http.el b/lisp/mastodon-http.el index c0fa101..f988e39 100644 --- a/lisp/mastodon-http.el +++ b/lisp/mastodon-http.el @@ -113,6 +113,7 @@ Authorization header is included by default unless UNAUTHENTICED-P is non-nil." (append (unless unauthenticed-p `(("Authorization" . ,(concat "Bearer " (mastodon-auth--access-token))))) + ;; pleroma compatibility: (unless (assoc "Content-Type" headers) '(("Content-Type" . "application/x-www-form-urlencoded"))) headers))) diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el index bb05103..9444658 100644 --- a/lisp/mastodon-notifications.el +++ b/lisp/mastodon-notifications.el @@ -55,7 +55,8 @@ ("favourite" . mastodon-notifications--favourite) ("reblog" . mastodon-notifications--reblog) ("follow_request" . mastodon-notifications--follow-request) - ("status" . mastodon-notifications--status)) + ("status" . mastodon-notifications--status) + ("poll" . mastodon-notifications--poll)) "Alist of notification types and their corresponding function.") (defvar mastodon-notifications--response-alist @@ -64,7 +65,8 @@ ("Favourited" . "your status from") ("Boosted" . "your status from") ("Requested to follow" . "you") - ("Posted" . "a post")) + ("Posted" . "a post") + ("Posted a poll" . "that has now ended")) "Alist of subjects for notification types.") (defun mastodon-notifications--byline-concat (message) @@ -75,14 +77,21 @@ " " (cdr (assoc message mastodon-notifications--response-alist)))) -(defun mastodon-notifications--follow-request-accept-notifs () - "Accept the follow request of user at point, in notifications view." +(defun mastodon-notifications--follow-request-process (&optional reject) + "Process the follow request at point. +With no argument, the request is accepted. Argument REJECT means +reject the request. Can be called in notifications view or in +follow-requests view." (interactive) (when (mastodon-tl--find-property-range 'toot-json (point)) (let* ((toot-json (mastodon-tl--property 'toot-json)) - (f-req-p (string= "follow_request" (alist-get 'type toot-json)))) + (f-reqs-view-p (string= "follow_requests" + (plist-get mastodon-tl--buffer-spec 'endpoint))) + (f-req-p (or (string= "follow_request" (alist-get 'type toot-json)) ;notifs + f-reqs-view-p))) (if f-req-p - (let* ((account (alist-get 'account toot-json)) + (let* ((account (or (alist-get 'account toot-json) ;notifs + toot-json)) ;f-reqs (id (alist-get 'id account)) (handle (alist-get 'acct account)) (name (alist-get 'username account))) @@ -91,142 +100,112 @@ (mastodon-http--post (concat (mastodon-http--api "follow_requests") - (format "/%s/authorize" id)) + (format "/%s/%s" id (if reject + "reject" + "authorize"))) nil nil))) (mastodon-http--triage response (lambda () - (mastodon-notifications--get) - (message "Follow request of %s (@%s) accepted!" - name handle)))) + (unless f-reqs-view-p + (mastodon-notifications--get)) + (message "Follow request of %s (@%s) %s!" + name handle (if reject + "rejected" + "accepted"))))) (message "No account result at point?"))) (message "No follow request at point?"))))) -(defun mastodon-notifications--follow-request-reject-notifs () - "Reject the follow request of user at point, in notifications view." +(defun mastodon-notifications--follow-request-accept () + "Accept a follow request. +Can be called in notifications view or in follow-requests view." (interactive) - (when (mastodon-tl--find-property-range 'toot-json (point)) - (let* ((toot-json (mastodon-tl--property 'toot-json)) - (f-req-p (string= "follow_request" (alist-get 'type toot-json)))) - (if f-req-p - (let* ((account (alist-get 'account toot-json)) - (id (alist-get 'id account)) - (handle (alist-get 'acct account)) - (name (alist-get 'username account))) - (if id - (let ((response - (mastodon-http--post - (concat - (mastodon-http--api "follow_requests") - (format "/%s/reject" id)) - nil nil))) - (mastodon-http--triage response - (lambda () - (mastodon-notifications--get) - (message "Follow request of %s (@%s) rejected!" - name handle)))) - (message "No account result at point?"))) - (message "No follow request at point?"))))) + (mastodon-notifications--follow-request-process)) + +(defun mastodon-notifications--follow-request-reject () + "Reject a follow request. +Can be called in notifications view or in follow-requests view." + (interactive) + (mastodon-notifications--follow-request-process t)) (defun mastodon-notifications--mention (note) "Format for a `mention' NOTE." - (let ((id (alist-get 'id note)) - (status (mastodon-tl--field 'status note))) - (mastodon-notifications--insert-status - status - (mastodon-tl--clean-tabs-and-nl - (if (mastodon-tl--has-spoiler status) - (mastodon-tl--spoiler status) - (mastodon-tl--content status))) - 'mastodon-tl--byline-author - (lambda (_status) - (mastodon-notifications--byline-concat - "Mentioned")) - id))) + (mastodon-notifications--format-note note 'mention)) (defun mastodon-notifications--follow (note) "Format for a `follow' NOTE." - (mastodon-tl--insert-status - ;; Using reblog with an empty id will mark this as something - ;; non-boostable/non-favable. - (cons '(reblog (id . nil)) note) - (propertize "Congratulations, you have a new follower!" - 'face 'default) - 'mastodon-tl--byline-author - (lambda (_status) - (mastodon-notifications--byline-concat - "Followed")))) + (mastodon-notifications--format-note note 'follow)) (defun mastodon-notifications--follow-request (note) "Format for a `follow-request' NOTE." - (let ((id (alist-get 'id note)) - (follower (alist-get 'username (alist-get 'account note)))) - (mastodon-notifications--insert-status - (cons '(reblog (id . nil)) note) - (propertize (format "You have a follow request from... %s" follower) - 'face 'default) - 'mastodon-tl--byline-author - (lambda (_status) - (mastodon-notifications--byline-concat - "Requested to follow")) - id))) + (mastodon-notifications--format-note note 'follow-request)) (defun mastodon-notifications--favourite (note) "Format for a `favourite' NOTE." - (let ((id (alist-get 'id note)) - (status (mastodon-tl--field 'status note))) - (mastodon-notifications--insert-status - status - (mastodon-tl--clean-tabs-and-nl - (if (mastodon-tl--has-spoiler status) - (mastodon-tl--spoiler status) - (mastodon-tl--content status))) - (lambda (_status) - (mastodon-tl--byline-author - note)) - (lambda (_status) - (mastodon-notifications--byline-concat - "Favourited")) - id))) + (mastodon-notifications--format-note note 'favorite)) (defun mastodon-notifications--reblog (note) "Format for a `boost' NOTE." - (let ((id (alist-get 'id note)) - (status (mastodon-tl--field 'status note))) - (mastodon-notifications--insert-status - status - (mastodon-tl--clean-tabs-and-nl - (if (mastodon-tl--has-spoiler status) - (mastodon-tl--spoiler status) - (mastodon-tl--content status))) - (lambda (_status) - (mastodon-tl--byline-author - note)) - (lambda (_status) - (mastodon-notifications--byline-concat - "Boosted")) - id))) + (mastodon-notifications--format-note note 'boost)) (defun mastodon-notifications--status (note) "Format for a `status' NOTE. Status notifications are given when `mastodon-tl--enable-notify-user-posts' has been set." - (let ((id (cdr (assoc 'id note))) - (status (mastodon-tl--field 'status note))) + (mastodon-notifications--format-note note 'status)) + +(defun mastodon-notifications--poll (note) + "Format for a `poll' NOTE." + (mastodon-notifications--format-note note 'poll)) + +(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)))) (mastodon-notifications--insert-status - status - (mastodon-tl--clean-tabs-and-nl - (if (mastodon-tl--has-spoiler status) - (mastodon-tl--spoiler status) - (mastodon-tl--content status))) - (lambda (_status) - (mastodon-tl--byline-author - note)) + (if (or (equal type 'follow) + (equal type 'follow-request)) + ;; Using reblog with an empty id will mark this as something + ;; non-boostable/non-favable. + (cons '(reblog (id . nil)) note) + status) + (if (or (equal type 'follow) + (equal 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)) + (mastodon-tl--clean-tabs-and-nl + (if (mastodon-tl--has-spoiler status) + (mastodon-tl--spoiler status) + (mastodon-tl--content status)))) + (if (or (equal type 'follow) + (equal type 'follow-request) + (equal type 'mention)) + 'mastodon-tl--byline-author + (lambda (_status) + (mastodon-tl--byline-author + note))) (lambda (_status) (mastodon-notifications--byline-concat - "Posted")) + (cond ((equal type 'boost) + "Boosted") + ((equal type 'favorite) + "Favourited") + ((equal type 'follow-request) + "Requested to follow") + ((equal type 'follow) + "Followed") + ((equal type 'mention) + "Mentioned") + ((equal type 'status) + "Posted") + ((equal type 'poll) + "Posted a poll")))) id))) -(defun mastodon-notifications--insert-status (toot body author-byline action-byline &optional id) +(defun mastodon-notifications--insert-status (toot body author-byline action-byline id) "Display the content and byline of timeline element TOOT. BODY will form the section of the toot above the byline. @@ -241,19 +220,7 @@ 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." - (let ((start-pos (point))) - (insert - (propertize - (concat "\n" - body - " \n" - (mastodon-tl--byline toot author-byline action-byline)) - 'toot-id id - 'base-toot-id (mastodon-tl--toot-id toot) - 'toot-json toot) - "\n") - (when mastodon-tl--display-media-p - (mastodon-media--inline-images start-pos (point))))) + (mastodon-tl--insert-status toot body author-byline action-byline id)) (defun mastodon-notifications--by-type (note) "Filters NOTE for those listed in `mastodon-notifications--types-alist'." diff --git a/lisp/mastodon-profile.el b/lisp/mastodon-profile.el index 05cacde..21b40b3 100644 --- a/lisp/mastodon-profile.el +++ b/lisp/mastodon-profile.el @@ -69,8 +69,6 @@ (let ((map (make-sparse-keymap))) (define-key map (kbd "s") #'mastodon-profile--open-followers) (define-key map (kbd "g") #'mastodon-profile--open-following) - (define-key map (kbd "a") #'mastodon-profile--follow-request-accept) - (define-key map (kbd "j") #'mastodon-profile--follow-request-reject) map) "Keymap for `mastodon-profile-mode'.") @@ -153,50 +151,6 @@ extra keybindings." "follow_requests" 'mastodon-profile--add-author-bylines)) -(defun mastodon-profile--follow-request-accept () - "Accept the follow request of user at point." - (interactive) - (if (mastodon-tl--find-property-range 'toot-json (point)) - (let* ((acct-json (mastodon-profile--toot-json)) - (id (alist-get 'id acct-json)) - (handle (alist-get 'acct acct-json)) - (name (alist-get 'username acct-json))) - (if id - (let ((response - (mastodon-http--post - (concat - (mastodon-http--api "follow_requests") - (format "/%s/authorize" id)) - nil nil))) - (mastodon-http--triage response - (lambda () - (message "Follow request of %s (@%s) accepted!" - name handle)))) - (message "No account result at point?"))) - (message "No follow request at point?"))) - -(defun mastodon-profile--follow-request-reject () - "Reject the follow request of user at point." - (interactive) - (if (mastodon-tl--find-property-range 'toot-json (point)) - (let* ((acct-json (mastodon-profile--toot-json)) - (id (alist-get 'id acct-json)) - (handle (alist-get 'acct acct-json)) - (name (alist-get 'username acct-json))) - (if id - (let ((response - (mastodon-http--post - (concat - (mastodon-http--api "follow_requests") - (format "/%s/reject" id)) - nil nil))) - (mastodon-http--triage response - (lambda () - (message "Follow request of %s (@%s) rejected!" - name handle)))) - (message "No account result at point?"))) - (message "No follow request at point?"))) - (defun mastodon-profile--update-user-profile-note () "Fetch user's profile note and display for editing." (interactive) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index b2b8026..0e3de0e 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -494,11 +494,8 @@ START and END are the boundaries of the link in the toot." url toot-instance-url)) (url-instance (concat "https://" (url-host (url-generic-parse-url url)))) - (maybe-userhandle (if (string= mastodon-instance-url url-instance) - ; if handle is local, then no instance suffix: - (buffer-substring-no-properties start end) - (mastodon-tl--extract-userhandle-from-url - url (buffer-substring-no-properties start end))))) + (maybe-userhandle (mastodon-tl--extract-userhandle-from-url + url (buffer-substring-no-properties start end)))) (cond (;; Hashtags: maybe-hashtag (setq mastodon-tab-stop-type 'hashtag @@ -550,11 +547,16 @@ START and END are the boundaries of the link in the toot." BUFFER-TEXT is the text covered by the link with URL, for a user profile this should be of the form <at-sign><user id>, e.g. \"@Gargon\"." - (let ((parsed-url (url-generic-parse-url url))) + (let* ((parsed-url (url-generic-parse-url url)) + (local-p (string= + (url-host (url-generic-parse-url mastodon-instance-url)) + (url-host parsed-url)))) (when (and (string= "@" (substring buffer-text 0 1)) (string= (downcase buffer-text) (downcase (substring (url-filename parsed-url) 1)))) - (concat buffer-text "@" (url-host parsed-url))))) + (if local-p + buffer-text ; no instance suffic for local mention + (concat buffer-text "@" (url-host parsed-url)))))) (defun mastodon-tl--extract-hashtag-from-url (url instance-url) "Return the hashtag that URL points to or nil if URL is not a tag link. @@ -734,7 +736,7 @@ Runs `mastodon-tl--render-text' and fetches poll or media." (mastodon-tl--get-poll toot)) (mastodon-tl--media toot)))) -(defun mastodon-tl--insert-status (toot body author-byline action-byline) +(defun mastodon-tl--insert-status (toot body author-byline action-byline &optional id) "Display the content and byline of timeline element TOOT. BODY will form the section of the toot above the byline. @@ -744,7 +746,10 @@ portion of the byline that takes one variable. By default it is 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'" +`mastodon-tl--byline-boosted'. + +ID is that of the toot, which is attached as a property if it is +a notification." (let ((start-pos (point))) (insert (propertize @@ -752,7 +757,8 @@ takes a single function. By default it is body " \n" (mastodon-tl--byline toot author-byline action-byline)) - 'toot-id (alist-get 'id toot) + 'toot-id (or id ; for notifications + (alist-get 'id toot)) 'base-toot-id (mastodon-tl--toot-id toot) 'toot-json toot) "\n") diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index ec1ba49..befffee 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -96,7 +96,8 @@ followers-only), or \"direct\"." :group 'mastodon-toot :type 'integer) -(defcustom mastodon-toot--enable-completion-for-mentions (if (require 'company nil :noerror) "following" "off") +(defcustom mastodon-toot--enable-completion-for-mentions + (if (require 'company nil :noerror) "following" "off") "Whether to enable company completion for mentions. Used for completion in toot compose buffer. @@ -125,7 +126,8 @@ This is only used if company mode is installed." (defvar-local mastodon-toot--visibility "public" "A string indicating the visibility of the toot being composed. -Valid values are \"direct\", \"private\" (followers-only), \"unlisted\", and \"public\".") +Valid values are \"direct\", \"private\" (followers-only), +\"unlisted\", and \"public\".") (defvar-local mastodon-toot--media-attachments nil "A list of the media attachments of the toot being composed.") @@ -279,6 +281,8 @@ Makes a POST request to the server." (if (y-or-n-p (format "%s this toot? " msg-y-or-n)) (mastodon-toot--action action (lambda () + (when mastodon-tl--buffer-spec + (mastodon-tl--reload-timeline-or-profile)) (message "Toot %s!" msg))))))) (defun mastodon-toot--delete-toot () @@ -873,11 +877,11 @@ REPLY-JSON is the full JSON of the toot being replied to." (buffer (or buffer-exists (get-buffer-create "*new toot*"))) (inhibit-read-only t)) (switch-to-buffer-other-window buffer) + (text-mode) (mastodon-toot-mode t) (when (not buffer-exists) (mastodon-toot--display-docs-and-status-fields) (mastodon-toot--setup-as-reply reply-to-user reply-to-id reply-json)) - (mastodon-toot-mode t) (unless mastodon-toot--max-toot-chars (mastodon-toot--get-max-toot-chars)) (when (require 'company nil :noerror) diff --git a/lisp/mastodon.el b/lisp/mastodon.el index d5f9b6e..f65a86d 100644 --- a/lisp/mastodon.el +++ b/lisp/mastodon.el @@ -69,8 +69,8 @@ (autoload 'mastodon-profile--my-profile "mastodon-profile") (autoload 'mastodon-profile--view-favourites "mastodon-profile") (autoload 'mastodon-profile--view-follow-requests "mastodon-profile") -(autoload 'mastodon-notifications--follow-request-accept-notifs "mastodon-profile") -(autoload 'mastodon-notifications--follow-request-reject-notifs "mastodon-profile") +(autoload 'mastodon-notifications--follow-request-accept "mastodon-notifications") +(autoload 'mastodon-notifications--follow-request-reject "mastodon-notifications") (autoload 'mastodon-search--search-query "mastodon-search") ;; (autoload 'mastodon-toot--delete-toot "mastodon-toot") ;; (autoload 'mastodon-toot--copy-toot-url "mastodon-toot") @@ -160,8 +160,8 @@ Use. e.g. \"%c\" for your locale's date and time format." ;; (define-key map (kbd "C-c l") #'mastodon-async--stream-local) ;; (define-key map (kbd "C-c n") #'mastodon-async--stream-notifications) (define-key map (kbd "U") #'mastodon-profile--update-user-profile-note) - (define-key map (kbd "a") #'mastodon-notifications--follow-request-accept-notifs) - (define-key map (kbd "j") #'mastodon-notifications--follow-request-reject-notifs) + (define-key map (kbd "a") #'mastodon-notifications--follow-request-accept) + (define-key map (kbd "j") #'mastodon-notifications--follow-request-reject) (define-key map (kbd "v") #'mastodon-tl--poll-vote) (define-key map (kbd "k") #'mastodon-toot--bookmark-toot-toggle) (define-key map (kbd "K") #'mastodon-profile--view-bookmarks) |