From 9150fc22f7cdeec0d1796157caec9e75d86e3d2d Mon Sep 17 00:00:00 2001 From: Subhamoy Biswas Date: Sun, 26 Oct 2025 23:48:35 +0530 Subject: [PATCH] feat: added debug mode and optimized logging --- src/App.tsx | 16 +++++++-- src/components/navbar.tsx | 2 +- src/helpers/use-logger.ts | 5 ++- src/pages/library.tsx | 6 ++-- src/pages/settings.tsx | 75 +++++++++++++++++++++++++++++++++------ src/services/store.ts | 8 +++++ src/types/logs.ts | 4 +-- src/types/settings.ts | 4 +++ 8 files changed, 101 insertions(+), 19 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 095eeff..12a0021 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -88,6 +88,10 @@ export default function App({ children }: { children: React.ReactNode }) { const USE_CUSTOM_COMMANDS = useSettingsPageStatesStore(state => state.settings.use_custom_commands); const CUSTOM_COMMANDS = useSettingsPageStatesStore(state => state.settings.custom_commands); const FILENAME_TEMPLATE = useSettingsPageStatesStore(state => state.settings.filename_template); + const DEBUG_MODE = useSettingsPageStatesStore(state => state.settings.debug_mode); + const LOG_VERBOSE = useSettingsPageStatesStore(state => state.settings.log_verbose); + const LOG_WARNING = useSettingsPageStatesStore(state => state.settings.log_warning); + const LOG_PROGRESS = useSettingsPageStatesStore(state => state.settings.log_progress); const isErrored = useDownloaderPageStatesStore((state) => state.isErrored); const isErrorExpected = useDownloaderPageStatesStore((state) => state.isErrorExpected); @@ -295,7 +299,6 @@ export default function App({ children }: { children: React.ReactNode }) { '--format', selectedFormat, '--no-mtime', - '--no-warnings', '--retries', MAX_RETRIES.toString(), ]; @@ -304,6 +307,14 @@ export default function App({ children }: { children: React.ReactNode }) { args.push('--ffmpeg-location', '/Applications/NeoDLP.app/Contents/MacOS'); } + if (!DEBUG_MODE || (DEBUG_MODE && !LOG_WARNING)) { + args.push('--no-warnings'); + } + + if (DEBUG_MODE && LOG_VERBOSE) { + args.push('--verbose'); + } + if (selectedSubtitles) { args.push('--embed-subs', '--sub-lang', selectedSubtitles); } @@ -462,7 +473,7 @@ export default function App({ children }: { children: React.ReactNode }) { command.stdout.on('data', line => { if (line.startsWith('status:') || line.startsWith('[#')) { console.log(line); - LOG.info(`YT-DLP Download ${downloadId}`, line); + if (DEBUG_MODE && LOG_PROGRESS) LOG.progress(`YT-DLP Download ${downloadId}`, line); const currentProgress = parseProgressLine(line); const state: DownloadState = { download_id: downloadId, @@ -653,6 +664,7 @@ export default function App({ children }: { children: React.ReactNode }) { if (!ongoingDownloads || ongoingDownloads && ongoingDownloads?.length < MAX_PARALLEL_DOWNLOADS) { LOG.info('NEODLP', `Starting yt-dlp download with args: ${args.join(' ')}`); + if(!DEBUG_MODE || (DEBUG_MODE && !LOG_PROGRESS)) LOG.warning('NEODLP', `Progress logs are hidden. Enable 'Debug Mode > Log Progress' in Settings to unhide.`); const child = await command.spawn(); processPid = child.pid; return Promise.resolve(); diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx index 8586a85..62a50b8 100644 --- a/src/components/navbar.tsx +++ b/src/components/navbar.tsx @@ -41,7 +41,7 @@ export default function Navbar() {

NO LOGS TO SHOW!

) : ( logs.slice().reverse().map((log, index) => ( -
+

{new Date(log.timestamp).toLocaleTimeString()} [{log.level.toUpperCase()}] {log.context} :

{log.message}

diff --git a/src/helpers/use-logger.ts b/src/helpers/use-logger.ts index be872c9..4f3050e 100644 --- a/src/helpers/use-logger.ts +++ b/src/helpers/use-logger.ts @@ -18,9 +18,12 @@ export function useLogger() { debug: (context: string, message: string) => { addLog({ timestamp: Date.now(), level: 'debug', context, message }); }, + progress: (context: string, message: string) => { + addLog({ timestamp: Date.now(), level: 'progress', context, message }); + }, getLogs: () => logs, clearLogs, }; return logger; -} \ No newline at end of file +} diff --git a/src/pages/library.tsx b/src/pages/library.tsx index 90c15d3..83b0d72 100644 --- a/src/pages/library.tsx +++ b/src/pages/library.tsx @@ -6,7 +6,7 @@ import { Progress } from "@/components/ui/progress"; import { Separator } from "@/components/ui/separator"; import { toast } from "sonner"; import { useAppContext } from "@/providers/appContextProvider"; -import { useCurrentVideoMetadataStore, useDownloadActionStatesStore, useDownloadStatesStore, useLibraryPageStatesStore } from "@/services/store"; +import { useCurrentVideoMetadataStore, useDownloadActionStatesStore, useDownloadStatesStore, useLibraryPageStatesStore, useSettingsPageStatesStore } from "@/services/store"; import { formatBitrate, formatCodec, formatDurationString, formatFileSize, formatSecToTimeString, formatSpeed } from "@/utils"; import { AudioLines, Clock, File, FileAudio2, FileQuestion, FileVideo2, FolderInput, ListVideo, Loader2, Music, Pause, Play, Search, Square, Trash2, Video, X } from "lucide-react"; import { invoke } from "@tauri-apps/api/core"; @@ -34,6 +34,8 @@ export default function LibraryPage() { const setIsCancelingDownload = useDownloadActionStatesStore(state => state.setIsCancelingDownload); const setIsDeleteFileChecked = useDownloadActionStatesStore(state => state.setIsDeleteFileChecked); + const debugMode = useSettingsPageStatesStore(state => state.settings.debug_mode); + const { pauseDownload, resumeDownload, cancelDownload } = useAppContext() const queryClient = useQueryClient(); @@ -379,7 +381,7 @@ export default function LibraryPage() {
)}
{ state.download_status && ( - `${state.download_status === 'downloading' && state.status === 'finished' ? 'Processing' : state.download_status.charAt(0).toUpperCase() + state.download_status.slice(1)} ${state.download_id ? `• ID: ${state.download_id.toUpperCase()}` : ""} ${state.download_status === 'downloading' && state.status !== 'finished' && state.speed ? `• Speed: ${formatSpeed(state.speed)}` : ""} ${state.download_status === 'downloading' && state.eta ? `• ETA: ${formatSecToTimeString(state.eta)}` : ""}` + `${state.download_status === 'downloading' && state.status === 'finished' ? 'Processing' : state.download_status.charAt(0).toUpperCase() + state.download_status.slice(1)} ${debugMode && state.download_id ? `• ID: ${state.download_id.toUpperCase()}` : ""} ${state.download_status === 'downloading' && state.status !== 'finished' && state.speed ? `• Speed: ${formatSpeed(state.speed)}` : ""} ${state.download_status === 'downloading' && state.eta ? `• ETA: ${formatSecToTimeString(state.eta)}` : ""}` )}
diff --git a/src/pages/settings.tsx b/src/pages/settings.tsx index 0d9940a..77d280e 100644 --- a/src/pages/settings.tsx +++ b/src/pages/settings.tsx @@ -7,7 +7,7 @@ import { Switch } from "@/components/ui/switch"; import { Label } from "@/components/ui/label"; import { Button } from "@/components/ui/button"; import { toast } from "sonner"; -import { ArrowDownToLine, ArrowRight, BrushCleaning, Cookie, EthernetPort, ExternalLink, FileVideo, Folder, FolderOpen, Info, Loader2, LucideIcon, Monitor, Moon, Radio, RotateCcw, RotateCw, ShieldMinus, SquareTerminal, Sun, Terminal, Trash, TriangleAlert, WandSparkles, Wifi, Wrench } from "lucide-react"; +import { ArrowDownToLine, ArrowRight, BrushCleaning, Bug, Cookie, EthernetPort, ExternalLink, FileVideo, Folder, FolderOpen, Info, Loader2, LucideIcon, Monitor, Moon, Radio, RotateCcw, RotateCw, ShieldMinus, SquareTerminal, Sun, Terminal, Trash, TriangleAlert, WandSparkles, Wifi, Wrench } from "lucide-react"; import { cn } from "@/lib/utils"; import { useEffect } from "react"; import { useTheme } from "@/providers/themeProvider"; @@ -123,6 +123,10 @@ export default function SettingsPage() { const useCustomCommands = useSettingsPageStatesStore(state => state.settings.use_custom_commands); const customCommands = useSettingsPageStatesStore(state => state.settings.custom_commands); const filenameTemplate = useSettingsPageStatesStore(state => state.settings.filename_template); + const debugMode = useSettingsPageStatesStore(state => state.settings.debug_mode); + const logVerbose = useSettingsPageStatesStore(state => state.settings.log_verbose); + const logWarning = useSettingsPageStatesStore(state => state.settings.log_warning); + const logProgress = useSettingsPageStatesStore(state => state.settings.log_progress); const websocketPort = useSettingsPageStatesStore(state => state.settings.websocket_port); const isChangingWebSocketPort = useSettingsPageStatesStore(state => state.isChangingWebSocketPort); @@ -525,9 +529,14 @@ export default function SettingsPage() { value="commands" className="data-[state=active]:bg-primary data-[state=active]:text-primary-foreground justify-start px-3 py-1.5 gap-2" > Commands + Debug
- +

Max Parallel Downloads

Set maximum number of allowed parallel downloads

@@ -583,7 +592,7 @@ export default function SettingsPage() { />
- +

Theme

Choose app interface theme

@@ -606,7 +615,7 @@ export default function SettingsPage() {
- +

Download Folder

Set default download folder (directory)

@@ -696,7 +705,7 @@ export default function SettingsPage() {
- +

Video Format

Choose in which format the final video file will be saved

@@ -764,7 +773,7 @@ export default function SettingsPage() { />
- +

Embed Metadata

Wheather to embed metadata in video/audio files (info, chapters)

@@ -798,7 +807,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)

@@ -893,7 +902,7 @@ export default function SettingsPage() { onCheckedChange={(checked) => saveSettingsKey('use_force_internet_protocol', checked)} disabled={useCustomCommands} /> - +
(Forced: {forceInternetProtocol === "ipv4" ? 'IPv4' : 'IPv6'}, Status: {useForceInternetProtocol && !useCustomCommands ? 'Enabled' : 'Disabled'})
- +

Cookies

Use cookies to access exclusive/private (login-protected) contents from sites (use wisely, over-use can even block/ban your account)

@@ -1003,7 +1012,7 @@ export default function SettingsPage() {
- +

Sponsor Block

Use sponsorblock to remove/mark unwanted segments in videos (sponsorships, intros, outros, etc.)

@@ -1127,7 +1136,7 @@ export default function SettingsPage() {
- +

Custom Commands

Run custom yt-dlp commands for your downloads

@@ -1229,6 +1238,50 @@ export default function SettingsPage() {
+ +
+

Debug Mode

+

Enable debug mode for troubleshooting issues (get debug logs, download ids, and more)

+
+ saveSettingsKey('debug_mode', checked)} + /> + +
+
+ +
+ saveSettingsKey('log_verbose', checked)} + disabled={!debugMode} + /> + +
+
+ saveSettingsKey('log_warning', checked)} + disabled={!debugMode} + /> + +
+
+ saveSettingsKey('log_progress', checked)} + disabled={!debugMode} + /> + +
+
+
+
diff --git a/src/services/store.ts b/src/services/store.ts index 2da4dfa..e5cba4c 100644 --- a/src/services/store.ts +++ b/src/services/store.ts @@ -180,6 +180,10 @@ export const useSettingsPageStatesStore = create((set) use_custom_commands: false, custom_commands: [], filename_template: '%(title)s_%(resolution|unknown)s', + debug_mode: false, + log_verbose: true, + log_warning: true, + log_progress: false, // extension settings websocket_port: 53511 }, @@ -241,6 +245,10 @@ export const useSettingsPageStatesStore = create((set) use_custom_commands: false, custom_commands: [], filename_template: '%(title)s_%(resolution|unknown)s', + debug_mode: false, + log_verbose: true, + log_warning: true, + log_progress: false, // extension settings websocket_port: 53511 }, diff --git a/src/types/logs.ts b/src/types/logs.ts index 49aa57a..1cd1c43 100644 --- a/src/types/logs.ts +++ b/src/types/logs.ts @@ -1,6 +1,6 @@ export interface Log { timestamp: number; - level: 'info' | 'warning' | 'error' | 'debug'; + level: 'info' | 'warning' | 'error' | 'debug' | 'progress'; context: string; message: string; -} \ No newline at end of file +} diff --git a/src/types/settings.ts b/src/types/settings.ts index f097125..6c65830 100644 --- a/src/types/settings.ts +++ b/src/types/settings.ts @@ -44,6 +44,10 @@ export interface Settings { use_custom_commands: boolean; custom_commands: CustomCommand[]; filename_template: string; + debug_mode: boolean; + log_verbose: boolean; + log_warning: boolean; + log_progress: boolean; // extension settings websocket_port: number; }