From fe963ec2db6a282f40300888e0dd9ede853bf3ff Mon Sep 17 00:00:00 2001 From: Christian Lawson-Perfect Date: Mon, 10 Feb 2025 11:52:12 +0000 Subject: [PATCH] Take a unique ID for maps. I want to be able to share this without giving away my data. The page takes a query parameter map=, which says which data file to load. If you load the page without a map ID, it makes up a random 8-digit hex string and uses that. The no-selection view shows a link to the map. --- app.js | 51 ++++++++++++++++++++++++++++++-------------- cgi-bin/save_data.py | 3 ++- elm.json | 2 +- index.html | 2 +- load-app.js | 21 ++++++++++++------ src/App.elm | 16 +++++++++++--- 6 files changed, 67 insertions(+), 28 deletions(-) diff --git a/app.js b/app.js index 1dc9ce8..f857b83 100644 --- a/app.js +++ b/app.js @@ -5160,9 +5160,9 @@ var $elm$core$Task$perform = F2( }); var $elm$browser$Browser$document = _Browser_document; var $elm$json$Json$Decode$decodeValue = _Json_run; -var $author$project$App$Flags = F2( - function (emoji, markers) { - return {emoji: emoji, markers: markers}; +var $author$project$App$Flags = F3( + function (emoji, markers, map_id) { + return {emoji: emoji, map_id: map_id, markers: markers}; }); var $author$project$App$Emoji = F2( function (emoji, description) { @@ -5198,8 +5198,9 @@ var $author$project$App$decode_marker = A5( A2($elm$json$Json$Decode$field, 'name', $elm$json$Json$Decode$string), A2($elm$json$Json$Decode$field, 'note', $elm$json$Json$Decode$string)); var $elm$json$Json$Decode$list = _Json_decodeList; -var $author$project$App$decode_flags = A3( - $elm$json$Json$Decode$map2, +var $elm$json$Json$Decode$map3 = _Json_map3; +var $author$project$App$decode_flags = A4( + $elm$json$Json$Decode$map3, $author$project$App$Flags, A2( $elm$json$Json$Decode$field, @@ -5208,7 +5209,8 @@ var $author$project$App$decode_flags = A3( A2( $elm$json$Json$Decode$field, 'markers', - $elm$json$Json$Decode$list($author$project$App$decode_marker))); + $elm$json$Json$Decode$list($author$project$App$decode_marker)), + A2($elm$json$Json$Decode$field, 'map_id', $elm$json$Json$Decode$string)); var $author$project$App$CurrentPositionCentre = {$: 'CurrentPositionCentre'}; var $author$project$App$NoSelection = {$: 'NoSelection'}; var $author$project$App$blank_marker = { @@ -5223,8 +5225,9 @@ var $elm$core$Basics$negate = function (n) { var $author$project$App$init_model = { accuracy: 0, centre: $author$project$App$CurrentPositionCentre, - current_position: {lat: 55.05155870729228, lon: -1.4652193740914812}, + current_position: {lat: 55.04, lon: -1.46}, emoji: _List_Nil, + map_id: '', markers: _List_Nil, new_marker: $author$project$App$blank_marker, selection: $author$project$App$NoSelection @@ -5244,7 +5247,7 @@ var $author$project$App$init = function (vflags) { var flags = _v0.a; return _Utils_update( $author$project$App$init_model, - {emoji: flags.emoji, markers: flags.markers}); + {emoji: flags.emoji, map_id: flags.map_id, markers: flags.markers}); } }()); }; @@ -5731,6 +5734,7 @@ var $author$project$App$UpdateExistingMarker = F2( var $author$project$App$UpdateNewMarker = function (a) { return {$: 'UpdateNewMarker', a: a}; }; +var $elm$html$Html$a = _VirtualDom_node('a'); var $elm$virtual_dom$VirtualDom$attribute = F2( function (key, value) { return A2( @@ -5841,6 +5845,12 @@ var $elm$html$Html$form = _VirtualDom_node('form'); var $elm$core$String$fromFloat = _String_fromNumber; var $elm$html$Html$h1 = _VirtualDom_node('h1'); var $elm$html$Html$h2 = _VirtualDom_node('h2'); +var $elm$html$Html$Attributes$href = function (url) { + return A2( + $elm$html$Html$Attributes$stringProperty, + 'href', + _VirtualDom_noJavaScriptUri(url)); +}; var $elm$html$Html$Attributes$id = $elm$html$Html$Attributes$stringProperty('id'); var $elm$html$Html$input = _VirtualDom_node('input'); var $elm$html$Html$label = _VirtualDom_node('label'); @@ -5906,13 +5916,6 @@ var $author$project$LatLonDistance$lat_lon_distance = F2( var $elm$html$Html$li = _VirtualDom_node('li'); var $elm$html$Html$Attributes$list = _VirtualDom_attribute('list'); var $elm$html$Html$main_ = _VirtualDom_node('main'); -var $elm$html$Html$a = _VirtualDom_node('a'); -var $elm$html$Html$Attributes$href = function (url) { - return A2( - $elm$html$Html$Attributes$stringProperty, - 'href', - _VirtualDom_noJavaScriptUri(url)); -}; var $elm$virtual_dom$VirtualDom$Normal = function (a) { return {$: 'Normal', a: a}; }; @@ -6390,7 +6393,23 @@ var $author$project$App$view = function (model) { A3($author$project$App$marker_link, m.icon + (' ' + m.name), i, m) ])); }, - A2($elm$core$List$take, 3, closest_markers))) + A2($elm$core$List$take, 3, closest_markers))), + A2( + $elm$html$Html$p, + _List_Nil, + _List_fromArray( + [ + A2( + $elm$html$Html$a, + _List_fromArray( + [ + $elm$html$Html$Attributes$href('?map=' + model.map_id) + ]), + _List_fromArray( + [ + $elm$html$Html$text('🔗 Link to this map') + ])) + ])) ])); } }(); diff --git a/cgi-bin/save_data.py b/cgi-bin/save_data.py index 3ead663..d151f47 100755 --- a/cgi-bin/save_data.py +++ b/cgi-bin/save_data.py @@ -10,8 +10,9 @@ form = cgi.FieldStorage() print('Content-Type: text/plain\n') content = form.getfirst('content') +map_id = form.getfirst('map_id') -with open(Path('..') / 'data' / 'markers.json', 'w') as f: +with open(Path('..') / 'data' / f'markers-{map_id}.json', 'w') as f: f.write(content) print(content) \ No newline at end of file diff --git a/elm.json b/elm.json index a51d89e..07ab2db 100644 --- a/elm.json +++ b/elm.json @@ -22,4 +22,4 @@ "direct": {}, "indirect": {} } -} +} \ No newline at end of file diff --git a/index.html b/index.html index 16f48ec..4711bfe 100644 --- a/index.html +++ b/index.html @@ -16,7 +16,7 @@
-

