From 00bcc7c2aa211aed0053dcc6a09aa6d2a476b9ab Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sun, 27 Jun 2021 20:28:28 +0200 Subject: add navbar --- bin/nvm | 23 ++++-- sass/app.scss | 117 ++++++++++++++++++++++++++++++- static/v0/css/dark.min.css | 2 +- static/v0/css/light.min.css | 2 +- static/v0/font/MaterialIcons-Regular.ttf | Bin 0 -> 285724 bytes static/v0/js/geolocation.js | 2 +- templates/departure_list.html | 6 ++ templates/landing_page.html | 3 +- templates/navbar.html | 17 +++++ templates/stops.html | 1 + 10 files changed, 164 insertions(+), 9 deletions(-) create mode 100644 static/v0/font/MaterialIcons-Regular.ttf create mode 100644 templates/navbar.html diff --git a/bin/nvm b/bin/nvm index 81289b8..c4c0a10 100755 --- a/bin/nvm +++ b/bin/nvm @@ -41,6 +41,12 @@ class Departure: self.classes = str() + self.station_name = None + self.stop_name = None + + self.stop_name = obj.get("stop", dict()).get("name", None) + self.station_name = obj.get("station", dict()).get("name", self.stop_name) + if "," in self.direction: self.direction, self.suffix = self.direction.split(",", maxsplit=1) else: @@ -117,13 +123,22 @@ async def show_departure_board(request): departures = list(map(Departure, departures)) + station_name_freq = dict() now = datetime.now().timestamp() for departure in departures: departure.set_relative(now) + station_name_freq[departure.station_name] = ( + station_name_freq.get(departure.station_name, 0) + 1 + ) + + if station_name_freq: + station_name = max(station_name_freq.keys(), key=lambda k: station_name_freq[k]) + else: + station_name = "NVM" departure_board = env.get_template("departure_list.html") return web.Response( - body=departure_board.render(title="Noot", departures=departures), + body=departure_board.render(title=station_name, departures=departures), headers=headers, ) @@ -137,7 +152,7 @@ async def redirect_to_departure_board(request): stops = await response.json() stops_page = env.get_template("stops.html") return web.Response( - body=stops_page.render(title="Noot", stops=stops), + body=stops_page.render(title=f"Suche nach „{stop_name}“", stops=stops), headers=headers, ) @@ -145,7 +160,7 @@ async def redirect_to_departure_board(request): async def show_landing_page(request): landing_page = env.get_template("landing_page.html") return web.Response( - body=landing_page.render(title="Noot"), + body=landing_page.render(title="NVM"), headers=headers, ) @@ -156,7 +171,7 @@ async def ajax_geolocation(request): lon = request_data["lon"] async with aiohttp.ClientSession() as session: async with session.get( - f"{db_rest_api}/stops/nearby?latitude={lat}&longitude={lon}&linesOfStops=true" + f"{db_rest_api}/stops/nearby?latitude={lat}&longitude={lon}" ) as response: departures = await response.json() return web.Response( diff --git a/sass/app.scss b/sass/app.scss index 4b01bf5..51fea67 100644 --- a/sass/app.scss +++ b/sass/app.scss @@ -14,6 +14,15 @@ html { margin-right: auto; } +.globalnote { + margin-top: 1em; + font-style: italic; + text-align: center; +} + +.geolocation { + margin-bottom: 1em; +} ul.stops { position:relative; @@ -42,7 +51,7 @@ ul.stops { .name { position: absolute; bottom: 0; - left: 0; + left: 5px; width: 70%; overflow: hidden; background-color: transparent; @@ -50,6 +59,18 @@ ul.stops { color: black; } + .distance { + position: absolute; + top: 1px; + right: 5px; + width: 30%; + text-align: right; + height: 1.2em; + overflow: hidden; + opacity: 50%; + } + + .note { position: absolute; top: 1px; @@ -217,12 +238,106 @@ ul.departures { } } +.navbar-fixed { + position: relative; + z-index: 997; + + nav { + position: fixed; + width: 100%; + box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.12), 0 1px 5px 0 rgba(0,0,0,.2); + overflow: hidden; + + a { + color: #ffffff; + } + + .container { + position: relative; + height: 100%; + } + + .main { + position: absolute; + display: inline-block; + padding-left: 0.5rem; + } + + ul { + float: right; + margin: 0; + padding-left: 0; + list-style-type: none; + + li { + float: left; + padding: 0; + list-style-type: none; + padding-left: .8em; + padding-right: .8em; + } + } + } +} + +@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; + .main { + font-size: 120%; + } + .material-icons { + height: 50px; + line-height: 50px; + } + } } @media only screen and (min-width: 600px) { + .navbar-fixed { + height: 60px; + } + nav { + height: 60px; + line-height: 60px; + .main { + font-size: 140%; + } + .material-icons { + height: 60px; + line-height: 60px; + } + } } diff --git a/static/v0/css/dark.min.css b/static/v0/css/dark.min.css index abc810b..2822abb 100644 --- a/static/v0/css/dark.min.css +++ b/static/v0/css/dark.min.css @@ -1 +1 @@ -body{margin:0;color:black;background-color:white}html{font-family:Sans-Serif}.container{max-width:60em;margin-left:auto;margin-right:auto}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:white;cursor:pointer}ul.stops>li .name{position:absolute;bottom:0;left:0;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:black}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 #ffcccc}ul.stops>li .lines .regional{background-color:#eeeeee}ul.stops>li .lines .tram{background-color:#ffcccc}ul.stops>li .lines .taxi{background-color:#eeaaee;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:#eeaaee;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:white}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:#eeeeee;font-weight:bold;padding-left:0.1em;padding-right:0.1em}ul.departures .longdistance{border:0.1em solid #ffcccc}ul.departures .tram{background-color:#ffcccc}ul.departures .suburban{background-color:#aaffba;border-radius:30px}ul.departures .subway{background-color:#aac0ff}ul.departures .bus{background-color:#eeaaee;border-radius:10px}ul.departures .dest{position:absolute;bottom:0;left:4em;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:black}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:black}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:black}@media only screen and (max-width: 600px){ul.departures>li,ul.stops>li{font-size:85%}} +body{margin:0;color:black;background-color:white}html{font-family:Sans-Serif}.container{max-width:60em;margin-left:auto;margin-right:auto}.globalnote{margin-top:1em;font-style:italic;text-align:center}.geolocation{margin-bottom:1em}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:white;cursor:pointer}ul.stops>li .name{position:absolute;bottom:0;left:5px;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:black}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 #ffcccc}ul.stops>li .lines .regional{background-color:#eeeeee}ul.stops>li .lines .tram{background-color:#ffcccc}ul.stops>li .lines .taxi{background-color:#eeaaee;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:#eeaaee;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:white}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:#eeeeee;font-weight:bold;padding-left:0.1em;padding-right:0.1em}ul.departures .longdistance{border:0.1em solid #ffcccc}ul.departures .tram{background-color:#ffcccc}ul.departures .suburban{background-color:#aaffba;border-radius:30px}ul.departures .subway{background-color:#aac0ff}ul.departures .bus{background-color:#eeaaee;border-radius:10px}ul.departures .dest{position:absolute;bottom:0;left:4em;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:black}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:black}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:black}.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}@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 index abc810b..2822abb 100644 --- a/static/v0/css/light.min.css +++ b/static/v0/css/light.min.css @@ -1 +1 @@ -body{margin:0;color:black;background-color:white}html{font-family:Sans-Serif}.container{max-width:60em;margin-left:auto;margin-right:auto}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:white;cursor:pointer}ul.stops>li .name{position:absolute;bottom:0;left:0;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:black}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 #ffcccc}ul.stops>li .lines .regional{background-color:#eeeeee}ul.stops>li .lines .tram{background-color:#ffcccc}ul.stops>li .lines .taxi{background-color:#eeaaee;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:#eeaaee;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:white}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:#eeeeee;font-weight:bold;padding-left:0.1em;padding-right:0.1em}ul.departures .longdistance{border:0.1em solid #ffcccc}ul.departures .tram{background-color:#ffcccc}ul.departures .suburban{background-color:#aaffba;border-radius:30px}ul.departures .subway{background-color:#aac0ff}ul.departures .bus{background-color:#eeaaee;border-radius:10px}ul.departures .dest{position:absolute;bottom:0;left:4em;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:black}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:black}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:black}@media only screen and (max-width: 600px){ul.departures>li,ul.stops>li{font-size:85%}} +body{margin:0;color:black;background-color:white}html{font-family:Sans-Serif}.container{max-width:60em;margin-left:auto;margin-right:auto}.globalnote{margin-top:1em;font-style:italic;text-align:center}.geolocation{margin-bottom:1em}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:white;cursor:pointer}ul.stops>li .name{position:absolute;bottom:0;left:5px;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:black}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 #ffcccc}ul.stops>li .lines .regional{background-color:#eeeeee}ul.stops>li .lines .tram{background-color:#ffcccc}ul.stops>li .lines .taxi{background-color:#eeaaee;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:#eeaaee;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:white}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:#eeeeee;font-weight:bold;padding-left:0.1em;padding-right:0.1em}ul.departures .longdistance{border:0.1em solid #ffcccc}ul.departures .tram{background-color:#ffcccc}ul.departures .suburban{background-color:#aaffba;border-radius:30px}ul.departures .subway{background-color:#aac0ff}ul.departures .bus{background-color:#eeaaee;border-radius:10px}ul.departures .dest{position:absolute;bottom:0;left:4em;width:70%;overflow:hidden;background-color:transparent;font-size:150%;color:black}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:black}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:black}.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}@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 new file mode 100644 index 0000000..453b3e4 Binary files /dev/null and b/static/v0/font/MaterialIcons-Regular.ttf differ diff --git a/static/v0/js/geolocation.js b/static/v0/js/geolocation.js index 4e868b0..acf672a 100644 --- a/static/v0/js/geolocation.js +++ b/static/v0/js/geolocation.js @@ -22,7 +22,7 @@ document.addEventListener("DOMContentLoaded", function() { link.textContent = result.name; link.href = "/board/" + result.id; - note.className = "note"; + note.className = "distance"; if (result.distance >= 1000) { note.textContent = result.distance.toFixed(1) + " km" } else { diff --git a/templates/departure_list.html b/templates/departure_list.html index a82e7c3..dea886c 100644 --- a/templates/departure_list.html +++ b/templates/departure_list.html @@ -5,8 +5,14 @@ {% include 'header.html' %} + +{% include 'navbar.html' %} +
+ {% if not departures %} +
Keine Abfahrten innerhalb der nächsten zwei Stunden
+ {% endif %}
    {% for departure in departures %}
  • diff --git a/templates/landing_page.html b/templates/landing_page.html index c89da47..c5a04fd 100644 --- a/templates/landing_page.html +++ b/templates/landing_page.html @@ -6,14 +6,15 @@ +{% include 'navbar.html' %}
    + - diff --git a/templates/navbar.html b/templates/navbar.html new file mode 100644 index 0000000..0b2908e --- /dev/null +++ b/templates/navbar.html @@ -0,0 +1,17 @@ + diff --git a/templates/stops.html b/templates/stops.html index affac69..5c47014 100644 --- a/templates/stops.html +++ b/templates/stops.html @@ -5,6 +5,7 @@ {% include 'header.html' %} +{% include 'navbar.html' %}
      -- cgit v1.2.3