commit 755b0014c96df6414bd77ffde9137773f31036fb
parent 7a0cd5f02045e5fc00083c88ae7a15afb4f61e8f
Author: Yureka <yuka@yuka.dev>
Date: Tue, 6 Sep 2022 11:08:31 +0200
parent 7a0cd5f02045e5fc00083c88ae7a15afb4f61e8f
Author: Yureka <yuka@yuka.dev>
Date: Tue, 6 Sep 2022 11:08:31 +0200
wip tripview
4 files changed, 215 insertions(+), 26 deletions(-)
diff --git a/src/app_functions.js b/src/app_functions.js @@ -68,23 +68,24 @@ const mkSettings = () => { const processJourneys = data => { for (const journey of data.journeys) processJourney(journey); - return 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.departure) leg.departure = new Date(leg.departure); + if (leg.arrival) leg.arrival = new Date(leg.arrival); + 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.departure) stopover.departure = new Date(stopover.departure); + if (stopover.arrival) stopover.arrival = new Date(stopover.arrival); + } +}; const processJourney = journey => { for (const leg of journey.legs) { - if (leg.plannedDeparture) leg.plannedDeparture = new Date(leg.plannedDeparture); - if (leg.plannedArrival) leg.plannedArrival = new Date(leg.plannedArrival); - if (leg.departure) leg.departure = new Date(leg.departure); - if (leg.arrival) leg.arrival = new Date(leg.arrival); - 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.departure) stopover.departure = new Date(stopover.departure); - if (stopover.arrival) stopover.arrival = new Date(stopover.arrival); - } + processLeg(leg); } - return journey; }; export const getJourneys = async slug => { @@ -99,7 +100,8 @@ export const getJourney = async (refreshToken, profile) => { if (!data || JSON.stringify(data.settings) != JSON.stringify(settings)) { data = await refreshJourney(refreshToken, profile); } - return processJourney(data); + processJourney(data); + return data; }; export const getMoreJourneys = async (slug, mode) => { @@ -173,7 +175,8 @@ export const newJourneys = async (params) => { data.settings = requestSettings; data.profile = settings.profile; await addJourneys(data); - return processJourneys(data); + processJourneys(data); + return data; }; export const t = (key, ...params) => {
diff --git a/src/journeyView.js b/src/journeyView.js @@ -43,7 +43,7 @@ const remarksTemplate = ([type, remarks]) => !!remarks.length ? html` <a class="link icon-${type}" @click=${() => showRemarksModal(type, remarks)}></a> ` : ''; -const legTemplate = leg => { +const legTemplate = (leg, profile) => { const allRemarks = leg.remarks || []; const remarks = { 'status': allRemarks.filter(r => r.type === 'status'), @@ -51,10 +51,6 @@ const legTemplate = leg => { 'other': allRemarks.filter(r => r.type !== 'status' && r.type !== 'hint'), }; - let marudorUrl = null; - if (leg.line && (leg.line.product == 'nationalExpress' || leg.line.product == 'national' || leg.line.product == 'regionalExp' || leg.line.product == 'regional')) { - marudorUrl = 'https://marudor.de/details/' + encodeURIComponent(getAdditionalName(leg.line) || leg.line.name) + '/' + Number(leg.plannedDeparture); - } return html` ${leg.walking ? html` @@ -69,11 +65,7 @@ const legTemplate = leg => { <thead> <tr> <td colspan="4"> - <span>${marudorUrl ? html` - <a href="${marudorUrl}">${leg.line.name}${leg.direction ? html` → ${leg.direction}` : ''}</a> - ` : html ` - ${leg.line.name}${leg.direction ? html` → ${leg.direction}` : ''} - `} + <span><a href="#/t/${profile}/${leg.tripId}">${leg.line.name}${leg.direction ? html` → ${leg.direction}` : ''}</a> ${leg.cancelled ? html`<b class="cancelled-text">${t('cancelled-ride')}</b>` : ''} ${Object.entries(remarks).map(remarksTemplate)} ${travelynxTemplate(leg)}</span> @@ -129,7 +121,6 @@ const legTemplate = leg => { const journeyTemplate = (data, profile) => { const duration = data.legs[data.legs.length - 1].arrival - data.legs[0].departure; - console.log(data); const legs = []; let changes = 0; let lastArrival; @@ -172,7 +163,7 @@ const journeyTemplate = (data, profile) => { <a class="reload icon-reload" title="${t("reload")}" @click=${() => refreshJourneyView(data.refreshToken, profile)}>${t("reload")}</a> </header> - ${legs.map(legTemplate)} + ${legs.map(leg => legTemplate(leg, profile))} </div> `; };
diff --git a/src/main.js b/src/main.js @@ -2,6 +2,7 @@ import { route, go, start } from './router.js'; import { searchView } from './searchView.js'; import { journeysView } from './journeysView.js'; import { journeyView } from './journeyView.js'; +import { tripView } from './tripView.js'; import { initSettings, settings } from './settings.js'; import { initDataStorage } from './dataStorage.js'; import { initHafasClient } from './hafas_client'; @@ -16,6 +17,7 @@ import { showDiv, hideDiv, ElementById } from './helpers.js'; route(/^\/$/, searchView); route(/^\/([a-zA-Z0-9]+)\/([a-z]+)$/, journeysView); route(/^\/j\/([a-z]+)\/(.+)$/, journeyView); + route(/^\/t\/([a-z]+)\/(.+)$/, tripView); ElementById('overlay').innerHTML = ''; hideDiv('overlay');
diff --git a/src/tripView.js b/src/tripView.js @@ -0,0 +1,193 @@ +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 { 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 travelynxTemplate = (element) => { + if (settings.travelynx && element.line && element.line.mode === 'train') { + const trainName = getAdditionalName(element.line) || element.line.name; + + return html` + <a class="link icon-travelynx" href="https://travelynx.de/s/${element.origin.id}?train=${encodeURIComponent(trainName)}"></a> + `; + } +}; + +const showRemarksModal = (type, remarks) => { + showModal(t('remarks'), remarksModalTemplate(type, remarks)); +}; +const remarksTemplate = ([type, remarks]) => !!remarks.length ? html` + <a class="link icon-${type}" @click=${() => showRemarksModal(type, remarks)}></a> +` : ''; + +const tripTemplate = (data, profile) => { + let changes = 0; + let lastArrival; + + const allRemarks = data.remarks || []; + const remarks = { + 'status': allRemarks.filter(r => r.type === 'status'), + 'hint': allRemarks.filter(r => r.type === 'hint'), + 'other': allRemarks.filter(r => r.type !== 'status' && r.type !== 'hint'), + }; + + let marudorUrl = null; + if (data.line && (data.line.product == 'nationalExpress' || data.line.product == 'national' || data.line.product == 'regionalExp' || data.line.product == 'regional')) { + marudorUrl = 'https://marudor.de/details/' + encodeURIComponent(getAdditionalName(data.line) || data.line.name) + '/' + Number(data.plannedDeparture); + } + + //<p>b>${t('duration')}: ${formatDuration(duration)} | ${t('changes')}: ${changes-1} | ${t('date')}: ${formatDateTime(data.plannedDeparture, 'date')}${settings.showPrices && data.price ? html` | ${t('price')}: <td><span>${formatPrice(data.price)}</span></td>` : ''}</b></p> + return html` + <div class="journey"> + <header> + <a class="back icon-back invisible"></a> + <div class="header-content"> + <h3>wip</h3> + </div> + <a class="reload icon-reload" title="${t("reload")}" @click=${() => refreshJourneyView(data.refreshToken, profile)}>${t("reload")}</a> + </header> + + <div class="card"> + <table> + <thead> + <tr> + <td colspan="4"> + <span>${marudorUrl ? html` + <a href="${marudorUrl}">${data.line.name}${data.direction ? html` → ${data.direction}` : ''}</a> + ` : html ` + ${data.line.name}${data.direction ? html` → ${data.direction}` : ''} + `} + ${data.cancelled ? html`<b class="cancelled-text">${t('cancelled-ride')}</b>` : ''} + ${Object.entries(remarks).map(remarksTemplate)} + ${travelynxTemplate(data)}</span> + </td> + </tr> + <tr> + <td colspan="4"> + <div class="train-details"> + ${getAdditionalName(data.line) ? html` + <div class="train-detail"> + Trip: ${getAdditionalName(data.line)} + </div> + ` : ''} + ${data.line.trainType ? html` + <div class="train-detail"> + Train type: ${data.line.trainType} + </div> + ` : ''} + <div class="train-detail"> + ${t('duration')}: ${formatDuration(data.arrival - data.departure)} + </div> + ${data.loadFactor ? html` + <div class="train-detail"> + ${t("load-"+data.loadFactor)} + </div> + ` : ''} + </div> + </td> + </tr> + <tr> + <th>${t('arrival')}</th> + <th>${t('departure')}</th> + <th class="station-column">${t('station')}</th> + <th>${t('platform')}</th> + </tr> + </thead> + <tbody> + ${(data.stopovers || []).map(stop => html` + <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> + </tr> + `)} + </tbody> + </table> + </div> + </div> + `; +}; + +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; + try { + profile = match[0]; + refreshToken = decodeURIComponent(match[1]); + const client = await getHafasClient(profile); + data = await client.trip(refreshToken, ".", {stopovers: true}); + processLeg(data); + } catch(e) { + showAlertModal(e.toString()); + throw e; + } + hideOverlay(); + + 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'); +};