268 lines
8.1 KiB
JavaScript
268 lines
8.1 KiB
JavaScript
'use strict';
|
|
|
|
import { dataStorage } from './app.js';
|
|
import { showDiv, hideDiv, ElementById, parseDateTime, formatDuration } from './helpers.js';
|
|
import { getCache, addCache, ConsoleLog, parseName, ds100Names, t } from './app_functions.js';
|
|
import { showModal } from './overlays.js';
|
|
import { get } from './api.js';
|
|
import { go } from './router.js';
|
|
import { html, render } from './lit-html.js';
|
|
|
|
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 travelynxTemplate = (element) => {
|
|
if (dataStorage.settings.travelynx && element.line.mode == 'Train') {
|
|
let trainName = '';
|
|
|
|
if (element.line.additionalName !== null) {
|
|
trainName = element.line.additionalName;
|
|
} else {
|
|
trainName = element.line.name;
|
|
}
|
|
|
|
return html`
|
|
<a class="link icon-travelynx" href="https://travelynx.de/s/${element.departure.point.stop.id}?train=${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 legTemplate = (leg) => {
|
|
const allRemarks = leg.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 hasMarudorURL = false;
|
|
let marudorUrl = '';
|
|
|
|
if (!leg.isWalking && !leg.isTransfer && !leg.isChange) {
|
|
if (leg.line.product == "nationalExp" || leg.line.product == "national" || leg.line.product == "regionalExp" || leg.line.product == "regional") {
|
|
hasMarudorURL = true;
|
|
}
|
|
|
|
if (!leg.line.additionalName) {
|
|
marudorUrl = 'https://marudor.de/details/' + leg.line.name + '/' + (leg.departure.plannedTime*1000)
|
|
} else {
|
|
marudorUrl = 'https://marudor.de/details/' + leg.line.additionalName + "/" + (leg.departure.plannedTime*1000)
|
|
}
|
|
}
|
|
|
|
return html`
|
|
${leg.isWalking ? html`
|
|
<p class="walk">${t('walkinfo', [parseName(leg.arrival.point), leg.distance])}</p>
|
|
` : leg.isTransfer ? html`
|
|
<p class="transfer">${t('transferinfo', [parseName(leg.arrival.point)])}</p>
|
|
` : leg.isChange ? html`
|
|
<p class="change">${t('changeinfo', [formatDuration(leg.duration)])}</p>
|
|
` : html`
|
|
<div class="card">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<td colspan="4">
|
|
<span>${hasMarudorURL ? html`
|
|
<a href="${marudorUrl}">${leg.line.name} → ${leg.direction}</a>
|
|
` : html `
|
|
${leg.line.name} → ${leg.direction}
|
|
`}
|
|
${leg.cancelled ? html`<b class="cancelled-text">${t('cancelled-ride')}</b>` : ''}
|
|
${Object.entries(remarks).map(remarksTemplate)}
|
|
${travelynxTemplate(leg)}</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="4">
|
|
<div class="train-details">
|
|
${leg.line.additionalName ? html`
|
|
<div class="train-detail">
|
|
Trip: ${leg.line.additionalName}
|
|
</div>
|
|
` : ''}
|
|
${leg.line.trainType ? html`
|
|
<div class="train-detail">
|
|
Train type: ${leg.line.trainType}
|
|
</div>
|
|
` : ''}
|
|
<div class="train-detail">
|
|
Duration: ${formatDuration((leg.arrival.prognosedTime || leg.arrival.plannedTime) - (leg.departure.prognosedTime || leg.departure.plannedTime))}
|
|
</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>
|
|
${leg.stopovers.map(stop => html`
|
|
<tr class="stop ${stop.cancelled ? 'cancelled' : ''}" @click=${() => {location.href = "https://marudor.de/"+stop.stop.id+"?searchType=hafas"}}>
|
|
<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>
|
|
`}
|
|
`;
|
|
};
|
|
|
|
const journeyTemplate = (data, requestId, journeyId) => {
|
|
const departure = data.legs[0].departure;
|
|
const arrival = data.legs[data.legs.length - 1].arrival;
|
|
|
|
const departureTime = departure.prognosedTime || departure.plannedTime;
|
|
const arrivalTime = arrival.prognosedTime || arrival.plannedTime;
|
|
const duration = arrivalTime - departureTime;
|
|
|
|
const legs = [];
|
|
let changes = 0;
|
|
let lastArrival;
|
|
for (let leg of data.legs) {
|
|
if (!leg.isWalking && !leg.isTransfer) {
|
|
|
|
// add change
|
|
if (lastArrival) {
|
|
const departure = leg.departure;
|
|
const arrival = lastArrival;
|
|
const departureTime = departure.prognosedTime ? departure.prognosedTime : departure.plannedTime;
|
|
const arrivalTime = arrival.prognosedTime ? arrival.prognosedTime : arrival.plannedTime;
|
|
const duration = departureTime - arrivalTime;
|
|
|
|
legs.push({
|
|
isChange: true,
|
|
duration: duration,
|
|
});
|
|
}
|
|
changes++;
|
|
|
|
lastArrival = leg.arrival;
|
|
} else if (legs.length) {
|
|
|
|
// if this is a walking leg and it is the first one, we don't want to
|
|
// insert a 0 minutes change entry for this
|
|
lastArrival = leg.arrival;
|
|
}
|
|
legs.push(leg);
|
|
}
|
|
|
|
return html`
|
|
<div class="journey">
|
|
<header>
|
|
<a class="back icon-back" href="#/${requestId}"></a>
|
|
<div class="header-content">
|
|
<h3>${parseName(departure.point)} → ${parseName(arrival.point)}</h3>
|
|
<p><b>${t('duration')}: ${formatDuration(duration)} | ${t('changes')}: ${changes-1} | ${t('date')}: ${parseDateTime(departure.plannedTime, 'date')}</b></p>
|
|
</div>
|
|
<a class="reload icon-reload" title="{{LABEL_RELOAD}}" @click=${() => reloadJourney(requestId, journeyId)}>{{LABEL_RELOAD}}</a>
|
|
</header>
|
|
|
|
${legs.map(legTemplate)}
|
|
</div>
|
|
`;
|
|
};
|
|
|
|
const timeTemplate = (data, mode) => {
|
|
let delay = 0;
|
|
|
|
if (data.prognosedTime !== null) {
|
|
delay = (data.prognosedTime - data.plannedTime)/60;
|
|
}
|
|
|
|
if (!data.plannedTime && !data.prognosedTime) return '-';
|
|
|
|
return html`
|
|
${delay > 0 ? html`
|
|
${parseDateTime(data.prognosedTime)} <b>(+${delay})</b>
|
|
` : html`
|
|
${parseDateTime(data.plannedTime)}
|
|
`}`;
|
|
}
|
|
|
|
const platformTemplate = (data) => html`
|
|
${data.prognosedPlatform ? html`
|
|
<b>${data.prognosedPlatform}</b>
|
|
` : (data.plannedPlatform ? data.plannedPlatform : '-')}
|
|
`;
|
|
|
|
const stopPlatformTemplate = (data) => {
|
|
if (data.departure.plannedPlatform | data.departure.prognosedPlatform) {
|
|
if (!data.departure.prognosedPlatform) {
|
|
return data.departure.plannedPlatform;
|
|
} else {
|
|
return html`<b>${data.departure.prognosedPlatform}</b>`;
|
|
}
|
|
} else if (data.arrival.plannedPlatform | data.arrival.prognosedPlatform) {
|
|
if (!data.arrival.prognosedPlatform) {
|
|
return data.arrival.plannedPlatform;
|
|
} else {
|
|
return html`<b>${data.arrival.prognosedPlatform}</b>`;
|
|
}
|
|
} else {
|
|
return '-'
|
|
}
|
|
};
|
|
|
|
export const journeyView = async (match) => {
|
|
const reqId = match[0];
|
|
const journeyId = match[1];
|
|
|
|
let data;
|
|
let all = getCache('journeys', reqId)
|
|
if (all && all.journeys && journeyId in all.journeys) {
|
|
data = all.journeys[journeyId];
|
|
} else {
|
|
const request = await get("/journeys", {"reqId": reqId});
|
|
addCache('journeys', request);
|
|
data = request.journeys[journeyId];
|
|
}
|
|
|
|
ConsoleLog(data);
|
|
render(journeyTemplate(data, reqId, journeyId), ElementById('content'));
|
|
|
|
const journeysHistory = getCache('journeysHistory');
|
|
const history_id = journeysHistory.findIndex(obj => obj.reqId === reqId);
|
|
|
|
if (journeysHistory[history_id] !== undefined) {
|
|
journeysHistory[history_id].journeyId = journeyId;
|
|
addCache('journeysHistory', journeysHistory);
|
|
}
|
|
};
|
|
|
|
const reloadJourney = async (reqId, journeyId) => {
|
|
document.querySelector('.reload').classList.add('spinning');
|
|
try {
|
|
let request = await get("/refreshJourney", {"reqId": reqId, "journeyId": journeyId}, true);
|
|
addCache('journeys', request);
|
|
journeyView([reqId, journeyId]);
|
|
} catch(err) {
|
|
ConsoleLog(err);
|
|
}
|
|
document.querySelector('.reload').classList.remove('spinning');
|
|
};
|