Skip to content

Commit

Permalink
Apply the Svelte trick to express shortcut mode as one component!
Browse files Browse the repository at this point in the history
  • Loading branch information
dabreegster committed Dec 22, 2023
1 parent 08c662a commit 2a9e6bb
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 103 deletions.
24 changes: 19 additions & 5 deletions web/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import NeighbourhoodLayer from "./NeighbourhoodLayer.svelte";
import NeighbourhoodMode from "./NeighbourhoodMode.svelte";
import NetworkLayer from "./NetworkLayer.svelte";
import ViewShortcutsLayer from "./ViewShortcutsLayer.svelte";
import { mapContents, sidebarContents } from "./stores";
import ViewShortcutsMode from "./ViewShortcutsMode.svelte";
let offlineMode = true;
Expand Down Expand Up @@ -309,6 +309,17 @@
rerender: 0,
};
}
let sidebarDiv;
let mapDiv;
$: if (sidebarDiv && $sidebarContents) {
sidebarDiv.innerHTML = "";
sidebarDiv.appendChild($sidebarContents);
}
$: if (mapDiv && $mapContents) {
mapDiv.innerHTML = "";
mapDiv.appendChild($mapContents);
}
</script>

<Layout>
Expand All @@ -325,9 +336,9 @@
<p>Draw the boundary...</p>
{:else if mode.mode == "neighbourhood"}
<NeighbourhoodMode bind:mode {app} {setBoundaryMode} />
{:else if mode.mode == "view-shortcuts"}
<ViewShortcutsMode bind:mode {app} prevMode={mode.prevMode} {map} />
{/if}

<div bind:this={sidebarDiv} />
</div>
<div slot="main" style="position:relative; width: 100%; height: 100vh;">
<MapLibre style={mapStyle} standardControls hash bind:map>
Expand All @@ -347,10 +358,13 @@
rerender={mode.rerender}
{offlineMode}
/>
{:else if mode.mode == "view-shortcuts"}
<ViewShortcutsLayer {app} />
{/if}
{/if}

