186 lines
6.3 KiB
JavaScript
186 lines
6.3 KiB
JavaScript
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)
|