diff --git a/src/App.tsx b/src/App.tsx index 546d102..4bef4e1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -73,7 +73,7 @@ export default function App() { ); const { items, channels, loading, error, reload } = useFeed(filter); - const live = useDownloads(reload); + const { live, clear: clearLive } = useDownloads(reload); useEffect(() => { let un: (() => void) | undefined; @@ -212,7 +212,7 @@ export default function App() { cancelDownload(item.id).catch((e) => setFailure(String(e))), onDelete: () => deleteDownload(item.id) - .then(() => { reload(); say("Download deleted"); }) + .then(() => { clearLive(item.id); reload(); say("Download deleted"); }) .catch((e) => setFailure(String(e))), }; return view === "grid" ? ( @@ -232,6 +232,7 @@ export default function App() { onClose={() => setPlaying(null)} onDelete={async () => { await deleteDownload(playing.item.id); + clearLive(playing.item.id); setPlaying(null); reload(); say("Download deleted"); diff --git a/src/hooks/useDownloads.ts b/src/hooks/useDownloads.ts index 7d84775..4a938c8 100644 --- a/src/hooks/useDownloads.ts +++ b/src/hooks/useDownloads.ts @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { onDownloadProgress, onDownloadState } from "../api"; import type { DownloadState } from "../types"; @@ -18,6 +18,20 @@ export interface LiveDownload { export function useDownloads(onFinished: () => void) { const [live, setLive] = useState>({}); + /** + * Drops a video's overlay. Required after deleting a download: the database + * row is gone, but a stale `done` entry here would keep the row showing + * "Saved" until the app restarts. + */ + const clear = useCallback((videoId: string) => { + setLive((prev) => { + if (!(videoId in prev)) return prev; + const next = { ...prev }; + delete next[videoId]; + return next; + }); + }, []); + useEffect(() => { const unlisteners: Array<() => void> = []; @@ -55,5 +69,5 @@ export function useDownloads(onFinished: () => void) { return () => unlisteners.forEach((u) => u()); }, [onFinished]); - return live; + return { live, clear }; }