diff --git a/src/App.tsx b/src/App.tsx index e3845e0..0a5495c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -55,7 +55,7 @@ export default function App({ children }: { children: React.ReactNode }) { const MAX_PARALLEL_DOWNLOADS = useSettingsPageStatesStore(state => state.settings.max_parallel_downloads); const DOWNLOAD_DIR = useSettingsPageStatesStore(state => state.settings.download_dir); const PREFER_VIDEO_OVER_PLAYLIST = useSettingsPageStatesStore(state => state.settings.prefer_video_over_playlist); - const SHOW_DOWNLOADABLE_STREAMS_ONLY = useSettingsPageStatesStore(state => state.settings.show_downloadable_streams_only); + const STRICT_DOWNLOADABILITY_CHECK = useSettingsPageStatesStore(state => state.settings.strict_downloadablity_check); const USE_PROXY = useSettingsPageStatesStore(state => state.settings.use_proxy); const PROXY_URL = useSettingsPageStatesStore(state => state.settings.proxy_url); const VIDEO_FORMAT = useSettingsPageStatesStore(state => state.settings.video_format); @@ -92,11 +92,12 @@ export default function App({ children }: { children: React.ReactNode }) { const fetchVideoMetadata = async (url: string, formatId?: string, playlistIndex?: string): Promise => { try { - const args = [url, '--dump-single-json']; + const args = [url, '--dump-single-json', '--no-warnings']; if (formatId) args.push('-f', formatId); if (playlistIndex) args.push('--playlist-items', playlistIndex); if (PREFER_VIDEO_OVER_PLAYLIST) args.push('--no-playlist'); - if (SHOW_DOWNLOADABLE_STREAMS_ONLY) args.push('--check-all-formats'); + if (STRICT_DOWNLOADABILITY_CHECK && !formatId) args.push('--check-all-formats'); + if (STRICT_DOWNLOADABILITY_CHECK && formatId) args.push('--check-formats'); if (USE_PROXY && PROXY_URL) args.push('--proxy', PROXY_URL); const command = Command.sidecar('binaries/yt-dlp', args); @@ -178,6 +179,7 @@ export default function App({ children }: { children: React.ReactNode }) { '-f', selectedFormat, '--no-mtime', + '--no-warnings', ]; if (selectedSubtitles) { diff --git a/src/pages/downloader.tsx b/src/pages/downloader.tsx index 65d8b3c..6bb1289 100644 --- a/src/pages/downloader.tsx +++ b/src/pages/downloader.tsx @@ -9,7 +9,7 @@ import { useToast } from "@/hooks/use-toast"; import { useAppContext } from "@/providers/appContextProvider"; import { useCurrentVideoMetadataStore, useDownloaderPageStatesStore, useSettingsPageStatesStore } from "@/services/store"; import { determineFileType, fileFormatFilter, formatBitrate, formatDurationString, formatFileSize, formatReleaseDate, formatYtStyleCount, isObjEmpty, sortByBitrate } from "@/utils"; -import { Calendar, Clock, DownloadCloud, Eye, Info, Loader2, Music, ThumbsUp, Video, File, ListVideo, PackageSearch } from "lucide-react"; +import { Calendar, Clock, DownloadCloud, Eye, Info, Loader2, Music, ThumbsUp, Video, File, ListVideo, PackageSearch, AlertCircleIcon } from "lucide-react"; import { FormatSelectionGroup, FormatSelectionGroupItem } from "@/components/custom/formatSelectionGroup"; import { useEffect, useRef } from "react"; import { ToggleGroup, ToggleGroupItem } from "@/components/custom/legacyToggleGroup"; @@ -21,6 +21,8 @@ import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod" import { Form, FormControl, FormField, FormItem, FormMessage } from "@/components/ui/form"; import { config } from "@/config"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; const searchFormSchema = z.object({ url: z.string().min(1, { message: "URL is required" }) @@ -42,12 +44,18 @@ export default function DownloaderPage() { const setRequestedUrl = useCurrentVideoMetadataStore((state) => state.setRequestedUrl); const setAutoSubmitSearch = useCurrentVideoMetadataStore((state) => state.setAutoSubmitSearch); + const activeDownloadModeTab = useDownloaderPageStatesStore((state) => state.activeDownloadModeTab); const isStartingDownload = useDownloaderPageStatesStore((state) => state.isStartingDownload); - const selctedDownloadFormat = useDownloaderPageStatesStore((state) => state.selctedDownloadFormat); + const selectedDownloadFormat = useDownloaderPageStatesStore((state) => state.selectedDownloadFormat); + const selectedCombinableVideoFormat = useDownloaderPageStatesStore((state) => state.selectedCombinableVideoFormat); + const selectedCombinableAudioFormat = useDownloaderPageStatesStore((state) => state.selectedCombinableAudioFormat); const selectedSubtitles = useDownloaderPageStatesStore((state) => state.selectedSubtitles); const selectedPlaylistVideoIndex = useDownloaderPageStatesStore((state) => state.selectedPlaylistVideoIndex); + const setActiveDownloadModeTab = useDownloaderPageStatesStore((state) => state.setActiveDownloadModeTab); const setIsStartingDownload = useDownloaderPageStatesStore((state) => state.setIsStartingDownload); - const setSelctedDownloadFormat = useDownloaderPageStatesStore((state) => state.setSelctedDownloadFormat); + const setSelectedDownloadFormat = useDownloaderPageStatesStore((state) => state.setSelectedDownloadFormat); + const setSelectedCombinableVideoFormat = useDownloaderPageStatesStore((state) => state.setSelectedCombinableVideoFormat); + const setSelectedCombinableAudioFormat = useDownloaderPageStatesStore((state) => state.setSelectedCombinableAudioFormat); const setSelectedSubtitles = useDownloaderPageStatesStore((state) => state.setSelectedSubtitles); const setSelectedPlaylistVideoIndex = useDownloaderPageStatesStore((state) => state.setSelectedPlaylistVideoIndex); @@ -82,22 +90,44 @@ export default function DownloaderPage() { const allFilteredFormats = [...(audioOnlyFormats || []), ...(videoOnlyFormats || []), ...(combinedFormats || []), ...(qualityPresetFormats || [])]; const selectedFormat = (() => { if (videoMetadata?._type === 'video') { - if (selctedDownloadFormat === 'best') { + if (selectedDownloadFormat === 'best') { return videoMetadata?.requested_downloads[0]; } return allFilteredFormats.find( - (format) => format.format_id === selctedDownloadFormat + (format) => format.format_id === selectedDownloadFormat ); } else if (videoMetadata?._type === 'playlist') { - if (selctedDownloadFormat === 'best') { + if (selectedDownloadFormat === 'best') { return videoMetadata?.entries[Number(selectedPlaylistVideoIndex) - 1].requested_downloads[0]; } return allFilteredFormats.find( - (format) => format.format_id === selctedDownloadFormat + (format) => format.format_id === selectedDownloadFormat ); } })(); const selectedFormatFileType = determineFileType(selectedFormat?.vcodec, selectedFormat?.acodec); + const selectedVideoFormat = (() => { + if (videoMetadata?._type === 'video') { + return allFilteredFormats.find( + (format) => format.format_id === selectedCombinableVideoFormat + ); + } else if (videoMetadata?._type === 'playlist') { + return allFilteredFormats.find( + (format) => format.format_id === selectedCombinableVideoFormat + ); + } + })(); + const selectedAudioFormat = (() => { + if (videoMetadata?._type === 'video') { + return allFilteredFormats.find( + (format) => format.format_id === selectedCombinableAudioFormat + ); + } else if (videoMetadata?._type === 'playlist') { + return allFilteredFormats.find( + (format) => format.format_id === selectedCombinableAudioFormat + ); + } + })(); const subtitles = videoMetadata?._type === 'video' ? (videoMetadata?.subtitles || {}) : videoMetadata?._type === 'playlist' ? (videoMetadata?.entries[Number(selectedPlaylistVideoIndex) - 1].subtitles || {}) : {}; const subtitleLanguages = Object.keys(subtitles).map(langCode => ({ @@ -109,7 +139,16 @@ export default function DownloaderPage() { const bottomBarRef = useRef(null); let selectedFormatExtensionMsg = 'Auto - unknown'; - if (selectedFormat?.ext) { + if (activeDownloadModeTab === 'combine') { + if (videoFormat !== 'auto') { + selectedFormatExtensionMsg = `Combined - ${videoFormat.toUpperCase()}`; + } + else if (selectedAudioFormat?.ext && selectedVideoFormat?.ext) { + selectedFormatExtensionMsg = `Combined - ${selectedVideoFormat.ext.toUpperCase()} + ${selectedAudioFormat.ext.toUpperCase()}`; + } else { + selectedFormatExtensionMsg = `Combined - unknown`; + } + } else if (selectedFormat?.ext) { if ((selectedFormatFileType === 'video+audio' || selectedFormatFileType === 'video') && videoFormat !== 'auto') { selectedFormatExtensionMsg = `Forced - ${videoFormat.toUpperCase()}`; } else if (selectedFormatFileType === 'audio' && audioFormat !== 'auto') { @@ -119,6 +158,42 @@ export default function DownloaderPage() { } } + let selectedFormatResolutionMsg = 'unknown'; + if (activeDownloadModeTab === 'combine') { + selectedFormatResolutionMsg = `${selectedVideoFormat?.resolution ?? 'unknown'} + ${selectedAudioFormat?.tbr ? formatBitrate(selectedAudioFormat.tbr) : 'unknown'}`; + } else if (selectedFormat?.resolution) { + selectedFormatResolutionMsg = selectedFormat.resolution; + } + + let selectedFormatDynamicRangeMsg = ''; + if (activeDownloadModeTab === 'combine') { + selectedFormatDynamicRangeMsg = selectedVideoFormat?.dynamic_range && selectedVideoFormat.dynamic_range !== 'SDR' ? selectedVideoFormat.dynamic_range : ''; + } else if (selectedFormat?.dynamic_range && selectedFormat.dynamic_range !== 'SDR') { + selectedFormatDynamicRangeMsg = selectedFormat.dynamic_range; + } + + let selectedFormatFileSizeMsg = 'unknown filesize'; + if (activeDownloadModeTab === 'combine') { + selectedFormatFileSizeMsg = selectedVideoFormat?.filesize_approx && selectedAudioFormat?.filesize_approx ? formatFileSize(selectedVideoFormat.filesize_approx + selectedAudioFormat.filesize_approx) : 'unknown filesize'; + } else if (selectedFormat?.filesize_approx) { + selectedFormatFileSizeMsg = formatFileSize(selectedFormat.filesize_approx); + } + + let selectedFormatFinalMsg = ''; + if (activeDownloadModeTab === 'combine') { + if (selectedCombinableVideoFormat && selectedCombinableAudioFormat) { + selectedFormatFinalMsg = `${selectedFormatExtensionMsg} (${selectedFormatResolutionMsg}) ${selectedFormatDynamicRangeMsg} ${selectedSubtitles.length > 0 ? `• ESUB` : ''} • ${selectedFormatFileSizeMsg}`; + } else { + selectedFormatFinalMsg = `Choose a video and audio stream to combine`; + } + } else { + if (selectedFormat) { + selectedFormatFinalMsg = `${selectedFormatExtensionMsg} (${selectedFormatResolutionMsg}) ${selectedFormatDynamicRangeMsg} ${selectedSubtitles.length > 0 ? `• ESUB` : ''} • ${selectedFormatFileSizeMsg}`; + } else { + selectedFormatFinalMsg = `Choose a stream to download`; + } + } + const searchForm = useForm>({ resolver: zodResolver(searchFormSchema), defaultValues: { @@ -131,7 +206,9 @@ export default function DownloaderPage() { function handleSearchSubmit(values: z.infer) { setVideoMetadata(null); setIsMetadataLoading(true); - setSelctedDownloadFormat('best'); + setSelectedDownloadFormat('best'); + setSelectedCombinableVideoFormat(''); + setSelectedCombinableAudioFormat(''); setSelectedSubtitles([]); setSelectedPlaylistVideoIndex('1'); fetchVideoMetadata(values.url).then((metadata) => { @@ -281,11 +358,11 @@ export default function DownloaderPage() { {!isMetadataLoading && videoMetadata && videoMetadata._type === 'video' && ( // === Single Video ===
-

+

Metadata

-
+
@@ -323,127 +400,222 @@ export default function DownloaderPage() { Extracted from {videoMetadata.extractor ? videoMetadata.extractor.charAt(0).toUpperCase() + videoMetadata.extractor.slice(1) : 'Unknown'}
-
+
-

- - Download Options -

-
- {subtitles && !isObjEmpty(subtitles) && ( - setSelectedSubtitles(value)} - disabled={selectedFormat?.ext !== 'mp4' && selectedFormat?.ext !== 'mkv' && selectedFormat?.ext !== 'webm'} - > -

Subtitle Languages

-
- {subtitleLanguages.map((lang) => ( - - {lang.lang} - - ))} -
-
- )} - { - setSelctedDownloadFormat(value); - const currentlySelectedFormat = value === 'best' ? videoMetadata?.requested_downloads[0] : allFilteredFormats.find((format) => format.format_id === value); - if (currentlySelectedFormat?.ext !== 'mp4' && currentlySelectedFormat?.ext !== 'mkv' && currentlySelectedFormat?.ext !== 'webm') { - setSelectedSubtitles([]); - } - }} - > -

Suggested

-
- + setActiveDownloadModeTab(tab)} + > +
+

+ + Download Options +

+ + Selective + Combine + +
+ +
+ {subtitles && !isObjEmpty(subtitles) && ( + setSelectedSubtitles(value)} + disabled={selectedFormat?.ext !== 'mp4' && selectedFormat?.ext !== 'mkv' && selectedFormat?.ext !== 'webm'} + > +

Subtitle Languages

+
+ {subtitleLanguages.map((lang) => ( + + {lang.lang} + + ))} +
+
+ )} + { + setSelectedDownloadFormat(value); + const currentlySelectedFormat = value === 'best' ? videoMetadata?.requested_downloads[0] : allFilteredFormats.find((format) => format.format_id === value); + if (currentlySelectedFormat?.ext !== 'mp4' && currentlySelectedFormat?.ext !== 'mkv' && currentlySelectedFormat?.ext !== 'webm') { + setSelectedSubtitles([]); + } + }} + > +

Suggested

+
+ +
+ {qualityPresetFormats && qualityPresetFormats.length > 0 && ( + <> +

Quality Presets

+
+ {qualityPresetFormats.map((format) => ( + + ))} +
+ + )} + {audioOnlyFormats && audioOnlyFormats.length > 0 && ( + <> +

Audio

+
+ {audioOnlyFormats.map((format) => ( + + ))} +
+ + )} + {videoOnlyFormats && videoOnlyFormats.length > 0 && ( + <> +

Video {videoOnlyFormats.every(format => format.acodec === 'none') ? '(no audio)' : ''}

+
+ {videoOnlyFormats.map((format) => ( + + ))} +
+ + )} + {combinedFormats && combinedFormats.length > 0 && ( + <> +

Video

+
+ {combinedFormats.map((format) => ( + + ))} +
+ + )} +
+
- {qualityPresetFormats && qualityPresetFormats.length > 0 && ( - <> -

Quality Presets

-
- {qualityPresetFormats.map((format) => ( - - ))} -
- - )} - {audioOnlyFormats && audioOnlyFormats.length > 0 && ( - <> -

Audio

-
- {audioOnlyFormats.map((format) => ( - - ))} -
- - )} - {videoOnlyFormats && videoOnlyFormats.length > 0 && ( - <> -

Video {videoOnlyFormats.every(format => format.acodec === 'none') ? '(no audio)' : ''}

-
- {videoOnlyFormats.map((format) => ( - - ))} -
- - )} - {combinedFormats && combinedFormats.length > 0 && ( - <> -

Video

-
- {combinedFormats.map((format) => ( - - ))} -
- - )} - -
-
+ + +
+ {audioOnlyFormats && audioOnlyFormats.length > 0 && videoOnlyFormats && videoOnlyFormats.length > 0 && subtitles && !isObjEmpty(subtitles) && ( + setSelectedSubtitles(value)} + disabled={selectedFormat?.ext !== 'mp4' && selectedFormat?.ext !== 'mkv' && selectedFormat?.ext !== 'webm'} + > +

Subtitle Languages

+
+ {subtitleLanguages.map((lang) => ( + + {lang.lang} + + ))} +
+
+ )} + { + setSelectedCombinableAudioFormat(value); + }} + > + {videoOnlyFormats && videoOnlyFormats.length > 0 && audioOnlyFormats && audioOnlyFormats.length > 0 && ( + <> +

Audio

+
+ {audioOnlyFormats.map((format) => ( + + ))} +
+ + )} +
+ { + setSelectedCombinableVideoFormat(value); + }} + > + {audioOnlyFormats && audioOnlyFormats.length > 0 && videoOnlyFormats && videoOnlyFormats.length > 0 && ( + <> +

Video

+
+ {videoOnlyFormats.map((format) => ( + + ))} +
+ + )} +
+ {(!videoOnlyFormats || videoOnlyFormats.length === 0 || !audioOnlyFormats || audioOnlyFormats.length === 0) && ( + + + Unable to use Combine Mode! + + Cannot use combine mode for this video as it does not have both audio and video formats available. Use Selective Mode or try another video. + + + )} +
+
+
+
)} {!isMetadataLoading && videoMetadata && videoMetadata._type === 'playlist' && ( // === Playlists ===
-

+

Playlist ({videoMetadata.entries[0].n_entries})

-
+

{videoMetadata.entries[0].playlist_title ? videoMetadata.entries[0].playlist_title : 'UNTITLED'}

{videoMetadata.entries[0].playlist_channel || videoMetadata.entries[0].playlist_uploader || 'unknown'}

{/* { setSelectedPlaylistVideoIndex(value); - setSelctedDownloadFormat('best'); + setSelectedDownloadFormat('best'); setSelectedSubtitles([]); + setSelectedCombinableVideoFormat(''); + setSelectedCombinableAudioFormat(''); }} > {videoMetadata.entries.map((entry) => entry ? ( @@ -481,120 +655,215 @@ export default function DownloaderPage() { Extracted from {videoMetadata.entries[0].extractor ? videoMetadata.entries[0].extractor.charAt(0).toUpperCase() + videoMetadata.entries[0].extractor.slice(1) : 'Unknown'}
-
+
-

- - Download Options -

-
- {subtitles && !isObjEmpty(subtitles) && ( - setSelectedSubtitles(value)} - disabled={selectedFormat?.ext !== 'mp4' && selectedFormat?.ext !== 'mkv' && selectedFormat?.ext !== 'webm'} - > -

Subtitle Languages

-
- {subtitleLanguages.map((lang) => ( - - {lang.lang} - - ))} -
-
- )} - { - setSelctedDownloadFormat(value); - const currentlySelectedFormat = value === 'best' ? videoMetadata?.entries[Number(value) - 1].requested_downloads[0] : allFilteredFormats.find((format) => format.format_id === value); - if (currentlySelectedFormat?.ext !== 'mp4' && currentlySelectedFormat?.ext !== 'mkv' && currentlySelectedFormat?.ext !== 'webm') { - setSelectedSubtitles([]); - } - }} - > -

Suggested

-
- + setActiveDownloadModeTab(tab)} + > +
+

+ + Download Options +

+ + Selective + Combine + +
+ +
+ {subtitles && !isObjEmpty(subtitles) && ( + setSelectedSubtitles(value)} + disabled={selectedFormat?.ext !== 'mp4' && selectedFormat?.ext !== 'mkv' && selectedFormat?.ext !== 'webm'} + > +

Subtitle Languages

+
+ {subtitleLanguages.map((lang) => ( + + {lang.lang} + + ))} +
+
+ )} + { + setSelectedDownloadFormat(value); + const currentlySelectedFormat = value === 'best' ? videoMetadata?.entries[Number(value) - 1].requested_downloads[0] : allFilteredFormats.find((format) => format.format_id === value); + if (currentlySelectedFormat?.ext !== 'mp4' && currentlySelectedFormat?.ext !== 'mkv' && currentlySelectedFormat?.ext !== 'webm') { + setSelectedSubtitles([]); + } + }} + > +

Suggested

+
+ +
+ {qualityPresetFormats && qualityPresetFormats.length > 0 && ( + <> +

Quality Presets

+
+ {qualityPresetFormats.map((format) => ( + + ))} +
+ + )} + {audioOnlyFormats && audioOnlyFormats.length > 0 && ( + <> +

Audio

+
+ {audioOnlyFormats.map((format) => ( + + ))} +
+ + )} + {videoOnlyFormats && videoOnlyFormats.length > 0 && ( + <> +

Video {videoOnlyFormats.every(format => format.acodec === 'none') ? '(no audio)' : ''}

+
+ {videoOnlyFormats.map((format) => ( + + ))} +
+ + )} + {combinedFormats && combinedFormats.length > 0 && ( + <> +

Video

+
+ {combinedFormats.map((format) => ( + + ))} +
+ + )} +
+
- {qualityPresetFormats && qualityPresetFormats.length > 0 && ( - <> -

Quality Presets

-
- {qualityPresetFormats.map((format) => ( - - ))} -
- - )} - {audioOnlyFormats && audioOnlyFormats.length > 0 && ( - <> -

Audio

-
- {audioOnlyFormats.map((format) => ( - - ))} -
- - )} - {videoOnlyFormats && videoOnlyFormats.length > 0 && ( - <> -

Video {videoOnlyFormats.every(format => format.acodec === 'none') ? '(no audio)' : ''}

-
- {videoOnlyFormats.map((format) => ( - - ))} -
- - )} - {combinedFormats && combinedFormats.length > 0 && ( - <> -

Video

-
- {combinedFormats.map((format) => ( - - ))} -
- - )} - -
-
+ + +
+ {audioOnlyFormats && audioOnlyFormats.length > 0 && videoOnlyFormats && videoOnlyFormats.length > 0 && subtitles && !isObjEmpty(subtitles) && ( + setSelectedSubtitles(value)} + disabled={selectedFormat?.ext !== 'mp4' && selectedFormat?.ext !== 'mkv' && selectedFormat?.ext !== 'webm'} + > +

Subtitle Languages

+
+ {subtitleLanguages.map((lang) => ( + + {lang.lang} + + ))} +
+
+ )} + { + setSelectedCombinableAudioFormat(value); + }} + > + {videoOnlyFormats && videoOnlyFormats.length > 0 && audioOnlyFormats && audioOnlyFormats.length > 0 && ( + <> +

Audio

+
+ {audioOnlyFormats.map((format) => ( + + ))} +
+ + )} +
+ { + setSelectedCombinableVideoFormat(value); + }} + > + {audioOnlyFormats && audioOnlyFormats.length > 0 && videoOnlyFormats && videoOnlyFormats.length > 0 && ( + <> +

Video

+
+ {videoOnlyFormats.map((format) => ( + + ))} +
+ + )} +
+ {(!videoOnlyFormats || videoOnlyFormats.length === 0 || !audioOnlyFormats || audioOnlyFormats.length === 0) && ( + + + Unable to use Combine Mode! + + Cannot use combine mode for this video as it does not have both audio and video formats available. Use Selective Mode or try another video. + + + )} +
+
+
+
)} - {!isMetadataLoading && videoMetadata && selctedDownloadFormat && ( // === Bottom Bar === + {!isMetadataLoading && videoMetadata && selectedDownloadFormat && ( // === Bottom Bar ===
@@ -610,7 +879,7 @@ export default function DownloaderPage() {
{videoMetadata._type === 'video' ? videoMetadata.title : videoMetadata._type === 'playlist' ? videoMetadata.entries[Number(selectedPlaylistVideoIndex) - 1].title : 'Unknown' } - {selectedFormatExtensionMsg} ({selectedFormat?.resolution ? selectedFormat.resolution : 'unknown'}) {selectedFormat?.dynamic_range && selectedFormat.dynamic_range !== 'SDR' ? selectedFormat.dynamic_range : null } {selectedSubtitles.length > 0 ? `• ESUB` : null} • {selectedFormat?.filesize_approx ? formatFileSize(selectedFormat?.filesize_approx) : 'unknown filesize'} + {selectedFormatFinalMsg}
saveSettingsKey('prefer_video_over_playlist', checked)} />
-
-

Show Downloadable Streams Only (Strict)

-

Check, filter-out and show the streams that are actualy downloadable (high quality results, takes longer time to search, start a download)

+
+

Strict Downloadablity Check

+

Only show streams that are actualy downloadable, also check formats before downloading (high quality results, takes longer time to search)

saveSettingsKey('show_downloadable_streams_only', checked)} + id="strict-downloadablity-check" + checked={strictDownloadabilityCheck} + onCheckedChange={(checked) => saveSettingsKey('strict_downloadablity_check', checked)} />
@@ -507,7 +507,7 @@ export default function SettingsPage() {

Proxy

-

Use proxy for downloads, Unblocks blocked sites in your region (Download speed may affect, Some sites may not work)

+

Use proxy for downloads, Unblocks blocked sites in your region (download speed may affect, some sites may not work)

openLink('https://chromewebstore.google.com/detail/neo-downloader-plus/mehopeailfjmiloiiohgicphlcgpompf', 'arc')}>Arc
-

* These links opens with coresponding browsers only. Make sure the browser is installed befor clicking the link

+

* These links opens with coresponding browsers only. Make sure the browser is installed before clicking the link

diff --git a/src/services/store.ts b/src/services/store.ts index c4721be..2f53720 100644 --- a/src/services/store.ts +++ b/src/services/store.ts @@ -42,12 +42,18 @@ export const useCurrentVideoMetadataStore = create((s })); export const useDownloaderPageStatesStore = create((set) => ({ + activeDownloadModeTab: 'selective', isStartingDownload: false, - selctedDownloadFormat: 'best', + selectedDownloadFormat: 'best', + selectedCombinableVideoFormat: '', + selectedCombinableAudioFormat: '', selectedSubtitles: [], selectedPlaylistVideoIndex: '1', + setActiveDownloadModeTab: (tab) => set(() => ({ activeDownloadModeTab: tab })), setIsStartingDownload: (isStarting) => set(() => ({ isStartingDownload: isStarting })), - setSelctedDownloadFormat: (format) => set(() => ({ selctedDownloadFormat: format })), + setSelectedDownloadFormat: (format) => set(() => ({ selectedDownloadFormat: format })), + setSelectedCombinableVideoFormat: (format) => set(() => ({ selectedCombinableVideoFormat: format })), + setSelectedCombinableAudioFormat: (format) => set(() => ({ selectedCombinableAudioFormat: format })), setSelectedSubtitles: (subtitles) => set(() => ({ selectedSubtitles: subtitles })), setSelectedPlaylistVideoIndex: (index) => set(() => ({ selectedPlaylistVideoIndex: index })) })); @@ -107,7 +113,7 @@ export const useSettingsPageStatesStore = create((set) theme: 'system', download_dir: '', prefer_video_over_playlist: true, - show_downloadable_streams_only: false, + strict_downloadablity_check: false, max_parallel_downloads: 2, use_proxy: false, proxy_url: '', @@ -148,7 +154,7 @@ export const useSettingsPageStatesStore = create((set) theme: 'system', download_dir: '', prefer_video_over_playlist: true, - show_downloadable_streams_only: false, + strict_downloadablity_check: false, max_parallel_downloads: 2, use_proxy: false, proxy_url: '', diff --git a/src/types/settings.ts b/src/types/settings.ts index f3f8f4c..bdf41fd 100644 --- a/src/types/settings.ts +++ b/src/types/settings.ts @@ -10,7 +10,7 @@ export interface Settings { download_dir: string; max_parallel_downloads: number; prefer_video_over_playlist: boolean; - show_downloadable_streams_only: boolean; + strict_downloadablity_check: boolean; use_proxy: boolean; proxy_url: string; video_format: string; diff --git a/src/types/store.ts b/src/types/store.ts index 4e4e172..4ff0e01 100644 --- a/src/types/store.ts +++ b/src/types/store.ts @@ -31,12 +31,18 @@ export interface CurrentVideoMetadataStore { } export interface DownloaderPageStatesStore { + activeDownloadModeTab: string; isStartingDownload: boolean; - selctedDownloadFormat: string; + selectedDownloadFormat: string; + selectedCombinableVideoFormat: string; + selectedCombinableAudioFormat: string; selectedSubtitles: string[]; selectedPlaylistVideoIndex: string; + setActiveDownloadModeTab: (tab: string) => void; setIsStartingDownload: (isStarting: boolean) => void; - setSelctedDownloadFormat: (format: string) => void; + setSelectedDownloadFormat: (format: string) => void; + setSelectedCombinableVideoFormat: (format: string) => void; + setSelectedCombinableAudioFormat: (format: string) => void; setSelectedSubtitles: (subtitles: string[]) => void; setSelectedPlaylistVideoIndex: (index: string) => void; }