Skip to content

feat: enhance UX with altitude profile, GPS-flags & quick-start widgets - #4

Merged
fetzu merged 6 commits into
mainfrom
beautiful-pike
Dec 7, 2025
Merged

feat: enhance UX with altitude profile, GPS-flags & quick-start widgets#4
fetzu merged 6 commits into
mainfrom
beautiful-pike

Conversation

@fetzu

@fetzu fetzu commented Dec 7, 2025

Copy link
Copy Markdown
Owner

What’s changed
This PR introduces several new features aimed at improving usability and instrumentation visibility:
• Enhanced the flight-log altitude profile: the Y-axis is now constrained to ±500 ft around the recorded altitude range, making variations easier to perceive. Icons (SF Symbols) now replace plain text labels for flight events, and a gold-highlight altitude indicator adds emphasis to high-points. Touch interaction on the map view allows the user to jump to an aircraft’s position at any recorded time.
• Added GPS failure states in the instruments view. The classification thresholds now include: “Good” (green), “Degraded” (orange, e.g., no fix for >2.5 s), and “Lost” (red, no signal for 10+ s). A white “X” overlay is shown for degraded GPS and a red/black “X” for lost GPS — data is hidden when the GPS is lost, but the target speed indicator remains visible.
• Introduced home-screen widgets (iOS/iPadOS) in small and medium sizes, enabling:
• Quick single-tap start of a new flight (e.g., for F-HVXA or HB-PFA)
• Direct access to the flight log from the medium widget
• Deep-link support via the aerocheck:// URL scheme for start-flight and flight-log actions

fetzu and others added 6 commits December 6, 2025 21:55
- Constrain Y-axis range to ±500ft from recorded altitude range
- Replace text labels with SF Symbol icons for flight events
- Add touch interaction to show aircraft position on map
- Display altitude indicator with gold highlight on chart

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…tors

- Revise GPS signal classification thresholds:
  - Green (good): accurate GPS signal
  - Orange (degraded): inaccurate signal or no update for 2.5+ seconds
  - Red (lost): no GPS signal for 10+ seconds
- Add InstrumentFailureFlag component with avionics-style X pattern
- Display white X overlay on degraded signal (data still visible)
- Display red X with black background on lost signal (data hidden)
- Target speed indicator always remains visible regardless of GPS status
- Update both iPad and iPhone compact instrument views

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add Share button to flight detail view toolbar (opposite Close button)
- Create FlightShareCard view (1200x630 landscape format)
- Display flight name/aircraft, date, duration, distance, GPS points
- Show max altitude, go-arounds, and touch-and-goes when available
- Include visual timeline of flight events (engine start, takeoff, landing, shutdown)
- Use ImageRenderer to generate high-resolution PNG for sharing
- Integrate with Apple's native share sheet

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add iOS/iPadOS widgets in small and medium sizes that allow users to:
- Start a new flight with F-HVXA or HB-PFA with a single tap
- Access Flight Log directly (medium widget only)

Implements deep linking via aerocheck:// URL scheme to enable widget
functionality. The app now handles start-flight and flight-log URLs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add iOS/iPadOS widgets in small and medium sizes that allow users to:
- Start a new flight with F-HVXA or HB-PFA with a single tap
- Access Flight Log directly (medium widget only)

Implements deep linking via aerocheck:// URL scheme to enable widget
functionality. The app now handles start-flight and flight-log URLs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…nto beautiful-pike

* 'beautiful-pike' of https://github.com/fetzu/AeroCheck:
  feat(widget): add home screen widgets for quick flight start

; Conflicts:
;	AeroCheckWidget/AeroCheckWidget.swift
@fetzu
fetzu merged commit c95f0fb into main Dec 7, 2025
@fetzu
fetzu deleted the beautiful-pike branch December 7, 2025 09:53
fetzu added a commit that referenced this pull request Feb 5, 2026
- Fix Engine Hours modal button cutoff on iPad with flexible layout (#1)
- Add validation for engine hours end >= start with alert (#2)
- Reorder Block Off/On in Flight Log timeline to correct sequence (#3)
- Fix aircraft selection in nav plan to show all activated aircraft (#4)
- Show airports on map when opened from Home menu (#5)
- Add ICAO code search for waypoints in flight plan editor (#6)
- Add tap airport on map to add to route (#7)
- Show aircraft registration instead of ID in Flight Log detail (#8)
- Capitalize ROUTE label and show all waypoints in flight log (#9)
- Fix action buttons layout on small devices with scaling (#10)
- Show airport primary frequency in map callout (#11)

Migrates FlightPlan.aircraftType from enum to string-based ID with
backwards-compatible Codable migration for existing saved plans.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fetzu added a commit that referenced this pull request Jun 16, 2026
…enta route, single edit control

Device feedback on the From/To bar (#2):

- Search perf: each keystroke no longer triggers a synchronous ~40K-airport
  scan. `scheduleSearch` debounces ~200ms and coalesces typing bursts into one
  scan (still main-actor — the service is @mainactor). (#1)
- Distance ordering: `searchAirports` gains `near:` — results sort by distance
  within each relevance tier (exact ICAO → prefix → other) so a typed identifier
  still wins but the closest fields float up. Reference = the other endpoint if
  set, else GPS position, else the map you're looking at. Each result row now
  shows its distance (replacing the old add-arrow). (#2)
- Heliport filter: `AirportType.fixedWing` ([large/medium/small]) now filters
  both the builder search and its map query; heliports/seaplane/closed/balloon
  are hidden. CLAUDE.md documents the one-line re-enable for rotorcraft. (#3)
- Result rows: removed the confusing "add" arrow; the whole row is tappable
  (contentShape + full-width); added a municipality subtitle for disambiguation. (#4)
- Route styling: route polyline + waypoint markers now use the in-flight
  navigation magenta (1.0,0,0.8) with a black casing, matching the nav map and
  staying visible on every chart layer (gold washed out on some). (#6)
- Edit/Done redundancy: removed the list `EditButton` from the nav bar (it
  collided with the screen's "Done"). Reordering now lives in a single in-panel
  toggle (arrow.up.arrow.down) above the waypoint list, leaving one unambiguous
  "Done" to exit. (#7)

Plumbs LocationManager into FlightPlanningView → the builder (all 3 present
sites + preview) for the distance reference. 176 tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fetzu added a commit that referenced this pull request Jun 16, 2026
The builder now detects, highlights, and lists the airspaces your route crosses
— live, updating as you reshape the route (including after a #3 drag):

- New OpenAIPDataService.airspacesCrossedByRoute: takes the bounding-box
  candidates and keeps only those a ~1 NM-sampled point along the route actually
  falls inside (ray-cast containsPoint), so a leg transiting a CTR is caught even
  with no waypoint inside it. Restrictive airspaces (prohibited/restricted/
  danger) sort first.
- Map highlight: the crossed airspaces draw as translucent colored polygons
  (reusing NavigationView's AirspacePolygon + its type/class colors), under the
  magenta route. Incremental add/remove by id.
- Side panel: a collapsible conflicts banner under the route summary — red with a
  warning when any crossing is restrictive, amber otherwise ("N airspaces on
  route · M restricted"); expands to a list with each airspace's name, type/class,
  altitude band, and primary frequency.
- Recompute is debounced and keyed off a full-coordinate route signature (so a
  middle-waypoint move re-runs it), after ensuring downloaded OpenAIP data is
  loaded. No conflicts shown if no airspace data is downloaded (no false safety).

176 tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fetzu added a commit that referenced this pull request Jun 16, 2026
…rapolated altitude

The conflicts panel was listing every airspace the route's footprint touched,
including FL90–FL195 airways for a flight that never goes near FL90.

airspacesCrossedByRoute now takes the waypoints' planned altitudes, builds a
piecewise-linear altitude profile along the route (clamped at the ends), and only
flags an airspace when the extrapolated flight altitude where the route enters it
is within the airspace's vertical band ± a 500 ft separation buffer. Flight levels
are compared as ~MSL (the buffer absorbs QNH error). With no altitudes set on any
waypoint it falls back to horizontal-crossing only (previous behavior).

So with just the departure/destination field elevations set (both under FL90), the
high airways drop off and only the airspaces the flight actually transits remain.
The scan re-runs when a coordinate OR an altitude changes.

176 tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fetzu added a commit that referenced this pull request Jun 16, 2026
…ain + vertical separation)

Replaces the flat always-expanded airspace list with the VFR-standard vertical
profile, per the validated mockup:

- A ROUTE CHECK status bar (green clear / amber airspace / red restricted-or-terrain)
  above an inline cross-section: distance along the bottom, altitude up the side.
- The profile draws the terrain silhouette (swisstopo via ElevationService; empty
  outside CH), the extrapolated planned-altitude line, and every airspace the route
  enters as a block at its [floor, ceiling] over the distance it spans — conflicts
  solid, "context" zones the route clears vertically drawn faded (so the FL90 airway
  you pass under is visible but not a warning). Red ticks mark where clearance over
  terrain busts 150 m.
- Under it, the genuine conflicts only: a terrain-proximity row (if <150 m) plus
  each conflicting airspace (name, class, band, frequency).

New OpenAIPDataService.airspaceProfileBlocks returns per-airspace distance band +
vertical band + conflict flag (airspacesCrossedByRoute is now a thin filter over
it). New RouteAltitudeProfile extrapolates the planned altitude (shared by the
profile line and the terrain-clearance computation) and is unit-tested. Terrain is
fetched debounced, recomputed with the airspace scan on any geometry/altitude
change.

180 tests green (+4 for RouteAltitudeProfile).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fetzu added a commit that referenced this pull request Jun 16, 2026
…+ Waypoints/Conflicts toggle)

Reworks the crowded/dead-space arrangement per the validated mockup:

- The route profile moves out of the right column into a wide, collapsible strip
  UNDER the map (EFB convention) — far more horizontal resolution; expand button
  opens it full-screen (replacing the Terrain sheet).
- The right column now shows a compact summary + a Waypoints | Conflicts toggle
  (the Conflicts tab carries the route-check status as a colored count badge / ✓),
  so only one focused view shows at a time instead of stacking profile + conflicts
  + list.
- Removed the Terrain button (profile replaces it) and the bottom Export/Terrain
  action bar; Export GPX, Table editor and Fit route move into a top-right ••• menu.
- Dedup: the title no longer repeats FROM→TO (the on-map endpoint bar already shows
  it) — it's the custom name or a neutral "Flight plan".

This also pre-empts next round's popups: the inline+expandable profile makes the
Terrain Profile popup redundant, and the Table editor drops to the ••• menu.

184 tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fetzu added a commit that referenced this pull request Jun 16, 2026
…highlight, layout tweaks

- Smart-insert live preview: while holding to drop a waypoint, the route now shows
  it spliced in at the cheapest-insertion position, recomputed as you move it —
  instead of first drawing it appended to the end. Matches the commit behavior.
- Tap a conflict (airspace or terrain row) to highlight it: the row selects, its
  airspace polygon pops on the map (brighter + thicker), and its block (or the
  terrain ticks) emphasises in the profile. Tap again to clear; cleared on route
  change.
- Profile strip ~15% taller (118 → 136 pt).
- Layer selector moved to the map's bottom-left (center/fit stays bottom-right);
  From/To bar stays at the top.
- Removed the redundant "Fit route" item from the ••• menu.

184 tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fetzu added a commit that referenced this pull request Jun 16, 2026
…file "looking here" band

Dead-space (Direction A): removed the system nav bar — Done and ••• now float as
chrome over the map's top corners, above the From/To bar — so the map and the right
column both reclaim the ~44 pt bar and the grey gap (the column starts at the
summary). The redundant "Flight plan" title is gone.

Profile/viewport (the validated middle-ground over full viewport-follow): the
profile stays route-anchored (whole-route overview, stable axis), and now shades
the along-track window currently visible on the map — a "looking here" band with
edge markers that tracks as you pan/zoom, correlating the profile with the top-down
view without rescaling it.

184 tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fetzu added a commit that referenced this pull request Jun 16, 2026
…ace Direction B

- Hold-to-center: tapping a conflict still highlights it; holding it ~1 s now also
  recenters/zooms the map on it (airspace bounds, or the lowest-clearance point for
  the terrain row) so a small zone you can't see when zoomed out is brought into
  view. Backed by a focusRegion/focusToken on the map view (setRegion on change);
  light haptic on center.
- Dead-space — switched A → B (per preference): the system nav bar stays, but its
  dead "Flight plan" title is replaced by the live WPT · DIST · EET summary, so the
  right column drops its summary row and starts at the Waypoints/Conflicts toggle.
  Reverted the floating Done/••• overlay; Done + ••• live in the bar again.

184 tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fetzu added a commit that referenced this pull request Jun 17, 2026
The inline, resizable route profile (#4) replaced the full-screen terrain sheet, and
nothing opens TerrainProfileView anymore (only two stale comments referenced it).
Removed the file + its four project.pbxproj entries (build file, file reference,
group membership, Sources phase) and refreshed the two comments.

184 tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fetzu added a commit that referenced this pull request Jun 17, 2026
#3 Subscription/paywall: was already cockpit-styled (dark cards, gold accents,
featured yearly card) — aligned the section headers to the v4 uppercase-tracked style.

#4 WaypointEditorSheet: was the one genuine legacy Form — converted to the cockpit
settings kit (SettingsPage + SettingsGroup cards: Location / Altitude / Navigation /
Radio / Remarks / Timing + Delete), with a local fieldRow helper for the text inputs
(keyboard types, placeholders, monospaced fonts preserved) and the mini-map / elevation /
delete housed on the cards. All bindings, map picker, elevation loading, save/delete
preserved.

EventConfirmationView and HourMeterInputView needed no work — already cockpit-styled
(the earlier audit over-flagged them as legacy on missing phase-comments alone).

Build clean, 184 tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant