项目从单体结构重构为 pnpm monorepo (shared/backend/frontend), 新增 YouTube、Instagram、Twitter/X、哔哩哔哩、微博 5 个平台适配器, 包含完整的单元测试和 E2E 测试覆盖。 - 完成 T-031~T-044: 5 个适配器实现、注册、配置和测试 - 重构前后端分离: Hono 后端 + Next.js 前端 - 151 个单元测试 + 21 个 Mock E2E + 25 个真实 E2E - 适配器基于真实 TikHub API 响应结构实现 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
"use client";
|
|
|
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
import type { ContentItem } from "@muse/shared";
|
|
import { API_BASE_URL } from "@/lib/api";
|
|
|
|
async function fetchDetail(
|
|
platform: string,
|
|
id: string
|
|
): Promise<ContentItem> {
|
|
const res = await fetch(
|
|
`${API_BASE_URL}/api/tikhub/${platform}/detail?id=${encodeURIComponent(id)}`
|
|
);
|
|
if (!res.ok) {
|
|
const data = await res.json().catch(() => ({}));
|
|
throw new Error(data.error || `请求失败: ${res.status}`);
|
|
}
|
|
const data = await res.json();
|
|
return data.data;
|
|
}
|
|
|
|
/**
|
|
* Look up an item from TanStack Query's trending list cache.
|
|
* Checks both platform-specific and "all" caches.
|
|
*/
|
|
function findCachedItem(
|
|
queryClient: ReturnType<typeof useQueryClient>,
|
|
platform: string,
|
|
id: string
|
|
): ContentItem | undefined {
|
|
const keys = [["content", platform], ["content", "all"]];
|
|
for (const key of keys) {
|
|
const items = queryClient.getQueryData<ContentItem[]>(key);
|
|
if (items) {
|
|
const found = items.find(
|
|
(item) => item.id === id && item.platform === platform
|
|
);
|
|
if (found) return found;
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
export function useDetailQuery(platform: string, id: string) {
|
|
const queryClient = useQueryClient();
|
|
const cached = findCachedItem(queryClient, platform, id);
|
|
|
|
return useQuery<ContentItem>({
|
|
queryKey: ["detail", platform, id],
|
|
queryFn: () => fetchDetail(platform, id),
|
|
// Skip API call if item already in trending cache
|
|
enabled: !!platform && !!id && !cached,
|
|
initialData: cached,
|
|
staleTime: 5 * 60 * 1000,
|
|
retry: 1,
|
|
});
|
|
}
|