mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Comment downloader code to try newarch
This commit is contained in:
parent
ab2201a19a
commit
18f7bda090
@ -18,7 +18,6 @@
|
|||||||
"@formatjs/intl-displaynames": "^6.8.1",
|
"@formatjs/intl-displaynames": "^6.8.1",
|
||||||
"@formatjs/intl-locale": "^4.2.1",
|
"@formatjs/intl-locale": "^4.2.1",
|
||||||
"@gorhom/portal": "^1.0.14",
|
"@gorhom/portal": "^1.0.14",
|
||||||
"@kesha-antonov/react-native-background-downloader": "^3.2.1",
|
|
||||||
"@kyoo/ui": "workspace:^",
|
"@kyoo/ui": "workspace:^",
|
||||||
"@material-symbols/svg-400": "^0.25.2",
|
"@material-symbols/svg-400": "^0.25.2",
|
||||||
"@react-native-community/netinfo": "11.4.1",
|
"@react-native-community/netinfo": "11.4.1",
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@gorhom/portal": "*",
|
"@gorhom/portal": "*",
|
||||||
"@kesha-antonov/react-native-background-downloader": "*",
|
|
||||||
"@material-symbols/svg-400": "*",
|
"@material-symbols/svg-400": "*",
|
||||||
"@shopify/flash-list": "*",
|
"@shopify/flash-list": "*",
|
||||||
"@tanstack/react-query": "*",
|
"@tanstack/react-query": "*",
|
||||||
|
@ -18,9 +18,6 @@
|
|||||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import RNBackgroundDownloader, {
|
|
||||||
type DownloadTask,
|
|
||||||
} from "@kesha-antonov/react-native-background-downloader";
|
|
||||||
import {
|
import {
|
||||||
type Account,
|
type Account,
|
||||||
type Episode,
|
type Episode,
|
||||||
@ -80,75 +77,75 @@ const query = <T,>(query: QueryIdentifier<T>, info: Account): Promise<T> =>
|
|||||||
info.token.access_token,
|
info.token.access_token,
|
||||||
);
|
);
|
||||||
|
|
||||||
const setupDownloadTask = (
|
// const setupDownloadTask = (
|
||||||
state: { data: Episode | Movie; info: WatchInfo; path: string },
|
// state: { data: Episode | Movie; info: WatchInfo; path: string },
|
||||||
task: DownloadTask,
|
// task: DownloadTask,
|
||||||
store: ReturnType<typeof useStore>,
|
// store: ReturnType<typeof useStore>,
|
||||||
queryClient: QueryClient,
|
// queryClient: QueryClient,
|
||||||
stateAtom?: PrimitiveAtom<State>,
|
// stateAtom?: PrimitiveAtom<State>,
|
||||||
) => {
|
// ) => {
|
||||||
if (!stateAtom) stateAtom = atom({} as State);
|
// if (!stateAtom) stateAtom = atom({} as State);
|
||||||
store.set(stateAtom, {
|
// store.set(stateAtom, {
|
||||||
status: task.state,
|
// status: task.state,
|
||||||
progress: task.bytesTotal ? (task.bytesDownloaded / task.bytesTotal) * 100 : null,
|
// progress: task.bytesTotal ? (task.bytesDownloaded / task.bytesTotal) * 100 : null,
|
||||||
size: task.bytesTotal,
|
// size: task.bytesTotal,
|
||||||
availableSize: task.bytesDownloaded,
|
// availableSize: task.bytesDownloaded,
|
||||||
pause: () => {
|
// pause: () => {
|
||||||
task.pause();
|
// task.pause();
|
||||||
store.set(stateAtom!, (x) => ({ ...x, state: "PAUSED" }));
|
// store.set(stateAtom!, (x) => ({ ...x, state: "PAUSED" }));
|
||||||
},
|
// },
|
||||||
resume: () => {
|
// resume: () => {
|
||||||
task.resume();
|
// task.resume();
|
||||||
store.set(stateAtom!, (x) => ({ ...x, state: "DOWNLOADING" }));
|
// store.set(stateAtom!, (x) => ({ ...x, state: "DOWNLOADING" }));
|
||||||
},
|
// },
|
||||||
remove: () => {
|
// remove: () => {
|
||||||
task.stop();
|
// task.stop();
|
||||||
store.set(downloadAtom, (x) => x.filter((y) => y.data.id !== task.id));
|
// store.set(downloadAtom, (x) => x.filter((y) => y.data.id !== task.id));
|
||||||
},
|
// },
|
||||||
play: () => {
|
// play: () => {
|
||||||
ToastAndroid.show("The file has not finished downloading", ToastAndroid.LONG);
|
// ToastAndroid.show("The file has not finished downloading", ToastAndroid.LONG);
|
||||||
},
|
// },
|
||||||
retry: () => {
|
// retry: () => {
|
||||||
const [newTask, path] = download(
|
// const [newTask, path] = download(
|
||||||
{
|
// {
|
||||||
type: state.data.kind,
|
// type: state.data.kind,
|
||||||
id: state.data.id,
|
// id: state.data.id,
|
||||||
slug: state.data.slug,
|
// slug: state.data.slug,
|
||||||
extension: state.info.extension,
|
// extension: state.info.extension,
|
||||||
},
|
// },
|
||||||
getCurrentAccount()!,
|
// getCurrentAccount()!,
|
||||||
);
|
// );
|
||||||
setupDownloadTask({ ...state, path }, newTask, store, queryClient, stateAtom);
|
// setupDownloadTask({ ...state, path }, newTask, store, queryClient, stateAtom);
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
// we use the store instead of the onMount because we want to update the state to cache it even if it was not
|
// // we use the store instead of the onMount because we want to update the state to cache it even if it was not
|
||||||
// used during this launch of the app.
|
// // used during this launch of the app.
|
||||||
const update = updater(store, stateAtom);
|
// const update = updater(store, stateAtom);
|
||||||
|
//
|
||||||
task
|
// task
|
||||||
.begin(({ expectedBytes }) => update((x) => ({ ...x, size: expectedBytes })))
|
// .begin(({ expectedBytes }) => update((x) => ({ ...x, size: expectedBytes })))
|
||||||
.progress(({ bytesDownloaded, bytesTotal }) => {
|
// .progress(({ bytesDownloaded, bytesTotal }) => {
|
||||||
update((x) => ({
|
// update((x) => ({
|
||||||
...x,
|
// ...x,
|
||||||
progress: Math.round((bytesDownloaded / bytesTotal) * 100),
|
// progress: Math.round((bytesDownloaded / bytesTotal) * 100),
|
||||||
size: bytesTotal,
|
// size: bytesTotal,
|
||||||
availableSize: bytesDownloaded,
|
// availableSize: bytesDownloaded,
|
||||||
status: "DOWNLOADING",
|
// status: "DOWNLOADING",
|
||||||
}));
|
// }));
|
||||||
})
|
// })
|
||||||
.done(() => {
|
// .done(() => {
|
||||||
update((x) => ({ ...x, progress: 100, status: "DONE", play: playFn(state, queryClient) }));
|
// update((x) => ({ ...x, progress: 100, status: "DONE", play: playFn(state, queryClient) }));
|
||||||
RNBackgroundDownloader.completeHandler(task.id);
|
// RNBackgroundDownloader.completeHandler(task.id);
|
||||||
})
|
// })
|
||||||
.error(({ error }) => {
|
// .error(({ error }) => {
|
||||||
update((x) => ({ ...x, status: "FAILED", error }));
|
// update((x) => ({ ...x, status: "FAILED", error }));
|
||||||
console.error(`Error downloading ${state.data.slug}`, error);
|
// console.error(`Error downloading ${state.data.slug}`, error);
|
||||||
ToastAndroid.show(`Error downloading ${state.data.slug}`, ToastAndroid.LONG);
|
// ToastAndroid.show(`Error downloading ${state.data.slug}`, ToastAndroid.LONG);
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
return { data: state.data, info: state.info, path: state.path, state: stateAtom };
|
// return { data: state.data, info: state.info, path: state.path, state: stateAtom };
|
||||||
};
|
// };
|
||||||
|
|
||||||
const updater = (
|
const updater = (
|
||||||
store: ReturnType<typeof useStore>,
|
store: ReturnType<typeof useStore>,
|
||||||
@ -173,32 +170,32 @@ const updater = (
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const download = (
|
// const download = (
|
||||||
{
|
// {
|
||||||
type,
|
// type,
|
||||||
id,
|
// id,
|
||||||
slug,
|
// slug,
|
||||||
extension,
|
// extension,
|
||||||
}: { slug: string; id: string; type: "episode" | "movie"; extension: string },
|
// }: { slug: string; id: string; type: "episode" | "movie"; extension: string },
|
||||||
account: Account,
|
// account: Account,
|
||||||
) => {
|
// ) => {
|
||||||
// TODO: support custom paths
|
// // TODO: support custom paths
|
||||||
const path = `${RNBackgroundDownloader.directories.documents}/${slug}-${id}.${extension}`;
|
// const path = `${RNBackgroundDownloader.directories.documents}/${slug}-${id}.${extension}`;
|
||||||
const task = RNBackgroundDownloader.download({
|
// const task = RNBackgroundDownloader.download({
|
||||||
id: id,
|
// id: id,
|
||||||
// TODO: support variant qualities
|
// // TODO: support variant qualities
|
||||||
url: `${account.apiUrl}/${type}/${slug}/direct`,
|
// url: `${account.apiUrl}/${type}/${slug}/direct`,
|
||||||
destination: path,
|
// destination: path,
|
||||||
headers: {
|
// headers: {
|
||||||
Authorization: account.token.access_token,
|
// Authorization: account.token.access_token,
|
||||||
},
|
// },
|
||||||
isNotificationVisible: true,
|
// isNotificationVisible: true,
|
||||||
// TODO: Implement only wifi
|
// // TODO: Implement only wifi
|
||||||
// network: Network.ALL,
|
// // network: Network.ALL,
|
||||||
});
|
// });
|
||||||
console.log("Starting download", path);
|
// console.log("Starting download", path);
|
||||||
return [task, path] as const;
|
// return [task, path] as const;
|
||||||
};
|
// };
|
||||||
|
|
||||||
export const useDownloader = () => {
|
export const useDownloader = () => {
|
||||||
const setDownloads = useSetAtom(downloadAtom);
|
const setDownloads = useSetAtom(downloadAtom);
|
||||||
@ -206,30 +203,30 @@ export const useDownloader = () => {
|
|||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
return async (type: "episode" | "movie", slug: string) => {
|
return async (type: "episode" | "movie", slug: string) => {
|
||||||
try {
|
// try {
|
||||||
const account = getCurrentAccount()!;
|
// const account = getCurrentAccount()!;
|
||||||
const [data, info] = await Promise.all([
|
// const [data, info] = await Promise.all([
|
||||||
query(Player.query(type, slug), account),
|
// query(Player.query(type, slug), account),
|
||||||
query(Player.infoQuery(type, slug), account),
|
// query(Player.infoQuery(type, slug), account),
|
||||||
]);
|
// ]);
|
||||||
|
//
|
||||||
if (store.get(downloadAtom).find((x) => x.data.id === data.id)) {
|
// if (store.get(downloadAtom).find((x) => x.data.id === data.id)) {
|
||||||
ToastAndroid.show(`${slug} is already downloaded, skipping`, ToastAndroid.LONG);
|
// ToastAndroid.show(`${slug} is already downloaded, skipping`, ToastAndroid.LONG);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
const [task, path] = download(
|
// const [task, path] = download(
|
||||||
{ type, slug, id: data.id, extension: info.extension },
|
// { type, slug, id: data.id, extension: info.extension },
|
||||||
account,
|
// account,
|
||||||
);
|
// );
|
||||||
setDownloads((x) => [
|
// setDownloads((x) => [
|
||||||
...x,
|
// ...x,
|
||||||
setupDownloadTask({ data, info, path }, task, store, queryClient),
|
// setupDownloadTask({ data, info, path }, task, store, queryClient),
|
||||||
]);
|
// ]);
|
||||||
} catch (e) {
|
// } catch (e) {
|
||||||
console.error("download error", e);
|
// console.error("download error", e);
|
||||||
ToastAndroid.show(`Error downloading ${slug}`, ToastAndroid.LONG);
|
// ToastAndroid.show(`Error downloading ${slug}`, ToastAndroid.LONG);
|
||||||
}
|
// }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -248,61 +245,61 @@ const playFn =
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const DownloadProvider = ({ children }: { children: ReactNode }) => {
|
export const DownloadProvider = ({ children }: { children: ReactNode }) => {
|
||||||
const store = useStore();
|
// const store = useStore();
|
||||||
const queryClient = useQueryClient();
|
// const queryClient = useQueryClient();
|
||||||
|
//
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
async function run() {
|
// async function run() {
|
||||||
if (store.get(downloadAtom).length) return;
|
// if (store.get(downloadAtom).length) return;
|
||||||
|
//
|
||||||
const tasks = await RNBackgroundDownloader.checkForExistingDownloads();
|
// const tasks = await RNBackgroundDownloader.checkForExistingDownloads();
|
||||||
const dls: { data: Episode | Movie; info: WatchInfo; path: string; state: State }[] =
|
// const dls: { data: Episode | Movie; info: WatchInfo; path: string; state: State }[] =
|
||||||
JSON.parse(storage.getString("downloads") ?? "[]");
|
// JSON.parse(storage.getString("downloads") ?? "[]");
|
||||||
const downloads = dls.map((dl) => {
|
// const downloads = dls.map((dl) => {
|
||||||
const t = tasks.find((x) => x.id === dl.data.id);
|
// const t = tasks.find((x) => x.id === dl.data.id);
|
||||||
if (t) return setupDownloadTask(dl, t, store, queryClient);
|
// if (t) return setupDownloadTask(dl, t, store, queryClient);
|
||||||
|
//
|
||||||
const stateAtom = atom({
|
// const stateAtom = atom({
|
||||||
status: dl.state.status === "DONE" ? "DONE" : "FAILED",
|
// status: dl.state.status === "DONE" ? "DONE" : "FAILED",
|
||||||
progress: dl.state.progress,
|
// progress: dl.state.progress,
|
||||||
size: dl.state.size,
|
// size: dl.state.size,
|
||||||
availableSize: dl.state.availableSize,
|
// availableSize: dl.state.availableSize,
|
||||||
pause: null,
|
// pause: null,
|
||||||
resume: null,
|
// resume: null,
|
||||||
play: playFn(dl, queryClient),
|
// play: playFn(dl, queryClient),
|
||||||
remove: () => {
|
// remove: () => {
|
||||||
deleteAsync(dl.path);
|
// deleteAsync(dl.path);
|
||||||
store.set(downloadAtom, (x) => x.filter((y) => y.data.id !== dl.data.id));
|
// store.set(downloadAtom, (x) => x.filter((y) => y.data.id !== dl.data.id));
|
||||||
},
|
// },
|
||||||
retry: () => {
|
// retry: () => {
|
||||||
const [newTask, path] = download(
|
// const [newTask, path] = download(
|
||||||
{
|
// {
|
||||||
type: dl.data.kind,
|
// type: dl.data.kind,
|
||||||
id: dl.data.id,
|
// id: dl.data.id,
|
||||||
slug: dl.data.slug,
|
// slug: dl.data.slug,
|
||||||
extension: dl.info.extension,
|
// extension: dl.info.extension,
|
||||||
},
|
// },
|
||||||
getCurrentAccount()!,
|
// getCurrentAccount()!,
|
||||||
);
|
// );
|
||||||
setupDownloadTask({ ...dl, path }, newTask, store, queryClient, stateAtom);
|
// setupDownloadTask({ ...dl, path }, newTask, store, queryClient, stateAtom);
|
||||||
},
|
// },
|
||||||
} as State);
|
// } as State);
|
||||||
return {
|
// return {
|
||||||
data: z.union([EpisodeP, MovieP]).parse(dl.data),
|
// data: z.union([EpisodeP, MovieP]).parse(dl.data),
|
||||||
info: WatchInfoP.parse(dl.info),
|
// info: WatchInfoP.parse(dl.info),
|
||||||
path: dl.path,
|
// path: dl.path,
|
||||||
state: stateAtom,
|
// state: stateAtom,
|
||||||
};
|
// };
|
||||||
});
|
// });
|
||||||
store.set(downloadAtom, downloads);
|
// store.set(downloadAtom, downloads);
|
||||||
|
//
|
||||||
for (const t of tasks) {
|
// for (const t of tasks) {
|
||||||
if (!downloads.find((x) => x.data.id === t.id)) t.stop();
|
// if (!downloads.find((x) => x.data.id === t.id)) t.stop();
|
||||||
}
|
// }
|
||||||
RNBackgroundDownloader.ensureDownloadsAreRunning();
|
// RNBackgroundDownloader.ensureDownloadsAreRunning();
|
||||||
}
|
// }
|
||||||
run();
|
// run();
|
||||||
}, [store, queryClient]);
|
// }, [store, queryClient]);
|
||||||
|
|
||||||
return children;
|
return children;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user