Repository navigation
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Paste remains available during replacement-audio loading and can discard the incoming audio.
1 open finding
What changed in this PR
Updates waveform editing controls so cut, copy, and paste respect selection and busy states.
Changes:
- Tracks region selection and active paste operations.
- Disables editing during playback, saving, or duplicate paste attempts.
- Adds hotkey and button-state tests.
| File | Description |
|---|---|
web/src/components/WSAudioPlayer.tsx |
Updates waveform edit guards and control states. |
web/src/components/WSAudioPlayer.hotkeys.test.tsx |
Tests selection, loading, playback, saving, and repeated paste behavior. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
gtryus
left a comment
There was a problem hiding this comment.
I reviewed the four commits that touch just WSAudioPlayer.tsx and its hotkey test.
- The
hasRegion→regionCountrename is cosmetic.
Smaller points, in the spirit of the article
-
regionSelectedduplicates existing state.regionSelectedRef.currentalways equalscurrentSegmentRef.current !== undefined, except right after the blob-reset effect, which clears one but not the other. The article's "avoid redundant state" idea applies here. You could clearcurrentSegmentRefin the reset and have the handlers readcurrentSegmentRef.currentdirectly. You would then need only theregionSelectedstate, which the render uses, and not the extra ref. As written, the two values can disagree after a blob change. -
The new line in the blob effect is acceptable.
setRegionSelected(false)is the article's "adjusting state when a prop changes" pattern. Here it sits inside an effect that already syncs with an external system (wsLoad/wsClear), so it adds no extra render pass. If wavesurfer already sendsonCurrentSegment(undefined)when it loads or clears, the line is redundant, but I didn't check whether it does. -
The enable rules are written twice and no longer match. This is the biggest practical issue. It isn't an effect problem, but it is the article's "compute it once during render" point:
Hotkey handler checks Button disabledchecksCut readyRef,regionSelectedRefregionSelected(no ready check)Copy regionSelectedRef(no ready check)regionSelectedPaste readyRef,wsHasClipboard(),playingRef,mediaSaveInProgress,pasteBusyRefplaying,mediaSaveInProgress,pasteBusy, withcanPastehiding the button; no ready checkFor example, one commit blocks pasting by hotkey while the player isn't ready, but the Paste button stays enabled during that time. Clicking it does nothing, because
handlePastereturns early. A fix would be to computecanCut,canCopyandcanPasteonce per render, use them fordisabled, and have the handlers read the same values, either through a ref updated during render or by passingreadyinto the handler's dependencies. -
The state-plus-ref pairs are justified.
regionSelected/regionSelectedRefandpasteBusy/pasteBusyRefeach have a combined setter. The state drives rendering and the ref lets hotkey callbacks stay stable. That matches existing code likesetReady, so it's consistent, even though the article would prefer reading state directly.
Bottom line
The branch adds no effects and puts the new state changes in handlers, as the article advises. The one change worth making before merging is item 3: compute each button's enabled state once so the buttons and hotkeys agree. Item 1 is an optional cleanup.
| const [regionSelected, setRegionSelectedx] = useState(false); | ||
| const regionSelectedRef = useRef(false); | ||
| const [pasteBusy, setPasteBusyx] = useState(false); | ||
| const pasteBusyRef = useRef(false); |
There was a problem hiding this comment.
@sarahentzel were these the kinds of changes we talked about changing?
There was a problem hiding this comment.
only if the state variables are unnecessary and could be computed on the fly
check connected for ai
currentSegment needed state as well as ref to update UI handle or ignore errors from handleChanged
|
Both reviews are done. The two that matter most: Save stays enabled after a failed edit, and the selection-reset code writes a ref during render again. I checked both in the source. StandardsThe localization part follows Hard violation
Likely bugs
Judgement calls
SpecThere is no issue or spec file, so this review checked the code against the three intents in the commit message. (a) Missing or partial
(c) Implemented, but looks wrong
(b) Not asked for
Summary: Standards has 1 hard violation, 3 likely bugs and 9 judgement calls; the worst is Save being enabled with a stale blob after a failed edit. Spec has 5 gaps, 3 questionable implementations and 2 test-only additions outside the stated intents; the worst is again Save after a failed edit, plus untranslated error text reaching the user. |
|
wsDuration() can throw inside the catch. If it does, handleChanged rejects, and publishChanged voids that on the assumption that it never rejects. |
synced pasteBusy and its ref

No description provided.