Commit 3ac98a8153e2

Vincent Demeester <vincent@sbr.pm>
2025-02-21 12:12:38
tools/emacs: trying something to show details of a notification
Doesn't really work.
1 parent 5a49716
Changed files (1)
tools/emacs/lisp/gh-notifications-mode.el
@@ -44,11 +44,25 @@
     (define-key map (kbd "a") 'github-notifications-approve-pr)
     (define-key map (kbd "w") 'github-notifications-copy-url)
     (define-key map (kbd "r") 'github-notifications-request-changes-on-pr)
+    (define-key map (kbd "v") 'github-notifications-show-details)
     (define-key map (kbd "RET") 'github-notifications-open-at-point)
     ;; m for mark
     map)
   "Keymap for GitHub notifications buffer.")
 
+(defvar github-notifications-detail-buffer-name "*GitHub Notification Detail*"
+  "Name of the buffer for displaying GitHub notification details.")
+
+(defvar github-notifications-detail-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "q") 'quit-window)
+    map)
+  "Keymap for GitHub notification detail buffer.")
+
+(define-derived-mode github-notifications-detail-mode special-mode "GitHub-Notification-Detail"
+  "Major mode for displaying GitHub notification details."
+  (setq buffer-read-only t))
+
 (defvar github-notifications--process-buffer "*github-notifications-process*"
   "Buffer for GitHub notifications processes.")
 
@@ -103,37 +117,38 @@ Creates a temporary buffer for the process output."
 (defun github-notifications--format-list-entry (notification)
   "Format a NOTIFICATION as a tabulated list entry."
   (let-alist notification
-      (list .id
-            (vector
-             (github-notifications--format-unread .unread)
-             (if (string= .type "PullRequest")
-		 (github-notifications--format-ci-status .ci_status)
-	       " ")
-	     ;; (if (string= .type "PullRequest")
-	     ;; 	 (or .ci_status "?")
-             ;;   "")
-             .repo
-             .type
-             (propertize .title
-                         'notification-id .id
-                        'github-notifications--copy-url .url
-                        'notification-type .type
-                        'repo .repo)
-             (github-notifications--format-time .updated)))))
+    (list .id
+          (vector
+           (github-notifications--format-unread .unread)
+           (if (string= .type "PullRequest")
+	       (github-notifications--format-ci-status .ci_status)
+	     " ")
+	   ;; (if (string= .type "PullRequest")
+	   ;; 	 (or .ci_status "?")
+           ;;   "")
+           .repo
+           .type
+           (propertize .title
+                       'notification-id .id
+                       'notification-url .url  ; Add this line
+                       'github-notifications--copy-url .url
+                       'notification-type .type
+                       'repo .repo)
+           (github-notifications--format-time .updated)))))
 
 (defun github-notifications-fetch ()
   "Fetch notifications using gh CLI asynchronously."
   (github-notifications--ensure-gh)
   (github-notifications--call-process-async
-     (lambda (output)
-       (let* ((raw-notifications (github-notifications--parse-json output))
-              (normalized-notifications
-               (mapcar #'github-notifications--normalize-notification raw-notifications)))
-         ;; For each PR notification, fetch its status
-         (dolist (notif normalized-notifications)
-           (when (and (equal (alist-get 'type notif) "PullRequest"))
-             (github-notifications--get-pr-statuses notif))
-	   ;; FIXME there is a bug here, it share the same thing
+   (lambda (output)
+     (let* ((raw-notifications (github-notifications--parse-json output))
+            (normalized-notifications
+             (mapcar #'github-notifications--normalize-notification raw-notifications)))
+       ;; For each PR notification, fetch its status
+       (dolist (notif normalized-notifications)
+         (when (and (equal (alist-get 'type notif) "PullRequest"))
+           (github-notifications--get-pr-statuses notif))
+	 ;; FIXME there is a bug here, it share the same thing
          (github-notifications--display normalized-notifications))))
    (get-buffer-create github-notifications--process-buffer)
    "github-notifications"
@@ -175,9 +190,9 @@ Creates a temporary buffer for the process output."
     (github-notifications--ensure-gh)
     (with-temp-buffer
       (unless (= 0 (call-process "gh" nil t nil
-                                "api"
-                                "-X" "PATCH"
-                                (format "/notifications/threads/%s" id)))
+                                 "api"
+                                 "-X" "PATCH"
+                                 (format "/notifications/threads/%s" id)))
         (error "Failed to mark notification as read")))
     (github-notifications-refresh)))
 
@@ -189,9 +204,9 @@ Creates a temporary buffer for the process output."
     (github-notifications--ensure-gh)
     (with-temp-buffer
       (unless (= 0 (call-process "gh" nil t nil
-                                "api"
-                                "-X" "DELETE"
-                                (format "/notifications/threads/%s" id)))
+                                 "api"
+                                 "-X" "DELETE"
+                                 (format "/notifications/threads/%s" id)))
         (error "Failed to mark notification as done")))
     (github-notifications-refresh)))
 
@@ -201,12 +216,12 @@ Creates a temporary buffer for the process output."
   (let* ((entry (github-notifications--get-entry-data))
 	 (api-url (nth 3 entry))
 	 (url (replace-regexp-in-string
-                   "api\\.github\\.com/repos"
-                   "github.com"
-                   (replace-regexp-in-string
-                    "/pulls/"
-                    "/pull/"
-                    api-url))))
+               "api\\.github\\.com/repos"
+               "github.com"
+               (replace-regexp-in-string
+                "/pulls/"
+                "/pull/"
+                api-url))))
     (kill-new url)))
 
 (defun github-notifications-open-at-point ()
@@ -216,12 +231,12 @@ Creates a temporary buffer for the process output."
               (title-col (aref entry 3))
               (url (get-text-property 0 'notification-url title-col)))
     (let ((web-url (replace-regexp-in-string
-                   "api\\.github\\.com/repos"
-                   "github.com"
-                   (replace-regexp-in-string
-                    "/pulls/"
-                    "/pull/"
-                    url))))
+                    "api\\.github\\.com/repos"
+                    "github.com"
+                    (replace-regexp-in-string
+                     "/pulls/"
+                     "/pull/"
+                     url))))
       (browse-url web-url))))
 
 (defun github-notifications--get-entry-data ()
@@ -276,9 +291,9 @@ Creates a temporary buffer for the process output."
          (repo (nth 1 pr-data))
          (pr-number (nth 2 pr-data))
          (args (list "pr" "review"
-                    pr-number
-                    "--approve"
-		    "--repo" repo)))
+                     pr-number
+                     "--approve"
+		     "--repo" repo)))
     (when (and repo pr-number)
       (when (and comment (not (string-empty-p comment)))
         (setq args (append args (list "--body" comment))))
@@ -321,9 +336,9 @@ Creates a temporary buffer for the process output."
 		  (failures (seq-count (lambda (s) (string= s "failure")) statuses))
 		  (pendings (seq-count (lambda (s) (string= s "pending")) statuses))
 		  (ci-status (list :total total
-			:successes successes
-			:failures failures
-			:pendings pendings)))
+				   :successes successes
+				   :failures failures
+				   :pendings pendings)))
 	     (setf (alist-get 'ci_status notification) ci-status)))
 	 (get-buffer-create (format "*github-notifications-%s-%s-process*" repo pr-number))
 	 (format "github-notifications-%s-%s" repo pr-number)
@@ -405,6 +420,85 @@ Creates a temporary buffer for the process output."
   (when (string-match "/pulls/\\([0-9]+\\)" url)
     (match-string 1 url)))
 
+(defun github-notifications-show-details ()
+  "Show detailed view of the notification at point."
+  (interactive)
+  (when-let* ((entry (tabulated-list-get-entry))
+              (title-cell (aref entry 4))
+              (type (get-text-property 0 'notification-type title-cell))
+              (repo (get-text-property 0 'repo title-cell))
+              (url (get-text-property 0 'github-notifications--copy-url title-cell)))
+    (let ((buffer (get-buffer-create github-notifications-detail-buffer-name)))
+      (with-current-buffer buffer
+        (let ((inhibit-read-only t))
+          (erase-buffer)
+          (github-notifications-detail-mode)
+          (cond
+           ((string= type "PullRequest")
+            (github-notifications--show-pr-details repo url))
+           ((string= type "Issue")
+            (github-notifications--show-issue-details repo url))
+           (t
+            (insert "No detailed view available for this notification type."))))
+        (goto-char (point-min)))
+      (display-buffer buffer))))
+
+(defun github-notifications--show-pr-details (repo url)
+  "Show pull request details for REPO and URL."
+  (let ((pr-number (github-notifications--get-pr-number url)))
+    (when pr-number
+      (insert (format "=== Pull Request #%s ===\n\n" pr-number))
+      ;; Fetch PR details
+      (github-notifications--call-process-async
+       (lambda (output)
+         (let ((inhibit-read-only t))
+           (save-excursion
+             (goto-char (point-min))
+             (forward-line 2)
+             (let* ((pr-data (github-notifications--parse-json output)))
+               (insert (format "Title: %s\n" (alist-get 'title pr-data)))
+               (insert (format "State: %s\n" (alist-get 'state pr-data)))
+               (insert (format "\nDescription:\n%s\n" (alist-get 'body pr-data)))))))
+       nil
+       "pr-details"
+       "pr" "view" pr-number "--json" "title,body,state" "--repo" repo)
+      
+      ;; Fetch and display diff
+      (insert "\n=== Diff ===\n\n")
+      (github-notifications--call-process-async
+       (lambda (output)
+         (let ((inhibit-read-only t))
+           (save-excursion
+             (goto-char (point-max))
+             (insert output)
+             (let ((diff-start (save-excursion
+                                 (goto-char (point-min))
+                                 (search-forward "\n=== Diff ===\n\n" nil t))))
+               (when diff-start
+                 (diff-mode-setup))))))
+       nil
+       "pr-diff"
+       "pr" "diff" pr-number "--repo" repo))))
+
+(defun github-notifications--get-issue-number (url)
+  "Extract issue number from URL."
+  (when (string-match "/issues/\\([0-9]+\\)" url)
+    (match-string 1 url)))
+
+(defun github-notifications--format-checks (checks)
+  "Format checks data for display."
+  (mapconcat
+   (lambda (check)
+     (let-alist check
+       (format "%s: %s"
+               .name
+               (propertize .status 'face
+                           (pcase .status
+                             ("success" '(:foreground "green"))
+                             ("failure" '(:foreground "red"))
+                             (_ '(:foreground "yellow")))))))
+   checks "\n"))
+
 ;;;###autoload
 (defun github-notifications ()
   "Display GitHub notifications in a buffer."