chore: update package versions and add user config sync API

- Bump version to 4.8.0 and update dependencies in package.json
- Implement user config sync API for cross-device settings persistence
- Add resolution badge auto-hide hook for improved user experience
- Create useConfigSync hook to manage user settings synchronization with the server
This commit is contained in:
kuekhaoyang
2026-03-18 12:44:05 +08:00
parent 54c1d353d7
commit 3564ce1ede
27 changed files with 721 additions and 215 deletions
+13
View File
@@ -12,6 +12,7 @@ const RETRY_DELAY = 200;
/**
* Fetch with timeout support
* Accepts an optional external AbortSignal for cancellation cascade.
*/
export async function fetchWithTimeout(
url: string,
@@ -21,6 +22,18 @@ export async function fetchWithTimeout(
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
// If an external signal is provided, propagate its abort
const externalSignal = options.signal;
if (externalSignal) {
if (externalSignal.aborted) {
clearTimeout(timeoutId);
controller.abort();
} else {
const onAbort = () => controller.abort();
externalSignal.addEventListener('abort', onAbort, { once: true });
}
}
try {
const response = await fetch(url, {
...options,
+6 -3
View File
@@ -10,7 +10,8 @@ import { fetchWithTimeout, withRetry } from './http-utils';
async function searchVideosBySource(
query: string,
source: VideoSource,
page: number = 1
page: number = 1,
signal?: AbortSignal
): Promise<{ results: VideoItem[]; source: string; responseTime: number; pagecount: number }> {
const startTime = Date.now();
@@ -27,6 +28,7 @@ async function searchVideosBySource(
'User-Agent': 'Mozilla/5.0',
...source.headers,
},
signal,
});
if (!res.ok) {
@@ -71,11 +73,12 @@ async function searchVideosBySource(
export async function searchVideos(
query: string,
sources: VideoSource[],
page: number = 1
page: number = 1,
signal?: AbortSignal
): Promise<Array<{ results: VideoItem[]; source: string; responseTime?: number; pagecount?: number; error?: string }>> {
const searchPromises = sources.map(async source => {
try {
return await searchVideosBySource(query, source, page);
return await searchVideosBySource(query, source, page, signal);
} catch (error) {
return {
results: [],