ctucx.git: trainsearch

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

commit 0f1e4143605871ed33ba3b2391ab8333eadafe94
parent a55c1a45f3e4980eec1f4511c7eabd5d01042666
Author: Katja (ctucx) <git@ctu.cx>
Date: Mon, 27 Jan 2025 10:19:30 +0100

cleanup
10 files changed, 53 insertions(+), 140 deletions(-)
M
.gitignore
|
1
+
D
.gitmodules
|
3
---
M
src/app_functions.js
|
23
++++++++++++-----------
M
src/departuresView.js
|
4
++--
M
src/journeyView.js
|
4
++--
M
src/journeysView.js
|
14
+++++++++-----
M
src/searchView.js
|
44
++++++++++++++++++++------------------------
M
src/tripView.js
|
4
++--
D
static/service-worker.js
|
91
-------------------------------------------------------------------------------
M
static/style.css
|
5
+++++
diff --git a/.gitignore b/.gitignore
@@ -1,2 +1,3 @@
 node_modules
 dist
+result
diff --git a/.gitmodules b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "hafas-rs"]
-       path = hafas-rs
-       url = ../hafas-rs
diff --git a/src/app_functions.js b/src/app_functions.js
@@ -9,7 +9,7 @@ import { formatDateTime } from './formatters.js';
 import { getHafasClient, client } from './hafas_client';
 import { trainsearchToHafas, hafasToTrainsearch } from './refresh_token';
 
