From 0acc1f03f0f3b811aff3fcc87829f75a8afef5ad Mon Sep 17 00:00:00 2001 From: Fredrik Burmester Date: Tue, 1 Oct 2024 17:42:09 +0200 Subject: [PATCH] wip --- app/(auth)/(tabs)/(home)/settings.tsx | 17 +- app/_layout.tsx | 233 ++++++++++++++++++++++- bun.lockb | Bin 595817 -> 598559 bytes components/downloads/ActiveDownloads.tsx | 3 +- components/settings/SettingToggles.tsx | 80 ++++++-- hooks/useRemuxHlsToMp4.ts | 2 +- package.json | 1 + providers/DownloadProvider.tsx | 147 +++++++------- providers/JellyfinProvider.tsx | 40 ++-- utils/atoms/settings.ts | 4 +- utils/background-tasks.ts | 23 +++ utils/optimize-server.ts | 5 + 12 files changed, 425 insertions(+), 130 deletions(-) create mode 100644 utils/background-tasks.ts diff --git a/app/(auth)/(tabs)/(home)/settings.tsx b/app/(auth)/(tabs)/(home)/settings.tsx index a75ca44c..f0811e7c 100644 --- a/app/(auth)/(tabs)/(home)/settings.tsx +++ b/app/(auth)/(tabs)/(home)/settings.tsx @@ -2,10 +2,7 @@ import { Button } from "@/components/Button"; import { Text } from "@/components/common/Text"; import { ListItem } from "@/components/ListItem"; import { SettingToggles } from "@/components/settings/SettingToggles"; -import { - registerBackgroundFetchAsync, - useDownload, -} from "@/providers/DownloadProvider"; +import { useDownload } from "@/providers/DownloadProvider"; import { apiAtom, useJellyfin, userAtom } from "@/providers/JellyfinProvider"; import { clearLogs, readFromLog } from "@/utils/log"; import { getQuickConnectApi } from "@jellyfin/sdk/lib/utils/api"; @@ -94,18 +91,6 @@ export default function settings() { - - Tests - - - Account and storage diff --git a/app/_layout.tsx b/app/_layout.tsx index 13bfb2a9..6743024d 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -1,18 +1,27 @@ import { DownloadProvider } from "@/providers/DownloadProvider"; -import { JellyfinProvider } from "@/providers/JellyfinProvider"; +import { + getOrSetDeviceId, + getServerUrlFromStorage, + getTokenFromStoraage, + JellyfinProvider, +} from "@/providers/JellyfinProvider"; import { JobQueueProvider } from "@/providers/JobQueueProvider"; import { PlaybackProvider } from "@/providers/PlaybackProvider"; import { orientationAtom } from "@/utils/atoms/orientation"; -import { useSettings } from "@/utils/atoms/settings"; +import { Settings, useSettings } from "@/utils/atoms/settings"; import { ActionSheetProvider } from "@expo/react-native-action-sheet"; import { BottomSheetModalProvider } from "@gorhom/bottom-sheet"; -import { checkForExistingDownloads } from "@kesha-antonov/react-native-background-downloader"; +import { + checkForExistingDownloads, + completeHandler, + download, +} from "@kesha-antonov/react-native-background-downloader"; import { DarkTheme, ThemeProvider } from "@react-navigation/native"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { useFonts } from "expo-font"; import { useKeepAwake } from "expo-keep-awake"; import * as Linking from "expo-linking"; -import { Stack } from "expo-router"; +import { router, Stack } from "expo-router"; import * as ScreenOrientation from "expo-screen-orientation"; import * as SplashScreen from "expo-splash-screen"; import { StatusBar } from "expo-status-bar"; @@ -22,9 +31,198 @@ import { AppState } from "react-native"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import "react-native-reanimated"; import { Toaster } from "sonner-native"; +import * as TaskManager from "expo-task-manager"; +import AsyncStorage from "@react-native-async-storage/async-storage"; +import * as BackgroundFetch from "expo-background-fetch"; +import { cancelJobById, getAllJobsByDeviceId } from "@/utils/optimize-server"; +import * as FileSystem from "expo-file-system"; +import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client"; +import * as Notifications from "expo-notifications"; +import { BACKGROUND_FETCH_TASK } from "@/utils/background-tasks"; SplashScreen.preventAutoHideAsync(); +Notifications.setNotificationHandler({ + handleNotification: async () => ({ + shouldShowAlert: true, + shouldPlaySound: true, + shouldSetBadge: false, + }), +}); + +function useNotificationObserver() { + useEffect(() => { + let isMounted = true; + + function redirect(notification: Notifications.Notification) { + const url = notification.request.content.data?.url; + if (url) { + router.push(url); + } + } + + Notifications.getLastNotificationResponseAsync().then((response) => { + if (!isMounted || !response?.notification) { + return; + } + redirect(response?.notification); + }); + + const subscription = Notifications.addNotificationResponseReceivedListener( + (response) => { + redirect(response.notification); + } + ); + + return () => { + isMounted = false; + subscription.remove(); + }; + }, []); +} + +TaskManager.defineTask(BACKGROUND_FETCH_TASK, async () => { + console.log("TaskManager ~ trigger"); + + const now = Date.now(); + + const settingsData = await AsyncStorage.getItem("settings"); + + if (!settingsData) return BackgroundFetch.BackgroundFetchResult.NoData; + + const settings: Partial = JSON.parse(settingsData); + const url = settings?.optimizedVersionsServerUrl; + + if (!settings?.autoDownload || !url) + return BackgroundFetch.BackgroundFetchResult.NoData; + + const token = await getTokenFromStoraage(); + const deviceId = await getOrSetDeviceId(); + const baseDirectory = FileSystem.documentDirectory; + + if (!token || !deviceId || !baseDirectory) + return BackgroundFetch.BackgroundFetchResult.NoData; + + console.log({ + token, + url, + deviceId, + }); + + const jobs = await getAllJobsByDeviceId({ + deviceId, + authHeader: token, + url, + }); + + console.log("TaskManager ~ Active jobs: ", jobs.length); + + for (let job of jobs) { + if (job.status === "completed") { + const downloadUrl = url + "download/" + job.id; + console.log({ + token, + deviceId, + baseDirectory, + url, + downloadUrl, + }); + + const tasks = await checkForExistingDownloads(); + + if (tasks.find((task) => task.id === job.id)) { + console.log("TaskManager ~ Download already in progress: ", job.id); + continue; + } + + download({ + id: job.id, + url: url + "download/" + job.id, + destination: `${baseDirectory}${job.item.Id}.mp4`, + headers: { + Authorization: token, + }, + }) + .begin(() => { + console.log("TaskManager ~ Download started: ", job.id); + Notifications.scheduleNotificationAsync({ + content: { + title: job.item.Name, + body: "Download started", + data: { + url: `/downloads`, + }, + }, + trigger: null, + }); + }) + .done(() => { + console.log("TaskManager ~ Download completed: ", job.id); + saveDownloadedItemInfo(job.item); + completeHandler(job.id); + cancelJobById({ + authHeader: token, + id: job.id, + url: url, + }); + Notifications.scheduleNotificationAsync({ + content: { + title: job.item.Name, + body: "Download completed", + data: { + url: `/downloads`, + }, + }, + trigger: null, + }); + }) + .error((error) => { + console.log("TaskManager ~ Download error: ", job.id, error); + completeHandler(job.id); + Notifications.scheduleNotificationAsync({ + content: { + title: job.item.Name, + body: "Download failed", + data: { + url: `/downloads`, + }, + }, + trigger: null, + }); + }); + } + } + + console.log(`Auto download started: ${new Date(now).toISOString()}`); + + // Be sure to return the successful result type! + return BackgroundFetch.BackgroundFetchResult.NewData; +}); + +const checkAndRequestPermissions = async () => { + try { + const hasAskedBefore = await AsyncStorage.getItem( + "hasAskedForNotificationPermission" + ); + + if (hasAskedBefore !== "true") { + const { status } = await Notifications.requestPermissionsAsync(); + + if (status === "granted") { + console.log("Notification permissions granted."); + } else { + console.log("Notification permissions denied."); + } + + await AsyncStorage.setItem("hasAskedForNotificationPermission", "true"); + } else { + console.log("Already asked for notification permissions before."); + } + } catch (error) { + console.error("Error checking/requesting notification permissions:", error); + } +}; + export default function RootLayout() { const [loaded] = useFonts({ SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"), @@ -52,6 +250,7 @@ function Layout() { const [orientation, setOrientation] = useAtom(orientationAtom); useKeepAwake(); + useNotificationObserver(); const queryClientRef = useRef( new QueryClient({ @@ -67,6 +266,10 @@ function Layout() { }) ); + useEffect(() => { + checkAndRequestPermissions(); + }, []); + useEffect(() => { if (settings?.autoRotate === true) ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.DEFAULT); @@ -164,7 +367,7 @@ function Layout() { ); } + +async function saveDownloadedItemInfo(item: BaseItemDto) { + try { + const downloadedItems = await AsyncStorage.getItem("downloadedItems"); + let items: BaseItemDto[] = downloadedItems + ? JSON.parse(downloadedItems) + : []; + + const existingItemIndex = items.findIndex((i) => i.Id === item.Id); + if (existingItemIndex !== -1) { + items[existingItemIndex] = item; + } else { + items.push(item); + } + + await AsyncStorage.setItem("downloadedItems", JSON.stringify(items)); + } catch (error) { + console.error("Failed to save downloaded item information:", error); + } +} diff --git a/bun.lockb b/bun.lockb index be0777f23ee14f029df4f30ac4f43cc376f9dafb..f20d90a6bb1685417d78227bc9af8e50437c76c0 100755 GIT binary patch delta 95247 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 rZkWp>~l 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 delta 93227 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 diff --git a/components/downloads/ActiveDownloads.tsx b/components/downloads/ActiveDownloads.tsx index 15b1557c..e8485627 100644 --- a/components/downloads/ActiveDownloads.tsx +++ b/components/downloads/ActiveDownloads.tsx @@ -101,7 +101,8 @@ const DownloadCard = ({ process, ...props }: DownloadCardProps) => { className="relative bg-neutral-900 border border-neutral-800 rounded-2xl overflow-hidden" {...props} > - {process.status === "optimizing" && ( + {(process.status === "optimizing" || + process.status === "downloading") && ( = ({ ...props }) => { const [marlinUrl, setMarlinUrl] = useState(""); const [optimizedVersionsServerUrl, setOptimizedVersionsServerUrl] = - useState(""); + useState(settings?.optimizedVersionsServerUrl || ""); const queryClient = useQueryClient(); + /******************** + * Background task + *******************/ + const [isRegistered, setIsRegistered] = useState(null); + const [status, setStatus] = + useState(null); + + useEffect(() => { + checkStatusAsync(); + }, []); + + const checkStatusAsync = async () => { + const status = await BackgroundFetch.getStatusAsync(); + const isRegistered = await TaskManager.isTaskRegisteredAsync( + BACKGROUND_FETCH_TASK + ); + setStatus(status); + setIsRegistered(isRegistered); + }; + + const toggleFetchTask = async () => { + if (isRegistered) { + console.log("Unregistering task"); + await unregisterBackgroundFetchAsync(); + updateSettings({ + autoDownload: false, + }); + } else { + console.log("Registering task"); + await registerBackgroundFetchAsync(); + updateSettings({ + autoDownload: true, + }); + } + + checkStatusAsync(); + }; + /********************** + *********************/ + const { data: mediaListCollections, isLoading: isLoadingMediaListCollections, @@ -515,6 +563,23 @@ export const SettingToggles: React.FC = ({ ...props }) => { + + + Auto download + + This will automatically download the media file when it's + finished optimizing on the server. + + + {isRegistered === null ? ( + + ) : ( + toggleFetchTask()} + /> + )} + = ({ ...props }) => { = ({ ...props }) => { Save - - {settings.optimizedVersionsServerUrl && ( - - {settings.optimizedVersionsServerUrl} - - )} diff --git a/hooks/useRemuxHlsToMp4.ts b/hooks/useRemuxHlsToMp4.ts index 18c5ee3d..091325fb 100644 --- a/hooks/useRemuxHlsToMp4.ts +++ b/hooks/useRemuxHlsToMp4.ts @@ -62,7 +62,7 @@ export const useRemuxHlsToMp4 = (item: BaseItemDto) => { itemId: item.Id, outputPath: "", progress: 0, - status: "running", + status: "downloading", timestamp: new Date(), } as JobStatus, ]); diff --git a/package.json b/package.json index 64755bbe..fa01ee7b 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "expo-linking": "~6.3.1", "expo-navigation-bar": "~3.0.7", "expo-network": "~6.0.1", + "expo-notifications": "~0.28.17", "expo-router": "~3.5.23", "expo-screen-orientation": "~7.0.5", "expo-sensors": "~13.0.9", diff --git a/providers/DownloadProvider.tsx b/providers/DownloadProvider.tsx index 0246cab5..06067fd9 100644 --- a/providers/DownloadProvider.tsx +++ b/providers/DownloadProvider.tsx @@ -11,22 +11,20 @@ import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; import { checkForExistingDownloads, completeHandler, - directories, download, setConfig, } from "@kesha-antonov/react-native-background-downloader"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { + focusManager, QueryClient, QueryClientProvider, useQuery, useQueryClient, } from "@tanstack/react-query"; import axios from "axios"; -import * as BackgroundFetch from "expo-background-fetch"; import * as FileSystem from "expo-file-system"; import { useRouter } from "expo-router"; -import * as TaskManager from "expo-task-manager"; import { useAtom } from "jotai"; import React, { createContext, @@ -34,37 +32,14 @@ import React, { useContext, useEffect, useMemo, - useRef, useState, } from "react"; +import { AppState, AppStateStatus } from "react-native"; import { toast } from "sonner-native"; import { apiAtom } from "./JellyfinProvider"; -export const BACKGROUND_FETCH_TASK = "background-fetch"; - -TaskManager.defineTask(BACKGROUND_FETCH_TASK, async () => { - const now = Date.now(); - - console.log( - `Got background fetch call at date: ${new Date(now).toISOString()}` - ); - - // Be sure to return the successful result type! - return BackgroundFetch.BackgroundFetchResult.NewData; -}); - -const STORAGE_KEY = "runningProcesses"; - -export async function registerBackgroundFetchAsync() { - return BackgroundFetch.registerTaskAsync(BACKGROUND_FETCH_TASK, { - minimumInterval: 60 * 15, // 1 minutes - stopOnTerminate: false, // android only, - startOnBoot: true, // android only - }); -} - -export async function unregisterBackgroundFetchAsync() { - return BackgroundFetch.unregisterTaskAsync(BACKGROUND_FETCH_TASK); +function onAppStateChange(status: AppStateStatus) { + focusManager.setFocused(status === "active"); } const DownloadContext = createContext { + const subscription = AppState.addEventListener("change", onAppStateChange); + + return () => subscription.remove(); + }, []); + useQuery({ queryKey: ["jobs"], queryFn: async () => { @@ -109,6 +93,29 @@ function useDownloadProvider() { url, }); + jobs.forEach((job) => { + const process = processes.find((p) => p.id === job.id); + if ( + process && + process.status === "optimizing" && + job.status === "completed" + ) { + if (settings.autoDownload) { + startDownload(job); + } else { + toast.info(`${job.item.Name} is ready to be downloaded`, { + action: { + label: "Go to downloads", + onClick: () => { + router.push("/downloads"); + toast.dismiss(); + }, + }, + }); + } + } + }); + // Local downloading processes that are still valid const downloadingProcesses = processes .filter((p) => p.status === "downloading") @@ -123,66 +130,30 @@ function useDownloadProvider() { return jobs; }, staleTime: 0, - refetchInterval: 1000, + refetchInterval: 2000, enabled: settings?.downloadMethod === "optimized", }); useEffect(() => { const checkIfShouldStartDownload = async () => { + if (processes.length === 0) return; const tasks = await checkForExistingDownloads(); - // for (let i = 0; i < processes.length; i++) { - // const job = processes[i]; + // if (settings?.autoDownload) { + // for (let i = 0; i < processes.length; i++) { + // const job = processes[i]; - // if (job.status === "completed") { - // // Check if the download is already in progress - // if (tasks.find((task) => task.id === job.id)) continue; - // await startDownload(job); - // continue; + // if (job.status === "completed") { + // // Check if the download is already in progress + // if (tasks.find((task) => task.id === job.id)) continue; + // await startDownload(job); + // continue; + // } // } // } }; checkIfShouldStartDownload(); - }, []); - - /******************** - * Background task - *******************/ - // useEffect(() => { - // // Check background task status - // checkStatusAsync(); - // }, []); - - // const [isRegistered, setIsRegistered] = useState(false); - // const [status, setStatus] = - // useState(null); - - // const checkStatusAsync = async () => { - // const status = await BackgroundFetch.getStatusAsync(); - // const isRegistered = await TaskManager.isTaskRegisteredAsync( - // BACKGROUND_FETCH_TASK - // ); - // setStatus(status); - // setIsRegistered(isRegistered); - - // console.log("Background fetch status:", status); - // console.log("Background fetch task registered:", isRegistered); - // }; - - // const toggleFetchTask = async () => { - // if (isRegistered) { - // console.log("Unregistering background fetch task"); - // await unregisterBackgroundFetchAsync(); - // } else { - // console.log("Registering background fetch task"); - // await registerBackgroundFetchAsync(); - // } - - // checkStatusAsync(); - // }; - /********************** - ********************** - *********************/ + }, [settings, processes]); const removeProcess = useCallback( async (id: string) => { @@ -228,6 +199,16 @@ function useDownloadProvider() { }, }); + toast.info(`Download started for ${process.item.Name}`, { + action: { + label: "Go to downloads", + onClick: () => { + router.push("/downloads"); + toast.dismiss(); + }, + }, + }); + const baseDirectory = FileSystem.documentDirectory; download({ @@ -236,7 +217,6 @@ function useDownloadProvider() { destination: `${baseDirectory}/${process.item.Id}.mp4`, }) .begin(() => { - toast.info(`Download started for ${process.item.Name}`); setProcesses((prev) => prev.map((p) => p.id === process.id @@ -268,7 +248,16 @@ function useDownloadProvider() { }) .done(async () => { await saveDownloadedItemInfo(process.item); - toast.success(`Download completed for ${process.item.Name}`); + toast.success(`Download completed for ${process.item.Name}`, { + duration: 3000, + action: { + label: "Go to downloads", + onClick: () => { + router.push("/downloads"); + toast.dismiss(); + }, + }, + }); setTimeout(() => { completeHandler(process.id); removeProcess(process.id); diff --git a/providers/JellyfinProvider.tsx b/providers/JellyfinProvider.tsx index f1a13370..bcd0fb07 100644 --- a/providers/JellyfinProvider.tsx +++ b/providers/JellyfinProvider.tsx @@ -40,17 +40,6 @@ const JellyfinContext = createContext( undefined ); -const getOrSetDeviceId = async () => { - let deviceId = await AsyncStorage.getItem("deviceId"); - - if (!deviceId) { - deviceId = uuid.v4() as string; - await AsyncStorage.setItem("deviceId", deviceId); - } - - return deviceId; -}; - export const JellyfinProvider: React.FC<{ children: ReactNode }> = ({ children, }) => { @@ -269,10 +258,10 @@ export const JellyfinProvider: React.FC<{ children: ReactNode }> = ({ ], queryFn: async () => { try { - const token = await AsyncStorage.getItem("token"); - const serverUrl = await AsyncStorage.getItem("serverUrl"); + const token = await getTokenFromStoraage(); + const serverUrl = await getServerUrlFromStorage(); const user = JSON.parse( - (await AsyncStorage.getItem("user")) as string + (await getUserFromStorage()) as string ) as UserDto; if (serverUrl && token && user.Id && jellyfin) { @@ -331,3 +320,26 @@ function useProtectedRoute(user: UserDto | null, loading = false) { } }, [user, segments, loading]); } + +export async function getTokenFromStoraage() { + return await AsyncStorage.getItem("token"); +} + +export async function getUserFromStorage() { + return await AsyncStorage.getItem("user"); +} + +export async function getServerUrlFromStorage() { + return await AsyncStorage.getItem("serverUrl"); +} + +export async function getOrSetDeviceId() { + let deviceId = await AsyncStorage.getItem("deviceId"); + + if (!deviceId) { + deviceId = uuid.v4() as string; + await AsyncStorage.setItem("deviceId", deviceId); + } + + return deviceId; +} diff --git a/utils/atoms/settings.ts b/utils/atoms/settings.ts index bf03502d..cabfc8cf 100644 --- a/utils/atoms/settings.ts +++ b/utils/atoms/settings.ts @@ -73,7 +73,8 @@ export type Settings = { forwardSkipTime: number; rewindSkipTime: number; optimizedVersionsServerUrl?: string | null; - downloadMethod?: "optimized" | "remux"; + downloadMethod: "optimized" | "remux"; + autoDownload: boolean; }; /** * @@ -110,6 +111,7 @@ const loadSettings = async (): Promise => { rewindSkipTime: 10, optimizedVersionsServerUrl: null, downloadMethod: "remux", + autoDownload: false, }; try { diff --git a/utils/background-tasks.ts b/utils/background-tasks.ts new file mode 100644 index 00000000..1d7f0a70 --- /dev/null +++ b/utils/background-tasks.ts @@ -0,0 +1,23 @@ +import * as BackgroundFetch from "expo-background-fetch"; + +export const BACKGROUND_FETCH_TASK = "background-fetch"; + +export async function registerBackgroundFetchAsync() { + try { + BackgroundFetch.registerTaskAsync(BACKGROUND_FETCH_TASK, { + minimumInterval: 60 * 1, // 1 minutes + stopOnTerminate: false, // android only, + startOnBoot: false, // android only + }); + } catch (error) { + console.log("Error registering background fetch task", error); + } +} + +export async function unregisterBackgroundFetchAsync() { + try { + BackgroundFetch.unregisterTaskAsync(BACKGROUND_FETCH_TASK); + } catch (error) { + console.log("Error unregistering background fetch task", error); + } +} diff --git a/utils/optimize-server.ts b/utils/optimize-server.ts index 3db17037..f52ad799 100644 --- a/utils/optimize-server.ts +++ b/utils/optimize-server.ts @@ -53,6 +53,11 @@ export async function getAllJobsByDeviceId({ }, }); if (statusResponse.status !== 200) { + console.error( + statusResponse.status, + statusResponse.data, + statusResponse.statusText + ); throw new Error("Failed to fetch job status"); }