diff --git a/src/c3nav/locale/de/LC_MESSAGES/django.po b/src/c3nav/locale/de/LC_MESSAGES/django.po index 8e61af35..55dadc24 100644 --- a/src/c3nav/locale/de/LC_MESSAGES/django.po +++ b/src/c3nav/locale/de/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-12-23 17:06+0100\n" +"POT-Creation-Date: 2019-12-24 03:50+0100\n" "PO-Revision-Date: 2019-12-22 00:44+0100\n" "Last-Translator: Jenny Danzmayr \n" "Language-Team: \n" @@ -556,9 +556,10 @@ msgstr "Zugangs­beschränkung" #: c3nav/control/templates/control/user.html:145 #: c3nav/editor/templates/editor/fragment_changesets.html:10 #: c3nav/editor/templates/editor/list.html:26 -#: c3nav/site/templates/site/map.html:90 c3nav/site/templates/site/map.html:124 -#: c3nav/site/templates/site/map.html:136 -#: c3nav/site/templates/site/map.html:142 +#: c3nav/site/templates/site/map.html:100 +#: c3nav/site/templates/site/map.html:134 +#: c3nav/site/templates/site/map.html:143 +#: c3nav/site/templates/site/map.html:164 msgid "Details" msgstr "Details" @@ -1490,12 +1491,12 @@ msgstr "Du hast direktes Bearbeiten aktiviert." msgid "You deactivated direct editing." msgstr "Du hast direktes Bearbeiten deaktiviert." -#: c3nav/mapdata/api.py:201 +#: c3nav/mapdata/api.py:202 #, python-format msgid "%(field)s is not an integer." msgstr "%(field)s ist keine ganze Zahl." -#: c3nav/mapdata/api.py:209 +#: c3nav/mapdata/api.py:210 #, python-format msgid "%(model)s not found." msgstr "%(model)s nicht gefunden." @@ -1844,12 +1845,12 @@ msgstr "" "Höhenmarker #%(marker_id)d in Raum #%(space_id)d auf Etage %(level_label)s " "ist nicht in einem begehbaren Bereich platziert" -#: c3nav/mapdata/models/geometry/level.py:639 +#: c3nav/mapdata/models/geometry/level.py:624 #, python-format msgid "%d altitude areas built." msgstr "%d Höhenbereiche gebaut." -#: c3nav/mapdata/models/geometry/level.py:640 +#: c3nav/mapdata/models/geometry/level.py:625 #, python-format msgid "" "%(num_modified)d modified, %(num_deleted)d deleted, %(num_created)d created." @@ -1916,7 +1917,6 @@ msgstr "Rampen" #: c3nav/mapdata/models/geometry/space.py:173 #: c3nav/mapdata/models/geometry/space.py:205 -#, fuzzy msgid "altitude above ground" msgstr "Höhe über Grund" @@ -2396,19 +2396,19 @@ msgstr[1] "%d freigeschaltete Bereiche" msgid "Login" msgstr "Anmelden" -#: c3nav/routing/api.py:49 +#: c3nav/routing/api.py:50 msgid "Not yet routable, try again shortly." msgstr "Noch nicht routebar, bitte einige Minuten warten." -#: c3nav/routing/api.py:53 +#: c3nav/routing/api.py:54 msgid "Unreachable location." msgstr "Unerreichbarer Ort." -#: c3nav/routing/api.py:57 +#: c3nav/routing/api.py:58 msgid "No route found." msgstr "Keine Route gefunden." -#: c3nav/routing/api.py:103 +#: c3nav/routing/api.py:110 msgid "Invalid scan data." msgstr "Invalide Scandaten." @@ -2456,65 +2456,65 @@ msgstr "Invalider Scan. Unerlaubte Frequenz." msgid "Invalid Scan. Invalid last timestamp." msgstr "Invalider Scan. Letzter Zeitstempel ungültig." -#: c3nav/routing/models.py:20 c3nav/routing/models.py:21 -#: c3nav/site/templates/site/map.html:149 +#: c3nav/routing/models.py:21 c3nav/routing/models.py:22 +#: c3nav/site/templates/site/map.html:177 msgid "Route options" msgstr "Routenoptionen" -#: c3nav/routing/models.py:32 +#: c3nav/routing/models.py:33 msgid "Routing mode" msgstr "Routemodus" -#: c3nav/routing/models.py:33 +#: c3nav/routing/models.py:34 msgid "fastest" msgstr "schnellste" -#: c3nav/routing/models.py:33 +#: c3nav/routing/models.py:34 msgid "shortest" msgstr "kürzeste" -#: c3nav/routing/models.py:37 +#: c3nav/routing/models.py:38 msgid "Walk speed" msgstr "Gehgeschwindigkeit" -#: c3nav/routing/models.py:38 +#: c3nav/routing/models.py:39 msgid "slow" msgstr "langsam" -#: c3nav/routing/models.py:38 +#: c3nav/routing/models.py:39 msgid "default" msgstr "standard" -#: c3nav/routing/models.py:38 +#: c3nav/routing/models.py:39 msgid "fast" msgstr "schnell" -#: c3nav/routing/models.py:44 +#: c3nav/routing/models.py:45 msgid "allow" msgstr "erlaubt" -#: c3nav/routing/models.py:46 +#: c3nav/routing/models.py:47 msgid "avoid upwards" msgstr "aufwärts vermeiden" -#: c3nav/routing/models.py:47 +#: c3nav/routing/models.py:48 msgid "avoid downwards" msgstr "abwärts vermeiden" -#: c3nav/routing/models.py:48 +#: c3nav/routing/models.py:49 msgid "avoid completely" msgstr "komplett vermeiden" -#: c3nav/routing/models.py:50 +#: c3nav/routing/models.py:51 msgid "avoid" msgstr "vermeiden" -#: c3nav/routing/models.py:143 +#: c3nav/routing/models.py:144 #, python-format msgid "Unknown route option: %s" msgstr "Unbekannte Routenoption: %s" -#: c3nav/routing/models.py:147 +#: c3nav/routing/models.py:148 #, python-format msgid "Invalid value for route option %s." msgstr "Invalider Wert für Routenoption %s." @@ -2549,11 +2549,11 @@ msgstr "einige Wegtypen vermieden" msgid "default options" msgstr "Standardoptionen" -#: c3nav/settings.py:305 +#: c3nav/settings.py:304 msgid "English" msgstr "Englisch" -#: c3nav/settings.py:306 +#: c3nav/settings.py:305 msgid "German" msgstr "Deutsch" @@ -2682,8 +2682,8 @@ msgstr "über c3nav" msgid "Select" msgstr "Auswählen" -#: c3nav/site/templates/site/map.html:40 c3nav/site/templates/site/map.html:51 -#: c3nav/site/templates/site/map.html:94 +#: c3nav/site/templates/site/map.html:40 c3nav/site/templates/site/map.html:61 +#: c3nav/site/templates/site/map.html:104 msgid "Share" msgstr "Teilen" @@ -2695,57 +2695,67 @@ msgstr "Route hierhin" msgid "Route from here" msgstr "Route von hier aus" -#: c3nav/site/templates/site/map.html:55 +#: c3nav/site/templates/site/map.html:52 c3nav/site/templates/site/map.html:149 +#: c3nav/site/templates/site/map.html:170 +msgid "Report issue" +msgstr "Fehler melden" + +#: c3nav/site/templates/site/map.html:56 c3nav/site/templates/site/map.html:153 +#| msgid "Select this location" +msgid "Report missing location" +msgstr "Fehlenden Ort melden" + +#: c3nav/site/templates/site/map.html:65 msgid "share" msgstr "Teilen" -#: c3nav/site/templates/site/map.html:56 +#: c3nav/site/templates/site/map.html:66 msgid "create shortcut" msgstr "Verknüpfung anlegen" -#: c3nav/site/templates/site/map.html:60 +#: c3nav/site/templates/site/map.html:70 msgid "Wifi-based location" msgstr "WLAN-basierte Ortung" -#: c3nav/site/templates/site/map.html:61 +#: c3nav/site/templates/site/map.html:71 msgid "Get the c3nav app for Android to see your location on the map." msgstr "" "Hole dir die c3nav-App für Android um deine Position auf der Karte zu sehen." -#: c3nav/site/templates/site/map.html:64 +#: c3nav/site/templates/site/map.html:74 msgid "Download APK" msgstr "APK herunterladen" -#: c3nav/site/templates/site/map.html:74 c3nav/site/templates/site/map.html:81 +#: c3nav/site/templates/site/map.html:84 c3nav/site/templates/site/map.html:91 msgid "Search any location…" msgstr "Suche einen beliebigen Ort…" -#: c3nav/site/templates/site/map.html:98 +#: c3nav/site/templates/site/map.html:108 msgid "Route" msgstr "Route" -#: c3nav/site/templates/site/map.html:110 #: c3nav/site/templates/site/map.html:120 +#: c3nav/site/templates/site/map.html:130 msgid "Swap" msgstr "Vertauschen" -#: c3nav/site/templates/site/map.html:114 +#: c3nav/site/templates/site/map.html:124 msgid "Close" msgstr "Schließen" -#: c3nav/site/templates/site/map.html:134 +#: c3nav/site/templates/site/map.html:157 msgid "Open in Editor" msgstr "Im Editor öffnen" -#: c3nav/site/templates/site/map.html:154 +#: c3nav/site/templates/site/map.html:182 msgid "Save and reroute" msgstr "Speichern und neu routen" -#: c3nav/site/templates/site/map.html:155 +#: c3nav/site/templates/site/map.html:183 msgid "Just reroute" msgstr "Nur neu routen" -#: c3nav/site/templates/site/map.html:164 +#: c3nav/site/templates/site/map.html:192 #, python-format msgid "" "Get the c3nav Android app on Google Play oder downloade " "die APK!" -#: c3nav/site/templates/site/map.html:169 +#: c3nav/site/templates/site/map.html:197 msgid "open in c3nav" msgstr "in c3nav öffnen" +#: c3nav/site/templates/site/report.html:6 +msgid "Coming soon" +msgstr "Coming soon" + #: c3nav/site/views.py:71 c3nav/site/views.py:318 msgid "You need to log in to unlock areas." msgstr "Du musst dich anmelden um Bereiche freizuschalten." @@ -2792,9 +2806,6 @@ msgstr[1] "Du wurdest eingeladen, die folgenden Bereiche freizuschalten:" #~ msgid "You can not edit this object." #~ msgstr "Du kannst dieses Objekt nicht bearbeiten." -#~ msgid "Select this location" -#~ msgstr "Diesen Ort auswählen" - #~ msgid "Get the c3nav Android app!" #~ msgstr "Hol' dir die c3nav Android-App!" diff --git a/src/c3nav/routing/api.py b/src/c3nav/routing/api.py index b914420b..1f188ffc 100644 --- a/src/c3nav/routing/api.py +++ b/src/c3nav/routing/api.py @@ -1,4 +1,5 @@ from django.core.exceptions import ValidationError +from django.urls import reverse from django.utils.translation import ugettext_lazy as _ from rest_framework.decorators import action from rest_framework.response import Response @@ -74,6 +75,11 @@ class RoutingViewSet(ViewSet): 'destination': form.cleaned_data['destination'].pk, }, 'options': options.serialize(), + 'report_issue_url': reverse('site.report', kwargs={ + 'origin': request.POST['origin'], + 'destination': request.POST['destination'], + 'options': options.serialize_string() + }), 'result': route.serialize(locations=visible_locations_for_request(request)), }) diff --git a/src/c3nav/routing/models.py b/src/c3nav/routing/models.py index 3aecbfd1..65bea5da 100644 --- a/src/c3nav/routing/models.py +++ b/src/c3nav/routing/models.py @@ -178,6 +178,9 @@ class RouteOptions(models.Model): for name, field in self.get_fields().items() ] + def serialize_string(self): + return ','.join('%s=%s' % (key, val) for key, val in self.data.items()) + def save(self, *args, **kwargs): if self.request is None or self.request.user.is_authenticated: self.user = self.request.user diff --git a/src/c3nav/routing/router.py b/src/c3nav/routing/router.py index bf648437..6e1fca55 100644 --- a/src/c3nav/routing/router.py +++ b/src/c3nav/routing/router.py @@ -1,4 +1,3 @@ -import json import logging import operator import os @@ -375,7 +374,7 @@ class Router: areas=areas, near_area=near_area, near_poi=near_poi) def shortest_path(self, restrictions, options): - options_key = json.dumps(options.data, separators=(',', '='), sort_keys=True)[1:-1] + options_key = options.serialize_string() cache_key = 'router:shortest_path:%s:%s:%s' % (MapUpdate.current_processed_cache_key(), restrictions.cache_key, options_key) diff --git a/src/c3nav/site/static/site/css/c3nav.scss b/src/c3nav/site/static/site/css/c3nav.scss index 7ca01b40..b481f79e 100644 --- a/src/c3nav/site/static/site/css/c3nav.scss +++ b/src/c3nav/site/static/site/css/c3nav.scss @@ -379,10 +379,12 @@ section.details { opacity: 0; line-height: 2; } -#sidebar section.details.loading > .details-body { +#sidebar section.details.loading > .details-body, +#sidebar section.details.loading > .details-buttons { max-height: 0; opacity: 0; } + #sidebar section.details:not(.loading) > .details-head { -webkit-transition: background-color 50ms; -o-transition: background-color 50ms; @@ -396,7 +398,8 @@ section.details { pointer-events: auto; opacity: 1; } -#sidebar section.details:not(.loading) > div.details-body { +#sidebar section.details:not(.loading) > div.details-body, +#sidebar section.details:not(.loading) > div.details-buttons { max-height: 100vh; -webkit-transition: max-height 150ms, opacity 50ms; -o-transition: max-height 150ms, opacity 50ms; @@ -745,18 +748,19 @@ main:not([data-view=route-result]) #route-dots { .buttons { border: 0 #dddddd solid; border-top-width: 1px; + .button-clear { + display:block; + width: 100%; + padding: 0 7px; + margin: 0; + line-height: 3.3rem; + } } .location { margin-right: 24px; padding-right: 0; overflow: hidden; } - .button-clear { - display:block; - width: 100%; - padding: 0 7px; - margin: 0; - } .as-location .material-icons { transform: rotate(-45deg); } diff --git a/src/c3nav/site/static/site/js/c3nav.js b/src/c3nav/site/static/site/js/c3nav.js index 95f420b3..7efe6ed9 100644 --- a/src/c3nav/site/static/site/js/c3nav.js +++ b/src/c3nav/site/static/site/js/c3nav.js @@ -193,7 +193,7 @@ c3nav = { .on('submit', 'form', c3nav._modal_submit) .on('click', '.mobileclient-share', c3nav._mobileclient_share_click) .on('click', '.mobileclient-shortcut', c3nav._mobileclient_shortcut_click); - $('header #user, #about-link').on('click', c3nav._modal_link_click); + $('header #user, #about-link, .buttons a').on('click', c3nav._modal_link_click); $('header h1 a').removeAttr('href'); @@ -351,13 +351,13 @@ c3nav = { var $location_details = $('#location-details'); if ($location_details.attr('data-id') !== String(location.id)) { $location_details.addClass('loading').attr('data-id', location.id); - $location_details.find('.details-buttons').hide(); c3nav._clear_route_layers(); $.getJSON('/api/locations/'+location.id+'/details', c3nav._location_details_loaded).fail(function (data) { var $location_details = $('#location-details'); $location_details.find('.details-body').text('Error '+String(data.status)); $location_details.find('.details-body').html('').append(elem); $location_details.find('.editor').hide(); + $location_details.find('.report').hide(); $location_details.removeClass('loading'); }); } @@ -394,7 +394,6 @@ c3nav = { elem.append(loclist); } } - $location_details.find('.details-buttons').show(); $location_details.find('.details-body').html('').append(elem); var $editor = $location_details.find('.editor'); @@ -404,6 +403,12 @@ c3nav = { $editor.hide(); } + var custom_location = typeof data.id !== 'number', + report_url = '/report/l/'+String(data.id)+'/'; + $location_details.find('.report').attr('href', report_url); + $location_details.find('.report-issue').toggle(!custom_location); + $location_details.find('.report-missing').toggle(custom_location); + if (data.geometry && data.level) { L.geoJSON(data.geometry, { style: { @@ -449,6 +454,7 @@ c3nav = { // loaded too late, information no longer needed return; } + $('#route-details .report').attr('href', data.report_issue_url); c3nav._push_state({route_result: data.result, route_options: data.options}, true); c3nav._display_route_result(data.result, nofly); c3nav._display_route_options(data.options); @@ -465,6 +471,8 @@ c3nav = { item, coords, description; c3nav._clear_route_layers(); + $details_wrapper.find('.report') + $details.html(''); $details.append(c3nav._build_location_html(result.origin)); @@ -778,6 +786,8 @@ c3nav = { c3nav.update_state(false); } else if ($(this).is('.share')) { c3nav._buttons_share_click(location); + } else if ($(this).is('a')) { + c3nav._modal_link_click.call(this, e); } else { var $locationinput = $(this).is('.as-origin') ? $origin : $destination, $other_locationinput = $(this).is('.as-origin') ? $destination : $origin, @@ -1246,7 +1256,10 @@ c3nav = { if (c3nav._click_anywhere_popup !== popup || !popup.isOpen()) return; popup.remove(); popup = L.popup(c3nav._add_map_padding({className: 'location-popup', maxWidth: 500}, 'autoPanPaddingTopLeft', 'autoPanPaddingBottomRight')); - popup.setLatLng(e.latlng).setContent(c3nav._build_location_html(data)+$('#popup-buttons').html()); + var buttons = $('#popup-buttons').clone(); + buttons.find('.report-issue').remove(); + buttons.find('.report').attr('href', '/report/l/'+String(data.id)+'/'); + popup.setLatLng(e.latlng).setContent(c3nav._build_location_html(data)+buttons.html()); c3nav._click_anywhere_popup = popup; popup.on('remove', function() { c3nav._click_anywhere_popup = null }).openOn(c3nav.map); }).fail(function() { @@ -1368,10 +1381,18 @@ c3nav = { } var point = c3nav._location_point_overrides[location.id] || location.point.slice(1), - latlng = L.GeoJSON.coordsToLatLng(point); + latlng = L.GeoJSON.coordsToLatLng(point), + buttons = $('#popup-buttons').clone(); + if (typeof location.id == 'number') { + buttons.find('.report-missing').remove(); + } else { + buttons.find('.report-issue').remove(); + } + buttons.find('.report').attr('href', '/report/l/'+String(location.id)+'/'); + L.marker(latlng, { icon: icon - }).bindPopup(location.elem+$('#popup-buttons').html(), c3nav._add_map_padding({ + }).bindPopup(location.elem+buttons.html(), c3nav._add_map_padding({ className: 'location-popup', maxWidth: 500 }, 'autoPanPaddingTopLeft', 'autoPanPaddingBottomRight')).addTo(c3nav._locationLayers[location.point[0]]); diff --git a/src/c3nav/site/templates/site/map.html b/src/c3nav/site/templates/site/map.html index e6636304..efb65334 100644 --- a/src/c3nav/site/templates/site/map.html +++ b/src/c3nav/site/templates/site/map.html @@ -46,6 +46,16 @@
+
+ + feedback + {% trans 'Report issue' %} + + + feedback + {% trans 'Report missing location' %} + +

