diff --git a/SetList.tsx b/SetList.tsx index fd02a9c..f87c5f7 100644 --- a/SetList.tsx +++ b/SetList.tsx @@ -26,8 +26,8 @@ export default function SetList() { const [offset, setOffset] = useState(0); const [search, setSearch] = useState(''); const [end, setEnd] = useState(false); - const [dates, setDates] = useState(false); const {settings} = useSettings(); + const [dates, setDates] = useState(!!settings.showDate); const navigation = useNavigation>(); const predict = useCallback(async () => { @@ -80,7 +80,8 @@ export default function SetList() { navigation.getParent()?.setOptions({ headerRight: () => , }); - }, [refresh, navigation]), + setDates(!!settings.showDate); + }, [refresh, navigation, settings.showDate]), ); useEffect(() => { diff --git a/SettingsPage.tsx b/SettingsPage.tsx index f5c9563..4c00798 100644 --- a/SettingsPage.tsx +++ b/SettingsPage.tsx @@ -30,6 +30,7 @@ export default function SettingsPage() { const [workouts, setWorkouts] = useState(!!settings.workouts); const [steps, setSteps] = useState(!!settings.steps); const [date, setDate] = useState('%Y-%m-%d %H:%M'); + const [showDate, setShowDate] = useState(false); const {color, setColor} = useContext(CustomTheme); const {toast} = useContext(SnackbarContext); @@ -52,6 +53,7 @@ export default function SettingsPage() { workouts: +workouts, steps: +steps, date, + showDate: +showDate, }); getSettings().then(setSettings); }, [ @@ -67,6 +69,7 @@ export default function SettingsPage() { steps, setSettings, date, + showDate, ]); const changeAlarmEnabled = useCallback( @@ -143,6 +146,15 @@ export default function SettingsPage() { [toast], ); + const changeShowDate = useCallback( + (enabled: boolean) => { + setShowDate(enabled); + if (enabled) toast('Show date for sets by default.', 4000); + else toast('Stopped showing date for sets by default.', 4000); + }, + [toast], + ); + const switches: Input[] = [ {name: 'Rest timers', value: alarm, onChange: changeAlarmEnabled}, {name: 'Vibrate', value: vibrate, onChange: changeVibrate}, @@ -151,6 +163,7 @@ export default function SettingsPage() { {name: 'Show unit', value: showUnit, onChange: changeUnit}, {name: 'Show workouts', value: workouts, onChange: changeWorkouts}, {name: 'Show steps', value: steps, onChange: changeSteps}, + {name: 'Show date', value: showDate, onChange: changeShowDate}, ]; return ( diff --git a/TimerPage.tsx b/TimerPage.tsx new file mode 100644 index 0000000..78a959f --- /dev/null +++ b/TimerPage.tsx @@ -0,0 +1,101 @@ +import {useFocusEffect} from '@react-navigation/native'; +import React, {useCallback, useEffect, useState} from 'react'; +import {NativeModules, View} from 'react-native'; +import {Button, Text} from 'react-native-paper'; +import {MARGIN, PADDING} from './constants'; +import { + getNext, + getSettings, + settings, + updateSettings, +} from './settings.service'; + +export default function TimerPage() { + const [next, setNext] = useState(new Date()); + const [ms, setMs] = useState(0); + const [intervalId, setIntervalId] = useState(0); + + const seconds = + ms > 0 + ? Math.floor((ms / 1000) % 60) + .toString() + .padStart(2, '0') + : '00'; + + const minutes = + ms > 0 + ? Math.floor(ms / 1000 / 60) + .toString() + .padStart(2, '0') + : '00'; + + useFocusEffect( + useCallback(() => { + getNext().then(nextIso => + setNext(nextIso ? new Date(nextIso) : new Date()), + ); + }, []), + ); + + const tick = (date: Date) => { + const remaining = date.getTime() - new Date().getTime(); + console.log(`${TimerPage.name}.tick`, {remaining}); + if (remaining <= 0) return 0; + setMs(remaining); + return remaining; + }; + + useEffect(() => { + console.log(`${TimerPage.name}.useEffect:`, {next}); + const date = next || new Date(); + if (tick(date) <= 0) return; + const id = setInterval(() => { + if (tick(date) <= 0) clearInterval(id); + }, 1000); + setIntervalId(oldId => { + clearInterval(oldId); + return id; + }); + return () => clearInterval(id); + }, [next]); + + const stop = () => { + NativeModules.AlarmModule.stop(); + setNext(new Date()); + updateSettings({...settings, nextAlarm: undefined}); + getSettings(); + tick(new Date()); + setMs(0); + }; + + const add = async () => { + console.log(`${TimerPage.name}.add:`, {intervalId, next}); + const date = next || new Date(); + date.setTime(date.getTime() + 1000 * 60); + await updateSettings({...settings, nextAlarm: date.toISOString()}); + setNext(date); + NativeModules.AlarmModule.add(ms, !!settings.vibrate, settings.sound); + tick(date); + const id = setInterval(() => { + if (tick(date) <= 0) clearInterval(id); + }, 1000); + setIntervalId(oldId => { + clearInterval(oldId); + return id; + }); + }; + + return ( + + + {minutes}:{seconds} + + + + + ); +} diff --git a/db.ts b/db.ts index d3efa36..27bee51 100644 --- a/db.ts +++ b/db.ts @@ -109,6 +109,9 @@ const migrations = [ ` ALTER TABLE settings ADD COLUMN date TEXT NULL `, + ` + ALTER TABLE settings ADD COLUMN showDate BOOLEAN DEFAULT 0 + `, ]; export let db: SQLiteDatabase; diff --git a/settings.ts b/settings.ts index 1b13756..e23cd13 100644 --- a/settings.ts +++ b/settings.ts @@ -11,4 +11,5 @@ export default interface Settings { nextAlarm?: string; steps?: number; date?: string; + showDate: number; }