feat: defer general resource upload until sections chosen - #653
Conversation
Backdrop clicks routed through the discard-confirm; disable backdrop close so only the X (or Cancel) can dismiss the Edit resource dialog. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ed on unmount - MediaUpload: reset showConfirm when the dialog hides so a stale discard prompt no longer blocks a reopened upload (Devin). - ProjectResourceConfigure: clear the tool-changed flag on unmount so an unexpected teardown can't leave UnsavedContext stuck (Copilot). - MediaUpload: make the confirmOnClose doc match actual behavior (Copilot). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace hard-coded '1px solid black' with the theme's custom.black token so the internalization section table stays consistent with app theming (Copilot). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…iff unit Re-indent the new passageDetailArtifacts.uploadAsResources trans-unit from tabs to the file's dominant pure-space style (whitespace-only; generated strings unchanged) per Devin's indentation flag. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Deferred staging currently risks unhandled async errors and can leave stale staged files that may incorrectly upload later if the user cancels out of SelectSections.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 3
Open (3)
What changed in this PR
This PR updates the “Add Audio Resource” flow for General (project) audio resources so files/recordings are staged at the initial dialog and only uploaded after sections/passages are selected (SelectSections → Upload), preventing orphaned media when users cancel early.
Changes:
- Added deferred-upload plumbing to stage prepared files/recordings and trigger the real upload later via the always-mounted
UploaderimportList. - Updated SelectSections and configure-step button text (“Next → Upload”, “Create {n} resources”) and introduced a new localized string
createXResources. - Refreshed localization bundle pointer (
exported-strings-name.json) and added the new string to localization source files.
| File | Description |
|---|---|
| src/renderer/src/store/localization/reducers.tsx | Adds createXResources default string. |
| src/renderer/src/store/localization/model.tsx | Extends typings to include createXResources. |
| src/renderer/src/store/localization/exported-strings-name.json | Updates localization bundle filename reference. |
| src/renderer/src/components/Uploader.tsx | Adds deferred-upload staging hooks (deferUpload, onStageFiles). |
| src/renderer/src/components/PassageRecordDlg.tsx | Forwards staging callback to the record tab. |
| src/renderer/src/components/PassageDetail/Internalization/SelectSections.tsx | Changes Next button label to “Upload” for deferred-upload flow. |
| src/renderer/src/components/PassageDetail/Internalization/ProjectResourceConfigure.tsx | Uses createXResources for the “Create {n} resources” button text. |
| src/renderer/src/components/PassageDetail/Internalization/PassageDetailArtifacts.tsx | Stores staged files, drives headless upload via importList, and adjusts post-upload routing. |
| src/renderer/src/components/MediaRecord.tsx | Stages recorded takes instead of uploading immediately when deferring. |
| localization/TranscriberAdmin-en.xlf | Adds passageDetailArtifacts.createXResources source string. |
| localization/TranscriberAdmin-en-1.2.xliff | Adds passageDetailArtifacts.createXResources source string with context. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The subtitle hardcoded "sections"; substitute the plan's organizedBy label (plural) at display so it reads correctly for non-section plans. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Heads-up on an interaction between the deferred-upload flow here and discarding at the configure step. With this change, the real upload runs when the user clicks Upload on SelectSections, and Context: the base branch ( |
Adding a General (project) audio resource no longer uploads the file at
the Add Audio Resource dialog. The prepared file (Upload tab) or recorded
take (Record tab) is staged and the upload runs only when the user clicks
Upload on the SelectSections dialog, then proceeds to configure. Cancelling
before that point uploads nothing, avoiding an orphaned mediafile.
Also renames the SelectSections Next button to "Upload" (new-add flow only)
and the configure button to "Create {n} resources".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
f633775 to
014ebb9
Compare
On a deferred general-resource upload, keep the SelectSections dialog open with its Upload button disabled and a spinner, rather than closing it and reopening on failure. On success it advances to the configure step; on failure it stays open with the selection intact so the user can retry without re-selecting (and without losing a recorded take). Rename the in-flight flag to `uploading`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Deferred-staging error handling and staged file type detection have edge cases that can lead to silent failures or incorrect UI flow.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 3
Open (3)
| setVisual( | ||
| Boolean(files[0] && !(files[0] as File).type.startsWith('audio')) | ||
| ); |
There was a problem hiding this comment.
We only run this for audio files. Fixed accordingly.
| setVisual( | ||
| Boolean(files[0] && !(files[0] as File).type.startsWith('audio')) | ||
| ); |
There was a problem hiding this comment.
We only run this for audio files. Fixed accordingly.
| const stageFiles = async (files: File[]) => { | ||
| try { | ||
| await onStageFiles?.(files); | ||
| return true; | ||
| } catch { | ||
| return false; | ||
| } | ||
| }; |
…licts
Automated conflict resolution by a scheduled Claude Code routine.
Resolved:
- PassageRecordDlg.tsx: both sides added `confirmOnClose`; this branch's
version is a superset (same prop plus `onStageFile` and its destructure),
so kept it. No behavior from develop dropped.
- SelectSections.tsx: this branch already contained develop's edits to the
file (paddingTop removal, table borders, onCancel removal, ml:'auto') and
adds `uploadsOnNext`/`uploading` plus the spinner, so kept it. Restored the
`ISharedStrings` import that develop removed but this branch still uses for
`ts.upload`.
- ProjectResourceConfigure.tsx: kept `t.createXResources`. develop switched
this button to `t.uploadAsResources`; this branch carries that string too
and deliberately renames the label ("Upload as {n}" -> "Create {n}"), since
the upload now happens at the SelectSections step.
- exported-strings-name.json: kept strings68154c51.json. Its bundle is a
strict superset of develop's (adds only the 11 createXResources locale
entries; no other key or value differs).
Verified: tsc --noEmit clean, prettier clean on the touched files.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XVsigNY97MR2u3rJGzfPUM
|
Merged
One leftover worth knowing about: develop's now-unreferenced Verified before pushing: Generated by Claude Code |
#683) * fix: load waveform in project resource configure after deferred upload The deferred general-resource upload (#653) opens ProjectResourceConfigure from afterUpload, bypassing handleSelectProjectResource, so the passage-detail player was never loaded and the waveform stayed empty. Select the uploaded media into the player there, and let setSelected fall back to the Orbit cache when its mediafiles snapshot predates the just-uploaded record. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: index the row built for new media in setSelected Read r from newRows when setSelected just built a row for the media, matching how rows is chosen below, instead of relying on oneMediaRow mutating state.rowData in place (Devin). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

Stacked on
add-audio-resource-wizard-polish.What
Adding a General (project) audio resource no longer uploads the file at the Add Audio Resource dialog. The prepared file (Upload tab) or recorded take (Record tab) is staged; the real upload runs only when the user clicks Upload on the SelectSections dialog, then proceeds to the configure step. Cancelling before that point uploads nothing.
Section/passage resources are unaffected (they have no SelectSections step and upload immediately).
Button text
createXResourcesstring).How
Uploader'simportList.MediaRecord.doUploadhands the finished (converted) take toonStageFileinstead ofuploadMediawhen staging.afterUploadroutes straight to the configure step (or visual write) when sections were pre-chosen.Test plan
Verified:
tsc --noEmitclean, ESLint clean on changed files, MediaRecord + Uploader jest suites pass (16/16).🤖 Generated with Claude Code