Refac APIClient to return data, error and status as object

This commit is contained in:
MerlinScheurer
2025-03-20 20:30:08 +01:00
parent 52083e6fb7
commit edcede5de6
67 changed files with 660 additions and 544 deletions

View File

@@ -1,8 +1,8 @@
import APIClient from '../../functions/APIClient';
import { CookieStateType } from '../loader/loadCookie';
const deleteCookie = async (): Promise<CookieStateType> => {
return APIClient('/api/appsettings/cookie/', {
const deleteCookie = async () => {
return APIClient<CookieStateType>('/api/appsettings/cookie/', {
method: 'DELETE',
});
};

View File

@@ -1,8 +1,8 @@
import APIClient from '../../functions/APIClient';
import { CookieStateType } from '../loader/loadCookie';
const updateCookie = async (cookie: string): Promise<CookieStateType> => {
return APIClient('/api/appsettings/cookie/', {
const updateCookie = async (cookie: string) => {
return APIClient<CookieStateType>('/api/appsettings/cookie/', {
method: 'PUT',
body: { cookie },
});

View File

@@ -25,8 +25,8 @@ export type UserConfigType = {
show_help_text: boolean;
};
const updateUserConfig = async (config: Partial<UserConfigType>): Promise<UserConfigType> => {
return APIClient('/api/user/me/', {
const updateUserConfig = async (config: Partial<UserConfigType>) => {
return APIClient<UserConfigType>('/api/user/me/', {
method: 'POST',
body: config,
});

View File

@@ -14,11 +14,8 @@ type VideoProgressProp = {
currentProgress: number;
};
const updateVideoProgressById = async ({
youtubeId,
currentProgress,
}: VideoProgressProp): Promise<VideoProgressResponseType> => {
return APIClient(`/api/video/${youtubeId}/progress/`, {
const updateVideoProgressById = async ({ youtubeId, currentProgress }: VideoProgressProp) => {
return APIClient<VideoProgressResponseType>(`/api/video/${youtubeId}/progress/`, {
method: 'POST',
body: { position: currentProgress },
});

View File

@@ -1,8 +1,8 @@
import APIClient from '../../functions/APIClient';
import { CookieStateType } from '../loader/loadCookie';
const validateCookie = async (): Promise<CookieStateType> => {
return APIClient('/api/appsettings/cookie/', {
const validateCookie = async () => {
return APIClient<CookieStateType>('/api/appsettings/cookie/', {
method: 'POST',
});
};

View File

@@ -4,8 +4,8 @@ type ApiTokenResponse = {
token: string;
};
const loadApiToken = async (): Promise<ApiTokenResponse> => {
return APIClient('/api/appsettings/token/');
const loadApiToken = async () => {
return APIClient<ApiTokenResponse>('/api/appsettings/token/');
};
export default loadApiToken;

View File

@@ -19,8 +19,8 @@ export type AppriseNotificationType = {
};
};
const loadAppriseNotification = async (): Promise<AppriseNotificationType> => {
return APIClient('/api/task/notification/');
const loadAppriseNotification = async () => {
return APIClient<AppriseNotificationType>('/api/task/notification/');
};
export default loadAppriseNotification;

View File

@@ -33,8 +33,8 @@ export type AppSettingsConfigType = {
};
};
const loadAppsettingsConfig = async (): Promise<AppSettingsConfigType> => {
return APIClient('/api/appsettings/config/');
const loadAppsettingsConfig = async () => {
return APIClient<AppSettingsConfigType>('/api/appsettings/config/');
};
export default loadAppsettingsConfig;

View File

@@ -1,7 +1,17 @@
import APIClient from '../../functions/APIClient';
type Backup = {
filename: string;
file_path: string;
file_size: number;
timestamp: string;
reason: string;
};
export type BackupListType = Backup[];
const loadBackupList = async () => {
return APIClient('/api/appsettings/backup/');
return APIClient<BackupListType>('/api/appsettings/backup/');
};
export default loadBackupList;

View File

@@ -13,8 +13,8 @@ export type ChannelAggsType = {
};
};
const loadChannelAggs = async (channelId: string): Promise<ChannelAggsType> => {
return APIClient(`/api/channel/${channelId}/aggs/`);
const loadChannelAggs = async (channelId: string) => {
return APIClient<ChannelAggsType>(`/api/channel/${channelId}/aggs/`);
};
export default loadChannelAggs;

View File

@@ -1,8 +1,10 @@
import APIClient from '../../functions/APIClient';
import { ChannelResponseType } from '../../pages/ChannelBase';
import { ChannelType } from '../../pages/Channels';
const loadChannelById = async (youtubeChannelId: string): Promise<ChannelResponseType> => {
return APIClient(`/api/channel/${youtubeChannelId}/`);
export type ChannelResponseType = ChannelType;
const loadChannelById = async (youtubeChannelId: string) => {
return APIClient<ChannelResponseType>(`/api/channel/${youtubeChannelId}/`);
};
export default loadChannelById;

View File

@@ -1,4 +1,13 @@
import { PaginationType } from '../../components/Pagination';
import APIClient from '../../functions/APIClient';
import { ChannelType } from '../../pages/Channels';
import { ConfigType } from '../../pages/Home';
export type ChannelsListResponse = {
data: ChannelType[];
paginate: PaginationType;
config?: ConfigType;
};
const loadChannelList = async (page: number, showSubscribed: boolean) => {
const searchParams = new URLSearchParams();
@@ -8,7 +17,7 @@ const loadChannelList = async (page: number, showSubscribed: boolean) => {
const endpoint = `/api/channel/${searchParams.toString() ? `?${searchParams.toString()}` : ''}`;
return APIClient(endpoint);
return APIClient<ChannelsListResponse>(endpoint);
};
export default loadChannelList;

View File

@@ -7,8 +7,8 @@ export type ChannelNavResponseType = {
has_pending: boolean;
};
const loadChannelNav = async (youtubeChannelId: string): Promise<ChannelNavResponseType> => {
return APIClient(`/api/channel/${youtubeChannelId}/nav/`);
const loadChannelNav = async (youtubeChannelId: string) => {
return APIClient<ChannelNavResponseType>(`/api/channel/${youtubeChannelId}/nav/`);
};
export default loadChannelNav;

View File

@@ -1,7 +1,10 @@
import { CommentsType } from '../../components/CommentBox';
import APIClient from '../../functions/APIClient';
export type CommentsResponseType = CommentsType[];
const loadCommentsbyVideoId = async (youtubeId: string) => {
return APIClient(`/api/video/${youtubeId}/comment/`);
return APIClient<CommentsResponseType>(`/api/video/${youtubeId}/comment/`);
};
export default loadCommentsbyVideoId;

View File

@@ -7,8 +7,8 @@ export type CookieStateType = {
validated_str?: string;
};
const loadCookie = async (): Promise<CookieStateType> => {
return APIClient('/api/appsettings/cookie/');
const loadCookie = async () => {
return APIClient<CookieStateType>('/api/appsettings/cookie/');
};
export default loadCookie;

View File

@@ -12,10 +12,10 @@ export type DownloadAggsType = {
buckets: DownloadAggsBucket[];
};
const loadDownloadAggs = async (showIgnored: boolean): Promise<DownloadAggsType> => {
const loadDownloadAggs = async (showIgnored: boolean) => {
const searchParams = new URLSearchParams();
searchParams.append('filter', showIgnored ? 'ignore' : 'pending');
return APIClient(
return APIClient<DownloadAggsType>(
`/api/download/aggs/${searchParams.toString() ? `?${searchParams.toString()}` : ''}`,
);
};

View File

@@ -1,11 +1,7 @@
import APIClient from '../../functions/APIClient';
import { DownloadResponseType } from '../../pages/Download';
const loadDownloadQueue = async (
page: number,
channelId: string | null,
showIgnored: boolean,
): Promise<DownloadResponseType> => {
const loadDownloadQueue = async (page: number, channelId: string | null, showIgnored: boolean) => {
const searchParams = new URLSearchParams();
if (page) searchParams.append('page', page.toString());
@@ -14,7 +10,7 @@ const loadDownloadQueue = async (
const endpoint = `/api/download/${searchParams.toString() ? `?${searchParams.toString()}` : ''}`;
return APIClient(endpoint);
return APIClient<DownloadResponseType>(endpoint);
};
export default loadDownloadQueue;

View File

@@ -2,6 +2,19 @@ import APIClient from '../../functions/APIClient';
export type NotificationPages = 'download' | 'settings' | 'channel' | 'all';
type NotificationType = {
title: string;
group: string;
api_stop: boolean;
level: string;
id: string;
command: boolean | string;
messages: string[];
progress: number;
};
export type NotificationResponseType = NotificationType[];
const loadNotifications = async (pageName: NotificationPages, includeReindex = false) => {
const searchParams = new URLSearchParams();
@@ -10,7 +23,7 @@ const loadNotifications = async (pageName: NotificationPages, includeReindex = f
}
const endpoint = `/api/notification/${searchParams.toString() ? `?${searchParams.toString()}` : ''}`;
return APIClient(endpoint);
return APIClient<NotificationResponseType>(endpoint);
};
export default loadNotifications;

View File

@@ -26,8 +26,8 @@ export type PlaylistType = {
export type PlaylistResponseType = PlaylistType;
const loadPlaylistById = async (playlistId: string | undefined): Promise<PlaylistResponseType> => {
return APIClient(`/api/playlist/${playlistId}/`);
const loadPlaylistById = async (playlistId: string | undefined) => {
return APIClient<PlaylistResponseType>(`/api/playlist/${playlistId}/`);
};
export default loadPlaylistById;

View File

@@ -1,12 +1,19 @@
import { PaginationType } from '../../components/Pagination';
import APIClient from '../../functions/APIClient';
import { PlaylistType } from './loadPlaylistById';
type PlaylistType = 'regular' | 'custom';
export type PlaylistsResponseType = {
data?: PlaylistType[];
paginate?: PaginationType;
};
type PlaylistCategoryType = 'regular' | 'custom';
type LoadPlaylistListProps = {
channel?: string;
page?: number | undefined;
subscribed?: boolean;
type?: PlaylistType;
type?: PlaylistCategoryType;
};
const loadPlaylistList = async ({ channel, page, subscribed, type }: LoadPlaylistListProps) => {
@@ -18,7 +25,7 @@ const loadPlaylistList = async ({ channel, page, subscribed, type }: LoadPlaylis
if (type) searchParams.append('type', type);
const endpoint = `/api/playlist/${searchParams.toString() ? `?${searchParams.toString()}` : ''}`;
return APIClient(endpoint);
return APIClient<PlaylistsResponseType>(endpoint);
};
export default loadPlaylistList;

View File

@@ -13,8 +13,8 @@ type ScheduleType = {
export type ScheduleResponseType = ScheduleType[];
const loadSchedule = async (): Promise<ScheduleResponseType> => {
return APIClient('/api/task/schedule/');
const loadSchedule = async () => {
return APIClient<ScheduleResponseType>('/api/task/schedule/');
};
export default loadSchedule;

View File

@@ -1,7 +1,22 @@
import APIClient from '../../functions/APIClient';
import { ChannelType } from '../../pages/Channels';
import { VideoType } from '../../pages/Home';
import { PlaylistType } from './loadPlaylistById';
type SearchResultType = {
video_results: VideoType[];
channel_results: ChannelType[];
playlist_results: PlaylistType[];
fulltext_results: [];
};
export type SearchResultsType = {
results: SearchResultType;
queryType: string;
};
const loadSearch = async (query: string) => {
return APIClient(`/api/search/?query=${query}`);
return APIClient<SearchResultsType>(`/api/search/?query=${query}`);
};
export default loadSearch;

View File

@@ -0,0 +1,8 @@
import APIClient from '../../functions/APIClient';
import { VideoResponseType } from './loadVideoById';
const loadSimilarVideosById = async (youtubeId: string) => {
return APIClient<VideoResponseType[]>(`/api/video/${youtubeId}/similar/`);
};
export default loadSimilarVideosById;

View File

@@ -1,7 +0,0 @@
import APIClient from '../../functions/APIClient';
const loadSimmilarVideosById = async (youtubeId: string) => {
return APIClient(`/api/video/${youtubeId}/similar/`);
};
export default loadSimmilarVideosById;

View File

@@ -1,7 +1,24 @@
import APIClient from '../../functions/APIClient';
export type SnapshotType = {
id: string;
state: string;
es_version: string;
start_date: string;
end_date: string;
end_stamp: number;
duration_s: number;
};
export type SnapshotListType = {
next_exec: number;
next_exec_str: string;
expire_after: string;
snapshots?: SnapshotType[];
};
const loadSnapshots = async () => {
return APIClient('/api/appsettings/snapshot/');
return APIClient<SnapshotListType>('/api/appsettings/snapshot/');
};
export default loadSnapshots;

View File

@@ -2,11 +2,24 @@ import APIClient from '../../functions/APIClient';
type BiggestChannelsOrderType = 'doc_count' | 'duration' | 'media_size';
type BiggestChannelsType = {
id: string;
name: string;
doc_count: number;
duration: number;
duration_str: string;
media_size: number;
};
export type BiggestChannelsStatsType = BiggestChannelsType[];
const loadStatsBiggestChannels = async (order: BiggestChannelsOrderType) => {
const searchParams = new URLSearchParams();
searchParams.append('order', order);
return APIClient(`/api/stats/biggestchannels/?${searchParams.toString()}`);
return APIClient<BiggestChannelsStatsType>(
`/api/stats/biggestchannels/?${searchParams.toString()}`,
);
};
export default loadStatsBiggestChannels;

View File

@@ -1,7 +1,13 @@
import APIClient from '../../functions/APIClient';
export type ChannelStatsType = {
doc_count: number;
active_true: number;
subscribed_true: number;
};
const loadStatsChannel = async () => {
return APIClient('/api/stats/channel/');
return APIClient<ChannelStatsType>('/api/stats/channel/');
};
export default loadStatsChannel;

View File

@@ -1,7 +1,14 @@
import APIClient from '../../functions/APIClient';
export type DownloadStatsType = {
pending: number;
pending_videos: number;
pending_shorts: number;
pending_streams: number;
};
const loadStatsDownload = async () => {
return APIClient('/api/stats/download/');
return APIClient<DownloadStatsType>('/api/stats/download/');
};
export default loadStatsDownload;

View File

@@ -1,7 +1,15 @@
import APIClient from '../../functions/APIClient';
type DownloadHistoryType = {
date: string;
count: number;
media_size: number;
};
export type DownloadHistoryStatsType = DownloadHistoryType[];
const loadStatsDownloadHistory = async () => {
return APIClient('/api/stats/downloadhist/');
return APIClient<DownloadHistoryStatsType>('/api/stats/downloadhist/');
};
export default loadStatsDownloadHistory;

View File

@@ -1,7 +1,14 @@
import APIClient from '../../functions/APIClient';
export type PlaylistStatsType = {
doc_count: number;
active_false: number;
active_true: number;
subscribed_true: number;
};
const loadStatsPlaylist = async () => {
return APIClient('/api/stats/playlist/');
return APIClient<PlaylistStatsType>('/api/stats/playlist/');
};
export default loadStatsPlaylist;

View File

@@ -1,7 +1,44 @@
import APIClient from '../../functions/APIClient';
export type VideoStatsType = {
doc_count: number;
media_size: number;
duration: number;
duration_str: string;
type_videos: {
doc_count: number;
media_size: number;
duration: number;
duration_str: string;
};
type_shorts: {
doc_count: number;
media_size: number;
duration: number;
duration_str: string;
};
active_true: {
doc_count: number;
media_size: number;
duration: number;
duration_str: string;
};
active_false: {
doc_count: number;
media_size: number;
duration: number;
duration_str: string;
};
type_streams: {
doc_count: number;
media_size: number;
duration: number;
duration_str: string;
};
};
const loadStatsVideo = async () => {
return APIClient('/api/stats/video/');
return APIClient<VideoStatsType>('/api/stats/video/');
};
export default loadStatsVideo;

View File

@@ -1,7 +1,27 @@
import APIClient from '../../functions/APIClient';
export type WatchProgressStatsType = {
total: {
duration: number;
duration_str: string;
items: number;
};
unwatched: {
duration: number;
duration_str: string;
progress: number;
items: number;
};
watched: {
duration: number;
duration_str: string;
progress: number;
items: number;
};
};
const loadStatsWatchProgress = async () => {
return APIClient('/api/stats/watch/');
return APIClient<WatchProgressStatsType>('/api/stats/watch/');
};
export default loadStatsWatchProgress;

View File

@@ -10,8 +10,8 @@ export type UserAccountType = {
last_login: string;
};
const loadUserAccount = async (): Promise<UserAccountType> => {
return APIClient('/api/user/account/');
const loadUserAccount = async () => {
return APIClient<UserAccountType>('/api/user/account/');
};
export default loadUserAccount;

View File

@@ -1,8 +1,8 @@
import { UserConfigType } from '../actions/updateUserConfig';
import APIClient from '../../functions/APIClient';
const loadUserMeConfig = async (): Promise<UserConfigType> => {
return APIClient('/api/user/me/');
const loadUserMeConfig = async () => {
return APIClient<UserConfigType>('/api/user/me/');
};
export default loadUserMeConfig;

View File

@@ -1,8 +1,10 @@
import APIClient from '../../functions/APIClient';
import { VideoResponseType } from '../../pages/Video';
import { VideoType } from '../../pages/Home';
const loadVideoById = async (youtubeId: string): Promise<VideoResponseType> => {
return APIClient(`/api/video/${youtubeId}/`);
export type VideoResponseType = VideoType;
const loadVideoById = async (youtubeId: string) => {
return APIClient<VideoResponseType>(`/api/video/${youtubeId}/`);
};
export default loadVideoById;

View File

@@ -21,9 +21,7 @@ type FilterType = {
type?: VideoTypes;
};
const loadVideoListByFilter = async (
filter: FilterType,
): Promise<VideoListByFilterResponseType> => {
const loadVideoListByFilter = async (filter: FilterType) => {
const searchParams = new URLSearchParams();
if (filter.playlist) {
@@ -39,7 +37,7 @@ const loadVideoListByFilter = async (
if (filter.type) searchParams.append('type', filter.type);
const endpoint = `/api/video/${searchParams.toString() ? `?${searchParams.toString()}` : ''}`;
return APIClient(endpoint);
return APIClient<VideoListByFilterResponseType>(endpoint);
};
export default loadVideoListByFilter;

View File

@@ -25,8 +25,8 @@ export type VideoNavResponseType = {
};
};
const loadVideoNav = async (youtubeVideoId: string): Promise<VideoNavResponseType[]> => {
return APIClient(`/api/video/${youtubeVideoId}/nav/`);
const loadVideoNav = async (youtubeVideoId: string) => {
return APIClient<VideoNavResponseType[]>(`/api/video/${youtubeVideoId}/nav/`);
};
export default loadVideoNav;