discovery-media-player 0.1.25 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "discovery-media-player",
3
- "version": "0.1.25",
3
+ "version": "0.1.26",
4
4
  "description": "Self-hosted document viewer: per-recipient tracked links, reading analytics, live presentation. The core knows nothing about the application hosting it — everything it borrows arrives through an injected context.",
5
5
  "keywords": [
6
6
  "pdf-viewer",
package/server/handler.js CHANGED
@@ -356,8 +356,8 @@ var Live=(function(){
356
356
  var i=document.getElementById('chatText'),cap=(i&&i.value||'').trim();if(i)i.value='';
357
357
  var o={action:'present-chat',slug:SLUG,name:ME.name,email:ME.email,avatar:ME.avatar,body:cap,authorToken:authToken(),attachment:{url:d.publicUrl,name:file.name,type:file.type,kind:d.kind}};
358
358
  if(CONTROL)o.control=CONTROL;
359
- return var h2={'Content-Type':'application/json'};var j2=accessToken();if(j2)h2.Authorization='Bearer '+j2;
360
- fetch('/api/doc',{method:'POST',headers:h2,body:JSON.stringify(o)});
359
+ var h2={'Content-Type':'application/json'};var j2=accessToken();if(j2)h2.Authorization='Bearer '+j2;
360
+ return fetch('/api/doc',{method:'POST',headers:h2,body:JSON.stringify(o)});
361
361
  });
362
362
  }).then(done).catch(function(){done();});}
363
363
  function applyLock(v){LOCKED=!!v;var t=document.getElementById('chatText'),s=document.getElementById('chatSend');var can=!LOCKED||canMod();if(t){t.disabled=!can;t.placeholder=can?'Écrire un message…':'Chat en lecture seule';}if(s)s.disabled=!can;var lk=document.getElementById('chatLockBtn');if(lk)lk.classList.toggle('on',LOCKED);var no=document.getElementById('chatLocked');if(no)no.style.display=(LOCKED&&!canMod())?'block':'none';toggleSend();}
@@ -455,7 +455,7 @@ var Live=(function(){
455
455
  var _relEtat=null,_relChat=null;
456
456
  // Groupé : dix diffusions d'affilée ne doivent pas produire dix requêtes.
457
457
  function relireEtat(){clearTimeout(_relEtat);_relEtat=setTimeout(function(){
458
- relire('&state=1',function(d){if(d.state)appliquerEtat(d.state);});
458
+ relire('&state=1',function(d){if(d.state)etatDuServeur(d.state);});
459
459
  },120);}
460
460
  function relireChat(){clearTimeout(_relChat);_relChat=setTimeout(function(){
461
461
  relire('&chat=1',function(d){
@@ -477,12 +477,12 @@ var Live=(function(){
477
477
  //
478
478
  // Le serveur renvoie la CLÉ de celui qui a prouvé le control_token ; l'audience compare. Pas
479
479
  // de clé, pas de titre : mieux vaut aucun titre qu'un titre usurpé.
480
- function appliquerEtat(st){
480
+ function etatDuServeur(st){
481
481
  if(typeof st.presenter_key!=='undefined'){var k=st.presenter_key||'';
482
482
  if(k!==PRESKEY){PRESKEY=k;try{if(ch)renderPres(ch.presenceState());}catch(e){}}}
483
483
  if(_onState)_onState(st);
484
484
  }
485
- relire('&state=1',function(d){if(d.state)appliquerEtat(d.state);});
485
+ relire('&state=1',function(d){if(d.state)etatDuServeur(d.state);});
486
486
 
487
487
  // Le message reçu sert à savoir QU'IL SE PASSE quelque chose, et à notifier ; son CONTENU
488
488
  // vient de la relecture. Sans ça, une notification pourrait afficher un texte forgé.
@@ -294,8 +294,14 @@ async function toggleReaction(slug, msgId, emoji, reactor) {
294
294
  */
295
295
  async function presenterKey(slug) {
296
296
  if (!slug) return null;
297
- const rows = await PLAYER.db.request(`doc_presentation_attendees?slug=eq.${enc(slug)}&is_presenter=is.true&select=attendee_key&order=last_seen.desc&limit=1`);
298
- return (Array.isArray(rows) && rows[0] && rows[0].attendee_key) || null;
297
+ // ⚠️ NE JAMAIS FAIRE ÉCHOUER LA RELECTURE D'ÉTAT. Cette recherche est un ajout à une route dont
298
+ // l'audience dépend pour savoir quelle page est affichée. Une requête de plus, c'est une raison
299
+ // de plus de renvoyer 500 — et perdre TOUT l'état parce qu'on n'a pas su dire qui porte un badge
300
+ // serait un très mauvais échange. Sans réponse : pas de clé, donc pas de titre, et le reste passe.
301
+ try {
302
+ const rows = await PLAYER.db.request(`doc_presentation_attendees?slug=eq.${enc(slug)}&is_presenter=is.true&select=attendee_key&order=last_seen.desc&limit=1`);
303
+ return (Array.isArray(rows) && rows[0] && rows[0].attendee_key) || null;
304
+ } catch { return null; }
299
305
  }
300
306
 
301
307
  // ── Statistiques de présentation (assistance) ────────────────────────────────────────────────────────────