mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Add a downloads tab
This commit is contained in:
parent
f1cc396bfc
commit
71d29a303f
@ -22,6 +22,7 @@ import { Icon } from "@kyoo/primitives";
|
||||
import { Tabs } from "expo-router";
|
||||
import Home from "@material-symbols/svg-400/rounded/home-fill.svg";
|
||||
import Browse from "@material-symbols/svg-400/rounded/browse-fill.svg";
|
||||
import Downloading from "@material-symbols/svg-400/rounded/downloading-fill.svg";
|
||||
|
||||
export default function TabsLayout() {
|
||||
return (
|
||||
@ -44,6 +45,13 @@ export default function TabsLayout() {
|
||||
tabBarIcon: ({ color, size }) => <Icon icon={Browse} color={color} size={size} />,
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="downloads"
|
||||
options={{
|
||||
tabBarLabel: "Downloads",
|
||||
tabBarIcon: ({ color, size }) => <Icon icon={Downloading} color={color} size={size} />,
|
||||
}}
|
||||
/>
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
|
23
front/apps/mobile/app/(app)/(tabs)/downloads.tsx
Normal file
23
front/apps/mobile/app/(app)/(tabs)/downloads.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Kyoo - A portable and vast media library solution.
|
||||
* Copyright (c) Kyoo.
|
||||
*
|
||||
* See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
*
|
||||
* Kyoo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Kyoo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { DownloadPage } from "@kyoo/ui";
|
||||
|
||||
export default DownloadPage;
|
@ -48,6 +48,7 @@ import "@formatjs/intl-displaynames/locale-data/fr";
|
||||
import en from "../../../translations/en.json";
|
||||
import fr from "../../../translations/fr.json";
|
||||
import { useTheme } from "yoshiki/native";
|
||||
import { DownloadProvider } from "@kyoo/ui";
|
||||
|
||||
i18next.use(initReactI18next).init({
|
||||
interpolation: {
|
||||
@ -103,9 +104,11 @@ export default function Root() {
|
||||
>
|
||||
<PortalProvider>
|
||||
<AccountProvider>
|
||||
<NavigationThemeProvider>
|
||||
<Slot />
|
||||
</NavigationThemeProvider>
|
||||
<DownloadProvider>
|
||||
<NavigationThemeProvider>
|
||||
<Slot />
|
||||
</NavigationThemeProvider>
|
||||
</DownloadProvider>
|
||||
</AccountProvider>
|
||||
</PortalProvider>
|
||||
</ThemeSelector>
|
||||
|
@ -52,6 +52,7 @@ const styleText = (
|
||||
{
|
||||
marginVertical: rem(0.5),
|
||||
color: type === "header" ? theme.heading : theme.paragraph,
|
||||
flexShrink: 1,
|
||||
fontSize: rem(1),
|
||||
fontFamily: theme.font.normal,
|
||||
},
|
||||
|
@ -27,7 +27,7 @@ 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/download";
|
||||
import { downloadFile } from "../downloads/state";
|
||||
|
||||
export const EpisodesContext = ({
|
||||
type = "episode",
|
||||
|
22
front/packages/ui/src/downloads/index.tsx
Normal file
22
front/packages/ui/src/downloads/index.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Kyoo - A portable and vast media library solution.
|
||||
* Copyright (c) Kyoo.
|
||||
*
|
||||
* See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
*
|
||||
* Kyoo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Kyoo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export { DownloadPage } from "./page";
|
||||
export { DownloadProvider } from "./state";
|
39
front/packages/ui/src/downloads/page.tsx
Normal file
39
front/packages/ui/src/downloads/page.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Kyoo - A portable and vast media library solution.
|
||||
* Copyright (c) Kyoo.
|
||||
*
|
||||
* See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
*
|
||||
* Kyoo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Kyoo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { useAtomValue } from "jotai";
|
||||
import { downloadAtom } from "./state";
|
||||
import { FlashList } from "@shopify/flash-list";
|
||||
import { View } from "react-native";
|
||||
|
||||
export const DownloadPage = () => {
|
||||
const downloads = useAtomValue(downloadAtom);
|
||||
|
||||
return (
|
||||
<FlashList
|
||||
data={downloads}
|
||||
renderItem={({ item }) => {
|
||||
<View>{item.data.name}</View>;
|
||||
}}
|
||||
keyExtractor={(x) => x.data.id}
|
||||
numColumns={1}
|
||||
/>
|
||||
);
|
||||
};
|
@ -18,13 +18,8 @@
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
download,
|
||||
completeHandler,
|
||||
directories,
|
||||
DownloadTask,
|
||||
checkForExistingDownloads,
|
||||
ensureDownloadsAreRunning,
|
||||
import RNBackgroundDownloader, {
|
||||
type DownloadTask,
|
||||
} from "@kesha-antonov/react-native-background-downloader";
|
||||
import { deleteAsync } from "expo-file-system";
|
||||
import {
|
||||
@ -39,7 +34,7 @@ import {
|
||||
import { Player } from "../player";
|
||||
import { atom, useSetAtom, PrimitiveAtom, useStore } from "jotai";
|
||||
import { getCurrentAccount, storage } from "@kyoo/models/src/account-internal";
|
||||
import { useEffect } from "react";
|
||||
import { ReactNode, useEffect } from "react";
|
||||
|
||||
type State = {
|
||||
status: "DOWNLOADING" | "PAUSED" | "DONE" | "FAILED" | "STOPPED";
|
||||
@ -53,7 +48,7 @@ type State = {
|
||||
play: () => void;
|
||||
};
|
||||
|
||||
const downloadAtom = atom<
|
||||
export const downloadAtom = atom<
|
||||
{
|
||||
data: Episode | Movie;
|
||||
info: WatchInfo;
|
||||
@ -116,7 +111,7 @@ 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
|
||||
completeHandler(task.id);
|
||||
RNBackgroundDownloader.completeHandler(task.id);
|
||||
})
|
||||
.error((error) => update((x) => ({ ...x, status: "FAILED", error })));
|
||||
|
||||
@ -158,8 +153,8 @@ export const useDownloader = () => {
|
||||
]);
|
||||
|
||||
// TODO: support custom paths
|
||||
const path = `${directories.documents}/${slug}-${data.id}.${info.extension}`;
|
||||
const task = download({
|
||||
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`,
|
||||
@ -175,14 +170,14 @@ export const useDownloader = () => {
|
||||
};
|
||||
};
|
||||
|
||||
export const DownloadProvider = () => {
|
||||
export const DownloadProvider = ({ children }: { children: ReactNode }) => {
|
||||
const store = useStore();
|
||||
|
||||
useEffect(() => {
|
||||
async function run() {
|
||||
if (store.get(downloadAtom).length) return;
|
||||
|
||||
const tasks = await checkForExistingDownloads();
|
||||
const tasks = await RNBackgroundDownloader.checkForExistingDownloads();
|
||||
const dls: { data: Episode | Movie; info: WatchInfo; path: string; state: State }[] =
|
||||
JSON.parse(storage.getString("downloads") ?? "[]");
|
||||
const downloads = dls.map((dl) => {
|
||||
@ -214,8 +209,10 @@ export const DownloadProvider = () => {
|
||||
for (const t of tasks) {
|
||||
if (!downloads.find((x) => x.data.id === t.id)) t.stop();
|
||||
}
|
||||
ensureDownloadsAreRunning();
|
||||
RNBackgroundDownloader.ensureDownloadsAreRunning();
|
||||
}
|
||||
run();
|
||||
}, [store]);
|
||||
|
||||
return children;
|
||||
};
|
@ -26,3 +26,4 @@ export { CollectionPage } from "./collection";
|
||||
export { Player } from "./player";
|
||||
export { SearchPage } from "./search";
|
||||
export { LoginPage, RegisterPage } from "./login";
|
||||
export { DownloadPage, DownloadProvider } from "./downloads";
|
||||
|
Loading…
x
Reference in New Issue
Block a user