mirror of
https://github.com/Jellify-Music/App.git
synced 2026-02-25 05:08:39 -06:00
lots of backend changes to slim up the app provider and to beef up the login provider
This commit is contained in:
@@ -25,8 +25,12 @@ export const serverMutation = async (serverUrl: string) => {
|
||||
return await getSystemApi(api).getPublicSystemInfo();
|
||||
}
|
||||
|
||||
export const mutateServer = async (server: JellifyServer | undefined) => {
|
||||
return await AsyncStorage.setItem(AsyncStorageKeys.ServerUrl, JSON.stringify(server));
|
||||
export const mutateServer = async (server?: JellifyServer) => {
|
||||
|
||||
if (!_.isUndefined(server))
|
||||
return await AsyncStorage.setItem(AsyncStorageKeys.ServerUrl, JSON.stringify(server));
|
||||
|
||||
return await AsyncStorage.removeItem(AsyncStorageKeys.ServerUrl);
|
||||
}
|
||||
|
||||
export const mutateServerCredentials = async (credentials?: JellyfinCredentials) => {
|
||||
|
||||
@@ -3,15 +3,11 @@ import { QueryKeys } from "../enums/query-keys";
|
||||
import { createApi, createPublicApi } from "./queries/functions/api";
|
||||
|
||||
export const usePublicApi = (serverUrl: string) => useQuery({
|
||||
queryKey: [QueryKeys.PublicApi, serverUrl],
|
||||
queryFn: ({ queryKey }) => {
|
||||
return createPublicApi(queryKey[1])
|
||||
}
|
||||
})
|
||||
queryKey: [QueryKeys.PublicApi, { serverUrl }],
|
||||
queryFn: createPublicApi
|
||||
});
|
||||
|
||||
export const useApi = () => useQuery({
|
||||
queryKey: [QueryKeys.Api],
|
||||
queryFn: () => {
|
||||
return createApi()
|
||||
}
|
||||
queryFn: createApi
|
||||
})
|
||||
@@ -2,21 +2,32 @@ import { Api } from "@jellyfin/sdk";
|
||||
import { fetchCredentials } from "./storage";
|
||||
import { client } from "../../client";
|
||||
import _ from "lodash";
|
||||
import { QueryFunctionContext, QueryKey } from "@tanstack/react-query";
|
||||
|
||||
/**
|
||||
* A promise to build an authenticated Jellyfin API client
|
||||
* @returns A Promise of the authenticated Jellyfin API client or a rejection
|
||||
*/
|
||||
export const createApi: () => Promise<Api> = () => new Promise(async (resolve, reject) => {
|
||||
let credentials = await fetchCredentials();
|
||||
export function createApi(): Promise<Api> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let credentials = await fetchCredentials();
|
||||
|
||||
if (_.isUndefined(credentials))
|
||||
reject("No credentials exist for the current user")
|
||||
|
||||
console.log("Signing into Jellyfin")
|
||||
resolve(client.createApi(credentials!.server, credentials!.password));
|
||||
});
|
||||
if (_.isUndefined(credentials)) {
|
||||
console.warn("No credentials exist for user, launching login flow");
|
||||
return reject("No credentials exist for the current user");
|
||||
}
|
||||
|
||||
console.log("Signing into Jellyfin")
|
||||
return resolve(client.createApi(credentials!.server, credentials!.password));
|
||||
});
|
||||
}
|
||||
|
||||
export const createPublicApi: (serverUrl: string) => Api = (serverUrl) => {
|
||||
return client.createApi(serverUrl);
|
||||
export function createPublicApi({ queryKey }: QueryFunctionContext): Promise<Api> {
|
||||
return new Promise((resolve) => {
|
||||
|
||||
///@ts-ignore
|
||||
const [_key, { serverUrl } ] = queryKey;
|
||||
|
||||
resolve(client.createApi(serverUrl));
|
||||
});
|
||||
}
|
||||
@@ -4,20 +4,21 @@ import { getItemsApi } from "@jellyfin/sdk/lib/utils/api/items-api";
|
||||
import _ from "lodash";
|
||||
|
||||
|
||||
export const fetchMusicLibraries : (api: Api) => Promise<BaseItemDto[]> = (api: Api) => new Promise( async (resolve) => {
|
||||
export function fetchMusicLibraries(api: Api): Promise<BaseItemDto[]> {
|
||||
return new Promise( async (resolve) => {
|
||||
console.log("Fetching music libraries from Jellyfin");
|
||||
|
||||
let libraries = await getItemsApi(api).getItems();
|
||||
|
||||
console.log("Fetching music libraries from Jellyfin");
|
||||
|
||||
let libraries = await getItemsApi(api).getItems();
|
||||
if (_.isUndefined(libraries.data.Items)) {
|
||||
console.log("No libraries found on Jellyfin");
|
||||
return Promise.reject("No libraries found on Jellyfin");
|
||||
}
|
||||
|
||||
if (_.isUndefined(libraries.data.Items)) {
|
||||
console.log("No libraries found on Jellyfin");
|
||||
return Promise.reject("No libraries found on Jellyfin");
|
||||
}
|
||||
let musicLibraries = libraries.data.Items!.filter(library => library.CollectionType == 'music');
|
||||
|
||||
let musicLibraries = libraries.data.Items!.filter(library => library.CollectionType == 'music');
|
||||
|
||||
console.log(`Found ${musicLibraries.length} music libraries`);
|
||||
|
||||
resolve(musicLibraries);
|
||||
});
|
||||
console.log(`Found ${musicLibraries.length} music libraries`);
|
||||
|
||||
resolve(musicLibraries);
|
||||
});
|
||||
}
|
||||
@@ -9,9 +9,9 @@ import { useApiClientContext } from "../jellyfin-api-provider";
|
||||
|
||||
export default function Login(): React.JSX.Element {
|
||||
|
||||
const { serverAddress, username, triggerAuth, setTriggerAuth } = useAuthenticationContext();
|
||||
const { serverAddress, storedServer, changeServer, username, changeUsername, triggerAuth, setTriggerAuth } = useAuthenticationContext();
|
||||
|
||||
const { apiClient, username: clientUsername } = useApiClientContext();
|
||||
const { apiClient } = useApiClientContext();
|
||||
|
||||
const Stack = createStackNavigator();
|
||||
|
||||
@@ -22,7 +22,7 @@ export default function Login(): React.JSX.Element {
|
||||
return (
|
||||
<Stack.Navigator screenOptions={{ headerShown: false }}>
|
||||
{
|
||||
(_.isUndefined(serverAddress) || _.isUndefined(apiClient)) ? (
|
||||
(_.isUndefined(storedServer) || changeServer) ? (
|
||||
<Stack.Screen
|
||||
name="ServerAddress"
|
||||
options={{
|
||||
@@ -33,7 +33,7 @@ export default function Login(): React.JSX.Element {
|
||||
/>
|
||||
) : (
|
||||
|
||||
(_.isUndefined(username) || _.isUndefined(clientUsername)) ? (
|
||||
(_.isUndefined(username) || changeUsername) ? (
|
||||
<Stack.Screen
|
||||
name="ServerAuthentication"
|
||||
options={{
|
||||
|
||||
@@ -14,17 +14,11 @@ import { Heading } from "../../helpers/text";
|
||||
import Input from "../../helpers/input";
|
||||
import Button from "../../helpers/button";
|
||||
|
||||
const http = "http://"
|
||||
const https = "https://"
|
||||
|
||||
export default function ServerAddress(): React.JSX.Element {
|
||||
|
||||
const { setServer, refetchApi } = useApiClientContext();
|
||||
const { serverAddress, setServerAddress } = useAuthenticationContext();
|
||||
const { serverAddress, setServerAddress, setChangeServer, useHttps, setUseHttps, refetchServer } = useAuthenticationContext();
|
||||
|
||||
const [useHttps, setUseHttps] = useState(true)
|
||||
|
||||
const theme = useTheme();
|
||||
const { apiClient } = useApiClientContext();
|
||||
|
||||
const useServerMutation = useMutation({
|
||||
mutationFn: serverMutation,
|
||||
@@ -45,9 +39,9 @@ export default function ServerAddress(): React.JSX.Element {
|
||||
startUpComplete: publicSystemInfoResponse.data.StartupWizardCompleted!
|
||||
}
|
||||
|
||||
setServer(jellifyServer);
|
||||
refetchApi();
|
||||
return await mutateServer(jellifyServer);
|
||||
await mutateServer(jellifyServer);
|
||||
await refetchServer();
|
||||
setChangeServer(false);
|
||||
},
|
||||
onError: async (error: Error) => {
|
||||
console.error("An error occurred connecting to the Jellyfin instance", error);
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
import React, { useEffect } from "react";
|
||||
import React from "react";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { useApiClientContext } from "../../jellyfin-api-provider";
|
||||
import _ from "lodash";
|
||||
import * as Keychain from "react-native-keychain"
|
||||
import { JellyfinCredentials } from "../../../api/types/jellyfin-credentials";
|
||||
import { View } from "tamagui";
|
||||
import { client } from "../../../api/client";
|
||||
import { useAuthenticationContext } from "../provider";
|
||||
import { Heading } from "../../helpers/text";
|
||||
import Button from "../../helpers/button";
|
||||
import Input from "../../helpers/input";
|
||||
|
||||
export default function ServerAuthentication(): React.JSX.Element {
|
||||
const { username, setUsername, setServerAddress } = useAuthenticationContext();
|
||||
const { username, setUsername, setChangeUsername, setServerAddress, storedServer } = useAuthenticationContext();
|
||||
const [password, setPassword] = React.useState<string | undefined>('');
|
||||
|
||||
const { apiClient, server, setUsername: setClientUsername } = useApiClientContext();
|
||||
const { apiClient, refetchApi } = useApiClientContext();
|
||||
|
||||
const useApiMutation = useMutation({
|
||||
mutationFn: async (credentials: JellyfinCredentials) => {
|
||||
@@ -23,7 +22,7 @@ export default function ServerAuthentication(): React.JSX.Element {
|
||||
},
|
||||
onSuccess: async (authResult, credentials) => {
|
||||
|
||||
console.log(`Received auth response from ${server!.name}`)
|
||||
console.log(`Received auth response from ${storedServer!.name}`)
|
||||
if (_.isUndefined(authResult))
|
||||
return Promise.reject(new Error("Authentication result was empty"))
|
||||
|
||||
@@ -33,15 +32,15 @@ export default function ServerAuthentication(): React.JSX.Element {
|
||||
if (_.isUndefined(authResult.data.User))
|
||||
return Promise.reject(new Error("Unable to login"));
|
||||
|
||||
console.log(`Successfully signed in to ${server!.name}`)
|
||||
console.log(`Successfully signed in to ${storedServer!.name}`)
|
||||
setUsername(credentials.username);
|
||||
setClientUsername(credentials.username);
|
||||
return await Keychain.setInternetCredentials(server!.url, credentials.username, (authResult.data.AccessToken as string));
|
||||
|
||||
setChangeUsername(false);
|
||||
await Keychain.setInternetCredentials(storedServer!.url, credentials.username, (authResult.data.AccessToken as string));
|
||||
return await refetchApi();
|
||||
},
|
||||
onError: async (error: Error) => {
|
||||
console.error("An error occurred connecting to the Jellyfin instance", error);
|
||||
return Promise.reject(`An error occured signing into ${server!.name}`);
|
||||
return Promise.reject(`An error occured signing into ${storedServer!.name}`);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -55,7 +54,7 @@ export default function ServerAuthentication(): React.JSX.Element {
|
||||
return (
|
||||
<View marginHorizontal={10} flex={1} justifyContent='center'>
|
||||
<Heading>
|
||||
{ `Sign in to ${server?.name ?? "Jellyfin"}`}
|
||||
{ `Sign in to ${storedServer?.name ?? "Jellyfin"}`}
|
||||
</Heading>
|
||||
<Button
|
||||
onPress={() => {
|
||||
@@ -81,8 +80,8 @@ export default function ServerAuthentication(): React.JSX.Element {
|
||||
onPress={() => {
|
||||
|
||||
if (!_.isUndefined(username)) {
|
||||
console.log(`Signing in to ${server!.name}`);
|
||||
useApiMutation.mutate({ username, password })
|
||||
console.log(`Signing in to ${storedServer!.name}`);
|
||||
useApiMutation.mutate({ username, password });
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -21,14 +21,12 @@ export default function ServerLibrary(): React.JSX.Element {
|
||||
|
||||
const { setUsername, libraryName, setLibraryName, libraryId, setLibraryId } = useAuthenticationContext();
|
||||
|
||||
const { apiClient, setUsername: setClientUsername } = useApiClientContext();
|
||||
const { apiClient } = useApiClientContext();
|
||||
|
||||
|
||||
const useLibraries = (api: Api) => useQuery({
|
||||
queryKey: [QueryKeys.Libraries, api],
|
||||
queryFn: async ({ queryKey }) => {
|
||||
return await fetchMusicLibraries(queryKey[1] as Api);
|
||||
}
|
||||
queryFn: async ({ queryKey }) => await fetchMusicLibraries(queryKey[1] as Api)
|
||||
});
|
||||
|
||||
const { data : libraries, isPending, refetch } = useLibraries(apiClient!);
|
||||
@@ -37,7 +35,6 @@ export default function ServerLibrary(): React.JSX.Element {
|
||||
mutationFn: async () => {
|
||||
|
||||
setUsername(undefined);
|
||||
setClientUsername(undefined);
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@@ -1,15 +1,26 @@
|
||||
import React, { createContext, ReactNode, SetStateAction, useContext, useEffect, useState } from "react";
|
||||
import { useApi } from "../../api/queries";
|
||||
import { useCredentials, useServer } from "../../api/queries/keychain";
|
||||
import { Api } from "@jellyfin/sdk";
|
||||
import _ from "lodash";
|
||||
import { SharedWebCredentials } from "react-native-keychain";
|
||||
import { JellifyServer } from "../../types/JellifyServer";
|
||||
import { QueryObserverResult, RefetchOptions } from "@tanstack/react-query";
|
||||
import { mutateServer, mutateServerCredentials } from "../../api/mutators/functions/storage";
|
||||
|
||||
interface JellyfinAuthenticationContext {
|
||||
username: string | undefined;
|
||||
setUsername: React.Dispatch<SetStateAction<string | undefined>>;
|
||||
changeUsername: boolean;
|
||||
setChangeUsername: React.Dispatch<SetStateAction<boolean>>;
|
||||
useHttp: boolean;
|
||||
setUseHttp: React.Dispatch<SetStateAction<boolean>>;
|
||||
useHttps: boolean;
|
||||
setUseHttps: React.Dispatch<SetStateAction<boolean>>;
|
||||
serverAddress: string | undefined;
|
||||
setServerAddress: React.Dispatch<SetStateAction<string | undefined>>;
|
||||
changeServer: boolean;
|
||||
setChangeServer: React.Dispatch<SetStateAction<boolean>>;
|
||||
storedServer: JellifyServer | undefined;
|
||||
refetchServer: (options?: RefetchOptions | undefined) => Promise<QueryObserverResult<JellifyServer, Error>>;
|
||||
libraryName: string | undefined;
|
||||
setLibraryName: React.Dispatch<React.SetStateAction<string | undefined>>;
|
||||
libraryId: string | undefined;
|
||||
@@ -20,21 +31,25 @@ interface JellyfinAuthenticationContext {
|
||||
|
||||
const JellyfinAuthenticationContextInitializer = () => {
|
||||
const [username, setUsername] = useState<string | undefined>(undefined);
|
||||
const [changeUsername, setChangeUsername] = useState<boolean>(false);
|
||||
|
||||
const [useHttp, setUseHttp] = useState<boolean>(false);
|
||||
const [useHttps, setUseHttps] = useState<boolean>(true);
|
||||
const [serverAddress, setServerAddress] = useState<string | undefined>(undefined);
|
||||
const [changeServer, setChangeServer] = useState<boolean>(false);
|
||||
|
||||
const [libraryName, setLibraryName] = useState<string | undefined>(undefined);
|
||||
|
||||
const [libraryId, setLibraryId] = useState<string | undefined>(undefined);
|
||||
|
||||
const [triggerAuth, setTriggerAuth] = useState<boolean>(true);
|
||||
|
||||
const { data: jellyfinServer, isPending: serverPending } = useServer();
|
||||
// Fetch from storage on init to load non-sensitive fields from previous logins
|
||||
const { data: storedServer, isPending: serverPending, refetch: refetchServer } = useServer();
|
||||
const { data: credentials, isPending: credentialsPending } : { data: SharedWebCredentials | undefined, isPending: boolean } = useCredentials();
|
||||
|
||||
useEffect(() => {
|
||||
if (!_.isUndefined(jellyfinServer)) {
|
||||
setServerAddress(jellyfinServer.url);
|
||||
if (!_.isUndefined(storedServer)) {
|
||||
setServerAddress(storedServer.url);
|
||||
}
|
||||
|
||||
if (!_.isUndefined(credentials)) {
|
||||
@@ -45,11 +60,33 @@ const JellyfinAuthenticationContextInitializer = () => {
|
||||
credentialsPending
|
||||
]);
|
||||
|
||||
// Remove stored creds if a change is requested
|
||||
useEffect(() => {
|
||||
if (changeUsername)
|
||||
mutateServerCredentials();
|
||||
|
||||
if (changeServer)
|
||||
mutateServer();
|
||||
}, [
|
||||
changeUsername,
|
||||
changeServer
|
||||
])
|
||||
|
||||
return {
|
||||
username,
|
||||
setUsername,
|
||||
changeUsername,
|
||||
setChangeUsername,
|
||||
useHttp,
|
||||
setUseHttp,
|
||||
useHttps,
|
||||
setUseHttps,
|
||||
serverAddress,
|
||||
setServerAddress,
|
||||
changeServer,
|
||||
setChangeServer,
|
||||
storedServer,
|
||||
refetchServer,
|
||||
libraryName,
|
||||
setLibraryName,
|
||||
libraryId,
|
||||
@@ -63,8 +100,18 @@ const JellyfinAuthenticationContext =
|
||||
createContext<JellyfinAuthenticationContext>({
|
||||
username: undefined,
|
||||
setUsername: () => {},
|
||||
changeUsername: false,
|
||||
setChangeUsername: () => {},
|
||||
useHttp: false,
|
||||
setUseHttp: () => {},
|
||||
useHttps: true,
|
||||
setUseHttps: () => {},
|
||||
serverAddress: undefined,
|
||||
setServerAddress: () => {},
|
||||
changeServer: false,
|
||||
setChangeServer: () => {},
|
||||
storedServer: undefined,
|
||||
refetchServer: () => new Promise(() => {}),
|
||||
libraryName: undefined,
|
||||
setLibraryName: () => {},
|
||||
libraryId: undefined,
|
||||
@@ -80,8 +127,18 @@ export const JellyfinAuthenticationProvider: ({ children }: {
|
||||
const {
|
||||
username,
|
||||
setUsername,
|
||||
changeUsername,
|
||||
setChangeUsername,
|
||||
useHttp,
|
||||
setUseHttp,
|
||||
useHttps,
|
||||
setUseHttps,
|
||||
serverAddress,
|
||||
setServerAddress,
|
||||
changeServer,
|
||||
setChangeServer,
|
||||
storedServer,
|
||||
refetchServer,
|
||||
libraryName,
|
||||
setLibraryName,
|
||||
libraryId,
|
||||
@@ -94,8 +151,18 @@ export const JellyfinAuthenticationProvider: ({ children }: {
|
||||
<JellyfinAuthenticationContext.Provider value={{
|
||||
username,
|
||||
setUsername,
|
||||
changeUsername,
|
||||
setChangeUsername,
|
||||
useHttp,
|
||||
setUseHttp,
|
||||
useHttps,
|
||||
setUseHttps,
|
||||
serverAddress,
|
||||
setServerAddress,
|
||||
changeServer,
|
||||
setChangeServer,
|
||||
storedServer,
|
||||
refetchServer,
|
||||
libraryName,
|
||||
setLibraryName,
|
||||
libraryId,
|
||||
|
||||
2
components/Login/utils/constants.ts
Normal file
2
components/Login/utils/constants.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export const http = "http://"
|
||||
export const https = "https://"
|
||||
@@ -32,11 +32,11 @@ function conditionalHomeRender(): React.JSX.Element {
|
||||
const isDarkMode = useColorScheme() === 'dark';
|
||||
|
||||
// If library ID hasn't been set, we haven't completed the auth flow
|
||||
const { library } = useApiClientContext();
|
||||
const { apiClient } = useApiClientContext();
|
||||
|
||||
return (
|
||||
<NavigationContainer theme={isDarkMode ? DarkTheme : DefaultTheme}>
|
||||
{ !_.isUndefined(library) ? (
|
||||
{ !_.isUndefined(apiClient) ? (
|
||||
<Navigation />
|
||||
) : (
|
||||
<JellyfinAuthenticationProvider>
|
||||
|
||||
@@ -1,106 +1,49 @@
|
||||
import { Api } from '@jellyfin/sdk';
|
||||
import React, { createContext, ReactNode, useContext, useEffect, useState } from 'react';
|
||||
import { useApi, usePublicApi } from '../api/queries';
|
||||
import React, { createContext, ReactNode, useContext } from 'react';
|
||||
import { useApi } from '../api/queries';
|
||||
import _ from 'lodash';
|
||||
import { JellifyServer } from '../types/JellifyServer';
|
||||
import { useCredentials, useServer } from '../api/queries/keychain';
|
||||
import { JellifyLibrary } from '../types/JellifyLibrary';
|
||||
import { SharedWebCredentials } from 'react-native-keychain';
|
||||
import { QueryObserverResult, RefetchOptions } from '@tanstack/react-query';
|
||||
|
||||
interface JellyfinApiClientContext {
|
||||
apiClient: Api | undefined;
|
||||
setApiClient: React.Dispatch<React.SetStateAction<Api | undefined>>;
|
||||
apiPending: boolean;
|
||||
refetchApi: (options?: RefetchOptions | undefined) => Promise<QueryObserverResult<Api, Error>>;
|
||||
server: JellifyServer | undefined;
|
||||
setServer: React.Dispatch<React.SetStateAction<JellifyServer | undefined>>;
|
||||
library: JellifyLibrary | undefined;
|
||||
setLibrary: React.Dispatch<React.SetStateAction<JellifyLibrary | undefined>>;
|
||||
username: string | undefined;
|
||||
setUsername: React.Dispatch<React.SetStateAction<string | undefined>>;
|
||||
}
|
||||
|
||||
const JellyfinApiClientContextInitializer = () => {
|
||||
const [apiClient, setApiClient] = useState<Api | undefined>(undefined);
|
||||
const [server, setServer] = useState<JellifyServer | undefined>(undefined);
|
||||
const [library, setLibrary] = useState<JellifyLibrary | undefined>(undefined);
|
||||
const [username, setUsername] = useState<string | undefined>();
|
||||
|
||||
const { data: api, isPending: apiPending, refetch: refetchApi } = useApi();
|
||||
const { data: jellyfinServer, isPending: serverPending } = useServer();
|
||||
const { data: credentials, isPending: credentialsPending } : { data: SharedWebCredentials | undefined, isPending: boolean } = useCredentials();
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
if (!_.isUndefined(api)) {
|
||||
console.log("Using authenticated API client")
|
||||
setApiClient(api);
|
||||
} else {
|
||||
setApiClient(undefined)
|
||||
}
|
||||
|
||||
setServer(jellyfinServer);
|
||||
setUsername(credentials?.username ?? undefined)
|
||||
}, [
|
||||
apiPending,
|
||||
credentialsPending,
|
||||
serverPending,
|
||||
]);
|
||||
|
||||
return {
|
||||
apiClient,
|
||||
setApiClient,
|
||||
api,
|
||||
apiPending,
|
||||
refetchApi,
|
||||
server,
|
||||
setServer,
|
||||
library,
|
||||
setLibrary,
|
||||
username,
|
||||
setUsername
|
||||
};
|
||||
}
|
||||
|
||||
export const JellyfinApiClientContext =
|
||||
createContext<JellyfinApiClientContext>({
|
||||
apiClient: undefined,
|
||||
setApiClient: () => {},
|
||||
apiPending: true,
|
||||
refetchApi: () => new Promise(() => {}),
|
||||
server: undefined,
|
||||
setServer: () => {},
|
||||
library: undefined,
|
||||
setLibrary: () => {},
|
||||
username: undefined,
|
||||
setUsername: () => {}
|
||||
});
|
||||
|
||||
export const JellyfinApiClientProvider: ({ children }: {
|
||||
children: ReactNode;
|
||||
}) => React.JSX.Element = ({ children }: { children: ReactNode }) => {
|
||||
const {
|
||||
apiClient,
|
||||
setApiClient,
|
||||
api,
|
||||
apiPending,
|
||||
refetchApi,
|
||||
server,
|
||||
setServer,
|
||||
library,
|
||||
setLibrary,
|
||||
username,
|
||||
setUsername
|
||||
} = JellyfinApiClientContextInitializer();
|
||||
|
||||
// Add your logic to check if credentials are stored and initialize the API client here.
|
||||
|
||||
return (
|
||||
<JellyfinApiClientContext.Provider value={{
|
||||
apiClient,
|
||||
setApiClient,
|
||||
apiClient: api,
|
||||
apiPending,
|
||||
refetchApi,
|
||||
server,
|
||||
setServer,
|
||||
library,
|
||||
setLibrary,
|
||||
username,
|
||||
setUsername
|
||||
}}>
|
||||
{children}
|
||||
</JellyfinApiClientContext.Provider>
|
||||
|
||||
Reference in New Issue
Block a user