initial commit
This commit is contained in:
579
index.html
Normal file
579
index.html
Normal file
@@ -0,0 +1,579 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
IDEAS:
|
||||
- Achievements (i.e. "take a train which is delayed by at least 60 minutes" xd)
|
||||
- Show a map in the end (no need for world map, just use coordinates on flat black rectangle)
|
||||
-->
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="color-scheme" content="light dark">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>🚉 bahnreise</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0px;
|
||||
border-width: 0px;
|
||||
padding: 0px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background: light-dark(#ECE, #000);
|
||||
}
|
||||
|
||||
#Header {
|
||||
position: sticky;
|
||||
top: 0px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
background: light-dark(#FC8888, #421414);
|
||||
width: 100%;
|
||||
border-bottom-style: solid;
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
border-bottom-width: 0.4em;
|
||||
margin-bottom: 0.2em;
|
||||
border-bottom-color: light-dark(#ECEA, #000A);
|
||||
}
|
||||
#HeaderLeft, #HeaderRight {
|
||||
display: inline-block;
|
||||
flex: 1;
|
||||
text-wrap-mode: nowrap;
|
||||
cursor: default;
|
||||
user-select: none;
|
||||
}
|
||||
#HeaderLeft {
|
||||
left: 0px;
|
||||
}
|
||||
#HeaderRight {
|
||||
right: 0px;
|
||||
}
|
||||
#StationCurrent, #StationDestination {
|
||||
position: relative;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#Welcome, #InGame {
|
||||
max-width: min(90%, 50em);
|
||||
margin: 0 auto;
|
||||
}
|
||||
#TransportModeSelection {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
cursor: default;
|
||||
}
|
||||
.TransportModeIcon {
|
||||
font-size: xx-large;
|
||||
text-wrap-mode: nowrap;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
#StartGameButton {
|
||||
border-style: solid;
|
||||
padding: 2px;
|
||||
border-width: 2px;
|
||||
border-radius: 4px;
|
||||
border-color: #0000;
|
||||
cursor: pointer;
|
||||
background: light-dark(#FC6C6C, #541818);
|
||||
opacity: 1;
|
||||
}
|
||||
#StartGameButton:hover {
|
||||
transition: filter 2s ease-out;
|
||||
filter: hue-rotate(-270deg);
|
||||
border-color: light-dark(#0004, #FFF3);
|
||||
}
|
||||
#StartGameButton:disabled {
|
||||
filter: none;
|
||||
border-color: #0000;
|
||||
cursor: default;
|
||||
}
|
||||
#StartGameButton:active {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
margin: 2px;
|
||||
padding: 2px;
|
||||
border-width: 2px;
|
||||
border-radius: 4px;
|
||||
border-style: solid;
|
||||
border-color: light-dark(#4006, #FCC6);
|
||||
background: inherit;
|
||||
}
|
||||
.StationSearchResult {
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#InGame {
|
||||
display: none;
|
||||
position: relative;
|
||||
}
|
||||
#FocusedDeparturePanel {
|
||||
position: fixed;
|
||||
top: 2.5em;
|
||||
bottom: 0.5em;
|
||||
right: max(5%, calc(50% - 25em));
|
||||
padding-right: 0.5em;
|
||||
padding-left: 0.5em;
|
||||
left: 100%;
|
||||
transition: left 0.3s ease-in-out;
|
||||
border: 1px solid light-dark(#0004, #FFF2);
|
||||
background: light-dark(#DBD, #080808);
|
||||
overflow: scroll;
|
||||
}
|
||||
#FocusedDeparturePanelStops {
|
||||
padding-left: 1em;
|
||||
min-height: 100%;
|
||||
}
|
||||
#FocusedDeparturePanelCloseClickable {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0px;
|
||||
}
|
||||
|
||||
.DetailedViewPastStop {
|
||||
opacity: 0.8;
|
||||
font-size: x-small;
|
||||
cursor: default;
|
||||
}
|
||||
.DetailedViewCurrentStop {
|
||||
opacity: 0.8;
|
||||
font-size: small;
|
||||
text-decoration: underline;
|
||||
cursor: default;
|
||||
}
|
||||
.DetailedViewFutureStop {
|
||||
opacity: 0.8;
|
||||
transition: opacity 0.15s;
|
||||
cursor: pointer;
|
||||
}
|
||||
.DetailedViewFutureStop:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="Header">
|
||||
<span id="HeaderLeft">⊙ <span id="StationCurrent"></span><pre style="display:inline;"> </pre></span>
|
||||
<span id="HeaderRight">➤ <span id="StationDestination"></span></span>
|
||||
</div>
|
||||
|
||||
<div id="Welcome">
|
||||
<div id="TransportModeHeader">I like traveling by...</div>
|
||||
<div id="TransportModeSelection">
|
||||
<span id="TransportModeBus" class="TransportModeIcon" title="Bus"> 🚌 </span>
|
||||
<span id="TransportModeTram" class="TransportModeIcon" title="Tram & Metro"> 🚊 </span>
|
||||
<span id="TransportModeS" class="TransportModeIcon" title="Light Rail / S-Bahn"> 🚈 </span>
|
||||
<span id="TransportModeRE" class="TransportModeIcon" title="Regional Train (RB/RE)"> 🚆 </span>
|
||||
<span id="TransportModeICE" class="TransportModeIcon" title="High-Speed Rail (IC/ICE)"> 🚄 </span>
|
||||
</div>
|
||||
<br>
|
||||
<div id="StartGameSection">
|
||||
<button id="StartGameButton">Begin Journey</button>
|
||||
</div>
|
||||
<br>
|
||||
<div id="StationSearch">
|
||||
<input id="StationSearchInput" type="text">
|
||||
<div id="StationSearchResults"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="InGame">
|
||||
<div id="DeparturesList"></div>
|
||||
<div id="FocusedDeparturePanelCloseClickable"></div>
|
||||
<div id="FocusedDeparturePanel">
|
||||
<div id="FocusedDeparturePanelHead"></div>
|
||||
<ul id="FocusedDeparturePanelStops"></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
// === Utilities ===
|
||||
|
||||
function runInit(func) {
|
||||
func();
|
||||
return func;
|
||||
}
|
||||
|
||||
// === Game State ===
|
||||
|
||||
var isInGame = false;
|
||||
|
||||
var transportModesInteger = 0b00011;
|
||||
var transportModeBus = true;
|
||||
var transportModeTram = true;
|
||||
var transportModeS = false;
|
||||
var transportModeRE = false;
|
||||
var transportModeICE = false;
|
||||
|
||||
var stationCurrent = null;
|
||||
var stationDestination = null;
|
||||
|
||||
// === Dragging ===
|
||||
|
||||
var draggingElement = null;
|
||||
var draggingStartPos = null;
|
||||
var draggingEndCallback = null;
|
||||
var draggableElements = new Array();
|
||||
|
||||
function draggingEnable(elem, onUp) {
|
||||
// NOTE: Assumes the element has `position: relative;`
|
||||
draggableElements.push(elem);
|
||||
elem.style.cursor = "grab";
|
||||
elem.addEventListener("mousedown", (e) => {
|
||||
if (isInGame) return;
|
||||
if (e.button != 0) return;
|
||||
draggingEndCallback = onUp;
|
||||
draggingOnDown(e.clientX, e.clientY, elem);
|
||||
});
|
||||
elem.addEventListener("touchstart", (e) => {
|
||||
if (isInGame) return;
|
||||
if (e.touches.length == 1) {
|
||||
draggingEndCallback = onUp;
|
||||
draggingOnDown(e.touches[0].clientX, e.touches[0].clientY, elem);
|
||||
} else {
|
||||
draggingCancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("mousemove", (e) => {
|
||||
draggingOnMove(e.clientX, e.clientY);
|
||||
});
|
||||
document.addEventListener("mouseup", (e) => {
|
||||
draggingOnUp(e.clientX, e.clientY);
|
||||
});
|
||||
document.addEventListener("touchmove", (e) => {
|
||||
if (e.touches.length == 1) {
|
||||
draggingOnMove(e.touches[0].clientX, e.touches[0].clientY);
|
||||
} else {
|
||||
draggingCancel();
|
||||
}
|
||||
});
|
||||
document.addEventListener("touchend", (e) => {
|
||||
if (e.changedTouches.length == 1) {
|
||||
draggingOnUp(e.changedTouches[0].clientX, e.changedTouches[0].clientY);
|
||||
}
|
||||
});
|
||||
document.addEventListener("touchcancel", (e) => {
|
||||
draggingCancel();
|
||||
});
|
||||
function draggingOnDown(x, y, e) {
|
||||
if (isInGame) return;
|
||||
if (draggingElement !== null) return;
|
||||
draggingElement = e;
|
||||
draggingStartPos = [x, y];
|
||||
}
|
||||
function draggingOnMove(x, y) {
|
||||
if (isInGame) return;
|
||||
if (draggingElement === null) return;
|
||||
let dx = x - draggingStartPos[0];
|
||||
let dy = y - draggingStartPos[1];
|
||||
draggingElement.style.top = dy + "px";
|
||||
draggingElement.style.left = dx + "px";
|
||||
}
|
||||
function draggingOnUp(x, y) {
|
||||
if (draggingElement === null) return;
|
||||
if (!isInGame) {
|
||||
if (draggingEndCallback) draggingEndCallback(x, y);
|
||||
}
|
||||
draggingCancel();
|
||||
}
|
||||
function draggingCancel() {
|
||||
draggingElement.style.removeProperty("top");
|
||||
draggingElement.style.removeProperty("left");
|
||||
draggingElement = null;
|
||||
}
|
||||
|
||||
// === Header ===
|
||||
|
||||
const domHeaderLeft = document.getElementById("HeaderLeft");
|
||||
const domHeaderRight = document.getElementById("HeaderRight");
|
||||
const domStationCurrent = document.getElementById("StationCurrent");
|
||||
const domStationDestination = document.getElementById("StationDestination");
|
||||
|
||||
function setHeaderTexts() {
|
||||
domStationCurrent.innerText = stationCurrent ? stationCurrent.name : "";
|
||||
domStationDestination.innerText = stationDestination ? stationDestination.name : "";
|
||||
}
|
||||
setHeaderTexts();
|
||||
|
||||
var chooseRandomStationsTimeoutId = null;
|
||||
async function chooseRandomStations() {
|
||||
if (chooseRandomStationsTimeoutId) clearTimeout(chooseRandomStationsTimeoutId);
|
||||
chooseRandomStationsTimeoutId = setTimeout(async () => {
|
||||
let response = await fetch("./random_stations/" + encodeURIComponent(transportModesInteger) + "/2/");
|
||||
if (!response.ok) return;
|
||||
let randomStations = await response.json();
|
||||
if (randomStations.length >= 2) {
|
||||
stationCurrent = { name: randomStations[0][0], evaNumber: randomStations[0][1] };
|
||||
stationDestination = { name: randomStations[1][0], evaNumber: randomStations[1][1] };
|
||||
setHeaderTexts();
|
||||
}
|
||||
chooseRandomStationsTimeoutId = null;
|
||||
}, 100);
|
||||
}
|
||||
|
||||
draggingEnable(domStationCurrent, (x, y) => {
|
||||
let target = domHeaderRight.getBoundingClientRect();
|
||||
if (target.left <= x && x <= target.right && target.top <= y && y <= target.bottom) {
|
||||
let temp = stationDestination;
|
||||
stationDestination = stationCurrent;
|
||||
stationCurrent = temp;
|
||||
setHeaderTexts();
|
||||
}
|
||||
});
|
||||
draggingEnable(domStationDestination, (x, y) => {
|
||||
let target = domHeaderLeft.getBoundingClientRect();
|
||||
if (target.left <= x && x <= target.right && target.top <= y && y <= target.bottom) {
|
||||
let temp = stationDestination;
|
||||
stationDestination = stationCurrent;
|
||||
stationCurrent = temp;
|
||||
setHeaderTexts();
|
||||
}
|
||||
});
|
||||
|
||||
// === Transport Mode Selection ===
|
||||
|
||||
const domTransportModeBus = document.getElementById("TransportModeBus");
|
||||
const domTransportModeTram = document.getElementById("TransportModeTram");
|
||||
const domTransportModeS = document.getElementById("TransportModeS");
|
||||
const domTransportModeRE = document.getElementById("TransportModeRE");
|
||||
const domTransportModeICE = document.getElementById("TransportModeICE");
|
||||
|
||||
const TRANSPORT_MODE_ICON_BUS = "🚌";
|
||||
const TRANSPORT_MODE_ICON_TRAM = "🚊";
|
||||
const TRANSPORT_MODE_ICON_S = "🚈";
|
||||
const TRANSPORT_MODE_ICON_RE = "🚆";
|
||||
const TRANSPORT_MODE_ICON_ICE = "🚄";
|
||||
const TRANSPORT_MODE_TEXT_BUS = domTransportModeBus.title;
|
||||
const TRANSPORT_MODE_TEXT_TRAM = domTransportModeTram.title;
|
||||
const TRANSPORT_MODE_TEXT_S = domTransportModeS.title;
|
||||
const TRANSPORT_MODE_TEXT_RE = domTransportModeRE.title;
|
||||
const TRANSPORT_MODE_TEXT_ICE = domTransportModeICE.title;
|
||||
|
||||
domTransportModeBus.addEventListener("click", runInit((e) => {
|
||||
if (e) e.preventDefault(); transportModeBus ^= true; transportModesInteger ^= 1;
|
||||
domTransportModeBus.style.opacity = transportModeBus ? 1 : 0.5;
|
||||
if (!transportModeBus || transportModesInteger == 1) chooseRandomStations();
|
||||
}));
|
||||
domTransportModeTram.addEventListener("click", runInit((e) => {
|
||||
if (e) e.preventDefault(); transportModeTram ^= true; transportModesInteger ^= 2;
|
||||
domTransportModeTram.style.opacity = transportModeTram ? 1 : 0.5;
|
||||
if (!transportModeTram || transportModesInteger == 2) chooseRandomStations();
|
||||
}));
|
||||
domTransportModeS.addEventListener("click", runInit((e) => {
|
||||
if (e) e.preventDefault(); transportModeS ^= true; transportModesInteger ^= 4;
|
||||
domTransportModeS.style.opacity = transportModeS ? 1 : 0.5;
|
||||
if (!transportModeS || transportModesInteger == 4) chooseRandomStations();
|
||||
}));
|
||||
domTransportModeRE.addEventListener("click", runInit((e) => {
|
||||
if (e) e.preventDefault(); transportModeRE ^= true; transportModesInteger ^= 8;
|
||||
domTransportModeRE.style.opacity = transportModeRE ? 1 : 0.5;
|
||||
if (!transportModeRE || transportModesInteger == 8) chooseRandomStations();
|
||||
}));
|
||||
domTransportModeICE.addEventListener("click", runInit((e) => {
|
||||
if (e) e.preventDefault(); transportModeICE ^= true; transportModesInteger ^= 16;
|
||||
domTransportModeICE.style.opacity = transportModeICE ? 1 : 0.5;
|
||||
if (!transportModeICE || transportModesInteger == 16) chooseRandomStations();
|
||||
}));
|
||||
|
||||
// === Station Search ===
|
||||
|
||||
const domStationSearchInput = document.getElementById("StationSearchInput");
|
||||
const domStationSearchResults = document.getElementById("StationSearchResults");
|
||||
|
||||
const stationSearchTimeoutDuration = 500;
|
||||
var stationSearchTimeoutId = null;
|
||||
var stationSearchPrevious = null;
|
||||
|
||||
const stationSearchInputChanged = () => {
|
||||
let query = domStationSearchInput.value;
|
||||
if (stationSearchPrevious === query) return;
|
||||
stationSearchPrevious = query;
|
||||
if (stationSearchTimeoutId !== null) clearTimeout(stationSearchTimeoutId);
|
||||
stationSearchTimeoutId = (query && query.length > 1) ? setTimeout(async () => {
|
||||
let response = await fetch("./query_stations/" + encodeURIComponent(query) + "/");
|
||||
if (!response.ok) {
|
||||
let error = await response.text();
|
||||
console.warn("Station Search: Got error " + response.status + " from server: " + error);
|
||||
} else {
|
||||
let result = await response.json();
|
||||
domStationSearchResults.replaceChildren();
|
||||
for (const [stationName, stationEvaNum, transportModesInteger] of result) {
|
||||
let searchResultElem = document.createElement("div");
|
||||
let searchResultTransportModesElem = document.createElement("small");
|
||||
searchResultTransportModesElem.style.cursor = "default";
|
||||
for (const [i, char, text] of [[1, TRANSPORT_MODE_ICON_BUS, TRANSPORT_MODE_TEXT_BUS], [2, TRANSPORT_MODE_ICON_TRAM, TRANSPORT_MODE_TEXT_TRAM], [4, TRANSPORT_MODE_ICON_S, TRANSPORT_MODE_TEXT_S], [8, TRANSPORT_MODE_ICON_RE, TRANSPORT_MODE_TEXT_RE], [16, TRANSPORT_MODE_ICON_ICE, TRANSPORT_MODE_TEXT_ICE]]) {
|
||||
if ((transportModesInteger & i) != 0) {
|
||||
let transportModeElem = document.createElement("span");
|
||||
transportModeElem.innerText = char;
|
||||
transportModeElem.title = text;
|
||||
searchResultTransportModesElem.append(transportModeElem);
|
||||
}
|
||||
}
|
||||
let searchResultNameElem = document.createElement("span");
|
||||
searchResultNameElem.innerText = stationName;
|
||||
searchResultElem.append(searchResultTransportModesElem, searchResultNameElem);
|
||||
searchResultElem.classList.add("StationSearchResult");
|
||||
draggingEnable(searchResultElem, (x, y) => {
|
||||
let right = domHeaderRight.getBoundingClientRect();
|
||||
let left = domHeaderLeft.getBoundingClientRect();
|
||||
if (left.left <= x && x <= left.right && left.top <= y && y <= left.bottom) {
|
||||
stationCurrent = { name: stationName, evaNumber: stationEvaNum };
|
||||
setHeaderTexts();
|
||||
}
|
||||
if (right.left <= x && x <= right.right && right.top <= y && y <= right.bottom) {
|
||||
stationDestination = { name: stationName, evaNumber: stationEvaNum };
|
||||
setHeaderTexts();
|
||||
}
|
||||
});
|
||||
domStationSearchResults.appendChild(searchResultElem);
|
||||
}
|
||||
}
|
||||
}, stationSearchTimeoutDuration) : (() => { domStationSearchResults.replaceChildren(); return null; })();
|
||||
;
|
||||
};
|
||||
domStationSearchInput.addEventListener("change", stationSearchInputChanged);
|
||||
domStationSearchInput.addEventListener("input", stationSearchInputChanged);
|
||||
|
||||
// === Loading (Network) ===
|
||||
|
||||
chooseRandomStations();
|
||||
|
||||
// === InGame ===
|
||||
|
||||
const domStartGameButton = document.getElementById("StartGameButton");
|
||||
const domWelcome = document.getElementById("Welcome");
|
||||
const domInGame = document.getElementById("InGame");
|
||||
const domDeparturesList = document.getElementById("DeparturesList");
|
||||
const domFocusedDeparturePanel = document.getElementById("FocusedDeparturePanel");
|
||||
const domFocusedDeparturePanelHead = document.getElementById("FocusedDeparturePanelHead");
|
||||
const domFocusedDeparturePanelStops = document.getElementById("FocusedDeparturePanelStops");
|
||||
const domFocusedDeparturePanelCloseClickable = document.getElementById("FocusedDeparturePanelCloseClickable");
|
||||
function hideFocusDeparturePanel() {
|
||||
domFocusedDeparturePanel.style.left = "100%";
|
||||
domFocusedDeparturePanelCloseClickable.style.display = "none";
|
||||
}
|
||||
domFocusedDeparturePanelCloseClickable.addEventListener("click", hideFocusDeparturePanel);
|
||||
|
||||
function goInGame() {
|
||||
isInGame = true;
|
||||
for (const elem of draggableElements) elem.style.cursor = "default";
|
||||
draggableElements = new Array();
|
||||
domWelcome.style.display = "none";
|
||||
domInGame.style.display = "block";
|
||||
reloadDepartures();
|
||||
}
|
||||
|
||||
domStartGameButton.onclick = () => goInGame();
|
||||
|
||||
async function reloadDepartures() {
|
||||
domDeparturesList.replaceChildren();
|
||||
hideFocusDeparturePanel();
|
||||
let currentEvaNumber = stationCurrent.evaNumber;
|
||||
if (currentEvaNumber === stationDestination.evaNumber) {
|
||||
// TODO: obv
|
||||
alert("You won! Unfortunately, i haven't made a screen for that yet...");
|
||||
location.reload();
|
||||
return;
|
||||
}
|
||||
let response = await fetch("./query_departures/" + encodeURIComponent(transportModesInteger) + "/" + encodeURIComponent(currentEvaNumber) + "/");
|
||||
if (!response.ok) {
|
||||
let error = await response.text();
|
||||
console.warn("Query Departures: Got error " + response.status + " from server: " + error);
|
||||
} else {
|
||||
let result = await response.json();
|
||||
for (const [route, stops, routeId] of result) {
|
||||
if (stops.length > 0) {
|
||||
let departureElem = document.createElement("div");
|
||||
let departureElemHead = document.createElement("div");
|
||||
departureElemHead.style.marginTop = "0.5em";
|
||||
departureElemHead.innerText = route + " ➟ " + stops[stops.length-1];
|
||||
let departureElemDetails = document.createElement("small");
|
||||
departureElemDetails.style.display = "flex";
|
||||
departureElemDetails.style.flexWrap = "wrap";
|
||||
let firstStop = true;
|
||||
for (const stop of stops.slice(0, stops.length-1)) {
|
||||
if (firstStop && stop == stationCurrent.name) continue;
|
||||
let departureStopElem = document.createElement("span");
|
||||
departureStopElem.style.whiteSpace = "pre";
|
||||
departureStopElem.innerText = (firstStop ? "" : " ➞ ") + stop;
|
||||
departureElemDetails.append(departureStopElem);
|
||||
firstStop = false;
|
||||
}
|
||||
let departureElemSelect = document.createElement("div");
|
||||
departureElemSelect.style.overflow = "hidden";
|
||||
departureElemSelect.style.height = "0vh";
|
||||
departureElemSelect.style.transition = "height 0.25s ease-in-out";
|
||||
departureElem.append(departureElemHead, departureElemDetails, departureElemSelect);
|
||||
departureElem.style.cursor = "pointer";
|
||||
let resultCache = [null];
|
||||
departureElem.addEventListener("click", async () => {
|
||||
domFocusedDeparturePanelHead.replaceChildren();
|
||||
domFocusedDeparturePanelStops.replaceChildren();
|
||||
domFocusedDeparturePanelCloseClickable.style.display = "block";
|
||||
domFocusedDeparturePanel.style.left = "max(calc(5% + 5em), calc(50% - 22.5em))";
|
||||
let headElem = document.createElement("b");
|
||||
headElem.innerText = route;
|
||||
let headSmallerElem = document.createElement("span");
|
||||
headSmallerElem.style.whiteSpace = "pre";
|
||||
headSmallerElem.innerText = " ➟ " + stops[stops.length-1];
|
||||
domFocusedDeparturePanelHead.append(headElem, headSmallerElem);
|
||||
if (resultCache[0] === null) {
|
||||
let response = await fetch("./query_route/" + encodeURIComponent(routeId) + "/");
|
||||
if (!response.ok) {
|
||||
let error = await response.text();
|
||||
console.warn("Query Route: Got error " + response.status + " from server: " + error);
|
||||
return;
|
||||
} else {
|
||||
resultCache[0] = await response.json();
|
||||
}
|
||||
}
|
||||
let result = resultCache[0];
|
||||
let canceled = result[1];
|
||||
let foundCurrent = true;
|
||||
for (const [stop, evaNumber] of result[0]) {
|
||||
if (evaNumber === currentEvaNumber) foundCurrent = false;
|
||||
}
|
||||
for (const [stop, evaNumber] of result[0]) {
|
||||
console.log(stop, ": ", evaNumber);
|
||||
let stopElem = document.createElement("li");
|
||||
stopElem.innerText = stop;
|
||||
stopElem.style.wordWrap = "nowrap";
|
||||
if (!foundCurrent) {
|
||||
if (evaNumber === currentEvaNumber) {
|
||||
foundCurrent = true;
|
||||
stopElem.classList.add("DetailedViewCurrentStop");
|
||||
} else {
|
||||
stopElem.classList.add("DetailedViewPastStop");
|
||||
}
|
||||
} else {
|
||||
stopElem.classList.add("DetailedViewFutureStop");
|
||||
stopElem.addEventListener("click", async () => {
|
||||
stationCurrent = { name: stop, evaNumber: evaNumber };
|
||||
setHeaderTexts();
|
||||
await reloadDepartures();
|
||||
});
|
||||
}
|
||||
domFocusedDeparturePanelStops.append(stopElem);
|
||||
}
|
||||
});
|
||||
domDeparturesList.append(departureElem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user