Skip to content

Commit

Permalink
Remember most state in the URL... except mode. #11
Browse files Browse the repository at this point in the history
  • Loading branch information
dabreegster committed Aug 18, 2024
1 parent 0ec6d02 commit 5f28267
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 10 deletions.
6 changes: 5 additions & 1 deletion web/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
wasmReady = true;
});
let fitBoundsAtStart = !window.location.hash;
let map: Map;
$: if (map) {
mapStore.set(map);
Expand All @@ -59,7 +60,10 @@
return;
}
console.log("New map model loaded");
zoomToFit();
if (fitBoundsAtStart) {
zoomToFit();
}
fitBoundsAtStart = true;
$mode = { kind: "route" };
}
$: gotModel($model);
Expand Down
8 changes: 3 additions & 5 deletions web/src/OsmSeparateSidewalksMode.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
import { SplitComponent } from "svelte-utils/top_bar_layout";
import { PropertiesTable, notNull } from "svelte-utils";
import { Popup } from "svelte-utils/map";
import { model } from "./stores";
import { model, duplicateSidewalks } from "./stores";
import NavBar from "./NavBar.svelte";
let duplicateSidewalks = true;
</script>

<SplitComponent>
Expand All @@ -20,14 +18,14 @@
</p>

<label>
<input type="checkbox" bind:checked={duplicateSidewalks} />
<input type="checkbox" bind:checked={$duplicateSidewalks} />
Only show roads with a <b>sidewalk=left,right,both</b> tag
</label>
</div>
<div slot="map">
<GeoJSON
data={JSON.parse(
notNull($model).findSeparateSidewalks(duplicateSidewalks),
notNull($model).findSeparateSidewalks($duplicateSidewalks),
)}
generateId
>
Expand Down
54 changes: 50 additions & 4 deletions web/src/stores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,55 @@ export let profile = urlState({
parse: enumUrl(["USA", "SidewalksOnHighways", "SeparateWays"]),
});

export let routeA: Writable<Position | null> = writable(null);
export let routeB: Writable<Position | null> = writable(null);
export let minScore = writable(0);
export let maxScore = writable(100);
export let routeA: Writable<Position | null> = urlState({
name: "routeA",
defaultValue: null,
stringify: (pt) => (pt ? `${pt[0]},${pt[1]}` : null),
parse: parsePt,
});
export let routeB: Writable<Position | null> = urlState({
name: "routeB",
defaultValue: null,
stringify: (pt) => (pt ? `${pt[0]},${pt[1]}` : null),
parse: parsePt,
});
export let minScore: Writable<number> = urlState({
name: "minScore",
defaultValue: 0,
stringify: (x) => (x == 0 ? null : x.toString()),
parse: parsePercent,
});
export let maxScore: Writable<number> = urlState({
name: "maxScore",
defaultValue: 100,
stringify: (x) => (x == 100 ? null : x.toString()),
parse: parsePercent,
});
export let duplicateSidewalks: Writable<boolean> = urlState({
name: "duplicateSidewalks",
defaultValue: true,
stringify: (x) => x ? "1" : "0",
parse: (x) => x == "1",
});

export type Position = [number, number];

function parsePt(pt: string): Position {
let [x, y] = pt.split(",");
return [notNan(parseFloat(x)), notNan(parseFloat(y))];
}

function notNan(n: number): number {
if (isNaN(n)) {
throw new Error("not a number");
}
return n;
}

function parsePercent(x: string): number {
let n = notNan(parseInt(x));
if (n < 0 || n > 100) {
throw new Error(`bad percent ${n}`);
}
return n;
}
1 change: 1 addition & 0 deletions web/src/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export function urlState<T>(params: {
}

// Generates a `parse` function that insists the input belongs to the set of values
// TODO More specific return type
export function enumUrl(values: string[]): (param: string) => string {
return (param) => {
if (values.includes(param)) {
Expand Down

0 comments on commit 5f28267

Please sign in to comment.