Elm app by clp

+

CLP's map app

This is an app which will either load succesfully, and you'll wonder whether you saw this text at all, or fail ignominiously, showing you only this text.

diff --git a/load-app.js b/load-app.js index 04f3fb0..899f73a 100644 --- a/load-app.js +++ b/load-app.js @@ -140,14 +140,21 @@ async function init_app() { return; } + const params = (new URL(window.location)).searchParams; + console.log(params); + let map_id = params.get('map') || ''; + if(!map_id) { + map_id = Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16).padStart(8,'0').slice(0,8); + } + let markers = []; try { - markers = await (await fetch('data/markers.json')).json(); + markers = await (await fetch(`data/markers-${map_id}.json`)).json(); } catch(e) { try { - const fh = await opfs.getFileHandle('markers.json'); + const fh = await opfs.getFileHandle(`markers-${map_id}.json`); const f = await fh.getFile(); markers = JSON.parse(await f.text()) } catch(e) { @@ -158,10 +165,11 @@ async function init_app() { const emoji = await (await fetch('emoji_metadata.json')).json(); - const app = Elm.App.init({node: document.body, flags: {emoji, markers}}); + const app = Elm.App.init({ + node: document.body, + flags: {emoji, markers, map_id} + }); - const params = new URLSearchParams(location.search); - navigator.geolocation.watchPosition( (r) => { app.ports.receive_position.send(r.coords); @@ -172,13 +180,14 @@ async function init_app() { const send_value_handlers = { save: async ({markers}) => { - const f = await opfs.getFileHandle('markers.json', {create:true}); + const f = await opfs.getFileHandle(`markers-${map_id}.json`, {create:true}); const w = await f.createWritable(); await w.write(JSON.stringify(markers)); await w.close(); const fd = new FormData(); fd.set('content', JSON.stringify(markers)); + fd.set('map_id', map_id); fetch('cgi-bin/save_data.py', { method: 'POST', body: fd diff --git a/src/App.elm b/src/App.elm index d576351..a5d042e 100644 --- a/src/App.elm +++ b/src/App.elm @@ -50,6 +50,7 @@ type MapCentre type alias Model = { markers : List Marker , emoji : List Emoji + , map_id : String , current_position : LatLon , selection : Selection , new_marker : Marker @@ -60,7 +61,8 @@ type alias Model = init_model = { markers = [] , emoji = [] - , current_position = {lat = 55.05155870729228, lon = -1.4652193740914812} + , map_id = "" + , current_position = {lat = 55.04, lon = -1.46} , selection = NoSelection , new_marker = blank_marker , accuracy = 0 @@ -91,18 +93,20 @@ decode_emoji = type alias Flags = { emoji : List Emoji , markers : List Marker + , map_id : String } decode_flags = - JD.map2 Flags + JD.map3 Flags (JD.field "emoji" (JD.list decode_emoji)) (JD.field "markers" (JD.list decode_marker)) + (JD.field "map_id" JD.string) init : (JD.Value) -> (Model, Cmd msg) init vflags = (case JD.decodeValue decode_flags vflags of Err _ -> init_model - Ok flags -> { init_model | emoji = flags.emoji, markers = flags.markers } + Ok flags -> { init_model | emoji = flags.emoji, markers = flags.markers, map_id = flags.map_id } ) |> nocmd nocmd m = (m, Cmd.none) @@ -387,6 +391,12 @@ view model = ) (closest_markers |> List.take 3) ) + , H.p + [] + [ H.a + [ HA.href <| "?map=" ++ model.map_id ] + [ H.text "🔗 Link to this map" ] + ] ] closest_markers =