UX: add progress bar for uploading images

This commit is contained in:
Pieter Vander Vennet 2025-05-07 16:31:00 +02:00
parent bb33c43950
commit 221b572a1f
8 changed files with 45 additions and 18 deletions

8
package-lock.json generated
View file

@ -72,7 +72,7 @@
"osm-auth": "^2.6.0",
"osmtogeojson": "^3.0.0-beta.5",
"pannellum": "^2.5.6",
"panoramax-js": "^0.4.12",
"panoramax-js": "^0.5.5",
"panzoom": "^9.4.3",
"papaparse": "^5.5.2",
"pg": "^8.11.3",
@ -22012,9 +22012,9 @@
"license": "MIT"
},
"node_modules/panoramax-js": {
"version": "0.4.12",
"resolved": "https://registry.npmjs.org/panoramax-js/-/panoramax-js-0.4.12.tgz",
"integrity": "sha512-BFNMGFumMmBfL7QC3IQxgWjy1nr2AWrcNcQY9n1y0UGGNLrDxv9+i6EzuZ3slgGP+qvb7tKx8mqfZaN6U/O/4g==",
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/panoramax-js/-/panoramax-js-0.5.5.tgz",
"integrity": "sha512-gIGeBFszIvtW2DhOHHQ9FtTzwkOv8MEBY2Lu9n+QxbGOlkiCbUpfA7afcv6XEbbEJ4HM8ffAVpcZgHLJFIFkvQ==",
"license": "GPL-3.0-or-later",
"dependencies": {
"@ogcapi-js/features": "^1.1.1",

View file

@ -235,7 +235,7 @@
"osm-auth": "^2.6.0",
"osmtogeojson": "^3.0.0-beta.5",
"pannellum": "^2.5.6",
"panoramax-js": "^0.4.12",
"panoramax-js": "^0.5.5",
"panzoom": "^9.4.3",
"papaparse": "^5.5.2",
"pg": "^8.11.3",

View file

@ -57,6 +57,9 @@ export class ImageUploadManager {
extramessage?: string
) => Promise<void>
private readonly _progressCurrentImage: UIEventSource<number> = new UIEventSource(0)
public readonly progressCurrentImage: Store<number> = this._progressCurrentImage
constructor(
layout: ThemeConfig,
uploader: ImageUploader,
@ -276,11 +279,12 @@ export class ImageUploadManager {
let absoluteUrl: string
try {
;({ key, value, absoluteUrl } = await this._uploader.uploadImage(
({ key, value, absoluteUrl } = await this._uploader.uploadImage(
blob,
location,
author,
noblur
noblur,
this._progressCurrentImage
))
} catch (e) {
console.error("Could again not upload image due to", e)

View file

@ -1,3 +1,5 @@
import { UIEventSource } from "../UIEventSource"
export interface ImageUploader {
maxFileSizeInMegabytes?: number
/**
@ -8,7 +10,8 @@ export interface ImageUploader {
blob: File,
currentGps: [number, number],
author: string,
noblur: boolean
noblur: boolean,
progress?: UIEventSource<number>
): Promise<UploadResult>
}

View file

@ -252,6 +252,7 @@ export class PanoramaxUploader implements ImageUploader {
currentGps: [number, number],
author: string,
noblur: boolean = false,
progress?: UIEventSource<number>,
sequenceId?: string,
datetime?: string
): Promise<{
@ -319,15 +320,25 @@ export class PanoramaxUploader implements ImageUploader {
const sequence: { id: string; "stats:items": { count: number } } = (
await p.mySequences()
).find((s) => s.id === sequenceId)
const img = <ImageData>await p.addImage(blob, sequence, {
const options = {
lon,
lat,
datetime,
isBlurred: noblur,
onProgress: undefined,
exifOverride: {
Artist: author,
},
})
}
if (progress) {
options.onProgress = (e: ProgressEvent) => {
if (e.lengthComputable) {
const percentage = (e.loaded / e.total) * 100
progress.set(Math.round(percentage))
}
}
}
const img = <ImageData>await p.addImage(blob, sequence, options)
PanoramaxImageProvider.singleton.addKnownMeta(img)
return {
key: "panoramax",

View file

@ -1,5 +1,4 @@
<script lang="ts">
import { twMerge } from "tailwind-merge"
import Loading from "../../assets/svg/Loading.svelte"
export let cls: string = "flex p-1 pl-2"
@ -9,7 +8,7 @@
<div class="h-6 w-6 min-w-6 shrink-0 animate-spin self-center">
<Loading />
</div>
<div class="ml-2">
<div class="ml-2 w-full">
<slot />
</div>
</div>

View file

@ -42,6 +42,7 @@
failed.addCallbackAndRun((failed) => {
dismissed = Math.min(failed, dismissed)
})
let progress = state.imageUploadManager.progressCurrentImage
</script>
{#if $debugging}
@ -53,11 +54,20 @@
{#if $pending - $failed > 0}
<div class="alert">
<Loading>
{#if $pending - $failed === 1}
<Tr t={t.upload.one.uploading} />
{:else if $pending - $failed > 1}
<Tr t={t.upload.multiple.uploading.Subs({ count: $pending })} />
{/if}
<div class="w-full flex flex-col">
<div class="w-full flex justify-between">
{#if $pending - $failed === 1}
<Tr t={t.upload.one.uploading} />
{:else if $pending - $failed > 1}
<Tr t={t.upload.multiple.uploading.Subs({ count: $pending })} />
{/if}
{$progress}%
</div>
<div class="w-full low-interaction h-1">
<div class="bg-black h-1" style={`width: calc(${$progress}%)`}></div>
</div>
</div>
</Loading>
</div>
{/if}

View file

@ -18,7 +18,7 @@
import LevelSelector from "./BigComponents/LevelSelector.svelte"
import type { RasterLayerPolygon } from "../Models/RasterLayers"
import { AvailableRasterLayers } from "../Models/RasterLayers"
import { onDestroy, setContext } from "svelte"
import { onDestroy } from "svelte"
import OpenBackgroundSelectorButton from "./BigComponents/OpenBackgroundSelectorButton.svelte"
import StateIndicator from "./BigComponents/StateIndicator.svelte"
import UploadingImageCounter from "./Image/UploadingImageCounter.svelte"