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";
|
||||
import { location } from "./location.svelte";
|
||||
import { protocol } from "$lib/services/OfflineTiles";
|
||||
import { saved } from "$lib/saved.svelte";
|
||||
|
||||
onMount(() => {
|
||||
window.addEventListener("resize", map.updateMapPadding);
|
||||
@ -23,6 +24,8 @@
|
||||
|
||||
let locationDot: 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
|
||||
</script>
|
||||
@ -63,6 +66,7 @@
|
||||
class="w-full h-full"
|
||||
style="/style.json"
|
||||
bind:map={map.value}
|
||||
bind:zoom={map.zoom}
|
||||
padding={map.padding}
|
||||
onload={async () => {
|
||||
map.updateMapPadding();
|
||||
@ -119,7 +123,7 @@
|
||||
enableHighAccuracy: true,
|
||||
}}
|
||||
trackUserLocation={true}
|
||||
autoTrigger={true}
|
||||
autoTrigger={true}""
|
||||
ongeolocate={(e: GeolocationPosition) => {
|
||||
const speed = Math.round((e.coords.speed || 0) * 3.6); // In km/h
|
||||
const accuracy = Math.round(e.coords.accuracy);
|
||||
@ -133,6 +137,36 @@
|
||||
{#if pin.isDropped}
|
||||
<Marker lnglat={{ lat: pin.lat, lng: pin.lng }} />
|
||||
{/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}
|
||||
<GeoJSONSource id="route-past" data={routing.geojson.routePast}>
|
||||
|
||||
@ -7,6 +7,7 @@ import { view } from "./sidebar.svelte";
|
||||
|
||||
export const map = $state({
|
||||
value: undefined as maplibregl.Map | undefined,
|
||||
zoom: 0,
|
||||
updateMapPadding: () => {
|
||||
if (document.querySelector<HTMLDivElement>("#sidebar") == null) {
|
||||
map._setPadding({
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
import Reviews from "../info/Reviews.svelte";
|
||||
import MapAi from "../info/MapAI.svelte";
|
||||
import RequiresCapability from "../RequiresCapability.svelte";
|
||||
import { saved, saveLocations } from "$lib/saved.svelte";
|
||||
|
||||
// let { feature }: { feature: Feature } = $props();
|
||||
|
||||
@ -170,10 +171,12 @@
|
||||
<Button
|
||||
variant="outline"
|
||||
onclick={() => {
|
||||
localStorage.setItem(
|
||||
"saved.home",
|
||||
JSON.stringify({ lat, lon: lng }),
|
||||
);
|
||||
// localStorage.setItem(
|
||||
// "saved.home",
|
||||
// JSON.stringify({ lat, lon: lng }),
|
||||
// );
|
||||
saved.home = { lat, lon: lng };
|
||||
saveLocations();
|
||||
}}
|
||||
>
|
||||
<HomeIcon />
|
||||
@ -182,10 +185,12 @@
|
||||
<Button
|
||||
variant="outline"
|
||||
onclick={() => {
|
||||
localStorage.setItem(
|
||||
"saved.work",
|
||||
JSON.stringify({ lat, lon: lng }),
|
||||
);
|
||||
// localStorage.setItem(
|
||||
// "saved.work",
|
||||
// JSON.stringify({ lat, lon: lng }),
|
||||
// );
|
||||
saved.work = { lat, lon: lng };
|
||||
saveLocations();
|
||||
}}
|
||||
>
|
||||
<BriefcaseIcon />
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
import VehicleSelector from "../VehicleSelector.svelte";
|
||||
import Post from "../Post.svelte";
|
||||
import RequiresCapability from "../RequiresCapability.svelte";
|
||||
import { saved } from "$lib/saved.svelte";
|
||||
</script>
|
||||
|
||||
<div
|
||||
@ -18,12 +19,11 @@
|
||||
variant="secondary"
|
||||
class="flex-1"
|
||||
onclick={() => {
|
||||
const home = localStorage.getItem("saved.home");
|
||||
if (!home) {
|
||||
const { lat, lon } = saved.home;
|
||||
if (!lat || !lon) {
|
||||
alert("No home location saved.");
|
||||
return;
|
||||
}
|
||||
const { lat, lon } = JSON.parse(home);
|
||||
pin.dropPin(lat, lon);
|
||||
pin.showInfo();
|
||||
map.value?.flyTo({
|
||||
@ -39,12 +39,11 @@
|
||||
variant="secondary"
|
||||
class="flex-1"
|
||||
onclick={() => {
|
||||
const work = localStorage.getItem("saved.work");
|
||||
if (!work) {
|
||||
const { lat, lon } = saved.work;
|
||||
if (!lat || !lon) {
|
||||
alert("No work location saved.");
|
||||
return;
|
||||
}
|
||||
const { lat, lon } = JSON.parse(work);
|
||||
pin.dropPin(lat, lon);
|
||||
pin.showInfo();
|
||||
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