Massive/EditWorkout.tsx

193 lines
5.6 KiB
TypeScript
Raw Normal View History

import {
RouteProp,
useFocusEffect,
useNavigation,
useRoute,
} from '@react-navigation/native'
2023-06-27 03:16:59 +00:00
import { useCallback, useRef, useState } from 'react'
import { ScrollView, TextInput, View } from 'react-native'
2022-10-31 04:22:08 +00:00
import DocumentPicker from 'react-native-document-picker'
2023-06-27 03:16:59 +00:00
import { Button, Card, TouchableRipple } from 'react-native-paper'
2023-01-01 02:20:56 +00:00
import AppInput from './AppInput'
2022-10-31 04:22:08 +00:00
import ConfirmDialog from './ConfirmDialog'
2023-06-27 03:16:59 +00:00
import { MARGIN, PADDING } from './constants'
import { getNow, planRepo, setRepo, settingsRepo } from './db'
import { defaultSet } from './gym-set'
import Settings from './settings'
2022-10-31 04:22:08 +00:00
import StackHeader from './StackHeader'
2023-06-27 03:16:59 +00:00
import { WorkoutsPageParams } from './WorkoutsPage'
export default function EditWorkout() {
2023-06-27 03:16:59 +00:00
const { params } = useRoute<RouteProp<WorkoutsPageParams, 'EditWorkout'>>()
2022-10-31 04:22:08 +00:00
const [removeImage, setRemoveImage] = useState(false)
const [showRemove, setShowRemove] = useState(false)
const [name, setName] = useState(params.value.name)
const [steps, setSteps] = useState(params.value.steps)
const [uri, setUri] = useState(params.value.image)
2022-09-27 04:42:41 +00:00
const [minutes, setMinutes] = useState(
params.value.minutes?.toString() ?? '3',
2022-10-31 04:22:08 +00:00
)
2022-09-27 04:42:41 +00:00
const [seconds, setSeconds] = useState(
params.value.seconds?.toString() ?? '30',
2022-10-31 04:22:08 +00:00
)
const [sets, setSets] = useState(params.value.sets?.toString() ?? '3')
const navigation = useNavigation()
const setsRef = useRef<TextInput>(null)
const stepsRef = useRef<TextInput>(null)
const minutesRef = useRef<TextInput>(null)
const secondsRef = useRef<TextInput>(null)
const [settings, setSettings] = useState<Settings>()
useFocusEffect(
useCallback(() => {
2023-06-27 03:16:59 +00:00
settingsRepo.findOne({ where: {} }).then(setSettings)
}, []),
)
const update = async () => {
await setRepo.update(
2023-06-27 03:16:59 +00:00
{ name: params.value.name },
{
name: name || params.value.name,
sets: Number(sets),
minutes: +minutes,
seconds: +seconds,
steps,
image: removeImage ? '' : uri,
},
2022-10-31 04:22:08 +00:00
)
await planRepo.query(
`UPDATE plans
SET workouts = REPLACE(workouts, $1, $2)
WHERE workouts LIKE $3`,
[params.value.name, name, `%${params.value.name}%`],
2022-10-31 04:22:08 +00:00
)
navigation.goBack()
}
const add = async () => {
2023-01-04 00:24:49 +00:00
const now = await getNow()
await setRepo.save({
2022-11-04 03:02:06 +00:00
...defaultSet,
name,
hidden: true,
image: uri,
minutes: minutes ? +minutes : 3,
seconds: seconds ? +seconds : 30,
sets: sets ? +sets : 3,
steps,
created: now,
2022-10-31 04:22:08 +00:00
})
navigation.goBack()
}
const save = async () => {
2022-10-31 04:22:08 +00:00
if (params.value.name) return update()
return add()
}
2022-08-28 08:55:12 +00:00
const changeImage = useCallback(async () => {
2023-06-27 03:16:59 +00:00
const { fileCopyUri } = await DocumentPicker.pickSingle({
type: DocumentPicker.types.images,
2022-08-28 08:55:12 +00:00
copyTo: 'documentDirectory',
2022-10-31 04:22:08 +00:00
})
if (fileCopyUri) setUri(fileCopyUri)
}, [])
2022-08-28 08:55:12 +00:00
const handleRemove = useCallback(async () => {
2022-10-31 04:22:08 +00:00
setUri('')
setRemoveImage(true)
setShowRemove(false)
}, [])
const submitName = () => {
2022-10-31 04:22:08 +00:00
if (settings.steps) stepsRef.current?.focus()
else setsRef.current?.focus()
}
return (
<>
2023-01-08 05:05:59 +00:00
<StackHeader title={params.value.name ? 'Edit workout' : 'Add workout'} />
2023-06-27 03:16:59 +00:00
<View style={{ padding: PADDING, flex: 1 }}>
<ScrollView style={{ flex: 1 }}>
2022-12-29 00:57:19 +00:00
<AppInput
autoFocus
2023-06-27 03:16:59 +00:00
label='Name'
value={name}
onChangeText={setName}
onSubmitEditing={submitName}
2022-09-24 05:29:52 +00:00
/>
2022-11-01 06:25:05 +00:00
{settings?.steps && (
2022-12-29 00:57:19 +00:00
<AppInput
innerRef={stepsRef}
selectTextOnFocus={false}
value={steps}
onChangeText={setSteps}
2023-06-27 03:16:59 +00:00
label='Steps'
multiline
onSubmitEditing={() => setsRef.current?.focus()}
/>
)}
2022-12-29 00:57:19 +00:00
<AppInput
2022-11-05 04:31:18 +00:00
innerRef={setsRef}
value={sets}
onChangeText={setSets}
2023-06-27 03:16:59 +00:00
label='Sets per workout'
keyboardType='numeric'
2022-11-05 04:31:18 +00:00
onSubmitEditing={() => minutesRef.current?.focus()}
/>
2022-11-01 06:25:05 +00:00
{settings?.alarm && (
<>
2022-12-29 00:57:19 +00:00
<AppInput
innerRef={minutesRef}
onSubmitEditing={() => secondsRef.current?.focus()}
value={minutes}
onChangeText={setMinutes}
2023-06-27 03:16:59 +00:00
label='Rest minutes'
keyboardType='numeric'
/>
2022-12-29 00:57:19 +00:00
<AppInput
innerRef={secondsRef}
value={seconds}
onChangeText={setSeconds}
2023-06-27 03:16:59 +00:00
label='Rest seconds'
keyboardType='numeric'
blurOnSubmit
/>
</>
)}
2022-11-01 06:25:05 +00:00
{settings?.images && uri && (
<TouchableRipple
2023-06-27 03:16:59 +00:00
style={{ marginBottom: MARGIN }}
onPress={changeImage}
2023-06-27 03:16:59 +00:00
onLongPress={() => setShowRemove(true)}
>
<Card.Cover source={{ uri }} />
</TouchableRipple>
)}
2022-11-01 06:25:05 +00:00
{settings?.images && !uri && (
<Button
2023-06-27 03:16:59 +00:00
style={{ marginBottom: MARGIN }}
onPress={changeImage}
2023-06-27 03:16:59 +00:00
icon='add-photo-alternate'
>
Image
</Button>
)}
</ScrollView>
2023-06-27 03:16:59 +00:00
<Button disabled={!name} mode='contained' icon='save' onPress={save}>
Save
</Button>
<ConfirmDialog
2023-06-27 03:16:59 +00:00
title='Remove image'
onOk={handleRemove}
show={showRemove}
2023-06-27 03:16:59 +00:00
setShow={setShowRemove}
>
Are you sure you want to remove the image?
</ConfirmDialog>
</View>
</>
2022-10-31 04:22:08 +00:00
)
}