Demo con contador de pasos e icono de detener, horas de sesión coherentes, IDs de sesión sin choques, URLs bloqueadas inertes, recortes de importación contados y sesionAGuion con deshacer
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
9a5f21badf
commit
c0b7d0c2ce
+56
-8
@@ -27,7 +27,42 @@ window.WAM = window.WAM || {};
|
||||
/* Mensajes de la sesión en curso (efímeros). */
|
||||
WAM.sesion = [];
|
||||
var contSesion = 0;
|
||||
function idSesion() { contSesion++; return "s" + contSesion; }
|
||||
|
||||
/* IDs del guion (mensajes, respuestas, botones, filas, cards) para que un
|
||||
ID de sesión nunca coincida con uno importado (p. ej. un guion con "s1"). */
|
||||
function idsDelGuion() {
|
||||
var usados = new Set();
|
||||
(function recorrer(o) {
|
||||
if (!o || typeof o !== "object") return;
|
||||
if (Array.isArray(o)) { for (var i = 0; i < o.length; i++) recorrer(o[i]); return; }
|
||||
if (typeof o.id === "string" && o.id) usados.add(o.id);
|
||||
["mensajes", "respuestas", "botones", "secciones", "filas", "cards"].forEach(function (k) {
|
||||
if (o[k] && typeof o[k] === "object") recorrer(o[k]);
|
||||
});
|
||||
})(WAM.estado);
|
||||
return usados;
|
||||
}
|
||||
|
||||
function idSesion() {
|
||||
var usados = WAM.estado ? idsDelGuion() : null;
|
||||
var id;
|
||||
do { contSesion++; id = "s" + contSesion; } while (usados && usados.has(id));
|
||||
return id;
|
||||
}
|
||||
|
||||
/* Hora para los mensajes de un flujo: la del último mensaje visible + 1 min,
|
||||
para que la línea temporal de la demo siga siendo coherente (si no hay
|
||||
ninguna hora legible, el reloj real). */
|
||||
function horaTras() {
|
||||
var metas = document.querySelectorAll("#chat-cuerpo .wa-row .meta");
|
||||
var t = null;
|
||||
for (var i = metas.length - 1; i >= 0 && !t; i--) {
|
||||
t = String(metas[i].textContent || "").match(/(\d{1,2}):(\d{2})/);
|
||||
}
|
||||
if (!t) return WAM.horaAhora();
|
||||
var min = (Number(t[1]) * 60 + Number(t[2]) + 1) % 1440;
|
||||
return ("0" + Math.floor(min / 60)).slice(-2) + ":" + ("0" + (min % 60)).slice(-2);
|
||||
}
|
||||
|
||||
/* ————————————————— temporizadores cancelables por grupo ————————————————— */
|
||||
|
||||
@@ -215,12 +250,12 @@ window.WAM = window.WAM || {};
|
||||
return pintar(msg);
|
||||
}
|
||||
|
||||
function mensajeOut(texto, cita) {
|
||||
function mensajeOut(texto, cita, hora) {
|
||||
var msg = {
|
||||
id: idSesion(),
|
||||
dir: "out",
|
||||
tipo: "text",
|
||||
hora: WAM.horaAhora(),
|
||||
hora: hora || WAM.horaAhora(),
|
||||
estado: "sent",
|
||||
texto: String(texto == null ? "" : texto)
|
||||
};
|
||||
@@ -243,7 +278,7 @@ window.WAM = window.WAM || {};
|
||||
if (TIPOS_VALIDOS.indexOf(copia.tipo) === -1) copia.tipo = "text";
|
||||
copia.id = idSesion();
|
||||
copia.dir = "in";
|
||||
copia.hora = WAM.horaAhora();
|
||||
copia.hora = horaTras();
|
||||
copia.estado = "sent";
|
||||
delete copia.cita;
|
||||
return copia;
|
||||
@@ -413,7 +448,7 @@ window.WAM = window.WAM || {};
|
||||
WAM.flujo = function (texto, respuestas, cita) {
|
||||
var lista = Array.isArray(respuestas) ? respuestas : [];
|
||||
var ctx = contexto("flujo");
|
||||
var out = mensajeOut(texto, cita || null);
|
||||
var out = mensajeOut(texto, cita || null, horaTras());
|
||||
anadirSesion(out);
|
||||
var tics = animarTics(out, ctx);
|
||||
tics.catch(nada);
|
||||
@@ -460,7 +495,8 @@ window.WAM = window.WAM || {};
|
||||
if (ds.btn !== undefined) {
|
||||
var n = parseInt(ds.btn, 10);
|
||||
var boton = (msg.botones || [])[n];
|
||||
if (!boton) return vacioR;
|
||||
/* botón de enlace con URL bloqueada: inerte, nunca un quick reply */
|
||||
if (!boton || boton.urlBloqueada) return vacioR;
|
||||
return {
|
||||
texto: vacio(boton.texto) ? "Botón " + (n + 1) : String(boton.texto),
|
||||
respuestas: boton.respuestas || [],
|
||||
@@ -472,7 +508,7 @@ window.WAM = window.WAM || {};
|
||||
if (ds.card !== undefined) {
|
||||
var c = parseInt(ds.card, 10);
|
||||
var card = (msg.cards || [])[c];
|
||||
if (!card) return vacioR;
|
||||
if (!card || card.urlBloqueada) return vacioR;
|
||||
return {
|
||||
texto: vacio(card.textoBoton) ? "Ver más" : String(card.textoBoton),
|
||||
respuestas: card.respuestas || [],
|
||||
@@ -509,11 +545,13 @@ window.WAM = window.WAM || {};
|
||||
return copia;
|
||||
});
|
||||
var n = nuevos.length;
|
||||
if (typeof WAM.puntoDeshacer === "function") { try { WAM.puntoDeshacer(); } catch (e) { /* opcional */ } }
|
||||
WAM.estado = WAM.normalizar ? WAM.normalizar({
|
||||
version: WAM.estado.version, tema: WAM.estado.tema, cuenta: WAM.estado.cuenta,
|
||||
mensajes: WAM.estado.mensajes.concat(nuevos)
|
||||
}) : WAM.estado;
|
||||
if (typeof WAM.guardar === "function") WAM.guardar();
|
||||
if (typeof WAM.marcarEditado === "function") { try { WAM.marcarEditado(); } catch (e) { /* opcional */ } }
|
||||
if (typeof WAM.render === "function") WAM.render();
|
||||
if (typeof WAM.renderEditor === "function") WAM.renderEditor();
|
||||
return n;
|
||||
@@ -594,7 +632,7 @@ window.WAM = window.WAM || {};
|
||||
|
||||
async function flujoEnDemo(sel, ctx) {
|
||||
if (!sel || !sel.msg) return;
|
||||
var out = mensajeOut(sel.texto, sel.cita);
|
||||
var out = mensajeOut(sel.texto, sel.cita, horaTras());
|
||||
anadirSesion(out);
|
||||
await animarTics(out, ctx);
|
||||
await responder(Array.isArray(sel.respuestas) ? sel.respuestas : [], ctx, true);
|
||||
@@ -609,6 +647,12 @@ window.WAM = window.WAM || {};
|
||||
}
|
||||
}
|
||||
|
||||
/* Progreso de la demo: mensajes del guion revelados / total. */
|
||||
var progreso = { paso: 0, total: 0 };
|
||||
WAM.progresoDemo = function () {
|
||||
return demoAndando ? { paso: progreso.paso, total: progreso.total } : { paso: 0, total: 0 };
|
||||
};
|
||||
|
||||
WAM.reproducirDemo = function () {
|
||||
if (demoAndando) return;
|
||||
/* aborta flujos, ticks y typing en curso: no se mezclan con la demo */
|
||||
@@ -621,6 +665,8 @@ window.WAM = window.WAM || {};
|
||||
vaciarChat();
|
||||
var ctx = contexto("demo");
|
||||
var secuencia = ((WAM.estado && WAM.estado.mensajes) || []).slice();
|
||||
progreso.paso = 0;
|
||||
progreso.total = secuencia.length;
|
||||
(async function () {
|
||||
try {
|
||||
for (var i = 0; i < secuencia.length; i++) {
|
||||
@@ -629,6 +675,8 @@ window.WAM = window.WAM || {};
|
||||
if (msg.dir === "in") await escribirDurante(ctx, 700);
|
||||
if (!ctx.vivo()) throw CANCELADO;
|
||||
pintar(msg);
|
||||
progreso.paso = i + 1;
|
||||
avisarDemo();
|
||||
await ctx.esperar(600);
|
||||
await autoPulsar(msg, ctx);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user