DRAFT: Add Tubearchivist Frontend React dev docker setup (#768)

* Add development docker-compose file

* Add /new/ path in nginx conf

* Add frontend production setup

* Fix lint

* Refac move prod docker compose into non suffixed file

* Fix run.sh fileendings on windows

* Fix docker file naming consistancies

* Add frontend dev setup

* Add docker compose dev command

* Refac remove docker network

* Fix potential error causes

* Chore update react-router-dom

* Add redirect to login after logout

* Refac allow basic auth for session login in api

* Fix loginresponsetype optional property

* Refac move isAdmin check into page Base

* Refac use node lts for dev container

* Refac remove old setup in readme

* Refac move getisAdmin into loader and rename

* Refac remove manual csrf cookie handing from actions and loader

* Fix post requiring csrf header & cookie

* Fix remove empty files

* Refac revert dockerfile changes

* Refac revert gitatrributes changes

* Refac revert docker changes

* Refac revert nginx changes

* Refac revert docker change

* Refac move frontend into frontend folder

* Add production steps to dockerfile

* Refac implement endpoint renaming

* Refac remove frontend dockerfile

* Add credentials include for dev env

* Fix allow cors with credentials for dev environment

* Fix images in dev mode

* Add credentials for dev mode to all loader and actions, except signin

* Revert cors config

* Revert cors config

* Fix nginx not serving /youtube/

* Fix video url missing api

* Fix media url missing api

* Add application settings page

* Add continue vids

* Add csrf to delete requests

* Refac use api/video endpoint with filter to home, channel, playlist pages

* Add channel nav request

* Add channel playlists

* Fix filterbar for playlist in channel

* Add playlist_nav to video page

* Add downloads aggs

* Refac remove basic auth

* Fix credentials include in signin

* Refac user config to user me config

* Add ApiToken get
This commit is contained in:
Merlin
2024-08-10 19:53:50 +02:00
committed by GitHub
parent 4dd7ac496a
commit 83bb7f678b
221 changed files with 16165 additions and 2 deletions

View File

@@ -0,0 +1,30 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import isDevEnvironment from '../../functions/isDevEnvironment';
const createCustomPlaylist = async (playlistId: string) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/playlist/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
body: JSON.stringify({ data: { create: playlistId } }),
});
const customPlaylist = await response.json();
if (isDevEnvironment()) {
console.log('createCustomPlaylist', customPlaylist);
}
return customPlaylist;
};
export default createCustomPlaylist;

View File

@@ -0,0 +1,28 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import isDevEnvironment from '../../functions/isDevEnvironment';
const deleteApiToken = async () => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/appsettings/token/`, {
method: 'DELETE',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
});
const resetToken = await response.json();
if (isDevEnvironment()) {
console.log('deleteApiToken', resetToken);
}
return resetToken;
};
export default deleteApiToken;

View File

@@ -0,0 +1,29 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import isDevEnvironment from '../../functions/isDevEnvironment';
const deleteChannel = async (channelId: string) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/channel/${channelId}/`, {
method: 'DELETE',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
});
const channelDeleted = await response.json();
if (isDevEnvironment()) {
console.log('deleteChannel', channelDeleted);
}
return channelDeleted;
};
export default deleteChannel;

View File

