3v324v23 commited on
Commit
d56a8bd
·
1 Parent(s): 4492f35

Ajout des commentaires sur le js

Browse files
Files changed (1) hide show
  1. jericho/static/main.js +20 -0
jericho/static/main.js CHANGED
@@ -9,6 +9,7 @@ const videoPlayer = document.getElementById('video-player');
9
  videoPlayer.muted = true;
10
  videoPlayer.defaultMuted = true;
11
 
 
12
  function escapeHtml(value) {
13
  return String(value)
14
  .replaceAll('&', '&')
@@ -18,6 +19,7 @@ function escapeHtml(value) {
18
  .replaceAll("'", ''');
19
  }
20
 
 
21
  async function sendPlayback(action, options = {}) {
22
  const projectName = options.projectName || currentLoadedProject;
23
  if (!projectName) return;
@@ -47,6 +49,7 @@ async function sendPlayback(action, options = {}) {
47
  }
48
  }
49
 
 
50
  function startSyncLoop() {
51
  stopSyncLoop();
52
  syncTimer = setInterval(() => {
@@ -56,6 +59,7 @@ function startSyncLoop() {
56
  }, SYNC_INTERVAL_MS);
57
  }
58
 
 
59
  function stopSyncLoop() {
60
  if (syncTimer) {
61
  clearInterval(syncTimer);
@@ -63,6 +67,7 @@ function stopSyncLoop() {
63
  }
64
  }
65
 
 
66
  document.addEventListener('DOMContentLoaded', () => {
67
  loadLibrary();
68
  setInterval(loadLibrary, 3000);
@@ -92,6 +97,7 @@ document.addEventListener('DOMContentLoaded', () => {
92
  });
93
  });
94
 
 
95
  document.getElementById('import-btn').onclick = function() {
96
  const name = document.getElementById('video-name').value.trim();
97
  const file = document.getElementById('video-file').files[0];
@@ -110,6 +116,7 @@ document.getElementById('import-btn').onclick = function() {
110
  const reader = new FileReader();
111
  reader.readAsDataURL(file);
112
 
 
113
  reader.onload = async function () {
114
  const base64data = reader.result;
115
 
@@ -140,6 +147,7 @@ document.getElementById('import-btn').onclick = function() {
140
  };
141
  };
142
 
 
143
  document.getElementById('yt-import-btn').onclick = async function() {
144
  const name = document.getElementById('yt-name').value.trim();
145
  const url = document.getElementById('yt-url').value.trim();
@@ -181,6 +189,7 @@ document.getElementById('yt-import-btn').onclick = async function() {
181
  }
182
  };
183
 
 
184
  window.deleteProject = async function(event, name) {
185
  event.stopPropagation();
186
 
@@ -212,6 +221,7 @@ window.deleteProject = async function(event, name) {
212
  }
213
  };
214
 
 
215
  async function loadLibrary() {
216
  try {
217
  const response = await fetch('/api/library');
@@ -276,6 +286,7 @@ async function loadLibrary() {
276
  }
277
  }
278
 
 
279
  window.loadVideoPlayer = async function(name, url) {
280
  if (currentLoadedProject && currentLoadedProject !== name) {
281
  await sendPlayback('stop', { projectName: currentLoadedProject, playing: false });
@@ -311,6 +322,7 @@ window.loadVideoPlayer = async function(name, url) {
311
  }
312
  };
313
 
 
314
  videoPlayer.addEventListener('play', () => {
315
  if (!currentLoadedProject) return;
316
  robotStatus.textContent = 'Lecture synchronisée — audio robot';
@@ -318,6 +330,7 @@ videoPlayer.addEventListener('play', () => {
318
  startSyncLoop();
319
  });
320
 
 
321
  videoPlayer.addEventListener('pause', () => {
322
  if (!currentLoadedProject || videoPlayer.ended) return;
323
  robotStatus.textContent = 'En pause';
@@ -325,26 +338,31 @@ videoPlayer.addEventListener('pause', () => {
325
  stopSyncLoop();
326
  });
327
 
 
328
  videoPlayer.addEventListener('seeking', () => {
329
  if (!currentLoadedProject) return;
330
  sendPlayback('seek', { playing: !videoPlayer.paused && !videoPlayer.ended });
331
  });
332
 
 
333
  videoPlayer.addEventListener('seeked', () => {
334
  if (!currentLoadedProject) return;
335
  sendPlayback('seek', { playing: !videoPlayer.paused && !videoPlayer.ended });
336
  });
337
 
 
338
  videoPlayer.addEventListener('timeupdate', () => {
339
  // synchro geree par startSyncLoop(), ici pas de double envoi
340
  });
341
 
 
342
  videoPlayer.addEventListener('ended', () => {
343
  robotStatus.textContent = 'Terminé';
344
  sendPlayback('stop', { playing: false });
345
  stopSyncLoop();
346
  });
347
 
 
348
  function createEmotionRow() {
349
  const row = document.createElement('div');
350
  row.className = 'emotion-row';
@@ -390,6 +408,7 @@ function createEmotionRow() {
390
  document.getElementById('sequence-list').appendChild(row);
391
  }
392
 
 
393
  document.addEventListener('DOMContentLoaded', () => {
394
  const addEmotionBtn = document.getElementById('add-emotion-btn');
395
  if(addEmotionBtn) {
@@ -408,6 +427,7 @@ document.addEventListener('DOMContentLoaded', () => {
408
  }
409
  });
410
 
 
411
  document.getElementById('save-seq-btn').onclick = async function() {
412
  const name = document.getElementById('seq-name').value.trim();
413
  const msg = document.getElementById('seq-msg');
 
9
  videoPlayer.muted = true;
10
  videoPlayer.defaultMuted = true;
11
 
12
+ // Sécurise le texte pour éviter les bugs d'affichage si le nom de la vidéo contient des caractères bizarres
13
  function escapeHtml(value) {
14
  return String(value)
15
  .replaceAll('&', '&')
 
19
  .replaceAll("'", ''');
20
  }
21
 
22
+ // Envoie l'état actuel de la vidéo (temps précis, si elle est en lecture ou pause) au serveur Python
23
  async function sendPlayback(action, options = {}) {
24
  const projectName = options.projectName || currentLoadedProject;
25
  if (!projectName) return;
 
49
  }
50
  }
