mirror of
https://git.vectorsigma.ru/public/tubearchivist.git
synced 2026-08-08 22:31:54 +00:00
Refac APIClient to return data, error and status as object
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
import { Fragment } from 'react';
|
||||
import StatsInfoBoxItem from './StatsInfoBoxItem';
|
||||
import formatNumbers from '../functions/formatNumbers';
|
||||
import { ChannelStatsType, PlaylistStatsType, DownloadStatsType } from '../pages/SettingsDashboard';
|
||||
import { ChannelStatsType } from '../api/loader/loadStatsChannel';
|
||||
import { PlaylistStatsType } from '../api/loader/loadStatsPlaylist';
|
||||
import { DownloadStatsType } from '../api/loader/loadStatsDownload';
|
||||
|
||||
type ApplicationStatsProps = {
|
||||
channelStats?: ChannelStatsType;
|
||||
|
||||
@@ -2,7 +2,7 @@ import humanFileSize from '../functions/humanFileSize';
|
||||
import formatNumbers from '../functions/formatNumbers';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Routes from '../configuration/routes/RouteList';
|
||||
import { BiggestChannelsStatsType } from '../pages/SettingsDashboard';
|
||||
import { BiggestChannelsStatsType } from '../api/loader/loadStatsBiggestChannels';
|
||||
|
||||
type BiggestChannelsStatsProps = {
|
||||
biggestChannelsStatsByCount?: BiggestChannelsStatsType;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import humanFileSize from '../functions/humanFileSize';
|
||||
import formatDate from '../functions/formatDates';
|
||||
import formatNumbers from '../functions/formatNumbers';
|
||||
import { DownloadHistoryStatsType } from '../pages/SettingsDashboard';
|
||||
import { DownloadHistoryStatsType } from '../api/loader/loadStatsDownloadHistory';
|
||||
|
||||
type DownloadHistoryStatsProps = {
|
||||
downloadHistoryStats?: DownloadHistoryStatsType;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { VideoResponseType } from '../pages/Video';
|
||||
import VideoPlayer from './VideoPlayer';
|
||||
import loadVideoById from '../api/loader/loadVideoById';
|
||||
import loadVideoById, { VideoResponseType } from '../api/loader/loadVideoById';
|
||||
import iconClose from '/img/icon-close.svg';
|
||||
import iconEye from '/img/icon-eye.svg';
|
||||
import iconThumb from '/img/icon-thumb.svg';
|
||||
@@ -13,6 +12,7 @@ import { Link, useSearchParams } from 'react-router-dom';
|
||||
import Routes from '../configuration/routes/RouteList';
|
||||
import loadPlaylistById from '../api/loader/loadPlaylistById';
|
||||
import { useAppSettingsStore } from '../stores/AppSettingsStore';
|
||||
import { ApiResponseType } from '../functions/APIClient';
|
||||
|
||||
type Playlist = {
|
||||
id: string;
|
||||
@@ -32,9 +32,11 @@ const EmbeddableVideoPlayer = ({ videoId }: EmbeddableVideoPlayerProps) => {
|
||||
|
||||
const [refresh, setRefresh] = useState(true);
|
||||
|
||||
const [videoResponse, setVideoResponse] = useState<VideoResponseType>();
|
||||
const [videoResponse, setVideoResponse] = useState<ApiResponseType<VideoResponseType>>();
|
||||
const [playlists, setPlaylists] = useState<PlaylistList>();
|
||||
|
||||
const { data: videoResponseData } = videoResponse ?? {};
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
if (!videoId) {
|
||||
@@ -43,27 +45,31 @@ const EmbeddableVideoPlayer = ({ videoId }: EmbeddableVideoPlayerProps) => {
|
||||
|
||||
inlinePlayerRef.current?.scrollIntoView();
|
||||
|
||||
if (refresh || videoId !== videoResponse?.youtube_id) {
|
||||
if (refresh || videoId !== videoResponseData?.youtube_id) {
|
||||
const videoResponse = await loadVideoById(videoId);
|
||||
|
||||
const playlistIds = videoResponse.playlist;
|
||||
const { data: videoResponseData } = videoResponse ?? {};
|
||||
|
||||
const playlistIds = videoResponseData?.playlist || [];
|
||||
if (playlistIds !== undefined) {
|
||||
const playlists = await Promise.all(
|
||||
playlistIds.map(async playlistid => {
|
||||
const playlistResponse = await loadPlaylistById(playlistid);
|
||||
|
||||
return playlistResponse;
|
||||
const { data: playlistResponseData } = playlistResponse ?? {};
|
||||
|
||||
return playlistResponseData;
|
||||
}),
|
||||
);
|
||||
|
||||
const playlistsFiltered = playlists
|
||||
.filter(playlist => {
|
||||
return playlist.playlist_subscribed;
|
||||
return playlist?.playlist_subscribed;
|
||||
})
|
||||
.map(playlist => {
|
||||
return {
|
||||
id: playlist.playlist_id,
|
||||
name: playlist.playlist_name,
|
||||
id: playlist?.playlist_id || '',
|
||||
name: playlist?.playlist_name || '',
|
||||
};
|
||||
});
|
||||
|
||||
@@ -77,11 +83,11 @@ const EmbeddableVideoPlayer = ({ videoId }: EmbeddableVideoPlayerProps) => {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [videoId, refresh]);
|
||||
|
||||
if (videoResponse === undefined || videoId === null) {
|
||||
if (videoResponseData === undefined || videoId === null) {
|
||||
return <div ref={inlinePlayerRef} className="player-wrapper" />;
|
||||
}
|
||||
|
||||
const video = videoResponse;
|
||||
const video = videoResponseData;
|
||||
const name = video.title;
|
||||
const channelId = video.channel.channel_id;
|
||||
const channelName = video.channel.channel_name;
|
||||
@@ -99,7 +105,7 @@ const EmbeddableVideoPlayer = ({ videoId }: EmbeddableVideoPlayerProps) => {
|
||||
<div ref={inlinePlayerRef} className="player-wrapper">
|
||||
<div className="video-player">
|
||||
<VideoPlayer
|
||||
video={videoResponse}
|
||||
video={videoResponseData}
|
||||
sponsorBlock={sponsorblock}
|
||||
embed={true}
|
||||
autoplay={true}
|
||||
|
||||
@@ -22,7 +22,11 @@ const Filterbar = ({ hideToggleText, viewStyleName, showSort = true }: Filterbar
|
||||
|
||||
const handleUserConfigUpdate = async (config: Partial<UserConfigType>) => {
|
||||
const updatedUserConfig = await updateUserConfig(config);
|
||||
setUserConfig(updatedUserConfig);
|
||||
const { data: updatedUserConfigData } = updatedUserConfig;
|
||||
|
||||
if (updatedUserConfigData) {
|
||||
setUserConfig(updatedUserConfigData);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -46,7 +46,12 @@ async function castVideoProgress(
|
||||
currentProgress: currentTime,
|
||||
});
|
||||
|
||||
if (videoProgressResponse.watched && video.player.watched !== videoProgressResponse.watched) {
|
||||
const { data: videoProgressResponseData } = videoProgressResponse ?? {};
|
||||
|
||||
if (
|
||||
videoProgressResponseData?.watched &&
|
||||
video.player.watched !== videoProgressResponseData.watched
|
||||
) {
|
||||
onWatchStateChanged?.(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
import { Fragment, useEffect, useState } from 'react';
|
||||
import loadNotifications, { NotificationPages } from '../api/loader/loadNotifications';
|
||||
import loadNotifications, {
|
||||
NotificationPages,
|
||||
NotificationResponseType,
|
||||
} from '../api/loader/loadNotifications';
|
||||
import iconStop from '/img/icon-stop.svg';
|
||||
import stopTaskByName from '../api/actions/stopTaskByName';
|
||||
|
||||
type NotificationType = {
|
||||
title: string;
|
||||
group: string;
|
||||
api_stop: boolean;
|
||||
level: string;
|
||||
id: string;
|
||||
command: boolean | string;
|
||||
messages: string[];
|
||||
progress: number;
|
||||
};
|
||||
|
||||
type NotificationResponseType = NotificationType[];
|
||||
import { ApiResponseType } from '../functions/APIClient';
|
||||
|
||||
type NotificationsProps = {
|
||||
pageName: NotificationPages;
|
||||
@@ -29,13 +20,17 @@ const Notifications = ({
|
||||
update,
|
||||
setShouldRefresh,
|
||||
}: NotificationsProps) => {
|
||||
const [notificationResponse, setNotificationResponse] = useState<NotificationResponseType>([]);
|
||||
const [notificationResponse, setNotificationResponse] =
|
||||
useState<ApiResponseType<NotificationResponseType>>();
|
||||
|
||||
const { data: notificationResponseData } = notificationResponse ?? {};
|
||||
|
||||
useEffect(() => {
|
||||
const intervalId = setInterval(async () => {
|
||||
const notifications = await loadNotifications(pageName, includeReindex);
|
||||
const { data: notificationsData } = notifications ?? {};
|
||||
|
||||
if (notifications.length === 0) {
|
||||
if (notificationsData?.length === 0) {
|
||||
setNotificationResponse(notifications);
|
||||
clearInterval(intervalId);
|
||||
setShouldRefresh?.(true);
|
||||
@@ -52,13 +47,13 @@ const Notifications = ({
|
||||
};
|
||||
}, [pageName, update, setShouldRefresh, includeReindex]);
|
||||
|
||||
if (notificationResponse.length === 0) {
|
||||
if (notificationResponseData?.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{notificationResponse.map(notification => (
|
||||
{notificationResponseData?.map(notification => (
|
||||
<div
|
||||
id={notification.id}
|
||||
className={`notification ${notification.level}`}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Fragment } from 'react';
|
||||
import humanFileSize from '../functions/humanFileSize';
|
||||
import StatsInfoBoxItem from './StatsInfoBoxItem';
|
||||
import formatNumbers from '../functions/formatNumbers';
|
||||
import { VideoStatsType } from '../pages/SettingsDashboard';
|
||||
import { VideoStatsType } from '../api/loader/loadStatsVideo';
|
||||
|
||||
type OverviewStatsProps = {
|
||||
videoStats?: VideoStatsType;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import updateVideoProgressById from '../api/actions/updateVideoProgressById';
|
||||
import { SponsorBlockSegmentType, SponsorBlockType, VideoResponseType } from '../pages/Video';
|
||||
import { SponsorBlockSegmentType, SponsorBlockType } from '../pages/Video';
|
||||
import {
|
||||
Dispatch,
|
||||
Fragment,
|
||||
@@ -13,6 +13,7 @@ import formatTime from '../functions/formatTime';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import getApiUrl from '../configuration/getApiUrl';
|
||||
import { useKeyPress } from '../functions/useKeypressHook';
|
||||
import { VideoResponseType } from '../api/loader/loadVideoById';
|
||||
|
||||
const VIDEO_PLAYBACK_SPEEDS = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3];
|
||||
|
||||
@@ -95,7 +96,9 @@ const handleTimeUpdate =
|
||||
currentProgress: currentTime,
|
||||
});
|
||||
|
||||
if (videoProgressResponse.watched && watched !== videoProgressResponse.watched) {
|
||||
const { data: videoProgressResponseData } = videoProgressResponse ?? {};
|
||||
|
||||
if (videoProgressResponseData?.watched && watched !== videoProgressResponseData.watched) {
|
||||
onWatchStateChanged?.(true);
|
||||
}
|
||||
}
|
||||
@@ -185,7 +188,9 @@ const VideoPlayer = ({
|
||||
currentProgress: currentTime,
|
||||
});
|
||||
|
||||
if (videoProgressResponse.watched && watched !== videoProgressResponse.watched) {
|
||||
const { data: videoProgressResponseData } = videoProgressResponse;
|
||||
|
||||
if (videoProgressResponseData?.watched && watched !== videoProgressResponseData.watched) {
|
||||
onWatchStateChanged?.(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Fragment } from 'react';
|
||||
import humanFileSize from '../functions/humanFileSize';
|
||||
import StatsInfoBoxItem from './StatsInfoBoxItem';
|
||||
import formatNumbers from '../functions/formatNumbers';
|
||||
import { VideoStatsType } from '../pages/SettingsDashboard';
|
||||
import { VideoStatsType } from '../api/loader/loadStatsVideo';
|
||||
|
||||
type VideoTypeStatsProps = {
|
||||
videoStats?: VideoStatsType;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Fragment } from 'react';
|
||||
import StatsInfoBoxItem from './StatsInfoBoxItem';
|
||||
import formatNumbers from '../functions/formatNumbers';
|
||||
import { WatchProgressStatsType } from '../pages/SettingsDashboard';
|
||||
import { WatchProgressStatsType } from '../api/loader/loadStatsWatchProgress';
|
||||
|
||||
const formatProgress = (progress: number) => {
|
||||
return (Number(progress) * 100).toFixed(2) ?? '0';
|
||||
|
||||
Reference in New Issue
Block a user