From 4e5a4a1c73bf57ec10df41a33696a773838d59e3 Mon Sep 17 00:00:00 2001 From: Subhamoy Biswas Date: Sun, 18 Jan 2026 19:11:56 +0530 Subject: [PATCH] fix: errored playlist downloads falsely showing up as completed --- src/App.tsx | 7 ++- src/components/navbar.tsx | 6 +-- src/components/pages/downloader/bottomBar.tsx | 4 +- .../pages/library/completedDownloads.tsx | 32 ++++++------ .../pages/library/incompleteDownloads.tsx | 10 ++-- .../pages/settings/applicationSettings.tsx | 12 ++--- .../pages/settings/extensionSettings.tsx | 2 +- src/components/sidebar.tsx | 21 ++------ src/helpers/use-downloader.ts | 50 ++++++++++--------- src/pages/downloader.tsx | 2 +- 10 files changed, 70 insertions(+), 76 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index ae34e94..821af72 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -107,7 +107,7 @@ export default function App({ children }: { children: React.ReactNode }) { appWindow.setFocus(); navigate('/'); if (event.payload.url) { - LOG.info('NEODLP', `Received download request from neodlp browser extension for URL: ${event.payload.url}`); + LOG.info('NEODLP', `Received search request from neodlp browser extension for URL: ${event.payload.url}`); const { setRequestedUrl, setAutoSubmitSearch } = useCurrentVideoMetadataStore.getState(); setRequestedUrl(event.payload.url); setAutoSubmitSearch(true); @@ -333,8 +333,11 @@ export default function App({ children }: { children: React.ReactNode }) { processedUnexpectedErrors.forEach((downloadId) => { const downloadState = globalDownloadStates.find(d => d.download_id === downloadId); + const isPlaylist = downloadState?.playlist_id !== null && downloadState?.playlist_indices !== null; + const isMultiplePlaylistItems = isPlaylist && downloadState?.playlist_indices && downloadState?.playlist_indices.includes(','); + toast.error("Download Failed", { - description: `The download for "${downloadState?.title}" failed because yt-dlp exited unexpectedly. Please try again later.`, + description: `The download for ${isMultiplePlaylistItems ? 'playlist ' : ''}"${isMultiplePlaylistItems ? downloadState?.playlist_title : downloadState?.title}" failed because yt-dlp exited unexpectedly. Please try again later.`, }); }); diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx index cc1d666..fe1d2ba 100644 --- a/src/components/navbar.tsx +++ b/src/components/navbar.tsx @@ -42,12 +42,12 @@ export default function Navbar() {

Logs

- + Log Viewer Monitor real-time app session logs (latest on top) -
+
{logs.length === 0 ? (

NO LOGS TO SHOW!

) : ( @@ -61,7 +61,7 @@ export default function Navbar() {
- + Dependencies Major dependencies of NeoDLP @@ -1505,7 +1505,7 @@ export function ApplicationSettings() { value={ytDlpUpdateChannel} onValueChange={(value) => saveSettingsKey('ytdlp_update_channel', value)} > - + @@ -1553,7 +1553,7 @@ export function ApplicationSettings() {
{tabsList.map((tab) => ( - + {tab.component} ))} diff --git a/src/components/pages/settings/extensionSettings.tsx b/src/components/pages/settings/extensionSettings.tsx index 4d97ceb..4c7b7ee 100644 --- a/src/components/pages/settings/extensionSettings.tsx +++ b/src/components/pages/settings/extensionSettings.tsx @@ -284,7 +284,7 @@ export function ExtensionSettings() {
{tabsList.map((tab) => ( - + {tab.component} ))} diff --git a/src/components/sidebar.tsx b/src/components/sidebar.tsx index 9105dd8..75ee11f 100644 --- a/src/components/sidebar.tsx +++ b/src/components/sidebar.tsx @@ -1,9 +1,10 @@ import { config } from "@/config"; import { Link, useLocation } from "react-router-dom"; import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarHeader, SidebarMenu, SidebarMenuButton, SidebarMenuItem, useSidebar } from "@/components/ui/sidebar"; -import { CircleArrowUp, Download, Settings, SquarePlay, } from "lucide-react"; +import { CircleArrowUp } from "lucide-react"; import { isActive as isActiveSidebarItem } from "@/utils"; import { RoutesObj } from "@/types/route"; +import { AllRoutes } from "@/routes"; import { useDownloadStatesStore, useSettingsPageStatesStore } from "@/services/store"; import { Badge } from "@/components/ui/badge"; import { useEffect, useState } from "react"; @@ -36,24 +37,12 @@ export function AppSidebar() { const [isNativeLinuxApp, setIsNativeLinuxApp] = useState(false); const topItems: Array = [ - { - title: "Downloader", - url: "/", - icon: Download, - }, - { - title: "Library", - url: "/library", - icon: SquarePlay, - } + AllRoutes[0], // Downloader + AllRoutes[1], // Library ]; const bottomItems: Array = [ - { - title: "Settings", - url: "/settings", - icon: Settings, - } + AllRoutes[2], // Settings ]; useEffect(() => { diff --git a/src/helpers/use-downloader.ts b/src/helpers/use-downloader.ts index 939ada6..31bfc22 100644 --- a/src/helpers/use-downloader.ts +++ b/src/helpers/use-downloader.ts @@ -14,6 +14,7 @@ import { ulid } from "ulid"; import { sendNotification } from '@tauri-apps/plugin-notification'; import { FetchVideoMetadataParams, StartDownloadParams } from "@/providers/appContextProvider"; import { useDebouncedCallback } from '@tanstack/react-pacer/debouncer'; +import { fetchDownloadStateById } from "@/services/database"; export default function useDownloader() { const globalDownloadStates = useDownloadStatesStore((state) => state.downloadStates); @@ -564,6 +565,9 @@ export default function useDownloader() { downloadFilePath = line.replace('Finalpath: ', '').trim().replace(/^"|"$/g, ''); const downloadedFileExt = downloadFilePath.split('.').pop(); + const state = await fetchDownloadStateById(downloadId); + const isLastPlaylistItem = state?.item && Number(state?.item.split('/')[0]) === Number(state?.item.split('/')[1]); + setTimeout(async () => { downloadFilePathUpdater.mutate({ download_id: downloadId, filepath: downloadFilePath as string, ext: downloadedFileExt as string }, { onSuccess: (data) => { @@ -574,33 +578,31 @@ export default function useDownloader() { console.error("Failed to update download filepath:", error); } }); - }, 1500); - } - if (isPlaylist && line.startsWith('[download] Finished downloading playlist:')) { - // Update completion status after a short delay to ensure database states are propagated correctly - console.log(`Playlist download completed with ID: ${downloadId}, updating status after 2s delay...`); - setTimeout(async () => { - LOG.info('NEODLP', `yt-dlp download completed with id: ${downloadId}`); - downloadStatusUpdater.mutate({ download_id: downloadId, download_status: 'completed' }, { - onSuccess: (data) => { - console.log("Download status updated successfully:", data); - queryClient.invalidateQueries({ queryKey: ['download-states'] }); - }, - onError: (error) => { - console.error("Failed to update download status:", error); - } - }); + if (isLastPlaylistItem) { + console.log(`Playlist download completed with ID: ${downloadId}, updating status...`); - toast.success(`${isMultiplePlaylistItems ? 'Playlist ' : ''}Download Completed`, { - description: `The download for ${isMultiplePlaylistItems ? 'playlist ' : ''}"${isMultiplePlaylistItems ? videoMetadata.playlist_title : videoMetadata.title}" has completed successfully.`, - }); - - if (ENABLE_NOTIFICATIONS && DOWNLOAD_COMPLETION_NOTIFICATION) { - sendNotification({ - title: `${isMultiplePlaylistItems ? 'Playlist ' : ''}Download Completed`, - body: `The download for ${isMultiplePlaylistItems ? 'playlist ' : ''}"${isMultiplePlaylistItems ? videoMetadata.playlist_title : videoMetadata.title}" has completed successfully.`, + LOG.info('NEODLP', `yt-dlp download completed with id: ${downloadId}`); + downloadStatusUpdater.mutate({ download_id: downloadId, download_status: 'completed' }, { + onSuccess: (data) => { + console.log("Download status updated successfully:", data); + queryClient.invalidateQueries({ queryKey: ['download-states'] }); + }, + onError: (error) => { + console.error("Failed to update download status:", error); + } }); + + toast.success("Download Completed", { + description: `The download for ${isMultiplePlaylistItems ? 'playlist ' : ''}"${isMultiplePlaylistItems ? videoMetadata.playlist_title : videoMetadata.title}" has completed successfully.`, + }); + + if (ENABLE_NOTIFICATIONS && DOWNLOAD_COMPLETION_NOTIFICATION) { + sendNotification({ + title: "Download Completed", + body: `The download for ${isMultiplePlaylistItems ? 'playlist ' : ''}"${isMultiplePlaylistItems ? videoMetadata.playlist_title : videoMetadata.title}" has completed successfully.`, + }); + } } }, 2000); } diff --git a/src/pages/downloader.tsx b/src/pages/downloader.tsx index 9f29f16..5a2d020 100644 --- a/src/pages/downloader.tsx +++ b/src/pages/downloader.tsx @@ -296,7 +296,7 @@ export default function DownloaderPage() {