Spaces:
Running
Running
Commit ·
853c602
1
Parent(s): 06d670f
Show generate icon for ungenerated segments
Browse files- index.html +44 -23
index.html
CHANGED
|
@@ -391,6 +391,14 @@ body {
|
|
| 391 |
.ab-dl-one:hover { color: var(--text); border-color: var(--border-hover); }
|
| 392 |
.ab-dl-one svg { width: 13px; height: 13px; }
|
| 393 |
.ab-dl-one.busy { opacity: 0.5; pointer-events: none; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 394 |
.ab-join {
|
| 395 |
position: absolute; left: 28px; bottom: -9px; z-index: 5;
|
| 396 |
width: 20px; height: 18px; border-radius: 5px; border: 1px solid var(--border);
|
|
@@ -3794,24 +3802,7 @@ function renderAbRows() {
|
|
| 3794 |
para.addEventListener("keydown", (e) => abParaKeydown(e, i));
|
| 3795 |
para.addEventListener("paste", (e) => abParaPaste(e, i));
|
| 3796 |
|
| 3797 |
-
|
| 3798 |
-
const play = document.createElement("button");
|
| 3799 |
-
play.type = "button"; play.className = "ab-play-one"; play.title = "Generate & play this line";
|
| 3800 |
-
play.innerHTML = '<svg viewBox="0 0 24 24" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3"/></svg>';
|
| 3801 |
-
play.onclick = () => abGenOne(i);
|
| 3802 |
-
const dl = document.createElement("button");
|
| 3803 |
-
dl.type = "button"; dl.className = "ab-dl-one"; dl.title = "Download this segment";
|
| 3804 |
-
dl.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>';
|
| 3805 |
-
dl.onclick = () => abDownloadOne(i);
|
| 3806 |
-
const st = document.createElement("span");
|
| 3807 |
-
st.className = "ab-row-status " + (s.status === "idle" ? "" : s.status);
|
| 3808 |
-
st.textContent = s.status === "done" ? "✓" : s.status === "error" ? "✕" : s.status === "active" ? "…" : "";
|
| 3809 |
-
const del = document.createElement("button");
|
| 3810 |
-
del.type = "button"; del.className = "ab-row-del"; del.title = "Remove segment"; del.textContent = "✕";
|
| 3811 |
-
del.onclick = () => abRemoveRow(i);
|
| 3812 |
-
side.appendChild(play); side.appendChild(dl); side.appendChild(st); side.appendChild(del);
|
| 3813 |
-
|
| 3814 |
-
row.appendChild(chip); row.appendChild(para); row.appendChild(side);
|
| 3815 |
// "join with next" affordance between adjacent segments
|
| 3816 |
if (multi && i < abSegments.length - 1) {
|
| 3817 |
const join = document.createElement("button");
|
|
@@ -3826,12 +3817,42 @@ function renderAbRows() {
|
|
| 3826 |
abUpdateCounts();
|
| 3827 |
}
|
| 3828 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3829 |
function abSetRowStatus(i, status) {
|
| 3830 |
const row = document.querySelector(`.ab-row[data-i="${i}"]`);
|
| 3831 |
-
if (!row) return;
|
| 3832 |
-
|
| 3833 |
-
|
| 3834 |
-
|
| 3835 |
}
|
| 3836 |
|
| 3837 |
function abParaKeydown(e, i) {
|
|
@@ -4000,7 +4021,7 @@ window.abGenOne = async function(i) {
|
|
| 4000 |
const s = abSegments[i];
|
| 4001 |
if (!s || !s.text.trim()) return;
|
| 4002 |
const row = document.querySelector(`.ab-row[data-i="${i}"]`);
|
| 4003 |
-
const play = row?.querySelector(".ab-play-one");
|
| 4004 |
play?.classList.add("busy");
|
| 4005 |
try {
|
| 4006 |
const url = await abEnsureGen(i);
|
|
|
|
| 391 |
.ab-dl-one:hover { color: var(--text); border-color: var(--border-hover); }
|
| 392 |
.ab-dl-one svg { width: 13px; height: 13px; }
|
| 393 |
.ab-dl-one.busy { opacity: 0.5; pointer-events: none; }
|
| 394 |
+
.ab-gen-one {
|
| 395 |
+
width: 26px; height: 26px; border-radius: 6px; border: 1px solid var(--accent);
|
| 396 |
+
background: rgba(245,158,11,0.12); color: var(--accent); cursor: pointer; padding: 0;
|
| 397 |
+
display: flex; align-items: center; justify-content: center;
|
| 398 |
+
}
|
| 399 |
+
.ab-gen-one:hover { background: var(--accent); color: var(--btn-text); }
|
| 400 |
+
.ab-gen-one svg { width: 14px; height: 14px; }
|
| 401 |
+
.ab-gen-one.busy { opacity: 0.5; pointer-events: none; }
|
| 402 |
.ab-join {
|
| 403 |
position: absolute; left: 28px; bottom: -9px; z-index: 5;
|
| 404 |
width: 20px; height: 18px; border-radius: 5px; border: 1px solid var(--border);
|
|
|
|
| 3802 |
para.addEventListener("keydown", (e) => abParaKeydown(e, i));
|
| 3803 |
para.addEventListener("paste", (e) => abParaPaste(e, i));
|
| 3804 |
|
| 3805 |
+
row.appendChild(chip); row.appendChild(para); row.appendChild(buildRowSide(s, i));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3806 |
// "join with next" affordance between adjacent segments
|
| 3807 |
if (multi && i < abSegments.length - 1) {
|
| 3808 |
const join = document.createElement("button");
|
|
|
|
| 3817 |
abUpdateCounts();
|
| 3818 |
}
|
| 3819 |
|
| 3820 |
+
const ICON_PLAY = '<svg viewBox="0 0 24 24" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3"/></svg>';
|
| 3821 |
+
const ICON_DL = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>';
|
| 3822 |
+
const ICON_GEN = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 3l1.4 3.8L14.7 8l-3.8 1.2L9.5 13 8.1 9.2 4.3 8l3.8-1.2z"/><path d="M17.5 13l.9 2.4 2.4.9-2.4.9-.9 2.4-.9-2.4L14.2 16l2.4-.6z"/></svg>';
|
| 3823 |
+
|
| 3824 |
+
function mkRowBtn(cls, title, html, onclick) {
|
| 3825 |
+
const b = document.createElement("button");
|
| 3826 |
+
b.type = "button"; b.className = cls; b.title = title; b.innerHTML = html;
|
| 3827 |
+
b.onclick = onclick;
|
| 3828 |
+
return b;
|
| 3829 |
+
}
|
| 3830 |
+
|
| 3831 |
+
function buildRowSide(s, i) {
|
| 3832 |
+
const side = document.createElement("div"); side.className = "ab-row-side";
|
| 3833 |
+
if (s.status === "done" && s.url) {
|
| 3834 |
+
side.appendChild(mkRowBtn("ab-play-one", "Play this segment", ICON_PLAY, () => abGenOne(i)));
|
| 3835 |
+
side.appendChild(mkRowBtn("ab-dl-one", "Download this segment", ICON_DL, () => abDownloadOne(i)));
|
| 3836 |
+
} else {
|
| 3837 |
+
const gen = mkRowBtn("ab-gen-one", "Generate this segment", ICON_GEN, () => abGenOne(i));
|
| 3838 |
+
if (s.status === "active") gen.classList.add("busy");
|
| 3839 |
+
side.appendChild(gen);
|
| 3840 |
+
}
|
| 3841 |
+
const st = document.createElement("span");
|
| 3842 |
+
st.className = "ab-row-status " + (s.status === "idle" ? "" : s.status);
|
| 3843 |
+
st.textContent = s.status === "done" ? "✓" : s.status === "error" ? "✕" : s.status === "active" ? "…" : "";
|
| 3844 |
+
side.appendChild(st);
|
| 3845 |
+
side.appendChild(mkRowBtn("ab-row-del", "Remove segment", "", () => abRemoveRow(i)));
|
| 3846 |
+
side.lastChild.textContent = "✕";
|
| 3847 |
+
return side;
|
| 3848 |
+
}
|
| 3849 |
+
|
| 3850 |
function abSetRowStatus(i, status) {
|
| 3851 |
const row = document.querySelector(`.ab-row[data-i="${i}"]`);
|
| 3852 |
+
if (!row || !abSegments[i]) return;
|
| 3853 |
+
abSegments[i].status = status;
|
| 3854 |
+
const oldSide = row.querySelector(".ab-row-side");
|
| 3855 |
+
if (oldSide) row.replaceChild(buildRowSide(abSegments[i], i), oldSide);
|
| 3856 |
}
|
| 3857 |
|
| 3858 |
function abParaKeydown(e, i) {
|
|
|
|
| 4021 |
const s = abSegments[i];
|
| 4022 |
if (!s || !s.text.trim()) return;
|
| 4023 |
const row = document.querySelector(`.ab-row[data-i="${i}"]`);
|
| 4024 |
+
const play = row?.querySelector(".ab-gen-one, .ab-play-one");
|
| 4025 |
play?.classList.add("busy");
|
| 4026 |
try {
|
| 4027 |
const url = await abEnsureGen(i);
|