Ensure only one connection to SQLite exists
This commit is contained in:
parent
ecb436f8a6
commit
570b43715f
22
App.tsx
22
App.tsx
|
@ -1,19 +1,20 @@
|
||||||
import {useAsyncStorage} from '@react-native-async-storage/async-storage';
|
import {useAsyncStorage} from '@react-native-async-storage/async-storage';
|
||||||
import Ionicon from 'react-native-vector-icons/Ionicons';
|
|
||||||
import {createMaterialTopTabNavigator} from '@react-navigation/material-top-tabs';
|
import {createMaterialTopTabNavigator} from '@react-navigation/material-top-tabs';
|
||||||
import {
|
import {
|
||||||
DarkTheme,
|
DarkTheme,
|
||||||
DefaultTheme,
|
DefaultTheme,
|
||||||
NavigationContainer,
|
NavigationContainer,
|
||||||
} from '@react-navigation/native';
|
} from '@react-navigation/native';
|
||||||
import React, {useEffect} from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import {StatusBar, useColorScheme} from 'react-native';
|
import {StatusBar, useColorScheme} from 'react-native';
|
||||||
import {
|
import {
|
||||||
DarkTheme as DarkThemePaper,
|
DarkTheme as DarkThemePaper,
|
||||||
DefaultTheme as DefaultThemePaper,
|
DefaultTheme as DefaultThemePaper,
|
||||||
Provider,
|
Provider,
|
||||||
} from 'react-native-paper';
|
} from 'react-native-paper';
|
||||||
import {setupSchema} from './db';
|
import {SQLiteDatabase} from 'react-native-sqlite-storage';
|
||||||
|
import Ionicon from 'react-native-vector-icons/Ionicons';
|
||||||
|
import {createPlans, createSets, getDb} from './db';
|
||||||
import Exercises from './Exercises';
|
import Exercises from './Exercises';
|
||||||
import Home from './Home';
|
import Home from './Home';
|
||||||
import Plans from './Plans';
|
import Plans from './Plans';
|
||||||
|
@ -27,16 +28,21 @@ export type RootStackParamList = {
|
||||||
Plans: {};
|
Plans: {};
|
||||||
};
|
};
|
||||||
|
|
||||||
setupSchema();
|
export const DatabaseContext = React.createContext<SQLiteDatabase>({} as any);
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
|
const [db, setDb] = useState<SQLiteDatabase | null>(null);
|
||||||
const dark = useColorScheme() === 'dark';
|
const dark = useColorScheme() === 'dark';
|
||||||
const {getItem: getMinutes, setItem: setMinutes} = useAsyncStorage('minutes');
|
const {getItem: getMinutes, setItem: setMinutes} = useAsyncStorage('minutes');
|
||||||
const {getItem: getSeconds, setItem: setSeconds} = useAsyncStorage('seconds');
|
const {getItem: getSeconds, setItem: setSeconds} = useAsyncStorage('seconds');
|
||||||
const {getItem: getAlarmEnabled, setItem: setAlarmEnabled} =
|
const {getItem: getAlarmEnabled, setItem: setAlarmEnabled} =
|
||||||
useAsyncStorage('alarmEnabled');
|
useAsyncStorage('alarmEnabled');
|
||||||
|
|
||||||
const defaults = async () => {
|
const init = async () => {
|
||||||
|
const gotDb = await getDb();
|
||||||
|
await gotDb.executeSql(createPlans);
|
||||||
|
await gotDb.executeSql(createSets);
|
||||||
|
setDb(gotDb);
|
||||||
const minutes = await getMinutes();
|
const minutes = await getMinutes();
|
||||||
if (minutes === null) await setMinutes('3');
|
if (minutes === null) await setMinutes('3');
|
||||||
const seconds = await getSeconds();
|
const seconds = await getSeconds();
|
||||||
|
@ -46,7 +52,7 @@ const App = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
defaults();
|
init();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -55,12 +61,16 @@ const App = () => {
|
||||||
settings={{icon: props => <Ionicon {...props} />}}>
|
settings={{icon: props => <Ionicon {...props} />}}>
|
||||||
<NavigationContainer theme={dark ? DarkTheme : DefaultTheme}>
|
<NavigationContainer theme={dark ? DarkTheme : DefaultTheme}>
|
||||||
<StatusBar barStyle={dark ? 'light-content' : 'dark-content'} />
|
<StatusBar barStyle={dark ? 'light-content' : 'dark-content'} />
|
||||||
|
{db && (
|
||||||
|
<DatabaseContext.Provider value={db}>
|
||||||
<Tab.Navigator>
|
<Tab.Navigator>
|
||||||
<Tab.Screen name="Home" component={Home} />
|
<Tab.Screen name="Home" component={Home} />
|
||||||
<Tab.Screen name="Plans" component={Plans} />
|
<Tab.Screen name="Plans" component={Plans} />
|
||||||
<Tab.Screen name="Exercises" component={Exercises} />
|
<Tab.Screen name="Exercises" component={Exercises} />
|
||||||
<Tab.Screen name="Settings" component={Settings} />
|
<Tab.Screen name="Settings" component={Settings} />
|
||||||
</Tab.Navigator>
|
</Tab.Navigator>
|
||||||
|
</DatabaseContext.Provider>
|
||||||
|
)}
|
||||||
</NavigationContainer>
|
</NavigationContainer>
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
|
|
23
EditPlan.tsx
23
EditPlan.tsx
|
@ -1,10 +1,9 @@
|
||||||
import React, {useEffect, useState} from 'react';
|
import React, {useContext, useEffect, useState} from 'react';
|
||||||
import {StyleSheet, Text, View} from 'react-native';
|
import {Button, Dialog, Portal} from 'react-native-paper';
|
||||||
import {Button, Dialog, Modal, Portal, TextInput} from 'react-native-paper';
|
import {DatabaseContext} from './App';
|
||||||
import DayMenu from './DayMenu';
|
import DayMenu from './DayMenu';
|
||||||
import WorkoutMenu from './WorkoutMenu';
|
|
||||||
import {getDb} from './db';
|
|
||||||
import {Plan} from './plan';
|
import {Plan} from './plan';
|
||||||
|
import WorkoutMenu from './WorkoutMenu';
|
||||||
|
|
||||||
export default function EditPlan({
|
export default function EditPlan({
|
||||||
id,
|
id,
|
||||||
|
@ -22,12 +21,10 @@ export default function EditPlan({
|
||||||
const [days, setDays] = useState('');
|
const [days, setDays] = useState('');
|
||||||
const [workouts, setWorkouts] = useState('');
|
const [workouts, setWorkouts] = useState('');
|
||||||
const [names, setNames] = useState<string[]>([]);
|
const [names, setNames] = useState<string[]>([]);
|
||||||
|
const db = useContext(DatabaseContext);
|
||||||
|
|
||||||
useEffect(() => {
|
const refresh = async () => {
|
||||||
getDb().then(async db => {
|
const [namesResult] = await db.executeSql('SELECT DISTINCT name FROM sets');
|
||||||
const [namesResult] = await db.executeSql(
|
|
||||||
'SELECT DISTINCT name FROM sets',
|
|
||||||
);
|
|
||||||
if (!namesResult.rows.length) return;
|
if (!namesResult.rows.length) return;
|
||||||
setNames(namesResult.rows.raw().map(({name}) => name));
|
setNames(namesResult.rows.raw().map(({name}) => name));
|
||||||
if (!id) return;
|
if (!id) return;
|
||||||
|
@ -38,12 +35,14 @@ export default function EditPlan({
|
||||||
const set: Plan = result.rows.item(0);
|
const set: Plan = result.rows.item(0);
|
||||||
setDays(set.days);
|
setDays(set.days);
|
||||||
setWorkouts(set.workouts);
|
setWorkouts(set.workouts);
|
||||||
});
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
refresh();
|
||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
if (!days || !workouts) return;
|
if (!days || !workouts) return;
|
||||||
const db = await getDb();
|
|
||||||
if (!id)
|
if (!id)
|
||||||
await db.executeSql(`INSERT INTO plans(days, workouts) VALUES (?, ?)`, [
|
await db.executeSql(`INSERT INTO plans(days, workouts) VALUES (?, ?)`, [
|
||||||
days,
|
days,
|
||||||
|
|
41
EditSet.tsx
41
EditSet.tsx
|
@ -1,22 +1,20 @@
|
||||||
import React, {useEffect, useRef, useState} from 'react';
|
|
||||||
import {StyleSheet, Text, View} from 'react-native';
|
|
||||||
import {Button, Dialog, Modal, Portal, TextInput} from 'react-native-paper';
|
|
||||||
import {getDb} from './db';
|
|
||||||
import Set from './set';
|
|
||||||
import {format} from 'date-fns';
|
import {format} from 'date-fns';
|
||||||
|
import React, {useContext, useEffect, useRef, useState} from 'react';
|
||||||
|
import {StyleSheet, Text} from 'react-native';
|
||||||
|
import {Button, Dialog, Portal, TextInput} from 'react-native-paper';
|
||||||
|
import {DatabaseContext} from './App';
|
||||||
|
import Set from './set';
|
||||||
|
|
||||||
export default function EditSet({
|
export default function EditSet({
|
||||||
id,
|
|
||||||
onSave,
|
onSave,
|
||||||
show,
|
show,
|
||||||
setShow,
|
setShow,
|
||||||
clearId,
|
set,
|
||||||
}: {
|
}: {
|
||||||
id?: number;
|
|
||||||
clearId: () => void;
|
|
||||||
onSave: () => void;
|
onSave: () => void;
|
||||||
show: boolean;
|
show: boolean;
|
||||||
setShow: (visible: boolean) => void;
|
setShow: (visible: boolean) => void;
|
||||||
|
set?: Set;
|
||||||
}) {
|
}) {
|
||||||
const [name, setName] = useState('');
|
const [name, setName] = useState('');
|
||||||
const [reps, setReps] = useState('');
|
const [reps, setReps] = useState('');
|
||||||
|
@ -26,27 +24,24 @@ export default function EditSet({
|
||||||
const weightRef = useRef<any>(null);
|
const weightRef = useRef<any>(null);
|
||||||
const repsRef = useRef<any>(null);
|
const repsRef = useRef<any>(null);
|
||||||
const unitRef = useRef<any>(null);
|
const unitRef = useRef<any>(null);
|
||||||
|
const db = useContext(DatabaseContext);
|
||||||
|
|
||||||
useEffect(() => {
|
const refresh = async () => {
|
||||||
if (!id) return setCreated(new Date(new Date().toUTCString()));
|
if (!set) return setCreated(new Date(new Date().toUTCString()));
|
||||||
getDb().then(async db => {
|
|
||||||
const [result] = await db.executeSql(`SELECT * FROM sets WHERE id = ?`, [
|
|
||||||
id,
|
|
||||||
]);
|
|
||||||
if (!result.rows.item(0)) throw new Error("Can't find specified Set.");
|
|
||||||
const set: Set = result.rows.item(0);
|
|
||||||
setName(set.name);
|
setName(set.name);
|
||||||
setReps(set.reps.toString());
|
setReps(set.reps.toString());
|
||||||
setWeight(set.weight.toString());
|
setWeight(set.weight.toString());
|
||||||
setUnit(set.unit);
|
setUnit(set.unit);
|
||||||
setCreated(new Date(set.created));
|
setCreated(new Date(set.created));
|
||||||
});
|
};
|
||||||
}, [id]);
|
|
||||||
|
useEffect(() => {
|
||||||
|
refresh();
|
||||||
|
}, [set]);
|
||||||
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
if (!name || !reps || !weight) return;
|
if (!name || !reps || !weight) return;
|
||||||
const db = await getDb();
|
if (!set)
|
||||||
if (!id)
|
|
||||||
await db.executeSql(
|
await db.executeSql(
|
||||||
`INSERT INTO sets(name, reps, weight, created, unit) VALUES (?,?,?,?,?)`,
|
`INSERT INTO sets(name, reps, weight, created, unit) VALUES (?,?,?,?,?)`,
|
||||||
[name, reps, weight, new Date().toISOString(), unit || 'kg'],
|
[name, reps, weight, new Date().toISOString(), unit || 'kg'],
|
||||||
|
@ -54,7 +49,7 @@ export default function EditSet({
|
||||||
else
|
else
|
||||||
await db.executeSql(
|
await db.executeSql(
|
||||||
`UPDATE sets SET name = ?, reps = ?, weight = ?, unit = ? WHERE id = ?`,
|
`UPDATE sets SET name = ?, reps = ?, weight = ?, unit = ? WHERE id = ?`,
|
||||||
[name, reps, weight, unit, id],
|
[name, reps, weight, unit, set.id],
|
||||||
);
|
);
|
||||||
setShow(false);
|
setShow(false);
|
||||||
onSave();
|
onSave();
|
||||||
|
@ -63,7 +58,7 @@ export default function EditSet({
|
||||||
return (
|
return (
|
||||||
<Portal>
|
<Portal>
|
||||||
<Dialog visible={show} onDismiss={() => setShow(false)}>
|
<Dialog visible={show} onDismiss={() => setShow(false)}>
|
||||||
<Dialog.Title>{id ? `Edit "${name}"` : 'Add a set'}</Dialog.Title>
|
<Dialog.Title>{set?.id ? `Edit "${name}"` : 'Add a set'}</Dialog.Title>
|
||||||
<Dialog.Content>
|
<Dialog.Content>
|
||||||
<TextInput
|
<TextInput
|
||||||
style={styles.text}
|
style={styles.text}
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
import {useFocusEffect} from '@react-navigation/native';
|
import {useFocusEffect} from '@react-navigation/native';
|
||||||
import {NativeStackScreenProps} from '@react-navigation/native-stack';
|
import React, {useContext, useEffect, useState} from 'react';
|
||||||
import React, {useEffect, useState} from 'react';
|
|
||||||
import {FlatList, StyleSheet, View} from 'react-native';
|
import {FlatList, StyleSheet, View} from 'react-native';
|
||||||
import {List, Searchbar, TextInput} from 'react-native-paper';
|
import {List, Searchbar} from 'react-native-paper';
|
||||||
import {RootStackParamList} from './App';
|
import {DatabaseContext} from './App';
|
||||||
import {getDb} from './db';
|
|
||||||
import Exercise from './exercise';
|
import Exercise from './exercise';
|
||||||
|
|
||||||
export default function Exercises() {
|
export default function Exercises() {
|
||||||
const [exercises, setExercises] = useState<Exercise[]>([]);
|
const [exercises, setExercises] = useState<Exercise[]>([]);
|
||||||
const [search, setSearch] = useState('');
|
const [search, setSearch] = useState('');
|
||||||
const [refreshing, setRefresing] = useState(false);
|
const [refreshing, setRefresing] = useState(false);
|
||||||
|
const db = useContext(DatabaseContext);
|
||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
const db = await getDb();
|
|
||||||
const [result] = await db.executeSql(
|
const [result] = await db.executeSql(
|
||||||
`SELECT name, reps, unit, MAX(weight) AS weight
|
`SELECT name, reps, unit, MAX(weight) AS weight
|
||||||
FROM sets
|
FROM sets
|
||||||
|
|
41
Home.tsx
41
Home.tsx
|
@ -1,9 +1,9 @@
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
import {useFocusEffect} from '@react-navigation/native';
|
import {useFocusEffect} from '@react-navigation/native';
|
||||||
import React, {useEffect, useState} from 'react';
|
import React, {useContext, useEffect, useState} from 'react';
|
||||||
import {FlatList, NativeModules, SafeAreaView, StyleSheet} from 'react-native';
|
import {FlatList, NativeModules, SafeAreaView, StyleSheet} from 'react-native';
|
||||||
import {AnimatedFAB, Searchbar} from 'react-native-paper';
|
import {AnimatedFAB, Searchbar} from 'react-native-paper';
|
||||||
import {getSets} from './db';
|
import {DatabaseContext} from './App';
|
||||||
import EditSet from './EditSet';
|
import EditSet from './EditSet';
|
||||||
|
|
||||||
import Set from './set';
|
import Set from './set';
|
||||||
|
@ -13,11 +13,28 @@ const limit = 20;
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const [sets, setSets] = useState<Set[]>();
|
const [sets, setSets] = useState<Set[]>();
|
||||||
const [id, setId] = useState<number>();
|
|
||||||
const [offset, setOffset] = useState(0);
|
const [offset, setOffset] = useState(0);
|
||||||
const [showEdit, setShowEdit] = useState(false);
|
const [edit, setEdit] = useState<Set>();
|
||||||
|
const [show, setShow] = useState(false);
|
||||||
const [search, setSearch] = useState('');
|
const [search, setSearch] = useState('');
|
||||||
const [refreshing, setRefresing] = useState(false);
|
const [refreshing, setRefresing] = useState(false);
|
||||||
|
const db = useContext(DatabaseContext);
|
||||||
|
|
||||||
|
const selectSets = `
|
||||||
|
SELECT * from sets
|
||||||
|
WHERE name LIKE ?
|
||||||
|
ORDER BY created DESC
|
||||||
|
LIMIT ? OFFSET ?
|
||||||
|
`;
|
||||||
|
const getSets = ({
|
||||||
|
search,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
}: {
|
||||||
|
search: string;
|
||||||
|
limit: number;
|
||||||
|
offset: number;
|
||||||
|
}) => db.executeSql(selectSets, [`%${search}%`, limit, offset]);
|
||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
const [result] = await getSets({search, limit, offset: 0});
|
const [result] = await getSets({search, limit, offset: 0});
|
||||||
|
@ -43,8 +60,8 @@ export default function Home() {
|
||||||
<SetItem
|
<SetItem
|
||||||
item={item}
|
item={item}
|
||||||
key={item.id}
|
key={item.id}
|
||||||
setShowEdit={setShowEdit}
|
setShowEdit={setShow}
|
||||||
setId={setId}
|
setSet={setEdit}
|
||||||
onRemove={refresh}
|
onRemove={refresh}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -82,13 +99,7 @@ export default function Home() {
|
||||||
refreshing={refreshing}
|
refreshing={refreshing}
|
||||||
onRefresh={refreshLoader}
|
onRefresh={refreshLoader}
|
||||||
/>
|
/>
|
||||||
<EditSet
|
<EditSet set={edit} show={show} setShow={setShow} onSave={save} />
|
||||||
clearId={() => setId(undefined)}
|
|
||||||
id={id}
|
|
||||||
show={showEdit}
|
|
||||||
setShow={setShowEdit}
|
|
||||||
onSave={save}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<AnimatedFAB
|
<AnimatedFAB
|
||||||
extended={false}
|
extended={false}
|
||||||
|
@ -96,8 +107,8 @@ export default function Home() {
|
||||||
icon="add"
|
icon="add"
|
||||||
style={{position: 'absolute', right: 20, bottom: 20}}
|
style={{position: 'absolute', right: 20, bottom: 20}}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
setId(undefined);
|
setEdit(undefined);
|
||||||
setShowEdit(true);
|
setShow(true);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, {useState} from 'react';
|
import React, {useContext, useState} from 'react';
|
||||||
import {IconButton, List, Menu} from 'react-native-paper';
|
import {IconButton, List, Menu} from 'react-native-paper';
|
||||||
import {getDb} from './db';
|
import {DatabaseContext} from './App';
|
||||||
import {Plan} from './plan';
|
import {Plan} from './plan';
|
||||||
|
|
||||||
export default function PlanItem({
|
export default function PlanItem({
|
||||||
|
@ -15,9 +15,9 @@ export default function PlanItem({
|
||||||
onRemove: () => void;
|
onRemove: () => void;
|
||||||
}) {
|
}) {
|
||||||
const [show, setShow] = useState(false);
|
const [show, setShow] = useState(false);
|
||||||
|
const db = useContext(DatabaseContext);
|
||||||
|
|
||||||
const remove = async () => {
|
const remove = async () => {
|
||||||
const db = await getDb();
|
|
||||||
await db.executeSql(`DELETE FROM plans WHERE id = ?`, [item.id]);
|
await db.executeSql(`DELETE FROM plans WHERE id = ?`, [item.id]);
|
||||||
setShow(false);
|
setShow(false);
|
||||||
onRemove();
|
onRemove();
|
||||||
|
|
20
Plans.tsx
20
Plans.tsx
|
@ -1,9 +1,9 @@
|
||||||
import {useFocusEffect} from '@react-navigation/native';
|
import {useFocusEffect} from '@react-navigation/native';
|
||||||
import {format} from 'date-fns';
|
import {format} from 'date-fns';
|
||||||
import React, {useEffect, useState} from 'react';
|
import React, {useContext, useEffect, useState} from 'react';
|
||||||
import {FlatList, StyleSheet, Text, View} from 'react-native';
|
import {FlatList, StyleSheet, Text, View} from 'react-native';
|
||||||
import {AnimatedFAB, ProgressBar, Searchbar} from 'react-native-paper';
|
import {AnimatedFAB, ProgressBar, Searchbar} from 'react-native-paper';
|
||||||
import {getPlans, getProgress} from './db';
|
import {DatabaseContext} from './App';
|
||||||
import EditPlan from './EditPlan';
|
import EditPlan from './EditPlan';
|
||||||
import {Plan} from './plan';
|
import {Plan} from './plan';
|
||||||
import PlanItem from './PlanItem';
|
import PlanItem from './PlanItem';
|
||||||
|
@ -18,6 +18,22 @@ export default function Plans() {
|
||||||
const [progresses, setProgresses] = useState<Progress[]>([]);
|
const [progresses, setProgresses] = useState<Progress[]>([]);
|
||||||
const today = `%${format(new Date(new Date().toUTCString()), 'EEEE')}%`;
|
const today = `%${format(new Date(new Date().toUTCString()), 'EEEE')}%`;
|
||||||
const now = `${format(new Date(new Date().toUTCString()), 'yyyy-MM-dd')}%`;
|
const now = `${format(new Date(new Date().toUTCString()), 'yyyy-MM-dd')}%`;
|
||||||
|
const db = useContext(DatabaseContext);
|
||||||
|
|
||||||
|
const selectPlans = `
|
||||||
|
SELECT * from plans
|
||||||
|
WHERE days LIKE ? OR workouts LIKE ?
|
||||||
|
`;
|
||||||
|
const getPlans = ({search}: {search: string}) =>
|
||||||
|
db.executeSql(selectPlans, [`%${search}%`, `%${search}%`]);
|
||||||
|
|
||||||
|
const selectProgress = `
|
||||||
|
SELECT COUNT(*) as count from sets
|
||||||
|
WHERE created LIKE ?
|
||||||
|
AND name = ?
|
||||||
|
`;
|
||||||
|
const getProgress = ({created, name}: {created: string; name: string}) =>
|
||||||
|
db.executeSql(selectProgress, [`%${created}%`, name]);
|
||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
const [plansResult] = await getPlans({search});
|
const [plansResult] = await getPlans({search});
|
||||||
|
|
12
SetItem.tsx
12
SetItem.tsx
|
@ -1,23 +1,23 @@
|
||||||
import React, {useState} from 'react';
|
import React, {useContext, useState} from 'react';
|
||||||
import {IconButton, List, Menu} from 'react-native-paper';
|
import {IconButton, List, Menu} from 'react-native-paper';
|
||||||
import {getDb} from './db';
|
import {DatabaseContext} from './App';
|
||||||
import Set from './set';
|
import Set from './set';
|
||||||
|
|
||||||
export default function SetItem({
|
export default function SetItem({
|
||||||
item,
|
item,
|
||||||
setId,
|
setSet,
|
||||||
setShowEdit,
|
setShowEdit,
|
||||||
onRemove,
|
onRemove,
|
||||||
}: {
|
}: {
|
||||||
item: Set;
|
item: Set;
|
||||||
setId: (id: number) => void;
|
setSet: (set: Set) => void;
|
||||||
setShowEdit: (show: boolean) => void;
|
setShowEdit: (show: boolean) => void;
|
||||||
onRemove: () => void;
|
onRemove: () => void;
|
||||||
}) {
|
}) {
|
||||||
const [show, setShow] = useState(false);
|
const [show, setShow] = useState(false);
|
||||||
|
const db = useContext(DatabaseContext);
|
||||||
|
|
||||||
const remove = async () => {
|
const remove = async () => {
|
||||||
const db = await getDb();
|
|
||||||
await db.executeSql(`DELETE FROM sets WHERE id = ?`, [item.id]);
|
await db.executeSql(`DELETE FROM sets WHERE id = ?`, [item.id]);
|
||||||
setShow(false);
|
setShow(false);
|
||||||
onRemove();
|
onRemove();
|
||||||
|
@ -27,7 +27,7 @@ export default function SetItem({
|
||||||
<>
|
<>
|
||||||
<List.Item
|
<List.Item
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
setId(item.id);
|
setSet(item);
|
||||||
setShowEdit(true);
|
setShowEdit(true);
|
||||||
}}
|
}}
|
||||||
title={item.name}
|
title={item.name}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
import {useFocusEffect, useNavigation} from '@react-navigation/native';
|
import {useFocusEffect} from '@react-navigation/native';
|
||||||
import React, {useEffect, useState} from 'react';
|
import React, {useContext, useEffect, useState} from 'react';
|
||||||
import {NativeModules, StyleSheet, Text, View} from 'react-native';
|
import {NativeModules, StyleSheet, Text, View} from 'react-native';
|
||||||
import {Button, Snackbar, Switch, TextInput} from 'react-native-paper';
|
import {Button, Snackbar, Switch, TextInput} from 'react-native-paper';
|
||||||
|
import {DatabaseContext} from './App';
|
||||||
import BatteryDialog from './BatteryDialog';
|
import BatteryDialog from './BatteryDialog';
|
||||||
import {getDb} from './db';
|
|
||||||
|
|
||||||
export default function Settings() {
|
export default function Settings() {
|
||||||
const [minutes, setMinutes] = useState<string>('');
|
const [minutes, setMinutes] = useState<string>('');
|
||||||
|
@ -13,6 +13,7 @@ export default function Settings() {
|
||||||
const [snackbar, setSnackbar] = useState('');
|
const [snackbar, setSnackbar] = useState('');
|
||||||
const [showBattery, setShowBattery] = useState(false);
|
const [showBattery, setShowBattery] = useState(false);
|
||||||
const [ignoring, setIgnoring] = useState(false);
|
const [ignoring, setIgnoring] = useState(false);
|
||||||
|
const db = useContext(DatabaseContext);
|
||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
setMinutes((await AsyncStorage.getItem('minutes')) || '3');
|
setMinutes((await AsyncStorage.getItem('minutes')) || '3');
|
||||||
|
@ -34,7 +35,6 @@ export default function Settings() {
|
||||||
const clear = async () => {
|
const clear = async () => {
|
||||||
setSnackbar('Deleting all data...');
|
setSnackbar('Deleting all data...');
|
||||||
setTimeout(() => setSnackbar(''), 5000);
|
setTimeout(() => setSnackbar(''), 5000);
|
||||||
const db = await getDb();
|
|
||||||
await db.executeSql(`DELETE FROM sets`);
|
await db.executeSql(`DELETE FROM sets`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
37
db.ts
37
db.ts
|
@ -3,7 +3,7 @@ import {enablePromise, openDatabase} from 'react-native-sqlite-storage';
|
||||||
enablePromise(true);
|
enablePromise(true);
|
||||||
export const getDb = () => openDatabase({name: 'massive.db'});
|
export const getDb = () => openDatabase({name: 'massive.db'});
|
||||||
|
|
||||||
const createSets = `
|
export const createSets = `
|
||||||
CREATE TABLE IF NOT EXISTS sets (
|
CREATE TABLE IF NOT EXISTS sets (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
|
@ -14,7 +14,7 @@ const createSets = `
|
||||||
);
|
);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const createPlans = `
|
export const createPlans = `
|
||||||
CREATE TABLE IF NOT EXISTS plans (
|
CREATE TABLE IF NOT EXISTS plans (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
days TEXT NOT NULL,
|
days TEXT NOT NULL,
|
||||||
|
@ -22,21 +22,6 @@ const createPlans = `
|
||||||
);
|
);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const setupSchema = () =>
|
|
||||||
getDb().then(db => {
|
|
||||||
db.executeSql(createSets);
|
|
||||||
db.executeSql(createPlans);
|
|
||||||
});
|
|
||||||
|
|
||||||
const selectPlans = `
|
|
||||||
SELECT * from plans
|
|
||||||
WHERE days LIKE ? OR workouts LIKE ?
|
|
||||||
`;
|
|
||||||
export const getPlans = ({search}: {search: string}) =>
|
|
||||||
getDb().then(db =>
|
|
||||||
db.executeSql(selectPlans, [`%${search}%`, `%${search}%`]),
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectProgress = `
|
const selectProgress = `
|
||||||
SELECT count(*) as count from sets
|
SELECT count(*) as count from sets
|
||||||
WHERE created LIKE ?
|
WHERE created LIKE ?
|
||||||
|
@ -44,21 +29,3 @@ const selectProgress = `
|
||||||
`;
|
`;
|
||||||
export const getProgress = ({created, name}: {created: string; name: string}) =>
|
export const getProgress = ({created, name}: {created: string; name: string}) =>
|
||||||
getDb().then(db => db.executeSql(selectProgress, [`%${created}%`, name]));
|
getDb().then(db => db.executeSql(selectProgress, [`%${created}%`, name]));
|
||||||
|
|
||||||
const selectSets = `
|
|
||||||
SELECT * from sets
|
|
||||||
WHERE name LIKE ?
|
|
||||||
ORDER BY created DESC
|
|
||||||
LIMIT ? OFFSET ?
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const getSets = ({
|
|
||||||
search,
|
|
||||||
limit,
|
|
||||||
offset,
|
|
||||||
}: {
|
|
||||||
search: string;
|
|
||||||
limit: number;
|
|
||||||
offset: number;
|
|
||||||
}) =>
|
|
||||||
getDb().then(db => db.executeSql(selectSets, [`%${search}%`, limit, offset]));
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user