forked from MapComplete/MapComplete
UX: add progress bar to panoramax upload, fix hanging upload in case of multiple selected images, rm old log statements
This commit is contained in:
parent
767bd18234
commit
e33d448055
8 changed files with 35 additions and 22 deletions
8
package-lock.json
generated
8
package-lock.json
generated
|
@ -72,7 +72,7 @@
|
|||
"osm-auth": "^2.6.0",
|
||||
"osmtogeojson": "^3.0.0-beta.5",
|
||||
"pannellum": "^2.5.6",
|
||||
"panoramax-js": "^0.5.5",
|
||||
"panoramax-js": "^0.6.1",
|
||||
"panzoom": "^9.4.3",
|
||||
"papaparse": "^5.5.2",
|
||||
"pg": "^8.11.3",
|
||||
|
@ -22012,9 +22012,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/panoramax-js": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/panoramax-js/-/panoramax-js-0.5.5.tgz",
|
||||
"integrity": "sha512-gIGeBFszIvtW2DhOHHQ9FtTzwkOv8MEBY2Lu9n+QxbGOlkiCbUpfA7afcv6XEbbEJ4HM8ffAVpcZgHLJFIFkvQ==",
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/panoramax-js/-/panoramax-js-0.6.1.tgz",
|
||||
"integrity": "sha512-aPs+HIkidTBzgNBVoqOKoCB4ksMtC4U86D7DL8dJLTBMlYM/qgbxNlpNTB5f7B2brU1KUKNJDHX8dlva+xHl9w==",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@ogcapi-js/features": "^1.1.1",
|
||||
|
|
|
@ -235,7 +235,7 @@
|
|||
"osm-auth": "^2.6.0",
|
||||
"osmtogeojson": "^3.0.0-beta.5",
|
||||
"pannellum": "^2.5.6",
|
||||
"panoramax-js": "^0.5.5",
|
||||
"panoramax-js": "^0.6.1",
|
||||
"panzoom": "^9.4.3",
|
||||
"papaparse": "^5.5.2",
|
||||
"pg": "^8.11.3",
|
||||
|
|
|
@ -166,8 +166,9 @@ export class ImageUploadManager {
|
|||
console.log("Checking image upload queue and uploading if needed")
|
||||
this.uploadingAll = true
|
||||
try {
|
||||
for (const imageToUpload of queue) {
|
||||
await this.handleQueueItem(imageToUpload)
|
||||
while (queue.length > 0) {
|
||||
const currentItem = queue[0]
|
||||
await this.handleQueueItem(currentItem)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Error while handling the queue:", e)
|
||||
|
@ -183,10 +184,12 @@ export class ImageUploadManager {
|
|||
* - indicates that the upload is busy
|
||||
* - Applies the action to the correct element
|
||||
* - indicates failure
|
||||
*
|
||||
* Modifies the queue: if the upload is successfull, deletes the item from the queue
|
||||
* @private
|
||||
*/
|
||||
private async handleQueueItem(args: ImageUploadArguments): Promise<void> {
|
||||
console.log("Handling queue item", args)
|
||||
console.log("Handling queue item", args.blob.name, args)
|
||||
if (!args) {
|
||||
return
|
||||
}
|
||||
|
@ -197,18 +200,22 @@ export class ImageUploadManager {
|
|||
while (attempts > 0 && result === undefined) {
|
||||
attempts--
|
||||
const doReport = attempts == 0
|
||||
result = await this.attemptSingleUpload(args, doReport)
|
||||
try {
|
||||
result = await this.attemptSingleUpload(args, doReport)
|
||||
} catch (e) {
|
||||
console.error("Uploading failed with error", e)
|
||||
}
|
||||
if (!result) {
|
||||
console.log("Upload attempt failed, attempts left:", attempts)
|
||||
}
|
||||
}
|
||||
this._isUploading.set(undefined)
|
||||
this._fails.set(this._fails.data.filter((a) => a !== args))
|
||||
if (result === undefined) {
|
||||
this._fails.data.push(args)
|
||||
this._fails.ping()
|
||||
return
|
||||
}
|
||||
this._fails.set(this._fails.data.filter((a) => a !== args))
|
||||
let properties: UIEventSource<Record<string, string>> = this._featureProperties.getStore(
|
||||
args.featureId
|
||||
)
|
||||
|
|
|
@ -11,7 +11,7 @@ export interface ImageUploader {
|
|||
currentGps: [number, number],
|
||||
author: string,
|
||||
noblur: boolean,
|
||||
progress?: UIEventSource<number>
|
||||
progress?: UIEventSource<number | undefined>
|
||||
): Promise<UploadResult>
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import SvelteUIElement from "../../UI/Base/SvelteUIElement"
|
|||
import Panoramax_bw from "../../assets/svg/Panoramax_bw.svelte"
|
||||
import Link from "../../UI/Base/Link"
|
||||
import { Feature, Point } from "geojson"
|
||||
import { AddImageOptions } from "panoramax-js/dist/Panoramax"
|
||||
|
||||
export default class PanoramaxImageProvider extends ImageProvider {
|
||||
public static readonly singleton: PanoramaxImageProvider = new PanoramaxImageProvider()
|
||||
|
@ -166,7 +167,6 @@ export default class PanoramaxImageProvider extends ImageProvider {
|
|||
|
||||
getRelevantUrls(tags: Record<string, string>, prefixes: string[]): Store<ProvidedImage[]> {
|
||||
const source = UIEventSource.FromPromise(super.getRelevantUrlsFor(tags, prefixes))
|
||||
console.trace("Getting relevant URLS for panoramax yielded", source.data)
|
||||
function hasLoading(data: ProvidedImage[]) {
|
||||
if (data === undefined) {
|
||||
return true
|
||||
|
@ -252,7 +252,7 @@ export class PanoramaxUploader implements ImageUploader {
|
|||
currentGps: [number, number],
|
||||
author: string,
|
||||
noblur: boolean = false,
|
||||
progress?: UIEventSource<number>,
|
||||
progress?: UIEventSource<number | undefined>,
|
||||
sequenceId?: string,
|
||||
datetime?: string
|
||||
): Promise<{
|
||||
|
@ -320,12 +320,13 @@ export class PanoramaxUploader implements ImageUploader {
|
|||
const sequence: { id: string; "stats:items": { count: number } } = (
|
||||
await p.mySequences()
|
||||
).find((s) => s.id === sequenceId)
|
||||
const options = {
|
||||
const options: AddImageOptions = {
|
||||
lon,
|
||||
lat,
|
||||
datetime,
|
||||
isBlurred: noblur,
|
||||
onProgress: undefined,
|
||||
indexInSequence: sequence["stats:items"].count + 1, // stats:items is '1'-indexed, so .count is also the last index
|
||||
exifOverride: {
|
||||
Artist: author,
|
||||
},
|
||||
|
@ -337,9 +338,11 @@ export class PanoramaxUploader implements ImageUploader {
|
|||
progress.set(Math.round(percentage))
|
||||
}
|
||||
}
|
||||
progress.set(0)
|
||||
}
|
||||
const img = <ImageData>await p.addImage(blob, sequence, options)
|
||||
const img = <ImageData>await p.addImage(blob, sequenceId, options)
|
||||
PanoramaxImageProvider.singleton.addKnownMeta(img)
|
||||
progress.set(undefined)
|
||||
return {
|
||||
key: "panoramax",
|
||||
value: img.id,
|
||||
|
|
|
@ -105,7 +105,7 @@ export default class ThemeViewStateHashActor {
|
|||
if (found.properties.id.startsWith("last_click")) {
|
||||
return true
|
||||
}
|
||||
console.log("Setting selected element based on hash", hash, "; found", found)
|
||||
console.log("Setting selected element based on hash", hash, "; found", found, "current:", selectedElement.data?.properties?.id)
|
||||
selectedElement.setData(found)
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ export class WithSelectedElementState extends UserMapFeatureswitchState {
|
|||
|
||||
// Add the selected element to the recently visited history
|
||||
this.selectedElement.addCallbackD((selected) => {
|
||||
console.trace("Selected element is", selected)
|
||||
const [osm_type, osm_id] = selected.properties.id.split("/")
|
||||
const [lon, lat] = GeoOperations.centerpointCoordinates(selected)
|
||||
const layer = this.theme.getMatchingLayer(selected.properties)
|
||||
|
|
|
@ -56,17 +56,21 @@
|
|||
<Loading>
|
||||
<div class="w-full flex flex-col">
|
||||
|
||||
<div class="w-full flex justify-between">
|
||||
<div class="w-full flex justify-between gap-x-8">
|
||||
{#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>
|
||||
{#if $progress !== undefined}
|
||||
{$progress}%
|
||||
{/if}
|
||||
</div>
|
||||
{#if $progress !== undefined}
|
||||
<div class="w-full low-interaction h-1 rounded-full overflow-hidden">
|
||||
<div class="bg-black h-1" style={`width: calc(${$progress}%)`}></div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</Loading>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue