fix: deduplicate recurring event masters vs expanded instances
Recurring events appeared twice on their creation day because both the series master (from POST cache) and the expanded instance (from sync) had different IDs. Now filters out masters when instances exist, and also deduplicates by title+startTime+calendarId as a fallback. v1.66.1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
13de53fe0a
commit
dbe60dd331
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "my-weekly-todo-list",
|
"name": "my-weekly-todo-list",
|
||||||
"version": "1.66.0",
|
"version": "1.66.1",
|
||||||
"description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view",
|
"description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -1613,11 +1613,29 @@ export default function WeeklyView() {
|
|||||||
const [weatherData, setWeatherData] = useState<Record<string, WeatherHour>>({});
|
const [weatherData, setWeatherData] = useState<Record<string, WeatherHour>>({});
|
||||||
|
|
||||||
// Extend events with editable flag from connections, deduplicate by id
|
// Extend events with editable flag from connections, deduplicate by id
|
||||||
|
// Also deduplicate recurring series masters vs expanded instances:
|
||||||
|
// When a recurring event is created, the master is cached. Then the sync
|
||||||
|
// returns expanded instances with different IDs but the same recurringEventId.
|
||||||
|
// We keep instances and discard masters that overlap with them.
|
||||||
const calendarEvents = useMemo(() => {
|
const calendarEvents = useMemo(() => {
|
||||||
const seen = new Set<string>();
|
const seen = new Set<string>();
|
||||||
|
const seenSlot = new Set<string>();
|
||||||
|
// Collect recurring event IDs that have expanded instances
|
||||||
|
const seriesWithInstances = new Set<string>();
|
||||||
|
for (const event of rawCalendarEvents) {
|
||||||
|
if (event.recurringEventId && event.id !== event.recurringEventId) {
|
||||||
|
seriesWithInstances.add(event.recurringEventId);
|
||||||
|
}
|
||||||
|
}
|
||||||
return rawCalendarEvents.filter((event) => {
|
return rawCalendarEvents.filter((event) => {
|
||||||
if (seen.has(event.id)) return false;
|
if (seen.has(event.id)) return false;
|
||||||
seen.add(event.id);
|
seen.add(event.id);
|
||||||
|
// Skip series master if expanded instances exist for this series
|
||||||
|
if (seriesWithInstances.has(event.id)) return false;
|
||||||
|
// Deduplicate by title+startTime+calendarId (catches optimistic add + cache read)
|
||||||
|
const slotKey = `${event.title}|${event.startTime}|${event.calendarId}`;
|
||||||
|
if (seenSlot.has(slotKey)) return false;
|
||||||
|
seenSlot.add(slotKey);
|
||||||
return true;
|
return true;
|
||||||
}).map((event) => {
|
}).map((event) => {
|
||||||
let isEditable = false;
|
let isEditable = false;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user