import { getNextPassage } from "./tcl.js"; const MIN_TIME_BETWEEN_DAYS = 2 * 60 * 60000 // 2 hours const MAX_LAST_PASSAGE_TIME = 30 * 60000 // 30 min const MAX_DERNIER_METRO_MESSAGE = 3 let tracked_stops = [ "line:SYTNEX:A/forward/stop_point:SYTNEX:46052", // Metro A dir Vaulx, Hotel de ville "line:SYTNEX:A/backward/stop_point:SYTNEX:42743", // Metro A dir Perrache, Hotel de ville "line:SYTNEX:9/forward/stop_point:SYTNEX:2494", // Bus 9 dir Satoney, Pont de lattre RD "line:SYTNEX:9/backward/stop_point:SYTNEX:2494", // Bus 9 dir cordeliers, Pont de lattre RD "line:SYTNEX:C/forward/stop_point:SYTNEX:10787", // Métro C dir Cuire, Croix-Paquet "line:SYTNEX:C6/forward/stop_point:SYTNEX:2496", // Bus C6 arret Pont de lattre RD campus lyon ouest "line:SYTNEX:C6/backward/stop_point:SYTNEX:2495", // Bus C6 arret Pont de lattre RD Gare part dieu v. merle "line:SYTNEX:C13/forward/stop_point:SYTNEX:10169", // Bus C13 arret Austerlitz montessuy gutemberg "line:SYTNEX:C13/backward/stop_point:SYTNEX:10169", // Bus C13 arret Austerlitz vers grange blanche "line:SYTNEX:PL2/backward/stop_point:SYTNEX:10889", // Bus PL2 arret Pont de lattre RD vers Musée des confluences "line:SYTNEX:PL2/forward/stop_point:SYTNEX:10169", // BUS PL2 arret Austerlitz vers Cuire "line:SYTNEX:C23/backward/stop_point:SYTNEX:10889", // Bus C13 arret Pont de lattre RD vers Flachet - Alain Gilles "line:SYTNEX:C23/forward/stop_point:SYTNEX:10889", // Bus C13 arret Pont de lattre RD vers Cite internationale ] let stops_cache = {} async function shuffleStops(){ tracked_stops = tracked_stops .map(value => ({ value, sort: Math.random() })) .sort((a, b) => a.sort - b.sort) .map(({ value }) => value) } async function getNextStop(){ let stop = tracked_stops.shift() tracked_stops.push(stop) return stop } async function showNextLine(){ let stop = await getNextStop() let nextPassage = await getNextPassage(stop) stops_cache[stop] = nextPassage let time = nextPassage.time if(!time){ time = nextPassage.line.timetable.find(it => it.time.getTime() > Date.now())?.time } if(!time){ return } let modal = document.getElementById("next-line") modal.hidden = false modal.querySelector(".line-picto").src = nextPassage.line.picto modal.querySelector(".line-name").textContent = nextPassage.line.displayName modal.querySelector(".stop-name").textContent = nextPassage.displayName let timeFormatter = new Intl.DateTimeFormat("fr-FR", { timeStyle: "short" }); let timeEl = modal.querySelector(".stop-passage-time") timeEl.textContent = timeFormatter.format(time) let relativeTimeFOrmatter = new Intl.RelativeTimeFormat("fr-FR", { style: "short", numeric: "auto" }); let time_minutes = Math.floor((time.getTime() - Date.now()) / 60000) let relative_time_str; if(time_minutes > 60) { let time_hours = Math.floor(time_minutes / 60) time_minutes -= time_hours * 60 relative_time_str = relativeTimeFOrmatter.format( time_hours, "hours" ) if(time_minutes > 0){ relative_time_str += ` et ${Math.abs(time_minutes)} min` } } else { relative_time_str = relativeTimeFOrmatter.format( time_minutes, "minutes" ) } modal.querySelector(".stop-passage-time-relative").textContent = relative_time_str setTimeout(() => modal.hidden = true, 15000) } function getLastPassageTime(stopOrLine){ let timetable = stopOrLine.timetable || stopOrLine.line.timetable if(!timetable){ return } let now = new Date() let last_passage = timetable .find((it, i) => { if((timetable[i+1]) && it.time.getTime() > now && (it.time.getTime() + MIN_TIME_BETWEEN_DAYS) < timetable[i+1].time.getTime()){ return true } else { return false } }) return last_passage } async function updateLastMetro(){ let last_passage_list = Object.values(stops_cache) .map(it => [it, getLastPassageTime(it)]) .filter(([_, lastPassage]) => lastPassage && (lastPassage.time.getTime() - Date.now()) < MAX_LAST_PASSAGE_TIME) let hidden_offset = 0 let last_hidden = true for(let el of document.querySelectorAll("#last-passage > .last-passage")){ if(last_hidden && el.hidden){ hidden_offset++ } else { last_hidden = false } el.remove() } let container = document.getElementById("last-passage") let template = document.querySelector("#last-passage template.last-passage-template"); if(hidden_offset >= last_passage_list.length){ hidden_offset = 0 } if(last_passage_list.length > 0){ let i = 0 for(let [stop, last_passage] of last_passage_list){ let el = template.content.cloneNode(true) el.children[0].hidden = i < hidden_offset || i >= hidden_offset + MAX_DERNIER_METRO_MESSAGE; el.querySelector(".line-picto").src = stop.line.picto el.querySelector(".line-name").textContent = stop.line.displayName el.querySelector(".stop-name").textContent = stop.displayName let timeFormatter = new Intl.DateTimeFormat("fr-FR", { timeStyle: "short" }); let timeEl = el.querySelector(".stop-passage-time") timeEl.textContent = timeFormatter.format(last_passage.time) timeEl.datetime = last_passage.time.toISOString() let relativeTimeFormatter = new Intl.RelativeTimeFormat("fr-FR", { style: "short", numeric: "auto" }); el.querySelector(".stop-passage-time-relative").textContent = relativeTimeFormatter.format( Math.floor((last_passage.time.getTime() - Date.now()) / 60000), "minutes" ) container.prepend(el) i++; } container.hidden = false } else { container.hidden = true } } shuffleStops() .then(() => showNextLine()) .then(() => updateLastMetro()) setInterval(() => showNextLine(), 17000) setInterval(() => updateLastMetro(), 60000)