diff options
author | marty hiatt <martianhiatus@riseup.net> | 2024-10-03 14:08:05 +0200 |
---|---|---|
committer | marty hiatt <martianhiatus@riseup.net> | 2024-10-03 14:08:05 +0200 |
commit | 113d998201546e13d924d6ac00ab0657a99cf2f3 (patch) | |
tree | 3a852e517cd565c51405aae67e09e2e69fd628db | |
parent | 951ad5d60e4ff24ad108f60a9f45df8e241ef7c2 (diff) |
add fields transient and profile note suffix
-rw-r--r-- | lisp/mastodon-transient.el | 156 |
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 |