fix(studio): pin synthesis controls below scrolling form
This commit is contained in:
+1
-1
@@ -10,7 +10,7 @@ the frozen-backend fallback mirror it for their toolchains.
|
||||
|
||||
**Highlights**
|
||||
|
||||
- Voice modes now lead the workspace as full-width tabs, with the active engine above them and each workflow below (#1823)
|
||||
- Voice modes now lead the workspace as full-width tabs, with the active engine above them and Synthesize pinned below the scrolling form (#1823)
|
||||
- Voice cloning now starts with a clear upload-or-record choice, reveals recording and reference details only when needed, and keeps sampling controls under Production Overrides (#1817)
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
| **Storage** | Voices, projects, settings, and outputs stay on the machine by default |
|
||||
| **License** | AGPL-3.0 application; downloaded models keep their upstream terms |
|
||||
|
||||
The Voice workspace starts with the active engine selector and three tabs: **From audio** for cloning, **By design** for creating a voice, and **Convert** for speech-to-speech conversion. Each tab displays its own workflow below.
|
||||
The Voice workspace starts with the active engine selector and three tabs: **From audio** for cloning, **By design** for creating a voice, and **Convert** for speech-to-speech conversion. Each tab displays its own workflow below. In From audio and By design, Synthesize Audio stays at the bottom while the form scrolls above it.
|
||||
|
||||
<a id="install"></a>
|
||||
|
||||
|
||||
@@ -2148,6 +2148,11 @@ div[role="dialog"].audio-trimmer {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.studio-action-bar .override-content {
|
||||
max-height: 40vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════
|
||||
RESPONSIVE — make every component adapt to viewport width
|
||||
════════════════════════════════════════════════════════════ */
|
||||
@@ -4953,7 +4958,7 @@ button.dub-stepper__action:focus-visible {
|
||||
.shell-narrow .studio-with-history__main,
|
||||
.shell-mini .studio-with-history__main {
|
||||
overflow: visible;
|
||||
flex: 0 0 auto;
|
||||
flex: 1 0 auto;
|
||||
order: 1;
|
||||
}
|
||||
.shell-narrow .studio-with-history__main .studio-action-bar,
|
||||
|
||||
@@ -443,14 +443,8 @@ export default function CloneDesignTab(props) {
|
||||
</TabsList>
|
||||
</div>
|
||||
<TabsContent value={defineMethod} className="flex min-h-0 flex-col">
|
||||
{/* #1771 follow-up (item 6): NOT flex-1 — the old always-open 12-row
|
||||
Design block was tall enough that this area routinely filled the
|
||||
full column height on its own. Now that Details defaults collapsed,
|
||||
forcing this to grow-fill would strand a dead gap between it and
|
||||
ActionBar below. Sizing to content (min-h-0 + overflow-y-auto still
|
||||
in play) lets it shrink for short content and still scroll when
|
||||
content genuinely exceeds the available height. */}
|
||||
<div className="flex flex-col gap-[6px] min-h-0 overflow-y-auto">
|
||||
{/* The form owns the remaining height and scrolls above the action bar. */}
|
||||
<div className="flex flex-1 flex-col gap-[6px] min-h-0 overflow-y-auto">
|
||||
{/* ═══ SCRIPT — what should it say ═══
|
||||
Hidden for Convert: the source clip IS the script (the backend
|
||||
transcribes it), so a text panel would only mislead. */}
|
||||
|
||||
@@ -46,6 +46,13 @@ describe('workspace narrow-shell reflow (#476 CTA-clipping guard)', () => {
|
||||
expect(css).toMatch(/\.studio-action-bar\s*\{[^}]*position:\s*sticky/s);
|
||||
});
|
||||
|
||||
it('fills narrow workspaces and bounds expanded settings above the pinned action', () => {
|
||||
expect(css).toMatch(/\.shell-mini\s+\.studio-with-history__main\s*\{[^}]*flex:\s*1 0 auto/s);
|
||||
expect(indexRaw).toMatch(
|
||||
/\.studio-action-bar\s+\.override-content\s*\{[^}]*max-height:\s*40vh;[^}]*overflow-y:\s*auto/s,
|
||||
);
|
||||
});
|
||||
|
||||
it('keeps saved voices in the left rail and generation history alone on the right', () => {
|
||||
expect(app).toMatch(
|
||||
/className="studio-voices">\s*<WorkspaceVoices[\s\S]*?<\/div>\s*<div className="studio-with-history__main">/,
|
||||
|
||||
Reference in New Issue
Block a user