aboutsummaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp')
-rw-r--r--lisp/mastodon-discover.el17
-rw-r--r--lisp/mastodon-http.el7
-rw-r--r--lisp/mastodon-profile.el8
-rw-r--r--lisp/mastodon-search.el3
-rw-r--r--lisp/mastodon-toot.el66
-rw-r--r--lisp/mastodon.el5
6 files changed, 84 insertions, 22 deletions
diff --git a/lisp/mastodon-discover.el b/lisp/mastodon-discover.el
index 8c47fbd..33ce3d5 100644
--- a/lisp/mastodon-discover.el
+++ b/lisp/mastodon-discover.el
@@ -49,7 +49,7 @@
("A" "View profile of author" mastodon-profile--get-toot-author)
("b" "Boost" mastodon-toot--boost)
("f" "Favourite" mastodon-toot--favourite)
- ("c" "Toggle hidden text" mastodon-tl--toggle-spoiler-text-in-toot)
+ ("c" "Toggle hidden text (CW)" mastodon-tl--toggle-spoiler-text-in-toot)
("n" "Next" mastodon-tl--goto-next-toot)
("p" "Prev" mastodon-tl--goto-prev-toot)
("TAB" "Next link item" mastodon-tl--next-tab-item)
@@ -58,18 +58,22 @@
("r" "Reply" mastodon-toot--reply)
("C" "Copy toot URL" mastodon-toot--copy-toot-url)
("d" "Delete (your) toot" mastodon-toot--delete-toot)
+ ("D" "Delete and redraft (your) toot" mastodon-toot--delete-toot)
("i" "Pin/Unpin (your) toot" mastodon-toot--pin-toot-toggle)
("P" "View user profile" mastodon-profile--show-user)
- ("T" "View thread" mastodon-tl--thread))
+ ("T" "View thread" mastodon-tl--thread)
+ ("v" "Vote on poll" mastodon-tl--poll-vote))
("Timelines"
- ("#" "Tag" mastodon-tl--get-tag-timeline)
+ ("h" "View mode help/keybindings" describe-mode)
+ ("#" "Tag search" mastodon-tl--get-tag-timeline)
("F" "Federated" mastodon-tl--get-federated-timeline)
("H" "Home" mastodon-tl--get-home-timeline)
("L" "Local" mastodon-tl--get-local-timeline)
("N" "Notifications" mastodon-notifications--get)
("u" "Update timeline" mastodon-tl--update)
("S" "Search" mastodon-search--search-query)
- ("C-S-P" "Jump to my profile" mastodon-profile--my-profile))
+ ("C-S-P" "Jump to your profile" mastodon-profile--my-profile)
+ ("K" "View bookmarks" mastodon-profile--view-bookmarks))
("Users"
("W" "Follow" mastodon-tl--follow-user)
("C-S-W" "Unfollow" mastodon-tl--unfollow-user)
@@ -86,10 +90,11 @@
("Profile view"
("o" "Show following" mastodon-profile--open-following)
("O" "Show followers" mastodon-profile--open-followers)
- ("v" "View favourites" mastodon-profile--view-favourites)
+
("R" "View follow requests" mastodon-profile--view-follow-requests)
("a" "Accept follow request" mastodon-profile--follow-request-accept)
- ("r" "Reject follow request" mastodon-profile--follow-request-reject))
+ ("j" "Reject follow request" mastodon-profile--follow-request-reject)
+ ("U" "Update your profile note" mastodon-profile--update-user-profile-note))
("Quit"
("q" "Quit mastodon and bury buffer." kill-this-buffer)
("Q" "Quit mastodon buffer and kill window." kill-buffer-and-window)))))))
diff --git a/lisp/mastodon-http.el b/lisp/mastodon-http.el
index 6df2aab..f092a2d 100644
--- a/lisp/mastodon-http.el
+++ b/lisp/mastodon-http.el
@@ -46,7 +46,7 @@
"HTTP request timeout, in seconds. Has no effect on Emacs < 26.1.")
(defun mastodon-http--api (endpoint)
- "Return Mastondon API URL for ENDPOINT."
+ "Return Mastodon API URL for ENDPOINT."
(concat mastodon-instance-url "/api/"
mastodon-http--api-version "/" endpoint))
@@ -114,7 +114,7 @@ Authorization header is included by default unless UNAUTHENTICED-P is non-nil."
(url-retrieve-synchronously url nil nil mastodon-http--timeout)))))
(defun mastodon-http--read-file-as-string (filename)
- ""
+ "Read a file FILENAME as a string. Used to generate image preview."
(with-temp-buffer
(insert-file-contents filename)
(string-to-unibyte (buffer-string))))
@@ -170,7 +170,8 @@ Pass response buffer to CALLBACK function."
(json-read-from-string json-string)))
(defun mastodon-http--get-search-json (url query &optional param)
- "Make GET request to URL, searching for QUERY and return JSON response."
+ "Make GET request to URL, searching for QUERY and return JSON response.
+PARAM is any extra parameters to send with the request."
(let ((buffer (mastodon-http--get-search url query param)))
(with-current-buffer buffer
(mastodon-http--process-json-search))))
diff --git a/lisp/mastodon-profile.el b/lisp/mastodon-profile.el
index 2c364da..a374061 100644
--- a/lisp/mastodon-profile.el
+++ b/lisp/mastodon-profile.el
@@ -143,6 +143,14 @@ extra keybindings."
"favourites"
'mastodon-tl--timeline))
+(defun mastodon-profile--view-bookmarks ()
+ "Open a new buffer displaying the user's bookmarks."
+ (interactive)
+ (message "Loading your bookmarked toots...")
+ (mastodon-tl--init "bookmarks"
+ "bookmarks"
+ 'mastodon-tl--timeline))
+
(defun mastodon-profile--view-follow-requests ()
"Open a new buffer displaying the user's follow requests."
(interactive)
diff --git a/lisp/mastodon-search.el b/lisp/mastodon-search.el
index 40f134d..ccac5e6 100644
--- a/lisp/mastodon-search.el
+++ b/lisp/mastodon-search.el
@@ -42,6 +42,7 @@
(defvar mastodon-instance-url)
(defvar mastodon-tl--link-keymap)
(defvar mastodon-http--timeout)
+(defvar mastodon-toot--enable-completion-for-mentions)
;; functions for company completion of mentions in mastodon-toot
@@ -55,7 +56,7 @@
Returns a nested list containing user handle, display name, and URL."
(interactive "sSearch mastodon for: ")
(let* ((url (format "%s/api/v1/accounts/search" mastodon-instance-url))
- (buffer (format "*mastodon-search-%s*" query))
+ ;; (buffer (format "*mastodon-search-%s*" query))
(response (if (equal mastodon-toot--enable-completion-for-mentions "followers")
(mastodon-http--get-search-json url query "following=true")
(mastodon-http--get-search-json url query))))
diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el
index d6502f8..0153c9b 100644
--- a/lisp/mastodon-toot.el
+++ b/lisp/mastodon-toot.el
@@ -31,6 +31,7 @@
(defvar mastodon-instance-url)
(defvar mastodon-media--attachment-height)
+(defvar mastodon-toot--enable-completion-for-mentions)
(when (require 'emojify nil :noerror)
(declare-function emojify-insert-emoji "emojify"))
@@ -44,6 +45,7 @@
(autoload 'mastodon-http--triage "mastodon-http")
(autoload 'mastodon-http--delete "mastodon-http")
(autoload 'mastodon-http--process-json "mastodon-http")
+(autoload 'mastodon-http--get-json "mastodon-http")
(autoload 'mastodon-tl--as-string "mastodon-tl")
(autoload 'mastodon-tl--clean-tabs-and-nl "mastodon-tl")
(autoload 'mastodon-tl--field "mastodon-tl")
@@ -126,6 +128,9 @@ Valid values are \"direct\", \"private\" (followers-only), \"unlisted\", and \"p
"Buffer-local variable to hold the list of media attachments.")
(make-variable-buffer-local 'mastodon-toot--media-attachments)
+(defvar mastodon-toot--max-toot-chars nil
+ "The maximum allowed characters count for a single toot.")
+
(defvar mastodon-toot-mode-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "C-c C-c") #'mastodon-toot--send)
@@ -141,6 +146,14 @@ Valid values are \"direct\", \"private\" (followers-only), \"unlisted\", and \"p
map)
"Keymap for `mastodon-toot'.")
+(defun mastodon-toot--get-max-toot-chars ()
+ "Fetch max_toot_chars from `mastodon-instance-url'."
+ (let ((instance-json (mastodon-http--get-json
+ (mastodon-http--api "instance"))))
+ (setq mastodon-toot--max-toot-chars
+ (number-to-string
+ (cdr (assoc 'max_toot_chars instance-json))))))
+
(defun mastodon-toot--action-success (marker byline-region remove)
"Insert/remove the text MARKER with 'success face in byline.
@@ -307,6 +320,30 @@ Remove MARKER if REMOVE is non-nil, otherwise add it."
(setq mastodon-toot--content-warning-from-reply-or-redraft toot-cw))
(mastodon-toot--update-status-fields))))))))))
+(defun mastodon-toot--bookmark-toot ()
+ "Bookmark toot at point synchronously."
+ (interactive)
+ (let* ((toot (mastodon-tl--property 'toot-json))
+ (id (mastodon-tl--as-string (mastodon-tl--toot-id toot)))
+ (url (mastodon-http--api (format "statuses/%s/bookmark" id))))
+ (if (y-or-n-p (format "Bookmark this toot? "))
+ (let ((response (mastodon-http--post url nil nil)))
+ (mastodon-http--triage response
+ (lambda ()
+ (message "Toot bookmarked!")))))))
+
+(defun mastodon-toot--unbookmark-toot ()
+ "Bookmark toot at point synchronously."
+ (interactive)
+ (let* ((toot (mastodon-tl--property 'toot-json))
+ (id (mastodon-tl--as-string (mastodon-tl--toot-id toot)))
+ (url (mastodon-http--api (format "statuses/%s/unbookmark" id))))
+ (if (y-or-n-p (format "Remove this toot from your bookmarks? "))
+ (let ((response (mastodon-http--post url nil nil)))
+ (mastodon-http--triage response
+ (lambda ()
+ (message "Toot unbookmarked!")))))))
+
(defun mastodon-toot--kill ()
"Kill `mastodon-toot-mode' buffer and window."
(kill-buffer-and-window))
@@ -364,13 +401,15 @@ If media items have been uploaded with `mastodon-toot--add-media-attachment', at
(if (and mastodon-toot--media-attachments
(equal mastodon-toot--media-attachment-ids nil))
(message "Looks like your uploads are not up: C-c C-u to upload...")
- (if empty-toot-p
- (message "Empty toot. Cowardly refusing to post this.")
- (let ((response (mastodon-http--post endpoint args nil)))
- (mastodon-http--triage response
- (lambda ()
- (mastodon-toot--kill)
- (message "Toot toot!"))))))))
+ (if (> (length toot) (string-to-number mastodon-toot--max-toot-chars))
+ (message "Looks like your toot is longer than that maximum allowed length.")
+ (if empty-toot-p
+ (message "Empty toot. Cowardly refusing to post this.")
+ (let ((response (mastodon-http--post endpoint args nil)))
+ (mastodon-http--triage response
+ (lambda ()
+ (mastodon-toot--kill)
+ (message "Toot toot!")))))))))
(defun mastodon-toot--process-local (acct)
"Add domain to local ACCT and replace the curent user name with \"\".
@@ -674,7 +713,8 @@ on the status of NSFW, content warning flags, media attachments, etc."
(defun mastodon-toot--setup-as-reply (reply-to-user reply-to-id reply-json)
"If REPLY-TO-USER is provided, inject their handle into the message.
-If REPLY-TO-ID is provided, set the MASTODON-TOOT--REPLY-TO-ID var."
+If REPLY-TO-ID is provided, set `mastodon-toot--reply-to-id'.
+REPLY-JSON is the full JSON of the toot being replied to."
(let ((reply-visibility (cdr (assoc 'visibility reply-json)))
(reply-cw (cdr (assoc 'spoiler_text reply-json))))
(when reply-to-user
@@ -703,8 +743,9 @@ If REPLY-TO-ID is provided, set the MASTODON-TOOT--REPLY-TO-ID var."
(point-min))))
(add-text-properties (car count-region) (cdr count-region)
(list 'display
- (format "%s characters"
- (- (point-max) (cdr header-region)))))
+ (format "%s/%s characters"
+ (- (point-max) (cdr header-region))
+ mastodon-toot--max-toot-chars)))
(add-text-properties (car visibility-region) (cdr visibility-region)
(list 'display
(format "Visibility: %s"
@@ -726,7 +767,8 @@ If REPLY-TO-ID is provided, set the MASTODON-TOOT--REPLY-TO-ID var."
(defun mastodon-toot--compose-buffer (reply-to-user reply-to-id &optional reply-json)
"Create a new buffer to capture text for a new toot.
If REPLY-TO-USER is provided, inject their handle into the message.
-If REPLY-TO-ID is provided, set the MASTODON-TOOT--REPLY-TO-ID var."
+If REPLY-TO-ID is provided, set the `mastodon-toot--reply-to-id' var.
+REPLY-JSON is the full JSON of the toot being replied to."
(let* ((buffer-exists (get-buffer "*new toot*"))
(buffer (or buffer-exists (get-buffer-create "*new toot*")))
(inhibit-read-only t))
@@ -736,6 +778,8 @@ If REPLY-TO-ID is provided, set the MASTODON-TOOT--REPLY-TO-ID var."
(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 mastodon-toot--enable-completion-for-mentions
(set (make-local-variable 'company-backends)
(add-to-list 'company-backends 'mastodon-toot--mentions-completion))
diff --git a/lisp/mastodon.el b/lisp/mastodon.el
index e6a01f8..387e9eb 100644
--- a/lisp/mastodon.el
+++ b/lisp/mastodon.el
@@ -81,6 +81,7 @@
(autoload 'mastodon-auth--user-acct "mastodon-auth")
(autoload 'mastodon-tl--poll-vote "mastodon-http")
(autoload 'mastodon-toot--delete-and-redraft-toot "mastodon-toot")
+(autoload 'mastodon-profile--view-bookmarks "mastodon-profile")
(defgroup mastodon nil
"Interface with Mastodon."
@@ -157,6 +158,7 @@ Use. e.g. \"%c\" for your locale's date and time format."
(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 "v") #'mastodon-tl--poll-vote)
+ (define-key map (kbd "K") #'mastodon-profile--view-bookmarks)
map)
"Keymap for `mastodon-mode'.")
@@ -209,7 +211,8 @@ Use. e.g. \"%c\" for your locale's date and time format."
(defun mastodon-toot (&optional user reply-to-id reply-json)
"Update instance with new toot. Content is captured in a new buffer.
If USER is non-nil, insert after @ symbol to begin new toot.
-If REPLY-TO-ID is non-nil, attach new toot to a conversation."
+If REPLY-TO-ID is non-nil, attach new toot to a conversation.
+If REPLY-JSON is the json of the toot being replied to."
(interactive)
(mastodon-toot--compose-buffer user reply-to-id reply-json))