havre: hear / whisper on the same line as remember / remind / delete (and fresh replies get that line too)
ci / test (pull_request) Successful in 4s
ci / test (pull_request) Successful in 4s
This commit is contained in:
1 parent
2e86c329d4
commit
4a146969c4
1 file changed
+9
-7
@@ -1028,11 +1028,13 @@ function jumpTo(t, m) {
|
||||
}
|
||||
|
||||
// ---------- editing and deleting messages ----------
|
||||
function msgTools(el, t, m) {
|
||||
function msgTools(el, t, m, voice = []) {
|
||||
if (!t || !m || !m.id) return;
|
||||
el.dataset.msg = m.id;
|
||||
for (const old of $$(".msgtools", el)) old.remove();
|
||||
const c = cardOf(t), words = !!String(m.content || "").trim() && c && !c.plain && S.ab.memory;
|
||||
el.append(h("span", { class: "msgtools" }, ...slashed([
|
||||
...voice,
|
||||
m.role === "user" && !m.media ? linkish("edit", () => editMsg(t, m), { "aria-label": "Edit this message" }) : null,
|
||||
words ? linkish("remember", () => rememberMsg(t, m), { "aria-label": "Add this to what they remember", title: "into their memory, in these words" }) : null,
|
||||
words ? linkish("remind", () => remindMsg(t, m), { "aria-label": "Remind them of this at a time", title: "back to mind at a time you pick" }) : null,
|
||||
@@ -1122,7 +1124,7 @@ function renderLog() {
|
||||
if (m.voice) put(voiceLine(c, m));
|
||||
let last = null;
|
||||
for (const b of bubblesOf(c, m.content)) { last = put(line(b, "them")); if (m.id) last.dataset.msg = m.id; }
|
||||
if (last) { offerVoice(last, c, m, t); msgTools(last, t, m); }
|
||||
if (last) msgTools(last, t, m, offerVoice(last, c, m, t));
|
||||
}
|
||||
}
|
||||
const ideas = hist.some((m) => m.role === "user" && !m.hidden) ? [] : C.suggestions(c);
|
||||
@@ -1376,7 +1378,7 @@ async function play(t, bubbles, signal, c, msg, drawn = S.gen) {
|
||||
if (msg && msg.id) last.dataset.msg = msg.id;
|
||||
scrollLog();
|
||||
}
|
||||
if (last && c && msg) offerVoice(last, c, msg, t);
|
||||
if (last && c && msg) msgTools(last, t, msg, offerVoice(last, c, msg, t));
|
||||
}
|
||||
|
||||
// ---------- photos, clips, voice notes, and yours, in the conversation ----------
|
||||
@@ -1446,7 +1448,7 @@ function voiceLine(c, m) {
|
||||
/** "hear it" after a reply that came as text: its voice note, made when asked for (once, however often it's clicked) */
|
||||
const voicing = new WeakSet();
|
||||
function offerVoice(el, c, m, t) {
|
||||
if (m.voice || m.demo || c.plain || !S.key || !t) return;
|
||||
if (m.voice || m.demo || c.plain || !S.key || !t) return [];
|
||||
const btns = [];
|
||||
const make = (label, asmr) => {
|
||||
const b = linkish(voicing.has(m) ? "recording…" : label, async () => {
|
||||
@@ -1457,15 +1459,15 @@ function offerVoice(el, c, m, t) {
|
||||
try {
|
||||
m.voice = await makeVoice(c, m.content, undefined, { asmr });
|
||||
saveThread(t);
|
||||
if (b.isConnected) { b.replaceWith(audioEl(m.voice.id)); for (const x of btns) if (x !== b) x.remove(); }
|
||||
else placeVoice(t, m);
|
||||
placeVoice(t, m); // the voice note goes above the words
|
||||
if (el.isConnected) msgTools(el, t, m); // and the line under them loses hear / whisper
|
||||
balanceSoon();
|
||||
} catch (e) { for (const x of btns) x.disabled = false; b.textContent = label; toast(e.message); } finally { voicing.delete(m); }
|
||||
}, { class: "linkish hear", "aria-label": asmr ? `Hear this whispered by ${c.name}, over soft rain` : `Hear this as a voice note from ${c.name}`, disabled: voicing.has(m) || null });
|
||||
btns.push(b);
|
||||
return b;
|
||||
};
|
||||
$(".said", el).append(" ", make("hear it", false), " ", make("whisper it", true));
|
||||
return [make("hear", false), make("whisper", true)];
|
||||
}
|
||||
/** a voice note of these words, in the character's voice and mood */
|
||||
async function makeVoice(c, text, signal, { asmr = false } = {}) {
|
||||
|
||||
Reference in new issue
Block a user