This commit is contained in:
lol
2026-06-13 20:42:03 +02:00
commit 58720611f7
12 changed files with 911 additions and 0 deletions
+185
View File
@@ -0,0 +1,185 @@
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)