Android: Missing Backend for Rhythm Screen - #2381
Conversation
|
Reviewed at 17c6ad5. The diagnosis is right and the screen genuinely was dead: hardcoded I would hold it on one thing: the read path does not do what it says it does, and the plumbing it needs already exists. The twins are already thereSwift's
This uses Which makes the new resolver unnecessary
Swapping to the union functions makes all of that moot, because So the change I would ask for is small and subtractive: drop On testsUnlike your Deep Timeline fix, this one is testable and I would ask for it. If the union functions replace the resolver then there may be nothing new left to test, which is the better outcome of the two. Not blockingThe screenshot is a good inclusion, and "tested on a real Android device using real life data" is the right claim to make for a screen with no test harness. The feature is wanted and the UI half is right; it is the read path that wants the existing plumbing rather than new plumbing. |
|
Thanks for the improvements! I had some troubles getting the sleep sessions detected. |
|
It still works with live data from last night on a real Android phone. |
The Rhythm screen was fully implemented but showed no data because it
was hardcoded with empty inputs (night = null, windows = emptyList()).
This commit adds the missing data-loading layer (RhythmRoute) that
mirrors macOS RhythmHost.load():
- Add anyRegisteredWhoopId() to WhoopRepository to load data from any
registered WHOOP device, not just the currently active one. This
allows Rhythm to work offline with historical data.
- Use sleepSessionsMerged() to search across both imported (raw) and
computed ("-noop") sleep sessions, matching Swift allSleepSessions()
which reads from both namespaces.
- Select the most recent session via maxByOrNull { it.endTs } instead
of lastOrNull(), ensuring we load the actual most recent sleep data
rather than the last item in an unsorted list.
- Window the night into 5-minute slices, gate each on stillness, and
run the pure RhythmScreener engine over each window.
- Use 14-day lookback window to match iOS allSleepSessions(days: 14).
Rhythm now displays data when sleep sessions exist in the database,
even when no strap is currently connected.
What this PR does
The Rhythm screen was fully implemented but showed no data because it was hardcoded with empty inputs (night = null, windows = emptyList()).
This commit adds the missing data-loading layer (RhythmRoute) that mirrors macOS RhythmHost.load():
Add anyRegisteredWhoopId() to WhoopRepository to load data from any registered WHOOP device, not just the currently active one. This allows Rhythm to work offline with historical data.
Use sleepSessionsMerged() to search across both imported (raw) and computed ("-noop") sleep sessions, matching Swift allSleepSessions() which reads from both namespaces.
Select the most recent session via maxByOrNull { it.endTs } instead of lastOrNull(), ensuring we load the actual most recent sleep data rather than the last item in an unsorted list.
Window the night into 5-minute slices, gate each on stillness, and run the pure RhythmScreener engine over each window.
Use 14-day lookback window to match iOS allSleepSessions(days: 14).
Rhythm now displays data when sleep sessions exist in the database, even when no strap is currently connected as shown below.
Type of change
How it was tested
It was tested on a real Android device using real life data.
Checklist
swift testinPackages/<name>)android/(./gradlew testFullDebugUnitTest)StrandDesigntokens — no hardcoded colors, fonts, or spacingdocs/CONTRIBUTING.mdStrand.xcodeproj/) or any secrets/keystoresRelated issues
Addresses #2380