feat(ui): segmented 90/220 toggle for growing codec (cleaner than dropdown)

Replace the VC-3 growing-codec dropdown with a clean two-button segmented
toggle (90 Mbps / 220 Mbps) in both the recorder config modal and the new-
recorder modal. Shows the bitrate + a one-line tradeoff (Lighter/default vs
Highest quality) so operators can swap quality at a glance. Removed the now-
redundant growing bitrate text.
This commit is contained in:
OpenCode 2026-06-05 05:29:26 +00:00
parent c40de38c45
commit 3b3e7edade
2 changed files with 56 additions and 15 deletions

View file

@ -433,12 +433,29 @@ function NewRecorderModal({ open, onClose }) {
{growingOn && <span style={{ marginLeft: 6, fontSize: 10, fontWeight: 700, letterSpacing: '0.06em', color: 'var(--text-3)' }}>· PREMIERE-NATIVE</span>}
</label>
{growingOn ? (
<select className="field-input" value={growingCodec}
onChange={e => setGrowingCodec(e.target.value)}
style={{ appearance: 'auto' }}>
<option value="vc3_90">VC-3 / DNxHD 90 (MXF OP1a, 4:2:2, ~90 Mbps)</option>
<option value="vc3_220">VC-3 / DNxHD 220 (MXF OP1a, 4:2:2, ~220 Mbps)</option>
</select>
<div style={{ display: 'flex', gap: 6 }}>
{[
{ v: 'vc3_90', big: '90', note: 'Lighter · default' },
{ v: 'vc3_220', big: '220', note: 'Highest quality' },
].map(opt => {
const active = growingCodec === opt.v;
return (
<button key={opt.v} type="button"
onClick={() => setGrowingCodec(opt.v)}
style={{
flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'flex-start',
padding: '8px 12px', borderRadius: 8, cursor: 'pointer',
border: active ? '1px solid var(--accent, #4a9eff)' : '1px solid var(--border, #333)',
background: active ? 'var(--accent-soft, rgba(74,158,255,0.12))' : 'transparent',
}}>
<span style={{ fontSize: 16, fontWeight: 700, lineHeight: 1 }}>
{opt.big}<span style={{ fontSize: 10, fontWeight: 500, marginLeft: 3, color: 'var(--text-3)' }}>Mbps</span>
</span>
<span style={{ fontSize: 10.5, color: active ? 'var(--accent, #4a9eff)' : 'var(--text-3)', marginTop: 3 }}>{opt.note}</span>
</button>
);
})}
</div>
) : (
<select className="field-input" value={recCodec}
onChange={e => setRecCodec(e.target.value)}

View file

@ -746,15 +746,39 @@ function RecorderConfigModal({ recorder, onClose, onSaved }) {
) : (
<div className="rec-cfg-grid">
<div className="field">
<label className="field-label">Growing codec</label>
<select className="field-input" value={growingCodec}
onChange={e => setGrowingCodec(e.target.value)} disabled={isRec}
style={{ appearance: 'auto' }}>
<option value="vc3_90">VC-3 / DNxHD 90 (MXF OP1a, ~90 Mbps)</option>
<option value="vc3_220">VC-3 / DNxHD 220 (MXF OP1a, ~220 Mbps)</option>
</select>
<div className="mono" style={{ fontSize: 10.5, color: 'var(--text-3)', marginTop: 4 }}>
VC-3 / DNxHD 8-bit 4:2:2 @ 1080p59.94, MXF OP1a. Premiere-native edit-while-record (imports + grows live). {growingCodec === 'vc3_220' ? '~220 Mbps, highest quality.' : '~90 Mbps, lighter storage (default).'}
<label className="field-label">Growing quality · VC-3 / DNxHD</label>
{/* Clean two-way segmented toggle for the only growing choice that
matters: 90 vs 220 Mbps. Both are VC-3/DNxHD MXF OP1a, the rest
is fixed, so a binary toggle reads faster than a dropdown. */}
<div className="seg-toggle" role="group" aria-label="Growing bitrate"
style={{ display: 'flex', gap: 6 }}>
{[
{ v: 'vc3_90', big: '90', sub: 'Mbps', note: 'Lighter · default' },
{ v: 'vc3_220', big: '220', sub: 'Mbps', note: 'Highest quality' },
].map(opt => {
const active = growingCodec === opt.v;
return (
<button key={opt.v} type="button"
onClick={() => !isRec && setGrowingCodec(opt.v)}
disabled={isRec}
className={`btn ${active ? 'active' : 'ghost'}`}
style={{
flex: 1, flexDirection: 'column', alignItems: 'flex-start',
padding: '8px 12px', borderRadius: 8,
border: active ? '1px solid var(--accent, #4a9eff)' : '1px solid var(--border, #333)',
background: active ? 'var(--accent-soft, rgba(74,158,255,0.12))' : 'transparent',
cursor: isRec ? 'not-allowed' : 'pointer', opacity: isRec ? 0.5 : 1,
}}>
<span style={{ fontSize: 16, fontWeight: 700, lineHeight: 1 }}>
{opt.big}<span style={{ fontSize: 10, fontWeight: 500, marginLeft: 3, color: 'var(--text-3)' }}>{opt.sub}</span>
</span>
<span style={{ fontSize: 10.5, color: active ? 'var(--accent, #4a9eff)' : 'var(--text-3)', marginTop: 3 }}>{opt.note}</span>
</button>
);
})}
</div>
<div className="mono" style={{ fontSize: 10.5, color: 'var(--text-3)', marginTop: 6 }}>
8-bit 4:2:2 · MXF OP1a · Premiere-native edit-while-record (imports + grows live).
</div>
</div>
</div>