Roadstr

app.roadstr
by LWB lwb89@cosanostr.com

**Roadstr** is an open-source, decentralised navigation app for Android, built on the [Nostr protocol](https://nostr.com/). It combines real-time GPS turn-by-turn navigation with community-sourced traffic alerts published as Nostr events, on-device AI voice guidance, Lightning Network tips for contributors, and privacy-first map data powered by OpenStreetMap.

First release: Jun 28, 2026, 42 total releases.

Most recent release: Sep 25, 2026.

Repo

Appears in 3 app stacks.

6,563 sats / 7 zaps received in the past year.

Sats Received

Underlying data available via MCP: app_zaps, app_releases.

Zap Count

Underlying data available via MCP: app_zaps, app_releases.

Releases

  • Sep 25, 2026 0.5.11
    # Roadstr 0.5.11 Turn-by-turn directions in the language you chose. ## Fixed - On the new map, the **turn-by-turn instructions were always in Italian**, whatever language the app was set to. Read aloud by a voice in your language, that came out as Italian with a foreign accent. They now follow the app's language.
    More…
    - With the language left on "system default", the **voice started in Italian** instead of the phone's language. It now follows the phone. - GraphHopper directions are now requested in the app's language (they were only ever Italian or English), and a language OpenRouteService does not offer falls back to English instead of failing the route. - Wikipedia place summaries fell back to the Italian edition when there was no article in your language. They now fall back to English. ## Updating Signed with the same release key as every previous version, so it installs over the top of an existing one — no need to uninstall, and nothing is lost. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 24, 2026 0.5.10
    # Roadstr 0.5.10 Police stations as a road report, the altitude readout back on the MapLibre home screen, and a round of battery savings. ## Added - **Police stations** can now be reported as their own road event. They are separate from the existing police report, which is a patrol or checkpoint that is gone within hours: a station is a building, so its marker stays on
    More…
    the map for 30 days, like a speed camera, and it gets no voice warning as you pass. Older versions show it as a generic "Other" marker. ## Fixed - The **altitude readout** had disappeared from the MapLibre map on the home screen since the last redesign, and the setting for it was buried in a collapsed "Road element overlays" group. Both are fixed: it shows again, and the switch is now a row of its own in the Map section. ## Changed ### Battery - Map markers (crosswalks, traffic lights, speed bumps, cameras, reports) are now built only when they can actually be on screen. Before, every marker in range was rebuilt on every camera frame, off-screen ones included, which in a dense city meant hundreds a frame. - The map camera is no longer re-rendered when it has not visibly moved — mostly in slow traffic. At road speed and in turns nothing changes. - The map camera stops animating while the app is in the background, so navigating with the screen off and just the voice no longer keeps the phone busy following a map nobody can see. - The distance in the navigation notification is updated at most once every three seconds instead of twice a second (a new instruction still shows at once), and the compass sensors only run when something can use them. - Map data (traffic lights, crosswalks, speed cameras) is no longer re-downloaded every two minutes while parked, and is fetched less often while driving. Traffic lights and crosswalks are also skipped while the screen is off, since they only feed map markers. ### Navigation - Finds its place on long routes without rescanning the whole route on every GPS fix, does much less work up front when starting a long route with many manoeuvres, and copes better with routes that double back over the same road. ## Updating Signed with the same release key as every previous version, so it installs over the top of an existing one — no need to uninstall, and nothing is lost. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 16, 2026 0.5.9
    # Roadstr 0.5.9 Security hardening from an independent audit: privacy opt-ins, Nostr relay resilience, and honest store/network claims. ## Changed - **Favorites sync is now a real opt-in** ("Sync automatically" in Settings, off by default). It used to auto-publish an encrypted snapshot on every edit and auto-pull one on every launch for anyone simply signed in with
    More…
    Nostr, contradicting the onboarding text's own "optional, enable it from Settings" wording. - **Logging in no longer publishes a profile-visibility event** unless you had actually chosen public visibility beforehand. Publishing the untouched, pseudonymous default on every sign-in tied your key to "uses Roadstr" on public relays for no benefit — its absence already means pseudonymous. - **The store listing no longer claims "GPS data never leaves your device"** or "offline-capable routing" — both were false. Rewritten to match what the app actually does, also fixing a license line that said AGPL instead of GPL. - **The self-hosted GraphHopper "localhost" hint now actually works**: cleartext is permitted for exactly `localhost`, `127.0.0.1` and the Android emulator alias, nothing else, and any other `http://` address is refused with a clear error instead of failing silently. ## Fixed - A relay outage could be retried roughly every 1.25 seconds indefinitely instead of backing off, because the reconnect counters were reset before the WebSocket handshake had actually finished. Now waits for a real handshake before resetting anything. - Confirmation votes and pending-event tracking on the Nostr road-event stream had no per-report or total ceiling, letting a flood of freshly minted Nostr identities grow memory use against one popular report without limit. Both are now capped, and cheap checks run before the costly signature verification on every incoming event, not after. - Voice-model downloads (Kokoro/Piper) only had a per-chunk stall timeout; a server trickling data indefinitely could hold a download open forever. Added a total time limit per file. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 14, 2026 0.5.8
    # Roadstr 0.5.8 An "avoid unpaved roads" option, offline road reports, and fixes for navigation, Bluetooth audio and GPS recovery. ## Added - **"Avoid unpaved roads"** — a new Settings preference that steers driving routes away from OSM-tagged tracks and dirt roads whenever a paved alternative exists. Applied automatically to every route and
    More…
    reroute once turned on, not something to remember to ask for each trip. Always a best-effort steer, never a guarantee — map data on road surfaces is incomplete, so a road's real condition still needs judging on sight. - Road reports created with no signal are now saved and published automatically the moment a relay connection succeeds, instead of being lost — useful on roads where signal is scarce. - Settings can now be opened during active navigation, from a new icon next to the mute button, without stopping the trip. ## Changed - Off-route recalculation no longer demands a U-turn. Deviating on purpose in a grid of perpendicular streets used to leave the app pinning the old route behind the car instead of recalculating; it now finds the short way back to the original route instead. - "Recalculate" after a traffic-jam alert now genuinely routes around the reported jam rather than handing back the same road. - The first-launch disclaimer now says plainly that turn-by-turn routing is OpenStreetMap data interpreted by third-party engines, not vetted by Roadstr — and can no longer be swiped away with the back button/gesture, only by accepting it. ## Fixed - Bluetooth music/podcasts could stay paused after Roadstr finished speaking instead of resuming, caused by the audio player managing the phone's audio session on its own and a stale internal flag that skipped handing focus back. - A GPS stream could silently stop delivering fixes after an Android location-provider fault, leaving "recenter" stuck on "Acquiring GPS…" indefinitely. It is now detected and restarted automatically. - A single very inaccurate GPS fix (e.g. deep among tall buildings) could trigger a needless reroute; a shaky fix is now ignored unless several fixes in a row actually confirm the driver left the route. - A malformed or empty response from a routing server could crash navigation outright — closed the same gap already guarded elsewhere. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 11, 2026 0.5.7
    # Roadstr 0.5.7 Visual redesign: a new home dashboard, refined glass-style panels throughout, and a simplified theme lineup. ## Changed ### A new look - New collapsible home dashboard on the map screen.
    More…
    - Frosted-glass styling applied consistently across the bottom bar, navigation HUD, route panels and search — one shared design language instead of several ad-hoc looks. - Cleaned up the bottom bar: removed a small logo that was crowding the notifications/profile/menu buttons, giving them more room. ### Simplified theming Dropped the "modern" gradient theme variants, keeping the four classic Nostr/Bitcoin themes (light and dark). Anyone who had picked a modern variant falls back to its closest classic counterpart automatically — no manual action needed. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 7, 2026 0.5.5
    # Roadstr 0.5.5 Crosswalk/speed-bump map icons, better search ranking, and a couple of route-planner fixes. ## Added ### Crosswalk and speed-bump icons Pedestrian crossings and speed bumps now show on the map at their exact
    More…
    OSM-mapped position (`highway=crossing`, `traffic_calming=*` — verified against OsmAnd's own rendering style), the same way the existing speed-camera and traffic-light markers already do. ## Fixed ### Search ranking - Results that actually match the query are now sorted purely by distance from you — a franchise's own branches no longer get reshuffled just because one of them happens to be worded slightly differently on the sign. - Typing a city name at the end of a search ("mercatino usato faenza") now prioritises results actually in that city over merely closer ones elsewhere — detected locally, no extra network round-trip. ### Route planner and map interactions - The two-point route planner's "My Location" field now falls back to the current map view when there's no GPS fix yet, instead of refusing to calculate. - Long-press on the map: "report event here" is back at the exact long-pressed point (previously the report action only worked from your current GPS position via its FAB). - Tapping the recentre button with no GPS fix now shows a "location services are off" prompt instead of silently doing nothing. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 6, 2026 0.5.4
    # Roadstr 0.5.4 German voice guidance. ## Added ### German turn-by-turn voice guidance Kokoro-82M, the neural TTS engine behind the other 7 supported languages, has no German voice at all — it was never trained on German audio. German now
    More…
    gets a second, independent on-device engine: Piper (VITS-based, github.com/OHF-Voice/piper1-gpl), using Thorsten-Voice's MIT-licensed "Martin" voice — a long-running, dedicated open-source German TTS project. Same download flow as before (Settings → voice model), same espeak-ng phonemizer already bundled for the other languages. The phoneme sequencing was verified directly against Piper's own source and tested end-to-end against the real model before shipping. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 6, 2026 0.5.3
    # Roadstr 0.5.3 Traffic-light icons on the map, plus fixes for repeated/overlapping voice guidance. ## Added ### Traffic-light icons Controlled intersections now show a traffic-light icon on the map at their exact OSM-mapped position, sourced from Overpass the same way the existing OSM speed-camera
    More…
    markers already are — cached and throttled the same way, visible from a closer zoom level since signals are far denser than speed cameras. ## Fixed ### Voice guidance repeating or cutting itself off Three related bugs in the turn-by-turn voice announcements: - "You have arrived" could play twice in a row when the final turn was close to the destination — the advance mention chained onto the previous turn ("...then you will arrive") landed only seconds before the real arrival announcement. - A turn mentioned in advance as part of the previous instruction ("...then in 300 metres take the ramp") could have its own standalone announcement fire moments later and cut the first one off mid-sentence. - Two different nearby reports of the same hazard/speed-camera category could be announced back to back with the identical sentence. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 5, 2026 0.5.2
    # Roadstr 0.5.2 Hotfix. 0.5.1 made the MapLibre engine the default and fixed the battery/heat reports from 0.5.0 — one of those fixes broke the screen entirely on real devices. ## Fixed ### The map screen lost every control Disabling a rendering mode to cut battery/heat had the opposite of the intended effect:
    More…
    MapLibre's Android renderer fell back to a mode that draws straight through the Android view hierarchy instead of composing through Flutter, which hid every on-screen control — the search bar, every button — behind the map itself. Reverted. The other battery/heat fixes from 0.5.1 (the screen no longer rebuilding on every camera frame, dead reckoning between GPS fixes) are unaffected and stay in place. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 5, 2026 0.5.1
    # Roadstr 0.5.1 0.5.0 shipped the MapLibre rendering engine as an option. A week of actually driving with it surfaced the rough edges an opt-in toggle doesn't get exposed to at scale — this release fixes them and makes it the default. ## Changed ### MapLibre is now the default map engine
    More…
    The original renderer isn't going anywhere — the "Motore mappa: MapLibre" toggle in Settings switches back to it at any time — but new installs now start on the new engine. ## Fixed ### Cursor smoothness between GPS fixes The camera and cursor only moved when a GPS fix landed, then sat frozen until the next one — visible as a freeze-then-jump at speed, where a fix interval's worth of travel is tens of metres. Both now advance continuously between fixes, using the last known heading and speed to fill the gap. ### Battery drain and device heat Smoothing that gap the naive way came with a real cost: a screen-wide rebuild — every route polyline, ZTL classification, traffic segment — was firing up to 60 times a second while driving, and the map was rendering through an Android compatibility mode it never needed. Both fixed; reports were a Pixel 9 running hot and 10% battery on a 30-minute drive. ### Route calculation feeling slow Showing the route picker waited on a cosmetic detail — roundabout exit counts, used only to word voice instructions like "take the 3rd exit" — with a timeout of up to 6 seconds if the data source was under load. Alternatives now show immediately; that detail fills in afterwards if it's still relevant. ### Kokoro voice Picking the male voice in Settings had no effect on an already-open map screen — it's now the default, and a change takes effect immediately regardless of what's on screen. ## Added - Long-press a point on the map to set it as parking, with a confirmation prompt in all 27 languages ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Aug 28, 2026 0.5.0
    # Roadstr 0.5.0 Two months ago Roadstr drew its first map exactly one way: flat raster tiles, no tilt, no rotation without blur. This release ships a second way to draw it — a full MapLibre-based 3D rendering engine, built from scratch on its own branch and now merged in at feature parity with the original. ## Added ### A MapLibre-based rendering engine, switchable in Settings
    More…
    Real 3D camera tilt and rotation instead of flat raster tiles, native map styling that extends the light and dark themes to the map itself instead of stopping at the UI around it, and a full navigation feature set built to match the existing renderer rather than trail behind it: - Destination search — POI categories, favourites, history — with a place-info panel shown before committing to a route - Multi-stop route planning - Route alternatives, with highway/toll avoidance - Public transport itineraries — bus, tram, metro, rail, coach, ferry - ZTL-aware route colouring - Speed-camera and hazard proximity alerts, hazard reporting with owner-editable speed limits - Turn-by-turn navigation with off-route detection, rerouting, chained voice instructions and full voice guidance It ships as an option, not a replacement: the "Motore mappa: MapLibre" toggle in Settings switches between it and the original renderer at will, and the app keeps loading the original one by default. Nothing changes for anyone who doesn't opt in. Google Play Services was the reason this was shelved the first time it was evaluated — MapLibre's Android SDK touches it in places the app doesn't otherwise need. It turned out not to matter: Roadstr already excludes the Play Services dependency groups outright at the build level, the same exclusion that keeps the de-Googled GPS stack clean, and the new engine never calls MapLibre's own location APIs to begin with. Zero Play Services code in this build, same as every build before it. ## Verifying this release sha256sum -c SHA256SUMS.txt ## Next up Offline maps. Vector data is small enough to carry a region on the device — which is what raster tiles never allowed.
  • Aug 27, 2026 0.4.29
    # Roadstr 0.4.29 Fixed the tag format that broke ZapStore updates. ## Fixed ### Updating from 0.4.27 to 0.4.28 failed on ZapStore Every release so far was tagged `v.X.Y.Z`, with a literal dot after the `v`. The publishing tool strips only the leading `v` when it reads a tag
    More…
    as a version number, which on this format left a stray dot behind: `.0.4.28` instead of `0.4.28`. Confirmed against the tool's own local cache, and against three other apps published by the same account that all use the plain `vX.Y.Z` convention and come out clean — Roadstr was the only one shaped differently. A malformed version string is exactly the kind of thing that breaks update comparison on the client, which is what surfaced as "can't update." Tags go out as `vX.Y.Z` from here on. This was never actually the project's own convention to begin with — `build_release.sh` has printed the correct, dot-free tag command in its own instructions all along; the dot was introduced by hand at release time and never caught until now. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 38, and contain zero Google classes.
  • Aug 27, 2026 0.4.28
    # Roadstr 0.4.28 Dark mode no longer depends on a third party that can revoke access without warning. ## Fixed ### Dark mode's map tiles came from a service that started requiring an API key Dark mode fetched its map tiles from a free, anonymous CARTO endpoint. It
    More…
    started serving an "API KEY REQUIRED" watermark instead of tiles once some unpublished usage threshold was crossed — a dependency that could, and did, break with zero warning, mid-drive, for anyone using dark mode. This is likely the same root cause behind an earlier, unresolved report of dark mode looking inconsistent on a longer drive: a mix of real dark tiles and watermarked ones reads exactly as "inconsistent." Dark mode now recolours the same OpenStreetMap tiles light mode already depends on, rather than trusting a second, separately-failing service to keep rendering a dark basemap for free. The recolouring inverts lightness (white background to black, dark labels to light) and rotates hue by 180° to undo the colour shift a plain inversion leaves behind — a green park would otherwise invert to magenta — followed by a desaturate-and-darken pass so area fills come out muted rather than vivid, closer to the cartography this replaces than a naive colour inversion would give. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 37, and contain zero Google classes.
  • Aug 26, 2026 0.4.27
    ## Roadstr 0.4.27 ### New - Added an optional real-time altitude badge to the map. - Altitude is displayed in metres or feet according to the selected unit system. - GPS altitude readings are smoothed to reduce normal location jitter. - Added altitude display controls to Settings. - Added tests for altitude formatting, imperial units and badge rendering.
  • Aug 21, 2026 0.4.26
    # Roadstr 0.4.26 A mirrored icon, and two new screen controls — all from continued field reports on the previous release. ## Fixed ### Merge maneuver icons were mirrored The merge symbol has two paths: the muted one for the carriageway being
    More…
    joined, the accent one for the ramp the driver is actually on. A "merge left" instruction means that carriageway is to the driver's left — which puts the ramp, the accent path, on the right at the bottom of the icon. The two were swapped, so every merge rendered as its own mirror image: a driver on a right-side ramp merging left onto the main road saw a left-side ramp merging right, and vice versa. Confirmed against a real routing response before touching the code — a live route with an actual `merge, modifier: slight left` step, the common case of a ramp joining from the right — rather than guessing from the screenshot alone. ## Added Two settings, both **off by default**: ### Keep the screen on outside navigation too The existing "keep screen on" setting only ever applied during an active route. Reading the map stopped, or planning a trip, still let the screen sleep mid-glance. A new toggle extends the same behaviour to free-roam use of the app — left off by default, since always-on is a real battery cost outside of driving. ### Minimum screen brightness Requested by an OLED user whose panel dims low enough, under the phone's own auto-brightness, that the map's grey text stops being readable. A slider sets a floor: while the app is open, the screen won't dim past it, whatever the system's own brightness curve would otherwise do. Off by default, since the entire point is that it only matters to some screens and some ambient conditions. Both settle back to their defaults on their own — ending navigation, or closing the app — rather than needing anything to be turned off by hand. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 35, and contain zero Google classes.
  • Aug 21, 2026 0.4.25
    # Roadstr 0.4.25 Fixes from real driving: a crash, a swinging map, voice timing, and a GPS receiver that let go too eagerly. ## Fixed ### GPS dropped on every background switch, even a glance at a notification Leaving the app — for any reason, not just switching away — released the
    More…
    location receiver the instant the app left the foreground, whether or not navigation was running. Coming back always meant reacquiring from nothing, even after three seconds spent reading a notification. The receiver now survives up to 30 seconds of actually being backgrounded before it is let go, and the pending shutdown is cancelled outright on return — so a quick glance away costs nothing, while a phone genuinely left in a pocket still stops updating. ### A crash while panning the map during navigation Investigating turned up something bigger than the specific crash: the app had **no global error handler at all**. Flutter's own build/layout/paint cycle already keeps a bad frame from taking the whole app down, but anything outside it — a gesture callback, a stream listener, an unawaited `Future` — did not have that protection, and an exception there killed the entire process instead of just the one thing that went wrong. A global handler now catches, logs and swallows those instead of letting them propagate. It won't retroactively explain the one crash that was reported, but it means the next unexpected exception, whatever it turns out to be, ends as a log line instead of a closed app. ### The map still swung on turns sharper than 90° An earlier release fixed the equivalent problem at roundabouts — the nearest piece of route geometry isn't always the one the car is actually on. Sharp turns kept swinging anyway, for a second, independent reason: once a large disagreement between the raw GPS bearing and the route's own direction was confirmed by a second fix, the heading **snapped** straight to the route's exact line instead of easing into it. The raw bearing through the turn was already noisy, since it's measured across two fixes taken on either side of the corner — so the snap landed a second discontinuity right on top of the first, which is what read as the map swinging just after the turn completed. The confirmed correction is now eased in at the same rate ordinary route-following uses, removing that second jump. ### Voice guidance timing, two separate bugs - **The final warning arrived too late at speed.** The point-of-action cue — the one spoken right at the turn — capped its lead distance at 120 metres no matter how fast the vehicle was going. At 120 km/h that is 3.6 seconds: enough time to hear "take the exit," not enough to act on it. The distance now keeps scaling past 100 km/h instead of flattening there, reaching 260 metres — about six seconds — by 160 km/h. - **Instructions ran on in dense junctions.** An advance warning for the next turn used to queue behind whatever maneuver announcement was already playing, rather than being dropped. In a run of closely spaced junctions that meant hearing about a turn that was already behind the car by the time its announcement finally played. A newer cue now simply replaces a stale queued one; the point-of-action repeat still always interrupts immediately, since arriving late at a junction is worse than talking over the warning it replaces. ### The hazard-report button changed sides It sat on the left of the screen before navigation started and jumped to the right the moment a trip began — the only control on screen that moved. It now stays on the right in both states. Parking and route planning stay on the left and pre-trip-only, since re-planning or checking a saved spot mid-drive isn't something either is meant to support. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 34, and contain zero Google classes.
  • Aug 19, 2026 0.4.24
    # Roadstr 0.4.24 Directions in every language the app speaks, restricted-zone warnings that mean something, and the map finally holding still. ## Added ### Turn-by-turn instructions in all 27 languages Until this release, exactly two languages had instructions of their own. The builder was a
    More…
    pair of ternaries on `lang == 'it'`, so the other **twenty-five languages the app ships were navigated in English** — not a missing street name, but a driver being given directions in a language they may not read. The wording now lives in a phrase table: 24 keys across 27 languages, with English as the fallback for anything absent. Adding a language is a data change, and a test reads the locale files from disk to make sure none is left behind. ### Instructions name the road — by its number Instructions say which road they lead onto, and prefer the code over the formal name: **"take the SS3bis"**, not "Strada Statale 3 bis Tiberina", which appears nowhere on the road itself. Where a road carries several codes only the first is spoken; reading a list of synonyms at a junction is worse than naming one of them. ### The street you are on Shown under the manoeuvre panel — **for town streets only**. A motorway number is already on every sign and in the panel above; a street name is the thing that is genuinely hard to know from inside a car in an unfamiliar town. The label sizes itself to the name, and stays clear of the speed-limit sign beside it. ## Fixed ### Warnings on streets that were not restricted The zone search collected every `highway=pedestrian` way **with no check on whether cars were actually barred**. Measured around one Italian historic centre, that was 160 of the 274 ways it returned — and in a dense centre there is almost always a pedestrian alley within a few metres of a perfectly drivable street, which is how an ordinary road came to be announced as restricted. Pedestrian ways now need a restriction like every other class, and `zone:traffic` no longer matches `urban`, which is the ordinary built-up-area tag that sets default speed limits. Same query, same place: **274 elements before, 115 after**. ### A warning could stick over the cursor until the app was restarted The comparison was on the street *name*, and restricted ways are frequently unnamed — leaving one meant comparing null with null, which registers as "no change", so it was never cleared. Compared by identity now. Warnings also sit clear of the cursor, and can be **swiped away**: somebody who holds a permit drives their own restricted street every day, and a warning that cannot be got rid of is one they stop reading. ### The map swinging round The route's direction was read from the nearest piece of it **by distance**. At a roundabout the exit arm passes within metres of the entry arm pointing the opposite way, so "nearest" happily returned a bearing that contradicted the direction of travel — which the heading filter then had to argue with, and occasionally lost to. The segment is now chosen by **progress along the route**. Progress advances monotonically, so the entry and exit of the same roundabout are hundreds of metres apart on it even when they are metres apart on the ground. ### Voice guidance - **Chained instructions no longer break mid-sentence.** The follow-up clause kept its capital letter, and the phonemizer reads a capital in the middle of a sentence as the start of a new one — an audible full stop after "then". - **A cue arriving between two others is no longer silently dropped.** The queue held one item, so the middle of three announcements was overwritten and never spoken. - **Nothing is cut off in its first 1.3 seconds.** Half a word is worse than silence, because the driver cannot tell whether it mattered. - **"Bivio" and similar words are pronounced properly.** The phonemes were defensible but gave the voice one syllable too many; corrected at the phoneme level, so the spelling on screen is untouched. ## Notes on things that turned out not to be bugs **Journey times come from the routing engine, not from this app.** Checked against the same 185 km route: OSRM estimates 2.73 h, Valhalla 2.58 h — agreeing within 6% — and the OSM data is correct, with `maxspeed=90` on 204 of the road's 212 segments. The app reports what the router says, pro-rata by remaining distance. Inventing a speed model to beat two mature routers is how you get confidently wrong arrival times. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 33, and contain zero Google classes.
  • Aug 18, 2026 0.4.22
    # Roadstr 0.4.22 A crash fixed at the root, limited-traffic zones answered street by street, and a new look for driving. ## Fixed ### The app could die outright mid-drive Traced from a captured crash rather than guessed at: a `SIGSEGV` inside
    More…
    `espeak_TextToPhonemes`, faulting two bytes short of a page boundary — the signature of a buffer running off the end of its page. The cause was not in this app. The bundled eSpeak NG was 1.52.0, from December 2024, and **twelve memory-safety fixes have landed upstream since** — including stack buffer overflows in number and clause formatting, which is precisely what voice guidance spends its time reading aloud. 1.52.0 is still upstream's latest tagged release, so the library is now pinned past those fixes rather than to a release, which is a deliberate trade: the alternative is shipping a phonemizer that can take the whole app down. The phonemizer also caps single-word length now. Voice guidance is a convenience; navigation is not, and no place name is legitimately sixty characters long. ### Other fixes - **The map no longer swings round after a roundabout or a slip road.** The heading filter deliberately holds a suspect bearing near junctions — that is the protection against 180° flips added in 0.4.19 — but a watchdog read that hold as a stuck camera and forced the whole accumulated correction through in a fixed 550 ms. The watchdog now measures whether the camera is converging, and self-driven rotation is rate-limited so no correction, from any source, can outrun the driver reading it. - **A destination chosen while the GPS is still acquiring is no longer discarded.** It is saved to recent searches, and the route starts on its own when the position arrives. - **Faster cold GPS fixes, still without Google.** The app asks the receiver to refresh its satellite assistance data — downloaded from whatever the device's own `/etc/gps.conf` names, which is the chipset vendor or a privacy-focused ROM's proxy. ## Limited traffic zones Previously the app announced a zone in the vicinity and left it there. Now the warning follows what is actually happening: - **Only the stretches of route on a restricted street turn red.** The rest keeps its colour and the part already driven stays grey — turning the whole line red claimed the entire journey was restricted when it is usually a block or two. - **"You are in a restricted zone" appears only when you are**, from the live GPS position rather than from the route touching a zone somewhere ahead. - **Driving past a restricted street shows a yellow notice naming it**, so a shortcut that looks open is not mistaken for one. - Restricted streets near the route are drawn dotted in red. Crossing a restricted street at a junction is deliberately *not* treated as entering it: turning the route red at every such junction would recreate the constant, ignorable alarm this replaces. ## Look and feel - **Four new themes** — modern light and dark, in Nostr Violet and Bitcoin Orange — built on a symmetric edge gradient that frames a panel without tinting the text. - **The route is drawn as a lit line**: a bright core between two rails of colour, with a soft halo. It works in violet, orange and the restricted-zone red alike. - **Driving panels float above the map** with rounded corners, lit edges and soft shadows. The manoeuvre tile and the map controls are lit surfaces rather than flat swatches. - **Time to arrival is now the headline figure**, with distance beside it. What a driver is deciding depends on how long is left, not on how many kilometres remain. - **Bicycle routes can be planned from the start**, rather than only chosen after a route has already been calculated. - The roundabout exit number is larger, and no longer clipped on roundabouts with many exits. ## Under the hood - Key derivation for favourites moved off the UI thread, where it blocked for over a second on every favourite edit and at every startup. - Network failures are typed, so a momentarily busy shared server is retried with backoff — honouring its own `Retry-After` — while a malformed answer is not. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 31, and contain zero Google classes.
  • Aug 18, 2026 0.4.21
    # Roadstr 0.4.21 Public transport routing arrives, and the map stops startling you at junctions. ## Added ### 🚌 Public transport Plan a journey by **bus, tram, metro, train, coach or ferry**. In the route planner, pick **On foot** and a sub-choice appears underneath it — walk the whole way, or take a
    More…
    scheduled service. Journeys are shown door to door: - the **walk to the stop**, with which stop to head for and the departure time - each **line** in its operator's own published colour, with the direction sign - the **changes**, and the walk at the far end Routing runs against openly published timetables worldwide through a community-run, provider-neutral service — no account, no API key, and no tracking of who asked for what. It is the same kind of shared infrastructure this app already uses for roads and geocoding. Coverage follows the data: where an operator publishes an open timetable, it works; where none exists, the app says so plainly instead of pretending there is no service. ### 🚲 Cycling from the planner Bicycle routes could previously only be selected *after* a route had already been calculated. The planner now offers cycling from the start. ## Fixed ### The map no longer swings round after a roundabout This was the one that mattered. Leaving a roundabout or a slip road, the map would rotate abruptly — exactly when a driver is checking whether they took the right exit. The heading logic deliberately **holds** a suspect bearing near junctions; that is the protection against 180° flips added in 0.4.19, and it works. But a watchdog read that hold as evidence of a stuck camera, and answered by cancelling the smooth easing and forcing the whole accumulated correction through a fixed 550 ms animation. The heading was never wrong — it was right, and delivered all at once. Two changes, so it does not come back by another route: - the watchdog now measures whether the **camera** is converging on the rotation it was asked for, rather than whether the heading has changed — a steady heading is also just what driving in a straight line looks like; - self-driven rotation is **rate-limited**. A real vehicle's yaw rate stays well under the ceiling even in a tight roundabout, so following genuine motion is untouched; what the limit catches is any *correction*, from any source, present or future. ### A destination is no longer lost while the GPS is acquiring Setting a route before the first fix showed "acquiring GPS" and then quietly discarded the destination — it was not even kept in recent searches, so it had to be found again. The destination is now saved immediately and the route starts on its own the moment the position arrives. ### Faster cold GPS fixes, still without Google The app now asks the receiver to refresh its **satellite assistance data**. Without it, the receiver has to read that data off the satellites themselves, which is a fixed half-minute of physics rather than a software delay. This is not a Google dependency: the platform downloads from whatever the device's own `/etc/gps.conf` already names — the chipset vendor's service, or a privacy-focused ROM's own proxy. It matters most on de-Googled devices, where there is no fused provider to paper over the wait. ### Other - The **exit number** on the roundabout symbol is larger, and no longer clipped on roundabouts with many exits. - **Saving or syncing favourites no longer freezes the app.** The password step is deliberately slow by design, and it was running on the same thread as the interface — on every favourite edit and at every startup. - Requests that fail because a shared server is momentarily **busy** now back off and retry, honouring the server's own requested delay, instead of being treated the same as a permanently broken request. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 30, and contain zero Google classes.
  • Aug 11, 2026 0.4.20
    # Roadstr 0.4.20 Pick your own colours, and a new way to walk. ## Added - **Seven colour tints for the vehicle cursor** — violet, indigo, blue, green, yellow, orange, red — chosen from Settings alongside the existing style picker. - **A new "Classic Fiat 500" cursor style.**
    More…
    ## Fixed - **A timing bug in the new walking animation.** Raw GPS speed readings are noisy — a swing of a few tenths of a km/h between two consecutive fixes is routine even at a constant pace. That noise could trigger the animation to start playing before all of its frames had finished loading, producing a visible flicker right when a walk begins. The frame-loading step now properly waits for itself to finish instead of letting a second request for the same sequence skip ahead of it. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 29, and contain zero Google classes.
  • Aug 11, 2026 0.4.19
    # Roadstr 0.4.19 Four field reports from the road, four fixes — each traced to a concrete cause, not guessed at. ## Fixed - **Search history was hidden, not lost.** Anyone with at least one saved favourite — most users, given the app's own favourites feature — never saw their recent searches at all. The "nothing typed yet" panel picked between two lists with an `if`/`else if`, and an empty search box matches *every* saved favourite, so the favourites branch always won.
    More…
    The two are now shown together: they're different things (shortcuts vs. recent searches), not competitors for the same slot. - **The map no longer flips 180° near junctions and roundabout exits.** The heading logic finds the nearest point on the route's own path to double-check its bearing — but "nearest by raw distance" has no idea which way that road actually runs. Right at a roundabout, or where two arms of a junction both sit close together, the nearest point can belong to the wrong arm and report a direction pointing the wrong way, and that single reading used to be trusted immediately. It now has to repeat on the next fix before the map acts on it — a real turn keeps producing the same reading; a bad match by the roundabout ring does not. - **Voice guidance could go completely silent for an entire drive**, then work again on the next one. Setup for the voice model runs once, right as the map, GPS and routing are all also starting up — a plausible moment for something to fail transiently — and until now a failure there had no retry for the rest of that session. It now retries later in the same drive instead of requiring you to start a new one to get your voice back. - **Recalculating after a wrong turn wasn't finding anything useful.** On a long road with nowhere to legally turn around, a reroute request used to assume the car could face any direction at all, including an instant reversal it physically can't perform — producing a route the driver couldn't follow, which triggered another reroute of the same shape, over and over, each with the map spinning as it re-evaluated. Reroutes now account for which way the car is actually facing, so they find a real way back — the next roundabout, the next junction — instead of an impossible one. Verified against Roadstr's own routing server: the same two points 400 m apart resolve to a degenerate two-metre route with no direction given, and to a realistic route via the next junction once the car's heading is taken into account. A safeguard against an absurd detour applies in both directions. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 28, and contain zero Google classes.
  • Aug 10, 2026 0.4.18
    # Roadstr 0.4.18 A crash during navigation, and the roundabout signs that were drawing the wrong junction. Both came from the previous release. Install this one. ## Fixed - **The app could die mid-route.** The map opened a new database watcher on every GPS fix and could not close the old ones fast enough — cancelling is asynchronous, opening is not — so after a few minutes of driving they piled up until the app ran out of memory.
    More…
    There is now one watcher, opened once. - **Roundabout signs showed too many arms.** Where a road meets a roundabout as two separate carriageways, it was counted as two exits: a four-exit junction drew as seven. How far apart those two connection points *look* depends entirely on the size of the roundabout — twelve metres spans 23° on a large ring and 74° on a small one — so the fixed threshold could never work. It is now measured from the roundabout itself. And when the shape still cannot be resolved confidently, a plain roundabout is drawn rather than a wrong one: on the road, a sign showing the wrong junction is worse than a sign showing no detail. - **Distances over a kilometre are spoken as kilometres.** "In 4567 metres" is now "in 4.5 kilometres" — with the decimal separator your language is actually read with, since a speech engine says 4.5 and 4,5 differently. - **One instruction no longer cuts off another.** Every announcement was marked urgent, which stops whatever is playing. Advance warnings now wait their turn; only the final "now" instruction takes over, because by then the junction is seconds away. - **The map no longer occasionally spins 180°.** Standing still, a GPS fix wanders by several metres, and the direction of travel was still being measured from where it had wandered to. Pulling away could point the map any way at all, including backwards. - **More restricted-traffic zones are recognised.** Most are mapped in OpenStreetMap as time-limited restrictions — active only during certain hours — and those tags were not being read at all. Checked against live data: eleven restricted streets in one Italian city centre that the app previously could not see. ## Changed - The secondary instruction panel is 15% narrower and covers less of the map. Text and padding scale with it, so the same instructions still fit on the same number of lines. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 27, and contain zero Google classes.
  • Aug 9, 2026 0.4.17
    # Roadstr 0.4.17 Roundabout signs that match the junction in front of you. ## Added - **Real roundabout shapes.** A routing engine only tells the app which exit to take — "third exit" describes a four-arm junction and a seven-arm one equally well, and until now the sign drew the same generic ring for both. The number of arms is now read from OpenStreetMap and drawn, so the symbol you glance at looks like the junction you are
    More…
    approaching. Where OSM has no usable ring mapped, the sign falls back to the generic one rather than inventing a shape. - **Cursor styles.** City, racing, SUV, electric, bicycle and formula, alongside the existing arrow. - **A redrawn speedometer.** ## Under the hood The roundabout lookup is deliberately bounded, on two counts. It batched every roundabout in every alternative route into a single OpenStreetMap query with no limit. A city route through France or the UK can pass fifty of them, which is a hundred search clauses sent in one request to a free, volunteer-run server — the same infrastructure this app went to some trouble to stop hammering two releases ago. The second reason matters more. Each of those coordinates is a piece of your itinerary, sent in one request before you have even set off. Every other OpenStreetMap lookup in Roadstr discloses only where the car *is*, progressively as you drive — never where it is going. The lookup now asks about at most 24 roundabouts, nearest first, with a test that an 80-roundabout route cannot exceed that. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 26, and contain zero Google classes.
  • Aug 8, 2026 0.4.15
    # Roadstr 0.4.15 **No Google code left in the app. None.** Roadstr was built to run on phones with no Google services, and it did. But the APK still carried Google Play Services code — fifteen classes it could never execute on the very devices this app exists for. Nobody put them there on purpose: they arrived as a dependency of the location plugin and stayed, because a shrinker cannot remove code that is still reachable on paper.
    More…
    They are gone. Verified on the release APK, not assumed: ``` com.google.android.gms.* 0 classes com.google.android.play.* 0 classes Google components in manifest none ``` ## What was there, and why it survived so long Roadstr has always read your position through Android's own `LocationManager` — every single call site asks for it explicitly, which is what makes the app work on GrapheneOS, /e/OS and LineageOS without Google apps. The Play Services code was never called. It shipped anyway because `geolocator` decides *at runtime* whether to use Google's fused provider or Android's own, so both remain reachable to the compiler. Excluding the library at the build level simply broke the build: the Google client will not compile without it. ## What changed `geolocator_android` 5.0.3 (MIT) is now vendored in the repository with the proprietary path removed — one file deleted, three lines changed, one dependency dropped. The Dart API is untouched. `third_party/geolocator_android/ROADSTR_FORK.md` records exactly what differs from upstream, so future versions stay easy to merge. Also removed: Google Play Store split-install and deferred-delivery classes, which Flutter links for apps that download parts of themselves from the Play Store. Roadstr does not. ## What does not change **Nothing about how location works.** Same provider, same accuracy, same behaviour on de-Googled phones — there is simply nothing else left beside it now. Location permissions are unchanged. ## Staying that way The Gradle build refuses `com.google.android.gms` and `com.google.android.play` outright, so neither can return quietly through some future dependency. A test fails if the vendored fork, the dependency override, or the exclusions are ever undone. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key and carry versionCode 24. Install the one matching your device (`arm64-v8a` for practically every phone made in the last decade), or `app-release.apk` if you would rather not think about it.
  • Aug 3, 2026 0.4.13
    # Roadstr 0.4.13 The cursor points where you are actually going, and every remote endpoint is now treated as something that might be lying. Outside navigation the arrow used to follow the phone's compass — which, in a cradle at an angle, means it pointed across the carriageway rather than along it. It now follows your direction of travel whenever you are moving, and it stays glued to the road through a curve instead of drifting and snapping back. Underneath that, a long list of places where a relay, a geocoder or a Lightning server could waste the app's memory, its battery, or
    More…
    your data allowance. ## Added - **Your own relay for favourites sync.** Settings → Favourites sync now takes one relay of your own. Favourites are the only thing in Roadstr you cannot re-create — road events expire and the community re-reports them, but home and work are gone if every relay holding them is. None of the three built-in relays declares a retention policy, so none of them owes you your saved places tomorrow; a relay you run or pay for does. Opt-in and empty by default, and deliberately typed in rather than read from your published NIP-65 relay list: that list is public, so publishing an encrypted snapshot to it would hand anyone curious the signed, authoritative list of places to look for your data. The address is checked strictly — `wss://` only, no credentials, no query string — because whatever that field accepts becomes a destination for an encrypted copy of your home address. - **A third relay for favourites sync.** Measured over ten minutes, `relay.damus.io` refused 22 of 30 connections with HTTP 503 while `nos.lol` accepted all 30 — so the old two-relay set was, most of the time, a one-relay set. `purplerelay.com` joins them: 100 % over the same run, and the fastest of the three. ## Fixed - **The cursor no longer sits sideways to the road in free drive.** The heading source is now one rule everywhere: your GPS course while moving, the compass only when you are standing still. The handover has a dead band, so crawling in traffic no longer makes the map change its mind twice a second. - **The cursor stays aligned through curves.** It was being counter-rotated and then corrected by hand every GPS tick, while the map turns every frame — so the correction was always stale, and most stale exactly mid-curve. The arrow now turns with the map itself, in the same frame. - **Free drive follows the road smoothly.** Heading-up mode outside navigation used the same smoothing as navigation instead of jumping to each new fix. - **Starting navigation while already driving** no longer swings the map to the compass bearing before picking up your actual course, and a GPS fix landing mid-transition no longer cuts the route overview short. - **Passphrase-protected favourites restore automatically again.** The auto-restore was reading the sync passphrase from a storage key that Settings migrates away and deletes, so after your first visit to Settings it always came up empty — silently skipping the restore in exactly the reinstall case the feature exists for. - **Deleting your last favourite now reaches the relays.** Pushing an empty list was treated as nothing to do, which left the old snapshot in place for the next reinstall to bring back. - **Two quick favourite edits can no longer land out of order** and resurrect a place you had just deleted. Uploads are queued. - **Sync no longer reports success** when a relay acknowledges a different event than the one that was sent. - **"My reports"** re-checks locally that each report is actually yours, and has its own processing budget, so a busy report's confirmations can no longer truncate the list. ## Changed - **Search sends far less traffic while you type.** Suggestions now come from the provider built for partial words; the strict address geocoder runs once you stop typing, or on submit. It was being asked on every 300 ms pause, and on a half-typed word it answers with nothing — measured across one query being typed out, it returned no results for half of the states while the other provider answered all of them. Results are unchanged: both providers already render addresses in the same shape. - **Reconnects and map-data lookups back off instead of retrying at a fixed rate.** A dropped relay connection was retried every 5 seconds indefinitely — 720 attempts an hour in a tunnel — and the speed-limit, speed-camera and restricted-zone services each retried Overpass every 15 seconds for the whole drive. Both now grow the delay and cap it, with jitter on the relay path so every client that dropped together does not come back together. Better battery life on a bad connection, and the app stops adding load to a service that is already failing. ## Security - **Addresses that look public but resolve inward** are now rejected on Lightning address lookups. `::ffff:127.0.0.1`, `::127.0.0.1` and NAT64 `64:ff9b::/96` all reach the loopback interface, and the private-range check was never looking at the bytes that decide where the packet actually goes. - **A slow peer can no longer hold a request open indefinitely** by sending one byte before each timeout: the response body has a total deadline, not a per-chunk one. - **Place names, addresses and opening hours from search providers are length-capped** before they are displayed or written to your history. Nothing on the other side of those APIs is under our control, and a kilobyte-long "street name" is both a layout problem and a storage one. - **A hostile relay can no longer grow the app's memory** by streaming updates that point at reports which never arrive, or by replaying activity forever. Both are now bounded and aged out. The anti-replay marks that stop an old, validly-signed update from being re-applied are deliberately kept out of that cleanup. - **NIP-44 encryption is now verified against the official v2 test vector**, not only against itself. ## Localisation - The new sync-relay setting is translated into all 27 languages. ## Housekeeping - Version bumped to 0.4.13 (versionCode 22). - The F-Droid metadata pointed at a tag that does not exist: the tags in this repository carry a dot after the `v`, and the build entry said `v0.4.13`. - The test suite went from 151 to 182, covering the motion hysteresis, the retry back-off, the relay-address validator, the inward-resolving addresses above, and the length caps on remote and stored text. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key. Install the one matching your device (`arm64-v8a` for practically every phone made in the last decade), or `app-release.apk` if you would rather not think about it.
  • Jul 26, 2026 0.4.12
    # Roadstr 0.4.12 One new feature and a long list of things that were quietly wrong. **Nearby** answers "where is the closest petrol station / cash machine / pharmacy" in one tap. **"Avoid motorways and tolls"** stops quoting travel times from a different routing engine than the routes it is compared against. **"My reports"** is no longer empty. Editing a speed limit no longer crashes. The restricted-traffic-zone warning is back on screen, the speed-limit sign goes away when it should, and Roadstr now talks to four relays instead of two — without waiting any longer for the answer.
    More…
    ## Added - **Nearby.** Tap the search box without typing anything and a row of one-tap categories appears — fuel, supermarket, cash machine, pharmacy, hospital, police, post office, parking, charging — each answering "what is around me right now" within 5 km of the **current GPS position**, not of wherever the map happens to be scrolled. Results are listed nearest first with the distance beside each one, and tapping one opens it like any other search result: opening hours, details, navigate. Everything comes straight from OpenStreetMap tags, so it works the same in Berlin, Tokyo, Nairobi and São Paulo (all verified live) — and places OSM has no name for are kept rather than dropped, labelled by category: a cash machine in a wall or an unbranded filling station is exactly what a driver is looking for. Category names are translated into all 27 languages. Repeating a category, or coming back to it, is served from a five-minute cache instead of another round trip, and a busy Overpass mirror no longer costs ten seconds of nothing: the second mirror is asked as soon as the first is late, and whichever answers first becomes the preferred one. ## Fixed - **"Avoid motorways and tolls" no longer reports an absurd travel time.** The avoidance route is computed by Valhalla — the only free engine that can exclude motorways and toll roads, since public OSRM rejects the `exclude` parameter outright — but every other route on screen is timed by OSRM, and the two disagree profoundly about secondary roads. Measured live: the motorway-free Ravenna→Florence route is 200 minutes according to Valhalla and 143 according to OSRM for the very same 135.4 km; Caltabellotta→Messina 621 vs 461; Udine→Genoa 639 vs 559. The avoidance option looked like a detour it never made. Roadstr now takes the road Valhalla found and re-times it with the engine that produced the other routes, by routing OSRM through waypoints sampled from that road — one every 5 km, a spacing measured to reproduce the same roads on journeys from 22 km to 1383 km. The check is per leg, so a single stretch OSRM refuses to follow costs the accuracy of that stretch alone instead of the whole re-timing; if less than half the route can be verified, or the request fails, the original figures are kept. Validated on 40 live runs: 29 journeys over 350 km across six continents (96–100 % of each route verified, no failures) plus 11 edge cases. The correction goes both ways — Delhi→Lucknow drops from 893 to 405 minutes, Houston→New Orleans rises from 535 to 627. Known limit: the public Valhalla refuses paths longer than 1500 km, so on those the avoidance switch reports no route (Perth→Adelaide). - **When the recommended route already avoids motorways and tolls**, the avoidance router returns that very same road; it is now recognised and the existing card is badged instead of showing the identical journey twice. - **Ferry routes are timed by the boat's schedule, not by a road router's guess.** OSM draws a ferry as a line with almost no points — Naples→Palermo arrives as a single 305 km straight jump — so sea crossings keep Valhalla's timing (it reads the crossing duration from OSM) while the driving on either side is still re-timed. - **"My reports" is no longer empty.** The profile page asked a single relay, relay.damus.io, which during testing refused a third of the connections outright (503) and answered one probe with no road event at all — so the page said "no reports yet" no matter how much the user had reported, while the map was displaying those very reports fetched from the other relay. Reports are now requested from every relay in parallel and merged, and the history window went from 30 days to a year. Pending speed-limit suggestions had the same defect: the first relay's empty answer hid what the others held. - **Editing the speed limit of an existing report no longer crashes** with the red "_dependents.isEmpty" screen. The dialog's text controller was disposed as soon as the dialog returned, while the dialog was still animating out and still rebuilding its text field — the disposed controller then brought the whole route down. The dialog now owns its controller and disposes it when it is really gone. Covered by a regression test. - **The report sheet scrolls.** A speed-camera report of your own, with a comment, a speed limit and pending suggestions, was taller than the sheet and overflowed into the yellow-and-black striped bar. - **The next-manoeuvre tile is back to half the screen width**, and a quarter shorter than before: the type scales with the box so the same instructions still fit. - **The speed-limit sign no longer sticks around after the route preview.** It is hidden while you are planning (preview, alternatives, planner, search and place panels), a cached limit now expires after 5 minutes instead of surviving forever while parked, and an Overpass query already in flight can no longer refill a cache that was just cleared. - **The restricted-traffic-zone (ZTL/ZAC) banner is back.** Zone data had kept being refreshed on every GPS fix, but the banner that displayed it was dropped when the map screen was split up — so entering a zone showed nothing at all. While navigating it now sits above the speed-limit sign, where it cannot cover the manoeuvre. - **The map no longer waits for a cold GPS lock before it moves.** The seeding from the position the OS already knows had been written for exactly that, then lost in a refactor: the method survived, its only caller did not. Restored. - **Coordinates on the Greenwich meridian no longer break OSM lookups.** A longitude below a millionth of a degree prints as `5e-7`, which Overpass rejects outright; speed limits, speed cameras, restricted zones and nearby searches now all format coordinates properly. - **Speed-limit updates apply newest-first** even when the update reaches the app before the report it belongs to. - **Fewer needless reroutes.** The off-route thresholds had been tuned against a distance calculation that read 28 % short north-south; with the geometry fixed they are retuned (30 m / 55 m) so a lane change no longer triggers a recalculation. - **Distances under 50 m read "0 m" / "0 ft"** instead of a bare "0" on the final approach. - Settings no longer risk a state update after the screen has been closed when saving the favourites-sync passphrase. ## Changed - **Four relays instead of two.** relay.primal.net and nostr.oxtr.dev join nos.lol and relay.damus.io. Each was verified end to end — publish a Roadstr event kind, then read it straight back — which is not a formality: of the candidates tested, two refused the write, one requires a web of trust, one requires AUTH, and three returned nothing at all for Roadstr's road-event kind. Reports are published to all four in parallel, and reports, confirmations, suggestions, profiles, visibility settings and zap receipts are now read from all four and merged, so no single relay outage can hide them (vote counts are merged, never summed, and zap receipts deduped by id, so nothing is double-counted). Redundancy without the wait: every relay is asked **at once**, never one after another, so the cost is the slowest relay rather than the sum of four. Measured against the live network: profile 0.2–0.9 s, my reports 0.4–0.7 s, edit suggestions 0.2–0.3 s, zap balance 1.6–1.7 s, and a Lightning address is cached for ten minutes so opening a second report costs nothing. A relay refusing the connection (damus answers 503 under load) is now caught where it happens instead of escaping as an unhandled error. - **Automatic dark theme is now off by default.** The theme you pick is the theme you get, until you turn sunset switching on yourself. - **Voice speed now defaults to 1.30×.** Kokoro's neutral pace is slower than a navigation voice needs to be — an instruction has to land before the junction. The pre-rendered start/arrival phrases now play at your chosen speed instead of being skipped whenever the speed was not exactly 1.0×, so they stay instant at any setting. ## Localisation - 21 strings — profile visibility, the notifications screen, and speed-limit editing/suggestions — were still English in every other language. They are now translated into all 26 non-English languages Roadstr ships with. - 38 leftover keys from removed features were dropped from all 27 translation files. ## Under the hood - The heading logic — which way the map faces, and the jitter, reversal and road-snap handling behind it — moved out of the GPS tick handler into a class of its own, six levels of nesting down to two, with thirteen tests where there were none. The GPS handler lost sixty lines with it. - The "my reports" relay listener was one hundred lines doing three jobs; it is now four named functions, and splitting it is what exposed the ordering bug above. - Dead code removed: an unused ZTL getter, an unused TTS alias, and the two heading state fields that left with the logic that used them. ## Housekeeping - Version bumped to 0.4.12 (versionCode 21) in `pubspec.yaml`, `README.md` and the F-Droid metadata. - The test suite went from 114 to 151: the same-road detection, the per-leg re-timing and its fallbacks, sea crossings, the heading filter, the nearby search (radius, unnamed places, sorting, de-duplication, cache, mirror failure) and its UI, and the speed-limit editing flow that used to crash.
  • Jul 21, 2026 0.4.11
    ## v0.4.11 (20) ### Notification - **Added notifications** for every zap, report and alert confirmed or discarded by other users. Notifications will not take place during navigation. - **Vocal alert for speed cameras**, when a user posts an alert for a speed camera a new field with speed limits can be filled. This will vocally alert users in close proximity. - **Bugfixes**, resized remaining time and remaining distance in a more properly dimensioned font.
  • Jul 20, 2026 0.4.10
    ## v0.4.10 (19) ### Location - **GPS now works on de-Googled devices (GrapheneOS, /e/OS, LineageOS without Google apps).** The app was binding to the Google Play Services location provider, which doesn't exist on these systems — so the map stayed stuck on a fallback position and never got a fix, no matter how long it searched. It now reads the GNSS hardware directly through the standard Android provider, which works on every device. Bonus: no location request touches Google Play Services on any device anymore — a privacy win for everyone. - **GPS warms up at launch again** (when location permission is already granted), so the first fix is ready when you need it instead of after a long cold start. You can turn this off in Settings.
  • Jul 20, 2026 0.4.9
    ## v0.4.9 (18) ### Routing - **Avoid highways & toll roads** now actually works. The feature was pointed at the wrong server (which returned a web page instead of route data), so every request silently failed. Fixed — the switch now returns a real motorway- and toll-free route, verified end to end. - **Long-distance walking & cycling routes no longer error out.** A transcontinental foot route (e.g. Boston → Miami, ~2,600 km / ~80,000 path points) was rejected as "too many points"; the internal limits are now generous enough for any realistic continental journey. ### Places - **Rich POI details on tap.** Tapping a place now shows the OpenStreetMap facts that matter: category, opening hours (open/closed now), phone, website, cuisine, operator, wheelchair access and address — no extra lookups, straight from the map data. ### Voice guidance
    More…
    - **New voice-volume slider.** Set the guidance volume independently of your media volume — turn it down when it's louder than your music, or up when a quiet podcast would otherwise drown it out. It still ducks other audio while speaking. - **Your own road reports are no longer read back to you.** Submitting a report used to trigger the very hazard announcement you just created, sometimes two or three times. Fixed. ### Location & units - **Faster "locate me."** The map now jumps to your last known position instantly while a precise fix warms up, instead of waiting several seconds on a cold GPS start. - **Imperial unit fixes.** Wind speed and the speed-limit sign now read in mph (they were still showing metric values under imperial units). ### Privacy - **Screenshots re-enabled.** Blocking all screenshots was overkill; the app-switcher thumbnail (which could reveal your location) stays hidden, but you can once again screenshot a route to share it.
  • Jul 18, 2026 0.4.8
    ### roadstrapp.0.4.8.apk ### Added - Added a strict BOLT11 invoice decoder with: - Network validation. - Amount and expiry verification. - Payment hash and description hash extraction. - Rejection of amountless and non-mainnet invoices. - Added bounded HTTP requests with streaming size limits, hard deadlines, and redirects disabled.
    More…
    - Added native OpenStreetMap information for POIs without a Wikipedia page: - Description. - Category. - Opening hours. - Operator and brand. - Cuisine. - Wheelchair accessibility. - Contact details. - Address and validated HTTPS website. - Added a restricted in-app Wikipedia reader. - Added an optional “Center on my position at startup” setting, disabled by default. - Added reproducible Android builds for the bundled eSpeak NG native libraries. - Added SHA-256 verification of bundled native assets before Android builds. - Added automated tests for BOLT11, bounded HTTP, road events, OSM POI details, and Wikipedia URL validation. ### Changed - Wikipedia articles now open inside Roadstr instead of immediately leaving the app. - Wikipedia lookup now verifies geographical and textual relevance before associating an article with a POI. - Minor POIs without Wikipedia remain useful through native OpenStreetMap data. - External web searches and POI websites require an explicit user action. - GPS no longer starts automatically when the app opens. - Startup GPS centering only runs when explicitly enabled and location permission has already been granted. - Speed limits are now displayed only when OpenStreetMap provides an explicit, unambiguous value. - Removed road-class and Italian default speed-limit inference to prevent incorrect limits. - Speed-limit matching now uses road geometry to avoid borrowing a limit from nearby parallel roads. - Optimized bundled eSpeak NG libraries, significantly reducing their size. - Updated and completed translations for all 27 supported languages. - Improved release signing behavior: unsigned builds are no longer silently replaced with debug-signed release artifacts. - Cleaned up static-analysis warnings and simplified several internal code paths. ### Security - Hardened LNURL and Nostr Wallet Connect payments: - Invoice amount must match the requested amount. - Description hash must match the zap request. - Expired invoices are rejected. - NWC response kind, author, tags, signature, and request binding are verified. - Empty payment results are no longer treated as success. - Payment preimages are verified against the invoice payment hash. - Replay paths are rejected. - Hardened the Wikipedia WebView: - Only validated HTTPS Wikipedia article URLs are allowed. - JavaScript is disabled. - Cookies, cache, and local storage are cleared. - WebView permissions are denied. - File access and mixed content are disabled. - SSL errors fail closed. - External redirects and deceptive Wikipedia-like domains are blocked. - Sanitized and length-limited all untrusted OpenStreetMap POI fields. - POI websites are accepted only when using HTTPS without credentials or custom ports. - Made Hive migrations fail closed with atomic backups instead of deleting unreadable data. - Added timestamp, expiration, TTL, coordinate, category, and duplicate-tag validation for road events. - Added anti-spoofing checks between event coordinates and geohash tags. - Added bounded relay caches to prevent unbounded memory growth. - Fixed stale asynchronous relay results through generation-based request invalidation. - Enforced the NIP-44 padding limit instead of producing oversized payloads. - Removed the Android `ACCESS_BACKGROUND_LOCATION` permission. - Prevented the initial fallback map position from being published to Nostr relays. - Removed committed environment secrets and strengthened repository ignore rules. ### Fixed - Fixed incorrect Wikipedia pages being assigned to nearby minor POIs. - Fixed stale asynchronous map and POI responses overwriting newer selections. - Fixed possible data loss during local database migrations. - Fixed expired or future-dated road events remaining visible or being accepted. - Fixed malformed or spoofed Nostr road events reaching the UI. - Fixed transient speed-limit results leaking between roads or navigation sessions. - Fixed release builds falling back to the debug signing key. - Fixed several race conditions in GPS, relay subscriptions, and map updates. - Fixed unbounded network responses and slow-response resource exhaustion. - Fixed multiple dead-code paths and obsolete services/widgets. ### Removed - Removed inferred speed limits based only on road classification. - Removed unused location-service code. - Removed obsolete HUD widget code. - Removed obsolete WebView ProGuard rules. - Removed generated Android build reports from source control. - Removed the background-location permission. ### Validation - `flutter analyze`: no issues found. - `flutter test`: 46 tests passed. - Android debug APK: built successfully. - Android release APK with R8: built successfully. - All 27 localization files contain the complete message set. ## What's Changed ### POI Search and Navigation Flow - Search results now open on the map before route calculation begins. - Selected POIs are automatically framed and displayed with their complete OSM information panel. - Applied the same information-first flow to search submission, history entries, and favorites. - Added a localized **Navigate here** button to the POI information panel. - Tapping **Navigate here** opens the complete route-selection preview. - Route selection is now available for short trips and single-route results. - Car, bicycle, and walking modes remain available. ### Highway and Toll Avoidance - Added an **Avoid highways and toll roads** toggle for driving routes. - The avoidance option adds a dedicated route without replacing standard alternatives. - Implemented a hybrid routing strategy: - Strictly excludes highways and toll roads whenever possible. - Automatically falls back to soft avoidance when strict exclusion cannot produce a route. - Soft avoidance applies: - Minimum highway preference. - Minimum toll-road preference. - A 900-second virtual toll-booth routing penalty. - Routing penalties influence route selection without artificially increasing the displayed ETA. - Added validation of Valhalla's `has_highway` and `has_toll` route summary fields. - The selected avoidance policy is preserved during automatic rerouting. ### Route Preview UI - Fully highway- and toll-free routes are displayed in green. - Routes containing an unavoidable highway or toll section are displayed in amber. - Added explicit route-card labels distinguishing strict avoidance from minimized usage. - Avoidance routes display both duration and distance in the configured metric or imperial units. - Updated route lines, time bubbles, cards, toggle styling, and loading feedback. - Protected toggle changes, mode switching, and concurrent calculations against stale asynchronous results. ### Localization - Added the new avoidance controls and unavoidable-section messaging to all 27 supported languages. - Regenerated all Flutter localization classes. ### Code Quality - Removed the obsolete search-pin panel and its unused state. - Removed unreliable provider-specific OSRM and GraphHopper avoidance parameters. - Replaced parallel UI state with route-level avoidance metadata. - Added bounded Valhalla polyline decoding and maneuver parsing. - Added defensive validation for route geometry, instructions, distance, duration, and provider responses. - Standard route alternatives remain available while the additional avoidance route is calculated.
  • Jul 17, 2026 0.4.7
    ## v0.4.7 (16) This release is a privacy hardening pass focused on the most sensitive data the app touches: your saved favorites (home/work addresses) and your Nostr identity. ### Favorites sync — privacy hardening - **Stopped relays from enumerating Roadstr users.** The sync event used a fixed, human-readable tag (`roadstr-favorites`), so a single relay query could list every npub using the app — a ready-made target list. The tag is now a per-user hash, so that bulk query no longer works. - **Optional sync passphrase.** You can now add a second encryption layer (PBKDF2 + AES-256-GCM) on top of the existing NIP-44 encryption. With it set, even a compromised Nostr key isn't enough to decrypt the favorites snapshot an attacker pulled or archived from relays. Set it once per device under Settings → favorites sync. - **Rollback protection.** Pull now queries all relays in parallel and keeps the newest verified snapshot, with a local high-water mark that rejects anything older — a malicious relay can no longer resurrect deleted favorites or restore a stale address by replaying an old (validly signed) event. - **Metadata minimization.** The snapshot is padded to a fixed size bucket before encryption (so ciphertext length no longer reveals how many favorites you have), and its timestamp is rounded to the hour (no more broadcasting the exact second you edited a favorite). - **Removed `relay.nostr.band` from sync** — it feeds a public search indexer, the worst place to park privacy-sensitive events.
    More…
    ### Location privacy - **Screen capture is now blocked (FLAG_SECURE).** Previously, minimizing the app left a live screenshot of the map — centered on your current location — as the recents/app-switcher thumbnail, visible to anyone who opened the task switcher. This also blocks screenshots and screen-recording of the app. (Trade-off: you can no longer screenshot a route to share it.) - **Coarser location subscriptions.** The road-event area subscription no longer sends a ~5×5 km geohash to the relay on every move; it now sends only the ~40×20 km cell, which matches the exact same events while giving relays a far coarser view of where you are. - **Opaque request identifiers.** Relay subscription IDs no longer carry descriptive prefixes that let a relay fingerprint the app or tell what each request was for. - **Weather requests are rounded** to ~1 km before being sent to the weather provider (the destination is often home; weather doesn't need street-level precision). ### Notes - Nostr private keys (nsec) remain stored only in Android's encrypted secure storage, are never transmitted, never logged, and cannot be revealed, exported, or copied out of the app. - Snapshots synced before this release keep their encrypted contents safe, but their metadata (the old readable tag, exact timestamps) is already public on relays; re-syncing after setting a passphrase is recommended for the strongest protection.
  • Jul 17, 2026 0.4.6
    ## v0.4.6 (15) ### ZTL (limited-traffic zones) - **Fixed a bug that made ZTL detection silently fail since the feature shipped.** The Overpass query used `["name"~"ZTL","i"]` — the quoted `"i"` is a syntax error in Overpass QL (case-insensitive regex needs an unquoted `,i`), so every ZTL fetch failed, on every mirror, from day one. - **Rewrote ZTL detection to match how Italian zones are actually mapped.** Italian ZTLs are tagged per-street (`motor_vehicle=permit`, `access=no/destination`, `highway=pedestrian`), not as named polygons — the old polygon-only query returned nothing even after the syntax fix. Detection is now proximity-based (≤12 m from a restricted way) in addition to the legacy polygon lookup, verified live against Ravenna's centro storico (251 restricted ways) and cross-checked against the ~350 Italian cities that do use the official `boundary=limited_traffic_zone` polygon tag. - **Removed the `overpass.osm.ch` mirror.** It turned out to be a Switzerland-only data extract that returned HTTP 200 with zero results for anywhere else — every dependent feature (ZTL, speed limits, speed cameras, POI search) silently read that as "nothing here." Replaced with two verified worldwide mirrors. - **Verified live against 24 cities worldwide** (12 European historic centres, 12 US cities/car-free towns) to check the new detection actually generalises rather than just fixing Italy. Works well anywhere OSM has restricted-access tagging; known gap where a town's equivalent has never been mapped by the local OSM community (e.g. Tangier Island, VA); intentionally does *not* flag toll-only zones (NYC congestion pricing, London ULEZ) as ZTL, since those don't restrict entry. - **The warning banner now shows the correct local term** instead of the Italian "ZTL" everywhere — "ZTL" in Italy and France (both use the same official term), "ZAC" in Portugal, a generic translated phrase elsewhere. Countries with no single official acronym (Spain, Germany, UK…) no longer get one invented for them. - Fixed the spoken ZTL warning, which previously had translations for only 9 of the app's 27 languages and silently fell back to English for the rest.
    More…
    ### Navigation - **Map no longer flips 180° mid-drive.** A GPS multipath glitch could teleport a fix 20+ m backward with an inverted bearing, slipping past the existing distance-based filter. A direction reversal during active navigation is now trusted only after two consecutive GPS samples agree on it — a real U-turn confirms itself on the next fix, a glitch doesn't. - **Voice no longer repeats the same instruction 3–4 times** on approach to a manoeuvre. The same normalised instruction is now suppressed for 12 seconds at the single choke-point every announcement passes through. - **Navigation cursor sits further down the screen**, trading a bit of "behind you" for more visible road ahead. - Renamed the button on the pin/place-info panels from "Start navigation" (which actually opened a route preview) to "Show route preview" — "Start navigation" now only appears where navigation genuinely starts. ### Security - **A malicious relay could have redirected Lightning zaps to its own wallet.** `fetchLightningAddress` trusted a relay's kind-0 profile event without checking its id hash, signature, or that the pubkey matched the person being zapped — fixed by verifying every profile event the same way road events already were. - **Logging out no longer destroys local data.** It previously called `deleteAll()` on secure storage, wiping the encrypted-settings key along with it — undecryptable on next launch, silently taking favourites, history and routing/NWC config with it. Logout now removes only the 5 Nostr-identity keys. - One-time report/confirmation fetches (profile screen) now verify event signatures and enforce one-vote-per-identity, matching the live subscription's rules — previously trusted unverified relay data and allowed repeat votes. - Amber (NIP-55) event publishing now broadcasts to all configured relays instead of only the primary one, matching nsec-login behaviour. - NIP-44 decryption now enforces the exact padded length the spec prescribes, rejecting malformed payloads other implementations would also refuse. - Consolidated three duplicated event-verification implementations into one shared, tested helper. ### Legal - **Rewritten as a proper worldwide terms-of-use, in all 27 languages**: an explicit assumption-of-risk clause covering accidents, injury, fines and legal consequences in any country; expanded no-warranty language; an indemnification clause; a severability clause. Speed-limit, speed-camera and ZTL data are now explicitly disclosed as community-sourced and not authoritative.
  • Jul 12, 2026 0.4.5
    ## v0.4.5 (14) ### Search & POI - **Search now favors places near you.** Nominatim results are biased toward your GPS position and re-sorted by distance — fixes generic terms like "cinema" or "supermercato" ranking a same-named place on the other side of the world above the one down the street. - New **category/brand search** (Overpass-powered): typing "farmacia," "benzinaio," or a store brand name now searches OSM directly within a radius of your position, sorted by real distance — independent of Nominatim's global relevance ranking. ### Speed cameras - Added an **OSM-sourced speed camera layer** (`highway=speed_camera` / `enforcement=maxspeed`), shown on the map with a distinct muted marker and included in the proximity beep — additive to, never replacing, community-reported Nostr cameras. ### Parking
    More…
    - **Save your parking spot** — a dedicated button for "I'm here now," plus a long-press map option for "actually it was back there" when you've already walked off. Local-only, never touches Nostr, persists until you clear it. ### Favorites: export, encryption, sync - **Export favorites to JSON**, with optional password encryption (PBKDF2 + AES-256-GCM). - **Encrypted cross-device sync via Nostr** — favorites publish as a self-encrypted NIP-44 event (kind 30078); relays only ever see ciphertext, nobody but you can read the contents. NIP-44 was implemented from scratch (the Nostr library in use didn't support it) and covered by round-trip tests. - Onboarding now explains the encrypted/anonymous sync option. ### Arrival precision - Arrival radius on the last leg is now **dynamic based on live GPS accuracy** (10–40 m) instead of a flat 60 m — tight and precise with a good fix, still forgiving in a parking garage or urban canyon. ### Voice - **Male voice option** added for every supported language except French (Kokoro-82M has no French male voice) — pick it in Settings, with a live preview sample. - **6-stage speech speed slider**, also previewable before committing. - Smoother navigation camera: replaced the fixed-duration tween with a continuous exponential-smoothing follow — removes the faint stutter that showed up when a new GPS fix landed mid-animation. - Secondary instruction panel width fixed to exactly half the screen (was growing unbounded with long text); speed-limit sign no longer overlaps the bottom nav panel. ### Cursor - Removed the extra cursor styles (muscle car, SUV, compact, vespa, moto, bike) — down to **arrow*. The others were too tacky. ### Security & privacy - Full security audit: removed a **dead, exported deep-link intent-filter** that any website could have triggered. - Replaced a Russian-hosted Overpass mirror with a Swiss one — no more real-time GPS coordinates going to a VK/mail.ru-operated server. - Fixed a crash from using a stale screen reference after an async gap. - Verified: private keys never leave secure storage, all incoming Nostr events are signature-verified, no tracking/analytics SDKs, encrypted local settings. - **License clarified as GPL-3.0** (copyleft) — README previously and incorrectly said MIT. - Cleaned up ~120 lint warnings and dead code.
  • Jul 11, 2026 0.4.4
    ## v0.4.3 (12) ### Navigation - **Speed limits actually work now.** The root cause: `annotations=maxspeed` is a Mapbox-only extension — vanilla OSRM (including the FOSSGIS server we use) never returned it. Speed limits now come from Overpass, with class-based inference (motorway/trunk/residential/living_street) for the many roads that have no explicit `maxspeed` tag, 3 rotating mirrors for reliability, and support in free-roam driving (not just active navigation). - **Recenter button** now pulls a fresh one-shot GPS fix instead of reusing the last stream sample, so it snaps to your *actual* current position. - **Compass/heading button** is a real toggle in both navigation and free-roam — free-roam heading-up mode now rotates the map with the magnetometer instead of doing nothing. - **Secondary instruction panel** (next-turn preview) enlarged ~100% — bigger icon, bigger text, easier to read at a glance. ### Voice - Turn instructions and hazard/ZTL alerts no longer cut each other off mid-sentence. Maneuvers are priority (interrupt immediately); ambient alerts queue and wait their turn, keeping only the most recent one.
    More…
    - Fixed a race in audio ducking where a stale utterance could release focus meant for a new one, breaking the "duck other media" behavior. ### Security - Nostr events are now cryptographically verified (event hash + BIP-340 signature) before being trusted — a malicious relay could previously fabricate road reports or confirmations under any pubkey. - One vote per identity per event confirmation (was previously unlimited/re-countable). - Local settings (favorites, search history) are now AES-256 encrypted at rest, key held in the Android Keystore. - `debugPrint` is silenced in release builds — no more street names/coordinates/TTS phrases in logcat. - Event comments capped at 500 chars to prevent relay-side payload abuse. ### Onboarding - Welcome page now shows the real app logo and a privacy notice recommending a VPN (Mullvad, Bitcoin-payable) given that road reports propagate over Nostr. - nsec login page now shows the same security disclaimer as the profile screen. - Fixed the Kokoro voice download completion indicator — it was implemented but never actually triggered (listener was waiting on a stream event that never fires); now shows a white check on a green circle when the download finishes. - GrapheneOS guidance now mentions setting location permission to "Allow all the time," not just "while in use."
  • Jul 11, 2026 0.4.3
    ## v0.4.3 (12) ### Navigation - **Speed limits actually work now.** The root cause: `annotations=maxspeed` is a Mapbox-only extension — vanilla OSRM (including the FOSSGIS server we use) never returned it. Speed limits now come from Overpass, with class-based inference (motorway/trunk/residential/living_street) for the many roads that have no explicit `maxspeed` tag, 3 rotating mirrors for reliability, and support in free-roam driving (not just active navigation). - **Recenter button** now pulls a fresh one-shot GPS fix instead of reusing the last stream sample, so it snaps to your *actual* current position. - **Compass/heading button** is a real toggle in both navigation and free-roam — free-roam heading-up mode now rotates the map with the magnetometer instead of doing nothing. - **Secondary instruction panel** (next-turn preview) enlarged ~100% — bigger icon, bigger text, easier to read at a glance. ### Voice - Turn instructions and hazard/ZTL alerts no longer cut each other off mid-sentence. Maneuvers are priority (interrupt immediately); ambient alerts queue and wait their turn, keeping only the most recent one.
    More…
    - Fixed a race in audio ducking where a stale utterance could release focus meant for a new one, breaking the "duck other media" behavior. ### Security - Nostr events are now cryptographically verified (event hash + BIP-340 signature) before being trusted — a malicious relay could previously fabricate road reports or confirmations under any pubkey. - One vote per identity per event confirmation (was previously unlimited/re-countable). - Local settings (favorites, search history) are now AES-256 encrypted at rest, key held in the Android Keystore. - `debugPrint` is silenced in release builds — no more street names/coordinates/TTS phrases in logcat. - Event comments capped at 500 chars to prevent relay-side payload abuse. ### Onboarding - Welcome page now shows the real app logo and a privacy notice recommending a VPN (Mullvad, Bitcoin-payable) given that road reports propagate over Nostr. - nsec login page now shows the same security disclaimer as the profile screen. - Fixed the Kokoro voice download completion indicator — it was implemented but never actually triggered (listener was waiting on a stream event that never fires); now shows a white check on a green circle when the download finishes. - GrapheneOS guidance now mentions setting location permission to "Allow all the time," not just "while in use."
  • Jul 7, 2026 0.4.1
    <h2>🔒 v0.4.1 — Navigation polish &amp; security hardening</h2> <h3>Navigation fixes</h3> <ul> <li><strong>TTS timing</strong> — Voice announcements now adapt to transport mode. Walking uses tighter distances (far 60 m · near 15 m); cycling uses intermediate distances (far 150 m · near 30 m); driving is unchanged. Back-to-back announcements on short steps are suppressed to prevent the "silencing" effect.</li> <li><strong>Walking arrival radius</strong> — Arrival is now confirmed at 15 m instead of 40 m when navigating on foot, so a 300 m route no longer triggers arrival halfway through.</li> <li><strong>Arrival screen removed</strong> — The 👍/👎 feedback dialog is gone. On arrival the destination pin turns green with a ✓ icon and stays visible on the map; a brief banner auto-dismisses after 6 seconds.</li> </ul> <h3>Security hardening</h3> <ul> <li><strong>EncryptedSharedPreferences enabled</strong> — All four <code>FlutterSecureStorage</code> instances now use <code>encryptedSharedPreferences: true</code>, encrypting both keys and values via Android Keystore (not just values).</li> <li><strong>NWC URI moved to SecureStorage</strong> — The <code>nostr+walletconnect://</code> URI (which contains a Lightning wallet private key) was stored in plain Hive. It is now stored in Android Keystore-backed SecureStorage. Automatic migration from Hive on first launch.</li> <li><strong>Routing API keys moved to SecureStorage</strong> — GraphHopper Cloud and OpenRouteService API keys were stored in plain Hive. Migrated to SecureStorage with the same automatic migration path.</li> <li><strong>WebView hardened</strong> — The Wikipedia/search WebView now blocks any navigation to non-HTTPS URLs via <code>onNavigationRequest</code>.</li> <li><strong>ADB backup disabled</strong> — <code>android:allowBackup="false"</code> added to <code>AndroidManifest.xml</code>. Prevents <code>adb backup</code> from extracting app data (including the Hive settings file) from an unlocked device with USB debugging enabled.</li> <li><strong>Release logging</strong> — Replaced a <code>print()</code> call in <code>gps_service.dart</code> (visible in logcat in release builds) with <code>debugPrint()</code> (stripped in release).</li> </ul> <blockquote> <strong>Migration note:</strong> NWC URI and routing API keys are migrated automatically from Hive to SecureStorage the first time each relevant screen is used after the update. No manual action required. </blockquote>
  • Jul 6, 2026 0.4.0
    <h2>First-launch onboarding</h2> <ul> <li>4-page flow on first install: features showcase → Nostr identity → permissions → ready.</li> <li>Nostr login via <strong>Amber NIP-55</strong> (recommended) or <strong>nsec key</strong> (stored in Android Keystore). Profile name and avatar fetched from relay immediately after login.</li> <li>Dedicated <strong>GrapheneOS guidance</strong>: grant Precise location <em>and</em> "Allow always" to keep GPS active in background.</li> <li>Optional <strong>Kokoro AI voice model</strong> download (82 MB) with live progress bar — can be deferred to Settings.</li> <li>Pages freely swipeable. Fully localised in all 27 supported languages.</li> </ul> <h2>ZTL / restricted zone ahead warning</h2>
    More…
    <ul> <li>Checks whether an upcoming turn leads <em>into</em> a restricted zone at the moment the instruction is announced — before the user enters.</li> <li><strong>Orange banner</strong> + spoken voice warning at that point. One warning per step, no repeated alerts.</li> <li>Distinct from the existing <strong>red banner</strong> shown when already inside a ZTL.</li> <li>Warning spoken in the user's language at runtime.</li> </ul> <h2>Missed-turn rerouting</h2> <ul> <li>After advancing to a new step, a <strong>2.5-second guard timer</strong> verifies the user is actually approaching the next waypoint.</li> <li>If distance hasn't improved and speed is above 3 km/h, silent reroute triggers automatically.</li> </ul> <h2>TTS announcement improvements</h2> <ul> <li>Urban steps now receive an <strong>immediate voice announcement</strong> right after a maneuver, replacing the previous premature 220 m trigger.</li> <li>Announcement distances adapt to road type and current speed.</li> </ul> <h2>Cursor styles overhaul</h2> <ul> <li><strong>7 selectable cursors</strong> rendered from SVG assets: Arrow, Muscle Car, SUV, Compact, Vespa, Racing Moto, Bicycle.</li> <li>Settings cursor grid replaced with a <strong>dropdown with live icon preview</strong>.</li> </ul> <h2>Localisation sweep</h2> <ul> <li>Event categories, transport mode chips, time labels, and weather strings now fully localised across all <strong>27 supported languages</strong>.</li> <li><strong>40 new ARB keys</strong> covering all onboarding screen strings.</li> </ul> <h2>Other improvements</h2> <ul> <li>Route preview panel now supports <strong>drag-to-close</strong> gesture with spring-back animation.</li> <li>Secondary nav instruction row shows distance to next maneuver.</li> </ul>
  • Jul 4, 2026 0.3.4
    <h2>v0.3.4 — Nav UX overhaul, roundabout icons, speed alerts</h2> <h3>New features</h3> <ul> <li>Nav banner now full-width edge-to-edge, covering the status bar area, with ~30% larger text</li> <li>Next-step preview row below the main instruction</li> <li>Roundabout exit icon: custom-drawn painter, exits 1–6, CCW arc — no Overpass API needed</li> <li>TTS: ordinal symbols (1°, 2°…) normalised to spoken words before synthesis</li> <li>Adaptive TTS announcement distances based on road type and current speed</li> <li>Speed limit exceeded → red speedometer arc, text and border</li>
    More…
    <li>Speed camera proximity alert: dual-tone beep (350 Hz + 440 Hz) within 250 m</li> <li>Weather row (Open-Meteo, no API key) in Alternatives panel and Pin panel</li> <li>Drag-to-close gesture on Alternatives panel</li> </ul> <h3>Bug fixes</h3> <ul> <li>Search bar restored to floating position (was accidentally pinned to screen top edge)</li> <li>Roundabout painter geometry corrected: arc now sweeps counter-clockwise (right-hand traffic)</li> <li>Alternatives panel horizontal overflow fixed; title/chip spacing improved</li> <li>Avoid motorways / avoid tolls chips now shown only when GraphHopper is selected</li> </ul>
  • Jul 4, 2026 0.3.3
    <h2>Roadstr 0.3.3</h2> <h3>Navigation</h3> <ul> <li><b>Map and cursor follow direction of travel</b> — definitive fix: <code>_toggleHeadingMode</code> is now a real toggle; <code>_recenter</code> re-enables heading mode during active navigation</li> <li><b>Rerouting on U-turn</b> — added bearing-difference check (&gt;150° at &gt;10 km/h) as a second reroute trigger alongside the existing distance check</li> </ul> <h3>Routing</h3> <ul>
    More…
    <li><b>Route alternatives</b> — panel shows multiple options when available (distance &gt;5 km)</li> <li><b>Cycling mode</b> — new "Bike" chip routing through the dedicated OSRM cycling endpoint, preferring cycle paths</li> <li><b>Route preferences</b> — "Avoid highways", "Avoid tolls", "Shortest route" chips (shown only with GraphHopper/ORS, hidden on OSRM)</li> <li><b>Drag-to-close</b> — alternatives panel closes on downward drag or flick; includes slide-in animation on open</li> </ul> <h3>Weather (Open-Meteo, no API key required)</h3> <ul> <li>Temperature, condition and wind speed shown in the alternatives panel and quick-search pin popup</li> <li>Lazy async loading, silent failure when offline</li> </ul> <h3>UI fixes</h3> <ul> <li>Fixed overflow in alternatives panel on narrow screens (&lt;360dp): title and mode chips are now on separate rows with horizontal scroll</li> <li>GPS camera animation: <code>_gpsAnimMs = 600</code> for continuous 60fps movement</li> </ul>
  • Jul 4, 2026 0.3.2
    Minor bugfixes and updated translations.
  • Jul 3, 2026 0.3.1
    Added vocal directions and bugfixes.
  • Jun 28, 2026 0.2.1
    First public release.