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