feat(settings): gate notifications page behind OS permission

This commit is contained in:
Gauvain
2026-06-03 23:59:17 +02:00
parent 752d1179bc
commit ac5dcbe751
2 changed files with 35 additions and 29 deletions

View File

@@ -1,47 +1,54 @@
import { Ionicons } from "@expo/vector-icons";
import * as Notifications from "expo-notifications";
import { t } from "i18next";
import { useEffect, useState } from "react";
import { Linking, ScrollView, Switch } from "react-native";
import { Linking, ScrollView, Switch, View } from "react-native";
import { Button } from "@/components/Button";
import { Text } from "@/components/common/Text";
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);
const [perm, setPerm] =
useState<Notifications.NotificationPermissionsStatus | null>(null);
useEffect(() => {
Notifications.getPermissionsAsync().then((p) => setGranted(p.granted));
Notifications.getPermissionsAsync().then(setPerm);
}, []);
const requestPermission = async () => {
const p = await Notifications.requestPermissionsAsync();
setGranted(p.granted);
if (!p.granted) Linking.openSettings();
const res = await Notifications.requestPermissionsAsync();
setPerm(res);
// Only bounce to system settings when the OS will not prompt again.
if (!res.granted && res.canAskAgain === false) {
Linking.openSettings();
}
};
if (!settings) return null;
if (!settings || perm === null) return null;
if (!perm.granted) {
return (
<View className='flex-1 items-center justify-center px-8'>
<Ionicons name='notifications-off-outline' size={56} color='#5A5960' />
<Text className='text-white text-lg font-semibold mt-4 text-center'>
{t("home.settings.notifications.disabled_title")}
</Text>
<Text className='text-[#9899A1] text-center mt-2'>
{t("home.settings.notifications.disabled_description")}
</Text>
<Button color='purple' className='mt-6' onPress={requestPermission}>
{t("home.settings.notifications.enable_button")}
</Button>
</View>
);
}
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'
>
<ListGroup title={t("home.settings.notifications.events_title")}>
<ListItem title={t("home.settings.notifications.master")}>
<Switch
value={settings.notificationsEnabled}

View File

@@ -136,10 +136,9 @@
},
"notifications": {
"title": "Notifications",
"permission_title": "Permission",
"system_permission": "System permission",
"granted": "Granted",
"denied": "Denied",
"disabled_title": "Notifications are off",
"disabled_description": "Allow notifications to get alerts about your downloads and more.",
"enable_button": "Enable notifications",
"events_title": "Notify me about",
"master": "Enable notifications",
"downloads": "Download completed / failed"