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;