Split up dark and light color settings

Previously it was possible to choose a color combination
that was almost impossible to read (due to contrast).
Now we have prevented this from happening, as well as
giving the user more customizability.
This commit is contained in:
Brandon Presley 2022-11-26 13:15:12 +13:00
parent 0c5a221e0f
commit dc27ae9868
9 changed files with 107 additions and 32 deletions

32
App.tsx
View File

@ -43,10 +43,12 @@ const App = () => {
const [snackbar, setSnackbar] = useState('')
const [theme, setTheme] = useState('system')
const [color, setColor] = useState<string>(
isDark
? CombinedDarkTheme.colors.primary
: CombinedDefaultTheme.colors.primary,
const [lightColor, setLightColor] = useState<string>(
CombinedDefaultTheme.colors.primary,
)
const [darkColor, setDarkColor] = useState<string>(
CombinedDarkTheme.colors.primary,
)
useEffect(() => {
@ -55,7 +57,7 @@ const App = () => {
const settings = await settingsRepo.findOne({where: {}})
console.log(`${App.name}.useEffect:`, {gotSettings: settings})
setTheme(settings.theme)
if (settings.color) setColor(settings.color)
if (settings.lightColor) setLightColor(settings.lightColor)
setInitialized(true)
}
init()
@ -70,23 +72,23 @@ const App = () => {
}, [])
const paperTheme = useMemo(() => {
const darkTheme = color
const darkTheme = lightColor
? {
...CombinedDarkTheme,
colors: {...CombinedDarkTheme.colors, primary: color},
colors: {...CombinedDarkTheme.colors, primary: darkColor},
}
: CombinedDarkTheme
const lightTheme = color
const lightTheme = lightColor
? {
...CombinedDefaultTheme,
colors: {...CombinedDefaultTheme.colors, primary: color},
colors: {...CombinedDefaultTheme.colors, primary: lightColor},
}
: CombinedDefaultTheme
let value = isDark ? darkTheme : lightTheme
if (theme === 'dark') value = darkTheme
else if (theme === 'light') value = lightTheme
return value
}, [isDark, theme, color])
}, [isDark, theme, lightColor, darkColor])
const action = useMemo(
() => ({
@ -103,7 +105,15 @@ const App = () => {
settings={{icon: props => <MaterialIcon {...props} />}}>
<NavigationContainer theme={paperTheme}>
{initialized && (
<ThemeContext.Provider value={{theme, setTheme, color, setColor}}>
<ThemeContext.Provider
value={{
theme,
setTheme,
lightColor,
setLightColor,
darkColor,
setDarkColor,
}}>
<Routes />
</ThemeContext.Provider>
)}

View File

@ -1,13 +1,12 @@
import {ComponentProps} from 'react'
import {FAB} from 'react-native-paper'
import {FAB, useTheme} from 'react-native-paper'
import {CombinedDarkTheme, CombinedDefaultTheme} from './App'
import {lightColors} from './colors'
import {useTheme} from './use-theme'
export default function MassiveFab(props: Partial<ComponentProps<typeof FAB>>) {
const {color} = useTheme()
const {colors} = useTheme()
const fabColor = lightColors.includes(color)
const fabColor = lightColors.includes(colors.primary)
? CombinedDarkTheme.colors.background
: CombinedDefaultTheme.colors.background
@ -19,7 +18,7 @@ export default function MassiveFab(props: Partial<ComponentProps<typeof FAB>>) {
position: 'absolute',
right: 20,
bottom: 20,
backgroundColor: color,
backgroundColor: colors.primary,
}}
{...props}
/>

View File

@ -40,7 +40,10 @@ export default function Select({
anchor={
<Button
onPress={() => setShow(true)}
style={{alignSelf: 'flex-start', marginTop: MARGIN}}>
style={{
alignSelf: 'flex-start',
marginTop: MARGIN,
}}>
{selected?.label}
</Button>
}>

View File

@ -36,7 +36,8 @@ export default function SettingsPage() {
const [showUnit, setShowUnit] = useState(false)
const [steps, setSteps] = useState(false)
const [date, setDate] = useState('P')
const {theme, setTheme, color, setColor} = useTheme()
const {theme, setTheme, lightColor, setLightColor, darkColor, setDarkColor} =
useTheme()
const [showDate, setShowDate] = useState(false)
const [noSound, setNoSound] = useState(false)
const [formatOptions, setFormatOptions] = useState<string[]>(defaultFormats)
@ -45,6 +46,7 @@ export default function SettingsPage() {
useFocusEffect(
useCallback(() => {
settingsRepo.findOne({where: {}}).then(settings => {
console.log(`${SettingsPage.name}.focus:`, settings)
setAlarm(settings.alarm)
setVibrate(settings.vibrate)
setSound(settings.sound)
@ -193,12 +195,20 @@ export default function SettingsPage() {
return ': ' + split.pop()
}, [sound])
const changeColor = useCallback(
const changeDarkColor = useCallback(
(value: string) => {
setColor(value)
settingsRepo.update({}, {color: value})
setDarkColor(value)
settingsRepo.update({}, {darkColor: value})
},
[setColor],
[setDarkColor],
)
const changeLightColor = useCallback(
(value: string) => {
setLightColor(value)
settingsRepo.update({}, {lightColor: value})
},
[setLightColor],
)
const renderItem = useCallback(
@ -247,10 +257,21 @@ export default function SettingsPage() {
)}
{'color'.includes(term.toLowerCase()) && (
<Select
value={color}
onChange={changeColor}
items={lightColors.concat(darkColors).map(colorOption => ({
label: 'Primary color',
value={darkColor}
onChange={changeDarkColor}
items={lightColors.map(colorOption => ({
label: 'Dark color',
value: colorOption,
color: colorOption,
}))}
/>
)}
{'color'.includes(term.toLowerCase()) && (
<Select
value={lightColor}
onChange={changeLightColor}
items={darkColors.map(colorOption => ({
label: 'Light color',
value: colorOption,
color: colorOption,
}))}

View File

@ -1,4 +1,7 @@
import {DarkTheme, DefaultTheme} from 'react-native-paper'
export const lightColors = [
DarkTheme.colors.primary,
'#B3E5FC',
'#FA8072',
'#FFC0CB',
@ -6,7 +9,12 @@ export const lightColors = [
'#BBA1CE',
]
export const darkColors = ['#8156A7', '#007AFF', '#000000', '#CD5C5C']
export const darkColors = [
DefaultTheme.colors.primary,
'#007AFF',
'#000000',
'#CD5C5C',
]
export const colorShade = (color: any, amount: number) => {
color = color.replace(/^#/, '')

View File

@ -23,6 +23,7 @@ import {addShowSets1667186443614} from './migrations/1667186443614-add-show-sets
import {addSetsCreated1667186451005} from './migrations/1667186451005-add-sets-created'
import {addNoSound1667186456118} from './migrations/1667186456118-add-no-sound'
import {dropMigrations1667190214743} from './migrations/1667190214743-drop-migrations'
import {splitColor1669420187764} from './migrations/1669420187764-split-color'
import {Plan} from './plan'
import Settings from './settings'
@ -57,5 +58,6 @@ export const AppDataSource = new DataSource({
addSetsCreated1667186451005,
addNoSound1667186456118,
dropMigrations1667190214743,
splitColor1669420187764,
],
})

View File

@ -0,0 +1,24 @@
import {MigrationInterface, QueryRunner, TableColumn} from 'typeorm'
export class splitColor1669420187764 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.addColumn(
'settings',
new TableColumn({name: 'lightColor', type: 'text', isNullable: true}),
)
await queryRunner.addColumn(
'settings',
new TableColumn({name: 'darkColor', type: 'text', isNullable: true}),
)
await queryRunner.dropColumn('settings', 'color')
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.dropColumn('settings', 'darkColor')
await queryRunner.dropColumn('settings', 'lightColor')
await queryRunner.addColumn(
'settings',
new TableColumn({name: 'color', type: 'text', isNullable: true}),
)
}
}

View File

@ -21,7 +21,10 @@ export default class Settings {
showUnit: boolean
@Column('text')
color?: string
lightColor?: string
@Column('text')
darkColor?: string
@Column('boolean')
steps: boolean

View File

@ -1,15 +1,20 @@
import {createContext, useContext} from 'react'
import {DarkTheme, DefaultTheme} from 'react-native-paper'
export const ThemeContext = createContext<{
theme: string
color: string
lightColor: string
setTheme: (value: string) => void
setColor: (value: string) => void
setLightColor: (value: string) => void
darkColor: string
setDarkColor: (value: string) => void
}>({
theme: 'system',
color: '',
lightColor: DefaultTheme.colors.primary,
setTheme: () => null,
setColor: () => null,
setLightColor: () => null,
darkColor: DarkTheme.colors.primary,
setDarkColor: () => null,
})
export function useTheme() {