Replace usage of react-native-async-storage with sqlite
This commit is contained in:
parent
37803ad0d4
commit
75b71b5851
31
App.tsx
31
App.tsx
|
@ -1,4 +1,3 @@
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
||||||
import {createDrawerNavigator} from '@react-navigation/drawer';
|
import {createDrawerNavigator} from '@react-navigation/drawer';
|
||||||
import {
|
import {
|
||||||
DarkTheme as NavigationDarkTheme,
|
DarkTheme as NavigationDarkTheme,
|
||||||
|
@ -14,7 +13,7 @@ import {
|
||||||
} from 'react-native-paper';
|
} from 'react-native-paper';
|
||||||
import {SQLiteDatabase} from 'react-native-sqlite-storage';
|
import {SQLiteDatabase} from 'react-native-sqlite-storage';
|
||||||
import Ionicon from 'react-native-vector-icons/Ionicons';
|
import Ionicon from 'react-native-vector-icons/Ionicons';
|
||||||
import {createPlans, createSets, getDb} from './db';
|
import {createPlans, createSets, createSettings, getDb} from './db';
|
||||||
import Routes from './Routes';
|
import Routes from './Routes';
|
||||||
|
|
||||||
export const Drawer = createDrawerNavigator<DrawerParamList>();
|
export const Drawer = createDrawerNavigator<DrawerParamList>();
|
||||||
|
@ -27,8 +26,6 @@ export type DrawerParamList = {
|
||||||
|
|
||||||
export const DatabaseContext = React.createContext<SQLiteDatabase>({} as any);
|
export const DatabaseContext = React.createContext<SQLiteDatabase>({} as any);
|
||||||
|
|
||||||
const {getItem, setItem} = AsyncStorage;
|
|
||||||
|
|
||||||
const CombinedDefaultTheme = {
|
const CombinedDefaultTheme = {
|
||||||
...PaperDefaultTheme,
|
...PaperDefaultTheme,
|
||||||
...NavigationDefaultTheme,
|
...NavigationDefaultTheme,
|
||||||
|
@ -52,21 +49,17 @@ const App = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
const gotDb = await getDb();
|
const _db = await getDb();
|
||||||
await gotDb.executeSql(createPlans);
|
await _db.executeSql(createPlans);
|
||||||
await gotDb.executeSql(createSets);
|
await _db.executeSql(createSets);
|
||||||
setDb(gotDb);
|
await _db.executeSql(createSettings);
|
||||||
const minutes = await getItem('minutes');
|
setDb(_db);
|
||||||
if (minutes === null) await setItem('minutes', '3');
|
const [result] = await _db.executeSql(`SELECT * FROM settings LIMIT 1`);
|
||||||
const seconds = await getItem('seconds');
|
if (result.rows.length === 0)
|
||||||
if (seconds === null) await setItem('seconds', '30');
|
return _db.executeSql(`
|
||||||
const alarmEnabled = await getItem('alarmEnabled');
|
INSERT INTO settings(minutes,seconds,alarm,vibrate,predict,sets)
|
||||||
if (alarmEnabled === null) await setItem('alarmEnabled', 'false');
|
VALUES(3,30,false,true,true,3);
|
||||||
const vibrate = await getItem('vibrate');
|
`);
|
||||||
if (vibrate === null) await setItem('vibrate', 'true');
|
|
||||||
if (!(await getItem('predictiveSets')))
|
|
||||||
await setItem('predictiveSets', 'true');
|
|
||||||
if (!(await getItem('maxSets'))) await setItem('maxSets', '3');
|
|
||||||
};
|
};
|
||||||
init();
|
init();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
16
EditSet.tsx
16
EditSet.tsx
|
@ -1,4 +1,3 @@
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
||||||
import {
|
import {
|
||||||
RouteProp,
|
RouteProp,
|
||||||
useFocusEffect,
|
useFocusEffect,
|
||||||
|
@ -12,6 +11,7 @@ import {DatabaseContext} from './App';
|
||||||
import {HomePageParams} from './HomePage';
|
import {HomePageParams} from './HomePage';
|
||||||
import Set from './set';
|
import Set from './set';
|
||||||
import SetForm from './SetForm';
|
import SetForm from './SetForm';
|
||||||
|
import Settings from './settings';
|
||||||
|
|
||||||
export default function EditSet() {
|
export default function EditSet() {
|
||||||
const {params} = useRoute<RouteProp<HomePageParams, 'EditSet'>>();
|
const {params} = useRoute<RouteProp<HomePageParams, 'EditSet'>>();
|
||||||
|
@ -30,14 +30,12 @@ export default function EditSet() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const startTimer = useCallback(async () => {
|
const startTimer = useCallback(async () => {
|
||||||
const enabled = await AsyncStorage.getItem('alarmEnabled');
|
const [result] = await db.executeSql(`SELECT * FROM settings LIMIT 1`);
|
||||||
if (enabled !== 'true') return;
|
const settings: Settings = result.rows.item(0);
|
||||||
const minutes = await AsyncStorage.getItem('minutes');
|
if (!settings.alarm) return;
|
||||||
const seconds = await AsyncStorage.getItem('seconds');
|
const milliseconds = settings.minutes * 60 * 1000 + settings.seconds * 1000;
|
||||||
const milliseconds = Number(minutes) * 60 * 1000 + Number(seconds) * 1000;
|
NativeModules.AlarmModule.timer(milliseconds, !!settings.vibrate);
|
||||||
const vibrate = (await AsyncStorage.getItem('vibrate')) === 'true';
|
}, [db]);
|
||||||
NativeModules.AlarmModule.timer(milliseconds, vibrate);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
async (set: Set) => {
|
async (set: Set) => {
|
||||||
|
|
11
SetList.tsx
11
SetList.tsx
|
@ -5,7 +5,6 @@ import {
|
||||||
} from '@react-navigation/native';
|
} from '@react-navigation/native';
|
||||||
import React, {useCallback, useContext, useEffect, useState} from 'react';
|
import React, {useCallback, useContext, useEffect, useState} from 'react';
|
||||||
import {FlatList, StyleSheet, View} from 'react-native';
|
import {FlatList, StyleSheet, View} from 'react-native';
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
||||||
import {List, Searchbar} from 'react-native-paper';
|
import {List, Searchbar} from 'react-native-paper';
|
||||||
import {DatabaseContext} from './App';
|
import {DatabaseContext} from './App';
|
||||||
import {HomePageParams} from './HomePage';
|
import {HomePageParams} from './HomePage';
|
||||||
|
@ -13,6 +12,7 @@ import MassiveFab from './MassiveFab';
|
||||||
import {Plan} from './plan';
|
import {Plan} from './plan';
|
||||||
import Set from './set';
|
import Set from './set';
|
||||||
import SetItem from './SetItem';
|
import SetItem from './SetItem';
|
||||||
|
import Settings from './settings';
|
||||||
import {DAYS} from './time';
|
import {DAYS} from './time';
|
||||||
|
|
||||||
const limit = 15;
|
const limit = 15;
|
||||||
|
@ -105,7 +105,9 @@ export default function SetList() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const predict = useCallback(async () => {
|
const predict = useCallback(async () => {
|
||||||
if ((await AsyncStorage.getItem('predictiveSets')) === 'false') return;
|
const [result] = await db.executeSql(`SELECT * FROM settings LIMIT 1`);
|
||||||
|
const settings: Settings = result.rows.item(0);
|
||||||
|
if (!settings.predict) return;
|
||||||
const todaysPlan = await getTodaysPlan();
|
const todaysPlan = await getTodaysPlan();
|
||||||
if (todaysPlan.length === 0) return;
|
if (todaysPlan.length === 0) return;
|
||||||
const todaysSets = await getTodaysSets();
|
const todaysSets = await getTodaysSets();
|
||||||
|
@ -115,15 +117,14 @@ export default function SetList() {
|
||||||
const count = todaysSets.filter(
|
const count = todaysSets.filter(
|
||||||
s => s.name === todaysSets[0].name,
|
s => s.name === todaysSets[0].name,
|
||||||
).length;
|
).length;
|
||||||
const maxSets = await AsyncStorage.getItem('maxSets');
|
|
||||||
nextWorkout = todaysSets[0].name;
|
nextWorkout = todaysSets[0].name;
|
||||||
if (count >= Number(maxSets))
|
if (count >= Number(settings.sets))
|
||||||
nextWorkout =
|
nextWorkout =
|
||||||
todaysWorkouts[todaysWorkouts.indexOf(todaysSets[0].name!) + 1];
|
todaysWorkouts[todaysWorkouts.indexOf(todaysSets[0].name!) + 1];
|
||||||
}
|
}
|
||||||
const best = await getBest(nextWorkout);
|
const best = await getBest(nextWorkout);
|
||||||
setNextSet({...best});
|
setNextSet({...best});
|
||||||
}, [getTodaysSets, getTodaysPlan, getBest]);
|
}, [getTodaysSets, getTodaysPlan, getBest, db]);
|
||||||
|
|
||||||
useFocusEffect(
|
useFocusEffect(
|
||||||
useCallback(() => {
|
useCallback(() => {
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
||||||
import React, {
|
import React, {
|
||||||
ReactNode,
|
ReactNode,
|
||||||
useCallback,
|
useCallback,
|
||||||
|
useContext,
|
||||||
useEffect,
|
useEffect,
|
||||||
useMemo,
|
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import {
|
import {
|
||||||
|
@ -14,10 +13,10 @@ import {
|
||||||
View,
|
View,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import {Searchbar, TextInput} from 'react-native-paper';
|
import {Searchbar, TextInput} from 'react-native-paper';
|
||||||
|
import {DatabaseContext} from './App';
|
||||||
import ConfirmDialog from './ConfirmDialog';
|
import ConfirmDialog from './ConfirmDialog';
|
||||||
import MassiveSwitch from './MassiveSwitch';
|
import MassiveSwitch from './MassiveSwitch';
|
||||||
|
import Settings from './settings';
|
||||||
const {getItem, setItem} = AsyncStorage;
|
|
||||||
|
|
||||||
export default function SettingsPage() {
|
export default function SettingsPage() {
|
||||||
const [vibrate, setVibrate] = useState(true);
|
const [vibrate, setVibrate] = useState(true);
|
||||||
|
@ -29,25 +28,36 @@ export default function SettingsPage() {
|
||||||
const [battery, setBattery] = useState(false);
|
const [battery, setBattery] = useState(false);
|
||||||
const [ignoring, setIgnoring] = useState(false);
|
const [ignoring, setIgnoring] = useState(false);
|
||||||
const [search, setSearch] = useState('');
|
const [search, setSearch] = useState('');
|
||||||
|
const db = useContext(DatabaseContext);
|
||||||
|
|
||||||
const refresh = useCallback(async () => {
|
const refresh = useCallback(async () => {
|
||||||
setMinutes((await getItem('minutes')) || '');
|
const [result] = await db.executeSql(`SELECT * FROM settings LIMIT 1`);
|
||||||
setSeconds((await getItem('seconds')) || '');
|
const settings: Settings = result.rows.item(0);
|
||||||
setAlarm((await getItem('alarmEnabled')) === 'true');
|
console.log('SettingsPage.refresh:', {settings});
|
||||||
setPredictive((await getItem('predictiveSets')) === 'true');
|
setMinutes(settings.minutes.toString());
|
||||||
setMaxSets((await getItem('maxSets')) || '');
|
setSeconds(settings.seconds.toString());
|
||||||
|
setAlarm(!!settings.alarm);
|
||||||
|
setPredictive(!!settings.predict);
|
||||||
|
setMaxSets(settings.sets.toString());
|
||||||
|
setVibrate(!!settings.vibrate);
|
||||||
NativeModules.AlarmModule.ignoringBattery(setIgnoring);
|
NativeModules.AlarmModule.ignoringBattery(setIgnoring);
|
||||||
}, []);
|
}, [db]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
refresh();
|
refresh();
|
||||||
}, [refresh]);
|
}, [refresh]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
db.executeSql(
|
||||||
|
`UPDATE settings SET vibrate=?,minutes=?,sets=?,seconds=?,alarm=?,predict=?`,
|
||||||
|
[vibrate, minutes, maxSets, seconds, alarm, predictive],
|
||||||
|
);
|
||||||
|
}, [vibrate, minutes, maxSets, seconds, alarm, predictive, db]);
|
||||||
|
|
||||||
const changeAlarmEnabled = useCallback(
|
const changeAlarmEnabled = useCallback(
|
||||||
(enabled: boolean) => {
|
(enabled: boolean) => {
|
||||||
setAlarm(enabled);
|
setAlarm(enabled);
|
||||||
if (enabled && !ignoring) setBattery(true);
|
if (enabled && !ignoring) setBattery(true);
|
||||||
setItem('alarmEnabled', enabled ? 'true' : 'false');
|
|
||||||
},
|
},
|
||||||
[setBattery, ignoring],
|
[setBattery, ignoring],
|
||||||
);
|
);
|
||||||
|
@ -55,7 +65,6 @@ export default function SettingsPage() {
|
||||||
const changePredictive = useCallback(
|
const changePredictive = useCallback(
|
||||||
(enabled: boolean) => {
|
(enabled: boolean) => {
|
||||||
setPredictive(enabled);
|
setPredictive(enabled);
|
||||||
setItem('predictiveSets', enabled ? 'true' : 'false');
|
|
||||||
ToastAndroid.show(
|
ToastAndroid.show(
|
||||||
'Predictive sets guess whats next based on todays plan.',
|
'Predictive sets guess whats next based on todays plan.',
|
||||||
ToastAndroid.LONG,
|
ToastAndroid.LONG,
|
||||||
|
@ -67,7 +76,6 @@ export default function SettingsPage() {
|
||||||
const changeVibrate = useCallback(
|
const changeVibrate = useCallback(
|
||||||
(value: boolean) => {
|
(value: boolean) => {
|
||||||
setVibrate(value);
|
setVibrate(value);
|
||||||
setItem('vibrate', value ? 'true' : 'false');
|
|
||||||
},
|
},
|
||||||
[setVibrate],
|
[setVibrate],
|
||||||
);
|
);
|
||||||
|
@ -82,7 +90,6 @@ export default function SettingsPage() {
|
||||||
keyboardType="numeric"
|
keyboardType="numeric"
|
||||||
onChangeText={value => {
|
onChangeText={value => {
|
||||||
setMaxSets(value);
|
setMaxSets(value);
|
||||||
setItem('maxSets', value);
|
|
||||||
}}
|
}}
|
||||||
style={styles.text}
|
style={styles.text}
|
||||||
selectTextOnFocus
|
selectTextOnFocus
|
||||||
|
@ -99,7 +106,6 @@ export default function SettingsPage() {
|
||||||
placeholder="30"
|
placeholder="30"
|
||||||
onChangeText={s => {
|
onChangeText={s => {
|
||||||
setSeconds(s);
|
setSeconds(s);
|
||||||
setItem('seconds', s);
|
|
||||||
}}
|
}}
|
||||||
style={styles.text}
|
style={styles.text}
|
||||||
selectTextOnFocus
|
selectTextOnFocus
|
||||||
|
@ -116,7 +122,6 @@ export default function SettingsPage() {
|
||||||
placeholder="3"
|
placeholder="3"
|
||||||
onChangeText={text => {
|
onChangeText={text => {
|
||||||
setMinutes(text);
|
setMinutes(text);
|
||||||
setItem('minutes', text);
|
|
||||||
}}
|
}}
|
||||||
style={styles.text}
|
style={styles.text}
|
||||||
selectTextOnFocus
|
selectTextOnFocus
|
||||||
|
@ -166,7 +171,12 @@ export default function SettingsPage() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Searchbar placeholder="Search" value={search} onChangeText={setSearch} />
|
<Searchbar
|
||||||
|
style={{marginBottom: 10}}
|
||||||
|
placeholder="Search"
|
||||||
|
value={search}
|
||||||
|
onChangeText={setSearch}
|
||||||
|
/>
|
||||||
{items
|
{items
|
||||||
.filter(item => item.name.toLowerCase().includes(search.toLowerCase()))
|
.filter(item => item.name.toLowerCase().includes(search.toLowerCase()))
|
||||||
.map(item => (
|
.map(item => (
|
||||||
|
|
11
db.ts
11
db.ts
|
@ -21,3 +21,14 @@ export const createPlans = `
|
||||||
workouts TEXT NOT NULL
|
workouts TEXT NOT NULL
|
||||||
);
|
);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const createSettings = `
|
||||||
|
CREATE TABLE IF NOT EXISTS settings (
|
||||||
|
minutes INTEGER NOT NULL DEFAULT 3,
|
||||||
|
seconds INTEGER NOT NULL DEFAULT 30,
|
||||||
|
alarm BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
vibrate BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
predict BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
sets INTEGER NOT NULL DEFAULT 3
|
||||||
|
);
|
||||||
|
`;
|
||||||
|
|
8
settings.ts
Normal file
8
settings.ts
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
export default interface Settings {
|
||||||
|
minutes: number;
|
||||||
|
seconds: number;
|
||||||
|
alarm: number;
|
||||||
|
vibrate: number;
|
||||||
|
predict: number;
|
||||||
|
sets: number;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user