- Leaving the Album put the camera in video mode even when it had been in
photo mode: it restored FlightModel.captureMode, which only follows the HUD
switch. It now restores the mode the camera reported before it was taken.
- Playing a video on the aircraft drew the player over the whole HUD. The
Album now sets FlightModel.hudHidden, and the flight screen shows only the
feed, full-screen, while it is set (the HUD stays mounted, offstage).
- Map tiles that failed once stayed as dark squares. Every map now uses one
OpenStreetMap provider whose client also retries dropped connections, and
failed tiles are fetched again when panned back into view.
- Find My Drone saved simulated positions as the aircraft's last fix.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The app still shipped under the identity of the DJI MSDK Flutter sample it
was started from, so every install, log line and crash report named a DJI
sample rather than PilotVault. Rename both namespaces:
Android com.dji.flutter.dji_msdk_sample -> com.pilotvault.flyapp
Dart dji_msdk_sample -> pilotvault_fly
The Kotlin sources move under com/pilotvault/flyapp to match. The manifest's
meta-data name stays com.dji.sdk.API_KEY — that string is fixed by the SDK's
own lookup and is not ours to rename.
A DJI App Key is bound to the application id, so the old key died with the
old id and a new one was registered against com.pilotvault.flyapp. That
forced the key to be touched anyway, so stop committing it: the Gradle
property becomes PILOTVAULT_FLY_API_KEY and now lives in the developer's
~/.gradle/gradle.properties, which Gradle merges into every build.
android/gradle.properties keeps the build flags — gitignoring it wholesale
would have taken useAndroidX and the Flutter migrator flags out of version
control with it — and documents where the key belongs.
A missing key prints a banner rather than silently baking the placeholder
into an APK that cannot register, which otherwise only surfaces as a
registration failure once the tablet is out at the aircraft. That warning
uses println because `flutter build` filters Gradle's warn-level output.
The rename means Android treats this as a new app: uninstall
com.dji.flutter.dji_msdk_sample before installing, or both will sit on the
tablet.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rebuild the Flutter/DJI-MSDK-V4 Fly App to the v2 UI kit and wire the
full SDK surface behind it.
Native (Kotlin): split DjiSdkBridge into a method/event router delegating
to per-subsystem SubBridge helpers sharing a BridgeCtx — FlightController
(takeoff/land/RTH + rich telemetry), Camera (mode/record/photo/exposure),
Gimbal, Mission (Waypoint + ActiveTrack; QuickShots via ActiveTrack
QUICK_SHOT), Media (MediaManager list/thumbnail/download), and optional
DJI account login. Manifest gains scoped media permissions.
Flutter: ten screens under lib/ui/ (Flight HUD, capture modes, camera
settings, settings menu, map+waypoints, home, album, academy, profile,
routes/flight logs), driven by an expanded FlightModel. New PVIcon renders
the kit's SVG paths via flutter_svg; map uses flutter_map + latlong2.
Pin transitive androidx.core/browser down to SDK-35-compatible versions
so the newer plugins don't force AGP 8.9.1 onto the DJI toolchain.
Verified with `flutter build apk --debug` (compiles Dart + all Kotlin);
runtime behaviour is untested here — it needs a physical DJI-connected
device.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The OpenSky "Default bounding box" now follows where flying happens.
A new "Automatic" picker mode (the default) resolves the live-map area
from a location cascade — drone telemetry → phone GPS → browser
geolocation → the user's Region country → Europe — instead of a fixed
box. Manual presets and Custom coordinates still work.
- Web App: new shared countries.js dataset (all countries + bbox,
offline point→country); the bbox picker gains all European countries
and an Automatic option (client pref prefs.autoBbox); the Region
setting expands from 6 locale entries to all countries; the live map
resolves the cascade each poll and sends it as ?bbox=.
- API Server: the states endpoint accepts and validates a ?bbox=
override (validBBox); the Web App BFF forwards the query; the hub
relays new phoneLatitude/phoneLongitude telemetry to the Web App.
- Fly App: reports the phone's own GPS (geolocator) alongside
telemetry, used as the "your location" fallback.
- API panel: the OpenSky bbox picker lists all European countries.
Builds verified across web, panel, both Go modules and the Fly App
APK. Region list, Automatic default and the cascade ?bbox= override
verified in the browser.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add API Server (Go/PocketBase), Web App (Go BFF + Vue), Fly App
(Flutter/DJI MSDK), Adobe Plugin, and Docker/Docker AIO deployment
configs. Design assets and build artifacts are gitignored.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>