@@ -34,6 +34,7 @@ GH_NOTIFY_PER_PAGE_LIMIT=50
34
34
: " ${GH_NOTIFY_VIEW_PATCH_KEY:= ctrl-p} "
35
35
: " ${GH_NOTIFY_RELOAD_KEY:= ctrl-r} "
36
36
: " ${GH_NOTIFY_MARK_READ_KEY:= ctrl-t} "
37
+ : " ${GH_NOTIFY_MARK_DONE_KEY:= ctrl-w} "
37
38
: " ${GH_NOTIFY_COMMENT_KEY:= ctrl-x} "
38
39
: " ${GH_NOTIFY_TOGGLE_KEY:= ctrl-y} "
39
40
: " ${GH_NOTIFY_RESIZE_PREVIEW_KEY:= btab} "
@@ -162,6 +163,7 @@ ${WHITE_BOLD}Key Bindings fzf${NC}
162
163
${GREEN}${GH_NOTIFY_VIEW_PATCH_KEY} ${NC} view diff in patch format
163
164
${GREEN}${GH_NOTIFY_RELOAD_KEY} ${NC} reload
164
165
${GREEN}${GH_NOTIFY_MARK_READ_KEY} ${NC} mark the selected notification as read and reload
166
+ ${GREEN}${GH_NOTIFY_MARK_DONE_KEY} ${NC} mark the selected notification as both read and done, and reload
165
167
${GREEN}${GH_NOTIFY_COMMENT_KEY} ${NC} write a comment with the editor and quit
166
168
${GREEN}${GH_NOTIFY_TOGGLE_KEY} ${NC} toggle the selected notification
167
169
${GREEN} esc ${NC} quit
@@ -539,14 +541,43 @@ mark_individual_read() {
539
541
fi
540
542
}
541
543
544
+ mark_individual_done () {
545
+ local thread_id thread_state
546
+ declare -a array_threads=()
547
+ while IFS=' ' read -r _ thread_id thread_state _; do
548
+ if [[ $thread_state == " UNREAD" ]]; then
549
+ array_threads+=(" $thread_id " )
550
+ fi
551
+ done < " $1 "
552
+
553
+ if [[ ${# array_threads[@]} -eq 1 ]]; then
554
+ gh_rest_api --silent --method DELETE " notifications/threads/${array_threads[0]} " ||
555
+ die " Failed to mark notifications as done."
556
+ elif [[ ${# array_threads[@]} -gt 1 ]]; then
557
+ # If there is a large number of threads to be processed, the number of background jobs can
558
+ # put pressure on the PC. Additionally, too many requests in short succession can trigger a
559
+ # rate limit by GitHub. Therefore, we process the threads in batches of 30, with a short
560
+ # delay of 0.3 seconds between each batch. This approach worked well in my tests with 200
561
+ # notifications.
562
+ for (( i = 0 ; i < ${# array_threads[@]} ; i += 30 )) ; do
563
+ for j in " ${array_threads[@]: i: 30} " ; do
564
+ # Running commands in the background of a script can cause it to hang, especially if
565
+ # the command outputs to stdout: https://tldp.org/LDP/abs/html/x9644.html#WAITHANG
566
+ gh_rest_api --silent --method DELETE " notifications/threads/${j} " & > /dev/null &
567
+ done
568
+ command sleep 0.3
569
+ done
570
+ fi
571
+ }
572
+
542
573
select_notif () {
543
574
local output expected_key selected_line repo_full_name type num
544
575
# Export functions to child processes. 'fzf' executes commands with $SHELL -c; to ensure
545
576
# compatibility when the default shell is not bash, set 'SHELL="$(which bash)"'.
546
577
export -f print_help_text print_notifs get_notifs
547
578
export -f process_page process_discussion process_url gh_rest_api
548
579
export -f highlight_output open_in_browser view_notification view_in_pager
549
- export -f mark_all_read mark_individual_read
580
+ export -f mark_all_read mark_individual_read mark_individual_done
550
581
# The 'die' function is not exported because 'fzf' warns you about the error in
551
582
# a failed 'print_notifs' call, but does not display the message.
552
583
@@ -562,6 +593,7 @@ select_notif() {
562
593
--bind " ${GH_NOTIFY_VIEW_PATCH_KEY} :toggle-preview+change-preview:if command grep -q PullRequest <<<{10}; then command gh pr diff {11} --patch --repo {5} | highlight_output; else view_notification {}; fi" \
563
594
--bind " ${GH_NOTIFY_RELOAD_KEY} :reload:print_notifs || true" \
564
595
--bind " ${GH_NOTIFY_MARK_READ_KEY} :execute-silent(mark_individual_read {+f})+reload:print_notifs || true" \
596
+ --bind " ${GH_NOTIFY_MARK_DONE_KEY} :execute-silent(mark_individual_read {+f}; mark_individual_done {+f})+reload:print_notifs || true" \
565
597
--bind " ${GH_NOTIFY_TOGGLE_KEY} :toggle+down" \
566
598
--bind " ${GH_NOTIFY_VIEW_KEY} :execute:view_in_pager {}" \
567
599
--bind " ${GH_NOTIFY_TOGGLE_PREVIEW_KEY} :toggle-preview+change-preview:view_notification {}" \
0 commit comments