chahinebrini 943afb827b feat(native): settings overhaul — DEV cleanup + notifications section
- Remove __DEV__ debug section from settings.tsx:
  Plan-Override-Row (4 rows: LLM, TTS, plan-override, realtime),
  PlanPickerSheetContent, planSheetRef, DEV_PLANS/DEV_PLAN_ACCENT,
  ActivityIndicator import. The debug.tsx page + realtimeDebug.ts store
  are kept — only UI entry points removed from settings.
- Wire notifications section: pushEnabled/streakReminderEnabled toggles
  + streakReminderTime picker (hour/minute scroll, quarters). State
  persisted in AsyncStorage via new stores/notificationPrefs.ts.
  setPushEnabled calls Notifications.requestPermissionsAsync() — if
  denied, toggle stays off. scheduleNotificationAsync is a TODO (no
  backend endpoint yet).
- Add _layout.tsx Stack.Screen entry for help/* route group.
- i18n: new keys settings.notifications_push_sublabel,
  notifications_streak_time, notifications_hour/minute,
  section_help, help_faq/contact/about/crisis + descs in DE/EN/FR.

TODO: expo-notifications scheduleNotificationAsync wiring once
backend streak-reminder endpoint exists.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 23:42:33 +02:00

64 lines
2.2 KiB
TypeScript

import { create } from 'zustand';
import AsyncStorage from '@react-native-async-storage/async-storage';
import * as Notifications from 'expo-notifications';
const STORAGE_KEY = '@rebreak/notifications-prefs';
type NotificationPrefsState = {
pushEnabled: boolean;
streakReminderEnabled: boolean;
streakReminderTime: { hour: number; minute: number };
init: () => Promise<void>;
setPushEnabled: (value: boolean) => Promise<void>;
setStreakReminderEnabled: (value: boolean) => Promise<void>;
setStreakReminderTime: (hour: number, minute: number) => Promise<void>;
};
async function persist(patch: Partial<Pick<NotificationPrefsState, 'pushEnabled' | 'streakReminderEnabled' | 'streakReminderTime'>>) {
const existing = await AsyncStorage.getItem(STORAGE_KEY);
const current = existing ? JSON.parse(existing) : {};
await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify({ ...current, ...patch }));
}
export const useNotificationPrefsStore = create<NotificationPrefsState>((set, get) => ({
pushEnabled: false,
streakReminderEnabled: false,
streakReminderTime: { hour: 9, minute: 0 },
init: async () => {
const stored = await AsyncStorage.getItem(STORAGE_KEY);
if (!stored) return;
const parsed = JSON.parse(stored);
set({
pushEnabled: parsed.pushEnabled ?? false,
streakReminderEnabled: parsed.streakReminderEnabled ?? false,
streakReminderTime: parsed.streakReminderTime ?? { hour: 9, minute: 0 },
});
},
// TODO: wire up expo-notifications requestPermissionsAsync + scheduleNotificationAsync
// once the streak reminder backend endpoint exists. Currently persists user intent only.
setPushEnabled: async (value) => {
if (value) {
const { status } = await Notifications.requestPermissionsAsync();
if (status !== 'granted') {
return;
}
}
set({ pushEnabled: value });
await persist({ pushEnabled: value });
},
setStreakReminderEnabled: async (value) => {
set({ streakReminderEnabled: value });
await persist({ streakReminderEnabled: value });
},
setStreakReminderTime: async (hour, minute) => {
const streakReminderTime = { hour, minute };
set({ streakReminderTime });
await persist({ streakReminderTime });
},
}));