aboutsummaryrefslogtreecommitdiff
path: root/lisp/mastodon-profile.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/mastodon-profile.el')
-rw-r--r--lisp/mastodon-profile.el150
1 files changed, 124 insertions, 26 deletions
diff --git a/lisp/mastodon-profile.el b/lisp/mastodon-profile.el
index 54f0e84..7e3262a 100644
--- a/lisp/mastodon-profile.el
+++ b/lisp/mastodon-profile.el
@@ -1,7 +1,9 @@
;;; mastodon-profile.el --- Functions for inspecting Mastodon profiles -*- lexical-binding: t -*-
;; Copyright (C) 2017-2019 Johnson Denen
+;; Copyright (C) 2020-2022 Marty Hiatt
;; Author: Johnson Denen <johnson.denen@gmail.com>
+;; Marty Hiatt <martianhiatus@riseup.net>
;; Maintainer: Marty Hiatt <martianhiatus@riseup.net>
;; Version: 1.0.0
;; Package-Requires: ((emacs "27.1"))
@@ -75,6 +77,7 @@
(autoload 'mastodon-tl--get-link-header-from-response "mastodon-tl")
(autoload 'mastodon-tl--set-buffer-spec "mastodon-tl")
(autoload 'mastodon-tl--symbol "mastodon-tl")
+(autoload 'mastodon-auth--get-account-id "mastodon-auth")
(defvar mastodon-instance-url)
(defvar mastodon-tl--buffer-spec)
@@ -129,7 +132,7 @@ extra keybindings."
(defvar mastodon-profile-update-mode-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "C-c C-c") #'mastodon-profile--user-profile-send-updated)
- (define-key map (kbd "C-c C-k") #'kill-buffer-and-window)
+ (define-key map (kbd "C-c C-k") #'mastodon-profile--update-profile-note-cancel)
map)
"Keymap for `mastodon-profile-update-mode'.")
@@ -287,33 +290,83 @@ JSON is the data returned by the server."
(defun mastodon-profile--update-user-profile-note ()
"Fetch user's profile note and display for editing."
(interactive)
- (let* ((url (mastodon-http--api "accounts/verify_credentials"))
+ (let* ((endpoint "accounts/verify_credentials")
+ (url (mastodon-http--api endpoint))
(json (mastodon-http--get-json url))
(source (alist-get 'source json))
(note (alist-get 'note source))
(buffer (get-buffer-create "*mastodon-update-profile*"))
- (inhibit-read-only t))
+ (inhibit-read-only t)
+ (msg-str "Edit your profile note. C-c C-c to send, C-c C-k to cancel."))
(switch-to-buffer-other-window buffer)
(text-mode)
+ (mastodon-tl--set-buffer-spec (buffer-name buffer)
+ endpoint
+ nil)
(setq-local header-line-format
- (propertize
- "Edit your profile note. C-c C-c to send, C-c C-k to cancel."
- 'face font-lock-comment-face))
+ (propertize msg-str
+ 'face font-lock-comment-face))
(mastodon-profile-update-mode t)
- (insert note)
- (goto-char (point-min))
+ (insert (propertize (concat (propertize "0"
+ 'note-counter t
+ 'display nil)
+ "/500 characters")
+ 'read-only t
+ 'face 'font-lock-comment-face
+ 'note-header t)
+ "\n")
+ (make-local-variable 'after-change-functions)
+ (push #'mastodon-profile--update-note-count after-change-functions)
+ (let ((start-point (point)))
+ (insert note)
+ (goto-char start-point))
(delete-trailing-whitespace) ; remove all ^M's
- (message "Edit your profile note. C-c C-c to send, C-c C-k to cancel.")))
+ (message msg-str)))
+
+(defun mastodon-profile--update-note-count (&rest _args)
+ "Display the character count of the profile note buffer."
+ (let ((inhibit-read-only t)
+ (header-region (mastodon-tl--find-property-range 'note-header
+ (point-min)))
+ (count-region (mastodon-tl--find-property-range 'note-counter
+ (point-min))))
+ (add-text-properties (car count-region) (cdr count-region)
+ (list 'display
+ (number-to-string
+ (mastodon-toot--count-toot-chars
+ (buffer-substring-no-properties
+ (cdr header-region) (point-max))))))))
+
+(defun mastodon-profile--update-profile-note-cancel ()
+ "Cancel updating user profile and kill buffer and window."
+ (interactive)
+ (when (y-or-n-p "Cancel updating your profile note?")
+ (kill-buffer-and-window)))
+
+(defun mastodon-profile--note-remove-header ()
+ "Get the body of a toot from the current compose buffer."
+ (let ((header-region (mastodon-tl--find-property-range 'note-header
+ (point-min))))
+ (buffer-substring (cdr header-region) (point-max))))
(defun mastodon-profile--user-profile-send-updated ()
- "Send PATCH request with the updated profile note."
+ "Send PATCH request with the updated profile note.
+Ask for confirmation if length > 500 characters."
(interactive)
- (let* ((note (buffer-substring-no-properties (point-min) (point-max)))
+ (let* ((note (mastodon-profile--note-remove-header))
(url (mastodon-http--api "accounts/update_credentials")))
- (kill-buffer-and-window)
- (let ((response (mastodon-http--patch url `(("note" . ,note)))))
- (mastodon-http--triage response
- (lambda () (message "Profile note updated!"))))))
+ (if (> (mastodon-toot--count-toot-chars note) 500)
+ (when (y-or-n-p "Note is over mastodon's max for profile notes (500). Proceed?")
+ (kill-buffer-and-window)
+ (mastodon-profile--user-profile-send-updated-do url note))
+ (kill-buffer-and-window)
+ (mastodon-profile--user-profile-send-updated-do url note))))
+
+(defun mastodon-profile--user-profile-send-updated-do (url note)
+ "Send PATCH request with the updated profile note."
+ (let ((response (mastodon-http--patch url `(("note" . ,note)))))
+ (mastodon-http--triage response
+ (lambda () (message "Profile note updated!")))))
(defun mastodon-profile--update-preference (pref val &optional source)
"Update account PREF erence to setting VAL.
@@ -497,6 +550,9 @@ This endpoint only holds a few preferences. For others, see
(switch-to-buffer-other-window buf)
(erase-buffer)
(special-mode)
+ (mastodon-tl--set-buffer-spec (buffer-name buf)
+ "preferences"
+ nil)
(let ((inhibit-read-only t))
(while response
(let ((el (pop response)))
@@ -566,18 +622,17 @@ NO-REBLOGS means do not display boosts in statuses.
HEADERS means also fetch link headers for pagination."
(let* ((id (mastodon-profile--account-field account 'id))
(args (when no-reblogs '(("exclude_reblogs" . "t"))))
- (url (mastodon-http--api (format "accounts/%s/%s" id endpoint-type)))
+ (endpoint (format "accounts/%s/%s" id endpoint-type))
+ (url (mastodon-http--api endpoint))
(acct (mastodon-profile--account-field account 'acct))
(buffer (concat "*mastodon-" acct "-" endpoint-type "*"))
(response (if headers
(mastodon-http--get-response url args)
(mastodon-http--get-json url args)))
(json (if headers (car response) response))
- (endpoint (format "accounts/%s/%s" id endpoint-type))
(link-header (when headers
(mastodon-tl--get-link-header-from-response
(cdr response))))
-
(note (mastodon-profile--account-field account 'note))
(locked (mastodon-profile--account-field account 'locked))
(followers-count (mastodon-tl--as-string
@@ -737,14 +792,6 @@ IMG_TYPE is the JSON key from the account data."
(message "Loading your profile...")
(mastodon-profile--show-user (mastodon-auth--get-account-name)))
-(defun mastodon-profile--view-author-profile ()
- "View the profile of author of present toot."
- (interactive)
- (let* ((toot-json (mastodon-tl--property 'toot-json))
- (acct (alist-get 'account toot-json))
- (handle (alist-get 'acct acct)))
- (mastodon-profile--show-user handle)))
-
(defun mastodon-profile--account-field (account field)
"Return FIELD from the ACCOUNT.
FIELD is used to identify regions under 'account"
@@ -840,5 +887,56 @@ These include the author, author of reblogged entries and any user mentioned."
(t
(mastodon-profile--search-account-by-handle handle)))))
+(defun mastodon-profile--remove-user-from-followers (&optional id)
+ "Remove a user from your followers.
+Optionally provide the ID of the account to remove."
+ (interactive)
+ (let* ((account (unless id (get-text-property (point) 'toot-json)))
+ (id (or id (alist-get 'id account)))
+ (handle (if account
+ (alist-get 'acct account)
+ (let ((account
+ (mastodon-profile--account-from-id id)))
+ (alist-get 'acct account))))
+ (url (mastodon-http--api
+ (format "accounts/%s/remove_from_followers" id))))
+ (when (y-or-n-p (format "Remove follower %s? " handle))
+ (let ((response (mastodon-http--post url)))
+ (mastodon-http--triage response
+ (lambda ()
+ (message "Follower %s removed!" handle)))))))
+
+(defun mastodon-profile--remove-from-followers-at-point ()
+ "Prompt for a user in the item at point and remove from followers."
+ (interactive)
+ (let* ((handles (mastodon-profile--extract-users-handles
+ (mastodon-profile--toot-json)))
+ (handle (completing-read "Remove from followers: "
+ handles nil))
+ (account (mastodon-profile--lookup-account-in-status
+ handle (mastodon-profile--toot-json)))
+ (id (alist-get 'id account)))
+ (mastodon-profile--remove-user-from-followers id)))
+
+(defun mastodon-profile--remove-from-followers-list ()
+ "Select a user from your followers and remove from followers.
+Currently limited to 100 handles. If not found, try
+`mastodon-search--search-query'."
+ (interactive)
+ (let* ((endpoint (format "accounts/%s/followers"
+ (mastodon-auth--get-account-id)))
+ (url (mastodon-http--api endpoint))
+ (response (mastodon-http--get-json url
+ `(("limit" . "100"))))
+ (handles (mapcar (lambda (x)
+ (cons
+ (alist-get 'acct x)
+ (alist-get 'id x)))
+ response))
+ (choice (completing-read "Remove from followers: "
+ handles))
+ (id (alist-get choice handles nil nil 'equal)))
+ (mastodon-profile--remove-user-from-followers id)))
+
(provide 'mastodon-profile)
;;; mastodon-profile.el ends here