mirror of
https://github.com/tubearchivist/tubearchivist.git
synced 2025-06-03 00:51:10 +00:00
Revert "Add Video details page to settings"
This reverts commit 776481c513e9e50e4cf45f76e5060308c9139f2e.
This commit is contained in:
parent
776481c513
commit
25b6ca2a1a
@ -31,8 +31,6 @@ class SortEnum(enum.Enum):
|
|||||||
LIKES = "stats.like_count"
|
LIKES = "stats.like_count"
|
||||||
DURATION = "player.duration"
|
DURATION = "player.duration"
|
||||||
MEDIASIZE = "media_size"
|
MEDIASIZE = "media_size"
|
||||||
WIDTH = "streams.width"
|
|
||||||
HEIGHT = "streams.height"
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def values(cls) -> list[str]:
|
def values(cls) -> list[str]:
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { ViewLayoutType } from '../../pages/Home';
|
import { SortByType, SortOrderType, ViewLayoutType } from '../../pages/Home';
|
||||||
import APIClient from '../../functions/APIClient';
|
import APIClient from '../../functions/APIClient';
|
||||||
import { SortByType, SortOrderType } from '../loader/loadVideoListByPage';
|
|
||||||
|
|
||||||
export type ColourVariants =
|
export type ColourVariants =
|
||||||
| 'dark.css'
|
| 'dark.css'
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ConfigType, VideoType } from '../../pages/Home';
|
import { ConfigType, SortByType, SortOrderType, VideoType } from '../../pages/Home';
|
||||||
import { PaginationType } from '../../components/Pagination';
|
import { PaginationType } from '../../components/Pagination';
|
||||||
import APIClient from '../../functions/APIClient';
|
import APIClient from '../../functions/APIClient';
|
||||||
|
|
||||||
@ -8,45 +8,9 @@ export type VideoListByFilterResponseType = {
|
|||||||
paginate?: PaginationType;
|
paginate?: PaginationType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SortByType =
|
type WatchTypes = 'watched' | 'unwatched' | 'continue';
|
||||||
| 'published'
|
|
||||||
| 'downloaded'
|
|
||||||
| 'views'
|
|
||||||
| 'likes'
|
|
||||||
| 'duration'
|
|
||||||
| 'mediasize'
|
|
||||||
| 'width'
|
|
||||||
| 'height';
|
|
||||||
export const SortByEnum = {
|
|
||||||
Published: 'published',
|
|
||||||
Downloaded: 'downloaded',
|
|
||||||
Views: 'views',
|
|
||||||
Likes: 'likes',
|
|
||||||
Duration: 'duration',
|
|
||||||
'Media Size': 'mediasize',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SortByExpandedEnum = {
|
|
||||||
...SortByEnum,
|
|
||||||
Width: 'width',
|
|
||||||
Height: 'height',
|
|
||||||
};
|
|
||||||
|
|
||||||
export type SortOrderType = 'asc' | 'desc';
|
|
||||||
export const SortOrderEnum = {
|
|
||||||
Asc: 'asc',
|
|
||||||
Desc: 'desc',
|
|
||||||
};
|
|
||||||
|
|
||||||
export type VideoTypes = 'videos' | 'streams' | 'shorts';
|
export type VideoTypes = 'videos' | 'streams' | 'shorts';
|
||||||
|
|
||||||
export type WatchTypes = 'watched' | 'unwatched' | 'continue';
|
|
||||||
export const WatchTypesEnum = {
|
|
||||||
Watched: 'watched',
|
|
||||||
Unwatched: 'unwatched',
|
|
||||||
Continue: 'continue',
|
|
||||||
};
|
|
||||||
|
|
||||||
type FilterType = {
|
type FilterType = {
|
||||||
page?: number;
|
page?: number;
|
||||||
playlist?: string;
|
playlist?: string;
|
||||||
|
@ -4,15 +4,10 @@ import iconAdd from '/img/icon-add.svg';
|
|||||||
import iconSubstract from '/img/icon-substract.svg';
|
import iconSubstract from '/img/icon-substract.svg';
|
||||||
import iconGridView from '/img/icon-gridview.svg';
|
import iconGridView from '/img/icon-gridview.svg';
|
||||||
import iconListView from '/img/icon-listview.svg';
|
import iconListView from '/img/icon-listview.svg';
|
||||||
|
import { SortByType, SortOrderType } from '../pages/Home';
|
||||||
import { useUserConfigStore } from '../stores/UserConfigStore';
|
import { useUserConfigStore } from '../stores/UserConfigStore';
|
||||||
import { ViewStyles } from '../configuration/constants/ViewStyle';
|
import { ViewStyles } from '../configuration/constants/ViewStyle';
|
||||||
import updateUserConfig, { UserConfigType } from '../api/actions/updateUserConfig';
|
import updateUserConfig, { UserConfigType } from '../api/actions/updateUserConfig';
|
||||||
import {
|
|
||||||
SortByEnum,
|
|
||||||
SortByType,
|
|
||||||
SortOrderEnum,
|
|
||||||
SortOrderType,
|
|
||||||
} from '../api/loader/loadVideoListByPage';
|
|
||||||
|
|
||||||
type FilterbarProps = {
|
type FilterbarProps = {
|
||||||
hideToggleText: string;
|
hideToggleText: string;
|
||||||
@ -72,9 +67,12 @@ const Filterbar = ({ hideToggleText, viewStyleName, showSort = true }: Filterbar
|
|||||||
handleUserConfigUpdate({ sort_by: event.target.value as SortByType });
|
handleUserConfigUpdate({ sort_by: event.target.value as SortByType });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{Object.entries(SortByEnum).map(([key, value]) => {
|
<option value="published">date published</option>
|
||||||
return <option value={value}>{key}</option>;
|
<option value="downloaded">date downloaded</option>
|
||||||
})}
|
<option value="views">views</option>
|
||||||
|
<option value="likes">likes</option>
|
||||||
|
<option value="duration">duration</option>
|
||||||
|
<option value="mediasize">media size</option>
|
||||||
</select>
|
</select>
|
||||||
<select
|
<select
|
||||||
name="sort_order"
|
name="sort_order"
|
||||||
@ -84,9 +82,8 @@ const Filterbar = ({ hideToggleText, viewStyleName, showSort = true }: Filterbar
|
|||||||
handleUserConfigUpdate({ sort_order: event.target.value as SortOrderType });
|
handleUserConfigUpdate({ sort_order: event.target.value as SortOrderType });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{Object.entries(SortOrderEnum).map(([key, value]) => {
|
<option value="asc">asc</option>
|
||||||
return <option value={value}>{key}</option>;
|
<option value="desc">desc</option>
|
||||||
})}
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -26,9 +26,6 @@ const SettingsNavigation = () => {
|
|||||||
<Link to={Routes.SettingsActions}>
|
<Link to={Routes.SettingsActions}>
|
||||||
<h3>Actions</h3>
|
<h3>Actions</h3>
|
||||||
</Link>
|
</Link>
|
||||||
<Link to={Routes.SettingsVideos}>
|
|
||||||
<h3>Videos</h3>
|
|
||||||
</Link>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
import { SortOrderType } from '../api/loader/loadVideoListByPage';
|
|
||||||
|
|
||||||
const ARROW_UP = '↑';
|
|
||||||
const ARROW_DOWN = '↓';
|
|
||||||
|
|
||||||
type SortArrowProps = {
|
|
||||||
visible: boolean;
|
|
||||||
sortOrder: SortOrderType;
|
|
||||||
};
|
|
||||||
|
|
||||||
const SortArrow = ({ visible, sortOrder }: SortArrowProps) => {
|
|
||||||
if (!visible) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sortOrder === 'asc') {
|
|
||||||
return ARROW_UP;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ARROW_DOWN;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SortArrow;
|
|
@ -17,7 +17,6 @@ const Routes = {
|
|||||||
SettingsApplication: '/settings/application/',
|
SettingsApplication: '/settings/application/',
|
||||||
SettingsScheduling: '/settings/scheduling/',
|
SettingsScheduling: '/settings/scheduling/',
|
||||||
SettingsActions: '/settings/actions/',
|
SettingsActions: '/settings/actions/',
|
||||||
SettingsVideos: '/settings/videos/',
|
|
||||||
Login: '/login/',
|
Login: '/login/',
|
||||||
Video: (id: string) => `/video/${id}`,
|
Video: (id: string) => `/video/${id}`,
|
||||||
VideoAtTimestamp: (id: string, timestamp: string) => `/video/${id}/?t=${timestamp}`,
|
VideoAtTimestamp: (id: string, timestamp: string) => `/video/${id}/?t=${timestamp}`,
|
||||||
|
@ -28,7 +28,6 @@ import Download from './pages/Download';
|
|||||||
import loadUserAccount from './api/loader/loadUserAccount';
|
import loadUserAccount from './api/loader/loadUserAccount';
|
||||||
import loadAppsettingsConfig from './api/loader/loadAppsettingsConfig';
|
import loadAppsettingsConfig from './api/loader/loadAppsettingsConfig';
|
||||||
import NotFound from './pages/NotFound';
|
import NotFound from './pages/NotFound';
|
||||||
import SettingsVideos from './pages/SettingsVideos';
|
|
||||||
|
|
||||||
const router = createBrowserRouter(
|
const router = createBrowserRouter(
|
||||||
[
|
[
|
||||||
@ -136,10 +135,6 @@ const router = createBrowserRouter(
|
|||||||
path: Routes.SettingsUser,
|
path: Routes.SettingsUser,
|
||||||
element: <SettingsUser />,
|
element: <SettingsUser />,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: Routes.SettingsVideos,
|
|
||||||
element: <SettingsVideos />,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: Routes.About,
|
path: Routes.About,
|
||||||
element: <About />,
|
element: <About />,
|
||||||
|
@ -99,6 +99,8 @@ export type ConfigType = {
|
|||||||
downloads: DownloadsType;
|
downloads: DownloadsType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type SortByType = 'published' | 'downloaded' | 'views' | 'likes' | 'duration' | 'mediasize';
|
||||||
|
export type SortOrderType = 'asc' | 'desc';
|
||||||
export type ViewLayoutType = 'grid' | 'list';
|
export type ViewLayoutType = 'grid' | 'list';
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
|
@ -1,214 +0,0 @@
|
|||||||
import { useEffect, useState } from 'react';
|
|
||||||
import SettingsNavigation from '../components/SettingsNavigation';
|
|
||||||
import { ApiResponseType } from '../functions/APIClient';
|
|
||||||
import loadVideoListByFilter, {
|
|
||||||
SortByExpandedEnum,
|
|
||||||
SortByType,
|
|
||||||
SortOrderEnum,
|
|
||||||
SortOrderType,
|
|
||||||
VideoListByFilterResponseType,
|
|
||||||
WatchTypes,
|
|
||||||
WatchTypesEnum,
|
|
||||||
} from '../api/loader/loadVideoListByPage';
|
|
||||||
import { Link, useOutletContext } from 'react-router-dom';
|
|
||||||
import { OutletContextType } from './Base';
|
|
||||||
import Pagination from '../components/Pagination';
|
|
||||||
import humanFileSize from '../functions/humanFileSize';
|
|
||||||
import { useUserConfigStore } from '../stores/UserConfigStore';
|
|
||||||
import { FileSizeUnits } from '../api/actions/updateUserConfig';
|
|
||||||
import Routes from '../configuration/routes/RouteList';
|
|
||||||
import SortArrow from '../components/SortArrow';
|
|
||||||
|
|
||||||
const SettingsVideos = () => {
|
|
||||||
const { userConfig } = useUserConfigStore();
|
|
||||||
const { currentPage, setCurrentPage } = useOutletContext() as OutletContextType;
|
|
||||||
|
|
||||||
const [refreshVideoList, setRefreshVideoList] = useState(false);
|
|
||||||
const [watchedState, setWatchedState] = useState<WatchTypes>('unwatched');
|
|
||||||
const [sortBy, setSortBy] = useState<SortByType>('mediasize');
|
|
||||||
const [sortOrder, setSortOrder] = useState<SortOrderType>('desc');
|
|
||||||
|
|
||||||
const [videoResponse, setVideoReponse] =
|
|
||||||
useState<ApiResponseType<VideoListByFilterResponseType>>();
|
|
||||||
|
|
||||||
const { data: videoResponseData } = videoResponse ?? {};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
(async () => {
|
|
||||||
const videos = await loadVideoListByFilter({
|
|
||||||
page: currentPage,
|
|
||||||
watch: watchedState,
|
|
||||||
sort: sortBy,
|
|
||||||
order: sortOrder,
|
|
||||||
});
|
|
||||||
|
|
||||||
setVideoReponse(videos);
|
|
||||||
|
|
||||||
setRefreshVideoList(false);
|
|
||||||
})();
|
|
||||||
}, [refreshVideoList, currentPage, watchedState, sortBy, sortOrder]);
|
|
||||||
|
|
||||||
const videoList = videoResponseData?.data;
|
|
||||||
const pagination = videoResponseData?.paginate;
|
|
||||||
const hasVideos = videoResponseData?.data?.length !== 0;
|
|
||||||
|
|
||||||
const useSiUnits = userConfig.file_size_unit === FileSizeUnits.Metric;
|
|
||||||
|
|
||||||
const toggleSortOrder = () => {
|
|
||||||
if (sortOrder === 'asc') {
|
|
||||||
setSortOrder('desc');
|
|
||||||
} else {
|
|
||||||
setSortOrder('asc');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onHeaderClicked = (header: SortByType) => {
|
|
||||||
if (sortBy === header) {
|
|
||||||
toggleSortOrder();
|
|
||||||
} else {
|
|
||||||
setSortBy(header);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<title>TA | Videos</title>
|
|
||||||
<div className="boxed-content">
|
|
||||||
<SettingsNavigation />
|
|
||||||
|
|
||||||
<div className="title-bar">
|
|
||||||
<h1>Video details</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="settings-group video-details">
|
|
||||||
<p>
|
|
||||||
Show watched:{' '}
|
|
||||||
<select
|
|
||||||
id="id_watchedstate"
|
|
||||||
value={watchedState}
|
|
||||||
onChange={event => {
|
|
||||||
setWatchedState(event.currentTarget.value as WatchTypes);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Object.entries(WatchTypesEnum).map(([key, value]) => {
|
|
||||||
return (
|
|
||||||
<option key={key} value={value}>
|
|
||||||
{key}
|
|
||||||
</option>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</select>
|
|
||||||
<br />
|
|
||||||
Sort by:
|
|
||||||
<select
|
|
||||||
name="sort_by"
|
|
||||||
id="sort"
|
|
||||||
value={sortBy}
|
|
||||||
onChange={event => {
|
|
||||||
setSortBy(event.currentTarget.value as SortByType);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Object.entries(SortByExpandedEnum).map(([key, value]) => {
|
|
||||||
return <option value={value}>{key}</option>;
|
|
||||||
})}
|
|
||||||
</select>
|
|
||||||
<select
|
|
||||||
name="sort_order"
|
|
||||||
id="sort-order"
|
|
||||||
value={sortOrder}
|
|
||||||
onChange={event => {
|
|
||||||
setSortOrder(event.currentTarget.value as SortOrderType);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Object.entries(SortOrderEnum).map(([key, value]) => {
|
|
||||||
return <option value={value}>{key}</option>;
|
|
||||||
})}
|
|
||||||
</select>
|
|
||||||
</p>
|
|
||||||
{!hasVideos && <p>No videos found</p>}
|
|
||||||
|
|
||||||
{hasVideos && (
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
{videoList?.map(({ youtube_id, title, channel, vid_type, media_size, streams }) => {
|
|
||||||
const [videoStream, audioStream] = streams;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<tr key={youtube_id}>
|
|
||||||
<td>
|
|
||||||
<Link to={Routes.Channel(channel.channel_id)}>{channel.channel_name}</Link>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<Link to={Routes.Video(youtube_id)}>{title}</Link>
|
|
||||||
</td>
|
|
||||||
<td>{vid_type}</td>
|
|
||||||
<td>{videoStream.width}</td>
|
|
||||||
<td>{videoStream.height}</td>
|
|
||||||
<td>{humanFileSize(media_size, useSiUnits)}</td>
|
|
||||||
<td>{videoStream.codec}</td>
|
|
||||||
<td>{humanFileSize(videoStream.bitrate, useSiUnits)}</td>
|
|
||||||
<td>{audioStream.codec}</td>
|
|
||||||
<td>{humanFileSize(audioStream.bitrate, useSiUnits)}</td>
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</tbody>
|
|
||||||
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Channel name</th>
|
|
||||||
<th>Video title</th>
|
|
||||||
<th>Type</th>
|
|
||||||
<th>
|
|
||||||
<a
|
|
||||||
onClick={() => {
|
|
||||||
onHeaderClicked('width');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<SortArrow visible={sortBy === 'width'} sortOrder={sortOrder} />
|
|
||||||
Width
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a
|
|
||||||
onClick={() => {
|
|
||||||
onHeaderClicked('height');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<SortArrow visible={sortBy === 'height'} sortOrder={sortOrder} />
|
|
||||||
Height
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<a
|
|
||||||
onClick={() => {
|
|
||||||
onHeaderClicked('mediasize');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<SortArrow visible={sortBy === 'mediasize'} sortOrder={sortOrder} />
|
|
||||||
Media size
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>Video codec</th>
|
|
||||||
<th>Video bitrate</th>
|
|
||||||
<th>Audio codec</th>
|
|
||||||
<th>Audio bitrate</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
</table>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{pagination && (
|
|
||||||
<div className="boxed-content">
|
|
||||||
<Pagination pagination={pagination} setPage={setCurrentPage} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SettingsVideos;
|
|
@ -133,11 +133,6 @@ button:hover {
|
|||||||
color: var(--main-bg);
|
color: var(--main-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-details table td,
|
|
||||||
.video-details table th {
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-box {
|
.button-box {
|
||||||
padding: 5px 2px;
|
padding: 5px 2px;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user