commit f951410ab5ff2b846ed7eb478718583f1467f9ad
parent fb46f86ab273a99008c5cddacd3971b64181b892
Author: Katja (ctucx) <git@ctu.cx>
Date: Sun, 2 Feb 2025 23:01:36 +0100
parent fb46f86ab273a99008c5cddacd3971b64181b892
Author: Katja (ctucx) <git@ctu.cx>
Date: Sun, 2 Feb 2025 23:01:36 +0100
journeyView: add share/copy function
4 files changed, 131 insertions(+), 0 deletions(-)
diff --git a/nginx.conf b/nginx.conf @@ -0,0 +1,99 @@ +daemon off; +worker_processes 1; + +pid /tmp/nginx.pid; + +error_log /dev/stdout debug; + +events { + use epoll; + worker_connections 128; +} + +http { + server_tokens off; + charset utf-8; + + map $vendotarget $vendopath { + default no; + locations '/mob/location/search'; + 'location' '/mob/location/details'; + journeys '/mob/angebote/fahrplan'; + journey '/mob/angebote/recon'; + departures '/mob/bahnhofstafel/abfahrt'; + trip '/mob/zuglauf'; + } + + map $hafastarget $hafasurl { + default no; + nahsh nah.sh.hafas.de; + rmv www.rmv.de; + vrn vrn.hafas.de; + bvg bvg-apps-ext.hafas.de; + oebb fahrplan.oebb.at; + } + + map $hafastarget $hafaspath { + default no; + nahsh '/bin/mgate.exe'; + rmv '/auskunft/bin/jp/mgate.exe'; + vrn '/bin/mgate.exe'; + bvg '/bin/mgate.exe'; + oebb '/bin/mgate.exe'; + } + + server { + server_name localhost; + listen 127.0.0.1:1234; + + access_log /dev/stdout; + + location /db/vehicle-sequence { + resolver 8.8.8.8; + proxy_ssl_server_name on; + proxy_ssl_name www.bahn.de; + proxy_set_header Host www.bahn.de; + proxy_pass https://www.bahn.de/web/api/reisebegleitung/wagenreihung/vehicle-sequence$is_args$args; + } + + + location ~ ^/db/vendo/(?<vendotarget>[a-z]+)(/([^\r\n].*))?$ { + set $vendodomain 'app.vendo.noncd.db.de'; + + add_header x-input $1.$2 always; + + if ($vendopath = no) { + return 400; + } + + if ($vendotarget = 'trip') { + set $vendopath '$vendopath$2'; + } + + if ($vendotarget = 'location') { + set $vendopath '$vendopath$2'; + } + + add_header x-target https://$vendodomain$vendopath always; + + resolver 8.8.8.8; + proxy_ssl_server_name on; + proxy_ssl_name $vendodomain; + proxy_set_header Host $vendodomain; + proxy_pass https://$vendodomain$vendopath; + } + + location ~ ^/hafas/(?<hafastarget>.*)$ { + if ($hafasurl = no) { + return 400; + } + + resolver 8.8.8.8; + proxy_ssl_server_name on; + proxy_ssl_name $hafasurl; + proxy_set_header Host $hafasurl; + proxy_pass https://$hafasurl$hafaspath; + } + } + +}
diff --git a/src/assets/icons.css b/src/assets/icons.css @@ -74,3 +74,10 @@ content: url('data:image/svg+xml;utf8,<svg version="1.1" viewBox="0 0 24 24" height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m11 5v14h2v-14zm-4-2v14h2v-14zm10 4h-2v14h2z" fill="white"/></svg>'); } +.icon-dots { + content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height="24" width="24"><path d="M12 16a2 2 0 0 1 2 2 2 2 0 0 1-2 2 2 2 0 0 1-2-2 2 2 0 0 1 2-2m0-6a2 2 0 0 1 2 2 2 2 0 0 1-2 2 2 2 0 0 1-2-2 2 2 0 0 1 2-2m0-6a2 2 0 0 1 2 2 2 2 0 0 1-2 2 2 2 0 0 1-2-2 2 2 0 0 1 2-2" fill="white"/></svg>'); +} + +.icon-share { + content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height="24" width="24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08" fill="white"/></svg>'); +}
diff --git a/src/journeyView.js b/src/journeyView.js @@ -9,6 +9,7 @@ import { showAlertModal, showLoader, hideOverlay, showModal } from './overlays.j 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 || []; @@ -129,6 +130,7 @@ const journeyTemplate = (data, profile) => { <header> ${data.slug ? html`<a class="icon-back" href="#/${data.slug}/${settings.journeysViewMode}" title="${t('back')}"></a>` : nothing} <div class="container"> + <a class="icon-dots" title="${t("more")}" @click=${() => moreOverlay()}></a> <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> @@ -197,3 +199,21 @@ const refreshJourneyView = async (refreshToken, profile) => { journeyView([profile, refreshToken], true); document.querySelector('.icon-reload').classList.remove('spinning'); }; + +const moreOverlay = () => { + 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); + } +};+ \ No newline at end of file
diff --git a/src/languages.js b/src/languages.js @@ -106,6 +106,8 @@ const languages = { 'walkingSpeedSlow': 'langsam', 'walkingSpeedNormal': 'normal', 'walkingSpeedFast': 'schnell', + 'shareURL': 'Link teilen', + 'copyURL': 'Link kopieren', }, 'nl': { @@ -252,5 +254,7 @@ const languages = { 'walkingSpeedSlow': 'slow', 'walkingSpeedNormal': 'normal', 'walkingSpeedFast': 'fast', + 'shareURL': 'Share URL', + 'copyURL': 'Copy URL', } };