Mercurial > lbo > hg > geohub
changeset 74:ebbecfa4231f
Refine behavior of livemap UI
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sat, 05 Dec 2020 11:43:38 +0100 |
parents | e22189546e10 |
children | afefa4d60653 |
files | README.md assets/livemap.html assets/trackme.html src/main.rs src/notifier.rs src/types.rs |
diffstat | 6 files changed, 69 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/README.md Sat Dec 05 10:58:26 2020 +0100 +++ b/README.md Sat Dec 05 11:43:38 2020 +0100 @@ -152,10 +152,9 @@ GeoHub with nothing more than Ajax and some third-party libraries. This also allows you to immediately use the `livemap` app at -`https://yourhost.com/geo/assets/livemap.html?client=<yourclient>&secret=verysecret`, -which consists of a single HTML page, a CSS file, and the leaflet.js library -(which is included). - latter is (c) 2010-2019 Vladimir Agafonkin, (c) 2010-2011 -CloudMade. +`https://yourhost.com/geo/assets/livemap.html`, which consists of a single HTML +page, a CSS file, and the leaflet.js library (which is included). - latter is +(c) 2010-2019 Vladimir Agafonkin, (c) 2010-2011 CloudMade. ## Ingestion
--- a/assets/livemap.html Sat Dec 05 10:58:26 2020 +0100 +++ b/assets/livemap.html Sat Dec 05 11:43:38 2020 +0100 @@ -59,6 +59,27 @@ } return userSecret ? userSecret : ''; } + function updateURL(client, secret) { + var url = window.location.toString(); + + if (url.search('\\?') < 0) { + url += '?'; + } + + if (url.search('secret=') > 0) { + url = url.replace(/secret=[a-zA-Z0-9]*/, `secret=${secret}`); + } else { + url += `&secret=${secret}`; + } + + if (url.search('client=') > 0) { + url = url.replace(/client=[a-zA-Z0-9]*/, `client=${client}`); + } else { + url += `&client=${client}`; + } + + window.history.pushState({}, "", url); + } // Set the current location, called on every new point. Updates the marker and adds // a new point (former position). @@ -84,7 +105,12 @@ console.log('xhrcallback called.', xhr.readyState, xhr.status); if (xhr.readyState === XMLHttpRequest.DONE && xhr.status == 200) { const response = xhr.response; - if (response['geo']) { + console.log("Client update for", response.client); + if (response.client != getClient()) { + console.log("Received outdated client update."); + return; + } + if (response.client == getClient() && response['geo']) { const features = response['geo']['features']; const lastfeature = features[0]; console.log(`xhrcallback: ${features.length} elements received.`); @@ -109,13 +135,15 @@ // Install next XHR. waitforupdate(); + } else { + return; } }; // Fetch the most recent point for this client and display them. function backfill(args) { - xhr = new XMLHttpRequest(); + var xhr = new XMLHttpRequest(); var client = getClient(); var secret = getSecret(); if (!client) { @@ -132,7 +160,7 @@ // Ask for updates. This request will hang until timeout is reached or // an update arrives. function waitforupdate() { - xhr = new XMLHttpRequest(); + var xhr = new XMLHttpRequest(); var client = getClient(); var secret = getSecret(); if (!client) { @@ -150,6 +178,7 @@ // "Go!" was clicked - clear markers and fetch data for new source. function buttonGoClicked() { clearAllMarkers(); + updateURL(getClient(), getSecret()); // Accelerate display. backfill(); }
--- a/assets/trackme.html Sat Dec 05 10:58:26 2020 +0100 +++ b/assets/trackme.html Sat Dec 05 11:43:38 2020 +0100 @@ -84,6 +84,28 @@ } return userSecret; } + // Update URL from client/secret. + function updateURL(client, secret) { + var url = window.location.toString(); + + if (url.search('\\?') < 0) { + url += '?'; + } + + if (url.search('secret=') > 0) { + url = url.replace(/secret=[a-zA-Z0-9]*/, `secret=${secret}`); + } else { + url += `&secret=${secret}`; + } + + if (url.search('client=') > 0) { + url = url.replace(/client=[a-zA-Z0-9]*/, `client=${client}`); + } else { + url += `&client=${client}`; + } + + window.history.pushState({}, "", url); + } // Update the link to the livemap if the user has changed client/secret. function updateLiveMap() { var secret = getSecret(); @@ -193,6 +215,7 @@ inputSecret.disabled = false; }; updateLiveMap(); + updateURL(); } // Pre-fill client/secret.
--- a/src/main.rs Sat Dec 05 10:58:26 2020 +0100 +++ b/src/main.rs Sat Dec 05 11:43:38 2020 +0100 @@ -15,10 +15,10 @@ /// Almost like retrieve/json, but sorts in descending order, doesn't work with intervals (only /// limit), and returns a LiveUpdate. /// Used for backfilling recent points in the UI. -#[rocket::get("/geo/<name>/retrieve/last?<secret>&<last>&<limit>")] +#[rocket::get("/geo/<client>/retrieve/last?<secret>&<last>&<limit>")] fn retrieve_last( db: db::DBConn, - name: String, + client: String, secret: Option<String>, last: Option<i32>, limit: Option<i64>, @@ -33,10 +33,11 @@ secret }; let db = db::DBQuery(&db.0); - if let Some((geojson, newlast)) = db.check_for_new_rows(&name, &secret, &last, &limit) { - rocket_contrib::json::Json(types::LiveUpdate::new(Some(newlast), Some(geojson), None)) + if let Some((geojson, newlast)) = db.check_for_new_rows(&client, &secret, &last, &limit) { + rocket_contrib::json::Json(types::LiveUpdate::new(client, Some(newlast), Some(geojson), None)) } else { rocket_contrib::json::Json(types::LiveUpdate::new( + client, last, None, Some("No rows returned".into()),
--- a/src/notifier.rs Sat Dec 05 10:58:26 2020 +0100 +++ b/src/notifier.rs Sat Dec 05 11:43:38 2020 +0100 @@ -75,16 +75,16 @@ }; let req = NotifyRequest { - client: client, + client: client.clone(), secret: secret, respond: send, }; self.0.send(req).unwrap(); if let Ok(response) = recv.recv_timeout(time::Duration::new(timeout.unwrap_or(30), 0)) { - types::LiveUpdate::new(response.last, response.geo, None) + types::LiveUpdate::new(client, response.last, response.geo, None) } else { - types::LiveUpdate::new(None, None, Some("timeout, try again".into())) + types::LiveUpdate::new(client, None, None, Some("timeout, try again".into())) } }
--- a/src/types.rs Sat Dec 05 10:58:26 2020 +0100 +++ b/src/types.rs Sat Dec 05 11:43:38 2020 +0100 @@ -14,15 +14,17 @@ pub struct LiveUpdate { #[serde(rename = "type")] typ: String, // always "GeoHubUpdate" + client: String, last: Option<i32>, geo: Option<GeoJSON>, error: Option<String>, } impl LiveUpdate { - pub fn new(last: Option<i32>, geo: Option<GeoJSON>, err: Option<String>) -> LiveUpdate { + pub fn new(client: String, last: Option<i32>, geo: Option<GeoJSON>, err: Option<String>) -> LiveUpdate { LiveUpdate { typ: "GeoHubUpdate".into(), + client: client, last: last, geo: geo, error: err,