docs(demo): la vidéo montre le thème et le format des statsUnverified
Pendant que le minuteur tourne, un détour d'une trentaine de secondes par les Réglages : bascule en contraste élevé, puis les mêmes statistiques revues en barres horizontales et en colonnes empilées, avant de rendre le thème par défaut à la suite du film. Le dock du minuteur reste à l'écran d'un bout à l'autre — la scène le démontre au passage, et allonge d'autant la mesure que la fin enregistre. Les boutons d'apparence sont désignés par la valeur postée et non par leur libellé, qui suit la langue du compte de démo. video-reset.sql remet alex et lou en organic/columns : une prise interrompue en pleine scène les laisserait en contraste élevé.
bc023fd parent: 8c08a86 modified
docs/slides/demo/video-reset.sql +6 -0 | @@ -31,4 +31,10 @@ DELETE FROM timers WHERE team_id = (SELECT id FROM teams WHERE name = 'Chez nous | ||
| 31 | 31 | -- Invitations reçues : elles poseraient un badge sur l'onglet Réglages. |
| 32 | 32 | DELETE FROM invitations WHERE invitee_id IN (SELECT id FROM users WHERE username IN ('alex', 'lou')); |
| 33 | 33 | |
| 34 | +-- Apparence : la scène « Apparence » bascule alex en contraste élevé et en | |
| 35 | +-- barres horizontales avant de rendre le thème par défaut. Une prise | |
| 36 | +-- interrompue le laisserait dans cet état — on repart toujours d'Organic. | |
| 37 | +UPDATE users SET theme = 'organic', stats_layout = 'columns' | |
| 38 | + WHERE username IN ('alex', 'lou'); | |
| 39 | + | |
| 34 | 40 | COMMIT; |
| @@ -31,4 +31,10 @@ DELETE FROM timers WHERE team_id = (SELECT id FROM teams WHERE name = 'Chez nous | |||
| 31 | -- Invitations reçues : elles poseraient un badge sur l'onglet Réglages. | 31 | -- Invitations reçues : elles poseraient un badge sur l'onglet Réglages. |
| 32 | DELETE FROM invitations WHERE invitee_id IN (SELECT id FROM users WHERE username IN ('alex', 'lou')); | 32 | DELETE FROM invitations WHERE invitee_id IN (SELECT id FROM users WHERE username IN ('alex', 'lou')); |
| 33 | 33 | ||
| 34 | +-- Apparence : la scène « Apparence » bascule alex en contraste élevé et en | ||
| 35 | +-- barres horizontales avant de rendre le thème par défaut. Une prise | ||
| 36 | +-- interrompue le laisserait dans cet état — on repart toujours d'Organic. | ||
| 37 | +UPDATE users SET theme = 'organic', stats_layout = 'columns' | ||
| 38 | + WHERE username IN ('alex', 'lou'); | ||
| 39 | + | ||
| 34 | COMMIT; | 40 | COMMIT; |
modified
docs/slides/demo/video.mjs +40 -7 | @@ -63,6 +63,7 @@ const SCENE = 2500; // changement d'écran : place pour un commentaire | ||
| 63 | 63 | const TOAST = 1900; // durée de vie du toast (tt-fade : 1,5 s + 0,4 s) |
| 64 | 64 | const KEY = 95; // délai entre deux frappes clavier |
| 65 | 65 | const DWELL = 2400; // scène des tâches : on prend son temps, le minuteur tourne |
| 66 | +const QUICK = 850; // détour d'apparence : on montre, on ne s'attarde pas | |
| 66 | 67 | const GLIDE = 420; // déplacement du curseur d'une cible à l'autre |
| 67 | 68 | |
| 68 | 69 | // ────────────────────────────────────────────── curseur tactile incrusté |
| @@ -300,6 +301,15 @@ async function tab(name, { pause = SCENE } = {}) { | ||
| 300 | 301 | await tap(`.tabbar a[href="${TAB[name]}"]`, { nav: true, fixed: true, pause }); |
| 301 | 302 | } |
| 302 | 303 | |
| 304 | +/** | |
| 305 | + * Bouton d'un réglage d'apparence (« Affichage » et « Graphiques » partagent | |
| 306 | + * la classe `.theme-choice`). On le désigne par la valeur postée, jamais par | |
| 307 | + * son libellé : celui-ci suit la langue du compte de démo. | |
| 308 | + */ | |
| 309 | +function look(action, value) { | |
| 310 | + return `form[action="/parametres/${action}"]:has(input[value="${value}"]) .theme-choice`; | |
| 311 | +} | |
| 312 | + | |
| 303 | 313 | function scene(title) { |
| 304 | 314 | console.log(`▸ ${title}`); |
| 305 | 315 | } |
| @@ -430,7 +440,29 @@ try { | ||
| 430 | 440 | await tab('add', { pause: READ }); |
| 431 | 441 | await tap('.choice-timer', { nav: true, pause: 5000 }); // les secondes défilent |
| 432 | 442 | |
| 433 | - // ─── 7. Créer des tâches (le minuteur tourne pendant ce temps) ────────── | |
| 443 | + // ─── 7. Apparence : thème et format des stats ─────────────────────────── | |
| 444 | + // Détour rapide pendant que le minuteur tourne — son dock reste à l'écran | |
| 445 | + // d'un bout à l'autre, ce que la scène montre au passage. Les mêmes | |
| 446 | + // statistiques sont revues dans les deux formats, en contraste élevé, puis | |
| 447 | + // on rend le thème par défaut à la suite du film. | |
| 448 | + scene('Apparence'); | |
| 449 | + await tab('settings', { pause: QUICK }); | |
| 450 | + await tap(look('affichage', 'hc'), { nav: true, pause: READ }); // tout bascule en noir et blanc | |
| 451 | + await tap(look('graphiques', 'rows'), { nav: true, pause: QUICK }); | |
| 452 | + | |
| 453 | + await tab('stats', { pause: READ }); // barres horizontales | |
| 454 | + await scrollThrough({ max: 2, pause: 1100 }); | |
| 455 | + | |
| 456 | + await tab('settings', { pause: QUICK }); | |
| 457 | + await tap(look('graphiques', 'columns'), { nav: true, pause: QUICK }); | |
| 458 | + await tab('stats', { pause: READ }); // mêmes données, colonnes empilées | |
| 459 | + await scrollThrough({ max: 1, pause: 1100 }); // « À la journée », le même bloc qu'en lignes | |
| 460 | + await sleep(READ); | |
| 461 | + | |
| 462 | + await tab('settings', { pause: QUICK }); | |
| 463 | + await tap(look('affichage', 'organic'), { nav: true, pause: READ }); | |
| 464 | + | |
| 465 | + // ─── 8. Créer des tâches (le minuteur tourne pendant ce temps) ────────── | |
| 434 | 466 | scene('Tâches'); |
| 435 | 467 | await tab('todos'); |
| 436 | 468 | |
| @@ -441,8 +473,9 @@ try { | ||
| 441 | 473 | { nom: 'Passer l’aspirateur', cat: 'Ménage', assigne: 'lou' }, |
| 442 | 474 | { nom: 'Trier le courrier', cat: 'Administratif', assigne: null }, |
| 443 | 475 | ]; |
| 444 | - // La scène est volontairement posée : c'est elle qui fait tourner le | |
| 445 | - // minuteur, et la mesure enregistrée à la fin doit être crédible. | |
| 476 | + // La scène est volontairement posée : c'est elle qui, avec le détour | |
| 477 | + // d'apparence, fait tourner le minuteur — la mesure enregistrée à la fin | |
| 478 | + // doit être crédible. | |
| 446 | 479 | for (const t of taches) { |
| 447 | 480 | await tap('a[href="/taches/nouvelle"]', { nav: true, pause: SCENE }); |
| 448 | 481 | await fill('#todo-nom', t.nom, { pause: DWELL }); |
| @@ -457,16 +490,16 @@ try { | ||
| 457 | 490 | await tap('.blk-toggle', { nav: true, pause: 3600 }); |
| 458 | 491 | await tap('.blk-toggle', { nav: true, pause: 3600 }); |
| 459 | 492 | |
| 460 | - // ─── 8. Arrêter le minuteur depuis la pill ────────────────────────────── | |
| 493 | + // ─── 9. Arrêter le minuteur depuis la pill ────────────────────────────── | |
| 461 | 494 | scene('Arrêt du minuteur'); |
| 462 | - await tap('.timer-banner.timer-running', { nav: true, fixed: true, pause: SCENE }); | |
| 495 | + await tap('.timer-dock .timer-btn', { nav: true, fixed: true, pause: SCENE }); | |
| 463 | 496 | |
| 464 | - // ─── 9. Ranger la mesure dans une catégorie ───────────────────────────── | |
| 497 | + // ─── 10. Ranger la mesure dans une catégorie ───────────────────────────── | |
| 465 | 498 | scene('Enregistrement de la mesure'); |
| 466 | 499 | await tap('.category-pick a', { text: 'Ménage', nav: true, pause: SCENE }); |
| 467 | 500 | await tap('form[data-duration] button[type="submit"]', { nav: true, pause: TOAST }); |
| 468 | 501 | |
| 469 | - // ─── 10. Plan de fin sur les stats ────────────────────────────────────── | |
| 502 | + // ─── 11. Plan de fin sur les stats ────────────────────────────────────── | |
| 470 | 503 | scene('Plan de fin'); |
| 471 | 504 | await tab('stats', { pause: SCENE }); |
| 472 | 505 | await moveTo(195, 880, 700); // le curseur sort du cadre |
| @@ -63,6 +63,7 @@ const SCENE = 2500; // changement d'écran : place pour un commentaire | |||
| 63 | const TOAST = 1900; // durée de vie du toast (tt-fade : 1,5 s + 0,4 s) | 63 | const TOAST = 1900; // durée de vie du toast (tt-fade : 1,5 s + 0,4 s) |
| 64 | const KEY = 95; // délai entre deux frappes clavier | 64 | const KEY = 95; // délai entre deux frappes clavier |
| 65 | const DWELL = 2400; // scène des tâches : on prend son temps, le minuteur tourne | 65 | const DWELL = 2400; // scène des tâches : on prend son temps, le minuteur tourne |
| 66 | +const QUICK = 850; // détour d'apparence : on montre, on ne s'attarde pas | ||
| 66 | const GLIDE = 420; // déplacement du curseur d'une cible à l'autre | 67 | const GLIDE = 420; // déplacement du curseur d'une cible à l'autre |
| 67 | 68 | ||
| 68 | // ────────────────────────────────────────────── curseur tactile incrusté | 69 | // ────────────────────────────────────────────── curseur tactile incrusté |
| @@ -300,6 +301,15 @@ async function tab(name, { pause = SCENE } = {}) { | |||
| 300 | await tap(`.tabbar a[href="${TAB[name]}"]`, { nav: true, fixed: true, pause }); | 301 | await tap(`.tabbar a[href="${TAB[name]}"]`, { nav: true, fixed: true, pause }); |
| 301 | } | 302 | } |
| 302 | 303 | ||
| 304 | +/** | ||
| 305 | + * Bouton d'un réglage d'apparence (« Affichage » et « Graphiques » partagent | ||
| 306 | + * la classe `.theme-choice`). On le désigne par la valeur postée, jamais par | ||
| 307 | + * son libellé : celui-ci suit la langue du compte de démo. | ||
| 308 | + */ | ||
| 309 | +function look(action, value) { | ||
| 310 | + return `form[action="/parametres/${action}"]:has(input[value="${value}"]) .theme-choice`; | ||
| 311 | +} | ||
| 312 | + | ||
| 303 | function scene(title) { | 313 | function scene(title) { |
| 304 | console.log(`▸ ${title}`); | 314 | console.log(`▸ ${title}`); |
| 305 | } | 315 | } |
| @@ -430,7 +440,29 @@ try { | |||
| 430 | await tab('add', { pause: READ }); | 440 | await tab('add', { pause: READ }); |
| 431 | await tap('.choice-timer', { nav: true, pause: 5000 }); // les secondes défilent | 441 | await tap('.choice-timer', { nav: true, pause: 5000 }); // les secondes défilent |
| 432 | 442 | ||
| 433 | - // ─── 7. Créer des tâches (le minuteur tourne pendant ce temps) ────────── | 443 | + // ─── 7. Apparence : thème et format des stats ─────────────────────────── |
| 444 | + // Détour rapide pendant que le minuteur tourne — son dock reste à l'écran | ||
| 445 | + // d'un bout à l'autre, ce que la scène montre au passage. Les mêmes | ||
| 446 | + // statistiques sont revues dans les deux formats, en contraste élevé, puis | ||
| 447 | + // on rend le thème par défaut à la suite du film. | ||
| 448 | + scene('Apparence'); | ||
| 449 | + await tab('settings', { pause: QUICK }); | ||
| 450 | + await tap(look('affichage', 'hc'), { nav: true, pause: READ }); // tout bascule en noir et blanc | ||
| 451 | + await tap(look('graphiques', 'rows'), { nav: true, pause: QUICK }); | ||
| 452 | + | ||
| 453 | + await tab('stats', { pause: READ }); // barres horizontales | ||
| 454 | + await scrollThrough({ max: 2, pause: 1100 }); | ||
| 455 | + | ||
| 456 | + await tab('settings', { pause: QUICK }); | ||
| 457 | + await tap(look('graphiques', 'columns'), { nav: true, pause: QUICK }); | ||
| 458 | + await tab('stats', { pause: READ }); // mêmes données, colonnes empilées | ||
| 459 | + await scrollThrough({ max: 1, pause: 1100 }); // « À la journée », le même bloc qu'en lignes | ||
| 460 | + await sleep(READ); | ||
| 461 | + | ||
| 462 | + await tab('settings', { pause: QUICK }); | ||
| 463 | + await tap(look('affichage', 'organic'), { nav: true, pause: READ }); | ||
| 464 | + | ||
| 465 | + // ─── 8. Créer des tâches (le minuteur tourne pendant ce temps) ────────── | ||
| 434 | scene('Tâches'); | 466 | scene('Tâches'); |
| 435 | await tab('todos'); | 467 | await tab('todos'); |
| 436 | 468 | ||
| @@ -441,8 +473,9 @@ try { | |||
| 441 | { nom: 'Passer l’aspirateur', cat: 'Ménage', assigne: 'lou' }, | 473 | { nom: 'Passer l’aspirateur', cat: 'Ménage', assigne: 'lou' }, |
| 442 | { nom: 'Trier le courrier', cat: 'Administratif', assigne: null }, | 474 | { nom: 'Trier le courrier', cat: 'Administratif', assigne: null }, |
| 443 | ]; | 475 | ]; |
| 444 | - // La scène est volontairement posée : c'est elle qui fait tourner le | 476 | + // La scène est volontairement posée : c'est elle qui, avec le détour |
| 445 | - // minuteur, et la mesure enregistrée à la fin doit être crédible. | 477 | + // d'apparence, fait tourner le minuteur — la mesure enregistrée à la fin |
| 478 | + // doit être crédible. | ||
| 446 | for (const t of taches) { | 479 | for (const t of taches) { |
| 447 | await tap('a[href="/taches/nouvelle"]', { nav: true, pause: SCENE }); | 480 | await tap('a[href="/taches/nouvelle"]', { nav: true, pause: SCENE }); |
| 448 | await fill('#todo-nom', t.nom, { pause: DWELL }); | 481 | await fill('#todo-nom', t.nom, { pause: DWELL }); |
| @@ -457,16 +490,16 @@ try { | |||
| 457 | await tap('.blk-toggle', { nav: true, pause: 3600 }); | 490 | await tap('.blk-toggle', { nav: true, pause: 3600 }); |
| 458 | await tap('.blk-toggle', { nav: true, pause: 3600 }); | 491 | await tap('.blk-toggle', { nav: true, pause: 3600 }); |
| 459 | 492 | ||
| 460 | - // ─── 8. Arrêter le minuteur depuis la pill ────────────────────────────── | 493 | + // ─── 9. Arrêter le minuteur depuis la pill ────────────────────────────── |
| 461 | scene('Arrêt du minuteur'); | 494 | scene('Arrêt du minuteur'); |
| 462 | - await tap('.timer-banner.timer-running', { nav: true, fixed: true, pause: SCENE }); | 495 | + await tap('.timer-dock .timer-btn', { nav: true, fixed: true, pause: SCENE }); |
| 463 | 496 | ||
| 464 | - // ─── 9. Ranger la mesure dans une catégorie ───────────────────────────── | 497 | + // ─── 10. Ranger la mesure dans une catégorie ───────────────────────────── |
| 465 | scene('Enregistrement de la mesure'); | 498 | scene('Enregistrement de la mesure'); |
| 466 | await tap('.category-pick a', { text: 'Ménage', nav: true, pause: SCENE }); | 499 | await tap('.category-pick a', { text: 'Ménage', nav: true, pause: SCENE }); |
| 467 | await tap('form[data-duration] button[type="submit"]', { nav: true, pause: TOAST }); | 500 | await tap('form[data-duration] button[type="submit"]', { nav: true, pause: TOAST }); |
| 468 | 501 | ||
| 469 | - // ─── 10. Plan de fin sur les stats ────────────────────────────────────── | 502 | + // ─── 11. Plan de fin sur les stats ────────────────────────────────────── |
| 470 | scene('Plan de fin'); | 503 | scene('Plan de fin'); |
| 471 | await tab('stats', { pause: SCENE }); | 504 | await tab('stats', { pause: SCENE }); |
| 472 | await moveTo(195, 880, 700); // le curseur sort du cadre | 505 | await moveTo(195, 880, 700); // le curseur sort du cadre |