foist
[kismet-logviewer.git] / logviewer / static / js / jquery.kismet.gps.js
1 // GPS status and window
2 //
3 // Requires js-storage and jquery be loaded prior
4 //
5 // dragorn@kismetwireless.net
6 // MIT/GPL License (pick one); the web ui code is licensed more
7 // freely than GPL to reflect the generally MIT-licensed nature
8 // of the web/jquery environment
9 //
10
11 (function ($) {
12     var local_uri_prefix = "";
13     if (typeof(KISMET_URI_PREFIX) !== 'undefined')
14         local_uri_prefix = KISMET_URI_PREFIX;
15
16     var base_options = {
17         use_color: true,
18     };
19
20     var options = base_options;
21
22     var timerid = -1;
23
24     var element = null;
25
26     var gpsicon = null;
27
28     var gpstext = null;
29
30     var gpsclick = null;
31
32     // Last time from the server
33     var last_time = 0;
34
35     var dialog = null;
36
37     var last_gps = null;
38
39     var gps_popup_content =
40             $('<div>', {
41             style: 'padding: 2px;'
42         })
43             .append(
44                 $('<div>', {
45                     id: 'gpsstatus',
46                     style: 'padding-bottom: 2px;'
47                 })
48             )
49             .append(
50                 $('<table>', {
51                     id: "gpsstatustable"
52                 })
53                 .append(
54                     $('<tr>')
55                     .append(
56                         $('<td>').html('Time')
57                     )
58                     .append(
59                         $('<td>', {
60                             id: 'time'
61                         }).html("n/a")
62                     )
63                 )
64                 .append(
65                     $('<tr>')
66                     .append(
67                         $('<td>').html('Location')
68                     )
69                     .append(
70                         $('<td>', {
71                             id: 'location'
72                         }).html("n/a")
73                     )
74                 )
75                 .append(
76                     $('<tr>')
77                     .append(
78                         $('<td>').html('Speed')
79                     )
80                     .append(
81                         $('<td>', {
82                             id: 'speed'
83                         }).html("n/a")
84                     )
85                 )
86                 .append(
87                     $('<tr>')
88                     .append(
89                         $('<td>').html('Heading')
90                     )
91                     .append(
92                         $('<td>', {
93                             id: 'heading'
94                         }).html("n/a")
95                     )
96                 )
97                 .append(
98                     $('<tr>')
99                     .append(
100                         $('<td>').html('Altitude')
101                     )
102                     .append(
103                         $('<td>', {
104                             id: 'altitude'
105                         }).html("n/a")
106                     )
107                 )
108             );
109
110     // Close the alert panel if we click outside it
111     var close_dialog_outside = function(e) {
112         if (e == null ||
113             (e != null && $(e.target).closest('#gpsdialog').length == 0)) {
114
115             if (dialog != null) {
116                 dialog.remove();
117                 dialog = null;
118             }
119
120             // Remove the handler
121             $('body').off('click', close_dialog_outside);
122
123             // Don't pass the click on
124             e.stopImmediatePropagation();
125         }
126     }
127
128     var open_dialog = function(e) {
129         if (dialog != null) {
130             close_dialog_outside(e);
131
132             e.stopImmediatePropagation();
133             return;
134         }
135
136         var fullscreen = false;
137
138         var nominal_w = 400;
139         //var nominal_h = ($(window).height() / 3) * 2;
140         var nominal_h = 120;
141
142         var pos = { };
143
144         if ($(window).width() < 450) {
145             nominal_w = $(window).width() - 5;
146             nominal_h = $(window).height() - 5;
147
148             pos = {
149                 "my": "left-top",
150                 "at": "left-top",
151                 "of": "window",
152                 "offsetX": 2,
153                 "offsetY": 2,
154                 "autoposition": "RIGHT"
155             };
156
157             fullscreen = true;
158         } else {
159             // Position under the element
160             var off_y = (nominal_h / 2) + (element.outerHeight() / 2) + 3;
161
162             // left-ish of the icon
163             var off_x = (nominal_w / 5) * 2;
164             off_x *= -1;
165
166             // Where the outer border lands
167             var outerborder = off_x + (nominal_w / 2);
168
169             pos = {
170                 of: element,
171                 offsetY: off_y,
172                 offsetX: off_x
173             };
174
175             fullscreen = false;
176         }
177
178         if (last_gps == null ||
179             (last_gps != null &&
180                 (last_gps['kismet.common.location.valid'] == 0) ||
181                 (last_gps['kismet.common.location.fix'] < 2))) {
182                     $('#gpsstatus', gps_popup_content).html('No GPS available');
183                     $('#time', gps_popup_content).html('n/a');
184                     $('#location', gps_popup_content).html('n/a');
185                     $('#speed', gps_popup_content).html('n/a');
186                     $('#heading', gps_popup_content).html('n/a');
187                     $('#altitude', gps_popup_content).html('n/a');
188                 }
189
190         if (fullscreen)
191             $('.kg-header-close', gps_popup_content).show();
192
193         dialog = $.jsPanel({
194             id: "gpsdialog",
195             headerRemove: true,
196             position: pos,
197             contentSize: {
198                 width: nominal_w,
199                 height: nominal_h
200             },
201             content: gps_popup_content,
202         });
203
204         $("body").on("click", close_dialog_outside);
205
206         e.stopImmediatePropagation();
207     }
208
209     var gps_refresh = function(data) {
210         if (kismet.getStorage('kismet.ui.gps.icon') === 'False') {
211             gpsicon.hide();
212         } else {
213             gpsicon.show();
214         }
215
216         if (kismet.getStorage('kismet.ui.gps.text') === 'False') {
217             gpstext.hide();
218         } else {
219             gpstext.show();
220         }
221
222         data = kismet.sanitizeObject(data);
223
224         last_gps = data;
225
226         var d = "Unknown"
227         try {
228             d = new Date(last_gps['kismet.common.location.time_sec']*1000).toISOString();
229         } catch (e) {
230             ;
231         }
232
233         if (last_gps['kismet.common.location.valid'] != 0 &&
234             last_gps['kismet.common.location.fix'] >= 2) {
235             if (last_gps['kismet.common.location.fix'] == 2) {
236                 $('#gpsstatus', gps_popup_content).html('GPS locked (2d)');
237                 $('#altitude', gps_popup_content).html('n/a');
238             } else {
239                 $('#gpsstatus', gps_popup_content).html('GPS locked (3d)');
240                 $('#altitude', gps_popup_content).html(kismet_ui.renderDistance(last_gps['kismet.common.location.alt'] / 1000, 0));
241             }
242
243             $('#time', gps_popup_content).html(d);
244             $('#location', gps_popup_content).html(last_gps['kismet.common.location.geopoint'][1] + " x " + last_gps['kismet.common.location.geopoint'][0]);
245             $('#speed', gps_popup_content).html(kismet_ui.renderSpeed(last_gps['kismet.common.location.speed']));
246             $('#heading', gps_popup_content).html(last_gps['kismet.common.location.heading']);
247         } else {
248             $('#gpsstatus', gps_popup_content).html('No GPS available');
249             $('#time', gps_popup_content).html('n/a');
250             $('#location', gps_popup_content).html('n/a');
251             $('#speed', gps_popup_content).html('n/a');
252             $('#heading', gps_popup_content).html('n/a');
253             $('#altitude', gps_popup_content).html('n/a');
254         }
255
256         if (last_gps == null ||
257             (last_gps != null && last_gps['kismet.common.location.valid'] == 0) ||
258             (last_gps != null && last_gps['kismet.common.location.fix'] < 2)) {
259             gpsicon.removeClass('kg-icon-3d');
260             gpsicon.removeClass('kg-icon-2d');
261             element.tooltipster('content', 'GPS connection lost...');
262
263             gpstext.addClass('gpstext_lost');
264             gpstext.html("<b>No GPS</b>");
265
266             return;
267         } else if (last_gps['kismet.common.location.fix'] == 2) {
268             gpsicon.removeClass('kg-icon-3d');
269             gpsicon.addClass('kg-icon-2d');
270             element.tooltipster('content', 'GPS fix' +  last_gps['kismet.common.location.geopoint'][1] + ' x ' +
271                 last_gps['kismet.common.location.geopoint'][0]);
272
273             gpstext.removeClass('gpstext_lost');
274             gpstext.html(kismet.censorLocation(last_gps['kismet.common.location.geopoint'][1]) + " x " + 
275                 kismet.censorLocation(last_gps['kismet.common.location.geopoint'][0]));
276         } else if (last_gps['kismet.common.location.fix'] == 3) {
277             gpsicon.removeClass('kg-icon-2d');
278             gpsicon.addClass('kg-icon-3d');
279             element.tooltipster('content', 'GPS fix ' +
280                 last_gps['kismet.common.location.geopoint'][1] + ' x ' +
281                 last_gps['kismet.common.location.geopoint'][0] + ' ' +
282                 kismet_ui.renderDistance(last_gps['kismet.common.location.alt'] / 1000, 0));
283
284             gpstext.removeClass('gpstext_lost');
285             gpstext.html(kismet.censorLocation(last_gps['kismet.common.location.geopoint'][1]) + " x " + 
286                 kismet.censorLocation(last_gps['kismet.common.location.geopoint'][0]));
287         }
288     }
289
290     $.fn.gps = function(data, inopt) {
291         // Get the stored value if one exists
292         storage = Storages.localStorage;
293
294         element = $(this);
295
296         element.addClass('kg-top-icon');
297
298         options = $.extend(base_options, inopt);
299
300         gpsicon = $('i.icon', this);
301         if (gpsicon.length == 0) {
302             gpsicon = $('<i>', {
303                 class: "icon fa fa-crosshairs kg-icon-base"
304             });
305         }
306
307         gpstext = $('span.gpstext', this);
308         if (gpstext.length == 0) {
309             gpstext = $('<span>', {
310                 "class": "gpstext",
311             }).html("Unknown");
312         }
313
314         gpsclick = $('a.gpsbutton', this);
315
316         if (gpsclick.length != 0) {
317             gpsclick.empty();
318         }
319
320         gpsclick = $('<a>', {
321             href: "#",
322             class: "gpsbutton"
323         })
324         .on('click', open_dialog);
325
326         if (kismet.getStorage('kismet.ui.gps.icon') === 'False') {
327             gpsicon.hide();
328         }
329
330         if (kismet.getStorage('kismet.ui.gps.text') === 'False') {
331             gpstext.hide();
332         }
333
334         gpsclick.append(gpstext);
335         gpsclick.append(gpsicon);
336
337         element.append(gpsclick);
338
339         element.tooltipster({
340             maxWidth: 450
341         });
342
343         $.get(local_uri_prefix + "gps/location.json")
344             .done(function(data) {
345                 gps_refresh(data);
346             });
347
348         kismet_ui_base.SubscribeEventbus("GPS_LOCATION", [], function(data) {
349             gps_refresh(data);
350         });
351     };
352
353 }(jQuery));