Massive/WeightList.tsx

151 lines
4.1 KiB
TypeScript
Raw Permalink Normal View History

2023-10-19 05:28:56 +00:00
import {
NavigationProp,
2023-10-20 22:57:31 +00:00
useFocusEffect,
2023-10-19 05:28:56 +00:00
useNavigation,
} from "@react-navigation/native";
2023-10-20 22:57:31 +00:00
import { useCallback, useState } from "react";
2023-10-19 05:28:56 +00:00
import { FlatList } from "react-native";
2023-10-20 22:57:31 +00:00
import { IconButton, List } from "react-native-paper";
2023-10-19 05:28:56 +00:00
import { Like } from "typeorm";
2023-11-14 22:21:49 +00:00
import { StackParams } from "./AppStack";
2023-10-19 05:28:56 +00:00
import { LIMIT } from "./constants";
2023-10-20 22:57:31 +00:00
import { getNow, settingsRepo, weightRepo } from "./db";
2023-10-19 05:28:56 +00:00
import DrawerHeader from "./DrawerHeader";
import Page from "./Page";
2023-10-20 22:57:31 +00:00
import Settings from "./settings";
import { default as Weight, defaultWeight } from "./weight";
import WeightItem from "./WeightItem";
2023-10-19 05:28:56 +00:00
export default function WeightList() {
const [refreshing, setRefreshing] = useState(false);
2023-10-20 22:57:31 +00:00
const [weights, setWeights] = useState<Weight[]>();
2023-10-19 05:28:56 +00:00
const [offset, setOffset] = useState(0);
const [end, setEnd] = useState(false);
const [settings, setSettings] = useState<Settings>();
const { navigate } = useNavigation<NavigationProp<StackParams>>();
2023-10-20 22:57:31 +00:00
const [term, setTerm] = useState("");
2023-10-19 05:28:56 +00:00
const reset = useCallback(
async (value: string) => {
2023-10-20 22:57:31 +00:00
const newWeights = await weightRepo.find({
where: [
{
value: isNaN(Number(term)) ? undefined : Number(term),
},
{
created: Like(`%${term}%`),
},
],
2023-10-19 05:28:56 +00:00
take: LIMIT,
skip: 0,
order: { created: "DESC" },
});
2023-10-20 22:57:31 +00:00
console.log(`${WeightList.name}.reset:`, { value, offset });
setWeights(newWeights);
2023-10-19 05:28:56 +00:00
setEnd(false);
},
2023-10-20 22:57:31 +00:00
[offset, term]
2023-10-19 05:28:56 +00:00
);
2023-10-20 22:57:31 +00:00
useFocusEffect(
useCallback(() => {
settingsRepo.findOne({ where: {} }).then(setSettings);
reset(term);
// eslint-disable-next-line
}, [term])
2023-10-20 22:57:31 +00:00
);
2023-10-19 05:28:56 +00:00
const search = (value: string) => {
2023-10-20 22:57:31 +00:00
console.log(`${WeightList.name}.search:`, value);
2023-10-19 05:28:56 +00:00
setTerm(value);
setOffset(0);
reset(value);
};
const renderItem = useCallback(
2023-10-20 22:57:31 +00:00
({ item }: { item: Weight }) => (
<WeightItem settings={settings} item={item} key={item.id} />
2023-10-19 05:28:56 +00:00
),
2023-10-20 22:57:31 +00:00
[settings]
2023-10-19 05:28:56 +00:00
);
const next = async () => {
console.log(`${WeightList.name}.next:`, { end, refreshing });
2023-10-19 05:28:56 +00:00
if (end || refreshing) return;
const newOffset = offset + LIMIT;
2023-10-20 22:57:31 +00:00
console.log(`${WeightList.name}.next:`, { offset, newOffset, term });
const newWeights = await weightRepo.find({
where: [
{
value: Number(term),
},
{
created: Like(`%${term}%`),
},
],
2023-10-19 05:28:56 +00:00
take: LIMIT,
skip: newOffset,
order: { created: "DESC" },
});
2023-10-20 22:57:31 +00:00
if (newWeights.length === 0) return setEnd(true);
if (!weights) return;
const map = new Map<number, Weight>();
for (const weight of weights) map.set(weight.id, weight);
for (const weight of newWeights) map.set(weight.id, weight);
2023-10-19 05:28:56 +00:00
const unique = Array.from(map.values());
2023-10-20 22:57:31 +00:00
setWeights(unique);
if (newWeights.length < LIMIT) return setEnd(true);
2023-10-19 05:28:56 +00:00
setOffset(newOffset);
};
const onAdd = useCallback(async () => {
const now = await getNow();
2023-11-13 05:13:23 +00:00
let weight: Partial<Weight> = { ...weights[0] };
2023-10-20 22:57:31 +00:00
if (!weight) weight = { ...defaultWeight };
weight.created = now;
delete weight.id;
navigate("EditWeight", { weight });
}, [navigate, weights]);
2023-10-19 05:28:56 +00:00
const getContent = () => {
if (!settings) return null;
2023-10-20 22:57:31 +00:00
if (weights?.length === 0)
2023-10-19 05:28:56 +00:00
return (
<List.Item
title="No sets yet"
description="A set is a group of repetitions. E.g. 8 reps of Squats."
/>
);
return (
<FlatList
2023-10-20 22:57:31 +00:00
data={weights ?? []}
2023-10-19 05:28:56 +00:00
style={{ flex: 1 }}
renderItem={renderItem}
onEndReached={next}
refreshing={refreshing}
keyExtractor={(set) => set.id?.toString()}
onRefresh={() => {
setOffset(0);
setRefreshing(true);
reset(term).finally(() => setRefreshing(false));
}}
/>
);
};
return (
<>
2023-10-20 22:57:31 +00:00
<DrawerHeader name="Weight">
<IconButton
onPress={() => navigate("ViewWeightGraph")}
icon="chart-bell-curve-cumulative"
2023-10-19 05:28:56 +00:00
/>
</DrawerHeader>
<Page onAdd={onAdd} term={term} search={search}>
{getContent()}
</Page>
</>
);
}