chore: expurgo de blobs excedentes e realinhamento de estado
release.yml (push) Invalid workflow file
release.yml (push) Invalid workflow file
This commit is contained in:
1 parent
593efd42e0
commit
a7cbd1a3b4
114 files changed
+20716
-4258
No files matched your search
@@ -0,0 +1,161 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { listen } from '@tauri-apps/api/event';
|
||||
|
||||
export interface ActiveQuery {
|
||||
query: string;
|
||||
source: string;
|
||||
round?: number;
|
||||
startedAt: number;
|
||||
}
|
||||
|
||||
export interface ActiveUrl {
|
||||
url: string;
|
||||
title?: string;
|
||||
status: 'started' | 'completed' | 'failed' | 'cached';
|
||||
source?: string;
|
||||
startedAt: number;
|
||||
duration?: number;
|
||||
}
|
||||
|
||||
interface SearchQueryEvent {
|
||||
query: string;
|
||||
source: string;
|
||||
round?: number;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
interface SearchQueryCompletedEvent {
|
||||
query: string;
|
||||
source: string;
|
||||
results_count: number;
|
||||
success: boolean;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
interface SearchSourceSwitchEvent {
|
||||
from: string;
|
||||
to: string;
|
||||
reason: string;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
interface ScrapingUrlEvent {
|
||||
url: string;
|
||||
title?: string;
|
||||
status: string;
|
||||
duration_ms?: number;
|
||||
source?: string;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
export function useWebSearchEvents() {
|
||||
const [activeQueries, setActiveQueries] = useState<ActiveQuery[]>([]);
|
||||
const [activeUrls, setActiveUrls] = useState<ActiveUrl[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
let unlistenQueries: (() => void) | null = null;
|
||||
let unlistenCompleted: (() => void) | null = null;
|
||||
let unlistenSwitched: (() => void) | null = null;
|
||||
let unlistenScraping: (() => void) | null = null;
|
||||
|
||||
const setupListeners = async () => {
|
||||
// Listener para query iniciada
|
||||
unlistenQueries = await listen<SearchQueryEvent>('search-query-started', (event) => {
|
||||
const { query, source, round, timestamp } = event.payload;
|
||||
setActiveQueries((prev) => {
|
||||
// Remover query anterior se existir (mesma query)
|
||||
const filtered = prev.filter((q) => q.query !== query);
|
||||
return [
|
||||
...filtered,
|
||||
{
|
||||
query,
|
||||
source,
|
||||
round,
|
||||
startedAt: timestamp,
|
||||
},
|
||||
];
|
||||
});
|
||||
});
|
||||
|
||||
// Listener para query completada
|
||||
unlistenCompleted = await listen<SearchQueryCompletedEvent>('search-query-completed', (event) => {
|
||||
const { query, source } = event.payload;
|
||||
setActiveQueries((prev) => prev.filter((q) => !(q.query === query && q.source === source)));
|
||||
});
|
||||
|
||||
// Listener para mudança de fonte
|
||||
unlistenSwitched = await listen<SearchSourceSwitchEvent>('search-source-switched', (event) => {
|
||||
const { from, to, reason } = event.payload;
|
||||
console.log(`[WebSearchEvents] Source switched: ${from} → ${to} (${reason})`);
|
||||
// Atualizar query ativa para nova fonte
|
||||
setActiveQueries((prev) =>
|
||||
prev.map((q) => (q.source === from ? { ...q, source: to } : q))
|
||||
);
|
||||
});
|
||||
|
||||
// Listener para eventos de scraping
|
||||
unlistenScraping = await listen<ScrapingUrlEvent>('scraping-url-event', (event) => {
|
||||
const { url, title, status, duration_ms, source, timestamp } = event.payload;
|
||||
|
||||
setActiveUrls((prev) => {
|
||||
const existingIndex = prev.findIndex((u) => u.url === url);
|
||||
const newUrl: ActiveUrl = {
|
||||
url,
|
||||
title,
|
||||
status: status as ActiveUrl['status'],
|
||||
source,
|
||||
startedAt: timestamp,
|
||||
duration: duration_ms,
|
||||
};
|
||||
|
||||
if (existingIndex >= 0) {
|
||||
// Atualizar URL existente
|
||||
const updated = [...prev];
|
||||
updated[existingIndex] = newUrl;
|
||||
return updated;
|
||||
} else {
|
||||
// Adicionar nova URL
|
||||
return [...prev, newUrl];
|
||||
}
|
||||
});
|
||||
|
||||
// Remover URLs completadas/falhadas após 5 segundos
|
||||
if (status === 'completed' || status === 'failed' || status === 'cached') {
|
||||
setTimeout(() => {
|
||||
setActiveUrls((prev) => prev.filter((u) => u.url !== url));
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
setupListeners();
|
||||
|
||||
return () => {
|
||||
if (unlistenQueries) unlistenQueries();
|
||||
if (unlistenCompleted) unlistenCompleted();
|
||||
if (unlistenSwitched) unlistenSwitched();
|
||||
if (unlistenScraping) unlistenScraping();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const clearActiveQueries = useCallback(() => {
|
||||
setActiveQueries([]);
|
||||
}, []);
|
||||
|
||||
const clearActiveUrls = useCallback(() => {
|
||||
setActiveUrls([]);
|
||||
}, []);
|
||||
|
||||
const clearAll = useCallback(() => {
|
||||
setActiveQueries([]);
|
||||
setActiveUrls([]);
|
||||
}, []);
|
||||
|
||||
return {
|
||||
activeQueries,
|
||||
activeUrls,
|
||||
clearActiveQueries,
|
||||
clearActiveUrls,
|
||||
clearAll,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user