]> git.openstreetmap.org Git - rails.git/blob - app/assets/javascripts/index/new_note.js
Replace qs with URLSearchParams
[rails.git] / app / assets / javascripts / index / new_note.js
1 OSM.NewNote = function (map) {
2   var noteLayer = map.noteLayer,
3       content = $("#sidebar_content"),
4       page = {},
5       addNoteButton = $(".control-note .control-button"),
6       newNoteMarker,
7       halo;
8
9   var noteIcons = {
10     "new": L.icon({
11       iconUrl: OSM.NEW_NOTE_MARKER,
12       iconSize: [25, 40],
13       iconAnchor: [12, 40]
14     }),
15     "open": L.icon({
16       iconUrl: OSM.OPEN_NOTE_MARKER,
17       iconSize: [25, 40],
18       iconAnchor: [12, 40]
19     }),
20     "closed": L.icon({
21       iconUrl: OSM.CLOSED_NOTE_MARKER,
22       iconSize: [25, 40],
23       iconAnchor: [12, 40]
24     })
25   };
26
27   addNoteButton.on("click", function (e) {
28     e.preventDefault();
29     e.stopPropagation();
30
31     if ($(this).hasClass("disabled")) return;
32
33     OSM.router.route("/note/new");
34   });
35
36   function createNote(location, text, callback) {
37     $.ajax({
38       url: "/api/0.6/notes.json",
39       type: "POST",
40       oauth: true,
41       data: {
42         lat: location.lat,
43         lon: location.lng,
44         text
45       },
46       success: callback
47     });
48   }
49
50   function addCreatedNoteMarker(feature) {
51     var marker = L.marker(feature.geometry.coordinates.reverse(), {
52       icon: noteIcons[feature.properties.status],
53       opacity: 0.9,
54       interactive: true
55     });
56     marker.id = feature.properties.id;
57     marker.addTo(noteLayer);
58   }
59
60   function addHalo(latlng) {
61     if (halo) map.removeLayer(halo);
62
63     halo = L.circleMarker(latlng, {
64       weight: 2.5,
65       radius: 20,
66       fillOpacity: 0.5,
67       color: "#FF6200"
68     });
69
70     map.addLayer(halo);
71   }
72
73   function removeHalo() {
74     if (halo) map.removeLayer(halo);
75     halo = null;
76   }
77
78   function addNewNoteMarker(latlng) {
79     if (newNoteMarker) map.removeLayer(newNoteMarker);
80
81     newNoteMarker = L.marker(latlng, {
82       icon: noteIcons.new,
83       opacity: 0.9,
84       draggable: true
85     });
86
87     newNoteMarker.on("dragstart dragend", function (a) {
88       removeHalo();
89       if (a.type === "dragend") {
90         addHalo(newNoteMarker.getLatLng());
91       }
92     });
93
94     newNoteMarker.addTo(map);
95     addHalo(newNoteMarker.getLatLng());
96
97     newNoteMarker.on("dragend", function () {
98       content.find("textarea").focus();
99     });
100   }
101
102   function removeNewNoteMarker() {
103     removeHalo();
104     if (newNoteMarker) map.removeLayer(newNoteMarker);
105     newNoteMarker = null;
106   }
107
108   function moveNewNotMarkerToClick(e) {
109     if (newNoteMarker) newNoteMarker.setLatLng(e.latlng);
110     if (halo) halo.setLatLng(e.latlng);
111     content.find("textarea").focus();
112   }
113
114   function updateControls() {
115     const zoomedOut = addNoteButton.hasClass("disabled");
116     const withoutText = content.find("textarea").val() === "";
117
118     content.find("#new-note-zoom-warning").prop("hidden", !zoomedOut);
119     content.find("input[type=submit]").prop("disabled", zoomedOut || withoutText);
120     if (newNoteMarker) newNoteMarker.setOpacity(zoomedOut ? 0.5 : 0.9);
121   }
122
123   page.pushstate = page.popstate = function (path) {
124     OSM.loadSidebarContent(path, function () {
125       page.load(path);
126     });
127   };
128
129   page.load = function (path) {
130     addNoteButton.addClass("active");
131
132     map.addLayer(noteLayer);
133
134     const params = new URLSearchParams(path.substring(path.indexOf("?")));
135     var markerLatlng;
136
137     if (params.has("lat") && params.has("lon")) {
138       markerLatlng = L.latLng(params.get("lat"), params.get("lon"));
139     } else {
140       markerLatlng = map.getCenter();
141     }
142
143     map.panInside(markerLatlng, {
144       padding: [50, 50]
145     });
146
147     addNewNoteMarker(markerLatlng);
148
149     content.find("textarea")
150       .on("input", updateControls)
151       .focus();
152
153     content.find("input[type=submit]").on("click", function (e) {
154       const location = newNoteMarker.getLatLng().wrap();
155       const text = content.find("textarea").val();
156
157       e.preventDefault();
158       $(this).prop("disabled", true);
159       newNoteMarker.options.draggable = false;
160       newNoteMarker.dragging.disable();
161
162       createNote(location, text, (feature) => {
163         if (typeof OSM.user === "undefined") {
164           var anonymousNotesCount = Number(Cookies.get("_osm_anonymous_notes_count")) || 0;
165           Cookies.set("_osm_anonymous_notes_count", anonymousNotesCount + 1, { secure: true, expires: 30, path: "/", samesite: "lax" });
166         }
167         content.find("textarea").val("");
168         addCreatedNoteMarker(feature);
169         OSM.router.route("/note/" + feature.properties.id);
170       });
171     });
172
173     map.on("click", moveNewNotMarkerToClick);
174     addNoteButton.on("disabled enabled", updateControls);
175     updateControls();
176
177     return map.getState();
178   };
179
180   page.unload = function () {
181     map.off("click", moveNewNotMarkerToClick);
182     addNoteButton.off("disabled enabled", updateControls);
183     removeNewNoteMarker();
184     addNoteButton.removeClass("active");
185   };
186
187   return page;
188 };