Feature: improve offline data management

This commit is contained in:
Pieter Vander Vennet 2025-08-01 00:44:08 +02:00
parent 6f44fe31d0
commit 77ef3a3572

View file

@ -18,8 +18,9 @@
import ShowDataLayer from "../Map/ShowDataLayer" import ShowDataLayer from "../Map/ShowDataLayer"
import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource" import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource"
import LayerConfig from "../../Models/ThemeConfig/LayerConfig" import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import AccordionSingle from "../Flowbite/AccordionSingle.svelte"
import { DownloadIcon, TrashIcon } from "@rgossiaux/svelte-heroicons/solid" import { DownloadIcon, TrashIcon } from "@rgossiaux/svelte-heroicons/solid"
import { Accordion, AccordionItem } from "flowbite-svelte"
import ServiceWorkerStatus from "./ServiceWorkerStatus.svelte"
export let state: ThemeViewState & SpecialVisualizationState = undefined export let state: ThemeViewState & SpecialVisualizationState = undefined
@ -35,7 +36,7 @@
const offlineMapManager = new OfflineBasemapManager("https://cache.mapcomplete.org/") const offlineMapManager = new OfflineBasemapManager("https://cache.mapcomplete.org/")
let installedMeta: UIEventSource<AreaDescription[]> = new UIEventSource() let installedMeta: UIEventSource<AreaDescription[]> = new UIEventSource([])
function updateMeta() { function updateMeta() {
@ -43,15 +44,7 @@
} }
async function pingServiceWorker() {
const l = window.location
const sw = await Utils.downloadJson(l.protocol + "//" + l.host + "/service-worker/offline-basemapM/update")
console.log("Service worker has data:", sw)
}
updateMeta() updateMeta()
pingServiceWorker()
let installing = new UIEventSource<string[]>([]) let installing = new UIEventSource<string[]>([])
@ -62,7 +55,6 @@
const descr = OfflineBasemapManager.getAreaDescriptionForMapcomplete(key + ".pmtiles") const descr = OfflineBasemapManager.getAreaDescriptionForMapcomplete(key + ".pmtiles")
await offlineMapManager.installArea(descr) await offlineMapManager.installArea(descr)
updateMeta() updateMeta()
pingServiceWorker()
} catch (e) { } catch (e) {
installing.set(installing.data.filter(k => k !== key)) installing.set(installing.data.filter(k => k !== key))
} finally { } finally {
@ -71,13 +63,14 @@
} }
let installed: Store<Feature<Polygon>> = installedMeta.map(meta => let installed: Store<Feature<Polygon>[]> = installedMeta.map(meta =>
(meta ?? []) (meta ?? [])
.map(area => { .map(area => {
const f = Tiles.asGeojson(area.minzoom, area.x, area.y) const f = Tiles.asGeojson(area.minzoom, area.x, area.y)
f.properties = { f.properties = {
id: area.minzoom + "-" + area.x + "-" + area.y, id: area.minzoom + "-" + area.x + "-" + area.y,
downloaded: "yes" downloaded: "yes",
text: area.name + " " + area.dataVersion + " " + Utils.toHumanByteSize(Number(area.size))
} }
return f return f
} }
@ -104,7 +97,7 @@
async function download() { async function download() {
const areasToInstall = Array.from(offlineMapManager.getInstallCandidates(focusTile.data)) const areasToInstall = Array.from(offlineMapManager.getInstallCandidates(focusTile.data))
for (const area: AreaDescription of areasToInstall) { for (const area of areasToInstall) {
console.log("Attempting to install", area) console.log("Attempting to install", area)
await install(area) await install(area)
} }
@ -135,7 +128,14 @@
] ]
} }
}], }],
pointRendering: null pointRendering: [
{
location: ["point", "centroid"],
label: "{text}",
labelCss: "width: w-min",
labelCssClasses: "bg-white rounded px-2"
}
]
}) })
}) })
@ -173,11 +173,17 @@
{#if $installedMeta === undefined} {#if $installedMeta === undefined}
<Loading /> <Loading />
{:else} {:else}
<div class="relative w-full h-3/4"> <div class="h-full overflow-auto pb-16">
<Accordion class="" inactiveClass="text-black">
<AccordionItem paddingDefault="p-2">
<div slot="header">Map</div>
<div class="relative leave-room">
<div class="rounded-lg absolute top-0 left-0 h-full w-full"> <div class="rounded-lg absolute top-0 left-0 h-full w-full">
<MaplibreMap {map} {mapProperties} /> <MaplibreMap {map} {mapProperties} />
</div> </div>
<div class="absolute top-0 left-0 h-full w-full flex flex-col justify-center items-center pointer-events-none"> <div
class="absolute top-0 left-0 h-full w-full flex flex-col justify-center items-center pointer-events-none">
<div class="w-16 h-32 mb-16"></div> <div class="w-16 h-32 mb-16"></div>
{#if $focusTileIsInstalling} {#if $focusTileIsInstalling}
<div class="normal-background rounded-lg"> <div class="normal-background rounded-lg">
@ -194,12 +200,16 @@
{/if} {/if}
</div> </div>
</div> </div>
</AccordionItem>
<AccordionSingle> <AccordionItem paddingDefault="p-2">
<div slot="header"> <div slot="header">
Offline tile management Offline tile management
</div> </div>
<div class="leave-room">
{Utils.toHumanByteSize(Utils.sum($installedMeta.map(area => area.size)))} {Utils.toHumanByteSize(Utils.sum($installedMeta.map(area => area.size)))}
<button on:click={() => { <button on:click={() => {
installedMeta?.data?.forEach(area => del(area)) installedMeta?.data?.forEach(area => del(area))
@ -207,7 +217,7 @@
<TrashIcon class="w-6" /> <TrashIcon class="w-6" />
Delete all Delete all
</button> </button>
<table class="w-full"> <table class="w-full ">
<tr> <tr>
<th>Name</th> <th>Name</th>
<th>Map generation date</th> <th>Map generation date</th>
@ -237,7 +247,27 @@
{/each} {/each}
</table> </table>
</AccordionSingle> </div>
</AccordionItem>
<AccordionItem paddingDefault="p-2">
<div slot="header">
Service worker status
</div>
<div class="leave-room">
<ServiceWorkerStatus />
</div>
</AccordionItem>
</Accordion>
</div>
{/if} {/if}
</div> </div>
<style>
.leave-room {
height: calc(100vh - 18rem);
overflow-x: auto;
width: 100%;
color: var(--foreground-color);
}
</style>