<div bind:this={mapDiv} />
{#if mode.mode == "view-shortcuts"}
<ViewShortcutsMode bind:mode {app} prevMode={mode.prevMode} {map} />
{/if}
</MapLibre>
</div>
</Layout>
Expand Down
14 changes: 14 additions & 0 deletions web/src/SplitComponent.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script lang="ts">
import { mapContents, sidebarContents } from "./stores";
// The kinda weird hack is that this must itself be nested underneath the
// MapLibre bit, so it has context. The sidebar is the "remote" part.
// TODO Maybe simplify accordingly
</script>

<div bind:this={$sidebarContents}>
<slot name="sidebar" />
</div>
<div bind:this={$mapContents}>
<slot name="map" />
</div>
40 changes: 0 additions & 40 deletions web/src/ViewShortcutsLayer.svelte

This file was deleted.

123 changes: 94 additions & 29 deletions web/src/ViewShortcutsMode.svelte
Original file line number Diff line number Diff line change
@@ -1,15 +1,41 @@
<script lang="ts">
import { LTN } from "backend";
import type { Map } from "maplibre-gl";
import { onDestroy, onMount } from "svelte";
import { state } from "./stores";
import { GeoJSON, LineLayer } from "svelte-maplibre";
import SplitComponent from "./SplitComponent.svelte";
export let mode: Mode;
export let app: LTN;
export let prevMode: Mode;
export let map: Map;
// Initially set this
$state = { state: "neutral" };
type State =
| {
state: "neutral";
}
| {
state: "chose-road";
road: number;
gj: FeatureCollection;
shortcutIndex: number | null;
};
let state = { state: "neutral" };
function choseRoad(app: LTN, road: number) {
let gj = JSON.parse(app.getShortcutsCrossingRoad(road));
if (gj.features.length == 0) {
window.alert("No shortcuts here");
return;
}
state = {
state: "chose-road",
road,
gj,
shortcutIndex: null,
};
}
onMount(() => {
map.keyboard.disable();
Expand All @@ -19,17 +45,17 @@
});
function onKeyDown(e: KeyboardEvent) {
if ($state.state == "chose-road") {
if (e.key == "ArrowLeft" && $state.shortcutIndex != 0) {
if (state.state == "chose-road") {
if (e.key == "ArrowLeft" && state.shortcutIndex != 0) {
e.stopPropagation();
$state.shortcutIndex--;
state.shortcutIndex--;
}
if (e.key == "ArrowRight") {
e.stopPropagation();
if ($state.shortcutIndex == null) {
$state.shortcutIndex = 0;
} else if ($state.shortcutIndex != $state.gj.features.length - 1) {
$state.shortcutIndex++;
if (state.shortcutIndex == null) {
state.shortcutIndex = 0;
} else if (state.shortcutIndex != state.gj.features.length - 1) {
state.shortcutIndex++;
}
}
}
Expand All @@ -42,24 +68,63 @@

<svelte:window on:keydown={onKeyDown} />

<div><button on:click={back}>Back to editing</button></div>
<SplitComponent>
<div slot="sidebar">
<div><button on:click={back}>Back to editing</button></div>

{#if state.state == "neutral"}
<p>Click a road to see shortcuts</p>
{:else if state.state == "chose-road"}
<div>
<button
disabled={state.shortcutIndex == null || state.shortcutIndex == 0}
on:click={() => state.shortcutIndex--}
>
Prev
</button>
{state.shortcutIndex} / {state.gj.features.length}
<button
disabled={state.shortcutIndex == state.gj.features.length - 1}
on:click={() => state.shortcutIndex++}
>
Next
</button>
</div>
{/if}
</div>

{#if $state.state == "neutral"}
<p>Click a road to see shortcuts</p>
{:else if $state.state == "chose-road"}
<div>
<button
disabled={$state.shortcutIndex == null || $state.shortcutIndex == 0}
on:click={() => $state.shortcutIndex--}
>
Prev
</button>
{$state.shortcutIndex} / {$state.gj.features.length}
<button
disabled={$state.shortcutIndex == $state.gj.features.length - 1}
on:click={() => $state.shortcutIndex++}
>
Next
</button>
<div slot="map">
{#if state.state == "neutral"}
<GeoJSON data={JSON.parse(app.render())}>
<LineLayer
paint={{
"line-width": 5,
"line-color": "black",
}}
on:click={(e) => choseRoad(app, e.detail.features[0].properties.id)}
hoverCursor="pointer"
/>
</GeoJSON>
{:else if state.state == "chose-road"}
{#if state.shortcutIndex == null}
<GeoJSON data={state.gj}>
<LineLayer
paint={{
"line-width": 5,
"line-color": "red",
}}
/>
</GeoJSON>
{:else}
<GeoJSON data={state.gj.features[state.shortcutIndex]}>
<LineLayer
paint={{
"line-width": 5,
"line-color": "red",
}}
/>
</GeoJSON>
{/if}
{/if}
</div>
{/if}
</SplitComponent>
32 changes: 3 additions & 29 deletions web/src/stores.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,4 @@
import { LTN } from "backend";
import { writable, type Writable } from "svelte/store";
import { writable } from "svelte/store";

export type State =
| {
state: "neutral";
}
| {
state: "chose-road";
road: number;
gj: FeatureCollection;
shortcutIndex: number | null;
};

export let state: Writable<State> = writable({ state: "neutral" });

export function choseRoad(app: LTN, road: number) {
let gj = JSON.parse(app.getShortcutsCrossingRoad(road));
if (gj.features.length == 0) {
window.alert("No shortcuts here");
return;
}

state.set({
state: "chose-road",
road,
gj,
shortcutIndex: null,
});
}
export let sidebarContents = writable(null);
export let mapContents = writable(null);

0 comments on commit 2a9e6bb

Please sign in to comment.