Improved channel updates handling
This commit is contained in:
parent
7c425b5a6a
commit
923250bc41
@ -654,16 +654,16 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var topMessages = [];
|
var indexes = [];
|
||||||
var topToDialogs = {};
|
var indexesToDialogs = {};
|
||||||
angular.forEach(dialogsUpdated, function (dialog, peerID) {
|
angular.forEach(dialogsUpdated, function (dialog, peerID) {
|
||||||
if ($scope.noUsers && peerID > 0) {
|
if ($scope.noUsers && peerID > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
topToDialogs[dialog.top_message] = dialog;
|
indexesToDialogs[dialog.index] = dialog;
|
||||||
topMessages.push(dialog.top_message);
|
indexes.push(dialog.index);
|
||||||
});
|
});
|
||||||
topMessages.sort();
|
indexes.sort();
|
||||||
|
|
||||||
var i, dialog;
|
var i, dialog;
|
||||||
var len = $scope.dialogs.length;
|
var len = $scope.dialogs.length;
|
||||||
@ -675,9 +675,9 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
len = topMessages.length;
|
len = indexes.length;
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
dialog = topToDialogs[topMessages[i]];
|
dialog = indexesToDialogs[indexes[i]];
|
||||||
$scope.dialogs.unshift(
|
$scope.dialogs.unshift(
|
||||||
AppMessagesManager.wrapForDialog(dialog.top_message, dialog.unread_count)
|
AppMessagesManager.wrapForDialog(dialog.top_message, dialog.unread_count)
|
||||||
);
|
);
|
||||||
@ -1654,6 +1654,11 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$scope.$on('history_reload', function (e, updPeerID) {
|
||||||
|
if (updPeerID == $scope.curDialog.peerID) {
|
||||||
|
loadHistory();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var typingTimeouts = {};
|
var typingTimeouts = {};
|
||||||
$scope.$on('history_append', function (e, addedMessage) {
|
$scope.$on('history_append', function (e, addedMessage) {
|
||||||
|
@ -140,6 +140,42 @@ angular.module('myApp.services')
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function saveChannelDialog (channelID, dialog) {
|
||||||
|
var peerID = -channelID;
|
||||||
|
var peerText = AppPeersManager.getPeerSearchText(peerID);
|
||||||
|
SearchIndexManager.indexObject(peerID, peerText, dialogsIndex);
|
||||||
|
|
||||||
|
var mid = getFullMessageID(dialog.top_important_message, channelID);
|
||||||
|
dialog.top_message = mid;
|
||||||
|
dialog.unread_count = dialog.unread_important_count;
|
||||||
|
dialog.read_inbox_max_id = getFullMessageID(dialog.read_inbox_max_id, channelID);
|
||||||
|
|
||||||
|
var message = getMessage(dialog.top_message);
|
||||||
|
var topDate = message.date;
|
||||||
|
var channel = AppChatsManager.getChat(channelID);
|
||||||
|
if (!topDate || channel.date && channel.date > topDate) {
|
||||||
|
topDate = channel.date;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.index = generateDialogIndex(topDate);
|
||||||
|
dialog.peerID = peerID;
|
||||||
|
|
||||||
|
pushDialogToStorage(dialog);
|
||||||
|
|
||||||
|
// Because we saved message without dialog present
|
||||||
|
if (message.mid && message.mid > dialog.read_inbox_max_id) {
|
||||||
|
message.unread = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (historiesStorage[peerID] === undefined) {
|
||||||
|
var historyStorage = {count: null, history: [mid], pending: []};
|
||||||
|
historiesStorage[peerID] = historyStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationsManager.savePeerSettings(peerID, dialog.notify_settings);
|
||||||
|
ApiUpdatesManager.addChannelState(channelID, dialog.pts);
|
||||||
|
}
|
||||||
|
|
||||||
function getAllChannels () {
|
function getAllChannels () {
|
||||||
if (channelsLoadPromise) {
|
if (channelsLoadPromise) {
|
||||||
return channelsLoadPromise;
|
return channelsLoadPromise;
|
||||||
@ -154,30 +190,10 @@ angular.module('myApp.services')
|
|||||||
|
|
||||||
angular.forEach(dialogsResult.dialogs, function (dialog) {
|
angular.forEach(dialogsResult.dialogs, function (dialog) {
|
||||||
var peerID = AppPeersManager.getPeerID(dialog.peer);
|
var peerID = AppPeersManager.getPeerID(dialog.peer);
|
||||||
var peerText = AppPeersManager.getPeerSearchText(peerID);
|
var channelID = -peerID;
|
||||||
SearchIndexManager.indexObject(peerID, peerText, dialogsIndex);
|
saveChannelDialog(channelID, dialog);
|
||||||
|
|
||||||
var mid = getFullMessageID(dialog.top_important_message, -peerID);
|
|
||||||
dialog.top_message = mid;
|
|
||||||
|
|
||||||
var message = getMessage(dialog.top_message);
|
|
||||||
var topDate = message.date;
|
|
||||||
var channel = AppChatsManager.getChat(-peerID);
|
|
||||||
if (!topDate || channel.date && channel.date > topDate) {
|
|
||||||
topDate = channel.date;
|
|
||||||
}
|
|
||||||
|
|
||||||
dialog.index = generateDialogIndex(topDate);
|
|
||||||
dialog.peerID = peerID;
|
|
||||||
|
|
||||||
pushDialogToStorage(dialog);
|
|
||||||
|
|
||||||
if (historiesStorage[peerID] === undefined) {
|
|
||||||
var historyStorage = {count: null, history: [mid], pending: []};
|
|
||||||
historiesStorage[peerID] = historyStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationsManager.savePeerSettings(peerID, dialog.notify_settings);
|
NotificationsManager.savePeerSettings(peerID, dialog.notify_settings);
|
||||||
|
ApiUpdatesManager.addChannelState(channelID, dialog.pts);
|
||||||
});
|
});
|
||||||
allChannelsLoaded = true;
|
allChannelsLoaded = true;
|
||||||
});
|
});
|
||||||
@ -188,7 +204,9 @@ angular.module('myApp.services')
|
|||||||
offset: offset,
|
offset: offset,
|
||||||
limit: limit
|
limit: limit
|
||||||
}).then(function (dialogsResult) {
|
}).then(function (dialogsResult) {
|
||||||
TelegramMeWebService.setAuthorized(true);
|
if (!offset) {
|
||||||
|
TelegramMeWebService.setAuthorized(true);
|
||||||
|
}
|
||||||
|
|
||||||
// Server-side bug
|
// Server-side bug
|
||||||
if (dialogsResult.count && offset >= dialogsResult.count) {
|
if (dialogsResult.count && offset >= dialogsResult.count) {
|
||||||
@ -288,8 +306,9 @@ angular.module('myApp.services')
|
|||||||
|
|
||||||
function requestHistory (inputPeer, maxID, limit, offset) {
|
function requestHistory (inputPeer, maxID, limit, offset) {
|
||||||
var peerID = AppPeersManager.getPeerID(inputPeer);
|
var peerID = AppPeersManager.getPeerID(inputPeer);
|
||||||
|
var isChannel = AppPeersManager.isChannel(peerID);
|
||||||
var promise;
|
var promise;
|
||||||
if (AppPeersManager.isChannel(peerID)) {
|
if (isChannel) {
|
||||||
promise = MtpApiManager.invokeApi('channels.getImportantHistory', {
|
promise = MtpApiManager.invokeApi('channels.getImportantHistory', {
|
||||||
channel: AppChatsManager.getChannelInput(-peerID),
|
channel: AppChatsManager.getChannelInput(-peerID),
|
||||||
offset_id: maxID ? getMessageLocalID(maxID) : 0,
|
offset_id: maxID ? getMessageLocalID(maxID) : 0,
|
||||||
@ -310,6 +329,10 @@ angular.module('myApp.services')
|
|||||||
AppChatsManager.saveApiChats(historyResult.chats);
|
AppChatsManager.saveApiChats(historyResult.chats);
|
||||||
saveMessages(historyResult.messages);
|
saveMessages(historyResult.messages);
|
||||||
|
|
||||||
|
if (isChannel) {
|
||||||
|
ApiUpdatesManager.addChannelState(-peerID, historyResult.pts);
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
peerID < 0 ||
|
peerID < 0 ||
|
||||||
!AppUsersManager.isBot(peerID) ||
|
!AppUsersManager.isBot(peerID) ||
|
||||||
@ -789,7 +812,6 @@ angular.module('myApp.services')
|
|||||||
for (i = historyStorage.history.length; i >= 0; i--) {
|
for (i = historyStorage.history.length; i >= 0; i--) {
|
||||||
messageID = historyStorage.history[i];
|
messageID = historyStorage.history[i];
|
||||||
message = messagesStorage[messageID];
|
message = messagesStorage[messageID];
|
||||||
// console.log('ms', message);
|
|
||||||
if (message && !message.out && message.unread) {
|
if (message && !message.out && message.unread) {
|
||||||
foundUnread = true;
|
foundUnread = true;
|
||||||
break;
|
break;
|
||||||
@ -826,6 +848,9 @@ angular.module('myApp.services')
|
|||||||
foundDialog[0].unread_count = 0;
|
foundDialog[0].unread_count = 0;
|
||||||
$rootScope.$broadcast('dialog_unread', {peerID: peerID, count: 0});
|
$rootScope.$broadcast('dialog_unread', {peerID: peerID, count: 0});
|
||||||
$rootScope.$broadcast('messages_read');
|
$rootScope.$broadcast('messages_read');
|
||||||
|
if (historyStorage && historyStorage.history.length) {
|
||||||
|
foundDialog[0].read_inbox_max_id = historyStorage.history[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})['finally'](function () {
|
})['finally'](function () {
|
||||||
delete historyStorage.readPromise;
|
delete historyStorage.readPromise;
|
||||||
@ -895,7 +920,6 @@ angular.module('myApp.services')
|
|||||||
if (apiMessage._ == 'messageEmpty') {
|
if (apiMessage._ == 'messageEmpty') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
apiMessage.unread = apiMessage.flags & 1 ? true : false;
|
|
||||||
apiMessage.out = apiMessage.flags & 2 ? true : false;
|
apiMessage.out = apiMessage.flags & 2 ? true : false;
|
||||||
apiMessage.media_unread = apiMessage.flags & 32 ? true : false;
|
apiMessage.media_unread = apiMessage.flags & 32 ? true : false;
|
||||||
|
|
||||||
@ -907,6 +931,13 @@ angular.module('myApp.services')
|
|||||||
apiMessage.mid = mid;
|
apiMessage.mid = mid;
|
||||||
messagesStorage[mid] = apiMessage;
|
messagesStorage[mid] = apiMessage;
|
||||||
|
|
||||||
|
if (channelID && !apiMessage.out) {
|
||||||
|
var dialog = getDialogByPeerID(toPeerID)[0];
|
||||||
|
apiMessage.unread = dialog ? mid > dialog.read_inbox_max_id : true;
|
||||||
|
} else {
|
||||||
|
apiMessage.unread = apiMessage.flags & 1 ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
if (apiMessage.reply_to_msg_id) {
|
if (apiMessage.reply_to_msg_id) {
|
||||||
apiMessage.reply_to_mid = getFullMessageID(apiMessage.reply_to_msg_id, channelID);
|
apiMessage.reply_to_mid = getFullMessageID(apiMessage.reply_to_msg_id, channelID);
|
||||||
}
|
}
|
||||||
@ -2059,6 +2090,9 @@ angular.module('myApp.services')
|
|||||||
function handleNewDialogs () {
|
function handleNewDialogs () {
|
||||||
$timeout.cancel(newDialogsHandlePromise);
|
$timeout.cancel(newDialogsHandlePromise);
|
||||||
newDialogsHandlePromise = false;
|
newDialogsHandlePromise = false;
|
||||||
|
angular.forEach(newDialogsToHandle, function (dialog) {
|
||||||
|
pushDialogToStorage(dialog);
|
||||||
|
});
|
||||||
$rootScope.$broadcast('dialogs_multiupdate', newDialogsToHandle);
|
$rootScope.$broadcast('dialogs_multiupdate', newDialogsToHandle);
|
||||||
newDialogsToHandle = {};
|
newDialogsToHandle = {};
|
||||||
}
|
}
|
||||||
@ -2089,19 +2123,26 @@ angular.module('myApp.services')
|
|||||||
}
|
}
|
||||||
|
|
||||||
$rootScope.$on('apiUpdate', function (e, update) {
|
$rootScope.$on('apiUpdate', function (e, update) {
|
||||||
// if (update._ != 'updateUserStatus') {
|
if (update._ != 'updateUserStatus') {
|
||||||
// console.log('on apiUpdate', update);
|
console.log('on apiUpdate', update);
|
||||||
// }
|
}
|
||||||
switch (update._) {
|
switch (update._) {
|
||||||
case 'updateMessageID':
|
case 'updateMessageID':
|
||||||
pendingByMessageID[update.id] = update.random_id;
|
pendingByMessageID[update.id] = update.random_id;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'updateNewMessage':
|
case 'updateNewMessage':
|
||||||
|
case 'updateNewChannelMessage':
|
||||||
var message = update.message,
|
var message = update.message,
|
||||||
peerID = getMessagePeer(message),
|
peerID = getMessagePeer(message),
|
||||||
historyStorage = historiesStorage[peerID];
|
historyStorage = historiesStorage[peerID];
|
||||||
|
|
||||||
|
if (update._ == 'updateNewChannelMessage' &&
|
||||||
|
!(message.flags & 16 || message.flags & 2 || (message.flags & 256) == 0)) {
|
||||||
|
// we don't support not important messages yet
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
saveMessages([message]);
|
saveMessages([message]);
|
||||||
|
|
||||||
if (historyStorage !== undefined) {
|
if (historyStorage !== undefined) {
|
||||||
@ -2127,12 +2168,11 @@ angular.module('myApp.services')
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (mergeReplyKeyboard(historyStorage, message)) {
|
if (mergeReplyKeyboard(historyStorage, message)) {
|
||||||
$rootScope.$broadcast('history_reply_markup', {peerID: peerID})
|
$rootScope.$broadcast('history_reply_markup', {peerID: peerID})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!message.out) {
|
if (!message.out && message.from_id) {
|
||||||
AppUsersManager.forceUserOnline(message.from_id);
|
AppUsersManager.forceUserOnline(message.from_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2162,24 +2202,20 @@ angular.module('myApp.services')
|
|||||||
|
|
||||||
if (foundDialog.length) {
|
if (foundDialog.length) {
|
||||||
dialog = foundDialog[0];
|
dialog = foundDialog[0];
|
||||||
if (foundDialog[1] > 0) {
|
|
||||||
dialogsStorage.dialogs.splice(foundDialog[1], 1);
|
|
||||||
dialogsStorage.dialogs.unshift(dialog);
|
|
||||||
}
|
|
||||||
dialog.top_message = message.mid;
|
dialog.top_message = message.mid;
|
||||||
if (inboxUnread) {
|
if (inboxUnread) {
|
||||||
dialog.unread_count++;
|
dialog.unread_count++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SearchIndexManager.indexObject(peerID, AppPeersManager.getPeerSearchText(peerID), dialogsIndex);
|
SearchIndexManager.indexObject(peerID, AppPeersManager.getPeerSearchText(peerID), dialogsIndex);
|
||||||
|
|
||||||
dialog = {
|
dialog = {
|
||||||
peerID: peerID,
|
peerID: peerID,
|
||||||
unread_count: inboxUnread ? 1 : 0,
|
unread_count: inboxUnread ? 1 : 0,
|
||||||
top_message: message.mid
|
top_message: message.mid
|
||||||
};
|
};
|
||||||
dialogsStorage.dialogs.unshift(dialog);
|
|
||||||
}
|
}
|
||||||
|
dialog.index = generateDialogIndex(message.date);
|
||||||
|
|
||||||
newDialogsToHandle[peerID] = dialog;
|
newDialogsToHandle[peerID] = dialog;
|
||||||
if (!newDialogsHandlePromise) {
|
if (!newDialogsHandlePromise) {
|
||||||
newDialogsHandlePromise = $timeout(handleNewDialogs, 0);
|
newDialogsHandlePromise = $timeout(handleNewDialogs, 0);
|
||||||
@ -2217,9 +2253,11 @@ angular.module('myApp.services')
|
|||||||
|
|
||||||
case 'updateReadHistoryInbox':
|
case 'updateReadHistoryInbox':
|
||||||
case 'updateReadHistoryOutbox':
|
case 'updateReadHistoryOutbox':
|
||||||
var maxID = update.max_id;
|
case 'updateReadChannelInbox':
|
||||||
var isOut = update._ == 'updateReadHistoryOutbox';
|
var isOut = update._ == 'updateReadHistoryOutbox';
|
||||||
var peerID = AppPeersManager.getPeerID(update.peer);
|
var channelID = update.channel_id;
|
||||||
|
var maxID = getFullMessageID(update.max_id, channelID);
|
||||||
|
var peerID = channelID ? -channelID : AppPeersManager.getPeerID(update.peer);
|
||||||
var foundDialog = getDialogByPeerID(peerID);
|
var foundDialog = getDialogByPeerID(peerID);
|
||||||
var history = (historiesStorage[peerID] || {}).history || [];
|
var history = (historiesStorage[peerID] || {}).history || [];
|
||||||
var newUnreadCount = false;
|
var newUnreadCount = false;
|
||||||
@ -2289,12 +2327,14 @@ angular.module('myApp.services')
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'updateDeleteMessages':
|
case 'updateDeleteMessages':
|
||||||
var dialogsUpdated = {},
|
case 'updateDeleteChannelMessages':
|
||||||
historiesUpdated = {},
|
var dialogsUpdated = {};
|
||||||
messageID, message, i, peerID, foundDialog, history;
|
var historiesUpdated = {};
|
||||||
|
var channelID = update.channel_id;
|
||||||
|
var messageID, message, i, peerID, foundDialog, history;
|
||||||
|
|
||||||
for (i = 0; i < update.messages.length; i++) {
|
for (i = 0; i < update.messages.length; i++) {
|
||||||
messageID = update.messages[i];
|
messageID = getFullMessageID(update.messages[i], channelID);
|
||||||
message = messagesStorage[messageID];
|
message = messagesStorage[messageID];
|
||||||
if (message) {
|
if (message) {
|
||||||
peerID = getMessagePeer(message);
|
peerID = getMessagePeer(message);
|
||||||
@ -2369,6 +2409,40 @@ angular.module('myApp.services')
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'updateChannelReload':
|
||||||
|
var channelID = update.channel_id;
|
||||||
|
var peerID = -channelID;
|
||||||
|
delete historiesStorage[peerID];
|
||||||
|
var foundDialog = getDialogByPeerID(peerID);
|
||||||
|
if (foundDialog[0]) {
|
||||||
|
dialogsStorage.dialogs.splice(foundDialog[1], 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var inputPeer = AppPeersManager.getInputPeerByID(peerID);
|
||||||
|
$q.all([
|
||||||
|
getHistory(inputPeer, 0),
|
||||||
|
AppChatsManager.getChannelFull(channelID, true)
|
||||||
|
]).then(function (results) {
|
||||||
|
var historyResult = results[0];
|
||||||
|
var channelResult = results[1];
|
||||||
|
var dialog = {
|
||||||
|
_: 'dialogChannel',
|
||||||
|
peer: AppPeersManager.getOutputPeer(peerID),
|
||||||
|
top_message: historyResult.history[0],
|
||||||
|
top_important_message: historyResult.history[0],
|
||||||
|
read_inbox_max_id: channelResult.read_inbox_max_id,
|
||||||
|
unread_count: channelResult.unread_count,
|
||||||
|
unread_important_count: channelResult.unread_important_count
|
||||||
|
};
|
||||||
|
saveChannelDialog(channelID, dialog);
|
||||||
|
|
||||||
|
var updatedDialogs = {};
|
||||||
|
updatedDialogs[peerID] = dialog;
|
||||||
|
$rootScope.$broadcast('dialogs_multiupdate', updatedDialogs);
|
||||||
|
$rootScope.$broadcast('history_reload', peerID);
|
||||||
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2254,21 +2254,23 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
|
|
||||||
.service('ApiUpdatesManager', function ($rootScope, MtpNetworkerFactory, AppUsersManager, AppChatsManager, AppPeersManager, MtpApiManager) {
|
.service('ApiUpdatesManager', function ($rootScope, MtpNetworkerFactory, AppUsersManager, AppChatsManager, AppPeersManager, MtpApiManager) {
|
||||||
|
|
||||||
var curState = {};
|
var updatesState = {
|
||||||
|
pendingPtsUpdates: [],
|
||||||
|
pendingSeqUpdates: {},
|
||||||
|
syncPending: false,
|
||||||
|
syncLoading: true
|
||||||
|
};
|
||||||
|
var channelStates = {};
|
||||||
|
|
||||||
var myID = 0;
|
var myID = 0;
|
||||||
MtpApiManager.getUserID().then(function (id) {
|
MtpApiManager.getUserID().then(function (id) {
|
||||||
myID = id;
|
myID = id;
|
||||||
});
|
});
|
||||||
|
|
||||||
var syncPending = false;
|
|
||||||
var syncLoading = true;
|
|
||||||
var pendingSeqUpdates = {};
|
|
||||||
var pendingPtsUpdates = [];
|
|
||||||
|
|
||||||
function popPendingSeqUpdate () {
|
function popPendingSeqUpdate () {
|
||||||
var nextSeq = curState.seq + 1,
|
var nextSeq = updatesState.seq + 1,
|
||||||
pendingUpdatesData = pendingSeqUpdates[nextSeq];
|
pendingUpdatesData = updatesState.pendingSeqUpdates[nextSeq];
|
||||||
if (!pendingUpdatesData) {
|
if (!pendingUpdatesData) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2277,32 +2279,33 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
for (var i = 0, length = updates.length; i < length; i++) {
|
for (var i = 0, length = updates.length; i < length; i++) {
|
||||||
saveUpdate(updates[i]);
|
saveUpdate(updates[i]);
|
||||||
}
|
}
|
||||||
curState.seq = pendingUpdatesData.seq;
|
updatesState.seq = pendingUpdatesData.seq;
|
||||||
if (pendingUpdatesData.date && curState.date < pendingUpdatesData.date) {
|
if (pendingUpdatesData.date && updatesState.date < pendingUpdatesData.date) {
|
||||||
curState.date = pendingUpdatesData.date;
|
updatesState.date = pendingUpdatesData.date;
|
||||||
}
|
}
|
||||||
delete pendingSeqUpdates[nextSeq];
|
delete updatesState.pendingSeqUpdates[nextSeq];
|
||||||
|
|
||||||
if (!popPendingSeqUpdate() &&
|
if (!popPendingSeqUpdate() &&
|
||||||
syncPending &&
|
updatesState.syncPending &&
|
||||||
syncPending.seqAwaiting &&
|
updatesState.syncPending.seqAwaiting &&
|
||||||
curState.seq >= syncPending.seqAwaiting) {
|
updatesState.seq >= updatesState.syncPending.seqAwaiting) {
|
||||||
if (!syncPending.ptsAwaiting) {
|
if (!updatesState.syncPending.ptsAwaiting) {
|
||||||
clearTimeout(syncPending.timeout);
|
clearTimeout(updatesState.syncPending.timeout);
|
||||||
syncPending = false;
|
updatesState.syncPending = false;
|
||||||
} else {
|
} else {
|
||||||
delete syncPending.seqAwaiting;
|
delete updatesState.syncPending.seqAwaiting;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function popPendingPtsUpdate () {
|
function popPendingPtsUpdate (channelID) {
|
||||||
if (!pendingPtsUpdates.length) {
|
var curState = channelID ? getChannelState(channelID) : updatesState;
|
||||||
|
if (!curState.pendingPtsUpdates.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pendingPtsUpdates.sort(function (a, b) {
|
curState.pendingPtsUpdates.sort(function (a, b) {
|
||||||
return a.pts - b.pts;
|
return a.pts - b.pts;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2310,8 +2313,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
var goodPts = false;
|
var goodPts = false;
|
||||||
var goodIndex = false;
|
var goodIndex = false;
|
||||||
var update;
|
var update;
|
||||||
for (var i = 0, length = pendingPtsUpdates.length; i < length; i++) {
|
for (var i = 0, length = curState.pendingPtsUpdates.length; i < length; i++) {
|
||||||
update = pendingPtsUpdates[i];
|
update = curState.pendingPtsUpdates[i];
|
||||||
curPts += update.pts_count;
|
curPts += update.pts_count;
|
||||||
if (curPts >= update.pts) {
|
if (curPts >= update.pts) {
|
||||||
goodPts = update.pts;
|
goodPts = update.pts;
|
||||||
@ -2325,17 +2328,17 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
|
|
||||||
curState.pts = goodPts;
|
curState.pts = goodPts;
|
||||||
for (i = 0; i <= goodIndex; i++) {
|
for (i = 0; i <= goodIndex; i++) {
|
||||||
update = pendingPtsUpdates[i];
|
update = curState.pendingPtsUpdates[i];
|
||||||
saveUpdate(update);
|
saveUpdate(update);
|
||||||
}
|
}
|
||||||
pendingPtsUpdates.splice(goodIndex, length - goodIndex);
|
curState.pendingPtsUpdates.splice(0, goodIndex + 1);
|
||||||
|
|
||||||
if (!pendingPtsUpdates.length && syncPending) {
|
if (!curState.pendingPtsUpdates.length && curState.syncPending) {
|
||||||
if (!syncPending.seqAwaiting) {
|
if (!curState.syncPending.seqAwaiting) {
|
||||||
clearTimeout(syncPending.timeout);
|
clearTimeout(curState.syncPending.timeout);
|
||||||
syncPending = false;
|
curState.syncPending = false;
|
||||||
} else {
|
} else {
|
||||||
delete syncPending.ptsAwaiting;
|
delete curState.syncPending.ptsAwaiting;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2343,7 +2346,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
}
|
}
|
||||||
|
|
||||||
function forceGetDifference () {
|
function forceGetDifference () {
|
||||||
if (!syncLoading) {
|
if (!updatesState.syncLoading) {
|
||||||
getDifference();
|
getDifference();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2409,23 +2412,23 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getDifference () {
|
function getDifference () {
|
||||||
if (!syncLoading) {
|
if (!updatesState.syncLoading) {
|
||||||
syncLoading = true;
|
updatesState.syncLoading = true;
|
||||||
pendingSeqUpdates = {};
|
updatesState.pendingSeqUpdates = {};
|
||||||
pendingPtsUpdates = [];
|
updatesState.pendingPtsUpdates = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (syncPending) {
|
if (updatesState.syncPending) {
|
||||||
clearTimeout(syncPending.timeout);
|
clearTimeout(updatesState.syncPending.timeout);
|
||||||
syncPending = false;
|
updatesState.syncPending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MtpApiManager.invokeApi('updates.getDifference', {pts: curState.pts, date: curState.date, qts: -1}).then(function (differenceResult) {
|
MtpApiManager.invokeApi('updates.getDifference', {pts: updatesState.pts, date: updatesState.date, qts: -1}).then(function (differenceResult) {
|
||||||
if (differenceResult._ == 'updates.differenceEmpty') {
|
if (differenceResult._ == 'updates.differenceEmpty') {
|
||||||
console.log(dT(), 'apply empty diff', differenceResult.seq);
|
console.log(dT(), 'apply empty diff', differenceResult.seq);
|
||||||
curState.date = differenceResult.date;
|
updatesState.date = differenceResult.date;
|
||||||
curState.seq = differenceResult.seq;
|
updatesState.seq = differenceResult.seq;
|
||||||
syncLoading = false;
|
updatesState.syncLoading = false;
|
||||||
$rootScope.$broadcast('stateSynchronized');
|
$rootScope.$broadcast('stateSynchronized');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2435,7 +2438,15 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
|
|
||||||
// Should be first because of updateMessageID
|
// Should be first because of updateMessageID
|
||||||
// console.log(dT(), 'applying', differenceResult.other_updates.length, 'other updates');
|
// console.log(dT(), 'applying', differenceResult.other_updates.length, 'other updates');
|
||||||
angular.forEach(differenceResult.other_updates, function(update){
|
angular.forEach(differenceResult.other_updates, function(update) {
|
||||||
|
if (update._ == 'updateChannelTooLong') {
|
||||||
|
var channelID = update.channel_id;
|
||||||
|
var channelState = channelStates[channelID];
|
||||||
|
if (channelState !== undefined && !channelState.syncLoading) {
|
||||||
|
getChannelDifference(channelID);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
saveUpdate(update);
|
saveUpdate(update);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2444,32 +2455,129 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
saveUpdate({
|
saveUpdate({
|
||||||
_: 'updateNewMessage',
|
_: 'updateNewMessage',
|
||||||
message: apiMessage,
|
message: apiMessage,
|
||||||
pts: curState.pts,
|
pts: updatesState.pts,
|
||||||
pts_count: 0
|
pts_count: 0
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var nextState = differenceResult.intermediate_state || differenceResult.state;
|
var nextState = differenceResult.intermediate_state || differenceResult.state;
|
||||||
curState.seq = nextState.seq;
|
updatesState.seq = nextState.seq;
|
||||||
curState.pts = nextState.pts;
|
updatesState.pts = nextState.pts;
|
||||||
curState.date = nextState.date;
|
updatesState.date = nextState.date;
|
||||||
|
|
||||||
console.log(dT(), 'apply diff', curState.seq, curState.pts);
|
console.log(dT(), 'apply diff', updatesState.seq, updatesState.pts);
|
||||||
|
|
||||||
if (differenceResult._ == 'updates.differenceSlice') {
|
if (differenceResult._ == 'updates.differenceSlice') {
|
||||||
getDifference();
|
getDifference();
|
||||||
} else {
|
} else {
|
||||||
// console.log(dT(), 'finished get diff');
|
// console.log(dT(), 'finished get diff');
|
||||||
$rootScope.$broadcast('stateSynchronized');
|
$rootScope.$broadcast('stateSynchronized');
|
||||||
syncLoading = false;
|
updatesState.syncLoading = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getChannelDifference (channelID) {
|
||||||
|
var channelState = getChannelState(channelID);
|
||||||
|
if (!channelState.syncLoading) {
|
||||||
|
channelState.syncLoading = true;
|
||||||
|
channelState.pendingPtsUpdates = [];
|
||||||
|
}
|
||||||
|
MtpApiManager.invokeApi('updates.getChannelDifference', {
|
||||||
|
channel: AppChatsManager.getChannelInput(channelID),
|
||||||
|
filter: {_: 'channelMessagesFilterEmpty'},
|
||||||
|
pts: channelState.pts,
|
||||||
|
limit: 10
|
||||||
|
}).then(function (differenceResult) {
|
||||||
|
channelState.pts = differenceResult.pts;
|
||||||
|
|
||||||
|
if (differenceResult._ == 'updates.channelDifferenceEmpty') {
|
||||||
|
console.log(dT(), 'apply channel empty diff', differenceResult);
|
||||||
|
channelState.syncLoading = false;
|
||||||
|
$rootScope.$broadcast('stateSynchronized');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (differenceResult._ == 'updates.channelDifferenceTooLong') {
|
||||||
|
console.log(dT(), 'channel diff too long', differenceResult);
|
||||||
|
channelState.syncLoading = false;
|
||||||
|
delete channelStates[channelID];
|
||||||
|
saveUpdate({_: 'updateChannelReload', channel_id: channelID});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppUsersManager.saveApiUsers(differenceResult.users);
|
||||||
|
AppChatsManager.saveApiChats(differenceResult.chats);
|
||||||
|
|
||||||
|
// Should be first because of updateMessageID
|
||||||
|
console.log(dT(), 'applying', differenceResult.other_updates.length, 'channel other updates');
|
||||||
|
angular.forEach(differenceResult.other_updates, function(update){
|
||||||
|
saveUpdate(update);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(dT(), 'applying', differenceResult.new_messages.length, 'channel new messages');
|
||||||
|
angular.forEach(differenceResult.new_messages, function (apiMessage) {
|
||||||
|
saveUpdate({
|
||||||
|
_: 'updateNewChannelMessage',
|
||||||
|
message: apiMessage,
|
||||||
|
pts: channelState.pts,
|
||||||
|
pts_count: 0
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(dT(), 'apply channel diff', channelState.pts);
|
||||||
|
|
||||||
|
if (differenceResult._ == 'updates.channelDifference' && !(differenceResult.flags & 1)) {
|
||||||
|
getChannelDifference(channelID);
|
||||||
|
} else {
|
||||||
|
console.log(dT(), 'finished channel get diff');
|
||||||
|
$rootScope.$broadcast('stateSynchronized');
|
||||||
|
channelState.syncLoading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addChannelState (channelID, pts) {
|
||||||
|
if (channelStates[channelID] === undefined) {
|
||||||
|
channelStates[channelID] = {
|
||||||
|
pts: pts,
|
||||||
|
pendingPtsUpdates: [],
|
||||||
|
syncPending: false,
|
||||||
|
syncLoading: false
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getChannelState (channelID, pts) {
|
||||||
|
if (channelStates[channelID] === undefined) {
|
||||||
|
if (!pts) {
|
||||||
|
throw new Error('Get channel empty state without pts ' + channelID);
|
||||||
|
}
|
||||||
|
addChannelState(channelID, pts);
|
||||||
|
}
|
||||||
|
return channelStates[channelID];
|
||||||
|
}
|
||||||
|
|
||||||
function processUpdate (update, options) {
|
function processUpdate (update, options) {
|
||||||
if (syncLoading) {
|
var channelID = false;
|
||||||
|
switch (update._) {
|
||||||
|
case 'updateNewChannelMessage':
|
||||||
|
channelID = -AppPeersManager.getPeerID(update.message.to_id);
|
||||||
|
break;
|
||||||
|
case 'updateDeleteChannelMessages':
|
||||||
|
channelID = update.channel_id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var curState = channelID ? getChannelState(channelID, update.pts) : updatesState;
|
||||||
|
|
||||||
|
console.log('process', channelID, curState, update);
|
||||||
|
|
||||||
|
if (curState.syncLoading) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update._ == 'updateNewMessage') {
|
if (update._ == 'updateNewMessage') {
|
||||||
var message = update.message;
|
var message = update.message;
|
||||||
var fwdPeerID = message.fwd_from_id ? AppPeersManager.getPeerID(message.fwd_from_id) : 0;
|
var fwdPeerID = message.fwd_from_id ? AppPeersManager.getPeerID(message.fwd_from_id) : 0;
|
||||||
@ -2491,15 +2599,19 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
var newPts = curState.pts + (update.pts_count || 0);
|
var newPts = curState.pts + (update.pts_count || 0);
|
||||||
if (newPts < update.pts) {
|
if (newPts < update.pts) {
|
||||||
console.log(dT(), 'Pts hole', curState, update);
|
console.log(dT(), 'Pts hole', curState, update);
|
||||||
pendingPtsUpdates.push(update);
|
curState.pendingPtsUpdates.push(update);
|
||||||
if (!syncPending) {
|
if (!curState.syncPending) {
|
||||||
syncPending = {
|
curState.syncPending = {
|
||||||
timeout: setTimeout(function () {
|
timeout: setTimeout(function () {
|
||||||
getDifference();
|
if (channelID) {
|
||||||
|
getChannelDifference(channelID);
|
||||||
|
} else {
|
||||||
|
getDifference();
|
||||||
|
}
|
||||||
}, 5000)
|
}, 5000)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
syncPending.ptsAwaiting = true;
|
curState.syncPending.ptsAwaiting = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (update.pts > curState.pts) {
|
if (update.pts > curState.pts) {
|
||||||
@ -2507,29 +2619,29 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
popPts = true;
|
popPts = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (options.seq > 0) {
|
else if (!channelID && options.seq > 0) {
|
||||||
var seq = options.seq;
|
var seq = options.seq;
|
||||||
var seqStart = options.seqStart || seq;
|
var seqStart = options.seqStart || seq;
|
||||||
|
|
||||||
if (seqStart != curState.seq + 1) {
|
if (seqStart != curState.seq + 1) {
|
||||||
if (seqStart > curState.seq) {
|
if (seqStart > curState.seq) {
|
||||||
console.warn(dT(), 'Seq hole', curState, syncPending && syncPending.seqAwaiting);
|
console.warn(dT(), 'Seq hole', curState, curState.syncPending && curState.syncPending.seqAwaiting);
|
||||||
|
|
||||||
if (pendingSeqUpdates[seqStart] === undefined) {
|
if (curState.pendingSeqUpdates[seqStart] === undefined) {
|
||||||
pendingSeqUpdates[seqStart] = {seq: seq, date: options.date, updates: []};
|
curState.pendingSeqUpdates[seqStart] = {seq: seq, date: options.date, updates: []};
|
||||||
}
|
}
|
||||||
pendingSeqUpdates[seqStart].updates.push(update);
|
curState.pendingSeqUpdates[seqStart].updates.push(update);
|
||||||
|
|
||||||
if (!syncPending) {
|
if (!curState.syncPending) {
|
||||||
syncPending = {
|
curState.syncPending = {
|
||||||
timeout: setTimeout(function () {
|
timeout: setTimeout(function () {
|
||||||
getDifference();
|
getDifference();
|
||||||
}, 5000)
|
}, 5000)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (!syncPending.seqAwaiting ||
|
if (!curState.syncPending.seqAwaiting ||
|
||||||
syncPending.seqAwaiting < seqStart) {
|
curState.syncPending.seqAwaiting < seqStart) {
|
||||||
syncPending.seqAwaiting = seqStart;
|
curState.syncPending.seqAwaiting = seqStart;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2544,12 +2656,10 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveUpdate(update);
|
||||||
saveUpdate (update);
|
|
||||||
|
|
||||||
|
|
||||||
if (popPts) {
|
if (popPts) {
|
||||||
popPendingPtsUpdate();
|
popPendingPtsUpdate(channelID);
|
||||||
}
|
}
|
||||||
else if (popSeq) {
|
else if (popSeq) {
|
||||||
popPendingSeqUpdate();
|
popPendingSeqUpdate();
|
||||||
@ -2563,16 +2673,16 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
function attach () {
|
function attach () {
|
||||||
MtpNetworkerFactory.setUpdatesProcessor(processUpdateMessage);
|
MtpNetworkerFactory.setUpdatesProcessor(processUpdateMessage);
|
||||||
MtpApiManager.invokeApi('updates.getState', {}, {noErrorBox: true}).then(function (stateResult) {
|
MtpApiManager.invokeApi('updates.getState', {}, {noErrorBox: true}).then(function (stateResult) {
|
||||||
curState.seq = stateResult.seq;
|
updatesState.seq = stateResult.seq;
|
||||||
curState.pts = stateResult.pts;
|
updatesState.pts = stateResult.pts;
|
||||||
curState.date = stateResult.date;
|
updatesState.date = stateResult.date;
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
syncLoading = false;
|
updatesState.syncLoading = false;
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
// curState.seq = 1;
|
// updatesState.seq = 1;
|
||||||
// curState.pts = stateResult.pts - 5000;
|
// updatesState.pts = stateResult.pts - 5000;
|
||||||
// curState.date = 1;
|
// updatesState.date = 1;
|
||||||
// getDifference();
|
// getDifference();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -2580,6 +2690,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
processUpdateMessage: processUpdateMessage,
|
processUpdateMessage: processUpdateMessage,
|
||||||
|
addChannelState: addChannelState,
|
||||||
attach: attach
|
attach: attach
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user