forked from MapComplete/MapComplete
Feature(offline): better support for making changes while offline
This commit is contained in:
parent
f671cd342f
commit
7155cd7f61
8 changed files with 89 additions and 10 deletions
|
@ -430,10 +430,10 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"id": "favourite_icon",
|
||||
"condition": "_favourite=yes",
|
||||
"description": "Only for rendering",
|
||||
"icon": "circle:white;heart:red",
|
||||
"condition": "_favourite=yes",
|
||||
"id": "favourite_icon",
|
||||
"metacondition": "__showTimeSensitiveIcons!=no"
|
||||
},
|
||||
{
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
"allFilteredAway": "No feature in view meets all filters",
|
||||
"loadingData": "Loading data…",
|
||||
"noData": "There are no relevant features in the current view",
|
||||
"noDataOffline": "No data is loaded and you are offline",
|
||||
"noDataOffline": "No data is loaded and you are offline",
|
||||
"ready": "Done!",
|
||||
"retrying": "Loading data failed. Trying again in {count} seconds…",
|
||||
"zoomIn": "Zoom in to view or edit the data"
|
||||
|
@ -639,6 +639,7 @@
|
|||
"uploading": "{count} images are being uploaded…"
|
||||
},
|
||||
"noBlur": "Images will not be blurred. Do not photograph people",
|
||||
"offline": "You are currently offline. Uploading images be attempted when your internet is back",
|
||||
"one": {
|
||||
"done": "Your image was successfully uploaded. Thank you!",
|
||||
"failed": "Sorry, we could not upload your image",
|
||||
|
@ -653,7 +654,7 @@
|
|||
"confirmDeleteTitle": "Delete this image?",
|
||||
"delete": "Delete this image",
|
||||
"intro": "The following images are queued for upload",
|
||||
"menu": "Image upload queue ({count})",
|
||||
"menu": "Pending changes and image uploads ({count})",
|
||||
"noFailedImages": "There are currently no images in the upload queue",
|
||||
"retryAll": "Retry uploading all images"
|
||||
},
|
||||
|
|
|
@ -19,6 +19,7 @@ import MarkdownUtils from "../../Utils/MarkdownUtils"
|
|||
import FeaturePropertiesStore from "../FeatureSource/Actors/FeaturePropertiesStore"
|
||||
import { Feature, Point } from "geojson"
|
||||
import { Lists } from "../../Utils/Lists"
|
||||
import { IsOnline } from "../Web/IsOnline"
|
||||
|
||||
/**
|
||||
* Handles all changes made to OSM.
|
||||
|
@ -287,6 +288,10 @@ export class Changes {
|
|||
if (this.pendingChanges.data.length === 0) {
|
||||
return
|
||||
}
|
||||
if(!IsOnline.isOnline.data){
|
||||
// No use to upload, we aren't connected anyway
|
||||
return
|
||||
}
|
||||
if (this.isUploading.data) {
|
||||
console.log("Is already uploading... Abort")
|
||||
return
|
||||
|
|
|
@ -64,6 +64,10 @@
|
|||
import { GlobeEuropeAfrica } from "@babeard/svelte-heroicons/solid/GlobeEuropeAfrica"
|
||||
import { onDestroy } from "svelte"
|
||||
import Avatar from "../Base/Avatar.svelte"
|
||||
import { SpecialVisualizationSvelte } from "../SpecialVisualization"
|
||||
import ThemeViewState from "../../Models/ThemeViewState"
|
||||
import { Changes } from "../../Logic/Osm/Changes"
|
||||
import PendingChangesView from "./PendingChangesView.svelte"
|
||||
|
||||
export let state: {
|
||||
favourites: FavouritesFeatureSource
|
||||
|
@ -73,6 +77,7 @@
|
|||
featureSwitches: Partial<FeatureSwitchState>
|
||||
mapProperties?: MapProperties
|
||||
userRelatedState?: UserRelatedState
|
||||
changes?: Changes
|
||||
}
|
||||
let userdetails = state.osmConnection.userDetails
|
||||
|
||||
|
@ -81,6 +86,7 @@
|
|||
let featureSwitches = state.featureSwitches
|
||||
let showHome = featureSwitches?.featureSwitchBackToThemeOverview
|
||||
let pg = state.guistate.pageStates
|
||||
let pendingChanges = state?.changes?.pendingChanges
|
||||
export let onlyLink: boolean
|
||||
const t = Translations.t.general.menu
|
||||
let shown = new UIEventSource(state.guistate.pageStates.menu.data || !onlyLink)
|
||||
|
@ -164,12 +170,14 @@
|
|||
/>
|
||||
</Page>
|
||||
|
||||
{#if $nrOfFailedImages.length > 0 || $failedImagesOpen}
|
||||
{#if $nrOfFailedImages.length > 0 || $failedImagesOpen || $pendingChanges?.length > 0 }
|
||||
<Page {onlyLink} shown={pg.failedImages} bodyPadding="p-0 pb-4">
|
||||
<svelte:fragment slot="header">
|
||||
<PhotoIcon />
|
||||
<Tr t={Translations.t.imageQueue.menu.Subs({ count: $nrOfFailedImages.length })} />
|
||||
<Tr
|
||||
t={Translations.t.imageQueue.menu.Subs({ count: ($nrOfFailedImages?.length ?? 0) + ($pendingChanges?.length ?? 0) })} />
|
||||
</svelte:fragment>
|
||||
<PendingChangesView {state} />
|
||||
<QueuedImagesView {state} />
|
||||
</Page>
|
||||
{/if}
|
||||
|
|
58
src/UI/BigComponents/PendingChangesView.svelte
Normal file
58
src/UI/BigComponents/PendingChangesView.svelte
Normal file
|
@ -0,0 +1,58 @@
|
|||
<script lang="ts">
|
||||
import { Changes } from "../../Logic/Osm/Changes"
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||
|
||||
export let state: { changes: Changes } & SpecialVisualizationState
|
||||
let pending = state.changes.pendingChanges
|
||||
let backend = state.osmConnection.Backend()
|
||||
let debug = state.featureSwitches.featureSwitchIsDebugging
|
||||
</script>
|
||||
{#if $pending?.length > 0}
|
||||
<div class="p-4">
|
||||
|
||||
<h3>Pending changes</h3>
|
||||
|
||||
There are currently {$pending.length} pending changes:
|
||||
|
||||
<table class="gap-x-2">
|
||||
<tr>
|
||||
<th>
|
||||
Theme
|
||||
</th>
|
||||
<th>
|
||||
Type
|
||||
</th>
|
||||
<th>
|
||||
Object
|
||||
</th>
|
||||
</tr>
|
||||
{#each $pending as change}
|
||||
<tr>
|
||||
<td>{change.meta.theme}</td>
|
||||
<td>{change.meta.changeType}</td>
|
||||
<td>
|
||||
<a href={`${backend}/${change.type}/${change.id}`} target="_blank">
|
||||
{change.type}/{change.id}
|
||||
</a>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{/each}
|
||||
</table>
|
||||
|
||||
{#if $debug}
|
||||
{#each $pending as change}
|
||||
{JSON.stringify(change)}
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{/if}
|
||||
|
||||
|
||||
<style>
|
||||
td {
|
||||
padding-left: 2rem;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
</style>
|
|
@ -8,9 +8,11 @@
|
|||
import type { ImageUploadArguments } from "../../Logic/ImageProviders/ImageUploadQueue"
|
||||
import { Store } from "../../Logic/UIEventSource"
|
||||
import UploadingImageCounter from "./UploadingImageCounter.svelte"
|
||||
import { IsOnline } from "../../Logic/Web/IsOnline"
|
||||
export let state: WithImageState
|
||||
let queued: Store<ImageUploadArguments[]> = state.imageUploadManager.queuedArgs
|
||||
let isUploading = state.imageUploadManager.isUploading
|
||||
let online = IsOnline.isOnline
|
||||
const t = Translations.t
|
||||
const q = t.imageQueue
|
||||
</script>
|
||||
|
@ -27,7 +29,7 @@
|
|||
|
||||
{#if $isUploading}
|
||||
<Loading />
|
||||
{:else}
|
||||
{:else if $online}
|
||||
<button class="primary" on:click={() => state.imageUploadManager.uploadQueue()}>
|
||||
<ArrowPathIcon class="m-1 h-8 w-8" />
|
||||
<Tr t={q.retryAll} />
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
let maintenanceBusy = false
|
||||
</script>
|
||||
|
||||
<LoginToggle {state}>
|
||||
<LoginToggle {state} offline>
|
||||
<LoginButton clss="small w-full" osmConnection={state.osmConnection} slot="not-logged-in">
|
||||
<Tr t={Translations.t.image.pleaseLogin} />
|
||||
</LoginButton>
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
import Tr from "../Base/Tr.svelte"
|
||||
import Loading from "../Base/Loading.svelte"
|
||||
import UploadFailedMessage from "./UploadFailedMessage.svelte"
|
||||
import { IsOnline } from "../../Logic/Web/IsOnline"
|
||||
|
||||
export let state: SpecialVisualizationState
|
||||
export let tags: Store<OsmTags> = undefined
|
||||
|
@ -59,6 +60,7 @@
|
|||
failed.addCallbackAndRun((failed) => {
|
||||
dismissed = Math.min(failed, dismissed)
|
||||
})
|
||||
let online = IsOnline.isOnline
|
||||
let progress = state.imageUploadManager.progressCurrentImage
|
||||
</script>
|
||||
|
||||
|
@ -91,8 +93,11 @@
|
|||
</Loading>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if $failed > dismissed}
|
||||
{#if !$online}
|
||||
<div class="alert">
|
||||
<Tr t={t.upload.offline} />
|
||||
</div>
|
||||
{:else if $failed > dismissed}
|
||||
<UploadFailedMessage failed={$failed} on:click={() => (dismissed = $failed)} {state} />
|
||||
{/if}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue