Delete Thread

Delete thread on Perplexity by pressing the Delete key and confirming with Enter

  1. // ==UserScript==
  2. // @name Delete Thread
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1.3
  5. // @description Delete thread on Perplexity by pressing the Delete key and confirming with Enter
  6. // @author JJJ
  7. // @match https://www.perplexity.ai/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=perplexity.ai
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16. // Listen for keydown events
  17. document.addEventListener('keydown', function (event) {
  18. // If the Delete key is pressed, open the menu and trigger the delete thread action
  19. if (event.key === 'Delete') {
  20. openMenuAndDeleteThread();
  21. }
  22. // If the Enter key is pressed, confirm the deletion
  23. else if (event.key === 'Enter') {
  24. confirmDeletion();
  25. }
  26. // If the ESC key is pressed, cancel the deletion
  27. else if (event.key === 'Escape') {
  28. cancelDeletion();
  29. }
  30. });
  31.  
  32. // Function to open the menu and trigger the delete thread action
  33. function openMenuAndDeleteThread() {
  34. var ellipsisButton = document.querySelector('[data-testid="thread-dropdown-menu"]');
  35. if (ellipsisButton) {
  36. ellipsisButton.click();
  37. setTimeout(deleteThread, 10); // Wait for a short time before triggering the delete thread action
  38. } else {
  39. console.log('Dropdown menu button not found');
  40. }
  41. }
  42.  
  43. // Function to trigger the delete thread action
  44. function deleteThread() {
  45. var deleteButton = document.querySelector('[data-testid="thread-delete"]');
  46. if (deleteButton) {
  47. deleteButton.click();
  48. console.log('Thread deletion triggered');
  49. } else {
  50. var deleteButtonText = Array.from(document.querySelectorAll('span')).find(button => button.textContent === 'Delete');
  51. if (deleteButtonText) {
  52. deleteButtonText.click();
  53. console.log('Thread deletion triggered via text content');
  54. } else {
  55. console.log('Delete button not found');
  56. }
  57. }
  58. }
  59.  
  60. // Function to confirm the deletion
  61. function confirmDeletion() {
  62. // Prefer new data-testid selector
  63. var confirmButton = document.querySelector('[data-testid="thread-delete-confirm"]');
  64. if (!confirmButton) {
  65. // Fallback to old class-based selector
  66. confirmButton = document.querySelector('.bg-superAlt.text-white');
  67. }
  68. if (confirmButton) {
  69. confirmButton.click();
  70. console.log('Confirm triggered');
  71. } else {
  72. console.log('Confirm button not found');
  73. }
  74. }
  75.  
  76. // Function to cancel the deletion
  77. function cancelDeletion() {
  78. // Prefer new data-testid selector
  79. var nevermindButton = document.querySelector('[data-testid="thread-delete-nevermind"]');
  80. if (!nevermindButton) {
  81. // Fallback to button with text content
  82. nevermindButton = Array.from(document.querySelectorAll('button')).find(
  83. button => button.textContent.trim() === 'Nevermind'
  84. );
  85. }
  86. if (!nevermindButton) {
  87. // Fallback to close button with data-testid
  88. nevermindButton = document.querySelector('[data-testid="close-modal"]');
  89. }
  90. if (!nevermindButton) {
  91. // Fallback to previous class-based selector as last resort
  92. nevermindButton = document.querySelector('button.bg-offsetPlus.dark\\:bg-offsetPlusDark.text-textMain.dark\\:text-textMainDark');
  93. }
  94. if (nevermindButton) {
  95. nevermindButton.click();
  96. console.log('Deletion canceled successfully');
  97. } else {
  98. console.log('Cancel button not found');
  99. }
  100. }
  101. })();