Skip to content

Release v1.3.0#233

Merged
psjostrom merged 1 commit into
mainfrom
release/v1.3.0
May 18, 2026
Merged

Release v1.3.0#233
psjostrom merged 1 commit into
mainfrom
release/v1.3.0

Conversation

@psjostrom
Copy link
Copy Markdown
Owner

@psjostrom psjostrom commented May 18, 2026

First stable release of the v1.3.0 line. Five RCs of validation against real-world CGM behavior. Everything since v1.2.0, no functional changes since rc.5.

The fenced ```markdown block below is what CI extracts as the GitHub Release body. The testing plan lives outside the fence so its checkboxes are interactive in this PR.

## Strimma v1.3.0

The headline features: **Workout Mode** (raises alert thresholds + the in-range band while you exercise), **user-controlled data retention** (replaces the silent 30-day prune), **Story month-by-month navigation** (browse any past month, not just last), **pause-all alerts** (one tap to pause Low + High together), and a **configurable foreground-notification action button** (workout toggle, snooze, or none).

Alongside the new features, a stack of reliability fixes targeting CGM edge cases (CamAPS Attempting handling, stale-notification rejection, `notification.when` timestamping) and process-startup robustness (airplane-mode boot, AlertManager init order, SyncOrchestrator off the Main dispatcher).

### Workout Mode

A new mode that raises BG alert thresholds and the in-range band on graphs **while you're exercising**. Defaults: low 6.0, urgent low 5.0, high 14.0, urgent high 16.0 mmol/L (vs. standard 4.0 / 3.0 / 10.0 / 13.0).

The intent is to match how BG actually moves during a run, ride, or workout: sharper drops at the low end mean an earlier low alert gives you time to fuel before going hypo; transient highs from adrenaline / catecholamines at the top mean a wider tolerance avoids false high alerts during normal exercise stress.

- **All four alert categories** (urgent low / low / high / urgent high) AND the in-range band on graphs (BG hero color, widget, web server) use the workout thresholds while on. Predict-low / predict-high also use them.
- **Stale-sensor alerts are suppressed for the first 30 minutes** of a session — sensor contact loss when you start moving is expected. After 30 min they re-arm even while workout mode stays on.
- **Historical analysis is unaffected.** Story / Stats always use your standard thresholds — opening Stats during a workout doesn't corrupt last month's report.
- Toggle from the runner icon at the top-right of the main screen, the **Workout** pill in the BG header, or a **Start workout** / **End workout** action button on the foreground notification.
- Auto-activates while a calendar event in your workout calendar is currently happening; manual OFF during an active calendar event sticks until that event ends.
- Auto-off safety net (1–12 h, default 3 h) for "I forgot to flip it off." Calendar-driven sessions have no timeout — they end when the event ends.
- Configure under **Settings → Exercise → Workout mode**.

See [Workout Mode docs](https://github.com/psjostrom/strimma/blob/main/docs/guide/workout-mode.md) for full details.

### User-controlled data retention

- New **Settings → General → Storage → Data retention** dropdown lets you choose how long Strimma keeps glucose, treatments, and exercise sessions on your device. Options: 3 months / 6 months / 1 year / 5 years / Forever (default).
- Replaces the old hidden 30-day reading prune that was silently deleting the first ~10 days of each month at month-end (visible in the Story view).
- Picking a shorter window asks for confirmation before deleting — Nightscout, your CGM app, and Health Connect are never touched.
- Changes apply within minutes, not 24 hours.

### Story month-by-month navigation

- Tap the ← / → arrows in the top-right of the Story screen to browse any past month with enough data, not just last month.
- Bounded by the earliest reading on your device on one end and the last completed month on the other; backfilling history from Nightscout (Settings → Sharing → Pull readings) unlocks earlier months automatically.
- Arrows visibly grey out at the data boundaries (no silent no-op clicks).
- The "Your April Story is ready" snackbar no longer re-fires after restart if you've already viewed April but tapped ← to browse March or earlier.
- Monthly story card persists in Stats in a muted style after viewing, so the story can be revisited.

### Pause All alerts

- New **All alerts** row at the top of the pause sheet — one tap pauses Low and High together with the same five duration chips (30m / 1h / 1.5h / 2h / 3h).
- When both categories share the same expiry, the BG header collapses to a single coral **All alerts paused · X** pill instead of two redundant pills.
- The pause-alerts bell icon in the header dims the moment any pause expires, including unified pauses.

### Configurable notification action button

The foreground notification's tap-target action used to be hardcoded to the workout toggle. Now configurable under **Settings → Notifications → Action Button**:

- **None** — no button shown
- **Workout** (default — preserves existing behaviour) — toggles workout mode on/off
- **Snooze** — pauses alerts for a chosen category (**All** / **High** / **Low**) and duration (15m / 30m / 1h / 2h / 3h). Button label reflects the choice (e.g. "Snooze all 1h").

The notification rebuilds the moment you change the setting (no longer waits for the next CGM reading). When alerts are paused — via the in-app sheet or the new Snooze button — the foreground notification's subtitle shows e.g. "All alerts paused 47m" / "High alerts paused 2h" / "Low alerts paused 15m" so confirmation is in-context.

### Reliability fixes

#### CGM ingestion correctness

- **Stale CGM notifications dropped at the parser layer.** When CamAPS FX loses sensor connection it switches its persistent notification from `"On"` to `"Attempting"` and reposts the last known glucose value every minute. Strimma now drops these reposts at the parser. (Late fix: rc.5 narrowed this so genuine fresh BG that arrives during pump-only "Attempting" — pump Bluetooth off but sensor still delivering — is no longer wrongly rejected.)
- **Reading timestamps bind to `notification.when`** instead of `currentTimeMillis()` at parse time. A notification rebind (settings change in the source app, OS reposting on theme switch) no longer re-stamps an old reading.

#### Foreground notification + widget freshness

- **"Xm" since-text advances every minute** on both the foreground notification and the home-screen widget. Previously they could sit at "0m" indefinitely between readings — most visible during a CamAPS disconnect.
- Workout-mode elapsed counter, IOB countdown, and alert-pause countdown all tick every minute on the foreground notification.

#### Process robustness

- **No more crash on boot in airplane mode.**
- **AlertManager init order fixed** (regression fix from the pause-all work).
- **SyncOrchestrator moved off `Dispatchers.Main`** onto a dedicated IO scope — eliminates UI jank during background follower / Tidepool sync.

#### Push behaviour

- Stale unpushed glucose readings can no longer block fresh BG from reaching Nightscout — newest data always pushes first.
- Treatments and readings tables are now indexed (`createdAt`, `pushed`) so reads stay fast as history grows.
- Treatment manual-pull options updated to 30 / 90 / 365 days (was 30 / 60 / 90).

### Under the hood

- Room schema 4 → 5 with auto-migration (existing data is preserved).
- Retention loop survives transient DataStore errors and reacts immediately to setting changes.
- Story screen survives process death — you land on the same month after Android kills the app.
- Settings backup now round-trips the notification action button config (action type, snooze category, snooze duration).
- Dependency updates (Compose BOM, Kotlin, AGP, KSP, Ktor, Navigation minor/patch bumps; gradle-wrapper).

### Requirements

- Android 13+ (API 33)
- A glucose data source (CGM app, LibreLinkUp, or Nightscout server)

Test plan

No code change vs. rc.5 — all functional verification was completed across rc.1–rc.5.

  • After merge: tag v1.3.0 and push — CI builds the APK and creates the GitHub Release using the fenced block above.

Docs check

  • docs/guide/workout-mode.md, docs/guide/exercise.md, docs/guide/notifications.md, docs/guide/main-screen.md, docs/guide/settings.md, docs/guide/story.md, docs/guide/alerts.md — all already updated in feature PRs.
  • settings.md self-flags a missing Storage screenshot.
  • Potentially stale screenshots (last touched March 23 — predate workout pill, runner icon, all-alerts pill, action-button toggle):
    • screenshots/main-screen.png — workout pill + workout-mode icon + all-alerts pill not visible
    • screenshots/notification-collapsed.png and notification-expanded.png — action button changes not reflected

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@psjostrom psjostrom merged commit 02d92c4 into main May 18, 2026
1 check passed
@psjostrom psjostrom deleted the release/v1.3.0 branch May 18, 2026 08:08
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