ctucx.git: trainsearch

web based trip-planner, fork of https://cyberchaos.dev/yuka/trainsearch

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
91 
92 
93 
94 
95 
96 
97 
98 
99 
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
110 
111 
112 
113 
114 
import { html, nothing, render } from 'lit-html';
import { settings } from './settings.js';
import { platformTemplate, timeTemplate } from './templates.js';
import { ElementById, setThemeColor, queryBackgroundColor } from './helpers.js';
import { processLeg } from './app_functions.js';
import { formatDateTime, formatDuration, formatPrice } from './formatters.js';
import { showAlertModal, showLoader, hideOverlay, showModal } from './overlays.js';
import { go } from './router.js';
import { getHafasClient, client } from './hafasClient.js';
import { t } from './languages.js';

const departuresTemplate = (data, profile, stopId, when) => {
	let changes = 0;
	let lastArrival;

	return html`
		<div class="header-container">
			<header>
				<a id="back" class="icon-back invisible" title="${t('back')}" @click=${() => history.back()}></a>
				<div class="container">
					<h3>Departures from ${data.name}</h3>
				</div>
				<a id="reload" class="icon-reload" title="${t("reload")}" @click=${() => refreshDeparturesView(profile, stopId, when)}></a>
			</header>
		</div>
		<div class="container departuresView">
			<div class="card">
			<table>
				<thead>
					<tr>
						<th>Time</th>
						<th class="station"></th>
						<th>${t('platform')}</th>
					</tr>
				</thead>
				<tbody>
					${(data.departures || []).map(departure => html`
						<tr @click=${() => go(`/t/${profile}/${departure.tripId}`)}>
							<td class="${departure.cancelled ? 'cancelled' : nothing}"><span>${timeTemplate(departure)}</span></td>
							<td class="${departure.cancelled ? 'cancelled' : nothing}"><span>${departure.line.name}${departure.direction ? html` → ${departure.direction}` : nothing}</span></td>
							${departure.cancelled ? html`
								<td><span class="cancelled-text">${t('cancelled-ride')}</span></td>
							` : html`
								<td>${platformTemplate(departure)}</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();

	render(departuresTemplate(data, profile, stopId, when), ElementById('content'));
	setThemeColor(queryBackgroundColor('header'));

	if (history.length > 0) ElementById('back').classList.remove('invisible');
};

const refreshDeparturesView = async (profile, stopId, when) => {
	document.querySelector('.icon-reload').classList.add('spinning');

	let data;

	try {
		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;
	}

	render(departuresTemplate(data, profile, stopId, when), ElementById('content'));
	document.querySelector('.icon-reload').classList.remove('spinning');
};