Browse Source

networker offline mode draft

master
Igor Zhukov 11 years ago
parent
commit
ad89c7978d
  1. 196
      app/js/lib/mtproto.js
  2. 2
      app/partials/chat_modal.html
  3. 2
      app/partials/contacts_modal.html
  4. 2
      app/partials/error_modal.html
  5. 2
      app/partials/settings_modal.html
  6. 2
      app/partials/user_modal.html
  7. 2
      app/vendor/ui-bootstrap/ui-bootstrap-custom-tpls-0.10.0.js

196
app/js/lib/mtproto.js

@ -1502,28 +1502,27 @@ factory('MtpSha1Service', function ($q) { @@ -1502,28 +1502,27 @@ factory('MtpSha1Service', function ($q) {
factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerator, MtpSecureRandom, MtpSha1Service, MtpAesService, AppConfigManager, $http, $q, $timeout, $interval) {
var updatesProcessor;
var updatesProcessor,
iii = 0,
offline = false;
function MtpNetworker(dcID, authKey, serverSalt, options) {
options = options || {};
function MtpNetworker(dcID, authKey, serverSalt) {
this.dcID = dcID;
this.iii = iii++;
this.authKey = authKey;
this.authKeyID = sha1Hash(authKey).slice(-8);
this.serverSalt = serverSalt;
// if (1 == dcID) {
// var self = this;
// (function () {
// console.log('update server salt');
// self.serverSalt = [0,0,0,0,0,0,0,0];
// $timeout(arguments.callee, nextRandomInt(2000, 12345));
// })();
// }
this.upload = options.upload || false;
this.updateSession();
this.currentRequests = 0;
this.checkConnectionPeriod = 0;
this.sentMessages = {};
this.serverMessages = [];
@ -1540,7 +1539,7 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato @@ -1540,7 +1539,7 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato
this.checkLongPoll();
};
MtpNetworker.prototype.updateSession = function (updateMessageID) {
MtpNetworker.prototype.updateSession = function () {
console.log('Update session');
this.seqNo = 0;
this.sessionID = new Array(8);
@ -1668,12 +1667,12 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato @@ -1668,12 +1667,12 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato
MtpNetworker.prototype.checkLongPoll = function(force) {
var isClean = this.cleanupSent();
// console.log('Check lp', this.longPollPending, tsNow());
if (this.longPollPending && tsNow() < this.longPollPending) {
if (this.longPollPending && tsNow() < this.longPollPending || this.offline) {
return false;
}
var self = this;
AppConfigManager.get('dc').then(function (baseDcID) {
if (baseDcID != self.dcID && isClean) {
if (isClean && (baseDcID != self.dcID || self.upload)) {
// console.warn('send long-poll for guest DC is delayed', self.dcID);
return;
}
@ -1682,15 +1681,25 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato @@ -1682,15 +1681,25 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato
};
MtpNetworker.prototype.sendLongPoll = function() {
var maxWait = 25000;
var maxWait = 25000,
self = this;
this.longPollPending = tsNow() + maxWait;
// console.log('Set lp', this.longPollPending, tsNow());
this.wrapMtpCall('http_wait', {max_delay: 0, wait_after: 0, max_wait: maxWait}, {noResponse: true}).
then((function () {
delete this.longPollPending;
$timeout(this.checkLongPoll.bind(this), 0);
}).bind(this));
this.wrapMtpCall('http_wait', {
max_delay: 0,
wait_after: 0,
max_wait: maxWait
}, {
noResponse: true
}).then(function () {
delete self.longPollPending;
$timeout(self.checkLongPoll.bind(self), 0);
}, function () {
console.log('Long-poll failed');
});
};
MtpNetworker.prototype.pushMessage = function(message, options) {
@ -1741,9 +1750,74 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato @@ -1741,9 +1750,74 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato
});
};
MtpNetworker.prototype.checkConnection = function(event) {
console.log('check connection', event);
$timeout.cancel(this.checkConnectionPromise);
var serializer = new TLSerialization({mtproto: true}),
pingID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)];
serializer.storeMethod('ping', {ping_id: pingID});
var pingMessage = {
msg_id: MtpMessageIdGenerator.generateID(),
seq_no: this.generateSeqNo(true),
body: serializer.getBytes()
};
var self = this;
this.sendEncryptedRequest(pingMessage).then(function (result) {
self.toggleOffline(false);
}, function () {
console.log('delay ', self.checkConnectionPeriod * 1000);
self.checkConnectionPromise = $timeout(self.checkConnection.bind(self), parseInt(self.checkConnectionPeriod * 1000));
self.checkConnectionPeriod = Math.min(60, self.checkConnectionPeriod * 1.5);
})
};
MtpNetworker.prototype.toggleOffline = function(enabled) {
console.log('toggle ', enabled, this.dcID, this.iii);
if (this.offline == enabled) {
return false;
}
this.offline = enabled;
if (this.offline) {
$timeout.cancel(this.nextReqPromise);
delete this.nextReq;
if (this.checkConnectionPeriod < 1.5) {
this.checkConnectionPeriod = 0;
}
this.checkConnectionPromise = $timeout(this.checkConnection.bind(this), parseInt(this.checkConnectionPeriod * 1000));
this.checkConnectionPeriod = Math.min(60, (1 + this.checkConnectionPeriod) * 1.5);
this.onOnlineCb = this.checkConnection.bind(this);
$(document.body).on('online', this.onOnlineCb);
} else {
delete this.longPollPending;
this.checkLongPoll();
this.sheduleRequest();
if (this.onOnlineCb) {
$(document.body).off('online', this.onOnlineCb);
}
$timeout.cancel(this.checkConnectionPromise);
}
};
MtpNetworker.prototype.performSheduledRequest = function() {
// console.log('start sheduled');
// console.trace('sheduled', this.dcID, this.iii);
if (this.offline) {
console.log('cancel sheduled');
return false;
}
delete this.nextReq;
if (this.pendingAcks.length) {
var ackMsgIDs = [];
@ -1846,7 +1920,32 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato @@ -1846,7 +1920,32 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato
});
self.checkLongPoll();
this.checkConnectionPeriod = Math.max(1.1, Math.sqrt(this.checkConnectionPeriod));
});
}, function (error) {
console.log('Encrypted request failed', error);
if (message.container) {
angular.forEach(message.inner, function (msgID) {
self.pendingMessages[msgID] = 0;
});
delete self.sentMessages[message.msg_id];
} else {
self.pendingMessages[message.msg_id] = 0;
}
angular.forEach(noResponseMsgs, function (msgID) {
if (self.sentMessages[msgID]) {
var deferred = self.sentMessages[msgID].deferred;
delete self.sentMessages[msgID];
delete self.pendingMessages[msgID];
deferred.reject();
}
});
self.toggleOffline(true);
});
};
@ -1970,6 +2069,9 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato @@ -1970,6 +2069,9 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato
};
MtpNetworker.prototype.sheduleRequest = function (delay) {
if (this.offline) {
this.checkConnection('forced shedule');
}
var nextReq = tsNow() + delay;
if (delay && this.nextReq && this.nextReq <= nextReq) {
@ -1979,9 +2081,9 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato @@ -1979,9 +2081,9 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato
// console.log('shedule req', delay);
// console.trace();
clearTimeout(this.nextReqTO);
$timeout.cancel(this.nextReqPromise);
this.nextReqTO = $timeout(this.performSheduledRequest.bind(this), delay || 0);
this.nextReqPromise = $timeout(this.performSheduledRequest.bind(this), delay || 0);
this.nextReq = nextReq;
};
@ -2173,8 +2275,8 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato @@ -2173,8 +2275,8 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato
};
return {
getNetworker: function (dcID, authKey, serverSalt) {
return new MtpNetworker(dcID, authKey, serverSalt);
getNetworker: function (dcID, authKey, serverSalt, options) {
return new MtpNetworker(dcID, authKey, serverSalt, options);
},
setUpdatesProcessor: function (callback) {
updatesProcessor = callback;
@ -2185,6 +2287,7 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato @@ -2185,6 +2287,7 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato
factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworkerFactory, $q) {
var cachedNetworkers = {},
cachedUploadNetworkers = {},
cachedExportPromise = {},
baseDcID = false;
@ -2211,13 +2314,14 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker @@ -2211,13 +2314,14 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker
});
}
function mtpGetNetworker (dcID) {
function mtpGetNetworker (dcID, upload) {
var cache = upload ? cachedUploadNetworkers : cachedNetworkers;
if (!dcID) {
throw new Exception('get Networker without dcID');
}
if (cachedNetworkers[dcID] !== undefined) {
return $q.when(cachedNetworkers[dcID]);
if (cache[dcID] !== undefined) {
return $q.when(cache[dcID]);
}
var akk = 'dc' + dcID + '_auth_key',
@ -2225,8 +2329,8 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker @@ -2225,8 +2329,8 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker
return AppConfigManager.get(akk, ssk).then(function (result) {
if (cachedNetworkers[dcID] !== undefined) {
return cachedNetworkers[dcID];
if (cache[dcID] !== undefined) {
return cache[dcID];
}
var authKeyHex = result[0],
@ -2236,7 +2340,7 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker @@ -2236,7 +2340,7 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker
var authKey = bytesFromHex(authKeyHex);
var serverSalt = bytesFromHex(serverSaltHex);
return cachedNetworkers[dcID] = MtpNetworkerFactory.getNetworker(dcID, authKey, serverSalt);
return cache[dcID] = MtpNetworkerFactory.getNetworker(dcID, authKey, serverSalt, {upload: upload});
}
return MtpAuthorizer.auth(dcID).then(function (auth) {
@ -2245,7 +2349,7 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker @@ -2245,7 +2349,7 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker
storeObj[ssk] = bytesToHex(auth.serverSalt);
AppConfigManager.set(storeObj);
return cachedNetworkers[dcID] = MtpNetworkerFactory.getNetworker(dcID, auth.authKey, auth.serverSalt);
return cache[dcID] = MtpNetworkerFactory.getNetworker(dcID, auth.authKey, auth.serverSalt, {upload: upload});
}, function (error) {
console.log('Get networker error', error, error.stack);
return $q.reject(error);
@ -2258,13 +2362,14 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker @@ -2258,13 +2362,14 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker
var deferred = $q.defer(),
dcID,
upload = options.fileDownload || options.fileUpload,
networkerPromise;
if (dcID = options.dcID) {
networkerPromise = mtpGetNetworker(dcID);
networkerPromise = mtpGetNetworker(dcID, upload);
} else {
networkerPromise = AppConfigManager.get('dc').then(function (baseDcID) {
return mtpGetNetworker(dcID = baseDcID || 1);
return mtpGetNetworker(dcID = baseDcID || 1, upload);
});
}
@ -2543,7 +2648,10 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) { @@ -2543,7 +2648,10 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
location: angular.extend({}, location, {_: 'inputFileLocation'}),
offset: 0,
limit: 0
}, {dcID: location.dc_id});
}, {
dcID: location.dc_id,
fileDownload: true
});
});
fileEntry.createWriter(function (fileWriter) {
@ -2577,7 +2685,10 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) { @@ -2577,7 +2685,10 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
location: angular.extend({}, location, {_: 'inputFileLocation'}),
offset: 0,
limit: 0
}, {dcID: location.dc_id});
}, {
dcID: location.dc_id,
fileDownload: true
});
}).then(function (result) {
deferred.resolve(cachedDownloads[fileName] = 'data:image/jpeg;base64,' + bytesToBase64(result.bytes))
}, errorHandler);
@ -2624,7 +2735,10 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) { @@ -2624,7 +2735,10 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
location: location,
offset: offset,
limit: limit
}, {dcID: dcID});
}, {
dcID: dcID,
fileDownload: true
});
}, 6).then(function (result) {
@ -2692,7 +2806,10 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) { @@ -2692,7 +2806,10 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
location: location,
offset: offset,
limit: limit
}, {dcID: dcID});
}, {
dcID: dcID,
fileDownload: true
});
}, 6).then(function (result) {
writeBlobPromise.then(function () {
try {
@ -2813,7 +2930,10 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) { @@ -2813,7 +2930,10 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
file_id: fileID,
file_part: part,
bytes: bytesFromArrayBuffer(e.target.result)
}, {startMaxLength: partSize + 256});
}, {
startMaxLength: partSize + 256,
fileUpload: true
});
}, errorHandler);
apiCurPromise.then(function (result) {

2
app/partials/chat_modal.html

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
<div class="chat_modal_wrap">
<div class="modal-header">
<a class="modal-close-link visible-xs visible-sm" ng-click="$close()">Close</a>
<a class="modal-close-link" ng-click="$close()">Close</a>
<h4 class="modal-title">Group Info</h4>
</div>

2
app/partials/contacts_modal.html

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
<div class="contacts_modal_wrap">
<div class="modal-header">
<a class="modal-close-link visible-xs visible-sm" ng-click="$close()">Close</a>
<a class="modal-close-link" ng-click="$close()">Close</a>
<h4 class="modal-title">Contacts</h4>
</div>

2
app/partials/error_modal.html

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
<div class="error_modal_wrap">
<div class="modal-header">
<a class="modal-close-link visible-xs visible-sm" ng-click="$close()">Close</a>
<a class="modal-close-link" ng-click="$close()">Close</a>
<h4 class="modal-title">{{title}}</h4>
</div>

2
app/partials/settings_modal.html

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
<div class="settings_modal_wrap">
<div class="modal-header">
<a class="modal-close-link visible-xs visible-sm" ng-click="$close()">Close</a>
<a class="modal-close-link" ng-click="$close()">Close</a>
<h4 class="modal-title">Settings</h4>
</div>

2
app/partials/user_modal.html

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
<div class="user_modal_wrap">
<div class="modal-header">
<a class="modal-close-link visible-xs visible-sm" ng-click="$close()">Close</a>
<a class="modal-close-link" ng-click="$close()">Close</a>
<h4 class="modal-title">Info</h4>
</div>

2
app/vendor/ui-bootstrap/ui-bootstrap-custom-tpls-0.10.0.js vendored

@ -1074,7 +1074,7 @@ angular.module("template/modal/backdrop.html", []).run(["$templateCache", functi @@ -1074,7 +1074,7 @@ angular.module("template/modal/backdrop.html", []).run(["$templateCache", functi
angular.module("template/modal/window.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("template/modal/window.html",
"<div tabindex=\"-1\" class=\"modal fade {{ windowClass }}\" ng-class=\"{in: animate}\" ng-style=\"{'z-index': 1050 + index*10, display: 'block'}\" ng-click=\"close($event)\">\n" +
" <div class=\"modal_close_wrap visible-md visible-lg\" ng-click=\"close($event)\">\n" +
" <div class=\"modal_close_wrap hidden-xs hidden-sm\" ng-click=\"close($event)\">\n" +
" <div class=\"modal_close\"></div>\n" +
" </div>\n" +
" <div class=\"modal-dialog\"><div class=\"modal-content\" ng-transclude></div></div>\n" +

Loading…
Cancel
Save