import { html, nothing, render } from 'lit-html'; import { cachedCoachSequence } from './coach-sequence/index.js'; import { settings } from './settings.js'; import { remarksModalTemplate, platformTemplate, stopTemplate, timeTemplate, footerTemplate } from './templates.js'; import { ElementById, setThemeColor, queryBackgroundColor } from './helpers.js'; import { getJourney, refreshJourney } from './app_functions.js'; import { formatName, formatDateTime, formatDuration, formatPrice, formatTrainTypes, formatLineAdditionalName, formatLineDisplayName } from './formatters.js'; import { showAlertModal, showLoader, hideOverlay, showModal } from './overlays.js'; import { go } from './router.js'; import { t } from './languages.js'; import { db } from './dataStorage.js'; import { showSelectModal } from './overlays.js'; const legTemplate = (leg, profile) => { const remarks = leg.remarks || []; const remarksStatus = remarks.some((obj) => obj.type === 'status'); const remarksWarning = remarks.some((obj) => obj.type === 'warning'); const remarksIcon = remarksWarning ? 'icon-warning' : (remarksStatus ? 'icon-status' : 'icon-hint'); return html` ${leg.walking ? html`

${t(leg.distance === null ? 'walkinfo' : 'walkinfo_meters', formatName(leg.destination), leg.distance)}

` : leg.transfer ? html`

${t('transferinfo', formatName(leg.destination))}

` : leg.change ? html`

${t('changeinfo', formatDuration(leg.duration))}

` : html`
${(leg.stopovers || []).map(stop => html` `)}
${formatLineDisplayName(leg.line)}${leg.direction ? html` → ${leg.direction}` : nothing} ${leg.cancelled ? html`${t('cancelled-ride')}` : nothing} ${!!remarks.length ? html` showModal(t('remarks'), remarksModalTemplate(remarks))}> ` : nothing}
${formatLineAdditionalName(leg.line) ? html`
Trip: ${formatLineAdditionalName(leg.line)}
` : nothing} ${leg.line.trainType ? html`
Train type: ${leg.line.trainType}
` : nothing} ${(leg.arrival && leg.departure) ? html`
${t('duration')}: ${formatDuration(leg.arrival - leg.departure)}
` : nothing} ${leg.loadFactor ? html`
${t("load-"+leg.loadFactor)}
` : nothing}
${t('arrival')} ${t('departure')} ${t('station')} ${t('platform')}
${timeTemplate(stop, 'arrival')} ${timeTemplate(stop, 'departure')} ${stopTemplate(profile, stop.stop)} ${platformTemplate(stop)}
`} `; }; const journeyTemplate = (data, profile) => { let duration = null; if (data.legs[data.legs.length - 1].arrival && data.legs[0].departure) duration = data.legs[data.legs.length - 1].arrival - data.legs[0].departure; const legs = []; let changes = 0; let lastArrival; for (const leg of data.legs) { if (!leg.walking && !leg.transfer) { // add change if (lastArrival) { let duration = null; if (leg.departure && lastArrival) { duration = leg.departure - lastArrival; } legs.push({ change: true, 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`
${data.slug ? html`` : nothing}
refreshJourneyView(profile, data.refreshToken)}>

${formatName(data.legs[0].origin)} → ${formatName(data.legs[data.legs.length - 1].destination)}

${t('duration')}: ${formatDuration(duration)} | ${t('changes')}: ${changes-1} | ${t('date')}: ${formatDateTime(data.legs[0].plannedDeparture, 'date')}${settings.showPrices && settings.profile === 'db' && data.price ? html` | ${t('price')}: ${formatPrice(data.price)}` : nothing}

moreModal(profile, data.refreshToken)}>
${legs.map(leg => legTemplate(leg, profile))}
${footerTemplate} `; }; export const journeyView = async (match, isUpdate) => { if (!isUpdate) showLoader(); let profile, refreshToken, journeyObject; try { profile = match[0]; refreshToken = decodeURIComponent(match[1]); journeyObject = await getJourney(refreshToken, profile); if (journeyObject.slug) { let overviewObject = await db.getJourneysOverview(journeyObject.slug); let historyObject = await db.getHistoryEntry(overviewObject.historyEntryId); historyObject.lastSelectedJourneyId = journeyObject.refreshToken; await db.updateHistoryEntry(overviewObject.historyEntryId, historyObject); } } catch(e) { console.error(e); await showAlertModal(e.toString()); go('/'); return; } for (const leg of journeyObject.legs) { if (leg.line && leg.line.name) { const [category, number] = leg.line.name.split(' '); const info = await cachedCoachSequence(category, leg.line.fahrtNr || number, leg.origin.id, leg.plannedDeparture); if (info) leg.line.trainType = formatTrainTypes(info); } } hideOverlay(); render(journeyTemplate(journeyObject, profile), ElementById('content')); setThemeColor(queryBackgroundColor('header')); }; const refreshJourneyView = async (profile, refreshToken) => { document.querySelector('.icon-reload').classList.add('spinning'); try { await refreshJourney(refreshToken, profile); } catch(e) { showAlertModal(e.toString()); document.querySelector('.icon-reload').classList.remove('spinning'); throw e; } journeyView([profile, refreshToken], true); document.querySelector('.icon-reload').classList.remove('spinning'); }; const moreModal = (profile, refreshToken) => { const options = [ { 'label': !navigator.canShare ? t('copyURL') : t('shareURL'), 'action': () => { shareAction(); hideOverlay(); }}, ]; showSelectModal(options); }; const shareAction = async () => { try { await navigator.share({ url: window.location, }); } catch (error) { navigator.clipboard.writeText(window.location); } };