Replace usage of react-native-async-storage with sqlite

This commit is contained in:
Brandon Presley 2022-08-24 12:01:39 +12:00
parent 37803ad0d4
commit 75b71b5851
6 changed files with 71 additions and 50 deletions

31
App.tsx
View File

@ -1,4 +1,3 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import {createDrawerNavigator} from '@react-navigation/drawer';
import {
DarkTheme as NavigationDarkTheme,
@ -14,7 +13,7 @@ import {
} from 'react-native-paper';
import {SQLiteDatabase} from 'react-native-sqlite-storage';
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';
export const Drawer = createDrawerNavigator<DrawerParamList>();
@ -27,8 +26,6 @@ export type DrawerParamList = {
export const DatabaseContext = React.createContext<SQLiteDatabase>({} as any);
const {getItem, setItem} = AsyncStorage;
const CombinedDefaultTheme = {
...PaperDefaultTheme,
...NavigationDefaultTheme,
@ -52,21 +49,17 @@ const App = () => {
useEffect(() => {
const init = async () => {
const gotDb = await getDb();
await gotDb.executeSql(createPlans);
await gotDb.executeSql(createSets);
setDb(gotDb);
const minutes = await getItem('minutes');
if (minutes === null) await setItem('minutes', '3');
const seconds = await getItem('seconds');
if (seconds === null) await setItem('seconds', '30');
const alarmEnabled = await getItem('alarmEnabled');
if (alarmEnabled === null) await setItem('alarmEnabled', 'false');
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');
const _db = await getDb();
await _db.executeSql(createPlans);
await _db.executeSql(createSets);
await _db.executeSql(createSettings);
setDb(_db);
const [result] = await _db.executeSql(`SELECT * FROM settings LIMIT 1`);
if (result.rows.length === 0)
return _db.executeSql(`
INSERT INTO settings(minutes,seconds,alarm,vibrate,predict,sets)
VALUES(3,30,false,true,true,3);
`);
};
init();
}, []);

View File

@ -1,4 +1,3 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import {
RouteProp,
useFocusEffect,
@ -12,6 +11,7 @@ import {DatabaseContext} from './App';
import {HomePageParams} from './HomePage';
import Set from './set';
import SetForm from './SetForm';
import Settings from './settings';
export default function EditSet() {
const {params} = useRoute<RouteProp<HomePageParams, 'EditSet'>>();
@ -30,14 +30,12 @@ export default function EditSet() {
);
const startTimer = useCallback(async () => {
const enabled = await AsyncStorage.getItem('alarmEnabled');
if (enabled !== 'true') return;
const minutes = await AsyncStorage.getItem('minutes');
const seconds = await AsyncStorage.getItem('seconds');
const milliseconds = Number(minutes) * 60 * 1000 + Number(seconds) * 1000;
const vibrate = (await AsyncStorage.getItem('vibrate')) === 'true';
NativeModules.AlarmModule.timer(milliseconds, vibrate);
}, []);
const [result] = await db.executeSql(`SELECT * FROM settings LIMIT 1`);
const settings: Settings = result.rows.item(0);
if (!settings.alarm) return;
const milliseconds = settings.minutes * 60 * 1000 + settings.seconds * 1000;
NativeModules.AlarmModule.timer(milliseconds, !!settings.vibrate);
}, [db]);
const update = useCallback(
async (set: Set) => {

View File

@ -5,7 +5,6 @@ import {
} from '@react-navigation/native';
import React, {useCallback, useContext, useEffect, useState} from 'react';
import {FlatList, StyleSheet, View} from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {List, Searchbar} from 'react-native-paper';
import {DatabaseContext} from './App';
import {HomePageParams} from './HomePage';
@ -13,6 +12,7 @@ import MassiveFab from './MassiveFab';
import {Plan} from './plan';
import Set from './set';
import SetItem from './SetItem';
import Settings from './settings';
import {DAYS} from './time';
const limit = 15;
@ -105,7 +105,9 @@ export default function SetList() {
);
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();
if (todaysPlan.length === 0) return;
const todaysSets = await getTodaysSets();
@ -115,15 +117,14 @@ export default function SetList() {
const count = todaysSets.filter(
s => s.name === todaysSets[0].name,
).length;
const maxSets = await AsyncStorage.getItem('maxSets');
nextWorkout = todaysSets[0].name;
if (count >= Number(maxSets))
if (count >= Number(settings.sets))
nextWorkout =
todaysWorkouts[todaysWorkouts.indexOf(todaysSets[0].name!) + 1];
}
const best = await getBest(nextWorkout);
setNextSet({...best});
}, [getTodaysSets, getTodaysPlan, getBest]);
}, [getTodaysSets, getTodaysPlan, getBest, db]);
useFocusEffect(
useCallback(() => {

View File

@ -1,9 +1,8 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import React, {
ReactNode,
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
import {
@ -14,10 +13,10 @@ import {
View,
} from 'react-native';
import {Searchbar, TextInput} from 'react-native-paper';
import {DatabaseContext} from './App';
import ConfirmDialog from './ConfirmDialog';
import MassiveSwitch from './MassiveSwitch';
const {getItem, setItem} = AsyncStorage;
import Settings from './settings';
export default function SettingsPage() {
const [vibrate, setVibrate] = useState(true);
@ -29,25 +28,36 @@ export default function SettingsPage() {
const [battery, setBattery] = useState(false);
const [ignoring, setIgnoring] = useState(false);
const [search, setSearch] = useState('');
const db = useContext(DatabaseContext);
const refresh = useCallback(async () => {
setMinutes((await getItem('minutes')) || '');
setSeconds((await getItem('seconds')) || '');
setAlarm((await getItem('alarmEnabled')) === 'true');
setPredictive((await getItem('predictiveSets')) === 'true');
setMaxSets((await getItem('maxSets')) || '');
const [result] = await db.executeSql(`SELECT * FROM settings LIMIT 1`);
const settings: Settings = result.rows.item(0);
console.log('SettingsPage.refresh:', {settings});
setMinutes(settings.minutes.toString());
setSeconds(settings.seconds.toString());
setAlarm(!!settings.alarm);
setPredictive(!!settings.predict);
setMaxSets(settings.sets.toString());
setVibrate(!!settings.vibrate);
NativeModules.AlarmModule.ignoringBattery(setIgnoring);
}, []);
}, [db]);
useEffect(() => {
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(
(enabled: boolean) => {
setAlarm(enabled);
if (enabled && !ignoring) setBattery(true);
setItem('alarmEnabled', enabled ? 'true' : 'false');
},
[setBattery, ignoring],
);
@ -55,7 +65,6 @@ export default function SettingsPage() {
const changePredictive = useCallback(
(enabled: boolean) => {
setPredictive(enabled);
setItem('predictiveSets', enabled ? 'true' : 'false');
ToastAndroid.show(
'Predictive sets guess whats next based on todays plan.',
ToastAndroid.LONG,
@ -67,7 +76,6 @@ export default function SettingsPage() {
const changeVibrate = useCallback(
(value: boolean) => {
setVibrate(value);
setItem('vibrate', value ? 'true' : 'false');
},
[setVibrate],
);
@ -82,7 +90,6 @@ export default function SettingsPage() {
keyboardType="numeric"
onChangeText={value => {
setMaxSets(value);
setItem('maxSets', value);
}}
style={styles.text}
selectTextOnFocus
@ -99,7 +106,6 @@ export default function SettingsPage() {
placeholder="30"
onChangeText={s => {
setSeconds(s);
setItem('seconds', s);
}}
style={styles.text}
selectTextOnFocus
@ -116,7 +122,6 @@ export default function SettingsPage() {
placeholder="3"
onChangeText={text => {
setMinutes(text);
setItem('minutes', text);
}}
style={styles.text}
selectTextOnFocus
@ -166,7 +171,12 @@ export default function SettingsPage() {
return (
<View style={styles.container}>
<Searchbar placeholder="Search" value={search} onChangeText={setSearch} />
<Searchbar
style={{marginBottom: 10}}
placeholder="Search"
value={search}
onChangeText={setSearch}
/>
{items
.filter(item => item.name.toLowerCase().includes(search.toLowerCase()))
.map(item => (

11
db.ts
View File

@ -21,3 +21,14 @@ export const createPlans = `
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
View File

@ -0,0 +1,8 @@
export default interface Settings {
minutes: number;
seconds: number;
alarm: number;
vibrate: number;
predict: number;
sets: number;
}