Files
orca/mobile/app/notifications.tsx
2026-05-04 13:08:27 -07:00

110 lines
3.0 KiB
TypeScript

import { useState, useCallback } from 'react'
import { View, Text, StyleSheet, Pressable, Switch } from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { useRouter, useFocusEffect } from 'expo-router'
import { ChevronLeft } from 'lucide-react-native'
import { colors, spacing, typography } from '../src/theme/mobile-theme'
import {
loadPushNotificationsEnabled,
savePushNotificationsEnabled
} from '../src/storage/preferences'
import { ensureNotificationPermissions } from '../src/notifications/mobile-notifications'
export default function NotificationsScreen() {
const router = useRouter()
const insets = useSafeAreaInsets()
const [pushEnabled, setPushEnabled] = useState(true)
useFocusEffect(
useCallback(() => {
void loadPushNotificationsEnabled().then(setPushEnabled)
}, [])
)
const togglePush = async (value: boolean) => {
if (value) {
const granted = await ensureNotificationPermissions()
if (!granted) return
}
setPushEnabled(value)
await savePushNotificationsEnabled(value)
}
return (
<View style={[styles.container, { paddingTop: insets.top + spacing.sm }]}>
<View style={styles.topRow}>
<Pressable style={styles.backButton} onPress={() => router.back()}>
<ChevronLeft size={22} color={colors.textSecondary} />
</Pressable>
<Text style={styles.heading}>Notifications</Text>
</View>
<View style={styles.section}>
<View style={styles.row}>
<Text style={styles.rowLabel}>Push Notifications</Text>
<Switch
value={pushEnabled}
onValueChange={(v) => void togglePush(v)}
trackColor={{ false: colors.bgRaised, true: colors.textSecondary }}
thumbColor={colors.textPrimary}
/>
</View>
<Text style={styles.hint}>
Receive notifications when an agent task completes on your desktop.
</Text>
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: colors.bgBase,
padding: spacing.lg
},
topRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: spacing.xl
},
backButton: {
width: 36,
height: 36,
borderRadius: 18,
alignItems: 'center',
justifyContent: 'center',
marginRight: spacing.sm
},
heading: {
fontSize: 20,
fontWeight: '700',
color: colors.textPrimary
},
section: {
backgroundColor: colors.bgPanel,
borderRadius: 12,
overflow: 'hidden'
},
row: {
flexDirection: 'row',
alignItems: 'center',
gap: spacing.sm + 2,
paddingVertical: spacing.md,
paddingHorizontal: spacing.md + 2
},
rowLabel: {
flex: 1,
fontSize: typography.bodySize,
fontWeight: '500',
color: colors.textPrimary
},
hint: {
fontSize: typography.metaSize,
color: colors.textMuted,
lineHeight: 18,
paddingHorizontal: spacing.md + 2,
paddingBottom: spacing.md
}
})