1 export default function (map) {
2 const noteLayer = map.noteLayer,
3 content = $("#sidebar_content"),
5 control = $(".control-note"),
6 addNoteButton = control.find(".control-button");
12 function createNote(location, text) {
13 return fetch("/api/0.6/notes.json", {
15 headers: { ...OSM.oauth },
16 body: new URLSearchParams({
23 if (resp.ok) return resp.json();
24 throw new Error(`HTTP Error ${resp.status} ${resp.statusText}`);
28 function addCreatedNoteMarker(feature) {
29 const marker = L.marker(feature.geometry.coordinates.reverse(), {
30 icon: OSM.noteMarkers[feature.properties.status],
34 marker.id = feature.properties.id;
35 marker.addTo(noteLayer);
38 function addHalo(latlng) {
39 if (halo) map.removeLayer(halo);
41 halo = L.circleMarker(latlng, {
51 function removeHalo() {
52 if (halo) map.removeLayer(halo);
56 function addNewNoteMarker(latlng) {
57 if (newNoteMarker) map.removeLayer(newNoteMarker);
59 newNoteMarker = L.marker(latlng, {
60 icon: OSM.noteMarkers.new,
65 newNoteMarker.on("dragstart", removeHalo);
66 newNoteMarker.on("dragend", function () {
68 addHalo(newNoteMarker.getLatLng());
71 newNoteMarker.addTo(map);
72 addHalo(newNoteMarker.getLatLng());
74 newNoteMarker.on("dragend", function () {
75 content.find("textarea").trigger("focus");
79 function removeNewNoteMarker() {
81 if (newNoteMarker) map.removeLayer(newNoteMarker);
85 function moveNewNoteMarkerToClick(e) {
86 if (newNoteMarker) newNoteMarker.setLatLng(e.latlng);
87 if (halo) halo.setLatLng(e.latlng);
88 content.find("textarea").trigger("focus");
91 function updateControls() {
92 const zoomedOut = addNoteButton.hasClass("disabled");
93 const withoutText = content.find("textarea").val() === "";
95 content.find("#new-note-zoom-warning").prop("hidden", !zoomedOut);
96 content.find("input[type=submit]").prop("disabled", zoomedOut || withoutText);
97 if (newNoteMarker) newNoteMarker.setOpacity(zoomedOut ? 0.5 : 0.9);
100 page.load = function (path) {
101 OSM.loadSidebarContent(path)
102 .then(() => page.init(path));
105 page.init = function (path) {
106 control.addClass("active");
108 map.addLayer(noteLayer);
110 const params = new URLSearchParams(path.substring(path.indexOf("?")));
113 if (params.has("lat") && params.has("lon")) {
114 markerLatlng = { lat: params.get("lat"), lng: params.get("lon") };
116 markerLatlng = map.getCenter();
119 map.panInside(markerLatlng, {
123 addNewNoteMarker(markerLatlng);
125 content.find("textarea")
126 .on("input", updateControls)
127 .attr("readonly", "readonly") // avoid virtual keyboard popping up on focus
129 .removeAttr("readonly");
131 content.find("input[type=submit]").on("click", function (e) {
132 const location = newNoteMarker.getLatLng().wrap();
133 const text = content.find("textarea").val();
135 errorPanel = content.find(".new-note-error");
136 errorPanel.addClass("d-none");
137 errorPanelDetail = errorPanel.find(".new-note-error-detail");
140 $(this).prop("disabled", true);
141 newNoteMarker.options.draggable = false;
142 newNoteMarker.dragging.disable();
144 createNote(location, text)
146 if (typeof OSM.user === "undefined") {
147 const anonymousNotesCount = Number(OSM.cookies.get("_osm_anonymous_notes_count")) || 0;
148 OSM.cookies.set("_osm_anonymous_notes_count", anonymousNotesCount + 1, { expires: 14 });
150 content.find("textarea").val("");
151 addCreatedNoteMarker(feature);
152 OSM.router.route("/note/" + feature.properties.id);
155 errorPanel.removeClass("d-none");
156 errorPanelDetail.text(err.message || err);
161 map.on("click", moveNewNoteMarkerToClick);
162 addNoteButton.on("disabled enabled", updateControls);
165 return map.getState();
168 page.unload = function () {
169 map.off("click", moveNewNoteMarkerToClick);
170 addNoteButton.off("disabled enabled", updateControls);
171 removeNewNoteMarker();
172 control.removeClass("active");