aboutsummaryrefslogtreecommitdiff
path: root/legacy/web/app/controller/Root.js
diff options
context:
space:
mode:
Diffstat (limited to 'legacy/web/app/controller/Root.js')
-rw-r--r--legacy/web/app/controller/Root.js363
1 files changed, 363 insertions, 0 deletions
diff --git a/legacy/web/app/controller/Root.js b/legacy/web/app/controller/Root.js
new file mode 100644
index 00000000..22869f45
--- /dev/null
+++ b/legacy/web/app/controller/Root.js
@@ -0,0 +1,363 @@
+/*
+ * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.controller.Root', {
+ extend: 'Ext.app.Controller',
+ alias: 'controller.root',
+
+ requires: [
+ 'Traccar.view.dialog.Login',
+ 'Traccar.view.Main',
+ 'Traccar.view.MainMobile',
+ 'Traccar.model.Position'
+ ],
+
+ init: function () {
+ var i, data, attribute, chartTypesStore, maintenanceTypesStore;
+ chartTypesStore = Ext.getStore('ReportChartTypes');
+ maintenanceTypesStore = Ext.getStore('MaintenanceTypes');
+ Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
+ data = Ext.getStore('PositionAttributes').getData().items;
+ for (i = 0; i < data.length; i++) {
+ attribute = data[i];
+ Traccar.model.Position.addFields([{
+ name: 'attribute.' + attribute.get('key'),
+ attributeKey: attribute.get('key'),
+ calculate: this.calculateAttribute,
+ persist: false
+ }]);
+ if (attribute.get('valueType') === 'number') {
+ chartTypesStore.add({
+ key: 'attribute.' + attribute.get('key'),
+ name: attribute.get('name')
+ });
+ maintenanceTypesStore.add(attribute);
+ }
+ }
+ },
+
+ calculateAttribute: function (data) {
+ var value = data.attributes[this.attributeKey];
+ if (value !== undefined) {
+ return Traccar.AttributeFormatter.getAttributeConverter(this.attributeKey)(value);
+ }
+ return value;
+ },
+
+ onLaunch: function () {
+ Ext.Ajax.request({
+ scope: this,
+ url: 'api/server',
+ callback: this.onServerReturn
+ });
+ },
+
+ showAnnouncement: function (announcement) {
+ var maxWidth = Ext.getBody().getViewSize().width - 2 * Traccar.Style.normalPadding;
+ if (maxWidth > Traccar.Style.windowWidth) {
+ maxWidth = Traccar.Style.windowWidth;
+ }
+ Ext.Msg.show({
+ msg: announcement,
+ buttons: Ext.Msg.OK,
+ closable: false,
+ modal: false,
+ maxWidth: maxWidth
+ }).alignTo(Ext.getBody(), 't-t', [0, Traccar.Style.normalPadding]);
+ },
+
+ onServerReturn: function (options, success, response) {
+ var announcement, token, parameters = {};
+ if (success) {
+ Traccar.app.setServer(Ext.decode(response.responseText));
+ announcement = Traccar.app.getServer().get('announcement');
+ if (announcement) {
+ this.showAnnouncement(announcement);
+ }
+ token = Ext.Object.fromQueryString(window.location.search).token;
+ if (token) {
+ parameters.token = token;
+ }
+ Ext.Ajax.request({
+ scope: this,
+ url: 'api/session',
+ method: 'GET',
+ params: parameters,
+ callback: this.onSessionReturn
+ });
+ } else {
+ Traccar.app.showError(response);
+ }
+ },
+
+ onSessionReturn: function (options, success, response) {
+ var passwordReset, dialog;
+ Ext.get('spinner').setVisible(false);
+ if (success) {
+ Traccar.app.setUser(Ext.decode(response.responseText));
+ this.loadApp();
+ } else {
+ this.login = Ext.create('widget.login', {
+ listeners: {
+ scope: this,
+ login: this.onLogin
+ }
+ });
+ this.login.show();
+
+ passwordReset = Ext.Object.fromQueryString(window.location.search).passwordReset;
+ if (passwordReset) {
+ dialog = Ext.Msg.prompt(Strings.loginReset, Strings.userPassword, function (btn, text) {
+ dialog.textField.inputEl.dom.type = 'text';
+ if (btn === 'ok') {
+ Ext.Ajax.request({
+ scope: this,
+ method: 'POST',
+ url: 'api/password/update',
+ params: {
+ token: passwordReset,
+ password: text
+ },
+ callback: function (options, success, response) {
+ if (success) {
+ Traccar.app.showToast(Strings.loginUpdateSuccess);
+ this.removeUrlParameter('passwordReset');
+ } else {
+ Traccar.app.showError(response.responseText);
+ }
+ }
+ });
+ }
+ }, this);
+ dialog.textField.inputEl.dom.type = 'password';
+ }
+ }
+ },
+
+ onLogin: function () {
+ this.login.close();
+ this.loadApp();
+ },
+
+ loadApp: function () {
+ var updateView, attributionView, eventId;
+
+ if (window.webkit && window.webkit.messageHandlers.appInterface) {
+ window.webkit.messageHandlers.appInterface.postMessage('login');
+ }
+ if (window.appInterface) {
+ window.appInterface.postMessage('login');
+ }
+
+ Ext.getStore('Groups').load();
+ Ext.getStore('Drivers').load();
+ Ext.getStore('Geofences').load();
+ Ext.getStore('Calendars').load();
+ Ext.getStore('Maintenances').load();
+ Ext.getStore('ComputedAttributes').load();
+ Ext.getStore('AllCommandTypes').load();
+ Ext.getStore('Commands').load();
+ Ext.getStore('AllNotificationTypes').load({
+ callback: function (records, operation, success) {
+ var store = Ext.getStore('ReportEventTypes');
+ if (success) {
+ store.add({
+ type: Traccar.store.ReportEventTypes.allEvents,
+ name: Strings.eventAll
+ });
+ store.loadData(records, true);
+ }
+ }
+ });
+ Ext.getStore('AllNotificators').load();
+ Ext.getStore('Notifications').load();
+
+ Ext.getStore('ServerAttributes').loadData(Ext.getStore('CommonDeviceAttributes').getData().items, true);
+ Ext.getStore('ServerAttributes').loadData(Ext.getStore('CommonUserAttributes').getData().items, true);
+ Ext.getStore('UserAttributes').loadData(Ext.getStore('CommonUserAttributes').getData().items, true);
+ Ext.getStore('DeviceAttributes').loadData(Ext.getStore('CommonDeviceAttributes').getData().items, true);
+ Ext.getStore('GroupAttributes').loadData(Ext.getStore('CommonDeviceAttributes').getData().items, true);
+
+ Ext.getStore('Devices').load({
+ scope: this,
+ callback: function () {
+ this.asyncUpdate(true);
+ }
+ });
+ updateView = Ext.get('update');
+ if (updateView) {
+ updateView.remove();
+ }
+ attributionView = Ext.get('attribution');
+ if (attributionView) {
+ attributionView.remove();
+ }
+ if (Traccar.app.isMobile()) {
+ Ext.create('widget.mainMobile');
+ } else {
+ Ext.create('widget.main');
+ }
+ eventId = Ext.Object.fromQueryString(window.location.search).eventId;
+ if (eventId) {
+ this.fireEvent('showsingleevent', eventId);
+ this.removeUrlParameter('eventId');
+ }
+ },
+
+ beep: function () {
+ if (!this.beepSound) {
+ this.beepSound = new Audio('beep.wav');
+ }
+ this.beepSound.play();
+ },
+
+ soundPressed: function () {
+ var soundButton = Ext.getCmp('soundButton');
+ return soundButton && soundButton.pressed;
+ },
+
+ removeUrlParameter: function (param) {
+ var params = Ext.Object.fromQueryString(window.location.search);
+ delete params[param];
+ if (Ext.Object.isEmpty(params)) {
+ window.history.pushState(null, null, window.location.pathname);
+ } else {
+ window.history.pushState(null, null, window.location.pathname + '?' + Ext.Object.toQueryString(params));
+ }
+ },
+
+ asyncUpdate: function (first) {
+ var self = this, protocol, pathname, socket;
+ protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
+ pathname = window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/') + 1);
+ socket = new WebSocket(protocol + '//' + window.location.host + pathname + 'api/socket');
+
+ socket.onclose = function () {
+ Ext.Ajax.request({
+ url: 'api/devices',
+ success: function (response) {
+ self.updateDevices(Ext.decode(response.responseText));
+ },
+ failure: function (response) {
+ if (response.status === 401) {
+ window.location.reload();
+ }
+ }
+ });
+
+ Ext.Ajax.request({
+ url: 'api/positions',
+ headers: {
+ Accept: 'application/json'
+ },
+ success: function (response) {
+ self.updatePositions(Ext.decode(response.responseText));
+ }
+ });
+
+ setTimeout(function () {
+ self.asyncUpdate(false);
+ }, Traccar.Style.reconnectTimeout);
+ };
+
+ socket.onmessage = function (event) {
+ var data = Ext.decode(event.data);
+
+ if (data.devices) {
+ self.updateDevices(data.devices);
+ }
+ if (data.positions) {
+ self.updatePositions(data.positions, first);
+ first = false;
+ }
+ if (data.events) {
+ self.updateEvents(data.events);
+ }
+ };
+ },
+
+ updateDevices: function (array) {
+ var i, store, entity;
+ store = Ext.getStore('Devices');
+ for (i = 0; i < array.length; i++) {
+ entity = store.getById(array[i].id);
+ if (entity) {
+ entity.set({
+ status: array[i].status,
+ lastUpdate: array[i].lastUpdate
+ }, {
+ dirty: false
+ });
+ }
+ }
+ },
+
+ updatePositions: function (array, first) {
+ var i, store, entity, uniqueId, device;
+ store = Ext.getStore('LatestPositions');
+ for (i = 0; i < array.length; i++) {
+ entity = store.findRecord('deviceId', array[i].deviceId, 0, false, false, true);
+ if (entity) {
+ entity.set(array[i]);
+ } else {
+ store.add(Ext.create('Traccar.model.Position', array[i]));
+ }
+ if (Ext.getStore('Events').findRecord('positionId', array[i].id, 0, false, false, true)) {
+ Ext.getStore('EventPositions').add(Ext.create('Traccar.model.Position', array[i]));
+ }
+ }
+ if (first) {
+ uniqueId = Ext.Object.fromQueryString(window.location.search).deviceId;
+ if (uniqueId) {
+ device = Ext.getStore('VisibleDevices').findRecord('uniqueId', uniqueId, 0, false, true, true);
+ if (device) {
+ this.fireEvent('selectdevice', device, true);
+ }
+ }
+ if (!device) {
+ this.zoomToAllDevices();
+ }
+ }
+ },
+
+ updateEvents: function (array) {
+ var i, store, device;
+ store = Ext.getStore('Events');
+ for (i = 0; i < array.length; i++) {
+ store.insert(0, array[i]);
+ device = Ext.getStore('Devices').getById(array[i].deviceId);
+ if (device) {
+ if (this.soundPressed()) {
+ this.beep();
+ }
+ Traccar.app.showToast(array[i].text, device.get('name'));
+ } else {
+ Traccar.app.showToast(array[i].text);
+ }
+ }
+ },
+
+ zoomToAllDevices: function () {
+ var lat, lon, zoom;
+ lat = Traccar.app.getPreference('latitude', 0);
+ lon = Traccar.app.getPreference('longitude', 0);
+ zoom = Traccar.app.getPreference('zoom', 0);
+ if (lat === 0 && lon === 0 && zoom === 0) {
+ this.fireEvent('zoomtoalldevices');
+ }
+ }
+});