Mark All Merged Notifications Done

Marks all merged notifications as "done" on GitHub (client-side) and only shows UI when needed. Includes console logging and error handling.

当前为 2025-02-17 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Mark All Merged Notifications Done
  3. // @namespace typpi.online
  4. // @version 1.6
  5. // @description Marks all merged notifications as "done" on GitHub (client-side) and only shows UI when needed. Includes console logging and error handling.
  6. // @author Nick2bad4u
  7. // @match https://github.com/notifications
  8. // @grant GM_addStyle
  9. // @grant GM_xmlhttpRequest
  10. // @connect api.github.com
  11. // @license Unlicense
  12. // @tag github
  13. // @icon https://www.google.com/s2/favicons?sz=64&domain=github.com
  14. // @homepageURL https://github.com/Nick2bad4u/UserStyles
  15. // @supportURL https://github.com/Nick2bad4u/UserStyles/issues
  16. // ==/UserScript==
  17.  
  18. (function() {
  19. 'use strict';
  20.  
  21. const DONE_BUTTON_SELECTOR = 'button[aria-label="Done"]';
  22. const NOTIFICATION_SELECTOR = '.notifications-list-item';
  23. const MERGED_ICON_SELECTOR = 'svg.octicon-git-merge';
  24. const DELAY_MS = 500; // Delay after each action (adjust as needed)
  25.  
  26. let markAsDoneButton; // Declare the button outside the function
  27.  
  28. function addButton() {
  29. try {
  30. markAsDoneButton = document.createElement('button');
  31. markAsDoneButton.textContent = 'Mark All Merged Done';
  32. markAsDoneButton.classList.add('mark-merged-done-button');
  33. markAsDoneButton.addEventListener('click', markAllMergedAsDone);
  34. markAsDoneButton.style.display = 'none'; // Initially hide the button
  35.  
  36. const notificationsToolbar = document.querySelector('.js-socket-channel.js-updatable-content');
  37. if (notificationsToolbar) {
  38. notificationsToolbar.appendChild(markAsDoneButton);
  39. console.log('Mark All Merged Done button added to notifications toolbar.');
  40. } else {
  41. console.warn('Could not find notifications toolbar. Button may not be visible.');
  42. document.body.appendChild(markAsDoneButton); // Fallback
  43. console.log('Mark All Merged Done button added to document body as fallback.');
  44. }
  45.  
  46. // Check for merged notifications and show the button if needed
  47. checkForMergedNotifications();
  48. } catch (error) {
  49. console.error('Error in addButton function:', error);
  50. }
  51. }
  52.  
  53. function checkForMergedNotifications() {
  54. try {
  55. const notifications = document.querySelectorAll(NOTIFICATION_SELECTOR);
  56. let hasMergedNotifications = false;
  57.  
  58. for (const notification of notifications) {
  59. if (notification.querySelector(MERGED_ICON_SELECTOR)) {
  60. hasMergedNotifications = true;
  61. break; // No need to continue checking
  62. }
  63. }
  64.  
  65. if (hasMergedNotifications) {
  66. markAsDoneButton.style.display = 'block'; // Show the button
  67. console.log('Merged notifications found. Showing Mark All Merged Done button.');
  68. } else {
  69. markAsDoneButton.style.display = 'none'; // Hide the button
  70. console.log('No merged notifications found. Hiding Mark All Merged Done button.');
  71. }
  72. } catch (error) {
  73. console.error('Error in checkForMergedNotifications function:', error);
  74. }
  75. }
  76.  
  77. async function markAllMergedAsDone() {
  78. try {
  79. const notifications = document.querySelectorAll(NOTIFICATION_SELECTOR);
  80. console.log(`Found ${notifications.length} notifications.`);
  81.  
  82. for (const notification of notifications) {
  83. if (notification.querySelector(MERGED_ICON_SELECTOR)) {
  84. console.log('Marking merged notification as done');
  85. const doneButton = notification.querySelector(DONE_BUTTON_SELECTOR);
  86.  
  87. if (doneButton) {
  88. doneButton.click();
  89. await delay(DELAY_MS); // Wait for the UI to update
  90. // notification.remove(); // Remove the notification after clicking "Done"
  91. } else {
  92. console.warn('Could not find "Done" button for merged notification.');
  93. }
  94. }
  95. }
  96.  
  97. console.log('Finished processing notifications.');
  98. checkForMergedNotifications(); // Recheck after marking
  99. } catch (error) {
  100. console.error('Error in markAllMergedAsDone function:', error);
  101. }
  102. }
  103.  
  104. // Helper function to introduce a delay
  105. function delay(ms) {
  106. return new Promise(resolve => setTimeout(resolve, ms));
  107. }
  108.  
  109. const style = document.createElement('style');
  110. document.head.appendChild(style);
  111. style.textContent = `
  112. .mark-merged-done-button {
  113. position: fixed;
  114. bottom: 50px; /* Adjusted bottom position */
  115. right: 10px;
  116. z-index: 999; /* Ensure it's below the other button if necessary */
  117. background-color: #2ea44f; /* Same color as the other script */
  118. color: #ffffff;
  119. border: none;
  120. padding: 10px;
  121. border-radius: 5px;
  122. cursor: pointer;
  123. }
  124. .mark-merged-done-button:hover {
  125. background-color: #79e4f2; /* Same hover color as the other script */
  126. }
  127. `;
  128.  
  129. window.addEventListener('load', addButton);
  130. })();