refactor: consistent theme with dark/light theme possibility

main
Torpenn 2025-04-08 21:44:56 +02:00
parent 459571979b
commit 14f1c50215
No known key found for this signature in database
GPG Key ID: 56C8A89C974E3ED2
11 changed files with 84 additions and 47 deletions

View File

@ -113,7 +113,7 @@ const Title = styled(Text)(({ theme }) => ({
textAlign: 'center',
fontSize: 40,
fontWeight: 'bold',
color: theme.colors.black
color: theme.colors.fixed.black
}));
const Container = styled.View({
@ -135,7 +135,5 @@ const CustomText = styled(Text)(({ theme }) => ({
fontSize: 20,
fontWeight: 'bold',
textAlign: 'center',
color: theme.colors.white
color: theme.colors.fixed.white
}))

View File

@ -102,6 +102,15 @@ export default function Timer() {
);
};
const handleReset = () => {
setCurrentRep(1);
setIsWorkPhase(true);
setTimeLeft(workTime);
setIsRunning(false);
setIsFinish(false);
cancelNotification();
};
const nextRep = () => {
if (currentRep < reps) {
if (isWorkPhase) {
@ -152,7 +161,7 @@ export default function Timer() {
return (
<Container bgColor={renderBgColor()}>
{isFinish && <FinishContent handleStart={handleStart} />}
{isFinish && <FinishContent handleStart={handleStart} handleReset={handleReset} />}
{!isFinish && (
<TimerContent
@ -164,6 +173,7 @@ export default function Timer() {
isRunning={isRunning}
nextRep={nextRep}
previousRep={previousRep}
handleReset={handleReset}
handleStop={handleStop}
handleContine={handleContine}
/>
@ -177,6 +187,6 @@ const Container = styled(View)<{ bgColor: TimerBgColor }>(
flex: 1,
alignItems: "center",
justifyContent: "center",
backgroundColor: theme.colors[bgColor],
backgroundColor: theme.colors.fixed[bgColor],
}),
);

View File

@ -1,6 +1,6 @@
import FontAwesome from '@expo/vector-icons/FontAwesome';
import { ThemeProvider } from '@emotion/react';
import { theme } from '@/app/shared/theme/index';
import { useThemeColors } from '@/app/shared/theme/index';
import { useFonts } from 'expo-font';
import { Stack } from 'expo-router';
import * as SplashScreen from 'expo-splash-screen';
@ -47,9 +47,11 @@ export default function RootLayout() {
}
function RootLayoutNav() {
const dynamicTheme = useThemeColors();
return (
<LanguageProvider>
<ThemeProvider theme={theme}>
<ThemeProvider theme={dynamicTheme}>
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="Timer" options={{ headerShown: false }} />

View File

@ -1,7 +0,0 @@
export const colors = {
black: '#000000',
white: '#FFFFFF',
red: '#FF4141',
green: '#3AC26E',
grey: '#F9F9F9',
} as const;

View File

@ -1,14 +1,22 @@
import { colors } from './colors';
import Colors from '@/constants/Colors';
import { layout } from './layout';
import { useColorScheme } from 'react-native';
export const theme = {
colors,
colors: Colors,
layout
};
export const useThemeColors = () => {
const colorScheme = useColorScheme() ?? 'light';
return {
...theme,
};
};
declare module '@emotion/react' {
export interface Theme {
colors: typeof colors;
colors: typeof Colors;
layout: typeof layout;
}
}

View File

@ -69,9 +69,9 @@ const Container = styled.TouchableOpacity<{
disabled: boolean;
secondary: boolean;
}>(({ theme, bgColor, secondary }) => ({
backgroundColor: theme.colors[bgColor],
backgroundColor: theme.colors.fixed[bgColor],
borderWidth: secondary ? 1 : 0,
borderColor: theme.colors[bgColor],
borderColor: theme.colors.fixed[bgColor],
borderRadius: 6,
height: theme.layout.gridUnit * 12,
justifyContent: 'center',
@ -81,13 +81,13 @@ const Container = styled.TouchableOpacity<{
}));
const Label = styled(Text)<{ color: LabelColor }>(({ theme, color }) => ({
color: theme.colors[color],
color: theme.colors.fixed[color],
fontSize: 16,
fontWeight: 'semibold',
}));
const SecondaryLabel = styled(Text)<{ bgColor: ButtonColor }>(({ theme, bgColor }) => ({
color: theme.colors[bgColor],
color: theme.colors.fixed[bgColor],
fontWeight: 'semibold',
}));
@ -97,4 +97,3 @@ const IconContainer = styled.View(({ theme }) => ({
alignItems: 'center',
justifyContent: 'center',
}));

View File

@ -43,7 +43,7 @@ const Container = styled.View<{
width: '100%',
borderRadius: 10,
overflow: 'hidden',
backgroundColor: theme.colors[bgColor]
backgroundColor: theme.colors.fixed[bgColor]
}));
export default Card;

View File

@ -42,6 +42,5 @@ const CustomText = styled(Text)(({ theme }) => ({
fontSize: 20,
fontWeight: 'bold',
textAlign: 'center',
color: theme.colors.white
color: theme.colors.fixed.white
}))

View File

@ -9,15 +9,22 @@ import { i18n } from '@/app/i18n/i18n';
type FinishContentProps = {
handleStart: () => void;
handleReset: () => void;
};
const t = i18n.scoped('timer.finishContent');
export default function FinishContent({
handleStart
handleStart,
handleReset
}: FinishContentProps) {
const router = useRouter();
const handleBackClick = () => {
router.push('/');
handleReset();
};
return (
<>
<Time>{t('finish')}</Time>
@ -29,7 +36,7 @@ export default function FinishContent({
<HorizontalSpacer widthUnits={3} />
<Button label={i18n.t('back')} onPress={() => router.push('/')} />
<Button label={i18n.t('back')} onPress={handleBackClick} />
</Row>
</>
);
@ -43,5 +50,5 @@ const Row = styled(View)(() => ({
const Time = styled(Text)(({ theme }) => ({
fontSize: 70,
fontWeight: 'bold',
color: theme.colors.white
color: theme.colors.fixed.white
}));

View File

@ -19,6 +19,7 @@ interface TimerContentProps {
nextRep: () => void;
previousRep: () => void;
bgColor: TimerBgColor;
handleReset: () => void;
}
const t = i18n.scoped('timer.timerContent');
@ -31,12 +32,18 @@ export default function TimerContent({
isRunning,
handleStop,
handleContine,
handleReset,
nextRep,
previousRep,
bgColor,
}: TimerContentProps ) {
const router = useRouter();
const handleBackClick = () => {
router.push('/');
handleReset();
};
return (
<>
<Title>{isWorkPhase ? t('fight') : t('rest')}</Title>
@ -71,13 +78,13 @@ export default function TimerContent({
<VerticalSpacer heightUnits={4} />
<Button label={i18n.t('back')} onPress={() => router.push('/')} />
<Button label={i18n.t('back')} onPress={handleBackClick} />
</>
);
}
const ButtonContainer = styled(View)<{ bgColor: TimerBgColor }>(({ theme, bgColor }) => ({
backgroundColor: theme.colors[bgColor],
backgroundColor: theme.colors.fixed[bgColor],
flexDirection: 'row',
justifyContent: 'space-between',
}));
@ -85,17 +92,17 @@ const ButtonContainer = styled(View)<{ bgColor: TimerBgColor }>(({ theme, bgColo
const Title = styled(Text)(({ theme }) => ({
fontSize: 50,
fontWeight: 'bold',
color: theme.colors.white
color: theme.colors.fixed.white
}));
const Time = styled(Text)(({ theme }) => ({
fontSize: 100,
fontWeight: 'bold',
color: theme.colors.white
color: theme.colors.fixed.white
}));
const Reps = styled(Text)(({ theme }) => ({
fontSize: 30,
fontWeight: 'bold',
color: theme.colors.white
color: theme.colors.fixed.white
}));

View File

@ -1,19 +1,33 @@
const tintColorLight = '#2f95dc';
const tintColorDark = '#fff';
const baseColors = {
black: '#000000',
white: '#FFFFFF',
red: '#FF4141',
green: '#3AC26E',
grey: '#F9F9F9',
} as const;
export default {
fixed: {
...baseColors,
},
// LightTheme
light: {
text: '#000',
background: '#fff',
tint: tintColorLight,
tabIconDefault: '#ccc',
tabIconSelected: tintColorLight,
primary: '#007AFF',
secondary: '#5856D6',
error: baseColors.red,
success: baseColors.green,
background: baseColors.white,
surface: '#F2F2F7',
text: baseColors.black,
},
// DarkTheme
dark: {
text: '#fff',
background: '#000',
tint: tintColorDark,
tabIconDefault: '#ccc',
tabIconSelected: tintColorDark,
primary: '#0A84FF',
secondary: '#5E5CE6',
error: '#FF453A',
success: '#32D74B',
background: baseColors.black,
surface: '#1C1C1E',
text: baseColors.white,
},
};
} as const;