51
 
52
+ // Lance le chronomètre qui synchronise la vidéo avec le robot (s'active 2 fois par seconde)
53
  function startSyncLoop() {
54
  stopSyncLoop();
55
  syncTimer = setInterval(() => {
 
59
  }, SYNC_INTERVAL_MS);
60
  }
61
 
62
+ // Arrête le chronomètre de synchronisation
63
  function stopSyncLoop() {
64
  if (syncTimer) {
65
  clearInterval(syncTimer);
 
67
  }
68
  }
69
 
70
+ // Initialisation au chargement de la page web : lance la bibliothèque et prépare les boutons d'émotions
71
  document.addEventListener('DOMContentLoaded', () => {
72
  loadLibrary();
73
  setInterval(loadLibrary, 3000);
 
97
  });
98
  });
99
 
100
+ // Gère l'envoi d'un fichier vidéo local depuis l'ordinateur vers le serveur
101
  document.getElementById('import-btn').onclick = function() {
102
  const name = document.getElementById('video-name').value.trim();
103
  const file = document.getElementById('video-file').files[0];
 
116
  const reader = new FileReader();
117
  reader.readAsDataURL(file);
118
 
119
+ // S'exécute quand la vidéo est transformée en texte (Base64) et prête à partir
120
  reader.onload = async function () {
121
  const base64data = reader.result;
122
 
 
147
  };
148
  };
149
 
150
+ // Gère l'envoi d'un lien YouTube au serveur pour qu'il le télécharge
151
  document.getElementById('yt-import-btn').onclick = async function() {
152
  const name = document.getElementById('yt-name').value.trim();
153
  const url = document.getElementById('yt-url').value.trim();
 
189
  }
190
  };
191
 
192
+ // Demande au serveur de supprimer définitivement un projet
193
  window.deleteProject = async function(event, name) {
194
  event.stopPropagation();
195
 
 
221
  }
222
  };
223
 
224
+ // Interroge le serveur pour récupérer la liste des vidéos et met à jour l'affichage
225
  async function loadLibrary() {
226
  try {
227
  const response = await fetch('/api/library');
 
286
  }
287
  }
288
 
289
+ // Charge la vidéo cliquée dans le lecteur principal et réinitialise l'affichage
290
  window.loadVideoPlayer = async function(name, url) {
291
  if (currentLoadedProject && currentLoadedProject !== name) {
292
  await sendPlayback('stop', { projectName: currentLoadedProject, playing: false });
 
322
  }
323
  };
324
 
325
+ // Prévient le serveur quand l'utilisateur clique sur Lecture
326
  videoPlayer.addEventListener('play', () => {
327
  if (!currentLoadedProject) return;
328
  robotStatus.textContent = 'Lecture synchronisée — audio robot';
 
330
  startSyncLoop();
331
  });
332
 
333
+ // Prévient le serveur quand l'utilisateur met la vidéo en pause
334
  videoPlayer.addEventListener('pause', () => {
335
  if (!currentLoadedProject || videoPlayer.ended) return;
336
  robotStatus.textContent = 'En pause';
 
338
  stopSyncLoop();
339
  });
340
 
341
+ // Prévient le serveur quand on clique sur la barre d'avancement pour faire un saut
342
  videoPlayer.addEventListener('seeking', () => {
343
  if (!currentLoadedProject) return;
344
  sendPlayback('seek', { playing: !videoPlayer.paused && !videoPlayer.ended });
345
  });
346
 
347
+ // Relance le processus juste après que le saut dans la vidéo soit terminé
348
  videoPlayer.addEventListener('seeked', () => {
349
  if (!currentLoadedProject) return;
350
  sendPlayback('seek', { playing: !videoPlayer.paused && !videoPlayer.ended });
351
  });
352
 
353
+ // Mouvement naturel de la vidéo (déjà géré par startSyncLoop, donc pas besoin de surcharger)
354
  videoPlayer.addEventListener('timeupdate', () => {
355
  // synchro geree par startSyncLoop(), ici pas de double envoi
356
  });
357
 
358
+ // Prévient le serveur que la vidéo est complètement terminée
359
  videoPlayer.addEventListener('ended', () => {
360
  robotStatus.textContent = 'Terminé';
361
  sendPlayback('stop', { playing: false });
362
  stopSyncLoop();
363
  });
364
 
365
+ // Ajoute une nouvelle ligne avec une émotion et un temps dans le créateur de séquence
366
  function createEmotionRow() {
367
  const row = document.createElement('div');
368
  row.className = 'emotion-row';
 
408
  document.getElementById('sequence-list').appendChild(row);
409
  }
410
 
411
+ // Configure le bouton "+" pour ajouter des lignes au créateur de séquence
412
  document.addEventListener('DOMContentLoaded', () => {
413
  const addEmotionBtn = document.getElementById('add-emotion-btn');
414
  if(addEmotionBtn) {
 
427
  }
428
  });
429
 
430
+ // Rassemble les émotions choisies et envoie l'ordre au serveur de créer la séquence
431
  document.getElementById('save-seq-btn').onclick = async function() {
432
  const name = document.getElementById('seq-name').value.trim();
433
  const msg = document.getElementById('seq-msg');