feat(web+server): map improvements (#2498)

* feat(web+server): map improvements

* add number format double to fix mobile
This commit is contained in:
Michel Heusschen
2023-05-21 08:26:06 +02:00
committed by GitHub
parent e028cf9002
commit a7b9adc692
34 changed files with 501 additions and 364 deletions

View File

@@ -2,22 +2,15 @@ import { AppRoute } from '$lib/constants';
import { redirect } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
export const load = (async ({ locals: { api, user } }) => {
export const load = (async ({ locals: { user } }) => {
if (!user) {
throw redirect(302, AppRoute.AUTH_LOGIN);
}
try {
const { data: mapMarkers } = await api.assetApi.getMapMarkers();
return {
user,
mapMarkers,
meta: {
title: 'Map'
}
};
} catch (e) {
throw redirect(302, AppRoute.AUTH_LOGIN);
}
return {
user,
meta: {
title: 'Map'
}
};
}) satisfies PageServerLoad;

View File

@@ -1,27 +1,43 @@
<script lang="ts">
import type { PageData } from '../map/$types';
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
import Portal from '$lib/components/shared-components/portal/portal.svelte';
import AssetViewer from '$lib/components/asset-viewer/asset-viewer.svelte';
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
import MapSettingsModal from '$lib/components/map-page/map-settings-modal.svelte';
import Portal from '$lib/components/shared-components/portal/portal.svelte';
import {
assetInteractionStore,
isViewingAssetStoreState,
viewingAssetStoreState
} from '$lib/stores/asset-interaction.store';
import { mapSettings } from '$lib/stores/preferences.store';
import { MapMarkerResponseDto, api } from '@api';
import { onDestroy, onMount } from 'svelte';
import Cog from 'svelte-material-icons/Cog.svelte';
import type { PageData } from './$types';
export let data: PageData;
let initialMapCenter: [number, number] = [48, 11];
$: {
if (data.mapMarkers.length) {
let firstMarker = data.mapMarkers[0];
initialMapCenter = [firstMarker.lat, firstMarker.lon];
}
}
let mapMarkersPromise: Promise<MapMarkerResponseDto[]>;
let abortController = new AbortController();
let viewingAssets: string[] = [];
let viewingAssetCursor = 0;
let showSettingsModal = false;
onMount(() => {
mapMarkersPromise = loadMapMarkers();
});
onDestroy(() => {
abortController.abort();
assetInteractionStore.clearMultiselect();
assetInteractionStore.setIsViewingAsset(false);
});
async function loadMapMarkers() {
const { data } = await api.assetApi.getMapMarkers($mapSettings.onlyFavorites || undefined, {
signal: abortController.signal
});
return data;
}
function onViewAssets(assets: string[]) {
assetInteractionStore.setViewingAssetId(assets[0]);
@@ -40,27 +56,55 @@
assetInteractionStore.setViewingAssetId(viewingAssets[--viewingAssetCursor]);
}
}
function getMapCenter(mapMarkers: MapMarkerResponseDto[]): [number, number] {
const marker = mapMarkers[0];
if (marker) {
return [marker.lat, marker.lon];
}
return [48, 11];
}
</script>
<UserPageLayout user={data.user} title={data.meta.title}>
<div slot="buttons" />
<div class="h-full w-full relative z-0">
{#await import('$lib/components/shared-components/leaflet') then { Map, TileLayer, AssetMarkerCluster }}
<Map latlng={initialMapCenter} zoom={7}>
<TileLayer
allowDarkMode={true}
urlTemplate={'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'}
<div class="h-full w-full isolate">
{#await import('$lib/components/shared-components/leaflet') then { Map, TileLayer, AssetMarkerCluster, Control }}
{#await mapMarkersPromise then mapMarkers}
<Map
center={getMapCenter(mapMarkers)}
zoom={7}
allowDarkMode={$mapSettings.allowDarkMode}
options={{
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
maxBounds: [
[-90, -180],
[90, 180]
],
minZoom: 3
}}
/>
<AssetMarkerCluster
markers={data.mapMarkers}
on:view={(event) => onViewAssets(event.detail.assets)}
/>
</Map>
>
<TileLayer
urlTemplate={'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'}
options={{
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}}
/>
<AssetMarkerCluster
markers={mapMarkers}
on:view={(event) => onViewAssets(event.detail.assets)}
/>
<Control>
<button
class="flex justify-center items-center bg-white text-black/70 w-8 h-8 font-bold rounded-sm border-2 border-black/20 hover:bg-gray-50 focus:bg-gray-50"
title="Open map settings"
on:click={() => (showSettingsModal = true)}
>
<Cog size="100%" class="p-1" />
</button>
</Control>
</Map>
{/await}
{/await}
</div>
</UserPageLayout>
@@ -78,3 +122,20 @@
/>
{/if}
</Portal>
{#if showSettingsModal}
<MapSettingsModal
settings={{ ...$mapSettings }}
on:close={() => (showSettingsModal = false)}
on:save={async ({ detail }) => {
const shouldUpdate = detail.onlyFavorites !== $mapSettings.onlyFavorites;
showSettingsModal = false;
$mapSettings = detail;
if (shouldUpdate) {
const markers = await loadMapMarkers();
mapMarkersPromise = Promise.resolve(markers);
}
}}
/>
{/if}