Skip to content

feat: defer general resource upload until sections chosen - #653

Merged
sarahentzel merged 15 commits into
developfrom
defer-general-resource-upload
Sep 23, 2026
Merged

sarahentzel merged 15 commits into
developfrom
defer-general-resource-upload

Conversation

@nabalone

@nabalone nabalone commented Sep 22, 2026

Copy link
Copy Markdown
Collaborator

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

  • SelectSections Next → Upload (new-add flow only; editing an existing resource still reads "Next").
  • Configure "Upload as {n} resources" → "Create {n} resources" (new createXResources string).

How

  • The staged file is uploaded headlessly through the always-mounted Uploader's importList.
  • Record tab: MediaRecord.doUpload hands the finished (converted) take to onStageFile instead of uploadMedia when staging.
  • afterUpload routes straight to the configure step (or visual write) when sections were pre-chosen.
  • Any newly-typed artifact category is committed at stage time (before the dialog's metaData unmounts).

Test plan

  • Add Audio Resource → General Resource, Upload tab: pick file → Next → SelectSections → Upload → configure → Create N resources.
  • Same via the Record tab.
  • Cancel at SelectSections before Upload → confirm no mediafile was created.
  • Editing an existing general resource still reads "Next" and skips upload.

Verified: tsc --noEmit clean, ESLint clean on changed files, MediaRecord + Uploader jest suites pass (16/16).

🤖 Generated with Claude Code

nabalone and others added 5 commits September 21, 2026 19:50
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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 Medium severity

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 Uploader importList.
  • 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.

Comment thread src/renderer/src/components/MediaRecord.tsx
Comment thread src/renderer/src/components/Uploader.tsx
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>
@nabalone

nabalone commented Sep 22, 2026

Copy link
Copy Markdown
Collaborator Author

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 afterUpload routes straight into the configure dialog (ProjectResourceConfigure). So by the time the user is in the configure step, the mediafile already exists.

Context: the base branch (add-audio-resource-wizard-polish) has an in-progress refactor of the configure dialog's close path (removing the old waitForSave close-race + lifetime dirty-latch, and making close/discard confirm parent-owned). That refactor only changes how the dialog closes. Flagging so the two efforts stay coordinated when this rebases onto the updated base.

nabalone and others added 5 commits September 22, 2026 19:45
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>
@nabalone
nabalone force-pushed the defer-general-resource-upload branch from f633775 to 014ebb9 Compare September 23, 2026 00:47
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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 Medium severity

Open (3)
Resolved since last review (3)

Comment on lines +918 to +920
setVisual(
Boolean(files[0] && !(files[0] as File).type.startsWith('audio'))
);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only run this for audio files. Fixed accordingly.

Comment on lines +895 to +897
setVisual(
Boolean(files[0] && !(files[0] as File).type.startsWith('audio'))
);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only run this for audio files. Fixed accordingly.

Comment on lines +458 to +465
const stageFiles = async (files: File[]) => {
try {
await onStageFiles?.(files);
return true;
} catch {
return false;
}
};

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@nabalone
nabalone marked this pull request as ready for review September 23, 2026 13:09
Base automatically changed from add-audio-resource-wizard-polish to develop September 23, 2026 14:45
…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
@nabalone

Copy link
Copy Markdown
Collaborator Author

Merged develop into this branch to clear a merge conflict (scheduled auto-resolve routine). Four files conflicted; in three of them this branch already contained develop's edits and simply adds more on top, so its side was kept:

  • PassageRecordDlg.tsx — both sides added confirmOnClose. This branch's version is a superset (same prop, plus onStageFile and its destructure/forward), so it was kept. Nothing from develop was dropped.
  • SelectSections.tsx — this branch already carried develop's edits here (paddingTop removal, table borders, onCancel removal, ml: 'auto') and adds uploadsOnNext/uploading plus the spinner. One fix-up was needed: develop removed the ISharedStrings import, which this branch still uses for ts.upload, so that import was restored.
  • ProjectResourceConfigure.tsx — the one line where the two sides genuinely differ. develop switched this button to t.uploadAsResources; this branch uses t.createXResources. Kept createXResources, since the branch already contains develop's uploadAsResources string and deliberately renames the label ("Upload as {n} resources" → "Create {n} resources") because the upload now happens at the SelectSections step — exactly as this PR's description states. Flagging it as the only judgement call here.
  • exported-strings-name.json — both sides regenerated the bundle. Kept strings68154c51.json: its contents are a strict superset of develop's stringsf1d2c668.json (adds only the 11 createXResources locale entries; no other key or value differs).

One leftover worth knowing about: develop's now-unreferenced src/renderer/public/localization/stringsf1d2c668.json is still in the tree. I left it alone rather than deleting a file the merge brought in — it'll disappear the next time you run the localization tool.

Verified before pushing: tsc --noEmit clean, and Prettier clean on the touched files. Test suites were not run.


Generated by Claude Code

@sarahentzel
sarahentzel merged commit d444dbe into develop Sep 23, 2026
2 checks passed
@sarahentzel
sarahentzel deleted the defer-general-resource-upload branch September 23, 2026 16:06
gtryus pushed a commit that referenced this pull request Sep 24, 2026
#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>
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.

3 participants