Commit graph

5 commits

Author SHA1 Message Date
ad55559f55 v0.5.0: persistent parking notification — foreground service, End/Extend
All checks were successful
build-apk / build (push) Successful in 28m55s
The ongoing countdown now appears whenever a car is parked, paid or free,
and sticks around the way ntfy's does on GrapheneOS.

Why it wasn't showing at all on a paid park: StartSessionScreen carried its
own stricter copy of parseApiTime that demanded MM-DD-YYYY + AM/PM. The
dual-format fix from deb78bf only landed in sessionStatus.ts, so when the
API returned the other format the parser returned null and the notification
was simply never posted. There is now one parser (api/parseTime.ts), and the
failure logs instead of going silent.

Persistence: a plain notify() was never enough — Android 14+ lets the user
swipe an ongoing notification away, and nothing brought it back after a
reboot. BbpSessionService is a real foreground service (type specialUse) that
owns the notification, plus a BOOT_COMPLETED receiver to restore it; specialUse
is one of the types Android 14/15 still allow to start from BOOT_COMPLETED.
The service's life is exactly the session's life: it stops itself, removing
the notification, on End, at expiry, or when there's no session to show.

Buttons: paid sessions previously got no actions at all (only free check-ins
did). Both now get End and Extend/Pay. End stops tracking — honest about the
fact that ParkSmarter has no stop-session endpoint, so bought time keeps
running at the meter. Extend opens the purchase screen for that exact zone.

The active session (with its Zone) is persisted locally, so the countdown and
Extend survive reboot, offline, and Anonymous Mode instead of depending on a
round-trip. sessionStatus.ts + features/checkin collapse into one owner,
features/session/activeParking — one record, one notification.

Verified: :bbp-notify:compileDebugKotlin passes, and the merged app manifest
carries the service (specialUse + FGS subtype property), both receivers, and
the FOREGROUND_SERVICE/SPECIAL_USE/RECEIVE_BOOT_COMPLETED permissions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 20:10:54 +00:00
463facbe5a v0.3.0: local free check-in with actionable countdown notification (Phase C)
All checks were successful
build-apk / build (push) Successful in 40m22s
For a zone labeled free_2h/3h/4h, "Check in (free · Xh)" starts a local, API-free
countdown to the free limit — no ParkSmarter call. The bbp-notify module gains a
showCheckin() that posts the ticking chronometer with "End" / "Pay" buttons, a
BbpActionReceiver (declared in the module's new AndroidManifest.xml) that records
the tap in SharedPreferences and, for Pay, relaunches the app; consumePendingAction()
is drained on foreground by useCheckinSync() — End clears the check-in, Pay hands
off to StartSession for the stored zone. A pre-expiry alert reuses the existing
reminder lead-minutes. Starting a paid session supersedes an active check-in.

Also: MeterDetail shows the free/pay-immediate label and (admins) labeling chips.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-24 18:23:58 +00:00
2b973348bc v0.2.4: fix countdown notification not appearing + wrong time-remaining
All checks were successful
build-apk / build (push) Successful in 28m23s
Countdown notification "nothing appears" on session start:
- The small icon was the adaptive launcher mipmap (applicationInfo.icon),
  which Android 13+/GrapheneOS rejects as an invalid notification small icon
  and drops the post silently. Ship a proper white-on-transparent vector
  small icon (bbp_stat_parking) inside the module and use it.
- showCountdown now returns a diagnostic string (posted / notifications
  disabled / exception) instead of swallowing failures; JS logs the branch,
  permission result, and native outcome to the in-app diagnostics log.
- Log the raw active-session payload in refreshSessionStatus (element shape
  was previously unconfirmed).

Time remaining showed "7694 min":
- API's TimeRemaining is SECONDS, not minutes. Format it as hours+minutes
  in SessionDetail; annotate the type.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 21:55:45 +00:00
9323bbd6c6 chore: untrack + gitignore local module gradle build output
All checks were successful
build-apk / build (push) Successful in 10m58s
Accidentally committed modules/bbp-notify/android/build/ from a local compile
check; remove it and ignore it going forward.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 21:05:09 -07:00
d0f31d5278 v0.2.3: true ticking countdown via a tiny native module (no deps)
Some checks failed
build-apk / build (push) Has been cancelled
Replaces the static status notification with a native Android chronometer that
counts DOWN to the session end — the system ticks it every second with zero app
CPU/battery, visible without opening the app.

- modules/bbp-notify: a ~50-line local Expo module using only NotificationCompat
  (setWhen + setUsesChronometer + setChronometerCountDown + ongoing). Zero
  third-party dependencies, no Firebase — fits the de-Googled ethos. Verified:
  autolinks + Kotlin compiles.
- sessionStatus.ts uses it when present, else falls back to the expo-notifications
  static expiry-time notification.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 21:03:53 -07:00