diff options
Diffstat (limited to 'lisp/mastodon-profile.el')
-rw-r--r-- | lisp/mastodon-profile.el | 216 |
1 files changed, 152 insertions, 64 deletions
diff --git a/lisp/mastodon-profile.el b/lisp/mastodon-profile.el index fca1bd8..e130c22 100644 --- a/lisp/mastodon-profile.el +++ b/lisp/mastodon-profile.el @@ -32,6 +32,40 @@ ;; - Show only Media ;;; Code: +(require 'seq) + +(autoload 'mastodon-http--api "mastodon-http.el") +(autoload 'mastodon-http--get-json "mastodon-http.el") +(autoload 'mastodon-media--get-media-link-rendering "mastodon-media.el") +(autoload 'mastodon-media--inline-images "mastodon-media.el") +(autoload 'mastodon-mode "mastodon.el") +(autoload 'mastodon-tl--byline-author "mastodon-tl.el") +(autoload 'mastodon-tl--goto-next-toot "mastodon-tl.el") +(autoload 'mastodon-tl--property "mastodon-tl.el") +(autoload 'mastodon-tl--render-text "mastodon-tl.el") +(autoload 'mastodon-tl--set-face "mastodon-tl.el") +(autoload 'mastodon-tl--timeline "mastodon-tl.el") + +(defvar mastodon-instance-url) +(defvar mastodon-tl--buffer-spec) +(defvar mastodon-tl--update-point) + +(defvar mastodon-profile--account nil + "The data for the account being described in the current profile buffer.") +(make-variable-buffer-local 'mastodon-profile--account) + +(define-minor-mode mastodon-profile-mode + "Toggle mastodon profile minor mode. + +This minor mode is used for mastodon profile pages and adds a couple of +extra keybindings." + :init-value nil + ;; The mode line indicator. + :lighter " Profile" + ;; The key bindings + :keymap '(((kbd "F") . mastodon-profile--open-followers) + ((kbd "f") . mastodon-profile--open-following)) + :group 'mastodon) (defun mastodon-profile--toot-json () "Get the next toot-json." @@ -40,24 +74,56 @@ (defun mastodon-profile--make-author-buffer (account) "Take a ACCOUNT and inserts a user account into a new buffer." + (mastodon-profile--make-profile-buffer-for + account "statuses" #'mastodon-tl--timeline)) + +(defun mastodon-profile--open-following () + "Open a profile buffer for the current profile showing the accounts +that current profile follows." + (interactive) + (if mastodon-profile--account + (mastodon-profile--make-profile-buffer-for + mastodon-profile--account + "following" + #'mastodon-profile--add-author-bylines) + (error "Not in a mastodon profile"))) + +(defun mastodon-profile--open-followers () + "Open a profile buffer for the current profile showing the accounts +following the current profile." + (interactive) + (if mastodon-profile--account + (mastodon-profile--make-profile-buffer-for + mastodon-profile--account + "followers" + #'mastodon-profile--add-author-bylines) + (error "Not in a mastodon profile"))) + +(defun mastodon-profile--make-profile-buffer-for (account endpoint-type update-function) (let* ((id (mastodon-profile--account-field account 'id)) - (acct (mastodon-profile--account-field account 'acct)) - (url (mastodon-http--api - (concat "accounts/" - (format "%s" id) - "/statuses" ))) - (buffer (concat "*mastodon-" acct "*")) + (acct (mastodon-profile--account-field account 'acct)) + (url (mastodon-http--api (format "accounts/%s/%s" + id endpoint-type))) + (buffer (concat "*mastodon-" acct "-" endpoint-type "*")) (note (mastodon-profile--account-field account 'note)) (json (mastodon-http--get-json url))) (with-output-to-temp-buffer buffer (switch-to-buffer buffer) (mastodon-mode) - (setq mastodon-tl--buffer-spec + (mastodon-profile-mode) + (setq mastodon-profile--account account + mastodon-tl--buffer-spec `(buffer-name ,buffer - endpoint ,(format "accounts/%s/statuses" id) - update-function - ,'mastodon-tl--timeline json)) - (let ((inhibit-read-only t)) + endpoint ,(format "accounts/%s/%s" id endpoint-type) + update-function ,update-function)) + (let* ((inhibit-read-only t) + (is-statuses (string= endpoint-type "statuses")) + (is-followers (string= endpoint-type "followers")) + (is-following (string= endpoint-type "following")) + (endpoint-name (cond + (is-statuses " TOOTS ") + (is-followers " FOLLOWERS ") + (is-following " FOLLOWING ")))) (insert "\n" (mastodon-profile--image-from-account account) @@ -72,12 +138,12 @@ (mastodon-tl--render-text note nil) (mastodon-tl--set-face (concat " ------------\n" - " TOOTS \n" + endpoint-name "\n" " ------------\n") 'success)) - (setq mastodon-tl-update-point (point)) + (setq mastodon-tl--update-point (point)) (mastodon-media--inline-images (point-min) (point)) - (mastodon-tl--timeline json))) + (funcall update-function json))) (mastodon-tl--goto-next-toot))) (defun mastodon-profile--get-toot-author () @@ -92,73 +158,55 @@ (unless (equal url "/avatars/original/missing.png") (mastodon-media--get-media-link-rendering url)))) +(defun mastodon-profile--show-user (user-handle) + "Query user for user id from current status and show that user's profile." + (interactive + (list + (let ((user-handles (mastodon-profile--extract-users-handles + (mastodon-profile--toot-json)))) + (completing-read "User handle: " + user-handles + nil ; predicate + 'confirm)))) + (let ((account (mastodon-profile--lookup-account-in-status + user-handle (mastodon-profile--toot-json)))) + (if account + (mastodon-profile--make-author-buffer account) + (message "Cannot find a user with handle %S" user-handle)))) + (defun mastodon-profile--account-field (account field) "Return FIELD from the ACCOUNT. FIELD is used to identify regions under 'account" (cdr (assoc field account))) -(defun mastodon-profile--get-next-authour-id () - "Get the author id of the next toot." - (interactive) - (get-authour-id (toot-proporties))) - (defun mastodon-profile--add-author-bylines (tootv) "Convert TOOTV into a author-bylines and insert." (let ((inhibit-read-only t)) - (mapc (lambda(toot) - (insert (propertize - (mastodon-tl--byline-author - (list (append (list 'account) toot))) - 'byline 't - 'toot-id (cdr (assoc 'id toot)) 'toot-json toot) - "\n")) + (mapc (lambda (toot) + (let ((start-pos (point))) + (insert "\n" + (propertize + (mastodon-tl--byline-author `((account . ,toot))) + 'byline 't + 'toot-id (cdr (assoc 'id toot)) + 'toot-json toot)) + (mastodon-media--inline-images start-pos (point)) + (insert "\n" + (mastodon-tl--render-text (cdr (assoc 'note toot)) nil) + "\n"))) tootv))) -(defun mastodon-profile--get-following () - "Request a list of those who the user under point follows." - (interactive) - (mastodon-profile--make-follow-buffer "following")) - -(defun mastodon-profile--followers () - "Request a list of those following the user under point." - (interactive) - (mastodon-profile--make-follow-buffer "followers")) - -(defun mastodon-profile--make-follow-buffer (string) - "Make a buffer contining followers or following of user under point. - -STRING is an endpoint, either following or followers." - (let* ((account - (cdr (assoc 'account (mastodon-profile--toot-json)))) - (id (mastodon-profile--account-field - account 'id)) - (acct (mastodon-profile--account-field - account 'acct)) - (buffer (format "*%s-%s*" string acct)) - (tootv (mastodon-http--get-json - (mastodon-http--api (format "accounts/%s/%s" - id string))))) - (with-output-to-temp-buffer buffer - (switch-to-buffer buffer) - (mastodon-mode) - (setq mastodon-tl--buffer-spec - `(buffer-name ,buffer - endpoint ,(format "accounts/%s/%s" id string) - update-function - ,'mastodon-profile--add-author-bylines)) - (mastodon-profile--add-author-bylines tootv)))) - -(defun mastodon-profile--search-account-by-handle (handle) +(defun mastodon-profile--search-account-by-handle (handle) "Return an account based on a users HANDLE. -If the handle does not match a search return then retun NIL." +If the handle does not match a search return then retun NIL." (let* ((handle (if (string= "@" (substring handle 0 1)) (substring handle 1 (length handle)) handle)) (matching-account - (remove-if-not - (lambda(x) (string= (cdr (assoc 'acct x)) handle)) + (seq-remove + (lambda(x) (not (string= (cdr (assoc 'acct x)) handle))) (mastodon-http--get-json (mastodon-http--api (format "accounts/search?q=%s" handle)))))) (when (equal 1 (length matching-account)) @@ -169,5 +217,45 @@ If the handle does not match a search return then retun NIL." (mastodon-http--get-json (mastodon-http--api (format "accounts/%s" user-id)))) +(defun mastodon-profile--extract-users-handles (status) + "Return all user handles found in STATUS. + +These include the author, author of reblogged entries and any user mentioned." + (when status + (let ((this-account (cdr (assoc 'account status))) + (mentions (cdr (assoc 'mentions status))) + (reblog (cdr (assoc 'reblog status)))) + (seq-filter + 'stringp + (seq-uniq + (seq-concatenate + 'list + (list (cdr (assoc 'acct this-account))) + (mastodon-profile--extract-users-handles reblog) + (mapcar (lambda (mention) + (cdr (assoc 'acct mention))) + mentions))))))) + +(defun mastodon-profile--lookup-account-in-status (handle status) + "Return account for HANDLE using hints in STATUS if possible." + (let* ((this-account (cdr (assoc 'account status))) + (reblog-account (cdr (assoc 'account (cdr (assoc 'reblog status))))) + (mention-id (seq-some + (lambda (mention) + (when (string= handle + (cdr (assoc 'acct mention))) + (cdr (assoc 'id mention)))) + (cdr (assoc 'mentions status))))) + (cond ((string= handle + (cdr (assoc 'acct this-account))) + this-account) + ((string= handle + (cdr (assoc 'acct reblog-account))) + reblog-account) + (mention-id + (mastodon-profile--account-from-id mention-id)) + (t + (mastodon-profile--search-account-by-handle handle))))) + (provide 'mastodon-profile) ;;; mastodon-profile.el ends here |