/**
* @type {string}
*/
var trainNumber
/**
* @type {string | null}
*/
var tripId = null
/**
* @type {Date}
*/
var date
var groupIndex = null
/**
* @type {string | null}
*/
var startId = null
/**
* @type {string | null}
*/
var stopId = null
var yesterday = false
var showKm = false
var trainData = null
/**
* @type {?Date}
*/
var lastSuccessfulFetch = null
var loadMap = false
/**
* @type {any}
*/
var leafletMap = null
/**
* @type {any[]}
*/
var mapLayers = []
/**
* @param {DbTrip & DbArrDep} data
* @param {?Date} fetchDate
*/
function onTrainData(data, fetchDate) {
if (loadMap) {
document.getElementById('load-map-button').remove()
}
if (window.localStorage) {
localStorage.setItem('recent/view-train', JSON.stringify({
trainNumber: data.line.fahrtNr,
name: data.line.name,
tripId: data.id,
date: date ? date.toISOString() : undefined,
$addDate: new Date().toISOString(),
}))
}
var title = document.getElementById('title')
title.textContent = ''
var titleCategory = ''
switch (data.line.product) {
case 'bus':
titleCategory = ''
break
case 'ferry':
titleCategory = 'Ferry'
break
default:
titleCategory = 'Train'
}
title.appendChild(document.createTextNode(titleCategory + ' '))
var lineNameSpan = document.createElement('span')
title.appendChild(lineNameSpan)
lineNameSpan.textContent = data.line.name
if (data.line.product) {
if (data.line.productName === 'STB' && data.line.name.startsWith('STB U')) {
data.line.product = 'subway'
}
if (data.line.adminCode === 'vvs020') {
// Stuttgart Stadtbahn
lineNameSpan.innerText = data.line.name.slice(4)
} else if (data.line.adminCode === '800643') {
// Stuttgart S-Bahn
lineNameSpan.innerText = 'S' + data.line.name.slice(2)
} else if (data.line.adminCode === 'kvv021') {
// Karlsruhe Tram
lineNameSpan.innerText = data.line.name.slice(4)
}
lineNameSpan.classList.add('product-' + data.line.product)
lineNameSpan.classList.add('product-id-' + data.line.id)
lineNameSpan.classList.add('product-adminCode-' + data.line.adminCode)
if (data.line.operator) {
lineNameSpan.classList.add('product-operator-' + data.line.operator.id)
}
}
// trainIdSpan(data.line.productName, data.line.fahrtNr, title)
// title.append(' ')
title.append(` (${data.line.fahrtNr})`)
document.getElementsByTagName('title')[0].textContent = `Train ${data.line.productName} ${data.line.fahrtNr} (${data.line.name})`
if (data.line.operator) {
document.getElementById('company').textContent = data.line.operator.name
}
var dateHref = document.createElement('a')
var dateP = document.getElementById('date')
while (dateP.childNodes.length > 0) {
dateP.childNodes[0].remove()
}
dateP.appendChild(dateHref)
dateHref.textContent = new Date(data.departure || data.plannedDeparture).toDateString()
dateHref.href = '#'
dateHref.classList.add('no-a-custom')
dateHref.classList.add('items', 'no-a-custom')
dateHref.addEventListener('click', function (e) {
e.preventDefault()
// Implement date switcher
yesterday = !yesterday
if (!yesterday) {
history.back()
}
else {
const yesterdayUrl = new URL(location.href)
const newDate = new Date(date.getTime())
newDate.setDate(newDate.getDate() - 1)
yesterdayUrl.searchParams.set('date', newDate.toISOString())
history.pushState('', '', yesterdayUrl)
}
refresh()
})
document.getElementById('loading').classList.add('hidden')
/**
* @type {DbTrip & DbArrDep}
*/
var group = data
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.origin.name
document.getElementById('route-to').textContent = group.destination.name
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)
/**
* @type {string[] | null}
*/
var journeyStations = null
if (startId && stopId) {
journeyStations = []
var include = false
for (var si = 0; si < group.stopovers.length; si++) {
if (group.stopovers[si].stop.id === startId) {
include = true
}
if (include) {
journeyStations.push(group.stopovers[si].stop.id)
}
if (group.stopovers[si].stop.id === stopId) {
break
}
}
}
group.stopovers.forEach(function (station) {
var stationItem = document.createElement('li')
stationsList.appendChild(stationItem)
stationItem.classList.add('stationItem')
if (station.cancelled && !station.arrival && !station.departure) {
stationItem.classList.add('cancelled')
}
if (journeyStations && !journeyStations.includes(station.stop.id)) {
stationItem.classList.add('not-in-journey')
}
var stationName = document.createElement('p')
stationItem.appendChild(stationName)
stationName.classList.add('pri', 'name')
var stationNameHref = document.createElement('a')
stationName.appendChild(stationNameHref)
stationNameHref.textContent = station.stop.name
stationNameHref.classList.add('items', 'no-a-custom')
var stationUrl = new URL('/view-station.html', window.location.origin)
stationUrl.searchParams.append('stationId', station.stop.id)
stationUrl.searchParams.append('date', (station.arrival || station.departure))
stationNameHref.href = stationUrl.toString()
if (station.arrival) {
var stationArrival = document.createElement('div')
stationItem.appendChild(stationArrival)
stationArrival.classList.add('arrival')
var originalArr = document.createElement('p')
stationArrival.appendChild(originalArr)
var originalArrSpan = document.createElement('pre')
originalArr.appendChild(originalArrSpan)
var arrDate = new Date(station.plannedArrival)
originalArrSpan.textContent = arrDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' })
originalArr.classList.add('pri')
if (station.arrivalDelay) {
originalArr.classList.remove('pri')
originalArr.classList.add('thi')
originalArrSpan.classList.add('original')
var delaySpanArr = document.createElement('span')
originalArr.appendChild(delaySpanArr)
delaySpanArr.textContent = `${station.arrivalDelay > 0 ? '+' : ''}${station.arrivalDelay / 60}`;
delaySpanArr.classList.add(station.arrivalDelay > 0 ? 'late' : 'early')
delaySpanArr.style.marginLeft = '4px'
var actualArr = document.createElement('p')
stationArrival.appendChild(actualArr)
arrDate.setSeconds(arrDate.getSeconds() + station.arrivalDelay)
actualArr.classList.add('pri', station.arrivalDelay > 0 ? 'late' : 'early')
// if (!station.arrival.status.real) {
// actualArr.classList.add('not-real')
// }
var actualArrPre = document.createElement('pre')
actualArr.appendChild(actualArrPre)
actualArrPre.textContent = arrDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' })
}
}
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.plannedDeparture)
var originalDepSpan = document.createElement('pre')
originalDep.appendChild(originalDepSpan)
originalDepSpan.textContent = depDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' })
originalDep.classList.add('pri')
if (station.departureDelay) {
originalDep.classList.remove('pri')
originalDep.classList.add('thi')
originalDepSpan.classList.add('original')
var delaySpanDep = document.createElement('span')
originalDep.appendChild(delaySpanDep)
delaySpanDep.textContent = `${station.departureDelay > 0 ? '+' : ''}${station.departureDelay / 60}`;
delaySpanDep.classList.add(station.departureDelay > 0 ? 'late' : 'early')
delaySpanDep.style.marginLeft = '4px'
var actualDep = document.createElement('p')
stationDeparture.appendChild(actualDep)
depDate.setSeconds(depDate.getSeconds() + station.departureDelay)
actualDep.classList.add('pri', station.departureDelay > 0 ? 'late' : 'early')
// if (!station.departure.status.real) {
// actualDep.classList.add('not-real')
// }
var actualDepPre = document.createElement('pre')
actualDep.appendChild(actualDepPre)
actualDepPre.textContent = depDate.toLocaleTimeString([], { 'hour': '2-digit', 'minute': '2-digit' })
}
}
// 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.arrivalPlatform || station.departurePlatform) {
var stationPlatform = document.createElement('p')
stationItem.appendChild(stationPlatform)
stationPlatform.textContent = `platform ${station.departurePlatform || station.arrivalPlatform}`
stationPlatform.classList.add('thi', 'platform')
if (station.departurePlatform && station.departurePlatform !== station.plannedDeparturePlatform) {
stationPlatform.classList.add('changed')
}
}
var stationNotes = document.createElement('div')
stationItem.appendChild(stationNotes)
stationNotes.classList.add('notes')
if (station.remarks) {
station.remarks.forEach(function (remark) {
var noteP = document.createElement('p')
stationNotes.appendChild(noteP)
noteP.classList.add('note', 'thi', `remark-${remark.type}`)
noteP.textContent = remark.text
})
}
if (journeyStations && station.stop.id === journeyStations[0]) {
var boardNoteP = document.createElement('p')
stationNotes.appendChild(boardNoteP)
boardNoteP.classList.add('note', 'thi', 'remark-board')
boardNoteP.textContent = 'Board here'
}
if (journeyStations && station.stop.id === journeyStations[journeyStations.length - 1]) {
var boardNoteP = document.createElement('p')
stationNotes.appendChild(boardNoteP)
boardNoteP.classList.add('note', 'thi', 'remark-exit')
boardNoteP.textContent = 'Exit here'
}
// if (station.notes && station.notes.length > 0) {
// 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 '
// trainIdSpan(note.rank, note.number, noteP)
// 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 '
// trainIdSpan(note.rank, note.number, noteP)
// break
// }
// }
// })
// }
if (station.cancelled && !station.arrival && !station.departure) {
var noteP = document.createElement('p')
stationNotes.appendChild(noteP)
noteP.classList.add('note', 'thi')
noteP.textContent = 'Stop is cancelled'
}
})
if (group.remarks && group.remarks.length > 0) {
var remarksSeparator = document.createElement('h4')
stationsDiv.appendChild(remarksSeparator)
remarksSeparator.textContent = 'Remarks'
var remarksList = document.createElement('ul')
stationsDiv.appendChild(remarksList)
remarksList.classList.add('remarks')
group.remarks.forEach(function (remark) {
var remarkItem = document.createElement('li')
remarksList.append(remarkItem)
remarkItem.classList.add('remarkItem', `remark-${remark.type}`)
var remarkSummaryP = document.createElement('p')
remarkItem.appendChild(remarkSummaryP)
remarkSummaryP.classList.add('remark', 'pri')
remarkSummaryP.textContent = remark.summary
var remarkTextP = document.createElement('p')
remarkItem.appendChild(remarkTextP)
remarkTextP.classList.add('remark', 'sec')
remarkTextP.textContent = remark.text
})
}
var mapDiv = document.getElementById('map')
if (group.polyline) {
console.log(group.polyline)
mapDiv.classList.remove('hidden')
var actualMap = document.getElementById('actual-map')
if (!actualMap) {
actualMap = document.createElement('div')
actualMap.id = 'actual-map'
mapDiv.insertBefore(actualMap, null)
}
if (!leafletMap) {
leafletMap = L.map('actual-map', {
zoomSnap: 0.5,
// zoomDelta: 0.5,
}).setView([51.1657, 10.4515], 6)
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(leafletMap);
L.tileLayer('https://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png', {
attribution: ' Style: CC-BY-SA 2.0 OpenRailwayMap and OpenStreetMap',
minZoom: 2,
maxZoom: 19,
tileSize: 256
}).addTo(leafletMap)
}
if (mapLayers) {
mapLayers.forEach(function (layer) { layer.remove() })
mapLayers = []
}
/**
* @type {[number, number][]}
*/
var lines = []
/**
* @type {[number, number][] | null}
*/
var journeyLines = null
include = false
var stops = []
var minLat = group.polyline.features[0].geometry.coordinates[1]
var maxLat = minLat
var minLng = group.polyline.features[0].geometry.coordinates[0]
var maxLng = minLng
for (var pi = 0; pi < group.polyline.features.length; pi++) {
var feature = group.polyline.features[pi]
var coord = feature.geometry.coordinates
lines.push([coord[1], coord[0]])
if (journeyStations && include !== -1) {
if (feature.properties && feature.properties.id === journeyStations[0]) {
minLat = maxLat = coord[1]
minLng = maxLng = coord[0]
include = true
}
if (include) {
if (!journeyLines) journeyLines = []
journeyLines.push([coord[1], coord[0]])
}
if (feature.properties && feature.properties.id === journeyStations[journeyStations.length - 1]) {
include = -1
}
}
if (feature.properties && feature.properties.type == 'stop') {
stops.push({
coord: [coord[1], coord[0]],
id: feature.properties.id,
})
}
if (!journeyStations || include === true) {
if (minLat > coord[1]) {
minLat = coord[1]
}
if (minLng > coord[0]) {
minLng = coord[0]
}
if (maxLat < coord[1]) {
maxLat = coord[1]
}
if (maxLng < coord[0]) {
maxLng = coord[0]
}
}
}
mapLayers.push(L.polyline(lines, {
color: !journeyLines ? '#6666ff' : '#9999dd',
opacity: !journeyLines ? 1.0 : 0.8,
weight: 4,
}).addTo(leafletMap));
if (journeyLines) {
mapLayers.push(L.polyline(journeyLines, {
color: '#6666ff',
weight: 2,
}).addTo(leafletMap));
}
for (var si = 0; si < stops.length; si++) {
var stop = stops[si]
mapLayers.push(L.circleMarker(stop.coord, {
color: !journeyStations || journeyStations.includes(stop.id) ? '#ffff66' : '#dfdf66',
radius: 5,
}).addTo(leafletMap))
}
leafletMap.flyToBounds([[minLat, minLng], [maxLat, maxLng]], {
duration: 0.2,
})
actualMap.scrollIntoView()
}
else if (loadMap) {
mapDiv.classList.add('hidden')
}
lastSuccessfulFetch = fetchDate || new Date()
}
var refreshStopToken = null
/**
* @typedef DbProducts
* @property {boolean} nationalExpress
* @property {boolean} national
* @property {boolean} regionalExpress
* @property {boolean} regional
* @property {boolean} suburban
* @property {boolean} bus
* @property {boolean} ferry
* @property {boolean} subway
* @property {boolean} tram
* @property {boolean} taxi
*/
/**
* @typedef DbLocation
* @property {'location'} type
* @property {?string} id
* @property {number} latitude
* @property {number} longitude
*/
/**
* @typedef DbLine
* @property {'line'} type
* @property {string} id
* @property {string} fahrtNr
* @property {string} name
* @property {boolean} public
* @property {string} adminCode
* @property {string} productName
* @property {string} mode
* @property {string} product
* @property {{type: 'operator', id: string, name: string}} operator
* @property {string} additionalName
*/
/**
* @typedef DbStop
* @property {'stop'} type
* @property {?string} id
* @property {string} name
* @property {DbLocation} location
* @property {DbProducts} products
*/
/**
* @typedef DbRemark
* @property {string} type
* @property {string} text
* @property {string} code
* @property {string} summary
*/
/**
* @typedef DbArrDep
* @property {string | null} arrival
* @property {string | null} plannedArrival
* @property {number | null} arrivalDelay
* @property {string | null} arrivalPlatform
* @property {string | null} plannedArrivalPlatform
* @property {string | null} arrivalPrognosisType
* @property {string | null} departure
* @property {string | null} plannedDeparture
* @property {number | null} departureDelay
* @property {string | null} departurePlatform
* @property {string | null} plannedDeparturePlatform
* @property {string | null} departurePrognosisType
*/
/**
* @typedef DbTrip
* @property {DbStop} origin
* @property {DbStop} destination
* @property {DbLine} line
* @property {string} direction
* @property {DbLocation} location
* @property {({stop: DbStop, cancelled?: boolean, remarks?: DbRemark[]} & DbArrDep)[]} stopovers
* @property {DbRemark[]} remarks
* @property {string} id
*/
/**
* @param {string | null} tripId
* @returns {Promise}
*/
function onTripId(tripId) {
if (tripId) {
var reqUrl = new URL(`https://v6.db.transport.rest/trips/${encodeURIComponent(tripId)}`)
reqUrl.searchParams.append('stopovers', 'true')
reqUrl.searchParams.append('remarks', 'true')
if (loadMap) {
reqUrl.searchParams.append('polyline', 'true')
}
return fetch(
reqUrl.toString(),
{
cache: 'no-store',
},
).then(function (response) {
if (!response.ok) {
// Check in 10 seconds if server returned error
return Promise.reject('Response not okay')
}
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 Promise.reject('No JSON response')
}
var cacheDate = response['$cacheDate']
if (cacheDate) {
cacheDate = new Date(cacheDate)
}
var success = !cacheDate
trainData = response.trip
onTrainData(response.trip, cacheDate)
return success
})
}
else {
return Promise.reject('No tripId found')
}
}
/**
* Callback for when trips are found
* @param {string} wantedTrainNumber
* @param {{trips: (DbTrip & DbArrDep)[]}} data
* @param {?Date} fetchDate
*/
function onTripsData(wantedTrainNumber, data, fetchDate) {
data.trips.forEach(function (trip) {
if (trip.line.fahrtNr == wantedTrainNumber || trip.line.name == wantedTrainNumber) {
tripId = trip.id
console.group('Found tripId by train number')
console.log(`ID: ${trip.id}`)
console.log(`Fahrt Nr: ${trip.line.fahrtNr}`)
console.log(`Name: ${trip.line.name}`)
console.log(`+Name: ${trip.line.additionalName}`)
console.groupEnd()
}
})
return onTripId(tripId)
}
/**
* @returns {Promise}
*/
function refresh() {
function reschedule(timeout) {
if (refreshStopToken != null) {
clearTimeout(refreshStopToken)
}
refreshStopToken = setTimeout(function () {
refresh()
}, timeout || 60000)
}
if (tripId) {
return onTripId(tripId)
}
/**
* @type {Date}
*/
var reqDate = new Date(date.valueOf())
if (yesterday) {
reqDate.setDate(reqDate.getDate() - 1)
}
reqDate.setMinutes(0, 0, 0)
var reqUrl = new URL(`https://v6.db.transport.rest/trips`)
reqUrl.searchParams.append('query', trainNumber)
if (loadMap) {
reqUrl.searchParams.append('polyline', 'true')
}
reqUrl.searchParams.append('when', reqDate.toISOString())
return fetch(
reqUrl.toString(),
{
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
return onTripsData(trainNumber, response, cacheDate)
.then(function () {
// 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('popstate', function (e) {
if (yesterday) {
yesterday = false
trainData = null
}
else {
groupIndex = null
}
if (trainData) {
onTrainData(trainData)
}
else {
refresh()
}
})
window.addEventListener('load', function (e) {
var sp = new URL(window.location.href).searchParams
if (!sp.has('train') && !sp.has('tripId')) {
window.history.back()
this.setTimeout(function () {
var url = new URL(window.location.href)
url.pathname = 'train.html'
window.location.href = url.toString()
}, 100)
}
trainNumber = sp.get('train')
date = sp.has('date') ? new Date(sp.get('date')) : new Date()
groupIndex = sp.has('groupIndex') ? parseInt(sp.get('groupIndex')) : null
tripId = sp.get('tripId')
startId = sp.get('startId')
stopId = sp.get('stopId')
if (window.localStorage) {
var oldRecent = localStorage.getItem('recent/view-train')
if (oldRecent) {
oldRecent = JSON.parse(oldRecent)
}
localStorage.setItem('recent/view-train', JSON.stringify({
trainNumber: trainNumber,
tripId: tripId,
date: date.toISOString(),
$addDate: new Date().toISOString(),
}))
}
document.querySelectorAll('.rsk').forEach(function (rskElem) {
rskElem.addEventListener('click', function (e) {
rsk()
})
})
if (navigator.canShare && navigator.canShare({ url: '' })) {
document.getElementById('title').addEventListener('click', function () {
navigator.share({ url: '' });
})
}
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)
}
})
document.getElementById('load-map-button').addEventListener('click', function (event) {
event.preventDefault()
event.target.textContent = 'Loading...'
loadMap = true;
refresh()
})
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)
// if (this.localStorage && !this.localStorage.getItem('info-yesterday')) {
// this.alert("New feature: You can now view yesterday's train by selecting the date!")
// this.localStorage.setItem('info-yesterday', 'true')
// }
})