From 8a04cf20c5d6dc577a7de7745cbeb292bf78529d Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sat, 21 Aug 2021 11:35:43 +0200 Subject: asset version management --- sass/app.scss | 2 +- scripts/asset-rebuild | 4 +- scripts/asset-release | 15 ++++ static/css/dark.min.css | 1 + static/css/light.min.css | 1 + static/font/MaterialIcons-Regular.ttf | Bin 0 -> 285724 bytes static/js/geolocation.js | 143 +++++++++++++++++++++++++++++++ static/v0 | 1 + static/v0/css/dark.min.css | 1 - static/v0/css/light.min.css | 1 - static/v0/font/MaterialIcons-Regular.ttf | Bin 285724 -> 0 bytes static/v0/js/geolocation.js | 143 ------------------------------- static/v1 | 1 + templates/header.html | 4 +- templates/landing_page.html | 2 +- 15 files changed, 168 insertions(+), 151 deletions(-) create mode 100755 scripts/asset-release create mode 100644 static/css/dark.min.css create mode 100644 static/css/light.min.css create mode 100644 static/font/MaterialIcons-Regular.ttf create mode 100644 static/js/geolocation.js create mode 120000 static/v0 delete mode 100644 static/v0/css/dark.min.css delete mode 100644 static/v0/css/light.min.css delete mode 100644 static/v0/font/MaterialIcons-Regular.ttf delete mode 100644 static/v0/js/geolocation.js create mode 120000 static/v1 diff --git a/sass/app.scss b/sass/app.scss index 621cb79..d4c9203 100644 --- a/sass/app.scss +++ b/sass/app.scss @@ -396,7 +396,7 @@ ul.departures { font-weight: 400; src: local('Material Icons'), local('MaterialIcons-Regular'), - url(/static/v0/font/MaterialIcons-Regular.ttf) format('truetype'); + url(/static/v1/font/MaterialIcons-Regular.ttf) format('truetype'); } .material-icons { diff --git a/scripts/asset-rebuild b/scripts/asset-rebuild index c2c722b..549fd7a 100755 --- a/scripts/asset-rebuild +++ b/scripts/asset-rebuild @@ -5,5 +5,5 @@ set -ex -sassc -t compressed sass/dark.scss static/v0/css/dark.min.css -sassc -t compressed sass/light.scss static/v0/css/light.min.css +sassc -t compressed sass/dark.scss static/css/dark.min.css +sassc -t compressed sass/light.scss static/css/light.min.css diff --git a/scripts/asset-release b/scripts/asset-release new file mode 100755 index 0000000..e0a74da --- /dev/null +++ b/scripts/asset-release @@ -0,0 +1,15 @@ +#!/bin/sh +# Copyright (C) 2020 Daniel Friesel +# +# SPDX-License-Identifier: CC0-1.0 + +set -ex + +current="$(find static/v* | tail -n 1 | grep -o '[0-9]*$')" +prev=$((current - 1)) +next=$((current + 1)) + +git mv static/v${prev} static/v${next} + +perl -pi -e "s!/static/v${current}/!/static/v${next}/!g" \ + sass/*.scss static/css/*.min.css templates/* diff --git a/static/css/dark.min.css b/static/css/dark.min.css new file mode 100644 index 0000000..42888b2 --- /dev/null +++ b/static/css/dark.min.css @@ -0,0 +1 @@ +body{margin:0;color:#fff;background-color:#101010}html{font-family:Sans-Serif}.container{max-width:60em;margin-left:auto;margin-right:auto}.textcontent{margin-left:1ex;margin-right:1ex}a{color:#99f;text-decoration:none}input,select,button{display:block;width:100%;max-width:100%;min-height:1.8em;border-radius:4px;font-size:90%;color:#fff;background-color:#101010;border:1px solid #444;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);margin-left:auto;margin-right:auto;text-align:center;vertical-align:middle;padding-top:1ex;padding-bottom:1ex;margin-top:1ex;margin-bottom:1ex}button{transition:background-color .3s;color:#fff;background-color:#337ab7;border-color:#2e6da4;cursor:pointer;box-shadow:none}button:active,button:focus,button:hover{color:#fff;background-color:#286090;border-color:#204d74}input[type="text"]{padding-left:0.5em;padding-right:0.5em;text-align:left;box-sizing:border-box}.globalnote{margin-top:1em;font-style:italic;text-align:center}.geolocation{margin-bottom:1em}.notice{padding:15px;margin-bottom:20px;border:1px solid #bce8f1;border-radius:4px;color:#31708f;background-color:#d9edf7;margin-left:auto;margin-right:auto}.warning{padding:15px;border:1px solid #faebcc;border-radius:4px;color:#8a6d3b;background-color:#fcf8e3;margin-left:auto;margin-right:auto}.warning .errcode{font-family:Monospace;margin-top:2em;font-size:100%;color:#aaaaaa}.error{padding:15px;margin-bottom:20px;border:1px solid #ebccd1;border-radius:4px;color:#a94442;background-color:#f2dede;margin-left:auto;margin-right:auto}.error strong{margin-right:.2em}.error .errcode{font-family:Monospace;margin-top:2em;font-size:100%;color:#aaaaaa}ul.stops{position:relative;width:100%;border-width:1px 2px;margin-bottom:5em;list-style-type:none;margin:0;padding:0}ul.stops a{text-decoration:none}ul.stops>li{display:block;height:4em;width:100%;position:relative;border-bottom:1px solid grey;background-color:#101010;cursor:pointer}ul.stops>li .name{position:absolute;bottom:0;left:5px;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:#fff}ul.stops>li .distance{position:absolute;top:1px;right:5px;width:30%;text-align:right;height:1.2em;overflow:hidden;opacity:50%}ul.stops>li .note{position:absolute;top:1px;left:0;width:70%;height:1.2em;overflow:hidden;opacity:50%}ul.stops>li .lines{position:absolute;bottom:0.1em;right:5px;background-color:transparent;font-weight:bold;font-size:120%}ul.stops>li .lines span{padding-left:0.1em;padding-right:0.1em;margin-left:0.2em}ul.stops>li .lines .longdistance{border:0.1em solid #7c1a1a}ul.stops>li .lines .regional{background-color:#444}ul.stops>li .lines .tram{background-color:#852121}ul.stops>li .lines .taxi{background-color:#7f3d7f;font-weight:normal}ul.stops>li .lines .suburban{background-color:#2f6639;border-radius:30px}ul.stops>li .lines .subway{background-color:#2045b0}ul.stops>li .lines .bus{background-color:#7f3d7f;border-radius:10px}ul.departures{position:relative;width:100%;border-width:1px 2px;margin-bottom:5em;list-style-type:none;margin:0;padding:0}ul.departures>li{display:block;height:3em;width:100%;position:relative;cursor:pointer;border-bottom:1px solid grey;background-color:#101010}ul.departures>li.cancelled{background-color:#ffe7d0}ul.departures .line{position:absolute;bottom:2px;left:2px;max-width:6em;max-height:3ex;max-width:5em;overflow:hidden;font-size:120%;background-color:#444;font-weight:bold;padding-left:0.1em;padding-right:0.1em}ul.departures .longdistance{border:0.1em solid #7c1a1a}ul.departures .tram{background-color:#852121}ul.departures .suburban{background-color:#2f6639;border-radius:30px}ul.departures .subway{background-color:#2045b0}ul.departures .bus{background-color:#7f3d7f;border-radius:10px}ul.departures .dest{position:absolute;bottom:0;left:4em;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:#fff}ul.departures .destsuffix{position:absolute;top:1px;left:6.1em;width:70%;height:1.2em;overflow:hidden}ul.departures .time{position:absolute;right:5px;top:1px;background-color:transparent;padding-left:0.2em;color:#fff}ul.departures .time .delay{padding-right:1ex;color:#ff0000}ul.departures .platform{position:absolute;bottom:0;right:5px;overflow:hidden;background-color:transparent;font-size:140%;font-weight:bold;color:#fff}.navbar-fixed{position:relative;z-index:997}.navbar-fixed nav{position:fixed;width:100%;box-shadow:0 2px 2px 0 rgba(0,0,0,0.14),0 3px 1px -2px rgba(0,0,0,0.12),0 1px 5px 0 rgba(0,0,0,0.2);overflow:hidden}.navbar-fixed nav a{color:#ffffff}.navbar-fixed nav .container{position:relative;height:100%}.navbar-fixed nav .main{position:absolute;display:inline-block;padding-left:0.5rem}.navbar-fixed nav ul{float:right;margin:0;padding-left:0;list-style-type:none}.navbar-fixed nav ul li{float:left;padding:0;list-style-type:none;padding-left:.8em;padding-right:.8em}.about{color:#bbb;margin-top:2em}@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:local("Material Icons"),local("MaterialIcons-Regular"),url(/static/v1/font/MaterialIcons-Regular.ttf) format("truetype")}.material-icons{font-family:'Material Icons';font-weight:normal;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr}@media only screen and (max-width: 600px){ul.departures>li,ul.stops>li{font-size:85%}.navbar-fixed{height:50px}nav{height:50px;line-height:50px}nav .main{font-size:120%}nav .material-icons{height:50px;line-height:50px}}@media only screen and (min-width: 600px){.navbar-fixed{height:60px}nav{height:60px;line-height:60px}nav .main{font-size:140%}nav .material-icons{height:60px;line-height:60px}} diff --git a/static/css/light.min.css b/static/css/light.min.css new file mode 100644 index 0000000..272efba --- /dev/null +++ b/static/css/light.min.css @@ -0,0 +1 @@ +body{margin:0;color:#000;background-color:#fff}html{font-family:Sans-Serif}.container{max-width:60em;margin-left:auto;margin-right:auto}.textcontent{margin-left:1ex;margin-right:1ex}a{color:#009;text-decoration:none}input,select,button{display:block;width:100%;max-width:100%;min-height:1.8em;border-radius:4px;font-size:90%;color:#000;background-color:#fff;border:1px solid #ccc;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);margin-left:auto;margin-right:auto;text-align:center;vertical-align:middle;padding-top:1ex;padding-bottom:1ex;margin-top:1ex;margin-bottom:1ex}button{transition:background-color .3s;color:#fff;background-color:#337ab7;border-color:#2e6da4;cursor:pointer;box-shadow:none}button:active,button:focus,button:hover{color:#fff;background-color:#286090;border-color:#204d74}input[type="text"]{padding-left:0.5em;padding-right:0.5em;text-align:left;box-sizing:border-box}.globalnote{margin-top:1em;font-style:italic;text-align:center}.geolocation{margin-bottom:1em}.notice{padding:15px;margin-bottom:20px;border:1px solid #bce8f1;border-radius:4px;color:#31708f;background-color:#d9edf7;margin-left:auto;margin-right:auto}.warning{padding:15px;border:1px solid #faebcc;border-radius:4px;color:#8a6d3b;background-color:#fcf8e3;margin-left:auto;margin-right:auto}.warning .errcode{font-family:Monospace;margin-top:2em;font-size:100%;color:#aaaaaa}.error{padding:15px;margin-bottom:20px;border:1px solid #ebccd1;border-radius:4px;color:#a94442;background-color:#f2dede;margin-left:auto;margin-right:auto}.error strong{margin-right:.2em}.error .errcode{font-family:Monospace;margin-top:2em;font-size:100%;color:#aaaaaa}ul.stops{position:relative;width:100%;border-width:1px 2px;margin-bottom:5em;list-style-type:none;margin:0;padding:0}ul.stops a{text-decoration:none}ul.stops>li{display:block;height:4em;width:100%;position:relative;border-bottom:1px solid grey;background-color:#fff;cursor:pointer}ul.stops>li .name{position:absolute;bottom:0;left:5px;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:#000}ul.stops>li .distance{position:absolute;top:1px;right:5px;width:30%;text-align:right;height:1.2em;overflow:hidden;opacity:50%}ul.stops>li .note{position:absolute;top:1px;left:0;width:70%;height:1.2em;overflow:hidden;opacity:50%}ul.stops>li .lines{position:absolute;bottom:0.1em;right:5px;background-color:transparent;font-weight:bold;font-size:120%}ul.stops>li .lines span{padding-left:0.1em;padding-right:0.1em;margin-left:0.2em}ul.stops>li .lines .longdistance{border:0.1em solid #fcc}ul.stops>li .lines .regional{background-color:#eee}ul.stops>li .lines .tram{background-color:#fcc}ul.stops>li .lines .taxi{background-color:#eae;font-weight:normal}ul.stops>li .lines .suburban{background-color:#aaffba;border-radius:30px}ul.stops>li .lines .subway{background-color:#aac0ff}ul.stops>li .lines .bus{background-color:#eae;border-radius:10px}ul.departures{position:relative;width:100%;border-width:1px 2px;margin-bottom:5em;list-style-type:none;margin:0;padding:0}ul.departures>li{display:block;height:3em;width:100%;position:relative;cursor:pointer;border-bottom:1px solid grey;background-color:#fff}ul.departures>li.cancelled{background-color:#ffe7d0}ul.departures .line{position:absolute;bottom:2px;left:2px;max-width:6em;max-height:3ex;max-width:5em;overflow:hidden;font-size:120%;background-color:#eee;font-weight:bold;padding-left:0.1em;padding-right:0.1em}ul.departures .longdistance{border:0.1em solid #fcc}ul.departures .tram{background-color:#fcc}ul.departures .suburban{background-color:#aaffba;border-radius:30px}ul.departures .subway{background-color:#aac0ff}ul.departures .bus{background-color:#eae;border-radius:10px}ul.departures .dest{position:absolute;bottom:0;left:4em;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:#000}ul.departures .destsuffix{position:absolute;top:1px;left:6.1em;width:70%;height:1.2em;overflow:hidden}ul.departures .time{position:absolute;right:5px;top:1px;background-color:transparent;padding-left:0.2em;color:#000}ul.departures .time .delay{padding-right:1ex;color:#ff0000}ul.departures .platform{position:absolute;bottom:0;right:5px;overflow:hidden;background-color:transparent;font-size:140%;font-weight:bold;color:#000}.navbar-fixed{position:relative;z-index:997}.navbar-fixed nav{position:fixed;width:100%;box-shadow:0 2px 2px 0 rgba(0,0,0,0.14),0 3px 1px -2px rgba(0,0,0,0.12),0 1px 5px 0 rgba(0,0,0,0.2);overflow:hidden}.navbar-fixed nav a{color:#ffffff}.navbar-fixed nav .container{position:relative;height:100%}.navbar-fixed nav .main{position:absolute;display:inline-block;padding-left:0.5rem}.navbar-fixed nav ul{float:right;margin:0;padding-left:0;list-style-type:none}.navbar-fixed nav ul li{float:left;padding:0;list-style-type:none;padding-left:.8em;padding-right:.8em}.about{color:#666;margin-top:2em}@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:local("Material Icons"),local("MaterialIcons-Regular"),url(/static/v1/font/MaterialIcons-Regular.ttf) format("truetype")}.material-icons{font-family:'Material Icons';font-weight:normal;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr}@media only screen and (max-width: 600px){ul.departures>li,ul.stops>li{font-size:85%}.navbar-fixed{height:50px}nav{height:50px;line-height:50px}nav .main{font-size:120%}nav .material-icons{height:50px;line-height:50px}}@media only screen and (min-width: 600px){.navbar-fixed{height:60px}nav{height:60px;line-height:60px}nav .main{font-size:140%}nav .material-icons{height:60px;line-height:60px}} diff --git a/static/font/MaterialIcons-Regular.ttf b/static/font/MaterialIcons-Regular.ttf new file mode 100644 index 0000000..453b3e4 Binary files /dev/null and b/static/font/MaterialIcons-Regular.ttf differ diff --git a/static/js/geolocation.js b/static/js/geolocation.js new file mode 100644 index 0000000..aba8b10 --- /dev/null +++ b/static/js/geolocation.js @@ -0,0 +1,143 @@ +document.addEventListener("DOMContentLoaded", function() { + const geoLocationButton = document.getElementById('geolocationsearch'); + + const mkTextNode = function(className, textContent) { + const node = document.createElement("span"); + node.className = className; + node.textContent = textContent; + return node + } + + const processResult = function(results) { + const list = document.createElement("ul"); + list.className = "stops"; + + if (results.error) { + showError("Backend-Fehler:", results.msg); + return; + } + + for (var result in results) { + result = results[result]; + const listentry = document.createElement("li"); + const link = document.createElement("a"); + const note = document.createElement("span"); + const lines = document.createElement("span"); + + link.className = "name"; + link.textContent = result.name; + link.href = "/board/" + result.id; + + note.className = "distance"; + if (result.distance >= 1000) { + note.textContent = (result.distance / 1000).toFixed(1) + " km" + } else { + note.textContent = result.distance + " m" + } + + lines.className = "lines"; + + if (result.products.nationalExpress) { + lines.appendChild(mkTextNode("longdistance", "ICE")); + } + if (result.products.national) { + lines.appendChild(mkTextNode("longdistance", "IC")); + } + if (result.products.regionalExp) { + lines.appendChild(mkTextNode("longdistance", "RE")); + } + if (result.products.regional) { + lines.appendChild(mkTextNode("longdistance", "R")); + } + if (result.products.suburban) { + lines.appendChild(mkTextNode("suburban", "S")); + } + if (result.products.tram) { + lines.appendChild(mkTextNode("tram", "T")); + } + if (result.products.bus) { + lines.appendChild(mkTextNode("bus", "Bus")); + } + if (result.products.ferry) { + lines.appendChild(mkTextNode("bus", "Fähre")); + } + if (result.products.taxi) { + lines.appendChild(mkTextNode("taxi", "AST")); + } + + listentry.appendChild(link); + listentry.appendChild(note); + listentry.appendChild(lines); + list.appendChild(listentry); + } + geoLocationButton.replaceWith(list); + }; + + const processLocation = function(loc) { + fetch('/geolocation', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + lon: loc.coords.longitude, + lat: loc.coords.latitude + }) + }).then(response => response.json()).then(processResult); + }; + + const showError = function(header, text, code) { + const errnode = document.createElement("div"); + const errhead = document.createElement("strong"); + const errtext = document.createTextNode(text); + const errcode = document.createElement("div"); + + errnode.className = "error"; + errcode.className = "errcode"; + + errhead.textContent = header; + errcode.textContent = code; + + errnode.appendChild(errhead); + errnode.appendChild(errtext); + errnode.appendChild(errcode); + + geoLocationButton.replaceWith(errnode); + } + + const processError = function(error) { + if (error.code == error.PERMISSION_DENIED) { + showError('Standortanfrage nicht möglich.', 'Vermutlich fehlen die Rechte im Browser oder der Android Location Service ist deaktiviert.', 'geolocation.error.PERMISSION_DENIED'); + } else if (error.code == error.POSITION_UNAVAILABLE) { + showError('Standort konnte nicht ermittelt werden', 'Service nicht verfügbar', 'geolocation.error.POSITION_UNAVAILABLE'); + } else if (error.code == error.TIMEOUT) { + showError('Standort konnte nicht ermittelt werden', 'Timeout', 'geolocation.error.TIMEOUT'); + } else { + showError('Standort konnte nicht ermittelt werden', 'unbekannter Fehler', 'unknown geolocation.error code'); + } + }; + + const getGeoLocation = function() { + geoLocationButton.textContent = "Suche Haltestellen ..."; + geoLocationButton.disabled = true; + navigator.geolocation.getCurrentPosition(processLocation, processError); + } + + if (geoLocationButton) { + if (navigator.geolocation) { + if (navigator.permissions) { + navigator.permissions.query({ name:'geolocation' }).then(function(value) { + if (value.state === 'prompt') { + geoLocationButton.addEventListener('click', getGeoLocation); + } else { + getGeoLocation(); + } + }); + } else { + geoLocationButton.addEventListener('click', getGeoLocation); + } + } else { + geoLocationButton.css('visibility', 'hidden'); + } + } +}); diff --git a/static/v0 b/static/v0 new file mode 120000 index 0000000..945c9b4 --- /dev/null +++ b/static/v0 @@ -0,0 +1 @@ +. \ No newline at end of file diff --git a/static/v0/css/dark.min.css b/static/v0/css/dark.min.css deleted file mode 100644 index 0f70df4..0000000 --- a/static/v0/css/dark.min.css +++ /dev/null @@ -1 +0,0 @@ -body{margin:0;color:#fff;background-color:#101010}html{font-family:Sans-Serif}.container{max-width:60em;margin-left:auto;margin-right:auto}.textcontent{margin-left:1ex;margin-right:1ex}a{color:#99f;text-decoration:none}input,select,button{display:block;width:100%;max-width:100%;min-height:1.8em;border-radius:4px;font-size:90%;color:#fff;background-color:#101010;border:1px solid #444;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);margin-left:auto;margin-right:auto;text-align:center;vertical-align:middle;padding-top:1ex;padding-bottom:1ex;margin-top:1ex;margin-bottom:1ex}button{transition:background-color .3s;color:#fff;background-color:#337ab7;border-color:#2e6da4;cursor:pointer;box-shadow:none}button:active,button:focus,button:hover{color:#fff;background-color:#286090;border-color:#204d74}input[type="text"]{padding-left:0.5em;padding-right:0.5em;text-align:left;box-sizing:border-box}.globalnote{margin-top:1em;font-style:italic;text-align:center}.geolocation{margin-bottom:1em}.notice{padding:15px;margin-bottom:20px;border:1px solid #bce8f1;border-radius:4px;color:#31708f;background-color:#d9edf7;margin-left:auto;margin-right:auto}.warning{padding:15px;border:1px solid #faebcc;border-radius:4px;color:#8a6d3b;background-color:#fcf8e3;margin-left:auto;margin-right:auto}.warning .errcode{font-family:Monospace;margin-top:2em;font-size:100%;color:#aaaaaa}.error{padding:15px;margin-bottom:20px;border:1px solid #ebccd1;border-radius:4px;color:#a94442;background-color:#f2dede;margin-left:auto;margin-right:auto}.error strong{margin-right:.2em}.error .errcode{font-family:Monospace;margin-top:2em;font-size:100%;color:#aaaaaa}ul.stops{position:relative;width:100%;border-width:1px 2px;margin-bottom:5em;list-style-type:none;margin:0;padding:0}ul.stops a{text-decoration:none}ul.stops>li{display:block;height:4em;width:100%;position:relative;border-bottom:1px solid grey;background-color:#101010;cursor:pointer}ul.stops>li .name{position:absolute;bottom:0;left:5px;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:#fff}ul.stops>li .distance{position:absolute;top:1px;right:5px;width:30%;text-align:right;height:1.2em;overflow:hidden;opacity:50%}ul.stops>li .note{position:absolute;top:1px;left:0;width:70%;height:1.2em;overflow:hidden;opacity:50%}ul.stops>li .lines{position:absolute;bottom:0.1em;right:5px;background-color:transparent;font-weight:bold;font-size:120%}ul.stops>li .lines span{padding-left:0.1em;padding-right:0.1em;margin-left:0.2em}ul.stops>li .lines .longdistance{border:0.1em solid #7c1a1a}ul.stops>li .lines .regional{background-color:#444}ul.stops>li .lines .tram{background-color:#852121}ul.stops>li .lines .taxi{background-color:#7f3d7f;font-weight:normal}ul.stops>li .lines .suburban{background-color:#2f6639;border-radius:30px}ul.stops>li .lines .subway{background-color:#2045b0}ul.stops>li .lines .bus{background-color:#7f3d7f;border-radius:10px}ul.departures{position:relative;width:100%;border-width:1px 2px;margin-bottom:5em;list-style-type:none;margin:0;padding:0}ul.departures>li{display:block;height:3em;width:100%;position:relative;cursor:pointer;border-bottom:1px solid grey;background-color:#101010}ul.departures>li.cancelled{background-color:#ffe7d0}ul.departures .line{position:absolute;bottom:2px;left:2px;max-width:6em;max-height:3ex;max-width:5em;overflow:hidden;font-size:120%;background-color:#444;font-weight:bold;padding-left:0.1em;padding-right:0.1em}ul.departures .longdistance{border:0.1em solid #7c1a1a}ul.departures .tram{background-color:#852121}ul.departures .suburban{background-color:#2f6639;border-radius:30px}ul.departures .subway{background-color:#2045b0}ul.departures .bus{background-color:#7f3d7f;border-radius:10px}ul.departures .dest{position:absolute;bottom:0;left:4em;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:#fff}ul.departures .destsuffix{position:absolute;top:1px;left:6.1em;width:70%;height:1.2em;overflow:hidden}ul.departures .time{position:absolute;right:5px;top:1px;background-color:transparent;padding-left:0.2em;color:#fff}ul.departures .time .delay{padding-right:1ex;color:#ff0000}ul.departures .platform{position:absolute;bottom:0;right:5px;overflow:hidden;background-color:transparent;font-size:140%;font-weight:bold;color:#fff}.navbar-fixed{position:relative;z-index:997}.navbar-fixed nav{position:fixed;width:100%;box-shadow:0 2px 2px 0 rgba(0,0,0,0.14),0 3px 1px -2px rgba(0,0,0,0.12),0 1px 5px 0 rgba(0,0,0,0.2);overflow:hidden}.navbar-fixed nav a{color:#ffffff}.navbar-fixed nav .container{position:relative;height:100%}.navbar-fixed nav .main{position:absolute;display:inline-block;padding-left:0.5rem}.navbar-fixed nav ul{float:right;margin:0;padding-left:0;list-style-type:none}.navbar-fixed nav ul li{float:left;padding:0;list-style-type:none;padding-left:.8em;padding-right:.8em}.about{color:#bbb;margin-top:2em}@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:local("Material Icons"),local("MaterialIcons-Regular"),url(/static/v0/font/MaterialIcons-Regular.ttf) format("truetype")}.material-icons{font-family:'Material Icons';font-weight:normal;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr}@media only screen and (max-width: 600px){ul.departures>li,ul.stops>li{font-size:85%}.navbar-fixed{height:50px}nav{height:50px;line-height:50px}nav .main{font-size:120%}nav .material-icons{height:50px;line-height:50px}}@media only screen and (min-width: 600px){.navbar-fixed{height:60px}nav{height:60px;line-height:60px}nav .main{font-size:140%}nav .material-icons{height:60px;line-height:60px}} diff --git a/static/v0/css/light.min.css b/static/v0/css/light.min.css deleted file mode 100644 index bd81374..0000000 --- a/static/v0/css/light.min.css +++ /dev/null @@ -1 +0,0 @@ -body{margin:0;color:#000;background-color:#fff}html{font-family:Sans-Serif}.container{max-width:60em;margin-left:auto;margin-right:auto}.textcontent{margin-left:1ex;margin-right:1ex}a{color:#009;text-decoration:none}input,select,button{display:block;width:100%;max-width:100%;min-height:1.8em;border-radius:4px;font-size:90%;color:#000;background-color:#fff;border:1px solid #ccc;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);margin-left:auto;margin-right:auto;text-align:center;vertical-align:middle;padding-top:1ex;padding-bottom:1ex;margin-top:1ex;margin-bottom:1ex}button{transition:background-color .3s;color:#fff;background-color:#337ab7;border-color:#2e6da4;cursor:pointer;box-shadow:none}button:active,button:focus,button:hover{color:#fff;background-color:#286090;border-color:#204d74}input[type="text"]{padding-left:0.5em;padding-right:0.5em;text-align:left;box-sizing:border-box}.globalnote{margin-top:1em;font-style:italic;text-align:center}.geolocation{margin-bottom:1em}.notice{padding:15px;margin-bottom:20px;border:1px solid #bce8f1;border-radius:4px;color:#31708f;background-color:#d9edf7;margin-left:auto;margin-right:auto}.warning{padding:15px;border:1px solid #faebcc;border-radius:4px;color:#8a6d3b;background-color:#fcf8e3;margin-left:auto;margin-right:auto}.warning .errcode{font-family:Monospace;margin-top:2em;font-size:100%;color:#aaaaaa}.error{padding:15px;margin-bottom:20px;border:1px solid #ebccd1;border-radius:4px;color:#a94442;background-color:#f2dede;margin-left:auto;margin-right:auto}.error strong{margin-right:.2em}.error .errcode{font-family:Monospace;margin-top:2em;font-size:100%;color:#aaaaaa}ul.stops{position:relative;width:100%;border-width:1px 2px;margin-bottom:5em;list-style-type:none;margin:0;padding:0}ul.stops a{text-decoration:none}ul.stops>li{display:block;height:4em;width:100%;position:relative;border-bottom:1px solid grey;background-color:#fff;cursor:pointer}ul.stops>li .name{position:absolute;bottom:0;left:5px;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:#000}ul.stops>li .distance{position:absolute;top:1px;right:5px;width:30%;text-align:right;height:1.2em;overflow:hidden;opacity:50%}ul.stops>li .note{position:absolute;top:1px;left:0;width:70%;height:1.2em;overflow:hidden;opacity:50%}ul.stops>li .lines{position:absolute;bottom:0.1em;right:5px;background-color:transparent;font-weight:bold;font-size:120%}ul.stops>li .lines span{padding-left:0.1em;padding-right:0.1em;margin-left:0.2em}ul.stops>li .lines .longdistance{border:0.1em solid #fcc}ul.stops>li .lines .regional{background-color:#eee}ul.stops>li .lines .tram{background-color:#fcc}ul.stops>li .lines .taxi{background-color:#eae;font-weight:normal}ul.stops>li .lines .suburban{background-color:#aaffba;border-radius:30px}ul.stops>li .lines .subway{background-color:#aac0ff}ul.stops>li .lines .bus{background-color:#eae;border-radius:10px}ul.departures{position:relative;width:100%;border-width:1px 2px;margin-bottom:5em;list-style-type:none;margin:0;padding:0}ul.departures>li{display:block;height:3em;width:100%;position:relative;cursor:pointer;border-bottom:1px solid grey;background-color:#fff}ul.departures>li.cancelled{background-color:#ffe7d0}ul.departures .line{position:absolute;bottom:2px;left:2px;max-width:6em;max-height:3ex;max-width:5em;overflow:hidden;font-size:120%;background-color:#eee;font-weight:bold;padding-left:0.1em;padding-right:0.1em}ul.departures .longdistance{border:0.1em solid #fcc}ul.departures .tram{background-color:#fcc}ul.departures .suburban{background-color:#aaffba;border-radius:30px}ul.departures .subway{background-color:#aac0ff}ul.departures .bus{background-color:#eae;border-radius:10px}ul.departures .dest{position:absolute;bottom:0;left:4em;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:#000}ul.departures .destsuffix{position:absolute;top:1px;left:6.1em;width:70%;height:1.2em;overflow:hidden}ul.departures .time{position:absolute;right:5px;top:1px;background-color:transparent;padding-left:0.2em;color:#000}ul.departures .time .delay{padding-right:1ex;color:#ff0000}ul.departures .platform{position:absolute;bottom:0;right:5px;overflow:hidden;background-color:transparent;font-size:140%;font-weight:bold;color:#000}.navbar-fixed{position:relative;z-index:997}.navbar-fixed nav{position:fixed;width:100%;box-shadow:0 2px 2px 0 rgba(0,0,0,0.14),0 3px 1px -2px rgba(0,0,0,0.12),0 1px 5px 0 rgba(0,0,0,0.2);overflow:hidden}.navbar-fixed nav a{color:#ffffff}.navbar-fixed nav .container{position:relative;height:100%}.navbar-fixed nav .main{position:absolute;display:inline-block;padding-left:0.5rem}.navbar-fixed nav ul{float:right;margin:0;padding-left:0;list-style-type:none}.navbar-fixed nav ul li{float:left;padding:0;list-style-type:none;padding-left:.8em;padding-right:.8em}.about{color:#666;margin-top:2em}@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:local("Material Icons"),local("MaterialIcons-Regular"),url(/static/v0/font/MaterialIcons-Regular.ttf) format("truetype")}.material-icons{font-family:'Material Icons';font-weight:normal;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr}@media only screen and (max-width: 600px){ul.departures>li,ul.stops>li{font-size:85%}.navbar-fixed{height:50px}nav{height:50px;line-height:50px}nav .main{font-size:120%}nav .material-icons{height:50px;line-height:50px}}@media only screen and (min-width: 600px){.navbar-fixed{height:60px}nav{height:60px;line-height:60px}nav .main{font-size:140%}nav .material-icons{height:60px;line-height:60px}} diff --git a/static/v0/font/MaterialIcons-Regular.ttf b/static/v0/font/MaterialIcons-Regular.ttf deleted file mode 100644 index 453b3e4..0000000 Binary files a/static/v0/font/MaterialIcons-Regular.ttf and /dev/null differ diff --git a/static/v0/js/geolocation.js b/static/v0/js/geolocation.js deleted file mode 100644 index aba8b10..0000000 --- a/static/v0/js/geolocation.js +++ /dev/null @@ -1,143 +0,0 @@ -document.addEventListener("DOMContentLoaded", function() { - const geoLocationButton = document.getElementById('geolocationsearch'); - - const mkTextNode = function(className, textContent) { - const node = document.createElement("span"); - node.className = className; - node.textContent = textContent; - return node - } - - const processResult = function(results) { - const list = document.createElement("ul"); - list.className = "stops"; - - if (results.error) { - showError("Backend-Fehler:", results.msg); - return; - } - - for (var result in results) { - result = results[result]; - const listentry = document.createElement("li"); - const link = document.createElement("a"); - const note = document.createElement("span"); - const lines = document.createElement("span"); - - link.className = "name"; - link.textContent = result.name; - link.href = "/board/" + result.id; - - note.className = "distance"; - if (result.distance >= 1000) { - note.textContent = (result.distance / 1000).toFixed(1) + " km" - } else { - note.textContent = result.distance + " m" - } - - lines.className = "lines"; - - if (result.products.nationalExpress) { - lines.appendChild(mkTextNode("longdistance", "ICE")); - } - if (result.products.national) { - lines.appendChild(mkTextNode("longdistance", "IC")); - } - if (result.products.regionalExp) { - lines.appendChild(mkTextNode("longdistance", "RE")); - } - if (result.products.regional) { - lines.appendChild(mkTextNode("longdistance", "R")); - } - if (result.products.suburban) { - lines.appendChild(mkTextNode("suburban", "S")); - } - if (result.products.tram) { - lines.appendChild(mkTextNode("tram", "T")); - } - if (result.products.bus) { - lines.appendChild(mkTextNode("bus", "Bus")); - } - if (result.products.ferry) { - lines.appendChild(mkTextNode("bus", "Fähre")); - } - if (result.products.taxi) { - lines.appendChild(mkTextNode("taxi", "AST")); - } - - listentry.appendChild(link); - listentry.appendChild(note); - listentry.appendChild(lines); - list.appendChild(listentry); - } - geoLocationButton.replaceWith(list); - }; - - const processLocation = function(loc) { - fetch('/geolocation', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - lon: loc.coords.longitude, - lat: loc.coords.latitude - }) - }).then(response => response.json()).then(processResult); - }; - - const showError = function(header, text, code) { - const errnode = document.createElement("div"); - const errhead = document.createElement("strong"); - const errtext = document.createTextNode(text); - const errcode = document.createElement("div"); - - errnode.className = "error"; - errcode.className = "errcode"; - - errhead.textContent = header; - errcode.textContent = code; - - errnode.appendChild(errhead); - errnode.appendChild(errtext); - errnode.appendChild(errcode); - - geoLocationButton.replaceWith(errnode); - } - - const processError = function(error) { - if (error.code == error.PERMISSION_DENIED) { - showError('Standortanfrage nicht möglich.', 'Vermutlich fehlen die Rechte im Browser oder der Android Location Service ist deaktiviert.', 'geolocation.error.PERMISSION_DENIED'); - } else if (error.code == error.POSITION_UNAVAILABLE) { - showError('Standort konnte nicht ermittelt werden', 'Service nicht verfügbar', 'geolocation.error.POSITION_UNAVAILABLE'); - } else if (error.code == error.TIMEOUT) { - showError('Standort konnte nicht ermittelt werden', 'Timeout', 'geolocation.error.TIMEOUT'); - } else { - showError('Standort konnte nicht ermittelt werden', 'unbekannter Fehler', 'unknown geolocation.error code'); - } - }; - - const getGeoLocation = function() { - geoLocationButton.textContent = "Suche Haltestellen ..."; - geoLocationButton.disabled = true; - navigator.geolocation.getCurrentPosition(processLocation, processError); - } - - if (geoLocationButton) { - if (navigator.geolocation) { - if (navigator.permissions) { - navigator.permissions.query({ name:'geolocation' }).then(function(value) { - if (value.state === 'prompt') { - geoLocationButton.addEventListener('click', getGeoLocation); - } else { - getGeoLocation(); - } - }); - } else { - geoLocationButton.addEventListener('click', getGeoLocation); - } - } else { - geoLocationButton.css('visibility', 'hidden'); - } - } -}); diff --git a/static/v1 b/static/v1 new file mode 120000 index 0000000..945c9b4 --- /dev/null +++ b/static/v1 @@ -0,0 +1 @@ +. \ No newline at end of file diff --git a/templates/header.html b/templates/header.html index 1bf6219..7480bea 100644 --- a/templates/header.html +++ b/templates/header.html @@ -10,11 +10,11 @@ - + + {% include 'navbar.html' %} -- cgit v1.2.3