Search for me button

Adds a 'Search for me' button to Mastodon instances for quick self-mention searches

当前为 2024-09-20 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Search for me button
  3. // @namespace http://tampermonkey.net/
  4. // @version 2024-09-21
  5. // @description Adds a 'Search for me' button to Mastodon instances for quick self-mention searches
  6. // @author Sevi Che
  7. // @match https://*/*
  8. // @grant GM_getValue
  9. // @grant GM_setValue
  10. // @grant GM_registerMenuCommand
  11. // @run-at document-idle
  12. // @license MIT
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. // Function to get the list of Mastodon instances
  19. function getMastodonInstances() {
  20. return GM_getValue('mastodonInstances', ['mastodon.social']);
  21. }
  22.  
  23. // Function to save the list of Mastodon instances
  24. function saveMastodonInstances(instances) {
  25. GM_setValue('mastodonInstances', instances);
  26. }
  27.  
  28. // Function to prompt user for Mastodon instances
  29. function promptForInstances() {
  30. const currentInstances = getMastodonInstances().join(', ');
  31. const input = prompt('Enter Mastodon instance URLs (comma-separated):', currentInstances);
  32. if (input !== null) {
  33. const instances = input.split(',').map(url => url.trim()).filter(url => url);
  34. saveMastodonInstances(instances);
  35. alert('Mastodon instances updated. Please refresh the page for changes to take effect.');
  36. }
  37. }
  38.  
  39. // Register menu command to customize instances
  40. GM_registerMenuCommand('Customize Mastodon Instances', promptForInstances);
  41.  
  42. function setReactInputValue(input, value) {
  43. const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
  44. nativeInputValueSetter.call(input, value);
  45. input.dispatchEvent(new Event('input', { bubbles: true }));
  46. }
  47.  
  48. function handleSearchForMe() {
  49. const searchInput = document.querySelector('input.search__input[type="text"]');
  50. if (searchInput) {
  51. const currentValue = searchInput.value.trim();
  52. const newValue = currentValue ? `from:me ${currentValue} ` : 'from:me ';
  53. setReactInputValue(searchInput, newValue);
  54. searchInput.focus();
  55. }
  56. }
  57.  
  58. function addSearchForMeButton() {
  59. const searchInput = document.querySelector('input.search__input[type="text"]');
  60. if (searchInput && !document.querySelector('#search-for-me-button')) {
  61. const button = document.createElement('button');
  62. button.id = 'search-for-me-button';
  63. button.textContent = 'Me';
  64. button.style.cssText = `
  65. position: absolute;
  66. left: 8px;
  67. top: 50%;
  68. transform: translateY(-50%);
  69. background-color: var(--color-accent-bg, #f7e7ed);
  70. color: var(--color-accent, #d3487f);
  71. border: 1px solid var(--color-accent, #d3487f);
  72. border-radius: 4px;
  73. padding: 2px 6px;
  74. font-size: 12px;
  75. cursor: pointer;
  76. z-index: 1;
  77. transition: background-color 0.2s, color 0.2s, border-color 0.2s;
  78. `;
  79. button.addEventListener('click', handleSearchForMe);
  80. button.addEventListener('mouseover', () => {
  81. button.style.backgroundColor = 'var(--color-accent, #d3487f)';
  82. button.style.color = 'var(--color-accent-fg, #ffffff)';
  83. });
  84. button.addEventListener('mouseout', () => {
  85. button.style.backgroundColor = 'var(--color-accent-bg, #f7e7ed)';
  86. button.style.color = 'var(--color-accent, #d3487f)';
  87. });
  88. searchInput.style.paddingLeft = '40px'; // Make room for the button
  89. searchInput.parentNode.style.position = 'relative';
  90. searchInput.parentNode.insertBefore(button, searchInput);
  91. }
  92. }
  93.  
  94. function init() {
  95. const instances = getMastodonInstances();
  96. const currentHost = window.location.hostname;
  97.  
  98. if (instances.includes(currentHost)) {
  99. addSearchForMeButton();
  100. const observer = new MutationObserver((mutations) => {
  101. if (!document.querySelector('#search-for-me-button')) {
  102. addSearchForMeButton();
  103. }
  104. });
  105. observer.observe(document.body, { childList: true, subtree: true });
  106. }
  107. }
  108.  
  109. if (document.readyState === 'loading') {
  110. document.addEventListener('DOMContentLoaded', init);
  111. } else {
  112. init();
  113. }
  114. })();