Skip to content

Add retry, history, multi-location results, loading animations - #18

Merged
neteinstein merged 1 commit into
mainfrom
feature/docs-gemini-prepaid-setup
Jul 21, 2026
Merged

Add retry, history, multi-location results, loading animations#18
neteinstein merged 1 commit into
mainfrom
feature/docs-gemini-prepaid-setup

Conversation

@neteinstein

Copy link
Copy Markdown
Owner

Description

Ships a backlog of five related improvements to the share pipeline:

  • Retry button: ShareScreen now shows a Retry action on any failure or "no location found"
    outcome, re-running the exact same video via ShareViewModel.retry() instead of requiring a
    fresh share. Touches feature:share.
  • Multi-location results: the Gemini prompt now asks for every place a video is actually
    about, ranked most-to-least likely, instead of a single best guess.
    GeminiLocationRepository/ResolveLocationUseCase (feature:geocoding) now return
    List<ResolvedLocation>. The results screen lists every match (scrollable) with its own
    name/address/"Open in Google Maps" CTA and no longer auto-opens Maps - the user picks. The
    result notification still deep-links straight to the top-ranked match for the tap-and-go case.
  • History screen: new core:history (domain/data/di) + feature:history (presentation/di)
    modules, mirroring the existing core:settings/feature:settings split. Every shared link -
    found, not-found, or failed - is recorded (capped at the last 50, newest first) via
    RecordHistoryEntryUseCase from ProcessSharedUrlWorker. A new History icon next to Settings
    opens a list of entries; tapping one reopens the original video, and a CTA opens Google Maps
    for the top location found, if any.
  • Eye-candy loading animations: the processing screen now cycles through a rotating pool of
    short status lines under the stage label (download, read the screen, ask Gemini, ...) with
    fade/slide transitions, plus supporting motion polish elsewhere in ShareScreen.
  • Docs: README.md "Usage"/"How it works" rewritten for the new retry, multi-location-picker,
    and history flows, plus a prepaid billing setup section for the Gemini API key. agents.md
    module map gains core:history/feature:history rows.

Bugs found and fixed along the way

  • A Koin DataStore<Preferences> qualifier collision: core:settings and core:instagramauth
    both bound an unqualified single<DataStore<Preferences>>, so the second-registered module's
    reads/writes silently went to the wrong file instead of failing loudly. Both (plus the new
    core:history) now use named(...) qualifiers.
  • org.json stub-returns-null under plain-JVM unit tests: Android's android.jar bundles
    non-functional stub JSONObject/JSONArray classes, and under this project's
    isReturnDefaultValues = true setting, calling .toString() on them returns null, which
    Kotlin's null-check then throws on. Fixed for core:history via a real org.json:json test
    dependency (gradle/libs.versions.toml + core/history/build.gradle.kts).
    feature:share/feature:geocoding use org.json too but have no test currently exercising
    that path, so they have the same latent exposure - flagged in agents.md's Testing Standards
    for whoever adds one next.

How to Test

  • ./gradlew ktlintCheck
  • ./gradlew compileDebugKotlin compileDebugUnitTestKotlin
  • ./gradlew test (all green, including new core:history/feature:history suites)
  • ./gradlew koverXmlReport koverHtmlReport
  • Manual: share a video with more than one identifiable place, confirm the results screen lists
    all of them (scrollable) instead of auto-opening Maps; trigger a failure (e.g. airplane mode)
    and confirm Retry re-runs the same video; open History from the icon next to Settings and
    confirm past shares appear, are tappable, and their Maps CTA works.

Checklist

  • ./gradlew ktlintCheck passes (or ktlintFormat was run to fix style)
  • ./gradlew test passes for all affected modules
  • New/changed logic has unit test coverage (domain and data layers especially)
  • agents.md / README.md updated if this changes architecture, setup, or dev workflow
  • No secrets, API keys, or credentials committed

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

Ships a backlog of five related improvements to the share pipeline:

- Retry button: ShareScreen now shows a Retry action on any failure or
  "no location found" outcome, re-running the exact same video via
  ShareViewModel.retry() instead of requiring a fresh share.

- Multi-location results: the Gemini prompt now asks for every place a
  video is actually about, ranked most-to-least likely, instead of a
  single best guess. GeminiLocationRepository/ResolveLocationUseCase
  return List<ResolvedLocation>; the results screen lists every match
  (scrollable) with its own name/address/"Open in Google Maps" CTA and
  no longer auto-opens Maps - the user picks. The result notification
  still deep-links straight to the top-ranked match for the tap-and-go
  case.

- History screen: new core:history (domain/data/di) + feature:history
  (presentation/di) modules, mirroring the core:settings/feature:settings
  split. Every shared link - found, not-found, or failed - is recorded
  (capped at the last 50, newest first) via RecordHistoryEntryUseCase
  from ProcessSharedUrlWorker. A new History icon next to Settings opens
  a list of entries; tapping one reopens the original video, and a CTA
  opens Google Maps for the top location found, if any.

- Eye-candy loading animations: the processing screen now cycles through
  a rotating pool of short status lines under the stage label (download,
  read the screen, ask Gemini, ...) with fade/slide transitions, plus
  supporting motion polish elsewhere in ShareScreen.

- Docs: README "Usage"/"How it works" rewritten for the new retry,
  multi-location-picker, and history flows, plus a prepaid billing setup
  section for the Gemini API key. agents.md module map gains core:history/
  feature:history rows and notes two bugs fixed along the way: a Koin
  DataStore-qualifier collision (core:settings/core:instagramauth DataStore
  singles were unqualified and silently shadowed each other) and an
  org.json stub-returns-null gap under plain-JVM unit tests (fixed for
  core:history via a real org.json:json test dependency; feature:share/
  feature:geocoding have the same latent, currently-untested exposure).

Validated with ktlintCheck, compileDebugKotlin, compileDebugUnitTestKotlin,
test, and koverXmlReport/koverHtmlReport across every module.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@neteinstein
neteinstein merged commit dcaefad into main Jul 21, 2026
4 checks passed
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