Use deno fmt instead of prettier

This commit is contained in:
Brandon Presley 2023-06-27 15:16:59 +12:00
parent 23ed95dcdb
commit 4303fe2cc4
67 changed files with 897 additions and 820 deletions

View File

@ -1,8 +0,0 @@
module.exports = {
arrowParens: 'avoid',
bracketSameLine: true,
bracketSpacing: false,
singleQuote: true,
trailingComma: 'all',
semi: false,
};

37
App.tsx
View File

@ -3,8 +3,8 @@ import {
DefaultTheme as NavigationDefaultTheme,
NavigationContainer,
} from '@react-navigation/native'
import React, {useEffect, useMemo, useState} from 'react'
import {DeviceEventEmitter, useColorScheme} from 'react-native'
import React, { useEffect, useMemo, useState } from 'react'
import { DeviceEventEmitter, useColorScheme } from 'react-native'
import {
DarkTheme as PaperDarkTheme,
DefaultTheme as PaperDefaultTheme,
@ -12,11 +12,11 @@ import {
Snackbar,
} from 'react-native-paper'
import MaterialIcon from 'react-native-vector-icons/MaterialIcons'
import {AppDataSource} from './data-source'
import {settingsRepo} from './db'
import { AppDataSource } from './data-source'
import { settingsRepo } from './db'
import Routes from './Routes'
import {TOAST} from './toast'
import {ThemeContext} from './use-theme'
import { TOAST } from './toast'
import { ThemeContext } from './use-theme'
export const CombinedDefaultTheme = {
...NavigationDefaultTheme,
@ -53,7 +53,7 @@ const App = () => {
useEffect(() => {
;(async () => {
if (!AppDataSource.isInitialized) await AppDataSource.initialize()
const settings = await settingsRepo.findOne({where: {}})
const settings = await settingsRepo.findOne({ where: {} })
setTheme(settings.theme)
if (settings.lightColor) setLightColor(settings.lightColor)
if (settings.darkColor) setDarkColor(settings.darkColor)
@ -61,7 +61,7 @@ const App = () => {
})()
const description = DeviceEventEmitter.addListener(
TOAST,
({value}: {value: string}) => {
({ value }: { value: string }) => {
setSnackbar(value)
},
)
@ -71,15 +71,15 @@ const App = () => {
const paperTheme = useMemo(() => {
const darkTheme = lightColor
? {
...CombinedDarkTheme,
colors: {...CombinedDarkTheme.colors, primary: darkColor},
}
...CombinedDarkTheme,
colors: { ...CombinedDarkTheme.colors, primary: darkColor },
}
: CombinedDarkTheme
const lightTheme = lightColor
? {
...CombinedDefaultTheme,
colors: {...CombinedDefaultTheme.colors, primary: lightColor},
}
...CombinedDefaultTheme,
colors: { ...CombinedDefaultTheme.colors, primary: lightColor },
}
: CombinedDefaultTheme
let value = isDark ? darkTheme : lightTheme
if (theme === 'dark') value = darkTheme
@ -99,7 +99,8 @@ const App = () => {
return (
<PaperProvider
theme={paperTheme}
settings={{icon: props => <MaterialIcon {...props} />}}>
settings={{ icon: (props) => <MaterialIcon {...props} /> }}
>
<NavigationContainer theme={paperTheme}>
{initialized && (
<ThemeContext.Provider
@ -110,7 +111,8 @@ const App = () => {
setLightColor,
darkColor,
setDarkColor,
}}>
}}
>
<Routes />
</ThemeContext.Provider>
)}
@ -120,7 +122,8 @@ const App = () => {
duration={3000}
onDismiss={() => setSnackbar('')}
visible={!!snackbar}
action={action}>
action={action}
>
{snackbar}
</Snackbar>
</PaperProvider>

View File

@ -1,14 +1,14 @@
import {ComponentProps, useMemo} from 'react'
import {FAB, useTheme} from 'react-native-paper'
import {CombinedDarkTheme, CombinedDefaultTheme} from './App'
import {lightColors} from './colors'
import { ComponentProps, useMemo } from 'react'
import { FAB, useTheme } from 'react-native-paper'
import { CombinedDarkTheme, CombinedDefaultTheme } from './App'
import { lightColors } from './colors'
export default function AppFab(props: Partial<ComponentProps<typeof FAB>>) {
const {colors} = useTheme()
const { colors } = useTheme()
const fabColor = useMemo(
() =>
lightColors.map(color => color.hex).includes(colors.primary)
lightColors.map((color) => color.hex).includes(colors.primary)
? CombinedDarkTheme.colors.background
: CombinedDefaultTheme.colors.background,
[colors.primary],
@ -16,8 +16,8 @@ export default function AppFab(props: Partial<ComponentProps<typeof FAB>>) {
return (
<FAB
icon="add"
testID="add"
icon='add'
testID='add'
color={fabColor}
style={{
position: 'absolute',

View File

@ -1,7 +1,7 @@
import React, {ComponentProps, Ref} from 'react'
import {TextInput} from 'react-native-paper'
import {CombinedDefaultTheme} from './App'
import {MARGIN} from './constants'
import React, { ComponentProps, Ref } from 'react'
import { TextInput } from 'react-native-paper'
import { CombinedDefaultTheme } from './App'
import { MARGIN } from './constants'
import useDark from './use-dark'
function AppInput(
@ -14,7 +14,7 @@ function AppInput(
return (
<TextInput
selectionColor={dark ? '#2A2A2A' : CombinedDefaultTheme.colors.border}
style={{marginBottom: MARGIN, minWidth: 100}}
style={{ marginBottom: MARGIN, minWidth: 100 }}
selectTextOnFocus
ref={props.innerRef}
blurOnSubmit={false}

View File

@ -3,11 +3,11 @@ import {
useFocusEffect,
useNavigation,
} from '@react-navigation/native'
import {useCallback, useState} from 'react'
import {FlatList, Image} from 'react-native'
import {List} from 'react-native-paper'
import {BestPageParams} from './BestPage'
import {setRepo, settingsRepo} from './db'
import { useCallback, useState } from 'react'
import { FlatList, Image } from 'react-native'
import { List } from 'react-native-paper'
import { BestPageParams } from './BestPage'
import { setRepo, settingsRepo } from './db'
import DrawerHeader from './DrawerHeader'
import GymSet from './gym-set'
import Page from './Page'
@ -21,7 +21,7 @@ export default function BestList() {
useFocusEffect(
useCallback(() => {
settingsRepo.findOne({where: {}}).then(setSettings)
settingsRepo.findOne({ where: {} }).then(setSettings)
}, []),
)
@ -30,19 +30,19 @@ export default function BestList() {
.createQueryBuilder()
.select()
.addSelect('MAX(weight)', 'weight')
.where('name LIKE :name', {name: `%${value.trim()}%`})
.where('name LIKE :name', { name: `%${value.trim()}%` })
.andWhere('NOT hidden')
.groupBy('name')
.getMany()
console.log(`${BestList.name}.refresh:`, {length: weights.length})
console.log(`${BestList.name}.refresh:`, { length: weights.length })
let newBest: GymSet[] = []
for (const set of weights) {
const reps = await setRepo
.createQueryBuilder()
.select()
.addSelect('MAX(reps)', 'reps')
.where('name = :name', {name: set.name})
.andWhere('weight = :weight', {weight: set.weight})
.where('name = :name', { name: set.name })
.andWhere('weight = :weight', { weight: set.weight })
.andWhere('NOT hidden')
.groupBy('name')
.getMany()
@ -65,33 +65,41 @@ export default function BestList() {
[refresh],
)
const renderItem = ({item}: {item: GymSet}) => (
const renderItem = ({ item }: { item: GymSet }) => (
<List.Item
key={item.name}
title={item.name}
description={`${item.reps} x ${item.weight}${item.unit || 'kg'}`}
onPress={() => navigation.navigate('ViewBest', {best: item})}
onPress={() => navigation.navigate('ViewBest', { best: item })}
left={() =>
(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 (
<>
<DrawerHeader name="Best" />
<DrawerHeader name='Best' />
<Page term={term} search={search}>
{bests?.length === 0 ? (
<List.Item
title="No exercises yet"
description="Once sets have been added, this will highlight your personal bests."
/>
) : (
<FlatList style={{flex: 1}} renderItem={renderItem} data={bests} />
)}
{bests?.length === 0
? (
<List.Item
title='No exercises yet'
description='Once sets have been added, this will highlight your personal bests.'
/>
)
: (
<FlatList
style={{ flex: 1 }}
renderItem={renderItem}
data={bests}
/>
)}
</Page>
</>
)

View File

@ -1,4 +1,4 @@
import {createStackNavigator} from '@react-navigation/stack'
import { createStackNavigator } from '@react-navigation/stack'
import BestList from './BestList'
import GymSet from './gym-set'
import ViewBest from './ViewBest'
@ -14,9 +14,10 @@ export type BestPageParams = {
export default function BestPage() {
return (
<Stack.Navigator
screenOptions={{headerShown: false, animationEnabled: false}}>
<Stack.Screen name="BestList" component={BestList} />
<Stack.Screen name="ViewBest" component={ViewBest} />
screenOptions={{ headerShown: false, animationEnabled: false }}
>
<Stack.Screen name='BestList' component={BestList} />
<Stack.Screen name='ViewBest' component={ViewBest} />
</Stack.Navigator>
)
}

View File

@ -1,9 +1,9 @@
import {useTheme} from '@react-navigation/native'
import { useTheme } from '@react-navigation/native'
import * as shape from 'd3-shape'
import {View} from 'react-native'
import {Grid, LineChart, XAxis, YAxis} from 'react-native-svg-charts'
import {CombinedDarkTheme, CombinedDefaultTheme} from './App'
import {MARGIN, PADDING} from './constants'
import { View } from 'react-native'
import { Grid, LineChart, XAxis, YAxis } from 'react-native-svg-charts'
import { CombinedDarkTheme, CombinedDefaultTheme } from './App'
import { MARGIN, PADDING } from './constants'
import GymSet from './gym-set'
import useDark from './use-dark'
@ -18,7 +18,7 @@ export default function Chart({
xFormat: (value: any, index: number) => string
yFormat: (value: any) => string
}) {
const {colors} = useTheme()
const { colors } = useTheme()
const dark = useDark()
const axesSvg = {
fontSize: 10,
@ -26,7 +26,7 @@ export default function Chart({
? CombinedDarkTheme.colors.text
: CombinedDefaultTheme.colors.text,
}
const verticalContentInset = {top: 10, bottom: 10}
const verticalContentInset = { top: 10, bottom: 10 }
const xAxisHeight = 30
return (
@ -36,29 +36,31 @@ export default function Chart({
height: 300,
padding: PADDING,
flexDirection: 'row',
}}>
}}
>
<YAxis
data={yData}
style={{marginBottom: xAxisHeight}}
style={{ marginBottom: xAxisHeight }}
contentInset={verticalContentInset}
svg={axesSvg}
formatLabel={yFormat}
/>
<View style={{flex: 1, marginLeft: MARGIN}}>
<View style={{ flex: 1, marginLeft: MARGIN }}>
<LineChart
style={{flex: 1}}
style={{ flex: 1 }}
data={yData}
contentInset={verticalContentInset}
curve={shape.curveBasis}
svg={{
stroke: colors.primary,
}}>
}}
>
<Grid />
</LineChart>
<XAxis
data={xData}
formatLabel={xFormat}
contentInset={{left: 15, right: 16}}
contentInset={{ left: 15, right: 16 }}
svg={axesSvg}
/>
</View>

View File

@ -1,4 +1,4 @@
import {Button, Dialog, Portal, Text} from 'react-native-paper'
import { Button, Dialog, Portal, Text } from 'react-native-paper'
export default function ConfirmDialog({
title,

View File

@ -1,7 +1,7 @@
import {DrawerNavigationProp} from '@react-navigation/drawer'
import {useNavigation} from '@react-navigation/native'
import {Appbar, IconButton} from 'react-native-paper'
import {DrawerParamList} from './drawer-param-list'
import { DrawerNavigationProp } from '@react-navigation/drawer'
import { useNavigation } from '@react-navigation/native'
import { Appbar, IconButton } from 'react-native-paper'
import { DrawerParamList } from './drawer-param-list'
import useDark from './use-dark'
export default function DrawerHeader({
@ -18,7 +18,7 @@ export default function DrawerHeader({
<Appbar.Header>
<IconButton
color={dark ? 'white' : 'white'}
icon="menu"
icon='menu'
onPress={navigation.openDrawer}
/>
<Appbar.Content title={name} />

View File

@ -4,22 +4,22 @@ import {
useNavigation,
useRoute,
} from '@react-navigation/native'
import {useCallback, useEffect, useState} from 'react'
import {ScrollView, StyleSheet, View} from 'react-native'
import {Button, IconButton, Text} from 'react-native-paper'
import {getLast} from './best.service'
import {MARGIN, PADDING} from './constants'
import {planRepo, setRepo} from './db'
import {defaultSet} from './gym-set'
import {PlanPageParams} from './plan-page-params'
import { useCallback, useEffect, useState } from 'react'
import { ScrollView, StyleSheet, View } from 'react-native'
import { Button, IconButton, Text } from 'react-native-paper'
import { getLast } from './best.service'
import { MARGIN, PADDING } from './constants'
import { planRepo, setRepo } from './db'
import { defaultSet } from './gym-set'
import { PlanPageParams } from './plan-page-params'
import StackHeader from './StackHeader'
import Switch from './Switch'
import {DAYS} from './time'
import { DAYS } from './time'
import useDark from './use-dark'
export default function EditPlan() {
const {params} = useRoute<RouteProp<PlanPageParams, 'EditPlan'>>()
const {plan} = params
const { params } = useRoute<RouteProp<PlanPageParams, 'EditPlan'>>()
const { plan } = params
const [days, setDays] = useState<string[]>(
plan.days ? plan.days.split(',') : [],
)
@ -37,18 +37,18 @@ export default function EditPlan() {
.distinct(true)
.orderBy('name')
.getRawMany()
.then(values => {
console.log(EditPlan.name, {values})
setNames(values.map(value => value.name))
.then((values) => {
console.log(EditPlan.name, { values })
setNames(values.map((value) => value.name))
})
}, [])
const save = useCallback(async () => {
console.log(`${EditPlan.name}.save`, {days, workouts, plan})
console.log(`${EditPlan.name}.save`, { days, workouts, plan })
if (!days || !workouts) return
const newWorkouts = workouts.filter(workout => workout).join(',')
const newDays = days.filter(day => day).join(',')
await planRepo.save({days: newDays, workouts: newWorkouts, id: plan.id})
const newWorkouts = workouts.filter((workout) => workout).join(',')
const newDays = days.filter((day) => day).join(',')
await planRepo.save({ days: newDays, workouts: newWorkouts, id: plan.id })
navigation.goBack()
}, [days, workouts, plan, navigation])
@ -57,7 +57,7 @@ export default function EditPlan() {
if (on) {
setWorkouts([...workouts, name])
} else {
setWorkouts(workouts.filter(workout => workout !== name))
setWorkouts(workouts.filter((workout) => workout !== name))
}
},
[setWorkouts, workouts],
@ -68,7 +68,7 @@ export default function EditPlan() {
if (on) {
setDays([...days, day])
} else {
setDays(days.filter(d => d !== day))
setDays(days.filter((d) => d !== day))
}
},
[setDays, days],
@ -77,52 +77,56 @@ export default function EditPlan() {
return (
<>
<StackHeader
title={typeof plan.id === 'number' ? 'Edit plan' : 'Add plan'}>
title={typeof plan.id === 'number' ? 'Edit plan' : 'Add plan'}
>
<IconButton
color={dark ? 'white' : 'white'}
onPress={async () => {
let first = await getLast(workouts[0])
if (!first) first = {...defaultSet, name: workouts[0]}
if (!first) first = { ...defaultSet, name: workouts[0] }
delete first.id
navigation.navigate('StartPlan', {plan: params.plan, first})
navigation.navigate('StartPlan', { plan: params.plan, first })
}}
icon="play-arrow"
icon='play-arrow'
/>
</StackHeader>
<View style={{padding: PADDING, flex: 1}}>
<ScrollView style={{flex: 1}}>
<View style={{ padding: PADDING, flex: 1 }}>
<ScrollView style={{ flex: 1 }}>
<Text style={styles.title}>Days</Text>
{DAYS.map(day => (
{DAYS.map((day) => (
<Switch
key={day}
onChange={value => toggleDay(value, day)}
onChange={(value) => toggleDay(value, day)}
value={days.includes(day)}
title={day}
/>
))}
<Text style={[styles.title, {marginTop: MARGIN}]}>Workouts</Text>
{names.length === 0 ? (
<View>
<Text>No workouts found.</Text>
</View>
) : (
names.map(name => (
<Switch
key={name}
onChange={value => toggleWorkout(value, name)}
value={workouts.includes(name)}
title={name}
/>
))
)}
<Text style={[styles.title, { marginTop: MARGIN }]}>Workouts</Text>
{names.length === 0
? (
<View>
<Text>No workouts found.</Text>
</View>
)
: (
names.map((name) => (
<Switch
key={name}
onChange={(value) => toggleWorkout(value, name)}
value={workouts.includes(name)}
title={name}
/>
))
)}
</ScrollView>
<Button
disabled={workouts.length === 0 && days.length === 0}
style={styles.button}
mode="contained"
icon="save"
onPress={save}>
mode='contained'
icon='save'
onPress={save}
>
Save
</Button>
</View>

View File

@ -1,28 +1,28 @@
import {DateTimePickerAndroid} from '@react-native-community/datetimepicker'
import { DateTimePickerAndroid } from '@react-native-community/datetimepicker'
import {
RouteProp,
useFocusEffect,
useNavigation,
useRoute,
} from '@react-navigation/native'
import {format} from 'date-fns'
import {useCallback, useRef, useState} from 'react'
import {NativeModules, TextInput, View} from 'react-native'
import { format } from 'date-fns'
import { useCallback, useRef, useState } from 'react'
import { NativeModules, TextInput, View } from 'react-native'
import DocumentPicker from 'react-native-document-picker'
import {Button, Card, TouchableRipple} from 'react-native-paper'
import { Button, Card, TouchableRipple } from 'react-native-paper'
import AppInput from './AppInput'
import ConfirmDialog from './ConfirmDialog'
import {MARGIN, PADDING} from './constants'
import {getNow, setRepo, settingsRepo} from './db'
import { MARGIN, PADDING } from './constants'
import { getNow, setRepo, settingsRepo } from './db'
import GymSet from './gym-set'
import {HomePageParams} from './home-page-params'
import { HomePageParams } from './home-page-params'
import Settings from './settings'
import StackHeader from './StackHeader'
import {toast} from './toast'
import { toast } from './toast'
export default function EditSet() {
const {params} = useRoute<RouteProp<HomePageParams, 'EditSet'>>()
const {set} = params
const { params } = useRoute<RouteProp<HomePageParams, 'EditSet'>>()
const { set } = params
const navigation = useNavigation()
const [settings, setSettings] = useState<Settings>({} as Settings)
const [name, setName] = useState(set.name)
@ -46,16 +46,16 @@ export default function EditSet() {
useFocusEffect(
useCallback(() => {
settingsRepo.findOne({where: {}}).then(setSettings)
settingsRepo.findOne({ where: {} }).then(setSettings)
}, []),
)
const startTimer = useCallback(
async (value: string) => {
if (!settings.alarm) return
const first = await setRepo.findOne({where: {name: value}})
const milliseconds =
(first?.minutes ?? 3) * 60 * 1000 + (first?.seconds ?? 0) * 1000
const first = await setRepo.findOne({ where: { name: value } })
const milliseconds = (first?.minutes ?? 3) * 60 * 1000 +
(first?.seconds ?? 0) * 1000
if (milliseconds) NativeModules.AlarmModule.timer(milliseconds)
},
[settings],
@ -64,25 +64,27 @@ export default function EditSet() {
const added = useCallback(
async (value: GymSet) => {
startTimer(value.name)
console.log(`${EditSet.name}.add`, {set: value})
console.log(`${EditSet.name}.add`, { set: value })
if (!settings.notify) return
if (
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],
)
const handleSubmit = async () => {
console.log(`${EditSet.name}.handleSubmit:`, {set, uri: newImage, name})
console.log(`${EditSet.name}.handleSubmit:`, { set, uri: newImage, name })
if (!name) return
let image = newImage
if (!newImage && !removeImage)
image = await setRepo.findOne({where: {name}}).then(s => s?.image)
if (!newImage && !removeImage) {
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 saved = await setRepo.save({
id: set.id,
@ -102,7 +104,7 @@ export default function EditSet() {
}
const changeImage = useCallback(async () => {
const {fileCopyUri} = await DocumentPicker.pickSingle({
const { fileCopyUri } = await DocumentPicker.pickSingle({
type: DocumentPicker.types.images,
copyTo: 'documentDirectory',
})
@ -137,9 +139,9 @@ export default function EditSet() {
title={typeof set.id === 'number' ? 'Edit set' : 'Add set'}
/>
<View style={{padding: PADDING, flex: 1}}>
<View style={{ padding: PADDING, flex: 1 }}>
<AppInput
label="Name"
label='Name'
value={name}
onChangeText={setName}
autoCorrect={false}
@ -148,20 +150,20 @@ export default function EditSet() {
/>
<AppInput
label="Reps"
keyboardType="numeric"
label='Reps'
keyboardType='numeric'
value={reps}
onChangeText={setReps}
onSubmitEditing={() => weightRef.current?.focus()}
selection={selection}
onSelectionChange={e => setSelection(e.nativeEvent.selection)}
onSelectionChange={(e) => setSelection(e.nativeEvent.selection)}
autoFocus={!!name}
innerRef={repsRef}
/>
<AppInput
label="Weight"
keyboardType="numeric"
label='Weight'
keyboardType='numeric'
value={weight}
onChangeText={setWeight}
onSubmitEditing={handleSubmit}
@ -170,8 +172,8 @@ export default function EditSet() {
{settings.showUnit && (
<AppInput
autoCapitalize="none"
label="Unit"
autoCapitalize='none'
label='Unit'
value={unit}
onChangeText={setUnit}
innerRef={unitRef}
@ -180,7 +182,7 @@ export default function EditSet() {
{typeof set.id === 'number' && settings.showDate && (
<AppInput
label="Created"
label='Created'
value={format(created, settings.date || 'P')}
onPressOut={pickDate}
/>
@ -188,18 +190,20 @@ export default function EditSet() {
{settings.images && newImage && (
<TouchableRipple
style={{marginBottom: MARGIN}}
style={{ marginBottom: MARGIN }}
onPress={changeImage}
onLongPress={() => setShowRemove(true)}>
<Card.Cover source={{uri: newImage}} />
onLongPress={() => setShowRemove(true)}
>
<Card.Cover source={{ uri: newImage }} />
</TouchableRipple>
)}
{settings.images && !newImage && (
<Button
style={{marginBottom: MARGIN}}
style={{ marginBottom: MARGIN }}
onPress={changeImage}
icon="add-photo-alternate">
icon='add-photo-alternate'
>
Image
</Button>
)}
@ -207,18 +211,20 @@ export default function EditSet() {
<Button
disabled={!name}
mode="contained"
icon="save"
style={{margin: MARGIN}}
onPress={handleSubmit}>
mode='contained'
icon='save'
style={{ margin: MARGIN }}
onPress={handleSubmit}
>
Save
</Button>
<ConfirmDialog
title="Remove image"
title='Remove image'
onOk={handleRemove}
show={showRemove}
setShow={setShowRemove}>
setShow={setShowRemove}
>
Are you sure you want to remove the image?
</ConfirmDialog>
</>

View File

@ -4,23 +4,23 @@ import {
useNavigation,
useRoute,
} from '@react-navigation/native'
import {useCallback, useState} from 'react'
import {View} from 'react-native'
import { useCallback, useState } from 'react'
import { View } from 'react-native'
import DocumentPicker from 'react-native-document-picker'
import {Button, Card, TouchableRipple} from 'react-native-paper'
import {In} from 'typeorm'
import { Button, Card, TouchableRipple } from 'react-native-paper'
import { In } from 'typeorm'
import AppInput from './AppInput'
import ConfirmDialog from './ConfirmDialog'
import {MARGIN, PADDING} from './constants'
import {setRepo, settingsRepo} from './db'
import { MARGIN, PADDING } from './constants'
import { setRepo, settingsRepo } from './db'
import GymSet from './gym-set'
import {HomePageParams} from './home-page-params'
import { HomePageParams } from './home-page-params'
import Settings from './settings'
import StackHeader from './StackHeader'
export default function EditSets() {
const {params} = useRoute<RouteProp<HomePageParams, 'EditSets'>>()
const {ids} = params
const { params } = useRoute<RouteProp<HomePageParams, 'EditSets'>>()
const { ids } = params
const navigation = useNavigation()
const [settings, setSettings] = useState<Settings>({} as Settings)
const [name, setName] = useState('')
@ -41,18 +41,18 @@ export default function EditSets() {
useFocusEffect(
useCallback(() => {
settingsRepo.findOne({where: {}}).then(setSettings)
setRepo.find({where: {id: In(ids)}}).then(sets => {
setNames(sets.map(set => set.name).join(', '))
setOldReps(sets.map(set => set.reps).join(', '))
setWeights(sets.map(set => set.weight).join(', '))
setUnits(sets.map(set => set.unit).join(', '))
settingsRepo.findOne({ where: {} }).then(setSettings)
setRepo.find({ where: { id: In(ids) } }).then((sets) => {
setNames(sets.map((set) => set.name).join(', '))
setOldReps(sets.map((set) => set.reps).join(', '))
setWeights(sets.map((set) => set.weight).join(', '))
setUnits(sets.map((set) => set.unit).join(', '))
})
}, [ids]),
)
const handleSubmit = async () => {
console.log(`${EditSets.name}.handleSubmit:`, {uri: newImage, name})
console.log(`${EditSets.name}.handleSubmit:`, { uri: newImage, name })
const update: Partial<GymSet> = {}
if (name) update.name = name
if (reps) update.reps = Number(reps)
@ -64,7 +64,7 @@ export default function EditSets() {
}
const changeImage = useCallback(async () => {
const {fileCopyUri} = await DocumentPicker.pickSingle({
const { fileCopyUri } = await DocumentPicker.pickSingle({
type: DocumentPicker.types.images,
copyTo: 'documentDirectory',
})
@ -80,7 +80,7 @@ export default function EditSets() {
<>
<StackHeader title={`Edit ${ids.length} sets`} />
<View style={{padding: PADDING, flex: 1}}>
<View style={{ padding: PADDING, flex: 1 }}>
<AppInput
label={`Names: ${names}`}
value={name}
@ -91,17 +91,17 @@ export default function EditSets() {
<AppInput
label={`Reps: ${oldReps}`}
keyboardType="numeric"
keyboardType='numeric'
value={reps}
onChangeText={setReps}
selection={selection}
onSelectionChange={e => setSelection(e.nativeEvent.selection)}
onSelectionChange={(e) => setSelection(e.nativeEvent.selection)}
autoFocus={!!name}
/>
<AppInput
label={`Weights: ${weights}`}
keyboardType="numeric"
keyboardType='numeric'
value={weight}
onChangeText={setWeight}
onSubmitEditing={handleSubmit}
@ -109,7 +109,7 @@ export default function EditSets() {
{settings.showUnit && (
<AppInput
autoCapitalize="none"
autoCapitalize='none'
label={`Units: ${units}`}
value={unit}
onChangeText={setUnit}
@ -118,35 +118,39 @@ export default function EditSets() {
{settings.images && newImage && (
<TouchableRipple
style={{marginBottom: MARGIN}}
style={{ marginBottom: MARGIN }}
onPress={changeImage}
onLongPress={() => setShowRemove(true)}>
<Card.Cover source={{uri: newImage}} />
onLongPress={() => setShowRemove(true)}
>
<Card.Cover source={{ uri: newImage }} />
</TouchableRipple>
)}
<ConfirmDialog
title="Remove image"
title='Remove image'
onOk={handleRemove}
show={showRemove}
setShow={setShowRemove}>
setShow={setShowRemove}
>
Are you sure you want to remove the image?
</ConfirmDialog>
{settings.images && !newImage && (
<Button
style={{marginBottom: MARGIN}}
style={{ marginBottom: MARGIN }}
onPress={changeImage}
icon="add-photo-alternate">
icon='add-photo-alternate'
>
Image
</Button>
)}
</View>
<Button
mode="contained"
icon="save"
style={{margin: MARGIN}}
onPress={handleSubmit}>
mode='contained'
icon='save'
style={{ margin: MARGIN }}
onPress={handleSubmit}
>
Save
</Button>
</>

View File

@ -4,21 +4,21 @@ import {
useNavigation,
useRoute,
} from '@react-navigation/native'
import {useCallback, useRef, useState} from 'react'
import {ScrollView, TextInput, View} from 'react-native'
import { useCallback, useRef, useState } from 'react'
import { ScrollView, TextInput, View } from 'react-native'
import DocumentPicker from 'react-native-document-picker'
import {Button, Card, TouchableRipple} from 'react-native-paper'
import { Button, Card, TouchableRipple } from 'react-native-paper'
import AppInput from './AppInput'
import ConfirmDialog from './ConfirmDialog'
import {MARGIN, PADDING} from './constants'
import {getNow, planRepo, setRepo, settingsRepo} from './db'
import {defaultSet} from './gym-set'
import { MARGIN, PADDING } from './constants'
import { getNow, planRepo, setRepo, settingsRepo } from './db'
import { defaultSet } from './gym-set'
import Settings from './settings'
import StackHeader from './StackHeader'
import {WorkoutsPageParams} from './WorkoutsPage'
import { WorkoutsPageParams } from './WorkoutsPage'
export default function EditWorkout() {
const {params} = useRoute<RouteProp<WorkoutsPageParams, 'EditWorkout'>>()
const { params } = useRoute<RouteProp<WorkoutsPageParams, 'EditWorkout'>>()
const [removeImage, setRemoveImage] = useState(false)
const [showRemove, setShowRemove] = useState(false)
const [name, setName] = useState(params.value.name)
@ -40,13 +40,13 @@ export default function EditWorkout() {
useFocusEffect(
useCallback(() => {
settingsRepo.findOne({where: {}}).then(setSettings)
settingsRepo.findOne({ where: {} }).then(setSettings)
}, []),
)
const update = async () => {
await setRepo.update(
{name: params.value.name},
{ name: params.value.name },
{
name: name || params.value.name,
sets: Number(sets),
@ -87,7 +87,7 @@ export default function EditWorkout() {
}
const changeImage = useCallback(async () => {
const {fileCopyUri} = await DocumentPicker.pickSingle({
const { fileCopyUri } = await DocumentPicker.pickSingle({
type: DocumentPicker.types.images,
copyTo: 'documentDirectory',
})
@ -108,11 +108,11 @@ export default function EditWorkout() {
return (
<>
<StackHeader title={params.value.name ? 'Edit workout' : 'Add workout'} />
<View style={{padding: PADDING, flex: 1}}>
<ScrollView style={{flex: 1}}>
<View style={{ padding: PADDING, flex: 1 }}>
<ScrollView style={{ flex: 1 }}>
<AppInput
autoFocus
label="Name"
label='Name'
value={name}
onChangeText={setName}
onSubmitEditing={submitName}
@ -123,7 +123,7 @@ export default function EditWorkout() {
selectTextOnFocus={false}
value={steps}
onChangeText={setSteps}
label="Steps"
label='Steps'
multiline
onSubmitEditing={() => setsRef.current?.focus()}
/>
@ -132,8 +132,8 @@ export default function EditWorkout() {
innerRef={setsRef}
value={sets}
onChangeText={setSets}
label="Sets per workout"
keyboardType="numeric"
label='Sets per workout'
keyboardType='numeric'
onSubmitEditing={() => minutesRef.current?.focus()}
/>
{settings?.alarm && (
@ -143,44 +143,47 @@ export default function EditWorkout() {
onSubmitEditing={() => secondsRef.current?.focus()}
value={minutes}
onChangeText={setMinutes}
label="Rest minutes"
keyboardType="numeric"
label='Rest minutes'
keyboardType='numeric'
/>
<AppInput
innerRef={secondsRef}
value={seconds}
onChangeText={setSeconds}
label="Rest seconds"
keyboardType="numeric"
label='Rest seconds'
keyboardType='numeric'
blurOnSubmit
/>
</>
)}
{settings?.images && uri && (
<TouchableRipple
style={{marginBottom: MARGIN}}
style={{ marginBottom: MARGIN }}
onPress={changeImage}
onLongPress={() => setShowRemove(true)}>
<Card.Cover source={{uri}} />
onLongPress={() => setShowRemove(true)}
>
<Card.Cover source={{ uri }} />
</TouchableRipple>
)}
{settings?.images && !uri && (
<Button
style={{marginBottom: MARGIN}}
style={{ marginBottom: MARGIN }}
onPress={changeImage}
icon="add-photo-alternate">
icon='add-photo-alternate'
>
Image
</Button>
)}
</ScrollView>
<Button disabled={!name} mode="contained" icon="save" onPress={save}>
<Button disabled={!name} mode='contained' icon='save' onPress={save}>
Save
</Button>
<ConfirmDialog
title="Remove image"
title='Remove image'
onOk={handleRemove}
show={showRemove}
setShow={setShowRemove}>
setShow={setShowRemove}
>
Are you sure you want to remove the image?
</ConfirmDialog>
</View>

View File

@ -1,7 +1,7 @@
import {createStackNavigator} from '@react-navigation/stack'
import { createStackNavigator } from '@react-navigation/stack'
import EditSet from './EditSet'
import EditSets from './EditSets'
import {HomePageParams} from './home-page-params'
import { HomePageParams } from './home-page-params'
import SetList from './SetList'
const Stack = createStackNavigator<HomePageParams>()
@ -9,10 +9,11 @@ const Stack = createStackNavigator<HomePageParams>()
export default function HomePage() {
return (
<Stack.Navigator
screenOptions={{headerShown: false, animationEnabled: false}}>
<Stack.Screen name="Sets" component={SetList} />
<Stack.Screen name="EditSet" component={EditSet} />
<Stack.Screen name="EditSets" component={EditSets} />
screenOptions={{ headerShown: false, animationEnabled: false }}
>
<Stack.Screen name='Sets' component={SetList} />
<Stack.Screen name='EditSet' component={EditSet} />
<Stack.Screen name='EditSets' component={EditSets} />
</Stack.Navigator>
)
}

View File

@ -1,5 +1,5 @@
import {useState} from 'react'
import {Divider, IconButton, Menu} from 'react-native-paper'
import { useState } from 'react'
import { Divider, IconButton, Menu } from 'react-native-paper'
import ConfirmDialog from './ConfirmDialog'
import useDark from './use-dark'
@ -55,45 +55,45 @@ export default function ListMenu({
<IconButton
color={dark ? 'white' : 'white'}
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
icon="clear"
title="Clear"
icon='clear'
title='Clear'
onPress={clear}
disabled={ids?.length === 0}
/>
<Menu.Item
icon="edit"
title="Edit"
icon='edit'
title='Edit'
onPress={edit}
disabled={ids?.length === 0}
/>
<Menu.Item
icon="content-copy"
title="Copy"
icon='content-copy'
title='Copy'
onPress={copy}
disabled={ids?.length === 0}
/>
<Divider />
<Menu.Item
icon="delete"
icon='delete'
onPress={() => setShowRemove(true)}
title="Delete"
title='Delete'
/>
<ConfirmDialog
title={ids?.length === 0 ? 'Delete all' : 'Delete selected'}
show={showRemove}
setShow={setShowRemove}
onOk={remove}
onCancel={() => setShowMenu(false)}>
{ids?.length === 0 ? (
<>This irreversibly deletes records from the app. Are you sure?</>
) : (
<>This will delete {ids?.length} record(s). Are you sure?</>
)}
onCancel={() => setShowMenu(false)}
>
{ids?.length === 0
? <>This irreversibly deletes records from the app. Are you sure?</>
: <>This will delete {ids?.length} record(s). Are you sure?</>}
</ConfirmDialog>
</Menu>
)

View File

@ -1,7 +1,7 @@
import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
import {Searchbar} from 'react-native-paper'
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'
import { Searchbar } from 'react-native-paper'
import AppFab from './AppFab'
import {PADDING} from './constants'
import { PADDING } from './constants'
export default function Page({
onAdd,
@ -19,11 +19,11 @@ export default function Page({
return (
<View style={[styles.view, style]}>
<Searchbar
placeholder="Search"
placeholder='Search'
value={term}
onChangeText={search}
icon="search"
clearIcon="clear"
icon='search'
clearIcon='clear'
/>
{children}
{onAdd && <AppFab onPress={onAdd} />}

View File

@ -3,15 +3,15 @@ import {
useFocusEffect,
useNavigation,
} from '@react-navigation/native'
import {useCallback, useMemo, useState} from 'react'
import {Text} from 'react-native'
import {List} from 'react-native-paper'
import {getLast} from './best.service'
import {DARK_RIPPLE, LIGHT_RIPPLE} from './constants'
import {defaultSet} from './gym-set'
import {Plan} from './plan'
import {PlanPageParams} from './plan-page-params'
import {DAYS} from './time'
import { useCallback, useMemo, useState } from 'react'
import { Text } from 'react-native'
import { List } from 'react-native-paper'
import { getLast } from './best.service'
import { DARK_RIPPLE, LIGHT_RIPPLE } from './constants'
import { defaultSet } from './gym-set'
import { Plan } from './plan'
import { PlanPageParams } from './plan-page-params'
import { DAYS } from './time'
import useDark from './use-dark'
export default function PlanItem({
@ -38,12 +38,13 @@ export default function PlanItem({
const start = useCallback(async () => {
const workout = item.workouts.split(',')[0]
let first = await getLast(workout)
if (!first) first = {...defaultSet, name: workout}
if (!first) first = { ...defaultSet, name: workout }
delete first.id
if (ids.length === 0)
return navigation.navigate('StartPlan', {plan: item, first})
const removing = ids.find(id => id === item.id)
if (removing) setIds(ids.filter(id => id !== item.id))
if (ids.length === 0) {
return navigation.navigate('StartPlan', { plan: item, first })
}
const removing = ids.find((id) => id === item.id)
if (removing