Use deno fmt instead of prettier
This commit is contained in:
parent
23ed95dcdb
commit
4303fe2cc4
|
@ -1,8 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
arrowParens: 'avoid',
|
|
||||||
bracketSameLine: true,
|
|
||||||
bracketSpacing: false,
|
|
||||||
singleQuote: true,
|
|
||||||
trailingComma: 'all',
|
|
||||||
semi: false,
|
|
||||||
};
|
|
9
App.tsx
9
App.tsx
|
@ -99,7 +99,8 @@ const App = () => {
|
||||||
return (
|
return (
|
||||||
<PaperProvider
|
<PaperProvider
|
||||||
theme={paperTheme}
|
theme={paperTheme}
|
||||||
settings={{icon: props => <MaterialIcon {...props} />}}>
|
settings={{ icon: (props) => <MaterialIcon {...props} /> }}
|
||||||
|
>
|
||||||
<NavigationContainer theme={paperTheme}>
|
<NavigationContainer theme={paperTheme}>
|
||||||
{initialized && (
|
{initialized && (
|
||||||
<ThemeContext.Provider
|
<ThemeContext.Provider
|
||||||
|
@ -110,7 +111,8 @@ const App = () => {
|
||||||
setLightColor,
|
setLightColor,
|
||||||
darkColor,
|
darkColor,
|
||||||
setDarkColor,
|
setDarkColor,
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<Routes />
|
<Routes />
|
||||||
</ThemeContext.Provider>
|
</ThemeContext.Provider>
|
||||||
)}
|
)}
|
||||||
|
@ -120,7 +122,8 @@ const App = () => {
|
||||||
duration={3000}
|
duration={3000}
|
||||||
onDismiss={() => setSnackbar('')}
|
onDismiss={() => setSnackbar('')}
|
||||||
visible={!!snackbar}
|
visible={!!snackbar}
|
||||||
action={action}>
|
action={action}
|
||||||
|
>
|
||||||
{snackbar}
|
{snackbar}
|
||||||
</Snackbar>
|
</Snackbar>
|
||||||
</PaperProvider>
|
</PaperProvider>
|
||||||
|
|
|
@ -8,7 +8,7 @@ export default function AppFab(props: Partial<ComponentProps<typeof FAB>>) {
|
||||||
|
|
||||||
const fabColor = useMemo(
|
const fabColor = useMemo(
|
||||||
() =>
|
() =>
|
||||||
lightColors.map(color => color.hex).includes(colors.primary)
|
lightColors.map((color) => color.hex).includes(colors.primary)
|
||||||
? CombinedDarkTheme.colors.background
|
? CombinedDarkTheme.colors.background
|
||||||
: CombinedDefaultTheme.colors.background,
|
: CombinedDefaultTheme.colors.background,
|
||||||
[colors.primary],
|
[colors.primary],
|
||||||
|
@ -16,8 +16,8 @@ export default function AppFab(props: Partial<ComponentProps<typeof FAB>>) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FAB
|
<FAB
|
||||||
icon="add"
|
icon='add'
|
||||||
testID="add"
|
testID='add'
|
||||||
color={fabColor}
|
color={fabColor}
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
|
|
26
BestList.tsx
26
BestList.tsx
|
@ -73,24 +73,32 @@ export default function BestList() {
|
||||||
onPress={() => navigation.navigate('ViewBest', { best: item })}
|
onPress={() => navigation.navigate('ViewBest', { best: item })}
|
||||||
left={() =>
|
left={() =>
|
||||||
(settings.images && item.image && (
|
(settings.images && item.image && (
|
||||||
<Image source={{uri: item.image}} style={{height: 75, width: 75}} />
|
<Image
|
||||||
|
source={{ uri: item.image }}
|
||||||
|
style={{ height: 75, width: 75 }}
|
||||||
|
/>
|
||||||
)) ||
|
)) ||
|
||||||
null
|
null}
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DrawerHeader name="Best" />
|
<DrawerHeader name='Best' />
|
||||||
<Page term={term} search={search}>
|
<Page term={term} search={search}>
|
||||||
{bests?.length === 0 ? (
|
{bests?.length === 0
|
||||||
|
? (
|
||||||
<List.Item
|
<List.Item
|
||||||
title="No exercises yet"
|
title='No exercises yet'
|
||||||
description="Once sets have been added, this will highlight your personal bests."
|
description='Once sets have been added, this will highlight your personal bests.'
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
: (
|
||||||
|
<FlatList
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
renderItem={renderItem}
|
||||||
|
data={bests}
|
||||||
/>
|
/>
|
||||||
) : (
|
|
||||||
<FlatList style={{flex: 1}} renderItem={renderItem} data={bests} />
|
|
||||||
)}
|
)}
|
||||||
</Page>
|
</Page>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -14,9 +14,10 @@ export type BestPageParams = {
|
||||||
export default function BestPage() {
|
export default function BestPage() {
|
||||||
return (
|
return (
|
||||||
<Stack.Navigator
|
<Stack.Navigator
|
||||||
screenOptions={{headerShown: false, animationEnabled: false}}>
|
screenOptions={{ headerShown: false, animationEnabled: false }}
|
||||||
<Stack.Screen name="BestList" component={BestList} />
|
>
|
||||||
<Stack.Screen name="ViewBest" component={ViewBest} />
|
<Stack.Screen name='BestList' component={BestList} />
|
||||||
|
<Stack.Screen name='ViewBest' component={ViewBest} />
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,8 @@ export default function Chart({
|
||||||
height: 300,
|
height: 300,
|
||||||
padding: PADDING,
|
padding: PADDING,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<YAxis
|
<YAxis
|
||||||
data={yData}
|
data={yData}
|
||||||
style={{ marginBottom: xAxisHeight }}
|
style={{ marginBottom: xAxisHeight }}
|
||||||
|
@ -52,7 +53,8 @@ export default function Chart({
|
||||||
curve={shape.curveBasis}
|
curve={shape.curveBasis}
|
||||||
svg={{
|
svg={{
|
||||||
stroke: colors.primary,
|
stroke: colors.primary,
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<Grid />
|
<Grid />
|
||||||
</LineChart>
|
</LineChart>
|
||||||
<XAxis
|
<XAxis
|
||||||
|
|
|
@ -18,7 +18,7 @@ export default function DrawerHeader({
|
||||||
<Appbar.Header>
|
<Appbar.Header>
|
||||||
<IconButton
|
<IconButton
|
||||||
color={dark ? 'white' : 'white'}
|
color={dark ? 'white' : 'white'}
|
||||||
icon="menu"
|
icon='menu'
|
||||||
onPress={navigation.openDrawer}
|
onPress={navigation.openDrawer}
|
||||||
/>
|
/>
|
||||||
<Appbar.Content title={name} />
|
<Appbar.Content title={name} />
|
||||||
|
|
38
EditPlan.tsx
38
EditPlan.tsx
|
@ -37,17 +37,17 @@ export default function EditPlan() {
|
||||||
.distinct(true)
|
.distinct(true)
|
||||||
.orderBy('name')
|
.orderBy('name')
|
||||||
.getRawMany()
|
.getRawMany()
|
||||||
.then(values => {
|
.then((values) => {
|
||||||
console.log(EditPlan.name, { values })
|
console.log(EditPlan.name, { values })
|
||||||
setNames(values.map(value => value.name))
|
setNames(values.map((value) => value.name))
|
||||||
})
|
})
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const save = useCallback(async () => {
|
const save = useCallback(async () => {
|
||||||
console.log(`${EditPlan.name}.save`, { days, workouts, plan })
|
console.log(`${EditPlan.name}.save`, { days, workouts, plan })
|
||||||
if (!days || !workouts) return
|
if (!days || !workouts) return
|
||||||
const newWorkouts = workouts.filter(workout => workout).join(',')
|
const newWorkouts = workouts.filter((workout) => workout).join(',')
|
||||||
const newDays = days.filter(day => day).join(',')
|
const newDays = days.filter((day) => day).join(',')
|
||||||
await planRepo.save({ days: newDays, workouts: newWorkouts, id: plan.id })
|
await planRepo.save({ days: newDays, workouts: newWorkouts, id: plan.id })
|
||||||
navigation.goBack()
|
navigation.goBack()
|
||||||
}, [days, workouts, plan, navigation])
|
}, [days, workouts, plan, navigation])
|
||||||
|
@ -57,7 +57,7 @@ export default function EditPlan() {
|
||||||
if (on) {
|
if (on) {
|
||||||
setWorkouts([...workouts, name])
|
setWorkouts([...workouts, name])
|
||||||
} else {
|
} else {
|
||||||
setWorkouts(workouts.filter(workout => workout !== name))
|
setWorkouts(workouts.filter((workout) => workout !== name))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[setWorkouts, workouts],
|
[setWorkouts, workouts],
|
||||||
|
@ -68,7 +68,7 @@ export default function EditPlan() {
|
||||||
if (on) {
|
if (on) {
|
||||||
setDays([...days, day])
|
setDays([...days, day])
|
||||||
} else {
|
} else {
|
||||||
setDays(days.filter(d => d !== day))
|
setDays(days.filter((d) => d !== day))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[setDays, days],
|
[setDays, days],
|
||||||
|
@ -77,7 +77,8 @@ export default function EditPlan() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<StackHeader
|
<StackHeader
|
||||||
title={typeof plan.id === 'number' ? 'Edit plan' : 'Add plan'}>
|
title={typeof plan.id === 'number' ? 'Edit plan' : 'Add plan'}
|
||||||
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
color={dark ? 'white' : 'white'}
|
color={dark ? 'white' : 'white'}
|
||||||
onPress={async () => {
|
onPress={async () => {
|
||||||
|
@ -86,30 +87,32 @@ export default function EditPlan() {
|
||||||
delete first.id
|
delete first.id
|
||||||
navigation.navigate('StartPlan', { plan: params.plan, first })
|
navigation.navigate('StartPlan', { plan: params.plan, first })
|
||||||
}}
|
}}
|
||||||
icon="play-arrow"
|
icon='play-arrow'
|
||||||
/>
|
/>
|
||||||
</StackHeader>
|
</StackHeader>
|
||||||
<View style={{ padding: PADDING, flex: 1 }}>
|
<View style={{ padding: PADDING, flex: 1 }}>
|
||||||
<ScrollView style={{ flex: 1 }}>
|
<ScrollView style={{ flex: 1 }}>
|
||||||
<Text style={styles.title}>Days</Text>
|
<Text style={styles.title}>Days</Text>
|
||||||
{DAYS.map(day => (
|
{DAYS.map((day) => (
|
||||||
<Switch
|
<Switch
|
||||||
key={day}
|
key={day}
|
||||||
onChange={value => toggleDay(value, day)}
|
onChange={(value) => toggleDay(value, day)}
|
||||||
value={days.includes(day)}
|
value={days.includes(day)}
|
||||||
title={day}
|
title={day}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<Text style={[styles.title, { marginTop: MARGIN }]}>Workouts</Text>
|
<Text style={[styles.title, { marginTop: MARGIN }]}>Workouts</Text>
|
||||||
{names.length === 0 ? (
|
{names.length === 0
|
||||||
|
? (
|
||||||
<View>
|
<View>
|
||||||
<Text>No workouts found.</Text>
|
<Text>No workouts found.</Text>
|
||||||
</View>
|
</View>
|
||||||
) : (
|
)
|
||||||
names.map(name => (
|
: (
|
||||||
|
names.map((name) => (
|
||||||
<Switch
|
<Switch
|
||||||
key={name}
|
key={name}
|
||||||
onChange={value => toggleWorkout(value, name)}
|
onChange={(value) => toggleWorkout(value, name)}
|
||||||
value={workouts.includes(name)}
|
value={workouts.includes(name)}
|
||||||
title={name}
|
title={name}
|
||||||
/>
|
/>
|
||||||
|
@ -120,9 +123,10 @@ export default function EditPlan() {
|
||||||
<Button
|
<Button
|
||||||
disabled={workouts.length === 0 && days.length === 0}
|
disabled={workouts.length === 0 && days.length === 0}
|
||||||
style={styles.button}
|
style={styles.button}
|
||||||
mode="contained"
|
mode='contained'
|
||||||
icon="save"
|
icon='save'
|
||||||
onPress={save}>
|
onPress={save}
|
||||||
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
|
|
50
EditSet.tsx
50
EditSet.tsx
|
@ -54,8 +54,8 @@ export default function EditSet() {
|
||||||
async (value: string) => {
|
async (value: string) => {
|
||||||
if (!settings.alarm) return
|
if (!settings.alarm) return
|
||||||
const first = await setRepo.findOne({ where: { name: value } })
|
const first = await setRepo.findOne({ where: { name: value } })
|
||||||
const milliseconds =
|
const milliseconds = (first?.minutes ?? 3) * 60 * 1000 +
|
||||||
(first?.minutes ?? 3) * 60 * 1000 + (first?.seconds ?? 0) * 1000
|
(first?.seconds ?? 0) * 1000
|
||||||
if (milliseconds) NativeModules.AlarmModule.timer(milliseconds)
|
if (milliseconds) NativeModules.AlarmModule.timer(milliseconds)
|
||||||
},
|
},
|
||||||
[settings],
|
[settings],
|
||||||
|
@ -69,8 +69,9 @@ export default function EditSet() {
|
||||||
if (
|
if (
|
||||||
value.weight > set.weight ||
|
value.weight > set.weight ||
|
||||||
(value.reps > set.reps && value.weight === set.weight)
|
(value.reps > set.reps && value.weight === set.weight)
|
||||||
)
|
) {
|
||||||
toast("Great work King! That's a new record.")
|
toast('Great work King! That\'s a new record.')
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[startTimer, set, settings],
|
[startTimer, set, settings],
|
||||||
)
|
)
|
||||||
|
@ -79,8 +80,9 @@ export default function EditSet() {
|
||||||
console.log(`${EditSet.name}.handleSubmit:`, { set, uri: newImage, name })
|
console.log(`${EditSet.name}.handleSubmit:`, { set, uri: newImage, name })
|
||||||
if (!name) return
|
if (!name) return
|
||||||
let image = newImage
|
let image = newImage
|
||||||
if (!newImage && !removeImage)
|
if (!newImage && !removeImage) {
|
||||||
image = await setRepo.findOne({where: {name}}).then(s => s?.image)
|
image = await setRepo.findOne({ where: { name } }).then((s) => s?.image)
|
||||||
|
}
|
||||||
|
|
||||||
console.log(`${EditSet.name}.handleSubmit:`, { image })
|
console.log(`${EditSet.name}.handleSubmit:`, { image })
|
||||||
const now = await getNow()
|
const now = await getNow()
|
||||||
|
@ -139,7 +141,7 @@ export default function EditSet() {
|
||||||
|
|
||||||
<View style={{ padding: PADDING, flex: 1 }}>
|
<View style={{ padding: PADDING, flex: 1 }}>
|
||||||
<AppInput
|
<AppInput
|
||||||
label="Name"
|
label='Name'
|
||||||
value={name}
|
value={name}
|
||||||
onChangeText={setName}
|
onChangeText={setName}
|
||||||
autoCorrect={false}
|
autoCorrect={false}
|
||||||
|
@ -148,20 +150,20 @@ export default function EditSet() {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<AppInput
|
<AppInput
|
||||||
label="Reps"
|
label='Reps'
|
||||||
keyboardType="numeric"
|
keyboardType='numeric'
|
||||||
value={reps}
|
value={reps}
|
||||||
onChangeText={setReps}
|
onChangeText={setReps}
|
||||||
onSubmitEditing={() => weightRef.current?.focus()}
|
onSubmitEditing={() => weightRef.current?.focus()}
|
||||||
selection={selection}
|
selection={selection}
|
||||||
onSelectionChange={e => setSelection(e.nativeEvent.selection)}
|
onSelectionChange={(e) => setSelection(e.nativeEvent.selection)}
|
||||||
autoFocus={!!name}
|
autoFocus={!!name}
|
||||||
innerRef={repsRef}
|
innerRef={repsRef}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<AppInput
|
<AppInput
|
||||||
label="Weight"
|
label='Weight'
|
||||||
keyboardType="numeric"
|
keyboardType='numeric'
|
||||||
value={weight}
|
value={weight}
|
||||||
onChangeText={setWeight}
|
onChangeText={setWeight}
|
||||||
onSubmitEditing={handleSubmit}
|
onSubmitEditing={handleSubmit}
|
||||||
|
@ -170,8 +172,8 @@ export default function EditSet() {
|
||||||
|
|
||||||
{settings.showUnit && (
|
{settings.showUnit && (
|
||||||
<AppInput
|
<AppInput
|
||||||
autoCapitalize="none"
|
autoCapitalize='none'
|
||||||
label="Unit"
|
label='Unit'
|
||||||
value={unit}
|
value={unit}
|
||||||
onChangeText={setUnit}
|
onChangeText={setUnit}
|
||||||
innerRef={unitRef}
|
innerRef={unitRef}
|
||||||
|
@ -180,7 +182,7 @@ export default function EditSet() {
|
||||||
|
|
||||||
{typeof set.id === 'number' && settings.showDate && (
|
{typeof set.id === 'number' && settings.showDate && (
|
||||||
<AppInput
|
<AppInput
|
||||||
label="Created"
|
label='Created'
|
||||||
value={format(created, settings.date || 'P')}
|
value={format(created, settings.date || 'P')}
|
||||||
onPressOut={pickDate}
|
onPressOut={pickDate}
|
||||||
/>
|
/>
|
||||||
|
@ -190,7 +192,8 @@ export default function EditSet() {
|
||||||
<TouchableRipple
|
<TouchableRipple
|
||||||
style={{ marginBottom: MARGIN }}
|
style={{ marginBottom: MARGIN }}
|
||||||
onPress={changeImage}
|
onPress={changeImage}
|
||||||
onLongPress={() => setShowRemove(true)}>
|
onLongPress={() => setShowRemove(true)}
|
||||||
|
>
|
||||||
<Card.Cover source={{ uri: newImage }} />
|
<Card.Cover source={{ uri: newImage }} />
|
||||||
</TouchableRipple>
|
</TouchableRipple>
|
||||||
)}
|
)}
|
||||||
|
@ -199,7 +202,8 @@ export default function EditSet() {
|
||||||
<Button
|
<Button
|
||||||
style={{ marginBottom: MARGIN }}
|
style={{ marginBottom: MARGIN }}
|
||||||
onPress={changeImage}
|
onPress={changeImage}
|
||||||
icon="add-photo-alternate">
|
icon='add-photo-alternate'
|
||||||
|
>
|
||||||
Image
|
Image
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
@ -207,18 +211,20 @@ export default function EditSet() {
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
disabled={!name}
|
disabled={!name}
|
||||||
mode="contained"
|
mode='contained'
|
||||||
icon="save"
|
icon='save'
|
||||||
style={{ margin: MARGIN }}
|
style={{ margin: MARGIN }}
|
||||||
onPress={handleSubmit}>
|
onPress={handleSubmit}
|
||||||
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
title="Remove image"
|
title='Remove image'
|
||||||
onOk={handleRemove}
|
onOk={handleRemove}
|
||||||
show={showRemove}
|
show={showRemove}
|
||||||
setShow={setShowRemove}>
|
setShow={setShowRemove}
|
||||||
|
>
|
||||||
Are you sure you want to remove the image?
|
Are you sure you want to remove the image?
|
||||||
</ConfirmDialog>
|
</ConfirmDialog>
|
||||||
</>
|
</>
|
||||||
|
|
36
EditSets.tsx
36
EditSets.tsx
|
@ -42,11 +42,11 @@ export default function EditSets() {
|
||||||
useFocusEffect(
|
useFocusEffect(
|
||||||
useCallback(() => {
|
useCallback(() => {
|
||||||
settingsRepo.findOne({ where: {} }).then(setSettings)
|
settingsRepo.findOne({ where: {} }).then(setSettings)
|
||||||
setRepo.find({where: {id: In(ids)}}).then(sets => {
|
setRepo.find({ where: { id: In(ids) } }).then((sets) => {
|
||||||
setNames(sets.map(set => set.name).join(', '))
|
setNames(sets.map((set) => set.name).join(', '))
|
||||||
setOldReps(sets.map(set => set.reps).join(', '))
|
setOldReps(sets.map((set) => set.reps).join(', '))
|
||||||
setWeights(sets.map(set => set.weight).join(', '))
|
setWeights(sets.map((set) => set.weight).join(', '))
|
||||||
setUnits(sets.map(set => set.unit).join(', '))
|
setUnits(sets.map((set) => set.unit).join(', '))
|
||||||
})
|
})
|
||||||
}, [ids]),
|
}, [ids]),
|
||||||
)
|
)
|
||||||
|
@ -91,17 +91,17 @@ export default function EditSets() {
|
||||||
|
|
||||||
<AppInput
|
<AppInput
|
||||||
label={`Reps: ${oldReps}`}
|
label={`Reps: ${oldReps}`}
|
||||||
keyboardType="numeric"
|
keyboardType='numeric'
|
||||||
value={reps}
|
value={reps}
|
||||||
onChangeText={setReps}
|
onChangeText={setReps}
|
||||||
selection={selection}
|
selection={selection}
|
||||||
onSelectionChange={e => setSelection(e.nativeEvent.selection)}
|
onSelectionChange={(e) => setSelection(e.nativeEvent.selection)}
|
||||||
autoFocus={!!name}
|
autoFocus={!!name}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<AppInput
|
<AppInput
|
||||||
label={`Weights: ${weights}`}
|
label={`Weights: ${weights}`}
|
||||||
keyboardType="numeric"
|
keyboardType='numeric'
|
||||||
value={weight}
|
value={weight}
|
||||||
onChangeText={setWeight}
|
onChangeText={setWeight}
|
||||||
onSubmitEditing={handleSubmit}
|
onSubmitEditing={handleSubmit}
|
||||||
|
@ -109,7 +109,7 @@ export default function EditSets() {
|
||||||
|
|
||||||
{settings.showUnit && (
|
{settings.showUnit && (
|
||||||
<AppInput
|
<AppInput
|
||||||
autoCapitalize="none"
|
autoCapitalize='none'
|
||||||
label={`Units: ${units}`}
|
label={`Units: ${units}`}
|
||||||
value={unit}
|
value={unit}
|
||||||
onChangeText={setUnit}
|
onChangeText={setUnit}
|
||||||
|
@ -120,15 +120,17 @@ export default function EditSets() {
|
||||||
<TouchableRipple
|
<TouchableRipple
|
||||||
style={{ marginBottom: MARGIN }}
|
style={{ marginBottom: MARGIN }}
|
||||||
onPress={changeImage}
|
onPress={changeImage}
|
||||||
onLongPress={() => setShowRemove(true)}>
|
onLongPress={() => setShowRemove(true)}
|
||||||
|
>
|
||||||
<Card.Cover source={{ uri: newImage }} />
|
<Card.Cover source={{ uri: newImage }} />
|
||||||
</TouchableRipple>
|
</TouchableRipple>
|
||||||
)}
|
)}
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
title="Remove image"
|
title='Remove image'
|
||||||
onOk={handleRemove}
|
onOk={handleRemove}
|
||||||
show={showRemove}
|
show={showRemove}
|
||||||
setShow={setShowRemove}>
|
setShow={setShowRemove}
|
||||||
|
>
|
||||||
Are you sure you want to remove the image?
|
Are you sure you want to remove the image?
|
||||||
</ConfirmDialog>
|
</ConfirmDialog>
|
||||||
|
|
||||||
|
@ -136,17 +138,19 @@ export default function EditSets() {
|
||||||
<Button
|
<Button
|
||||||
style={{ marginBottom: MARGIN }}
|
style={{ marginBottom: MARGIN }}
|
||||||
onPress={changeImage}
|
onPress={changeImage}
|
||||||
icon="add-photo-alternate">
|
icon='add-photo-alternate'
|
||||||
|
>
|
||||||
Image
|
Image
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
mode="contained"
|
mode='contained'
|
||||||
icon="save"
|
icon='save'
|
||||||
style={{ margin: MARGIN }}
|
style={{ margin: MARGIN }}
|
||||||
onPress={handleSubmit}>
|
onPress={handleSubmit}
|
||||||
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -112,7 +112,7 @@ export default function EditWorkout() {
|
||||||
<ScrollView style={{ flex: 1 }}>
|
<ScrollView style={{ flex: 1 }}>
|
||||||
<AppInput
|
<AppInput
|
||||||
autoFocus
|
autoFocus
|
||||||
label="Name"
|
label='Name'
|
||||||
value={name}
|
value={name}
|
||||||
onChangeText={setName}
|
onChangeText={setName}
|
||||||
onSubmitEditing={submitName}
|
onSubmitEditing={submitName}
|
||||||
|
@ -123,7 +123,7 @@ export default function EditWorkout() {
|
||||||
selectTextOnFocus={false}
|
selectTextOnFocus={false}
|
||||||
value={steps}
|
value={steps}
|
||||||
onChangeText={setSteps}
|
onChangeText={setSteps}
|
||||||
label="Steps"
|
label='Steps'
|
||||||
multiline
|
multiline
|
||||||
onSubmitEditing={() => setsRef.current?.focus()}
|
onSubmitEditing={() => setsRef.current?.focus()}
|
||||||
/>
|
/>
|
||||||
|
@ -132,8 +132,8 @@ export default function EditWorkout() {
|
||||||
innerRef={setsRef}
|
innerRef={setsRef}
|
||||||
value={sets}
|
value={sets}
|
||||||
onChangeText={setSets}
|
onChangeText={setSets}
|
||||||
label="Sets per workout"
|
label='Sets per workout'
|
||||||
keyboardType="numeric"
|
keyboardType='numeric'
|
||||||
onSubmitEditing={() => minutesRef.current?.focus()}
|
onSubmitEditing={() => minutesRef.current?.focus()}
|
||||||
/>
|
/>
|
||||||
{settings?.alarm && (
|
{settings?.alarm && (
|
||||||
|
@ -143,15 +143,15 @@ export default function EditWorkout() {
|
||||||
onSubmitEditing={() => secondsRef.current?.focus()}
|
onSubmitEditing={() => secondsRef.current?.focus()}
|
||||||
value={minutes}
|
value={minutes}
|
||||||
onChangeText={setMinutes}
|
onChangeText={setMinutes}
|
||||||
label="Rest minutes"
|
label='Rest minutes'
|
||||||
keyboardType="numeric"
|
keyboardType='numeric'
|
||||||
/>
|
/>
|
||||||
<AppInput
|
<AppInput
|
||||||
innerRef={secondsRef}
|
innerRef={secondsRef}
|
||||||
value={seconds}
|
value={seconds}
|
||||||
onChangeText={setSeconds}
|
onChangeText={setSeconds}
|
||||||
label="Rest seconds"
|
label='Rest seconds'
|
||||||
keyboardType="numeric"
|
keyboardType='numeric'
|
||||||
blurOnSubmit
|
blurOnSubmit
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
@ -160,7 +160,8 @@ export default function EditWorkout() {
|
||||||
<TouchableRipple
|
<TouchableRipple
|
||||||
style={{ marginBottom: MARGIN }}
|
style={{ marginBottom: MARGIN }}
|
||||||
onPress={changeImage}
|
onPress={changeImage}
|
||||||
onLongPress={() => setShowRemove(true)}>
|
onLongPress={() => setShowRemove(true)}
|
||||||
|
>
|
||||||
<Card.Cover source={{ uri }} />
|
<Card.Cover source={{ uri }} />
|
||||||
</TouchableRipple>
|
</TouchableRipple>
|
||||||
)}
|
)}
|
||||||
|
@ -168,19 +169,21 @@ export default function EditWorkout() {
|
||||||
<Button
|
<Button
|
||||||
style={{ marginBottom: MARGIN }}
|
style={{ marginBottom: MARGIN }}
|
||||||
onPress={changeImage}
|
onPress={changeImage}
|
||||||
icon="add-photo-alternate">
|
icon='add-photo-alternate'
|
||||||
|
>
|
||||||
Image
|
Image
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<Button disabled={!name} mode="contained" icon="save" onPress={save}>
|
<Button disabled={!name} mode='contained' icon='save' onPress={save}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
title="Remove image"
|
title='Remove image'
|
||||||
onOk={handleRemove}
|
onOk={handleRemove}
|
||||||
show={showRemove}
|
show={showRemove}
|
||||||
setShow={setShowRemove}>
|
setShow={setShowRemove}
|
||||||
|
>
|
||||||
Are you sure you want to remove the image?
|
Are you sure you want to remove the image?
|
||||||
</ConfirmDialog>
|
</ConfirmDialog>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -9,10 +9,11 @@ const Stack = createStackNavigator<HomePageParams>()
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
return (
|
return (
|
||||||
<Stack.Navigator
|
<Stack.Navigator
|
||||||
screenOptions={{headerShown: false, animationEnabled: false}}>
|
screenOptions={{ headerShown: false, animationEnabled: false }}
|
||||||
<Stack.Screen name="Sets" component={SetList} />
|
>
|
||||||
<Stack.Screen name="EditSet" component={EditSet} />
|
<Stack.Screen name='Sets' component={SetList} />
|
||||||
<Stack.Screen name="EditSets" component={EditSets} />
|
<Stack.Screen name='EditSet' component={EditSet} />
|
||||||
|
<Stack.Screen name='EditSets' component={EditSets} />
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
34
ListMenu.tsx
34
ListMenu.tsx
|
@ -55,45 +55,45 @@ export default function ListMenu({
|
||||||
<IconButton
|
<IconButton
|
||||||
color={dark ? 'white' : 'white'}
|
color={dark ? 'white' : 'white'}
|
||||||
onPress={() => setShowMenu(true)}
|
onPress={() => setShowMenu(true)}
|
||||||
icon="more-vert"
|
icon='more-vert'
|
||||||
/>
|
/>
|
||||||
}>
|
}
|
||||||
<Menu.Item icon="done-all" title="Select all" onPress={select} />
|
>
|
||||||
|
<Menu.Item icon='done-all' title='Select all' onPress={select} />
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
icon="clear"
|
icon='clear'
|
||||||
title="Clear"
|
title='Clear'
|
||||||
onPress={clear}
|
onPress={clear}
|
||||||
disabled={ids?.length === 0}
|
disabled={ids?.length === 0}
|
||||||
/>
|
/>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
icon="edit"
|
icon='edit'
|
||||||
title="Edit"
|
title='Edit'
|
||||||
onPress={edit}
|
onPress={edit}
|
||||||
disabled={ids?.length === 0}
|
disabled={ids?.length === 0}
|
||||||
/>
|
/>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
icon="content-copy"
|
icon='content-copy'
|
||||||
title="Copy"
|
title='Copy'
|
||||||
onPress={copy}
|
onPress={copy}
|
||||||
disabled={ids?.length === 0}
|
disabled={ids?.length === 0}
|
||||||
/>
|
/>
|
||||||
<Divider />
|
<Divider />
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
icon="delete"
|
icon='delete'
|
||||||
onPress={() => setShowRemove(true)}
|
onPress={() => setShowRemove(true)}
|
||||||
title="Delete"
|
title='Delete'
|
||||||
/>
|
/>
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
title={ids?.length === 0 ? 'Delete all' : 'Delete selected'}
|
title={ids?.length === 0 ? 'Delete all' : 'Delete selected'}
|
||||||
show={showRemove}
|
show={showRemove}
|
||||||
setShow={setShowRemove}
|
setShow={setShowRemove}
|
||||||
onOk={remove}
|
onOk={remove}
|
||||||
onCancel={() => setShowMenu(false)}>
|
onCancel={() => setShowMenu(false)}
|
||||||
{ids?.length === 0 ? (
|
>
|
||||||
<>This irreversibly deletes records from the app. Are you sure?</>
|
{ids?.length === 0
|
||||||
) : (
|
? <>This irreversibly deletes records from the app. Are you sure?</>
|
||||||
<>This will delete {ids?.length} record(s). Are you sure?</>
|
: <>This will delete {ids?.length} record(s). Are you sure?</>}
|
||||||
)}
|
|
||||||
</ConfirmDialog>
|
</ConfirmDialog>
|
||||||
</Menu>
|
</Menu>
|
||||||
)
|
)
|
||||||
|
|
6
Page.tsx
6
Page.tsx
|
@ -19,11 +19,11 @@ export default function Page({
|
||||||
return (
|
return (
|
||||||
<View style={[styles.view, style]}>
|
<View style={[styles.view, style]}>
|
||||||
<Searchbar
|
<Searchbar
|
||||||
placeholder="Search"
|
placeholder='Search'
|
||||||
value={term}
|
value={term}
|
||||||
onChangeText={search}
|
onChangeText={search}
|
||||||
icon="search"
|
icon='search'
|
||||||
clearIcon="clear"
|
clearIcon='clear'
|
||||||
/>
|
/>
|
||||||
{children}
|
{children}
|
||||||
{onAdd && <AppFab onPress={onAdd} />}
|
{onAdd && <AppFab onPress={onAdd} />}
|
||||||
|
|
17
PlanItem.tsx
17
PlanItem.tsx
|
@ -40,10 +40,11 @@ export default function PlanItem({
|
||||||
let first = await getLast(workout)
|
let first = await getLast(workout)
|
||||||
if (!first) first = { ...defaultSet, name: workout }
|
if (!first) first = { ...defaultSet, name: workout }
|
||||||
delete first.id
|
delete first.id
|
||||||
if (ids.length === 0)
|
if (ids.length === 0) {
|
||||||
return navigation.navigate('StartPlan', { plan: item, first })
|
return navigation.navigate('StartPlan', { plan: item, first })
|
||||||
const removing = ids.find(id => id === item.id)
|
}
|
||||||
if (removing) setIds(ids.filter(id => id !== item.id))
|
const removing = ids.find((id) => id === item.id)
|
||||||
|
if (removing) setIds(ids.filter((id) => id !== item.id))
|
||||||
else setIds([...ids, item.id])
|
else setIds([...ids, item.id])
|
||||||
}, [ids, setIds, item, navigation])
|
}, [ids, setIds, item, navigation])
|
||||||
|
|
||||||
|
@ -56,11 +57,15 @@ export default function PlanItem({
|
||||||
() =>
|
() =>
|
||||||
days.map((day, index) => (
|
days.map((day, index) => (
|
||||||
<Text key={day}>
|
<Text key={day}>
|
||||||
{day === today ? (
|
{day === today
|
||||||
<Text style={{fontWeight: 'bold', textDecorationLine: 'underline'}}>
|
? (
|
||||||
|
<Text
|
||||||
|
style={{ fontWeight: 'bold', textDecorationLine: 'underline' }}
|
||||||
|
>
|
||||||
{day}
|
{day}
|
||||||
</Text>
|
</Text>
|
||||||
) : (
|
)
|
||||||
|
: (
|
||||||
day
|
day
|
||||||
)}
|
)}
|
||||||
{index === days.length - 1 ? '' : ', '}
|
{index === days.length - 1 ? '' : ', '}
|
||||||
|
|
14
PlanList.tsx
14
PlanList.tsx
|
@ -82,7 +82,7 @@ export default function PlanList() {
|
||||||
}, [ids, refresh, term])
|
}, [ids, refresh, term])
|
||||||
|
|
||||||
const select = useCallback(() => {
|
const select = useCallback(() => {
|
||||||
setIds(plans.map(plan => plan.id))
|
setIds(plans.map((plan) => plan.id))
|
||||||
}, [plans])
|
}, [plans])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -98,17 +98,19 @@ export default function PlanList() {
|
||||||
/>
|
/>
|
||||||
</DrawerHeader>
|
</DrawerHeader>
|
||||||
<Page onAdd={onAdd} term={term} search={search}>
|
<Page onAdd={onAdd} term={term} search={search}>
|
||||||
{plans?.length === 0 ? (
|
{plans?.length === 0
|
||||||
|
? (
|
||||||
<List.Item
|
<List.Item
|
||||||
title="No plans yet"
|
title='No plans yet'
|
||||||
description="A plan is a list of workouts for certain days."
|
description='A plan is a list of workouts for certain days.'
|
||||||
/>
|
/>
|
||||||
) : (
|
)
|
||||||
|
: (
|
||||||
<FlatList
|
<FlatList
|
||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
data={plans}
|
data={plans}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
keyExtractor={set => set.id?.toString() || ''}
|
keyExtractor={(set) => set.id?.toString() || ''}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Page>
|
</Page>
|
||||||
|
|
11
PlanPage.tsx
11
PlanPage.tsx
|
@ -10,11 +10,12 @@ const Stack = createStackNavigator<PlanPageParams>()
|
||||||
export default function PlanPage() {
|
export default function PlanPage() {
|
||||||
return (
|
return (
|
||||||
<Stack.Navigator
|
<Stack.Navigator
|
||||||
screenOptions={{headerShown: false, animationEnabled: false}}>
|
screenOptions={{ headerShown: false, animationEnabled: false }}
|
||||||
<Stack.Screen name="PlanList" component={PlanList} />
|
>
|
||||||
<Stack.Screen name="EditPlan" component={EditPlan} />
|
<Stack.Screen name='PlanList' component={PlanList} />
|
||||||
<Stack.Screen name="StartPlan" component={StartPlan} />
|
<Stack.Screen name='EditPlan' component={EditPlan} />
|
||||||
<Stack.Screen name="EditSet" component={EditSet} />
|
<Stack.Screen name='StartPlan' component={StartPlan} />
|
||||||
|
<Stack.Screen name='EditSet' component={EditSet} />
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
27
Routes.tsx
27
Routes.tsx
|
@ -20,36 +20,37 @@ export default function Routes() {
|
||||||
headerTintColor: dark ? 'white' : 'black',
|
headerTintColor: dark ? 'white' : 'black',
|
||||||
swipeEdgeWidth: 1000,
|
swipeEdgeWidth: 1000,
|
||||||
headerShown: false,
|
headerShown: false,
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<Drawer.Screen
|
<Drawer.Screen
|
||||||
name="Home"
|
name='Home'
|
||||||
component={HomePage}
|
component={HomePage}
|
||||||
options={{drawerIcon: () => <IconButton icon="home" />}}
|
options={{ drawerIcon: () => <IconButton icon='home' /> }}
|
||||||
/>
|
/>
|
||||||
<Drawer.Screen
|
<Drawer.Screen
|
||||||
name="Plans"
|
name='Plans'
|
||||||
component={PlanPage}
|
component={PlanPage}
|
||||||
options={{drawerIcon: () => <IconButton icon="event" />}}
|
options={{ drawerIcon: () => <IconButton icon='event' /> }}
|
||||||
/>
|
/>
|
||||||
<Drawer.Screen
|
<Drawer.Screen
|
||||||
name="Best"
|
name='Best'
|
||||||
component={BestPage}
|
component={BestPage}
|
||||||
options={{drawerIcon: () => <IconButton icon="insights" />}}
|
options={{ drawerIcon: () => <IconButton icon='insights' /> }}
|
||||||
/>
|
/>
|
||||||
<Drawer.Screen
|
<Drawer.Screen
|
||||||
name="Workouts"
|
name='Workouts'
|
||||||
component={WorkoutsPage}
|
component={WorkoutsPage}
|
||||||
options={{drawerIcon: () => <IconButton icon="fitness-center" />}}
|
options={{ drawerIcon: () => <IconButton icon='fitness-center' /> }}
|
||||||
/>
|
/>
|
||||||
<Drawer.Screen
|
<Drawer.Screen
|
||||||
name="Timer"
|
name='Timer'
|
||||||
component={TimerPage}
|
component={TimerPage}
|
||||||
options={{drawerIcon: () => <IconButton icon="access-time" />}}
|
options={{ drawerIcon: () => <IconButton icon='access-time' /> }}
|
||||||
/>
|
/>
|
||||||
<Drawer.Screen
|
<Drawer.Screen
|
||||||
name="Settings"
|
name='Settings'
|
||||||
component={SettingsPage}
|
component={SettingsPage}
|
||||||
options={{drawerIcon: () => <IconButton icon="settings" />}}
|
options={{ drawerIcon: () => <IconButton icon='settings' /> }}
|
||||||
/>
|
/>
|
||||||
</Drawer.Navigator>
|
</Drawer.Navigator>
|
||||||
)
|
)
|
||||||
|
|
13
Select.tsx
13
Select.tsx
|
@ -24,7 +24,7 @@ function Select({
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
|
|
||||||
const selected = useMemo(
|
const selected = useMemo(
|
||||||
() => items.find(item => item.value === value) || items[0],
|
() => items.find((item) => item.value === value) || items[0],
|
||||||
[items, value],
|
[items, value],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -42,7 +42,8 @@ function Select({
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
paddingLeft: ITEM_PADDING,
|
paddingLeft: ITEM_PADDING,
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
{label && <Subheading style={{ width: 100 }}>{label}</Subheading>}
|
{label && <Subheading style={{ width: 100 }}>{label}</Subheading>}
|
||||||
<Menu
|
<Menu
|
||||||
visible={show}
|
visible={show}
|
||||||
|
@ -52,11 +53,13 @@ function Select({
|
||||||
onPress={() => setShow(true)}
|
onPress={() => setShow(true)}
|
||||||
style={{
|
style={{
|
||||||
alignSelf: 'flex-start',
|
alignSelf: 'flex-start',
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
{selected?.label}
|
{selected?.label}
|
||||||
</Button>
|
</Button>
|
||||||
}>
|
}
|
||||||
{items.map(item => (
|
>
|
||||||
|
{items.map((item) => (
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
key={item.value}
|
key={item.value}
|
||||||
titleStyle={{ color: item.color || colors.text }}
|
titleStyle={{ color: item.color || colors.text }}
|
||||||
|
|
15
SetItem.tsx
15
SetItem.tsx
|
@ -31,8 +31,8 @@ export default function SetItem({
|
||||||
|
|
||||||
const press = useCallback(() => {
|
const press = useCallback(() => {
|
||||||
if (ids.length === 0) return navigation.navigate('EditSet', { set: item })
|
if (ids.length === 0) return navigation.navigate('EditSet', { set: item })
|
||||||
const removing = ids.find(id => id === item.id)
|
const removing = ids.find((id) => id === item.id)
|
||||||
if (removing) setIds(ids.filter(id => id !== item.id))
|
if (removing) setIds(ids.filter((id) => id !== item.id))
|
||||||
else setIds([...ids, item.id])
|
else setIds([...ids, item.id])
|
||||||
}, [ids, item, navigation, setIds])
|
}, [ids, item, navigation, setIds])
|
||||||
|
|
||||||
|
@ -53,9 +53,11 @@ export default function SetItem({
|
||||||
left={() =>
|
left={() =>
|
||||||
settings.images &&
|
settings.images &&
|
||||||
item.image && (
|
item.image && (
|
||||||
<Image source={{uri: item.image}} style={{height: 75, width: 75}} />
|
<Image
|
||||||
)
|
source={{ uri: item.image }}
|
||||||
}
|
style={{ height: 75, width: 75 }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
right={() => (
|
right={() => (
|
||||||
<>
|
<>
|
||||||
{settings.showDate && (
|
{settings.showDate && (
|
||||||
|
@ -63,7 +65,8 @@ export default function SetItem({
|
||||||
style={{
|
style={{
|
||||||
alignSelf: 'center',
|
alignSelf: 'center',
|
||||||
color: dark ? '#909090ff' : '#717171ff',
|
color: dark ? '#909090ff' : '#717171ff',
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
{format(new Date(item.created), settings.date || 'P')}
|
{format(new Date(item.created), settings.date || 'P')}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
|
|
12
SetList.tsx
12
SetList.tsx
|
@ -121,7 +121,7 @@ export default function SetList() {
|
||||||
}, [ids, refresh, term])
|
}, [ids, refresh, term])
|
||||||
|
|
||||||
const select = useCallback(() => {
|
const select = useCallback(() => {
|
||||||
setIds(sets.map(set => set.id))
|
setIds(sets.map((set) => set.id))
|
||||||
}, [sets])
|
}, [sets])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -138,12 +138,14 @@ export default function SetList() {
|
||||||
</DrawerHeader>
|
</DrawerHeader>
|
||||||
|
|
||||||
<Page onAdd={onAdd} term={term} search={search}>
|
<Page onAdd={onAdd} term={term} search={search}>
|
||||||
{sets?.length === 0 ? (
|
{sets?.length === 0
|
||||||
|
? (
|
||||||
<List.Item
|
<List.Item
|
||||||
title="No sets yet"
|
title='No sets yet'
|
||||||
description="A set is a group of repetitions. E.g. 8 reps of Squats."
|
description='A set is a group of repetitions. E.g. 8 reps of Squats.'
|
||||||
/>
|
/>
|
||||||
) : (
|
)
|
||||||
|
: (
|
||||||
settings && (
|
settings && (
|
||||||
<FlatList
|
<FlatList
|
||||||
data={sets}
|
data={sets}
|
||||||
|
|
|
@ -52,8 +52,14 @@ export default function SettingsPage() {
|
||||||
})
|
})
|
||||||
const settings = watch()
|
const settings = watch()
|
||||||
|
|
||||||
const {theme, setTheme, lightColor, setLightColor, darkColor, setDarkColor} =
|
const {
|
||||||
useTheme()
|
theme,
|
||||||
|
setTheme,
|
||||||
|
lightColor,
|
||||||
|
setLightColor,
|
||||||
|
darkColor,
|
||||||
|
setDarkColor,
|
||||||
|
} = useTheme()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
NativeModules.SettingsModule.ignoringBattery(setIgnoring)
|
NativeModules.SettingsModule.ignoringBattery(setIgnoring)
|
||||||
|
@ -168,7 +174,7 @@ export default function SettingsPage() {
|
||||||
<Switch
|
<Switch
|
||||||
key={item.name}
|
key={item.name}
|
||||||
value={item.value}
|
value={item.value}
|
||||||
onChange={value => changeBoolean(item.key, value)}
|
onChange={(value) => changeBoolean(item.key, value)}
|
||||||
title={item.name}
|
title={item.name}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
|
@ -176,7 +182,7 @@ export default function SettingsPage() {
|
||||||
)
|
)
|
||||||
|
|
||||||
const switchesMarkup = useMemo(
|
const switchesMarkup = useMemo(
|
||||||
() => switches.filter(filter).map(s => renderSwitch(s)),
|
() => switches.filter(filter).map((s) => renderSwitch(s)),
|
||||||
[filter, switches, renderSwitch],
|
[filter, switches, renderSwitch],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -227,7 +233,7 @@ export default function SettingsPage() {
|
||||||
{
|
{
|
||||||
name: 'Date format',
|
name: 'Date format',
|
||||||
value: settings.date,
|
value: settings.date,
|
||||||
items: formatOptions.map(option => ({
|
items: formatOptions.map((option) => ({
|
||||||
label: format(today, option),
|
label: format(today, option),
|
||||||
value: option,
|
value: option,
|
||||||
})),
|
})),
|
||||||
|
@ -241,7 +247,7 @@ export default function SettingsPage() {
|
||||||
<Select
|
<Select
|
||||||
key={item.name}
|
key={item.name}
|
||||||
value={item.value}
|
value={item.value}
|
||||||
onChange={value => changeString(item.key, value)}
|
onChange={(value) => changeString(item.key, value)}
|
||||||
label={item.name}
|
label={item.name}
|
||||||
items={item.items}
|
items={item.items}
|
||||||
/>
|
/>
|
||||||
|
@ -287,12 +293,13 @@ export default function SettingsPage() {
|
||||||
name: 'Alarm sound',
|
name: 'Alarm sound',
|
||||||
element: (
|
element: (
|
||||||
<View
|
<View
|
||||||
key="alarm-sound"
|
key='alarm-sound'
|
||||||
style={{
|
style={{
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
paddingLeft: ITEM_PADDING,
|
paddingLeft: ITEM_PADDING,
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<Subheading style={{ width: 100 }}>Alarm sound</Subheading>
|
<Subheading style={{ width: 100 }}>Alarm sound</Subheading>
|
||||||
<Button onPress={changeSound}>{soundString || 'Default'}</Button>
|
<Button onPress={changeSound}>{soundString || 'Default'}</Button>
|
||||||
</View>
|
</View>
|
||||||
|
@ -302,9 +309,10 @@ export default function SettingsPage() {
|
||||||
name: 'Export database',
|
name: 'Export database',
|
||||||
element: (
|
element: (
|
||||||
<Button
|
<Button
|
||||||
key="export-db"
|
key='export-db'
|
||||||
style={{ alignSelf: 'flex-start' }}
|
style={{ alignSelf: 'flex-start' }}
|
||||||
onPress={exportDatabase}>
|
onPress={exportDatabase}
|
||||||
|
>
|
||||||
Export database
|
Export database
|
||||||
</Button>
|
</Button>
|
||||||
),
|
),
|
||||||
|
@ -313,9 +321,10 @@ export default function SettingsPage() {
|
||||||
name: 'Import database',
|
name: 'Import database',
|
||||||
element: (
|
element: (
|
||||||
<Button
|
<Button
|
||||||
key="import-db"
|
key='import-db'
|
||||||
style={{ alignSelf: 'flex-start' }}
|
style={{ alignSelf: 'flex-start' }}
|
||||||
onPress={() => setImporting(true)}>
|
onPress={() => setImporting(true)}
|
||||||
|
>
|
||||||
Import database
|
Import database
|
||||||
</Button>
|
</Button>
|
||||||
),
|
),
|
||||||
|
@ -325,13 +334,13 @@ export default function SettingsPage() {
|
||||||
)
|
)
|
||||||
|
|
||||||
const buttonsMarkup = useMemo(
|
const buttonsMarkup = useMemo(
|
||||||
() => buttons.filter(filter).map(b => b.element),
|
() => buttons.filter(filter).map((b) => b.element),
|
||||||
[buttons, filter],
|
[buttons, filter],
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DrawerHeader name="Settings" />
|
<DrawerHeader name='Settings' />
|
||||||
|
|
||||||
<Page term={term} search={setTerm} style={{ flexGrow: 1 }}>
|
<Page term={term} search={setTerm} style={{ flexGrow: 1 }}>
|
||||||
<ScrollView style={{ marginTop: MARGIN, flex: 1 }}>
|
<ScrollView style={{ marginTop: MARGIN, flex: 1 }}>
|
||||||
|
@ -342,10 +351,11 @@ export default function SettingsPage() {
|
||||||
</Page>
|
</Page>
|
||||||
|
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
title="Are you sure?"
|
title='Are you sure?'
|
||||||
onOk={confirmImport}
|
onOk={confirmImport}
|
||||||
setShow={setImporting}
|
setShow={setImporting}
|
||||||
show={importing}>
|
show={importing}
|
||||||
|
>
|
||||||
Importing a database overwrites your current data. This action cannot be
|
Importing a database overwrites your current data. This action cannot be
|
||||||
reversed!
|
reversed!
|
||||||
</ConfirmDialog>
|
</ConfirmDialog>
|
||||||
|
|
|
@ -16,7 +16,7 @@ export default function StackHeader({
|
||||||
<Appbar.Header>
|
<Appbar.Header>
|
||||||
<IconButton
|
<IconButton
|
||||||
color={dark ? 'white' : 'white'}
|
color={dark ? 'white' : 'white'}
|
||||||
icon="arrow-back"
|
icon='arrow-back'
|
||||||
onPress={navigation.goBack}
|
onPress={navigation.goBack}
|
||||||
/>
|
/>
|
||||||
<Appbar.Content title={title} />
|
<Appbar.Content title={title} />
|
||||||
|
|
|
@ -104,11 +104,12 @@ export default function StartPlan() {
|
||||||
if (
|
if (
|
||||||
settings.notify &&
|
settings.notify &&
|
||||||
(+weight > best.weight || (+reps > best.reps && +weight === best.weight))
|
(+weight > best.weight || (+reps > best.reps && +weight === best.weight))
|
||||||
)
|
) {
|
||||||
toast("Great work King! That's a new record.")
|
toast('Great work King! That\'s a new record.')
|
||||||
|
}
|
||||||
if (!settings.alarm) return
|
if (!settings.alarm) return
|
||||||
const milliseconds =
|
const milliseconds = Number(best.minutes) * 60 * 1000 +
|
||||||
Number(best.minutes) * 60 * 1000 + Number(best.seconds) * 1000
|
Number(best.seconds) * 1000
|
||||||
NativeModules.AlarmModule.timer(milliseconds)
|
NativeModules.AlarmModule.timer(milliseconds)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,24 +119,24 @@ export default function StartPlan() {
|
||||||
<IconButton
|
<IconButton
|
||||||
color={dark ? 'white' : 'white'}
|
color={dark ? 'white' : 'white'}
|
||||||
onPress={() => navigation.navigate('EditPlan', { plan: params.plan })}
|
onPress={() => navigation.navigate('EditPlan', { plan: params.plan })}
|
||||||
icon="edit"
|
icon='edit'
|
||||||
/>
|
/>
|
||||||
</StackHeader>
|
</StackHeader>
|
||||||
<View style={{ padding: PADDING, flex: 1, flexDirection: 'column' }}>
|
<View style={{ padding: PADDING, flex: 1, flexDirection: 'column' }}>
|
||||||
<View style={{ flex: 1 }}>
|
<View style={{ flex: 1 }}>
|
||||||
<AppInput
|
<AppInput
|
||||||
label="Reps"
|
label='Reps'
|
||||||
keyboardType="numeric"
|
keyboardType='numeric'
|
||||||
value={reps}
|
value={reps}
|
||||||
onChangeText={setReps}
|
onChangeText={setReps}
|
||||||
onSubmitEditing={() => weightRef.current?.focus()}
|
onSubmitEditing={() => weightRef.current?.focus()}
|
||||||
selection={selection}
|
selection={selection}
|
||||||
onSelectionChange={e => setSelection(e.nativeEvent.selection)}
|
onSelectionChange={(e) => setSelection(e.nativeEvent.selection)}
|
||||||
innerRef={repsRef}
|
innerRef={repsRef}
|
||||||
/>
|
/>
|
||||||
<AppInput
|
<AppInput
|
||||||
label="Weight"
|
label='Weight'
|
||||||
keyboardType="numeric"
|
keyboardType='numeric'
|
||||||
value={weight}
|
value={weight}
|
||||||
onChangeText={setWeight}
|
onChangeText={setWeight}
|
||||||
onSubmitEditing={handleSubmit}
|
onSubmitEditing={handleSubmit}
|
||||||
|
@ -144,8 +145,8 @@ export default function StartPlan() {
|
||||||
/>
|
/>
|
||||||
{settings?.showUnit && (
|
{settings?.showUnit && (
|
||||||
<AppInput
|
<AppInput
|
||||||
autoCapitalize="none"
|
autoCapitalize='none'
|
||||||
label="Unit"
|
label='Unit'
|
||||||
value={unit}
|
value={unit}
|
||||||
onChangeText={setUnit}
|
onChangeText={setUnit}
|
||||||
innerRef={unitRef}
|
innerRef={unitRef}
|
||||||
|
@ -154,7 +155,7 @@ export default function StartPlan() {
|
||||||
{counts && (
|
{counts && (
|
||||||
<FlatList
|
<FlatList
|
||||||
data={counts}
|
data={counts}
|
||||||
renderItem={props => (
|
renderItem={(props) => (
|
||||||
<View>
|
<View>
|
||||||
<StartPlanItem
|
<StartPlanItem
|
||||||
{...props}
|
{...props}
|
||||||
|
@ -170,7 +171,7 @@ export default function StartPlan() {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
<Button mode="contained" icon="save" onPress={handleSubmit}>
|
<Button mode='contained' icon='save' onPress={handleSubmit}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -66,14 +66,15 @@ export default function StartPlanItem(props: Props) {
|
||||||
<List.Item
|
<List.Item
|
||||||
onLongPress={longPress}
|
onLongPress={longPress}
|
||||||
title={item.name}
|
title={item.name}
|
||||||
description={
|
description={item.sets
|
||||||
item.sets ? `${item.total} / ${item.sets}` : item.total.toString()
|
? `${item.total} / ${item.sets}`
|
||||||
}
|
: item.total.toString()}
|
||||||
onPress={() => onSelect(index)}
|
onPress={() => onSelect(index)}
|
||||||
left={() => (
|
left={() => (
|
||||||
<View style={{ alignItems: 'center', justifyContent: 'center' }}>
|
<View style={{ alignItems: 'center', justifyContent: 'center' }}>
|
||||||
<RadioButton
|
<RadioButton
|
||||||
onPress={() => onSelect(index)}
|
onPress={() =>
|
||||||
|
onSelect(index)}
|
||||||
value={index.toString()}
|
value={index.toString()}
|
||||||
status={selected === index ? 'checked' : 'unchecked'}
|
status={selected === index ? 'checked' : 'unchecked'}
|
||||||
color={colors.primary}
|
color={colors.primary}
|
||||||
|
@ -85,13 +86,15 @@ export default function StartPlanItem(props: Props) {
|
||||||
style={{
|
style={{
|
||||||
width: '25%',
|
width: '25%',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<Menu
|
<Menu
|
||||||
anchor={anchor}
|
anchor={anchor}
|
||||||
visible={showMenu}
|
visible={showMenu}
|
||||||
onDismiss={() => setShowMenu(false)}>
|
onDismiss={() => setShowMenu(false)}
|
||||||
<Menu.Item icon="edit" onPress={edit} title="Edit" />
|
>
|
||||||
<Menu.Item icon="undo" onPress={undo} title="Undo" />
|
<Menu.Item icon='edit' onPress={edit} title='Edit' />
|
||||||
|
<Menu.Item icon='undo' onPress={undo} title='Undo' />
|
||||||
</Menu>
|
</Menu>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -22,7 +22,8 @@ function Switch({
|
||||||
flexWrap: 'wrap',
|
flexWrap: 'wrap',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
marginBottom: Platform.OS === 'ios' ? MARGIN : null,
|
marginBottom: Platform.OS === 'ios' ? MARGIN : null,
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<PaperSwitch
|
<PaperSwitch
|
||||||
color={colors.primary}
|
color={colors.primary}
|
||||||
style={{ marginRight: MARGIN }}
|
style={{ marginRight: MARGIN }}
|
||||||
|
|
|
@ -45,14 +45,15 @@ export default function TimerPage() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DrawerHeader name="Timer" />
|
<DrawerHeader name='Timer' />
|
||||||
<View style={{ flexGrow: 1, padding: PADDING }}>
|
<View style={{ flexGrow: 1, padding: PADDING }}>
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<Text style={{ fontSize: 70, position: 'absolute' }}>
|
<Text style={{ fontSize: 70, position: 'absolute' }}>
|
||||||
{minutes}:{seconds}
|
{minutes}:{seconds}
|
||||||
</Text>
|
</Text>
|
||||||
|
@ -68,7 +69,7 @@ export default function TimerPage() {
|
||||||
<Button onPress={add} style={{ position: 'absolute', top: '82%', left }}>
|
<Button onPress={add} style={{ position: 'absolute', top: '82%', left }}>
|
||||||
Add 1 min
|
Add 1 min
|
||||||
</Button>
|
</Button>
|
||||||
<AppFab icon="stop" onPress={stop} />
|
<AppFab icon='stop' onPress={stop} />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
44
ViewBest.tsx
44
ViewBest.tsx
|
@ -34,11 +34,11 @@ export default function ViewBest() {
|
||||||
if (period === Periods.Yearly) group = '%Y-%m'
|
if (period === Periods.Yearly) group = '%Y-%m'
|
||||||
const builder = setRepo
|
const builder = setRepo
|
||||||
.createQueryBuilder()
|
.createQueryBuilder()
|
||||||
.select("STRFTIME('%Y-%m-%d', created)", 'created')
|
.select('STRFTIME(\'%Y-%m-%d\', created)', 'created')
|
||||||
.addSelect('unit')
|
.addSelect('unit')
|
||||||
.where('name = :name', { name: params.best.name })
|
.where('name = :name', { name: params.best.name })
|
||||||
.andWhere('NOT hidden')
|
.andWhere('NOT hidden')
|
||||||
.andWhere("DATE(created) >= DATE('now', 'weekday 0', :difference)", {
|
.andWhere('DATE(created) >= DATE(\'now\', \'weekday 0\', :difference)', {
|
||||||
difference,
|
difference,
|
||||||
})
|
})
|
||||||
.groupBy('name')
|
.groupBy('name')
|
||||||
|
@ -64,7 +64,7 @@ export default function ViewBest() {
|
||||||
'weight',
|
'weight',
|
||||||
)
|
)
|
||||||
.getRawMany()
|
.getRawMany()
|
||||||
.then(newWeights => {
|
.then((newWeights) => {
|
||||||
console.log({ weights: newWeights })
|
console.log({ weights: newWeights })
|
||||||
setWeights(newWeights)
|
setWeights(newWeights)
|
||||||
})
|
})
|
||||||
|
@ -76,32 +76,31 @@ export default function ViewBest() {
|
||||||
(metric === Metrics.Volume && volumes?.length === 0) ||
|
(metric === Metrics.Volume && volumes?.length === 0) ||
|
||||||
(metric === Metrics.Weight && weights?.length === 0) ||
|
(metric === Metrics.Weight && weights?.length === 0) ||
|
||||||
(metric === Metrics.OneRepMax && weights?.length === 0)
|
(metric === Metrics.OneRepMax && weights?.length === 0)
|
||||||
)
|
) {
|
||||||
return <List.Item title="No data yet." />
|
return <List.Item title='No data yet.' />
|
||||||
if (metric === Metrics.Volume && volumes?.length && weights?.length)
|
}
|
||||||
|
if (metric === Metrics.Volume && volumes?.length && weights?.length) {
|
||||||
return (
|
return (
|
||||||
<Chart
|
<Chart
|
||||||
yData={volumes.map(v => v.value)}
|
yData={volumes.map((v) => v.value)}
|
||||||
yFormat={(value: number) =>
|
yFormat={(value: number) =>
|
||||||
`${value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')}${
|
`${value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')}${
|
||||||
volumes[0].unit || 'kg'
|
volumes[0].unit || 'kg'
|
||||||
}`
|
}`}
|
||||||
}
|
|
||||||
xData={weights}
|
xData={weights}
|
||||||
xFormat={(_value, index) =>
|
xFormat={(_value, index) =>
|
||||||
format(new Date(weights[index].created), 'd/M')
|
format(new Date(weights[index].created), 'd/M')}
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Chart
|
<Chart
|
||||||
yData={weights?.map(set => set.weight) || []}
|
yData={weights?.map((set) => set.weight) || []}
|
||||||
yFormat={value => `${value}${weights?.[0].unit}`}
|
yFormat={(value) => `${value}${weights?.[0].unit}`}
|
||||||
xData={weights || []}
|
xData={weights || []}
|
||||||
xFormat={(_value, index) =>
|
xFormat={(_value, index) =>
|
||||||
format(new Date(weights?.[index].created), 'd/M')
|
format(new Date(weights?.[index].created), 'd/M')}
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}, [volumes, weights, metric])
|
}, [volumes, weights, metric])
|
||||||
|
@ -112,21 +111,20 @@ export default function ViewBest() {
|
||||||
<IconButton
|
<IconButton
|
||||||
color={dark ? 'white' : 'white'}
|
color={dark ? 'white' : 'white'}
|
||||||
onPress={() =>
|
onPress={() =>
|
||||||
captureScreen().then(async uri => {
|
captureScreen().then(async (uri) => {
|
||||||
const base64 = await FileSystem.readFile(uri, 'base64')
|
const base64 = await FileSystem.readFile(uri, 'base64')
|
||||||
const url = `data:image/jpeg;base64,${base64}`
|
const url = `data:image/jpeg;base64,${base64}`
|
||||||
Share.open({
|
Share.open({
|
||||||
type: 'image/jpeg',
|
type: 'image/jpeg',
|
||||||
url,
|
url,
|
||||||
})
|
})
|
||||||
})
|
})}
|
||||||
}
|
icon='share'
|
||||||
icon="share"
|
|
||||||
/>
|
/>
|
||||||
</StackHeader>
|
</StackHeader>
|
||||||
<View style={{ padding: PADDING }}>
|
<View style={{ padding: PADDING }}>
|
||||||
<Select
|
<Select
|
||||||
label="Metric"
|
label='Metric'
|
||||||
items={[
|
items={[
|
||||||
{ value: Metrics.Volume, label: Metrics.Volume },
|
{ value: Metrics.Volume, label: Metrics.Volume },
|
||||||
{ value: Metrics.OneRepMax, label: Metrics.OneRepMax },
|
{ value: Metrics.OneRepMax, label: Metrics.OneRepMax },
|
||||||
|
@ -135,17 +133,17 @@ export default function ViewBest() {
|
||||||
value: Metrics.Weight,
|
value: Metrics.Weight,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
onChange={value => setMetric(value as Metrics)}
|
onChange={(value) => setMetric(value as Metrics)}
|
||||||
value={metric}
|
value={metric}
|
||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
label="Period"
|
label='Period'
|
||||||
items={[
|
items={[
|
||||||
{ value: Periods.Weekly, label: Periods.Weekly },
|
{ value: Periods.Weekly, label: Periods.Weekly },
|
||||||
{ value: Periods.Monthly, label: Periods.Monthly },
|
{ value: Periods.Monthly, label: Periods.Monthly },
|
||||||
{ value: Periods.Yearly, label: Periods.Yearly },
|
{ value: Periods.Yearly, label: Periods.Yearly },
|
||||||
]}
|
]}
|
||||||
onChange={value => setPeriod(value as Periods)}
|
onChange={(value) => setPeriod(value as Periods)}
|
||||||
value={period}
|
value={period}
|
||||||
/>
|
/>
|
||||||
{charts}
|
{charts}
|
||||||
|
|
|
@ -50,25 +50,29 @@ export default function WorkoutItem({
|
||||||
left={() =>
|
left={() =>
|
||||||
images &&
|
images &&
|
||||||
item.image && (
|
item.image && (
|
||||||
<Image source={{uri: item.image}} style={{height: 75, width: 75}} />
|
<Image
|
||||||
)
|
source={{ uri: item.image }}
|
||||||
}
|
style={{ height: 75, width: 75 }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
right={() => (
|
right={() => (
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
alignSelf: 'center',
|
alignSelf: 'center',
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<Menu
|
<Menu
|
||||||
anchor={anchor}
|
anchor={anchor}
|
||||||
visible={showMenu}
|
visible={showMenu}
|
||||||
onDismiss={() => setShowMenu(false)}>
|
onDismiss={() => setShowMenu(false)}
|
||||||
|
>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
icon="delete"
|
icon='delete'
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
setShowRemove(item.name)
|
setShowRemove(item.name)
|
||||||
setShowMenu(false)
|
setShowMenu(false)
|
||||||
}}
|
}}
|
||||||
title="Delete"
|
title='Delete'
|
||||||
/>
|
/>
|
||||||
</Menu>
|
</Menu>
|
||||||
</Text>
|
</Text>
|
||||||
|
@ -77,8 +81,9 @@ export default function WorkoutItem({
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
title={`Delete ${showRemove}`}
|
title={`Delete ${showRemove}`}
|
||||||
show={!!showRemove}
|
show={!!showRemove}
|
||||||
setShow={show => (show ? null : setShowRemove(''))}
|
setShow={(show) => (show ? null : setShowRemove(''))}
|
||||||
onOk={remove}>
|
onOk={remove}
|
||||||
|
>
|
||||||
This irreversibly deletes ALL sets related to this workout. Are you
|
This irreversibly deletes ALL sets related to this workout. Are you
|
||||||
sure?
|
sure?
|
||||||
</ConfirmDialog>
|
</ConfirmDialog>
|
||||||
|
|
|
@ -100,19 +100,21 @@ export default function WorkoutList() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DrawerHeader name="Workouts" />
|
<DrawerHeader name='Workouts' />
|
||||||
<Page onAdd={onAdd} term={term} search={search}>
|
<Page onAdd={onAdd} term={term} search={search}>
|
||||||
{workouts?.length === 0 ? (
|
{workouts?.length === 0
|
||||||
|
? (
|
||||||
<List.Item
|
<List.Item
|
||||||
title="No workouts yet."
|
title='No workouts yet.'
|
||||||
description="A workout is something you do at the gym. For example Deadlifts are a workout."
|
description='A workout is something you do at the gym. For example Deadlifts are a workout.'
|
||||||
/>
|
/>
|
||||||
) : (
|
)
|
||||||
|
: (
|
||||||
<FlatList
|
<FlatList
|
||||||
data={workouts}
|
data={workouts}
|
||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
keyExtractor={w => w.name}
|
keyExtractor={(w) => w.name}
|
||||||
onEndReached={next}
|
onEndReached={next}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -15,9 +15,10 @@ const Stack = createStackNavigator<WorkoutsPageParams>()
|
||||||
export default function WorkoutsPage() {
|
export default function WorkoutsPage() {
|
||||||
return (
|
return (
|
||||||
<Stack.Navigator
|
<Stack.Navigator
|
||||||
screenOptions={{headerShown: false, animationEnabled: false}}>
|
screenOptions={{ headerShown: false, animationEnabled: false }}
|
||||||
<Stack.Screen name="WorkoutList" component={WorkoutList} />
|
>
|
||||||
<Stack.Screen name="EditWorkout" component={EditWorkout} />
|
<Stack.Screen name='WorkoutList' component={WorkoutList} />
|
||||||
|
<Stack.Screen name='EditWorkout' component={EditWorkout} />
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,8 @@ export const getLast = async (name: string): Promise<GymSet> => {
|
||||||
.createQueryBuilder()
|
.createQueryBuilder()
|
||||||
.where('name = :name', { name })
|
.where('name = :name', { name })
|
||||||
.andWhere('reps >= 5')
|
.andWhere('reps >= 5')
|
||||||
.andWhere("strftime('%Y-%m-%d', 'now', 'localtime') > created")
|
.andWhere('strftime(\'%Y-%m-%d\', \'now\', \'localtime\') > created')
|
||||||
.groupBy("STRFTIME('%Y-%m-%d', created)")
|
.groupBy('STRFTIME(\'%Y-%m-%d\', created)')
|
||||||
.orderBy('created', 'DESC')
|
.orderBy('created', 'DESC')
|
||||||
.select('reps')
|
.select('reps')
|
||||||
.addSelect('MAX(weight) as weight')
|
.addSelect('MAX(weight) as weight')
|
||||||
|
|
|
@ -18,8 +18,9 @@ export const darkColors = [
|
||||||
|
|
||||||
export const colorShade = (color: any, amount: number) => {
|
export const colorShade = (color: any, amount: number) => {
|
||||||
color = color.replace(/^#/, '')
|
color = color.replace(/^#/, '')
|
||||||
if (color.length === 3)
|
if (color.length === 3) {
|
||||||
color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2]
|
color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2]
|
||||||
|
}
|
||||||
|
|
||||||
let [r, g, b] = color.match(/.{2}/g)
|
let [r, g, b] = color.match(/.{2}/g)
|
||||||
;[r, g, b] = [
|
;[r, g, b] = [
|
||||||
|
|
2
db.ts
2
db.ts
|
@ -9,7 +9,7 @@ export const settingsRepo = AppDataSource.manager.getRepository(Settings)
|
||||||
|
|
||||||
export const getNow = async (): Promise<string> => {
|
export const getNow = async (): Promise<string> => {
|
||||||
const query = await AppDataSource.manager.query(
|
const query = await AppDataSource.manager.query(
|
||||||
"SELECT STRFTIME('%Y-%m-%dT%H:%M:%S','now','localtime') AS now",
|
'SELECT STRFTIME(\'%Y-%m-%dT%H:%M:%S\',\'now\',\'localtime\') AS now',
|
||||||
)
|
)
|
||||||
return query[0].now
|
return query[0].now
|
||||||
}
|
}
|
||||||
|
|
11
deno.json
Normal file
11
deno.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"fmt": {
|
||||||
|
"useTabs": false,
|
||||||
|
"lineWidth": 80,
|
||||||
|
"semiColons": false,
|
||||||
|
"singleQuote": true,
|
||||||
|
"proseWrap": "preserve",
|
||||||
|
"include": ["src/"],
|
||||||
|
"exclude": ["src/testdata/", "data/fixtures/**/*.ts"]
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,7 @@ export const MockProviders = ({
|
||||||
}: {
|
}: {
|
||||||
children: JSX.Element | JSX.Element[]
|
children: JSX.Element | JSX.Element[]
|
||||||
}) => (
|
}) => (
|
||||||
<PaperProvider settings={{icon: props => <MaterialIcon {...props} />}}>
|
<PaperProvider settings={{ icon: (props) => <MaterialIcon {...props} /> }}>
|
||||||
<ThemeContext.Provider
|
<ThemeContext.Provider
|
||||||
value={{
|
value={{
|
||||||
theme: 'system',
|
theme: 'system',
|
||||||
|
@ -22,7 +22,8 @@ export const MockProviders = ({
|
||||||
darkColor: DarkTheme.colors.primary,
|
darkColor: DarkTheme.colors.primary,
|
||||||
setLightColor: jest.fn(),
|
setLightColor: jest.fn(),
|
||||||
setDarkColor: jest.fn(),
|
setDarkColor: jest.fn(),
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<NavigationContainer>{children}</NavigationContainer>
|
<NavigationContainer>{children}</NavigationContainer>
|
||||||
</ThemeContext.Provider>
|
</ThemeContext.Provider>
|
||||||
</PaperProvider>
|
</PaperProvider>
|
||||||
|
|
|
@ -6,13 +6,13 @@ export const themeOptions = [
|
||||||
{ label: 'Light', value: 'light' },
|
{ label: 'Light', value: 'light' },
|
||||||
]
|
]
|
||||||
|
|
||||||
export const lightOptions = lightColors.map(color => ({
|
export const lightOptions = lightColors.map((color) => ({
|
||||||
label: color.name,
|
label: color.name,
|
||||||
value: color.hex,
|
value: color.hex,
|
||||||
color: color.hex,
|
color: color.hex,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
export const darkOptions = darkColors.map(color => ({
|
export const darkOptions = darkColors.map((color) => ({
|
||||||
label: color.name,
|
label: color.name,
|
||||||
value: color.hex,
|
value: color.hex,
|
||||||
color: color.hex,
|
color: color.hex,
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
organize-imports-cli *.ts* tests/*.ts* && prettier --write *.ts* tests/*.ts*
|
organize-imports-cli *.ts* tests/*.ts* && deno fmt *.ts* tests/*.ts*
|
||||||
|
|
|
@ -34,7 +34,7 @@ jest.mock('../db.ts', () => ({
|
||||||
reps: 10,
|
reps: 10,
|
||||||
image: 'https://picsum.photos/id/1/1000/600',
|
image: 'https://picsum.photos/id/1/1000/600',
|
||||||
},
|
},
|
||||||
]),
|
])
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|
|
@ -18,7 +18,7 @@ jest.mock('../db.ts', () => ({
|
||||||
{ name: 'Bench press' },
|
{ name: 'Bench press' },
|
||||||
{ name: 'Bicep curls' },
|
{ name: 'Bicep curls' },
|
||||||
{ name: 'Rows' },
|
{ name: 'Rows' },
|
||||||
]),
|
])
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
@ -37,7 +37,7 @@ test('renders correctly', async () => {
|
||||||
id: 1,
|
id: 1,
|
||||||
} as Plan,
|
} as Plan,
|
||||||
}}
|
}}
|
||||||
name="EditPlan"
|
name='EditPlan'
|
||||||
component={EditPlan}
|
component={EditPlan}
|
||||||
/>
|
/>
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
|
|
|
@ -37,7 +37,7 @@ test('renders correctly', async () => {
|
||||||
id: 1,
|
id: 1,
|
||||||
} as GymSet,
|
} as GymSet,
|
||||||
}}
|
}}
|
||||||
name="EditSet"
|
name='EditSet'
|
||||||
component={EditSet}
|
component={EditSet}
|
||||||
/>
|
/>
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
|
@ -58,7 +58,7 @@ test('saves', async () => {
|
||||||
const { getByText, getAllByText, getByTestId } = render(
|
const { getByText, getAllByText, getByTestId } = render(
|
||||||
<MockProviders>
|
<MockProviders>
|
||||||
<Stack.Navigator>
|
<Stack.Navigator>
|
||||||
<Stack.Screen name="Sets" component={SetList} />
|
<Stack.Screen name='Sets' component={SetList} />
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
initialParams={{
|
initialParams={{
|
||||||
set: {
|
set: {
|
||||||
|
@ -66,7 +66,7 @@ test('saves', async () => {
|
||||||
id: 1,
|
id: 1,
|
||||||
} as GymSet,
|
} as GymSet,
|
||||||
}}
|
}}
|
||||||
name="EditSet"
|
name='EditSet'
|
||||||
component={EditSet}
|
component={EditSet}
|
||||||
/>
|
/>
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
|
|
|
@ -43,7 +43,7 @@ test('renders correctly', async () => {
|
||||||
<Stack.Navigator>
|
<Stack.Navigator>
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
initialParams={{ ids: [1, 2, 3] }}
|
initialParams={{ ids: [1, 2, 3] }}
|
||||||
name="EditSets"
|
name='EditSets'
|
||||||
component={EditSets}
|
component={EditSets}
|
||||||
/>
|
/>
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
|
@ -65,7 +65,7 @@ test('saves', async () => {
|
||||||
<Stack.Navigator>
|
<Stack.Navigator>
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
initialParams={{ ids: [1, 2, 3] }}
|
initialParams={{ ids: [1, 2, 3] }}
|
||||||
name="EditSets"
|
name='EditSets'
|
||||||
component={EditSets}
|
component={EditSets}
|
||||||
/>
|
/>
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
|
|
|
@ -27,7 +27,7 @@ test('renders correctly', async () => {
|
||||||
initialParams={{
|
initialParams={{
|
||||||
value: { name: 'Bench press' } as GymSet,
|
value: { name: 'Bench press' } as GymSet,
|
||||||
}}
|
}}
|
||||||
name="EditWorkout"
|
name='EditWorkout'
|
||||||
component={EditWorkout}
|
component={EditWorkout}
|
||||||
/>
|
/>
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
|
|
|
@ -26,7 +26,7 @@ jest.mock('../db.ts', () => ({
|
||||||
{
|
{
|
||||||
name: 'Rows',
|
name: 'Rows',
|
||||||
},
|
},
|
||||||
]),
|
])
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|
|
@ -37,7 +37,7 @@ jest.mock('../data-source.ts', () => ({
|
||||||
{ name: 'Bench', total: 0 },
|
{ name: 'Bench', total: 0 },
|
||||||
{ name: 'Rows', total: 0 },
|
{ name: 'Rows', total: 0 },
|
||||||
{ name: 'Curls', total: 0 },
|
{ name: 'Curls', total: 0 },
|
||||||
]),
|
])
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -56,7 +56,7 @@ test('renders correctly', async () => {
|
||||||
days: 'Monday,Tuesday,Thursday',
|
days: 'Monday,Tuesday,Thursday',
|
||||||
} as Plan,
|
} as Plan,
|
||||||
}}
|
}}
|
||||||
name="StartPlan"
|
name='StartPlan'
|
||||||
component={StartPlan}
|
component={StartPlan}
|
||||||
/>
|
/>
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
|
@ -86,7 +86,7 @@ test('saves', async () => {
|
||||||
days: 'Monday,Tuesday,Thursday',
|
days: 'Monday,Tuesday,Thursday',
|
||||||
} as Plan,
|
} as Plan,
|
||||||
}}
|
}}
|
||||||
name="StartPlan"
|
name='StartPlan'
|
||||||
component={StartPlan}
|
component={StartPlan}
|
||||||
/>
|
/>
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
|
|
|
@ -35,7 +35,7 @@ jest.mock('../db.ts', () => ({
|
||||||
created: '2021-01-05T03:58:02.565Z',
|
created: '2021-01-05T03:58:02.565Z',
|
||||||
weight: 28,
|
weight: 28,
|
||||||
},
|
},
|
||||||
]),
|
])
|
||||||
),
|
),
|
||||||
getMany: jest.fn(() =>
|
getMany: jest.fn(() =>
|
||||||
Promise.resolve([
|
Promise.resolve([
|
||||||
|
@ -57,7 +57,7 @@ jest.mock('../db.ts', () => ({
|
||||||
reps: 10,
|
reps: 10,
|
||||||
image: 'https://picsum.photos/id/1/1000/600',
|
image: 'https://picsum.photos/id/1/1000/600',
|
||||||
},
|
},
|
||||||
]),
|
])
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|
3
write.ts
3
write.ts
|
@ -14,7 +14,8 @@ export const write = async (name: string, data: string) => {
|
||||||
const granted = await permission()
|
const granted = await permission()
|
||||||
if (!granted) return
|
if (!granted) return
|
||||||
await FileSystem.writeFile(filePath, data)
|
await FileSystem.writeFile(filePath, data)
|
||||||
if (Platform.OS === 'android')
|
if (Platform.OS === 'android') {
|
||||||
await FileSystem.cpExternal(filePath, name, 'downloads')
|
await FileSystem.cpExternal(filePath, name, 'downloads')
|
||||||
|
}
|
||||||
toast(`Downloaded ${name}`)
|
toast(`Downloaded ${name}`)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user