aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.woodpecker.yml10
-rw-r--r--README.org8
-rw-r--r--lisp/mastodon-profile.el10
-rw-r--r--lisp/mastodon-tl.el46
-rw-r--r--lisp/mastodon-toot.el47
-rw-r--r--lisp/mastodon.el2
6 files changed, 84 insertions, 39 deletions
diff --git a/.woodpecker.yml b/.woodpecker.yml
index 53952ec..ba2c7b5 100644
--- a/.woodpecker.yml
+++ b/.woodpecker.yml
@@ -1,7 +1,15 @@
pipeline:
- build:
+ current:
image: silex/emacs:cask
commands:
+ - emacs --version
+ - cask install
+ - cask emacs -batch -l test/ert-helper.el -f ert-run-tests-batch-and-exit
+ last:
+ image: silex/emacs:27-ci-cask
+ commands:
+ - emacs --version
- cask install
- cask emacs -batch -l test/ert-helper.el -f ert-run-tests-batch-and-exit
++branches: [ main, develop ]
diff --git a/README.org b/README.org
index 4289d32..73a42e5 100644
--- a/README.org
+++ b/README.org
@@ -205,6 +205,14 @@ You can download and use your instance's custom emoji
| =C-c C-e= | add emoji (if =emojify= installed) |
|---------+----------------------------------|
+**** draft toots
+
+- Compose buffer text is saved as you type, kept in =mastodon-toot-current-toot-text=.
+- =mastodon-toot-save-draft=: save the current toot as a draft.
+- =mastodon-toot-open-draft-toot=: Open a compose buffer and insert one of your draft toots.
+- =mastodon-toot-delete-draft-toot=: Delete a draft toot.
+- =mastodon-toot-delete-all-drafts=: Delete all your drafts.
+
*** Other commands and account settings:
- =mastodon-url-lookup=: Attempt to load URL in =mastodon.el=. URL may be the one at point or provided in the minibuffer. Should also work if =mastodon.el= is not yet loaded.
diff --git a/lisp/mastodon-profile.el b/lisp/mastodon-profile.el
index 6ecabb2..0b35fa4 100644
--- a/lisp/mastodon-profile.el
+++ b/lisp/mastodon-profile.el
@@ -509,10 +509,12 @@ FIELDS means provide a fields vector fetched by other means."
(mastodon-profile--account-field
account 'statuses_count)))
(relationships (mastodon-profile--relationships-get id))
- (followed-by-you (alist-get 'following
- (aref relationships 0)))
- (follows-you (alist-get 'followed_by
- (aref relationships 0)))
+ (followed-by-you (when (not (seq-empty-p relationships))
+ (alist-get 'following
+ (aref relationships 0))))
+ (follows-you (when (not (seq-empty-p relationships))
+ (alist-get 'followed_by
+ (aref relationships 0))))
(followsp (or (equal follows-you 't) (equal followed-by-you 't)))
(fields (mastodon-profile--fields-get account))
(pinned (mastodon-profile--get-statuses-pinned account)))
diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el
index 4726d29..130b01f 100644
--- a/lisp/mastodon-tl.el
+++ b/lisp/mastodon-tl.el
@@ -668,8 +668,10 @@ START and END are the boundaries of the link in the toot."
(;; User handles:
maybe-userhandle
;; this fails on mentions in profile notes:
- (let ((maybe-userid (mastodon-tl--extract-userid-toot
- toot maybe-userhandle)))
+ (let ((maybe-userid
+ (when (proper-list-p toot)
+ (mastodon-tl--extract-userid-toot
+ toot maybe-userhandle))))
(setq mastodon-tab-stop-type 'user-handle
keymap mastodon-tl--link-keymap
help-echo (concat "Browse user profile of " maybe-userhandle)
@@ -1412,13 +1414,12 @@ INSTANCE is an instance domain name."
(reblog (alist-get 'reblog toot))
(account (or (alist-get 'account reblog)
(alist-get 'account toot)))
- (acct (alist-get 'acct account))
+ (url (alist-get 'url account))
(username (alist-get 'username account))
- (instance
- (concat "https://"
- (or instance
- (string-remove-prefix (concat username "@")
- acct))))
+ (instance (if instance
+ (concat "https://" instance)
+ (string-remove-suffix (concat "/@" username)
+ url)))
(response (mastodon-http--get-json
(if user
(mastodon-http--api "instance")
@@ -1496,17 +1497,24 @@ IND is the optional indentation level to print at."
(mastodon-tl--print-json-keys
(cdr el) (if ind (+ ind 4) 4)))
(t
- (when ind (indent-to ind))
- (insert (mastodon-tl--format-key el pad)
- " "
- (mastodon-tl--newline-if-long el)
- ;; only send strings straight to --render-text
- ;; this makes hyperlinks work:
- (if (not (stringp (cdr el)))
- (mastodon-tl--render-text
- (prin1-to-string (cdr el)))
- (mastodon-tl--render-text (cdr el)))
- "\n")))))))
+ ;; basic handling of raw booleans:
+ (let ((val (cond ((equal (cdr el) ':json-false)
+ "no")
+ ((equal (cdr el) 't)
+ "yes")
+ (t
+ (cdr el)))))
+ (when ind (indent-to ind))
+ (insert (mastodon-tl--format-key el pad)
+ " "
+ (mastodon-tl--newline-if-long el)
+ ;; only send strings straight to --render-text
+ ;; this makes hyperlinks work:
+ (if (not (stringp val))
+ (mastodon-tl--render-text
+ (prin1-to-string val))
+ (mastodon-tl--render-text val))
+ "\n"))))))))
(defun mastodon-tl--print-instance-rules-or-fields (alist)
"Print ALIST of instance rules or contact account fields."
diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el
index 5ec58dd..bcf9c83 100644
--- a/lisp/mastodon-toot.el
+++ b/lisp/mastodon-toot.el
@@ -50,6 +50,8 @@
(defvar mastodon-instance-url)
(defvar mastodon-tl--buffer-spec)
(defvar mastodon-tl--enable-proportional-fonts)
+(defvar mastodon-profile-account-settings)
+
(autoload 'mastodon-auth--user-acct "mastodon-auth")
(autoload 'mastodon-http--api "mastodon-http")
(autoload 'mastodon-http--delete "mastodon-http")
@@ -196,13 +198,17 @@ send.")
nil t)))
(mastodon-profile--update-preference "privacy" vis :source)))
-(defun mastodon-toot--get-max-toot-chars (&optional no-toot)
- "Fetch max_toot_chars from `mastodon-instance-url' asynchronously."
+(defun mastodon-toot--get-max-toot-chars (&optional _no-toot)
+ "Fetch max_toot_chars from `mastodon-instance-url' asynchronously.
+NO-TOOT means we are not calling from a toot buffer."
(mastodon-http--get-json-async
- (mastodon-http--api "instance") 'mastodon-toot--get-max-toot-chars-callback 'no-toot))
+ (mastodon-http--api "instance")
+ 'mastodon-toot--get-max-toot-chars-callback 'no-toot))
-(defun mastodon-toot--get-max-toot-chars-callback (json-response &optional no-toot)
- "Set max_toot_chars returned in JSON-RESPONSE and display in new toot buffer."
+(defun mastodon-toot--get-max-toot-chars-callback (json-response
+ &optional no-toot)
+ "Set max_toot_chars returned in JSON-RESPONSE and display in new toot buffer.
+NO-TOOT means we are not calling from a toot buffer."
(let ((max-chars
(or
(alist-get 'max_toot_chars json-response)
@@ -472,12 +478,23 @@ CANCEL means the toot was not sent, so we save the toot text as a draft."
(defun mastodon-toot--cancel ()
"Kill new-toot buffer/window. Does not POST content to Mastodon.
-Toot text is saved as a draft."
+If toot is not empty, prompt to save text as a draft."
(interactive)
(if (mastodon-toot-empty-p)
- (mastodon-toot--kill :cancel)
- (when (y-or-n-p "Discard draft toot? (text will be saved)")
- (mastodon-toot--kill :cancel))))
+ (mastodon-toot--kill)
+ (when (y-or-n-p "Save draft toot?")
+ (mastodon-toot-save-draft))
+ (mastodon-toot--kill)))
+
+(defun mastodon-toot-save-draft ()
+ "Save the current compose toot text as a draft.
+Pushes `mastodon-toot-current-toot-text' to
+`mastodon-toot-draft-toots-list'."
+ (interactive)
+ (unless (eq mastodon-toot-current-toot-text nil)
+ (cl-pushnew mastodon-toot-current-toot-text
+ mastodon-toot-draft-toots-list :test 'equal)
+ (message "Draft saved!")))
(defun mastodon-toot-empty-p (&optional text-only)
"Return t if no text or attachments have been added to the compose buffer.
@@ -761,7 +778,10 @@ Customize `mastodon-toot-display-orig-in-reply-buffer' to display
text of the toot being replied to in the compose buffer."
(interactive)
(let* ((toot (mastodon-tl--property 'toot-json))
- (parent (mastodon-tl--property 'parent-toot)) ; for new notifs handling
+ ;; NB: we cannot use mastodon-tl--property for 'parent-toot
+ ;; because if it doesn't have one, it is fetched from next toot!
+ ;; we also cannot use --field because we need to get a different property first
+ (parent (get-text-property (point) 'parent-toot)) ; for new notifs handling
(id (mastodon-tl--as-string
(mastodon-tl--field 'id (or parent toot))))
(account (mastodon-tl--field 'account toot))
@@ -1065,16 +1085,15 @@ REPLY-JSON is the full JSON of the toot being replied to."
(list 'invisible (not mastodon-toot--content-warning)
'face 'mastodon-cw-face)))))
-(defun mastodon-toot-save-toot-text (&rest _args)
+(defun mastodon-toot--save-toot-text (&rest _args)
"Save the current toot text in `mastodon-toot-current-toot-text'.
Added to `after-change-functions' in new toot buffers."
- (interactive)
(let ((text (mastodon-toot--remove-docs)))
(unless (string-empty-p text)
(setq mastodon-toot-current-toot-text text))))
(defun mastodon-toot-open-draft-toot ()
- "Prompt for a draft toot and open a new compose buffer containing the draft."
+ "Prompt for a draft and compose a toot with it."
(interactive)
(if mastodon-toot-draft-toots-list
(let ((text (completing-read "Select draft toot: "
@@ -1164,7 +1183,7 @@ a draft into the buffer."
(mastodon-toot--update-status-fields)
;; draft toot text saving:
(setq mastodon-toot-current-toot-text nil)
- (push #'mastodon-toot-save-toot-text after-change-functions)
+ (push #'mastodon-toot--save-toot-text after-change-functions)
(when initial-text
(insert initial-text))))
diff --git a/lisp/mastodon.el b/lisp/mastodon.el
index 72043cf..bc624d9 100644
--- a/lisp/mastodon.el
+++ b/lisp/mastodon.el
@@ -5,7 +5,7 @@
;; Author: Johnson Denen <johnson.denen@gmail.com>
;; Maintainer: Marty Hiatt <martianhiatus@riseup.net>
;; Version: 1.0.0
-;; Package-Requires: ((emacs "27.1") (request "0.3.0"))
+;; Package-Requires: ((emacs "27.1") (request "0.3.0") (persist "0.4"))
;; Homepage: https://codeberg.org/martianh/mastodon.el
;; This file is not part of GNU Emacs.