]> git.openstreetmap.org Git - rails.git/blob - app/assets/javascripts/user.js
Merge remote-tracking branch 'upstream/pull/6062'
[rails.git] / app / assets / javascripts / user.js
1 //= require leaflet.locate
2 //= require ./home_location_name-endpoint
3
4 (function () {
5   $(document).on("change", "#user_all", function () {
6     $("#user_list input[type=checkbox]").prop("checked", $("#user_all").prop("checked"));
7   });
8 }());
9
10 $(function () {
11   const defaultHomeZoom = 12;
12   let map, marker, deleted_lat, deleted_lon, deleted_home_name, homeLocationNameGeocoder, savedLat, savedLon;
13
14   if ($("#social_links").length) {
15     $("#add-social-link").on("click", function () {
16       const newIndex = -Date.now();
17
18       $("#social_links template").contents().clone().appendTo("#social_links")
19         .find("input").attr("name", `user[social_links_attributes][${newIndex}][url]`).trigger("focus");
20
21       renumberSocialLinks();
22     });
23
24     $("#social_links").on("click", "button", function () {
25       const row = $(this).closest(".row");
26       const [destroyCheckbox] = row.find(".social_link_destroy input[type='checkbox']");
27
28       if (destroyCheckbox) {
29         destroyCheckbox.checked = true;
30         row.addClass("d-none");
31       } else {
32         row.remove();
33       }
34
35       renumberSocialLinks();
36     });
37
38     $(".social_link_destroy input[type='checkbox']:checked").each(function () {
39       $(this).closest(".row").addClass("d-none");
40     });
41
42     renumberSocialLinks();
43   }
44
45   function renumberSocialLinks() {
46     $("#social_links .row:not(.d-none)").each(function (i) {
47       const inputLabel = OSM.i18n.t("javascripts.profile.social_link_n", { n: i + 1 });
48       const removeButtonLabel = OSM.i18n.t("javascripts.profile.remove_social_link_n", { n: i + 1 });
49
50       $(this).find("input[type='text']")
51         .attr("placeholder", inputLabel)
52         .attr("aria-label", inputLabel);
53       $(this).find("button")
54         .attr("title", removeButtonLabel);
55     });
56   }
57
58   if ($("#map").length) {
59     map = L.map("map", {
60       attributionControl: false,
61       zoomControl: false
62     }).addLayer(new L.OSM.Mapnik());
63
64     savedLat = $("#home_lat").val();
65     savedLon = $("#home_lon").val();
66     homeLocationNameGeocoder = OSM.HomeLocationNameGeocoder($("#home_lat"), $("#home_lon"), $("#home_location_name"));
67
68     const position = $("html").attr("dir") === "rtl" ? "topleft" : "topright";
69
70     L.OSM.zoom({ position }).addTo(map);
71
72     L.OSM.locate({ position }).addTo(map);
73
74     if (OSM.home) {
75       map.setView([OSM.home.lat, OSM.home.lon], defaultHomeZoom);
76     } else {
77       map.setView([0, 0], 0);
78     }
79
80     marker = L.marker([0, 0], {
81       icon: OSM.getMarker({}),
82       keyboard: false,
83       interactive: false
84     });
85
86     if (OSM.home) {
87       marker.setLatLng([OSM.home.lat, OSM.home.lon]);
88       marker.addTo(map);
89     }
90
91     map.on("click", function (e) {
92       if (!$("#updatehome").is(":checked")) return;
93
94       const [lat, lon] = OSM.cropLocation(e.latlng, map.getZoom());
95
96       $("#home_lat").val(lat);
97       $("#home_lon").val(lon);
98
99       clearDeletedText();
100       respondToHomeLatLonUpdate();
101     }).on("moveend", function () {
102       const lat = $("#home_lat").val().trim(),
103             lon = $("#home_lon").val().trim();
104       let location;
105
106       try {
107         if (lat && lon) {
108           location = L.latLng(lat, lon);
109         }
110       } catch (error) {
111         // keep location undefined
112       }
113
114       $("#home_show").prop("disabled", !location || isCloseEnoughToMapCenter(location));
115     });
116
117     $("#home_lat, #home_lon").on("input", function () {
118       clearDeletedText();
119       respondToHomeLatLonUpdate();
120     });
121
122     $("#home_location_name").on("input", function () {
123       homeLocationNameGeocoder.autofill = false;
124       clearDeletedText();
125
126       respondToHomeLatLonUpdate(false);
127     });
128
129     $("#home_show").click(function () {
130       const lat = $("#home_lat").val(),
131             lon = $("#home_lon").val();
132
133       map.setView([lat, lon], defaultHomeZoom);
134     });
135
136     $("#home_delete").click(function () {
137       const lat = $("#home_lat").val(),
138             lon = $("#home_lon").val(),
139             locationName = $("#home_location_name").val();
140
141       $("#home_lat, #home_lon, #home_location_name").val("");
142       deleted_lat = lat;
143       deleted_lon = lon;
144       deleted_home_name = locationName;
145
146       respondToHomeLatLonUpdate(false);
147       $("#home_undelete").trigger("focus");
148     });
149
150     $("#home_undelete").click(function () {
151       $("#home_lat").val(deleted_lat);
152       $("#home_lon").val(deleted_lon);
153       $("#home_location_name").val(deleted_home_name);
154       clearDeletedText();
155
156       respondToHomeLatLonUpdate(false);
157       $("#home_delete").trigger("focus");
158     });
159   }
160
161   function respondToHomeLatLonUpdate(updateLocationName = true) {
162     const lat = $("#home_lat").val().trim(),
163           lon = $("#home_lon").val().trim(),
164           locationName = $("#home_location_name").val().trim();
165     let location;
166
167     try {
168       if (lat && lon) {
169         location = L.latLng(lat, lon);
170         if (updateLocationName) {
171           if (savedLat && savedLon && $("#home_location_name").val().trim()) {
172             homeLocationNameGeocoder.updateHomeLocationName(false, savedLat, savedLon, () => {
173               savedLat = savedLon = null;
174               homeLocationNameGeocoder.updateHomeLocationName();
175             });
176           } else {
177             savedLat = savedLon = null;
178             homeLocationNameGeocoder.updateHomeLocationName();
179           }
180         }
181       }
182       $("#home_lat, #home_lon").removeClass("is-invalid");
183     } catch (error) {
184       if (lat && isNaN(lat)) $("#home_lat").addClass("is-invalid");
185       if (lon && isNaN(lon)) $("#home_lon").addClass("is-invalid");
186     }
187
188     $("#home_message").toggleClass("invisible", Boolean(location));
189     $("#home_show").prop("hidden", !location);
190     $("#home_delete").prop("hidden", !location && !locationName);
191     $("#home_undelete").prop("hidden", !(
192       (!location || !locationName) &&
193       ((deleted_lat && deleted_lon) || deleted_home_name)
194     ));
195     if (location) {
196       marker.setLatLng([lat, lon]);
197       marker.addTo(map);
198       map.panTo([lat, lon]);
199     } else {
200       marker.removeFrom(map);
201     }
202   }
203
204   function isCloseEnoughToMapCenter(location) {
205     const inputPt = map.latLngToContainerPoint(location),
206           centerPt = map.latLngToContainerPoint(map.getCenter());
207
208     return centerPt.distanceTo(inputPt) < 10;
209   }
210
211   function clearDeletedText() {
212     deleted_lat = null;
213     deleted_lon = null;
214     deleted_home_name = null;
215   }
216
217   $("input#user_avatar").on("change", function () {
218     $("#user_avatar_action_new").prop("checked", true);
219   });
220
221   $("#content.user_confirm").each(function () {
222     $(this).hide();
223     $(this).find("#confirm").submit();
224   });
225
226   $("input[name=legale]").change(function () {
227     $("#contributorTerms").html("<div class='spinner-border' role='status'><span class='visually-hidden'>" + OSM.i18n.t("browse.start_rjs.loading") + "</span></div>");
228     fetch($(this).data("url"))
229       .then(r => r.text())
230       .then(html => { $("#contributorTerms").html(html); });
231   });
232
233   $("#read_ct").on("click", function () {
234     $("#continue").prop("disabled", !($(this).prop("checked") && $("#read_tou").prop("checked")));
235   });
236
237   $("#read_tou").on("click", function () {
238     $("#continue").prop("disabled", !($(this).prop("checked") && $("#read_ct").prop("checked")));
239   });
240 });