commit 24c289fa4af4f49b3c4cd51c24c77dcbc3056c5b
parent f95b7e361263aeea1b11458e42893496da101ba5
Author: Yureka <yuka@yuka.dev>
Date: Sat, 10 Sep 2022 18:34:48 +0200
parent f95b7e361263aeea1b11458e42893496da101ba5
Author: Yureka <yuka@yuka.dev>
Date: Sat, 10 Sep 2022 18:34:48 +0200
departuresView
6 files changed, 200 insertions(+), 80 deletions(-)
A
|
119
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/src/app_functions.js b/src/app_functions.js @@ -1,4 +1,5 @@ import { db } from './dataStorage.js'; +import { go } from './router.js'; import { settings, subscribeSettings } from './settings.js'; import { showLoader, hideOverlay, showModal, showAlertModal } from './overlays.js'; import { languages } from './languages.js'; @@ -67,13 +68,17 @@ const processJourneys = data => { export const processLeg = leg => { if (leg.plannedDeparture) leg.plannedDeparture = new Date(leg.plannedDeparture); if (leg.plannedArrival) leg.plannedArrival = new Date(leg.plannedArrival); + if (leg.plannedWhen) leg.plannedWhen = new Date(leg.plannedWhen); if (leg.departure) leg.departure = new Date(leg.departure); if (leg.arrival) leg.arrival = new Date(leg.arrival); + if (leg.when) leg.when = new Date(leg.when); for (const stopover of (leg.stopovers || [])) { if (stopover.plannedDeparture) stopover.plannedDeparture = new Date(stopover.plannedDeparture); if (stopover.plannedArrival) stopover.plannedArrival = new Date(stopover.plannedArrival); + if (stopover.plannedWhen) stopover.plannedWhen = new Date(stopover.plannedWhen); if (stopover.departure) stopover.departure = new Date(stopover.departure); if (stopover.arrival) stopover.arrival = new Date(stopover.arrival); + if (stopover.when) stopover.when = new Date(stopover.when); } }; const processJourney = journey => { @@ -205,7 +210,7 @@ export const parseName = (point) => { return nameHTML; }; -export const ds100Names = (id) => { +const ds100Names = (id) => { if (!settings.showRIL100Names) return ''; if (!ds100[Number(id)]) return ''; return '('+ds100[Number(id)]+')'; @@ -223,10 +228,26 @@ export const loadDS100 = async () => { }; export const timeTemplate = (data, mode) => { - const time = data[mode] || data['planned'+mode.replace(/^\w/, c => c.toUpperCase())]; + const fieldsMap = { + when: { + departure: 'departure', + arrival: 'arrival', + }, + plannedWhen: { + departure: 'plannedDeparture', + arrival: 'plannedArrival', + }, + delay: { + departure: 'departureDelay', + arrival: 'arrivalDelay', + }, + }; + const getField = fieldName => data[fieldsMap[fieldName][mode] || fieldName]; + + const time = getField('when') || getField('plannedWhen'); if (!time) return '-'; - const delayMinutes = Math.round(data[mode+'Delay'] / 60); + const delayMinutes = Math.round(getField('delay') / 60); return html` ${delayMinutes != 0 ? html` @@ -237,3 +258,30 @@ export const timeTemplate = (data, mode) => { `; }; +export const platformTemplate = (data) => { + if (data.departurePlatform) { + if (data.departurePlatform != data.plannedDeparturePlatform) { + return html`<b>${data.departurePlatform}</b>`; + } else { + return data.plannedDeparturePlatform; + } + } else if (data.platform) { + if (data.platform != data.plannedPlatform) { + return html`<b>${data.platform}</b>`; + } else { + return data.plannedPlatform; + } + } else if (data.arrivalPlatform) { + if (data.arrivalPlatform != data.plannedArrivalPlatform) { + return html`<b>${data.arrivalPlatform}</b>`; + } else { + return data.plannedArrivalPlatform; + } + } else { + return '-'; + } +}; + +export const stopTemplate = (profile, stop) => { + return html`<a href="#/d/${profile}/${stop.id}">${stop.name} ${ds100Names(stop.id)}</a>`; +}
diff --git a/src/departuresView.js b/src/departuresView.js @@ -0,0 +1,119 @@ +import { settings } from './settings.js'; +import { showDiv, hideDiv, ElementById, formatDateTime, formatDuration, formatPrice } from './helpers.js'; +import { ConsoleLog, parseName, t, timeTemplate, processLeg, platformTemplate } from './app_functions.js'; +import { showAlertModal, showLoader, hideOverlay, showModal } from './overlays.js'; +import { go } from './router.js'; +import { html, render } from 'lit-html'; +import { getHafasClient, client } from './hafas_client'; + +const remarksModalTemplate = (type, remarks) => html` + <table class="remarks"> + ${remarks.map(element => html` + <tr> + <td> + <span class="remark icon-${type}"></span> + <span>${element.text}</span> + </td> + </tr> + `)} + </table> +`; + +const getAdditionalName = (line) => { + const splitName = line.name.split(' '); + if (splitName.length === 2 && line.fahrtNr && line.fahrtNr != splitName[1]) + return `${splitName[0]} ${line.fahrtNr}`; + else + return null; +}; + +const departuresTemplate = (data, profile) => { + let changes = 0; + let lastArrival; + + //<a class="reload icon-reload" title="${t("reload")}" @click=${() => refreshJourneyView(data.refreshToken, profile)}>${t("reload")}</a> + return html` + <div class="departures"> + <header> + <a class="back icon-back invisible"></a> + <div class="header-content"> + <h3>Departures from ${data.name}</h3> + </div> + <a class="reload icon-reload invisible">${t("reload")}</a> + </header> + + <div class="card"> + <table> + <thead> + <tr> + <th>Time</th> + <th class="station-column"></th> + <th>${t('platform')}</th> + </tr> + </thead> + <tbody> + ${(data.departures || []).map(departure => html` + <tr class="departure" @click=${() => go(`/t/${profile}/${departure.tripId}`)}> + <td class="${departure.cancelled ? 'cancelled' : ''}"><span>${timeTemplate(departure)}</span></td> + <td class="${departure.cancelled ? 'cancelled' : ''}"><span>${departure.line.name}${departure.direction ? html` → ${departure.direction}` : ''}</span></td> + ${departure.cancelled ? html` + <td><span class="cancelled-text">${t('cancelled-ride')}</span></td> + ` : html` + <td><span>${platformTemplate(departure)}</span></td> + `} + </tr> + `)} + </tbody> + </table> + </div> + </div> + `; +}; + +export const departuresView = async (match, isUpdate) => { + if (!isUpdate) showLoader(); + let profile, stopId, when, data; + try { + profile = match[0]; + stopId = match[1]; + if (match[2]) when = new Date(parseInt(match[2].substring(1))); + const client = await getHafasClient(profile); + const [ departures, stopInfo ] = await Promise.all([ + client.departures(stopId, { when }), + client.stop(stopId), + ]); + for (let departure of departures) { + processLeg(departure); + }; + data = { ...stopInfo, departures }; + } catch(e) { + showAlertModal(e.toString()); + throw e; + } + hideOverlay(); + + ConsoleLog(data); + render(departuresTemplate(data, profile), ElementById('content')); + + //if (!isUpdate) refreshJourneyView(refreshToken); // update data in the background + + /*const history_id = dataStorage.journeysHistory.findIndex(obj => obj.reqId === reqId); + + if (dataStorage.journeysHistory[history_id] !== undefined) { + dataStorage.journeysHistory[history_id].journeyId = journeyId; + saveDataStorage(); + }*/ +}; + +const refreshJourneyView = async (refreshToken, profile) => { + document.querySelector('.reload').classList.add('spinning'); + try { + await refreshJourney(refreshToken, profile); + } catch(e) { + showAlertModal(e.toString()); + document.querySelector('.reload').classList.remove('spinning'); + throw e; + } + journeyView([profile, refreshToken], true); + document.querySelector('.reload').classList.remove('spinning'); +};
diff --git a/src/journeyView.js b/src/journeyView.js @@ -1,6 +1,6 @@ import { settings } from './settings.js'; import { showDiv, hideDiv, ElementById, formatDateTime, formatDuration, formatPrice } from './helpers.js'; -import { ConsoleLog, parseName, ds100Names, t, timeTemplate, getJourney, refreshJourney } from './app_functions.js'; +import { ConsoleLog, parseName, t, timeTemplate, getJourney, refreshJourney, platformTemplate, stopTemplate } from './app_functions.js'; import { showAlertModal, showLoader, hideOverlay, showModal } from './overlays.js'; import { go } from './router.js'; import { html, render } from 'lit-html'; @@ -107,8 +107,8 @@ const legTemplate = (leg, profile) => { <tr class="stop ${stop.cancelled ? 'cancelled' : ''}"> <td><span>${timeTemplate(stop, 'arrival')}</span></td> <td><span>${timeTemplate(stop, 'departure')}</span></td> - <td><span>${stop.stop.name} ${ds100Names(stop.stop.id)}</span></td> - <td><span>${stopPlatformTemplate(stop)}</span></td> + <td>${stopTemplate(profile, stop.stop)}</td> + <td><span>${platformTemplate(stop)}</span></td> </tr> `)} </tbody> @@ -168,24 +168,6 @@ const journeyTemplate = (data, profile) => { `; }; -const stopPlatformTemplate = (data) => { - if (data.departurePlatform) { - if (data.departurePlatform != data.plannedDeparturePlatform) { - return html`<b>${data.departurePlatform}</b>`; - } else { - return data.plannedDeparturePlatform; - } - } else if (data.arrivalPlatform) { - if (data.arrivalPlatform != data.plannedArrivalPlatform) { - return html`<b>${data.arrivalPlatform}</b>`; - } else { - return data.plannedArrivalPlatform; - } - } else { - return '-'; - } -}; - export const journeyView = async (match, isUpdate) => { if (!isUpdate) showLoader(); let profile, refreshToken, data;
diff --git a/src/main.js b/src/main.js @@ -3,10 +3,12 @@ import { searchView } from './searchView.js'; import { journeysView } from './journeysView.js'; import { journeyView } from './journeyView.js'; import { tripView } from './tripView.js'; +import { departuresView } from './departuresView.js'; import { initSettings, settings } from './settings.js'; import { initDataStorage } from './dataStorage.js'; import { initHafasClient } from './hafas_client'; -import { showDiv, hideDiv, ElementById } from './helpers.js'; +import { hideDiv, ElementById } from './helpers.js'; +import { showAlertModal } from './overlays.js'; (async () => { // read settings from indexeddb @@ -18,6 +20,11 @@ import { showDiv, hideDiv, ElementById } from './helpers.js'; route(/^\/([a-zA-Z0-9]+)\/([a-z]+)$/, journeysView); route(/^\/j\/([a-z]+)\/(.+)$/, journeyView); route(/^\/t\/([a-z]+)\/(.+)$/, tripView); + route(/^\/d\/([a-z]+)\/([^/]+)(\/[0-9]+)?$/, departuresView); + route(/^.*$/, async () => { + await showAlertModal('Route not found'); + go('/'); + }); ElementById('overlay').innerHTML = ''; hideDiv('overlay');
diff --git a/src/tripView.js b/src/tripView.js @@ -1,6 +1,6 @@ import { settings } from './settings.js'; import { showDiv, hideDiv, ElementById, formatDateTime, formatDuration, formatPrice } from './helpers.js'; -import { ConsoleLog, parseName, ds100Names, t, timeTemplate, processLeg } from './app_functions.js'; +import { ConsoleLog, parseName, t, timeTemplate, processLeg, platformTemplate, stopTemplate } from './app_functions.js'; import { showAlertModal, showLoader, hideOverlay, showModal } from './overlays.js'; import { go } from './router.js'; import { html, render } from 'lit-html'; @@ -66,9 +66,9 @@ const tripTemplate = (data, profile) => { <header> <a class="back icon-back invisible"></a> <div class="header-content"> - <h3>wip</h3> + <h3>Trip of ${data.line.name}</h3> </div> - <a class="reload icon-reload" title="${t("reload")}" @click=${() => refreshJourneyView(data.refreshToken, profile)}>${t("reload")}</a> + <a class="reload icon-reload invisible">${t("reload")}</a> </header> <div class="card"> @@ -122,8 +122,8 @@ const tripTemplate = (data, profile) => { <tr class="stop ${stop.cancelled ? 'cancelled' : ''}"> <td><span>${timeTemplate(stop, 'arrival')}</span></td> <td><span>${timeTemplate(stop, 'departure')}</span></td> - <td><span>${stop.stop.name} ${ds100Names(stop.stop.id)}</span></td> - <td><span>${stopPlatformTemplate(stop)}</span></td> + <td><span>${stopTemplate(profile, stop.stop)}</span></td> + <td><span>${platformTemplate(stop)}</span></td> </tr> `)} </tbody> @@ -133,24 +133,6 @@ const tripTemplate = (data, profile) => { `; }; -const stopPlatformTemplate = (data) => { - if (data.departurePlatform) { - if (data.departurePlatform != data.plannedDeparturePlatform) { - return html`<b>${data.departurePlatform}</b>`; - } else { - return data.plannedDeparturePlatform; - } - } else if (data.arrivalPlatform) { - if (data.arrivalPlatform != data.plannedArrivalPlatform) { - return html`<b>${data.arrivalPlatform}</b>`; - } else { - return data.plannedArrivalPlatform; - } - } else { - return '-'; - } -}; - export const tripView = async (match, isUpdate) => { if (!isUpdate) showLoader(); let profile, refreshToken, data; @@ -168,26 +150,4 @@ export const tripView = async (match, isUpdate) => { ConsoleLog(data); render(tripTemplate(data, profile), ElementById('content')); - - //if (!isUpdate) refreshJourneyView(refreshToken); // update data in the background - - /*const history_id = dataStorage.journeysHistory.findIndex(obj => obj.reqId === reqId); - - if (dataStorage.journeysHistory[history_id] !== undefined) { - dataStorage.journeysHistory[history_id].journeyId = journeyId; - saveDataStorage(); - }*/ -}; - -const refreshJourneyView = async (refreshToken, profile) => { - document.querySelector('.reload').classList.add('spinning'); - try { - await refreshJourney(refreshToken, profile); - } catch(e) { - showAlertModal(e.toString()); - document.querySelector('.reload').classList.remove('spinning'); - throw e; - } - journeyView([profile, refreshToken], true); - document.querySelector('.reload').classList.remove('spinning'); };
diff --git a/static/style.css b/static/style.css @@ -56,14 +56,14 @@ header { } .cancelled-text { font-weight: bold; - color: red; + color: red !important; } .pointer { cursor: pointer; } -.back.invisible { +.invisible { visibility: hidden; } .back, @@ -238,11 +238,16 @@ tbody tr:hover td { } .journey, -.journeys { +.journeys, +.departures { display: flex; flex-direction: column; min-height: 100vh; } +.journeys tbody tr, +.departures tbody tr { + cursor: pointer; +} .search { color: white; @@ -312,7 +317,8 @@ tbody tr:hover td { } .journeys table a, -.journey table span { +.journey table span, +.departures table span { padding: 5px 3px; display: flex; justify-content: center; @@ -322,7 +328,8 @@ tbody tr:hover td { color: black; } -.journey table a { +.journey table a, +.departures table a { padding: 5px 3px; display: flex; justify-content: center; @@ -336,8 +343,8 @@ tbody tr:hover td { padding: 0; } -.journey tbody td:nth-child(3) { - text-align: left; +.departures tbody td:nth-child(2) span { + justify-content: start; } .journey tbody:not(:last-child) { @@ -410,9 +417,6 @@ tbody tr:hover td { @media (max-width: 799px) { - .back.invisible { - display: none; - } .header-content { flex-grow: 1; }