Refactor CalendarSection and CalendarScreen components to integrate theme context for improved UI consistency

This update enhances the CalendarSection and CalendarScreen components by incorporating the ThemeContext, allowing for dynamic theming throughout the calendar interface. Styles have been adjusted to reflect the current theme colors, improving visual consistency and user experience. Key changes include updates to button styles, text colors, and background settings, ensuring a cohesive interface that adapts to different themes. Additionally, the CalendarSection's date handling logic has been optimized for better performance.
This commit is contained in:
tapframe 2025-05-04 02:44:38 +05:30
parent 9ab154f8b8
commit 29347ee028
3 changed files with 276 additions and 311 deletions

View file

@ -1,4 +1,4 @@
import React, { useState, useRef, useEffect } from 'react'; import React, { useState, useRef, useEffect, useCallback } from 'react';
import { import {
View, View,
Text, Text,
@ -8,24 +8,14 @@ import {
Dimensions Dimensions
} from 'react-native'; } from 'react-native';
import { MaterialIcons } from '@expo/vector-icons'; import { MaterialIcons } from '@expo/vector-icons';
import { colors } from '../../styles/colors'; import { format, addMonths, subMonths, startOfMonth, endOfMonth, eachDayOfInterval, isSameMonth, isToday, isSameDay } from 'date-fns';
import {
format,
addMonths,
subMonths,
startOfMonth,
endOfMonth,
isSameMonth,
isSameDay,
getDay,
isToday,
parseISO
} from 'date-fns';
import Animated, { FadeIn } from 'react-native-reanimated'; import Animated, { FadeIn } from 'react-native-reanimated';
import { useTheme } from '../../contexts/ThemeContext';
const { width } = Dimensions.get('window'); const { width } = Dimensions.get('window');
const COLUMN_COUNT = 7; // 7 days in a week const COLUMN_COUNT = 7; // 7 days in a week
const DAY_ITEM_SIZE = width / 9; // Slightly smaller than 1/7 to fit all days const DAY_ITEM_SIZE = (width - 32 - 56) / 7; // Slightly smaller than 1/7 to fit all days
const weekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
interface CalendarEpisode { interface CalendarEpisode {
id: string; id: string;
@ -54,37 +44,40 @@ const DayItem = ({
isSelected, isSelected,
hasEvents, hasEvents,
onPress onPress
}: DayItemProps) => ( }: DayItemProps) => {
<TouchableOpacity const { currentTheme } = useTheme();
style={[ return (
styles.dayItem, <TouchableOpacity
today && styles.todayItem, style={[
isSelected && styles.selectedItem, styles.dayButton,
hasEvents && styles.dayWithEvents today && styles.todayItem,
]} isSelected && styles.selectedItem,
onPress={() => onPress(date)} hasEvents && styles.dayWithEvents
> ]}
<Text style={[ onPress={() => onPress(date)}
styles.dayText, >
!isCurrentMonth && styles.otherMonthDay, <Text style={[
today && styles.todayText, styles.dayText,
isSelected && styles.selectedDayText !isCurrentMonth && { color: currentTheme.colors.lightGray + '80' },
]}> today && styles.todayText,
{date.getDate()} isSelected && styles.selectedDayText
</Text> ]}>
{hasEvents && ( {date.getDate()}
<View style={styles.eventIndicator} /> </Text>
)} {hasEvents && (
</TouchableOpacity> <View style={[styles.eventIndicator, { backgroundColor: currentTheme.colors.primary }]} />
); )}
</TouchableOpacity>
);
};
export const CalendarSection: React.FC<CalendarSectionProps> = ({ export const CalendarSection: React.FC<CalendarSectionProps> = ({
episodes = [], episodes = [],
onSelectDate onSelectDate
}) => { }) => {
console.log(`[CalendarSection] Rendering with ${episodes.length} episodes`); const { currentTheme } = useTheme();
const [currentDate, setCurrentDate] = useState(new Date()); const [currentDate, setCurrentDate] = useState(new Date());
const [selectedDate, setSelectedDate] = useState(new Date()); const [selectedDate, setSelectedDate] = useState<Date | null>(null);
const scrollViewRef = useRef<ScrollView>(null); const scrollViewRef = useRef<ScrollView>(null);
// Map of dates with episodes // Map of dates with episodes
@ -97,7 +90,7 @@ export const CalendarSection: React.FC<CalendarSectionProps> = ({
episodes.forEach(episode => { episodes.forEach(episode => {
if (episode.releaseDate) { if (episode.releaseDate) {
const releaseDate = parseISO(episode.releaseDate); const releaseDate = new Date(episode.releaseDate);
const dateKey = format(releaseDate, 'yyyy-MM-dd'); const dateKey = format(releaseDate, 'yyyy-MM-dd');
dateMap[dateKey] = true; dateMap[dateKey] = true;
} }
@ -107,201 +100,194 @@ export const CalendarSection: React.FC<CalendarSectionProps> = ({
setDatesWithEpisodes(dateMap); setDatesWithEpisodes(dateMap);
}, [episodes]); }, [episodes]);
const goToPreviousMonth = () => { const goToPreviousMonth = useCallback(() => {
setCurrentDate(prevDate => subMonths(prevDate, 1)); setCurrentDate(prev => subMonths(prev, 1));
}; }, []);
const goToNextMonth = () => { const goToNextMonth = useCallback(() => {
setCurrentDate(prevDate => addMonths(prevDate, 1)); setCurrentDate(prev => addMonths(prev, 1));
}; }, []);
const handleDayPress = (date: Date) => { const handleDateSelect = useCallback((date: Date) => {
setSelectedDate(date); setSelectedDate(date);
if (onSelectDate) { onSelectDate?.(date);
onSelectDate(date); }, [onSelectDate]);
const renderDays = () => {
const start = startOfMonth(currentDate);
const end = endOfMonth(currentDate);
const days = eachDayOfInterval({ start, end });
// Get the day of the week for the first day (0-6)
const firstDayOfWeek = start.getDay();
// Add empty days at the start
const emptyDays = Array(firstDayOfWeek).fill(null);
// Calculate remaining days to fill the last row
const totalDays = emptyDays.length + days.length;
const remainingDays = 7 - (totalDays % 7);
const endEmptyDays = remainingDays === 7 ? [] : Array(remainingDays).fill(null);
const allDays = [...emptyDays, ...days, ...endEmptyDays];
const weeks = [];
for (let i = 0; i < allDays.length; i += 7) {
weeks.push(allDays.slice(i, i + 7));
} }
return weeks.map((week, weekIndex) => (
<View key={weekIndex} style={styles.weekRow}>
{week.map((day, dayIndex) => {
if (!day) {
return <View key={`empty-${dayIndex}`} style={styles.emptyDay} />;
}
const isCurrentMonth = isSameMonth(day, currentDate);
const isCurrentDay = isToday(day);
const isSelected = selectedDate && isSameDay(day, selectedDate);
const hasEvents = datesWithEpisodes[format(day, 'yyyy-MM-dd')] || false;
return (
<TouchableOpacity
key={day.toISOString()}
style={[
styles.dayButton,
isCurrentDay && [styles.todayItem, { backgroundColor: currentTheme.colors.primary + '30', borderColor: currentTheme.colors.primary }],
isSelected && [styles.selectedItem, { backgroundColor: currentTheme.colors.primary + '60', borderColor: currentTheme.colors.primary }],
hasEvents && styles.dayWithEvents
]}
onPress={() => handleDateSelect(day)}
>
<Text
style={[
styles.dayText,
{ color: currentTheme.colors.text },
!isCurrentMonth && { color: currentTheme.colors.lightGray + '80' },
isCurrentDay && [styles.todayText, { color: currentTheme.colors.primary }],
isSelected && [styles.selectedDayText, { color: currentTheme.colors.text }]
]}
>
{format(day, 'd')}
</Text>
{hasEvents && (
<View style={[styles.eventDot, { backgroundColor: currentTheme.colors.primary }]} />
)}
</TouchableOpacity>
);
})}
</View>
));
}; };
// Generate days for the current month view
const generateDaysForMonth = () => {
const monthStart = startOfMonth(currentDate);
const monthEnd = endOfMonth(currentDate);
const startDate = new Date(monthStart);
// Adjust the start date to the beginning of the week
const dayOfWeek = getDay(startDate);
startDate.setDate(startDate.getDate() - dayOfWeek);
// Ensure we have 6 complete weeks in our view
const endDate = new Date(monthEnd);
const lastDayOfWeek = getDay(endDate);
if (lastDayOfWeek < 6) {
endDate.setDate(endDate.getDate() + (6 - lastDayOfWeek));
}
// Get dates for a complete 6-week calendar
const totalDaysNeeded = 42; // 6 weeks × 7 days
const daysInView = [];
let currentDateInView = new Date(startDate);
for (let i = 0; i < totalDaysNeeded; i++) {
daysInView.push(new Date(currentDateInView));
currentDateInView.setDate(currentDateInView.getDate() + 1);
}
return daysInView;
};
const dayItems = generateDaysForMonth();
// Break days into rows (6 rows of 7 days each)
const rows = [];
for (let i = 0; i < dayItems.length; i += COLUMN_COUNT) {
rows.push(dayItems.slice(i, i + COLUMN_COUNT));
}
// Get weekday names for header
const weekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
return ( return (
<Animated.View entering={FadeIn.duration(300)} style={styles.container}> <View style={[styles.container, { backgroundColor: currentTheme.colors.darkBackground }]}>
<View style={styles.header}> <View style={[styles.header, { borderBottomColor: currentTheme.colors.border }]}>
<TouchableOpacity onPress={goToPreviousMonth} style={styles.headerButton}> <TouchableOpacity
<MaterialIcons name="chevron-left" size={24} color={colors.text} /> onPress={goToPreviousMonth}
style={styles.headerButton}
>
<MaterialIcons name="chevron-left" size={24} color={currentTheme.colors.text} />
</TouchableOpacity> </TouchableOpacity>
<Text style={styles.monthTitle}> <Text style={[styles.headerTitle, { color: currentTheme.colors.text }]}>
{format(currentDate, 'MMMM yyyy')} {format(currentDate, 'MMMM yyyy')}
</Text> </Text>
<TouchableOpacity onPress={goToNextMonth} style={styles.headerButton}> <TouchableOpacity
<MaterialIcons name="chevron-right" size={24} color={colors.text} /> onPress={goToNextMonth}
style={styles.headerButton}
>
<MaterialIcons name="chevron-right" size={24} color={currentTheme.colors.text} />
</TouchableOpacity> </TouchableOpacity>
</View> </View>
<View style={styles.weekHeader}> <View style={styles.weekDaysContainer}>
{weekDays.map((day, index) => ( {weekDays.map((day, index) => (
<View key={index} style={styles.weekHeaderItem}> <Text
<Text style={styles.weekDayText}>{day}</Text> key={index}
</View> style={[styles.weekDayText, { color: currentTheme.colors.lightGray }]}
>
{day}
</Text>
))} ))}
</View> </View>
<View style={styles.calendarGrid}> <View style={styles.daysContainer}>
{rows.map((row, rowIndex) => ( {renderDays()}
<View key={rowIndex} style={styles.row}>
{row.map((date, cellIndex) => {
const isCurrentMonthDay = isSameMonth(date, currentDate);
const isSelectedToday = isToday(date);
const isDateSelected = isSameDay(date, selectedDate);
// Check if this date has episodes
const dateKey = format(date, 'yyyy-MM-dd');
const hasEvents = datesWithEpisodes[dateKey] || false;
// Log every 7 days to avoid console spam
if (cellIndex === 0 && rowIndex === 0) {
console.log(`[CalendarSection] Sample date check - ${dateKey}: hasEvents=${hasEvents}`);
}
return (
<DayItem
key={cellIndex}
date={date}
isCurrentMonth={isCurrentMonthDay}
isToday={isSelectedToday}
isSelected={isDateSelected}
hasEvents={hasEvents}
onPress={handleDayPress}
/>
);
})}
</View>
))}
</View> </View>
</Animated.View> </View>
); );
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
backgroundColor: colors.darkBackground, width: '100%',
marginBottom: 12,
borderRadius: 8,
overflow: 'hidden',
borderWidth: 1,
borderColor: colors.border,
}, },
header: { header: {
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between', justifyContent: 'space-between',
paddingVertical: 12, alignItems: 'center',
paddingHorizontal: 16, padding: 16,
borderBottomWidth: 1, borderBottomWidth: 1,
borderBottomColor: colors.border,
}, },
headerButton: { headerButton: {
padding: 8, padding: 8,
}, },
monthTitle: { headerTitle: {
fontSize: 18, fontSize: 18,
fontWeight: 'bold', fontWeight: 'bold',
color: colors.text,
}, },
weekHeader: { weekDaysContainer: {
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'space-around',
padding: 8, padding: 8,
borderBottomWidth: 1,
borderBottomColor: colors.border,
},
weekHeaderItem: {
width: DAY_ITEM_SIZE,
alignItems: 'center',
}, },
weekDayText: { weekDayText: {
fontSize: 12, fontSize: 12,
color: colors.lightGray,
}, },
calendarGrid: { daysContainer: {
padding: 8, padding: 8,
}, },
row: { weekRow: {
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'space-around', justifyContent: 'space-around',
marginBottom: 8, marginBottom: 8,
}, },
dayItem: { dayButton: {
width: DAY_ITEM_SIZE, width: 36,
height: DAY_ITEM_SIZE, height: 36,
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
borderRadius: DAY_ITEM_SIZE / 2, borderRadius: 18,
borderWidth: 1,
borderColor: 'transparent',
}, },
dayText: { dayText: {
fontSize: 14, fontSize: 14,
color: colors.text,
}, },
otherMonthDay: { emptyDay: {
color: colors.lightGray + '80', // 50% opacity width: 36,
height: 36,
},
eventDot: {
width: 4,
height: 4,
borderRadius: 2,
position: 'absolute',
bottom: 6,
}, },
todayItem: { todayItem: {
backgroundColor: colors.primary + '30', // 30% opacity
borderWidth: 1, borderWidth: 1,
borderColor: colors.primary,
}, },
selectedItem: { selectedItem: {
backgroundColor: colors.primary + '60', // 60% opacity
borderWidth: 1, borderWidth: 1,
borderColor: colors.primary,
}, },
todayText: { todayText: {
fontWeight: 'bold', fontWeight: 'bold',
color: colors.primary,
}, },
selectedDayText: { selectedDayText: {
fontWeight: 'bold', fontWeight: 'bold',
color: colors.text,
}, },
dayWithEvents: { dayWithEvents: {
position: 'relative', position: 'relative',
@ -312,6 +298,5 @@ const styles = StyleSheet.create({
width: 4, width: 4,
height: 4, height: 4,
borderRadius: 2, borderRadius: 2,
backgroundColor: colors.primary,
}, },
}); });

View file

@ -9,7 +9,6 @@ import {
RefreshControl, RefreshControl,
SafeAreaView, SafeAreaView,
StatusBar, StatusBar,
useColorScheme,
Dimensions, Dimensions,
SectionList SectionList
} from 'react-native'; } from 'react-native';
@ -18,7 +17,7 @@ import { NavigationProp } from '@react-navigation/native';
import { Image } from 'expo-image'; import { Image } from 'expo-image';
import { MaterialIcons } from '@expo/vector-icons'; import { MaterialIcons } from '@expo/vector-icons';
import { LinearGradient } from 'expo-linear-gradient'; import { LinearGradient } from 'expo-linear-gradient';
import { colors } from '../styles/colors'; import { useTheme } from '../contexts/ThemeContext';
import { RootStackParamList } from '../navigation/AppNavigator'; import { RootStackParamList } from '../navigation/AppNavigator';
import { stremioService } from '../services/stremioService'; import { stremioService } from '../services/stremioService';
import { useLibrary } from '../hooks/useLibrary'; import { useLibrary } from '../hooks/useLibrary';
@ -53,6 +52,7 @@ interface CalendarSection {
const CalendarScreen = () => { const CalendarScreen = () => {
const navigation = useNavigation<NavigationProp<RootStackParamList>>(); const navigation = useNavigation<NavigationProp<RootStackParamList>>();
const { libraryItems, loading: libraryLoading } = useLibrary(); const { libraryItems, loading: libraryLoading } = useLibrary();
const { currentTheme } = useTheme();
logger.log(`[Calendar] Initial load - Library has ${libraryItems?.length || 0} items, loading: ${libraryLoading}`); logger.log(`[Calendar] Initial load - Library has ${libraryItems?.length || 0} items, loading: ${libraryLoading}`);
const [calendarData, setCalendarData] = useState<CalendarSection[]>([]); const [calendarData, setCalendarData] = useState<CalendarSection[]>([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
@ -270,7 +270,7 @@ const CalendarScreen = () => {
return ( return (
<Animated.View entering={FadeIn.duration(300).delay(100)}> <Animated.View entering={FadeIn.duration(300).delay(100)}>
<TouchableOpacity <TouchableOpacity
style={styles.episodeItem} style={[styles.episodeItem, { borderBottomColor: currentTheme.colors.border + '20' }]}
onPress={() => handleEpisodePress(item)} onPress={() => handleEpisodePress(item)}
activeOpacity={0.7} activeOpacity={0.7}
> >
@ -287,18 +287,18 @@ const CalendarScreen = () => {
</TouchableOpacity> </TouchableOpacity>
<View style={styles.episodeDetails}> <View style={styles.episodeDetails}>
<Text style={styles.seriesName} numberOfLines={1}> <Text style={[styles.seriesName, { color: currentTheme.colors.text }]} numberOfLines={1}>
{item.seriesName} {item.seriesName}
</Text> </Text>
{hasReleaseDate ? ( {hasReleaseDate ? (
<> <>
<Text style={styles.episodeTitle} numberOfLines={2}> <Text style={[styles.episodeTitle, { color: currentTheme.colors.lightGray }]} numberOfLines={2}>
S{item.season}:E{item.episode} - {item.title} S{item.season}:E{item.episode} - {item.title}
</Text> </Text>
{item.overview ? ( {item.overview ? (
<Text style={styles.overview} numberOfLines={2}> <Text style={[styles.overview, { color: currentTheme.colors.lightGray }]} numberOfLines={2}>
{item.overview} {item.overview}
</Text> </Text>
) : null} ) : null}
@ -308,9 +308,9 @@ const CalendarScreen = () => {
<MaterialIcons <MaterialIcons
name={isFuture ? "event" : "event-available"} name={isFuture ? "event" : "event-available"}
size={16} size={16}
color={colors.lightGray} color={currentTheme.colors.lightGray}
/> />
<Text style={styles.date}>{formattedDate}</Text> <Text style={[styles.date, { color: currentTheme.colors.lightGray }]}>{formattedDate}</Text>
</View> </View>
{item.vote_average > 0 && ( {item.vote_average > 0 && (
@ -318,9 +318,9 @@ const CalendarScreen = () => {
<MaterialIcons <MaterialIcons
name="star" name="star"
size={16} size={16}
color={colors.primary} color={currentTheme.colors.primary}
/> />
<Text style={styles.rating}> <Text style={[styles.rating, { color: currentTheme.colors.primary }]}>
{item.vote_average.toFixed(1)} {item.vote_average.toFixed(1)}
</Text> </Text>
</View> </View>
@ -329,16 +329,16 @@ const CalendarScreen = () => {
</> </>
) : ( ) : (
<> <>
<Text style={styles.noEpisodesText}> <Text style={[styles.noEpisodesText, { color: currentTheme.colors.text }]}>
No scheduled episodes No scheduled episodes
</Text> </Text>
<View style={styles.dateContainer}> <View style={styles.dateContainer}>
<MaterialIcons <MaterialIcons
name="event-busy" name="event-busy"
size={16} size={16}
color={colors.lightGray} color={currentTheme.colors.lightGray}
/> />
<Text style={styles.date}>Check back later</Text> <Text style={[styles.date, { color: currentTheme.colors.lightGray }]}>Check back later</Text>
</View> </View>
</> </>
)} )}
@ -349,8 +349,13 @@ const CalendarScreen = () => {
}; };
const renderSectionHeader = ({ section }: { section: CalendarSection }) => ( const renderSectionHeader = ({ section }: { section: CalendarSection }) => (
<View style={styles.sectionHeader}> <View style={[styles.sectionHeader, {
<Text style={styles.sectionTitle}>{section.title}</Text> backgroundColor: currentTheme.colors.darkBackground,
borderBottomColor: currentTheme.colors.border
}]}>
<Text style={[styles.sectionTitle, { color: currentTheme.colors.text }]}>
{section.title}
</Text>
</View> </View>
); );
@ -386,22 +391,22 @@ const CalendarScreen = () => {
if (libraryItems.length === 0 && !libraryLoading) { if (libraryItems.length === 0 && !libraryLoading) {
return ( return (
<SafeAreaView style={styles.container}> <SafeAreaView style={[styles.container, { backgroundColor: currentTheme.colors.darkBackground }]}>
<StatusBar barStyle="light-content" /> <StatusBar barStyle="light-content" />
<View style={styles.header}> <View style={[styles.header, { borderBottomColor: currentTheme.colors.border }]}>
<TouchableOpacity <TouchableOpacity
style={styles.backButton} style={styles.backButton}
onPress={() => navigation.goBack()} onPress={() => navigation.goBack()}
> >
<MaterialIcons name="arrow-back" size={24} color={colors.text} /> <MaterialIcons name="arrow-back" size={24} color={currentTheme.colors.text} />
</TouchableOpacity> </TouchableOpacity>
<Text style={styles.headerTitle}>Calendar</Text> <Text style={[styles.headerTitle, { color: currentTheme.colors.text }]}>Calendar</Text>
<View style={{ width: 40 }} /> <View style={{ width: 40 }} />
</View> </View>
<View style={styles.emptyLibraryContainer}> <View style={styles.emptyLibraryContainer}>
<MaterialIcons name="video-library" size={64} color={colors.lightGray} /> <MaterialIcons name="video-library" size={64} color={currentTheme.colors.lightGray} />
<Text style={styles.emptyText}> <Text style={styles.emptyText}>
Your library is empty Your library is empty
</Text> </Text>
@ -423,10 +428,10 @@ const CalendarScreen = () => {
if (loading && !refreshing) { if (loading && !refreshing) {
return ( return (
<SafeAreaView style={styles.container}> <SafeAreaView style={[styles.container, { backgroundColor: currentTheme.colors.darkBackground }]}>
<StatusBar barStyle="light-content" /> <StatusBar barStyle="light-content" />
<View style={styles.loadingContainer}> <View style={styles.loadingContainer}>
<ActivityIndicator size="large" color={colors.primary} /> <ActivityIndicator size="large" color={currentTheme.colors.primary} />
<Text style={styles.loadingText}>Loading calendar...</Text> <Text style={styles.loadingText}>Loading calendar...</Text>
</View> </View>
</SafeAreaView> </SafeAreaView>
@ -434,27 +439,27 @@ const CalendarScreen = () => {
} }
return ( return (
<SafeAreaView style={styles.container}> <SafeAreaView style={[styles.container, { backgroundColor: currentTheme.colors.darkBackground }]}>
<StatusBar barStyle="light-content" /> <StatusBar barStyle="light-content" />
<View style={styles.header}> <View style={[styles.header, { borderBottomColor: currentTheme.colors.border }]}>
<TouchableOpacity <TouchableOpacity
style={styles.backButton} style={styles.backButton}
onPress={() => navigation.goBack()} onPress={() => navigation.goBack()}
> >
<MaterialIcons name="arrow-back" size={24} color={colors.text} /> <MaterialIcons name="arrow-back" size={24} color={currentTheme.colors.text} />
</TouchableOpacity> </TouchableOpacity>
<Text style={styles.headerTitle}>Calendar</Text> <Text style={[styles.headerTitle, { color: currentTheme.colors.text }]}>Calendar</Text>
<View style={{ width: 40 }} /> <View style={{ width: 40 }} />
</View> </View>
{selectedDate && filteredEpisodes.length > 0 && ( {selectedDate && filteredEpisodes.length > 0 && (
<View style={styles.filterInfoContainer}> <View style={[styles.filterInfoContainer, { borderBottomColor: currentTheme.colors.border }]}>
<Text style={styles.filterInfoText}> <Text style={[styles.filterInfoText, { color: currentTheme.colors.text }]}>
Showing episodes for {format(selectedDate, 'MMMM d, yyyy')} Showing episodes for {format(selectedDate, 'MMMM d, yyyy')}
</Text> </Text>
<TouchableOpacity onPress={clearDateFilter} style={styles.clearFilterButton}> <TouchableOpacity onPress={clearDateFilter} style={styles.clearFilterButton}>
<MaterialIcons name="close" size={18} color={colors.text} /> <MaterialIcons name="close" size={18} color={currentTheme.colors.text} />
</TouchableOpacity> </TouchableOpacity>
</View> </View>
)} )}
@ -474,22 +479,22 @@ const CalendarScreen = () => {
<RefreshControl <RefreshControl
refreshing={refreshing} refreshing={refreshing}
onRefresh={onRefresh} onRefresh={onRefresh}
tintColor={colors.primary} tintColor={currentTheme.colors.primary}
colors={[colors.primary]} colors={[currentTheme.colors.primary]}
/> />
} }
/> />
) : selectedDate && filteredEpisodes.length === 0 ? ( ) : selectedDate && filteredEpisodes.length === 0 ? (
<View style={styles.emptyFilterContainer}> <View style={styles.emptyFilterContainer}>
<MaterialIcons name="event-busy" size={48} color={colors.lightGray} /> <MaterialIcons name="event-busy" size={48} color={currentTheme.colors.lightGray} />
<Text style={styles.emptyFilterText}> <Text style={[styles.emptyFilterText, { color: currentTheme.colors.text }]}>
No episodes for {format(selectedDate, 'MMMM d, yyyy')} No episodes for {format(selectedDate, 'MMMM d, yyyy')}
</Text> </Text>
<TouchableOpacity <TouchableOpacity
style={styles.clearFilterButtonLarge} style={[styles.clearFilterButtonLarge, { backgroundColor: currentTheme.colors.primary }]}
onPress={clearDateFilter} onPress={clearDateFilter}
> >
<Text style={styles.clearFilterButtonText}> <Text style={[styles.clearFilterButtonText, { color: currentTheme.colors.text }]}>
Show All Episodes Show All Episodes
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
@ -505,18 +510,18 @@ const CalendarScreen = () => {
<RefreshControl <RefreshControl
refreshing={refreshing} refreshing={refreshing}
onRefresh={onRefresh} onRefresh={onRefresh}
tintColor={colors.primary} tintColor={currentTheme.colors.primary}
colors={[colors.primary]} colors={[currentTheme.colors.primary]}
/> />
} }
/> />
) : ( ) : (
<View style={styles.emptyContainer}> <View style={styles.emptyContainer}>
<MaterialIcons name="calendar-today" size={64} color={colors.lightGray} /> <MaterialIcons name="calendar-today" size={64} color={currentTheme.colors.lightGray} />
<Text style={styles.emptyText}> <Text style={[styles.emptyText, { color: currentTheme.colors.text }]}>
No upcoming episodes found No upcoming episodes found
</Text> </Text>
<Text style={styles.emptySubtext}> <Text style={[styles.emptySubtext, { color: currentTheme.colors.lightGray }]}>
Add series to your library to see their upcoming episodes here Add series to your library to see their upcoming episodes here
</Text> </Text>
</View> </View>
@ -528,7 +533,6 @@ const CalendarScreen = () => {
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
backgroundColor: colors.darkBackground,
}, },
listContent: { listContent: {
paddingBottom: 20, paddingBottom: 20,
@ -539,19 +543,15 @@ const styles = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
}, },
loadingText: { loadingText: {
color: colors.text,
marginTop: 10, marginTop: 10,
fontSize: 16, fontSize: 16,
}, },
sectionHeader: { sectionHeader: {
backgroundColor: colors.darkBackground,
paddingVertical: 8, paddingVertical: 8,
paddingHorizontal: 16, paddingHorizontal: 16,
borderBottomWidth: 1, borderBottomWidth: 1,
borderBottomColor: colors.border,
}, },
sectionTitle: { sectionTitle: {
color: colors.text,
fontSize: 18, fontSize: 18,
fontWeight: 'bold', fontWeight: 'bold',
}, },
@ -559,7 +559,6 @@ const styles = StyleSheet.create({
flexDirection: 'row', flexDirection: 'row',
padding: 12, padding: 12,
borderBottomWidth: 1, borderBottomWidth: 1,
borderBottomColor: colors.border + '20',
}, },
poster: { poster: {
width: 120, width: 120,
@ -572,18 +571,15 @@ const styles = StyleSheet.create({
justifyContent: 'space-between', justifyContent: 'space-between',
}, },
seriesName: { seriesName: {
color: colors.text,
fontSize: 16, fontSize: 16,
fontWeight: 'bold', fontWeight: 'bold',
marginBottom: 4, marginBottom: 4,
}, },
episodeTitle: { episodeTitle: {
color: colors.lightGray,
fontSize: 14, fontSize: 14,
lineHeight: 20, lineHeight: 20,
}, },
overview: { overview: {
color: colors.lightGray,
fontSize: 12, fontSize: 12,
marginTop: 4, marginTop: 4,
lineHeight: 16, lineHeight: 16,
@ -599,7 +595,6 @@ const styles = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
}, },
date: { date: {
color: colors.lightGray,
fontSize: 14, fontSize: 14,
marginLeft: 4, marginLeft: 4,
}, },
@ -608,7 +603,6 @@ const styles = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
}, },
rating: { rating: {
color: colors.primary,
fontSize: 14, fontSize: 14,
marginLeft: 4, marginLeft: 4,
fontWeight: 'bold', fontWeight: 'bold',
@ -620,14 +614,12 @@ const styles = StyleSheet.create({
padding: 20, padding: 20,
}, },
emptyText: { emptyText: {
color: colors.text,
fontSize: 18, fontSize: 18,
fontWeight: 'bold', fontWeight: 'bold',
marginTop: 16, marginTop: 16,
textAlign: 'center', textAlign: 'center',
}, },
emptySubtext: { emptySubtext: {
color: colors.lightGray,
fontSize: 14, fontSize: 14,
marginTop: 8, marginTop: 8,
textAlign: 'center', textAlign: 'center',
@ -638,10 +630,8 @@ const styles = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
padding: 12, padding: 12,
borderBottomWidth: 1, borderBottomWidth: 1,
borderBottomColor: colors.border,
}, },
filterInfoText: { filterInfoText: {
color: colors.text,
fontSize: 16, fontSize: 16,
fontWeight: 'bold', fontWeight: 'bold',
}, },
@ -655,7 +645,6 @@ const styles = StyleSheet.create({
padding: 20, padding: 20,
}, },
emptyFilterText: { emptyFilterText: {
color: colors.text,
fontSize: 18, fontSize: 18,
fontWeight: 'bold', fontWeight: 'bold',
marginTop: 16, marginTop: 16,
@ -664,11 +653,9 @@ const styles = StyleSheet.create({
clearFilterButtonLarge: { clearFilterButtonLarge: {
marginTop: 20, marginTop: 20,
padding: 16, padding: 16,
backgroundColor: colors.primary,
borderRadius: 8, borderRadius: 8,
}, },
clearFilterButtonText: { clearFilterButtonText: {
color: colors.text,
fontSize: 16, fontSize: 16,
fontWeight: 'bold', fontWeight: 'bold',
}, },
@ -681,7 +668,6 @@ const styles = StyleSheet.create({
padding: 8, padding: 8,
}, },
headerTitle: { headerTitle: {
color: colors.text,
fontSize: 18, fontSize: 18,
fontWeight: 'bold', fontWeight: 'bold',
marginLeft: 12, marginLeft: 12,
@ -694,16 +680,13 @@ const styles = StyleSheet.create({
}, },
discoverButton: { discoverButton: {
padding: 16, padding: 16,
backgroundColor: colors.primary,
borderRadius: 8, borderRadius: 8,
}, },
discoverButtonText: { discoverButtonText: {
color: colors.text,
fontSize: 16, fontSize: 16,
fontWeight: 'bold', fontWeight: 'bold',
}, },
noEpisodesText: { noEpisodesText: {
color: colors.text,
fontSize: 14, fontSize: 14,
marginBottom: 4, marginBottom: 4,
}, },

View file

@ -11,7 +11,7 @@ import {
StatusBar, StatusBar,
} from 'react-native'; } from 'react-native';
import { MaterialIcons } from '@expo/vector-icons'; import { MaterialIcons } from '@expo/vector-icons';
import { colors } from '../styles/colors'; import { useTheme } from '../contexts/ThemeContext';
import { notificationService, NotificationSettings } from '../services/notificationService'; import { notificationService, NotificationSettings } from '../services/notificationService';
import Animated, { FadeIn, FadeOut } from 'react-native-reanimated'; import Animated, { FadeIn, FadeOut } from 'react-native-reanimated';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
@ -19,6 +19,7 @@ import { logger } from '../utils/logger';
const NotificationSettingsScreen = () => { const NotificationSettingsScreen = () => {
const navigation = useNavigation(); const navigation = useNavigation();
const { currentTheme } = useTheme();
const [settings, setSettings] = useState<NotificationSettings>({ const [settings, setSettings] = useState<NotificationSettings>({
enabled: true, enabled: true,
newEpisodeNotifications: true, newEpisodeNotifications: true,
@ -155,36 +156,36 @@ const NotificationSettingsScreen = () => {
if (loading) { if (loading) {
return ( return (
<SafeAreaView style={styles.container}> <SafeAreaView style={[styles.container, { backgroundColor: currentTheme.colors.darkBackground }]}>
<View style={styles.header}> <View style={[styles.header, { borderBottomColor: currentTheme.colors.border }]}>
<TouchableOpacity <TouchableOpacity
style={styles.backButton} style={styles.backButton}
onPress={() => navigation.goBack()} onPress={() => navigation.goBack()}
> >
<MaterialIcons name="arrow-back" size={24} color={colors.text} /> <MaterialIcons name="arrow-back" size={24} color={currentTheme.colors.text} />
</TouchableOpacity> </TouchableOpacity>
<Text style={styles.headerTitle}>Notification Settings</Text> <Text style={[styles.headerTitle, { color: currentTheme.colors.text }]}>Notification Settings</Text>
<View style={{ width: 40 }} /> <View style={{ width: 40 }} />
</View> </View>
<View style={styles.loadingContainer}> <View style={styles.loadingContainer}>
<Text style={styles.loadingText}>Loading settings...</Text> <Text style={[styles.loadingText, { color: currentTheme.colors.text }]}>Loading settings...</Text>
</View> </View>
</SafeAreaView> </SafeAreaView>
); );
} }
return ( return (
<SafeAreaView style={styles.container}> <SafeAreaView style={[styles.container, { backgroundColor: currentTheme.colors.darkBackground }]}>
<StatusBar barStyle="light-content" /> <StatusBar barStyle="light-content" />
<View style={styles.header}> <View style={[styles.header, { borderBottomColor: currentTheme.colors.border }]}>
<TouchableOpacity <TouchableOpacity
style={styles.backButton} style={styles.backButton}
onPress={() => navigation.goBack()} onPress={() => navigation.goBack()}
> >
<MaterialIcons name="arrow-back" size={24} color={colors.text} /> <MaterialIcons name="arrow-back" size={24} color={currentTheme.colors.text} />
</TouchableOpacity> </TouchableOpacity>
<Text style={styles.headerTitle}>Notification Settings</Text> <Text style={[styles.headerTitle, { color: currentTheme.colors.text }]}>Notification Settings</Text>
<View style={{ width: 40 }} /> <View style={{ width: 40 }} />
</View> </View>
@ -193,72 +194,72 @@ const NotificationSettingsScreen = () => {
entering={FadeIn.duration(300)} entering={FadeIn.duration(300)}
exiting={FadeOut.duration(200)} exiting={FadeOut.duration(200)}
> >
<View style={styles.section}> <View style={[styles.section, { borderBottomColor: currentTheme.colors.border }]}>
<Text style={styles.sectionTitle}>General</Text> <Text style={[styles.sectionTitle, { color: currentTheme.colors.text }]}>General</Text>
<View style={styles.settingItem}> <View style={[styles.settingItem, { borderBottomColor: currentTheme.colors.border + '50' }]}>
<View style={styles.settingInfo}> <View style={styles.settingInfo}>
<MaterialIcons name="notifications" size={24} color={colors.text} /> <MaterialIcons name="notifications" size={24} color={currentTheme.colors.text} />
<Text style={styles.settingText}>Enable Notifications</Text> <Text style={[styles.settingText, { color: currentTheme.colors.text }]}>Enable Notifications</Text>
</View> </View>
<Switch <Switch
value={settings.enabled} value={settings.enabled}
onValueChange={(value) => updateSetting('enabled', value)} onValueChange={(value) => updateSetting('enabled', value)}
trackColor={{ false: colors.border, true: colors.primary + '80' }} trackColor={{ false: currentTheme.colors.border, true: currentTheme.colors.primary + '80' }}
thumbColor={settings.enabled ? colors.primary : colors.lightGray} thumbColor={settings.enabled ? currentTheme.colors.primary : currentTheme.colors.lightGray}
/> />
</View> </View>
</View> </View>
{settings.enabled && ( {settings.enabled && (
<> <>
<View style={styles.section}> <View style={[styles.section, { borderBottomColor: currentTheme.colors.border }]}>
<Text style={styles.sectionTitle}>Notification Types</Text> <Text style={[styles.sectionTitle, { color: currentTheme.colors.text }]}>Notification Types</Text>
<View style={styles.settingItem}> <View style={[styles.settingItem, { borderBottomColor: currentTheme.colors.border + '50' }]}>
<View style={styles.settingInfo}> <View style={styles.settingInfo}>
<MaterialIcons name="new-releases" size={24} color={colors.text} /> <MaterialIcons name="new-releases" size={24} color={currentTheme.colors.text} />
<Text style={styles.settingText}>New Episodes</Text> <Text style={[styles.settingText, { color: currentTheme.colors.text }]}>New Episodes</Text>
</View> </View>
<Switch <Switch
value={settings.newEpisodeNotifications} value={settings.newEpisodeNotifications}
onValueChange={(value) => updateSetting('newEpisodeNotifications', value)} onValueChange={(value) => updateSetting('newEpisodeNotifications', value)}
trackColor={{ false: colors.border, true: colors.primary + '80' }} trackColor={{ false: currentTheme.colors.border, true: currentTheme.colors.primary + '80' }}
thumbColor={settings.newEpisodeNotifications ? colors.primary : colors.lightGray} thumbColor={settings.newEpisodeNotifications ? currentTheme.colors.primary : currentTheme.colors.lightGray}
/> />
</View> </View>
<View style={styles.settingItem}> <View style={[styles.settingItem, { borderBottomColor: currentTheme.colors.border + '50' }]}>
<View style={styles.settingInfo}> <View style={styles.settingInfo}>
<MaterialIcons name="event" size={24} color={colors.text} /> <MaterialIcons name="event" size={24} color={currentTheme.colors.text} />
<Text style={styles.settingText}>Upcoming Shows</Text> <Text style={[styles.settingText, { color: currentTheme.colors.text }]}>Upcoming Shows</Text>
</View> </View>
<Switch <Switch
value={settings.upcomingShowsNotifications} value={settings.upcomingShowsNotifications}
onValueChange={(value) => updateSetting('upcomingShowsNotifications', value)} onValueChange={(value) => updateSetting('upcomingShowsNotifications', value)}
trackColor={{ false: colors.border, true: colors.primary + '80' }} trackColor={{ false: currentTheme.colors.border, true: currentTheme.colors.primary + '80' }}
thumbColor={settings.upcomingShowsNotifications ? colors.primary : colors.lightGray} thumbColor={settings.upcomingShowsNotifications ? currentTheme.colors.primary : currentTheme.colors.lightGray}
/> />
</View> </View>
<View style={styles.settingItem}> <View style={[styles.settingItem, { borderBottomColor: currentTheme.colors.border + '50' }]}>
<View style={styles.settingInfo}> <View style={styles.settingInfo}>
<MaterialIcons name="alarm" size={24} color={colors.text} /> <MaterialIcons name="alarm" size={24} color={currentTheme.colors.text} />
<Text style={styles.settingText}>Reminders</Text> <Text style={[styles.settingText, { color: currentTheme.colors.text }]}>Reminders</Text>
</View> </View>
<Switch <Switch
value={settings.reminderNotifications} value={settings.reminderNotifications}
onValueChange={(value) => updateSetting('reminderNotifications', value)} onValueChange={(value) => updateSetting('reminderNotifications', value)}
trackColor={{ false: colors.border, true: colors.primary + '80' }} trackColor={{ false: currentTheme.colors.border, true: currentTheme.colors.primary + '80' }}
thumbColor={settings.reminderNotifications ? colors.primary : colors.lightGray} thumbColor={settings.reminderNotifications ? currentTheme.colors.primary : currentTheme.colors.lightGray}
/> />
</View> </View>
</View> </View>
<View style={styles.section}> <View style={[styles.section, { borderBottomColor: currentTheme.colors.border }]}>
<Text style={styles.sectionTitle}>Notification Timing</Text> <Text style={[styles.sectionTitle, { color: currentTheme.colors.text }]}>Notification Timing</Text>
<Text style={styles.settingDescription}> <Text style={[styles.settingDescription, { color: currentTheme.colors.lightGray }]}>
When should you be notified before an episode airs? When should you be notified before an episode airs?
</Text> </Text>
@ -268,13 +269,24 @@ const NotificationSettingsScreen = () => {
key={hours} key={hours}
style={[ style={[
styles.timingOption, styles.timingOption,
settings.timeBeforeAiring === hours && styles.selectedTimingOption {
backgroundColor: currentTheme.colors.elevation1,
borderColor: currentTheme.colors.border
},
settings.timeBeforeAiring === hours && {
backgroundColor: currentTheme.colors.primary + '30',
borderColor: currentTheme.colors.primary,
}
]} ]}
onPress={() => setTimeBeforeAiring(hours)} onPress={() => setTimeBeforeAiring(hours)}
> >
<Text style={[ <Text style={[
styles.timingText, styles.timingText,
settings.timeBeforeAiring === hours && styles.selectedTimingText { color: currentTheme.colors.text },
settings.timeBeforeAiring === hours && {
color: currentTheme.colors.primary,
fontWeight: 'bold',
}
]}> ]}>
{hours === 1 ? '1 hour' : `${hours} hours`} {hours === 1 ? '1 hour' : `${hours} hours`}
</Text> </Text>
@ -283,27 +295,37 @@ const NotificationSettingsScreen = () => {
</View> </View>
</View> </View>
<View style={styles.section}> <View style={[styles.section, { borderBottomColor: currentTheme.colors.border }]}>
<Text style={styles.sectionTitle}>Advanced</Text> <Text style={[styles.sectionTitle, { color: currentTheme.colors.text }]}>Advanced</Text>
<TouchableOpacity <TouchableOpacity
style={styles.resetButton} style={[
styles.resetButton,
{
backgroundColor: currentTheme.colors.error + '20',
borderColor: currentTheme.colors.error + '50'
}
]}
onPress={resetAllNotifications} onPress={resetAllNotifications}
> >
<MaterialIcons name="refresh" size={24} color={colors.error} /> <MaterialIcons name="refresh" size={24} color={currentTheme.colors.error} />
<Text style={styles.resetButtonText}>Reset All Notifications</Text> <Text style={[styles.resetButtonText, { color: currentTheme.colors.error }]}>Reset All Notifications</Text>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity <TouchableOpacity
style={[ style={[
styles.resetButton, styles.resetButton,
{ marginTop: 12, backgroundColor: colors.primary + '20', borderColor: colors.primary + '50' } {
marginTop: 12,
backgroundColor: currentTheme.colors.primary + '20',
borderColor: currentTheme.colors.primary + '50'
}
]} ]}
onPress={handleTestNotification} onPress={handleTestNotification}
disabled={countdown !== null} disabled={countdown !== null}
> >
<MaterialIcons name="bug-report" size={24} color={colors.primary} /> <MaterialIcons name="bug-report" size={24} color={currentTheme.colors.primary} />
<Text style={[styles.resetButtonText, { color: colors.primary }]}> <Text style={[styles.resetButtonText, { color: currentTheme.colors.primary }]}>
{countdown !== null {countdown !== null
? `Notification in ${countdown}s...` ? `Notification in ${countdown}s...`
: 'Test Notification (1min)'} : 'Test Notification (1min)'}
@ -315,16 +337,16 @@ const NotificationSettingsScreen = () => {
<MaterialIcons <MaterialIcons
name="timer" name="timer"
size={16} size={16}
color={colors.primary} color={currentTheme.colors.primary}
style={styles.countdownIcon} style={styles.countdownIcon}
/> />
<Text style={styles.countdownText}> <Text style={[styles.countdownText, { color: currentTheme.colors.primary }]}>
Notification will appear in {countdown} seconds Notification will appear in {countdown} seconds
</Text> </Text>
</View> </View>
)} )}
<Text style={styles.resetDescription}> <Text style={[styles.resetDescription, { color: currentTheme.colors.lightGray }]}>
This will cancel all scheduled notifications. You'll need to re-enable them manually. This will cancel all scheduled notifications. You'll need to re-enable them manually.
</Text> </Text>
</View> </View>
@ -339,7 +361,6 @@ const NotificationSettingsScreen = () => {
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
backgroundColor: colors.darkBackground,
}, },
header: { header: {
flexDirection: 'row', flexDirection: 'row',
@ -348,7 +369,6 @@ const styles = StyleSheet.create({
paddingHorizontal: 16, paddingHorizontal: 16,
paddingVertical: 12, paddingVertical: 12,
borderBottomWidth: 1, borderBottomWidth: 1,
borderBottomColor: colors.border,
}, },
backButton: { backButton: {
padding: 8, padding: 8,
@ -356,7 +376,6 @@ const styles = StyleSheet.create({
headerTitle: { headerTitle: {
fontSize: 18, fontSize: 18,
fontWeight: 'bold', fontWeight: 'bold',
color: colors.text,
}, },
content: { content: {
flex: 1, flex: 1,
@ -367,18 +386,15 @@ const styles = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
}, },
loadingText: { loadingText: {
color: colors.text,
fontSize: 16, fontSize: 16,
}, },
section: { section: {
padding: 16, padding: 16,
borderBottomWidth: 1, borderBottomWidth: 1,
borderBottomColor: colors.border,
}, },
sectionTitle: { sectionTitle: {
fontSize: 16, fontSize: 16,
fontWeight: 'bold', fontWeight: 'bold',
color: colors.text,
marginBottom: 16, marginBottom: 16,
}, },
settingItem: { settingItem: {
@ -387,7 +403,6 @@ const styles = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
paddingVertical: 12, paddingVertical: 12,
borderBottomWidth: 1, borderBottomWidth: 1,
borderBottomColor: colors.border + '50',
}, },
settingInfo: { settingInfo: {
flexDirection: 'row', flexDirection: 'row',
@ -395,12 +410,10 @@ const styles = StyleSheet.create({
}, },
settingText: { settingText: {
fontSize: 16, fontSize: 16,
color: colors.text,
marginLeft: 12, marginLeft: 12,
}, },
settingDescription: { settingDescription: {
fontSize: 14, fontSize: 14,
color: colors.lightGray,
marginBottom: 16, marginBottom: 16,
}, },
timingOptions: { timingOptions: {
@ -410,47 +423,32 @@ const styles = StyleSheet.create({
marginTop: 8, marginTop: 8,
}, },
timingOption: { timingOption: {
backgroundColor: colors.elevation1,
paddingVertical: 10, paddingVertical: 10,
paddingHorizontal: 16, paddingHorizontal: 16,
borderRadius: 8, borderRadius: 8,
borderWidth: 1, borderWidth: 1,
borderColor: colors.border,
marginBottom: 8, marginBottom: 8,
width: '48%', width: '48%',
alignItems: 'center', alignItems: 'center',
}, },
selectedTimingOption: {
backgroundColor: colors.primary + '30',
borderColor: colors.primary,
},
timingText: { timingText: {
color: colors.text,
fontSize: 14, fontSize: 14,
}, },
selectedTimingText: {
color: colors.primary,
fontWeight: 'bold',
},
resetButton: { resetButton: {
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
padding: 12, padding: 12,
backgroundColor: colors.error + '20',
borderRadius: 8, borderRadius: 8,
borderWidth: 1, borderWidth: 1,
borderColor: colors.error + '50',
marginBottom: 8, marginBottom: 8,
}, },
resetButtonText: { resetButtonText: {
color: colors.error,
fontSize: 16, fontSize: 16,
fontWeight: 'bold', fontWeight: 'bold',
marginLeft: 8, marginLeft: 8,
}, },
resetDescription: { resetDescription: {
fontSize: 12, fontSize: 12,
color: colors.lightGray,
fontStyle: 'italic', fontStyle: 'italic',
}, },
countdownContainer: { countdownContainer: {
@ -458,14 +456,13 @@ const styles = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
marginTop: 8, marginTop: 8,
padding: 8, padding: 8,
backgroundColor: colors.primary + '10', backgroundColor: 'rgba(0, 0, 0, 0.1)',
borderRadius: 4, borderRadius: 4,
}, },
countdownIcon: { countdownIcon: {
marginRight: 8, marginRight: 8,
}, },
countdownText: { countdownText: {
color: colors.primary,
fontSize: 14, fontSize: 14,
}, },
}); });