diff --git a/templates/internal/base.html b/templates/internal/base.html index 4717e66a66c23e452dbdf106b7c426413d4b28c1..c5393eb1c641d92d525fb203078e6be07f7d3b99 100644 --- a/templates/internal/base.html +++ b/templates/internal/base.html @@ -163,7 +163,7 @@ }; // another jquery "plugin" for modifying the behaviour of external links - // TODO: disable when not running on the display + // - this is probably not really enough, consider adding a tab blocker on the display and/or disable iframes, object tags, etc. $.fn.disableExternalLinks = function(force = false) { // for some extra security the first condition is resolved when templates are compiled if (({{ (not g.is_kiosk)|tojson|safe }} && !force) || this.data('links-disabled')) @@ -183,8 +183,13 @@ }).modal(); }; - // the to slashes are for the benefit of urls that contain refering URI in the query string + // the two slashes are for the benefit of urls that contain refering URI in the query string this.on('click', 'a[href^="http"]:not([href*="//{{ request.host }}"])', handler); + // disable links for foreign protocols, just in case + this.on('click', 'a[href^="mailto:"]', function(e) { e.preventDefault(); }); + this.on('click', 'a[href*="://"]:not([href^="http"])', function(e) { e.preventDefault(); }); + + // avoid duplicate calls (see info page, twitter widget) this.data('links-disabled', true); return this; }; diff --git a/templates/map.html b/templates/map.html index 46539269a1b2e65ba22755ba5b433412f8ffb7c6..39db1c248f23aa10ce8b41f3c27e70999593a4e0 100644 --- a/templates/map.html +++ b/templates/map.html @@ -73,15 +73,23 @@ // focusedMarker is the title of the focused marker var focusedMarker = undefined; + // the currently focused bus information var focusedBus = undefined; + // shapes currently drawn on map var mapShapes = []; + // info window for currently focused bus var focusedBusWindow = undefined; - var apiEndpoint = "{{ url_for('apiLocatorService', version = 1, stopId = stop_info.stop_id, type = 'nearby', _external = True) }}"; - var trackingLoop = null; - var currentMode = null; + + // map zoom and centered stop var busStop = {{ stop_info|tojson|safe }}; var mapZoom = 16; + // map updating related variables + var mapUpdating = false; // block mode changes when map is busy + var pendingEvent = null; + var trackingLoop = null; + var currentMode = null; + var positionToGoogleLatLng = function(lat, lon) { return new google.maps.LatLng(lat, lon); }; @@ -151,6 +159,23 @@ } }; + // handle events skipped due to ongoing map update, see variable mapUpdating and click handlers + var completeMapUpdate = function() { + if (!mapUpdating) + console.log('superfluous call to completeMapUpdate(), map is not busy...'); + + mapUpdating = false; + if (pendingEvent !== null) { + if (pendingEvent === "mapClicked") { + mapClicked(); + } else if (gmarkers[pendingEvent] !== undefined) { + markerClicked(gmarkers[pendingEvent]); + } + + pendingEvent = null; + } + }; + // this function will determine what to draw on the map every 3 seconds var busTrackingLoop = function(mode, pollTime = 3000) { if (trackingLoop !== null) { @@ -178,12 +203,24 @@ } } + // store the skipped event for when update has finished + if (mapUpdating) { + pendingEvent = marker.title; + return; + } + focusedMarker = marker.title; initOneBusTracking(); } var mapClicked = function() { if (focusedMarker !== undefined) { + // store the skipped event for when update has finished + if (mapUpdating) { + pendingEvent = "mapClicked"; + return; + } + gmap.setZoom(mapZoom); gmap.panTo(positionToGoogleLatLng(busStop.stop_lat, busStop.stop_lon)); @@ -210,7 +247,7 @@ } markers = {}; - $.getJSON(apiEndpoint, + $.getJSON("{{ url_for('apiLocatorService', version = 1, stopId = stop_info.stop_id, type = 'nearby', _external = True) }}", function (data) { console.log('found this many buses: ' + Object.keys(data).length); $.each( data, function( key, value ) { @@ -227,7 +264,10 @@ }; var drawAllBuses = function() { - $.getJSON(apiEndpoint, + // mark the map as busy + mapUpdating = true; + + $.getJSON("{{ url_for('apiLocatorService', version = 1, stopId = stop_info.stop_id, type = 'nearby', _external = True) }}", function (data) { // poor man's locking if (trackingLoop === null) @@ -259,6 +299,8 @@ value.setMap(null); } }); + + completeMapUpdate(); } ) }; @@ -329,6 +371,9 @@ }; var drawOneBus = function() { + // mark the map as busy + mapUpdating = true; + var requestFocus = focusedMarker; $.post( "{{ url_for('apiBusInfo', version = 1, _external = True) }}", @@ -354,6 +399,8 @@ marker.setPosition(position); gmap.panTo(position); } + + completeMapUpdate(); }, 'json' ) @@ -364,9 +411,9 @@ // TODO is there a better way of doing this, this way is pretty ugly var infoWindowContent = ` <h4>` + focusedBus.lineref + ' - ' + focusedBus.destinationname + `</h4> - Next Stop: ` + focusedBus.next_stoppointname + ` <br> - Aimed Arrival: ` + moment.unix(focusedBus.next_aimedarrivaltime).format('HH:mm:ss') + ` <br> - Expected Arrival: ` + moment.unix(focusedBus.next_expectedarrivaltime).format('HH:mm:ss') + ` <br> + {{ _("Next Stop") }}: ` + focusedBus.next_stoppointname + ` <br> + {{ _("Aimed Arrival") }}: ` + moment.unix(focusedBus.next_aimedarrivaltime).format('HH:mm:ss') + ` <br> + {{ _("Expected Arrival") }}: ` + moment.unix(focusedBus.next_expectedarrivaltime).format('HH:mm:ss') + ` <br> `; if (focusedBusWindow === undefined || recreate) { @@ -385,21 +432,24 @@ $(document).ready(function() { console.log(busStop); - console.log("hello world"); - // this draws an initial map that is zoomed and centered on the bus stop // this map is used then to start drawing buses dynamically on it - gmap = drawMap(busStop, $('#map-canvas')); - google.maps.event.addListener(gmap, 'click', function() { mapClicked() }); + $canvas = $('#map-canvas'); + gmap = drawMap(busStop, $canvas); - drawBusStop(gmap, busStop.stop_lat, busStop.stop_lon, busStop.stop_name, busStop.stop_id); + // wait for the map to load before we queue other work + google.maps.event.addListenerOnce(gmap, 'tilesloaded', function() { + // this may or may not violate Google Maps ToS (9.4), but frankly not allowing users to break out + // of the application on public displays is more important (and its not like we are removing attribution) + $canvas.disableExternalLinks(); - // start bus tracking loop - initAllBusesTracking(); + google.maps.event.addListener(gmap, 'click', function() { mapClicked() }); - // this may or may not violate Google Maps ToS (10.1.1, 9.4), but frankly not allowing users to break out - // of the application on public displays is more important (and its not like we are removing attribution) - google.maps.event.addListenerOnce(gmap, 'tilesloaded', function() { $('#map-canvas').disableExternalLinks(); }) + drawBusStop(gmap, busStop.stop_lat, busStop.stop_lon, busStop.stop_name, busStop.stop_id); + + // start bus tracking loop + initAllBusesTracking(); + }); }); </script> {% endblock scripts %} diff --git a/translations/en/LC_MESSAGES/messages.po b/translations/en/LC_MESSAGES/messages.po index a340c8a5ad1001ad99a6eab6d65904f5778b8333..0cf6a7999029a670b2bf03470b64fc45d7d0f95e 100644 --- a/translations/en/LC_MESSAGES/messages.po +++ b/translations/en/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2018-03-05 20:03+0200\n" +"POT-Creation-Date: 2018-03-07 20:32+0200\n" "PO-Revision-Date: 2018-02-10 01:33+0200\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language: en\n" @@ -76,6 +76,18 @@ msgid "" "to move in an unrealistic way." msgstr "" +#: templates/map.html:414 +msgid "Next Stop" +msgstr "" + +#: templates/map.html:415 +msgid "Aimed Arrival" +msgstr "" + +#: templates/map.html:416 +msgid "Expected Arrival" +msgstr "" + #: templates/timetables.html:10 msgid "Busses Arriving Soon" msgstr "" diff --git a/translations/fi/LC_MESSAGES/messages.po b/translations/fi/LC_MESSAGES/messages.po index 024781cf5a9f3e725afd2ac0455de52267ced0d5..663ccee03bc3b0db17dc7bf5935cb64f378d7456 100644 --- a/translations/fi/LC_MESSAGES/messages.po +++ b/translations/fi/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2018-03-05 20:03+0200\n" +"POT-Creation-Date: 2018-03-07 20:32+0200\n" "PO-Revision-Date: 2018-02-10 01:35+0200\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language: fi\n" @@ -79,6 +79,18 @@ msgstr "" " puutteellisesta paikannuksesta johtuen bussit saattavat paikoitellen " "liikkua epärealistisella tavalla" +#: templates/map.html:414 +msgid "Next Stop" +msgstr "Seuraava pysäkki" + +#: templates/map.html:415 +msgid "Aimed Arrival" +msgstr "Tavoitteellinen saapumisaika" + +#: templates/map.html:416 +msgid "Expected Arrival" +msgstr "Odotettu saapumisaika" + #: templates/timetables.html:10 msgid "Busses Arriving Soon" msgstr "Pian saapuvat bussit"