{% trans 'Share' %}

@@ -132,13 +142,21 @@

{% trans 'Details' %}

-
@@ -146,6 +164,12 @@

{% trans 'Details' %}

+
diff --git a/src/c3nav/site/templates/site/report.html b/src/c3nav/site/templates/site/report.html new file mode 100644 index 00000000..53e02dd0 --- /dev/null +++ b/src/c3nav/site/templates/site/report.html @@ -0,0 +1,10 @@ +{% extends 'site/base.html' %} +{% load i18n %} + +{% block content %} +
+

{% trans 'Coming soon' %}

+ + {% include 'site/fragment_messages.html' %} +
+{% endblock %} diff --git a/src/c3nav/site/urls.py b/src/c3nav/site/urls.py index b2e12a14..67ea455d 100644 --- a/src/c3nav/site/urls.py +++ b/src/c3nav/site/urls.py @@ -1,9 +1,10 @@ from django.conf.urls import url from c3nav.site.views import (about_view, access_redeem_view, account_view, change_password_view, choose_language, - login_view, logout_view, map_index, qr_code, register_view) + login_view, logout_view, map_index, qr_code, register_view, report_view) slug = r'(?P[a-z0-9-_.:]+)' +coordinates = r'(?P[a-z0-9-_:]+:-?\d+(\.\d+)?:-?\d+(\.\d+)?)' slug2 = r'(?P[a-z0-9-_.:]+)' details = r'(?P
details/)?' options = r'(?Poptions/)?' @@ -25,4 +26,8 @@ urlpatterns = [ url(r'^access/(?P[^/]+)$', access_redeem_view, name='site.access.redeem'), url(r'^lang/$', choose_language, name='site.language'), url(r'^about/$', about_view, name='site.about'), + url(r'^report/$', about_view, name='site.about'), + url(r'^report/l/%s/$' % coordinates, report_view, name='site.report'), + url(r'^report/l/(?P\d+)/$', report_view, name='site.report'), + url(r'^report/r/(?P[^/]+)/(?P[^/]+)/(?P[^/]+)/$', report_view, name='site.report'), ] diff --git a/src/c3nav/site/views.py b/src/c3nav/site/views.py index 2bcdbf78..51b04e76 100644 --- a/src/c3nav/site/views.py +++ b/src/c3nav/site/views.py @@ -348,3 +348,8 @@ def about_view(request): 'team': settings.IMPRINT_TEAM, 'hosting': settings.IMPRINT_HOSTING, }) + + +@never_cache +def report_view(request, coordinates=None, location=None, origin=None, destination=None, options=None): + return render(request, 'site/report.html', {})