Skip to content

Sleep and nap edits, and workouts first release - #21

Open
sayed0am wants to merge 72 commits into
mainfrom
develop
Open

sayed0am wants to merge 72 commits into
mainfrom
develop

Conversation

@sayed0am

Copy link
Copy Markdown
Owner

Two features, built on their own branches and merged here.

Sleep and nap edits

Spec: docs/design/sleep-edit/spec.md

  • Adjust times and Delete on the main sleep and on naps, from one sheet: two time boxes with the chosen span shaded on the heart rate.
  • Delete has Undo, Restore, and Deleted sleep under You, Your data. Deleted sleep is removed for good after 7 days, and a marker keeps a resync from bringing it back.
  • A move under 15 minutes keeps the strap's score. A bigger move adjusts it from OpenStrap's own model.
  • Every reader of sleep goes through SleepSource, so the Sleep tab, Today, Recovery, the widgets, Healthspan and Health Connect show the same totals.
  • A hint on naps whose heart rate stayed as when sitting still.

Workouts, first release

Spec: docs/design/workouts/spec.md

  • Choose and a new Ready screen, filled from last time.
  • Live screens per kind (run, indoor, strength, intervals, mind and body, games), Paused, and one glance for Today and the floating bar.
  • Strength sets, rest and an optional log. HIIT presets, run reps, saved workouts and named buzzes.
  • Summaries per kind, and past phone workouts open as summaries.
  • Weekly goal, personal bests, badges and celebrations. Only workouts of 10 minutes or more earn badges and count toward the goal.

Database

  • 24 to 25: nap_edit becomes sleep_edit (auto migration, SleepEditMigration).
  • 25 to 26: the workouts tables and columns (WorkoutsMigration).
  • Both migration tests open a version 24 database and go to 26.

Also

  • -PdevApp builds a debug app as org.openstrap.app.dev, named with its version ("OpenStrap 2.3"), so it installs beside the release.

Tested

  • Unit tests pass.
  • On the phone, in the demo app: sleep adjust, delete, Undo, Restore and Deleted sleep. Workouts: Choose, Ready, the live screens, Paused, summaries, past workouts, goals, bests and badges.
  • Not tested yet: anything that needs the strap (heart rate, buzzes) or GPS on a real workout.

🤖 Generated with Claude Code

sayed0am and others added 30 commits October 30, 2026 23:05
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GlowWorkoutMode.kt keeps what all the workout pages share. Choose a sport,
Ready, the capsule and each live part move to their own files, the live ones
under ui/glow/live. LiveFrame holds the live screen's top bar, the notes any
workout may need and the controls row, so each family's screen only draws its
middle. Nothing changes on screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nap_edit becomes sleep_edit (Room 25, SleepEditMigration renames it and marks every row a nap, edited now): the
user's times for a main sleep or a nap, or its delete, keyed by the strap's start. NapTimes becomes SleepEdits, one
pure object for both kinds: resolve matches an edit by the exact start, else one of the same kind within 15
minutes, apply drops deleted sessions and moves edited ones, problem has main sleep's lengths and the overlap check,
and a move under 15 minutes in all keeps the strap's score. Naps work as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SleepSource reads the strap's sessions through the user's edits: deleted ones left out, moved ones at the user's
times with their stages clipped and their totals worked out again, the window taken on the end as shown. The
repository, Recovery, Healthspan, Health Connect, the Sleep and Moment widgets, the widgets' moment and the workout
suggestions all read it, so they count the same sleep. Healthspan's cache key changes with any edit. The backup
gets sleep_edit.csv, and SleepReadersTest keeps the DAO's sleep reads to the source, the sync and the backup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every sport now maps to a family (Workouts.family), kept internal. Ready
opens on what was set the last time the sport started, saved per sport, and
has one frame for all: the live heart rate large, one status line saying
what the strap or GPS will do, and the sport's one choice. Goal chips learn
the two goals used most, with More for the rest, and distance goals are new
(halfway and goal buzzes). Strength gets its plan with sets and rest
steppers.