-let ds100 = {};
+let ds100  = {};
 let ds100R = {};
 
 subscribeSettings(async () => {

@@ -19,7 +19,7 @@ subscribeSettings(async () => {
 const journeySettings = () => { return {
 	stopovers: true,
 	polylines: false,
-	tickets:   settings.showPrices,
+	tickets:   true,
 	language:  settings.language,
 }};
 

@@ -42,7 +42,6 @@ const addJourneys = async data => {
 		};
 	});
 
-
 	if (typeof data.params.loyaltyCard === 'object') data.params.loyaltyCard = loyaltyCardToString(data.params.loyaltyCard);
 
 	const journeysOverviewEntry = {

@@ -57,6 +56,10 @@ const processJourneys = data => {
 	for (const journey of data.journeys) processJourney(journey);
 }
 
+const processJourney = journey => {
+	for (const leg of journey.legs) processLeg(leg);
+};
+
 export const processLeg = leg => {
 	if (leg.plannedDeparture) leg.plannedDeparture = new Date(leg.plannedDeparture);
 	if (leg.plannedArrival) leg.plannedArrival = new Date(leg.plannedArrival);

@@ -74,14 +77,9 @@ export const processLeg = leg => {
 	}
 };
 
-const processJourney = journey => {
-	for (const leg of journey.legs) {
-		processLeg(leg);
-	}
-};
-
 export const getJourneys = async slug => {
 	let data = await db.getJourneysOverview(slug);
+
 	if (!data) return null;
 
 	return {

@@ -91,23 +89,25 @@ export const getJourneys = async slug => {
 };
 
 export const getJourney = async (refreshToken, profile) => {
-	let data       = await db.getJourney(refreshToken);
+	let data = await db.getJourney(refreshToken);
 
 	if (!data || JSON.stringify(data.settings) != JSON.stringify(journeySettings())) {
 		data = await refreshJourney(refreshToken, profile);
 	}
 
 	processJourney(data);
+
 	return data;
 };
 
 export const getMoreJourneys = async (slug, mode) => {
-	const saved = await db.getJourneysOverview(slug);
+	const saved  = await db.getJourneysOverview(slug);
 	const params = { ...saved.params, ...journeySettings() };
 
 	if (typeof params.loyaltyCard === 'string') params.loyaltyCard = loyaltyCardFromString(params.loyaltyCard);
 
 	params[mode+'Than'] = saved[mode+'Ref'];
+
 	let { departure, arrival, from, to, ...moreOpt } = params;
 	const [newData, ...existingJourneys] = await Promise.all(
 		[ client.journeys(from, to, moreOpt) ]

@@ -148,6 +148,7 @@ export const refreshJourney = async (refreshToken, profile) => {
 		db.getJourney(refreshToken),
 		client.refreshJourney(trainsearchToHafas(refreshToken), journeySettings())
 	]);
+
 	const {journey} = data;
 
 	journey.settings     = journeySettings();
diff --git a/src/departuresView.js b/src/departuresView.js
@@ -15,11 +15,11 @@ const departuresTemplate = (data, profile) => {
 	return html`
 		<div class="departuresView column">
 			<header>
-				<a id="back" class="icon-back hidden" title="${t('back')}" @click=${() => history.back()}>${t('back')}</a>
+				<a id="back" class="icon-back hidden" title="${t('back')}" @click=${() => history.back()}></a>
 				<div class="content">
 					<h3>Departures from ${data.name}</h3>
 				</div>
-				<a id="reload" class="icon-reload invisible" title="${t("reload")}">${t("reload")}</a>
+				<a id="reload" class="icon-reload invisible" title="${t("reload")}"></a>
 			</header>
 
 			<div class="card">
diff --git a/src/journeyView.js b/src/journeyView.js
@@ -122,12 +122,12 @@ const journeyTemplate = (data, profile) => {
 	return html`
 		<div class="journeyView column">
 			<header>
-				${data.slug ? html`<a class="icon-back" href="#/${data.slug}/${settings.journeysViewMode}" title="${t('back')}">${t('back')}</a>` : nothing}
+				${data.slug ? html`<a class="icon-back" href="#/${data.slug}/${settings.journeysViewMode}" title="${t('back')}"></a>` : nothing}
 				<div class="content">
 					<h3>${formatName(data.legs[0].origin)} → ${formatName(data.legs[data.legs.length - 1].destination)}</h3>
 					<p><b>${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')}: <td><span>${formatPrice(data.price)}</span></td>` : nothing}</b></p>
 				</div>
-				<a class="icon-reload" title="${t("reload")}" @click=${() => refreshJourneyView(data.refreshToken, profile)}>${t("reload")}</a>
+				<a class="icon-reload" title="${t("reload")}" @click=${() => refreshJourneyView(data.refreshToken, profile)}></a>
 			</header>
 
 			${legs.map(leg => legTemplate(leg, profile))}
diff --git a/src/journeysView.js b/src/journeysView.js
@@ -11,7 +11,7 @@ import { showAlertModal, showLoader, hideOverlay } from './overlays.js';
 const journeysTemplate = (data) => html`
 	<div class="journeysView column">
 		<header id="header">
-			<a class="icon-back" href="#/" title="${t('back')}">${t('back')}</a>
+			<a class="icon-back" href="#/" title="${t('back')}"></a>
 			<div class="content">
 				<h3>${t('from')}: ${formatName(getFrom(data.journeys))}</h3>
 				<h3>${t('to')}: ${formatName(getTo(data.journeys))}</h3>

@@ -26,7 +26,7 @@ const journeysTemplate = (data) => html`
 					</a>
 				</div>
 			</div>
-			<a class="icon-reload" title="${t("reload")}" @click=${() => refreshJourneysView(data.slug)}>${t("reload")}</a>
+			<a class="icon-reload" title="${t("reload")}" @click=${() => refreshJourneysView(data.slug)}></a>
 		</header>
 
 		${settings.journeysViewMode === 'canvas' ? html`

@@ -136,29 +136,32 @@ export const journeysView = async (match, isUpdate) => {
 		go('/');
 		return;
 	}
+
 	hideOverlay();
 
 	render(journeysTemplate(data), ElementById('content'));
 
-	// if (!isUpdate) refreshJourneysView(slug); // update data in the background
-
-	if (settings.journeysViewMode === 'canvas') return setupCanvas(data, isUpdate);
+	if (settings.journeysViewMode === 'canvas')
+		return setupCanvas(data, isUpdate);
 };
 
 export const moreJourneys = async (slug, mode) => {
 	showLoader();
+
 	try {
 		await getMoreJourneys(slug, mode);
 	} catch(e) {
 		showAlertModal(e.toString());
 		throw e;
 	}
+
 	hideOverlay();
 	journeysView([slug, settings.journeysViewMode], true);
 };
 
 const refreshJourneysView = async (slug) => {
 	document.querySelector('.icon-reload').classList.add('spinning');
+
 	try {
 		await refreshJourneys(slug, true);
 	} catch(e) {

@@ -166,6 +169,7 @@ const refreshJourneysView = async (slug) => {
 		document.querySelector('.icon-reload').classList.remove('spinning');
 		throw e;
 	}
+
 	journeysView([slug, settings.journeysViewMode], true);
 	document.querySelector('.icon-reload').classList.remove('spinning');
 };
diff --git a/src/searchView.js b/src/searchView.js
@@ -147,7 +147,26 @@ const searchTemplate = (journeysHistory) => html`
 			` : nothing}
 		</form>
 
-		${journeysHistoryTemplate(journeysHistory)}
+		<div id="history" class="history hidden">
+			${journeysHistory.map(element => html`
+			<div class="row" @click="${() => {journeysHistoryAction(journeysHistory, element);}}">
+				<div class="from">
+					<small>${t('from')}:</small>
+					${formatName(element.fromPoint)}
+					${element.viaPoint ? html`
+						<div class="via">
+							<small>${t('via')} ${formatName(element.viaPoint)}</small>
+						</div>
+					` : nothing}
+				</div>
+				<div class="icon-arrow1"></div>
+				<div class="to">
+					<small>${t('to')}:</small>
+					${formatName(element.toPoint)}
+				</div>
+			</div>
+			`)}
+		</div>
 
 		<footer>
 			<a href="https://git.ctu.cx/trainsearch">Source-Code</a>

@@ -156,29 +175,6 @@ const searchTemplate = (journeysHistory) => html`
 	</div>
 `;
 
-const journeysHistoryTemplate = (journeysHistory) => html`
-	<div id="history" class="history hidden">
-		${journeysHistory.map(element => html`
-		<div class="row" @click="${() => {journeysHistoryAction(journeysHistory, element);}}">
-			<div class="from">
-				<small>${t('from')}:</small><br>
-				${formatName(element.fromPoint)}
-				${element.viaPoint ? html`
-					<div class="via">
-						<small>${t('via')} ${formatName(element.viaPoint)}</small>
-					</div>
-				` : nothing}
-			</div>
-			<div class="icon-arrow1"></div>
-			<div class="to">
-				<small>${t('to')}:</small><br>
-				${formatName(element.toPoint)}
-			</div>
-		</div>
-		`)}
-	</div>
-`;
-
 const journeysHistoryAction = (journeysHistory, element) => showSelectModal([
 	{'label': t('setfromto'),       'action': () => { setFromHistory(journeysHistory.length - 1 - journeysHistory.indexOf(element)); hideOverlay(); }},
 	{'label': t('journeyoverview'), 'action': () => { go('/'+element.slug+'/'+settings.journeysViewMode); hideOverlay(); }}
diff --git a/src/tripView.js b/src/tripView.js
@@ -28,11 +28,11 @@ const tripTemplate = (data, profile) => {
 	return html`
 		<div class="journeyView column">
 			<header>
-				<a id="back" class="icon-back hidden" title="${t('back')}" @click=${() => history.back()}>${t('back')}</a>
+				<a id="back" class="icon-back hidden" title="${t('back')}" @click=${() => history.back()}>$</a>
 				<div class="content">
 					<h3>Trip of ${formatLineDisplayName(data.line)} to ${data.direction}</h3>
 				</div>
-				<a class="icon-reload invisible">${t("reload")}</a>
+				<a class="icon-reload invisible" title="${t('title')}"></a>
 			</header>
 
 			<div class="card">
diff --git a/static/service-worker.js b/static/service-worker.js
@@ -1,91 +0,0 @@
-'use strict';
-
-const CACHE = 'cache-v34';
-
-let preCache = [
-	'./img/product_bus_grey.svg',
-	'./img/product_cablecar_color.svg',
-	'./img/product_cablecar_grey.svg',
-	'./img/product_call_color.svg',
-	'./img/product_call_grey.svg',
-	'./img/product_ferry_color.svg',
-	'./img/product_ferry_grey.svg',
-	'./img/product_highspeed_color.svg',
-	'./img/product_highspeed_grey.svg',
-	'./img/product_suburban_color.svg',
-	'./img/product_suburban_grey.svg',
-	'./img/product_subway_color.svg',
-	'./img/product_subway_grey.svg',
-	'./img/product_train_color.svg',
-	'./img/product_train_grey.svg',
-	'./img/product_bus_color.svg',
-	'./img/product_tram_grey.svg',
-	'./img/product_tram_color.svg',
-	'./img/back.svg',
-	'./img/baseline-beenhere-24px.svg',
-	'./img/baseline-departure_board-24px.svg',
-	'./img/baseline-directions-24px.svg',
-	'./img/baseline-directions-24px_white.svg',
-	'./img/baseline-directions_walk-24px.svg',
-	'./img/baseline-expand_more-24px.svg',
-	'./img/baseline-import_export-24px.svg',
-	'./img/baseline-navigation-24px.svg',
-	'./img/baseline-place-24px.svg',
-	'./img/baseline-settings-20px.svg',
-	'./ing/baseline-swap_vert-24px.svg',
-	'./img/baseline-refresh-24px.svg',
-	'./img/ba8064fd767ceaa170589aa3dd11e58e.jpg',
-	'./img/favicon-16x16.png',
-	'./img/favicon-32x32.png',
-	'./img/favicon-64x64.png',
-	'./img/favicon-512x512.png',
-	'./img/apple-touch-icon.png',
-	'./js/api.js',
-	'./js/canvas.js',
-	'./js/journeysView.js',
-	'./js/journeyView.js',
-	'./js/searchView.js',
-	'./js/settingsView.js',
-	'./js/app_functions.js',
-	'./js/helpers.js',
-	'./js/app.js',
-	'./js/router.js',
-	'./js/overlays.js',
-	'./css/product_selector.css',
-	'./css/style.css',
-	'./manifest.json',
-	'./index.html',
-	'./'
-];
-
-self.addEventListener('install', function (evt) {
-	self.skipWaiting();
-	evt.waitUntil(caches.open(CACHE).then(function (cache) {
-		cache.addAll(preCache);
-	}));
-});
-
-self.addEventListener('fetch', function (evt) {
-	evt.respondWith(fromCache(evt.request).then(function (match) {
-		if (match) {
-			return match;
-		} else {
-			return fetch(evt.request);
-		}
-	}));
-});
-
-self.addEventListener('activate', function (event) {
-	event.waitUntil(clients.claim());
-	event.waitUntil(clients.claim().then(function () {
-		return caches.keys().then(function (cacheNames) {
-			return Promise.all(cacheNames.filter(c => c !== CACHE).map(c => caches.delete(c)));
-		});
-	}));
-});
-
-function fromCache (request) {
-	return caches.open(CACHE).then(function (cache) {
-		return cache.match(request);
-	});
-}
diff --git a/static/style.css b/static/style.css
@@ -381,6 +381,11 @@ header {
 			text-align: right;
 		}
 
+		small::after {
+			content: "\a";
+			white-space: pre;
+		}
+
 		.icon-arrow1 {
 			width: 25px;
 		}