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;
|
||||
}
|
||||
|
||||
var topMessages = [];
|
||||
var topToDialogs = {};
|
||||
var indexes = [];
|
||||
var indexesToDialogs = {};
|
||||
angular.forEach(dialogsUpdated, function (dialog, peerID) {
|
||||
if ($scope.noUsers && peerID > 0) {
|
||||
return;
|
||||
}
|
||||
topToDialogs[dialog.top_message] = dialog;
|
||||
topMessages.push(dialog.top_message);
|
||||
indexesToDialogs[dialog.index] = dialog;
|
||||
indexes.push(dialog.index);
|
||||
});
|
||||
topMessages.sort();
|
||||
indexes.sort();
|
||||
|
||||
var i, dialog;
|
||||
var len = $scope.dialogs.length;
|
||||
@ -675,9 +675,9 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
||||
len--;
|
||||
}
|
||||
}
|
||||
len = topMessages.length;
|
||||
len = indexes.length;
|
||||
for (i = 0; i < len; i++) {
|
||||
dialog = topToDialogs[topMessages[i]];
|
||||
dialog = indexesToDialogs[indexes[i]];
|
||||
$scope.dialogs.unshift(
|
||||
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 = {};
|
||||
$scope.$on('history_append', function (e, addedMessage) {
|
||||
|
@ -140,6 +140,42 @@ angular.module('myApp.services')
|
||||
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 () {
|
||||
if (channelsLoadPromise) {
|
||||
return channelsLoadPromise;
|
||||
@ -154,30 +190,10 @@ angular.module('myApp.services')
|
||||
|
||||
angular.forEach(dialogsResult.dialogs, function (dialog) {
|
||||
var peerID = AppPeersManager.getPeerID(dialog.peer);
|
||||
var peerText = AppPeersManager.getPeerSearchText(peerID);
|
||||
SearchIndexManager.indexObject(peerID, peerText, dialogsIndex);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
var channelID = -peerID;
|
||||
saveChannelDialog(channelID, dialog);
|
||||
NotificationsManager.savePeerSettings(peerID, dialog.notify_settings);
|
||||
ApiUpdatesManager.addChannelState(channelID, dialog.pts);
|
||||
});
|
||||
allChannelsLoaded = true;
|
||||
});
|
||||
@ -188,7 +204,9 @@ angular.module('myApp.services')
|
||||
offset: offset,
|
||||
limit: limit
|
||||
}).then(function (dialogsResult) {
|
||||
TelegramMeWebService.setAuthorized(true);
|
||||
if (!offset) {
|
||||
TelegramMeWebService.setAuthorized(true);
|
||||
}
|
||||
|
||||
// Server-side bug
|
||||
if (dialogsResult.count && offset >= dialogsResult.count) {
|
||||
@ -288,8 +306,9 @@ angular.module('myApp.services')
|
||||
|
||||
function requestHistory (inputPeer, maxID, limit, offset) {
|
||||
var peerID = AppPeersManager.getPeerID(inputPeer);
|
||||
var isChannel = AppPeersManager.isChannel(peerID);
|
||||
var promise;
|
||||
if (AppPeersManager.isChannel(peerID)) {
|
||||
if (isChannel) {
|
||||
promise = MtpApiManager.invokeApi('channels.getImportantHistory', {
|
||||
channel: AppChatsManager.getChannelInput(-peerID),
|
||||
offset_id: maxID ? getMessageLocalID(maxID) : 0,
|
||||
@ -310,6 +329,10 @@ angular.module('myApp.services')
|
||||
AppChatsManager.saveApiChats(historyResult.chats);
|
||||
saveMessages(historyResult.messages);
|
||||
|
||||
if (isChannel) {
|
||||
ApiUpdatesManager.addChannelState(-peerID, historyResult.pts);
|
||||
}
|
||||
|
||||
if (
|
||||
peerID < 0 ||
|
||||
!AppUsersManager.isBot(peerID) ||
|
||||
@ -789,7 +812,6 @@ angular.module('myApp.services')
|
||||
for (i = historyStorage.history.length; i >= 0; i--) {
|
||||
messageID = historyStorage.history[i];
|
||||
message = messagesStorage[messageID];
|
||||
// console.log('ms', message);
|
||||
if (message && !message.out && message.unread) {
|
||||
foundUnread = true;
|
||||
break;
|
||||
@ -826,6 +848,9 @@ angular.module('myApp.services')
|
||||
foundDialog[0].unread_count = 0;
|
||||
$rootScope.$broadcast('dialog_unread', {peerID: peerID, count: 0});
|
||||
$rootScope.$broadcast('messages_read');
|
||||
if (historyStorage && historyStorage.history.length) {
|
||||
foundDialog[0].read_inbox_max_id = historyStorage.history[0];
|
||||
}
|
||||
}
|
||||
})['finally'](function () {
|
||||
delete historyStorage.readPromise;
|
||||
@ -895,7 +920,6 @@ angular.module('myApp.services')
|
||||
if (apiMessage._ == 'messageEmpty') {
|
||||
return;
|
||||
}
|
||||
apiMessage.unread = apiMessage.flags & 1 ? true : false;
|
||||
apiMessage.out = apiMessage.flags & 2 ? true : false;
|
||||
apiMessage.media_unread = apiMessage.flags & 32 ? true : false;
|
||||
|
||||
@ -907,6 +931,13 @@ angular.module('myApp.services')
|
||||
apiMessage.mid = mid;
|
||||
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) {
|
||||
apiMessage.reply_to_mid = getFullMessageID(apiMessage.reply_to_msg_id, channelID);
|
||||
}
|
||||
@ -2059,6 +2090,9 @@ angular.module('myApp.services')
|
||||
function handleNewDialogs () {
|
||||
$timeout.cancel(newDialogsHandlePromise);
|
||||
newDialogsHandlePromise = false;
|
||||
angular.forEach(newDialogsToHandle, function (dialog) {
|
||||
pushDialogToStorage(dialog);
|
||||
});
|
||||
$rootScope.$broadcast('dialogs_multiupdate', newDialogsToHandle);
|
||||
newDialogsToHandle = {};
|
||||
}
|
||||
@ -2089,19 +2123,26 @@ angular.module('myApp.services')
|
||||
}
|
||||
|
||||
$rootScope.$on('apiUpdate', function (e, update) {
|
||||
// if (update._ != 'updateUserStatus') {
|
||||
// console.log('on apiUpdate', update);
|
||||
// }
|
||||
if (update._ != 'updateUserStatus') {
|
||||
console.log('on apiUpdate', update);
|
||||
}
|
||||
switch (update._) {
|
||||
case 'updateMessageID':
|
||||
pendingByMessageID[update.id] = update.random_id;
|
||||
break;
|
||||
|
||||
case 'updateNewMessage':
|
||||
case 'updateNewChannelMessage':
|
||||
var message = update.message,
|
||||
peerID = getMessagePeer(message),
|
||||
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]);
|
||||
|
||||
if (historyStorage !== undefined) {
|
||||
@ -2127,12 +2168,11 @@ angular.module('myApp.services')
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
if (mergeReplyKeyboard(historyStorage, message)) {
|
||||
$rootScope.$broadcast('history_reply_markup', {peerID: peerID})
|
||||
}
|
||||
|
||||
if (!message.out) {
|
||||
if (!message.out && message.from_id) {
|
||||
AppUsersManager.forceUserOnline(message.from_id);
|
||||
}
|
||||
|
||||
@ -2162,24 +2202,20 @@ angular.module('myApp.services')
|
||||
|
||||
if (foundDialog.length) {
|
||||
dialog = foundDialog[0];
|
||||
if (foundDialog[1] > 0) {
|
||||
dialogsStorage.dialogs.splice(foundDialog[1], 1);
|
||||
dialogsStorage.dialogs.unshift(dialog);
|
||||
}
|
||||
dialog.top_message = message.mid;
|
||||
if (inboxUnread) {
|
||||
dialog.unread_count++;
|
||||
}
|
||||
} else {
|
||||
SearchIndexManager.indexObject(peerID, AppPeersManager.getPeerSearchText(peerID), dialogsIndex);
|
||||
|
||||
dialog = {
|
||||
peerID: peerID,
|
||||
unread_count: inboxUnread ? 1 : 0,
|
||||
top_message: message.mid
|
||||
};
|
||||
dialogsStorage.dialogs.unshift(dialog);
|
||||
}
|
||||
dialog.index = generateDialogIndex(message.date);
|
||||
|
||||
newDialogsToHandle[peerID] = dialog;
|
||||
if (!newDialogsHandlePromise) {
|
||||
newDialogsHandlePromise = $timeout(handleNewDialogs, 0);
|
||||
@ -2217,9 +2253,11 @@ angular.module('myApp.services')
|
||||
|
||||
case 'updateReadHistoryInbox':
|
||||
case 'updateReadHistoryOutbox':
|
||||
var maxID = update.max_id;
|
||||
case 'updateReadChannelInbox':
|
||||
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 history = (historiesStorage[peerID] || {}).history || [];
|
||||
var newUnreadCount = false;
|
||||
@ -2289,12 +2327,14 @@ angular.module('myApp.services')
|
||||
break;
|
||||
|
||||
case 'updateDeleteMessages':
|
||||
var dialogsUpdated = {},
|
||||
historiesUpdated = {},
|
||||
messageID, message, i, peerID, foundDialog, history;
|
||||
case 'updateDeleteChannelMessages':
|
||||
var dialogsUpdated = {};
|
||||
var historiesUpdated = {};
|
||||
var channelID = update.channel_id;
|
||||
var messageID, message, i, peerID, foundDialog, history;
|
||||
|
||||
for (i = 0; i < update.messages.length; i++) {
|
||||
messageID = update.messages[i];
|
||||
messageID = getFullMessageID(update.messages[i], channelID);
|
||||
message = messagesStorage[messageID];
|
||||
if (message) {
|
||||
peerID = getMessagePeer(message);
|
||||
@ -2369,6 +2409,40 @@ angular.module('myApp.services')
|
||||
}
|
||||
});
|
||||
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) {
|
||||
|
||||
var curState = {};
|
||||
var updatesState = {
|
||||
pendingPtsUpdates: [],
|
||||
pendingSeqUpdates: {},
|
||||
syncPending: false,
|
||||
syncLoading: true
|
||||
};
|
||||
var channelStates = {};
|
||||
|
||||
var myID = 0;
|
||||
MtpApiManager.getUserID().then(function (id) {
|
||||
myID = id;
|
||||
});
|
||||
|
||||
var syncPending = false;
|
||||
var syncLoading = true;
|
||||
var pendingSeqUpdates = {};
|
||||
var pendingPtsUpdates = [];
|
||||
|
||||
function popPendingSeqUpdate () {
|
||||
var nextSeq = curState.seq + 1,
|
||||
pendingUpdatesData = pendingSeqUpdates[nextSeq];
|
||||
var nextSeq = updatesState.seq + 1,
|
||||
pendingUpdatesData = updatesState.pendingSeqUpdates[nextSeq];
|
||||
if (!pendingUpdatesData) {
|
||||
return false;
|
||||
}
|
||||
@ -2277,32 +2279,33 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
||||
for (var i = 0, length = updates.length; i < length; i++) {
|
||||
saveUpdate(updates[i]);
|
||||
}
|
||||
curState.seq = pendingUpdatesData.seq;
|
||||
if (pendingUpdatesData.date && curState.date < pendingUpdatesData.date) {
|
||||
curState.date = pendingUpdatesData.date;
|
||||
updatesState.seq = pendingUpdatesData.seq;
|
||||
if (pendingUpdatesData.date && updatesState.date < pendingUpdatesData.date) {
|
||||
updatesState.date = pendingUpdatesData.date;
|
||||
}
|
||||
delete pendingSeqUpdates[nextSeq];
|
||||
delete updatesState.pendingSeqUpdates[nextSeq];
|
||||
|
||||
if (!popPendingSeqUpdate() &&
|
||||
syncPending &&
|
||||
syncPending.seqAwaiting &&
|
||||
curState.seq >= syncPending.seqAwaiting) {
|
||||
if (!syncPending.ptsAwaiting) {
|
||||
clearTimeout(syncPending.timeout);
|
||||
syncPending = false;
|
||||
updatesState.syncPending &&
|
||||
updatesState.syncPending.seqAwaiting &&
|
||||
updatesState.seq >= updatesState.syncPending.seqAwaiting) {
|
||||
if (!updatesState.syncPending.ptsAwaiting) {
|
||||
clearTimeout(updatesState.syncPending.timeout);
|
||||
updatesState.syncPending = false;
|
||||
} else {
|
||||
delete syncPending.seqAwaiting;
|
||||
delete updatesState.syncPending.seqAwaiting;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function popPendingPtsUpdate () {
|
||||
if (!pendingPtsUpdates.length) {
|
||||
function popPendingPtsUpdate (channelID) {
|
||||
var curState = channelID ? getChannelState(channelID) : updatesState;
|
||||
if (!curState.pendingPtsUpdates.length) {
|
||||
return false;
|
||||
}
|
||||
pendingPtsUpdates.sort(function (a, b) {
|
||||
curState.pendingPtsUpdates.sort(function (a, b) {
|
||||
return a.pts - b.pts;
|
||||
});
|
||||
|
||||
@ -2310,8 +2313,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
||||
var goodPts = false;
|
||||
var goodIndex = false;
|
||||
var update;
|
||||
for (var i = 0, length = pendingPtsUpdates.length; i < length; i++) {
|
||||
update = pendingPtsUpdates[i];
|
||||
for (var i = 0, length = curState.pendingPtsUpdates.length; i < length; i++) {
|
||||
update = curState.pendingPtsUpdates[i];
|
||||
curPts += update.pts_count;
|
||||
if (curPts >= update.pts) {
|
||||
goodPts = update.pts;
|
||||
@ -2325,17 +2328,17 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
||||
|
||||
curState.pts = goodPts;
|
||||
for (i = 0; i <= goodIndex; i++) {
|
||||
update = pendingPtsUpdates[i];
|
||||
update = curState.pendingPtsUpdates[i];
|
||||
saveUpdate(update);
|
||||
}
|
||||
pendingPtsUpdates.splice(goodIndex, length - goodIndex);
|
||||
curState.pendingPtsUpdates.splice(0, goodIndex + 1);
|
||||
|
||||
if (!pendingPtsUpdates.length && syncPending) {
|
||||
if (!syncPending.seqAwaiting) {
|
||||
clearTimeout(syncPending.timeout);
|
||||
syncPending = false;
|
||||
if (!curState.pendingPtsUpdates.length && curState.syncPending) {
|
||||
if (!curState.syncPending.seqAwaiting) {
|
||||
clearTimeout(curState.syncPending.timeout);
|
||||
curState.syncPending = false;
|
||||
} else {
|
||||
delete syncPending.ptsAwaiting;
|
||||
delete curState.syncPending.ptsAwaiting;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2343,7 +2346,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
||||
}
|
||||
|
||||
function forceGetDifference () {
|
||||
if (!syncLoading) {
|
||||
if (!updatesState.syncLoading) {
|
||||
getDifference();
|
||||
}
|
||||
}
|
||||
@ -2409,23 +2412,23 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
||||
}
|
||||
|
||||
function getDifference () {
|
||||
if (!syncLoading) {
|
||||
syncLoading = true;
|
||||
pendingSeqUpdates = {};
|
||||
pendingPtsUpdates = [];
|
||||
if (!updatesState.syncLoading) {
|
||||
updatesState.syncLoading = true;
|
||||
updatesState.pendingSeqUpdates = {};
|
||||
updatesState.pendingPtsUpdates = [];
|
||||
}
|
||||
|
||||
if (syncPending) {
|
||||
clearTimeout(syncPending.timeout);
|
||||
syncPending = false;
|
||||
if (updatesState.syncPending) {
|
||||
clearTimeout(updatesState.syncPending.timeout);
|
||||
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') {
|
||||
console.log(dT(), 'apply empty diff', differenceResult.seq);
|
||||
curState.date = differenceResult.date;
|
||||
curState.seq = differenceResult.seq;
|
||||
syncLoading = false;
|
||||
updatesState.date = differenceResult.date;
|
||||
updatesState.seq = differenceResult.seq;
|
||||
updatesState.syncLoading = false;
|
||||
$rootScope.$broadcast('stateSynchronized');
|
||||
return false;
|
||||
}
|
||||
@ -2435,7 +2438,15 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
||||
|
||||
// Should be first because of updateMessageID
|
||||
// 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);
|
||||
});
|
||||
|
||||
@ -2444,32 +2455,129 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
||||
saveUpdate({
|
||||
_: 'updateNewMessage',
|
||||
message: apiMessage,
|
||||
pts: curState.pts,
|
||||
pts: updatesState.pts,
|
||||
pts_count: 0
|
||||
});
|
||||
});
|
||||
|
||||
var nextState = differenceResult.intermediate_state || differenceResult.state;
|
||||
curState.seq = nextState.seq;
|
||||
curState.pts = nextState.pts;
|
||||
curState.date = nextState.date;
|
||||
updatesState.seq = nextState.seq;
|
||||
updatesState.pts = nextState.pts;
|
||||
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') {
|
||||
getDifference();
|
||||
} else {
|
||||
// console.log(dT(), 'finished get diff');
|
||||
$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) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (update._ == 'updateNewMessage') {
|
||||
var message = update.message;
|
||||
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);
|
||||
if (newPts < update.pts) {
|
||||
console.log(dT(), 'Pts hole', curState, update);
|
||||
pendingPtsUpdates.push(update);
|
||||
if (!syncPending) {
|
||||
syncPending = {
|
||||
curState.pendingPtsUpdates.push(update);
|
||||
if (!curState.syncPending) {
|
||||
curState.syncPending = {
|
||||
timeout: setTimeout(function () {
|
||||
getDifference();
|
||||
if (channelID) {
|
||||
getChannelDifference(channelID);
|
||||
} else {
|
||||
getDifference();
|
||||
}
|
||||
}, 5000)
|
||||
};
|
||||
}
|
||||
syncPending.ptsAwaiting = true;
|
||||
curState.syncPending.ptsAwaiting = true;
|
||||
return false;
|
||||
}
|
||||
if (update.pts > curState.pts) {
|
||||
@ -2507,29 +2619,29 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
||||
popPts = true;
|
||||
}
|
||||
}
|
||||
else if (options.seq > 0) {
|
||||
else if (!channelID && options.seq > 0) {
|
||||
var seq = options.seq;
|
||||
var seqStart = options.seqStart || seq;
|
||||
|
||||
if (seqStart != curState.seq + 1) {
|
||||
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) {
|
||||
pendingSeqUpdates[seqStart] = {seq: seq, date: options.date, updates: []};
|
||||
if (curState.pendingSeqUpdates[seqStart] === undefined) {
|
||||
curState.pendingSeqUpdates[seqStart] = {seq: seq, date: options.date, updates: []};
|
||||
}
|
||||
pendingSeqUpdates[seqStart].updates.push(update);
|
||||
curState.pendingSeqUpdates[seqStart].updates.push(update);
|
||||
|
||||
if (!syncPending) {
|
||||
syncPending = {
|
||||
if (!curState.syncPending) {
|
||||
curState.syncPending = {
|
||||
timeout: setTimeout(function () {
|
||||
getDifference();
|
||||
}, 5000)
|
||||
};
|
||||
}
|
||||
if (!syncPending.seqAwaiting ||
|
||||
syncPending.seqAwaiting < seqStart) {
|
||||
syncPending.seqAwaiting = seqStart;
|
||||
if (!curState.syncPending.seqAwaiting ||
|
||||
curState.syncPending.seqAwaiting < seqStart) {
|
||||
curState.syncPending.seqAwaiting = seqStart;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -2544,12 +2656,10 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
saveUpdate (update);
|
||||
|
||||
saveUpdate(update);
|
||||
|
||||
if (popPts) {
|
||||
popPendingPtsUpdate();
|
||||
popPendingPtsUpdate(channelID);
|
||||
}
|
||||
else if (popSeq) {
|
||||
popPendingSeqUpdate();
|
||||
@ -2563,16 +2673,16 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
||||
function attach () {
|
||||
MtpNetworkerFactory.setUpdatesProcessor(processUpdateMessage);
|
||||
MtpApiManager.invokeApi('updates.getState', {}, {noErrorBox: true}).then(function (stateResult) {
|
||||
curState.seq = stateResult.seq;
|
||||
curState.pts = stateResult.pts;
|
||||
curState.date = stateResult.date;
|
||||
updatesState.seq = stateResult.seq;
|
||||
updatesState.pts = stateResult.pts;
|
||||
updatesState.date = stateResult.date;
|
||||
setTimeout(function () {
|
||||
syncLoading = false;
|
||||
updatesState.syncLoading = false;
|
||||
}, 1000);
|
||||
|
||||
// curState.seq = 1;
|
||||
// curState.pts = stateResult.pts - 5000;
|
||||
// curState.date = 1;
|
||||
// updatesState.seq = 1;
|
||||
// updatesState.pts = stateResult.pts - 5000;
|
||||
// updatesState.date = 1;
|
||||
// getDifference();
|
||||
})
|
||||
}
|
||||
@ -2580,6 +2690,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
||||
|
||||
return {
|
||||
processUpdateMessage: processUpdateMessage,
|
||||
addChannelState: addChannelState,
|
||||
attach: attach
|
||||
}
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user