feat: 新增进度条、收藏夹、历史记录、 通知提醒功能

## 新功能
1. 进度条 - 可视化抓取进度
2. 收藏夹 - 持久收藏磁力链接(♡按钮)
3. 历史记录 - 关键词搜索历史(点击输入框显示)
4. 通知提醒 - 完成时提示音 + 浏览器通知

## 技术实现
- 使用 localStorage 存储收藏和历史
- 使用 Web Audio API 播放提示音
- 使用 Notification API 显示浏览器通知
- CSS 进度条动画效果
This commit is contained in:
Developer
2026-03-11 18:23:06 +08:00
parent 52304d10e0
commit 1b702b1b93
2 changed files with 548 additions and 3 deletions

View File

@@ -472,12 +472,100 @@
'}',
'.magnet-empty-state-text{',
' font-size:14px;line-height:1.6;',
'}',
/* === 进度条 === */',
'.magnet-progress-container{',
' width:100%;height:6px;background:var(--m-bg-secondary);border-radius:3px;overflow:hidden;margin-top:8px;',
'}',
'.magnet-progress-bar{',
' height:100%;background:linear-gradient(90deg, var(--m-accent), #00f5c4);border-radius:3px;transition:width 0.3s ease;',
'}',
'.magnet-progress-text{',
' display:flex;justify-content:space-between;font-size:11px;color:var(--m-text-muted);margin-top:4px;',
'}',
/* === 收藏按钮 === */',
'.magnet-favorite-btn{',
' padding:6px 10px;background:transparent;border:1px solid var(--m-border);border-radius:8px;cursor:pointer;font-size:11px;color:var(--m-text-muted);transition:all 0.2s ease;',
'}',
'.magnet-favorite-btn:hover{',
' border-color:var(--m-accent-secondary);color:var(--m-accent-secondary);',
'}',
'.magnet-favorite-btn.is-favorite{',
' background:rgba(167,139,250,0.15);border-color:var(--m-accent-secondary);color:var(--m-accent-secondary);',
'}',
/* === 收藏视图 === */',
'#magnet-favorites-view .magnet-favorite-item{',
' display:flex;align-items:center;gap:10px;padding:10px 12px;background:var(--m-bg-card);border:1px solid var(--m-border);border-radius:var(--m-radius-md);margin-bottom:8px;',
'}',
'#magnet-favorites-view .magnet-favorite-item:hover{',
' border-color:var(--m-border-accent);',
'}',
'#magnet-favorites-view .magnet-favorite-title{',
' flex:1;font-size:12px;color:var(--m-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;',
'}',
'#magnet-favorites-view .magnet-favorite-actions{',
' display:flex;gap:6px;',
'}',
'#magnet-favorites-view .magnet-favorite-copy,',
'#magnet-favorites-view .magnet-favorite-remove{',
' padding:5px 8px;border:none;border-radius:6px;cursor:pointer;font-size:10px;font-weight:600;transition:all 0.2s ease;',
'}',
'#magnet-favorites-view .magnet-favorite-copy{',
' background:linear-gradient(135deg, var(--m-accent), #00f5c4);color:var(--m-bg-deep);',
'}',
'#magnet-favorites-view .magnet-favorite-remove{',
' background:rgba(239,68,68,0.15);color:var(--m-error);',
'}',
/* === 历史记录下拉 === */',
'.magnet-history-dropdown{',
' position:absolute;top:100%;left:0;right:0;background:var(--m-bg-card);border:1px solid var(--m-border);border-radius:var(--m-radius-md);box-shadow:var(--m-shadow-lg);z-index:100;max-height:200px;overflow-y:auto;',
'}',
'.magnet-history-item{',
' padding:10px 14px;cursor:pointer;font-size:12px;color:var(--m-text-primary);transition:background 0.2s ease;',
'}',
'.magnet-history-item:hover{',
' background:var(--m-bg-secondary);',
'}',
'.magnet-history-item:first-child{',
' border-radius:var(--m-radius-md) var(--m-radius-md) 0 0;',
'}',
'.magnet-history-item:last-child{',
' border-radius:0 0 var(--m-radius-md) var(--m-radius-md);',
'}',
'.magnet-history-clear{',
' padding:10px 14px;border-top:1px solid var(--m-border);font-size:11px;color:var(--m-error);cursor:pointer;text-align:center;',
'}'
].join('');
document.head.appendChild(style);
}
function setPanelView(viewName) {
var resultsView = document.getElementById('magnet-results-view');
var cacheView = document.getElementById('magnet-cache-view');
var favoritesView = document.getElementById('magnet-favorites-view');
var resultsBtn = document.getElementById('magnet-view-results');
var cacheBtn = document.getElementById('magnet-view-cache');
var favoritesBtn = document.getElementById('magnet-view-favorites');
if (!resultsView || !cacheView || !favoritesView || !resultsBtn || !cacheBtn || !favoritesBtn) {
return;
}
resultsView.classList.toggle('is-active', viewName === 'results');
cacheView.classList.toggle('is-active', viewName === 'cache');
favoritesView.classList.toggle('is-active', viewName === 'favorites');
resultsBtn.classList.toggle('is-active', viewName === 'results');
cacheBtn.classList.toggle('is-active', viewName === 'cache');
favoritesBtn.classList.toggle('is-active', viewName === 'favorites');
if (viewName === 'favorites') {
renderFavoritesList();
}
}
var resultsView = document.getElementById('magnet-results-view');
var cacheView = document.getElementById('magnet-cache-view');
var resultsBtn = document.getElementById('magnet-view-results');
@@ -527,7 +615,7 @@
var panel = document.createElement('div');
panel.id = 'magnet-floating-panel';
panel.innerHTML = '<div class="magnet-panel-header"><div class="magnet-panel-brand"><div class="magnet-panel-title">MAGNET LINKS</div><div class="magnet-panel-subtitle">智能抓取 · 缓存加速 · 一键复制</div></div><div class="magnet-panel-head-actions"><button id="magnet-view-results" class="magnet-panel-switch is-active">结果</button><button id="magnet-view-cache" class="magnet-panel-switch">缓存</button><button class="magnet-panel-close" title="关闭">×</button></div></div><div class="magnet-settings" id="magnet-settings"></div><div class="magnet-panel-content"><div id="magnet-results-view" class="magnet-view is-active"><div class="magnet-view-toolbar"><div><div class="magnet-view-title">搜索结果</div><div class="magnet-view-meta">关键词命中的磁力链接</div></div><div class="magnet-view-meta">共 <span id="magnet-count-num">0</span> 条</div></div><div class="magnet-list" id="magnet-list"></div></div><div id="magnet-cache-view" class="magnet-view"><div class="magnet-view-toolbar"><div><div class="magnet-view-title">缓存总览</div><div class="magnet-view-meta">数据统计与快照管理</div></div><div class="magnet-view-toolbar-actions"><button id="magnet-refresh-cache" class="magnet-panel-switch is-active">刷新</button><button id="magnet-clear-cache-inline" class="magnet-panel-switch">清空</button></div></div><div id="magnet-cache-panel"></div></div></div><div class="magnet-panel-footer"><div id="magnet-status">设置参数后开始抓取</div><button id="magnet-copy-all">一键复制全部</button></div>';
panel.innerHTML = '<div class="magnet-panel-header"><div class="magnet-panel-brand"><div class="magnet-panel-title">MAGNET LINKS</div><div class="magnet-panel-subtitle">智能抓取 · 缓存加速 · 一键复制</div></div><div class="magnet-panel-head-actions"><button id="magnet-view-results" class="magnet-panel-switch is-active">结果</button><button id="magnet-view-favorites" class="magnet-panel-switch">收藏</button><button id="magnet-view-cache" class="magnet-panel-switch">缓存</button><button class="magnet-panel-close" title="关闭">×</button></div></div><div class="magnet-settings" id="magnet-settings"></div><div class="magnet-panel-content"><div id="magnet-results-view" class="magnet-view is-active"><div class="magnet-view-toolbar"><div><div class="magnet-view-title">搜索结果</div><div class="magnet-view-meta">关键词命中的磁力链接</div></div><div class="magnet-view-meta">共 <span id="magnet-count-num">0</span> 条</div></div><div class="magnet-list" id="magnet-list"></div></div><div id="magnet-favorites-view" class="magnet-view"><div class="magnet-view-toolbar"><div><div class="magnet-view-title">我的收藏</div><div class="magnet-view-meta">持久保存的磁力链接</div></div><div class="magnet-view-toolbar-actions"><button id="magnet-clear-favorites" class="magnet-panel-switch">清空收藏</button></div></div><div id="magnet-favorites-list"></div></div><div id="magnet-cache-view" class="magnet-view"><div class="magnet-view-toolbar"><div><div class="magnet-view-title">缓存总览</div><div class="magnet-view-meta">数据统计与快照管理</div></div><div class="magnet-view-toolbar-actions"><button id="magnet-refresh-cache" class="magnet-panel-switch is-active">刷新</button><button id="magnet-clear-cache-inline" class="magnet-panel-switch">清空</button></div></div><div id="magnet-cache-panel"></div></div></div><div class="magnet-panel-footer"><div id="magnet-status">设置参数后开始抓取</div><div class="magnet-progress-container"><div class="magnet-progress-bar" id="magnet-progress-bar" style="width:0%"></div></div><div class="magnet-progress-text"><span id="magnet-progress-label">等待开始</span><span id="magnet-progress-percent">0%</span></div><button id="magnet-copy-all">一键复制全部</button></div>';
document.body.appendChild(panel);
setPanelView('results');
@@ -569,7 +657,48 @@
panel.style.display = 'none';
ball.style.display = 'flex';
};
var favoritesSwitch = panel.querySelector('#magnet-view-favorites');
if (favoritesSwitch) {
favoritesSwitch.onclick = function() {
setPanelView('favorites');
};
}
var clearFavoritesBtn = panel.querySelector('#magnet-clear-favorites');
if (clearFavoritesBtn) {
clearFavoritesBtn.onclick = function() {
if (confirm('确定要清空所有收藏吗')) {
saveFavorites([]);
renderFavoritesList();
}
};
}
var copyAllBtn = panel.querySelector('#magnet-copy-all');
if (copyAllBtn) {
copyAllBtn.onclick = function() {
var links = allMagnetLinks.length > 0
? allMagnetLinks.slice()
: Array.from(document.querySelectorAll('.magnet-item .magnet-copy-btn'))
.map(function(btn) { return btn.getAttribute('data-magnet'); })
.filter(function(link) { return !!link; });
if (links.length === 0) {
alert('暂无可复制的磁力链接');
return;
}
var allLinks = links.join('\n');
navigator.clipboard.writeText(allLinks)
.then(function() {
alert('已复制 ' + links.length + ' 个磁力链接!');
})
.catch(function(err) {
var errorMsg = err && err.message ? err.message : '复制失败';
alert('复制失败: ' + errorMsg);
});
};
}
return panel;
var copyAllBtn = panel.querySelector('#magnet-copy-all');
if (copyAllBtn) {
copyAllBtn.onclick = function() {
@@ -754,6 +883,280 @@
if (countEl) countEl.textContent = count;
}
// === 进度条功能 ===
function updateProgress(current, total, label) {
var progressBar = document.getElementById('magnet-progress-bar');
var progressLabel = document.getElementById('magnet-progress-label');
var progressPercent = document.getElementById('magnet-progress-percent');
if (progressBar) {
var percent = total > 0 ? Math.round((current / total) * 100) : 0;
progressBar.style.width = percent + '%';
}
if (progressLabel) {
progressLabel.textContent = label || ('进度: ' + current + '/' + total);
}
if (progressPercent) {
var percent = total > 0 ? Math.round((current / total) * 100) : 0;
progressPercent.textContent = percent + '%';
}
}
function resetProgress() {
updateProgress(0, 0, '等待开始');
}
// === 收藏夹功能 ===
var FAVORITES_KEY = 'magnet-favorites';
var favoritesCache = null;
function loadFavorites() {
if (favoritesCache !== null) {
return favoritesCache;
}
try {
var stored = localStorage.getItem(FAVORITES_KEY);
favoritesCache = stored ? JSON.parse(stored) : [];
} catch (e) {
favoritesCache = [];
}
return favoritesCache;
}
function saveFavorites(favorites) {
try {
localStorage.setItem(FAVORITES_KEY, JSON.stringify(favorites));
favoritesCache = favorites;
} catch (e) {
log('保存收藏失败: ' + e);
}
}
function isFavorited(link) {
var favorites = loadFavorites();
return favorites.some(function(f) { return f.link === link; });
}
function toggleFavorite(title, link, btn) {
var favorites = loadFavorites();
var existingIndex = favorites.findIndex(function(f) { return f.link === link; });
if (existingIndex >= 0) {
favorites.splice(existingIndex, 1);
btn.classList.remove('is-favorite');
btn.innerHTML = '♡';
btn.title = '收藏';
} else {
favorites.push({
title: title,
link: link,
addedAt: Date.now()
});
btn.classList.add('is-favorite');
btn.innerHTML = '♥';
btn.title = '取消收藏';
}
saveFavorites(favorites);
}
function renderFavoritesList() {
var list = document.getElementById('magnet-favorites-list');
if (!list) return;
var favorites = loadFavorites();
list.innerHTML = '';
if (favorites.length === 0) {
list.innerHTML = '<div class="magnet-empty-state"><div class="magnet-empty-state-icon">📭</div><div class="magnet-empty-state-text">暂无收藏\br>点击结果列表中的 ♡ 按钮添加收藏</div></div>';
return;
}
favorites.forEach(function(fav) {
var item = document.createElement('div');
item.className = 'magnet-favorite-item';
var titleEl = document.createElement('div');
titleEl.className = 'magnet-favorite-title';
titleEl.textContent = fav.title;
titleEl.title = fav.title;
var actionsEl = document.createElement('div');
actionsEl.className = 'magnet-favorite-actions';
var copyBtn = document.createElement('button');
copyBtn.className = 'magnet-favorite-copy';
copyBtn.textContent = '复制';
copyBtn.onclick = function() {
navigator.clipboard.writeText(fav.link)
.then(function() {
copyBtn.textContent = '已复制';
setTimeout(function() { copyBtn.textContent = '复制'; }, 1000);
});
};
var removeBtn = document.createElement('button');
removeBtn.className = 'magnet-favorite-remove';
removeBtn.textContent = '删除';
removeBtn.onclick = function() {
var favorites = loadFavorites();
var idx = favorites.findIndex(function(f) { return f.link === fav.link; });
if (idx >= 0) {
favorites.splice(idx, 1);
saveFavorites(favorites);
renderFavoritesList();
}
};
actionsEl.appendChild(copyBtn);
actionsEl.appendChild(removeBtn);
item.appendChild(titleEl);
item.appendChild(actionsEl);
list.appendChild(item);
});
}
// === 历史记录功能 ===
var HISTORY_KEY = 'magnet-search-history';
var MAX_HISTORY = 20;
function loadSearchHistory() {
try {
var stored = localStorage.getItem(HISTORY_KEY);
return stored ? JSON.parse(stored) : [];
} catch (e) {
return [];
}
}
function saveSearchHistory(keyword) {
if (!keyword || typeof keyword !== 'string' || !keyword.trim()) {
return;
}
keyword = keyword.trim();
var history = loadSearchHistory();
// 移除已存在的相同关键词
var idx = history.indexOf(keyword);
if (idx >= 0) {
history.splice(idx, 1);
}
// 添加到开头
history.unshift(keyword);
// 限制数量
if (history.length > MAX_HISTORY) {
history = history.slice(0, MAX_HISTORY);
}
try {
localStorage.setItem(HISTORY_KEY, JSON.stringify(history));
} catch (e) {
log('保存历史记录失败: ' + e);
}
}
function showHistoryDropdown(input) {
var history = loadSearchHistory();
if (history.length === 0) {
return;
}
// 移除已存在的下拉框
var existing = document.querySelector('.magnet-history-dropdown');
if (existing) existing.remove();
var dropdown = document.createElement('div');
dropdown.className = 'magnet-history-dropdown';
history.forEach(function(kw) {
var item = document.createElement('div');
item.className = 'magnet-history-item';
item.textContent = kw;
item.onclick = function() {
input.value = kw;
dropdown.remove();
input.focus();
};
dropdown.appendChild(item);
});
var clearItem = document.createElement('div');
clearItem.className = 'magnet-history-clear';
clearItem.textContent = '清空历史';
clearItem.onclick = function() {
localStorage.removeItem(HISTORY_KEY);
dropdown.remove();
};
dropdown.appendChild(clearItem);
input.parentNode.style.position = 'relative';
input.parentNode.appendChild(dropdown);
// 点击外部关闭
setTimeout(function() {
document.addEventListener('click', function closeDropdown(e) {
if (!dropdown.contains(e.target)) {
dropdown.remove();
document.removeEventListener('click', closeDropdown);
}
});
}, 100);
}
// === 通知功能 ===
function playNotificationSound() {
try {
var audioContext = new (window.AudioContext || window.webkitAudioContext)();
var oscillator = audioContext.createOscillator();
var gainNode = audioContext.createGain();
oscillator.connect(gainNode);
gainNode.connect(audioContext.destination);
oscillator.frequency.value = 800;
oscillator.type = 'sine';
gainNode.gain.setValue(0.3);
gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.3);
oscillator.start(audioContext.currentTime);
oscillator.stop(audioContext.currentTime + 0.3);
} catch (e) {
log('播放提示音失败: ' + e);
}
}
function showBrowserNotification(title, body) {
if (!('Notification' in window)) {
return;
}
if (Notification.permission === 'granted') {
new Notification(title, { body: body, icon: chrome.runtime ? chrome.runtime.getURL('icon.png') : undefined });
} else if (Notification.permission !== 'denied') {
Notification.requestPermission().then(function(permission) {
if (permission === 'granted') {
new Notification(title, { body: body, icon: chrome.runtime ? chrome.runtime.getURL('icon.png') : undefined });
}
});
}
}
function notifyComplete(count, duration) {
playNotificationSound();
var durationText = '';
if (duration && duration > 0) {
var seconds = Math.floor(duration / 1000);
if (seconds >= 60) {
durationText = ',耗时 ' + Math.floor(seconds / 60) + ' 分 ' + (seconds % 60) + ' 秒';
} else {
durationText = ',耗时 ' + seconds + ' 秒';
}
}
showBrowserNotification('磁力链接抓取完成', '共获取 ' + count + ' 个磁力链接' + durationText);
}
var countEl = document.getElementById('magnet-count-num');
if (countEl) countEl.textContent = count;
}
function clearMagnetList(skipPersist) {
var list = document.getElementById('magnet-list');
if (list) list.innerHTML = '';
@@ -794,6 +1197,100 @@
titleEl.title = safeTitle;
titleEl.textContent = safeTitle;
var btnContainer = document.createElement('div');
btnContainer.style.cssText = 'display:flex;gap:6px;flex-shrink:0;';
var copyBtn = document.createElement('button');
copyBtn.className = 'magnet-copy-btn';
copyBtn.setAttribute('data-magnet', safeLink);
copyBtn.textContent = '复制';
// 收藏按钮
var favoriteBtn = document.createElement('button');
favoriteBtn.className = 'magnet-favorite-btn';
favoriteBtn.innerHTML = '♡';
favoriteBtn.title = '收藏';
favoriteBtn.onclick = function() {
toggleFavorite(safeTitle, safeLink, favoriteBtn);
};
// 检查是否已收藏
isFavorite(safeLink).then(function(isFav) {
if (isFav) {
favoriteBtn.classList.add('is-favorite');
favoriteBtn.title = '取消收藏';
}
});
titleEl.onclick = function() {
navigator.clipboard.writeText(safeLink)
.then(function() {
titleEl.textContent = '已复制: ' + safeTitle.substring(0, 20) + '...';
setTimeout(function() {
titleEl.textContent = safeTitle;
}, 1500);
})
.catch(function(err) {
var errorMsg = err && err.message ? err.message : '复制失败';
log('标题复制失败: ' + errorMsg);
updateStatus('复制失败,请检查剪贴板权限', 'error');
});
};
copyBtn.onclick = function() {
navigator.clipboard.writeText(safeLink)
.then(function() {
copyBtn.textContent = '已复制';
setTimeout(function() {
copyBtn.textContent = '复制';
}, 1000);
})
.catch(function(err) {
var errorMsg = err && err.message ? err.message : '复制失败';
log('按钮复制失败: ' + errorMsg);
updateStatus('复制失败,请检查剪贴板权限', 'error');
});
};
item.appendChild(titleEl);
btnContainer.appendChild(favoriteBtn);
btnContainer.appendChild(copyBtn);
item.appendChild(btnContainer);
list.appendChild(item);
setPanelView('results');
updateCount(list.children.length);
if (!options || !options.skipPersist) {
scheduleStatePersist();
}
}
var list = document.getElementById('magnet-list');
if (!list) return;
var safeTitle = typeof title === 'string' ? title : String(title || '');
var safeLink = typeof link === 'string' ? link : String(link || '');
if (!safeLink) return;
if (magnetRecordMap[safeLink]) {
return;
}
magnetRecordMap[safeLink] = safeTitle || '恢复记录';
allMagnetRecords.push({
title: magnetRecordMap[safeLink],
link: safeLink
});
allMagnetLinks.push(safeLink);
var item = document.createElement('div');
item.className = 'magnet-item';
var titleEl = document.createElement('span');
titleEl.className = 'magnet-title';
titleEl.title = safeTitle;
titleEl.textContent = safeTitle;
var copyBtn = document.createElement('button');
copyBtn.className = 'magnet-copy-btn';
copyBtn.setAttribute('data-magnet', safeLink);
@@ -1797,6 +2294,11 @@
updateStatus('第' + page + '/' + context.normalizedEnd + '页...', 'loading');
// 更新进度条
var totalPages = context.normalizedEnd - (context.startPage || startPage) + 1;
var currentPage = page - (context.startPage || startPage) + 1;
updateProgress(currentPage, totalPages, '第' + page + '/' + context.normalizedEnd + '页');
var pageUrl = context.baseUrl + page + '.html';
try {
var response = await sendRuntimeMessage({
@@ -1877,6 +2379,18 @@
progressRuntime.endPage = earlyEnd;
progressRuntime.resumeFromPage = earlyStart;
// 重置进度条
resetProgress();
// 记录开始时间
var startTime = Date.now();
stopFetching = false;
progressRuntime.isRunning = true;
progressRuntime.stoppedByUser = false;
progressRuntime.startPage = earlyStart;
progressRuntime.endPage = earlyEnd;
progressRuntime.resumeFromPage = earlyStart;
var panel = createFloatingPanel();
var ball = document.getElementById('magnet-float-ball');
panel.style.display = 'flex';
@@ -2010,6 +2524,28 @@
var keywordMsg = keyword ? ' (关键词:' + keyword + ' 匹配:' + searchContext.matchedThreads + '帖)' : '';
var failedMsg = searchContext.failedPages > 0 ? ',失败页:' + searchContext.failedPages : '';
// 更新进度条为100%
updateProgress(normalizedEnd - normalizedStart + 1, normalizedEnd - normalizedStart + 1, '已完成');
if (stopFetching) {
progressRuntime.stoppedByUser = true;
updateStatus('已停止 - 找到' + searchContext.allMagnets.size + '个磁力' + keywordMsg + ',已处理帖子:' + searchContext.totalFetched + failedMsg, 'error');
} else {
progressRuntime.stoppedByUser = false;
progressRuntime.resumeFromPage = normalizedEnd + 1;
updateStatus('完成! 共' + searchContext.allMagnets.size + '个磁力' + keywordMsg + ',已处理帖子:' + searchContext.totalFetched + failedMsg, 'done');
// 发送完成通知
var duration = Date.now() - startTime;
notifyComplete(searchContext.allMagnets.size, duration);
// 保存搜索历史
if (keyword) {
saveSearchHistory(keyword);
}
}
var failedMsg = searchContext.failedPages > 0 ? ',失败页:' + searchContext.failedPages : '';
if (stopFetching) {
progressRuntime.stoppedByUser = true;
updateStatus('已停止 - 找到' + searchContext.allMagnets.size + '个磁力' + keywordMsg + ',已处理帖子:' + searchContext.totalFetched + failedMsg, 'error');
@@ -2059,6 +2595,14 @@
keywordDiv.className = 'magnet-control-row';
keywordDiv.innerHTML = '<input type="text" id="keyword-input" placeholder="关键词(逗号分隔多关键词)" style="width:100%;padding:11px 14px;border:1px solid rgba(0,212,170,0.3);border-radius:12px;font-size:13px;box-sizing:border-box;background:#0f1419;color:#f0f4f8;box-shadow:inset 0 1px 2px rgba(0,0,0,0.2)">';
// 添加历史记录下拉功能
var keywordInput = keywordDiv.querySelector('#keyword-input');
if (keywordInput) {
keywordInput.addEventListener('focus', function() {
showHistoryDropdown(keywordInput);
});
}
var pageRange = document.createElement('div');
pageRange.className = 'magnet-control-row';
pageRange.style.cssText = 'font-size:12px;color:#8892a4;display:flex;align-items:center;gap:8px';

View File

@@ -2,12 +2,13 @@
"manifest_version": 3,
"name": "涩花塘磁力助手",
"version": "1.3",
"description": "一键获取磁力链接 - 暗色科技风UI",
"description": "一键获取磁力链接 - 暗色科技风UI + 收藏夹 + 吜索历史 + 宔完成通知",
"permissions": [
"activeTab",
"clipboardWrite",
"storage",
"unlimitedStorage"
"unlimitedStorage",
"notifications"
],
"host_permissions": [
"http://sehuatang.net/*",