import { Button } from "@/components/ui/button"; import { toast } from "sonner"; import { useAppContext } from "@/providers/appContextProvider"; import { useDownloaderPageStatesStore, useSettingsPageStatesStore } from "@/services/store"; import { formatBitrate, formatFileSize } from "@/utils"; import { Loader2, Music, Video, File, AlertCircleIcon, Settings2 } from "lucide-react"; import { useEffect, useRef } from "react"; import { RawVideoInfo, VideoFormat } from "@/types/video"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import { Label } from "@/components/ui/label"; import { Switch } from "@/components/ui/switch"; import { Checkbox } from "@/components/ui/checkbox"; interface DownloadConfigDialogProps { selectedFormatFileType: "video+audio" | "video" | "audio" | "unknown"; } interface BottomBarProps { videoMetadata: RawVideoInfo; selectedFormat: VideoFormat | undefined; selectedFormatFileType: "video+audio" | "video" | "audio" | "unknown"; selectedVideoFormat: VideoFormat | undefined; selectedAudioFormats: VideoFormat[] | undefined; containerRef: React.RefObject; } function DownloadConfigDialog({ selectedFormatFileType }: DownloadConfigDialogProps) { const activeDownloadModeTab = useDownloaderPageStatesStore((state) => state.activeDownloadModeTab); const activeDownloadConfigurationTab = useDownloaderPageStatesStore((state) => state.activeDownloadConfigurationTab); const selectedDownloadFormat = useDownloaderPageStatesStore((state) => state.selectedDownloadFormat); const selectedCombinableVideoFormat = useDownloaderPageStatesStore((state) => state.selectedCombinableVideoFormat); const selectedCombinableAudioFormats = useDownloaderPageStatesStore((state) => state.selectedCombinableAudioFormats); const downloadConfiguration = useDownloaderPageStatesStore((state) => state.downloadConfiguration); const setActiveDownloadConfigurationTab = useDownloaderPageStatesStore((state) => state.setActiveDownloadConfigurationTab); const setDownloadConfigurationKey = useDownloaderPageStatesStore((state) => state.setDownloadConfigurationKey); const embedVideoMetadata = useSettingsPageStatesStore(state => state.settings.embed_video_metadata); const embedAudioMetadata = useSettingsPageStatesStore(state => state.settings.embed_audio_metadata); const embedVideoThumbnail = useSettingsPageStatesStore(state => state.settings.embed_video_thumbnail); const embedAudioThumbnail = useSettingsPageStatesStore(state => state.settings.embed_audio_thumbnail); const useCustomCommands = useSettingsPageStatesStore(state => state.settings.use_custom_commands); const customCommands = useSettingsPageStatesStore(state => state.settings.custom_commands); const isCombineableAudioSelected = selectedCombinableAudioFormats && selectedCombinableAudioFormats.length > 0; return (

Configurations

Configurations Tweak this download's configurations
setActiveDownloadConfigurationTab(tab)} > Options Commands {useCustomCommands ? ( Options Unavailable! You cannot use these options when custom commands are enabled. To use these options, disable custom commands from Settings. ) : null}
{(selectedFormatFileType && (selectedFormatFileType === 'video' || selectedFormatFileType === 'video+audio')) || activeDownloadModeTab === 'combine' ? ( setDownloadConfigurationKey('output_format', value)} disabled={useCustomCommands} >
) : selectedFormatFileType && selectedFormatFileType === 'audio' ? ( setDownloadConfigurationKey('output_format', value)} disabled={useCustomCommands} >
) : ( setDownloadConfigurationKey('output_format', value)} disabled={useCustomCommands} >
)}
setDownloadConfigurationKey('sponsorblock', value)} disabled={useCustomCommands} >
setDownloadConfigurationKey('embed_metadata', checked)} disabled={useCustomCommands} />
setDownloadConfigurationKey('embed_thumbnail', checked)} disabled={useCustomCommands} />
setDownloadConfigurationKey('square_crop_thumbnail', checked)} disabled={useCustomCommands || !(downloadConfiguration.embed_thumbnail !== null ? downloadConfiguration.embed_thumbnail : (selectedFormatFileType && (selectedFormatFileType === 'video' || selectedFormatFileType === 'video+audio')) || activeDownloadModeTab === 'combine' ? embedVideoThumbnail : selectedFormatFileType && selectedFormatFileType === 'audio' ? embedAudioThumbnail : false)} />
{!useCustomCommands ? ( Enable Custom Commands! To run custom commands for downloads, please enable it from the Settings. ) : null}
{customCommands.length === 0 ? (

NO CUSTOM COMMAND TEMPLATE ADDED YET!

) : ( setDownloadConfigurationKey('custom_command', value)} > {customCommands.map((command) => (
))}
)}
); } export function BottomBar({ videoMetadata, selectedFormat, selectedFormatFileType, selectedVideoFormat, selectedAudioFormats, containerRef }: BottomBarProps) { const { startDownload } = useAppContext(); const activeDownloadModeTab = useDownloaderPageStatesStore((state) => state.activeDownloadModeTab); const isStartingDownload = useDownloaderPageStatesStore((state) => state.isStartingDownload); const selectedDownloadFormat = useDownloaderPageStatesStore((state) => state.selectedDownloadFormat); const selectedCombinableVideoFormat = useDownloaderPageStatesStore((state) => state.selectedCombinableVideoFormat); const selectedCombinableAudioFormats = useDownloaderPageStatesStore((state) => state.selectedCombinableAudioFormats); const selectedSubtitles = useDownloaderPageStatesStore((state) => state.selectedSubtitles); const selectedPlaylistVideos = useDownloaderPageStatesStore((state) => state.selectedPlaylistVideos); const downloadConfiguration = useDownloaderPageStatesStore((state) => state.downloadConfiguration); const setActiveDownloadConfigurationTab = useDownloaderPageStatesStore((state) => state.setActiveDownloadConfigurationTab); const setIsStartingDownload = useDownloaderPageStatesStore((state) => state.setIsStartingDownload); const videoFormat = useSettingsPageStatesStore(state => state.settings.video_format); const audioFormat = useSettingsPageStatesStore(state => state.settings.audio_format); const useSponsorblock = useSettingsPageStatesStore(state => state.settings.use_sponsorblock); const useCustomCommands = useSettingsPageStatesStore(state => state.settings.use_custom_commands); const bottomBarRef = useRef(null); const isPlaylist = videoMetadata._type === 'playlist'; const isMultiplePlaylistItems = isPlaylist && selectedPlaylistVideos.length > 1; const isCombineableAudioSelected = selectedCombinableAudioFormats && selectedCombinableAudioFormats.length > 0 && selectedAudioFormats && selectedAudioFormats.length > 0; const isMultipleCombineableAudioSelected = selectedCombinableAudioFormats && selectedCombinableAudioFormats.length > 1 && selectedAudioFormats && selectedAudioFormats.length > 1; let selectedFormatExtensionMsg = 'Auto - unknown'; if (activeDownloadModeTab === 'combine') { if (downloadConfiguration.output_format && downloadConfiguration.output_format !== 'auto') { selectedFormatExtensionMsg = `Combined - ${downloadConfiguration.output_format.toUpperCase()}`; } else if (videoFormat !== 'auto') { selectedFormatExtensionMsg = `Combined - ${videoFormat.toUpperCase()}`; } else if (isCombineableAudioSelected && selectedVideoFormat?.ext) { if (isMultipleCombineableAudioSelected) { selectedFormatExtensionMsg = `Combined - ${selectedVideoFormat.ext.toUpperCase()} + ${selectedAudioFormats.length} Audio`; } else { selectedFormatExtensionMsg = `Combined - ${selectedVideoFormat.ext.toUpperCase()} + ${selectedAudioFormats[0].ext.toUpperCase()}`; } } else { selectedFormatExtensionMsg = `Combined - unknown`; } } else if (selectedFormat?.ext) { if ((selectedFormatFileType === 'video+audio' || selectedFormatFileType === 'video') && ((downloadConfiguration.output_format && downloadConfiguration.output_format !== 'auto') || videoFormat !== 'auto')) { selectedFormatExtensionMsg = `Forced - ${(downloadConfiguration.output_format && downloadConfiguration.output_format !== 'auto') ? downloadConfiguration.output_format.toUpperCase() : videoFormat.toUpperCase()}`; } else if (selectedFormatFileType === 'audio' && ((downloadConfiguration.output_format && downloadConfiguration.output_format !== 'auto') || audioFormat !== 'auto')) { selectedFormatExtensionMsg = `Forced - ${(downloadConfiguration.output_format && downloadConfiguration.output_format !== 'auto') ? downloadConfiguration.output_format.toUpperCase() : audioFormat.toUpperCase()}`; } else if (selectedFormatFileType === 'unknown' && downloadConfiguration.output_format && downloadConfiguration.output_format !== 'auto') { selectedFormatExtensionMsg = `Forced - ${downloadConfiguration.output_format.toUpperCase()}`; } else { selectedFormatExtensionMsg = `Auto - ${selectedFormat.ext.toUpperCase()}`; } } let selectedFormatResolutionMsg = 'unknown'; let totalTbr = 0; if (activeDownloadModeTab === 'combine') { if (isCombineableAudioSelected) { if (isMultipleCombineableAudioSelected) { const totalAudioTbr = selectedAudioFormats.reduce((acc, format) => acc + (format.tbr ?? 0), 0); totalTbr = (selectedVideoFormat?.tbr ?? 0) + totalAudioTbr; selectedFormatResolutionMsg = `${selectedVideoFormat?.resolution ?? 'unknown'} + ${formatBitrate(totalAudioTbr)}`; } else { totalTbr = (selectedVideoFormat?.tbr ?? 0) + (selectedAudioFormats && selectedAudioFormats[0].tbr ? selectedAudioFormats[0].tbr : 0); selectedFormatResolutionMsg = `${selectedVideoFormat?.resolution ?? 'unknown'} + ${selectedAudioFormats && selectedAudioFormats[0].tbr ? formatBitrate(selectedAudioFormats[0].tbr) : 'unknown'}`; } } else { totalTbr = selectedVideoFormat?.tbr ?? 0; selectedFormatResolutionMsg = `${selectedVideoFormat?.resolution ?? 'unknown'} + unknown`; } } else if (selectedFormat?.resolution) { totalTbr = selectedFormat.tbr ?? 0; selectedFormatResolutionMsg = selectedFormat.resolution; } let selectedFormatDynamicRangeMsg = ''; if (activeDownloadModeTab === 'combine') { selectedFormatDynamicRangeMsg = selectedVideoFormat?.dynamic_range && selectedVideoFormat.dynamic_range !== 'SDR' && selectedVideoFormat.dynamic_range !== 'auto' ? selectedVideoFormat.dynamic_range : ''; } else if (selectedFormat?.dynamic_range && selectedFormat.dynamic_range !== 'SDR' && selectedFormat.dynamic_range !== 'auto') { selectedFormatDynamicRangeMsg = selectedFormat.dynamic_range; } let selectedFormatFileSizeMsg = 'unknown filesize'; let totalFilesize = 0; if (activeDownloadModeTab === 'combine') { if (isCombineableAudioSelected) { if (isMultipleCombineableAudioSelected) { totalFilesize = (selectedVideoFormat?.filesize_approx ?? 0) + selectedAudioFormats.reduce((acc, format) => acc + (format.filesize_approx ?? 0), 0); selectedFormatFileSizeMsg = totalFilesize > 0 ? formatFileSize(totalFilesize) : 'unknown filesize'; } else { totalFilesize = (selectedVideoFormat?.filesize_approx ?? 0) + (selectedAudioFormats && selectedAudioFormats[0].filesize_approx ? selectedAudioFormats[0].filesize_approx : 0); selectedFormatFileSizeMsg = (selectedVideoFormat?.filesize_approx && selectedAudioFormats && selectedAudioFormats[0].filesize_approx) ? formatFileSize(selectedVideoFormat.filesize_approx + selectedAudioFormats[0].filesize_approx) : 'unknown filesize'; } } else { totalFilesize = selectedVideoFormat?.filesize_approx ?? 0; selectedFormatFileSizeMsg = selectedVideoFormat?.filesize_approx ? formatFileSize(selectedVideoFormat.filesize_approx) : 'unknown filesize'; } } else if (selectedFormat?.filesize_approx) { totalFilesize = selectedFormat.filesize_approx; selectedFormatFileSizeMsg = formatFileSize(selectedFormat.filesize_approx); } let selectedFormatFinalMsg = ''; if (activeDownloadModeTab === 'combine') { if (selectedCombinableVideoFormat && selectedCombinableAudioFormats.length > 0) { selectedFormatFinalMsg = `${selectedFormatExtensionMsg} (${selectedFormatResolutionMsg}) ${selectedFormatDynamicRangeMsg} ${selectedSubtitles.length > 0 ? `• ESUB` : ''} ${useSponsorblock || (downloadConfiguration.sponsorblock && downloadConfiguration.sponsorblock !== 'auto') ? `• SPBLOCK` : ''} • ${selectedFormatFileSizeMsg}`; } else { selectedFormatFinalMsg = `Choose a video and audio streams to combine`; } } else { if (selectedFormat) { selectedFormatFinalMsg = `${selectedFormatExtensionMsg} (${selectedFormatResolutionMsg}) ${selectedFormatDynamicRangeMsg} ${selectedSubtitles.length > 0 ? `• ESUB` : ''} ${useSponsorblock || (downloadConfiguration.sponsorblock && downloadConfiguration.sponsorblock !== 'auto') ? `• SPBLOCK` : ''} • ${selectedFormatFileSizeMsg}`; } else { selectedFormatFinalMsg = `Select a stream to download`; } } useEffect(() => { const updateBottomBarWidth = (): void => { if (containerRef.current && bottomBarRef.current) { bottomBarRef.current.style.width = `${containerRef.current.offsetWidth}px`; const containerRect = containerRef.current.getBoundingClientRect(); bottomBarRef.current.style.left = `${containerRect.left}px`; } }; updateBottomBarWidth(); const resizeObserver = new ResizeObserver(() => { updateBottomBarWidth(); }); if (containerRef.current) { resizeObserver.observe(containerRef.current); } window.addEventListener('resize', updateBottomBarWidth); window.addEventListener('scroll', updateBottomBarWidth); return () => { resizeObserver.disconnect(); window.removeEventListener('resize', updateBottomBarWidth); window.removeEventListener('scroll', updateBottomBarWidth); }; }, []); useEffect(() => { useCustomCommands ? setActiveDownloadConfigurationTab('commands') : setActiveDownloadConfigurationTab('options'); }, []); return (
{activeDownloadModeTab === 'combine' && (
{videoMetadata._type === 'video' ? videoMetadata.title : videoMetadata._type === 'playlist' ? selectedPlaylistVideos.length === 1 ? videoMetadata.entries[Number(selectedPlaylistVideos[0]) - 1].title : `${selectedPlaylistVideos.length} Items` : 'Unknown' } {selectedFormatFinalMsg}
); }