1
This commit is contained in:
@@ -1,49 +1,87 @@
|
||||
import {onMounted, onUnmounted, ref} from "vue";
|
||||
import {platformConfigs} from "@/config/platforms";
|
||||
import {CrawlTaskState} from "@/types";
|
||||
import {sendBackgroundMessage} from "@/shared/message";
|
||||
import { onMounted, onUnmounted, ref } from 'vue';
|
||||
import { platformConfigs } from '@/config/platforms';
|
||||
import type { CrawlTaskState } from '@/types';
|
||||
import { sendBackgroundMessage } from '@/shared/message';
|
||||
|
||||
const CRAWL_TASK_STORAGE_KEY = 'crawlTaskState';
|
||||
const ACTIVE_STATUSES = new Set(['running', 'paused']);
|
||||
|
||||
export const useScan = () => {
|
||||
//选中id
|
||||
const selectedPlatformId = ref(platformConfigs[0]?.id ?? '');
|
||||
//防抖
|
||||
const isScanning = ref<boolean>(false)
|
||||
//步骤数据
|
||||
const isScanning = ref<boolean>(false);
|
||||
const crawlState = ref<CrawlTaskState | null>(null);
|
||||
//爬取时间
|
||||
const elapsedSeconds = ref<number>(0)
|
||||
|
||||
const elapsedSeconds = ref<number>(0);
|
||||
|
||||
let timer: number | undefined;
|
||||
/**
|
||||
* 开始爬取
|
||||
*/
|
||||
|
||||
const handleScan = async () => {
|
||||
if (isScanning.value) return
|
||||
isScanning.value = true
|
||||
if (isScanning.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
isScanning.value = true;
|
||||
|
||||
try {
|
||||
updateSeconds()
|
||||
//定时器
|
||||
timer = window.setInterval(() => {
|
||||
updateSeconds();
|
||||
}, 1000);
|
||||
//发送
|
||||
ensureElapsedTimer();
|
||||
|
||||
const response = await sendBackgroundMessage<CrawlTaskState>({
|
||||
action: 'START_CRAWL',
|
||||
payload: {platformId: selectedPlatformId.value},
|
||||
payload: { platformId: selectedPlatformId.value },
|
||||
});
|
||||
if (response.data) {
|
||||
crawlState.value = response.data;
|
||||
|
||||
if (response.ok) {
|
||||
syncCrawlState(response.data ?? null);
|
||||
} else {
|
||||
console.error('[crawl] start failed', response.error);
|
||||
}
|
||||
} finally {
|
||||
isScanning.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancelCrawl = async () => {
|
||||
const response = await sendBackgroundMessage<CrawlTaskState | null>({ action: 'CANCEL_CRAWL' });
|
||||
|
||||
if (response.ok) {
|
||||
syncCrawlState(response.data ?? null);
|
||||
return;
|
||||
}
|
||||
|
||||
console.error('[crawl] cancel failed', response.error);
|
||||
await refreshCrawlState();
|
||||
};
|
||||
|
||||
function syncCrawlState(state: CrawlTaskState | null) {
|
||||
crawlState.value = state;
|
||||
updateSeconds();
|
||||
|
||||
if (state && ACTIVE_STATUSES.has(state.status)) {
|
||||
ensureElapsedTimer();
|
||||
return;
|
||||
}
|
||||
|
||||
clearElapsedTimer();
|
||||
}
|
||||
|
||||
function ensureElapsedTimer() {
|
||||
if (timer !== undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
timer = window.setInterval(() => {
|
||||
updateSeconds();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function clearElapsedTimer() {
|
||||
if (timer === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.clearInterval(timer);
|
||||
timer = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
function updateSeconds() {
|
||||
if (!crawlState.value) {
|
||||
elapsedSeconds.value = 0;
|
||||
@@ -53,33 +91,54 @@ export const useScan = () => {
|
||||
elapsedSeconds.value = Math.max(0, Math.floor((Date.now() - crawlState.value.startedAt) / 1000));
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步爬取状态
|
||||
*/
|
||||
async function refreshCrawlState() {
|
||||
const response = await sendBackgroundMessage<CrawlTaskState | null>({action: 'GET_CRAWL_STATE'});
|
||||
const response = await sendBackgroundMessage<CrawlTaskState | null>({ action: 'GET_CRAWL_STATE' });
|
||||
|
||||
if (response.data) {
|
||||
crawlState.value = response.data ?? null;
|
||||
updateSeconds();
|
||||
if (response.ok) {
|
||||
syncCrawlState(response.data ?? null);
|
||||
}
|
||||
}
|
||||
|
||||
function handleStorageChanged(changes: Record<string, chrome.storage.StorageChange>, areaName: string) {
|
||||
if (areaName !== 'local') {
|
||||
return;
|
||||
}
|
||||
|
||||
const change = changes[CRAWL_TASK_STORAGE_KEY];
|
||||
|
||||
if (!change) {
|
||||
return;
|
||||
}
|
||||
|
||||
syncCrawlState(isCrawlTaskState(change.newValue) ? change.newValue : null);
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await refreshCrawlState()
|
||||
})
|
||||
await refreshCrawlState();
|
||||
|
||||
if (typeof chrome !== 'undefined' && chrome.storage?.onChanged) {
|
||||
chrome.storage.onChanged.addListener(handleStorageChanged);
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer) {
|
||||
window.clearInterval(timer);
|
||||
clearElapsedTimer();
|
||||
|
||||
if (typeof chrome !== 'undefined' && chrome.storage?.onChanged) {
|
||||
chrome.storage.onChanged.removeListener(handleStorageChanged);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return {
|
||||
selectedPlatformId,
|
||||
isScanning,
|
||||
crawlState,
|
||||
handleScan,
|
||||
handleCancelCrawl,
|
||||
elapsedSeconds,
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function isCrawlTaskState(value: unknown): value is CrawlTaskState {
|
||||
return typeof value === 'object' && value !== null && 'id' in value && 'steps' in value;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user