mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-06-04 13:08:33 +01:00
feat(settings): add Account and Notifications pages, gate download notifications
This commit is contained in:
@@ -243,6 +243,28 @@ export default function IndexLayout() {
|
||||
headerLeft: () => <HeaderBackButton />,
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='settings/account/page'
|
||||
options={{
|
||||
title: t("home.settings.account.title"),
|
||||
headerShown: !Platform.isTV,
|
||||
headerBlurEffect: "none",
|
||||
headerTransparent: Platform.OS === "ios",
|
||||
headerShadowVisible: false,
|
||||
headerLeft: () => <HeaderBackButton />,
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='settings/notifications/page'
|
||||
options={{
|
||||
title: t("home.settings.notifications.title"),
|
||||
headerShown: !Platform.isTV,
|
||||
headerBlurEffect: "none",
|
||||
headerTransparent: Platform.OS === "ios",
|
||||
headerShadowVisible: false,
|
||||
headerLeft: () => <HeaderBackButton />,
|
||||
}}
|
||||
/>
|
||||
{Object.entries(nestedTabPageScreenOptions).map(([name, options]) => (
|
||||
<Stack.Screen key={name} name={name} options={options} />
|
||||
))}
|
||||
|
||||
53
app/(auth)/(tabs)/(home)/settings/account/page.tsx
Normal file
53
app/(auth)/(tabs)/(home)/settings/account/page.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import * as Application from "expo-application";
|
||||
import { setStringAsync } from "expo-clipboard";
|
||||
import { t } from "i18next";
|
||||
import { useAtom } from "jotai";
|
||||
import { useState } from "react";
|
||||
import { Alert, ScrollView } from "react-native";
|
||||
import { ListGroup } from "@/components/list/ListGroup";
|
||||
import { ListItem } from "@/components/list/ListItem";
|
||||
import { useHaptic } from "@/hooks/useHaptic";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
|
||||
export default function AccountPage() {
|
||||
const [api] = useAtom(apiAtom);
|
||||
const [user] = useAtom(userAtom);
|
||||
const [revealed, setRevealed] = useState(false);
|
||||
const success = useHaptic("success");
|
||||
const version = Application.nativeApplicationVersion ?? "N/A";
|
||||
const token = api?.accessToken ?? "";
|
||||
const masked = token ? `•••• •••• •••• ${token.slice(-4)}` : "";
|
||||
|
||||
return (
|
||||
<ScrollView contentContainerStyle={{ padding: 16 }}>
|
||||
<ListGroup title={t("home.settings.user_info.user_info_title")}>
|
||||
<ListItem
|
||||
title={t("home.settings.user_info.user")}
|
||||
value={user?.Name}
|
||||
/>
|
||||
<ListItem
|
||||
title={t("home.settings.user_info.server")}
|
||||
value={api?.basePath}
|
||||
/>
|
||||
<ListItem
|
||||
title={t("home.settings.user_info.token")}
|
||||
value={revealed ? token : masked}
|
||||
onPress={() => setRevealed((r) => !r)}
|
||||
/>
|
||||
<ListItem
|
||||
title={t("home.settings.account.copy_token")}
|
||||
textColor='blue'
|
||||
onPress={async () => {
|
||||
await setStringAsync(token);
|
||||
success();
|
||||
Alert.alert(t("home.settings.account.copied"));
|
||||
}}
|
||||
/>
|
||||
<ListItem
|
||||
title={t("home.settings.user_info.app_version")}
|
||||
value={version}
|
||||
/>
|
||||
</ListGroup>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
61
app/(auth)/(tabs)/(home)/settings/notifications/page.tsx
Normal file
61
app/(auth)/(tabs)/(home)/settings/notifications/page.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import * as Notifications from "expo-notifications";
|
||||
import { t } from "i18next";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Linking, ScrollView, Switch } from "react-native";
|
||||
import { ListGroup } from "@/components/list/ListGroup";
|
||||
import { ListItem } from "@/components/list/ListItem";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
|
||||
export default function NotificationsPage() {
|
||||
const { settings, updateSettings } = useSettings();
|
||||
const [granted, setGranted] = useState<boolean | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
Notifications.getPermissionsAsync().then((p) => setGranted(p.granted));
|
||||
}, []);
|
||||
|
||||
const requestPermission = async () => {
|
||||
const p = await Notifications.requestPermissionsAsync();
|
||||
setGranted(p.granted);
|
||||
if (!p.granted) Linking.openSettings();
|
||||
};
|
||||
|
||||
if (!settings) return null;
|
||||
|
||||
return (
|
||||
<ScrollView contentContainerStyle={{ padding: 16 }}>
|
||||
<ListGroup title={t("home.settings.notifications.permission_title")}>
|
||||
<ListItem
|
||||
title={t("home.settings.notifications.system_permission")}
|
||||
value={
|
||||
granted == null
|
||||
? "…"
|
||||
: granted
|
||||
? t("home.settings.notifications.granted")
|
||||
: t("home.settings.notifications.denied")
|
||||
}
|
||||
textColor={granted ? "default" : "blue"}
|
||||
onPress={granted ? undefined : requestPermission}
|
||||
/>
|
||||
</ListGroup>
|
||||
<ListGroup
|
||||
title={t("home.settings.notifications.events_title")}
|
||||
className='mt-4'
|
||||
>
|
||||
<ListItem title={t("home.settings.notifications.master")}>
|
||||
<Switch
|
||||
value={settings.notificationsEnabled}
|
||||
onValueChange={(v) => updateSettings({ notificationsEnabled: v })}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem title={t("home.settings.notifications.downloads")}>
|
||||
<Switch
|
||||
value={settings.notifyDownloads}
|
||||
disabled={!settings.notificationsEnabled}
|
||||
onValueChange={(v) => updateSettings({ notifyDownloads: v })}
|
||||
/>
|
||||
</ListItem>
|
||||
</ListGroup>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user