diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js index 0d2c435..5fecd57 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js @@ -5914,10 +5914,11 @@ function renderRecorderFiles() { for (const f of page) { const safeName = escapeMapHtml(f.name); const encodedName = encodeURIComponent(f.name); - html += "" + html += '' + "" + safeName + "" + "" + recorderFormatSize(f.size) + "" + '
' + + '' + 'Download' + '' + "
"; @@ -5925,6 +5926,47 @@ function renderRecorderFiles() { html += ""; el.innerHTML = html; + el.querySelectorAll(".rec-play-btn").forEach(function (btn) { + btn.addEventListener("click", function () { + const row = btn.closest("tr"); + if (!row) return; + const next = row.nextElementSibling; + if (next && next.classList.contains("rec-player-row")) { + const audio = next.querySelector("audio"); + if (audio) { try { audio.pause(); } catch (_) {} } + next.remove(); + btn.setAttribute("aria-expanded", "false"); + btn.textContent = "Play"; + return; + } + // Close any other open player. + el.querySelectorAll(".rec-player-row").forEach(function (r) { + const a = r.querySelector("audio"); + if (a) { try { a.pause(); } catch (_) {} } + r.remove(); + }); + el.querySelectorAll(".rec-play-btn").forEach(function (b) { + b.setAttribute("aria-expanded", "false"); + b.textContent = "Play"; + }); + const playerRow = document.createElement("tr"); + playerRow.className = "rec-player-row"; + const cell = document.createElement("td"); + cell.colSpan = 3; + const audio = document.createElement("audio"); + audio.controls = true; + audio.preload = "metadata"; + audio.src = btn.dataset.url; + audio.className = "rec-player-audio"; + cell.appendChild(audio); + playerRow.appendChild(cell); + row.parentNode.insertBefore(playerRow, row.nextSibling); + btn.setAttribute("aria-expanded", "true"); + btn.textContent = "Hide"; + try { audio.play(); } catch (_) {} + }); + }); + el.querySelectorAll(".rec-delete-btn").forEach(function (btn) { btn.addEventListener("click", async function () { const name = btn.dataset.name; diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css index 8ff986e..8655362 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css @@ -1279,6 +1279,18 @@ small { color: var(--text-muted); } .recorder-table .rec-file-btn:active { background: color-mix(in srgb, var(--btn-bg) 55%, var(--accent-green)); border-color: var(--accent-green); box-shadow: none; transform: translateY(1px); } .recorder-table .rec-file-btn.rec-delete-btn { color: var(--accent-red); border-color: var(--accent-red); } .recorder-table .rec-file-btn.rec-delete-btn:hover { background: color-mix(in srgb, var(--btn-bg) 75%, var(--accent-red)); border-color: var(--accent-red); box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent-red) 18%, transparent); } +.recorder-table tr.rec-player-row > td { + padding: 0.4rem 0.6rem 0.6rem; + background: color-mix(in srgb, var(--btn-bg) 55%, transparent); + border-top: 0; +} +.recorder-table .rec-player-audio { + display: block; + width: 100%; + height: 2.1rem; + border-radius: 0.25rem; + outline: none; +} .recorder-page-bar { display: flex; align-items: center;