fix: dark mode inconsistencies

fixes #226
fixes #198
This commit is contained in:
Lei Nelissen
2024-07-22 13:17:26 +02:00
parent 87b08050e4
commit a64f52c4f9
5 changed files with 33 additions and 19 deletions

View File

@@ -3,16 +3,14 @@ import { Provider } from 'react-redux';
import TrackPlayer, { Capability } from 'react-native-track-player'; import TrackPlayer, { Capability } from 'react-native-track-player';
import { PersistGate } from 'redux-persist/integration/react'; import { PersistGate } from 'redux-persist/integration/react';
import Routes from '../screens'; import Routes from '../screens';
import store, { persistedStore, useTypedSelector } from '@/store'; import store, { persistedStore } from '@/store';
import { import {
NavigationContainer, NavigationContainer,
DefaultTheme, DefaultTheme,
DarkTheme as BaseDarkTheme, DarkTheme as BaseDarkTheme,
} from '@react-navigation/native'; } from '@react-navigation/native';
import { ColorSchemeProvider, themes } from './Colors'; import { ColorSchemeProvider, themes, useUserOrSystemScheme } from './Colors';
import DownloadManager from './DownloadManager'; import DownloadManager from './DownloadManager';
import { useColorScheme } from 'react-native';
import { ColorScheme } from '@/store/settings/types';
const LightTheme = { const LightTheme = {
...DefaultTheme, ...DefaultTheme,
@@ -35,9 +33,7 @@ const DarkTheme = {
* right theme is selected based on OS color scheme settings along with user preferences. * right theme is selected based on OS color scheme settings along with user preferences.
*/ */
function ThemedNavigationContainer({ children }: PropsWithChildren<{}>) { function ThemedNavigationContainer({ children }: PropsWithChildren<{}>) {
const systemScheme = useColorScheme(); const scheme = useUserOrSystemScheme();
const userScheme = useTypedSelector((state) => state.settings.colorScheme);
const scheme = userScheme === ColorScheme.System ? systemScheme : userScheme;
return ( return (
<NavigationContainer <NavigationContainer

View File

@@ -108,14 +108,21 @@ export const themes: Record<'dark' | 'light' | 'dark-highcontrast' | 'light-high
// Create context for supplying the theming information // Create context for supplying the theming information
export const ColorSchemeContext = React.createContext(themes.dark); export const ColorSchemeContext = React.createContext(themes.dark);
/**
* This hook returns the proper color scheme, taking into account potential user overrides.
*/
export function useUserOrSystemScheme() {
const systemScheme = useColorScheme();
const userScheme = useTypedSelector((state) => state.settings.colorScheme);
return userScheme === ColorScheme.System ? systemScheme : userScheme;
}
/** /**
* This provider contains the logic for settings the right theme on the ColorSchemeContext. * This provider contains the logic for settings the right theme on the ColorSchemeContext.
*/ */
export function ColorSchemeProvider({ children }: PropsWithChildren<{}>) { export function ColorSchemeProvider({ children }: PropsWithChildren<{}>) {
const systemScheme = useColorScheme();
const highContrast = useAccessibilitySetting('darkerSystemColors'); const highContrast = useAccessibilitySetting('darkerSystemColors');
const userScheme = useTypedSelector((state) => state.settings.colorScheme); const scheme = useUserOrSystemScheme();
const scheme = userScheme === ColorScheme.System ? systemScheme : userScheme;
const theme = highContrast const theme = highContrast
? themes[`${scheme || 'light'}-highcontrast`] ? themes[`${scheme || 'light'}-highcontrast`]
: themes[scheme || 'light']; : themes[scheme || 'light'];

View File

@@ -1,7 +1,7 @@
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { Dimensions, useColorScheme, ViewProps } from 'react-native'; import { Dimensions, ViewProps } from 'react-native';
import { Canvas, Blur, Image as SkiaImage, useImage, Offset, Mask, RoundedRect, Shadow } from '@shopify/react-native-skia'; import { Canvas, Blur, Image as SkiaImage, useImage, Offset, Mask, RoundedRect, Shadow } from '@shopify/react-native-skia';
import useDefaultStyles from './Colors'; import useDefaultStyles, { useUserOrSystemScheme } from './Colors';
import styled from 'styled-components/native'; import styled from 'styled-components/native';
const Screen = Dimensions.get('screen'); const Screen = Dimensions.get('screen');
@@ -45,10 +45,13 @@ function CoverImage({
src, src,
}: Props) { }: Props) {
const defaultStyles = useDefaultStyles(); const defaultStyles = useDefaultStyles();
const colorScheme = useColorScheme(); const colorScheme = useUserOrSystemScheme();
const image = useImage(src || null); const image = useImage(src || null);
const fallback = useImage(colorScheme === 'light' ? require('@/assets/images/empty-album-light.png') : require('@/assets/images/empty-album-dark.png')); const fallback = useImage(colorScheme === 'light'
? require('@/assets/images/empty-album-light.png')
: require('@/assets/images/empty-album-dark.png')
);
const { canvasSize, imageSize } = useMemo(() => { const { canvasSize, imageSize } = useMemo(() => {
const imageSize = Screen.width - margin; const imageSize = Screen.width - margin;
const canvasSize = imageSize + blurRadius * 2; const canvasSize = imageSize + blurRadius * 2;

View File

@@ -1,7 +1,8 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import styled from 'styled-components/native'; import styled from 'styled-components/native';
import FastImage, { FastImageProps } from 'react-native-fast-image'; import FastImage, { FastImageProps } from 'react-native-fast-image';
import { Dimensions, useColorScheme } from 'react-native'; import { Dimensions } from 'react-native';
import { useUserOrSystemScheme } from '@/components/Colors';
const Screen = Dimensions.get('screen'); const Screen = Dimensions.get('screen');
export const AlbumWidth = Screen.width / 2 - 24; export const AlbumWidth = Screen.width / 2 - 24;
@@ -23,11 +24,17 @@ const Container = styled(FastImage)`
function AlbumImage(props: FastImageProps) { function AlbumImage(props: FastImageProps) {
const [hasError, setError] = useState(false); const [hasError, setError] = useState(false);
const colorScheme = useColorScheme(); const colorScheme = useUserOrSystemScheme();
if (!props.source || hasError) { if (!props.source || hasError) {
return ( return (
<Container {...props} source={colorScheme === 'light' ? require('@/assets/images/empty-album-light.png') : require('@/assets/images/empty-album-dark.png')} /> <Container
{...props}
source={colorScheme === 'light'
? require('@/assets/images/empty-album-light.png')
: require('@/assets/images/empty-album-dark.png')
}
/>
); );
} }

View File

@@ -1,12 +1,13 @@
import React from 'react'; import React from 'react';
import TrackPlayer, { State, usePlaybackState } from 'react-native-track-player'; import TrackPlayer, { State, usePlaybackState } from 'react-native-track-player';
import { TouchableOpacity, useColorScheme } from 'react-native'; import { TouchableOpacity } from 'react-native';
import styled from 'styled-components/native'; import styled from 'styled-components/native';
import { useHasNextQueue, useHasPreviousQueue } from '@/utility/useQueue'; import { useHasNextQueue, useHasPreviousQueue } from '@/utility/useQueue';
import ForwardIcon from '@/assets/icons/forward-end.svg'; import ForwardIcon from '@/assets/icons/forward-end.svg';
import BackwardIcon from '@/assets/icons/backward-end.svg'; import BackwardIcon from '@/assets/icons/backward-end.svg';
import PlayIcon from '@/assets/icons/play.svg'; import PlayIcon from '@/assets/icons/play.svg';
import PauseIcon from '@/assets/icons/pause.svg'; import PauseIcon from '@/assets/icons/pause.svg';
import { useUserOrSystemScheme } from '@/components/Colors';
const BUTTON_SIZE = 40; const BUTTON_SIZE = 40;
@@ -33,7 +34,7 @@ const Button = styled.View`
`; `;
export default function MediaControls() { export default function MediaControls() {
const scheme = useColorScheme(); const scheme = useUserOrSystemScheme();
const fill = scheme === 'dark' ? '#ffffff' : '#000000'; const fill = scheme === 'dark' ? '#ffffff' : '#000000';
return ( return (