diff --git a/EditPlan.tsx b/EditPlan.tsx index b1d3d39..b0dad84 100644 --- a/EditPlan.tsx +++ b/EditPlan.tsx @@ -86,7 +86,7 @@ export default function EditPlan({ setShow(false)}> {id ? `Edit "${days}"` : 'Add a plan'} - + {days.split(',').map((day, index) => ( repsRef.current?.focus()} + autoCorrect={false} /> ) { +export default function Exercises() { const [exercises, setExercises] = useState([]); const [search, setSearch] = useState(''); const [refreshing, setRefresing] = useState(false); @@ -26,7 +25,10 @@ export default function Exercises({ setExercises(result.rows.raw()); }; - useEffect(() => navigation.addListener('focus', refresh), [navigation]); + useFocusEffect(() => { + refresh(); + }); + useEffect(() => { refresh(); }, [search]); diff --git a/Home.tsx b/Home.tsx index 0a6dd07..e1cc59c 100644 --- a/Home.tsx +++ b/Home.tsx @@ -1,13 +1,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; -import {useNavigation} from '@react-navigation/native'; +import {useFocusEffect} from '@react-navigation/native'; import React, {useEffect, useState} from 'react'; -import { - FlatList, - NativeModules, - SafeAreaView, - StyleSheet, - View, -} from 'react-native'; +import {FlatList, NativeModules, SafeAreaView, StyleSheet} from 'react-native'; import {AnimatedFAB, Searchbar} from 'react-native-paper'; import {getSets} from './db'; import EditSet from './EditSet'; @@ -24,23 +18,26 @@ export default function Home() { const [showEdit, setShowEdit] = useState(false); const [search, setSearch] = useState(''); const [refreshing, setRefresing] = useState(false); - const navigation = useNavigation(); const refresh = async () => { - setRefresing(true); - const [result] = await getSets({search, limit, offset: 0}).finally(() => - setRefresing(false), - ); + const [result] = await getSets({search, limit, offset: 0}); if (!result) return setSets([]); setSets(result.rows.raw()); setOffset(0); }; + const refreshLoader = async () => { + setRefresing(true); + refresh().finally(() => setRefresing(false)); + }; + useEffect(() => { refresh(); }, [search]); - useEffect(() => navigation.addListener('focus', refresh), [navigation]); + useFocusEffect(() => { + refresh(); + }); const renderItem = ({item}: {item: Set}) => ( set.id.toString()} onEndReached={next} refreshing={refreshing} - onRefresh={refresh} + onRefresh={refreshLoader} /> setId(undefined)} @@ -113,6 +109,7 @@ const styles = StyleSheet.create({ fontSize: 18, }, container: { + flexGrow: 1, flex: 1, padding: 10, }, diff --git a/Plans.tsx b/Plans.tsx index 8016880..c0aad30 100644 --- a/Plans.tsx +++ b/Plans.tsx @@ -1,10 +1,13 @@ +import {useFocusEffect} from '@react-navigation/native'; +import {format} from 'date-fns'; import React, {useEffect, useState} from 'react'; -import {FlatList, View} from 'react-native'; -import {AnimatedFAB, Searchbar} from 'react-native-paper'; -import {getPlans} from './db'; +import {FlatList, StyleSheet, Text, View} from 'react-native'; +import {AnimatedFAB, ProgressBar, Searchbar} from 'react-native-paper'; +import {getPlans, getProgress} from './db'; import EditPlan from './EditPlan'; import {Plan} from './plan'; import PlanItem from './PlanItem'; +import Progress from './progress'; export default function Plans() { const [search, setSearch] = useState(''); @@ -12,12 +15,31 @@ export default function Plans() { const [refreshing, setRefresing] = useState(false); const [id, setId] = useState(); const [showEdit, setShowEdit] = useState(false); + const [progresses, setProgresses] = useState([]); + const today = `%${format(new Date(new Date().toUTCString()), 'EEEE')}%`; + const now = `${format(new Date(new Date().toUTCString()), 'yyyy-MM-dd')}%`; const refresh = async () => { const [plansResult] = await getPlans({search}); setPlans(plansResult.rows.raw()); + const [todaysResult] = await getPlans({search: today}); + if (todaysResult.rows.length === 0) return; + const workouts: string[] = todaysResult.rows.item(0).workouts.split(','); + const newProgress: Progress[] = []; + for (const workout of workouts) { + const [workoutResult] = await getProgress({ + created: now, + name: workout, + }); + newProgress.push({name: workout, sets: workoutResult.rows.item(0).count}); + } + setProgresses(newProgress); }; + useFocusEffect(() => { + refresh(); + }); + useEffect(() => { refresh(); }, [search]); @@ -33,15 +55,24 @@ export default function Plans() { ); return ( - + + {progresses.map(progress => ( + + {progress.name} + + + ))} + set.id.toString()} refreshing={refreshing} - onRefresh={refresh} + onRefresh={() => { + setRefresing(true); + refresh().finally(() => setRefresing(false)); + }} /> ); } + +const styles = StyleSheet.create({ + container: { + flexGrow: 1, + padding: 10, + }, + progress: { + marginTop: 10, + }, +}); diff --git a/Settings.tsx b/Settings.tsx index 1a9b1ef..a1e48e3 100644 --- a/Settings.tsx +++ b/Settings.tsx @@ -1,28 +1,29 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; -import {NativeStackScreenProps} from '@react-navigation/native-stack'; +import {useFocusEffect, useNavigation} from '@react-navigation/native'; import React, {useEffect, useState} from 'react'; import {NativeModules, StyleSheet, Text, View} from 'react-native'; import {Button, Snackbar, Switch, TextInput} from 'react-native-paper'; -import {RootStackParamList} from './App'; -import {getDb} from './db'; import BatteryDialog from './BatteryDialog'; +import {getDb} from './db'; -export default function Settings({ - navigation, -}: NativeStackScreenProps) { +export default function Settings() { const [minutes, setMinutes] = useState(''); const [seconds, setSeconds] = useState(''); const [alarmEnabled, setAlarmEnabled] = useState(true); const [snackbar, setSnackbar] = useState(''); const [showBattery, setShowBattery] = useState(false); + const [ignoring, setIgnoring] = useState(false); - useEffect(() => { - (async () => { - setMinutes((await AsyncStorage.getItem('minutes')) || '3'); - setSeconds((await AsyncStorage.getItem('seconds')) || ''); - setAlarmEnabled((await AsyncStorage.getItem('alarmEnabled')) === 'true'); - })(); - }, [navigation]); + const refresh = async () => { + setMinutes((await AsyncStorage.getItem('minutes')) || '3'); + setSeconds((await AsyncStorage.getItem('seconds')) || ''); + setAlarmEnabled((await AsyncStorage.getItem('alarmEnabled')) === 'true'); + NativeModules.AlarmModule.ignoringBatteryOptimizations(setIgnoring); + }; + + useFocusEffect(() => { + refresh(); + }); useEffect(() => { if (minutes) AsyncStorage.setItem('minutes', minutes); @@ -46,13 +47,8 @@ export default function Settings({ }; const changeAlarmEnabled = (enabled: boolean) => { - if (!enabled) return setAlarmEnabled(enabled); - NativeModules.AlarmModule.ignoringBatteryOptimizations( - (ignoring: boolean) => { - if (ignoring) return setAlarmEnabled(true); - setShowBattery(true); - }, - ); + setAlarmEnabled(enabled); + if (enabled && !ignoring) setShowBattery(true); }; return ( diff --git a/db.ts b/db.ts index b0de527..02673ab 100644 --- a/db.ts +++ b/db.ts @@ -37,6 +37,14 @@ export const getPlans = ({search}: {search: string}) => db.executeSql(selectPlans, [`%${search}%`, `%${search}%`]), ); +const selectProgress = ` + SELECT count(*) as count from sets + WHERE created LIKE ? + AND name = ? +`; +export const getProgress = ({created, name}: {created: string; name: string}) => + getDb().then(db => db.executeSql(selectProgress, [`%${created}%`, name])); + const selectSets = ` SELECT * from sets WHERE name LIKE ? diff --git a/progress.ts b/progress.ts new file mode 100644 index 0000000..9f8c493 --- /dev/null +++ b/progress.ts @@ -0,0 +1,4 @@ +export default interface Progress { + name: string; + sets: number; +}