aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.org336
-rw-r--r--lisp/mastodon-discover.el6
-rw-r--r--lisp/mastodon-http.el134
-rw-r--r--lisp/mastodon-profile.el47
-rw-r--r--lisp/mastodon-tl.el143
-rw-r--r--lisp/mastodon-toot.el134
6 files changed, 408 insertions, 392 deletions
diff --git a/README.org b/README.org
index a072c52..7503328 100644
--- a/README.org
+++ b/README.org
@@ -1,115 +1,8 @@
#+OPTIONS: toc:nil
-* mastodon.el updated
-
-This is an updated version of the great but seemingly dormant mastodon client for emacs.
-
-This is now the version available via MELPA.
-
-[The original readme is below.]
-
-It adds the following features:
-
-| Profiles: | |
-| | display profile metadata fields |
-| | display pinned toots first |
-| | display relationship (follows you/followed by you) |
-| | display toots/follows/followers counts |
-| | links/tags/mentions in profile bios are active links |
-| | show a lock icon for locked accounts |
-| =G= | view follow suggestions |
-| =R=, =a=, =r= | view/accept/reject follow requests |
-| =V= | view your favorited toots |
-| =i= | toggle pinning of toots |
-| =U= | update your profile bio note |
-| =O= | jump to own profile |
-| Notifications: | |
-| | follow requests now also appear in notifications |
-| =a=, =j= | accept/reject follow request |
-| | notifications for when a user posts (=mastodon-tl--enable-notify-user-posts=) |
-| Timelines: | |
-| =C= | copy url of toot at point |
-| =d= | delete your toot at point, and reload current timeline |
-| =D= | delete and redraft toot at point, preserving reply/CW/visibility |
-| =W=, =M=, =B= | (un)follow, (un)mute, (un)block author of toot at point |
-| =k=, =K= | toggle bookmark of toot at point, view bookmarked toots |
-| =I=, =c=, =d= | view, create, and delete filters |
-| | display image captions |
-| | display polls and vote on them |
-| | images are links to the full image, can be zoomed/rotated/saved (see image keymap) |
-| | images scale properly |
-| | toot visibility (direct, followers only) icon appears in toot bylines |
-| | display toot's number of favorites, boosts and replies |
-| | play gifs and videos (requires =mpv= to be installed) |
-| | customize option to cache images |
-| Toots: | |
-| | mention booster in replies by default |
-| | replies preserve visibility status/CW of original toot |
-| | autocompletion of user mentions, via =company-mode= (must be installed to work) |
-| =C-c C-a= | media uploads, asynchronous |
-| | media upload previews displayed in toot compose buffer |
-| =C-c C-n= | and sensitive media/nsfw flag |
-| =C-c C-e= | add emoji (if =emojify= installed) |
-| | download and use your instance's custom emoji |
-| | server's maximum toot length shown in toot compose buffer |
-| Search: | |
-| =S= | search (posts, users, tags) (NB: only posts you have interacted with are searched) |
-| | |
-
-It also makes some small cosmetic changes to make timelines easier to read, and makes some functions asynchronous, based on https://github.com/ieure/mastodon.el.
+* README
-The minimum Emacs version is now 27.1. But if you are running an older version it shouldn't be very hard to get it working.
-
-** live-updating timelines: =mastodon-async-mode=
-
-(code taken from https://github.com/alexjgriffith/mastodon-future.el.)
-
-Works for federated, local, and home timelines and for notifications. It's a little touchy, one thing to avoid is trying to load a timeline more than once at a time. It can go off the rails a bit, but it's still pretty cool.
-
-To enable, it, add =(require 'mastodon-async)= to your =init.el=. Then you can view a timeline with one of the commands that begin with =mastodon-async--stream-=.
-
-** translating toots
-
-You can translate toots with =mastodon-toot--translate-toot-text=. At the moment this requires [[https://codeberg.org/martianh/lingva.el][lingva.el]], a little interface I wrote to https://lingva.ml, to be installed to work.
-
-You could easily modify the simple function to use your emacs translator of choice (=google-translate=, =babel=, =go-translate=, etc.), you just need to fetch the toot's content with =(mastodon-tl--content toot)= and pass it to your translator function as its text argument. Here's what =mastodon-toot--translate-toot-text= looks like:
-
-#+begin_src emacs-lisp
- (defun mastodon-toot--translate-toot-text ()
- "Translate text of toot at point.
- Uses `lingva.el'."
- (interactive)
- (let* ((toot (mastodon-tl--property 'toot-json)))
- (if toot
- (lingva-translate nil (mastodon-tl--content toot))
- (message "No toot to translate?"))))
-#+end_src
-
-** NB: dependencies
-
-This version depends on the library =request= (for uploading attachments). You can install it from MELPA, or https://github.com/tkf/emacs-request. It also depends on =seq=.
-
-Optional dependencies:
-- =company= for autocompletion of mentions when composing a toot
-- =emojify= for inserting and viewing emojis
-- =mpv= and =mpv.el= for viewing videos and gifs
-- =lingva.el= for translating toots
-
-** NB: bugs
-
-This repo also incorporates fixes for two bugs that were never merged into the upstream repo:
-- https://github.com/jdenen/mastodon.el/issues/227 (and https://github.com/jdenen/mastodon.el/issues/234)
-- https://github.com/jdenen/mastodon.el/issues/228
-
-** contributing
-
-Contributions are welcome.
-
-1. Create an here on codeberg detailing the feature you'd like to add.
-2. Fork the repository and create a branch off of =develop=.
-3. Create a pull request referencing the issue created in step 1.
-
-* Original README
+=mastodon.el= is an Emacs client for the Mastodon and Pleroma social networks. For info see https://joinmastodon.org/.
** Installation
@@ -128,6 +21,8 @@ Or, with =use-package=:
:ensure t)
#+END_SRC
+The minimum Emacs version is now 27.1. But if you are running an older version it shouldn't be very hard to get it working.
+
*** MELPA
Add =MELPA= to your archives:
@@ -171,12 +66,13 @@ Or, with =use-package=:
#+END_SRC
** Usage
-*** Instance
+
+*** Logging in to your instance
You need to set 2 variables in your init file to get started:
-1. mastodon-instance-url
-2. mastodon-active-user
+1. =mastodon-instance-url=
+2. =mastodon-active-user=
(see their doc strings for details). For example If you want to post
toots as "example_user@social.instance.org", then put this in your init
@@ -192,95 +88,181 @@ to internet before you do this. If you have multiple mastodon accounts
you can activate one at a time by changing those two variables and
restarting Emacs.
-If you have been using mastodon.el before this change and the above
-steps do not work it's advisable that you delete the old file specified
-by =mastodon-client--token-file= and restart Emacs and follow the steps
-again.
+If you were using mastodon.el before 2FA was implemented and the above steps
+do not work, delete the old file specified by =mastodon-client--token-file= and
+restart Emacs and follow the steps again.
*** Timelines
=M-x mastodon=
-Opens a =*mastodon-home*= buffer in the major mode so you can see toots. You will be prompted for email and password. The app registration process will take place if your =mastodon-token-file= does not contain =:client_id= and =:client_secret=.
+Opens a =*mastodon-home*= buffer in the major mode and displays toots. You
+will be prompted for email and password. The app registration process will
+take place if your =mastodon-token-file= does not contain =:client_id= and
+=:client_secret=.
**** Keybindings
-|-----------------+---------------------------------------------------------|
-| Key | Action |
-|-----------------+---------------------------------------------------------|
-| | /Help/ |
-| =?= | Open context menu if =discover= is available |
-| | /Timeline actions/ |
-| =n= | Go to next item (toot, notification) |
-| =p= | Go to previous item (toot, notification) |
-| =M-n=/=<tab>= | Go to the next interesting thing that has an action |
-| =M-p=/=<S-tab>= | Go to the previous interesting thing that has an action |
-| =u= | Update timeline |
-| =#= | Prompt for tag and open its timeline |
-| =A= | Open author profile of toot under =point= |
-| =F= | Open federated timeline |
-| =H= | Open home timeline |
-| =L= | Open local timeline |
-| =N= | Open notifications timeline |
-| =P= | Open profile of user attached to toot under =point= |
-| =T= | Open thread buffer for toot under =point= |
-| | /Toot actions/ |
-| =c= | Toggle content warning content |
-| =b= | Boost toot under =point= |
-| =f= | Favourite toot under =point= |
-| =r= | Reply to toot under =point= |
-| =n= | Compose a new toot |
-| | /Switching to other buffers/ |
-| | /Quitting/ |
-| =q= | Quit mastodon buffer, leave window open |
-| =Q= | Quit mastodon buffer and kill window |
-|-----------------+---------------------------------------------------------|
+|---------------+-----------------------------------------------------------------------|
+| Key | Action |
+|---------------+-----------------------------------------------------------------------|
+| | /Help/ |
+| =?= | Open context menu if =discover= is available |
+|---------------+-----------------------------------------------------------------------|
+| | /Timeline actions/ |
+| =n= | Go to next item (toot, notification) |
+| =p= | Go to previous item (toot, notification) |
+| =M-n=/=<tab>= | Go to the next interesting thing that has an action |
+| =M-p=/=<S-tab>= | Go to the previous interesting thing that has an action |
+| =u= | Update timeline |
+| =#= | Prompt for tag and open its timeline |
+| =A= | Open author profile of toot under =point= |
+| =F= | Open federated timeline |
+| =H= | Open home timeline |
+| =L= | Open local timeline |
+| =N= | Open notifications timeline |
+| =P= | Open profile of user attached to toot under =point= |
+| =O= | View own profile |
+| =U= | update your profile bio note |
+| =T= | Open thread buffer for toot under =point= |
+|---------------+-----------------------------------------------------------------------|
+| | Other views |
+| =S= | search (posts, users, tags) (NB: only posts you have interacted with) |
+| =I=, =c=, =d= | view, create, and delete filters |
+| =R=, =a=, =r= | view/accept/reject follow requests |
+| =G= | view follow suggestions |
+| =V= | view your favorited toots |
+| =K= | view bookmarked toots |
+|---------------+-----------------------------------------------------------------------|
+| | /Toot actions/ |
+| =c= | Toggle content warning content |
+| =b= | Boost toot under =point= |
+| =f= | Favourite toot under =point= |
+| =r= | Reply to toot under =point= |
+| =t= | Compose a new toot |
+| =v= | Vote on poll at point |
+| =C= | copy url of toot at point |
+| =C-RET= | play video/gif at point (requires =mpv=) |
+| =i= | (un)pin toot at point |
+| =d= | delete your toot at point, and reload current timeline |
+| =D= | delete and redraft toot at point, preserving reply/CW/visibility |
+| =W=, =M=, =B= | (un)follow, (un)mute, (un)block author of toot at point |
+| =k= | toggle bookmark of toot at point |
+|---------------+-----------------------------------------------------------------------|
+| | Notifications view |
+| =a=, =j= | accept/reject follow request |
+|---------------+-----------------------------------------------------------------------|
+| | /Switching to other buffers/ |
+| | /Quitting/ |
+| =q= | Quit mastodon buffer, leave window open |
+| =Q= | Quit mastodon buffer and kill window |
+|---------------+-----------------------------------------------------------------------|
**** Legend
-|--------+-------------------------|
-| Marker | Meaning |
-|--------+-------------------------|
-| =(B)= | I boosted this toot. |
-| =(F)= | I favourited this toot. |
-|--------+-------------------------|
+|----------------+------------------------|
+| Marker | Meaning |
+|----------------+------------------------|
+| =(B)= | I boosted this toot |
+| =(F)= | I favourited this toot |
+| (=K=) (or emoji) | I bookmarked this toot |
+|----------------+------------------------|
-*** Toot toot
+*** Composing toots
-=M-x mastodon-toot=
+=M-x mastodon-toot= (or =t= from a mastodon.el buffer).
-Pops a new buffer/window with a =mastodon-toot= minor mode. Enter the
+Pops a new buffer/window in =mastodon-toot= minor mode. Enter the
contents of your toot here. =C-c C-c= sends the toot. =C-c C-k= cancels.
Both actions kill the buffer and window.
-If you have not previously authenticated, you will be prompted for your
-account email and password. *NOTE*: Email and password are NOT stored by mastodon.el.
+Autocompletion of mentions is provided by a mastodon company backend (requires =company-mode=).
-Authentication stores your access token in the =mastodon-auth--token=
-variable. It is not stored on your filesystem, so you will have to
-re-authenticate when you close/reopen Emacs.
+Replies preserve visibility status/content warnings, and include boosters by default.
-**** Customization
-The default toot visibility can be changed by setting or customizing the =mastodon-toot--default-visibility= variable. Valid values are ="public"=, ="unlisted"=, ="private"=, or =direct=.
+Server's max toot length, and attachment previews, are shown.
-Toot visibility can also be changed on a per-toot basis from the new toot buffer.
+You can download and use your instance's custom emoji
+(=mastodon-toot--download-custom-emoji=, =mastodon-toot--enable-custom-emoji=).
**** Keybindings
-|-----------+------------------------|
-| Key | Action |
-|-----------+------------------------|
-| =C-c C-c= | Send toot |
-| =C-c C-k= | Cancel toot |
-| =C-c C-w= | Add content warning |
-| =C-c C-v= | Change toot visibility |
-|-----------+------------------------|
+|---------+----------------------------------|
+| Key | Action |
+|---------+----------------------------------|
+| =C-c C-c= | Send toot |
+| =C-c C-k= | Cancel toot |
+| =C-c C-w= | Add content warning |
+| =C-c C-v= | Change toot visibility |
+| =C-c C-n= | Add sensitive media/nsfw flag |
+| =C-c C-a= | Upload attachment(s) |
+| =C-c != | Remove all attachments |
+| =C-c C-e= | add emoji (if =emojify= installed) |
+|---------+----------------------------------|
+
+*** Customization
+
+See =M-x customize-group RET mastodon= to view all customize options.
+
+- Timeline options:
+ - Use proportional fonts
+ - Timestamp format
+ - Relative timestamps
+ - Display use avatars
+ - Avatar image hight
+ - Enable image caching
+
+- Compose options:
+ - Default toot visibility, using =mastodon-toot--default-visibility= variable. Valid values are ="public"=, ="unlisted"=, ="private"=, or =direct=.
+ - Completions for mentions
+ - Enable custom emoji
+
+*** live-updating timelines: =mastodon-async-mode=
+
+(code taken from https://github.com/alexjgriffith/mastodon-future.el.)
+
+Works for federated, local, and home timelines and for notifications. It's a
+little touchy, one thing to avoid is trying to load a timeline more than once
+at a time. It can go off the rails a bit, but it's still pretty cool. The
+current maintainer of =mastodon.el= is unable to debug improve this feature.
+
+To enable, it, add =(require 'mastodon-async)= to your =init.el=. Then you can
+view a timeline with one of the commands that begin with
+=mastodon-async--stream-=.
+
+*** translating toots
+
+You can translate toots with =mastodon-toot--translate-toot-text=. At the moment
+this requires [[https://codeberg.org/martianh/lingva.el][lingva.el]], a little interface I wrote to https://lingva.ml, to
+be installed to work.
+
+You could easily modify the simple function to use your emacs translator of
+choice (=libretrans.el= , =google-translate=, =babel=, =go-translate=, etc.), you just
+need to fetch the toot's content with =(mastodon-tl--content toot)= and pass it
+to your translator function as its text argument. Here's what
+=mastodon-toot--translate-toot-text= looks like:
+
+#+begin_src emacs-lisp
+ (defun mastodon-toot--translate-toot-text ()
+ "Translate text of toot at point.
+ Uses `lingva.el'."
+ (interactive)
+ (let* ((toot (mastodon-tl--property 'toot-json)))
+ (if toot
+ (lingva-translate nil (mastodon-tl--content toot))
+ (message "No toot to translate?"))))
+#+end_src
-** Roadmap
+** dependencies
-[[https://github.com/jdenen/mastodon.el/milestone/1][Here]] are the features I plan to implement before putting mastodon.el on MELPA.
+This version depends on the library =request= (for uploading attachments). You
+can install it from MELPA, or https://github.com/tkf/emacs-request.
-[[https://github.com/jdenen/mastodon.el/milestone/2][Here]] are the plans I have for the =1.0.0= release.
+Optional dependencies:
+- =company= for autocompletion of mentions when composing a toot
+- =emojify= for inserting and viewing emojis
+- =mpv= and =mpv.el= for viewing videos and gifs
+- =lingva.el= for translating toots
** Contributing
@@ -297,7 +279,3 @@ PRs, issues, and feature requests are very welcome!
1. In an [[https://github.com/jdenen/mastodon.el/issues][issue]], let me know that you're working to fix it.
2. Fork the repository and create a branch off of =develop=.
3. Create a pull request referencing the issue from step 1.
-
-** Connect
-
-If you want to get in touch with me, give me a [[https://mastodon.social/@johnson][toot]] or leave an [[https://github.com/jdenen/mastodon.el/issues][issue]].
diff --git a/lisp/mastodon-discover.el b/lisp/mastodon-discover.el
index 7046070..a63d500 100644
--- a/lisp/mastodon-discover.el
+++ b/lisp/mastodon-discover.el
@@ -89,9 +89,9 @@
("-" "zoom out" 'image-decrease-size)
("u" "copy URL" 'shr-maybe-probe-and-copy-url))
("Profile view"
- ("o" "Show following" mastodon-profile--open-following)
- ("O" "Show followers" mastodon-profile--open-followers)
-
+ ("g" "Show following" mastodon-profile--open-following)
+ ("s" "Show followers" mastodon-profile--open-followers)
+ ("C-c C-c" "Cycle profile views" mastodon-profile-account-view-cycle)
("R" "View follow requests" mastodon-profile--view-follow-requests)
("a" "Accept follow request" mastodon-profile--follow-request-accept)
("j" "Reject follow request" mastodon-profile--follow-request-reject)
diff --git a/lisp/mastodon-http.el b/lisp/mastodon-http.el
index 35fd070..ec3b5e6 100644
--- a/lisp/mastodon-http.el
+++ b/lisp/mastodon-http.el
@@ -97,39 +97,47 @@ Message status and JSON error from RESPONSE if unsuccessful."
(insert-file-contents filename)
(string-to-unibyte (buffer-string))))
-(defun mastodon-http--post (url args headers &optional unauthenticed-p)
+(defmacro mastodon-http--authorized-request (method body &optional unauthenticated-p)
+ "Make a METHOD type request using BODY, with Mastodon authorization.
+Unless UNAUTHENTICATED-P is non-nil."
+ `(let ((url-request-method ,method)
+ (url-request-extra-headers
+ (unless ,unauthenticated-p
+ (list (cons "Authorization"
+ (concat "Bearer " (mastodon-auth--access-token)))))))
+ ,body))
+
+(defun mastodon-http--post (url args headers &optional unauthenticated-p)
"POST synchronously to URL with ARGS and HEADERS.
-Authorization header is included by default unless UNAUTHENTICED-P is non-nil."
- (let ((url-request-method "POST")
- (url-request-data
- (when args
- (mapconcat (lambda (arg)
- (concat (url-hexify-string (car arg))
- "="
- (url-hexify-string (cdr arg))))
- args
- "&")))
- (url-request-extra-headers
- (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)))
- (with-temp-buffer
- (mastodon-http--url-retrieve-synchronously url))))
+Authorization header is included by default unless UNAUTHENTICATED-P is non-nil."
+ (mastodon-http--authorized-request
+ "POST"
+ (let ((url-request-data
+ (when args
+ (mapconcat (lambda (arg)
+ (concat (url-hexify-string (car arg))
+ "="
+ (url-hexify-string (cdr arg))))
+ args
+ "&")))
+ (url-request-extra-headers
+ (append url-request-extra-headers ; auth set in macro
+ ;; pleroma compat:
+ (unless (assoc "Content-Type" headers)
+ '(("Content-Type" . "application/x-www-form-urlencoded")))
+ headers)))
+ (with-temp-buffer
+ (mastodon-http--url-retrieve-synchronously url)))
+ unauthenticated-p))
(defun mastodon-http--get (url)
"Make synchronous GET request to URL.
Pass response buffer to CALLBACK function."
- (let ((url-request-method "GET")
- (url-request-extra-headers
- `(("Authorization" . ,(concat "Bearer "
- (mastodon-auth--access-token))))))
- (mastodon-http--url-retrieve-synchronously url)))
+ (mastodon-http--authorized-request
+ "GET"
+ (mastodon-http--url-retrieve-synchronously url)))
(defun mastodon-http--get-json (url)
"Make synchronous GET request to URL. Return JSON response."
@@ -138,6 +146,8 @@ Pass response buffer to CALLBACK function."
(defun mastodon-http--process-json ()
"Process JSON response."
+ ;; view raw response:
+ ;; (switch-to-buffer (current-buffer))
(goto-char (point-min))
(re-search-forward "^$" nil 'move)
(let ((json-string
@@ -150,12 +160,10 @@ Pass response buffer to CALLBACK function."
(defun mastodon-http--delete (url)
"Make DELETE request to URL."
- (let ((url-request-method "DELETE")
- (url-request-extra-headers
- `(("Authorization" . ,(concat "Bearer "
- (mastodon-auth--access-token))))))
- (with-temp-buffer
- (mastodon-http--url-retrieve-synchronously url))))
+ (mastodon-http--authorized-request
+ "DELETE"
+ (with-temp-buffer
+ (mastodon-http--url-retrieve-synchronously url))))
(defun mastodon-http--append-query-string (url params)
"Append PARAMS to URL as query strings and return it.
@@ -187,14 +195,12 @@ PARAM is any extra parameters to send with the request."
"Make GET request to BASE-URL, searching for QUERY.
Pass response buffer to CALLBACK function.
PARAM is a formatted request parameter, eg 'following=true'."
- (let ((url-request-method "GET")
- (url (if param
- (concat base-url "?" param "&q=" (url-hexify-string query))
- (concat base-url "?q=" (url-hexify-string query))))
- (url-request-extra-headers
- `(("Authorization" . ,(concat "Bearer "
- (mastodon-auth--access-token))))))
- (mastodon-http--url-retrieve-synchronously url)))
+ (mastodon-http--authorized-request
+ "GET"
+ (let ((url (if param
+ (concat base-url "?" param "&q=" (url-hexify-string query))
+ (concat base-url "?q=" (url-hexify-string query)))))
+ (mastodon-http--url-retrieve-synchronously url))))
;; profile update functions
@@ -208,25 +214,21 @@ PARAM is a formatted request parameter, eg 'following=true'."
"Make synchronous PATCH request to BASE-URL.
Optionally specify the NOTE to edit.
Pass response buffer to CALLBACK function."
- (let ((url-request-method "PATCH")
- (url (if note
+ (mastodon-http--authorized-request
+ "PATCH"
+ (let ((url (if note
(concat base-url "?note=" (url-hexify-string note))
- base-url))
- (url-request-extra-headers
- `(("Authorization" . ,(concat "Bearer "
- (mastodon-auth--access-token))))))
- (mastodon-http--url-retrieve-synchronously url)))
+ base-url)))
+ (mastodon-http--url-retrieve-synchronously url))))
;; Asynchronous functions
(defun mastodon-http--get-async (url &optional callback &rest cbargs)
"Make GET request to URL.
Pass response buffer to CALLBACK function with args CBARGS."
- (let ((url-request-method "GET")
- (url-request-extra-headers
- `(("Authorization" . ,(concat "Bearer "
- (mastodon-auth--access-token))))))
- (url-retrieve url callback cbargs)))
+ (mastodon-http--authorized-request
+ "GET"
+ (url-retrieve url callback cbargs)))
(defun mastodon-http--get-json-async (url &optional callback &rest args)
"Make GET request to URL. Call CALLBACK with json-vector and ARGS."
@@ -240,21 +242,19 @@ Pass response buffer to CALLBACK function with args CBARGS."
"POST asynchronously to URL with ARGS and HEADERS.
Then run function CALLBACK with arguements CBARGS.
Authorization header is included by default unless UNAUTHENTICED-P is non-nil."
- (let ((url-request-method "POST")
- (request-timeout 5)
- (url-request-data
- (when args
- (mapconcat (lambda (arg)
- (concat (url-hexify-string (car arg))
- "="
- (url-hexify-string (cdr arg))))
- args
- "&")))
- (url-request-extra-headers
- (append `(("Authorization" . ,(concat "Bearer " (mastodon-auth--access-token))))
- headers)))
- (with-temp-buffer
- (url-retrieve url callback cbargs))))
+ (mastodon-http--authorized-request
+ "POST"
+ (let ((request-timeout 5)
+ (url-request-data
+ (when args
+ (mapconcat (lambda (arg)
+ (concat (url-hexify-string (car arg))
+ "="
+ (url-hexify-string (cdr arg))))
+ args
+ "&"))))
+ (with-temp-buffer
+ (url-retrieve url callback cbargs)))))
;; TODO: test for curl first?
(defun mastodon-http--post-media-attachment (url filename caption)
diff --git a/lisp/mastodon-profile.el b/lisp/mastodon-profile.el
index 6065bdd..ae244d8 100644
--- a/lisp/mastodon-profile.el
+++ b/lisp/mastodon-profile.el
@@ -78,6 +78,7 @@
(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 "C-c C-c") #'mastodon-profile--account-view-cycle)
map)
"Keymap for `mastodon-profile-mode'.")
@@ -88,7 +89,7 @@
(define-key map (kbd "a") #'mastodon-notifications--follow-request-accept)
(define-key map (kbd "n") #'mastodon-tl--goto-next-item)
(define-key map (kbd "p") #'mastodon-tl--goto-prev-item)
- (define-key map (kbd "g") 'mastodon-profile--view-follow-requests)
+ (define-key map (kbd "g") #'mastodon-profile--view-follow-requests)
;; (define-key map (kbd "t") #'mastodon-toot)
;; (define-key map (kbd "q") #'kill-current-buffer)
;; (define-key map (kbd "Q") #'kill-buffer-and-window)
@@ -130,6 +131,19 @@ extra keybindings."
(mastodon-profile--make-profile-buffer-for
account "statuses" #'mastodon-tl--timeline))
+;; TODO: we shd just load all views' data then switch coz this is slow af:
+(defun mastodon-profile-account-view-cycle ()
+ "Cycle through profile view: toots, followers, and following."
+ (interactive)
+ (let ((endpoint (plist-get mastodon-tl--buffer-spec 'endpoint)))
+ (cond ((string-suffix-p "statuses" endpoint)
+ (mastodon-profile--open-followers))
+ ((string-suffix-p "followers" endpoint)
+ (mastodon-profile--open-following))
+ (t
+ (mastodon-profile--make-profile-buffer-for
+ mastodon-profile--account "statuses" #'mastodon-tl--timeline)))))
+
(defun mastodon-profile--open-following ()
"Open a profile buffer showing the accounts that current profile follows."
(interactive)
@@ -207,6 +221,7 @@ JSON is the data returned by the server."
(buffer (get-buffer-create "*mastodon-update-profile*"))
(inhibit-read-only t))
(switch-to-buffer-other-window buffer)
+ (text-mode)
(setq-local header-line-format
(propertize
"Edit your profile note. C-c C-c to send, C-c C-k to cancel."
@@ -238,37 +253,25 @@ JSON is the data returned by the server."
(defun mastodon-profile--fields-get (account)
"Fetch the fields vector (aka profile metadata) from profile of ACCOUNT.
-
Returns a list of lists."
(let ((fields (mastodon-profile--account-field account 'fields)))
(when fields
- (mapcar
- (lambda (el)
- (list
- (alist-get 'name el)
- (alist-get 'value el)))
- fields))))
+ (mapcar (lambda (el)
+ (list (alist-get 'name el)
+ (alist-get 'value el)))
+ fields))))
(defun mastodon-profile--fields-insert (fields)
"Format and insert field pairs (a.k.a profile metadata) in FIELDS."
(let* ((car-fields (mapcar 'car fields))
- ;; (cdr-fields (mapcar 'cadr fields))
- ;; (cdr-fields-rendered
- ;; (list
- ;; (mapcar (lambda (x)
- ;; (mastodon-tl--render-text x nil))
- ;; cdr-fields)))
(left-width (car (sort (mapcar 'length car-fields) '>))))
- ;; (right-width (car (sort (mapcar 'length cdr-fields) '>))))
(mapconcat (lambda (field)
(mastodon-tl--render-text
(concat
(format "_ %s " (car field))
(make-string (- (+ 1 left-width) (length (car field))) ?_)
(format " :: %s" (cadr field)))
- ;; (make-string (- (+ 1 right-width) (length (cdr field))) ?_)
- ;; " |")
- field)) ; nil)) ; hack to make links tabstops
+ field)) ; hack to make links tabstops
fields "")))
(defun mastodon-profile--get-statuses-pinned (account)
@@ -413,14 +416,18 @@ If toot is a boost, opens the profile of the booster."
user-handles
nil ; predicate
'confirm)))))
- (if (not (get-text-property (point) 'toot-json))
+ (if (not (or
+ ;; own profile has no need for toot-json test:
+ (equal user-handle (mastodon-auth--get-account-name))
+ (get-text-property (point) 'toot-json)))
(message "Looks like there's no toot or user at point?")
(let ((account (mastodon-profile--lookup-account-in-status
user-handle (mastodon-profile--toot-json))))
(if account
(progn
(message "Loading profile of user %s..." user-handle)
- (mastodon-profile--make-author-buffer account))
+ (mastodon-profile--make-author-buffer account)
+ (message "'C-c C-c' to cycle profile views: toots, followers, following"))
(message "Cannot find a user with handle %S" user-handle)))))
(defun mastodon-profile--my-profile ()
diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el
index 8bb034c..f9b6bf6 100644
--- a/lisp/mastodon-tl.el
+++ b/lisp/mastodon-tl.el
@@ -264,7 +264,7 @@ text, i.e. hidden spoiler text."
"local" "timelines/public?local=true" 'mastodon-tl--timeline))
(defun mastodon-tl--get-tag-timeline ()
- "Prompts for tag and opens its timeline."
+ "Prompt for tag and opens its timeline."
(interactive)
(let* ((word (or (word-at-point) ""))
(input (read-string (format "Load timeline for tag (%s): " word)))
@@ -532,6 +532,10 @@ By default it is `mastodon-tl--byline-boosted'"
(parsed-time (date-to-time created-time))
(faved (equal 't (mastodon-tl--field 'favourited toot)))
(boosted (equal 't (mastodon-tl--field 'reblogged toot)))
+ (bookmarked (equal 't (mastodon-tl--field 'bookmarked toot)))
+ (bookmark-str (if (fontp (char-displayable-p #10r128278))
+ "🔖"
+ "K"))
(visibility (mastodon-tl--field 'visibility toot)))
(concat
;; Boosted/favourited markers are not technically part of the byline, so
@@ -544,18 +548,20 @@ By default it is `mastodon-tl--byline-boosted'"
(concat (when boosted
(mastodon-tl--format-faved-or-boosted-byline "B"))
(when faved
- (mastodon-tl--format-faved-or-boosted-byline "F")))
+ (mastodon-tl--format-faved-or-boosted-byline "F"))
+ (when bookmarked
+ (mastodon-tl--format-faved-or-boosted-byline bookmark-str)))
(propertize
(concat
;; we propertize help-echo format faves for author name
;; in `mastodon-tl--byline-author'
(funcall author-byline toot)
(cond ((equal visibility "direct")
- (if (fontp (char-displayable-p #10r128274))
+ (if (fontp (char-displayable-p #10r9993))
" ✉"
" [direct]"))
((equal visibility "private")
- (if (fontp (char-displayable-p #10r9993))
+ (if (fontp (char-displayable-p #10r128274))
" 🔒"
" [followers]")))
(funcall action-byline toot)
@@ -586,13 +592,23 @@ By default it is `mastodon-tl--byline-boosted'"
(propertize "\n ------------\n" 'face 'default))
'favourited-p faved
'boosted-p boosted
+ 'bookmarked-p bookmarked
'byline t))))
(defun mastodon-tl--format-faved-or-boosted-byline (letter)
"Format the byline marker for a boosted or favourited status.
-LETTER is a string, either F or B."
- (format "(%s) "
- (propertize letter 'face 'mastodon-boost-fave-face)))
+LETTER is a string, F for favourited, B for boosted, or K for bookmarked."
+ (let ((help-string (cond ((equal letter "F")
+ "favourited")
+ ((equal letter "B")
+ "boosted")
+ ((equal letter (or "🔖" "K"))
+ "bookmarked"))))
+ (format "(%s) "
+ (propertize letter 'face 'mastodon-boost-fave-face
+ ;; emojify breaks this for 🔖:
+ 'help-echo (format "You have %s this status."
+ help-string)))))
(defun mastodon-tl--render-text (string toot)
"Return a propertized text rendering the given HTML string STRING.
@@ -898,7 +914,9 @@ PARENT-TOOT is the JSON of the toot responded to."
(mastodon-tl--byline toot author-byline action-byline detailed-p))
'toot-id (or id ; for notifications
(alist-get 'id toot))
- 'base-toot-id (mastodon-tl--toot-id toot)
+ 'base-toot-id (mastodon-tl--toot-id
+ ;; if a favourite/boost notif, get ID of toot responded to:
+ (or parent-toot toot))
'toot-json toot
'parent-toot parent-toot)
"\n")
@@ -1325,28 +1343,31 @@ RESPONSE is the JSON returned by the server."
(mastodon-search--insert-users-propertized response :note)
(goto-char (point-min)))
+(defmacro mastodon-tl--do-if-toot (&rest body)
+ "Execute BODY if we have a toot or user at point."
+ `(if (and (not (string-prefix-p "accounts" (mastodon-tl--get-endpoint))) ;profile view
+ (not (mastodon-tl--property 'toot-json)))
+ (message "Looks like there's no toot or user at point?")
+ ,@body))
+
(defun mastodon-tl--follow-user (user-handle &optional notify)
"Query for USER-HANDLE from current status and follow that user.
If NOTIFY is \"true\", enable notifications when that user posts.
If NOTIFY is \"false\", disable notifications when that user posts.
Can be called to toggle NOTIFY on users already being followed."
- (interactive
- (list
- (mastodon-tl--interactive-user-handles-get "follow")))
- (if (and (not (string-prefix-p "accounts" (mastodon-tl--get-endpoint))) ;profile view
- (not (get-text-property (point) 'toot-json)))
- (message "Looks like there's no toot or user at point?")
- (mastodon-tl--do-user-action-and-response user-handle "follow" nil notify)))
+ (interactive
+ (list
+ (mastodon-tl--interactive-user-handles-get "follow")))
+ (mastodon-tl--do-if-toot
+ (mastodon-tl--do-user-action-and-response user-handle "follow" nil notify)))
(defun mastodon-tl--enable-notify-user-posts (user-handle)
"Query for USER-HANDLE and enable notifications when they post."
(interactive
(list
(mastodon-tl--interactive-user-handles-get "enable")))
- (if (and (not (string-prefix-p "accounts" (mastodon-tl--get-endpoint))) ;profile view
- (not (get-text-property (point) 'toot-json)))
- (message "Looks like there's no toot or user at point?")
- (mastodon-tl--follow-user user-handle "true")))
+ (mastodon-tl--do-if-toot
+ (mastodon-tl--follow-user user-handle "true")))
(defun mastodon-tl--disable-notify-user-posts (user-handle)
"Query for USER-HANDLE and disable notifications when they post."
@@ -1360,20 +1381,16 @@ Can be called to toggle NOTIFY on users already being followed."
(interactive
(list
(mastodon-tl--interactive-user-handles-get "unfollow")))
- (if (and (not (string-prefix-p "accounts" (mastodon-tl--get-endpoint))) ;profile view
- (not (get-text-property (point) 'toot-json)))
- (message "Looks like there's no toot or user at point?")
- (mastodon-tl--do-user-action-and-response user-handle "unfollow" t)))
+ (mastodon-tl--do-if-toot
+ (mastodon-tl--do-user-action-and-response user-handle "unfollow" t)))
(defun mastodon-tl--block-user (user-handle)
"Query for USER-HANDLE from current status and block that user."
(interactive
(list
(mastodon-tl--interactive-user-handles-get "block")))
- (if (and (not (string-prefix-p "accounts" (mastodon-tl--get-endpoint))) ;profile view
- (not (get-text-property (point) 'toot-json)))
- (message "Looks like there's no toot or user at point?")
- (mastodon-tl--do-user-action-and-response user-handle "block")))
+ (mastodon-tl--do-if-toot
+ (mastodon-tl--do-user-action-and-response user-handle "block")))
(defun mastodon-tl--unblock-user (user-handle)
"Query for USER-HANDLE from list of blocked users and unblock that user."
@@ -1389,10 +1406,8 @@ Can be called to toggle NOTIFY on users already being followed."
(interactive
(list
(mastodon-tl--interactive-user-handles-get "mute")))
- (if (and (not (string-prefix-p "accounts" (mastodon-tl--get-endpoint))) ;profile view
- (not (get-text-property (point) 'toot-json)))
- (message "Looks like there's no toot or user at point?")
- (mastodon-tl--do-user-action-and-response user-handle "mute")))
+ (mastodon-tl--do-if-toot
+ (mastodon-tl--do-user-action-and-response user-handle "mute")))
(defun mastodon-tl--unmute-user (user-handle)
"Query for USER-HANDLE from list of muted users and unmute that user."
@@ -1405,31 +1420,29 @@ Can be called to toggle NOTIFY on users already being followed."
(defun mastodon-tl--interactive-user-handles-get (action)
"Get the list of user-handles for ACTION from the current toot."
- (if (and (not (string-prefix-p "accounts" (mastodon-tl--get-endpoint))) ;profile view
- (not (get-text-property (point) 'toot-json)))
- (message "Looks like there's no toot or user at point?")
- (let ((user-handles
- (cond ((or (equal (buffer-name) "*mastodon-follow-suggestions*")
- ;; follow suggests / search / foll requests compat:
- (string-prefix-p "*mastodon-search" (buffer-name))
- (equal (buffer-name) "*mastodon-follow-requests*")
- ;; profile view follows/followers compat:
- ;; but not for profile statuses:
- (and (string-prefix-p "accounts" (mastodon-tl--get-endpoint))
- (not (string-suffix-p "statuses" (mastodon-tl--get-endpoint)))))
- ;; avoid tl--property here because it calls next-toot
- ;; which breaks non-toot buffers like foll reqs etc.:
- (list (alist-get 'acct (get-text-property (point) 'toot-json))))
- (t
- (mastodon-profile--extract-users-handles
- (mastodon-profile--toot-json))))))
- (completing-read (if (or (equal action "disable")
- (equal action "enable"))
- (format "%s notifications when user posts: " action)
- (format "Handle of user to %s: " action))
- user-handles
- nil ; predicate
- 'confirm))))
+ (mastodon-tl--do-if-toot
+ (let ((user-handles
+ (cond ((or (equal (buffer-name) "*mastodon-follow-suggestions*")
+ ;; follow suggests / search / foll requests compat:
+ (string-prefix-p "*mastodon-search" (buffer-name))
+ (equal (buffer-name) "*mastodon-follow-requests*")
+ ;; profile view follows/followers compat:
+ ;; but not for profile statuses:
+ (and (string-prefix-p "accounts" (mastodon-tl--get-endpoint))
+ (not (string-suffix-p "statuses" (mastodon-tl--get-endpoint)))))
+ ;; avoid tl--property here because it calls next-toot
+ ;; which breaks non-toot buffers like foll reqs etc.:
+ (list (alist-get 'acct (get-text-property (point) 'toot-json))))
+ (t
+ (mastodon-profile--extract-users-handles
+ (mastodon-profile--toot-json))))))
+ (completing-read (if (or (equal action "disable")
+ (equal action "enable"))
+ (format "%s notifications when user posts: " action)
+ (format "Handle of user to %s: " action))
+ user-handles
+ nil ; predicate
+ 'confirm))))
(defun mastodon-tl--interactive-blocks-or-mutes-list-get (action)
"Fetch the list of accounts for ACTION from the server.
@@ -1490,7 +1503,8 @@ by `mastodon-tl--follow-user' to enable or disable notifications."
((string-equal notify "false")
(message "Not receiving notifications for user %s (@%s)!"
name user-handle))
- ((string-equal action "mute")
+ ((or (string-equal action "mute")
+ (string-equal action "unmute"))
(message "User %s (@%s) %sd!" name user-handle action))
((eq notify nil)
(message "User %s (@%s) %sed!" name user-handle action)))))))
@@ -1733,14 +1747,13 @@ JSON is the data returned from the server."
#'mastodon-tl--update-timestamps-callback
(current-buffer)
nil)))
- (unless
- ;; for everything save profiles:
- (string-prefix-p "accounts" endpoint))
- ;;(or (equal endpoint "notifications")
- ;; (string-prefix-p "timelines" endpoint)
- ;; (string-prefix-p "favourites" endpoint)
- ;; (string-prefix-p "statuses" endpoint))
- (mastodon-tl--goto-first-item)))
+ (unless (string-prefix-p "accounts" endpoint)
+ ;; for everything save profiles
+ (mastodon-tl--goto-first-item))))
+;;(or (equal endpoint "notifications")
+;; (string-prefix-p "timelines" endpoint)
+;; (string-prefix-p "favourites" endpoint)
+;; (string-prefix-p "statuses" endpoint))
(defun mastodon-tl--init-sync (buffer-name endpoint update-function)
"Initialize BUFFER-NAME with timeline targeted by ENDPOINT.
diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el
index d571b6e..3081637 100644
--- a/lisp/mastodon-toot.el
+++ b/lisp/mastodon-toot.el
@@ -216,8 +216,6 @@ Makes a POST request to the server."
(let ((response (mastodon-http--post url nil nil)))
(mastodon-http--triage response callback))))
-
-
(defun mastodon-toot--toggle-boost-or-favourite (type)
"Toggle boost or favourite of toot at `point'.
TYPE is a symbol, either 'favourite or 'boost."
@@ -240,26 +238,27 @@ TYPE is a symbol, either 'favourite or 'boost."
(remove (if boost-p (when boosted t) (when faved t)))
(toot-type (alist-get 'type (mastodon-tl--property 'toot-json))))
(if byline-region
- (cond ((mastodon-toot--own-toot-p (mastodon-tl--property 'toot-json))
- (error "You can't %s your own toots." action-string))
- ((equal "reblog" toot-type)
- (error "You can't %s boosts." action-string))
- ((equal "favourite" toot-type)
- (error "Your can't %s favourites." action-string))
- (t
- (mastodon-toot--action
- action
- (lambda ()
- (let ((inhibit-read-only t))
- (add-text-properties (car byline-region)
- (cdr byline-region)
- (if boost-p
- (list 'boosted-p (not boosted))
- (list 'favourited-p (not faved))))
- (mastodon-toot--action-success
- (if boost-p "B" "F")
- byline-region remove))
- (message (format "%s #%s" (if boost-p msg action) id))))))
+ (cond ;; actually there's nothing wrong with faving/boosting own toots!
+ ;;((mastodon-toot--own-toot-p (mastodon-tl--property 'toot-json))
+ ;;(error "You can't %s your own toots." action-string))
+ ((equal "reblog" toot-type)
+ (error "You can't %s boosts." action-string))
+ ((equal "favourite" toot-type)
+ (error "Your can't %s favourites." action-string))
+ (t
+ (mastodon-toot--action
+ action
+ (lambda ()
+ (let ((inhibit-read-only t))
+ (add-text-properties (car byline-region)
+ (cdr byline-region)
+ (if boost-p
+ (list 'boosted-p (not boosted))
+ (list 'favourited-p (not faved))))
+ (mastodon-toot--action-success
+ (if boost-p "B" "F")
+ byline-region remove))
+ (message (format "%s #%s" (if boost-p msg action) id))))))
(message (format "Nothing to %s here?!?" action-string)))))
(defun mastodon-toot--toggle-boost ()
@@ -272,6 +271,43 @@ TYPE is a symbol, either 'favourite or 'boost."
(interactive)
(mastodon-toot--toggle-boost-or-favourite 'favourite))
+;; TODO maybe refactor into boost/fave fun
+(defun mastodon-toot--bookmark-toot-toggle ()
+ "Bookmark or unbookmark toot at point."
+ (interactive)
+ (let* ((toot (mastodon-tl--property 'toot-json))
+ (id (mastodon-tl--property 'base-toot-id))
+ ;; (mastodon-tl--as-string (mastodon-tl--toot-id toot)))
+ (bookmarked-p (mastodon-tl--property 'bookmarked-p))
+ (prompt (if bookmarked-p
+ (format "Toot already bookmarked. Remove? ")
+ (format "Bookmark this toot? ")))
+ (byline-region
+ (when id
+ (mastodon-tl--find-property-range 'byline (point))))
+ (action (if bookmarked-p "unbookmark" "bookmark"))
+ (bookmark-str (if (fontp (char-displayable-p #10r128278))
+ "🔖"
+ "K"))
+ (message (if bookmarked-p
+ "Bookmark removed!"
+ "Toot bookmarked!"))
+ (remove (when bookmarked-p t)))
+ (if byline-region
+ (when (y-or-n-p prompt)
+ (mastodon-toot--action
+ action
+ (lambda ()
+ (let ((inhibit-read-only t))
+ (add-text-properties (car byline-region)
+ (cdr byline-region)
+ (list 'bookmarked-p (not bookmarked-p))))
+ (mastodon-toot--action-success
+ bookmark-str
+ byline-region remove)
+ (message (format "%s #%s" message id)))))
+ (message (format "Nothing to %s here?!?" action)))))
+
(defun mastodon-toot--copy-toot-url ()
"Copy URL of toot at point."
(interactive)
@@ -365,6 +401,12 @@ NO-REDRAFT means delete toot only."
toot-visibility
toot-cw)))))))))
+(defun mastodon-toot-set-cw (&optional cw)
+ "Set content warning to CW if it is non-nil"
+ (unless (equal cw "")
+ (setq mastodon-toot--content-warning t)
+ (setq mastodon-toot--content-warning-from-reply-or-redraft cw)))
+
(defun mastodon-toot--redraft (response &optional reply-id toot-visibility toot-cw)
"Opens a new toot compose buffer using values from RESPONSE buffer.
REPLY-ID, TOOT-VISIBILITY, and TOOT-CW of deleted toot are preseved."
@@ -378,32 +420,9 @@ REPLY-ID, TOOT-VISIBILITY, and TOOT-CW of deleted toot are preseved."
(when reply-id
(setq mastodon-toot--reply-to-id reply-id))
(setq mastodon-toot--visibility toot-visibility)
- (when (not (equal toot-cw ""))
- (setq mastodon-toot--content-warning t)
- (setq mastodon-toot--content-warning-from-reply-or-redraft toot-cw))
+ (mastodon-toot-set-cw toot-cw)
(mastodon-toot--update-status-fields))))
-(defun mastodon-toot--bookmark-toot-toggle ()
- "Bookmark or unbookmark toot at point synchronously."
- (interactive)
- (let* ((toot (mastodon-tl--property 'toot-json))
- (id (mastodon-tl--as-string (mastodon-tl--toot-id toot)))
- (bookmarked (alist-get 'bookmarked toot))
- (url (mastodon-http--api (if (equal bookmarked t)
- (format "statuses/%s/unbookmark" id)
- (format "statuses/%s/bookmark" id))))
- (prompt (if (equal bookmarked t)
- (format "Toot already bookmarked. Remove? ")
- (format "Bookmark this toot? ")))
- (message (if (equal bookmarked t)
- "Bookmark removed!"
- "Toot bookmarked!")))
- (when (y-or-n-p prompt)
- (let ((response (mastodon-http--post url nil nil)))
- (mastodon-http--triage response
- (lambda ()
- (message message)))))))
-
(defun mastodon-toot--kill ()
"Kill `mastodon-toot-mode' buffer and window."
(kill-buffer-and-window))
@@ -465,10 +484,10 @@ The list is formatted for `emojify-user-emojis', which see."
(mapc (lambda (x)
(push
`(,(concat ":"
- (file-name-base x)
- ":") . (("name" . ,(file-name-base x))
- ("image" . ,(concat mastodon-custom-emojis-dir x))
- ("style" . "github")))
+ (file-name-base x) ":")
+ . (("name" . ,(file-name-base x))
+ ("image" . ,(concat mastodon-custom-emojis-dir x))
+ ("style" . "github")))
mastodon-emojify-user-emojis))
custom-emoji-files)
(reverse mastodon-emojify-user-emojis)))
@@ -482,7 +501,8 @@ to `emojify-user-emojis', and the emoji data is updated."
(unless (file-exists-p (concat (expand-file-name
emojify-emojis-dir)
"/mastodon-custom-emojis/"))
- (when (y-or-n-p "Looks like you haven't downloaded your instance's custom emoji yet. Download now? ")
+ (when (y-or-n-p "Looks like you haven't downloaded your
+ instance's custom emoji yet. Download now? ")
(mastodon-toot--download-custom-emoji)))
(setq emojify-user-emojis
(append (mastodon-toot--collect-custom-emoji)
@@ -885,12 +905,10 @@ REPLY-JSON is the full JSON of the toot being replied to."
(when reply-to-user
(insert (format "%s " reply-to-user))
(setq mastodon-toot--reply-to-id reply-to-id)
- (if (not (equal mastodon-toot--visibility
- reply-visibility))
- (setq mastodon-toot--visibility reply-visibility))
- (when (not (equal reply-cw ""))
- (setq mastodon-toot--content-warning t)
- (setq mastodon-toot--content-warning-from-reply-or-redraft reply-cw)))))
+ (unless (equal mastodon-toot--visibility
+ reply-visibility)
+ (setq mastodon-toot--visibility reply-visibility))
+ (mastodon-toot-set-cw reply-cw))))
(defun mastodon-toot--update-status-fields (&rest _args)
"Update the status fields in the header based on the current state."
@@ -940,7 +958,7 @@ REPLY-JSON is the full JSON of the toot being replied to."
(switch-to-buffer-other-window buffer)
(text-mode)
(mastodon-toot-mode t)
- (when (not buffer-exists)
+ (unless buffer-exists
(mastodon-toot--display-docs-and-status-fields)
(mastodon-toot--setup-as-reply reply-to-user reply-to-id reply-json))
(unless mastodon-toot--max-toot-chars