(state)
| 106 | } |
| 107 | |
| 108 | function applyState(state) { |
| 109 | if (state.job_id) { |
| 110 | addTrackToLibrary({ |
| 111 | id: state.job_id, |
| 112 | title: state.title || urlInput.value || "Processing track", |
| 113 | channel: state.status === "done" ? "Extracted" : "Processing", |
| 114 | thumb: state.thumbnail, |
| 115 | stems: state.selected_stems || state.stems?.map((stem) => stem.name) || [...selectedStems], |
| 116 | selectedStems: state.selected_stems || [...selectedStems], |
| 117 | audioStems: state.stems || [], |
| 118 | status: state.status, |
| 119 | duration: state.duration, |
| 120 | bpm: state.bpm, |
| 121 | key: state.key, |
| 122 | scale: state.scale, |
| 123 | keyConfidence: state.key_confidence, |
| 124 | lufs: state.lufs, |
| 125 | peakDb: state.peak_db, |
| 126 | stemPresence: state.stem_presence, |
| 127 | sourceUrl: jobSources.get(state.job_id) || urlInput.value, |
| 128 | createdAt: state.created_at, |
| 129 | }); |
| 130 | setCurrentTrack(state.job_id); |
| 131 | } |
| 132 | if (state.title) { |
| 133 | jobTitleEl.textContent = state.title; |
| 134 | titleEl.textContent = state.title; |
| 135 | } |
| 136 | if (state.bpm) bpmChip.textContent = `${state.bpm} BPM`; |
| 137 | if (state.key) keyChip.textContent = state.key; |
| 138 | if (state.title || state.bpm || state.key || state.thumbnail) { |
| 139 | updateFooterTrack({ |
| 140 | title: state.title, |
| 141 | thumbnail: state.thumbnail, |
| 142 | key: state.key, |
| 143 | bpm: state.bpm, |
| 144 | stemCount: state.stems ? state.stems.filter((s) => s.name !== "original").length : null, |
| 145 | }); |
| 146 | } |
| 147 | const summaryKey = document.getElementById("summary-key"); |
| 148 | const summaryBpm = document.getElementById("summary-bpm"); |
| 149 | const summaryScale = document.getElementById("summary-scale"); |
| 150 | const summaryScaleName = document.getElementById("summary-scale-name"); |
| 151 | const summaryConfidence = document.getElementById("summary-confidence"); |
| 152 | const summaryConfidenceLabel = document.getElementById("summary-confidence-label"); |
| 153 | const summaryLufs = document.getElementById("summary-lufs"); |
| 154 | const summaryPeak = document.getElementById("summary-peak"); |
| 155 | const summaryDuration = document.getElementById("summary-duration"); |
| 156 | if (summaryKey && state.key) summaryKey.textContent = state.key; |
| 157 | if (summaryBpm && state.bpm) summaryBpm.textContent = String(state.bpm); |
| 158 | if (summaryScale && state.scale) summaryScale.textContent = state.scale; |
| 159 | if (summaryScaleName && state.scale) summaryScaleName.textContent = state.scale; |
| 160 | if (summaryLufs && state.lufs != null) summaryLufs.textContent = state.lufs.toFixed(1); |
| 161 | if (summaryPeak && state.peak_db != null) summaryPeak.textContent = `Peak ${state.peak_db.toFixed(1)} dB`; |
| 162 | if (summaryDuration && state.duration) { |
| 163 | const m = Math.floor(state.duration / 60); |
| 164 | const s = Math.floor(state.duration % 60).toString().padStart(2, "0"); |
| 165 | summaryDuration.textContent = `${m.toString().padStart(2, "0")}:${s}`; |
no test coverage detected