import Combine from "../Base/Combine" import { OsmConnection } from "../../Logic/Osm/OsmConnection" import { UIEventSource } from "../../Logic/UIEventSource" import Title from "../Base/Title" import Toggle from "../Input/Toggle" import Loading from "../Base/Loading" import { VariableUiElement } from "../Base/VariableUIElement" import { FixedUiElement } from "../Base/FixedUiElement" import { SubtleButton } from "../Base/SubtleButton" import Svg from "../../Svg" import Translations from "../i18n/Translations" import { Translation } from "../i18n/Translation" export class CreateNotes extends Combine { public static createNoteContentsUi( feature: { properties: any; geometry: { coordinates: [number, number] } }, options: { wikilink: string; intro: string; source: string; theme: string } ): (Translation | string)[] { const src = feature.properties["source"] ?? feature.properties["src"] ?? options.source delete feature.properties["source"] delete feature.properties["src"] let extraNote = "" if (feature.properties["note"]) { extraNote = feature.properties["note"] + "\n" delete feature.properties["note"] } const tags: string[] = [] for (const key in feature.properties) { if (feature.properties[key] === null || feature.properties[key] === undefined) { console.warn("Null or undefined key for ", feature.properties) continue } if (feature.properties[key] === "") { continue } tags.push( key + "=" + (feature.properties[key] + "") .replace(/=/, "\\=") .replace(/;/g, "\\;") .replace(/\n/g, "\\n") ) } const lat = feature.geometry.coordinates[1] const lon = feature.geometry.coordinates[0] const note = Translations.t.importHelper.noteParts return [ options.intro, extraNote, note.datasource.Subs({ source: src }), note.wikilink.Subs(options), "", note.importEasily, `https://mapcomplete.osm.be/${options.theme}.html?z=18&lat=${lat}&lon=${lon}#import`, ...tags, ] } public static createNoteContents( feature: { properties: any; geometry: { coordinates: [number, number] } }, options: { wikilink: string; intro: string; source: string; theme: string } ): string[] { return CreateNotes.createNoteContentsUi(feature, options).map((trOrStr) => { if (typeof trOrStr === "string") { return trOrStr } return trOrStr.txt }) } constructor( state: { osmConnection: OsmConnection }, v: { features: any[]; wikilink: string; intro: string; source: string; theme: string } ) { const t = Translations.t.importHelper.createNotes const createdNotes: UIEventSource = new UIEventSource([]) const failed = new UIEventSource([]) const currentNote = createdNotes.map((n) => n.length) for (const f of v.features) { const lat = f.geometry.coordinates[1] const lon = f.geometry.coordinates[0] const text = CreateNotes.createNoteContents(f, v).join("\n") state.osmConnection.openNote(lat, lon, text).then( ({ id }) => { createdNotes.data.push(id) createdNotes.ping() }, (err) => { failed.data.push(err) failed.ping() } ) } super([ new Title(t.title), t.loading, new Toggle( new Loading( new VariableUiElement( currentNote.map((count) => t.creating.Subs({ count, total: v.features.length, }) ) ) ), new Combine([ Svg.party_svg().SetClass("w-24"), t.done.Subs({ count: v.features.length }).SetClass("thanks"), new SubtleButton(Svg.note_svg(), t.openImportViewer, { url: "import_viewer.html", }), ]), currentNote.map((count) => count < v.features.length) ), new VariableUiElement( failed.map((failed) => { if (failed.length === 0) { return undefined } return new Combine([ new FixedUiElement("Some entries failed").SetClass("alert"), ...failed, ]).SetClass("flex flex-col") }) ), ]) this.SetClass("flex flex-col") } }