Skip to content

Add "Update to latest" button to Settings - #20

Merged
neteinstein merged 1 commit into
mainfrom
feature/update-to-latest-button
Jul 21, 2026
Merged

Add "Update to latest" button to Settings#20
neteinstein merged 1 commit into
mainfrom
feature/update-to-latest-button

Conversation

@neteinstein

Copy link
Copy Markdown
Owner

What

Adds an Update to latest button to the Settings screen. Pressing it checks GitHub Releases for a build newer than the one installed, downloads its APK if one exists, and hands it to the system Package Installer to update in place.

If the device doesn't have "install unknown apps" (sideloading) enabled for InstaMaps, pressing the button shows a warning instead of downloading, with an action that jumps straight to that permission's system Settings screen.

How

  • core:update (new module): UpdateRepository/CheckForUpdateUseCase/DownloadAppUpdateUseCase (domain) + GitHubUpdateRepository (data) hit the unauthenticated GitHub "get the latest release" API (same raw HttpURLConnection/org.json approach as GeminiLocationRepository - no new SDK dependency). VersionComparator.isNewerVersion compares versions numerically per-segment, not lexicographically ("1.0.9" vs "1.0.16" would otherwise compare backwards as plain strings). AppUpdateInstaller is the Android glue: checks/requests the per-app "install unknown apps" permission and launches the system installer via a FileProvider content:// URI.
  • app: REQUEST_INSTALL_PACKAGES permission + FileProvider <provider> entry (scoped to a cacheDir/updates/ subdirectory), Koin module registration.
  • feature:settings: new "Updates" section with the button and live status (checking/downloading/up-to-date/failed/sideloading-blocked), wired through SettingsViewModel/SettingsUiState/SettingsScreen. The flow checks the sideloading permission before downloading, so no bandwidth is wasted if it's blocked.

Testing

  • New unit tests: VersionComparatorTest (7 cases, including the numeric-vs-lexicographic bug it exists to avoid), CheckForUpdateUseCaseTest/DownloadAppUpdateUseCaseTest (fake-repository delegation), GitHubUpdateRepositoryTest (real org.json parsing of GitHub's actual response shape, verified against a live fetch of the repo's latest release).
  • Ran ./gradlew ktlintCheck compileDebugKotlin compileDebugUnitTestKotlin test - all green, including the full existing suite.
  • Ran ./gradlew :app:assembleDebug and inspected the merged manifest to confirm the FileProvider authority and REQUEST_INSTALL_PACKAGES permission are wired correctly end-to-end.
  • Updated agents.md (module map + tech stack + testing standards) and README.md (new "Updating InstaMaps" section) per repo docs policy.

Co-authored-by: Copilot App 223556219+Copilot@users.noreply.github.com

Adds a new core:update module that checks GitHub Releases
(neteinstein/InstaMaps) for a build newer than the one installed,
downloads its APK, and hands it to the system Package Installer.

- core:update: UpdateRepository/CheckForUpdateUseCase/DownloadAppUpdateUseCase
  (domain), GitHubUpdateRepository (data, raw HttpURLConnection + org.json,
  same pattern as GeminiLocationRepository), VersionComparator.isNewerVersion
  (numeric, not lexicographic, version comparison), and AppUpdateInstaller
  (Android glue: checks/requests the "install unknown apps" permission,
  launches the system installer via a FileProvider content:// URI).
- app: REQUEST_INSTALL_PACKAGES permission plus FileProvider provider entry,
  Koin module registration.
- feature:settings: "Update to latest" button and status section wired
  through SettingsViewModel/SettingsUiState/SettingsScreen. Checks for an
  update, then checks the sideloading permission before downloading (to
  avoid wasted bandwidth) - shows a WarningBanner with an "enable
  sideloading" action if it is not granted instead of downloading.
- Unit tests for VersionComparator, the two use cases, and
  parseGitHubReleaseResponse; docs updated in agents.md and README.md.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@neteinstein
neteinstein merged commit 3ba2a28 into main Jul 21, 2026
4 checks passed
@neteinstein
neteinstein deleted the feature/update-to-latest-button branch July 21, 2026 11:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant