From c6f9981a547384a08a6cf707495f4f24c0d2f625 Mon Sep 17 00:00:00 2001 From: Scarriffle Date: Sun, 31 May 2026 21:14:48 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20Gruppenansicht=20=E2=80=93=20Termine=20?= =?UTF-8?q?=C3=BCber=20Cache/Prefetch=20laden=20(kein=20Range-Gap)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Der Gruppen-Modus ersetzte events nur mit dem schmalen aktuellen Fetch, statt denselben Cache/Prefetch-Pfad wie die Normalansicht zu nutzen -> Termine erschienen erst nach Scrollen. Jetzt fetchForMode (personal/group) läuft durch loadEvents + prefetchBackground + refreshFromCache; Moduswechsel lädt breit neu. In der Gruppenansicht greift der "ausgeblendet"-Filter nicht. Co-Authored-By: Claude Opus 4.8 --- Calendarr iOS/Models/CalendarStore.swift | 35 ++++++++++--------- .../Views/Calendar/CalendarHostView.swift | 4 ++- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/Calendarr iOS/Models/CalendarStore.swift b/Calendarr iOS/Models/CalendarStore.swift index 8832d73..725cfd4 100644 --- a/Calendarr iOS/Models/CalendarStore.swift +++ b/Calendarr iOS/Models/CalendarStore.swift @@ -219,6 +219,12 @@ class CalendarStore { /// `start` / `end` are kept in the signature for call-site clarity. func refreshFromCache(start: Date, end: Date) { _ = (start, end) + // In group overlay mode show everything (the per-calendar hide/banish + // toggles are for the personal view only). + if activeGroup != nil { + events = allCachedEvents + return + } events = allCachedEvents.filter { ev in let key = Self.calendarKey(source: ev.source, calendarId: ev.calendarId) return !hiddenCalendarKeys.contains(key) @@ -242,20 +248,6 @@ class CalendarStore { /// unless `force` is set (used after create/edit to pull fresh server data /// for the visible range, bypassing the cache). func loadEvents(api: CalendarrAPI, start: Date, end: Date, force: Bool = false) async { - // Group overlay mode: always fetch the combined view for the range - // (no personal cache), decorating each event with its owner. - if let g = activeGroup { - isLoading = true - lastError = nil - defer { isLoading = false } - do { - let fetched = try await api.fetchGroupCombined(groupId: g.id, start: start, end: end) - events = fetched.map { decorateGroupEvent($0) } - } catch { - lastError = error.localizedDescription - } - return - } if !force, isCached(start: start, end: end) { refreshFromCache(start: start, end: end) return @@ -264,7 +256,7 @@ class CalendarStore { lastError = nil defer { isLoading = false } do { - let fetched = try await api.fetchEvents(start: start, end: end) + let fetched = try await fetchForMode(api: api, start: start, end: end) mergeIntoCache(fetched, rangeStart: start, rangeEnd: end) refreshFromCache(start: start, end: end) } catch { @@ -272,6 +264,17 @@ class CalendarStore { } } + /// Fetch events for the current mode (personal vs. group overlay). Group + /// events go through the same cache/prefetch/refresh path as personal ones, + /// so the whole visible grid is covered (no "only the middle weeks" gaps). + private func fetchForMode(api: CalendarrAPI, start: Date, end: Date) async throws -> [CalEvent] { + if let g = activeGroup { + let combined = try await api.fetchGroupCombined(groupId: g.id, start: start, end: end) + return combined.map { decorateGroupEvent($0) } + } + return try await api.fetchEvents(start: start, end: end) + } + /// Prefix a combined-view event with its owner (others) or 👥 + creator /// (group calendar). Colour comes from the server's display_color. private func decorateGroupEvent(_ ev: CalEvent) -> CalEvent { @@ -298,7 +301,7 @@ class CalendarStore { isCachingBackground = true defer { isCachingBackground = false } do { - let fetched = try await api.fetchEvents(start: start, end: end) + let fetched = try await fetchForMode(api: api, start: start, end: end) mergeIntoCache(fetched, rangeStart: start, rangeEnd: end) // Refresh visible range from newly expanded cache let (vs, ve) = rangeForCurrentView() diff --git a/Calendarr iOS/Views/Calendar/CalendarHostView.swift b/Calendarr iOS/Views/Calendar/CalendarHostView.swift index 709ad5b..78c4164 100644 --- a/Calendarr iOS/Views/Calendar/CalendarHostView.swift +++ b/Calendarr iOS/Views/Calendar/CalendarHostView.swift @@ -251,7 +251,9 @@ struct CalendarHostView: View { private func switchGroup(_ g: CalGroup?) { store.activeGroup = g - Task { await onNavigate() } + // The cache holds the previous mode's events — drop it and reload the + // visible range + prefetch a wide window so the whole grid is covered. + Task { await forceReload() } } private var viewPickerMenu: some View {