Choose is the new first screen from All sports and Other sport: your usual
with Start inside it, which skips Ready, two recent sports, and All sports
for the picker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Sleep score detail gets Adjust times under its figures, as each nap has. NapTimesSheet becomes SleepTimesSheet:
Sleep times or Nap times, the heart rate from two hours either side with the chosen span shaded and its edges
drawn, the result line by kind, and the overlap check against the day's other sleep and naps. Use the strap's
times is a PageButton with an icon. Once moved, a note says the times are yours, the hypnogram shows the strap's
night with what's outside dimmed, and the score's info sheet says when the score is worked out from your times. An
edit writes the night to Health Connect again right away while auto sync is on. Nap rows read 14:05 to 14:47.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Delete sits beside Adjust times on the main sleep and each nap, in the warning colour. It asks once, then a
snackbar offers Undo for 8 seconds. A deleted night shows No score and a No sleep recorded card with the times and
Restore, and its day loses its dot. You, Data gets a Deleted sleep row while there's something in it, opening a
page with each night or nap, its times, the days left and Restore. After every sync, deletes older than 7 days
take their session and stages for good and leave a marker edit without times, so a resync stays out. A delete
keeps the user's times, so Undo and Restore bring back exactly what was there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… be one

When a nap's average heart rate is within 5 bpm of the hour before it and it has no deep sleep, a line under its
title says so. The buttons are the same, and nothing is removed by itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… bar

A GPS distance workout gets two views under the moving time: Pace, with the
pace large, a bar per kilometre and the heart rate on a strip in its zone,
then distance, climb and kcal, and Map. Indoor cardio, and a distance sport
without GPS, gets the heart card with time in each zone. Both pause into the
Paused view, where End workout still takes a hold. Other sports keep the
screen they had.

LiveGlance is worked out off the screen from the recording and feeds both
the Today hero and the floating bar, so they never disagree. The bar now
shows the next action for the moment (Pause, Resume, Keep going and End)
and a goal's progress, and stays away while the Today hero is on screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…elease

Database version 25 in one named migration (WorkoutsMigration, not an auto
migration, so it can be renumbered at merge): a workout's structure, a set's
exercise, reps and weight, and tables for rounds, saved workouts, the
exercise list, personal bests, badges and weekly results. Schema exported,
and every migration test now opens with it.

Strength gets its own live screen: the set's clock with Set done, then rest
counting down in green with the heart line falling to the level that ends it
sooner, +30 s and Start set N. With Log reps and weight on (a switch on
Ready), a card after each set fills reps and kg from the last set of that
exercise. Exercises are picked once from yours and a short list of common
lifts, or typed. The bar and the Today hero show Set done, the rest left,
Start set N and +30 s. Sets export with their log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A structured workout's rounds run on a small state machine (Phases), pure
and tested, whose state is the rounds recorded so far, so a workout picked
up after the process died carries on. It ticks once a second with the
screen off, by the clock, by the distance for run reps, and on taps, and
leaves paused time out.

HIIT's Ready has Tabata, 40 / 20, Every minute and Free, with Warm up first.
Its live screen counts each work and rest down in work red and rest green,
with Skip, +10 s and each round's peak. A run can be reps of a distance or
a time from More, and saved by name: the newest saved one shows on Choose.
The bar and the Today hero show work, rest, Skip rest and Start rounds.

Every workout buzz now goes through WorkoutBuzz (two short for work, one
short for rest, one long for halfway, three short for the goal and the
end). The phone beeps the last three seconds of a timed phase when its
ringer is on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A night moved 15 minutes or more took OpenStrap's own score outright, so cutting 35 minutes from the start of a
night the strap scored 83 showed 90. Now the strap's score is the anchor: it moves by what OpenStrap's own model
says the new times change (own score of the user's span less own score of the strap's span), 0 to 100, and a
shorter night never scores above the strap's, nor a longer one below it. The info sheet says "The strap's score,
adjusted for your times." Spec section 5 updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…left there

The delete sheet said You, Data, but the You page's section is Your data, so the sheet, the spec and the code's
comments now say You, Your data, Deleted sleep. Restoring the last entry on the Deleted sleep page left an empty
panel: the page now stays open and says "Nothing deleted in the last 7 days." with no panel and no footnote.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd loses its dot

After deleting last night, the Sleep tab's hero, Today's morning hero, the Recovery hero, the Sleep widget and the
Moment widget asked "Was the strap on?". A night the user deleted now reads "You deleted last night's sleep."
(Recovery: "..., so there's no score today."), the Sleep hero has a Restore button, and the Sleep widget no
longer shows yesterday's night in its place. The sleep strip on the Sleep score and Regularity details takes the
day shown from its own night, so no dot stands beside a deleted one. DeletedNightStateTest runs the day's state
through a delete and a restore.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mind and body gets a dark live screen: the time against its length and a
soft heart line settling, dimming to near black after ten seconds and
lighting on a touch, which does nothing else. Its strap stays quiet, no
halfway or zone cues, and buzzes once, softly, when the length is over.
The bar is smaller and unlit.

