mirror of
https://git.vectorsigma.ru/public/tubearchivist.git
synced 2026-08-04 22:59:39 +00:00
Refac use file_size_unit from user config in frontend #886
This commit is contained in:
@@ -3,6 +3,11 @@ import APIClient from '../../functions/APIClient';
|
|||||||
|
|
||||||
export type ColourVariants = 'dark.css' | 'light.css' | 'matrix.css' | 'midnight.css';
|
export type ColourVariants = 'dark.css' | 'light.css' | 'matrix.css' | 'midnight.css';
|
||||||
|
|
||||||
|
export const FileSizeUnits = {
|
||||||
|
Binary: 'binary',
|
||||||
|
Metric: 'metric',
|
||||||
|
};
|
||||||
|
|
||||||
export type UserConfigType = {
|
export type UserConfigType = {
|
||||||
stylesheet: ColourVariants;
|
stylesheet: ColourVariants;
|
||||||
page_size: number;
|
page_size: number;
|
||||||
@@ -14,6 +19,7 @@ export type UserConfigType = {
|
|||||||
view_style_playlist: ViewLayoutType;
|
view_style_playlist: ViewLayoutType;
|
||||||
grid_items: number;
|
grid_items: number;
|
||||||
hide_watched: boolean;
|
hide_watched: boolean;
|
||||||
|
file_size_unit: 'binary' | 'metric';
|
||||||
show_ignored_only: boolean;
|
show_ignored_only: boolean;
|
||||||
show_subed_only: boolean;
|
show_subed_only: boolean;
|
||||||
show_help_text: boolean;
|
show_help_text: boolean;
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ type BiggestChannelsStatsProps = {
|
|||||||
biggestChannelsStatsByCount?: BiggestChannelsStatsType;
|
biggestChannelsStatsByCount?: BiggestChannelsStatsType;
|
||||||
biggestChannelsStatsByDuration?: BiggestChannelsStatsType;
|
biggestChannelsStatsByDuration?: BiggestChannelsStatsType;
|
||||||
biggestChannelsStatsByMediaSize?: BiggestChannelsStatsType;
|
biggestChannelsStatsByMediaSize?: BiggestChannelsStatsType;
|
||||||
useSI: boolean;
|
useSIUnits: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const BiggestChannelsStats = ({
|
const BiggestChannelsStats = ({
|
||||||
biggestChannelsStatsByCount,
|
biggestChannelsStatsByCount,
|
||||||
biggestChannelsStatsByDuration,
|
biggestChannelsStatsByDuration,
|
||||||
biggestChannelsStatsByMediaSize,
|
biggestChannelsStatsByMediaSize,
|
||||||
useSI,
|
useSIUnits,
|
||||||
}: BiggestChannelsStatsProps) => {
|
}: BiggestChannelsStatsProps) => {
|
||||||
if (
|
if (
|
||||||
!biggestChannelsStatsByCount &&
|
!biggestChannelsStatsByCount &&
|
||||||
@@ -94,7 +94,9 @@ const BiggestChannelsStats = ({
|
|||||||
<td className="agg-channel-name">
|
<td className="agg-channel-name">
|
||||||
<Link to={Routes.Channel(id)}>{name}</Link>
|
<Link to={Routes.Channel(id)}>{name}</Link>
|
||||||
</td>
|
</td>
|
||||||
<td className="agg-channel-right-align">{humanFileSize(media_size, useSI)}</td>
|
<td className="agg-channel-right-align">
|
||||||
|
{humanFileSize(media_size, useSIUnits)}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import { DownloadHistoryStatsType } from '../pages/SettingsDashboard';
|
|||||||
|
|
||||||
type DownloadHistoryStatsProps = {
|
type DownloadHistoryStatsProps = {
|
||||||
downloadHistoryStats?: DownloadHistoryStatsType;
|
downloadHistoryStats?: DownloadHistoryStatsType;
|
||||||
useSI: boolean;
|
useSIUnits: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const DownloadHistoryStats = ({ downloadHistoryStats, useSI }: DownloadHistoryStatsProps) => {
|
const DownloadHistoryStats = ({ downloadHistoryStats, useSIUnits }: DownloadHistoryStatsProps) => {
|
||||||
if (!downloadHistoryStats) {
|
if (!downloadHistoryStats) {
|
||||||
return <p id="loading">Loading...</p>;
|
return <p id="loading">Loading...</p>;
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ const DownloadHistoryStats = ({ downloadHistoryStats, useSI }: DownloadHistorySt
|
|||||||
<p>
|
<p>
|
||||||
+{formatNumbers(count)} {videoText}
|
+{formatNumbers(count)} {videoText}
|
||||||
<br />
|
<br />
|
||||||
{humanFileSize(media_size, useSI)}
|
{humanFileSize(media_size, useSIUnits)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import { VideoStatsType } from '../pages/SettingsDashboard';
|
|||||||
|
|
||||||
type OverviewStatsProps = {
|
type OverviewStatsProps = {
|
||||||
videoStats?: VideoStatsType;
|
videoStats?: VideoStatsType;
|
||||||
useSI: boolean;
|
useSIUnits: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const OverviewStats = ({ videoStats, useSI }: OverviewStatsProps) => {
|
const OverviewStats = ({ videoStats, useSIUnits }: OverviewStatsProps) => {
|
||||||
if (!videoStats) {
|
if (!videoStats) {
|
||||||
return <p id="loading">Loading...</p>;
|
return <p id="loading">Loading...</p>;
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ const OverviewStats = ({ videoStats, useSI }: OverviewStatsProps) => {
|
|||||||
title: 'All: ',
|
title: 'All: ',
|
||||||
data: {
|
data: {
|
||||||
Videos: formatNumbers(videoStats?.doc_count || 0),
|
Videos: formatNumbers(videoStats?.doc_count || 0),
|
||||||
['Media Size']: humanFileSize(videoStats?.media_size || 0, useSI),
|
['Media Size']: humanFileSize(videoStats?.media_size || 0, useSIUnits),
|
||||||
Duration: videoStats?.duration_str,
|
Duration: videoStats?.duration_str,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -27,7 +27,7 @@ const OverviewStats = ({ videoStats, useSI }: OverviewStatsProps) => {
|
|||||||
title: 'Active: ',
|
title: 'Active: ',
|
||||||
data: {
|
data: {
|
||||||
Videos: formatNumbers(videoStats?.active_true?.doc_count || 0),
|
Videos: formatNumbers(videoStats?.active_true?.doc_count || 0),
|
||||||
['Media Size']: humanFileSize(videoStats?.active_true?.media_size || 0, useSI),
|
['Media Size']: humanFileSize(videoStats?.active_true?.media_size || 0, useSIUnits),
|
||||||
Duration: videoStats?.active_true?.duration_str || 'NA',
|
Duration: videoStats?.active_true?.duration_str || 'NA',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -35,7 +35,7 @@ const OverviewStats = ({ videoStats, useSI }: OverviewStatsProps) => {
|
|||||||
title: 'Inactive: ',
|
title: 'Inactive: ',
|
||||||
data: {
|
data: {
|
||||||
Videos: formatNumbers(videoStats?.active_false?.doc_count || 0),
|
Videos: formatNumbers(videoStats?.active_false?.doc_count || 0),
|
||||||
['Media Size']: humanFileSize(videoStats?.active_false?.media_size || 0, useSI),
|
['Media Size']: humanFileSize(videoStats?.active_false?.media_size || 0, useSIUnits),
|
||||||
Duration: videoStats?.active_false?.duration_str || 'NA',
|
Duration: videoStats?.active_false?.duration_str || 'NA',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import { VideoStatsType } from '../pages/SettingsDashboard';
|
|||||||
|
|
||||||
type VideoTypeStatsProps = {
|
type VideoTypeStatsProps = {
|
||||||
videoStats?: VideoStatsType;
|
videoStats?: VideoStatsType;
|
||||||
useSI: boolean;
|
useSIUnits: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const VideoTypeStats = ({ videoStats, useSI }: VideoTypeStatsProps) => {
|
const VideoTypeStats = ({ videoStats, useSIUnits }: VideoTypeStatsProps) => {
|
||||||
if (!videoStats) {
|
if (!videoStats) {
|
||||||
return <p id="loading">Loading...</p>;
|
return <p id="loading">Loading...</p>;
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ const VideoTypeStats = ({ videoStats, useSI }: VideoTypeStatsProps) => {
|
|||||||
title: 'Regular Videos: ',
|
title: 'Regular Videos: ',
|
||||||
data: {
|
data: {
|
||||||
Videos: formatNumbers(videoStats?.type_videos?.doc_count || 0),
|
Videos: formatNumbers(videoStats?.type_videos?.doc_count || 0),
|
||||||
['Media Size']: humanFileSize(videoStats?.type_videos?.media_size || 0, useSI),
|
['Media Size']: humanFileSize(videoStats?.type_videos?.media_size || 0, useSIUnits),
|
||||||
Duration: videoStats?.type_videos?.duration_str || 'NA',
|
Duration: videoStats?.type_videos?.duration_str || 'NA',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -27,7 +27,7 @@ const VideoTypeStats = ({ videoStats, useSI }: VideoTypeStatsProps) => {
|
|||||||
title: 'Shorts: ',
|
title: 'Shorts: ',
|
||||||
data: {
|
data: {
|
||||||
Videos: formatNumbers(videoStats?.type_shorts?.doc_count || 0),
|
Videos: formatNumbers(videoStats?.type_shorts?.doc_count || 0),
|
||||||
['Media Size']: humanFileSize(videoStats?.type_shorts?.media_size || 0, useSI),
|
['Media Size']: humanFileSize(videoStats?.type_shorts?.media_size || 0, useSIUnits),
|
||||||
Duration: videoStats?.type_shorts?.duration_str || 'NA',
|
Duration: videoStats?.type_shorts?.duration_str || 'NA',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -35,7 +35,7 @@ const VideoTypeStats = ({ videoStats, useSI }: VideoTypeStatsProps) => {
|
|||||||
title: 'Streams: ',
|
title: 'Streams: ',
|
||||||
data: {
|
data: {
|
||||||
Videos: formatNumbers(videoStats?.type_streams?.doc_count || 0),
|
Videos: formatNumbers(videoStats?.type_streams?.doc_count || 0),
|
||||||
['Media Size']: humanFileSize(videoStats?.type_streams?.media_size || 0, useSI),
|
['Media Size']: humanFileSize(videoStats?.type_streams?.media_size || 0, useSIUnits),
|
||||||
Duration: videoStats?.type_streams?.duration_str || 'NA',
|
Duration: videoStats?.type_streams?.duration_str || 'NA',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import loadVideoListByFilter, {
|
|||||||
import loadChannelAggs, { ChannelAggsType } from '../api/loader/loadChannelAggs';
|
import loadChannelAggs, { ChannelAggsType } from '../api/loader/loadChannelAggs';
|
||||||
import humanFileSize from '../functions/humanFileSize';
|
import humanFileSize from '../functions/humanFileSize';
|
||||||
import { useUserConfigStore } from '../stores/UserConfigStore';
|
import { useUserConfigStore } from '../stores/UserConfigStore';
|
||||||
|
import { FileSizeUnits } from '../api/actions/updateUserConfig';
|
||||||
|
|
||||||
type ChannelParams = {
|
type ChannelParams = {
|
||||||
channelId: string;
|
channelId: string;
|
||||||
@@ -47,6 +48,7 @@ const ChannelVideo = ({ videoType }: ChannelVideoProps) => {
|
|||||||
const pagination = videoResponse?.paginate;
|
const pagination = videoResponse?.paginate;
|
||||||
|
|
||||||
const hasVideos = videoResponse?.data?.length !== 0;
|
const hasVideos = videoResponse?.data?.length !== 0;
|
||||||
|
const useSiUnits = userConfig.file_size_unit === FileSizeUnits.Metric;
|
||||||
|
|
||||||
const view = userConfig.view_style_home;
|
const view = userConfig.view_style_home;
|
||||||
const isGridView = view === ViewStyles.grid;
|
const isGridView = view === ViewStyles.grid;
|
||||||
@@ -114,7 +116,7 @@ const ChannelVideo = ({ videoType }: ChannelVideoProps) => {
|
|||||||
<span className="space-carrot">|</span>{' '}
|
<span className="space-carrot">|</span>{' '}
|
||||||
{videoAggsResponse.total_duration.value_str} playback{' '}
|
{videoAggsResponse.total_duration.value_str} playback{' '}
|
||||||
<span className="space-carrot">|</span> Total size{' '}
|
<span className="space-carrot">|</span> Total size{' '}
|
||||||
{humanFileSize(videoAggsResponse.total_size.value, true)}
|
{humanFileSize(videoAggsResponse.total_size.value, useSiUnits)}
|
||||||
</p>
|
</p>
|
||||||
<div className="button-box">
|
<div className="button-box">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import DownloadHistoryStats from '../components/DownloadHistoryStats';
|
|||||||
import BiggestChannelsStats from '../components/BiggestChannelsStats';
|
import BiggestChannelsStats from '../components/BiggestChannelsStats';
|
||||||
import Notifications from '../components/Notifications';
|
import Notifications from '../components/Notifications';
|
||||||
import PaginationDummy from '../components/PaginationDummy';
|
import PaginationDummy from '../components/PaginationDummy';
|
||||||
|
import { useUserConfigStore } from '../stores/UserConfigStore';
|
||||||
|
import { FileSizeUnits } from '../api/actions/updateUserConfig';
|
||||||
|
|
||||||
export type VideoStatsType = {
|
export type VideoStatsType = {
|
||||||
doc_count: number;
|
doc_count: number;
|
||||||
@@ -125,7 +127,7 @@ type DashboardStatsReponses = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const SettingsDashboard = () => {
|
const SettingsDashboard = () => {
|
||||||
const [useSi, setUseSi] = useState(false);
|
const { userConfig } = useUserConfigStore();
|
||||||
|
|
||||||
const [response, setResponse] = useState<DashboardStatsReponses>({
|
const [response, setResponse] = useState<DashboardStatsReponses>({
|
||||||
videoStats: undefined,
|
videoStats: undefined,
|
||||||
@@ -181,6 +183,8 @@ const SettingsDashboard = () => {
|
|||||||
})();
|
})();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const useSiUnits = userConfig.file_size_unit === FileSizeUnits.Metric;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<title>TA | Settings Dashboard</title>
|
<title>TA | Settings Dashboard</title>
|
||||||
@@ -190,31 +194,17 @@ const SettingsDashboard = () => {
|
|||||||
<div className="title-bar">
|
<div className="title-bar">
|
||||||
<h1>Your Archive</h1>
|
<h1>Your Archive</h1>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
|
||||||
File Sizes in:
|
|
||||||
<select
|
|
||||||
value={useSi ? 'true' : 'false'}
|
|
||||||
onChange={event => {
|
|
||||||
const value = event.target.value;
|
|
||||||
console.log(value);
|
|
||||||
setUseSi(value === 'true');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<option value="true">SI units</option>
|
|
||||||
<option value="false">Binary units</option>
|
|
||||||
</select>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div className="settings-item">
|
<div className="settings-item">
|
||||||
<h2>Overview</h2>
|
<h2>Overview</h2>
|
||||||
<div className="info-box info-box-3">
|
<div className="info-box info-box-3">
|
||||||
<OverviewStats videoStats={videoStats} useSI={useSi} />
|
<OverviewStats videoStats={videoStats} useSIUnits={useSiUnits} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="settings-item">
|
<div className="settings-item">
|
||||||
<h2>Video Type</h2>
|
<h2>Video Type</h2>
|
||||||
<div className="info-box info-box-3">
|
<div className="info-box info-box-3">
|
||||||
<VideoTypeStats videoStats={videoStats} useSI={useSi} />
|
<VideoTypeStats videoStats={videoStats} useSIUnits={useSiUnits} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="settings-item">
|
<div className="settings-item">
|
||||||
@@ -236,7 +226,7 @@ const SettingsDashboard = () => {
|
|||||||
<div className="settings-item">
|
<div className="settings-item">
|
||||||
<h2>Download History</h2>
|
<h2>Download History</h2>
|
||||||
<div className="info-box info-box-4">
|
<div className="info-box info-box-4">
|
||||||
<DownloadHistoryStats downloadHistoryStats={downloadHistoryStats} useSI={false} />
|
<DownloadHistoryStats downloadHistoryStats={downloadHistoryStats} useSIUnits={false} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="settings-item">
|
<div className="settings-item">
|
||||||
@@ -246,7 +236,7 @@ const SettingsDashboard = () => {
|
|||||||
biggestChannelsStatsByCount={biggestChannelsStatsByCount}
|
biggestChannelsStatsByCount={biggestChannelsStatsByCount}
|
||||||
biggestChannelsStatsByDuration={biggestChannelsStatsByDuration}
|
biggestChannelsStatsByDuration={biggestChannelsStatsByDuration}
|
||||||
biggestChannelsStatsByMediaSize={biggestChannelsStatsByMediaSize}
|
biggestChannelsStatsByMediaSize={biggestChannelsStatsByMediaSize}
|
||||||
useSI={useSi}
|
useSIUnits={useSiUnits}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import updateUserConfig, { ColourVariants, UserConfigType } from '../api/actions/updateUserConfig';
|
import updateUserConfig, {
|
||||||
|
ColourVariants,
|
||||||
|
FileSizeUnits,
|
||||||
|
UserConfigType,
|
||||||
|
} from '../api/actions/updateUserConfig';
|
||||||
import { ColourConstant } from '../configuration/colours/useColours';
|
import { ColourConstant } from '../configuration/colours/useColours';
|
||||||
import SettingsNavigation from '../components/SettingsNavigation';
|
import SettingsNavigation from '../components/SettingsNavigation';
|
||||||
import Notifications from '../components/Notifications';
|
import Notifications from '../components/Notifications';
|
||||||
@@ -18,14 +22,21 @@ const SettingsUser = () => {
|
|||||||
const [styleSheetRefresh, setStyleSheetRefresh] = useState(false);
|
const [styleSheetRefresh, setStyleSheetRefresh] = useState(false);
|
||||||
const [pageSize, setPageSize] = useState<number>(userConfig.page_size);
|
const [pageSize, setPageSize] = useState<number>(userConfig.page_size);
|
||||||
const [showHelpText, setShowHelpText] = useState(userConfig.show_help_text);
|
const [showHelpText, setShowHelpText] = useState(userConfig.show_help_text);
|
||||||
|
const [selectedFileSizeUnit, setSelectedFileSizeUnit] = useState(FileSizeUnits.Binary);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
setStyleSheet(userConfig.stylesheet);
|
setStyleSheet(userConfig.stylesheet);
|
||||||
setPageSize(userConfig.page_size);
|
setPageSize(userConfig.page_size);
|
||||||
setShowHelpText(userConfig.show_help_text);
|
setShowHelpText(userConfig.show_help_text);
|
||||||
|
setSelectedFileSizeUnit(userConfig.file_size_unit);
|
||||||
})();
|
})();
|
||||||
}, [userConfig.page_size, userConfig.stylesheet, userConfig.show_help_text]);
|
}, [
|
||||||
|
userConfig.page_size,
|
||||||
|
userConfig.stylesheet,
|
||||||
|
userConfig.show_help_text,
|
||||||
|
userConfig.file_size_unit,
|
||||||
|
]);
|
||||||
|
|
||||||
const handleStyleSheetChange = async (selectedStyleSheet: ColourVariants) => {
|
const handleStyleSheetChange = async (selectedStyleSheet: ColourVariants) => {
|
||||||
handleUserConfigUpdate({ stylesheet: selectedStyleSheet });
|
handleUserConfigUpdate({ stylesheet: selectedStyleSheet });
|
||||||
@@ -41,6 +52,10 @@ const SettingsUser = () => {
|
|||||||
handleUserConfigUpdate({ [configKey]: configValue });
|
handleUserConfigUpdate({ [configKey]: configValue });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleFileSizeUnitChange = async (configKey: string, configValue: string) => {
|
||||||
|
handleUserConfigUpdate({ [configKey]: configValue });
|
||||||
|
};
|
||||||
|
|
||||||
const handleUserConfigUpdate = async (config: Partial<UserConfigType>) => {
|
const handleUserConfigUpdate = async (config: Partial<UserConfigType>) => {
|
||||||
const updatedUserConfig = await updateUserConfig(config);
|
const updatedUserConfig = await updateUserConfig(config);
|
||||||
setUserConfig(updatedUserConfig);
|
setUserConfig(updatedUserConfig);
|
||||||
@@ -88,6 +103,7 @@ const SettingsUser = () => {
|
|||||||
{styleSheetRefresh && <button onClick={handlePageRefresh}>Refresh</button>}
|
{styleSheetRefresh && <button onClick={handlePageRefresh}>Refresh</button>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="settings-box-wrapper">
|
<div className="settings-box-wrapper">
|
||||||
<div>
|
<div>
|
||||||
<p>Archive view page size</p>
|
<p>Archive view page size</p>
|
||||||
@@ -113,18 +129,40 @@ const SettingsUser = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="settings-box-wrapper">
|
<div className="settings-box-wrapper">
|
||||||
<div>
|
<div>
|
||||||
<p>Show help text</p>
|
<p>Show help text</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ToggleConfig
|
<ToggleConfig
|
||||||
name="show_help_text"
|
name="show_help_text"
|
||||||
value={showHelpText}
|
value={showHelpText}
|
||||||
updateCallback={handleShowHelpTextChange}
|
updateCallback={handleShowHelpTextChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="settings-box-wrapper"
|
||||||
|
title="Metric (SI) units, aka powers of 1000. Binary (IEC), aka powers of 1024."
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<p>File size units:</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<select
|
||||||
|
value={selectedFileSizeUnit}
|
||||||
|
onChange={event => {
|
||||||
|
handleFileSizeUnitChange('file_size_unit', event.currentTarget.value);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option value={FileSizeUnits.Metric}>SI units</option>
|
||||||
|
<option value={FileSizeUnits.Binary}>Binary units</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{isAdmin && (
|
{isAdmin && (
|
||||||
<>
|
<>
|
||||||
<div className="settings-group">
|
<div className="settings-group">
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ import ToggleConfig from '../components/ToggleConfig';
|
|||||||
import { PlaylistType } from '../api/loader/loadPlaylistById';
|
import { PlaylistType } from '../api/loader/loadPlaylistById';
|
||||||
import { useAppSettingsStore } from '../stores/AppSettingsStore';
|
import { useAppSettingsStore } from '../stores/AppSettingsStore';
|
||||||
import updateDownloadQueueStatusById from '../api/actions/updateDownloadQueueStatusById';
|
import updateDownloadQueueStatusById from '../api/actions/updateDownloadQueueStatusById';
|
||||||
|
import { FileSizeUnits } from '../api/actions/updateUserConfig';
|
||||||
|
import { useUserConfigStore } from '../stores/UserConfigStore';
|
||||||
|
|
||||||
const isInPlaylist = (videoId: string, playlist: PlaylistType) => {
|
const isInPlaylist = (videoId: string, playlist: PlaylistType) => {
|
||||||
return playlist.playlist_entries.some(entry => {
|
return playlist.playlist_entries.some(entry => {
|
||||||
@@ -112,6 +114,7 @@ const Video = () => {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const isAdmin = useIsAdmin();
|
const isAdmin = useIsAdmin();
|
||||||
const { appSettingsConfig } = useAppSettingsStore();
|
const { appSettingsConfig } = useAppSettingsStore();
|
||||||
|
const { userConfig } = useUserConfigStore();
|
||||||
|
|
||||||
const [videoEnded, setVideoEnded] = useState(false);
|
const [videoEnded, setVideoEnded] = useState(false);
|
||||||
const [playlistAutoplay, setPlaylistAutoplay] = useState(
|
const [playlistAutoplay, setPlaylistAutoplay] = useState(
|
||||||
@@ -199,6 +202,7 @@ const Video = () => {
|
|||||||
const customPlaylists = customPlaylistsResponse?.data;
|
const customPlaylists = customPlaylistsResponse?.data;
|
||||||
const starRating = convertStarRating(video?.stats?.average_rating);
|
const starRating = convertStarRating(video?.stats?.average_rating);
|
||||||
const comments = commentsResponse;
|
const comments = commentsResponse;
|
||||||
|
const useSiUnits = userConfig.file_size_unit === FileSizeUnits.Metric;
|
||||||
|
|
||||||
console.log('playlistNav', playlistNav);
|
console.log('playlistNav', playlistNav);
|
||||||
|
|
||||||
@@ -439,14 +443,14 @@ const Video = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="info-box-item">
|
<div className="info-box-item">
|
||||||
{video.media_size && <p>File size: {humanFileSize(video.media_size)}</p>}
|
{video.media_size && <p>File size: {humanFileSize(video.media_size, useSiUnits)}</p>}
|
||||||
|
|
||||||
{video.streams &&
|
{video.streams &&
|
||||||
video.streams.map(stream => {
|
video.streams.map(stream => {
|
||||||
return (
|
return (
|
||||||
<p key={stream.index}>
|
<p key={stream.index}>
|
||||||
{capitalizeFirstLetter(stream.type)}: {stream.codec}{' '}
|
{capitalizeFirstLetter(stream.type)}: {stream.codec}{' '}
|
||||||
{humanFileSize(stream.bitrate)}/s
|
{humanFileSize(stream.bitrate, useSiUnits)}/s
|
||||||
{stream.width && (
|
{stream.width && (
|
||||||
<>
|
<>
|
||||||
<span className="space-carrot">|</span> {stream.width}x{stream.height}
|
<span className="space-carrot">|</span> {stream.width}x{stream.height}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export const useUserConfigStore = create<UserConfigState>(set => ({
|
|||||||
view_style_playlist: 'grid',
|
view_style_playlist: 'grid',
|
||||||
grid_items: 3,
|
grid_items: 3,
|
||||||
hide_watched: false,
|
hide_watched: false,
|
||||||
|
file_size_unit: 'binary',
|
||||||
show_ignored_only: false,
|
show_ignored_only: false,
|
||||||
show_subed_only: false,
|
show_subed_only: false,
|
||||||
show_help_text: true,
|
show_help_text: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user