99 lines
2.5 KiB
TypeScript
99 lines
2.5 KiB
TypeScript
import { apiClient } from "./client";
|
|
|
|
export interface SearchResult {
|
|
id: string;
|
|
title: string;
|
|
description: string;
|
|
thumbnail: string;
|
|
url: string;
|
|
duration: string;
|
|
views: string;
|
|
channel: string;
|
|
isShort: boolean;
|
|
published: string;
|
|
}
|
|
|
|
export interface SearchResponse {
|
|
results: SearchResult[];
|
|
total: number;
|
|
page: number;
|
|
hasMore: boolean;
|
|
}
|
|
|
|
export interface SearchParams {
|
|
query: string;
|
|
page?: number;
|
|
limit?: number;
|
|
}
|
|
|
|
export async function searchVideos(
|
|
params: SearchParams,
|
|
): Promise<SearchResponse> {
|
|
const response = await apiClient.get<SearchResponse>("/search", {
|
|
params: {
|
|
q: params.query,
|
|
page: params.page || 1,
|
|
limit: params.limit || 15,
|
|
},
|
|
});
|
|
|
|
// Handle server errors that return 200 but have error field
|
|
const serverData = response.data as any;
|
|
if (serverData.error) {
|
|
throw new Error(serverData.error);
|
|
}
|
|
|
|
// Server returns {results, total, page, hasMore, query} directly
|
|
const actualData = serverData.data || serverData;
|
|
const videos = actualData.results || [];
|
|
|
|
return {
|
|
results: videos.map((v: any) => ({
|
|
id: v.id,
|
|
videoId: v.videoId || v.id,
|
|
title: v.title,
|
|
description: v.description || "",
|
|
thumbnail: v.thumbnail || `https://i.ytimg.com/vi/${v.id}/hqdefault.jpg`,
|
|
url: v.url,
|
|
category: "General",
|
|
duration: v.duration || "0:00",
|
|
views: v.views || "0",
|
|
channel: v.channel || "Unknown",
|
|
isShort: v.isShort || false,
|
|
published: v.published || "",
|
|
})),
|
|
total: videos.length,
|
|
page: actualData.page || params.page || 1,
|
|
hasMore: actualData.hasMore || videos.length >= 15,
|
|
};
|
|
}
|
|
|
|
export async function getVideoDetails(videoId: string): Promise<SearchResult> {
|
|
const response = await apiClient.get<SearchResult>(`/video/${videoId}`);
|
|
return response.data;
|
|
}
|
|
|
|
export async function getVideoInfo(url: string): Promise<SearchResult> {
|
|
const response = await apiClient.get<SearchResult>("/info", {
|
|
params: { url },
|
|
});
|
|
return response.data;
|
|
}
|
|
|
|
export async function getRecentSearches(): Promise<string[]> {
|
|
const response = await apiClient.get<string[]>("/recent-searches");
|
|
return response.data;
|
|
}
|
|
|
|
export async function clearRecentSearches(): Promise<void> {
|
|
await apiClient.delete("/recent-searches");
|
|
}
|
|
|
|
export async function removeRecentSearch(query: string): Promise<void> {
|
|
await apiClient.delete(`/recent-searches/${encodeURIComponent(query)}`);
|
|
}
|
|
|
|
export async function saveRecentSearch(query: string): Promise<void> {
|
|
await apiClient.post("/recent-searches", { query });
|
|
}
|