var trainNumber var date var showKm = false var trainData = null var lastSuccessfulFetch = null function onTrainData(data) { var title = document.getElementsByTagName('h1')[0] 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.getElementById('company').textContent = data.operator document.getElementById('date').textContent = data.date document.getElementById('route-from').textContent = data.route.from document.getElementById('route-to').textContent = data.route.to if (data.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 = data.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 (data.status.state === 'arrival') { stateString += 'when arriving at ' } else if (data.status.state === 'departure') { stateString += 'when departing from ' } else if (data.status.state === 'passing') { stateString += 'while passing through ' } statusLocation.appendChild(document.createTextNode(stateString)) var stationSpan = document.createElement('span') statusLocation.appendChild(stationSpan) stationSpan.textContent = data.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) data.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') } }) lastSuccessfulFetch = new Date() } var refreshStopToken = null function refresh() { return fetch(`https://scraper.infotren.dcdev.ro/v2/train/${trainNumber}?date=${date.getFullYear().toString()}-${(date.getMonth() + 1).toString().padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}`) .then(function (response) { return response.json() }) .then(function (response) { trainData = response onTrainData(response) }) .then(function () { if (refreshStopToken != null) { clearTimeout(refreshStopToken) } refreshStopToken = setTimeout(function () { refresh() }, 60000) }) } window.addEventListener('unload', function (e) { if (refreshStopToken != null) { clearTimeout(refreshStopToken) } }) function rsk() { 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() 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) { return } document.querySelectorAll('.lsk').forEach(function (elem) { elem.textContent = `Last refreshed ${timeStr} ago` elem.classList.add('last-refreshed') }) }, 500) })