From e1625a717d9479f3a0b8c8b4c47cb1ea069a8001 Mon Sep 17 00:00:00 2001 From: fspecii <4722521+fspecii@users.noreply.github.com> Date: Mon, 2 Mar 2026 17:43:53 +0200 Subject: [PATCH] Fix multiple issues: format API, Gradio availability, storage, UI responsiveness - Format endpoint now calls ACE-Step /format_input REST API directly instead of spawning Python, fixing ENOENT errors on Windows (#44, #27, #34) - isGradioAvailable() tries /gradio_api/info, /info, / in sequence to handle Gradio 4.x/5.x/6.x version differences, fixing generation fallback (#53, #20) - Storage getUrl/getPublicUrl normalize /audio/ prefix to prevent double-prefix URLs when reference tracks are used for cover generation (#10) - Gradio args: fix normalization_db default from 0.0 to -1.0 (Gradio default) - Volume popover: add 400ms delay before hiding to prevent accidental dismissal (#51) - Polling: skip setSongs state update when nothing changed to reduce re-renders (#51) - FFmpeg: add jsdelivr CDN fallback when unpkg fails (#30) - Model switching: add switchModelIfNeeded() via /v1/init REST API (#45) --- App.tsx | 24 +++--- components/Player.tsx | 10 ++- components/VideoGeneratorModal.tsx | 25 +++++-- server/src/routes/generate.ts | 108 ++++++++++++++++++++++----- server/src/services/acestep.ts | 66 ++++++++++++---- server/src/services/gradio-client.ts | 29 ++++--- server/src/services/storage/local.ts | 9 +-- 7 files changed, 208 insertions(+), 63 deletions(-) diff --git a/App.tsx b/App.tsx index 1a2bf0e..5233de8 100644 --- a/App.tsx +++ b/App.tsx @@ -707,17 +707,21 @@ function AppContent() { ? (Number(status.progress) > 1 ? Number(status.progress) / 100 : Number(status.progress)) : undefined; - setSongs(prev => prev.map(s => { - if (s.id === tempId) { - return { - ...s, - queuePosition: status.status === 'queued' ? status.queuePosition : undefined, - progress: normalizedProgress ?? s.progress, - stage: status.stage ?? s.stage, - }; + setSongs(prev => { + const song = prev.find(s => s.id === tempId); + if (!song) return prev; + const newQueuePos = status.status === 'queued' ? status.queuePosition : undefined; + const newProgress = normalizedProgress ?? song.progress; + const newStage = status.stage ?? song.stage; + // Skip update if nothing changed to avoid unnecessary re-renders + if (newProgress === song.progress && newStage === song.stage && newQueuePos === song.queuePosition) { + return prev; } - return s; - })); + return prev.map(s => { + if (s.id !== tempId) return s; + return { ...s, queuePosition: newQueuePos, progress: newProgress, stage: newStage }; + }); + }); if (status.status === 'succeeded' && status.result) { cleanupJob(jobId, tempId); diff --git a/components/Player.tsx b/components/Player.tsx index 331abbb..2fd3950 100644 --- a/components/Player.tsx +++ b/components/Player.tsx @@ -69,6 +69,7 @@ export const Player: React.FC = ({ const progressBarRef = useRef(null); const fullscreenProgressRef = useRef(null); const [isHoveringVolume, setIsHoveringVolume] = useState(false); + const volumeHideTimer = useRef | null>(null); const [showDropdown, setShowDropdown] = useState(false); const [isFullscreen, setIsFullscreen] = useState(false); const [shareModalOpen, setShareModalOpen] = useState(false); @@ -755,8 +756,13 @@ export const Player: React.FC = ({ {/* Volume Control with Vertical Slider */}
setIsHoveringVolume(true)} - onMouseLeave={() => setIsHoveringVolume(false)} + onMouseEnter={() => { + if (volumeHideTimer.current) clearTimeout(volumeHideTimer.current); + setIsHoveringVolume(true); + }} + onMouseLeave={() => { + volumeHideTimer.current = setTimeout(() => setIsHoveringVolume(false), 400); + }} >