refactor: consistent theme with dark/light theme possibility
parent
459571979b
commit
14f1c50215
|
|
@ -113,7 +113,7 @@ const Title = styled(Text)(({ theme }) => ({
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
fontSize: 40,
|
fontSize: 40,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
color: theme.colors.black
|
color: theme.colors.fixed.black
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const Container = styled.View({
|
const Container = styled.View({
|
||||||
|
|
@ -135,7 +135,5 @@ const CustomText = styled(Text)(({ theme }) => ({
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
color: theme.colors.white
|
color: theme.colors.fixed.white
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,15 @@ export default function Timer() {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
setCurrentRep(1);
|
||||||
|
setIsWorkPhase(true);
|
||||||
|
setTimeLeft(workTime);
|
||||||
|
setIsRunning(false);
|
||||||
|
setIsFinish(false);
|
||||||
|
cancelNotification();
|
||||||
|
};
|
||||||
|
|
||||||
const nextRep = () => {
|
const nextRep = () => {
|
||||||
if (currentRep < reps) {
|
if (currentRep < reps) {
|
||||||
if (isWorkPhase) {
|
if (isWorkPhase) {
|
||||||
|
|
@ -152,7 +161,7 @@ export default function Timer() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container bgColor={renderBgColor()}>
|
<Container bgColor={renderBgColor()}>
|
||||||
{isFinish && <FinishContent handleStart={handleStart} />}
|
{isFinish && <FinishContent handleStart={handleStart} handleReset={handleReset} />}
|
||||||
|
|
||||||
{!isFinish && (
|
{!isFinish && (
|
||||||
<TimerContent
|
<TimerContent
|
||||||
|
|
@ -164,6 +173,7 @@ export default function Timer() {
|
||||||
isRunning={isRunning}
|
isRunning={isRunning}
|
||||||
nextRep={nextRep}
|
nextRep={nextRep}
|
||||||
previousRep={previousRep}
|
previousRep={previousRep}
|
||||||
|
handleReset={handleReset}
|
||||||
handleStop={handleStop}
|
handleStop={handleStop}
|
||||||
handleContine={handleContine}
|
handleContine={handleContine}
|
||||||
/>
|
/>
|
||||||
|
|
@ -177,6 +187,6 @@ const Container = styled(View)<{ bgColor: TimerBgColor }>(
|
||||||
flex: 1,
|
flex: 1,
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
backgroundColor: theme.colors[bgColor],
|
backgroundColor: theme.colors.fixed[bgColor],
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import FontAwesome from '@expo/vector-icons/FontAwesome';
|
import FontAwesome from '@expo/vector-icons/FontAwesome';
|
||||||
import { ThemeProvider } from '@emotion/react';
|
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 { useFonts } from 'expo-font';
|
||||||
import { Stack } from 'expo-router';
|
import { Stack } from 'expo-router';
|
||||||
import * as SplashScreen from 'expo-splash-screen';
|
import * as SplashScreen from 'expo-splash-screen';
|
||||||
|
|
@ -47,9 +47,11 @@ export default function RootLayout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function RootLayoutNav() {
|
function RootLayoutNav() {
|
||||||
|
const dynamicTheme = useThemeColors();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LanguageProvider>
|
<LanguageProvider>
|
||||||
<ThemeProvider theme={theme}>
|
<ThemeProvider theme={dynamicTheme}>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||||
<Stack.Screen name="Timer" options={{ headerShown: false }} />
|
<Stack.Screen name="Timer" options={{ headerShown: false }} />
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
export const colors = {
|
|
||||||
black: '#000000',
|
|
||||||
white: '#FFFFFF',
|
|
||||||
red: '#FF4141',
|
|
||||||
green: '#3AC26E',
|
|
||||||
grey: '#F9F9F9',
|
|
||||||
} as const;
|
|
||||||
|
|
@ -1,14 +1,22 @@
|
||||||
import { colors } from './colors';
|
import Colors from '@/constants/Colors';
|
||||||
import { layout } from './layout';
|
import { layout } from './layout';
|
||||||
|
import { useColorScheme } from 'react-native';
|
||||||
|
|
||||||
export const theme = {
|
export const theme = {
|
||||||
colors,
|
colors: Colors,
|
||||||
layout
|
layout
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useThemeColors = () => {
|
||||||
|
const colorScheme = useColorScheme() ?? 'light';
|
||||||
|
return {
|
||||||
|
...theme,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
declare module '@emotion/react' {
|
declare module '@emotion/react' {
|
||||||
export interface Theme {
|
export interface Theme {
|
||||||
colors: typeof colors;
|
colors: typeof Colors;
|
||||||
layout: typeof layout;
|
layout: typeof layout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,9 @@ const Container = styled.TouchableOpacity<{
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
secondary: boolean;
|
secondary: boolean;
|
||||||
}>(({ theme, bgColor, secondary }) => ({
|
}>(({ theme, bgColor, secondary }) => ({
|
||||||
backgroundColor: theme.colors[bgColor],
|
backgroundColor: theme.colors.fixed[bgColor],
|
||||||
borderWidth: secondary ? 1 : 0,
|
borderWidth: secondary ? 1 : 0,
|
||||||
borderColor: theme.colors[bgColor],
|
borderColor: theme.colors.fixed[bgColor],
|
||||||
borderRadius: 6,
|
borderRadius: 6,
|
||||||
height: theme.layout.gridUnit * 12,
|
height: theme.layout.gridUnit * 12,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
|
|
@ -81,13 +81,13 @@ const Container = styled.TouchableOpacity<{
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const Label = styled(Text)<{ color: LabelColor }>(({ theme, color }) => ({
|
const Label = styled(Text)<{ color: LabelColor }>(({ theme, color }) => ({
|
||||||
color: theme.colors[color],
|
color: theme.colors.fixed[color],
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: 'semibold',
|
fontWeight: 'semibold',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const SecondaryLabel = styled(Text)<{ bgColor: ButtonColor }>(({ theme, bgColor }) => ({
|
const SecondaryLabel = styled(Text)<{ bgColor: ButtonColor }>(({ theme, bgColor }) => ({
|
||||||
color: theme.colors[bgColor],
|
color: theme.colors.fixed[bgColor],
|
||||||
fontWeight: 'semibold',
|
fontWeight: 'semibold',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
@ -97,4 +97,3 @@ const IconContainer = styled.View(({ theme }) => ({
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ const Container = styled.View<{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
borderRadius: 10,
|
borderRadius: 10,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
backgroundColor: theme.colors[bgColor]
|
backgroundColor: theme.colors.fixed[bgColor]
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default Card;
|
export default Card;
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,5 @@ const CustomText = styled(Text)(({ theme }) => ({
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
color: theme.colors.white
|
color: theme.colors.fixed.white
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,22 @@ import { i18n } from '@/app/i18n/i18n';
|
||||||
|
|
||||||
type FinishContentProps = {
|
type FinishContentProps = {
|
||||||
handleStart: () => void;
|
handleStart: () => void;
|
||||||
|
handleReset: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const t = i18n.scoped('timer.finishContent');
|
const t = i18n.scoped('timer.finishContent');
|
||||||
|
|
||||||
export default function FinishContent({
|
export default function FinishContent({
|
||||||
handleStart
|
handleStart,
|
||||||
|
handleReset
|
||||||
}: FinishContentProps) {
|
}: FinishContentProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const handleBackClick = () => {
|
||||||
|
router.push('/');
|
||||||
|
handleReset();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Time>{t('finish')}</Time>
|
<Time>{t('finish')}</Time>
|
||||||
|
|
@ -29,7 +36,7 @@ export default function FinishContent({
|
||||||
|
|
||||||
<HorizontalSpacer widthUnits={3} />
|
<HorizontalSpacer widthUnits={3} />
|
||||||
|
|
||||||
<Button label={i18n.t('back')} onPress={() => router.push('/')} />
|
<Button label={i18n.t('back')} onPress={handleBackClick} />
|
||||||
</Row>
|
</Row>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
@ -43,5 +50,5 @@ const Row = styled(View)(() => ({
|
||||||
const Time = styled(Text)(({ theme }) => ({
|
const Time = styled(Text)(({ theme }) => ({
|
||||||
fontSize: 70,
|
fontSize: 70,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
color: theme.colors.white
|
color: theme.colors.fixed.white
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ interface TimerContentProps {
|
||||||
nextRep: () => void;
|
nextRep: () => void;
|
||||||
previousRep: () => void;
|
previousRep: () => void;
|
||||||
bgColor: TimerBgColor;
|
bgColor: TimerBgColor;
|
||||||
|
handleReset: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const t = i18n.scoped('timer.timerContent');
|
const t = i18n.scoped('timer.timerContent');
|
||||||
|
|
@ -31,12 +32,18 @@ export default function TimerContent({
|
||||||
isRunning,
|
isRunning,
|
||||||
handleStop,
|
handleStop,
|
||||||
handleContine,
|
handleContine,
|
||||||
|
handleReset,
|
||||||
nextRep,
|
nextRep,
|
||||||
previousRep,
|
previousRep,
|
||||||
bgColor,
|
bgColor,
|
||||||
}: TimerContentProps ) {
|
}: TimerContentProps ) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const handleBackClick = () => {
|
||||||
|
router.push('/');
|
||||||
|
handleReset();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Title>{isWorkPhase ? t('fight') : t('rest')}</Title>
|
<Title>{isWorkPhase ? t('fight') : t('rest')}</Title>
|
||||||
|
|
@ -71,13 +78,13 @@ export default function TimerContent({
|
||||||
|
|
||||||
<VerticalSpacer heightUnits={4} />
|
<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 }) => ({
|
const ButtonContainer = styled(View)<{ bgColor: TimerBgColor }>(({ theme, bgColor }) => ({
|
||||||
backgroundColor: theme.colors[bgColor],
|
backgroundColor: theme.colors.fixed[bgColor],
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
}));
|
}));
|
||||||
|
|
@ -85,17 +92,17 @@ const ButtonContainer = styled(View)<{ bgColor: TimerBgColor }>(({ theme, bgColo
|
||||||
const Title = styled(Text)(({ theme }) => ({
|
const Title = styled(Text)(({ theme }) => ({
|
||||||
fontSize: 50,
|
fontSize: 50,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
color: theme.colors.white
|
color: theme.colors.fixed.white
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const Time = styled(Text)(({ theme }) => ({
|
const Time = styled(Text)(({ theme }) => ({
|
||||||
fontSize: 100,
|
fontSize: 100,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
color: theme.colors.white
|
color: theme.colors.fixed.white
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const Reps = styled(Text)(({ theme }) => ({
|
const Reps = styled(Text)(({ theme }) => ({
|
||||||
fontSize: 30,
|
fontSize: 30,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
color: theme.colors.white
|
color: theme.colors.fixed.white
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,33 @@
|
||||||
const tintColorLight = '#2f95dc';
|
const baseColors = {
|
||||||
const tintColorDark = '#fff';
|
black: '#000000',
|
||||||
|
white: '#FFFFFF',
|
||||||
|
red: '#FF4141',
|
||||||
|
green: '#3AC26E',
|
||||||
|
grey: '#F9F9F9',
|
||||||
|
} as const;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
fixed: {
|
||||||
|
...baseColors,
|
||||||
|
},
|
||||||
|
// LightTheme
|
||||||
light: {
|
light: {
|
||||||
text: '#000',
|
primary: '#007AFF',
|
||||||
background: '#fff',
|
secondary: '#5856D6',
|
||||||
tint: tintColorLight,
|
error: baseColors.red,
|
||||||
tabIconDefault: '#ccc',
|
success: baseColors.green,
|
||||||
tabIconSelected: tintColorLight,
|
background: baseColors.white,
|
||||||
|
surface: '#F2F2F7',
|
||||||
|
text: baseColors.black,
|
||||||
},
|
},
|
||||||
|
// DarkTheme
|
||||||
dark: {
|
dark: {
|
||||||
text: '#fff',
|
primary: '#0A84FF',
|
||||||
background: '#000',
|
secondary: '#5E5CE6',
|
||||||
tint: tintColorDark,
|
error: '#FF453A',
|
||||||
tabIconDefault: '#ccc',
|
success: '#32D74B',
|
||||||
tabIconSelected: tintColorDark,
|
background: baseColors.black,
|
||||||
|
surface: '#1C1C1E',
|
||||||
|
text: baseColors.white,
|
||||||
},
|
},
|
||||||
};
|
} as const;
|
||||||
Loading…
Reference in New Issue