import React, { ReactNode, useCallback, useContext, useEffect, useState, } from 'react'; import {NativeModules, ScrollView, StyleSheet, View} from 'react-native'; import DocumentPicker from 'react-native-document-picker'; import {Button, Searchbar, Text} from 'react-native-paper'; import {SnackbarContext} from './App'; import ConfirmDialog from './ConfirmDialog'; import {getSettings, setSettings} from './db'; import MassiveInput from './MassiveInput'; import MassiveSwitch from './MassiveSwitch'; export default function SettingsPage() { const [vibrate, setVibrate] = useState(true); const [minutes, setMinutes] = useState(''); const [sets, setMaxSets] = useState('3'); const [seconds, setSeconds] = useState(''); const [alarm, setAlarm] = useState(false); const [predict, setPredict] = useState(false); const [sound, setSound] = useState(''); const [notify, setNotify] = useState(false); const [images, setImages] = useState(false); const [battery, setBattery] = useState(false); const [ignoring, setIgnoring] = useState(false); const [search, setSearch] = useState(''); const {toast} = useContext(SnackbarContext); const refresh = useCallback(async () => { const settings = await getSettings(); console.log('SettingsPage.refresh:', {settings}); setMinutes(settings.minutes.toString()); setSeconds(settings.seconds.toString()); setAlarm(!!settings.alarm); setPredict(!!settings.predict); setMaxSets(settings.sets.toString()); setVibrate(!!settings.vibrate); setSound(settings.sound); setNotify(!!settings.notify); setImages(!!settings.images); NativeModules.AlarmModule.ignoringBattery(setIgnoring); }, []); useEffect(() => { refresh(); }, [refresh]); useEffect(() => { setSettings({ vibrate: +vibrate, minutes: +minutes, seconds: +seconds, alarm: +alarm, predict: +predict, sound, notify: +notify, images: +images, sets: +sets, }); }, [vibrate, minutes, sets, seconds, alarm, predict, sound, notify, images]); const changeAlarmEnabled = useCallback( (enabled: boolean) => { setAlarm(enabled); toast('Time your rest duration after each set.', 4000); if (enabled && !ignoring) setBattery(true); }, [setBattery, ignoring, toast], ); const changePredict = useCallback( (enabled: boolean) => { setPredict(enabled); toast('Predict your next set based on todays plan.', 4000); }, [setPredict, toast], ); const changeVibrate = useCallback( (value: boolean) => { setVibrate(value); toast('When a timer completes, vibrate your phone.', 4000); }, [setVibrate, toast], ); const changeSound = useCallback(async () => { const {fileCopyUri} = await DocumentPicker.pickSingle({ type: 'audio/*', copyTo: 'documentDirectory', }); if (fileCopyUri) setSound(fileCopyUri); }, []); const changeNotify = useCallback( (value: boolean) => { setNotify(value); toast('If a set is a new record, show a notification.', 4000); }, [toast], ); const items: {name: string; element: ReactNode}[] = [ { name: 'Sets per workout', element: ( { setMaxSets(value); }} /> ), }, { name: 'Rest minutes Rest seconds', element: ( { setMinutes(text); }} /> { setSeconds(s); }} /> ), }, { name: 'Rest timers', element: ( <> Rest timers ), }, { name: 'Vibrate', element: ( <> Vibrate ), }, { name: 'Predict sets', element: ( <> Predict sets ), }, { name: 'Record notifications', element: ( <> Record notifications ), }, { name: 'Show images', element: ( <> Show images ), }, { name: 'Alarm sound', element: ( ), }, ]; return ( {items .filter(item => item.name.toLowerCase().includes(search.toLowerCase()), ) .map(item => ( {item.element} ))} { NativeModules.AlarmModule.ignoreBattery(); setBattery(false); }}> Disable battery optimizations for Massive to use rest timers. ); } const styles = StyleSheet.create({ container: { padding: 10, flex: 1, }, text: { marginBottom: 10, }, });