Fix download button errors

This commit is contained in:
Zoe Roux 2023-12-18 13:54:12 +01:00
parent fb04daff9f
commit 7b035411c0
4 changed files with 68 additions and 29 deletions

View File

@ -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<ComponentProps<typeof Menu<typeof IconButton>>>) => {
const account = useAccount();
const downloader = useDownloader();
const { css } = useYoshiki();
const { t } = useTranslation();
const queryClient = useQueryClient();
@ -55,7 +61,12 @@ export const EpisodesContext = ({
});
return (
<Menu Trigger={IconButton} icon={MoreVert} {...tooltip(t("misc.more"))} {...(props as any)}>
<Menu
Trigger={IconButton}
icon={MoreVert}
{...tooltip(t("misc.more"))}
{...(css([Platform.OS !== "web" && !force && { display: "none" }], props) as any)}
>
{showSlug && (
<Menu.Item label={t("home.episodeMore.goToShow")} icon={Info} href={`/show/${showSlug}`} />
)}
@ -80,7 +91,7 @@ export const EpisodesContext = ({
<Menu.Item
label={t("home.episodeMore.download")}
icon={Download}
onSelect={() => downloadFile(type, slug)}
onSelect={() => downloader(type, slug)}
/>
)}
</Menu>
@ -91,11 +102,22 @@ export const ItemContext = ({
type,
slug,
status,
force,
...props
}: {
type: "movie" | "show";
slug: string;
status: WatchStatusV | null;
force?: boolean;
} & Partial<ComponentProps<typeof Menu<typeof IconButton>>>) => {
return <EpisodesContext type={type} slug={slug} status={status} showSlug={null} {...props} />;
return (
<EpisodesContext
type={type}
slug={slug}
status={status}
showSlug={null}
force={force}
{...props}
/>
);
};

View File

@ -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 (
<FlashList
data={downloads}
renderItem={({ item }) => {
<View>{item.data.name}</View>;
}}
renderItem={({ item }) => <P>{item.data.name}</P>}
keyExtractor={(x) => x.data.id}
numColumns={1}
/>

View File

@ -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);
}
};
};

View File

@ -157,7 +157,13 @@ export const ItemDetails = ({
<View
{...css({ flexShrink: 1, flexGrow: 1, justifyContent: "flex-end", marginBottom: px(50) })}
>
<View {...css({ flexDirection: "row-reverse", justifyContent: "space-between" })}>
<View
{...css({
flexDirection: "row-reverse",
justifyContent: "space-between",
alignContent: "flex-start",
})}
>
{slug && type && type !== "collection" && watchStatus !== undefined && (
<ItemContext
type={type}
@ -165,6 +171,7 @@ export const ItemDetails = ({
status={watchStatus}
isOpen={moreOpened}
setOpen={(v) => setMoreOpened(v)}
force
/>
)}
{(isLoading || tagline) && (