X/Twitter 干净的选单和侧边栏(支持多种语言)

干净的 选单、Grok、高级订阅、已认证组织、其他、探索、通知、私信、书签、书签、右侧边栏和可自订设定

目前为 2025-03-09 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name X/Twitter Clean menu and sidebar (Supports multiple language)
  3. // @name:ja X/Twitter きれいなメニューとサイドバー(多言語対応)
  4. // @name:zh-TW X/Twitter 乾淨的選單和側邊欄(支持多種語言)
  5. // @name:zh-cn X/Twitter 干净的选单和侧边栏(支持多种语言)
  6. // @version 2.2
  7. // @description hidden Menu,Grok,Premium subscription,Verified Orgs,other,Explore,Notifications,Messages,Communities,Bookmarks,Right Column and Customizable Settings
  8. // @description:ja 清潔なメニュー、Grok、高度なサブスクリプション、認証済み組織、他の、探索、通知、メッセージ、コミュニティ、ブックマーク、右側カラム、およびカスタム設定
  9. // @description:zh-tw 乾淨的 選單、Grok、高級訂閱、已認證組織、其他、探索、通知、訊息、社群、書籤、右側邊欄和可自訂設定
  10. // @description:zh-cn 干净的 选单、Grok、高级订阅、已认证组织、其他、探索、通知、私信、书签、书签、右侧边栏和可自订设定
  11. // @license MIT
  12. // @author movwei
  13. // @match https://x.com/*
  14. // @match https://twitter.com/*
  15. // @grant GM_registerMenuCommand
  16. // @grant GM_setValue
  17. // @grant GM_getValue
  18. // @grant GM_addStyle
  19. // @namespace https://gf.qytechs.cn/users/1041101
  20. // ==/UserScript==
  21.  
  22. (function() {
  23. 'use strict';
  24.  
  25. const defaultSettings = {
  26. hideGrok: true,
  27. hidePremiumSignUp: true,
  28. hideSelectors: true,
  29. hideVerifiedOrgs: true,
  30. hideother: true,
  31. hideExplore: false,
  32. hideNotifications: false,
  33. hideBookmarks: false,
  34. hideMessages: false,
  35. hideCommunities: false,
  36. hideRightColumn: false,
  37. };
  38.  
  39. const settings = {
  40. hideGrok: GM_getValue('hideGrok', defaultSettings.hideGrok),
  41. hidePremiumSignUp: GM_getValue('hidePremiumSignUp', defaultSettings.hidePremiumSignUp),
  42. hideSelectors: GM_getValue('hideSelectors', defaultSettings.hideSelectors),
  43. hideVerifiedOrgs: GM_getValue('hideVerifiedOrgs', defaultSettings.hideVerifiedOrgs),
  44. hideother: GM_getValue('hideother', defaultSettings.hideother),
  45. hideExplore: GM_getValue('hideExplore', defaultSettings.hideExplore),
  46. hideNotifications: GM_getValue('hideNotifications', defaultSettings.hideNotifications),
  47. hideBookmarks: GM_getValue('hideBookmarks', defaultSettings.hideBookmarks),
  48. hideCommunities: GM_getValue('hideCommunities', defaultSettings.hideCommunities),
  49. hideMessages: GM_getValue('hideMessages', defaultSettings.hideMessages),
  50. hideRightColumn: GM_getValue('hideRightColumn', defaultSettings.hideRightColumn),
  51. };
  52.  
  53. // 多語言支持
  54. const language = navigator.language || navigator.userLanguage;
  55. const languages = {
  56. 'en': {
  57. 'hideGrok': 'Hide Grok',
  58. 'hidePremiumSignUp': 'Hide Premium Sign-up',
  59. 'hideSelectors': 'Hide Subscribe Message',
  60. 'hideVerifiedOrgs': 'Hide Verified Orgs',
  61. 'hideExplore': 'Hide Explore',
  62. 'hideNotifications': 'Hide Notifications',
  63. 'hideMessages': 'Hide Messages',
  64. 'hideCommunities': 'Hide Communities',
  65. 'hideBookmarks': 'Hide Bookmarks',
  66. 'hideother': 'Hide other',
  67. 'hideRightColumn': 'Hide Right Column',
  68. 'settings': 'Settings',
  69. 'saveRefresh': 'Save & refresh',
  70. 'close': 'Close'
  71. },
  72. 'zh-TW': {
  73. 'hideGrok': '隱藏 Grok',
  74. 'hidePremiumSignUp': '隱藏 高級訂閱',
  75. 'hideSelectors': '隱藏 訂閱訊息',
  76. 'hideVerifiedOrgs': '隱藏 已認證組織',
  77. 'hideExplore': '隱藏 探索',
  78. 'hideNotifications': '隱藏 通知',
  79. 'hideMessages': '隱藏 訊息',
  80. 'hideCommunities': '隱藏 社群',
  81. 'hideBookmarks': '隱藏 書籤',
  82. 'hideother': '隱藏 其他',
  83. 'hideRightColumn': '隱藏 右側邊欄',
  84. 'settings': '設定',
  85. 'saveRefresh': '保存並刷新',
  86. 'close': '關閉'
  87. },
  88. 'zh-CN': {
  89. 'hideGrok': '隐藏 Grok',
  90. 'hidePremiumSignUp': '隐藏 高级订阅',
  91. 'hideSelectors': '隐藏 订阅消息',
  92. 'hideVerifiedOrgs': '隐藏 已认证组织',
  93. 'hideExplore': '隐藏 探索',
  94. 'hideNotifications': '隐藏 通知',
  95. 'hideMessages': '隐藏 私信',
  96. 'hideCommunities': '隐藏 社群',
  97. 'hideBookmarks': '隐藏 书签',
  98. 'hideother': '隐藏 其他',
  99. 'hideRightColumn': '隐藏 右侧边栏',
  100. 'settings': '设置',
  101. 'saveRefresh': '保存并刷新',
  102. 'close': '关闭'
  103. },
  104. 'ja': {
  105. 'hideGrok': 'Grokを非表示',
  106. 'hidePremiumSignUp': 'プレミアムサインアップを非表示',
  107. 'hideSelectors': 'サブスクライブメッセージを非表示',
  108. 'hideVerifiedOrgs': '認証済み組織を非表示',
  109. 'hideExplore': '話題を検索を非表示',
  110. 'hideNotifications': '通知を非表示',
  111. 'hideMessages': 'メッセージを非表示',
  112. 'hideCommunities': 'コミュニティを非表示',
  113. 'hideBookmarks': 'ブックマークを非表示',
  114. 'hideother': '他のを非表示',
  115. 'hideRightColumn': '右側カラムを非表示',
  116. 'settings': '設定',
  117. 'saveRefresh': '保存してリフレッシュ',
  118. 'close': '閉じる'
  119. },
  120. };
  121.  
  122. const currentLanguage = languages[language] || languages['en'];
  123.  
  124. function createSettingsPanel() {
  125. const panel = document.createElement('div');
  126. panel.id = 'settingsPanel';
  127. panel.innerHTML = `
  128. <div id="settingsPanelContent">
  129. <div class="settings-header">
  130. <h2>${currentLanguage['settings']}</h2>
  131. </div>
  132.  
  133. <div class="settings-section">
  134. <label class="toggle-switch">
  135. <input type="checkbox" id="hideGrokCheckbox" ${settings.hideGrok ? 'checked' : ''}>
  136. <span class="toggle-slider"></span>
  137. <span class="toggle-label">${currentLanguage['hideGrok']}</span>
  138. </label>
  139. <label class="toggle-switch">
  140. <input type="checkbox" id="hidePremiumSignUpCheckbox" ${settings.hidePremiumSignUp ? 'checked' : ''}>
  141. <span class="toggle-slider"></span>
  142. <span class="toggle-label">${currentLanguage['hidePremiumSignUp']}</span>
  143. </label>
  144. <label class="toggle-switch">
  145. <input type="checkbox" id="hideSelectorsCheckbox" ${settings.hideSelectors ? 'checked' : ''}>
  146. <span class="toggle-slider"></span>
  147. <span class="toggle-label">${currentLanguage['hideSelectors']}</span>
  148. </label>
  149. <label class="toggle-switch">
  150. <input type="checkbox" id="hideVerifiedOrgsCheckbox" ${settings.hideVerifiedOrgs ? 'checked' : ''}>
  151. <span class="toggle-slider"></span>
  152. <span class="toggle-label">${currentLanguage['hideVerifiedOrgs']}</span>
  153. </label>
  154. <label class="toggle-switch">
  155. <input type="checkbox" id="hideotherCheckbox" ${settings.hideother ? 'checked' : ''}>
  156. <span class="toggle-slider"></span>
  157. <span class="toggle-label">${currentLanguage['hideother']}</span>
  158. </label>
  159. </div>
  160.  
  161. <div class="settings-section">
  162. <label class="toggle-switch">
  163. <input type="checkbox" id="hideExploreCheckbox" ${settings.hideExplore ? 'checked' : ''}>
  164. <span class="toggle-slider"></span>
  165. <span class="toggle-label">${currentLanguage['hideExplore']}</span>
  166. </label>
  167. <label class="toggle-switch">
  168. <input type="checkbox" id="hideNotificationsCheckbox" ${settings.hideNotifications ? 'checked' : ''}>
  169. <span class="toggle-slider"></span>
  170. <span class="toggle-label">${currentLanguage['hideNotifications']}</span>
  171. </label>
  172. <label class="toggle-switch">
  173. <input type="checkbox" id="hideMessagesCheckbox" ${settings.hideMessages ? 'checked' : ''}>
  174. <span class="toggle-slider"></span>
  175. <span class="toggle-label">${currentLanguage['hideMessages']}</span>
  176. </label>
  177. <label class="toggle-switch">
  178. <input type="checkbox" id="hideCommunitiesCheckbox" ${settings.hideCommunities ? 'checked' : ''}>
  179. <span class="toggle-slider"></span>
  180. <span class="toggle-label">${currentLanguage['hideCommunities']}</span>
  181. </label>
  182. <label class="toggle-switch">
  183. <input type="checkbox" id="hideBookmarksCheckbox" ${settings.hideBookmarks ? 'checked' : ''}>
  184. <span class="toggle-slider"></span>
  185. <span class="toggle-label">${currentLanguage['hideBookmarks']}</span>
  186. </label>
  187. </div>
  188.  
  189. <div class="settings-section">
  190. <label class="toggle-switch">
  191. <input type="checkbox" id="hideRightColumnCheckbox" ${settings.hideRightColumn ? 'checked' : ''}>
  192. <span class="toggle-slider"></span>
  193. <span class="toggle-label">${currentLanguage['hideRightColumn']}</label>
  194. </label>
  195. </div>
  196.  
  197. <div class="buttons-container">
  198. <button id="saveSettingsButton" class="panel-button primary-button">${currentLanguage['saveRefresh']}</button>
  199. <button id="closeSettingsButton" class="panel-button secondary-button">${currentLanguage['close']}</button>
  200. </div>
  201. </div>
  202. `;
  203. document.body.appendChild(panel);
  204. document.getElementById('saveSettingsButton').addEventListener('click', saveSettings);
  205. document.getElementById('closeSettingsButton').addEventListener('click', () => {
  206. document.getElementById('settingsPanel').style.display = 'none';
  207. });
  208. }
  209.  
  210. function saveSettings() {
  211. settings.hideGrok = document.getElementById('hideGrokCheckbox').checked;
  212. settings.hidePremiumSignUp = document.getElementById('hidePremiumSignUpCheckbox').checked;
  213. settings.hideSelectors = document.getElementById('hideSelectorsCheckbox').checked;
  214. settings.hideVerifiedOrgs = document.getElementById('hideVerifiedOrgsCheckbox').checked;
  215. settings.hideExplore = document.getElementById('hideExploreCheckbox').checked;
  216. settings.hideNotifications = document.getElementById('hideNotificationsCheckbox').checked;
  217. settings.hideBookmarks = document.getElementById('hideBookmarksCheckbox').checked;
  218. settings.hideMessages = document.getElementById('hideMessagesCheckbox').checked;
  219. settings.hideCommunities = document.getElementById('hideCommunitiesCheckbox').checked;
  220. settings.hideother = document.getElementById('hideotherCheckbox').checked;
  221. settings.hideRightColumn = document.getElementById('hideRightColumnCheckbox').checked;
  222.  
  223. GM_setValue('hideGrok', settings.hideGrok);
  224. GM_setValue('hidePremiumSignUp', settings.hidePremiumSignUp);
  225. GM_setValue('hideSelectors', settings.hideSelectors);
  226. GM_setValue('hideVerifiedOrgs', settings.hideVerifiedOrgs);
  227. GM_setValue('hideExplore', settings.hideExplore);
  228. GM_setValue('hideNotifications', settings.hideNotifications);
  229. GM_setValue('hideBookmarks', settings.hideBookmarks);
  230. GM_setValue('hideMessages', settings.hideMessages);
  231. GM_setValue('hideCommunities', settings.hideCommunities);
  232. GM_setValue('hideother', settings.hideother);
  233. GM_setValue('hideRightColumn', settings.hideRightColumn);
  234. location.reload();
  235. }
  236.  
  237. GM_addStyle(`
  238. #settingsPanel {
  239. width: 320px;
  240. position: fixed;
  241. top: 50%;
  242. left: 50%;
  243. transform: translate(-50%, -50%);
  244. background-color: #ffffff;
  245. border: none;
  246. padding: 0;
  247. z-index: 10000;
  248. display: none;
  249. box-shadow: 0 8px 30px rgba(0,0,0,0.12);
  250. border-radius: 16px;
  251. font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  252. overflow: hidden;
  253. }
  254.  
  255. #settingsPanelContent {
  256. display: flex;
  257. flex-direction: column;
  258. width: 100%;
  259. }
  260.  
  261. .settings-header {
  262. display: flex;
  263. justify-content: center;
  264. align-items: center;
  265. padding: 16px 20px;
  266. border-bottom: 1px solid rgba(0,0,0,0.08);
  267. }
  268.  
  269. #settingsPanel h2 {
  270. margin: 0;
  271. font-size: 18px;
  272. font-weight: 700;
  273. color: #0f1419;
  274. text-align: center;
  275. }
  276.  
  277. .settings-section {
  278. padding: 12px 20px;
  279. border-bottom: 1px solid rgba(0,0,0,0.08);
  280. }
  281.  
  282. .toggle-switch {
  283. position: relative;
  284. display: flex;
  285. align-items: center;
  286. margin: 12px 0;
  287. padding: 6px 0;
  288. cursor: pointer;
  289. }
  290.  
  291. .toggle-switch input {
  292. opacity: 0;
  293. width: 0;
  294. height: 0;
  295. }
  296.  
  297. .toggle-slider {
  298. position: relative;
  299. display: inline-block;
  300. width: 42px;
  301. height: 24px;
  302. background-color: #cfd9de;
  303. border-radius: 24px;
  304. transition: .3s;
  305. margin-right: 12px;
  306. flex-shrink: 0;
  307. }
  308.  
  309. .toggle-slider:before {
  310. position: absolute;
  311. content: "";
  312. height: 18px;
  313. width: 18px;
  314. left: 3px;
  315. bottom: 3px;
  316. background-color: white;
  317. border-radius: 50%;
  318. transition: .3s;
  319. }
  320.  
  321. input:checked + .toggle-slider {
  322. background-color: #1d9bf0;
  323. }
  324.  
  325. input:checked + .toggle-slider:before {
  326. transform: translateX(18px);
  327. }
  328.  
  329. .toggle-label {
  330. font-size: 15px;
  331. color: #0f1419;
  332. }
  333.  
  334. .buttons-container {
  335. display: flex;
  336. justify-content: center;
  337. padding: 16px 20px;
  338. gap: 10px;
  339. }
  340.  
  341. .panel-button {
  342. flex: 1;
  343. padding: 12px 0;
  344. font-size: 15px;
  345. font-weight: 600;
  346. border: none;
  347. border-radius: 9999px;
  348. cursor: pointer;
  349. transition: background-color 0.2s;
  350. text-align: center;
  351. }
  352.  
  353. .primary-button {
  354. color: white;
  355. background-color: #1d9bf0;
  356. }
  357.  
  358. .primary-button:hover {
  359. background-color: #1a8cd8;
  360. }
  361.  
  362. .secondary-button {
  363. color: #0f1419;
  364. background-color: #e6e7e7;
  365. }
  366.  
  367. .secondary-button:hover {
  368. background-color: #d1d1d1;
  369. }
  370. `);
  371.  
  372. createSettingsPanel();
  373. GM_registerMenuCommand(currentLanguage['settings'], () => {
  374. const panel = document.getElementById('settingsPanel');
  375. panel.style.display = 'block';
  376. });
  377.  
  378. function addGlobalStyle(css) {
  379. var head, style;
  380. head = document.getElementsByTagName('head')[0];
  381. if (!head) { return; }
  382. style = document.createElement('style');
  383. style.type = 'text/css';
  384. style.innerHTML = css;
  385. head.appendChild(style);
  386. }
  387.  
  388. var cssRules = '';
  389.  
  390. if (settings.hideSelectors) {
  391. const observer = new MutationObserver(mutations => {
  392. mutations.forEach(mutation => {
  393. const elements = document.querySelectorAll('.css-175oi2r.r-1habvwh.r-eqz5dr.r-uaa2di.r-1mmae3n.r-3pj75a.r-bnwqim');
  394. elements.forEach(element => {
  395. const parentDiv = element.closest('div');
  396. if (parentDiv) {
  397. parentDiv.remove();
  398. }
  399. });
  400. });
  401. });
  402.  
  403. observer.observe(document.body, { childList: true, subtree: true });
  404. }
  405.  
  406. if (settings.hideGrok) {
  407. const targetPathD = "M2.205 7.423L11.745 21h4.241L6.446 7.423H2.204zm4.237 7.541L2.2 21h4.243l2.12-3.017-2.121-3.02zM16.957 0L9.624 10.435l2.122 3.02L21.2 0h-4.243zm.767 6.456V21H21.2V1.51l-3.476 4.946z";
  408. const targetGrokImageGenPathD = "M12.745 20.54l10.97-8.19c.539-.4 1.307-.244 1.564.38 1.349 3.288.746 7.241-1.938 9.955-2.683 2.714-6.417 3.31-9.83 1.954l-3.728 1.745c5.347 3.697 11.84 2.782 15.898-1.324 3.219-3.255 4.216-7.692 3.284-11.693l.008.009c-1.351-5.878.332-8.227 3.782-13.031L33 0l-4.54 4.59v-.014L12.743 20.544M10.48 22.531c-3.837-3.707-3.175-9.446.1-12.755 2.42-2.449 6.388-3.448 9.852-1.979l3.72-1.737c-.67-.49-1.53-1.017-2.515-1.387-4.455-1.854-9.789-.931-13.41 2.728-3.483 3.523-4.579 8.94-2.697 13.561 1.405 3.454-.899 5.898-3.22 8.364C1.49 30.2.666 31.074 0 32l10.478-9.466";
  409. const observer = new MutationObserver(mutations => {
  410. mutations.forEach(mutation => {
  411. const svgs = document.querySelectorAll('svg[aria-hidden="true"].r-4qtqp9');
  412. svgs.forEach(svg => {
  413. const path = svg.querySelector('path');
  414. if (path && path.getAttribute('d') === targetPathD) {
  415. const container = svg.closest('button') || svg.closest('div');
  416. if (container) {
  417. container.remove();
  418. }
  419. }
  420. });
  421.  
  422. const grokImgGenButtons = document.querySelectorAll('button[data-testid="grokImgGen"]');
  423. grokImgGenButtons.forEach(button => {
  424. button.remove();
  425. });
  426. });
  427. });
  428. observer.observe(document.body, { childList: true, subtree: true });
  429.  
  430. GM_addStyle(`
  431. a[href="/i/grok"] {
  432. display: none !important;
  433. }
  434. .css-175oi2r.r-1867qdf.r-xnswec.r-13awgt0.r-1ce3o0f.r-1udh08x.r-u8s1d.r-13qz1uu.r-173mn98.r-1e5uvyk.r-ii8lfi.r-40lpo0.r-rs99b7.r-12jitg0 {
  435. display: none;
  436. }
  437. `);
  438. }
  439. if (settings.hideCommunities) {
  440. const targetCommunitiesPathD = "M7.501 19.917L7.471 21H.472l.029-1.027c.184-6.618 3.736-8.977 7-8.977.963 0 1.95.212 2.87.672-.444.478-.851 1.03-1.212 1.656-.507-.204-1.054-.329-1.658-.329-2.767 0-4.57 2.223-4.938 6.004H7.56c-.023.302-.05.599-.059.917zm15.998.056L23.528 21H9.472l.029-1.027c.184-6.618 3.736-8.977 7-8.977s6.816 2.358 7 8.977zM21.437 19c-.367-3.781-2.17-6.004-4.938-6.004s-4.57 2.223-4.938 6.004h9.875zm-4.938-9c-.799 0-1.527-.279-2.116-.73-.836-.64-1.384-1.638-1.384-2.77 0-1.93 1.567-3.5 3.5-3.5s3.5 1.57 3.5 3.5c0 1.132-.548 2.13-1.384 2.77-.589.451-1.317.73-2.116.73zm-1.5-3.5c0 .827.673 1.5 1.5 1.5s1.5-.673 1.5-1.5-.673-1.5-1.5-1.5-1.5.673-1.5 1.5zM7.5 3C9.433 3 11 4.57 11 6.5S9.433 10 7.5 10 4 8.43 4 6.5 5.567 3 7.5 3zm0 2C6.673 5 6 5.673 6 6.5S6.673 8 7.5 8 9 7.327 9 6.5 8.327 5 7.5 5z";
  441.  
  442. const observerCommunities = new MutationObserver(mutations => {
  443. mutations.forEach(() => {
  444. const svgs = document.querySelectorAll('svg[aria-hidden="true"].r-4qtqp9');
  445. svgs.forEach(svg => {
  446. const path = svg.querySelector('path');
  447. if (path && path.getAttribute('d') === targetCommunitiesPathD) {
  448. const container = svg.closest('a') || svg.closest('div');
  449. if (container) {
  450. container.remove();
  451. }
  452. }
  453. });
  454. });
  455. });
  456. observerCommunities.observe(document.body, { childList: true, subtree: true });
  457. }
  458. if (settings.hidePremiumSignUp) {
  459. cssRules += 'a[href="/i/premium_sign_up"] { display: none !important; }';
  460. }
  461. if (settings.hideVerifiedOrgs) {
  462. cssRules += 'a[href="/i/verified-orgs-signup"] { display: none !important; }';
  463. }
  464. if (settings.hideother) {
  465. cssRules += 'a[href="/jobs"] { display: none !important; }';
  466. cssRules += '.css-175oi2r.r-l00any.r-109y4c4.r-kuekak { display: none !important; }';
  467. cssRules += 'a.css-175oi2r.r-5oul0u.r-knv0ih.r-faml9v.r-2dysd3.r-13qz1uu.r-o7ynqc.r-6416eg.r-1ny4l3l.r-1loqt21 { display: none !important; }';
  468. cssRules += 'a.css-175oi2r.r-5oul0u.r-1wzrnnt.r-1c4vpko.r-1c7gwzm.r-13qz1uu.r-o7ynqc.r-6416eg.r-1ny4l3l.r-1loqt21 { display: none !important; }';
  469. }
  470. if (settings.hideExplore) {
  471. cssRules += 'a[href="/explore"] { display: none !important; }';
  472. }
  473. if (settings.hideNotifications) {
  474. cssRules += 'a[href="/notifications"] { display: none !important; }';
  475. }
  476. if (settings.hideBookmarks) {
  477. cssRules += 'a[href="/i/bookmarks"] { display: none !important; }';
  478. }
  479. if (settings.hideMessages) {
  480. cssRules += 'a[href="/messages"] { display: none !important; }';
  481. }
  482. if (settings.hideRightColumn) {
  483. cssRules += '.css-175oi2r.r-yfoy6g.r-18bvks7.r-1867qdf.r-1phboty.r-rs99b7.r-1ifxtd0.r-1udh08x { display: none !important; }';
  484. cssRules += '.css-175oi2r.r-18bvks7.r-1867qdf.r-1phboty.r-1ifxtd0.r-1udh08x.r-1niwhzg.r-1yadl64 { display: none !important; }';
  485. }
  486.  
  487. addGlobalStyle(cssRules);
  488. })();

QingJ © 2025

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