Remove csv import/export
This is replaced with the backup/restore feature in Settings page. - Not sure anybody is using this besides me for testing purposes - Backing up the entire SQLite database is faster than CSV conversion - This prevents missing data and will work nicely with future plan changes Closes #128
This commit is contained in:
parent
0b2d4d52e1
commit
533b21a907
124
DrawerMenu.tsx
124
DrawerMenu.tsx
|
@ -1,21 +1,11 @@
|
|||
import {NavigationProp, useNavigation} from '@react-navigation/native'
|
||||
import {useCallback, useState} from 'react'
|
||||
import DocumentPicker from 'react-native-document-picker'
|
||||
import {FileSystem} from 'react-native-file-access'
|
||||
import {Divider, IconButton, Menu} from 'react-native-paper'
|
||||
import {IconButton, Menu} from 'react-native-paper'
|
||||
import ConfirmDialog from './ConfirmDialog'
|
||||
import {AppDataSource} from './data-source'
|
||||
import {planRepo} from './db'
|
||||
import {planRepo, setRepo} from './db'
|
||||
import {DrawerParamList} from './drawer-param-list'
|
||||
import GymSet from './gym-set'
|
||||
import {Plan} from './plan'
|
||||
import {toast} from './toast'
|
||||
import useDark from './use-dark'
|
||||
import {write} from './write'
|
||||
|
||||
const setFields = 'id,name,reps,weight,created,unit,hidden,sets,minutes,seconds'
|
||||
const planFields = 'id,days,workouts'
|
||||
const setRepo = AppDataSource.manager.getRepository(GymSet)
|
||||
|
||||
export default function DrawerMenu({name}: {name: keyof DrawerParamList}) {
|
||||
const [showMenu, setShowMenu] = useState(false)
|
||||
|
@ -23,113 +13,6 @@ export default function DrawerMenu({name}: {name: keyof DrawerParamList}) {
|
|||
const {reset} = useNavigation<NavigationProp<DrawerParamList>>()
|
||||
const dark = useDark()
|
||||
|
||||
const exportSets = useCallback(async () => {
|
||||
const sets = await setRepo.find({})
|
||||
const data = [setFields]
|
||||
.concat(
|
||||
sets.map(set =>
|
||||
setFields
|
||||
.split(',')
|
||||
.map(fieldString => {
|
||||
const field = fieldString as keyof GymSet
|
||||
if (field === 'unit') return set[field] || 'kg'
|
||||
return set[field]
|
||||
})
|
||||
.join(','),
|
||||
),
|
||||
)
|
||||
.join('\n')
|
||||
console.log(`${DrawerMenu.name}.exportSets`, {length: sets.length})
|
||||
await write('sets.csv', data)
|
||||
}, [])
|
||||
|
||||
const exportPlans = useCallback(async () => {
|
||||
const plans = await planRepo.find({})
|
||||
const data = [planFields]
|
||||
.concat(plans.map(set => `"${set.id}","${set.days}","${set.workouts}"`))
|
||||
.join('\n')
|
||||
console.log(`${DrawerMenu.name}.exportPlans`, {length: plans.length})
|
||||
await write('plans.csv', data)
|
||||
}, [])
|
||||
|
||||
const download = useCallback(async () => {
|
||||
setShowMenu(false)
|
||||
if (name === 'Home') exportSets()
|
||||
else if (name === 'Plans') exportPlans()
|
||||
}, [name, exportSets, exportPlans])
|
||||
|
||||
const uploadSets = useCallback(async () => {
|
||||
const result = await DocumentPicker.pickSingle()
|
||||
const file = await FileSystem.readFile(result.uri)
|
||||
console.log(`${DrawerMenu.name}.uploadSets:`, file.length)
|
||||
const lines = file.split('\n')
|
||||
if (!setFields.includes(lines[0])) return toast('Invalid csv.')
|
||||
const values = lines
|
||||
.slice(1)
|
||||
.filter(line => line)
|
||||
.map(line => {
|
||||
let [
|
||||
,
|
||||
setName,
|
||||
reps,
|
||||
weight,
|
||||
created,
|
||||
unit,
|
||||
hidden,
|
||||
sets,
|
||||
minutes,
|
||||
seconds,
|
||||
] = line.split(',')
|
||||
const set: GymSet = {
|
||||
name: setName,
|
||||
reps: +reps,
|
||||
weight: +weight,
|
||||
created,
|
||||
unit: unit ?? 'kg',
|
||||
hidden: !!Number(hidden),
|
||||
sets: +sets,
|
||||
minutes: +minutes,
|
||||
seconds: +seconds,
|
||||
image: '',
|
||||
}
|
||||
return set
|
||||
})
|
||||
await setRepo.insert(values)
|
||||
toast('Data imported.')
|
||||
reset({index: 0, routes: [{name}]})
|
||||
}, [reset, name])
|
||||
|
||||
const uploadPlans = useCallback(async () => {
|
||||
const result = await DocumentPicker.pickSingle()
|
||||
const file = await FileSystem.readFile(result.uri)
|
||||
console.log(`${DrawerMenu.name}.uploadPlans:`, file.length)
|
||||
const lines = file.split('\n')
|
||||
if (lines[0] !== planFields) return toast('Invalid csv.')
|
||||
const values = file
|
||||
.split('\n')
|
||||
.slice(1)
|
||||
.filter(line => line)
|
||||
.map(set => {
|
||||
const [, days, workouts] = set
|
||||
.split('","')
|
||||
.map(cell => cell.replace(/"/g, ''))
|
||||
const plan: Plan = {
|
||||
days,
|
||||
workouts,
|
||||
}
|
||||
return plan
|
||||
})
|
||||
await planRepo.insert(values)
|
||||
toast('Data imported.')
|
||||
}, [])
|
||||
|
||||
const upload = useCallback(async () => {
|
||||
setShowMenu(false)
|
||||
if (name === 'Home') await uploadSets()
|
||||
else if (name === 'Plans') await uploadPlans()
|
||||
reset({index: 0, routes: [{name}]})
|
||||
}, [name, uploadPlans, uploadSets, reset])
|
||||
|
||||
const remove = useCallback(async () => {
|
||||
setShowMenu(false)
|
||||
setShowRemove(false)
|
||||
|
@ -151,9 +34,6 @@ export default function DrawerMenu({name}: {name: keyof DrawerParamList}) {
|
|||
icon="more-vert"
|
||||
/>
|
||||
}>
|
||||
<Menu.Item icon="arrow-downward" onPress={download} title="Download" />
|
||||
<Menu.Item icon="arrow-upward" onPress={upload} title="Upload" />
|
||||
<Divider />
|
||||
<Menu.Item
|
||||
icon="delete"
|
||||
onPress={() => setShowRemove(true)}
|
||||
|
|
16
EditSet.tsx
16
EditSet.tsx
|
@ -99,18 +99,6 @@ export default function EditSet() {
|
|||
navigation.goBack()
|
||||
}
|
||||
|
||||
const handleName = useCallback((value: string) => {
|
||||
setName(value.replace(/,|'/g, ''))
|
||||
if (value.match(/,|'/))
|
||||
toast('Commas and single quotes would break CSV exports')
|
||||
}, [])
|
||||
|
||||
const handleUnit = useCallback((value: string) => {
|
||||
setUnit(value.replace(/,|'/g, ''))
|
||||
if (value.match(/,|'/))
|
||||
toast('Commas and single quotes would break CSV exports')
|
||||
}, [])
|
||||
|
||||
const changeImage = useCallback(async () => {
|
||||
const {fileCopyUri} = await DocumentPicker.pickSingle({
|
||||
type: DocumentPicker.types.images,
|
||||
|
@ -133,7 +121,7 @@ export default function EditSet() {
|
|||
<MassiveInput
|
||||
label="Name"
|
||||
value={name}
|
||||
onChangeText={handleName}
|
||||
onChangeText={setName}
|
||||
autoCorrect={false}
|
||||
autoFocus={!name}
|
||||
onSubmitEditing={() => repsRef.current?.focus()}
|
||||
|
@ -165,7 +153,7 @@ export default function EditSet() {
|
|||
autoCapitalize="none"
|
||||
label="Unit"
|
||||
value={unit}
|
||||
onChangeText={handleUnit}
|
||||
onChangeText={setUnit}
|
||||
innerRef={unitRef}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -15,7 +15,6 @@ import {defaultSet} from './gym-set'
|
|||
import MassiveInput from './MassiveInput'
|
||||
import Settings from './settings'
|
||||
import StackHeader from './StackHeader'
|
||||
import {toast} from './toast'
|
||||
import {WorkoutsPageParams} from './WorkoutsPage'
|
||||
|
||||
export default function EditWorkout() {
|
||||
|
@ -101,18 +100,6 @@ export default function EditWorkout() {
|
|||
setShowRemove(false)
|
||||
}, [])
|
||||
|
||||
const handleName = (value: string) => {
|
||||
setName(value.replace(/,|'/g, ''))
|
||||
if (value.match(/,|'/))
|
||||
toast('Commas and single quotes would break CSV exports')
|
||||
}
|
||||
|
||||
const handleSteps = (value: string) => {
|
||||
setSteps(value.replace(/,|'/g, ''))
|
||||
if (value.match(/,|'/))
|
||||
toast('Commas and single quotes would break CSV exports')
|
||||
}
|
||||
|
||||
const submitName = () => {
|
||||
if (settings.steps) stepsRef.current?.focus()
|
||||
else setsRef.current?.focus()
|
||||
|
@ -127,7 +114,7 @@ export default function EditWorkout() {
|
|||
autoFocus
|
||||
label="Name"
|
||||
value={name}
|
||||
onChangeText={handleName}
|
||||
onChangeText={setName}
|
||||
onSubmitEditing={submitName}
|
||||
/>
|
||||
{settings?.steps && (
|
||||
|
@ -135,7 +122,7 @@ export default function EditWorkout() {
|
|||
innerRef={stepsRef}
|
||||
selectTextOnFocus={false}
|
||||
value={steps}
|
||||
onChangeText={handleSteps}
|
||||
onChangeText={setSteps}
|
||||
label="Steps"
|
||||
multiline
|
||||
onSubmitEditing={() => setsRef.current?.focus()}
|
||||
|
|
|
@ -111,12 +111,6 @@ export default function StartPlan() {
|
|||
NativeModules.AlarmModule.timer(...args)
|
||||
}
|
||||
|
||||
const handleUnit = useCallback((value: string) => {
|
||||
setUnit(value.replace(/,|'/g, ''))
|
||||
if (value.match(/,|'/))
|
||||
toast('Commas and single quotes would break CSV exports')
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<StackHeader title={params.plan.days.replace(/,/g, ', ')} />
|
||||
|
@ -146,7 +140,7 @@ export default function StartPlan() {
|
|||
autoCapitalize="none"
|
||||
label="Unit"
|
||||
value={unit}
|
||||
onChangeText={handleUnit}
|
||||
onChangeText={setUnit}
|
||||
innerRef={unitRef}
|
||||
/>
|
||||
)}
|
||||
|
|
Loading…
Reference in New Issue
Block a user