Massive/WorkoutList.tsx

125 lines
3.2 KiB
TypeScript

import {
NavigationProp,
useFocusEffect,
useNavigation,
} from '@react-navigation/native'
import { useCallback, useState } from 'react'
import { FlatList } from 'react-native'
import { List } from 'react-native-paper'
import { setRepo, settingsRepo } from './db'
import DrawerHeader from './DrawerHeader'
import GymSet from './gym-set'
import Page from './Page'
import SetList from './SetList'
import Settings from './settings'
import WorkoutItem from './WorkoutItem'
import { WorkoutsPageParams } from './WorkoutsPage'
const limit = 15
export default function WorkoutList() {
const [workouts, setWorkouts] = useState<GymSet[]>()
const [offset, setOffset] = useState(0)
const [term, setTerm] = useState('')
const [end, setEnd] = useState(false)
const [settings, setSettings] = useState<Settings>()
const navigation = useNavigation<NavigationProp<WorkoutsPageParams>>()
const refresh = useCallback(async (value: string) => {
const newWorkouts = await setRepo
.createQueryBuilder()
.select()
.where('name LIKE :name', { name: `%${value.trim()}%` })
.groupBy('name')
.orderBy('name')
.limit(limit)
.getMany()
console.log(`${WorkoutList.name}`, { newWorkout: newWorkouts[0] })
setWorkouts(newWorkouts)
setOffset(0)
setEnd(false)
}, [])
useFocusEffect(
useCallback(() => {
refresh(term)
settingsRepo.findOne({ where: {} }).then(setSettings)
}, [refresh, term]),
)
const renderItem = useCallback(
({ item }: { item: GymSet }) => (
<WorkoutItem
images={settings?.images}
item={item}
key={item.name}
onRemove={() => refresh(term)}
/>
),
[refresh, term, settings?.images],
)
const next = useCallback(async () => {
if (end) return
const newOffset = offset + limit
console.log(`${SetList.name}.next:`, {
offset,
limit,
newOffset,
term,
})
const newWorkouts = await setRepo
.createQueryBuilder()
.select()
.where('name LIKE :name', { name: `%${term.trim()}%` })
.groupBy('name')
.orderBy('name')
.limit(limit)
.offset(newOffset)
.getMany()
if (newWorkouts.length === 0) return setEnd(true)
if (!workouts) return
setWorkouts([...workouts, ...newWorkouts])
if (newWorkouts.length < limit) return setEnd(true)
setOffset(newOffset)
}, [term, end, offset, workouts])
const onAdd = useCallback(async () => {
navigation.navigate('EditWorkout', {
value: new GymSet(),
})
}, [navigation])
const search = useCallback(
(value: string) => {
setTerm(value)
refresh(value)
},
[refresh],
)
return (
<>
<DrawerHeader name='Workouts' />
<Page onAdd={onAdd} term={term} search={search}>
{workouts?.length === 0
? (
<List.Item
title='No workouts yet.'
description='A workout is something you do at the gym. For example Deadlifts are a workout.'
/>
)
: (
<FlatList
data={workouts}
style={{ flex: 1 }}
renderItem={renderItem}
keyExtractor={(w) => w.name}
onEndReached={next}
/>
)}
</Page>
</>
)
}