Grok Delete File Uploads

Add a button to delete all uploaded files on grok.com/files

  1. // ==UserScript==
  2. // @name Grok Delete File Uploads
  3. // @namespace nisc
  4. // @version 2025.06.08-A
  5. // @description Add a button to delete all uploaded files on grok.com/files
  6. // @homepageURL https://github.com/nisc/grok-userscripts/
  7. // @author nisc
  8. // @match https://grok.com/files
  9. // @icon https://grok.com/images/favicon-light.png
  10. // @run-at document-end
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. /**
  18. * Configuration object containing all constants used in the script
  19. * - Button appearance and behavior settings
  20. * - DOM selectors for finding elements
  21. * - Timing delays for various operations
  22. */
  23. const CONFIG = {
  24. BUTTON_ID: 'delete-all-btn',
  25. BUTTON_TEXT: 'Delete all files',
  26. BUTTON_STYLES: {
  27. backgroundColor: 'white',
  28. color: 'black',
  29. padding: '8px 12px',
  30. border: 'none',
  31. borderRadius: '8px',
  32. cursor: 'pointer',
  33. marginBottom: '30px'
  34. },
  35. CONTAINER_SELECTOR: '.max-w-\\[50rem\\]',
  36. DELETE_BUTTON_SELECTOR: 'button[aria-label="Delete"]',
  37. CONFIRM_BUTTON_SELECTOR: 'button[aria-label="Confirm"]',
  38. DELAYS: {
  39. DELETE_BUTTON: 200, // Time to wait after clicking delete button
  40. CONFIRM_BUTTON: 200, // Time to wait after clicking confirm button
  41. MODAL_RENDER: 500 // Time to wait for all modals to render
  42. }
  43. };
  44.  
  45. /**
  46. * Utility function to create a promise that resolves after specified milliseconds
  47. * Used to add necessary delays between operations
  48. */
  49. const sleep = ms => new Promise(res => setTimeout(res, ms));
  50.  
  51. /**
  52. * Main deletion function that:
  53. * 1. Clicks all delete buttons sequentially
  54. * 2. Waits for confirmation modals to render
  55. * 3. Clicks all confirm buttons sequentially
  56. *
  57. * Delays are added between operations to ensure UI can keep up
  58. */
  59. async function deleteAll() {
  60. // First phase: Click all delete buttons
  61. const deleteButtons = Array.from(document.querySelectorAll(CONFIG.DELETE_BUTTON_SELECTOR));
  62. if (deleteButtons.length === 0) {
  63. return;
  64. }
  65.  
  66. for (const btn of deleteButtons) {
  67. btn.click();
  68. await sleep(CONFIG.DELAYS.DELETE_BUTTON);
  69. }
  70.  
  71. // Wait for all confirmation modals to render
  72. await sleep(CONFIG.DELAYS.MODAL_RENDER);
  73.  
  74. // Second phase: Confirm all deletions
  75. const confirmButtons = Array.from(document.querySelectorAll(CONFIG.CONFIRM_BUTTON_SELECTOR));
  76. if (confirmButtons.length === 0) {
  77. return;
  78. }
  79.  
  80. for (const conf of confirmButtons) {
  81. conf.click();
  82. await sleep(CONFIG.DELAYS.CONFIRM_BUTTON);
  83. }
  84. }
  85.  
  86. /**
  87. * Creates and adds the "Delete all files" button to the page
  88. * Only adds the button if it doesn't already exist
  89. */
  90. function addButton() {
  91. const container = document.querySelector(CONFIG.CONTAINER_SELECTOR);
  92. if (container && !document.getElementById(CONFIG.BUTTON_ID)) {
  93. const btn = document.createElement('button');
  94. btn.id = CONFIG.BUTTON_ID;
  95. btn.textContent = CONFIG.BUTTON_TEXT;
  96. Object.assign(btn.style, CONFIG.BUTTON_STYLES);
  97. btn.addEventListener('click', deleteAll);
  98. container.insertBefore(btn, container.firstChild);
  99. }
  100. }
  101.  
  102. // Watch for DOM changes and try to add button when possible
  103. // This ensures the button is added even if the container loads dynamically
  104. new MutationObserver(addButton).observe(document.body, { childList: true, subtree: true });
  105.  
  106. // Initial attempt to add the button
  107. addButton();
  108. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址