feat(record): settle before the first episode, and clarify the recording screen - #106
Conversation
045b897 to
27e825f
Compare
f3eec6a to
84c3b18
Compare
nicolas-rabault
left a comment
There was a problem hiding this comment.
Thanks for the contribution! The recording transition checks passed. Please address the startup exit issue before merging; details inline.
| <p className="mt-4 text-sm text-red-400">{startupError}</p> | ||
| )} | ||
| <Button | ||
| onClick={() => navigate("/")} |
There was a problem hiding this comment.
[P2] Stop the session before leaving the startup screen. If /start-recording succeeds but /recording-status fails, this button navigates home without sending /stop-recording. Unmounting only cancels polling, so the recording worker keeps driving the arm and cycling through takes without its recording controls. The same race exists if the start request is still pending when the button is clicked. Make this exit cancel the session, including a late successful start response, and retain a way to stop it if cancellation fails.
There was a problem hiding this comment.
This should be fixed by the last commit, testing this afternoon
nicolas-rabault
left a comment
There was a problem hiding this comment.
Thanks for the contribution! The recording transition checks passed. Please address the startup exit issue before merging; details inline.
84c3b18 to
fc82f52
Compare
…ing screen Recording jumped straight from *preparing* into writing frames, so the first seconds of episode 1 caught the arm still being moved into position. Every later episode already gets that grace period: the reset phase between episodes runs the control loop with no dataset, so the arm keeps following the leader while nothing is recorded. The first episode simply never had one. It does now — same phase, same reset_time_s, same orange in the UI, same exit-early control to skip it. No new setting: a second duration for what is mechanically the same phase would only mean two orange stretches back to back between episodes. The loop called record_loop in four places with the same eight arguments each time, differing only in `dataset` and `control_time_s`. `loop_kwargs` collects the shared part once; each call site keeps the real `record_loop(**loop_kwargs, ...)` call and states just what differs. (Deliberately not functools.partial: that would leave exactly one `record_loop(` in the file and make the four real call sites ungreppable by name.) The recording screen itself: - episode counter is a boxed chip instead of small gray text - phase limit reads at a glance next to the elapsed time (00:12 / 00:30), with a caption naming what is being timed, so it isn't confused with the session clock - re-record is a real button next to the primary action (DEL or left arrow) rather than a row in the overflow menu - the startup screen says which half of the handshake is stuck instead of spinning "Connecting..." with no way back Both "Back to Home" exits now stop the session instead of abandoning it: the startup screen's (if /start-recording already succeeded, or succeeds after the click while it was still in flight) and the main screen's (once a session is confirmed live). Either fires /stop-recording before navigating; a failed stop keeps the user on the screen with a retry rather than navigating home and losing the only control that could shut down a worker thread left driving the arm unattended. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
fc82f52 to
b24e75d
Compare
What
Recording jumped straight from preparing into writing frames, so the first seconds of episode 1 caught the arm still being moved into position.
Every later episode already gets that grace period: the reset phase between episodes runs the control loop with no dataset, so the arm keeps following the leader while nothing is recorded. The first episode simply never had one. It does now — same phase, same
reset_time_s, same orange in the UI, same exit-early control to skip it.No new setting on purpose: a second duration for what is mechanically the same phase would only mean two orange stretches back to back between episodes.
Cleanup
The loop called
record_loopin four places with the same eight arguments each time, differing only indatasetandcontrol_time_s.loop_kwargscollects the shared part once; each call site keeps the realrecord_loop(**loop_kwargs, ...)call and states just what differs. (Deliberately notfunctools.partial: that would leave exactly onerecord_loop(in the file and make the four real call sites ungreppable by name.)Recording screen
00:12 / 00:30), with a caption naming what is being timed, so it isn't confused with the session clockFix (review feedback)
Both "Back to Home" exits used to navigate away unconditionally, leaving an active session's worker thread driving the arm with no UI attached to it:
/start-recordinghad already succeeded — or succeeded after the click while still in flight — leaving abandoned it. Fixed by resolving "was a session started, and is it stopped?" before navigating; a still-pending start's own continuation fires the stop once it resolves./stop-recordingfirst.Either way, a failed stop keeps the user on the screen with a retry instead of navigating home and losing the only control that could shut it down.
Notes
frontend/dist/rebuilt with Node 22, as the Quality workflow requires.🤖 Generated with Claude Code