aboutsummaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authormarty hiatt <martianhiatus@riseup.net>2024-10-03 14:08:05 +0200
committermarty hiatt <martianhiatus@riseup.net>2024-10-03 14:08:05 +0200
commit113d998201546e13d924d6ac00ab0657a99cf2f3 (patch)
tree3a852e517cd565c51405aae67e09e2e69fd628db /lisp
parent951ad5d60e4ff24ad108f60a9f45df8e241ef7c2 (diff)
add fields transient and profile note suffix
Diffstat (limited to 'lisp')
-rw-r--r--lisp/mastodon-transient.el156
1 files changed, 136 insertions, 20 deletions
diff --git a/lisp/mastodon-transient.el b/lisp/mastodon-transient.el
index 7de780c..533dc8c 100644
--- a/lisp/mastodon-transient.el
+++ b/lisp/mastodon-transient.el
@@ -26,6 +26,8 @@
(require 'tp)
+;;; UTILS
+
(defun mastodon-transient-parse-source-key (key)
"Parse mastodon source KEY.
If KEY needs to be source[key], format like so, else just return
@@ -43,8 +45,55 @@ the inner key part."
collect (cons (mastodon-transient-parse-source-key (car a))
(cdr a))))
-;; FIXME: PATCHing source vals as JSON request body doesn't work!
-;; existing `mastodon-profile--update-preference' doesn't use it! it just uses
+(defun mastodon-transient-get-creds ()
+ "Fetch account data."
+ (mastodon-http--get-json
+ (mastodon-http--api "accounts/verify_credentials")
+ nil :silent))
+
+;; fields utils:
+;; to PATCH fields, we just need fields[x][name] and fields[x][value]
+
+(defun mastodon-transient-fields-to-transient ()
+ "Convert fields in `tp-server-settings' to transient key=val args."
+ (flatten-tree
+ (let-alist tp-server-settings
+ (cl-loop
+ for f in .source.fields
+ for count from 1 to 5
+ collect
+ (cl-loop for x in f
+ collect
+ (concat "fields." (number-to-string count)
+ "." (symbol-name (car x))
+ "=" (cdr x)))))))
+
+(defun mastodon-transient-field-dot-to-array (key)
+ "Convert KEY from tp dot annotation to array[key] annotation."
+ (let* ((split (split-string key "\\."))
+ (count (length split)))
+ (cond ((not key) nil)
+ ((= 1 count) key)
+ (t
+ (concat ;; first item
+ (car split)
+ "_attributes"
+ ;; but last item
+ "[" (car (last split (1- count)))
+ ;; last item:
+ "][" (car (last split)) "]")))))
+
+(defun mastodon-transient-dot-fields-to-arrays (alist)
+ "Parse fields ALIST in dot notation to array notation."
+ (cl-loop for y in alist
+ collect
+ (cons (mastodon-transient-field-dot-to-array (car y))
+ (cdr y))))
+
+;;; TRANSIENTS
+
+;; FIXME: PATCHing source vals as JSON request body doesn't work! existing
+;; `mastodon-profile--update-preference' doesn't use it! it just uses
;; query params! strange thing is it works for non-source params
(transient-define-suffix mastodon-user-settings-update (&optional args)
"Update current user settings on the server."
@@ -61,51 +110,118 @@ the inner key part."
(mastodon-http--triage
resp
(lambda (_)
- (message "Settings updated!\n%s" parsed-source)))))
-
-(defun mastodon-transient-get-creds ()
- "Fetch account data."
- (mastodon-http--get-json
- (mastodon-http--api "accounts/verify_credentials")
- nil :silent))
+ (message "Settings updated!\n%s" (pp-to-string parsed-source))))))
(transient-define-prefix mastodon-user-settings ()
"A transient for setting current user settings."
:value (lambda () (tp-return-data
#'mastodon-transient-get-creds))
[:description
- ;; '()
(lambda ()
- "Settings")
- ;; (format "User settings for %s" mastodon-active-user))
+ (format "User settings for %s" mastodon-active-user))
(:info
- "Note: use the empty string (\"\") to remove a value from an option.")
- ]
+ "Note: use the empty string (\"\") to remove a value from an option.")]
;; strings
["Account info"
- ("n" "display name" "display_name=" :class tp-option-str)]
+ ("n" "display name" "display_name=" :class tp-option-str)
+ ("t" "update profile note" mastodon-update-profile-note)
+ ("f" "update profile fields" mastodon-profile-fields)]
;; "choice" booleans (so we can PATCH :json-false explicitly):
["Account options"
("l" "locked" "locked=" :class tp-choice-bool)
("b" "bot" "bot=" :class tp-choice-bool)
("d" "discoverable" "discoverable=" :class tp-choice-bool)
-
("c" "hide follower/following lists" "source.hide_collections=" :class tp-choice-bool)
("i" "indexable" "source.indexable=" :class tp-choice-bool)]
["Tooting options"
("p" "default privacy" "source.privacy=" :class tp-option
- :choices (lambda () mastodon-toot-visibility-settings-list))
+ :choices mastodon-toot-visibility-settings-list)
+ ;; ("public" "unlisted" "private"))
+ ;; (lambda () mastodon-toot-visibility-settings-list))
("s" "mark sensitive" "source.sensitive=" :class tp-choice-bool)
("g" "default language" "source.language=" :class tp-option
- :choices (lambda () mastodon-iso-639-regional))]
+ :choices mastodon-iso-639-regional)]
["Update"
("C-c C-c" "Save settings" mastodon-user-settings-update)
- ;; ("C-c C-k" :info "to revert all changes")
- ]
+ ("C-c C-k" :info "to revert all changes")]
(interactive)
(if (not mastodon-active-user)
(user-error "User not set")
(transient-setup 'mastodon-user-settings)))
+(transient-define-suffix mastodon-update-profile-note ()
+ "Update current user profile note."
+ :transient 'transient--do-exit
+ (interactive)
+ (mastodon-profile--update-user-profile-note))
+
+(transient-define-suffix mastodon-profile-fields-update (args)
+ "Update current user profile fields."
+ :transient 'transient--do-exit
+ (interactive (list (transient-args 'mastodon-profile-fields)))
+ (let* ((alist (tp-transient-to-alist args))
+ ;; FIXME: maybe only changed also won't work with fields, as
+ ;; perhaps what is PATCHed overwrites whatever is on the server?
+ ;; (only-changed (tp-only-changed-args alist))
+ (arrays (mastodon-transient-dot-fields-to-arrays alist))
+ (endpoint "accounts/update_credentials")
+ (url (mastodon-http--api endpoint))
+ (resp (mastodon-http--patch url arrays))) ; :json)))
+ (mastodon-http--triage
+ resp
+ (lambda (_)
+ (message "Fields updated!\n%s" (pp-to-string arrays))))))
+
+(transient-define-prefix mastodon-profile-fields ()
+ "A transient for setting profile fields."
+ :value (lambda ()
+ (tp-return-data #'mastodon-transient-get-creds)
+ (mastodon-transient-fields-to-transient))
+ ["Field 1"
+ :class transient-row
+ ("1n" "name:" "fields.1.name=" :class mastodon-transient-field)
+ ("1v" "value:" "fields.1.value=" :class mastodon-transient-field)]
+ ["Field 2"
+ :class transient-row
+ ("2n" "name:" "fields.2.name=" :class mastodon-transient-field)
+ ("2v" "value:" "fields.2.value=" :class mastodon-transient-field)]
+ ["Field 3"
+ :class transient-row
+ ("3n" "name:" "fields.3.name=" :class mastodon-transient-field)
+ ("3v" "value:" "fields.3.value=" :class mastodon-transient-field)]
+ ["Field 4"
+ :class transient-row
+ ("4n" "name:" "fields.4.name=" :class mastodon-transient-field)
+ ("4v" "value:" "fields.4.value=" :class mastodon-transient-field)]
+ ["Update"
+ ("C-c C-c" "Save settings" mastodon-profile-fields-update)
+ ("C-c C-k" :info "to revert all changes")]
+ (interactive)
+ (if (not mastodon-active-user)
+ (user-error "User not set")
+ (transient-setup 'mastodon-profile-fields)))
+
+;;; CLASSES
+
+(defclass mastodon-transient-field (tp-option-str)
+ ((always-read :initarg :always-read :initform t))
+ "An infix option class for our options.
+We always read.")
+
+(cl-defmethod transient-format-value ((obj mastodon-transient-field))
+ "Format the value of OBJ.
+Format should just be a string, highlighted green if it has been
+changed from the server value."
+ (let* ((pair (transient-infix-value obj))
+ (value (when pair (cadr (split-string pair "=")))))
+ (if (not pair)
+ ""
+ ;; FIXME: not sure how to compare with server, as fields are not
+ ;; numbered in the JSON?
+ (propertize value
+ 'face (if (tp-arg-changed-p pair)
+ 'transient-value
+ 'transient-inactive-value)))))
+
(provide 'mastodon-transient)
;;; mastodon-transient.el ends here