diff --git a/.fdignore b/.fdignore
new file mode 100644
index 0000000..e33609d
--- /dev/null
+++ b/.fdignore
@@ -0,0 +1 @@
+*.png
diff --git a/App.tsx b/App.tsx
index b3fd9a2..b388185 100644
--- a/App.tsx
+++ b/App.tsx
@@ -4,7 +4,7 @@ import {
DefaultTheme as NavigationDefaultTheme,
NavigationContainer,
} from '@react-navigation/native';
-import React from 'react';
+import React, {useState} from 'react';
import {useColorScheme} from 'react-native';
import {
DarkTheme as PaperDarkTheme,
@@ -44,20 +44,40 @@ export const CombinedDarkTheme = {
},
};
+export const CustomTheme = React.createContext({
+ color: '',
+ setColor: (_value: string) => {},
+});
+
const App = () => {
const dark = useColorScheme() === 'dark';
+ const [color, setColor] = useState(
+ dark
+ ? CombinedDarkTheme.colors.primary
+ : CombinedDefaultTheme.colors.primary,
+ );
+ const theme = dark
+ ? {
+ ...CombinedDarkTheme,
+ colors: {...CombinedDarkTheme.colors, primary: color},
+ }
+ : {
+ ...CombinedDefaultTheme,
+ colors: {...CombinedDefaultTheme.colors, primary: color},
+ };
return (
- }}>
-
-
-
-
-
-
+
+ }}>
+
+
+
+
+
+
+
);
};
diff --git a/Chart.tsx b/Chart.tsx
index 204cc07..0ee44ec 100644
--- a/Chart.tsx
+++ b/Chart.tsx
@@ -1,8 +1,8 @@
import * as shape from 'd3-shape';
-import React from 'react';
-import {useColorScheme, View} from 'react-native';
+import React, {useContext} from 'react';
+import {View} from 'react-native';
import {Grid, LineChart, XAxis, YAxis} from 'react-native-svg-charts';
-import {CombinedDarkTheme, CombinedDefaultTheme} from './App';
+import {CustomTheme} from './App';
import {MARGIN, PADDING} from './constants';
import Set from './set';
@@ -17,7 +17,7 @@ export default function Chart({
xFormat: (value: any, index: number) => string;
yFormat: (value: any) => string;
}) {
- const dark = useColorScheme() === 'dark';
+ const {color} = useContext(CustomTheme);
const axesSvg = {fontSize: 10, fill: 'grey'};
const verticalContentInset = {top: 10, bottom: 10};
const xAxisHeight = 30;
@@ -39,9 +39,7 @@ export default function Chart({
contentInset={verticalContentInset}
curve={shape.curveBasis}
svg={{
- stroke: dark
- ? CombinedDarkTheme.colors.primary
- : CombinedDefaultTheme.colors.primary,
+ stroke: color,
}}>
diff --git a/MassiveFab.tsx b/MassiveFab.tsx
index 37328cc..d32a50c 100644
--- a/MassiveFab.tsx
+++ b/MassiveFab.tsx
@@ -1,12 +1,13 @@
-import React from 'react';
+import React, {useContext} from 'react';
import {useColorScheme} from 'react-native';
import {FAB} from 'react-native-paper';
-import {CombinedDarkTheme, CombinedDefaultTheme} from './App';
+import {CombinedDarkTheme, CustomTheme} from './App';
export default function MassiveFab(
props: Partial>,
) {
const dark = useColorScheme() === 'dark';
+ const {color} = useContext(CustomTheme);
return (
);
diff --git a/MassiveSnack.tsx b/MassiveSnack.tsx
index dec4339..f862775 100644
--- a/MassiveSnack.tsx
+++ b/MassiveSnack.tsx
@@ -1,7 +1,7 @@
-import React, {useState} from 'react';
+import React, {useContext, useState} from 'react';
import {useColorScheme} from 'react-native';
import {Snackbar} from 'react-native-paper';
-import {CombinedDarkTheme, CombinedDefaultTheme} from './App';
+import {CombinedDarkTheme, CustomTheme} from './App';
export const SnackbarContext = React.createContext<{
toast: (value: string, timeout: number) => void;
@@ -11,6 +11,7 @@ const MassiveSnack = ({children}: {children: JSX.Element[] | JSX.Element}) => {
const [snackbar, setSnackbar] = useState('');
const [timeoutId, setTimeoutId] = useState(0);
const dark = useColorScheme() === 'dark';
+ const {color} = useContext(CustomTheme);
const toast = (value: string, timeout: number) => {
setSnackbar(value);
@@ -30,9 +31,7 @@ const MassiveSnack = ({children}: {children: JSX.Element[] | JSX.Element}) => {
action={{
label: 'Close',
onPress: () => setSnackbar(''),
- color: dark
- ? CombinedDarkTheme.colors.background
- : CombinedDefaultTheme.colors.primary,
+ color: dark ? CombinedDarkTheme.colors.background : color,
}}>
{snackbar}
diff --git a/MassiveSwitch.tsx b/MassiveSwitch.tsx
index e8033d5..e44baa1 100644
--- a/MassiveSwitch.tsx
+++ b/MassiveSwitch.tsx
@@ -1,23 +1,12 @@
-import React from 'react';
-import {useColorScheme} from 'react-native';
+import React, {useContext} from 'react';
import {Switch} from 'react-native-paper';
-import {CombinedDarkTheme, CombinedDefaultTheme} from './App';
+import {CustomTheme} from './App';
import {MARGIN} from './constants';
export default function MassiveSwitch(
props: Partial>,
) {
- const dark = useColorScheme() === 'dark';
+ const {color} = useContext(CustomTheme);
- return (
-
- );
+ return ;
}
diff --git a/Routes.tsx b/Routes.tsx
index 23fab86..f760f0c 100644
--- a/Routes.tsx
+++ b/Routes.tsx
@@ -1,12 +1,12 @@
-import React, {useEffect, useState} from 'react';
+import React, {useContext, useEffect, useState} from 'react';
import {useColorScheme} from 'react-native';
import {IconButton} from 'react-native-paper';
-import {Drawer, DrawerParamList} from './App';
+import {CustomTheme, Drawer, DrawerParamList} from './App';
import BestPage from './BestPage';
import {runMigrations} from './db';
import HomePage from './HomePage';
import PlanPage from './PlanPage';
-import {getSettings} from './settings.service';
+import {getSettings, settings} from './settings.service';
import SettingsPage from './SettingsPage';
import WorkoutsPage from './WorkoutsPage';
@@ -19,12 +19,16 @@ interface Route {
export default function Routes() {
const [migrated, setMigrated] = useState(false);
const dark = useColorScheme() === 'dark';
+ const {setColor} = useContext(CustomTheme);
useEffect(() => {
runMigrations()
.then(getSettings)
- .then(() => setMigrated(true));
- }, []);
+ .then(() => setMigrated(true))
+ .then(() => {
+ if (settings.color) setColor(settings.color);
+ });
+ }, [setColor]);
if (!migrated) return null;
diff --git a/SettingsPage.tsx b/SettingsPage.tsx
index 6a74214..1947022 100644
--- a/SettingsPage.tsx
+++ b/SettingsPage.tsx
@@ -1,8 +1,10 @@
+import {Picker} from '@react-native-picker/picker';
import {useFocusEffect} from '@react-navigation/native';
import React, {useCallback, useContext, useEffect, useState} from 'react';
-import {NativeModules, ScrollView} from 'react-native';
+import {NativeModules, ScrollView, StyleSheet} from 'react-native';
import DocumentPicker from 'react-native-document-picker';
import {Button, Text} from 'react-native-paper';
+import {CustomTheme} from './App';
import ConfirmDialog from './ConfirmDialog';
import {MARGIN} from './constants';
import {SnackbarContext} from './MassiveSnack';
@@ -27,6 +29,7 @@ export default function SettingsPage() {
const [ignoring, setIgnoring] = useState(false);
const [search, setSearch] = useState('');
const [showUnit, setShowUnit] = useState(true);
+ const {color, setColor} = useContext(CustomTheme);
const {toast} = useContext(SnackbarContext);
useFocusEffect(
@@ -35,7 +38,7 @@ export default function SettingsPage() {
setAlarm(!!settings.alarm);
setPredict(!!settings.predict);
setVibrate(!!settings.vibrate);
- setSound(settings.sound);
+ setSound(settings.sound ?? '');
setNotify(!!settings.notify);
setImages(!!settings.images);
NativeModules.AlarmModule.ignoringBattery(setIgnoring);
@@ -51,9 +54,10 @@ export default function SettingsPage() {
notify: +notify,
images: +images,
showUnit: +showUnit,
+ color,
});
getSettings();
- }, [vibrate, alarm, predict, sound, notify, images, showUnit]);
+ }, [vibrate, alarm, predict, sound, notify, images, showUnit, color]);
const changeAlarmEnabled = useCallback(
(enabled: boolean) => {
@@ -131,16 +135,16 @@ export default function SettingsPage() {
return (
-
+
{switches
.filter(input =>
input.name.toLowerCase().includes(search.toLowerCase()),
)
.map(input => (
- {input.name}
+ {input.name}
@@ -154,6 +158,18 @@ export default function SettingsPage() {
: null}
)}
+ {'color'.includes(search.toLowerCase()) && (
+ setColor(value)}>
+
+
+
+
+
+ )}
);
}
+
+const styles = StyleSheet.create({
+ item: {
+ alignSelf: 'flex-start',
+ marginBottom: MARGIN,
+ marginLeft: MARGIN,
+ },
+});
diff --git a/db.ts b/db.ts
index 2892238..1360e06 100644
--- a/db.ts
+++ b/db.ts
@@ -88,6 +88,9 @@ const migrations = [
`
DROP TABLE workouts
`,
+ `
+ ALTER TABLE settings ADD COLUMN color TEXT NULL
+ `,
];
export let db: SQLiteDatabase;
diff --git a/settings.ts b/settings.ts
index 5131da3..869a094 100644
--- a/settings.ts
+++ b/settings.ts
@@ -2,8 +2,9 @@ export default interface Settings {
alarm: number;
vibrate: number;
predict: number;
- sound: string;
- notify: number;
- images: number;
- showUnit: number;
+ sound?: string;
+ notify?: number;
+ images?: number;
+ showUnit?: number;
+ color?: string;
}