// ==UserScript==
// @name X - Optimized Tweet Buttons
// @name:zh-TW X - 優化推文按鈕
// @name:zh-CN X - 优化推文按钮
// @namespace http://tampermonkey.net/
// @version 5.0
// @description You can freely show or hide the buttons on a tweet, including Reply, Retweet, Like, View Count, Bookmark, and Share. The interface supports switching between Chinese and English.
// @description:zh-TW 可以自由顯示/隱藏,推文上的按鈕,包括,回覆、轉推、喜歡、觀看次數、書籤、分享等按鈕,並且有中英兩種功能語言可以切換
// @description:zh-CN 可以自由显示/隐藏,推文上的按钮,包括,回覆、转推、喜欢、观看次数、书签、分享等按钮,并且有中英两种功能语言可以切换
// @author deepseek
// @match https://twitter.com/*
// @match https://x.com/*
// @grant GM_registerMenuCommand
// @grant GM_getValue
// @grant GM_setValue
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// === 性能優化核心 ===
const OPT = {
debounceTime: 500, // 防抖間隔
observerConfig: { // 精準監控範圍
childList: true,
subtree: false,
attributes: false,
characterData: false
}
};
// === 配置系統 ===
const CONFIG_KEY = 'XButtonSettings';
const defaults = {
hideReply: true,
hideRetweet: true,
hideBookmark: true,
hideViews: true,
hideShare: true,
hideLike: false,
language: 'EN' // 預設英文
};
const config = {
get() {
return {...defaults, ...GM_getValue(CONFIG_KEY, {})};
},
update(key, value) {
const current = this.get();
GM_setValue(CONFIG_KEY, {...current, [key]: value});
}
};
// === 高效多語言系統 ===
const i18n = {
EN: {
reply: 'Reply',
retweet: 'Retweet',
bookmark: 'Bookmark',
views: 'View count',
share: 'Share',
like: 'Like',
language: 'Language'
},
ZH: {
reply: '回覆',
retweet: '轉推',
bookmark: '書籤',
views: '觀看次數',
share: '分享',
like: '喜歡',
language: '語言'
}
};
const t = () => i18n[config.get().language];
// === 樣式管理 ===
const style = {
element: null,
rules: new Map([
['hideReply', '[data-testid="reply"]{display:none!important}'],
['hideRetweet','[data-testid="retweet"]{display:none!important}'],
['hideBookmark','[data-testid="bookmark"]{display:none!important}'],
['hideViews','a[href*="/analytics"]{display:none!important}'],
['hideShare','button[aria-label="分享貼文"]:not(:has(svg g.download)){display:none!important}'],
['hideLike','[data-testid="like"],[data-testid="unlike"]{display:none!important}']
]),
init() {
this.element = document.createElement('style');
this.element.id = 'x-btn-hider-styles';
document.head.append(this.element);
this.update();
},
update() {
const activeRules = Object.entries(config.get())
.filter(([k,v]) => this.rules.has(k) && v)
.map(([k]) => this.rules.get(k));
this.element.textContent = activeRules.join('');
}
};
// === 選單系統 (防抖優化) ===
const menu = {
cmds: [],
build: () => {
// 清除舊選單
menu.cmds.forEach(id => GM_unregisterMenuCommand(id));
menu.cmds = [];
// 主功能選單
const items = [
{key: 'hideReply', label: t().reply},
{key: 'hideRetweet', label: t().retweet},
{key: 'hideBookmark', label: t().bookmark},
{key: 'hideViews', label: t().views},
{key: 'hideShare', label: t().share},
{key: 'hideLike', label: t().like}
];
items.forEach(({key, label}) => {
const status = config.get()[key] ? '✅' : '❌';
menu.cmds.push(GM_registerMenuCommand(
`${label} ${status}`,
() => {
config.update(key, !config.get()[key]);
debouncedReload();
}
));
});
// 語言切換
const langStatus = config.get().language === 'EN' ? 'EN' : 'ZH';
menu.cmds.push(GM_registerMenuCommand(
`${t().language}: ${langStatus}`,
() => {
config.update('language', config.get().language === 'EN' ? 'ZH' : 'EN');
debouncedReload();
}
));
}
};
// === 性能優化工具 ===
const debounce = (func, delay) => {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => func(...args), delay);
};
};
const debouncedReload = debounce(() => location.reload(), 300);
const debouncedStyleUpdate = debounce(() => style.update(), OPT.debounceTime);
// === 初始化流程 ===
(function init() {
// 樣式初始化
style.init();
// 選單初始化
menu.build();
// 精準DOM監控
const observer = new MutationObserver(mutations => {
if (mutations.some(m => m.addedNodes.length > 0)) {
debouncedStyleUpdate();
}
});
observer.observe(document.body, OPT.observerConfig);
})();
})();