mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-01-11 20:10:25 +00:00
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:
parent
9ab154f8b8
commit
29347ee028
3 changed files with 276 additions and 311 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
|
|
@ -8,24 +8,14 @@ import {
|
|||
Dimensions
|
||||
} from 'react-native';
|
||||
import { MaterialIcons } from '@expo/vector-icons';
|
||||
import { colors } from '../../styles/colors';
|
||||
import {
|
||||
format,
|
||||
addMonths,
|
||||
subMonths,
|
||||
startOfMonth,
|
||||
endOfMonth,
|
||||
isSameMonth,
|
||||
isSameDay,
|
||||
getDay,
|
||||
isToday,
|
||||
parseISO
|
||||
} from 'date-fns';
|
||||
import { format, addMonths, subMonths, startOfMonth, endOfMonth, eachDayOfInterval, isSameMonth, isToday, isSameDay } from 'date-fns';
|
||||
import Animated, { FadeIn } from 'react-native-reanimated';
|
||||
import { useTheme } from '../../contexts/ThemeContext';
|
||||
|
||||
const { width } = Dimensions.get('window');
|
||||
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 {
|
||||
id: string;
|
||||
|
|
@ -54,37 +44,40 @@ const DayItem = ({
|
|||
isSelected,
|
||||
hasEvents,
|
||||
onPress
|
||||
}: DayItemProps) => (
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.dayItem,
|
||||
today && styles.todayItem,
|
||||
isSelected && styles.selectedItem,
|
||||
hasEvents && styles.dayWithEvents
|
||||
]}
|
||||
onPress={() => onPress(date)}
|
||||
>
|
||||
<Text style={[
|
||||
styles.dayText,
|
||||
!isCurrentMonth && styles.otherMonthDay,
|
||||
today && styles.todayText,
|
||||
isSelected && styles.selectedDayText
|
||||
]}>
|
||||
{date.getDate()}
|
||||
</Text>
|
||||
{hasEvents && (
|
||||
<View style={styles.eventIndicator} />
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}: DayItemProps) => {
|
||||
const { currentTheme } = useTheme();
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.dayButton,
|
||||
today && styles.todayItem,
|
||||
isSelected && styles.selectedItem,
|
||||
hasEvents && styles.dayWithEvents
|
||||
]}
|
||||
onPress={() => onPress(date)}
|
||||
>
|
||||
<Text style={[
|
||||
styles.dayText,
|
||||
!isCurrentMonth && { color: currentTheme.colors.lightGray + '80' },
|
||||
today && styles.todayText,
|
||||
isSelected && styles.selectedDayText
|
||||
]}>
|
||||
{date.getDate()}
|
||||
</Text>
|
||||
{hasEvents && (
|
||||
<View style={[styles.eventIndicator, { backgroundColor: currentTheme.colors.primary }]} />
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
||||
export const CalendarSection: React.FC<CalendarSectionProps> = ({
|
||||
episodes = [],
|
||||
onSelectDate
|
||||
}) => {
|
||||
console.log(`[CalendarSection] Rendering with ${episodes.length} episodes`);
|
||||
const { currentTheme } = useTheme();
|
||||
const [currentDate, setCurrentDate] = useState(new Date());
|
||||
const [selectedDate, setSelectedDate] = useState(new Date());
|
||||
const [selectedDate, setSelectedDate] = useState<Date | null>(null);
|
||||
const scrollViewRef = useRef<ScrollView>(null);
|
||||
|
||||
// Map of dates with episodes
|
||||
|
|
@ -97,7 +90,7 @@ export const CalendarSection: React.FC<CalendarSectionProps> = ({
|
|||
|
||||
episodes.forEach(episode => {
|
||||
if (episode.releaseDate) {
|
||||
const releaseDate = parseISO(episode.releaseDate);
|
||||
const releaseDate = new Date(episode.releaseDate);
|
||||
const dateKey = format(releaseDate, 'yyyy-MM-dd');
|
||||
dateMap[dateKey] = true;
|
||||
}
|
||||
|
|
@ -107,201 +100,194 @@ export const CalendarSection: React.FC<CalendarSectionProps> = ({
|
|||
setDatesWithEpisodes(dateMap);
|
||||
}, [episodes]);
|
||||
|
||||
const goToPreviousMonth = () => {
|
||||
setCurrentDate(prevDate => subMonths(prevDate, 1));
|
||||
};
|
||||
const goToPreviousMonth = useCallback(() => {
|
||||
setCurrentDate(prev => subMonths(prev, 1));
|
||||
}, []);
|
||||
|
||||
const goToNextMonth = () => {
|
||||
setCurrentDate(prevDate => addMonths(prevDate, 1));
|
||||
};
|
||||
const goToNextMonth = useCallback(() => {
|
||||
setCurrentDate(prev => addMonths(prev, 1));
|
||||
}, []);
|
||||
|
||||
const handleDayPress = (date: Date) => {
|
||||
const handleDateSelect = useCallback((date: 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 (
|
||||
<Animated.View entering={FadeIn.duration(300)} style={styles.container}>
|
||||
<View style={styles.header}>
|
||||
<TouchableOpacity onPress={goToPreviousMonth} style={styles.headerButton}>
|
||||
<MaterialIcons name="chevron-left" size={24} color={colors.text} />
|
||||
<View style={[styles.container, { backgroundColor: currentTheme.colors.darkBackground }]}>
|
||||
<View style={[styles.header, { borderBottomColor: currentTheme.colors.border }]}>
|
||||
<TouchableOpacity
|
||||
onPress={goToPreviousMonth}
|
||||
style={styles.headerButton}
|
||||
>
|
||||
<MaterialIcons name="chevron-left" size={24} color={currentTheme.colors.text} />
|
||||
</TouchableOpacity>
|
||||
|
||||
<Text style={styles.monthTitle}>
|
||||
<Text style={[styles.headerTitle, { color: currentTheme.colors.text }]}>
|
||||
{format(currentDate, 'MMMM yyyy')}
|
||||
</Text>
|
||||
|
||||
<TouchableOpacity onPress={goToNextMonth} style={styles.headerButton}>
|
||||
<MaterialIcons name="chevron-right" size={24} color={colors.text} />
|
||||
<TouchableOpacity
|
||||
onPress={goToNextMonth}
|
||||
style={styles.headerButton}
|
||||
>
|
||||
<MaterialIcons name="chevron-right" size={24} color={currentTheme.colors.text} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<View style={styles.weekHeader}>
|
||||
|
||||
<View style={styles.weekDaysContainer}>
|
||||
{weekDays.map((day, index) => (
|
||||
<View key={index} style={styles.weekHeaderItem}>
|
||||
<Text style={styles.weekDayText}>{day}</Text>
|
||||
</View>
|
||||
<Text
|
||||
key={index}
|
||||
style={[styles.weekDayText, { color: currentTheme.colors.lightGray }]}
|
||||
>
|
||||
{day}
|
||||
</Text>
|
||||
))}
|
||||
</View>
|
||||
|
||||
<View style={styles.calendarGrid}>
|
||||
{rows.map((row, rowIndex) => (
|
||||
<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 style={styles.daysContainer}>
|
||||
{renderDays()}
|
||||
</View>
|
||||
</Animated.View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: colors.darkBackground,
|
||||
marginBottom: 12,
|
||||
borderRadius: 8,
|
||||
overflow: 'hidden',
|
||||
borderWidth: 1,
|
||||
borderColor: colors.border,
|
||||
width: '100%',
|
||||
},
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 16,
|
||||
alignItems: 'center',
|
||||
padding: 16,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.border,
|
||||
},
|
||||
headerButton: {
|
||||
padding: 8,
|
||||
},
|
||||
monthTitle: {
|
||||
headerTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
color: colors.text,
|
||||
},
|
||||
weekHeader: {
|
||||
weekDaysContainer: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around',
|
||||
padding: 8,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.border,
|
||||
},
|
||||
weekHeaderItem: {
|
||||
width: DAY_ITEM_SIZE,
|
||||
alignItems: 'center',
|
||||
},
|
||||
weekDayText: {
|
||||
fontSize: 12,
|
||||
color: colors.lightGray,
|
||||
},
|
||||
calendarGrid: {
|
||||
daysContainer: {
|
||||
padding: 8,
|
||||
},
|
||||
row: {
|
||||
weekRow: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around',
|
||||
marginBottom: 8,
|
||||
},
|
||||
dayItem: {
|
||||
width: DAY_ITEM_SIZE,
|
||||
height: DAY_ITEM_SIZE,
|
||||
dayButton: {
|
||||
width: 36,
|
||||
height: 36,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderRadius: DAY_ITEM_SIZE / 2,
|
||||
borderRadius: 18,
|
||||
borderWidth: 1,
|
||||
borderColor: 'transparent',
|
||||
},
|
||||
dayText: {
|
||||
fontSize: 14,
|
||||
color: colors.text,
|
||||
},
|
||||
otherMonthDay: {
|
||||
color: colors.lightGray + '80', // 50% opacity
|
||||
emptyDay: {
|
||||
width: 36,
|
||||
height: 36,
|
||||
},
|
||||
eventDot: {
|
||||
width: 4,
|
||||
height: 4,
|
||||
borderRadius: 2,
|
||||
position: 'absolute',
|
||||
bottom: 6,
|
||||
},
|
||||
todayItem: {
|
||||
backgroundColor: colors.primary + '30', // 30% opacity
|
||||
borderWidth: 1,
|
||||
borderColor: colors.primary,
|
||||
},
|
||||
selectedItem: {
|
||||
backgroundColor: colors.primary + '60', // 60% opacity
|
||||
borderWidth: 1,
|
||||
borderColor: colors.primary,
|
||||
},
|
||||
todayText: {
|
||||
fontWeight: 'bold',
|
||||
color: colors.primary,
|
||||
},
|
||||
selectedDayText: {
|
||||
fontWeight: 'bold',
|
||||
color: colors.text,
|
||||
},
|
||||
dayWithEvents: {
|
||||
position: 'relative',
|
||||
|
|
@ -312,6 +298,5 @@ const styles = StyleSheet.create({
|
|||
width: 4,
|
||||
height: 4,
|
||||
borderRadius: 2,
|
||||
backgroundColor: colors.primary,
|
||||
},
|
||||
});
|
||||
|
|
@ -9,7 +9,6 @@ import {
|
|||
RefreshControl,
|
||||
SafeAreaView,
|
||||
StatusBar,
|
||||
useColorScheme,
|
||||
Dimensions,
|
||||
SectionList
|
||||
} from 'react-native';
|
||||
|
|
@ -18,7 +17,7 @@ import { NavigationProp } from '@react-navigation/native';
|
|||
import { Image } from 'expo-image';
|
||||
import { MaterialIcons } from '@expo/vector-icons';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { colors } from '../styles/colors';
|
||||
import { useTheme } from '../contexts/ThemeContext';
|
||||
import { RootStackParamList } from '../navigation/AppNavigator';
|
||||
import { stremioService } from '../services/stremioService';
|
||||
import { useLibrary } from '../hooks/useLibrary';
|
||||
|
|
@ -53,6 +52,7 @@ interface CalendarSection {
|
|||
const CalendarScreen = () => {
|
||||
const navigation = useNavigation<NavigationProp<RootStackParamList>>();
|
||||
const { libraryItems, loading: libraryLoading } = useLibrary();
|
||||
const { currentTheme } = useTheme();
|
||||
logger.log(`[Calendar] Initial load - Library has ${libraryItems?.length || 0} items, loading: ${libraryLoading}`);
|
||||
const [calendarData, setCalendarData] = useState<CalendarSection[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
|
@ -270,7 +270,7 @@ const CalendarScreen = () => {
|
|||
return (
|
||||
<Animated.View entering={FadeIn.duration(300).delay(100)}>
|
||||
<TouchableOpacity
|
||||
style={styles.episodeItem}
|
||||
style={[styles.episodeItem, { borderBottomColor: currentTheme.colors.border + '20' }]}
|
||||
onPress={() => handleEpisodePress(item)}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
|
|
@ -287,18 +287,18 @@ const CalendarScreen = () => {
|
|||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.episodeDetails}>
|
||||
<Text style={styles.seriesName} numberOfLines={1}>
|
||||
<Text style={[styles.seriesName, { color: currentTheme.colors.text }]} numberOfLines={1}>
|
||||
{item.seriesName}
|
||||
</Text>
|
||||
|
||||
{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}
|
||||
</Text>
|
||||
|
||||
{item.overview ? (
|
||||
<Text style={styles.overview} numberOfLines={2}>
|
||||
<Text style={[styles.overview, { color: currentTheme.colors.lightGray }]} numberOfLines={2}>
|
||||
{item.overview}
|
||||
</Text>
|
||||
) : null}
|
||||
|
|
@ -308,9 +308,9 @@ const CalendarScreen = () => {
|
|||
<MaterialIcons
|
||||
name={isFuture ? "event" : "event-available"}
|
||||
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>
|
||||
|
||||
{item.vote_average > 0 && (
|
||||
|
|
@ -318,9 +318,9 @@ const CalendarScreen = () => {
|
|||
<MaterialIcons
|
||||
name="star"
|
||||
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)}
|
||||
</Text>
|
||||
</View>
|
||||
|
|
@ -329,16 +329,16 @@ const CalendarScreen = () => {
|
|||
</>
|
||||
) : (
|
||||
<>
|
||||
<Text style={styles.noEpisodesText}>
|
||||
<Text style={[styles.noEpisodesText, { color: currentTheme.colors.text }]}>
|
||||
No scheduled episodes
|
||||
</Text>
|
||||
<View style={styles.dateContainer}>
|
||||
<MaterialIcons
|
||||
name="event-busy"
|
||||
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>
|
||||
</>
|
||||
)}
|
||||
|
|
@ -349,8 +349,13 @@ const CalendarScreen = () => {
|
|||
};
|
||||
|
||||
const renderSectionHeader = ({ section }: { section: CalendarSection }) => (
|
||||
<View style={styles.sectionHeader}>
|
||||
<Text style={styles.sectionTitle}>{section.title}</Text>
|
||||
<View style={[styles.sectionHeader, {
|
||||
backgroundColor: currentTheme.colors.darkBackground,
|
||||
borderBottomColor: currentTheme.colors.border
|
||||
}]}>
|
||||
<Text style={[styles.sectionTitle, { color: currentTheme.colors.text }]}>
|
||||
{section.title}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
|
|
@ -386,22 +391,22 @@ const CalendarScreen = () => {
|
|||
|
||||
if (libraryItems.length === 0 && !libraryLoading) {
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<SafeAreaView style={[styles.container, { backgroundColor: currentTheme.colors.darkBackground }]}>
|
||||
<StatusBar barStyle="light-content" />
|
||||
|
||||
<View style={styles.header}>
|
||||
<View style={[styles.header, { borderBottomColor: currentTheme.colors.border }]}>
|
||||
<TouchableOpacity
|
||||
style={styles.backButton}
|
||||
onPress={() => navigation.goBack()}
|
||||
>
|
||||
<MaterialIcons name="arrow-back" size={24} color={colors.text} />
|
||||
<MaterialIcons name="arrow-back" size={24} color={currentTheme.colors.text} />
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.headerTitle}>Calendar</Text>
|
||||
<Text style={[styles.headerTitle, { color: currentTheme.colors.text }]}>Calendar</Text>
|
||||
<View style={{ width: 40 }} />
|
||||
</View>
|
||||
|
||||
<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}>
|
||||
Your library is empty
|
||||
</Text>
|
||||
|
|
@ -423,10 +428,10 @@ const CalendarScreen = () => {
|
|||
|
||||
if (loading && !refreshing) {
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<SafeAreaView style={[styles.container, { backgroundColor: currentTheme.colors.darkBackground }]}>
|
||||
<StatusBar barStyle="light-content" />
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="large" color={colors.primary} />
|
||||
<ActivityIndicator size="large" color={currentTheme.colors.primary} />
|
||||
<Text style={styles.loadingText}>Loading calendar...</Text>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
|
|
@ -434,27 +439,27 @@ const CalendarScreen = () => {
|
|||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<SafeAreaView style={[styles.container, { backgroundColor: currentTheme.colors.darkBackground }]}>
|
||||
<StatusBar barStyle="light-content" />
|
||||
|
||||
<View style={styles.header}>
|
||||
<View style={[styles.header, { borderBottomColor: currentTheme.colors.border }]}>
|
||||
<TouchableOpacity
|
||||
style={styles.backButton}
|
||||
onPress={() => navigation.goBack()}
|
||||
>
|
||||
<MaterialIcons name="arrow-back" size={24} color={colors.text} />
|
||||
<MaterialIcons name="arrow-back" size={24} color={currentTheme.colors.text} />
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.headerTitle}>Calendar</Text>
|
||||
<Text style={[styles.headerTitle, { color: currentTheme.colors.text }]}>Calendar</Text>
|
||||
<View style={{ width: 40 }} />
|
||||
</View>
|
||||
|
||||
{selectedDate && filteredEpisodes.length > 0 && (
|
||||
<View style={styles.filterInfoContainer}>
|
||||
<Text style={styles.filterInfoText}>
|
||||
<View style={[styles.filterInfoContainer, { borderBottomColor: currentTheme.colors.border }]}>
|
||||
<Text style={[styles.filterInfoText, { color: currentTheme.colors.text }]}>
|
||||
Showing episodes for {format(selectedDate, 'MMMM d, yyyy')}
|
||||
</Text>
|
||||
<TouchableOpacity onPress={clearDateFilter} style={styles.clearFilterButton}>
|
||||
<MaterialIcons name="close" size={18} color={colors.text} />
|
||||
<MaterialIcons name="close" size={18} color={currentTheme.colors.text} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)}
|
||||
|
|
@ -474,22 +479,22 @@ const CalendarScreen = () => {
|
|||
<RefreshControl
|
||||
refreshing={refreshing}
|
||||
onRefresh={onRefresh}
|
||||
tintColor={colors.primary}
|
||||
colors={[colors.primary]}
|
||||
tintColor={currentTheme.colors.primary}
|
||||
colors={[currentTheme.colors.primary]}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
) : selectedDate && filteredEpisodes.length === 0 ? (
|
||||
<View style={styles.emptyFilterContainer}>
|
||||
<MaterialIcons name="event-busy" size={48} color={colors.lightGray} />
|
||||
<Text style={styles.emptyFilterText}>
|
||||
<MaterialIcons name="event-busy" size={48} color={currentTheme.colors.lightGray} />
|
||||
<Text style={[styles.emptyFilterText, { color: currentTheme.colors.text }]}>
|
||||
No episodes for {format(selectedDate, 'MMMM d, yyyy')}
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
style={styles.clearFilterButtonLarge}
|
||||
style={[styles.clearFilterButtonLarge, { backgroundColor: currentTheme.colors.primary }]}
|
||||
onPress={clearDateFilter}
|
||||
>
|
||||
<Text style={styles.clearFilterButtonText}>
|
||||
<Text style={[styles.clearFilterButtonText, { color: currentTheme.colors.text }]}>
|
||||
Show All Episodes
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
|
@ -505,18 +510,18 @@ const CalendarScreen = () => {
|
|||
<RefreshControl
|
||||
refreshing={refreshing}
|
||||
onRefresh={onRefresh}
|
||||
tintColor={colors.primary}
|
||||
colors={[colors.primary]}
|
||||
tintColor={currentTheme.colors.primary}
|
||||
colors={[currentTheme.colors.primary]}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<View style={styles.emptyContainer}>
|
||||
<MaterialIcons name="calendar-today" size={64} color={colors.lightGray} />
|
||||
<Text style={styles.emptyText}>
|
||||
<MaterialIcons name="calendar-today" size={64} color={currentTheme.colors.lightGray} />
|
||||
<Text style={[styles.emptyText, { color: currentTheme.colors.text }]}>
|
||||
No upcoming episodes found
|
||||
</Text>
|
||||
<Text style={styles.emptySubtext}>
|
||||
<Text style={[styles.emptySubtext, { color: currentTheme.colors.lightGray }]}>
|
||||
Add series to your library to see their upcoming episodes here
|
||||
</Text>
|
||||
</View>
|
||||
|
|
@ -528,7 +533,6 @@ const CalendarScreen = () => {
|
|||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: colors.darkBackground,
|
||||
},
|
||||
listContent: {
|
||||
paddingBottom: 20,
|
||||
|
|
@ -539,19 +543,15 @@ const styles = StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
},
|
||||
loadingText: {
|
||||
color: colors.text,
|
||||
marginTop: 10,
|
||||
fontSize: 16,
|
||||
},
|
||||
sectionHeader: {
|
||||
backgroundColor: colors.darkBackground,
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 16,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.border,
|
||||
},
|
||||
sectionTitle: {
|
||||
color: colors.text,
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
|
|
@ -559,7 +559,6 @@ const styles = StyleSheet.create({
|
|||
flexDirection: 'row',
|
||||
padding: 12,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.border + '20',
|
||||
},
|
||||
poster: {
|
||||
width: 120,
|
||||
|
|
@ -572,18 +571,15 @@ const styles = StyleSheet.create({
|
|||
justifyContent: 'space-between',
|
||||
},
|
||||
seriesName: {
|
||||
color: colors.text,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
marginBottom: 4,
|
||||
},
|
||||
episodeTitle: {
|
||||
color: colors.lightGray,
|
||||
fontSize: 14,
|
||||
lineHeight: 20,
|
||||
},
|
||||
overview: {
|
||||
color: colors.lightGray,
|
||||
fontSize: 12,
|
||||
marginTop: 4,
|
||||
lineHeight: 16,
|
||||
|
|
@ -599,7 +595,6 @@ const styles = StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
},
|
||||
date: {
|
||||
color: colors.lightGray,
|
||||
fontSize: 14,
|
||||
marginLeft: 4,
|
||||
},
|
||||
|
|
@ -608,7 +603,6 @@ const styles = StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
},
|
||||
rating: {
|
||||
color: colors.primary,
|
||||
fontSize: 14,
|
||||
marginLeft: 4,
|
||||
fontWeight: 'bold',
|
||||
|
|
@ -620,14 +614,12 @@ const styles = StyleSheet.create({
|
|||
padding: 20,
|
||||
},
|
||||
emptyText: {
|
||||
color: colors.text,
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
marginTop: 16,
|
||||
textAlign: 'center',
|
||||
},
|
||||
emptySubtext: {
|
||||
color: colors.lightGray,
|
||||
fontSize: 14,
|
||||
marginTop: 8,
|
||||
textAlign: 'center',
|
||||
|
|
@ -638,10 +630,8 @@ const styles = StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
padding: 12,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.border,
|
||||
},
|
||||
filterInfoText: {
|
||||
color: colors.text,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
|
|
@ -655,7 +645,6 @@ const styles = StyleSheet.create({
|
|||
padding: 20,
|
||||
},
|
||||
emptyFilterText: {
|
||||
color: colors.text,
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
marginTop: 16,
|
||||
|
|
@ -664,11 +653,9 @@ const styles = StyleSheet.create({
|
|||
clearFilterButtonLarge: {
|
||||
marginTop: 20,
|
||||
padding: 16,
|
||||
backgroundColor: colors.primary,
|
||||
borderRadius: 8,
|
||||
},
|
||||
clearFilterButtonText: {
|
||||
color: colors.text,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
|
|
@ -681,7 +668,6 @@ const styles = StyleSheet.create({
|
|||
padding: 8,
|
||||
},
|
||||
headerTitle: {
|
||||
color: colors.text,
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
marginLeft: 12,
|
||||
|
|
@ -694,16 +680,13 @@ const styles = StyleSheet.create({
|
|||
},
|
||||
discoverButton: {
|
||||
padding: 16,
|
||||
backgroundColor: colors.primary,
|
||||
borderRadius: 8,
|
||||
},
|
||||
discoverButtonText: {
|
||||
color: colors.text,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
noEpisodesText: {
|
||||
color: colors.text,
|
||||
fontSize: 14,
|
||||
marginBottom: 4,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import {
|
|||
StatusBar,
|
||||
} from 'react-native';
|
||||
import { MaterialIcons } from '@expo/vector-icons';
|
||||
import { colors } from '../styles/colors';
|
||||
import { useTheme } from '../contexts/ThemeContext';
|
||||
import { notificationService, NotificationSettings } from '../services/notificationService';
|
||||
import Animated, { FadeIn, FadeOut } from 'react-native-reanimated';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
|
|
@ -19,6 +19,7 @@ import { logger } from '../utils/logger';
|
|||
|
||||
const NotificationSettingsScreen = () => {
|
||||
const navigation = useNavigation();
|
||||
const { currentTheme } = useTheme();
|
||||
const [settings, setSettings] = useState<NotificationSettings>({
|
||||
enabled: true,
|
||||
newEpisodeNotifications: true,
|
||||
|
|
@ -155,36 +156,36 @@ const NotificationSettingsScreen = () => {
|
|||
|
||||
if (loading) {
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<View style={styles.header}>
|
||||
<SafeAreaView style={[styles.container, { backgroundColor: currentTheme.colors.darkBackground }]}>
|
||||
<View style={[styles.header, { borderBottomColor: currentTheme.colors.border }]}>
|
||||
<TouchableOpacity
|
||||
style={styles.backButton}
|
||||
onPress={() => navigation.goBack()}
|
||||
>
|
||||
<MaterialIcons name="arrow-back" size={24} color={colors.text} />
|
||||
<MaterialIcons name="arrow-back" size={24} color={currentTheme.colors.text} />
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.headerTitle}>Notification Settings</Text>
|
||||
<Text style={[styles.headerTitle, { color: currentTheme.colors.text }]}>Notification Settings</Text>
|
||||
<View style={{ width: 40 }} />
|
||||
</View>
|
||||
<View style={styles.loadingContainer}>
|
||||
<Text style={styles.loadingText}>Loading settings...</Text>
|
||||
<Text style={[styles.loadingText, { color: currentTheme.colors.text }]}>Loading settings...</Text>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<SafeAreaView style={[styles.container, { backgroundColor: currentTheme.colors.darkBackground }]}>
|
||||
<StatusBar barStyle="light-content" />
|
||||
|
||||
<View style={styles.header}>
|
||||
<View style={[styles.header, { borderBottomColor: currentTheme.colors.border }]}>
|
||||
<TouchableOpacity
|
||||
style={styles.backButton}
|
||||
onPress={() => navigation.goBack()}
|
||||
>
|
||||
<MaterialIcons name="arrow-back" size={24} color={colors.text} />
|
||||
<MaterialIcons name="arrow-back" size={24} color={currentTheme.colors.text} />
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.headerTitle}>Notification Settings</Text>
|
||||
<Text style={[styles.headerTitle, { color: currentTheme.colors.text }]}>Notification Settings</Text>
|
||||
<View style={{ width: 40 }} />
|
||||
</View>
|
||||
|
||||
|
|
@ -193,72 +194,72 @@ const NotificationSettingsScreen = () => {
|
|||
entering={FadeIn.duration(300)}
|
||||
exiting={FadeOut.duration(200)}
|
||||
>
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>General</Text>
|
||||
<View style={[styles.section, { borderBottomColor: currentTheme.colors.border }]}>
|
||||
<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}>
|
||||
<MaterialIcons name="notifications" size={24} color={colors.text} />
|
||||
<Text style={styles.settingText}>Enable Notifications</Text>
|
||||
<MaterialIcons name="notifications" size={24} color={currentTheme.colors.text} />
|
||||
<Text style={[styles.settingText, { color: currentTheme.colors.text }]}>Enable Notifications</Text>
|
||||
</View>
|
||||
<Switch
|
||||
value={settings.enabled}
|
||||
onValueChange={(value) => updateSetting('enabled', value)}
|
||||
trackColor={{ false: colors.border, true: colors.primary + '80' }}
|
||||
thumbColor={settings.enabled ? colors.primary : colors.lightGray}
|
||||
trackColor={{ false: currentTheme.colors.border, true: currentTheme.colors.primary + '80' }}
|
||||
thumbColor={settings.enabled ? currentTheme.colors.primary : currentTheme.colors.lightGray}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{settings.enabled && (
|
||||
<>
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>Notification Types</Text>
|
||||
<View style={[styles.section, { borderBottomColor: currentTheme.colors.border }]}>
|
||||
<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}>
|
||||
<MaterialIcons name="new-releases" size={24} color={colors.text} />
|
||||
<Text style={styles.settingText}>New Episodes</Text>
|
||||
<MaterialIcons name="new-releases" size={24} color={currentTheme.colors.text} />
|
||||
<Text style={[styles.settingText, { color: currentTheme.colors.text }]}>New Episodes</Text>
|
||||
</View>
|
||||
<Switch
|
||||
value={settings.newEpisodeNotifications}
|
||||
onValueChange={(value) => updateSetting('newEpisodeNotifications', value)}
|
||||
trackColor={{ false: colors.border, true: colors.primary + '80' }}
|
||||
thumbColor={settings.newEpisodeNotifications ? colors.primary : colors.lightGray}
|
||||
trackColor={{ false: currentTheme.colors.border, true: currentTheme.colors.primary + '80' }}
|
||||
thumbColor={settings.newEpisodeNotifications ? currentTheme.colors.primary : currentTheme.colors.lightGray}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.settingItem}>
|
||||
<View style={[styles.settingItem, { borderBottomColor: currentTheme.colors.border + '50' }]}>
|
||||
<View style={styles.settingInfo}>
|
||||
<MaterialIcons name="event" size={24} color={colors.text} />
|
||||
<Text style={styles.settingText}>Upcoming Shows</Text>
|
||||
<MaterialIcons name="event" size={24} color={currentTheme.colors.text} />
|
||||
<Text style={[styles.settingText, { color: currentTheme.colors.text }]}>Upcoming Shows</Text>
|
||||
</View>
|
||||
<Switch
|
||||
value={settings.upcomingShowsNotifications}
|
||||
onValueChange={(value) => updateSetting('upcomingShowsNotifications', value)}
|
||||
trackColor={{ false: colors.border, true: colors.primary + '80' }}
|
||||
thumbColor={settings.upcomingShowsNotifications ? colors.primary : colors.lightGray}
|
||||
trackColor={{ false: currentTheme.colors.border, true: currentTheme.colors.primary + '80' }}
|
||||
thumbColor={settings.upcomingShowsNotifications ? currentTheme.colors.primary : currentTheme.colors.lightGray}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.settingItem}>
|
||||
<View style={[styles.settingItem, { borderBottomColor: currentTheme.colors.border + '50' }]}>
|
||||
<View style={styles.settingInfo}>
|
||||
<MaterialIcons name="alarm" size={24} color={colors.text} />
|
||||
<Text style={styles.settingText}>Reminders</Text>
|
||||
<MaterialIcons name="alarm" size={24} color={currentTheme.colors.text} />
|
||||
<Text style={[styles.settingText, { color: currentTheme.colors.text }]}>Reminders</Text>
|
||||
</View>
|
||||
<Switch
|
||||
value={settings.reminderNotifications}
|
||||
onValueChange={(value) => updateSetting('reminderNotifications', value)}
|
||||
trackColor={{ false: colors.border, true: colors.primary + '80' }}
|
||||
thumbColor={settings.reminderNotifications ? colors.primary : colors.lightGray}
|
||||
trackColor={{ false: currentTheme.colors.border, true: currentTheme.colors.primary + '80' }}
|
||||
thumbColor={settings.reminderNotifications ? currentTheme.colors.primary : currentTheme.colors.lightGray}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>Notification Timing</Text>
|
||||
<View style={[styles.section, { borderBottomColor: currentTheme.colors.border }]}>
|
||||
<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?
|
||||
</Text>
|
||||
|
||||
|
|
@ -268,13 +269,24 @@ const NotificationSettingsScreen = () => {
|
|||
key={hours}
|
||||
style={[
|
||||
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)}
|
||||
>
|
||||
<Text style={[
|
||||
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`}
|
||||
</Text>
|
||||
|
|
@ -283,27 +295,37 @@ const NotificationSettingsScreen = () => {
|
|||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>Advanced</Text>
|
||||
<View style={[styles.section, { borderBottomColor: currentTheme.colors.border }]}>
|
||||
<Text style={[styles.sectionTitle, { color: currentTheme.colors.text }]}>Advanced</Text>
|
||||
|
||||
<TouchableOpacity
|
||||
style={styles.resetButton}
|
||||
style={[
|
||||
styles.resetButton,
|
||||
{
|
||||
backgroundColor: currentTheme.colors.error + '20',
|
||||
borderColor: currentTheme.colors.error + '50'
|
||||
}
|
||||
]}
|
||||
onPress={resetAllNotifications}
|
||||
>
|
||||
<MaterialIcons name="refresh" size={24} color={colors.error} />
|
||||
<Text style={styles.resetButtonText}>Reset All Notifications</Text>
|
||||
<MaterialIcons name="refresh" size={24} color={currentTheme.colors.error} />
|
||||
<Text style={[styles.resetButtonText, { color: currentTheme.colors.error }]}>Reset All Notifications</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.resetButton,
|
||||
{ marginTop: 12, backgroundColor: colors.primary + '20', borderColor: colors.primary + '50' }
|
||||
styles.resetButton,
|
||||
{
|
||||
marginTop: 12,
|
||||
backgroundColor: currentTheme.colors.primary + '20',
|
||||
borderColor: currentTheme.colors.primary + '50'
|
||||
}
|
||||
]}
|
||||
onPress={handleTestNotification}
|
||||
disabled={countdown !== null}
|
||||
>
|
||||
<MaterialIcons name="bug-report" size={24} color={colors.primary} />
|
||||
<Text style={[styles.resetButtonText, { color: colors.primary }]}>
|
||||
<MaterialIcons name="bug-report" size={24} color={currentTheme.colors.primary} />
|
||||
<Text style={[styles.resetButtonText, { color: currentTheme.colors.primary }]}>
|
||||
{countdown !== null
|
||||
? `Notification in ${countdown}s...`
|
||||
: 'Test Notification (1min)'}
|
||||
|
|
@ -315,16 +337,16 @@ const NotificationSettingsScreen = () => {
|
|||
<MaterialIcons
|
||||
name="timer"
|
||||
size={16}
|
||||
color={colors.primary}
|
||||
color={currentTheme.colors.primary}
|
||||
style={styles.countdownIcon}
|
||||
/>
|
||||
<Text style={styles.countdownText}>
|
||||
<Text style={[styles.countdownText, { color: currentTheme.colors.primary }]}>
|
||||
Notification will appear in {countdown} seconds
|
||||
</Text>
|
||||
</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.
|
||||
</Text>
|
||||
</View>
|
||||
|
|
@ -339,7 +361,6 @@ const NotificationSettingsScreen = () => {
|
|||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: colors.darkBackground,
|
||||
},
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
|
|
@ -348,7 +369,6 @@ const styles = StyleSheet.create({
|
|||
paddingHorizontal: 16,
|
||||
paddingVertical: 12,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.border,
|
||||
},
|
||||
backButton: {
|
||||
padding: 8,
|
||||
|
|
@ -356,7 +376,6 @@ const styles = StyleSheet.create({
|
|||
headerTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
color: colors.text,
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
|
|
@ -367,18 +386,15 @@ const styles = StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
},
|
||||
loadingText: {
|
||||
color: colors.text,
|
||||
fontSize: 16,
|
||||
},
|
||||
section: {
|
||||
padding: 16,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.border,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: colors.text,
|
||||
marginBottom: 16,
|
||||
},
|
||||
settingItem: {
|
||||
|
|
@ -387,7 +403,6 @@ const styles = StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
paddingVertical: 12,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.border + '50',
|
||||
},
|
||||
settingInfo: {
|
||||
flexDirection: 'row',
|
||||
|
|
@ -395,12 +410,10 @@ const styles = StyleSheet.create({
|
|||
},
|
||||
settingText: {
|
||||
fontSize: 16,
|
||||
color: colors.text,
|
||||
marginLeft: 12,
|
||||
},
|
||||
settingDescription: {
|
||||
fontSize: 14,
|
||||
color: colors.lightGray,
|
||||
marginBottom: 16,
|
||||
},
|
||||
timingOptions: {
|
||||
|
|
@ -410,47 +423,32 @@ const styles = StyleSheet.create({
|
|||
marginTop: 8,
|
||||
},
|
||||
timingOption: {
|
||||
backgroundColor: colors.elevation1,
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 16,
|
||||
borderRadius: 8,
|
||||
borderWidth: 1,
|
||||
borderColor: colors.border,
|
||||
marginBottom: 8,
|
||||
width: '48%',
|
||||
alignItems: 'center',
|
||||
},
|
||||
selectedTimingOption: {
|
||||
backgroundColor: colors.primary + '30',
|
||||
borderColor: colors.primary,
|
||||
},
|
||||
timingText: {
|
||||
color: colors.text,
|
||||
fontSize: 14,
|
||||
},
|
||||
selectedTimingText: {
|
||||
color: colors.primary,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
resetButton: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
padding: 12,
|
||||
backgroundColor: colors.error + '20',
|
||||
borderRadius: 8,
|
||||
borderWidth: 1,
|
||||
borderColor: colors.error + '50',
|
||||
marginBottom: 8,
|
||||
},
|
||||
resetButtonText: {
|
||||
color: colors.error,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
marginLeft: 8,
|
||||
},
|
||||
resetDescription: {
|
||||
fontSize: 12,
|
||||
color: colors.lightGray,
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
countdownContainer: {
|
||||
|
|
@ -458,14 +456,13 @@ const styles = StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
marginTop: 8,
|
||||
padding: 8,
|
||||
backgroundColor: colors.primary + '10',
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.1)',
|
||||
borderRadius: 4,
|
||||
},
|
||||
countdownIcon: {
|
||||
marginRight: 8,
|
||||
},
|
||||
countdownText: {
|
||||
color: colors.primary,
|
||||
fontSize: 14,
|
||||
},
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue