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:
urieljareth
2026-09-27 21:09:42 -06:00
co-authored by Claude Opus 5.5
parent 9a5f21badf
commit c0b7d0c2ce
4 changed files with 189 additions and 26 deletions
+16 -3
View File
@@ -51,6 +51,8 @@ con `dir:"in"`, anidados, NO se renderizan en el chat: los consume la interactiv
Convenciones: `src`/`avatar`/`headerMedia`/`media` = dataURL o URL remota; `""` → placeholder SVG
de `WAM.svgPlaceholder(texto)`. Botones con `url` no vacía se renderizan como `<a target="_blank">`
(cta_url, template URL, card de carousel); sin `url` → flujo interactivo con `respuestas`.
Botón de plantilla o card con URL no permitida: `normalizar` deja `url: ""` y añade `urlBloqueada: true`
(sigue siendo un botón de enlace, inerte; nunca un quick reply con flujo; `resolverFlujo` lo ignora).
`WAM.normalizar(o)` rellena campos faltantes por tipo y devuelve el estado válido (import/upgrade).
Campo opcional `autoPulsar` (entero ≥ 0) en `template`/`buttons`/`list`/`carousel` (también en respuestas
anidadas): índice del botón, de la fila aplanada de la lista o de la card que «Reproducir demo» pulsa sola
@@ -72,7 +74,12 @@ cancela demo y flujos (interactivity.js envuelve `WAM.render`).
(main.js lo pinta con `WAM.avisar`) hasta el siguiente guardado correcto.
- `WAM.resetear()` → void (borra LS, estado = demo con IDs desde `m1`)
- `WAM.normalizar(o)` → estado (acepta un array de mensajes como raíz; IDs duplicados o inválidos se
reasignan; vacía URLs con esquema no permitido; respuestas string → text; conserva campos extra primitivos)
reasignan; vacía URLs con esquema no permitido; respuestas string → text; conserva campos extra primitivos).
Lo recortado (más de 500 mensajes, 10 botones/secciones/filas/cards, 20 respuestas o 12 niveles) queda en
`WAM.ultimosRecortes` y en `estado.__recortes` (no enumerable): `{ mensajes, mensajesOriginales, botones,
secciones, filas, cards, respuestas, profundidad }`.
- `WAM.describirRecortes(r?)` → string en español para el toast de importar («Se importaron 500 de 600
mensajes; se recortaron 3 respuestas…») o `""` si no se recortó nada (por defecto `WAM.ultimosRecortes`)
- `WAM.generarId()` → string (nunca repite un ID ya entregado aunque aún no esté en el estado)
- `WAM.crearAlocador(extra?)` → `function tomar()` que reparte IDs únicos frente al estado, a los ya
entregados y a los de `extra` (para clonar mensajes con respuestas anidadas)
@@ -154,9 +161,15 @@ cancela demo y flujos (interactivity.js envuelve `WAM.render`).
" + descripcion`.
- `WAM.mensajeDeElemento(el)` → Mensaje · `WAM.abrirLista(msg)` → abre la hoja (`abrirSheet(i | msg)`)
- `WAM.marcarUsado(el)` → clase `.usado` (gris, sin más clics) · `WAM.reiniciarChat()` (= `render()`)
- `WAM.sesionAGuion()` → n: añade la sesión al guion (acción explícita) + guardar + re-render
- `WAM.sesionAGuion()` → n: añade la sesión al guion (acción explícita) + `puntoDeshacer` + guardar +
`marcarEditado` + re-render
- Hora de la sesión: las salientes de un flujo y sus respuestas usan la hora del último mensaje visible
+ 1 min (línea temporal coherente con el guion); el composer libre usa `WAM.horaAhora()`. Los IDs de sesión
(`s1`, `s2`…) saltan los que ya existen en el guion.
- `WAM.getVelocidad()` / `WAM.setVelocidad(0.5|1|2)` (persistida en `wam-mockup-v1-velocidad`)
- `WAM.demoActiva()` → bool · hook opcional `WAM.onDemoChange(activa)`
- `WAM.demoActiva()` → bool · hook opcional `WAM.onDemoChange(activa)` (también se llama en cada paso)
- `WAM.progresoDemo()` → `{ paso, total }` (mensajes del guion revelados / total; `{0, 0}` sin demo).
main.js lo pinta en `#demo-paso` («Paso 3/12», `aria-live`) dentro de `#barra-movil`
- `WAM.reproducirDemo()` / `WAM.detenerDemo()` → void: cancela flujos en curso, vacía `#chat-cuerpo` y revela
`estado.mensajes` uno a uno (pulsando solas las opciones `autoPulsar`); detener vuelve al guion
(~600 ms; mensaje `in` precedido de typing ~700 ms; cancelable)