1 OSM.NewNote = function (map) {
2 const noteLayer = map.noteLayer,
3 content = $("#sidebar_content"),
5 control = $(".control-note"),
6 addNoteButton = control.find(".control-button");
10 addNoteButton.on("click", function (e) {
14 if ($(this).hasClass("disabled")) return;
16 OSM.router.route("/note/new");
19 function createNote(location, text, callback) {
20 fetch("/api/0.6/notes.json", {
22 headers: { ...OSM.oauth },
23 body: new URLSearchParams({
29 .then(response => response.json())
33 function addCreatedNoteMarker(feature) {
34 const marker = L.marker(feature.geometry.coordinates.reverse(), {
35 icon: OSM.getMarker({ icon: `${feature.properties.status}_NOTE_MARKER`, shadow: false, height: 40 }),
39 marker.id = feature.properties.id;
40 marker.addTo(noteLayer);
43 function addHalo(latlng) {
44 if (halo) map.removeLayer(halo);
46 halo = L.circleMarker(latlng, {
56 function removeHalo() {
57 if (halo) map.removeLayer(halo);
61 function addNewNoteMarker(latlng) {
62 if (newNoteMarker) map.removeLayer(newNoteMarker);
64 newNoteMarker = L.marker(latlng, {
65 icon: OSM.getMarker({ icon: "NEW_NOTE_MARKER", shadow: false, height: 40 }),
70 newNoteMarker.on("dragstart dragend", function (a) {
72 if (a.type === "dragend") {
73 addHalo(newNoteMarker.getLatLng());
77 newNoteMarker.addTo(map);
78 addHalo(newNoteMarker.getLatLng());
80 newNoteMarker.on("dragend", function () {
81 content.find("textarea").trigger("focus");
85 function removeNewNoteMarker() {
87 if (newNoteMarker) map.removeLayer(newNoteMarker);
91 function moveNewNoteMarkerToClick(e) {
92 if (newNoteMarker) newNoteMarker.setLatLng(e.latlng);
93 if (halo) halo.setLatLng(e.latlng);
94 content.find("textarea").trigger("focus");
97 function updateControls() {
98 const zoomedOut = addNoteButton.hasClass("disabled");
99 const withoutText = content.find("textarea").val() === "";
101 content.find("#new-note-zoom-warning").prop("hidden", !zoomedOut);
102 content.find("input[type=submit]").prop("disabled", zoomedOut || withoutText);
103 if (newNoteMarker) newNoteMarker.setOpacity(zoomedOut ? 0.5 : 0.9);
106 page.pushstate = page.popstate = function (path) {
107 OSM.loadSidebarContent(path, function () {
112 page.load = function (path) {
113 control.addClass("active");
115 map.addLayer(noteLayer);
117 const params = new URLSearchParams(path.substring(path.indexOf("?")));
120 if (params.has("lat") && params.has("lon")) {
121 markerLatlng = L.latLng(params.get("lat"), params.get("lon"));
123 markerLatlng = map.getCenter();
126 map.panInside(markerLatlng, {
130 addNewNoteMarker(markerLatlng);
132 content.find("textarea")
133 .on("input", updateControls)
134 .attr("readonly", "readonly") // avoid virtual keyboard popping up on focus
136 .removeAttr("readonly");
138 content.find("input[type=submit]").on("click", function (e) {
139 const location = newNoteMarker.getLatLng().wrap();
140 const text = content.find("textarea").val();
143 $(this).prop("disabled", true);
144 newNoteMarker.options.draggable = false;
145 newNoteMarker.dragging.disable();
147 createNote(location, text, (feature) => {
148 if (typeof OSM.user === "undefined") {
149 const anonymousNotesCount = Number(Cookies.get("_osm_anonymous_notes_count")) || 0;
150 Cookies.set("_osm_anonymous_notes_count", anonymousNotesCount + 1, { secure: true, expires: 30, path: "/", samesite: "lax" });
152 content.find("textarea").val("");
153 addCreatedNoteMarker(feature);
154 OSM.router.route("/note/" + feature.properties.id);
158 map.on("click", moveNewNoteMarkerToClick);
159 addNoteButton.on("disabled enabled", updateControls);
162 return map.getState();
165 page.unload = function () {
166 map.off("click", moveNewNoteMarkerToClick);
167 addNoteButton.off("disabled enabled", updateControls);
168 removeNewNoteMarker();
169 control.removeClass("active");