Satisfy ESLint
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / js / WoltLabSuite / Core / Controller / Map / Route / Planner.js
1 /**
2 * Map route planner based on Google Maps.
3 *
4 * @author Matthias Schmidt
5 * @copyright 2001-2019 WoltLab GmbH
6 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
7 * @module WoltLabSuite/Core/Controller/Map/Route/Planner
8 * @woltlabExcludeBundle all
9 */
10 define(["require", "exports", "tslib", "../../../Ajax/Status", "../../../Core", "../../../Dom/Util", "../../../Language", "../../../Ui/Dialog"], function (require, exports, tslib_1, AjaxStatus, Core, Util_1, Language, Dialog_1) {
11 "use strict";
12 AjaxStatus = tslib_1.__importStar(AjaxStatus);
13 Core = tslib_1.__importStar(Core);
14 Util_1 = tslib_1.__importDefault(Util_1);
15 Language = tslib_1.__importStar(Language);
16 Dialog_1 = tslib_1.__importDefault(Dialog_1);
17 class ControllerMapRoutePlanner {
18 constructor(buttonId, destination) {
19 this.didInitDialog = false;
20 this.directionsRenderer = undefined;
21 this.directionsService = undefined;
22 this.googleLink = undefined;
23 this.lastOrigin = undefined;
24 this.map = undefined;
25 this.originInput = undefined;
26 this.travelMode = undefined;
27 const button = document.getElementById(buttonId);
28 if (button === null) {
29 throw new Error(`Unknown button with id '${buttonId}'`);
30 }
31 this.button = button;
32 this.button.addEventListener("click", (ev) => this.openDialog(ev));
33 this.destination = destination;
34 }
35 /**
36 * Calculates the route based on the given result of a location search.
37 */
38 _calculateRoute(data) {
39 const dialog = Dialog_1.default.getDialog(this).dialog;
40 if (data.label) {
41 this.originInput.value = data.label;
42 }
43 if (this.map === undefined) {
44 const mapContainer = dialog.querySelector(".googleMap");
45 this.map = new google.maps.Map(mapContainer, {
46 disableDoubleClickZoom: window.WCF.Location.GoogleMaps.Settings.get("disableDoubleClickZoom"),
47 draggable: window.WCF.Location.GoogleMaps.Settings.get("draggable"),
48 mapTypeId: google.maps.MapTypeId.ROADMAP,
49 scaleControl: window.WCF.Location.GoogleMaps.Settings.get("scaleControl"),
50 scrollwheel: window.WCF.Location.GoogleMaps.Settings.get("scrollwheel"),
51 });
52 this.directionsService = new google.maps.DirectionsService();
53 this.directionsRenderer = new google.maps.DirectionsRenderer();
54 this.directionsRenderer.setMap(this.map);
55 const directionsContainer = dialog.querySelector(".googleMapsDirections");
56 this.directionsRenderer.setPanel(directionsContainer);
57 this.googleLink = dialog.querySelector(".googleMapsDirectionsGoogleLink");
58 }
59 const request = {
60 destination: this.destination,
61 origin: data.location,
62 provideRouteAlternatives: true,
63 travelMode: google.maps.TravelMode[this.travelMode.value.toUpperCase()],
64 };
65 AjaxStatus.show();
66 // .route() returns a promise, but we rely on the callback API for compatibility reasons.
67 void this.directionsService.route(request, (result, status) => this.setRoute(result, status));
68 this.googleLink.href = this.getGoogleMapsLink(data.location, this.travelMode.value);
69 this.lastOrigin = data.location;
70 }
71 /**
72 * Returns the Google Maps link based on the given optional directions origin
73 * and optional travel mode.
74 */
75 getGoogleMapsLink(origin, travelMode) {
76 if (origin) {
77 let link = `https://www.google.com/maps/dir/?api=1&origin=${origin.lat()},${origin.lng()}&destination=${this.destination.lat()},${this.destination.lng()}`;
78 if (travelMode) {
79 link += `&travelmode=${travelMode}`;
80 }
81 return link;
82 }
83 return `https://www.google.com/maps/search/?api=1&query=${this.destination.lat()},${this.destination.lng()}`;
84 }
85 /**
86 * Initializes the route planning dialog.
87 */
88 initDialog() {
89 if (!this.didInitDialog) {
90 const dialog = Dialog_1.default.getDialog(this).dialog;
91 // make input element a location search
92 this.originInput = dialog.querySelector('input[name="origin"]');
93 new window.WCF.Location.GoogleMaps.LocationSearch(this.originInput, (data) => this._calculateRoute(data));
94 this.travelMode = dialog.querySelector('select[name="travelMode"]');
95 this.travelMode.addEventListener("change", this.updateRoute.bind(this));
96 this.didInitDialog = true;
97 }
98 }
99 /**
100 * Opens the route planning dialog.
101 */
102 openDialog(event) {
103 event.preventDefault();
104 Dialog_1.default.open(this);
105 }
106 /**
107 * Handles the response of the direction service.
108 */
109 setRoute(result, status) {
110 AjaxStatus.hide();
111 if (status === google.maps.DirectionsStatus.OK) {
112 Util_1.default.show(this.map.getDiv().parentElement);
113 google.maps.event.trigger(this.map, "resize");
114 this.directionsRenderer.setDirections(result);
115 Util_1.default.show(this.travelMode.closest("dl"));
116 Util_1.default.show(this.googleLink);
117 Util_1.default.innerError(this.originInput, false);
118 }
119 else {
120 // map irrelevant errors to not found error
121 if (status !== google.maps.DirectionsStatus.OVER_QUERY_LIMIT &&
122 status !== google.maps.DirectionsStatus.REQUEST_DENIED) {
123 status = google.maps.DirectionsStatus.NOT_FOUND;
124 }
125 Util_1.default.innerError(this.originInput, Language.get(`wcf.map.route.error.${status.toLowerCase()}`));
126 }
127 }
128 /**
129 * Updates the route after the travel mode has been changed.
130 */
131 updateRoute() {
132 this._calculateRoute({
133 location: this.lastOrigin,
134 });
135 }
136 /**
137 * Sets up the route planner dialog.
138 */
139 _dialogSetup() {
140 return {
141 id: this.button.id + "Dialog",
142 options: {
143 onShow: this.initDialog.bind(this),
144 title: Language.get("wcf.map.route.planner"),
145 },
146 source: `
147 <div class="googleMapsDirectionsContainer" style="display: none;">
148 <div class="googleMap"></div>
149 <div class="googleMapsDirections"></div>
150 </div>
151 <small class="googleMapsDirectionsGoogleLinkContainer">
152 <a href="${this.getGoogleMapsLink()}" class="googleMapsDirectionsGoogleLink" target="_blank" style="display: none;">${Language.get("wcf.map.route.viewOnGoogleMaps")}</a>
153 </small>
154 <dl>
155 <dt>${Language.get("wcf.map.route.origin")}</dt>
156 <dd>
157 <input type="text" name="origin" class="long" autofocus>
158 </dd>
159 </dl>
160 <dl style="display: none;">
161 <dt>${Language.get("wcf.map.route.travelMode")}</dt>
162 <dd>
163 <select name="travelMode">
164 <option value="driving">${Language.get("wcf.map.route.travelMode.driving")}</option>
165 <option value="walking">${Language.get("wcf.map.route.travelMode.walking")}</option>
166 <option value="bicycling">${Language.get("wcf.map.route.travelMode.bicycling")}</option>
167 <option value="transit">${Language.get("wcf.map.route.travelMode.transit")}</option>
168 </select>
169 </dd>
170 </dl>`,
171 };
172 }
173 }
174 Core.enableLegacyInheritance(ControllerMapRoutePlanner);
175 return ControllerMapRoutePlanner;
176 });