From cb981c5380df4990df4a83b06096b5bee0ce982e Mon Sep 17 00:00:00 2001 From: Trey T Date: Sun, 31 May 2026 13:05:21 -0500 Subject: [PATCH] Route map: filter from allFlights + filters internally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the user opened the map and picked a year (e.g. 2026) in the in-map filter sheet, the map kept drawing every flight instead of just 2026. Root cause: the map was taking a pre-filtered `flights` prop from HistoryView via the .sheet content closure. SwiftUI does propagate the `filters` Binding into the sheet correctly, but it doesn't reliably re-render the .sheet content closure with the new pre-filtered prop value when the parent rerenders mid-presentation — so .onChange(of: filters) fires, reset() runs, but `self.flights` is the old (unfiltered) prop value, and the rebuilt schedule still includes every flight. Fix: stop relying on the parent doing the filtering. The map now takes `allFlights` (unfiltered) and computes the displayed set itself via `allFlights.filter { filters.matches($0) }`. Since `filters` is a Binding that propagates cleanly, the computed set is always in sync with whatever the user just selected in the filter sheet — no parent-render-order race. Also: when opening the map from HistoryView's toolbar or quick-link card, fold the year-strip `selectedYear` into `filters.years` so the map opens scoped to whatever the user was browsing on the home list. Co-Authored-By: Claude Opus 4.7 --- Flights/Views/HistoryRouteMapView.swift | 15 +++++++++++++-- Flights/Views/HistoryView.swift | 14 +++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Flights/Views/HistoryRouteMapView.swift b/Flights/Views/HistoryRouteMapView.swift index ff0fda5..8b0aefa 100644 --- a/Flights/Views/HistoryRouteMapView.swift +++ b/Flights/Views/HistoryRouteMapView.swift @@ -20,13 +20,24 @@ import CoreLocation /// 5. Bottom drawer is a real swipe-up sheet with detents — peek /// shows the count + replay; expanded shows filter chips. struct HistoryRouteMapView: View { - let flights: [LoggedFlight] // filtered - let allFlights: [LoggedFlight] // unfiltered (kept for parent-API compat) + /// The user's full unfiltered log. The map filters this set + /// internally by `filters` so changes from the in-map filter sheet + /// reliably re-scope the animation, even if the parent's + /// .sheet content closure doesn't propagate a new pre-filtered + /// array to us in time. + let allFlights: [LoggedFlight] let database: AirportDatabase let openSky: OpenSkyClient let store: FlightHistoryStore @Binding var filters: HistoryFilters + /// Locally-derived "what to draw" set. Recomputed on every body + /// pass; cheap because it's a single array filter on ~hundreds of + /// items at most. + private var flights: [LoggedFlight] { + allFlights.filter { filters.matches($0) } + } + @State private var position: MapCameraPosition = .automatic @State private var progress: Double = 0 @State private var animationKey: Int = 0 diff --git a/Flights/Views/HistoryView.swift b/Flights/Views/HistoryView.swift index 8366613..ea9602b 100644 --- a/Flights/Views/HistoryView.swift +++ b/Flights/Views/HistoryView.swift @@ -102,7 +102,13 @@ struct HistoryView: View { } Section("Explore") { Button { showingPassport = true } label: { Label("Passport", systemImage: "book.closed") } - Button { showingMap = true } label: { Label("Route map", systemImage: "map.fill") } + Button { + // Carry the year-strip scope into the map's + // filter binding so the map opens showing + // the same year the user was browsing. + if let y = selectedYear { filters.years = [y] } + showingMap = true + } label: { Label("Route map", systemImage: "map.fill") } Button { showingAircraftStats = true } label: { Label("Aircraft stats", systemImage: "airplane.circle") } Button { showingYearInReview = true } label: { Label("Year in Review", systemImage: "sparkles") } } @@ -123,7 +129,6 @@ struct HistoryView: View { .sheet(isPresented: $showingMap) { NavigationStack { HistoryRouteMapView( - flights: scoped, allFlights: flights, database: database, openSky: openSky, @@ -285,7 +290,10 @@ struct HistoryView: View { @ViewBuilder private var quickLinks: some View { HStack(spacing: 10) { - quickLink(title: "Map", icon: "map.fill") { showingMap = true } + quickLink(title: "Map", icon: "map.fill") { + if let y = selectedYear { filters.years = [y] } + showingMap = true + } quickLink(title: "Aircraft", icon: "airplane.circle.fill") { showingAircraftStats = true } quickLink(title: "Year", icon: "sparkles") { showingYearInReview = true } }