Skip to content

VeloSpot v1.0.26

Choose a tag to compare

@github-actions github-actions released this 26 Jul 07:14
e077714

VeloSpot v1.0.26

Added

  • AMOLED pure-black map (a dark-mode sub-option) β€” a new AMOLED toggle in Settings β†’ Appearance & map switches the dark map to a true-black style (map_style_amoled.json, derived from map_style_dark.json with a #000000 background, near-black fills and black text halos) so OLED panels can switch pixels off and save battery on night rides. It's an extension of dark mode: enabling it also turns dark mode on if it wasn't already, and it has no effect in light mode. Off by default and persisted via the DataStore-backed MapSettingsRepository (amoledEnabled, MapViewModel.amoledEnabled); the style reloads live when toggled (a new MAP_STYLE_URL_AMOLED resolved by mapStyleUrl(isDarkTheme, amoled)). Localised across all eight supported languages (menu_amoled_mode).
  • Recent destinations in the search bar β€” focusing the (empty) address search field now initially expands its dropdown to show the last 3 destinations the rider navigated to, so a frequent place is one tap away without re-typing the address. Every navigation start (parking spot, address, saved place, custom pin) is recorded β€” de-duplicated by rounded coordinate and capped β€” in a dedicated, isolated Room store (DestinationHistoryDatabase / recent_destinations, independent of the parking / rides / places stores), exposed reactively via a new DestinationHistoryRepository and MapViewModel.recentDestinations. Localised across all eight supported languages (search_recent_title, recent_destination_fallback).
  • Download a whole route corridor for offline use β€” the saved-route preview card gains a Download for offline use action that fetches the entire route corridor β€” the map tiles along the route (not just a 40 km box around the start) and every BRouter routing tile the route passes through β€” so a long tour into a dead zone works end-to-end offline. Built on a pure, JVM-testable RouteCorridor.corridorBoxes (splitting the route polyline into overlapping, padded map-tile boxes) plus BRouterSegmentManager.downloadSegmentsForRoute / requiredSegmentNamesForPoints and OfflineMapTilesManager.downloadRouteCorridor, wired through a new OfflineRegionsController.downloadRouteCorridor (MapViewModel.downloadRouteForOffline). The corridor is registered as one offline-region pack (reusing the existing download progress overlay, listing and Wi-Fi gating); OfflineRegionPack now carries the exact routingTiles it needs so deleting a region only removes routing tiles no other region still depends on. Localised across all eight supported languages (offline_download_route).
  • First-launch welcome onboarding β€” the very first app start now greets the rider with a compact three-card welcome sheet instead of dropping them straight onto the bare map. The cards mirror VeloSpot's own building blocks: a short "what is VeloSpot" intro, an "offline maps & routing" card that explains navigation works without a connection and offers a direct "Set up offline routing" button (which opens the offline-regions manager), and a "ready to ride" card pointing at search, the map and the menus. It's a swipeable HorizontalPager bottom sheet with page-indicator dots and a Skip / Next / Get started button β€” deliberately not a coordinate-based coach-mark tour (the previous attempt broke against the map overlays, insets and async layout). Shown only once, gated behind a new DataStore flag (onboardingCompleted on MapSettingsRepository, exposed via MapViewModel.onboardingCompleted / completeOnboarding / replayOnboarding) that only reveals the sheet after the launch splash and once the stored value has definitely loaded as false (so returning users never see a flash). It can be re-opened any time from a new App tour row on the About VeloSpot sheet. Localised across all eight supported languages (onboarding_*, about_replay_onboarding*).
  • Unified, multi-region offline use β€” map tiles and routing, downloaded together per region β€” the two separate Settings β†’ Navigation & routing entries (offline routing segments and offline map tiles) are merged into a single Offline regions manager, so a region always gets both halves at once β€” no more "offline route on a blank grey map", and no more "map with no offline route". Each region is one combined pack: the visible vector map (a ~40 km box) plus the BRouter 5°×5Β° routing tile covering the same spot, downloaded in two clearly-labelled phases with an inline progress bar. Crucially the manager is now multi-region: a region is anchored on the rider's current position or a spot they pick on the map (a centre crosshair they pan the map under, then confirm), so a rider based in, say, Frankfurt can add a second region while on holiday in Sydney β€” or pre-download a destination before leaving home β€” and have the map + routing for both offline. The add screen shows a coverage hint (the map box is a ~40 km radius; bike routing covers a much larger surrounding area). Each downloaded region is listed with its reverse-geocoded place name (via NominatimGeocoder) and can be deleted individually β€” the shared 5Β° routing tile is only removed when no other region still needs it (so a separate "disable offline routing" button is no longer needed and was removed from the routing-profile sheet). The huge "whole area (DE/FR/LU)" download is dropped in favour of these lightweight, on-the-go regions. Built on a new OfflineRegionsController + OfflineRegionsStore (a small org.json SharedPreferences list, the source of truth) over the existing OfflineMapTilesManager / BRouterSegmentManager (extended with a per-region name + tile helpers), a single OfflineRegionsUiState, and a new OfflineRegionsSheet, replacing the old split OfflineRoutingController / OfflineMapController, their UI states and setup sheets. Nothing is bundled into the APK and it adds no new dependency (F-Droid- and reproducibility-safe). Localised across all eight supported languages (offline_regions_*, menu_offline_regions_*).

Changed

  • Polished "My routes" list β€” each saved route is now a richer card: a rounded route-icon avatar, the name, compact stat pills (distance Β· ↑ ascent Β· waypoints), a prominent Ride button plus an outlined Reverse, and a visible secondary action row (Map Β· Ranking Β· Offline) β€” the offline-corridor download is now reachable straight from the list, not only the preview. Localised across all eight supported languages (route_map_short, route_leaderboard_short, route_offline_short, common_more_options).

Security

  • Hardened GitHub Actions workflows (OpenSSF Scorecard) β€” tightened CI token permissions to least privilege (the ci workflow now defaults to contents: read at the top level and only the coverage job elevates to pull-requests: write / id-token: write, dropping the unused actions: write), added persist-credentials: false to all read-only actions/checkout steps (so the repo token is never left on disk for build/lint/test/scan jobs), and enabled Renovate's helpers:pinGitHubActionDigests preset so every GitHub Action is pinned to a full commit SHA (with a version comment) and kept up to date automatically β€” satisfying Scorecard's Pinned-Dependencies and Token-Permissions checks.

πŸ“₯ APK Variants

File Description
VeloSpot-v1.0.26.apk F-Droid flavor – no Google services, ready to sideload; this is the APK F-Droid reproducibly verifies
VeloSpot-v1.0.26-googlePlay.apk Google Play flavor – includes Google Play Services Location
VeloSpot-v1.0.26-sbom.cdx.json / .xml CycloneDX SBOM – full dependency + license inventory

πŸ” Supply-chain verification

All release artifacts ship with signed build provenance attestations.
Verify any downloaded file with the GitHub CLI:

gh attestation verify VeloSpot-v1.0.26.apk --repo drzeeb/VeloSpot

Installation (sideload)

  1. Download the APK below.
  2. On your Android device: Settings β†’ Apps β†’ Install unknown apps β†’ allow your browser or file manager.
  3. Open the APK and tap Install.

The F-Droid flavor is also available on F-Droid.