Merge pull request #321 from herrrta/fix/jellyseerr-pass-prompt

Better jellyseerr password input with loading indicator
This commit is contained in:
Fredrik Burmester
2024-12-30 22:02:09 +01:00
committed by GitHub

View File

@@ -21,9 +21,8 @@ import * as BackgroundFetch from "expo-background-fetch";
import * as ScreenOrientation from "expo-screen-orientation"; import * as ScreenOrientation from "expo-screen-orientation";
import * as TaskManager from "expo-task-manager"; import * as TaskManager from "expo-task-manager";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import React, {useCallback, useEffect, useState} from "react"; import React, {useCallback, useEffect, useRef, useState} from "react";
import { import {
Alert,
Linking, Linking,
Switch, Switch,
TouchableOpacity, TouchableOpacity,
@@ -59,7 +58,10 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
const [api] = useAtom(apiAtom); const [api] = useAtom(apiAtom);
const [user] = useAtom(userAtom); const [user] = useAtom(userAtom);
const jellyseerrPassInputRef = useRef(null);
const [marlinUrl, setMarlinUrl] = useState<string>(""); const [marlinUrl, setMarlinUrl] = useState<string>("");
const [promptForJellyseerrPass, setPromptForJellyseerrPass] = useState<boolean>(false);
const [isJellyseerrLoading, setIsLoadingJellyseerr] = useState<boolean>(false);
const [jellyseerrPassword, setJellyseerrPassword] = useState<string | undefined>(undefined); const [jellyseerrPassword, setJellyseerrPassword] = useState<string | undefined>(undefined);
const [optimizedVersionsServerUrl, setOptimizedVersionsServerUrl] = const [optimizedVersionsServerUrl, setOptimizedVersionsServerUrl] =
useState<string>(settings?.optimizedVersionsServerUrl || ""); useState<string>(settings?.optimizedVersionsServerUrl || "");
@@ -121,39 +123,9 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
staleTime: 0, staleTime: 0,
}); });
const promptForJellyseerrLogin = useCallback(() => const loginToJellyseerr = useCallback(() => {
Alert.prompt(
'Enter jellyfin password',
`Enter password for jellyfin user ${user?.Name}`,
(input) => setJellyseerrPassword(input),
'secure-text'
),
[user, setJellyseerrPassword]
);
const testJellyseerrServerUrl = useCallback(async () => {
if (!jellyseerrServerUrl || jellyseerrApi)
return;
const jellyseerrTempApi = new JellyseerrApi(jellyseerrServerUrl);
jellyseerrTempApi.test().then(result => {
if (result.isValid) {
if (result.requiresPass)
promptForJellyseerrLogin()
else
updateSettings({jellyseerrServerUrl})
}
else {
setjellyseerrServerUrl(undefined);
clearAllJellyseerData();
}
})
}, [jellyseerrServerUrl])
useEffect(() => {
if (jellyseerrServerUrl && user?.Name && jellyseerrPassword) { if (jellyseerrServerUrl && user?.Name && jellyseerrPassword) {
setIsLoadingJellyseerr(true)
const jellyseerrTempApi = new JellyseerrApi(jellyseerrServerUrl); const jellyseerrTempApi = new JellyseerrApi(jellyseerrServerUrl);
jellyseerrTempApi.login(user?.Name, jellyseerrPassword) jellyseerrTempApi.login(user?.Name, jellyseerrPassword)
.then(user => { .then(user => {
@@ -165,10 +137,35 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
}) })
.finally(() => { .finally(() => {
setJellyseerrPassword(undefined); setJellyseerrPassword(undefined);
setPromptForJellyseerrPass(false)
setIsLoadingJellyseerr(false)
}) })
} }
}, [user, jellyseerrServerUrl, jellyseerrPassword]); }, [user, jellyseerrServerUrl, jellyseerrPassword]);
const testJellyseerrServerUrl = useCallback(async () => {
if (!jellyseerrServerUrl || jellyseerrApi)
return;
setIsLoadingJellyseerr(true)
const jellyseerrTempApi = new JellyseerrApi(jellyseerrServerUrl);
jellyseerrTempApi.test().then(result => {
if (result.isValid) {
if (result.requiresPass)
setPromptForJellyseerrPass(true)
// promptForJellyseerrLogin()
else
updateSettings({jellyseerrServerUrl})
}
else {
setPromptForJellyseerrPass(false)
setjellyseerrServerUrl(undefined);
clearAllJellyseerData();
}
}).finally(() => setIsLoadingJellyseerr(false))
}, [jellyseerrServerUrl])
if (!settings) return null; if (!settings) return null;
return ( return (
@@ -697,7 +694,7 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
<View className="mt-4"> <View className="mt-4">
<Text className="text-lg font-bold mb-2">Jellyseerr</Text> <Text className="text-lg font-bold mb-2">Jellyseerr</Text>
<View className="flex flex-col rounded-xl overflow-hidden divide-y-2 divide-solid divide-neutral-800"> <View className="flex flex-col rounded-xl overflow-hidden divide-y-2 divide-solid divide-neutral-800">
{jellyseerrUser && <> {jellyseerrUser && <>
<View className="flex flex-col overflow-hidden divide-y-2 divide-solid divide-neutral-800"> <View className="flex flex-col overflow-hidden divide-y-2 divide-solid divide-neutral-800">
<ListItem title="Total media requests" subTitle={jellyseerrUser?.requestCount?.toString()}/> <ListItem title="Total media requests" subTitle={jellyseerrUser?.requestCount?.toString()}/>
@@ -718,7 +715,7 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
: "opacity-50" : "opacity-50"
}`} }`}
> >
<View className="flex flex-col bg-neutral-900 px-4 py-4"> <View className="flex flex-col bg-neutral-900 px-4 py-4 space-y-2">
<View className="flex flex-col shrink mb-2"> <View className="flex flex-col shrink mb-2">
<View className="flex flex-row justify-between items-center"> <View className="flex flex-row justify-between items-center">
<Text className="font-semibold"> <Text className="font-semibold">
@@ -741,17 +738,49 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
textContentType="URL" textContentType="URL"
onChangeText={setjellyseerrServerUrl} onChangeText={setjellyseerrServerUrl}
/> />
{promptForJellyseerrPass &&
<Input
autoFocus={true}
focusable={true}
placeholder={`Enter password for jellyfin user ${user?.Name}`}
value={jellyseerrPassword}
keyboardType="default"
secureTextEntry={true}
returnKeyType="done"
autoCapitalize="none"
textContentType="password"
onChangeText={setJellyseerrPassword}
/>
}
</View> </View>
</View> </View>
{isJellyseerrLoading &&
<Loader className="rounded-xl overflow-hidden w-full h-full bg-neutral-700/10 absolute"/>
}
<Button <Button
color="purple" color="purple"
className="h-12 mt-2" className="h-12 mt-2"
onPress={() => jellyseerrUser onPress={() =>
? clearAllJellyseerData().finally(() => setjellyseerrServerUrl(undefined)) jellyseerrUser
: testJellyseerrServerUrl() ? clearAllJellyseerData().finally(() => {
setjellyseerrServerUrl(undefined)
setPromptForJellyseerrPass(false)
setIsLoadingJellyseerr(false)
})
:
promptForJellyseerrPass
? loginToJellyseerr()
: testJellyseerrServerUrl()
} }
> >
{jellyseerrUser ? "Clear jellyseerr data" : "Save"} {jellyseerrUser
? "Clear jellyseerr data"
:
promptForJellyseerrPass
? "Login"
: "Save"
}
</Button> </Button>
</View> </View>
</View> </View>