diff --git a/finito-buffer.el b/finito-buffer.el index 0e2754d..bcf7bc3 100644 --- a/finito-buffer.el +++ b/finito-buffer.el @@ -88,6 +88,11 @@ "Face for the average rating in a summary buffer." :group 'finito) +(defface finito-review + '((t :foreground "grey")) + "Face for the content of a user book review." + :group 'finito) + ;;; Custom variables (defcustom finito-use-image-uris @@ -118,6 +123,15 @@ This can be overridden locally on a buffer by buffer basis via the :group 'finito :type 'boolean) +(defcustom finito-show-reviews-default + nil + "If non-nil, write reviews when displaying books in a finito buffer. + +This can be overridden locally on a buffer by buffer basis via the +\"v\" key, or alternatively via the `finito--show-reviews' local variable." + :group 'finito + :type 'boolean) + ;;; Constants (defconst finito--summary-recommended-text @@ -133,6 +147,9 @@ This can be overridden locally on a buffer by buffer basis via the (defvar finito-show-description-alist nil) (cl-pushnew 'finito-show-description-alist savehist-additional-variables) +(defvar finito-show-review-alist nil) +(cl-pushnew 'finito-show-review-alist savehist-additional-variables) + ;;; Buffer local variables (defvar-local finito--ewoc @@ -158,6 +175,10 @@ Its nodes should be alists of the form returned by nil "An override that can be used to show/hide descriptions in all finito buffers.") +(defvar-local finito--show-reviews + nil + "An override that can be used to show/hide user reviews in all finito buffers.") + ;;; Classes for working with buffers (defclass finito-book-writer () @@ -247,6 +268,20 @@ BOOK-ALIST is an alist of the format returned by `finito--create-book-alist'" 'face 'finito-book-descriptions))) +(cl-defmethod finito-insert-review ((_ finito-book-writer) review) + "Insert REVIEW into the current buffer." + (when (or (and (bound-and-true-p finito--collection) + (alist-get finito--collection + finito-show-review-alist + finito-show-reviews-default + nil + 'equal)) + (bound-and-true-p finito--show-reviews)) + (insert review "\n") + (overlay-put (make-overlay (- (point) 2) (- (point) (length review) 2)) + 'face + 'finito-book-reviews))) + (cl-defmethod finito-use-pagination ((_ finito-book-writer)) "Return non-nil if pagination should be used alongside this writer." t) diff --git a/finito.el b/finito.el index c1f8af2..2af6d90 100644 --- a/finito.el +++ b/finito.el @@ -396,12 +396,11 @@ request is successful" ((_ _ from-year) (calendar-current-date -30))) (cons (format "%s-01-01" from-year) (format "%s-%02d-%02d" year month day)))) -(defun finito--set-show-description-for-collection (collection flag) - "Set show description to FLAG for COLLECTION." - (if (member collection (mapcar #'car finito-show-description-alist)) - (setf (cdr (assoc finito--collection finito-show-description-alist)) flag) - (setq finito-show-description-alist - `((,collection . ,flag) . ,finito-show-description-alist)))) +(defun finito--set-show-attribute-for-collection (alist collection flag) + "Set show the attribute implied by ALIST to FLAG for COLLECTION." + (if (member collection (mapcar #'car alist)) + (setf (cdr (assoc finito--collection alist)) flag) + (setq alist `((,collection . ,flag) . ,alist)))) (defun finito--init-summary-buffer (summary-alist) "Create a summary buffer using data from SUMMARY-ALIST." @@ -468,9 +467,11 @@ request is successful" (define-key map "e" #'finito-series-at-point) (define-key map "w" #'finito-title-of-book-at-point) (define-key map "d" #'finito-toggle-show-descriptions) + (define-key map "W" #'finito-toggle-show-reviews) (define-key map "M" #'finito-toggle-minimal) (define-key map "g" #'revert-buffer) (define-key map "l" #'finito-replay-search) + (define-key map "R" #'finito-review-book-at-point) (define-key map (kbd "C-m") #'finito-open-my-books-collection) (define-key map (kbd "C-r") #'finito-open-currently-reading-collection) map)) @@ -826,11 +827,20 @@ maximum of MAX-RESULTS results." Note this overwrites any existing review." (interactive) (finito--wait-for-server-then - (let ((book (finito--book-at-point)) - (review (read-string "Review: "))) - (finito--replace-book-at-point-from-request - (finito--review-book-request-plist book review) - (format "Added review for '%s'" (alist-get 'title book)))))) + (let* ((book (finito--book-at-point)) + (buf (generate-new-buffer (format "%s Review" (alist-get 'title book))))) + (with-current-buffer buf + (local-set-key + (kbd "C-c C-c") + (lambda () (interactive) + (finito--make-request + (finito--review-book-request-plist + book + (buffer-substring-no-properties (point-min) (point-max))) + (lambda (&rest _) (format "Added review for '%s'" (alist-get 'title book)))) + (kill-buffer-and-window)))) + (pop-to-buffer buf '(display-buffer-below-selected . nil)) + (message "Use C-c C-c to submit the review")))) (defun finito-start-book-at-point (&optional date) "Mark the book at point as currently reading. @@ -1015,6 +1025,7 @@ Example: (kill-new title) (message "Copied '%s' to the kill ring" title)))) +;; The setq-local make these next two hard to DRY (defun finito-toggle-show-descriptions () "Toggle display of descriptions." (interactive) @@ -1026,8 +1037,10 @@ Example: nil 'equal)))) (cond ((bound-and-true-p finito--collection) - (finito--set-show-description-for-collection finito--collection - (not alist-val))) + (finito--set-show-attribute-for-collection + finito-show-description-alist + finito--collection + (not alist-val))) ((boundp 'finito--show-descriptions) (setq finito--show-descriptions (not local-val))) (t (setq-local finito--show-descriptions @@ -1037,6 +1050,30 @@ Example: (ewoc-goto-node finito--ewoc node)) (org-display-inline-images))) +(defun finito-toggle-show-reviews () + "Toggle display of reviews." + (interactive) + (let ((local-val (bound-and-true-p finito--show-reviews)) + (alist-val (when (bound-and-true-p finito--collection) + (alist-get finito--collection + finito-show-review-alist + finito-show-reviews-default + nil + 'equal)))) + (cond ((bound-and-true-p finito--collection) + (finito--set-show-attribute-for-collection + finito-show-review-alist + finito--collection + (not alist-val))) + ((boundp 'finito--show-reviews) + (setq finito--show-reviews (not local-val))) + (t (setq-local finito--show-reviews + (not finito-show-reviews-default)))) + (let ((node (ewoc-locate finito--ewoc))) + (ewoc-refresh finito--ewoc) + (ewoc-goto-node finito--ewoc node)) + (org-display-inline-images))) + (defun finito-toggle-minimal () "Toggle the book writer instance to/from a minimal book writer." (interactive)