This commit is contained in:
gpt-engineer-app[bot] 2025-12-21 15:18:54 +00:00
parent 6693f94b65
commit 64fec848fe
2 changed files with 113 additions and 108 deletions

View File

@ -157,7 +157,7 @@ export function MiniOscilloscope() {
return (
<div
onClick={handleClick}
className="fixed bottom-6 left-1/2 -translate-x-1/2 w-[400px] md:w-[600px] h-[80px] z-50 cursor-pointer group"
className="fixed bottom-6 left-1/2 -translate-x-1/2 w-[200px] h-[50px] md:w-[600px] md:h-[80px] z-50 cursor-pointer group"
title="Open Oscilloscope"
>
<div className="relative w-full h-full rounded-lg border border-primary/50 overflow-hidden bg-background/80 backdrop-blur-sm transition-all duration-300 group-hover:border-primary group-hover:shadow-[0_0_20px_hsl(var(--primary)/0.4)]">

View File

@ -247,7 +247,7 @@ export function Oscilloscope() {
const canGenerate = audioData !== null && originalFile !== null && !isExporting && !isLoading;
return (
<div className="space-y-6 max-w-6xl mx-auto">
<div className="space-y-6 max-w-7xl mx-auto">
{/* Header */}
<div className="text-center space-y-4">
<h2 className="font-minecraft text-2xl md:text-3xl text-primary text-glow-strong">
@ -258,130 +258,135 @@ export function Oscilloscope() {
</p>
</div>
{/* Controls Row */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
{/* Left Column: Audio Input */}
<div className="space-y-4">
{/* Audio Input Row */}
<div className="flex flex-col sm:flex-row items-start sm:items-center gap-4">
<div className="flex-1 w-full sm:w-auto">
<AudioUploader
onFileSelect={handleFileSelect}
isLoading={isLoading}
fileName={fileName}
/>
{/* Microphone Toggle */}
<div className="flex items-center gap-4">
<Button
onClick={toggleMic}
variant={isMicActive ? "default" : "outline"}
className={`flex items-center gap-2 font-crt ${
isMicActive
? 'bg-primary text-primary-foreground'
: 'border-primary/50 hover:bg-primary/10'
}`}
>
{isMicActive ? <MicOff size={16} /> : <Mic size={16} />}
{isMicActive ? 'STOP MIC' : 'USE MICROPHONE'}
</Button>
{isMicActive && (
<div className="flex items-center gap-4">
<div className="text-sm text-muted-foreground font-mono-crt">
Real-time input active
</div>
<Button
onClick={() => setShowMicCalibration(!showMicCalibration)}
variant="outline"
size="sm"
className="font-mono-crt text-xs"
>
Calibrate
</Button>
</div>
)}
</div>
</div>
{/* Right Column: Control Panel */}
<OscilloscopeControls
mode={mode}
onModeChange={setMode}
canGenerate={canGenerate}
isGenerating={isExporting}
progress={progress}
exportedUrl={exportedUrl}
onGenerate={handleGenerate}
onReset={handleReset}
isPlaying={isPlaying}
onPreview={handlePreview}
canPreview={canPreview}
playbackSpeed={playbackSpeed}
onPlaybackSpeedChange={handlePlaybackSpeedChange}
isLooping={isLooping}
onLoopingChange={handleLoopingChange}
exportResolution={exportResolution}
onExportResolutionChange={handleExportResolutionChange}
exportFps={exportFps}
onExportFpsChange={handleExportFpsChange}
exportQuality={exportQuality}
onExportQualityChange={handleExportQualityChange}
liveSettings={liveSettings}
onLiveSettingsChange={setLiveSettings}
/>
</div>
{/* Microphone Toggle */}
<div className="flex items-center gap-4">
<Button
onClick={toggleMic}
variant={isMicActive ? "default" : "outline"}
className={`flex items-center gap-2 font-crt ${
isMicActive
? 'bg-primary text-primary-foreground'
: 'border-primary/50 hover:bg-primary/10'
}`}
>
{isMicActive ? <MicOff size={16} /> : <Mic size={16} />}
{isMicActive ? 'STOP MIC' : 'USE MICROPHONE'}
</Button>
{/* Oscilloscope Display */}
<div className="flex justify-center flex-col items-center gap-4">
<OscilloscopeDisplay
audioData={audioData}
micAnalyzer={micAnalyzer}
mode={liveSettings.displayMode}
isPlaying={isPlaying}
playbackSpeed={playbackSpeed}
isLooping={isLooping}
audioElementRef={audioRef}
onPlaybackEnd={() => {
setIsPlaying(false);
setCurrentTime(0);
setSeekPosition(0);
}}
onSeek={handleSeek}
liveSettings={liveSettings}
/>
{/* Audio Playback Controls */}
{audioData && originalFile && (
<div className="w-full max-w-3xl space-y-2 px-4">
{/* Play/Pause and Time Display */}
{isMicActive && (
<div className="flex items-center gap-4">
<div className="text-sm text-muted-foreground font-mono-crt">
Real-time input active
</div>
<Button
onClick={handlePreview}
onClick={() => setShowMicCalibration(!showMicCalibration)}
variant="outline"
size="sm"
className="font-crt border-primary/50 hover:bg-primary/10"
disabled={isExporting}
className="font-mono-crt text-xs"
>
{isPlaying ? <Pause size={16} /> : <Play size={16} />}
Calibrate
</Button>
</div>
)}
</div>
</div>
<span className="font-mono-crt text-sm text-foreground/80 min-w-[80px]">
{formatTime(currentTime)} / {formatTime(audioData.duration)}
</span>
{/* Main Content: Display + Controls Side by Side */}
<div className="grid grid-cols-1 xl:grid-cols-[1fr_320px] gap-6">
{/* Oscilloscope Display */}
<div className="flex flex-col items-center gap-4 order-2 xl:order-1">
<OscilloscopeDisplay
audioData={audioData}
micAnalyzer={micAnalyzer}
mode={liveSettings.displayMode}
isPlaying={isPlaying}
playbackSpeed={playbackSpeed}
isLooping={isLooping}
audioElementRef={audioRef}
onPlaybackEnd={() => {
setIsPlaying(false);
setCurrentTime(0);
setSeekPosition(0);
}}
onSeek={handleSeek}
liveSettings={liveSettings}
/>
{/* Progress Bar */}
<div className="flex-1">
<Slider
value={[seekPosition * 100]}
onValueChange={(value) => handleSeek(value[0] / 100)}
max={100}
step={0.1}
className="cursor-pointer"
/>
{/* Audio Playback Controls */}
{audioData && originalFile && (
<div className="w-full max-w-3xl space-y-2 px-4">
{/* Play/Pause and Time Display */}
<div className="flex items-center gap-4">
<Button
onClick={handlePreview}
variant="outline"
size="sm"
className="font-crt border-primary/50 hover:bg-primary/10"
disabled={isExporting}
>
{isPlaying ? <Pause size={16} /> : <Play size={16} />}
</Button>
<span className="font-mono-crt text-sm text-foreground/80 min-w-[80px]">
{formatTime(currentTime)} / {formatTime(audioData.duration)}
</span>
{/* Progress Bar */}
<div className="flex-1">
<Slider
value={[seekPosition * 100]}
onValueChange={(value) => handleSeek(value[0] / 100)}
max={100}
step={0.1}
className="cursor-pointer"
/>
</div>
</div>
</div>
</div>
)}
)}
</div>
{/* Control Panel */}
<div className="order-1 xl:order-2">
<OscilloscopeControls
mode={mode}
onModeChange={setMode}
canGenerate={canGenerate}
isGenerating={isExporting}
progress={progress}
exportedUrl={exportedUrl}
onGenerate={handleGenerate}
onReset={handleReset}
isPlaying={isPlaying}
onPreview={handlePreview}
canPreview={canPreview}
playbackSpeed={playbackSpeed}
onPlaybackSpeedChange={handlePlaybackSpeedChange}
isLooping={isLooping}
onLoopingChange={handleLoopingChange}
exportResolution={exportResolution}
onExportResolutionChange={handleExportResolutionChange}
exportFps={exportFps}
onExportFpsChange={handleExportFpsChange}
exportQuality={exportQuality}
onExportQualityChange={handleExportQualityChange}
liveSettings={liveSettings}
onLiveSettingsChange={setLiveSettings}
/>
</div>
</div>
{/* Microphone Calibration */}
{showMicCalibration && isMicActive && (
<div className="bg-card border border-border rounded-lg p-4 max-w-md mx-auto">