Remove useFocusEffect

It was lagging the app out.
This commit is contained in:
Brandon Presley 2022-07-07 15:13:44 +12:00
parent 570b43715f
commit 1d68ba86f5
9 changed files with 43 additions and 91 deletions

View File

@ -6,17 +6,15 @@ import {Plan} from './plan';
import WorkoutMenu from './WorkoutMenu'; import WorkoutMenu from './WorkoutMenu';
export default function EditPlan({ export default function EditPlan({
id, plan,
onSave, onSave,
show, show,
setShow, setShow,
clearId,
}: { }: {
id?: number;
clearId: () => void;
onSave: () => void; onSave: () => void;
show: boolean; show: boolean;
setShow: (visible: boolean) => void; setShow: (visible: boolean) => void;
plan?: Plan;
}) { }) {
const [days, setDays] = useState(''); const [days, setDays] = useState('');
const [workouts, setWorkouts] = useState(''); const [workouts, setWorkouts] = useState('');
@ -27,23 +25,18 @@ export default function EditPlan({
const [namesResult] = await db.executeSql('SELECT DISTINCT name FROM sets'); const [namesResult] = await db.executeSql('SELECT DISTINCT name FROM sets');
if (!namesResult.rows.length) return; if (!namesResult.rows.length) return;
setNames(namesResult.rows.raw().map(({name}) => name)); setNames(namesResult.rows.raw().map(({name}) => name));
if (!id) return; if (!plan) return;
const [result] = await db.executeSql(`SELECT * FROM plans WHERE id = ?`, [ setDays(plan.days);
id, setWorkouts(plan.workouts);
]);
if (!result.rows.item(0)) throw new Error("Can't find specified Set.");
const set: Plan = result.rows.item(0);
setDays(set.days);
setWorkouts(set.workouts);
}; };
useEffect(() => { useEffect(() => {
refresh(); refresh();
}, [id]); }, [plan]);
const save = async () => { const save = async () => {
if (!days || !workouts) return; if (!days || !workouts) return;
if (!id) if (!plan)
await db.executeSql(`INSERT INTO plans(days, workouts) VALUES (?, ?)`, [ await db.executeSql(`INSERT INTO plans(days, workouts) VALUES (?, ?)`, [
days, days,
workouts, workouts,
@ -51,7 +44,7 @@ export default function EditPlan({
else else
await db.executeSql( await db.executeSql(
`UPDATE plans SET days = ?, workouts = ? WHERE id = ?`, `UPDATE plans SET days = ?, workouts = ? WHERE id = ?`,
[days, workouts, id], [days, workouts, plan.id],
); );
setShow(false); setShow(false);
onSave(); onSave();
@ -84,7 +77,7 @@ export default function EditPlan({
return ( return (
<Portal> <Portal>
<Dialog visible={show} onDismiss={() => setShow(false)}> <Dialog visible={show} onDismiss={() => setShow(false)}>
<Dialog.Title>{id ? `Edit "${days}"` : 'Add a plan'}</Dialog.Title> <Dialog.Title>{plan ? `Edit "${days}"` : 'Add a plan'}</Dialog.Title>
<Dialog.Content> <Dialog.Content>
{days.split(',').map((day, index) => ( {days.split(',').map((day, index) => (
<DayMenu <DayMenu

View File

@ -41,7 +41,7 @@ export default function EditSet({
const save = async () => { const save = async () => {
if (!name || !reps || !weight) return; if (!name || !reps || !weight) return;
if (!set) if (!set?.id)
await db.executeSql( await db.executeSql(
`INSERT INTO sets(name, reps, weight, created, unit) VALUES (?,?,?,?,?)`, `INSERT INTO sets(name, reps, weight, created, unit) VALUES (?,?,?,?,?)`,
[name, reps, weight, new Date().toISOString(), unit || 'kg'], [name, reps, weight, new Date().toISOString(), unit || 'kg'],

View File

@ -1,4 +1,3 @@
import {useFocusEffect} from '@react-navigation/native';
import React, {useContext, useEffect, useState} from 'react'; import React, {useContext, useEffect, useState} from 'react';
import {FlatList, StyleSheet, View} from 'react-native'; import {FlatList, StyleSheet, View} from 'react-native';
import {List, Searchbar} from 'react-native-paper'; import {List, Searchbar} from 'react-native-paper';
@ -23,10 +22,6 @@ export default function Exercises() {
setExercises(result.rows.raw()); setExercises(result.rows.raw());
}; };
useFocusEffect(() => {
refresh();
});
useEffect(() => { useEffect(() => {
refresh(); refresh();
}, [search]); }, [search]);

View File

@ -1,5 +1,4 @@
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from '@react-native-async-storage/async-storage';
import {useFocusEffect} from '@react-navigation/native';
import React, {useContext, useEffect, useState} from 'react'; import React, {useContext, useEffect, useState} from 'react';
import {FlatList, NativeModules, SafeAreaView, StyleSheet} from 'react-native'; import {FlatList, NativeModules, SafeAreaView, StyleSheet} from 'react-native';
import {AnimatedFAB, Searchbar} from 'react-native-paper'; import {AnimatedFAB, Searchbar} from 'react-native-paper';
@ -18,6 +17,7 @@ export default function Home() {
const [show, setShow] = useState(false); const [show, setShow] = useState(false);
const [search, setSearch] = useState(''); const [search, setSearch] = useState('');
const [refreshing, setRefresing] = useState(false); const [refreshing, setRefresing] = useState(false);
const [end, setEnd] = useState(false);
const db = useContext(DatabaseContext); const db = useContext(DatabaseContext);
const selectSets = ` const selectSets = `
@ -41,6 +41,7 @@ export default function Home() {
if (!result) return setSets([]); if (!result) return setSets([]);
setSets(result.rows.raw()); setSets(result.rows.raw());
setOffset(0); setOffset(0);
setEnd(false);
}; };
const refreshLoader = async () => { const refreshLoader = async () => {
@ -52,10 +53,6 @@ export default function Home() {
refresh(); refresh();
}, [search]); }, [search]);
useFocusEffect(() => {
refresh();
});
const renderItem = ({item}: {item: Set}) => ( const renderItem = ({item}: {item: Set}) => (
<SetItem <SetItem
item={item} item={item}
@ -77,14 +74,16 @@ export default function Home() {
}; };
const next = async () => { const next = async () => {
if (end) return;
setRefresing(true); setRefresing(true);
const newOffset = offset + limit; const newOffset = offset + limit;
const [result] = await getSets({search, limit, offset: newOffset}).finally( const [result] = await getSets({search, limit, offset: newOffset}).finally(
() => setRefresing(false), () => setRefresing(false),
); );
if (result.rows.length === 0) return; if (result.rows.length === 0) return setEnd(true);
if (!sets) return; if (!sets) return;
setSets([...sets, ...result.rows.raw()]); setSets([...sets, ...result.rows.raw()]);
if (result.rows.length < limit) return setEnd(true);
setOffset(newOffset); setOffset(newOffset);
}; };
@ -92,9 +91,10 @@ export default function Home() {
<SafeAreaView style={styles.container}> <SafeAreaView style={styles.container}>
<Searchbar placeholder="Search" value={search} onChangeText={setSearch} /> <Searchbar placeholder="Search" value={search} onChangeText={setSearch} />
<FlatList <FlatList
style={{height: 100}}
data={sets} data={sets}
renderItem={renderItem} renderItem={renderItem}
keyExtractor={set => set.id.toString()} keyExtractor={set => set.id!.toString()}
onEndReached={next} onEndReached={next}
refreshing={refreshing} refreshing={refreshing}
onRefresh={refreshLoader} onRefresh={refreshLoader}
@ -121,11 +121,6 @@ const styles = StyleSheet.create({
}, },
container: { container: {
flexGrow: 1, flexGrow: 1,
flex: 1,
padding: 10, padding: 10,
}, },
bottom: {
alignSelf: 'center',
flexDirection: 'row',
},
}); });

View File

@ -5,12 +5,12 @@ import {Plan} from './plan';
export default function PlanItem({ export default function PlanItem({
item, item,
setId, setPlan,
setShowEdit, setShowEdit,
onRemove, onRemove,
}: { }: {
item: Plan; item: Plan;
setId: (id: number) => void; setPlan: (plan: Plan) => void;
setShowEdit: (show: boolean) => void; setShowEdit: (show: boolean) => void;
onRemove: () => void; onRemove: () => void;
}) { }) {
@ -27,7 +27,7 @@ export default function PlanItem({
<> <>
<List.Item <List.Item
onPress={() => { onPress={() => {
setId(item.id); setPlan(item);
setShowEdit(true); setShowEdit(true);
}} }}
title={item.days} title={item.days}

View File

@ -1,23 +1,17 @@
import {useFocusEffect} from '@react-navigation/native';
import {format} from 'date-fns';
import React, {useContext, useEffect, useState} from 'react'; import React, {useContext, useEffect, useState} from 'react';
import {FlatList, StyleSheet, Text, View} from 'react-native'; import {FlatList, StyleSheet, View} from 'react-native';
import {AnimatedFAB, ProgressBar, Searchbar} from 'react-native-paper'; import {AnimatedFAB, Searchbar} from 'react-native-paper';
import {DatabaseContext} from './App'; import {DatabaseContext} from './App';
import EditPlan from './EditPlan'; import EditPlan from './EditPlan';
import {Plan} from './plan'; import {Plan} from './plan';
import PlanItem from './PlanItem'; import PlanItem from './PlanItem';
import Progress from './progress';
export default function Plans() { export default function Plans() {
const [search, setSearch] = useState(''); const [search, setSearch] = useState('');
const [plans, setPlans] = useState<Plan[]>([]); const [plans, setPlans] = useState<Plan[]>([]);
const [refreshing, setRefresing] = useState(false); const [refreshing, setRefresing] = useState(false);
const [id, setId] = useState<number>(); const [plan, setPlan] = useState<Plan>();
const [showEdit, setShowEdit] = useState(false); const [showEdit, setShowEdit] = useState(false);
const [progresses, setProgresses] = useState<Progress[]>([]);
const today = `%${format(new Date(new Date().toUTCString()), 'EEEE')}%`;
const now = `${format(new Date(new Date().toUTCString()), 'yyyy-MM-dd')}%`;
const db = useContext(DatabaseContext); const db = useContext(DatabaseContext);
const selectPlans = ` const selectPlans = `
@ -27,35 +21,11 @@ export default function Plans() {
const getPlans = ({search}: {search: string}) => const getPlans = ({search}: {search: string}) =>
db.executeSql(selectPlans, [`%${search}%`, `%${search}%`]); db.executeSql(selectPlans, [`%${search}%`, `%${search}%`]);
const selectProgress = `
SELECT COUNT(*) as count from sets
WHERE created LIKE ?
AND name = ?
`;
const getProgress = ({created, name}: {created: string; name: string}) =>
db.executeSql(selectProgress, [`%${created}%`, name]);
const refresh = async () => { const refresh = async () => {
const [plansResult] = await getPlans({search}); const [plansResult] = await getPlans({search});
setPlans(plansResult.rows.raw()); 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(() => { useEffect(() => {
refresh(); refresh();
}, [search]); }, [search]);
@ -65,7 +35,7 @@ export default function Plans() {
item={item} item={item}
key={item.id} key={item.id}
setShowEdit={setShowEdit} setShowEdit={setShowEdit}
setId={setId} setPlan={setPlan}
onRemove={refresh} onRemove={refresh}
/> />
); );
@ -73,13 +43,6 @@ export default function Plans() {
return ( return (
<View style={styles.container}> <View style={styles.container}>
<Searchbar value={search} onChangeText={setSearch} placeholder="Search" /> <Searchbar value={search} onChangeText={setSearch} placeholder="Search" />
{progresses.map(progress => (
<React.Fragment key={progress.name}>
<Text style={styles.progress}>{progress.name}</Text>
<ProgressBar progress={progress.sets / 3} />
</React.Fragment>
))}
<FlatList <FlatList
data={plans} data={plans}
renderItem={renderItem} renderItem={renderItem}
@ -92,11 +55,10 @@ export default function Plans() {
/> />
<EditPlan <EditPlan
clearId={() => setId(undefined)}
onSave={refresh} onSave={refresh}
setShow={setShowEdit} setShow={setShowEdit}
show={showEdit} show={showEdit}
id={id} plan={plan}
/> />
<AnimatedFAB <AnimatedFAB
@ -105,7 +67,7 @@ export default function Plans() {
icon="add" icon="add"
style={{position: 'absolute', right: 20, bottom: 20}} style={{position: 'absolute', right: 20, bottom: 20}}
onPress={() => { onPress={() => {
setId(undefined); setPlan(undefined);
setShowEdit(true); setShowEdit(true);
}} }}
/> />

View File

@ -14,15 +14,22 @@ export default function SetItem({
setShowEdit: (show: boolean) => void; setShowEdit: (show: boolean) => void;
onRemove: () => void; onRemove: () => void;
}) { }) {
const [show, setShow] = useState(false); const [showMenu, setShowMenu] = useState(false);
const db = useContext(DatabaseContext); const db = useContext(DatabaseContext);
const remove = async () => { const remove = async () => {
await db.executeSql(`DELETE FROM sets WHERE id = ?`, [item.id]); await db.executeSql(`DELETE FROM sets WHERE id = ?`, [item.id]);
setShow(false); setShowMenu(false);
onRemove(); onRemove();
}; };
const copy = () => {
const {id, ...set} = {...item};
setSet(set);
setShowEdit(true);
setShowMenu(false);
};
return ( return (
<> <>
<List.Item <List.Item
@ -32,18 +39,19 @@ export default function SetItem({
}} }}
title={item.name} title={item.name}
description={`${item.reps} x ${item.weight}${item.unit}`} description={`${item.reps} x ${item.weight}${item.unit}`}
onLongPress={() => setShow(true)} onLongPress={() => setShowMenu(true)}
right={() => ( right={() => (
<Menu <Menu
anchor={ anchor={
<IconButton <IconButton
icon="ellipsis-vertical" icon="ellipsis-vertical"
onPress={() => setShow(true)} onPress={() => setShowMenu(true)}
/> />
} }
visible={show} visible={showMenu}
onDismiss={() => setShow(false)}> onDismiss={() => setShowMenu(false)}>
<Menu.Item icon="trash" onPress={remove} title="Delete" /> <Menu.Item icon="trash" onPress={remove} title="Delete" />
<Menu.Item icon="copy" onPress={copy} title="Copy" />
</Menu> </Menu>
)} )}
/> />

View File

@ -1,5 +1,4 @@
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from '@react-native-async-storage/async-storage';
import {useFocusEffect} from '@react-navigation/native';
import React, {useContext, useEffect, useState} from 'react'; import React, {useContext, useEffect, useState} from 'react';
import {NativeModules, StyleSheet, Text, View} from 'react-native'; import {NativeModules, StyleSheet, Text, View} from 'react-native';
import {Button, Snackbar, Switch, TextInput} from 'react-native-paper'; import {Button, Snackbar, Switch, TextInput} from 'react-native-paper';
@ -22,9 +21,9 @@ export default function Settings() {
NativeModules.AlarmModule.ignoringBatteryOptimizations(setIgnoring); NativeModules.AlarmModule.ignoringBatteryOptimizations(setIgnoring);
}; };
useFocusEffect(() => { useEffect(() => {
refresh(); refresh();
}); }, []);
useEffect(() => { useEffect(() => {
if (minutes) AsyncStorage.setItem('minutes', minutes); if (minutes) AsyncStorage.setItem('minutes', minutes);

2
set.ts
View File

@ -1,5 +1,5 @@
export default interface Set { export default interface Set {
id: number; id?: number;
name: string; name: string;
reps: number; reps: number;
weight: number; weight: number;