This commit is contained in:
parent
7d21081780
commit
1ca5e4a3a8
1 changed files with 31 additions and 108 deletions
|
|
@ -279,17 +279,6 @@ function RecordingDetail({ recording: r, data, onBack, allHighlights, setAllHigh
|
||||||
'follow-up': 'var(--amber-dim)', meeting: 'var(--green)', personal: 'var(--text2)', work: 'var(--teal)',
|
'follow-up': 'var(--amber-dim)', meeting: 'var(--green)', personal: 'var(--text2)', work: 'var(--teal)',
|
||||||
};
|
};
|
||||||
|
|
||||||
const progressPct = (currentTime / totalSeconds) * 100;
|
|
||||||
|
|
||||||
// Waveform: fake bars
|
|
||||||
const waveformBars = 120;
|
|
||||||
const waveHeights = useRefRD(null);
|
|
||||||
if (!waveHeights.current) {
|
|
||||||
const rand = (seed) => { let s = seed; return () => { s = (s * 16807) % 2147483647; return (s - 1) / 2147483646; }; };
|
|
||||||
const rng = rand(r.id * 42);
|
|
||||||
waveHeights.current = Array.from({ length: waveformBars }, () => 0.1 + rng() * 0.9);
|
|
||||||
}
|
|
||||||
|
|
||||||
const qualityDetails = [
|
const qualityDetails = [
|
||||||
{ label: 'Quality', value: r.quality, cls: `q-${r.quality}` },
|
{ label: 'Quality', value: r.quality, cls: `q-${r.quality}` },
|
||||||
{ label: 'Sample Rate', value: `${r.sampleRate / 1000} kHz`, cls: '' },
|
{ label: 'Sample Rate', value: `${r.sampleRate / 1000} kHz`, cls: '' },
|
||||||
|
|
@ -407,110 +396,44 @@ function RecordingDetail({ recording: r, data, onBack, allHighlights, setAllHigh
|
||||||
{/* Left: Player + Transcript */}
|
{/* Left: Player + Transcript */}
|
||||||
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
|
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
|
||||||
|
|
||||||
{/* Player */}
|
{/* Player - simplified with native controls */}
|
||||||
<div style={{ padding: '16px 20px', borderBottom: '1px solid var(--border)', background: 'var(--bg2)', flexShrink: 0 }}>
|
<div style={{ padding: '16px 20px', borderBottom: '1px solid var(--border)', background: 'var(--bg2)', flexShrink: 0 }}>
|
||||||
{/* Waveform */}
|
{audioLoading && (
|
||||||
<div
|
<div style={{ color: 'var(--text3)', fontSize: 11, fontFamily: 'var(--font-mono)', marginBottom: 8 }}>
|
||||||
onClick={seek}
|
Loading audio...
|
||||||
style={{ height: 56, display: 'flex', alignItems: 'center', gap: 1, cursor: 'pointer', marginBottom: 8, position: 'relative' }}
|
</div>
|
||||||
>
|
)}
|
||||||
{waveHeights.current.map((h, i) => {
|
|
||||||
const barPct = i / waveformBars;
|
|
||||||
const barTime = barPct * totalSeconds;
|
|
||||||
const isPast = barPct <= progressPct / 100;
|
|
||||||
const isActive = Math.abs(barPct - progressPct / 100) < 0.015;
|
|
||||||
|
|
||||||
// Check if bar is within any highlight range (or near a point highlight)
|
{/* Native audio element with controls */}
|
||||||
const inHighlight = recHighlights.some(hl => {
|
{audioBlobUrl && (
|
||||||
if (hl.endSeconds != null) {
|
<audio
|
||||||
// Range highlight - check if bar is within range
|
ref={audioRef}
|
||||||
return barTime >= hl.startSeconds && barTime <= hl.endSeconds;
|
src={audioBlobUrl}
|
||||||
} else {
|
controls
|
||||||
// Point highlight - check if near
|
style={{ width: '100%', marginBottom: 12 }}
|
||||||
return Math.abs(hl.startSeconds - barTime) < (totalSeconds / waveformBars);
|
/>
|
||||||
}
|
)}
|
||||||
});
|
|
||||||
|
|
||||||
// Check if bar is within the pending highlight being created
|
{/* Extra controls: skip buttons and speed */}
|
||||||
const inPendingHighlight = showAddHighlight && highlightStartTime != null && (
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||||
highlightEndTime != null
|
<button onClick={() => skipTime(-30)} style={{ color: 'var(--text2)', fontFamily: 'var(--font-mono)', fontSize: 11, padding: '4px 8px', background: 'var(--bg4)', borderRadius: 4 }}>-30s</button>
|
||||||
? barTime >= highlightStartTime && barTime <= highlightEndTime
|
<button onClick={() => skipTime(-5)} style={{ color: 'var(--text2)', fontFamily: 'var(--font-mono)', fontSize: 11, padding: '4px 8px', background: 'var(--bg4)', borderRadius: 4 }}>-5s</button>
|
||||||
: Math.abs(highlightStartTime - barTime) < (totalSeconds / waveformBars)
|
<button onClick={() => skipTime(5)} style={{ color: 'var(--text2)', fontFamily: 'var(--font-mono)', fontSize: 11, padding: '4px 8px', background: 'var(--bg4)', borderRadius: 4 }}>+5s</button>
|
||||||
);
|
<button onClick={() => skipTime(30)} style={{ color: 'var(--text2)', fontFamily: 'var(--font-mono)', fontSize: 11, padding: '4px 8px', background: 'var(--bg4)', borderRadius: 4 }}>+30s</button>
|
||||||
|
|
||||||
return (
|
|
||||||
<div key={i} style={{
|
|
||||||
flex: 1,
|
|
||||||
height: `${Math.round(h * 100)}%`,
|
|
||||||
background: inPendingHighlight ? 'var(--red)' : inHighlight ? 'var(--amber)' : isPast ? 'var(--teal)' : 'var(--bg4)',
|
|
||||||
borderRadius: 1,
|
|
||||||
minHeight: 2,
|
|
||||||
transition: 'background 0.05s',
|
|
||||||
opacity: isActive ? 1 : 0.85,
|
|
||||||
}} />
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
|
|
||||||
{/* Highlight range markers when creating */}
|
|
||||||
{showAddHighlight && highlightStartTime != null && (
|
|
||||||
<div style={{
|
|
||||||
position: 'absolute', left: `${(highlightStartTime / totalSeconds) * 100}%`, top: 0, bottom: 0,
|
|
||||||
width: 2, background: 'var(--red)', pointerEvents: 'none',
|
|
||||||
}} />
|
|
||||||
)}
|
|
||||||
{showAddHighlight && highlightEndTime != null && (
|
|
||||||
<div style={{
|
|
||||||
position: 'absolute', left: `${(highlightEndTime / totalSeconds) * 100}%`, top: 0, bottom: 0,
|
|
||||||
width: 2, background: 'var(--red)', pointerEvents: 'none',
|
|
||||||
}} />
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Playhead */}
|
|
||||||
<div style={{
|
|
||||||
position: 'absolute', left: `${progressPct}%`, top: 0, bottom: 0,
|
|
||||||
width: 2, background: 'var(--amber)', pointerEvents: 'none',
|
|
||||||
boxShadow: '0 0 6px var(--amber)',
|
|
||||||
}} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Hidden audio element */}
|
|
||||||
{audioBlobUrl && <audio ref={audioRef} src={audioBlobUrl} preload="metadata" />}
|
|
||||||
{audioLoading && <div style={{ color: 'var(--text3)', fontSize: 11, fontFamily: 'var(--font-mono)' }}>Loading audio...</div>}
|
|
||||||
|
|
||||||
{/* Controls */}
|
|
||||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
|
||||||
<button onClick={() => skipTime(-30)} style={{ color: 'var(--text2)', fontFamily: 'var(--font-mono)', fontSize: 11 }}>-30s</button>
|
|
||||||
<button onClick={() => skipTime(-5)} style={{ color: 'var(--text2)', fontFamily: 'var(--font-mono)', fontSize: 11 }}>-5s</button>
|
|
||||||
<button
|
|
||||||
onClick={togglePlay}
|
|
||||||
style={{
|
|
||||||
width: 36, height: 36, borderRadius: '50%',
|
|
||||||
background: 'var(--amber)', color: 'var(--bg)',
|
|
||||||
fontSize: 14, display: 'flex', alignItems: 'center', justifyContent: 'center',
|
|
||||||
flexShrink: 0,
|
|
||||||
}}
|
|
||||||
>{playing ? '⏸' : '▶'}</button>
|
|
||||||
<button onClick={() => skipTime(5)} style={{ color: 'var(--text2)', fontFamily: 'var(--font-mono)', fontSize: 11 }}>+5s</button>
|
|
||||||
<button onClick={() => skipTime(30)} style={{ color: 'var(--text2)', fontFamily: 'var(--font-mono)', fontSize: 11 }}>+30s</button>
|
|
||||||
|
|
||||||
<div style={{ flex: 1 }} />
|
<div style={{ flex: 1 }} />
|
||||||
|
|
||||||
{/* Speed */}
|
{/* Speed */}
|
||||||
<div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
|
<span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--text3)' }}>Speed:</span>
|
||||||
{[0.5, 1.0, 1.5, 2.0, 3.0].map(s => (
|
{[0.5, 1.0, 1.5, 2.0, 3.0].map(s => (
|
||||||
<button key={s} onClick={() => setSpeed(s)} style={{
|
<button key={s} onClick={() => setSpeed(s)} style={{
|
||||||
fontFamily: 'var(--font-mono)', fontSize: 10, padding: '2px 7px',
|
fontFamily: 'var(--font-mono)', fontSize: 10, padding: '2px 7px',
|
||||||
borderRadius: 3,
|
borderRadius: 3,
|
||||||
background: speed === s ? 'var(--amber)' : 'var(--bg4)',
|
background: speed === s ? 'var(--amber)' : 'var(--bg4)',
|
||||||
color: speed === s ? 'var(--bg)' : 'var(--text3)',
|
color: speed === s ? 'var(--bg)' : 'var(--text3)',
|
||||||
border: '1px solid var(--border)',
|
border: '1px solid var(--border)',
|
||||||
}}>{s}×</button>
|
}}>{s}×</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text2)', minWidth: 100, textAlign: 'right' }}>
|
|
||||||
{formatTime(currentTime)} / {formatTime(totalSeconds)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue