import { html, nothing } from 'lit'; import { classMap } from 'lit/directives/class-map.js'; import { choose } from 'lit/directives/choose.js'; import { when } from 'lit/directives/when.js'; import { join } from 'lit/directives/join.js'; import { sleep, queryBackgroundColor, setThemeColor } from './helpers.js'; import { getJourneys, getMoreJourneys, refreshJourneys, getFromPoint, getToPoint } from './app_functions.js'; import { formatPoint, formatDuration, formatPrice } from './formatters.js'; import { timeTemplate } from './templates.js'; import { t } from './translate.js'; import { headerStyles, tableStyles, journeysViewStyles } from './styles.js'; import { JourneysCanvas } from './journeysCanvas.js'; export class JourneysView extends JourneysCanvas { static styles = [ super.styles, headerStyles, tableStyles, journeysViewStyles ]; static properties = { slug: { attribute: true }, mode: { attribute: true }, viewState: { state: true }, }; constructor () { super(); this.viewState = null; } async connectedCallback () { super.connectedCallback(); if (this.mode === 'canvas') this.connectCanvas(); await sleep(200); setThemeColor(queryBackgroundColor(this.renderRoot, 'header')); } disconnectedCallback () { super.disconnectedCallback(); this.viewState = null; if (this.mode === 'canvas') this.disconnectCanvas(); } async willUpdate (previous) { if (previous.has('slug')) { this.resetCanvasPosition(); this.viewState = null; } if (previous.has('mode')) { if (previous.get('mode') === 'canvas' && this.mode !== 'canvas') this.disconnectCanvas(); if (this.settingsState.journeysViewMode !== this.mode) this.settingsState.setJourneysViewMode(this.mode); } if (!this.viewState && !this.overlayState.visible) { await this.updateViewState(); if (this.mode === 'canvas' && this.viewState) await this.getCoachSequences(); } if (this.mode === 'canvas') this.connectCanvas(); } updated (previous) { super.updated(previous, 'JourneysView'); if (this.mode === 'canvas') this.renderCanvas(); if (isDevServer && previous.has('viewState')) console.info('JourneysView(viewState): ', this.viewState); } renderView = () => [ html`

${t('from')}: ${!this.viewState ? '...' : formatPoint(getFromPoint(this.viewState.journeys))}

${t('to')}: ${!this.viewState ? '...' : formatPoint(getToPoint(this.viewState.journeys))}

`, when( !this.viewState, () => html`
`, () => choose(this.settingsState.journeysViewMode, [ [ 'canvas', () => this.getCanvas() ], [ 'table', () => html`
${when( this.viewState.earlierRef, () => html`
this.moreJourneys('earlier')}>` )}
${t('departure')} ${t('arrival')} ${t('duration')} ${t('changes')} ${t('products')} ${when( this.settingsState.showPrices && this.viewState.profile === 'db', () => html`${t('price')}` )}
${this.viewState.journeys.map(journey => this.journeyTemplate(journey))}
${when( this.viewState.laterRef, () => html` this.moreJourneys('later')}>` )}
` ], ]) ) ]; journeyTemplate = journey => { const firstLeg = journey.legs[0]; const lastLeg = journey.legs[journey.legs.length - 1]; return html` ${timeTemplate(firstLeg, 'departure')} ${when( !journey.cancelled, () => html`${timeTemplate(lastLeg, 'arrival')}`, () => html`${t('cancelled')}` )} ${formatDuration(journey.duration)} ${journey.changes-1} ${join(journey.products, ', ')} ${when( this.settingsState.showPrices && this.viewState.profile === 'db', () => html`${formatPrice(journey.price)}` )} `; }; updateViewState = async () => { try { let viewState = await getJourneys(this.slug); if (!viewState) { this.showAlertOverlay( html`journeys overview id invalid.
journeys overview links can not be shared across devices.`, () => { window.location = '#/'; } ); return; } viewState.journeys.forEach((journey, index, journeys) => { const firstLeg = journey.legs[0]; const lastLeg = journey.legs[journey.legs.length - 1]; journeys[index].changesDuration = 0; journeys[index].duration = Number(lastLeg.arrival || lastLeg.plannedArrival) - Number(firstLeg.departure || firstLeg.plannedDeparture); journeys[index].cancelled = false; journeys[index].changes = 0; journeys[index].products = []; let previousLegArrival = null; journey.legs.forEach(leg => { if (leg.cancelled) journeys[index].cancelled = true; if (leg.walking || leg.transfer) return; if (previousLegArrival) journeys[index].changesDuration += Number(leg.departure || leg.plannedDeparture) - previousLegArrival; previousLegArrival = Number(leg.arrival || leg.plannedArrival) journeys[index].changes++; if (leg.line) { const productName = leg.line.name.split(' ')[0]; if (!journeys[index].products.includes(productName)) { journeys[index].products.push(productName); } } }); }); this.viewState = viewState; } catch(e) { this.showAlertOverlay( e.toString(), () => { window.location = '#/'; } ); console.error(e); } }; refreshJourneys = async () => { if (this.isOffline || this.isUpdating) return; try { this.isUpdating = true; await refreshJourneys(this.slug); await this.updateViewState(); if (this.mode === 'canvas') await this.getCoachSequences('noCache'); this.isUpdating = false; } catch(e) { this.isUpdating = false; this.showAlertOverlay(e.toString()); console.error(e); } }; moreJourneys = async mode => { if (this.isOffline) { this.showAlertOverlay(t('offline')); return; } try { this.isUpdating = true; this.showLoaderOverlay(); await getMoreJourneys(this.slug, mode); await this.updateViewState(); this.hideOverlay(); if (this.mode === 'canvas') await this.getCoachSequences(); this.isUpdating = false; } catch(e) { this.isUpdating = false; this.hideOverlay(); this.showAlertOverlay(e.toString()); console.error(e); } }; } customElements.define('journeys-view', JourneysView);