Kenneth Bruen
3 years ago
commit
f5c01f97c9
10 changed files with 813 additions and 0 deletions
@ -0,0 +1,8 @@ |
|||||||
|
window.addEventListener('load', function (e) { |
||||||
|
this.document.body.addEventListener('keydown', function (e) { |
||||||
|
if (e.key == 'Backspace') { |
||||||
|
e.preventDefault() |
||||||
|
window.history.back() |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,199 @@ |
|||||||
|
html { |
||||||
|
height: 100vh; |
||||||
|
padding: 0; |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
|
||||||
|
body { |
||||||
|
height: 100vh; |
||||||
|
padding: 0; |
||||||
|
margin: 0; |
||||||
|
|
||||||
|
font-size: 17px; |
||||||
|
font-weight: 400; |
||||||
|
|
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: stretch; |
||||||
|
} |
||||||
|
|
||||||
|
.content { |
||||||
|
height: 100%; |
||||||
|
|
||||||
|
overflow-y: scroll; |
||||||
|
|
||||||
|
-ms-overflow-style: none; |
||||||
|
scrollbar-width: none; |
||||||
|
} |
||||||
|
|
||||||
|
.content::-webkit-scrollbar { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
footer { |
||||||
|
margin-top: auto; |
||||||
|
display: flex; |
||||||
|
|
||||||
|
background-color: #e0e0e0; |
||||||
|
} |
||||||
|
|
||||||
|
footer * { |
||||||
|
text-transform: capitalize; |
||||||
|
} |
||||||
|
|
||||||
|
footer .lsk { |
||||||
|
text-align: start; |
||||||
|
} |
||||||
|
|
||||||
|
footer .csk { |
||||||
|
flex-grow: 1; |
||||||
|
text-align: center; |
||||||
|
text-transform: uppercase; |
||||||
|
} |
||||||
|
|
||||||
|
footer .rsk { |
||||||
|
text-align: end; |
||||||
|
} |
||||||
|
|
||||||
|
h1 { |
||||||
|
font-size: 17px; |
||||||
|
font-weight: 400; |
||||||
|
text-align: center; |
||||||
|
|
||||||
|
margin: 8px; |
||||||
|
} |
||||||
|
|
||||||
|
h2 { |
||||||
|
font-size: 17px; |
||||||
|
font-weight: 600; |
||||||
|
|
||||||
|
margin: 1px 0; |
||||||
|
padding-left: 8px; |
||||||
|
padding-right: 8px; |
||||||
|
} |
||||||
|
|
||||||
|
h3 { |
||||||
|
font-size: 14px; |
||||||
|
font-weight: 400; |
||||||
|
|
||||||
|
margin: 1px 0; |
||||||
|
padding-left: 8px; |
||||||
|
padding-right: 8px; |
||||||
|
} |
||||||
|
|
||||||
|
h4 { |
||||||
|
font-size: 14px; |
||||||
|
font-weight: 400; |
||||||
|
|
||||||
|
margin: 1px 0; |
||||||
|
padding-left: 8px; |
||||||
|
padding-right: 8px; |
||||||
|
|
||||||
|
color: #606060; |
||||||
|
background-color: #f0f0f0; |
||||||
|
} |
||||||
|
|
||||||
|
h5 { |
||||||
|
font-size: 14px; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
|
||||||
|
p.pri { |
||||||
|
font-size: 17px; |
||||||
|
font-weight: 400; |
||||||
|
|
||||||
|
margin: 0 8px; |
||||||
|
} |
||||||
|
|
||||||
|
p.sec { |
||||||
|
font-size: 14px; |
||||||
|
font-weight: 400; |
||||||
|
|
||||||
|
margin: 0 8px; |
||||||
|
|
||||||
|
color: gray; |
||||||
|
} |
||||||
|
|
||||||
|
p.thi { |
||||||
|
font-size: 12px; |
||||||
|
font-weight: 400; |
||||||
|
|
||||||
|
margin: 0 8px; |
||||||
|
|
||||||
|
color: gray; |
||||||
|
} |
||||||
|
|
||||||
|
p, ul { |
||||||
|
font-size: 17px; |
||||||
|
font-weight: 400; |
||||||
|
} |
||||||
|
|
||||||
|
p.link, a { |
||||||
|
font-size: 17px; |
||||||
|
font-weight: 700; |
||||||
|
} |
||||||
|
|
||||||
|
p.btn, button { |
||||||
|
font-size: 17px; |
||||||
|
font-weight: 400; |
||||||
|
|
||||||
|
margin: 8px; |
||||||
|
padding: 8px; |
||||||
|
border: 1px solid grey; |
||||||
|
border-radius: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
ul { |
||||||
|
padding: 0; |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
|
||||||
|
li { |
||||||
|
list-style: none; |
||||||
|
margin: 0; |
||||||
|
|
||||||
|
display: block; |
||||||
|
} |
||||||
|
|
||||||
|
li:focus { |
||||||
|
color: white; |
||||||
|
background-color: blue; |
||||||
|
} |
||||||
|
|
||||||
|
a { |
||||||
|
display: block; |
||||||
|
|
||||||
|
padding: 8px; |
||||||
|
|
||||||
|
color: black; |
||||||
|
text-decoration: none; |
||||||
|
} |
||||||
|
|
||||||
|
a.disabled { |
||||||
|
color: grey; |
||||||
|
} |
||||||
|
|
||||||
|
a:not(.disabled):hover:not(:focus) { |
||||||
|
color: black; |
||||||
|
background-color: lightskyblue; |
||||||
|
} |
||||||
|
|
||||||
|
a:focus { |
||||||
|
color: white; |
||||||
|
background-color: blue; |
||||||
|
} |
||||||
|
|
||||||
|
input { |
||||||
|
display: block; |
||||||
|
|
||||||
|
box-sizing: border-box; |
||||||
|
width: calc(100% - 16px); |
||||||
|
|
||||||
|
margin: 8px; |
||||||
|
padding: 2px; |
||||||
|
border: 2px solid grey; |
||||||
|
} |
||||||
|
|
||||||
|
.hidden { |
||||||
|
display: none; |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||||
|
<title>InfoTren</title> |
||||||
|
|
||||||
|
<link rel="stylesheet" href="/base.css"> |
||||||
|
|
||||||
|
<script src="items.js"></script> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<h1>InfoTren</h1> |
||||||
|
|
||||||
|
<div class="content"> |
||||||
|
<ul> |
||||||
|
<li><a class="items disabled" href="">Train routes</a></li> |
||||||
|
<li><a class="items" href="train.html">My train</a></li> |
||||||
|
<li><a class="items disabled" href="station.html">Station departures/arrivals</a></li> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
|
||||||
|
<footer> |
||||||
|
<div class="csk">Select</div> |
||||||
|
</footer> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,48 @@ |
|||||||
|
var currentIndex = 0 |
||||||
|
|
||||||
|
function nav(offset) { |
||||||
|
var items = document.querySelectorAll('.items:not(.disabled)') |
||||||
|
if (offset === -1) { |
||||||
|
if (currentIndex <= 0) { |
||||||
|
return |
||||||
|
} |
||||||
|
} |
||||||
|
else if (offset === 1) { |
||||||
|
if (currentIndex >= items.length - 1) { |
||||||
|
return |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
console.error(`nav called with unknown offset: ${offset}`) |
||||||
|
} |
||||||
|
|
||||||
|
currentIndex += offset |
||||||
|
items[currentIndex].focus() |
||||||
|
items[currentIndex].addEventListener('keydown', handleKeyDown) |
||||||
|
} |
||||||
|
|
||||||
|
function handleKeyDown(e) { |
||||||
|
switch (e.key) { |
||||||
|
case 'ArrowUp': |
||||||
|
e.preventDefault() |
||||||
|
e.stopPropagation() |
||||||
|
nav(-1) |
||||||
|
break |
||||||
|
case 'ArrowDown': |
||||||
|
e.preventDefault() |
||||||
|
e.stopPropagation() |
||||||
|
nav(1) |
||||||
|
break |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
window.addEventListener('load', function (e) { |
||||||
|
// Select first item
|
||||||
|
var items = document.querySelectorAll('.items:not(.disabled)') |
||||||
|
if (items.length > 0) { |
||||||
|
items[0].focus() |
||||||
|
items[0].addEventListener('keydown', handleKeyDown) |
||||||
|
} |
||||||
|
|
||||||
|
document.body.addEventListener('keydown', handleKeyDown) |
||||||
|
}) |
@ -0,0 +1,16 @@ |
|||||||
|
{ |
||||||
|
"version": "1", |
||||||
|
"name": "InfoTren", |
||||||
|
"launch_path": "/index.html", |
||||||
|
"description": "Frontend for InfoFer scraper", |
||||||
|
"developer": { |
||||||
|
"name": "Dan Cojocaru", |
||||||
|
"url": "https://dcdev.ro" |
||||||
|
}, |
||||||
|
"installs_allowed_from": [ |
||||||
|
"*" |
||||||
|
], |
||||||
|
"default_locale": "en", |
||||||
|
"permissions": {}, |
||||||
|
"cursor": false |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||||
|
<title>Train - InfoTren</title> |
||||||
|
|
||||||
|
<link rel="stylesheet" href="/base.css"> |
||||||
|
|
||||||
|
<script src="back.js"></script> |
||||||
|
<script src="items.js"></script> |
||||||
|
<script src="train.js"></script> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<h1>Train Information</h1> |
||||||
|
|
||||||
|
<h4>Train Number</h4> |
||||||
|
<input class="items" type="tel" name="trainNumber" id="trainNumber"> |
||||||
|
|
||||||
|
<h4>Suggestions</h4> |
||||||
|
<div class="content"> |
||||||
|
<ul id="suggestionsArea"></ul> |
||||||
|
</div> |
||||||
|
|
||||||
|
<footer> |
||||||
|
<div class="csk">Search</div> |
||||||
|
</footer> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,109 @@ |
|||||||
|
var knownTrains = [] |
||||||
|
|
||||||
|
function goToTrain(number) { |
||||||
|
var url = new URL(window.location.href) |
||||||
|
url.pathname = 'view-train.html' |
||||||
|
url.searchParams.set('train', number) |
||||||
|
url.searchParams.set('date', new Date().toISOString()) |
||||||
|
window.location.href = url.toString() |
||||||
|
} |
||||||
|
|
||||||
|
var _rebuildDebounce = null |
||||||
|
var _rebuildRequested = false |
||||||
|
function rebuildSuggestions() { |
||||||
|
if (_rebuildDebounce !== null) { |
||||||
|
_rebuildRequested = true |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
_rebuildRequested = false |
||||||
|
_rebuildDebounce = 123 |
||||||
|
|
||||||
|
var suggestionsArea = document.getElementById('suggestionsArea') |
||||||
|
while (suggestionsArea.childNodes.length > 0) { |
||||||
|
suggestionsArea.childNodes[0].remove() |
||||||
|
} |
||||||
|
|
||||||
|
var trainNumberInput = document.getElementById('trainNumber') |
||||||
|
var trainNumber = trainNumberInput.value.trim() |
||||||
|
|
||||||
|
var suggestions = [] |
||||||
|
for (var i = 0; i < knownTrains.length; i++) { |
||||||
|
if (trainNumber) { |
||||||
|
if (!knownTrains[i].number.includes(trainNumber)) { |
||||||
|
continue |
||||||
|
} |
||||||
|
} |
||||||
|
suggestions.push(knownTrains[i]) |
||||||
|
} |
||||||
|
|
||||||
|
suggestions.forEach(function (suggestion, index) { |
||||||
|
var suggestionLi = document.createElement('li') |
||||||
|
suggestionsArea.appendChild(suggestionLi) |
||||||
|
|
||||||
|
setTimeout(function () { |
||||||
|
suggestionLi.classList.add('items') |
||||||
|
suggestionLi.tabIndex = index + 1 |
||||||
|
suggestionLi.style.padding = '2px 0' |
||||||
|
|
||||||
|
function onAction(e) { |
||||||
|
goToTrain(suggestion.number) |
||||||
|
} |
||||||
|
suggestionLi.addEventListener('click', onAction) |
||||||
|
suggestionLi.addEventListener('keypress', function (e) { |
||||||
|
if (e.key == 'Enter') { |
||||||
|
onAction(e) |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
var trainNameP = document.createElement('p') |
||||||
|
suggestionLi.appendChild(trainNameP) |
||||||
|
|
||||||
|
trainNameP.textContent = `${suggestion.rank} ${suggestion.number}` |
||||||
|
trainNameP.classList.add('pri', 'trainName') |
||||||
|
|
||||||
|
var trainCompanyP = document.createElement('p') |
||||||
|
suggestionLi.appendChild(trainCompanyP) |
||||||
|
|
||||||
|
trainCompanyP.textContent = suggestion.company |
||||||
|
trainCompanyP.classList.add('thi') |
||||||
|
}, 0) |
||||||
|
}) |
||||||
|
|
||||||
|
setTimeout(function () { |
||||||
|
_rebuildDebounce = null |
||||||
|
if (_rebuildRequested) { |
||||||
|
rebuildSuggestions() |
||||||
|
} |
||||||
|
}, 500) |
||||||
|
} |
||||||
|
|
||||||
|
window.addEventListener('load', function (e) { |
||||||
|
var trainNumber = document.getElementById('trainNumber') |
||||||
|
trainNumber.addEventListener('input', function (e) { |
||||||
|
rebuildSuggestions() |
||||||
|
}) |
||||||
|
trainNumber.addEventListener('focus', function (e) { |
||||||
|
document.getElementsByClassName('csk')[0].textContent = 'Search' |
||||||
|
}) |
||||||
|
trainNumber.addEventListener('blur', function (e) { |
||||||
|
document.getElementsByClassName('csk')[0].textContent = 'Select' |
||||||
|
}) |
||||||
|
trainNumber.addEventListener('keypress', function (e) { |
||||||
|
if (e.key == 'Enter') { |
||||||
|
goToTrain(trainNumber.value.trim()) |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
fetch('https://scraper.infotren.dcdev.ro/v2/trains') |
||||||
|
.then(function (response) { |
||||||
|
return response.json() |
||||||
|
}) |
||||||
|
.then(function (response) { |
||||||
|
knownTrains = response |
||||||
|
knownTrains.sort(function(a, b) { return a.number - b.number }) |
||||||
|
}) |
||||||
|
.then(function () { |
||||||
|
rebuildSuggestions() |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,75 @@ |
|||||||
|
.IR, .IRN { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
|
||||||
|
.early { |
||||||
|
color: green; |
||||||
|
} |
||||||
|
|
||||||
|
.late { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
|
||||||
|
.station { |
||||||
|
color: black; |
||||||
|
} |
||||||
|
|
||||||
|
#company { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.stationItem { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: 50px auto 50px; |
||||||
|
grid-template-rows: auto; |
||||||
|
grid-template-areas: |
||||||
|
"arr name dep" |
||||||
|
"arr km dep" |
||||||
|
"arr platform dep"; |
||||||
|
padding: 4px 0; |
||||||
|
} |
||||||
|
|
||||||
|
.stationItem .name { |
||||||
|
text-align: center; |
||||||
|
grid-area: name; |
||||||
|
} |
||||||
|
|
||||||
|
.stationItem .arrival { |
||||||
|
text-align: start; |
||||||
|
grid-area: arr; |
||||||
|
|
||||||
|
align-items: flex-start; |
||||||
|
} |
||||||
|
|
||||||
|
.stationItem .departure { |
||||||
|
text-align: end; |
||||||
|
grid-area: dep; |
||||||
|
|
||||||
|
align-items: flex-end; |
||||||
|
} |
||||||
|
|
||||||
|
.stationItem .arrival, .station .departure { |
||||||
|
align-self: center; |
||||||
|
|
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
} |
||||||
|
|
||||||
|
.stationItem .arrival .original, .stationItem .departure .original { |
||||||
|
color: #a0a0a0; |
||||||
|
text-decoration: line-through; |
||||||
|
} |
||||||
|
|
||||||
|
.stationItem .arrival .not-real, .stationItem .departure .not-real { |
||||||
|
font-style: italic; |
||||||
|
} |
||||||
|
|
||||||
|
.stationItem .km { |
||||||
|
text-align: center; |
||||||
|
grid-area: km; |
||||||
|
} |
||||||
|
|
||||||
|
.stationItem .platform { |
||||||
|
text-align: center; |
||||||
|
grid-area: platform; |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||||
|
<title>View Train - InfoTren</title> |
||||||
|
|
||||||
|
<link rel="stylesheet" href="/base.css"> |
||||||
|
<link rel="stylesheet" href="view-train.css"> |
||||||
|
|
||||||
|
<script src="back.js"></script> |
||||||
|
<script src="view-train.js"></script> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<h1>Train Info</h1> |
||||||
|
<p class="sec" id="company"></p> |
||||||
|
|
||||||
|
<div class="content" tabindex="0"> |
||||||
|
<div id="route"> |
||||||
|
<h4>Route</h4> |
||||||
|
<p class="thi">From</p> |
||||||
|
<p class="pri" id="route-from"></p> |
||||||
|
<p class="thi">To</p> |
||||||
|
<p class="pri" id="route-to"></p> |
||||||
|
</div> |
||||||
|
<div id="status" class="hidden"> |
||||||
|
<h4>Status</h4> |
||||||
|
<p class="pri" id="status-delay"></p> |
||||||
|
<p class="sec" id="status-location"></p> |
||||||
|
</div> |
||||||
|
<div id="stations"> |
||||||
|
<h4>Stations</h4> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<footer> |
||||||
|
<div class="csk"></div> |
||||||
|
<div class="rsk">Refresh</div> |
||||||
|
</footer> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,258 @@ |
|||||||
|
var trainNumber |
||||||
|
var date |
||||||
|
|
||||||
|
var showKm = false |
||||||
|
|
||||||
|
var trainData = 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('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 = 'No delay' |
||||||
|
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.getHours().toString().padStart(2, "0")}:${arrDate.getMinutes().toString().padStart(2, "0")}` |
||||||
|
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.getHours().toString().padStart(2, "0")}:${arrDate.getMinutes().toString().padStart(2, "0")}` |
||||||
|
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.getHours().toString().padStart(2, "0")}:${depDate.getMinutes().toString().padStart(2, "0")}` |
||||||
|
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.getHours().toString().padStart(2, "0")}:${depDate.getMinutes().toString().padStart(2, "0")}` |
||||||
|
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') |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
var refreshStopToken = null |
||||||
|
function refresh() { |
||||||
|
fetch(`https://scraper.infotren.dcdev.ro/v2/train/${trainNumber}?date=${date.toISOString()}`) |
||||||
|
.then(function (response) { |
||||||
|
return response.json() |
||||||
|
}) |
||||||
|
.then(function (response) { |
||||||
|
trainData = response |
||||||
|
onTrainData(response) |
||||||
|
}) |
||||||
|
.then(function () { |
||||||
|
refreshStopToken = setTimeout(function () {
|
||||||
|
refresh() |
||||||
|
}, 60000) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
window.addEventListener('unload', function (e) { |
||||||
|
if (refreshStopToken != null) { |
||||||
|
clearTimeout(refreshStopToken) |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
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() |
||||||
|
|
||||||
|
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': |
||||||
|
refresh() |
||||||
|
break |
||||||
|
case '*': |
||||||
|
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() |
||||||
|
}) |
Loading…
Reference in new issue