Games get Free play, Halves or Quarters on Ready, with length and break
steppers and no label. Their periods run on the same rounds as intervals,
so the strap buzzes long at the end of each period and twice when the break
is over, with the screen off. The live screen shows the period and its
time, the heart rate, an effort bar from the time in zones, peak bpm and
hard efforts, and Half time. The bar and the hero follow the period.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the sleep colour, as drawn

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The summary leads with the sport and when, then a hero with the one number
that matters: km for a run, average bpm indoors, kg lifted (or sets without
a log) for strength, rounds for intervals, minutes for yoga and a game. Under
it each kind's own section: the route with its climb and splits with the
fastest marked, time in zones and the heart rate line with last time, sets per
exercise with peaks and how fast rest brought the heart rate down, each
round's peak and drop, how the heart settled with this week's days, and a
game's periods with one line on how it went. What it earned follows, then the
heart rate drop and Load. Share waits for the share screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rewards are worked out from the workouts and days alone, so they are rebuilt
on a new workout, a trim or a delete and earned for past history on first
launch: the weekly goal (3 a week by default, workouts of 10 minutes or more
you started, two a day at most, weeks from the locale's first day, past weeks
keeping their goal), weeks in a row, personal bests (a run's fastest 1 km,
5 km, 10 km and half from GPS only, the longest run and workout, the heaviest
set per exercise, the most steps in a day) and 24 badges, never taken back.
A run keeps its fastest stretches when it ends, kept route or not.

The summary lists what the workout earned with the weekly goal last. Done
goes through a full screen card for a personal best, then the goal moment
once a week. Goals and bests from You shows this week, the bests, the badges
with the next to earn, All badges and last week's recap; a Monday morning
notification opens the recap. Both celebrations turn off in one sheet. The
badges past history earned show once, on one screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mmaries

A summary whose own number is missing (an indoor workout with no heart
rate, strength with no sets, intervals with no rounds) leads with the
minutes instead, and a missing figure shows the waiting dash, never None.

Firsts and workout counts are earned only by workouts that count toward the
weekly goal, so a one minute mis-tap earns nothing; distance and steps still
add up. The first weekly goal badge shows the goal it was met at. The
longest workout reads as a duration.

A past phone workout opens as its summary did, per kind, with a back arrow
and without Done or Earned, keeping what its page had: the heart rate line
with the drop, the facts and map, In your day, Load with its (i), zones and
laps, Trim and Delete. The strap's own workouts keep their page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ut heart rate, Load lit from the left

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sleep edits keep database 25. Workouts move to 25 to 26 (WorkoutsMigration), with the 26 schema exported. The sleep
edit migration test now opens with every migration.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s version

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Your usual as a slim row with Start, the search over every sport, Recent
as chips with saved workouts among them, then the sport tiles and More
sports. Activity's All sports and the Start widget's both open it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sayed0am and others added 5 commits November 1, 2026 14:30
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The live page follows the RunIntervals board: the plan and a bar of the reps,
the metres to go large with the rep's pace, the rest's seconds, and each rep's
time. Skip shows a skip icon. A summary with no heart rate shows each rep's
time instead of an empty card.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The weekly recap gets Share week beside Next week: a story card with the
count in dots, the day dots, hours, distance and kcal with icons, and the
streak and a best. The share screen hides the tab bar, and the photo
button sits right under the card. Search on Choose opens its own page with
a count and a list, names starting with what's typed first. Goals and
bests shows the week as a bar of the goal's workouts and the badges as a
row of rings. Day dots use the plain tick.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Workouts to the canvas: Ready, live screens, summaries, sharing, search and rewards
- One sleep read for the night and the strip of nights, so a delete or a
  restore changes both in the same state (DeletedNightStateTest on CI)
- Mind and body: a paused quiet screen shows Resume, not a dead Pause
- Backup: badges, past weeks, saved workouts, exercises and rounds
- Personal bests: a lift typed in another case still beats its best
- Game summary: periods named from how the game was set up
- Sleep edits: resolved among neighbouring sessions, so editing one nap
  can't overwrite the next one's edit
- Times sheet: checks overlaps against every sleep around the day
- Zone ranges read again after the zones are moved
- Start on your usual: no kcal goal Ready wouldn't offer

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sayed0am and others added 20 commits November 1, 2026 16:55
Speed: cache the smoothed route and the rep metres, read the pulse dot
scale and IME inset off composition, keep live controls stable, key the
map's zone colours on coarse sizes, binary search the strength peak,
read each night's stages once in RecoveryEngine, and let RewardsKeeper
keep its days between refreshes and write only what changed.

