Massive/HomePage.tsx

227 lines
6.8 KiB
TypeScript
Raw Normal View History

2022-07-03 01:50:01 +00:00
import AsyncStorage from '@react-native-async-storage/async-storage';
2022-07-09 01:27:19 +00:00
import React, {useCallback, useContext, useEffect, useState} from 'react';
import {FlatList, NativeModules, StyleSheet, View} from 'react-native';
2022-07-08 02:59:19 +00:00
import {List, Searchbar} from 'react-native-paper';
import {DatabaseContext} from './App';
2022-07-03 01:50:01 +00:00
import EditSet from './EditSet';
2022-07-08 02:59:19 +00:00
import MassiveFab from './MassiveFab';
2022-07-10 05:40:11 +00:00
import {Plan} from './plan';
2022-07-04 04:03:48 +00:00
import Set from './set';
import SetItem from './SetItem';
2022-07-10 05:40:11 +00:00
import {DAYS} from './time';
2022-07-03 01:50:01 +00:00
2022-07-09 01:48:45 +00:00
const limit = 15;
2022-07-03 01:50:01 +00:00
export default function HomePage() {
2022-07-03 01:50:01 +00:00
const [sets, setSets] = useState<Set[]>();
const [offset, setOffset] = useState(0);
const [edit, setEdit] = useState<Set>();
2022-07-10 04:22:19 +00:00
const [showEdit, setShowEdit] = useState(false);
const [showNew, setShowNew] = useState(false);
2022-07-09 03:57:58 +00:00
const [newSet, setNewSet] = useState<Set>();
2022-07-03 01:50:01 +00:00
const [search, setSearch] = useState('');
2022-07-09 03:57:58 +00:00
const [refreshing, setRefreshing] = useState(false);
const [end, setEnd] = useState(false);
const db = useContext(DatabaseContext);
const selectSets = `
SELECT * from sets
WHERE name LIKE ?
ORDER BY created DESC
LIMIT ? OFFSET ?
`;
2022-07-03 01:50:01 +00:00
2022-07-09 01:27:19 +00:00
const refresh = useCallback(async () => {
const [result] = await db.executeSql(selectSets, [`%${search}%`, limit, 0]);
2022-07-03 01:50:01 +00:00
if (!result) return setSets([]);
console.log(`${HomePage.name}.refresh:`, {search, limit});
2022-07-03 01:50:01 +00:00
setSets(result.rows.raw());
setOffset(0);
setEnd(false);
2022-07-09 01:48:45 +00:00
}, [search, db, selectSets]);
2022-07-03 01:50:01 +00:00
2022-07-09 03:57:58 +00:00
const refreshLoader = useCallback(async () => {
setRefreshing(true);
refresh().finally(() => setRefreshing(false));
}, [setRefreshing, refresh]);
2022-07-07 00:45:45 +00:00
2022-07-03 01:50:01 +00:00
useEffect(() => {
refresh();
2022-07-09 01:48:45 +00:00
}, [search, refresh]);
2022-07-03 01:50:01 +00:00
2022-07-09 23:51:52 +00:00
const renderItem = useCallback(
({item}: {item: Set}) => (
2022-07-10 04:09:15 +00:00
<SetItem
setNewSet={setNewSet}
item={item}
key={item.id}
setEdit={setEdit}
onRemove={refresh}
2022-07-10 04:22:19 +00:00
setShowEdit={setShowEdit}
setShowNew={setShowNew}
2022-07-10 04:09:15 +00:00
/>
2022-07-09 23:51:52 +00:00
),
2022-07-10 04:09:15 +00:00
[setEdit, refresh, setNewSet],
2022-07-03 01:50:01 +00:00
);
2022-07-09 03:57:58 +00:00
const update = useCallback(async () => {
2022-07-09 04:38:57 +00:00
console.log('HomePage.update', {edit});
2022-07-09 03:57:58 +00:00
await db.executeSql(
2022-07-09 04:38:57 +00:00
`UPDATE sets SET name = ?, reps = ?, weight = ?, created = ?, unit = ? WHERE id = ?`,
[
edit?.name,
edit?.reps,
edit?.weight,
edit?.created,
edit?.unit,
edit?.id,
],
2022-07-09 03:57:58 +00:00
);
2022-07-10 04:22:19 +00:00
setShowEdit(false);
2022-07-09 03:57:58 +00:00
await refresh();
2022-07-10 04:22:19 +00:00
}, [edit, setShowEdit, refresh, db]);
2022-07-09 03:57:58 +00:00
const add = useCallback(async () => {
if (
newSet?.name === undefined ||
newSet?.reps === 0 ||
newSet?.weight === 0
)
return;
await db.executeSql(
`INSERT INTO sets(name, reps, weight, created, unit) VALUES (?,?,?,?,?)`,
[
newSet?.name,
newSet?.reps,
newSet?.weight,
new Date().toISOString(),
newSet?.unit || 'kg',
],
);
2022-07-10 04:22:19 +00:00
setShowNew(false);
2022-07-09 03:57:58 +00:00
await refresh();
2022-07-03 01:50:01 +00:00
const enabled = await AsyncStorage.getItem('alarmEnabled');
if (enabled !== 'true') return;
const minutes = await AsyncStorage.getItem('minutes');
const seconds = await AsyncStorage.getItem('seconds');
const milliseconds = Number(minutes) * 60 * 1000 + Number(seconds) * 1000;
2022-07-03 06:25:21 +00:00
NativeModules.AlarmModule.timer(milliseconds);
2022-07-10 04:22:19 +00:00
}, [newSet, setShowNew, refresh, db]);
2022-07-03 01:50:01 +00:00
2022-07-09 01:27:19 +00:00
const next = useCallback(async () => {
if (end) return;
2022-07-09 03:57:58 +00:00
setRefreshing(true);
2022-07-03 01:50:01 +00:00
const newOffset = offset + limit;
2022-07-09 01:48:45 +00:00
console.log(`${HomePage.name}.next:`, {
offset,
limit,
newOffset,
search,
});
2022-07-09 01:27:19 +00:00
const [result] = await db
.executeSql(selectSets, [`%${search}%`, limit, newOffset])
2022-07-09 03:57:58 +00:00
.finally(() => setRefreshing(false));
if (result.rows.length === 0) return setEnd(true);
2022-07-03 01:50:01 +00:00
if (!sets) return;
setSets([...sets, ...result.rows.raw()]);
if (result.rows.length < limit) return setEnd(true);
2022-07-03 01:50:01 +00:00
setOffset(newOffset);
2022-07-09 01:48:45 +00:00
}, [search, end, offset, sets, db, selectSets]);
2022-07-03 01:50:01 +00:00
2022-07-10 05:40:11 +00:00
const getTodaysPlan = useCallback(async (): Promise<Plan[]> => {
const today = DAYS[new Date().getDay()];
const [result] = await db.executeSql(
`SELECT * FROM plans WHERE days LIKE ? LIMIT 1`,
[`%${today}%`],
);
return result.rows.raw();
}, [db]);
const getTodaysSets = useCallback(async (): Promise<Set[]> => {
const today = new Date().toISOString().split('T')[0];
const [result] = await db.executeSql(
`SELECT * FROM sets WHERE created LIKE ? ORDER BY created DESC`,
[`${today}%`],
);
return result.rows.raw();
}, [db]);
const onAdd = useCallback(async () => {
const created = new Date().toISOString();
setNewSet({created});
setShowNew(true);
2022-07-10 05:53:38 +00:00
if ((await AsyncStorage.getItem('predictiveSets')) === 'false') return;
2022-07-10 05:40:11 +00:00
const todaysPlan = await getTodaysPlan();
if (todaysPlan.length === 0) return;
console.log(`${HomePage.name}.onAdd: todaysPlan =`, todaysPlan);
const todaysSets = await getTodaysSets();
const todaysWorkouts = todaysPlan[0].workouts.split(',');
if (todaysSets.length === 0)
return setNewSet({created, name: todaysWorkouts[0]});
console.log(`${HomePage.name}.onAdd: todaysSets =`, todaysSets);
const count = todaysSets.filter(
set => set.name === todaysSets[0].name,
).length;
console.log(`${HomePage.name}.onAdd: count =`, count);
const maxSets = await AsyncStorage.getItem('maxSets');
if (count < Number(maxSets))
return setNewSet({...todaysSets[0], id: undefined, created});
2022-07-10 05:40:11 +00:00
const nextWorkout =
todaysWorkouts[todaysWorkouts.indexOf(todaysSets[0].name!) + 1];
if (!nextWorkout)
return setNewSet({...todaysSets[0], id: undefined, created});
console.log(`${HomePage.name}.onAdd: nextWorkout =`, nextWorkout);
setNewSet({created, name: nextWorkout});
2022-07-10 05:41:26 +00:00
}, [getTodaysPlan, getTodaysSets, setNewSet, setShowNew]);
2022-07-10 05:40:11 +00:00
2022-07-03 01:50:01 +00:00
return (
2022-07-07 07:50:38 +00:00
<View style={styles.container}>
<Searchbar placeholder="Search" value={search} onChangeText={setSearch} />
2022-07-03 01:50:01 +00:00
<FlatList
data={sets}
2022-07-08 02:43:31 +00:00
style={{height: '100%'}}
2022-07-07 05:20:27 +00:00
ListEmptyComponent={
<List.Item
title="No sets yet"
description="A set is a group of repetitions. E.g. 8 reps of Squats."
2022-07-07 05:20:27 +00:00
/>
}
2022-07-03 01:50:01 +00:00
renderItem={renderItem}
keyExtractor={set => set.id!.toString()}
onEndReached={next}
refreshing={refreshing}
2022-07-07 00:45:45 +00:00
onRefresh={refreshLoader}
2022-07-03 01:50:01 +00:00
/>
2022-07-09 03:57:58 +00:00
<EditSet
set={edit}
setSet={setEdit}
title={`Edit ${edit?.name}`}
saveText="Edit"
onSave={update}
2022-07-10 04:22:19 +00:00
show={showEdit}
setShow={setShowEdit}
2022-07-09 03:57:58 +00:00
/>
<EditSet
set={newSet}
setSet={setNewSet}
title="Add set"
saveText="Add"
onSave={add}
2022-07-10 04:22:19 +00:00
show={showNew}
setShow={setShowNew}
2022-07-09 03:57:58 +00:00
/>
2022-07-10 05:40:11 +00:00
<MassiveFab onPress={onAdd} />
2022-07-07 07:50:38 +00:00
</View>
2022-07-03 01:50:01 +00:00
);
}
const styles = StyleSheet.create({
container: {
2022-07-07 00:45:45 +00:00
flexGrow: 1,
2022-07-04 04:03:48 +00:00
padding: 10,
paddingBottom: '10%',
2022-07-03 01:50:01 +00:00
},
});