feat: 增加了自动加载所有图片的逻辑
This commit is contained in:
@@ -1,15 +1,19 @@
|
||||
import { showPageMarker } from "@/components/page-marker";
|
||||
import { PinCollector } from "#imports";
|
||||
import { AutoLoader } from '@/components/autoLoader';
|
||||
import type { PinData } from '#imports';
|
||||
|
||||
let loader: AutoLoader | null = null;
|
||||
|
||||
export default defineContentScript({
|
||||
matches: ['*://*.huaban.com/*'],
|
||||
runAt: 'document_idle',
|
||||
|
||||
main() {
|
||||
sayHello();
|
||||
|
||||
const collector = new PinCollector();
|
||||
// 首次加载自动收集并存储
|
||||
|
||||
|
||||
// 允许 popup 主动触发重新收集
|
||||
browser.runtime.onMessage.addListener((msg, sender, sendResponse) => {
|
||||
if (msg.type === 'COLLECT_PINS') {
|
||||
@@ -18,6 +22,62 @@ export default defineContentScript({
|
||||
return true; // 异步响应
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: 首次加载自动收集并存储
|
||||
|
||||
browser.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
|
||||
if (msg.action === 'start') {
|
||||
const id = location.pathname.match(/\/boards\/(\d+)/)?.[1] ?? '';
|
||||
|
||||
if (!id) {
|
||||
console.warn('[content] 当前页面不是画板页,无法启动');
|
||||
sendResponse({ ok: false, error: '不在画板页' });
|
||||
return true;
|
||||
}
|
||||
|
||||
loader = new AutoLoader({
|
||||
endpoint: `https://huaban.com/v3/boards/${id}/pins`,
|
||||
paginationMode: 'cursor',
|
||||
limit: 40,
|
||||
cursor: { paramName: 'max', valuePath: 'pin_id' },
|
||||
interval: 1000,
|
||||
itemsPath: 'pins',
|
||||
baseParams: { sort: 'seq', fields: 'pins:PIN|board:BOARD_DETAIL|check' },
|
||||
onProgress: (p) => {
|
||||
browser.runtime.sendMessage({ type: 'progress', ...p });
|
||||
},
|
||||
onError: (err, pageOrCursor) => {
|
||||
browser.runtime.sendMessage({
|
||||
type: 'progress',
|
||||
requestCount: -1,
|
||||
totalItems: -1,
|
||||
newItems: 0,
|
||||
done: false,
|
||||
error: err.message,
|
||||
}).catch(() => { });
|
||||
},
|
||||
onData: async (items) => {
|
||||
const newPins: PinData[] = items.map((pin: any) => extractPinData(pin));
|
||||
// 读取已有数据,按 pin_id 去重合并
|
||||
const stored = await browser.storage.local.get('collectedPins') as { collectedPins?: PinData[] };
|
||||
const existing: PinData[] = stored.collectedPins || [];
|
||||
const existingIds = new Set(existing.map((p) => p.pinId));
|
||||
const merged = [...existing, ...newPins.filter((p) => !existingIds.has(p.pinId))];
|
||||
await browser.storage.local.set({ collectedPins: merged });
|
||||
console.log(`[content] 已写入 storage,累计 ${merged.length} 条`);
|
||||
},
|
||||
});
|
||||
loader.start();
|
||||
sendResponse({ ok: true });
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msg.action === 'stop') {
|
||||
loader?.stop();
|
||||
sendResponse({ ok: true });
|
||||
return true;
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -32,3 +92,16 @@ function sayHello() {
|
||||
autoRemoveSeconds: 10,
|
||||
});
|
||||
}
|
||||
|
||||
function extractPinData(pin: any): PinData {
|
||||
return {
|
||||
pinId: pin.pin_id ?? '',
|
||||
imgSmallSrc: pin.file?.url ?? '',
|
||||
imgSrc: (pin.file?.url ?? '').replace(/_fw\d+webp|_png/, ''),
|
||||
alt: pin.raw_text ?? '',
|
||||
author: pin.user?.username ?? '',
|
||||
time: pin.created_at ?? '',
|
||||
tags: pin.tags?.map((t: any) => t.tag ?? t) ?? [],
|
||||
url: `/pins/${pin.pin_id}/`,
|
||||
};
|
||||
}
|
||||
@@ -7,6 +7,8 @@ document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
|
||||
<div class="actions">
|
||||
<button id="collectBtn">📥 收集</button>
|
||||
<button id="clearBtn">🗑 清空</button>
|
||||
<button id="start-btn">start-btn</button>
|
||||
<button id="stop-btn">stop-btn</button>
|
||||
</div>
|
||||
<div id="status"></div>
|
||||
<div id="pinList"></div>
|
||||
@@ -26,8 +28,9 @@ document.getElementById('collectBtn')!.addEventListener('click', async () => {
|
||||
type: 'COLLECT_PINS',
|
||||
});
|
||||
if (response?.success) {
|
||||
await browser.storage.local.set({ collectedPins: response.pins });
|
||||
renderPins(response.pins as PinData[]);
|
||||
// await browser.storage.local.set({ collectedPins: response.pins });
|
||||
// renderPins(response.pins as PinData[]);
|
||||
await loadAndRender();
|
||||
showStatus(`✅ 已收集 ${response.count} 个 Pin`, 'success');
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -91,3 +94,31 @@ function escapeHtml(str: string): string {
|
||||
div.textContent = str;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
let activeTabId: number | null = null;
|
||||
// 获取当前标签页 ID
|
||||
browser.tabs.query({ active: true, currentWindow: true }, ([tab]) => {
|
||||
activeTabId = tab.id!;
|
||||
document.getElementById('start-btn')?.addEventListener('click', () => {
|
||||
browser.tabs.sendMessage(activeTabId!, { action: 'start' });
|
||||
});
|
||||
document.getElementById('stop-btn')?.addEventListener('click', () => {
|
||||
browser.tabs.sendMessage(activeTabId!, { action: 'stop' });
|
||||
});
|
||||
});
|
||||
// 接收进度回调
|
||||
browser.runtime.onMessage.addListener(async (msg) => {
|
||||
if (msg.type === 'progress') {
|
||||
if (msg.error) {
|
||||
document.getElementById('status')!.textContent = `❌ 错误: ${msg.error}`;
|
||||
} else {
|
||||
document.getElementById('status')!.textContent =
|
||||
`第 ${msg.requestCount} 次 · 共 ${msg.totalItems} 条`;
|
||||
}
|
||||
if (msg.done) {
|
||||
await loadAndRender();
|
||||
document.getElementById('status')!.textContent =
|
||||
`✅ 加载完成 · 共 ${msg.totalItems} 条`;
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user