From 7b035411c076e911104e3b9a003b9bbdc7df9f5c Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 18 Dec 2023 13:54:12 +0100 Subject: [PATCH] Fix download button errors --- .../ui/src/components/context-menus.tsx | 30 +++++++++-- front/packages/ui/src/downloads/page.tsx | 5 +- front/packages/ui/src/downloads/state.tsx | 53 +++++++++++-------- front/packages/ui/src/home/recommanded.tsx | 9 +++- 4 files changed, 68 insertions(+), 29 deletions(-) diff --git a/front/packages/ui/src/components/context-menus.tsx b/front/packages/ui/src/components/context-menus.tsx index 1aef55e5..80ae18eb 100644 --- a/front/packages/ui/src/components/context-menus.tsx +++ b/front/packages/ui/src/components/context-menus.tsx @@ -27,21 +27,27 @@ import Download from "@material-symbols/svg-400/rounded/download.svg"; import { WatchStatusV, queryFn, useAccount } from "@kyoo/models"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { watchListIcon } from "./watchlist-info"; -import { downloadFile } from "../downloads/state"; +import { useDownloader } from "../downloads/state"; +import { Platform } from "react-native"; +import { useYoshiki } from "yoshiki/native"; export const EpisodesContext = ({ type = "episode", slug, showSlug, status, + force, ...props }: { type?: "show" | "movie" | "episode"; showSlug?: string | null; slug: string; status: WatchStatusV | null; + force?: boolean; } & Partial>>) => { const account = useAccount(); + const downloader = useDownloader(); + const { css } = useYoshiki(); const { t } = useTranslation(); const queryClient = useQueryClient(); @@ -55,7 +61,12 @@ export const EpisodesContext = ({ }); return ( - + {showSlug && ( )} @@ -80,7 +91,7 @@ export const EpisodesContext = ({ downloadFile(type, slug)} + onSelect={() => downloader(type, slug)} /> )} @@ -91,11 +102,22 @@ export const ItemContext = ({ type, slug, status, + force, ...props }: { type: "movie" | "show"; slug: string; status: WatchStatusV | null; + force?: boolean; } & Partial>>) => { - return ; + return ( + + ); }; diff --git a/front/packages/ui/src/downloads/page.tsx b/front/packages/ui/src/downloads/page.tsx index 8cd2a6cc..47c0edc8 100644 --- a/front/packages/ui/src/downloads/page.tsx +++ b/front/packages/ui/src/downloads/page.tsx @@ -22,6 +22,7 @@ import { useAtomValue } from "jotai"; import { downloadAtom } from "./state"; import { FlashList } from "@shopify/flash-list"; import { View } from "react-native"; +import { P } from "@kyoo/primitives"; export const DownloadPage = () => { const downloads = useAtomValue(downloadAtom); @@ -29,9 +30,7 @@ export const DownloadPage = () => { return ( { - {item.data.name}; - }} + renderItem={({ item }) =>

{item.data.name}

} keyExtractor={(x) => x.data.id} numColumns={1} /> diff --git a/front/packages/ui/src/downloads/state.tsx b/front/packages/ui/src/downloads/state.tsx index f7641769..3aa6c837 100644 --- a/front/packages/ui/src/downloads/state.tsx +++ b/front/packages/ui/src/downloads/state.tsx @@ -35,6 +35,7 @@ import { Player } from "../player"; import { atom, useSetAtom, PrimitiveAtom, useStore } from "jotai"; import { getCurrentAccount, storage } from "@kyoo/models/src/account-internal"; import { ReactNode, useEffect } from "react"; +import { Platform, ToastAndroid } from "react-native"; type State = { status: "DOWNLOADING" | "PAUSED" | "DONE" | "FAILED" | "STOPPED"; @@ -111,9 +112,13 @@ const setupDownloadTask = ( update((x) => ({ ...x, percent: 100, status: "DONE" })); // apparently this is needed for ios /shrug i'm totaly gona forget this // if i ever implement ios so keeping this here - RNBackgroundDownloader.completeHandler(task.id); + if (Platform.OS === "ios") RNBackgroundDownloader.completeHandler(task.id); }) - .error((error) => update((x) => ({ ...x, status: "FAILED", error }))); + .error((error) => { + update((x) => ({ ...x, status: "FAILED", error })); + console.error(`Error downloading ${state.data.slug}`, error); + ToastAndroid.show(`Error downloading ${state.data.slug}`, ToastAndroid.LONG); + }); return { data: state.data, info: state.info, path: state.path, state: stateAtom }; }; @@ -146,27 +151,33 @@ export const useDownloader = () => { const store = useStore(); return async (type: "episode" | "movie", slug: string) => { - const account = getCurrentAccount()!; - const [data, info] = await Promise.all([ - query(Player.query(type, slug), account), - query(Player.infoQuery(type, slug), account), - ]); + try { + const account = getCurrentAccount()!; + const [data, info] = await Promise.all([ + query(Player.query(type, slug), account), + query(Player.infoQuery(type, slug), account), + ]); - // TODO: support custom paths - const path = `${RNBackgroundDownloader.directories.documents}/${slug}-${data.id}.${info.extension}`; - const task = RNBackgroundDownloader.download({ - id: data.id, - // TODO: support variant qualities - url: `${account.apiUrl}/api/video/${type}/${slug}/direct`, - destination: path, - headers: { - Authorization: account.token.access_token, - }, - // TODO: Implement only wifi - // network: Network.ALL, - }); + // TODO: support custom paths + const path = `${RNBackgroundDownloader.directories.documents}/${slug}-${data.id}.${info.extension}`; + const task = RNBackgroundDownloader.download({ + id: data.id, + // TODO: support variant qualities + url: `${account.apiUrl}/video/${type}/${slug}/direct`, + destination: path, + headers: { + Authorization: account.token.access_token, + }, + // TODO: Implement only wifi + // network: Network.ALL, + }); + console.log("Starting download", path); - setDownloads((x) => [...x, setupDownloadTask({ data, info, path }, task, store)]); + setDownloads((x) => [...x, setupDownloadTask({ data, info, path }, task, store)]); + } catch (e) { + console.error("download error", e); + ToastAndroid.show(`Error downloading ${slug}`, ToastAndroid.LONG); + } }; }; diff --git a/front/packages/ui/src/home/recommanded.tsx b/front/packages/ui/src/home/recommanded.tsx index db8fccf4..0c58a7eb 100644 --- a/front/packages/ui/src/home/recommanded.tsx +++ b/front/packages/ui/src/home/recommanded.tsx @@ -157,7 +157,13 @@ export const ItemDetails = ({ - + {slug && type && type !== "collection" && watchStatus !== undefined && ( setMoreOpened(v)} + force /> )} {(isLoading || tagline) && (