MapComplete/src/UI/SpecialVisualisations/NoteVisualisations.ts

199 lines
6.4 KiB
TypeScript
Raw Normal View History

2025-07-10 18:26:31 +02:00
import {
SpecialVisualization,
SpecialVisualizationState,
SpecialVisualizationSvelte,
} from "../SpecialVisualization"
import Constants from "../../Models/Constants"
import { UIEventSource } from "../../Logic/UIEventSource"
import { Feature } from "geojson"
import { GeoOperations } from "../../Logic/GeoOperations"
import SvelteUIElement from "../Base/SvelteUIElement"
import CreateNewNote from "../Popup/Notes/CreateNewNote.svelte"
import { Utils } from "../../Utils"
import CloseNoteButton from "../Popup/Notes/CloseNoteButton.svelte"
import Translations from "../i18n/Translations"
import AddNoteComment from "../Popup/Notes/AddNoteComment.svelte"
import UploadImage from "../Image/UploadImage.svelte"
import { VariableUiElement } from "../Base/VariableUIElement"
import Combine from "../Base/Combine"
import NoteCommentElement from "../Popup/Notes/NoteCommentElement.svelte"
import { ServerSourceInfo } from "../../Models/SourceOverview"
class CloseNoteViz extends SpecialVisualizationSvelte {
public readonly funcName = "close_note"
public readonly needsUrls: ServerSourceInfo[] = [Constants.osmAuthConfig, Constants.panoramax]
public readonly docs =
"Button to close a note. A predefined text can be defined to close the note with. If the note is already closed, will show a small text."
public readonly args = [
{
name: "text",
doc: "Text to show on this button",
2025-02-10 02:04:58 +01:00
required: true,
},
{
name: "icon",
doc: "Icon to show",
2025-02-10 02:04:58 +01:00
defaultValue: "checkmark.svg",
},
{
name: "idkey",
doc: "The property name where the ID of the note to close can be found",
2025-02-10 02:04:58 +01:00
defaultValue: "id",
},
{
name: "comment",
2025-02-10 02:04:58 +01:00
doc: "Text to add onto the note when closing",
},
{
name: "minZoom",
2025-02-10 02:04:58 +01:00
doc: "If set, only show the closenote button if zoomed in enough",
},
{
name: "zoomButton",
2025-02-10 02:04:58 +01:00
doc: "Text to show if not zoomed in enough",
},
]
public readonly group = "notes"
public constr(
state: SpecialVisualizationState,
tags: UIEventSource<Record<string, string>>,
2025-07-10 18:26:31 +02:00
args: string[]
): SvelteUIElement {
const { text, icon, idkey, comment, minZoom, zoomButton } = Utils.ParseVisArgs(
this.args,
2025-07-10 18:26:31 +02:00
args
)
return new SvelteUIElement(CloseNoteButton, {
state,
tags,
icon,
idkey,
message: comment,
text: Translations.T(text),
minzoom: minZoom,
2025-02-10 02:04:58 +01:00
zoomMoreMessage: zoomButton,
})
}
}
class AddNoteCommentViz extends SpecialVisualizationSvelte {
funcName = "add_note_comment"
needsUrls = [Constants.osmAuthConfig]
docs = "A textfield to add a comment to a node (with the option to close the note)."
args = [
{
name: "Id-key",
doc: "The property name where the ID of the note to close can be found",
2025-02-10 02:04:58 +01:00
defaultValue: "id",
},
]
public readonly group = "notes"
2025-02-10 02:04:58 +01:00
public constr(
state: SpecialVisualizationState,
2025-07-10 18:26:31 +02:00
tags: UIEventSource<Record<string, string>>
2025-02-10 02:04:58 +01:00
): SvelteUIElement {
return new SvelteUIElement(AddNoteComment, { state, tags })
}
}
class OpenNote extends SpecialVisualizationSvelte {
funcName = "open_note"
args = []
group = "notes"
needsUrls = [Constants.osmAuthConfig]
2025-07-10 18:26:31 +02:00
docs =
"Creates a new map note on the given location. This options is placed in the 'last_click'-popup automatically if the 'notes'-layer is enabled"
constr(
state: SpecialVisualizationState,
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
2025-07-10 18:26:31 +02:00
feature: Feature
): SvelteUIElement {
const [lon, lat] = GeoOperations.centerpointCoordinates(feature)
return new SvelteUIElement(CreateNewNote, {
state,
coordinate: new UIEventSource({ lon, lat }),
})
}
}
class AddImageToNote extends SpecialVisualizationSvelte {
funcName = "add_image_to_note"
docs = "Adds an image to a node"
args = [
{
name: "Id-key",
doc: "The property name where the ID of the note to close can be found",
defaultValue: "id",
},
]
group = "notes"
needsUrls = []
constr(state, tags, args, feature) {
const id = tags.data[args[0] ?? "id"]
tags = state.featureProperties.getStore(id)
return new SvelteUIElement(UploadImage, { state, tags, feature })
}
}
class VisualiseNoteComment extends SpecialVisualization {
funcName = "visualize_note_comments"
group = "notes"
docs = "Visualises the comments for notes"
args = [
{
name: "commentsKey",
doc: "The property name of the comments, which should be stringified json",
defaultValue: "comments",
},
{
name: "start",
doc: "Drop the first 'start' comments",
defaultValue: "0",
},
]
needsUrls = [Constants.osmAuthConfig]
constr(state, tags, args) {
return new VariableUiElement(
tags
.map((tags) => tags[args[0]])
.map((commentsStr) => {
const comments: { text: string }[] = JSON.parse(commentsStr)
const startLoc = Number(args[1] ?? 0)
if (!isNaN(startLoc) && startLoc > 0) {
comments.splice(0, startLoc)
}
return new Combine(
comments
.filter((c) => c.text !== "")
.map(
(comment) =>
new SvelteUIElement(NoteCommentElement, {
comment,
state,
2025-07-10 18:26:31 +02:00
})
)
).SetClass("flex flex-col")
2025-07-10 18:26:31 +02:00
})
)
}
}
export class NoteVisualisations {
public static initList(): (SpecialVisualization & { group })[] {
2025-02-10 02:04:58 +01:00
return [
new AddNoteCommentViz(),
new CloseNoteViz(),
new OpenNote(),
new AddImageToNote(),
new VisualiseNoteComment(),
]
}
}