@@ -0,0 +1,29 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import isDevEnvironment from '../../functions/isDevEnvironment';
const deleteDownloadById = async (youtubeId: string) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/download/${youtubeId}/`, {
method: 'DELETE',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
});
const downloadState = await response.json();
if (isDevEnvironment()) {
console.log('deleteDownloadById', downloadState);
}
return downloadState;
};
export default deleteDownloadById;

View File

@@ -0,0 +1,37 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import isDevEnvironment from '../../functions/isDevEnvironment';
type FilterType = 'ignore' | 'pending';
const deleteDownloadQueueByFilter = async (filter: FilterType) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const searchParams = new URLSearchParams();
if (filter) {
searchParams.append('filter', filter);
}
const response = await fetch(`${apiUrl}/api/download/?${searchParams.toString()}`, {
method: 'DELETE',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
});
const downloadState = await response.json();
if (isDevEnvironment()) {
console.log('deleteDownloadQueueByFilter', downloadState);
}
return downloadState;
};
export default deleteDownloadQueueByFilter;

View File

@@ -0,0 +1,34 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import isDevEnvironment from '../../functions/isDevEnvironment';
const deletePlaylist = async (playlistId: string, allVideos = false) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
let params = '';
if (allVideos) {
params = '?delete-videos=true';
}
const response = await fetch(`${apiUrl}/api/playlist/${playlistId}/${params}`, {
method: 'DELETE',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
});
const playlistDeleted = await response.json();
if (isDevEnvironment()) {
console.log('deletePlaylist', playlistDeleted);
}
return playlistDeleted;
};
export default deletePlaylist;

View File

@@ -0,0 +1,29 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import isDevEnvironment from '../../functions/isDevEnvironment';
const deleteVideo = async (videoId: string) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/video/${videoId}/`, {
method: 'DELETE',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
});
const videoDeleted = await response.json();
if (isDevEnvironment()) {
console.log('deleteVideo', videoDeleted);
}
return videoDeleted;
};
export default deleteVideo;

View File

@@ -0,0 +1,29 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import isDevEnvironment from '../../functions/isDevEnvironment';
const deleteVideoProgressById = async (youtubeId: string) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/video/${youtubeId}/progress/`, {
method: 'DELETE',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
});
const watchedState = await response.json();
if (isDevEnvironment()) {
console.log('deleteVideoProgressById', watchedState);
}
return watchedState;
};
export default deleteVideoProgressById;

View File

@@ -0,0 +1,29 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import isDevEnvironment from '../../functions/isDevEnvironment';
const queueBackup = async () => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/appsettings/backup/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
});
const backupQueued = await response.json();
if (isDevEnvironment()) {
console.log('queueBackup', backupQueued);
}
return backupQueued;
};
export default queueBackup;

View File

@@ -0,0 +1,48 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import isDevEnvironment from '../../functions/isDevEnvironment';
export type ReindexType = 'channel' | 'video' | 'playlist';
export const ReindexTypeEnum = {
channel: 'channel',
video: 'video',
playlist: 'playlist',
};
const queueReindex = async (id: string, type: ReindexType, reindexVideos = false) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
let params = '';
if (reindexVideos) {
params = '?extract_videos=true';
}
const body = JSON.stringify({
[type]: id,
});
const response = await fetch(`${apiUrl}/api/refresh/${params}`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
body,
});
const channelDeleted = await response.json();
if (isDevEnvironment()) {
console.log('queueReindex', channelDeleted);
}
return channelDeleted;
};
export default queueReindex;

View File

@@ -0,0 +1,29 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import isDevEnvironment from '../../functions/isDevEnvironment';
const queueSnapshot = async () => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/appsettings/snapshot/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
});
const snapshotQueued = await response.json();
if (isDevEnvironment()) {
console.log('queueSnapshot', snapshotQueued);
}
return snapshotQueued;
};
export default queueSnapshot;

View File

@@ -0,0 +1,29 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import isDevEnvironment from '../../functions/isDevEnvironment';
const restoreBackup = async (fileName: string) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/appsettings/backup/${fileName}/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
});
const backupRestored = await response.json();
if (isDevEnvironment()) {
console.log('restoreBackup', backupRestored);
}
return backupRestored;
};
export default restoreBackup;

View File

@@ -0,0 +1,29 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import isDevEnvironment from '../../functions/isDevEnvironment';
const restoreSnapshot = async (snapshotId: string) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/appsettings/snapshot/${snapshotId}/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
});
const backupRestored = await response.json();
if (isDevEnvironment()) {
console.log('restoreSnapshot', backupRestored);
}
return backupRestored;
};
export default restoreSnapshot;

View File

@@ -0,0 +1,39 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
export type LoginResponseType = {
token?: string;
user_id: number;
is_superuser: boolean;
is_staff: boolean;
user_groups: [];
};
const signIn = async (username: string, password: string, saveLogin: boolean) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/user/login/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
body: JSON.stringify({
username,
password,
remember_me: saveLogin ? 'on' : 'off',
}),
});
if (response.status === 403) {
console.log('Might be already logged in.', await response.json());
}
return response;
};
export default signIn;

View File

@@ -0,0 +1,27 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
const stopTaskByName = async (taskId: string) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/task/by-id/${taskId}/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
body: JSON.stringify({ command: 'stop' }),
});
const downloadQueueState = await response.json();
console.log('stopTaskByName', downloadQueueState);
return downloadQueueState;
};
export default stopTaskByName;

View File

@@ -0,0 +1,27 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import { AppSettingsConfigType } from '../loader/loadAppsettingsConfig';
const updateAppsettingsConfig = async (config: AppSettingsConfigType) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/appsettings/config/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
body: JSON.stringify(config),
});
const appSettingsConfig = await response.json();
console.log('updateAppsettingsConfig', appSettingsConfig);
return appSettingsConfig;
};
export default updateAppsettingsConfig;

View File

@@ -0,0 +1,29 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
const updateChannelSubscription = async (channelId: string, status: boolean) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/channel/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
body: JSON.stringify({
data: [{ channel_id: channelId, channel_subscribed: status }],
}),
});
const channelSubscription = await response.json();
console.log('updateChannelSubscription', channelSubscription);
return channelSubscription;
};
export default updateChannelSubscription;

View File

@@ -0,0 +1,32 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
export type ValidatedCookieType = {
cookie_enabled: boolean;
status: boolean;
validated: number;
validated_str: string;
};
const updateCookie = async (): Promise<ValidatedCookieType> => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/appsettings/cookie/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
});
const validatedCookie = await response.json();
console.log('updateCookie', validatedCookie);
return validatedCookie;
};
export default updateCookie;

View File

@@ -0,0 +1,33 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
type CustomPlaylistActionType = 'create' | 'up' | 'down' | 'top' | 'bottom' | 'remove';
const updateCustomPlaylist = async (
action: CustomPlaylistActionType,
playlistId: string,
videoId: string,
) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/playlist/${playlistId}/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
body: JSON.stringify({ action, video_id: videoId }),
});
const customPlaylist = await response.json();
console.log('updateCustomPlaylist', action, customPlaylist);
return customPlaylist;
};
export default updateCustomPlaylist;

View File

@@ -0,0 +1,34 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
const updateDownloadQueue = async (download: string, autostart: boolean) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
let params = '';
if (autostart) {
params = '?autostart=true';
}
const response = await fetch(`${apiUrl}/api/download/${params}`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
body: JSON.stringify({
data: [{ youtube_id: download, status: 'pending' }],
}),
});
const downloadState = await response.json();
console.log('updateDownloadQueue', downloadState);
return downloadState;
};
export default updateDownloadQueue;

View File

@@ -0,0 +1,31 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
export type DownloadQueueStatus = 'ignore' | 'pending' | 'priority';
const updateDownloadQueueStatusById = async (youtubeId: string, status: DownloadQueueStatus) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/download/${youtubeId}/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
body: JSON.stringify({
status,
}),
});
const downloadQueueState = await response.json();
console.log('updateDownloadQueueStatusById', downloadQueueState);
return downloadQueueState;
};
export default updateDownloadQueueStatusById;

View File

@@ -0,0 +1,29 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
const updatePlaylistSubscription = async (playlistId: string, status: boolean) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/playlist/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
body: JSON.stringify({
data: [{ playlist_id: playlistId, playlist_subscribed: status }],
}),
});
const playlistSubscription = await response.json();
console.log('updatePlaylistSubscription', playlistSubscription);
return playlistSubscription;
};
export default updatePlaylistSubscription;

View File

@@ -0,0 +1,32 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
type TaskNamesType =
| 'download_pending'
| 'update_subscribed'
| 'manual_import'
| 'resync_thumbs'
| 'rescan_filesystem';
const updateTaskByName = async (taskName: TaskNamesType) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/task/by-name/${taskName}/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
});
const downloadQueueState = await response.json();
console.log('updateTaskByName', downloadQueueState);
return downloadQueueState;
};
export default updateTaskByName;

View File

@@ -0,0 +1,56 @@
import { ColourVariants } from '../../configuration/colours/getColours';
import { SortByType, SortOrderType, ViewLayoutType } from '../../pages/Home';
import getApiUrl from '../../configuration/getApiUrl';
import defaultHeaders from '../../configuration/defaultHeaders';
import getCookie from '../../functions/getCookie';
import getFetchCredentials from '../../configuration/getFetchCredentials';
export type UserMeType = {
id: number;
name: string;
is_superuser: boolean;
is_staff: boolean;
groups: [];
user_permissions: [];
last_login: string;
config: UserConfigType;
};
export type UserConfigType = {
stylesheet?: ColourVariants;
page_size?: number;
sort_by?: SortByType;
sort_order?: SortOrderType;
view_style_home?: ViewLayoutType;
view_style_channel?: ViewLayoutType;
view_style_downloads?: ViewLayoutType;
view_style_playlist?: ViewLayoutType;
grid_items?: number;
hide_watched?: boolean;
show_ignored_only?: boolean;
show_subed_only?: boolean;
sponsorblock_id?: number;
};
const updateUserConfig = async (config: UserConfigType): Promise<UserMeType> => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/user/me/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
body: JSON.stringify({ config }),
});
const userConfig = await response.json();
console.log('updateUserConfig', userConfig);
return userConfig;
};
export default updateUserConfig;

View File

@@ -0,0 +1,34 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
type VideoProgressProp = {
youtubeId: string;
currentProgress: number;
};
const updateVideoProgressById = async ({ youtubeId, currentProgress }: VideoProgressProp) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/video/${youtubeId}/progress/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
body: JSON.stringify({
position: currentProgress,
}),
});
const userConfig = await response.json();
console.log('updateVideoProgressById', userConfig);
return userConfig;
};
export default updateVideoProgressById;

View File

@@ -0,0 +1,37 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import deleteVideoProgressById from './deleteVideoProgressById';
export type Watched = {
id: string;
is_watched: boolean;
};
const updateWatchedState = async (watched: Watched) => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
if (watched.is_watched) {
await deleteVideoProgressById(watched.id);
}
const response = await fetch(`${apiUrl}/api/watched/`, {
method: 'POST',
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
body: JSON.stringify(watched),
});
const watchedState = await response.json();
console.log('updateWatchedState', watchedState);
return watchedState;
};
export default updateWatchedState;

View File

@@ -0,0 +1,32 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
import isDevEnvironment from '../../functions/isDevEnvironment';
type ApiTokenResponse = {
token: string;
};
const loadApiToken = async (): Promise<ApiTokenResponse> => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/appsettings/token/`, {
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
});
const apiToken = await response.json();
if (isDevEnvironment()) {
console.log('loadApiToken', apiToken);
}
return apiToken;
};
export default loadApiToken;

View File

@@ -0,0 +1,54 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
export type AppSettingsConfigType = {
subscriptions: {
channel_size: number;
live_channel_size: number;
shorts_channel_size: number;
auto_start: boolean;
};
downloads: {
limit_speed: boolean | number;
sleep_interval: number;
autodelete_days: boolean | number;
format: boolean | string;
format_sort: boolean | string;
add_metadata: boolean;
add_thumbnail: boolean;
subtitle: boolean | string;
subtitle_source: boolean | string;
subtitle_index: boolean;
comment_max: boolean | number;
comment_sort: string;
cookie_import: boolean;
throttledratelimit: boolean | number;
extractor_lang: boolean | string;
integrate_ryd: boolean;
integrate_sponsorblock: boolean;
};
application: {
enable_snapshot: boolean;
};
};
const loadAppsettingsConfig = async (): Promise<AppSettingsConfigType> => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/appsettings/config/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const appSettingsConfig = await response.json();
if (isDevEnvironment()) {
console.log('loadApplicationConfig', appSettingsConfig);
}
return appSettingsConfig;
};
export default loadAppsettingsConfig;

View File

@@ -0,0 +1,21 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import getCookie from '../../functions/getCookie';
const loadAuth = async () => {
const apiUrl = getApiUrl();
const csrfCookie = getCookie('csrftoken');
const response = await fetch(`${apiUrl}/api/ping/`, {
headers: {
...defaultHeaders,
'X-CSRFToken': csrfCookie || '',
},
credentials: getFetchCredentials(),
});
return response;
};
export default loadAuth;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadBackupList = async () => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/appsettings/backup/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const backupList = await response.json();
if (isDevEnvironment()) {
console.log('loadBackupList', backupList);
}
return backupList;
};
export default loadBackupList;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadChannelById = async (youtubeChannelId: string) => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/channel/${youtubeChannelId}/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const channel = await response.json();
if (isDevEnvironment()) {
console.log('loadChannelById', channel);
}
return channel;
};
export default loadChannelById;

View File

@@ -0,0 +1,33 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadChannelList = async (page: number, showSubscribed: boolean) => {
const apiUrl = getApiUrl();
const searchParams = new URLSearchParams();
if (page) {
searchParams.append('page', page.toString());
}
if (showSubscribed) {
searchParams.append('filter', 'subscribed');
}
const response = await fetch(`${apiUrl}/api/channel/?${searchParams.toString()}`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const channels = await response.json();
if (isDevEnvironment()) {
console.log('loadChannelList', channels);
}
return channels;
};
export default loadChannelList;

View File

@@ -0,0 +1,30 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
export type ChannelNavResponseType = {
has_streams: boolean;
has_shorts: boolean;
has_playlists: boolean;
has_pending: boolean;
};
const loadChannelNav = async (youtubeChannelId: string): Promise<ChannelNavResponseType> => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/channel/${youtubeChannelId}/nav/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const channel = await response.json();
if (isDevEnvironment()) {
console.log('loadChannelNav', channel);
}
return channel;
};
export default loadChannelNav;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadCommentsbyVideoId = async (youtubeId: string) => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/video/${youtubeId}/comment/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const comments = await response.json();
if (isDevEnvironment()) {
console.log('loadCommentsbyVideoId', comments);
}
return comments;
};
export default loadCommentsbyVideoId;

View File

@@ -0,0 +1,37 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
type DownloadAggsBucket = {
key: string[];
key_as_string: string;
doc_count: number;
};
export type DownloadAggsType = {
channel_downloads: {
doc_count_error_upper_bound: number;
sum_other_doc_count: number;
buckets: DownloadAggsBucket[];
};
};
const loadDownloadAggs = async (): Promise<DownloadAggsType> => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/download/aggs/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const downloadAggs = await response.json();
if (isDevEnvironment()) {
console.log('loadDownloadAggs', downloadAggs);
}
return downloadAggs;
};
export default loadDownloadAggs;

View File

@@ -0,0 +1,35 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadDownloadQueue = async (page: number, channelId: string | null, showIgnored: boolean) => {
const apiUrl = getApiUrl();
const searchParams = new URLSearchParams();
if (page) {
searchParams.append('page', page.toString());
}
if (channelId) {
searchParams.append('channel', channelId);
}
searchParams.append('filter', showIgnored ? 'ignore' : 'pending');
const response = await fetch(`${apiUrl}/api/download/?${searchParams.toString()}`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const playlist = await response.json();
if (isDevEnvironment()) {
console.log('loadDownloadQueue', playlist);
}
return playlist;
};
export default loadDownloadQueue;

View File

@@ -0,0 +1,30 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
export type NotificationPages = 'download' | 'settings' | 'channel' | 'all';
const loadNotifications = async (pageName: NotificationPages, includeReindex = false) => {
const apiUrl = getApiUrl();
let params = '';
if (!includeReindex && pageName !== 'all') {
params = `?filter=${pageName}`;
}
const response = await fetch(`${apiUrl}/api/notification/${params}`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const notifications = await response.json();
if (isDevEnvironment()) {
console.log('loadNotifications', notifications);
}
return notifications;
};
export default loadNotifications;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadPlaylistById = async (playlistId: string | undefined) => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/playlist/${playlistId}/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const videos = await response.json();
if (isDevEnvironment()) {
console.log('loadPlaylistById', videos);
}
return videos;
};
export default loadPlaylistById;

View File

@@ -0,0 +1,50 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
type PlaylistType = 'regular' | 'custom';
type LoadPlaylistListProps = {
channel?: string;
page?: number | undefined;
subscribed?: boolean;
type?: PlaylistType;
};
const loadPlaylistList = async ({ channel, page, subscribed, type }: LoadPlaylistListProps) => {
const apiUrl = getApiUrl();
const searchParams = new URLSearchParams();
if (channel) {
searchParams.append('channel', channel);
}
if (page) {
searchParams.append('page', page.toString());
}
if (subscribed) {
searchParams.append('subscribed', subscribed.toString());
}
if (type) {
searchParams.append('type', type);
}
const response = await fetch(`${apiUrl}/api/playlist/?${searchParams.toString()}`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const playlist = await response.json();
if (isDevEnvironment()) {
console.log('loadPlaylistList', playlist);
}
return playlist;
};
export default loadPlaylistList;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadSearch = async (query: string) => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/search/?query=${query}`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const searchResults = await response.json();
if (isDevEnvironment()) {
console.log('loadSearch', searchResults);
}
return searchResults;
};
export default loadSearch;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadSimmilarVideosById = async (youtubeId: string) => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/video/${youtubeId}/similar/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const videos = await response.json();
if (isDevEnvironment()) {
console.log('loadSimmilarVideosById', videos);
}
return videos;
};
export default loadSimmilarVideosById;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadSnapshots = async () => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/appsettings/snapshot/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const backupList = await response.json();
if (isDevEnvironment()) {
console.log('loadSnapshots', backupList);
}
return backupList;
};
export default loadSnapshots;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadSponsorblockByVideoId = async (youtubeId: string) => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/video/${youtubeId}/sponsor/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const videos = await response.json();
if (isDevEnvironment()) {
console.log('loadSponsorblockByVideoId', videos);
}
return videos;
};
export default loadSponsorblockByVideoId;

View File

@@ -0,0 +1,28 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
type BiggestChannelsOrderType = 'doc_count' | 'duration' | 'media_size';
const loadStatsBiggestChannels = async (order: BiggestChannelsOrderType) => {
const apiUrl = getApiUrl();
const searchParams = new URLSearchParams();
searchParams.append('order', order);
const response = await fetch(`${apiUrl}/api/stats/biggestchannels/?${searchParams.toString()}`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const notifications = await response.json();
if (isDevEnvironment()) {
console.log('loadStatsBiggestChannels', notifications);
}
return notifications;
};
export default loadStatsBiggestChannels;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadStatsChannel = async () => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/stats/channel/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const notifications = await response.json();
if (isDevEnvironment()) {
console.log('loadStatsChannel', notifications);
}
return notifications;
};
export default loadStatsChannel;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadStatsDownload = async () => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/stats/download/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const notifications = await response.json();
if (isDevEnvironment()) {
console.log('loadStatsDownload', notifications);
}
return notifications;
};
export default loadStatsDownload;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadStatsDownloadHistory = async () => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/stats/downloadhist/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const notifications = await response.json();
if (isDevEnvironment()) {
console.log('loadStatsDownloadHistory', notifications);
}
return notifications;
};
export default loadStatsDownloadHistory;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadStatsPlaylist = async () => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/stats/playlist/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const notifications = await response.json();
if (isDevEnvironment()) {
console.log('loadStatsPlaylist', notifications);
}
return notifications;
};
export default loadStatsPlaylist;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadStatsVideo = async () => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/stats/video/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const notifications = await response.json();
if (isDevEnvironment()) {
console.log('loadStatsVideo', notifications);
}
return notifications;
};
export default loadStatsVideo;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadStatsWatchProgress = async () => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/stats/watch/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const notifications = await response.json();
if (isDevEnvironment()) {
console.log('loadStatsWatchProgress', notifications);
}
return notifications;
};
export default loadStatsWatchProgress;

View File

@@ -0,0 +1,24 @@
import { UserMeType } from '../actions/updateUserConfig';
import isDevEnvironment from '../../functions/isDevEnvironment';
import getApiUrl from '../../configuration/getApiUrl';
import defaultHeaders from '../../configuration/defaultHeaders';
import getFetchCredentials from '../../configuration/getFetchCredentials';
const loadUserMeConfig = async (): Promise<UserMeType> => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/user/me/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const userConfig = await response.json();
if (isDevEnvironment()) {
console.log('loadUserMeConfig', userConfig);
}
return userConfig;
};
export default loadUserMeConfig;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadVideoById = async (youtubeId: string) => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/video/${youtubeId}/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const videos = await response.json();
if (isDevEnvironment()) {
console.log('loadVideoById', videos);
}
return videos;
};
export default loadVideoById;

View File

@@ -0,0 +1,65 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
import { SortByType, SortOrderType } from '../../pages/Home';
type WatchTypes = 'watched' | 'unwatched' | 'continue';
type VideoTypes = 'videos' | 'streams' | 'shorts';
type FilterType = {
page?: number;
playlist?: string;
channel?: string;
watch?: WatchTypes;
sort?: SortByType;
order?: SortOrderType;
type?: VideoTypes;
};
const loadVideoListByFilter = async (filter: FilterType) => {
const apiUrl = getApiUrl();
const searchParams = new URLSearchParams();
if (filter.page) {
searchParams.append('page', filter.page.toString());
}
if (filter.playlist) {
searchParams.append('playlist', filter.playlist);
} else if (filter.channel) {
searchParams.append('channel', filter.channel);
}
if (filter.watch) {
searchParams.append('watch', filter.watch);
}
if (filter.sort) {
searchParams.append('sort', filter.sort);
}
if (filter.order) {
searchParams.append('order', filter.order);
}
if (filter.type) {
searchParams.append('type', filter.type);
}
const response = await fetch(`${apiUrl}/api/video/?${searchParams.toString()}`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const videos = await response.json();
if (isDevEnvironment()) {
console.log('loadVideoListByFilter', filter, videos);
}
return videos;
};
export default loadVideoListByFilter;

View File

@@ -0,0 +1,48 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
export type VideoNavResponseType = {
playlist_meta: {
current_idx: number;
playlist_id: string;
playlist_name: string;
playlist_channel: string;
};
playlist_previous: {
youtube_id: string;
title: string;
uploader: string;
idx: number;
downloaded: boolean;
vid_thumb: string;
};
playlist_next: {
youtube_id: string;
title: string;
uploader: string;
idx: number;
downloaded: boolean;
vid_thumb: string;
};
};
const loadVideoNav = async (youtubeVideoId: string): Promise<VideoNavResponseType[]> => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/video/${youtubeVideoId}/nav/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const videoNav = await response.json();
if (isDevEnvironment()) {
console.log('loadVideoNav', videoNav);
}
return videoNav;
};
export default loadVideoNav;

View File

@@ -0,0 +1,23 @@
import defaultHeaders from '../../configuration/defaultHeaders';
import getApiUrl from '../../configuration/getApiUrl';
import getFetchCredentials from '../../configuration/getFetchCredentials';
import isDevEnvironment from '../../functions/isDevEnvironment';
const loadVideoProgressById = async (youtubeId: string) => {
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/api/video/${youtubeId}/progress/`, {
headers: defaultHeaders,
credentials: getFetchCredentials(),
});
const videoProgress = await response.json();
if (isDevEnvironment()) {
console.log('loadVideoProgressById', videoProgress);
}
return videoProgress;
};
export default loadVideoProgressById;