From a09191b65fe78f36c90bcc7b76f28ce022706a8b Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Fri, 7 Nov 2014 19:07:54 +0300 Subject: [PATCH] Single instance checks --- app/js/lib/config.js | 2 +- app/js/lib/mtproto.js | 22 +++++++- app/js/lib/mtproto_wrapper.js | 81 ++++++++++++++++++++++++++- app/js/lib/ng_utils.js | 5 ++ app/js/locales/en-us.json | 3 + app/js/services.js | 4 +- app/partials/desktop/error_modal.html | 3 + 7 files changed, 114 insertions(+), 6 deletions(-) diff --git a/app/js/lib/config.js b/app/js/lib/config.js index bf0f6fbe..80f2aa85 100644 --- a/app/js/lib/config.js +++ b/app/js/lib/config.js @@ -133,7 +133,7 @@ Config.LangCountries = {"es": "ES", "ru": "RU", "en": "US", "de": "DE", "it": "I for (i = 0; i < keys.length; i++) { key = keys[i] = prefix + keys[i]; - if (cache[key] !== undefined) { + if (key.substr(0, 3) != 'xt_' && cache[key] !== undefined) { result.push(cache[key]); } else if (useLs) { diff --git a/app/js/lib/mtproto.js b/app/js/lib/mtproto.js index c56a8709..29fdf562 100644 --- a/app/js/lib/mtproto.js +++ b/app/js/lib/mtproto.js @@ -563,6 +563,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) iii = 0, offline, offlineInited = false, + akStopped = false, chromeMatches = navigator.userAgent.match(/Chrome\/(\d+(\.\d+)?)/), chromeVersion = chromeMatches && parseFloat(chromeMatches[1]) || false, xhrSendBuffer = !('ArrayBufferView' in window) && (!chromeVersion || chromeVersion < 30); @@ -771,7 +772,9 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) MtpNetworker.prototype.checkLongPoll = function(force) { var isClean = this.cleanupSent(); // console.log('Check lp', this.longPollPending, tsNow(), this.dcID, isClean); - if (this.longPollPending && tsNow() < this.longPollPending || this.offline) { + if (this.longPollPending && tsNow() < this.longPollPending || + this.offline || + akStopped) { return false; } var self = this; @@ -962,7 +965,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) MtpNetworker.prototype.performSheduledRequest = function() { // console.log(dT(), 'sheduled', this.dcID, this.iii); - if (this.offline) { + if (this.offline || akStopped) { console.log(dT(), 'Cancel sheduled'); return false; } @@ -1558,13 +1561,26 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) } }; + function startAll() { + if (akStopped) { + akStopped = false; + updatesProcessor({_: 'new_session_created'}); + } + } + + function stopAll() { + akStopped = true; + } + return { getNetworker: function (dcID, authKey, serverSalt, options) { return new MtpNetworker(dcID, authKey, serverSalt, options); }, setUpdatesProcessor: function (callback) { updatesProcessor = callback; - } + }, + stopAll: stopAll, + startAll: startAll }; }) diff --git a/app/js/lib/mtproto_wrapper.js b/app/js/lib/mtproto_wrapper.js index 50a3fe7b..6ea95e85 100644 --- a/app/js/lib/mtproto_wrapper.js +++ b/app/js/lib/mtproto_wrapper.js @@ -7,12 +7,14 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto']) -.factory('MtpApiManager', function (Storage, MtpAuthorizer, MtpNetworkerFactory, ErrorService, $q) { +.factory('MtpApiManager', function (Storage, MtpAuthorizer, MtpNetworkerFactory, MtpSingleInstanceService, ErrorService, $q) { var cachedNetworkers = {}, cachedUploadNetworkers = {}, cachedExportPromise = {}, baseDcID = false; + MtpSingleInstanceService.start(); + Storage.get('dc').then(function (dcID) { if (dcID) { baseDcID = dcID; @@ -610,3 +612,80 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto']) uploadFile: uploadFile }; }) + +.service('MtpSingleInstanceService', function ($rootScope, $interval, Storage, AppRuntimeManager, IdleManager, ErrorService, MtpNetworkerFactory) { + + var instanceID = nextRandomInt(0xFFFFFFFF); + var started = false; + var masterInstance = false; + var startTime = tsNow(); + var errorShowTime = 0; + + function start() { + if (!started) { + started = true; + + IdleManager.start(); + + startTime = tsNow(); + $rootScope.$watch('idle.isIDLE', checkInstance); + $interval(checkInstance, 5000); + checkInstance(); + + try { + $($window).on('beforeunload', clearInstance); + } catch (e) {}; + } + } + + function clearInstance () { + Storage.remove(masterInstance ? 'xt_instance' : 'xt_idle_instance'); + } + + function checkInstance() { + var time = tsNow(); + var idle = $rootScope.idle && $rootScope.idle.isIDLE; + var newInstance = {id: instanceID, idle: idle, time: time}; + + Storage.get('xt_instance', 'xt_idle_instance').then(function (result) { + var curInstance = result[0], + idleInstance = result[1]; + + if (!curInstance || + curInstance.time < time - 60000 || + curInstance.id == instanceID || + curInstance.idle || + !idle) { + + if (idleInstance) { + if (idleInstance.id == instanceID) { + Storage.remove('xt_idle_instance'); + } + else if (idleInstance.time > time - 10000 && + time > errorShowTime) { + + ErrorService.show({error: {type: 'MULTIPLE_TABS_OPEN'}}); + errorShowTime += tsNow() + 60000; + } + } + Storage.set({xt_instance: newInstance}); + if (!masterInstance) { + MtpNetworkerFactory.startAll(); + } + masterInstance = true; + } else { + Storage.set({xt_idle_instance: newInstance}); + if (masterInstance) { + MtpNetworkerFactory.stopAll(); + } + masterInstance = false; + + } + }); + } + + return { + start: start + } +}) + diff --git a/app/js/lib/ng_utils.js b/app/js/lib/ng_utils.js index d5eb5702..929cd58a 100644 --- a/app/js/lib/ng_utils.js +++ b/app/js/lib/ng_utils.js @@ -808,6 +808,11 @@ angular.module('izhukov.utils', []) chrome.runtime.reload(); }; }, + close: function () { + try { + $window.close(); + } catch (e) {} + }, focus: function () { if (window.navigator.mozApps && document.hidden) { // Get app instance and launch it to bring app to foreground diff --git a/app/js/locales/en-us.json b/app/js/locales/en-us.json index 59ee2914..f0031597 100644 --- a/app/js/locales/en-us.json +++ b/app/js/locales/en-us.json @@ -195,6 +195,7 @@ "message_service_left_group": "left group", "message_service_unsupported_action": "Unsupported action {action}", + "error_modal_warning_title": "Warning", "error_modal_bad_request_title": "Error", "error_modal_unauthorized_title": "Unauthorized", "error_modal_forbidden_title": "Access denied", @@ -224,6 +225,8 @@ "error_modal_flood_description": "You are performing too many actions. Please try again later.", "error_modal_internal_description": "Internal server error occured. Please try again later.", "error_modal_tech_details": "Technical details here", + "error_modal_multiple_open_tabs": "Telegram Web doesn't support working in multiple tabs. Please close other app instances.", + "head_new_group": "New Group", "head_new_contact": "New Contact", diff --git a/app/js/services.js b/app/js/services.js index 462ceeba..51ee0ac2 100644 --- a/app/js/services.js +++ b/app/js/services.js @@ -3463,7 +3463,9 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) try { - $($window).on('beforeunload', notificationsClear); + if ('onbeforeunload' in window) { + $($window).on('beforeunload', notificationsClear); + } } catch (e) {} } diff --git a/app/partials/desktop/error_modal.html b/app/partials/desktop/error_modal.html index 30c7400c..341b425f 100644 --- a/app/partials/desktop/error_modal.html +++ b/app/partials/desktop/error_modal.html @@ -5,6 +5,7 @@