forked from MapComplete/MapComplete
Merge branch 'master' into develop
This commit is contained in:
commit
969a878bb1
10 changed files with 64 additions and 30 deletions
|
@ -164,7 +164,7 @@
|
||||||
"special": {
|
"special": {
|
||||||
"classes": "p-2 m-1 my-4 border-2 border-dashed border-black",
|
"classes": "p-2 m-1 my-4 border-2 border-dashed border-black",
|
||||||
"key": "_nearby_osm_poi:props",
|
"key": "_nearby_osm_poi:props",
|
||||||
"tagrendering": "<b><a href='#{id}'>{id}</a></b> ({_distance}m, {openbenches:id}) {minimap(17,id;_original:id)} {tag_apply($_original:tags,Link this object.,link,id,_original:id)}",
|
"tagrendering": "<b><a href='#{id}'>{id}</a></b> ({_distance}m, {openbenches:id}) {minimap(17,id;_original:id)} {tag_apply($_original:tags,Link this object.,link,id,_original:id,import:attribute)}",
|
||||||
"type": "multi"
|
"type": "multi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -608,6 +608,7 @@
|
||||||
"doDelete": "Remove image",
|
"doDelete": "Remove image",
|
||||||
"isDeleted": "Deleted",
|
"isDeleted": "Deleted",
|
||||||
"loadingFailed": "Loading this image failed",
|
"loadingFailed": "Loading this image failed",
|
||||||
|
"maintenance": "Due to maintenance, uploading images is currently not possible. Sorry about this!",
|
||||||
"mapillaryTrackingProtection": "Strict tracking protection blocks loading images from Mapillary, as Mapillary is owned by Facebook/Meta. Disable strict tracking protection if you want to see this image.",
|
"mapillaryTrackingProtection": "Strict tracking protection blocks loading images from Mapillary, as Mapillary is owned by Facebook/Meta. Disable strict tracking protection if you want to see this image.",
|
||||||
"nearby": {
|
"nearby": {
|
||||||
"close": "Collapse panel with nearby images",
|
"close": "Collapse panel with nearby images",
|
||||||
|
@ -617,6 +618,7 @@
|
||||||
"seeNearby": "Browse nearby pictures",
|
"seeNearby": "Browse nearby pictures",
|
||||||
"title": "Nearby streetview imagery"
|
"title": "Nearby streetview imagery"
|
||||||
},
|
},
|
||||||
|
"noteReopen": "Adding a picture will reopen the note",
|
||||||
"openOnWebsite": "Open this image on {name}",
|
"openOnWebsite": "Open this image on {name}",
|
||||||
"panoramax": {
|
"panoramax": {
|
||||||
"deletionRequested": "The report has been sent. A moderator will look to it shortly",
|
"deletionRequested": "The report has been sent. A moderator will look to it shortly",
|
||||||
|
|
|
@ -221,6 +221,7 @@ export class GenerateDocs extends Script {
|
||||||
this.generateSidebar("nl")
|
this.generateSidebar("nl")
|
||||||
|
|
||||||
this.generatedPaths.push(".gitignore")
|
this.generatedPaths.push(".gitignore")
|
||||||
|
this.generatedPaths.push("nl/index.html")
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
"./Docs/.gitignore",
|
"./Docs/.gitignore",
|
||||||
this.generatedPaths.map((p) => p.replace("./Docs/", "")).join("\n"),
|
this.generatedPaths.map((p) => p.replace("./Docs/", "")).join("\n"),
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
import type { Feature } from "geojson"
|
import type { Feature } from "geojson"
|
||||||
import Camera from "@babeard/svelte-heroicons/mini/Camera"
|
import Camera from "@babeard/svelte-heroicons/mini/Camera"
|
||||||
import ArrowUpTray from "@babeard/svelte-heroicons/solid/ArrowUpTray"
|
import ArrowUpTray from "@babeard/svelte-heroicons/solid/ArrowUpTray"
|
||||||
|
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||||
|
import NoteCommentElement from "../Popup/Notes/NoteCommentElement"
|
||||||
|
|
||||||
export let state: SpecialVisualizationState
|
export let state: SpecialVisualizationState
|
||||||
|
|
||||||
|
@ -23,6 +25,7 @@
|
||||||
export let targetKey: string = undefined
|
export let targetKey: string = undefined
|
||||||
export let noBlur: boolean = false
|
export let noBlur: boolean = false
|
||||||
export let feature: Feature
|
export let feature: Feature
|
||||||
|
export let layer: LayerConfig
|
||||||
/**
|
/**
|
||||||
* Image to show in the button
|
* Image to show in the button
|
||||||
* NOT the image to upload!
|
* NOT the image to upload!
|
||||||
|
@ -33,6 +36,8 @@
|
||||||
}
|
}
|
||||||
export let labelText: string = undefined
|
export let labelText: string = undefined
|
||||||
const t = Translations.t.image
|
const t = Translations.t.image
|
||||||
|
const isNote = layer.id === "note"
|
||||||
|
const noteIsOpened = tags.mapD(tags => tags.closed_at === undefined)
|
||||||
|
|
||||||
let errors = new UIEventSource<Translation[]>([])
|
let errors = new UIEventSource<Translation[]>([])
|
||||||
|
|
||||||
|
@ -47,7 +52,15 @@
|
||||||
errs.push(canBeUploaded.error)
|
errs.push(canBeUploaded.error)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
await state?.imageUploadManager?.uploadImageAndApply(
|
|
||||||
|
if (isNote) {
|
||||||
|
if (!noteIsOpened.data) {
|
||||||
|
await state.osmConnection.reopenNote(tags.data.id)
|
||||||
|
NoteCommentElement.mimickStatusChange(tags, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state?.imageUploadManager?.uploadImageAndApply(
|
||||||
file,
|
file,
|
||||||
tags,
|
tags,
|
||||||
targetKey,
|
targetKey,
|
||||||
|
@ -72,7 +85,7 @@
|
||||||
</LoginButton>
|
</LoginButton>
|
||||||
{#if maintenanceBusy}
|
{#if maintenanceBusy}
|
||||||
<div class="alert">
|
<div class="alert">
|
||||||
Due to maintenance, uploading images is currently not possible. Sorry about this!
|
<Tr t={Translations.t.image.maintenance}></Tr>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="my-4 flex flex-col">
|
<div class="my-4 flex flex-col">
|
||||||
|
@ -109,6 +122,9 @@
|
||||||
<Tr t={t.upload.noBlur} />
|
<Tr t={t.upload.noBlur} />
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if isNote && !$noteIsOpened}
|
||||||
|
<Tr t={t.noteReopen} />
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</FileSelector>
|
</FileSelector>
|
||||||
|
@ -150,14 +166,20 @@
|
||||||
<Tr t={t.upload.noBlur} />
|
<Tr t={t.upload.noBlur} />
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if isNote && !$noteIsOpened}
|
||||||
|
<Tr t={t.noteReopen} />
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</FileSelector>
|
</FileSelector>
|
||||||
|
|
||||||
|
|
||||||
<div class="subtle text-xs italic">
|
<div class="subtle text-xs italic">
|
||||||
<Tr t={Translations.t.general.attribution.panoramaxLicenseCCBYSA} />
|
<Tr t={Translations.t.general.attribution.panoramaxLicenseCCBYSA} />
|
||||||
<span class="mx-1">—</span>
|
<span class="mx-1">—</span>
|
||||||
<Tr t={t.respectPrivacy} />
|
<Tr t={t.respectPrivacy} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</LoginToggle>
|
</LoginToggle>
|
||||||
|
|
|
@ -7,6 +7,7 @@ import Maproulette from "../../../Logic/Maproulette"
|
||||||
import { GeoOperations } from "../../../Logic/GeoOperations"
|
import { GeoOperations } from "../../../Logic/GeoOperations"
|
||||||
import { Tag } from "../../../Logic/Tags/Tag"
|
import { Tag } from "../../../Logic/Tags/Tag"
|
||||||
import { SpecialVisualizationState } from "../../SpecialVisualization"
|
import { SpecialVisualizationState } from "../../SpecialVisualization"
|
||||||
|
import NoteCommentElement from "../Notes/NoteCommentElement"
|
||||||
|
|
||||||
export interface PointImportFlowArguments extends ImportFlowArguments {
|
export interface PointImportFlowArguments extends ImportFlowArguments {
|
||||||
max_snap_distance?: string
|
max_snap_distance?: string
|
||||||
|
@ -74,8 +75,7 @@ export class PointImportFlowState extends ImportFlow<PointImportFlowArguments> {
|
||||||
|
|
||||||
if (note_id !== undefined) {
|
if (note_id !== undefined) {
|
||||||
await this.state.osmConnection.closeNote(note_id, "imported")
|
await this.state.osmConnection.closeNote(note_id, "imported")
|
||||||
originalFeatureTags.data["closed_at"] = new Date().toISOString()
|
NoteCommentElement.mimickStatusChange(originalFeatureTags, false)
|
||||||
originalFeatureTags.ping()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const maproulette_id = originalFeatureTags.data[this.args.maproulette_id]
|
const maproulette_id = originalFeatureTags.data[this.args.maproulette_id]
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
if (isClosed.data) {
|
if (isClosed.data) {
|
||||||
await state.osmConnection.reopenNote(id, txt.data)
|
await state.osmConnection.reopenNote(id, txt.data)
|
||||||
await state.osmConnection.closeNote(id)
|
await state.osmConnection.closeNote(id)
|
||||||
|
NoteCommentElement.mimickStatusChange(tags, false)
|
||||||
} else {
|
} else {
|
||||||
await state.osmConnection.addCommentToNote(id, txt.data)
|
await state.osmConnection.addCommentToNote(id, txt.data)
|
||||||
}
|
}
|
||||||
|
@ -54,16 +55,15 @@
|
||||||
async function closeNote() {
|
async function closeNote() {
|
||||||
isProcessing.set(true)
|
isProcessing.set(true)
|
||||||
await state.osmConnection.closeNote(id, txt.data)
|
await state.osmConnection.closeNote(id, txt.data)
|
||||||
isProcessing.set(false)
|
|
||||||
tags.data["closed_at"] = new Date().toISOString()
|
|
||||||
NoteCommentElement.addCommentTo(txt.data, tags, state)
|
NoteCommentElement.addCommentTo(txt.data, tags, state)
|
||||||
tags.ping()
|
NoteCommentElement.mimickStatusChange(tags, false) // Will ping
|
||||||
|
isProcessing.set(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function reopenNote() {
|
async function reopenNote() {
|
||||||
isProcessing.set(true)
|
isProcessing.set(true)
|
||||||
await state.osmConnection.reopenNote(id, txt.data)
|
await state.osmConnection.reopenNote(id, txt.data)
|
||||||
tags.data["closed_at"] = undefined
|
NoteCommentElement.mimickStatusChange(tags, true)
|
||||||
NoteCommentElement.addCommentTo(txt.data, tags, state)
|
NoteCommentElement.addCommentTo(txt.data, tags, state)
|
||||||
tags.ping()
|
tags.ping()
|
||||||
txt.set(undefined)
|
txt.set(undefined)
|
||||||
|
|
|
@ -26,8 +26,7 @@
|
||||||
const id = tags.data[idkey]
|
const id = tags.data[idkey]
|
||||||
await state.osmConnection.closeNote(id, message)
|
await state.osmConnection.closeNote(id, message)
|
||||||
NoteCommentElement.addCommentTo(message, tags, state)
|
NoteCommentElement.addCommentTo(message, tags, state)
|
||||||
tags.data["closed_at"] = new Date().toISOString()
|
NoteCommentElement.mimickStatusChange(tags, false)
|
||||||
tags.ping()
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,17 @@
|
||||||
import { Store, UIEventSource } from "../../../Logic/UIEventSource"
|
import { Store, UIEventSource } from "../../../Logic/UIEventSource"
|
||||||
|
|
||||||
export default class NoteCommentElement {
|
export default class NoteCommentElement {
|
||||||
|
|
||||||
|
public static mimickStatusChange(tags: UIEventSource<Record<string, string>>, opened: boolean) {
|
||||||
|
if (opened) {
|
||||||
|
tags.data.status = "open"
|
||||||
|
tags.data.closed_at = undefined
|
||||||
|
} else {
|
||||||
|
tags.data.status = "closed"
|
||||||
|
tags.data.closed_at = new Date().toISOString()
|
||||||
|
}
|
||||||
|
tags.ping()
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Adds the comment to the _visualisation_ of the given note; doesn't _actually_ upload
|
* Adds the comment to the _visualisation_ of the given note; doesn't _actually_ upload
|
||||||
* @param txt
|
* @param txt
|
||||||
|
@ -16,9 +27,9 @@ export default class NoteCommentElement {
|
||||||
const username = state.osmConnection.userDetails.data.name
|
const username = state.osmConnection.userDetails.data.name
|
||||||
|
|
||||||
const urlRegex = /(https?:\/\/[^\s]+)/g
|
const urlRegex = /(https?:\/\/[^\s]+)/g
|
||||||
const html = txt.replace(urlRegex, function (url) {
|
const html = txt?.replace(urlRegex, function(url) {
|
||||||
return '<a href="' + url + '">' + url + "</a>"
|
return '<a href="' + url + '">' + url + "</a>"
|
||||||
})
|
}) ?? ""
|
||||||
|
|
||||||
comments.push({
|
comments.push({
|
||||||
date: new Date().toISOString(),
|
date: new Date().toISOString(),
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
import {
|
import { SpecialVisualisationParams, SpecialVisualization, SpecialVisualizationSvelte } from "../SpecialVisualization"
|
||||||
SpecialVisualisationParams,
|
|
||||||
SpecialVisualization,
|
|
||||||
SpecialVisualizationSvelte,
|
|
||||||
} from "../SpecialVisualization"
|
|
||||||
import Constants from "../../Models/Constants"
|
import Constants from "../../Models/Constants"
|
||||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||||
import { Feature } from "geojson"
|
import { Feature } from "geojson"
|
||||||
|
@ -126,10 +122,10 @@ class AddImageToNote extends SpecialVisualizationSvelte {
|
||||||
group = "notes"
|
group = "notes"
|
||||||
needsUrls = []
|
needsUrls = []
|
||||||
|
|
||||||
constr({ state, tags, args, feature }: SpecialVisualisationParams) {
|
constr(params: SpecialVisualisationParams) {
|
||||||
const id = tags.data[args[0] ?? "id"]
|
const id = params.tags.data[params.args[0] ?? "id"]
|
||||||
tags = state.featureProperties.getStore(id)
|
const tags = params.state.featureProperties.getStore(id)
|
||||||
return new SvelteUIElement(UploadImage, { state, tags, feature })
|
return new SvelteUIElement(UploadImage, { ...params, tags })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
import { AutoAction } from "../Popup/AutoApplyButtonVis"
|
import { AutoAction } from "../Popup/AutoApplyButtonVis"
|
||||||
import {
|
import { SpecialVisualisationParams, SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization"
|
||||||
SpecialVisualisationParams,
|
|
||||||
SpecialVisualization,
|
|
||||||
SpecialVisualizationState,
|
|
||||||
} from "../SpecialVisualization"
|
|
||||||
import { Utils } from "../../Utils"
|
import { Utils } from "../../Utils"
|
||||||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||||
import { Tag } from "../../Logic/Tags/Tag"
|
import { Tag } from "../../Logic/Tags/Tag"
|
||||||
|
@ -47,6 +43,11 @@ export default class TagApplyViz extends SpecialVisualization implements AutoAct
|
||||||
defaultValue: undefined,
|
defaultValue: undefined,
|
||||||
doc: "If specified, this maproulette-challenge will be closed when the tags are applied. This should be the `id` of the individual task, _not_ the task_id (which corresponds with the challenge).",
|
doc: "If specified, this maproulette-challenge will be closed when the tags are applied. This should be the `id` of the individual task, _not_ the task_id (which corresponds with the challenge).",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "changeset_type",
|
||||||
|
defaultValue: "answer",
|
||||||
|
doc: "If set, this attribute will be set on the changeset. A typical example is `answer` if it answers a question or `import:attribute` if attributes are copied"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
public readonly example =
|
public readonly example =
|
||||||
"`{tag_apply(survey_date=$_now:date, Surveyed today!)}`, `{tag_apply(addr:street=$addr:street, Apply the address, apply_icon.svg, _closest_osm_id)"
|
"`{tag_apply(survey_date=$_now:date, Surveyed today!)}`, `{tag_apply(addr:street=$addr:street, Apply the address, apply_icon.svg, _closest_osm_id)"
|
||||||
|
@ -133,7 +134,8 @@ export default class TagApplyViz extends SpecialVisualization implements AutoAct
|
||||||
_: Feature,
|
_: Feature,
|
||||||
state: SpecialVisualizationState,
|
state: SpecialVisualizationState,
|
||||||
tags: UIEventSource<any>,
|
tags: UIEventSource<any>,
|
||||||
args: string[]
|
args: string[],
|
||||||
|
changesetMetaattribute: string = "change"
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const tagsToApply = TagApplyViz.generateTagsToApply(args[0], tags)
|
const tagsToApply = TagApplyViz.generateTagsToApply(args[0], tags)
|
||||||
const targetIdKey = args[3]
|
const targetIdKey = args[3]
|
||||||
|
@ -145,7 +147,7 @@ export default class TagApplyViz extends SpecialVisualization implements AutoAct
|
||||||
tags.data, // We pass in the tags of the selected element, not the tags of the target element!
|
tags.data, // We pass in the tags of the selected element, not the tags of the target element!
|
||||||
{
|
{
|
||||||
theme: state.theme.id,
|
theme: state.theme.id,
|
||||||
changeType: "answer",
|
changeType: changesetMetaattribute
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
await state.changes.applyAction(changeAction)
|
await state.changes.applyAction(changeAction)
|
||||||
|
@ -184,12 +186,13 @@ export default class TagApplyViz extends SpecialVisualization implements AutoAct
|
||||||
let image = args[2]?.trim()
|
let image = args[2]?.trim()
|
||||||
const targetIdKey = args[3]
|
const targetIdKey = args[3]
|
||||||
const maprouletteId = args[4]
|
const maprouletteId = args[4]
|
||||||
|
const changeType = args[5]
|
||||||
if (image === "" || image === "undefined") {
|
if (image === "" || image === "undefined") {
|
||||||
image = undefined
|
image = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const onApply = async () => {
|
const onApply = async () => {
|
||||||
await this.applyActionOn(feature, state, tags, args)
|
await this.applyActionOn(feature, state, tags, args, changeType)
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SvelteUIElement(TagApplyButton, {
|
return new SvelteUIElement(TagApplyButton, {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue