From 5645486453cf8bbd9cc8d5794c13997059575fed Mon Sep 17 00:00:00 2001 From: espadonne Date: Thu, 2 Apr 2026 18:25:24 -0400 Subject: [PATCH] fix Activity 4 preset unlock; fix take duration resolution Applying an EQ preset now also logs effect_applied so it counts toward the Activity 4 requirement (3 effect uses). Duration resolution in TakesImportModal now uses fetch+decode for proxy/HTTP URLs (Audio element needs range-request support that the proxy doesn't provide). Added onerror handler and cleanup for blob URL fallback. Removed per-render console spam. --- .../audio/DAW/Multitrack/ClipEffectsRack.js | 8 +++- .../audio/DAW/Multitrack/TakesImportModal.js | 41 +++++++++++++++---- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/components/audio/DAW/Multitrack/ClipEffectsRack.js b/components/audio/DAW/Multitrack/ClipEffectsRack.js index c92ccdc..c6fa78d 100644 --- a/components/audio/DAW/Multitrack/ClipEffectsRack.js +++ b/components/audio/DAW/Multitrack/ClipEffectsRack.js @@ -356,12 +356,18 @@ export default function ClipEffectsRack({ show, onHide, selectedClipId, logOpera clips: selectedTrack.clips.map(c => c.id === selectedClipId ? updatedClip : c) }); - // Log for study protocol (Activity 3) + // Log for study protocol if (logOperation) { + // eq_preset_applied unlocks Activity 3 Q5 logOperation('eq_preset_applied', { clipId: selectedClipId, presetName: presetName }); + // Applying a preset is also applying an effect (Activity 4 requirement) + logOperation('effect_applied', { + clipId: selectedClipId, + effectType: 'preset:' + presetName + }); } }, [selectedClip, selectedClipId, selectedTrack, updateTrack, logOperation]); diff --git a/components/audio/DAW/Multitrack/TakesImportModal.js b/components/audio/DAW/Multitrack/TakesImportModal.js index 0ac2459..cef343a 100644 --- a/components/audio/DAW/Multitrack/TakesImportModal.js +++ b/components/audio/DAW/Multitrack/TakesImportModal.js @@ -17,8 +17,32 @@ export default function TakesImportModal({ show, onHide, takes = [] }) { useEffect(() => { if (!show || takes.length === 0) return; + const audioElements = []; + takes.forEach((take) => { if (take.duration > 0 || !take.audioURL || resolvedDurations[take.id] != null) return; + + // For proxy / HTTP URLs, resolve duration via fetch + AudioContext decode + // since