Files
custom-plugin/entrypoints/content.ts
2026-05-02 04:19:32 +08:00

107 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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') {
const pins = collector.collect();
sendResponse({ success: true, count: pins.length, pins });
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;
}
});
},
});
function sayHello() {
console.log('检测到花瓣网!', window.location.href);
console.log('这个插件是一个用于自动收集图片的插件。');
showPageMarker({
text: '检测到花瓣网!插件已启动',
position: 'top-right',
backgroundColor: 'rgba(34, 139, 34, 0.9)',
closable: true, // 用户可点击 × 关闭
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}/`,
};
}