diff --git a/app/(auth)/(tabs)/(home)/downloads/index.tsx b/app/(auth)/(tabs)/(home)/downloads/index.tsx index 1bd33ba2..07d3dbc5 100644 --- a/app/(auth)/(tabs)/(home)/downloads/index.tsx +++ b/app/(auth)/(tabs)/(home)/downloads/index.tsx @@ -90,6 +90,19 @@ export default function page() { } }, [downloadedFiles]); + const otherMedia = useMemo(() => { + try { + return ( + downloadedFiles?.filter( + (f) => f.item.Type !== "Movie" && f.item.Type !== "Episode", + ) || [] + ); + } catch { + setShowMigration(true); + return []; + } + }, [downloadedFiles]); + useEffect(() => { navigation.setOptions({ headerRight: () => ( @@ -128,8 +141,30 @@ export default function page() { writeToLog("ERROR", reason); toast.error(t("home.downloads.toasts.failed_to_delete_all_tvseries")); }); + const deleteOtherMedia = () => + Promise.all( + otherMedia.map((item) => + deleteFileByType(item.item.Type) + .then(() => + toast.success( + t("home.downloads.toasts.deleted_media_successfully", { + type: item.item.Type, + }), + ), + ) + .catch((reason) => { + writeToLog("ERROR", reason); + toast.error( + t("home.downloads.toasts.failed_to_delete_media", { + type: item.item.Type, + }), + ); + }), + ), + ); + const deleteAllMedia = async () => - await Promise.all([deleteMovies(), deleteShows()]); + await Promise.all([deleteMovies(), deleteShows(), deleteOtherMedia()]); return ( <> @@ -238,6 +273,34 @@ export default function page() { )} + + {otherMedia.length > 0 && ( + + + + {t("home.downloads.other_media")} + + + + {otherMedia?.length} + + + + + + {otherMedia?.map((item) => ( + + + + ))} + + + + )} {downloadedFiles?.length === 0 && ( @@ -273,6 +336,11 @@ export default function page() { + {otherMedia.length > 0 && ( + + )} diff --git a/components/downloads/MovieCard.tsx b/components/downloads/MovieCard.tsx index e9c8ab97..b0a5d555 100644 --- a/components/downloads/MovieCard.tsx +++ b/components/downloads/MovieCard.tsx @@ -37,7 +37,7 @@ export const MovieCard: React.FC = ({ item }) => { */ const handleDeleteFile = useCallback(() => { if (item.Id) { - deleteFile(item.Id, "Movie"); + deleteFile(item.Id, item.Type); } }, [deleteFile, item.Id]); diff --git a/providers/DownloadProvider.tsx b/providers/DownloadProvider.tsx index 4306b8d6..ffb15e9e 100644 --- a/providers/DownloadProvider.tsx +++ b/providers/DownloadProvider.tsx @@ -301,7 +301,7 @@ function useDownloadProvider() { return db.movies[id]; } - // If not in movies, check episodes + // Check episodes for (const series of Object.values(db.series)) { for (const season of Object.values(series.seasons)) { for (const episode of Object.values(season.episodes)) { @@ -312,6 +312,11 @@ function useDownloadProvider() { } } + // Check other media types + if (db.other[id]) { + return db.other[id]; + } + return undefined; }; @@ -348,7 +353,7 @@ function useDownloadProvider() { if (file) { return JSON.parse(file) as DownloadsDatabase; } - return { movies: {}, series: {} }; + return { movies: {}, series: {}, other: {} }; // Initialize other media types storage }; const getDownloadedItems = () => { @@ -360,6 +365,7 @@ function useDownloadProvider() { Object.values(season.episodes), ), ), + ...Object.values(db.other), // Include other media types in results ]; return allItems; }; @@ -658,6 +664,9 @@ function useDownloadProvider() { db.series[item.SeriesId].seasons[seasonNumber].episodes[ episodeNumber ] = downloadedItem; + } else if (item.Id) { + // Handle other media types + db.other[item.Id] = downloadedItem; } await saveDownloadsDatabase(db); @@ -856,16 +865,16 @@ function useDownloadProvider() { [authHeader, startDownload], ); - const deleteFile = async (id: string, type: "Movie" | "Episode") => { + const deleteFile = async (id: string, type: BaseItemDto["Type"]) => { const db = getDownloadsDatabase(); let downloadedItem: DownloadedItem | undefined; - if (type === "Movie") { + if (type === "Movie" && Object.entries(db.movies).length !== 0) { downloadedItem = db.movies[id]; if (downloadedItem) { delete db.movies[id]; } - } else if (type === "Episode") { + } else if (type === "Episode" && Object.entries(db.series).length !== 0) { const cleanUpEmptyParents = ( series: any, seasonNumber: string, @@ -895,6 +904,12 @@ function useDownloadProvider() { } if (downloadedItem) break; } + } else { + // Handle other media types + downloadedItem = db.other[id]; + if (downloadedItem) { + delete db.other[id]; + } } if (downloadedItem?.videoFilePath) { @@ -928,7 +943,7 @@ function useDownloadProvider() { const deleteItems = async (items: BaseItemDto[]) => { for (const item of items) { - if (item.Id && (item.Type === "Movie" || item.Type === "Episode")) { + if (item.Id) { await deleteFile(item.Id, item.Type); } } @@ -970,6 +985,8 @@ function useDownloadProvider() { const db = getDownloadsDatabase(); if (db.movies[itemId]) { db.movies[itemId] = updatedItem; + } else if (db.other[itemId]) { + db.other[itemId] = updatedItem; } else { for (const series of Object.values(db.series)) { for (const season of Object.values(series.seasons)) { diff --git a/providers/Downloads/types.ts b/providers/Downloads/types.ts index cff87ddf..8eb6833f 100644 --- a/providers/Downloads/types.ts +++ b/providers/Downloads/types.ts @@ -88,6 +88,8 @@ export interface DownloadsDatabase { movies: Record; /** A map of series IDs to their downloaded series data. */ series: Record; + /** A map of IDs to downloaded items that are neither movies nor episodes */ + other: Record; } /** diff --git a/translations/en.json b/translations/en.json index 8578567a..82723427 100644 --- a/translations/en.json +++ b/translations/en.json @@ -237,12 +237,14 @@ "tvseries": "TV-Series", "movies": "Movies", "queue": "Queue", + "other_media": "Other media", "queue_hint": "Queue and downloads will be lost on app restart", "no_items_in_queue": "No Items in Queue", "no_downloaded_items": "No Downloaded Items", "delete_all_movies_button": "Delete All Movies", "delete_all_tvseries_button": "Delete All TV-Series", "delete_all_button": "Delete All", + "delete_all_other_media_button": "Delete other media", "active_download": "Active Download", "no_active_downloads": "No Active Downloads", "active_downloads": "Active Downloads", @@ -259,6 +261,8 @@ "failed_to_delete_all_movies": "Failed to Delete All Movies", "deleted_all_tvseries_successfully": "Deleted All TV-Series Successfully!", "failed_to_delete_all_tvseries": "Failed to Delete All TV-Series", + "deleted_media_successfully": "Deleted other media Successfully!", + "failed_to_delete_media": "Failed to Delete other media", "download_deleted": "Download Deleted", "could_not_delete_download": "Could Not Delete Download", "download_paused": "Download Paused",