Duplication: one bucketMeans and evenly for chart lines, one zoneLine,
one max heart rate window, one tested max range, badge thresholds read
from BADGES, the share card's heart line from FamilySummary, rep names
from StartCopy.repParts, a pace field on the summary hero instead of a
label lookup, the Health Connect sleep export in one place, and the
repeated surface colours pointed at their shared tokens.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Workouts synced while the app was closed never reached week_result, so the
recap went out with old numbers and was then marked sent. RewardsKeeper now
has refreshNow, which builds the merged workout list once and refreshes with
the stored weekly goal, and WeeklyRecap.check runs it first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Half open on a fold, the live screen used to fall back to the old
shared screen, so HIIT and run reps lost Skip and +10 s, games lost
Half time and strength showed the old sets panel. Every kind now keeps
its own screen and controls. Games and indoor leave the heart rate to
the other half, where the glance shows it. The old screen, its sets
panel, map page and side figures are removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s page

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d facts, live clock

The recap's rewards refresh reads the shared max heart rate too, and
the indoor screen keeps its split view zone bar with the ticking time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On the unfolded phone the glow's radius, 90% of the width, was taller
than its 420 dp box, so it ended in a straight line across the page.
The radius is now capped at the box height. Phones look the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the two-column width, the rest of the sports, A to Z, sit in a
column of their own beside the tiles, each side scrolling by itself,
so none waits behind More sports. Folded it's the same as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On a phone it's still your three most used and All sports. Wider, as
many tiles as fit at a phone's spacing: your other sports, then the
everyday ones, one tile per sport whichever kind.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Opening or closing a detail beside the tab on an unfolded phone
rebuilds and resizes the cards. Until a card's glow for its new size
was drawn, it showed the plain body colour, a flat green flash on
Steps. Now it keeps its last glow, or the last one drawn for that look
at any size, stretched to fit until its own is ready, and the cache
holds 16 instead of 10 so the sizes in use stay in it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…screen

The pace page's strip and the map's chip were the same pill at two
heights, now LitHeartPill. Every live screen says Paused, Waiting for
the strap or Waiting for heart rate through WorkoutCopy.noHeartRate,
where some said No heart rate yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It kept its own typing state, focus tracking and tap target, the same
as TypedValue's. Time keeps its own: one figure of hours moves on to
the minutes by itself, which TypedValue doesn't do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RoundIcon takes a size, surface and ink, so Ready's 52 dp steppers, the
live minimize buttons and the map's buttons use it. MinusPlus is the
stepper for Ready's goals and the strength log card. Ten list rows draw
their divider with Modifier.topHairline, and five copies of the HH:mm
clock are one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A run with GPS fixes all in one spot drew a map zoomed out to the
world. Route.mappable needs the fixes to spread 25 m, and the summary
card, the past workout page and the share card use it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Leftovers from earlier designs that no screen calls any more: the old
Panel and PanelHeader, chart and glow helpers, the personal best line,
the saved title, Ready's target hint and strength steppers, the step
divergence check, and others, with the tests that only covered them.
The layout helpers tests use to check widget and grid geometry stay.

The past workout page's map check now uses Route.mappable too, and
the needless !!, ?. and else that the compiler warned about are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Past the PastSummary return, GlowWorkoutScreen only ever shows a
strap workout, so its phone branches are gone. LiveMapScreen always
sits under the shared bottom bar, so its own dots, controls and notes
are gone and bottomRoom is required.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sayed0am and others added 3 commits November 1, 2026 21:07
Stood like a laptop, the half under the fold is about 355 dp high and
the live screens kept their full layouts, so they overflowed: HIIT's
seconds sat on the buttons, the run's pace and distance were squeezed
away, strength and yoga lost their controls off the bottom, and games
lost the controls' labels.

Below 480 dp the screens are now compact: the total small on top,
HIIT's phase, seconds and +10 s on one row, the run's distance, pace
and kcal in one row, strength's set or rest as one row with its clock,
and yoga's time without the ring. With the heart rate on the other
half, the map and yoga leave out their own. Checked on the Fold with
a HIIT, run, strength, basketball, cross-training and yoga.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed pill

Stood like a book, the heart card takes a whole half of the screen,
and the level's fixed 22 dp fade turned into a hard line across it.
The fade is now at least 8% of the card's length, so it stays soft;
phone-sized cards keep 22 dp. The run's pace page leaves out its heart
pill when the heart card is beside it, as the map already did.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fix the develop review: CI race, bugs, split view, speed and cleanup
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