Night dimming now uses the actual sunrise/sunset at the active
location (classic Almanac algorithm) instead of a fixed 22:00-06:00
window, with a fallback to that fixed window while location or time
isn't known yet. Applies to both the backlight (main.cpp) and the
radar's own color dimming (radar_screen.cpp).
Heavy-category aircraft (ADS-B emitter category "A5") now get a
distinct marker (larger circle with an outer ring, plus the usual
heading line) instead of sharing the orange "notable" ring, on both
the device display and the WebUI radar.
Note: the orange "notable" ring itself (military/government callsign
prefixes) remains unimplemented - Config::NOTABLE_CALLSIGN_PREFIXES
has never been defined anywhere in this project. The WebUI radar's
"notable" field is hardcoded false until that's actually specified;
on the device it was never wired up in the first place.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Detail panel now shows origin/destination via adsbdb.com callsign
lookup. Rotorcraft (ADS-B category A7) get a distinct rotor-cross
marker instead of a heading arrowhead, same rationale as the existing
ground-vehicle marker. WebUI info screen gets a QR button (when WiFi
is connected) that renders the local WebUI URL as a scannable code.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Bundles several small local follow-ups since v3.3.0:
- Radar screen aircraft detail panel: long lines (model name, distance
with km/nm/mi) now scroll horizontally instead of being cut off with
"..." (up to 9 independent scrolling lines, reusing the existing
InfoMarquee pattern).
- "Setup complete" screen: small centered "Tap to skip" hint below the
countdown button, translated into all 6 languages.
- Location Presets screen: long preset names/coordinates in the list
now scroll left-aligned instead of being truncated with "...".
- Address search confirmation screen: the found place name is no
longer hard-cut at 150 characters - it's now a vertically scrollable
paragraph (same pattern as the existing Location Presets info
screen), since it's multi-line wrapped text rather than a single
overflowing line.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Mirrors the existing detail-panel star field (updateDetailPanelStars)
with the same twinkle logic, but placed via rejection sampling outside
the radar circle (radius + margin around the center) so it never
collides with the sweep line, aircraft markers, or rings redrawn every
tick(). Star positions are computed once on first tick() and never
redistributed, same as the detail-panel field.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Five places ignored the Units setting (Menu > Units) and always showed
fixed metric values even when Imperial was selected: the radar range
button (now km/nm), the radar's ring distance labels (now km/nm), the
aircraft list's altitude/distance columns (now m+km or ft+nm), the
Location Presets screen's nearest-airport distance (now km/nm), and
the Stats screen's highest-altitude-today line (now m or ft). The
range button had already been touched previously but used "mi"
instead of "nm" - aligned to nm here for consistency with the other
distance displays, which all pair with km rather than miles.
The radar detail panel's simultaneous multi-unit display and the
climb/descent rate (always ft/min, aviation convention) are
intentionally left unchanged.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The yellow (mid-altitude) legend entry was pinned to a fixed 1/3-grid
column like the outer green/red entries, but its label ("3000-9100")
is noticeably longer than the others, making it sit visually too far
right - almost touching the red entry while leaving a lot of empty
space next to the short green label. Green and red keep their fixed
positions; yellow is now centered in the actual gap between them,
computed from gfx.textWidth() so it works correctly in both unit
modes (Metric and Imperial).
Refreshes firmware.bin to match this build.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The header clock now shows 12-hour time with AM/PM when Imperial
units are selected (Menu > Units), instead of always using 24-hour
format - the clock-clear region was widened from 50px to 80px to fully
erase the longer "12:59PM"-style text.
The aircraft detail panel's distance line now also shows miles
alongside km and nautical miles (e.g. "12km / 6nm / 7mi"), since nm
alone wasn't self-explanatory for lay users from Imperial-unit
countries.
Also fixes the radar screen's range button, which still always showed
a fixed "km" label regardless of the Metric/Imperial setting - it now
shows mi (converted) when Imperial is selected, matching the pattern
already used by the altitude legend.
Refreshes firmware.bin to match this build.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ground vehicles (ADS-B emitter category "C*") now render as filled
blue squares instead of the normal circle+arrowhead aircraft marker,
using a fixed color independent of altitude (they're practically
always at 0ft, which would otherwise collide with the low-altitude
green). A second legend line explains the marker, but only when
ground vehicles are actually visible (Flight Options > "Hide ground
vehicles" off) - the info bar height, and therefore the radar circle
size, is otherwise unchanged from before.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The trail/tail-line rendering behind each aircraft marker was already
superseded by the heading arrowhead in drawAircraftMarker() but was
never removed, so it kept running in parallel (dimColorForAltitude,
TrailEntry, clearTrails/pruneStaleTrails/findOrCreateTrail/
pushTrailPoint/drawTrail, and their call sites in render(), tick() and
handleTap()) - all removed as dead weight.
The proximity-alert blink-off phase used to paint a flat 40x30px black
rectangle over each nearby aircraft to hide it, which also blacked out
the radar rings/compass lines underneath regardless of altitude color
(the blink logic is purely distance-based). Now redraws the exact same
shapes used for normal rendering (marker, emergency/watchlist ring,
label) in black instead, so only the aircraft itself disappears during
the blink-off phase.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Two bugs from the radar info marquee: the line briefly blinked on
every fetch cycle (visible in sync with the heartbeat LED) because
render() clears the line but tick() didn't redraw it for up to 80ms;
fixed by having render() immediately redraw the marquee at its current
scroll state right after clearing.
The "empty sky since..." text never scrolled even as it grew longer,
because needsScroll was only computed once when the marquee was first
set up (with the short "...0s" text) and never re-checked as the text
grew. updateInfoMarqueeText() now re-evaluates needsScroll on every
call.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The bottom info line on the radar screen (tap hint / empty-sky timer)
is now a continuously scrolling marquee instead of static text,
consistent with the nearest-airport ticker on the Location Presets
screen. The text is redrawn every tick() call (80ms) rather than only
on render(), so it scrolls smoothly and the empty-sky second counter
keeps advancing fluidly.
Also clarifies the tap hint in all 6 languages to make it explicit
that you need to tap an aircraft (e.g. "Tap an aircraft for more
details" instead of the more ambiguous "Tap for details").
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
New:
- Flight logbook safety net: disabled by default, requires confirming
a full-screen warning before it can be turned on, and automatically
switches off again after exactly 24 hours - survives restarts and
power cycles (no valid enable timestamp = guaranteed off). Each
activation now writes its own CSV file instead of endlessly
appending to one growing file, and every file can be deleted
individually from Logbook files.
- Adjustable display brightness (10-100% in 10% steps, Menu -> System
-> "Brightness") with a live preview.
- About screen (Menu -> System -> "About") showing project name,
description, and firmware version.
Fixed:
- Radar's red altitude band (>9100m/30000ft) no longer gets dimmed at
night - the previous dim tone looked orange-brown and was hard to
tell apart from yellow. Legend and markers are consistent again.
- Radius change no longer leaves a stale "tail" trail behind each
aircraft between the old and new position.
- Splash screen no longer shows a time-of-day greeting that appeared
too late in the boot sequence to be useful; the star animation now
starts immediately instead of only near the end of boot.
- Clock stayed on raw UTC after the first boot instead of local time
(missing DST handling in some timezones) because the location wait
loop skipped the timezone lookup once a location was already saved.
- Header clock no longer leaves stale digit fragments behind the
current time, most visible on the last minute digit.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
New:
- Aircraft list (Menu -> Flight Options, top entry): sortable list
(distance/altitude/callsign) of every aircraft currently in range,
with the same altitude color-coding and emergency/watchlist border
highlighting as the radar. Tapping a row jumps back to the radar
with that aircraft's detail panel already open.
- Night dimming now also softens the radar screen itself (aircraft
markers and the sweep line switch to darker tones) during the
existing 22:00-06:00 window, reusing the same setting - no new
toggle.
Improved:
- Removed the unused built-in TFT_eSPI number fonts (GLCD/Font2/
Font4/Font6/Font7/Font8) from platformio.ini - the project only
ever uses the custom UI font via setFreeFont(). Saves ~15KB flash.
Also documents a CYD-flightradar.bin staleness safety check in the
CLAUDE.md release workflow (delete any leftover copy from a previous
release before renaming the fresh build, so an old binary can never
be silently re-used for a GitHub release).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Three small layout bugs found after v2.7.0:
- Watchlist info screen title now wraps word-by-word via
layoutWrapped() instead of println(), which cut it off mid-word.
- Watchlist overview screen draws the "?" info button first, so the
title and two description lines start below it instead of running
underneath and getting obscured.
- The radar's "empty sky for..." timer now shows only whole minutes
once past the first minute (e.g. "2min" instead of "2min 05s"),
since the seconds suffix collided with the range button.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Three small usability additions:
- Splash screen now shows a "Good morning/day/evening" greeting under
the title, based on local time (computed after the timezone offset
from IP geolocation is applied via configTime(), not before, so it
reflects actual local time rather than UTC).
- Selecting an aircraft on the radar now also draws a dotted bearing
line plus a degree label from the radar center to the compass edge,
showing which direction to actually look to spot it in the sky
(distinct from the aircraft's own heading arrow).
- The radar info bar now shows "Empty sky for <time>" instead of the
"tap for details" hint whenever no aircraft are currently in range
after all filters, counting up from the last sighting.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
drawAircraftMarker() previously drew a plain symmetric line for an
aircraft's heading, making it impossible to tell at a glance which
end pointed "forward". The line now ends in a small two-stroke
arrowhead (chevron), so the direction of travel is unambiguous.
Also documents that the index.html version-badge check (release
workflow step 4) is mandatory and not optional, since it was
accidentally skipped on a recent patch release.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>