// ==UserScript== // @name 增强版推特搜索助手-Twitter Search Assistant Enhanced // @namespace example.twitter.enhanced // @version 1.1 // @description 增强版推特搜索助手 // @match https://twitter.com/* // @match https://x.com/* // @grant none // @license MIT // @downloadURL none // ==/UserScript== (function () { 'use strict'; // 定义搜索预设 const presets = { "📷 图片": "filter:images -filter:retweets -filter:replies", "🎬 视频": "filter:videos -filter:retweets -filter:replies", "🔥 高热度": "min_faves:200 -filter:retweets", "🈶 日语": "lang:ja -filter:retweets -filter:replies", "🌎 英语": "lang:en -filter:retweets -filter:replies", "💬 感想": "感想 OR 評価 lang:ja -filter:retweets -filter:replies", "⏰ 近期": "since:2024-07-25 -filter:retweets", "🎵 BGM讨论": "BGM OR 音乐 OR OST lang:ja -filter:retweets" }; // 主面板HTML const panel = document.createElement('div'); panel.id = 'tw-search-assistant'; panel.innerHTML = `
搜索助手
单选模式
`; // 样式 - 修正高度和间距 const style = document.createElement('style'); style.textContent = ` #tw-search-assistant { position: fixed; top: 75px; right: 400px; z-index: 10000; width: 280px; background: #ffffff; border: 1px solid #e1e8ed; border-radius: 12px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size: 13px; color: #0f1419; transition: all 0.3s ease; opacity: 0; transform: translateY(-10px); } #tw-search-assistant.show { opacity: 1; transform: translateY(0); } #tw-search-assistant:hover { box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12); } .panel-header { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px 8px; border-bottom: 1px solid #eff3f4; font-weight: 600; } .toggle-mode { background: none; border: none; cursor: pointer; font-size: 14px; padding: 2px 4px; border-radius: 4px; transition: background 0.2s; } .toggle-mode:hover { background: #f7f9fa; } .mode-indicator { padding: 4px 16px; font-size: 11px; color: #536471; background: #f7f9fa; margin: 0 16px 8px; border-radius: 6px; text-align: center; } .mode-indicator.multi-mode { background: #e8f5fe; color: #1da1f2; } #tw-keyword { width: calc(100% - 32px); margin: 0 16px 12px; padding: 8px 12px; border: 1px solid #eff3f4; border-radius: 8px; font-size: 14px; outline: none; transition: border-color 0.2s; } #tw-keyword:focus { border-color: #1da1f2; box-shadow: 0 0 0 3px rgba(29, 161, 242, 0.1); } .preset-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; padding: 0 16px 12px; } .preset-btn { padding: 8px 12px; background: #f7f9fa; border: 1px solid #eff3f4; border-radius: 8px; color: #0f1419; cursor: pointer; font-size: 12px; transition: all 0.2s; display: flex; align-items: center; gap: 4px; } .preset-btn:hover { background: #e8f5fe; border-color: #cfe5f7; } .preset-btn.selected { background: #e8f5fe; color: #1da1f2; border-color: #1da1f2; } .preset-btn.selected::after { content: '✓'; margin-left: auto; font-size: 11px; font-weight: bold; } .action-buttons { display: flex; gap: 8px; padding: 0 16px 16px; } .btn-clear, .btn-apply { flex: 1; padding: 8px; border: none; border-radius: 8px; font-size: 13px; cursor: pointer; transition: all 0.2s; font-weight: 500; } .btn-clear { background: #f7f9fa; color: #536471; border: 1px solid #eff3f4; } .btn-clear:hover { background: #e1e8ed; } .btn-apply { background: #1da1f2; color: white; } .btn-apply:hover { background: #1a91da; } /* 多选模式下应用按钮高亮 */ .btn-apply.active { background: #17bf63; box-shadow: 0 2px 8px rgba(23, 191, 99, 0.3); } /* 响应式调整 */ @media (max-width: 1280px) { #tw-search-assistant { right: 360px; } } @media (max-width: 1100px) { #tw-search-assistant { right: 20px; top: 60px; } } `; document.head.appendChild(style); document.body.appendChild(panel); // 状态管理 let isMultiSelectMode = false; let selectedPresets = new Set(); let currentFilterStr = ''; // 从URL提取搜索参数(过滤掉现有的filter条件,只保留关键词) function extractKeyword(url) { if (!url.includes('/search?q=')) return ''; const match = url.match(/\/search\?q=([^&]+)/); if (!match) return ''; const query = decodeURIComponent(match[1]); // 移除所有filter:、lang:、min_faves:、since:等条件,只保留关键词 const keyword = query.split(/\s+(?:filter:|lang:|min_faves:|since:|until:|from:|to:)/)[0].trim(); // 移除常见的布尔操作符后面的内容(如果有多余的) return keyword.replace(/\s+(OR|AND|NOT)\s+.*$/i, '').trim(); } // 提取当前已有的过滤条件 function extractCurrentFilters(url) { if (!url.includes('/search?q=')) return ''; const match = url.match(/\/search\?q=([^&]+)/); if (!match) return ''; const query = decodeURIComponent(match[1]); // 提取所有以filter:、lang:、min_faves:、since:等开头的条件 const filters = query.match(/\s+(?:filter:|lang:|min_faves:|since:|until:|from:|to:)[^\s]+/g) || []; return filters.join(' '); } // 处理预设点击 - 彻底重写多选逻辑 function handlePresetClick(btn, filter) { if (isMultiSelectMode) { // 多选模式:切换选中状态 if (selectedPresets.has(filter)) { selectedPresets.delete(filter); btn.classList.remove('selected'); } else { selectedPresets.add(filter); btn.classList.add('selected'); } // 更新应用按钮状态 updateApplyButton(); } else { // 单选模式:直接跳转搜索 performSingleSearch(filter); } } // 单选模式搜索 function performSingleSearch(filter) { const kw = document.getElementById('tw-keyword').value.trim() || extractKeyword(window.location.href); if (!kw) { alert('请输入关键词'); return; } const searchUrl = `https://twitter.com/search?q=${encodeURIComponent(kw + ' ' + filter)}&src=typed_query&f=top`; window.location.href = searchUrl; } // 更新应用按钮状态 function updateApplyButton() { const applyBtn = document.querySelector('.btn-apply'); if (isMultiSelectMode && selectedPresets.size > 0) { applyBtn.classList.add('active'); applyBtn.textContent = `应用搜索(${selectedPresets.size})`; } else { applyBtn.classList.remove('active'); applyBtn.textContent = '应用搜索'; } } // 多选模式应用搜索 - 彻底重写 function applyMultiSelectSearch() { if (!isMultiSelectMode || selectedPresets.size === 0) { alert('多选模式下请至少选择一个筛选条件'); return; } const keyword = document.getElementById('tw-keyword').value.trim() || extractKeyword(window.location.href); if (!keyword) { alert('请输入关键词'); return; } // 获取当前已有的过滤条件 const existingFilters = extractCurrentFilters(window.location.href); // 组合所有选中的预设条件 const selectedFilters = Array.from(selectedPresets).join(' '); // 构建最终搜索查询 let finalQuery = keyword; if (existingFilters) { finalQuery += ' ' + existingFilters + ' ' + selectedFilters; } else { finalQuery += ' ' + selectedFilters; } const searchUrl = `https://twitter.com/search?q=${encodeURIComponent(finalQuery.trim())}&src=typed_query&f=top`; window.location.href = searchUrl; } // 清空选择 function clearSelection() { selectedPresets.clear(); document.querySelectorAll('.preset-btn.selected').forEach(btn => { btn.classList.remove('selected'); }); updateApplyButton(); } // 切换模式 - 彻底重写 function toggleMode() { isMultiSelectMode = !isMultiSelectMode; const indicator = document.querySelector('.mode-indicator'); const applyBtn = document.querySelector('.btn-apply'); if (isMultiSelectMode) { indicator.textContent = '多选模式'; indicator.classList.add('multi-mode'); applyBtn.style.display = 'block'; clearSelection(); // 清空之前的单选状态 } else { indicator.textContent = '单选模式'; indicator.classList.remove('multi-mode'); applyBtn.style.display = 'none'; clearSelection(); } } // 自动填充关键词 function autoFillKeyword() { const keyword = extractKeyword(window.location.href); if (keyword && !document.getElementById('tw-keyword').value) { document.getElementById('tw-keyword').value = keyword; } // 如果当前页面是搜索页且有过滤条件,自动检测并显示 const currentFilters = extractCurrentFilters(window.location.href); if (currentFilters) { // 可以在这里添加逻辑来高亮当前已应用的过滤条件 console.log('当前过滤条件:', currentFilters); } } // 初始化按钮 function initButtons() { const grid = document.querySelector('.preset-grid'); Object.keys(presets).forEach(name => { const btn = document.createElement('button'); btn.className = 'preset-btn'; btn.textContent = name; btn.onclick = () => handlePresetClick(btn, presets[name]); grid.appendChild(btn); }); } // 绑定事件 document.querySelector('.toggle-mode').onclick = toggleMode; document.querySelector('.btn-clear').onclick = clearSelection; document.querySelector('.btn-apply').onclick = applyMultiSelectSearch; // 自动获取URL变化(处理浏览器前进后退) function observeUrlChanges() { let currentUrl = window.location.href; // 检查URL变化 setInterval(() => { if (window.location.href !== currentUrl) { currentUrl = window.location.href; autoFillKeyword(); clearSelection(); // 清空选择状态 } }, 1000); } // 初始化 initButtons(); autoFillKeyword(); observeUrlChanges(); // 显示面板(延迟显示效果) setTimeout(() => { panel.classList.add('show'); }, 100); })();