Repository navigation
TT-7761 TT-7762 TT-7763 TT-7765 cut paste buttons disabled properly - #753
sarahentzel wants to merge 9 commits into
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

No description provided.