Add 'add new note' functionality, fix bug where 'test'-theme comes up when deleting images
This commit is contained in:
parent
e562975f6b
commit
6ae8ec8036
16 changed files with 212 additions and 59 deletions
23
Docs/TagInfo/mapcomplete_notes.json
Normal file
23
Docs/TagInfo/mapcomplete_notes.json
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"data_format": 1,
|
||||||
|
"project": {
|
||||||
|
"name": "MapComplete Notes on OpenStreetMap",
|
||||||
|
"description": "A note is a pin on the map with some text to indicate something wrong",
|
||||||
|
"project_url": "https://mapcomplete.osm.be/notes",
|
||||||
|
"doc_url": "https://github.com/pietervdvn/MapComplete/tree/master/assets/themes/",
|
||||||
|
"icon_url": "https://mapcomplete.osm.be/assets/svg/resolved.svg",
|
||||||
|
"contact_name": "Pieter Vander Vennet, MapComplete",
|
||||||
|
"contact_email": "pietervdvn@posteo.net"
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"key": "id",
|
||||||
|
"description": "The MapComplete theme Notes on OpenStreetMap has a layer OpenStreetMap notes showing features with this tag"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "id",
|
||||||
|
"description": "The MapComplete theme Notes on OpenStreetMap has a layer Your track showing features with this tag",
|
||||||
|
"value": "location_track"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
import * as L from "leaflet";
|
import * as L from "leaflet";
|
||||||
import {UIEventSource} from "../UIEventSource";
|
import {UIEventSource} from "../UIEventSource";
|
||||||
import ScrollableFullScreen from "../../UI/Base/ScrollableFullScreen";
|
import ScrollableFullScreen from "../../UI/Base/ScrollableFullScreen";
|
||||||
import AddNewMarker from "../../UI/BigComponents/AddNewMarker";
|
|
||||||
import FilteredLayer from "../../Models/FilteredLayer";
|
import FilteredLayer from "../../Models/FilteredLayer";
|
||||||
import Constants from "../../Models/Constants";
|
import Constants from "../../Models/Constants";
|
||||||
|
import BaseUIElement from "../../UI/BaseUIElement";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The stray-click-hanlders adds a marker to the map if no feature was clicked.
|
* The stray-click-hanlders adds a marker to the map if no feature was clicked.
|
||||||
|
@ -13,37 +13,41 @@ export default class StrayClickHandler {
|
||||||
private _lastMarker;
|
private _lastMarker;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
lastClickLocation: UIEventSource<{ lat: number, lon: number }>,
|
state: {
|
||||||
selectedElement: UIEventSource<string>,
|
LastClickLocation: UIEventSource<{ lat: number, lon: number }>,
|
||||||
filteredLayers: UIEventSource<FilteredLayer[]>,
|
selectedElement: UIEventSource<string>,
|
||||||
leafletMap: UIEventSource<L.Map>,
|
filteredLayers: UIEventSource<FilteredLayer[]>,
|
||||||
uiToShow: ScrollableFullScreen) {
|
leafletMap: UIEventSource<L.Map>
|
||||||
|
},
|
||||||
|
uiToShow: ScrollableFullScreen,
|
||||||
|
iconToShow: BaseUIElement) {
|
||||||
const self = this;
|
const self = this;
|
||||||
filteredLayers.data.forEach((filteredLayer) => {
|
const leafletMap = state.leafletMap
|
||||||
|
state.filteredLayers.data.forEach((filteredLayer) => {
|
||||||
filteredLayer.isDisplayed.addCallback(isEnabled => {
|
filteredLayer.isDisplayed.addCallback(isEnabled => {
|
||||||
if (isEnabled && self._lastMarker && leafletMap.data !== undefined) {
|
if (isEnabled && self._lastMarker && leafletMap.data !== undefined) {
|
||||||
// When a layer is activated, we remove the 'last click location' in order to force the user to reclick
|
// When a layer is activated, we remove the 'last click location' in order to force the user to reclick
|
||||||
// This reclick might be at a location where a feature now appeared...
|
// This reclick might be at a location where a feature now appeared...
|
||||||
leafletMap.data.removeLayer(self._lastMarker);
|
state.leafletMap.data.removeLayer(self._lastMarker);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
lastClickLocation.addCallback(function (lastClick) {
|
state.LastClickLocation.addCallback(function (lastClick) {
|
||||||
|
|
||||||
if (self._lastMarker !== undefined) {
|
if (self._lastMarker !== undefined) {
|
||||||
leafletMap.data?.removeLayer(self._lastMarker);
|
state.leafletMap.data?.removeLayer(self._lastMarker);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastClick === undefined) {
|
if (lastClick === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedElement.setData(undefined);
|
state.selectedElement.setData(undefined);
|
||||||
const clickCoor: [number, number] = [lastClick.lat, lastClick.lon]
|
const clickCoor: [number, number] = [lastClick.lat, lastClick.lon]
|
||||||
self._lastMarker = L.marker(clickCoor, {
|
self._lastMarker = L.marker(clickCoor, {
|
||||||
icon: L.divIcon({
|
icon: L.divIcon({
|
||||||
html: new AddNewMarker(filteredLayers).ConstructElement(),
|
html: iconToShow.ConstructElement(),
|
||||||
iconSize: [50, 50],
|
iconSize: [50, 50],
|
||||||
iconAnchor: [25, 50],
|
iconAnchor: [25, 50],
|
||||||
popupAnchor: [0, -45]
|
popupAnchor: [0, -45]
|
||||||
|
@ -71,7 +75,7 @@ export default class StrayClickHandler {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
selectedElement.addCallback(() => {
|
state.selectedElement.addCallback(() => {
|
||||||
if (self._lastMarker !== undefined) {
|
if (self._lastMarker !== undefined) {
|
||||||
leafletMap.data.removeLayer(self._lastMarker);
|
leafletMap.data.removeLayer(self._lastMarker);
|
||||||
this._lastMarker = undefined;
|
this._lastMarker = undefined;
|
||||||
|
|
|
@ -223,7 +223,7 @@ export class OsmConnection {
|
||||||
if ((text ?? "") !== "") {
|
if ((text ?? "") !== "") {
|
||||||
textSuffix = "?text=" + encodeURIComponent(text)
|
textSuffix = "?text=" + encodeURIComponent(text)
|
||||||
}
|
}
|
||||||
if(this._dryRun){
|
if (this._dryRun) {
|
||||||
console.warn("Dryrun enabled - not actually closing note ", id, " with text ", text)
|
console.warn("Dryrun enabled - not actually closing note ", id, " with text ", text)
|
||||||
return new Promise((ok, error) => {
|
return new Promise((ok, error) => {
|
||||||
ok()
|
ok()
|
||||||
|
@ -232,7 +232,7 @@ export class OsmConnection {
|
||||||
return new Promise((ok, error) => {
|
return new Promise((ok, error) => {
|
||||||
this.auth.xhr({
|
this.auth.xhr({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
path: `/api/0.6/notes/${id}/close${textSuffix}`
|
path: `/api/0.6/notes/${id}/close${textSuffix}`,
|
||||||
}, function (err, response) {
|
}, function (err, response) {
|
||||||
if (err !== null) {
|
if (err !== null) {
|
||||||
error(err)
|
error(err)
|
||||||
|
@ -246,7 +246,7 @@ export class OsmConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
public reopenNote(id: number | string, text?: string): Promise<any> {
|
public reopenNote(id: number | string, text?: string): Promise<any> {
|
||||||
if(this._dryRun){
|
if (this._dryRun) {
|
||||||
console.warn("Dryrun enabled - not actually reopening note ", id, " with text ", text)
|
console.warn("Dryrun enabled - not actually reopening note ", id, " with text ", text)
|
||||||
return new Promise((ok, error) => {
|
return new Promise((ok, error) => {
|
||||||
ok()
|
ok()
|
||||||
|
@ -272,9 +272,40 @@ export class OsmConnection {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public openNote(lat: number, lon: number, text: string): Promise<{ id: number }> {
|
||||||
|
if (this._dryRun) {
|
||||||
|
console.warn("Dryrun enabled - not actually opening note with text ", text)
|
||||||
|
return new Promise((ok, error) => {
|
||||||
|
ok()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const auth = this.auth;
|
||||||
|
const content = {lat, lon, text}
|
||||||
|
return new Promise((ok, error) => {
|
||||||
|
auth.xhr({
|
||||||
|
method: 'POST',
|
||||||
|
path: `/api/0.6/notes.json`,
|
||||||
|
options: {header:
|
||||||
|
{'Content-Type': 'application/json'}},
|
||||||
|
content: JSON.stringify(content)
|
||||||
|
|
||||||
|
}, function (err, response) {
|
||||||
|
if (err !== null) {
|
||||||
|
error(err)
|
||||||
|
} else {
|
||||||
|
const id = Number(response.children[0].children[0].children.item("id").innerHTML)
|
||||||
|
console.log("OPENED NOTE", id)
|
||||||
|
ok({id})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public addCommentToNode(id: number | string, text: string): Promise<any> {
|
public addCommentToNode(id: number | string, text: string): Promise<any> {
|
||||||
if(this._dryRun){
|
if (this._dryRun) {
|
||||||
console.warn("Dryrun enabled - not actually adding comment ",text, "to note ", id)
|
console.warn("Dryrun enabled - not actually adding comment ", text, "to note ", id)
|
||||||
return new Promise((ok, error) => {
|
return new Promise((ok, error) => {
|
||||||
ok()
|
ok()
|
||||||
});
|
});
|
||||||
|
@ -286,7 +317,8 @@ export class OsmConnection {
|
||||||
return new Promise((ok, error) => {
|
return new Promise((ok, error) => {
|
||||||
this.auth.xhr({
|
this.auth.xhr({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
path: `/api/0.6/notes/${id}/comment?text=${encodeURIComponent(text)}`
|
|
||||||
|
path: `/api/0.6/notes.json/${id}/comment?text=${encodeURIComponent(text)}`
|
||||||
}, function (err, response) {
|
}, function (err, response) {
|
||||||
if (err !== null) {
|
if (err !== null) {
|
||||||
error(err)
|
error(err)
|
||||||
|
|
|
@ -2,7 +2,7 @@ import {Utils} from "../Utils";
|
||||||
|
|
||||||
export default class Constants {
|
export default class Constants {
|
||||||
|
|
||||||
public static vNumber = "0.14.0-alpha-2";
|
public static vNumber = "0.14.0-alpha-3";
|
||||||
public static ImgurApiKey = '7070e7167f0a25a'
|
public static ImgurApiKey = '7070e7167f0a25a'
|
||||||
public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85"
|
public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85"
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,9 @@ export default class AddNewMarker extends Combine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(icons.length === 0){
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
if (icons.length === 1) {
|
if (icons.length === 1) {
|
||||||
return icons[0]
|
return icons[0]
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,9 +138,6 @@ export default class SimpleAddUI extends Toggle {
|
||||||
loginButton,
|
loginButton,
|
||||||
state.osmConnection.isLoggedIn
|
state.osmConnection.isLoggedIn
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
this.SetStyle("font-size:large");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,9 @@ import Lazy from "./Base/Lazy";
|
||||||
import {DefaultGuiState} from "./DefaultGuiState";
|
import {DefaultGuiState} from "./DefaultGuiState";
|
||||||
import LayerConfig from "../Models/ThemeConfig/LayerConfig";
|
import LayerConfig from "../Models/ThemeConfig/LayerConfig";
|
||||||
import * as home_location_json from "../assets/layers/home_location/home_location.json";
|
import * as home_location_json from "../assets/layers/home_location/home_location.json";
|
||||||
|
import NewNoteUi from "./Popup/NewNoteUi";
|
||||||
|
import Combine from "./Base/Combine";
|
||||||
|
import AddNewMarker from "./BigComponents/AddNewMarker";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,45 +57,63 @@ export default class DefaultGUI {
|
||||||
|
|
||||||
public setupClickDialogOnMap(filterViewIsOpened: UIEventSource<boolean>, state: FeaturePipelineState) {
|
public setupClickDialogOnMap(filterViewIsOpened: UIEventSource<boolean>, state: FeaturePipelineState) {
|
||||||
|
|
||||||
|
const hasPresets = state.layoutToUse.layers.some(layer => layer.presets.length > 0);
|
||||||
|
const noteLayer= state.filteredLayers.data.filter(l => l.layerDef.id === "note")[0]
|
||||||
|
let addNewNoteDialog : () => BaseUIElement = undefined;
|
||||||
|
if(noteLayer !== undefined){
|
||||||
|
addNewNoteDialog = () => new NewNoteUi(state.LastClickLocation, state)
|
||||||
|
}
|
||||||
|
|
||||||
function setup() {
|
function setup() {
|
||||||
let presetCount = 0;
|
|
||||||
for (const layer of state.layoutToUse.layers) {
|
|
||||||
for (const preset of layer.presets) {
|
|
||||||
presetCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (presetCount == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
console.warn("Settuping ")
|
||||||
|
if(!hasPresets && addNewNoteDialog === undefined){
|
||||||
|
return; // nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const newPointDialogIsShown = new UIEventSource<boolean>(false);
|
const newPointDialogIsShown = new UIEventSource<boolean>(false);
|
||||||
const addNewPoint = new ScrollableFullScreen(
|
const addNewPoint = new ScrollableFullScreen(
|
||||||
() => Translations.t.general.add.title.Clone(),
|
() => hasPresets ? Translations.t.general.add.title : Translations.t.notes.createNoteTitle,
|
||||||
() => new SimpleAddUI(newPointDialogIsShown, filterViewIsOpened, state),
|
() => {
|
||||||
|
let addNew = undefined;
|
||||||
|
if(hasPresets){
|
||||||
|
addNew = new SimpleAddUI(newPointDialogIsShown, filterViewIsOpened, state);
|
||||||
|
}
|
||||||
|
let addNote = undefined;
|
||||||
|
if(noteLayer !== undefined){
|
||||||
|
addNote = addNewNoteDialog()
|
||||||
|
}
|
||||||
|
return new Combine([addNew, addNote]).SetClass("flex flex-col font-lg text-lg")
|
||||||
|
},
|
||||||
"new",
|
"new",
|
||||||
newPointDialogIsShown
|
newPointDialogIsShown
|
||||||
);
|
);
|
||||||
|
|
||||||
addNewPoint.isShown.addCallback((isShown) => {
|
addNewPoint.isShown.addCallback((isShown) => {
|
||||||
if (!isShown) {
|
if (!isShown) {
|
||||||
|
// Clear the 'last-click'-location when the dialog is closed - this causes the popup and the marker to be removed
|
||||||
state.LastClickLocation.setData(undefined);
|
state.LastClickLocation.setData(undefined);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
new StrayClickHandler(
|
new StrayClickHandler(
|
||||||
state.LastClickLocation,
|
state,
|
||||||
state.selectedElement,
|
addNewPoint,
|
||||||
state.filteredLayers,
|
hasPresets ? new AddNewMarker(state.filteredLayers) : new Combine([Svg.note_svg().SetStyle("height: 40px"), Svg.addSmall_svg().SetClass("absolute bottom-0 right-0 w-6 animate-pulse")]).SetClass("block relative")
|
||||||
state.leafletMap,
|
|
||||||
addNewPoint
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.featureSwitchAddNew.addCallbackAndRunD(addNewAllowed => {
|
if(noteLayer !== undefined){
|
||||||
if (addNewAllowed) {
|
setup()
|
||||||
setup()
|
}else{
|
||||||
return true;
|
state.featureSwitchAddNew.addCallbackAndRunD(addNewAllowed => {
|
||||||
}
|
if (addNewAllowed) {
|
||||||
})
|
setup()
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,18 +7,19 @@ import {Tag} from "../../Logic/Tags/Tag";
|
||||||
import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction";
|
import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction";
|
||||||
import {Changes} from "../../Logic/Osm/Changes";
|
import {Changes} from "../../Logic/Osm/Changes";
|
||||||
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
|
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
|
||||||
|
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
|
||||||
|
|
||||||
export default class DeleteImage extends Toggle {
|
export default class DeleteImage extends Toggle {
|
||||||
|
|
||||||
constructor(key: string, tags: UIEventSource<any>, state: {changes?: Changes, osmConnection?: OsmConnection}) {
|
constructor(key: string, tags: UIEventSource<any>, state: {layoutToUse: LayoutConfig, changes?: Changes, osmConnection?: OsmConnection}) {
|
||||||
const oldValue = tags.data[key]
|
const oldValue = tags.data[key]
|
||||||
const isDeletedBadge = Translations.t.image.isDeleted.Clone()
|
const isDeletedBadge = Translations.t.image.isDeleted.Clone()
|
||||||
.SetClass("rounded-full p-1")
|
.SetClass("rounded-full p-1")
|
||||||
.SetStyle("color:white;background:#ff8c8c")
|
.SetStyle("color:white;background:#ff8c8c")
|
||||||
.onClick(async () => {
|
.onClick(async () => {
|
||||||
await state?.changes?.applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data, {
|
await state?.changes?.applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data, {
|
||||||
changeType: "answer",
|
changeType: "delete-image",
|
||||||
theme: "test"
|
theme: state.layoutToUse.id
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,13 @@ import Toggle from "../Input/Toggle";
|
||||||
import ImageProvider from "../../Logic/ImageProviders/ImageProvider";
|
import ImageProvider from "../../Logic/ImageProviders/ImageProvider";
|
||||||
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
|
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
|
||||||
import {Changes} from "../../Logic/Osm/Changes";
|
import {Changes} from "../../Logic/Osm/Changes";
|
||||||
|
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
|
||||||
|
|
||||||
export class ImageCarousel extends Toggle {
|
export class ImageCarousel extends Toggle {
|
||||||
|
|
||||||
constructor(images: UIEventSource<{ key: string, url: string, provider: ImageProvider }[]>,
|
constructor(images: UIEventSource<{ key: string, url: string, provider: ImageProvider}[]>,
|
||||||
tags: UIEventSource<any>,
|
tags: UIEventSource<any>,
|
||||||
state: {osmConnection?: OsmConnection, changes?: Changes}) {
|
state: {osmConnection?: OsmConnection, changes?: Changes, layoutToUse: LayoutConfig }) {
|
||||||
const uiElements = images.map((imageURLS: { key: string, url: string, provider: ImageProvider }[]) => {
|
const uiElements = images.map((imageURLS: { key: string, url: string, provider: ImageProvider }[]) => {
|
||||||
const uiElements: BaseUIElement[] = [];
|
const uiElements: BaseUIElement[] = [];
|
||||||
for (const url of imageURLS) {
|
for (const url of imageURLS) {
|
||||||
|
|
57
UI/Popup/NewNoteUi.ts
Normal file
57
UI/Popup/NewNoteUi.ts
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import Combine from "../Base/Combine";
|
||||||
|
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||||
|
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
|
||||||
|
import Translations from "../i18n/Translations";
|
||||||
|
import Title from "../Base/Title";
|
||||||
|
import ValidatedTextField from "../Input/ValidatedTextField";
|
||||||
|
import {SubtleButton} from "../Base/SubtleButton";
|
||||||
|
import Svg from "../../Svg";
|
||||||
|
import {LocalStorageSource} from "../../Logic/Web/LocalStorageSource";
|
||||||
|
import Toggle from "../Input/Toggle";
|
||||||
|
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
|
||||||
|
import FeaturePipeline from "../../Logic/FeatureSource/FeaturePipeline";
|
||||||
|
|
||||||
|
export default class NewNoteUi extends Toggle {
|
||||||
|
|
||||||
|
constructor(lastClickLocation: UIEventSource<{ lat: number, lon: number }>,
|
||||||
|
state: { osmConnection: OsmConnection, layoutToUse: LayoutConfig, featurePipeline: FeaturePipeline }) {
|
||||||
|
|
||||||
|
const t = Translations.t.notes;
|
||||||
|
const isCreated = new UIEventSource(false);
|
||||||
|
const text = ValidatedTextField.InputForType("text", {
|
||||||
|
value: LocalStorageSource.Get("note-text")
|
||||||
|
})
|
||||||
|
text.SetClass("border rounded-sm border-grey-500")
|
||||||
|
|
||||||
|
const postNote = new SubtleButton(Svg.addSmall_svg().SetClass("max-h-7"), t.createNote)
|
||||||
|
postNote.onClick(async () => {
|
||||||
|
let txt = text.GetValue().data
|
||||||
|
if (txt === undefined || txt === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
txt += "\n\n #MapComplete #" + state?.layoutToUse?.id
|
||||||
|
const loc = lastClickLocation.data;
|
||||||
|
state?.osmConnection?.openNote(loc.lat, loc.lon, txt)
|
||||||
|
text.GetValue().setData("")
|
||||||
|
isCreated.setData(true)
|
||||||
|
})
|
||||||
|
const createNoteDialog = new Combine([
|
||||||
|
new Title(t.createNoteTitle),
|
||||||
|
t.createNoteIntro,
|
||||||
|
text,
|
||||||
|
new Combine([new Toggle(undefined, t.warnAnonymous, state?.osmConnection?.isLoggedIn).SetClass("alert"), postNote]).SetClass("flex justify-end items-center")
|
||||||
|
]).SetClass("flex flex-col border-2 border-black rounded-xl p-4");
|
||||||
|
|
||||||
|
|
||||||
|
super(
|
||||||
|
new Toggle(t.isCreated.SetClass("thanks"),
|
||||||
|
createNoteDialog,
|
||||||
|
isCreated
|
||||||
|
),
|
||||||
|
undefined,
|
||||||
|
new UIEventSource<boolean>(true)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -7,7 +7,11 @@ const layout = QueryParameters.GetQueryParameter("layout", undefined).data ?? ""
|
||||||
const customLayout = QueryParameters.GetQueryParameter("userlayout", undefined).data ?? ""
|
const customLayout = QueryParameters.GetQueryParameter("userlayout", undefined).data ?? ""
|
||||||
const l = window.location;
|
const l = window.location;
|
||||||
if( layout !== ""){
|
if( layout !== ""){
|
||||||
window.location.replace(l.protocol + "//" + window.location.host+"/"+layout+".html"+ l.search + l.hash);
|
if(window.location.host.startsWith("127.0.0.1")){
|
||||||
|
window.location.replace(l.protocol + "//" + window.location.host+"/theme.html"+ l.search + "&layout="+layout + l.hash);
|
||||||
|
}else{
|
||||||
|
window.location.replace(l.protocol + "//" + window.location.host+"/"+layout+".html"+ l.search + l.hash);
|
||||||
|
}
|
||||||
}else if (customLayout !== ""){
|
}else if (customLayout !== ""){
|
||||||
window.location.replace(l.protocol + "//" + window.location.host+"/theme.html"+ l.search + l.hash);
|
window.location.replace(l.protocol + "//" + window.location.host+"/theme.html"+ l.search + l.hash);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"name": {
|
"name": {
|
||||||
"en": "OpenStreetMap notes"
|
"en": "OpenStreetMap notes"
|
||||||
},
|
},
|
||||||
"description": "This layer shows notes on OpenStreetMap.",
|
"description": "This layer shows notes on OpenStreetMap. Having this layer in your theme will trigger the 'add new note' functionality in the 'addNewPoint'-popup (or if your theme has no presets, it'll enable adding notes)",
|
||||||
"source": {
|
"source": {
|
||||||
"osmTags": "id~*",
|
"osmTags": "id~*",
|
||||||
"geoJson": "https://api.openstreetmap.org/api/0.6/notes.json?closed=7&bbox={x_min},{y_min},{x_max},{y_max}",
|
"geoJson": "https://api.openstreetmap.org/api/0.6/notes.json?closed=7&bbox={x_min},{y_min},{x_max},{y_max}",
|
||||||
|
|
|
@ -28,10 +28,12 @@
|
||||||
],
|
],
|
||||||
"isShown": {
|
"isShown": {
|
||||||
"render": "yes",
|
"render": "yes",
|
||||||
"mappings": [{
|
"mappings": [
|
||||||
"if": "_trigger_index=",
|
{
|
||||||
"then": "no"
|
"if": "_trigger_index=",
|
||||||
}]
|
"then": "no"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"titleIcons": [
|
"titleIcons": [
|
||||||
{
|
{
|
||||||
|
@ -59,7 +61,6 @@
|
||||||
"id": "close_note_mapped",
|
"id": "close_note_mapped",
|
||||||
"render": "{close_note(Already mapped, ./assets/svg/checkmark.svg, id, Already mapped)}"
|
"render": "{close_note(Already mapped, ./assets/svg/checkmark.svg, id, Already mapped)}"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"id": "comment",
|
"id": "comment",
|
||||||
"render": "{add_note_comment()}"
|
"render": "{add_note_comment()}"
|
||||||
|
|
|
@ -441,6 +441,13 @@
|
||||||
"anonymous": "Anonymous user",
|
"anonymous": "Anonymous user",
|
||||||
"loginToAddComment": "Login to add a comment",
|
"loginToAddComment": "Login to add a comment",
|
||||||
"loginToAddPicture": "Login to add a picture",
|
"loginToAddPicture": "Login to add a picture",
|
||||||
"loginToClose": "Login to close this note"
|
"loginToClose": "Login to close this note",
|
||||||
|
"createNoteTitle": "Create a new note here",
|
||||||
|
"createNote": "Create a new note",
|
||||||
|
"noteIsPublic": "This will be visible to everyone",
|
||||||
|
"createNoteIntro": "Is something wrong or missing on the map? Create a note here. These will be checked by volunteers",
|
||||||
|
"warnAnonymous": "You are not logged in. We won't be able to contact you to resolve your issue.",
|
||||||
|
"notesLayerMustBeEnabled": "The 'notes'-layer is disabled. Enable it to add a note",
|
||||||
|
"isCreated": "Your note has been created!"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3375,6 +3375,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"note_import": {
|
"note_import": {
|
||||||
|
"name": "Possible bookcases",
|
||||||
"title": {
|
"title": {
|
||||||
"render": "Possible feature"
|
"render": "Possible feature"
|
||||||
}
|
}
|
||||||
|
|
3
test.ts
3
test.ts
|
@ -1 +1,2 @@
|
||||||
console.log("Hello world")
|
import NewNoteUi from "./UI/Popup/NewNoteUi";
|
||||||
|
import {UIEventSource} from "./Logic/UIEventSource";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue