var station var date var stationData = null var lastSuccessfulFetch = null function onStationData(data) { if (!data) { return } var title = document.getElementById('title') title.textContent = data.stationName document.getElementById('date').textContent = data.date document.getElementById('loading').classList.add('hidden') /** * @param {HTMLElement} elem * @param {any[]} trains */ function addTrains(elem, trains) { while (elem.childNodes.length > 0) { elem.childNodes[0].remove() } var trainsList = document.createElement('ul') elem.appendChild(trainsList) trains.forEach(function (train, tIdx) { var trainItem = document.createElement('li') trainsList.appendChild(trainItem) trainItem.classList.add('train-item') if (train.status && train.status.cancelled) { trainItem.classList.add('cancelled') } var timeDiv = document.createElement('p') trainItem.appendChild(timeDiv) timeDiv.classList.add('pri', 'time') timeDiv.textContent = new Date(train.time).toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' }) if (train.status && train.status.delay != 0) { var delayDiv = document.createElement('p') trainItem.appendChild(delayDiv) delayDiv.classList.add('thi', 'delay') delayDiv.textContent = `${train.status.delay} min ` // delayDiv.appendChild(document.createElement('br')) var descSpan = document.createElement('span') delayDiv.appendChild(descSpan) if (train.status.delay > 0) { descSpan.classList.add('late') descSpan.textContent = 'late' } else { descSpan.classList.add('early') descSpan.textContent = 'early' } } var rankDiv = document.createElement('p') trainItem.appendChild(rankDiv) rankDiv.textContent = train.train.rank rankDiv.classList.add('sec', 'rank', train.train.rank) var trainDiv = document.createElement('p') trainItem.appendChild(trainDiv) trainDiv.classList.add('pri', 'train') trainDiv.appendChild(document.createTextNode(`${train.train.number}`)) var terminusDiv = document.createElement('p') trainItem.appendChild(terminusDiv) terminusDiv.classList.add('pri', 'terminus') terminusDiv.textContent = train.train.terminus if (train.status && train.status.platform) { var platformDiv = document.createElement('div') trainItem.appendChild(platformDiv) platformDiv.classList.add('thi', 'platform') platformDiv.textContent = train.status.platform } if (train.status && train.status.cancelled) { var statusDiv = document.createElement('p') trainItem.appendChild(statusDiv) statusDiv.classList.add('sec', 'status') statusDiv.textContent = 'This train is cancelled' } }) } addTrains(document.getElementById('arrivals'), data.arrivals) addTrains(document.getElementById('departures'), data.departures) } var refreshStopToken = null function refresh() { function reschedule(timeout) { if (refreshStopToken != null) { clearTimeout(refreshStopToken) } refreshStopToken = setTimeout(function () { refresh() }, timeout || 90000) } return fetch( `https://scraper.infotren.dcdev.ro/v3/stations/${station}?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 } var cacheDate = response.headers.get('SW-Cached-At') return response.json().then(function (data) { data['$cacheDate'] = cacheDate return data }) }).then(function (response) { if (!response) { return } var cacheDate = response['$cacheDate'] if (cacheDate) { cacheDate = new Date(cacheDate) } var success = !cacheDate stationData = response onStationData(response) // Check in 1 seconds if network error reschedule(success ? undefined : 1000) return success }).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() { function changeRskText(newText) { document.querySelectorAll('.rsk').forEach(function (elem) { elem.textContent = newText }) } changeRskText('Refreshing...') refresh().catch(function () { return false}).then(function (success) { if (!success) { changeRskText('Refreshing failed') setTimeout(function (_) { changeRskText('Refresh') }, 3000) } else { changeRskText('Refresh') } }) } window.addEventListener('load', function (e) { if (!new URL(window.location.href).searchParams.has('station')) { window.history.back() this.setTimeout(function () { var url = new URL(window.location.href) url.pathname = 'station.html' window.location.href = url.toString() }, 100) } var sp = new URL(window.location.href).searchParams station = sp.get('station') date = sp.has('date') ? new Date(sp.get('date')) : new Date() // View departures first selectedTab = 1 selectTab(selectedTab) document.querySelectorAll('.rsk').forEach(function (rskElem) { rskElem.addEventListener('click', function (e) { rsk() }) }) 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) })