fix: recurring event display and AI query improvements
- Use occurrenceStart instead of startTime in getEventsInRange so recurring events show their actual occurrence date to the AI - Add lazy CalDAV sync in ChatService (syncOnce before first DB access) - Add CaldavService.sync() with internal config check (silent no-op) - Show German recurrence description (e.g. "Jede Woche") instead of generic "Wiederkehrend" in EventCardBase via formatRecurrenceRule() - Move RepeatType and REPEAT_TYPE_LABELS from editEvent to shared - Separate calendar overlay useFocusEffect from event loading
This commit is contained in:
@@ -122,17 +122,22 @@ const Calendar = () => {
|
||||
// Load events when tab gains focus or month/year changes
|
||||
// NOTE: Wrapper needed because loadEvents is async (returns Promise)
|
||||
// and useFocusEffect expects a sync function (optionally returning cleanup)
|
||||
// Also re-open overlay if selectedDate exists (for back navigation from editEvent)
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
loadEvents();
|
||||
if (selectedDate) {
|
||||
setOverlayVisible(true);
|
||||
}
|
||||
|
||||
const interval = setInterval(loadEvents, 10_000);
|
||||
return () => clearInterval(interval);
|
||||
}, [loadEvents, selectedDate]),
|
||||
}, [loadEvents]),
|
||||
);
|
||||
|
||||
// Re-open overlay after back navigation from editEvent
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
if (selectedDate) {
|
||||
setOverlayVisible(true);
|
||||
}
|
||||
}, [selectedDate]),
|
||||
);
|
||||
|
||||
// Group events by date (YYYY-MM-DD format)
|
||||
|
||||
@@ -19,7 +19,7 @@ import { Ionicons } from "@expo/vector-icons";
|
||||
import { ScrollableDropdown } from "../components/ScrollableDropdown";
|
||||
import { useDropdownPosition } from "../hooks/useDropdownPosition";
|
||||
import { EventService, ChatService } from "../services";
|
||||
import { buildRRule, CreateEventDTO } from "@calchat/shared";
|
||||
import { buildRRule, CreateEventDTO, REPEAT_TYPE_LABELS, RepeatType } from "@calchat/shared";
|
||||
import { useChatStore } from "../stores";
|
||||
import CustomTextInput, {
|
||||
CustomTextInputProps,
|
||||
@@ -86,15 +86,6 @@ const PickerRow = ({
|
||||
);
|
||||
};
|
||||
|
||||
type RepeatType = "Tag" | "Woche" | "Monat" | "Jahr";
|
||||
|
||||
const REPEAT_TYPE_LABELS: Record<RepeatType, string> = {
|
||||
Tag: "Tage",
|
||||
Woche: "Wochen",
|
||||
Monat: "Monate",
|
||||
Jahr: "Jahre",
|
||||
};
|
||||
|
||||
type RepeatPressableProps = {
|
||||
focused: boolean;
|
||||
repeatType: RepeatType;
|
||||
|
||||
@@ -19,7 +19,7 @@ export const EventCard = ({ event, onEdit, onDelete }: EventCardProps) => {
|
||||
startTime={event.occurrenceStart}
|
||||
endTime={event.occurrenceEnd}
|
||||
description={event.description}
|
||||
isRecurring={!!event.recurrenceRule}
|
||||
recurrenceRule={event.recurrenceRule}
|
||||
>
|
||||
{/* Action buttons - TouchableOpacity with delayPressIn allows ScrollView to detect scroll gestures */}
|
||||
<View className="flex-row justify-end mt-3 gap-3">
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
formatDateWithWeekday,
|
||||
formatDateWithWeekdayShort,
|
||||
formatTime,
|
||||
formatRecurrenceRule,
|
||||
} from "@calchat/shared";
|
||||
|
||||
type EventCardBaseProps = {
|
||||
@@ -16,7 +17,7 @@ type EventCardBaseProps = {
|
||||
startTime: Date;
|
||||
endTime: Date;
|
||||
description?: string;
|
||||
isRecurring?: boolean;
|
||||
recurrenceRule?: string;
|
||||
children?: ReactNode;
|
||||
};
|
||||
|
||||
@@ -46,7 +47,7 @@ export const EventCardBase = ({
|
||||
startTime,
|
||||
endTime,
|
||||
description,
|
||||
isRecurring,
|
||||
recurrenceRule,
|
||||
children,
|
||||
}: EventCardBaseProps) => {
|
||||
const { theme } = useThemeStore();
|
||||
@@ -95,7 +96,7 @@ export const EventCardBase = ({
|
||||
</View>
|
||||
|
||||
{/* Recurring indicator */}
|
||||
{isRecurring && (
|
||||
{recurrenceRule && (
|
||||
<View className="flex-row items-center mb-1">
|
||||
<Feather
|
||||
name="repeat"
|
||||
@@ -103,7 +104,9 @@ export const EventCardBase = ({
|
||||
color={theme.textPrimary}
|
||||
style={{ marginRight: 8 }}
|
||||
/>
|
||||
<Text style={{ color: theme.textPrimary }}>Wiederkehrend</Text>
|
||||
<Text style={{ color: theme.textPrimary }}>
|
||||
{formatRecurrenceRule(recurrenceRule)}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ export const ProposedEventCard = ({
|
||||
startTime={event.startTime}
|
||||
endTime={event.endTime}
|
||||
description={event.description}
|
||||
isRecurring={!!event.recurrenceRule}
|
||||
recurrenceRule={event.recurrenceRule}
|
||||
>
|
||||
{/* Show new exception date for delete/single actions */}
|
||||
{newExceptionDate && (
|
||||
|
||||
Reference in New Issue
Block a user