diff --git a/src/hooks/useAnnonceSonoreRealtime.js b/src/hooks/useAnnonceSonoreRealtime.js index 83ef403..b49673d 100644 --- a/src/hooks/useAnnonceSonoreRealtime.js +++ b/src/hooks/useAnnonceSonoreRealtime.js @@ -1,16 +1,51 @@ import { useEffect, useRef } from 'react'; import supabase from '../lib/supabase'; -export default function useAnnonceSonoreRealtime(gareId) { +// Helper pour normaliser le nom du quai pour comparaison robuste +const normalizeQuai = (val) => { + if (!val) return ''; + return String(val) + .toLowerCase() + .replace(/\s+/g, '') + .replace(/voie/g, '') + .replace(/quai/g, ''); +}; + +export default function useAnnonceSonoreRealtime(gareId, affType = null, quaiName = null) { const audioRef = useRef(null); const lastAnnonceIdRef = useRef(null); useEffect(() => { if (!supabase || !gareId) return; - console.debug(`[useAnnonceSonoreRealtime] Setup for gareId: ${gareId}`); + console.debug(`[useAnnonceSonoreRealtime] Setup for gareId: ${gareId}, type: ${affType}, quai: ${quaiName}`); const playAnnonce = (newRecord) => { + // 1. Déterminer les afficheurs cibles + const variables = newRecord.annonce?.variables_values || {}; + const targetAfficheurs = variables.afficheurs || []; + const trainQuai = variables.quai || ''; + + // Si targetAfficheurs est renseigné, filtrer + if (affType && targetAfficheurs.length > 0) { + const isTargeted = targetAfficheurs.includes(affType); + if (!isTargeted) { + console.debug(`[useAnnonceSonoreRealtime] Ignoré : cet afficheur (${affType}) n'est pas ciblé par l'annonce.`); + return; + } + + // Si l'afficheur est de type "Quais" (se termine par "Quais"), on vérifie la voie/quai + const isQuaiDisplay = affType.toLowerCase().endsWith('quais'); + if (isQuaiDisplay && quaiName && trainQuai) { + const normDisplayQuai = normalizeQuai(quaiName); + const normTrainQuai = normalizeQuai(trainQuai); + if (normDisplayQuai !== normTrainQuai) { + console.debug(`[useAnnonceSonoreRealtime] Ignoré : voie non correspondante (Afficheur: ${quaiName}, Train: ${trainQuai})`); + return; + } + } + } + // 1. Couper l'audio en cours de lecture if (audioRef.current) { try { audioRef.current.pause(); } catch (e) {} @@ -59,7 +94,12 @@ export default function useAnnonceSonoreRealtime(gareId) { try { const { data, error } = await supabase .from('annonces_diffusions') - .select('*') + .select(` + *, + annonce:annonces_enregistrees( + variables_values + ) + `) .eq('gare_id', gareId) .order('created_at', { ascending: false }) .limit(1); @@ -106,5 +146,5 @@ export default function useAnnonceSonoreRealtime(gareId) { try { window.speechSynthesis.cancel(); } catch (e) {} } }; - }, [gareId]); + }, [gareId, affType, quaiName]); } diff --git a/src/pages/afficheurs/afl/AFLArrivees.js b/src/pages/afficheurs/afl/AFLArrivees.js index 75077e7..ff3135a 100644 --- a/src/pages/afficheurs/afl/AFLArrivees.js +++ b/src/pages/afficheurs/afl/AFLArrivees.js @@ -87,7 +87,7 @@ export default function AFLArrivees(){ const [, setRawDebug] = useState({ count: 0, sample: [] }); const [resolvedGareId, setResolvedGareId] = useState(gareIdParam || null); - useAnnonceSonoreRealtime(resolvedGareId); + useAnnonceSonoreRealtime(resolvedGareId, 'AFLArrivees'); useAutoAnnonce(horaires, currentTime, true); // Récupérer le type de gare une seule fois au montage ou quand les paramètres changent diff --git a/src/pages/afficheurs/afl/AFLArriveesQuais.js b/src/pages/afficheurs/afl/AFLArriveesQuais.js index 625778d..c3f4166 100644 --- a/src/pages/afficheurs/afl/AFLArriveesQuais.js +++ b/src/pages/afficheurs/afl/AFLArriveesQuais.js @@ -32,7 +32,7 @@ const AFLArriveesQuais = () => { const gareDisplay = gareParam ? decodeURIComponent(String(gareParam).replace(/\+/g, ' ')).replace(/-/g, ' ') : null; const [resolvedGareId, setResolvedGareId] = useState(gareIdParam || null); - useAnnonceSonoreRealtime(resolvedGareId); + useAnnonceSonoreRealtime(resolvedGareId, 'AFLArriveesQuais', quaiParam); useEffect(() => { let mounted = true; diff --git a/src/pages/afficheurs/afl/AFLDeparts.js b/src/pages/afficheurs/afl/AFLDeparts.js index 539a25b..c71b27b 100644 --- a/src/pages/afficheurs/afl/AFLDeparts.js +++ b/src/pages/afficheurs/afl/AFLDeparts.js @@ -87,7 +87,7 @@ export default function AFLDeparts(){ const [, setRawDebug] = useState({ count: 0, sample: [] }); const [resolvedGareId, setResolvedGareId] = useState(gareIdParam || null); - useAnnonceSonoreRealtime(resolvedGareId); + useAnnonceSonoreRealtime(resolvedGareId, 'AFLDeparts'); useAutoAnnonce(horaires, currentTime, false); // Récupérer le type de gare une seule fois au montage ou quand les paramètres changent diff --git a/src/pages/afficheurs/afl/AFLDepartsQuais.js b/src/pages/afficheurs/afl/AFLDepartsQuais.js index 732a67d..a3f2ac1 100644 --- a/src/pages/afficheurs/afl/AFLDepartsQuais.js +++ b/src/pages/afficheurs/afl/AFLDepartsQuais.js @@ -32,7 +32,7 @@ const AFLDepartsQuais = () => { const gareDisplay = gareParam ? decodeURIComponent(String(gareParam).replace(/\+/g, ' ')).replace(/-/g, ' ') : null; const [resolvedGareId, setResolvedGareId] = useState(gareIdParam || null); - useAnnonceSonoreRealtime(resolvedGareId); + useAnnonceSonoreRealtime(resolvedGareId, 'AFLDepartsQuais', quaiParam); useEffect(() => { let mounted = true; diff --git a/src/pages/afficheurs/classiques/ClassiquesArrivees.js b/src/pages/afficheurs/classiques/ClassiquesArrivees.js index 743b5a6..53ff8c2 100644 --- a/src/pages/afficheurs/classiques/ClassiquesArrivees.js +++ b/src/pages/afficheurs/classiques/ClassiquesArrivees.js @@ -100,7 +100,7 @@ export default function ClassiquesArrivees(){ const [rawDebug, setRawDebug] = useState({ count: 0, sample: [] }); const [resolvedGareId, setResolvedGareId] = useState(gareIdParam || null); - useAnnonceSonoreRealtime(resolvedGareId); + useAnnonceSonoreRealtime(resolvedGareId, 'ClassiquesArrivees'); useAutoAnnonce(horaires, currentTime, true); // Récupérer le type de gare une seule fois au montage ou quand les paramètres changent diff --git a/src/pages/afficheurs/classiques/ClassiquesDeparts.js b/src/pages/afficheurs/classiques/ClassiquesDeparts.js index 05ce3ef..41f8cf5 100644 --- a/src/pages/afficheurs/classiques/ClassiquesDeparts.js +++ b/src/pages/afficheurs/classiques/ClassiquesDeparts.js @@ -100,7 +100,7 @@ export default function ClassiquesDeparts(){ const [rawDebug, setRawDebug] = useState({ count: 0, sample: [] }); const [resolvedGareId, setResolvedGareId] = useState(gareIdParam || null); - useAnnonceSonoreRealtime(resolvedGareId); + useAnnonceSonoreRealtime(resolvedGareId, 'ClassiquesDeparts'); useAutoAnnonce(horaires, currentTime, false); // Récupérer le type de gare une seule fois au montage ou quand les paramètres changent diff --git a/src/pages/afficheurs/classiques/quais/ClassiquesArriveesQuais.js b/src/pages/afficheurs/classiques/quais/ClassiquesArriveesQuais.js index 631f5ad..f6f9474 100644 --- a/src/pages/afficheurs/classiques/quais/ClassiquesArriveesQuais.js +++ b/src/pages/afficheurs/classiques/quais/ClassiquesArriveesQuais.js @@ -49,7 +49,7 @@ export default function ClassiquesArriveesQuais() { const [currentTime, setCurrentTime] = useState(new Date()); const [resolvedGareId, setResolvedGareId] = useState(gareIdParam || null); - useAnnonceSonoreRealtime(resolvedGareId); + useAnnonceSonoreRealtime(resolvedGareId, 'ClassiquesArriveesQuais', quaiParam); useAutoAnnonce(selectedHoraire ? [selectedHoraire] : [], currentTime, true); const [alternateDelayPhase, setAlternateDelayPhase] = useState(true); const [alternateCancelPhase, setAlternateCancelPhase] = useState(true); diff --git a/src/pages/afficheurs/classiques/quais/ClassiquesDepartsQuais.js b/src/pages/afficheurs/classiques/quais/ClassiquesDepartsQuais.js index a479848..54c0348 100644 --- a/src/pages/afficheurs/classiques/quais/ClassiquesDepartsQuais.js +++ b/src/pages/afficheurs/classiques/quais/ClassiquesDepartsQuais.js @@ -49,7 +49,7 @@ export default function ClassiquesDepartsQuais() { const [currentTime, setCurrentTime] = useState(new Date()); const [resolvedGareId, setResolvedGareId] = useState(gareIdParam || null); - useAnnonceSonoreRealtime(resolvedGareId); + useAnnonceSonoreRealtime(resolvedGareId, 'ClassiquesDepartsQuais', quaiParam); useAutoAnnonce(selectedHoraire ? [selectedHoraire] : [], currentTime, false); const [alternateDelayPhase, setAlternateDelayPhase] = useState(true); const [alternateCancelPhase, setAlternateCancelPhase] = useState(true);