mirror of
https://codeberg.org/kbruen/kai.infotren.git
synced 2025-02-22 17:19:37 +02:00
If train data is already known, don't refresh when going back to the group selection screen.
447 lines
12 KiB
JavaScript
Executable file
447 lines
12 KiB
JavaScript
Executable file
var trainNumber
|
|
var date
|
|
var groupIndex = null
|
|
|
|
var showKm = false
|
|
|
|
var trainData = null
|
|
var lastSuccessfulFetch = null
|
|
|
|
function onTrainData(data) {
|
|
var title = document.getElementById('title')
|
|
title.textContent = ''
|
|
title.appendChild(document.createTextNode('Train '))
|
|
var rankSpan = document.createElement('span')
|
|
rankSpan.textContent = data.rank
|
|
rankSpan.classList.add(data.rank)
|
|
title.appendChild(rankSpan)
|
|
title.appendChild(document.createTextNode(` ${data.number}`))
|
|
|
|
document.getElementsByTagName('title')[0].textContent = `Train ${data.rank} ${data.number}`
|
|
|
|
document.getElementById('company').textContent = data.operator
|
|
document.getElementById('date').textContent = data.date
|
|
|
|
var group = null;
|
|
if (data.groups.length > 1 && groupIndex == null) {
|
|
document.getElementById('group-choice').classList.remove('hidden')
|
|
document.getElementById('group-choice').focus()
|
|
document.getElementById('train-info').classList.add('hidden')
|
|
|
|
document.getElementsByClassName('rsk')[0].textContent = ''
|
|
document.getElementsByClassName('csk')[0].textContent = 'Select'
|
|
|
|
title.textContent = `Select Group for ${data.rank} ${data.number}`
|
|
|
|
var gc = document.getElementById('group-choice')
|
|
while (gc.childNodes.length > 0) {
|
|
gc.childNodes[0].remove()
|
|
}
|
|
|
|
for (var i = 0; i < data.groups.length; i++) {
|
|
var g = data.groups[i]
|
|
|
|
var groupLi = document.createElement('li')
|
|
gc.append(groupLi)
|
|
groupLi.tabIndex = i
|
|
groupLi.classList.add('items')
|
|
if (i === currentIndex) {
|
|
groupLi.focus()
|
|
}
|
|
|
|
(function (i) {
|
|
function onAction(e) {
|
|
var url = new URL(window.location.toString())
|
|
groupIndex = i
|
|
url.searchParams.append('groupIndex', groupIndex)
|
|
window.history.pushState({'groupIndex': groupIndex}, '', url.toString( ))
|
|
onTrainData(data)
|
|
}
|
|
groupLi.addEventListener('click', onAction)
|
|
groupLi.addEventListener('keypress', function (e) {
|
|
if (e.key == 'Enter') {
|
|
onAction(e)
|
|
}
|
|
})
|
|
})(i)
|
|
|
|
var routeP = document.createElement('p')
|
|
groupLi.append(routeP)
|
|
routeP.classList.add('pri')
|
|
routeP.textContent = `${g.route.from} ➔ ${g.route.to}`
|
|
|
|
var groupP = document.createElement('p')
|
|
groupLi.append(groupP)
|
|
groupP.classList.add('thi')
|
|
groupP.textContent = i === 0 ? 'Main train' : `Group ${i}`
|
|
|
|
}
|
|
|
|
return
|
|
}
|
|
else if (data.groups.length === 1) {
|
|
group = data.groups[0]
|
|
}
|
|
else {
|
|
group = data.groups[groupIndex]
|
|
}
|
|
document.getElementById('group-choice').classList.add('hidden')
|
|
document.getElementById('train-info').classList.remove('hidden')
|
|
document.getElementById('train-info').focus()
|
|
|
|
document.getElementsByClassName('rsk')[0].textContent = 'Refresh'
|
|
document.getElementsByClassName('csk')[0].textContent = ''
|
|
|
|
document.getElementById('route-from').textContent = group.route.from
|
|
document.getElementById('route-to').textContent = group.route.to
|
|
|
|
if (group.status) {
|
|
document.getElementById('status').classList.remove('hidden')
|
|
|
|
var statusDelay = document.getElementById('status-delay')
|
|
while (statusDelay.childNodes.length > 0) {
|
|
statusDelay.childNodes[0].remove()
|
|
}
|
|
var delayString = ''
|
|
var delayMinutes = group.status.delay
|
|
if (delayMinutes === 0) {
|
|
delayString = 'On time'
|
|
statusDelay.appendChild(document.createTextNode(delayString))
|
|
}
|
|
else {
|
|
var early = false
|
|
if (delayMinutes < 0) {
|
|
early = true
|
|
delayMinutes = -delayMinutes
|
|
}
|
|
|
|
if (delayMinutes >= 60) {
|
|
var hours = Math.floor(delayMinutes / 60)
|
|
delayMinutes = delayMinutes % 60
|
|
delayString += hours.toString()
|
|
delayString += ' hour'
|
|
if (hours > 1) {
|
|
delayString += 's'
|
|
}
|
|
}
|
|
if (delayMinutes > 0) {
|
|
if (delayString.length > 0) {
|
|
delayString += ' and '
|
|
}
|
|
delayString += delayMinutes.toString()
|
|
delayString += ' minute'
|
|
if (delayMinutes > 1) {
|
|
delayString += 's'
|
|
}
|
|
}
|
|
delayString += ' '
|
|
statusDelay.appendChild(document.createTextNode(delayString))
|
|
|
|
var kindSpan = document.createElement('span')
|
|
statusDelay.appendChild(kindSpan)
|
|
if (early) {
|
|
kindSpan.textContent = 'early'
|
|
kindSpan.classList.add('early')
|
|
}
|
|
else {
|
|
kindSpan.textContent = 'late'
|
|
kindSpan.classList.add('late')
|
|
}
|
|
}
|
|
|
|
var statusLocation = document.getElementById('status-location')
|
|
while (statusLocation.childNodes.length > 0) {
|
|
statusLocation.childNodes[0].remove()
|
|
}
|
|
var stateString = ''
|
|
if (group.status.state === 'arrival') {
|
|
stateString += 'when arriving at '
|
|
}
|
|
else if (group.status.state === 'departure') {
|
|
stateString += 'when departing from '
|
|
}
|
|
else if (group.status.state === 'passing') {
|
|
stateString += 'while passing through '
|
|
}
|
|
statusLocation.appendChild(document.createTextNode(stateString))
|
|
var stationSpan = document.createElement('span')
|
|
statusLocation.appendChild(stationSpan)
|
|
stationSpan.textContent = group.status.station
|
|
stationSpan.classList.add('station')
|
|
}
|
|
else {
|
|
document.getElementById('status').classList.add('hidden')
|
|
}
|
|
|
|
var stationsDiv = document.getElementById('stations')
|
|
while (stationsDiv.childNodes.length > 0) {
|
|
stationsDiv.childNodes[0].remove()
|
|
}
|
|
|
|
var separator = document.createElement('h4')
|
|
stationsDiv.appendChild(separator)
|
|
separator.textContent = 'Stations'
|
|
|
|
var stationsList = document.createElement('ul')
|
|
stationsDiv.appendChild(stationsList)
|
|
|
|
group.stations.forEach(function (station) {
|
|
var stationItem = document.createElement('li')
|
|
stationsList.appendChild(stationItem)
|
|
stationItem.classList.add('stationItem')
|
|
|
|
var stationName = document.createElement('p')
|
|
stationItem.appendChild(stationName)
|
|
stationName.textContent = station.name
|
|
stationName.classList.add('pri', 'name')
|
|
|
|
if (station.arrival) {
|
|
var stationArrival = document.createElement('div')
|
|
stationItem.appendChild(stationArrival)
|
|
stationArrival.classList.add('arrival')
|
|
|
|
var originalArr = document.createElement('p')
|
|
stationArrival.appendChild(originalArr)
|
|
var arrDate = new Date(station.arrival.scheduleTime)
|
|
originalArr.textContent = arrDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' })
|
|
originalArr.classList.add('pri')
|
|
if (station.arrival.status && station.arrival.status.delay != 0) {
|
|
originalArr.classList.remove('pri')
|
|
originalArr.classList.add('thi', 'original')
|
|
|
|
var actualArr = document.createElement('p')
|
|
stationArrival.appendChild(actualArr)
|
|
arrDate.setMinutes(arrDate.getMinutes() + station.arrival.status.delay)
|
|
actualArr.textContent = arrDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' })
|
|
actualArr.classList.add('pri', station.arrival.status.delay > 0 ? 'late' : 'early')
|
|
if (!station.arrival.status.real) {
|
|
actualArr.classList.add('not-real')
|
|
}
|
|
}
|
|
}
|
|
|
|
if (station.departure) {
|
|
var stationDeparture = document.createElement('div')
|
|
stationItem.appendChild(stationDeparture)
|
|
stationDeparture.classList.add('departure')
|
|
|
|
var originalDep = document.createElement('p')
|
|
stationDeparture.appendChild(originalDep)
|
|
var depDate = new Date(station.departure.scheduleTime)
|
|
originalDep.textContent = depDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' })
|
|
originalDep.classList.add('pri')
|
|
if (station.departure.status && station.departure.status.delay != 0) {
|
|
originalDep.classList.remove('pri')
|
|
originalDep.classList.add('thi', 'original')
|
|
|
|
var actualDep = document.createElement('p')
|
|
stationDeparture.appendChild(actualDep)
|
|
depDate.setMinutes(depDate.getMinutes() + station.departure.status.delay)
|
|
actualDep.textContent = depDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' })
|
|
actualDep.classList.add('pri', station.departure.status.delay > 0 ? 'late' : 'early')
|
|
if (!station.departure.status.real) {
|
|
actualDep.classList.add('not-real')
|
|
}
|
|
}
|
|
}
|
|
|
|
var stationKm = document.createElement('p')
|
|
stationItem.appendChild(stationKm)
|
|
stationKm.textContent = `${station.km} km`
|
|
stationKm.classList.add('thi', 'km')
|
|
if (!showKm) {
|
|
stationKm.classList.add('hidden')
|
|
}
|
|
|
|
if (station.platform) {
|
|
var stationPlatform = document.createElement('p')
|
|
stationItem.appendChild(stationPlatform)
|
|
stationPlatform.textContent = `platform ${station.platform}`
|
|
stationPlatform.classList.add('thi', 'platform')
|
|
}
|
|
|
|
if (station.notes && station.notes.length > 0) {
|
|
var stationNotes = document.createElement('div')
|
|
stationItem.appendChild(stationNotes)
|
|
stationNotes.classList.add('notes')
|
|
|
|
station.notes.forEach(function (note) {
|
|
var noteP = document.createElement('p')
|
|
stationNotes.appendChild(noteP)
|
|
noteP.classList.add('note', 'thi')
|
|
|
|
switch (note.kind) {
|
|
case 'departsAs': {
|
|
noteP.textContent = `Train departs as ${note.rank} ${note.number}`
|
|
break
|
|
}
|
|
case 'detachingWagons': {
|
|
noteP.textContent = `Detaching wagons to ${note.station}`
|
|
break
|
|
}
|
|
case 'receivingWagons': {
|
|
noteP.textContent = `Receiving wagons from ${note.station}`
|
|
break
|
|
}
|
|
case 'trainNumberChange': {
|
|
noteP.textContent = `Train changes number to ${note.rank} ${note.number}`
|
|
break
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
lastSuccessfulFetch = new Date()
|
|
}
|
|
|
|
var refreshStopToken = null
|
|
function refresh() {
|
|
function reschedule(timeout) {
|
|
if (refreshStopToken != null) {
|
|
clearTimeout(refreshStopToken)
|
|
}
|
|
refreshStopToken = setTimeout(function () {
|
|
refresh()
|
|
}, timeout || 60000)
|
|
}
|
|
return fetch(
|
|
`https://scraper.infotren.dcdev.ro/v3/trains/${trainNumber}?date=${date.getFullYear().toString()}-${(date.getMonth() + 1).toString().padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}`,
|
|
{
|
|
cache: 'no-store',
|
|
},
|
|
).then(function (response) {
|
|
if (!response.ok) {
|
|
// Check in 10 seconds if server returned error
|
|
reschedule(10000)
|
|
return
|
|
}
|
|
return response.json()
|
|
}).then(function (response) {
|
|
if (!response) {
|
|
return
|
|
}
|
|
trainData = response
|
|
onTrainData(response)
|
|
reschedule()
|
|
}).catch(function (e) {
|
|
// Check in 1 second if network error
|
|
reschedule(1000)
|
|
throw e
|
|
})
|
|
}
|
|
|
|
window.addEventListener('unload', function (e) {
|
|
if (refreshStopToken != null) {
|
|
clearTimeout(refreshStopToken)
|
|
}
|
|
})
|
|
|
|
function rsk() {
|
|
refresh()
|
|
}
|
|
|
|
window.addEventListener('popstate', function (e) {
|
|
groupIndex = null
|
|
if (trainData) {
|
|
onTrainData(trainData)
|
|
}
|
|
else {
|
|
refresh()
|
|
}
|
|
})
|
|
|
|
window.addEventListener('load', function (e) {
|
|
if (!new URL(window.location.href).searchParams.has('train')) {
|
|
window.history.back()
|
|
this.setTimeout(function () {
|
|
var url = new URL(window.location.href)
|
|
url.pathname = 'train.html'
|
|
window.location.href = url.toString()
|
|
}, 100)
|
|
}
|
|
|
|
var sp = new URL(window.location.href).searchParams
|
|
|
|
trainNumber = sp.get('train')
|
|
date = sp.has('date') ? new Date(sp.get('date')) : new Date()
|
|
groupIndex = sp.has('groupIndex') ? parseInt(sp.get('groupIndex')) : null
|
|
|
|
document.querySelectorAll('.rsk').forEach(function (rskElem) {
|
|
rskElem.addEventListener('click', function (e) {
|
|
rsk()
|
|
})
|
|
})
|
|
|
|
var content = document.getElementsByClassName('content')[0]
|
|
content.focus()
|
|
content.addEventListener('keydown', function (e) {
|
|
switch (e.key) {
|
|
case 'ArrowUp':
|
|
content.scrollBy(0, -50)
|
|
break
|
|
case 'ArrowDown':
|
|
content.scrollBy(0, 50)
|
|
break
|
|
case 'SoftRight':
|
|
rsk()
|
|
break
|
|
case '1':
|
|
date.setDate(date.getDate() - 1)
|
|
refresh()
|
|
break
|
|
case '3':
|
|
date.setDate(date.getDate() + 1)
|
|
refresh()
|
|
break
|
|
case '7':
|
|
showKm = !showKm
|
|
document.querySelectorAll('.km').forEach(function (kmItem) {
|
|
if (showKm) {
|
|
kmItem.classList.remove('hidden')
|
|
}
|
|
else {
|
|
kmItem.classList.add('hidden')
|
|
}
|
|
})
|
|
break
|
|
default:
|
|
console.log(e.key)
|
|
}
|
|
})
|
|
|
|
refresh()
|
|
|
|
setInterval(function () {
|
|
if (!lastSuccessfulFetch) {
|
|
return
|
|
}
|
|
var millis = new Date() - lastSuccessfulFetch
|
|
var secs = Math.floor(millis / 1000)
|
|
|
|
var timeStr = ''
|
|
if (secs / 3600 >= 1) {
|
|
timeStr += `${Math.floor(secs / 3600)}h`
|
|
secs = secs % 3600
|
|
}
|
|
if (secs / 60 >= 1) {
|
|
timeStr += `${Math.floor(secs / 60)}m`
|
|
secs = secs % 60
|
|
}
|
|
if (secs >= 1) {
|
|
timeStr += `${Math.floor(secs)}s`
|
|
}
|
|
if (!timeStr) {
|
|
document.querySelectorAll('.lsk').forEach(function (elem) {
|
|
elem.textContent = 'Last refreshed now'
|
|
elem.classList.add('last-refreshed')
|
|
})
|
|
}
|
|
else {
|
|
document.querySelectorAll('.lsk').forEach(function (elem) {
|
|
elem.textContent = `Last refreshed ${timeStr} ago`
|
|
elem.classList.add('last-refreshed')
|
|
})
|
|
}
|
|
}, 500)
|
|
})
|