Massive/HomePage.tsx

188 lines
5.1 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-04 04:03:48 +00:00
import Set from './set';
import SetItem from './SetItem';
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
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-09 04:38:57 +00:00
<MassiveFab
2022-07-10 04:22:19 +00:00
onPress={() => {
setNewSet(
newSet
? {...newSet, created: new Date().toISOString()}
: {created: new Date().toISOString()},
);
setShowNew(true);
}}
2022-07-09 04:38:57 +00:00
/>
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
},
});