feat!: improve saving locations
Shows saved home and work locations with a marker on the map and provides a better API for saved locations opening room for more locations in the future BREAKING CHANGE: no longer uses saved.home, saved.work localStorage entries, locations need to be re-entered to use the saved entry instead
This commit is contained in:
BIN
public/img/saved/home.png
Normal file
BIN
public/img/saved/home.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.8 KiB |
BIN
public/img/saved/work.png
Normal file
BIN
public/img/saved/work.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
@ -15,6 +15,7 @@
|
|||||||
} from "$lib/services/navigation/routing.svelte";
|
} from "$lib/services/navigation/routing.svelte";
|
||||||
import { location } from "./location.svelte";
|
import { location } from "./location.svelte";
|
||||||
import { protocol } from "$lib/services/OfflineTiles";
|
import { protocol } from "$lib/services/OfflineTiles";
|
||||||
|
import { saved } from "$lib/saved.svelte";
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
window.addEventListener("resize", map.updateMapPadding);
|
window.addEventListener("resize", map.updateMapPadding);
|
||||||
@ -23,6 +24,8 @@
|
|||||||
|
|
||||||
let locationDot: HTMLDivElement | undefined = $state();
|
let locationDot: HTMLDivElement | undefined = $state();
|
||||||
let locationAccuracyCircle: HTMLDivElement | undefined = $state();
|
let locationAccuracyCircle: HTMLDivElement | undefined = $state();
|
||||||
|
let homeMarker: HTMLImageElement | undefined = $state();
|
||||||
|
let workMarker: HTMLImageElement | undefined = $state();
|
||||||
|
|
||||||
const DEBUG_POINTS = false; // Set to true to show debug points on the map
|
const DEBUG_POINTS = false; // Set to true to show debug points on the map
|
||||||
</script>
|
</script>
|
||||||
@ -63,6 +66,7 @@
|
|||||||
class="w-full h-full"
|
class="w-full h-full"
|
||||||
style="/style.json"
|
style="/style.json"
|
||||||
bind:map={map.value}
|
bind:map={map.value}
|
||||||
|
bind:zoom={map.zoom}
|
||||||
padding={map.padding}
|
padding={map.padding}
|
||||||
onload={async () => {
|
onload={async () => {
|
||||||
map.updateMapPadding();
|
map.updateMapPadding();
|
||||||
@ -119,7 +123,7 @@
|
|||||||
enableHighAccuracy: true,
|
enableHighAccuracy: true,
|
||||||
}}
|
}}
|
||||||
trackUserLocation={true}
|
trackUserLocation={true}
|
||||||
autoTrigger={true}
|
autoTrigger={true}""
|
||||||
ongeolocate={(e: GeolocationPosition) => {
|
ongeolocate={(e: GeolocationPosition) => {
|
||||||
const speed = Math.round((e.coords.speed || 0) * 3.6); // In km/h
|
const speed = Math.round((e.coords.speed || 0) * 3.6); // In km/h
|
||||||
const accuracy = Math.round(e.coords.accuracy);
|
const accuracy = Math.round(e.coords.accuracy);
|
||||||
@ -133,6 +137,36 @@
|
|||||||
{#if pin.isDropped}
|
{#if pin.isDropped}
|
||||||
<Marker lnglat={{ lat: pin.lat, lng: pin.lng }} />
|
<Marker lnglat={{ lat: pin.lat, lng: pin.lng }} />
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if saved.home && map.zoom > 9}
|
||||||
|
<img
|
||||||
|
src="/img/saved/home.png"
|
||||||
|
alt="Home Marker"
|
||||||
|
bind:this={homeMarker}
|
||||||
|
style="width: 32px;"
|
||||||
|
/>
|
||||||
|
<Marker
|
||||||
|
lnglat={{
|
||||||
|
lat: saved.home.lat,
|
||||||
|
lng: saved.home.lon,
|
||||||
|
}}
|
||||||
|
element={homeMarker}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
{#if saved.work && map.zoom > 9}
|
||||||
|
<img
|
||||||
|
src="/img/saved/work.png"
|
||||||
|
alt="Work Marker"
|
||||||
|
bind:this={workMarker}
|
||||||
|
style="width: 32px;"
|
||||||
|
/>
|
||||||
|
<Marker
|
||||||
|
lnglat={{
|
||||||
|
lat: saved.work.lat,
|
||||||
|
lng: saved.work.lon,
|
||||||
|
}}
|
||||||
|
element={workMarker}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#if routing.geojson.routePast}
|
{#if routing.geojson.routePast}
|
||||||
<GeoJSONSource id="route-past" data={routing.geojson.routePast}>
|
<GeoJSONSource id="route-past" data={routing.geojson.routePast}>
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { view } from "./sidebar.svelte";
|
|||||||
|
|
||||||
export const map = $state({
|
export const map = $state({
|
||||||
value: undefined as maplibregl.Map | undefined,
|
value: undefined as maplibregl.Map | undefined,
|
||||||
|
zoom: 0,
|
||||||
updateMapPadding: () => {
|
updateMapPadding: () => {
|
||||||
if (document.querySelector<HTMLDivElement>("#sidebar") == null) {
|
if (document.querySelector<HTMLDivElement>("#sidebar") == null) {
|
||||||
map._setPadding({
|
map._setPadding({
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
import Reviews from "../info/Reviews.svelte";
|
import Reviews from "../info/Reviews.svelte";
|
||||||
import MapAi from "../info/MapAI.svelte";
|
import MapAi from "../info/MapAI.svelte";
|
||||||
import RequiresCapability from "../RequiresCapability.svelte";
|
import RequiresCapability from "../RequiresCapability.svelte";
|
||||||
|
import { saved, saveLocations } from "$lib/saved.svelte";
|
||||||
|
|
||||||
// let { feature }: { feature: Feature } = $props();
|
// let { feature }: { feature: Feature } = $props();
|
||||||
|
|
||||||
@ -170,10 +171,12 @@
|
|||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
localStorage.setItem(
|
// localStorage.setItem(
|
||||||
"saved.home",
|
// "saved.home",
|
||||||
JSON.stringify({ lat, lon: lng }),
|
// JSON.stringify({ lat, lon: lng }),
|
||||||
);
|
// );
|
||||||
|
saved.home = { lat, lon: lng };
|
||||||
|
saveLocations();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<HomeIcon />
|
<HomeIcon />
|
||||||
@ -182,10 +185,12 @@
|
|||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
localStorage.setItem(
|
// localStorage.setItem(
|
||||||
"saved.work",
|
// "saved.work",
|
||||||
JSON.stringify({ lat, lon: lng }),
|
// JSON.stringify({ lat, lon: lng }),
|
||||||
);
|
// );
|
||||||
|
saved.work = { lat, lon: lng };
|
||||||
|
saveLocations();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<BriefcaseIcon />
|
<BriefcaseIcon />
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
import VehicleSelector from "../VehicleSelector.svelte";
|
import VehicleSelector from "../VehicleSelector.svelte";
|
||||||
import Post from "../Post.svelte";
|
import Post from "../Post.svelte";
|
||||||
import RequiresCapability from "../RequiresCapability.svelte";
|
import RequiresCapability from "../RequiresCapability.svelte";
|
||||||
|
import { saved } from "$lib/saved.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@ -18,12 +19,11 @@
|
|||||||
variant="secondary"
|
variant="secondary"
|
||||||
class="flex-1"
|
class="flex-1"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
const home = localStorage.getItem("saved.home");
|
const { lat, lon } = saved.home;
|
||||||
if (!home) {
|
if (!lat || !lon) {
|
||||||
alert("No home location saved.");
|
alert("No home location saved.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { lat, lon } = JSON.parse(home);
|
|
||||||
pin.dropPin(lat, lon);
|
pin.dropPin(lat, lon);
|
||||||
pin.showInfo();
|
pin.showInfo();
|
||||||
map.value?.flyTo({
|
map.value?.flyTo({
|
||||||
@ -39,12 +39,11 @@
|
|||||||
variant="secondary"
|
variant="secondary"
|
||||||
class="flex-1"
|
class="flex-1"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
const work = localStorage.getItem("saved.work");
|
const { lat, lon } = saved.work;
|
||||||
if (!work) {
|
if (!lat || !lon) {
|
||||||
alert("No work location saved.");
|
alert("No work location saved.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { lat, lon } = JSON.parse(work);
|
|
||||||
pin.dropPin(lat, lon);
|
pin.dropPin(lat, lon);
|
||||||
pin.showInfo();
|
pin.showInfo();
|
||||||
map.value?.flyTo({
|
map.value?.flyTo({
|
||||||
|
|||||||
7
src/lib/saved.svelte.ts
Normal file
7
src/lib/saved.svelte.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export const saved: Record<string, WorldLocation> = $state(
|
||||||
|
JSON.parse(localStorage.getItem("saved") ?? "{}"),
|
||||||
|
);
|
||||||
|
|
||||||
|
export function saveLocations() {
|
||||||
|
localStorage.setItem("saved", JSON.stringify(saved));
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user