diff --git a/app/js/controllers.js b/app/js/controllers.js index 1275388b..79c9080a 100644 --- a/app/js/controllers.js +++ b/app/js/controllers.js @@ -632,6 +632,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) $scope.phonebookAvailable = PhonebookContactsService.isAvailable(); var searchMessages = false; + var offsetIndex = 0; var maxID = 0; var hasMore = false; var jump = 0; @@ -791,52 +792,50 @@ angular.module('myApp.controllers', ['myApp.i18n']) var searchTimeoutPromise; function getDialogs(force) { - var curJump = ++jump, - promise; + var curJump = ++jump; $timeout.cancel(searchTimeoutPromise); + if (searchMessages) { searchTimeoutPromise = (force || maxID) ? $q.when() : $timeout(angular.noop, 500); - promise = searchTimeoutPromise.then(function () { - return AppMessagesManager.getSearch({_: 'inputPeerEmpty'}, $scope.search.query, {_: 'inputMessagesFilterEmpty'}, maxID); + return searchTimeoutPromise.then(function () { + return AppMessagesManager.getSearch({_: 'inputPeerEmpty'}, $scope.search.query, {_: 'inputMessagesFilterEmpty'}, maxID).then(function (result) { + if (curJump != jump) { + return $q.reject(); + } + var dialogs = []; + angular.forEach(result.history, function (messageID) { + var message = AppMessagesManager.getMessage(messageID), + peerID = AppMessagesManager.getMessagePeer(message); + + dialogs.push({ + peerID: peerID, + top_message: messageID, + unread_count: -1 + }); + }); + + return { + dialogs: dialogs + }; + }) }); - } else { - var query = $scope.search.query; - if ($scope.noUsers) { - query = '%pg ' + (query || ''); - } - promise = AppMessagesManager.getDialogs(query, maxID); } - return promise.then(function (result) { + var query = $scope.search.query || ''; + if ($scope.noUsers) { + query = '%pg ' + query; + } + return AppMessagesManager.getConversations(query, offsetIndex).then(function (result) { if (curJump != jump) { return $q.reject(); } - if (searchMessages) { - var dialogs = []; - angular.forEach(result.history, function (messageID) { - var message = AppMessagesManager.getMessage(messageID), - peerID = AppMessagesManager.getMessagePeer(message); - - dialogs.push({ - peerID: peerID, - top_message: messageID, - unread_count: -1 - }); - }); - - result = { - count: result.count, - dialogs: dialogs - }; - } - return result; }); }; function loadDialogs (force) { - maxID = 0; + offsetIndex = 0; hasMore = false; if (!searchMessages) { peersInDialogs = {}; @@ -862,18 +861,21 @@ angular.module('myApp.controllers', ['myApp.i18n']) dialogsList.push(wrappedDialog); }); - maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message; - hasMore = dialogsResult.count === null || dialogsList.length < dialogsResult.count; - - if (!searchMessages) { + if (searchMessages) { + maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message; + } else { + offsetIndex = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].index; delete $scope.isEmpty.dialogs; } + hasMore = true; + } else { + hasMore = false; } $scope.$broadcast('ui_dialogs_change'); if (!$scope.search.query) { - AppMessagesManager.getDialogs('', maxID, 100); + AppMessagesManager.getConversations('', offsetIndex, 100); if (!dialogsResult.dialogs.length) { $scope.isEmpty.dialogs = true; showMoreDialogs(); @@ -886,7 +888,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) } function showMoreDialogs () { - if (contactsShown && (!hasMore || !maxID)) { + if (contactsShown && (!hasMore || !offsetIndex && !maxID)) { return; } @@ -910,10 +912,18 @@ angular.module('myApp.controllers', ['myApp.i18n']) dialogsList.push(wrappedDialog); }); - maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message; - hasMore = dialogsResult.count === null || dialogsList.length < dialogsResult.count; + if (searchMessages) { + maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message; + } else { + offsetIndex = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].index; + } $scope.$broadcast('ui_dialogs_append'); + + hasMore = true; + } + else { + hasMore = false; } }); }; diff --git a/app/js/services.js b/app/js/services.js index cea79c37..ff169d2e 100755 --- a/app/js/services.js +++ b/app/js/services.js @@ -1068,10 +1068,18 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) NotificationsManager.start(); - function getDialogs (query, maxID, limit) { + var allChannelsLoaded = false; + var channelsLoadPromise = false; + var allDialogsLoaded = false + var loadedDialogsCount = 0; + var dialogsNum = 0; + var minDialogsIndex = Math.pow(2, 50); + + function getConversations (query, offsetIndex, limit) { var curDialogStorage = dialogsStorage; + var isSearch = angular.isString(query) && query.length; - if (angular.isString(query) && query.length) { + if (isSearch) { if (!limit || cachedResults.query !== query) { cachedResults.query = query; @@ -1091,73 +1099,136 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) } var offset = 0; - if (maxID > 0) { + if (offsetIndex > 0) { for (offset = 0; offset < curDialogStorage.dialogs.length; offset++) { - if (maxID > curDialogStorage.dialogs[offset].top_message) { + if (offsetIndex > curDialogStorage.dialogs[offset].index) { break; } } } - if (curDialogStorage.count !== null && curDialogStorage.dialogs.length == curDialogStorage.count || - curDialogStorage.dialogs.length >= offset + (limit || 1) + limit = limit || 20; + + if ( + isSearch || + (allChannelsLoaded && allDialogsLoaded) || + ( + curDialogStorage.dialogs.length >= offset + limit && + curDialogStorage.dialogs[offset + limit - 1].index >= minDialogsIndex + ) ) { return $q.when({ - count: curDialogStorage.count, - dialogs: curDialogStorage.dialogs.slice(offset, offset + (limit || 20)) + dialogs: curDialogStorage.dialogs.slice(offset, offset + limit) }); } - limit = limit || 20; + return $q.all([getAllChannels(), getTopMessages(loadedDialogsCount, limit)]).then(function () { + console.log(curDialogStorage); + offset = 0; + if (offsetIndex > 0) { + for (offset = 0; offset < curDialogStorage.dialogs.length; offset++) { + if (offsetIndex > curDialogStorage.dialogs[offset].index) { + break; + } + } + } + console.log(curDialogStorage.dialogs.slice(offset, offset + limit)); + return { + // count: curDialogStorage.count, + dialogs: curDialogStorage.dialogs.slice(offset, offset + limit) + } + }); + } + + function getDialogByPeerID (peerID) { + for (var i = 0; i < dialogsStorage.dialogs.length; i++) { + if (dialogsStorage.dialogs[i].peerID == peerID) { + return [dialogsStorage.dialogs[i], i]; + } + } + + return []; + } + + function getAllChannels () { + if (channelsLoadPromise) { + return channelsLoadPromise; + } + return channelsLoadPromise = MtpApiManager.invokeApi('channels.getDialogs', { + offset: 0, + limit: 100 + }).then(function (dialogsResult) { + AppUsersManager.saveApiUsers(dialogsResult.users); + AppChatsManager.saveApiChats(dialogsResult.chats); + saveMessages(dialogsResult.messages); + + angular.forEach(dialogsResult.dialogs, function (dialog) { + var peerID = AppPeersManager.getPeerID(dialog.peer); + var peerText = AppPeersManager.getPeerSearchText(peerID); + SearchIndexManager.indexObject(peerID, peerText, dialogsIndex); + + dialog.top_message = dialog.top_important_message; + + var message = getMessage(peerID + '_' + dialog.top_message); + var topDate = message.date; + var channel = AppChatsManager.getChat(-peerID); + if (channel.date > topDate) { + topDate = channel.date; + } + + dialog.index = generateDialogIndex(topDate); + dialog.peerID = peerID; + + pushDialogToStorage(dialog); + + if (historiesStorage[peerID] === undefined) { + var historyStorage = {count: null, history: [dialog.top_message], pending: []}; + historiesStorage[peerID] = historyStorage; + } + + NotificationsManager.savePeerSettings(peerID, dialog.notify_settings); + }); + allChannelsLoaded = true; + }); + } + + function getTopMessages (offset, limit) { return MtpApiManager.invokeApi('messages.getDialogs', { offset: offset, - limit: limit, - max_id: maxID || 0 + limit: limit }).then(function (dialogsResult) { TelegramMeWebService.setAuthorized(true); AppUsersManager.saveApiUsers(dialogsResult.users); AppChatsManager.saveApiChats(dialogsResult.chats); - - // return { - // count: 0, - // dialogs: [] - // }; - saveMessages(dialogsResult.messages); - if (maxID > 0) { - for (offset = 0; offset < curDialogStorage.dialogs.length; offset++) { - if (maxID > curDialogStorage.dialogs[offset].top_message) { - break; - } - } + if (!dialogsResult.dialogs.length) { + allDialogsLoaded = true; } - - curDialogStorage.count = dialogsResult.count || dialogsResult.dialogs.length; - - if (!maxID && curDialogStorage.dialogs.length) { - incrementMaxSeenID(curDialogStorage.dialogs[0].top_message); + else if (!offset) { + incrementMaxSeenID(dialogsResult.dialogs[0].top_message); } - curDialogStorage.dialogs.splice(offset, curDialogStorage.dialogs.length - offset); angular.forEach(dialogsResult.dialogs, function (dialog) { - var peerID = AppPeersManager.getPeerID(dialog.peer), - peerText = AppPeersManager.getPeerSearchText(peerID); - + var peerID = AppPeersManager.getPeerID(dialog.peer); + var peerText = AppPeersManager.getPeerSearchText(peerID); SearchIndexManager.indexObject(peerID, peerText, dialogsIndex); - curDialogStorage.dialogs.push({ - peerID: peerID, - top_message: dialog.top_message, - unread_count: dialog.unread_count - }); + var message = getMessage(dialog.top_message); + + dialog.index = generateDialogIndex(message.date); + if (dialog.index < 0) { + console.log('ind', dialog.index, message.date); + } + dialog.peerID = peerID; + + pushDialogToStorage(dialog); if (historiesStorage[peerID] === undefined) { var historyStorage = {count: null, history: [dialog.top_message], pending: []}; historiesStorage[peerID] = historyStorage; - var message = getMessage(dialog.top_message); if (mergeReplyKeyboard(historyStorage, message)) { $rootScope.$broadcast('history_reply_markup', {peerID: peerID}); } @@ -1170,7 +1241,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) maxSeenID && dialog.top_message > maxSeenID ) { - var message = getMessage(dialog.top_message); var notifyPeer = message.flags & 16 ? message.from_id : peerID; if (message.unread && !message.out) { NotificationsManager.getPeerMuted(notifyPeer).then(function (muted) { @@ -1181,14 +1251,52 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) } } }); - - return { - count: curDialogStorage.count, - dialogs: curDialogStorage.dialogs.slice(offset, offset + limit) - }; }); } + function generateDialogIndex (date) { + if (date === undefined) { + date = tsNow(true) + serverTimeOffset; + } + return (date * 65536) + ((++dialogsNum) & 0xFFFF); + } + + function pushDialogToStorage (dialog) { + var dialogs = dialogsStorage.dialogs; + + var pos = getDialogByPeerID(dialog.peerID)[1]; + var index = dialog.index; + var isDialog = dialog._ == 'dialog'; + if (pos !== undefined) { + dialogs.splice(pos, 1); + } + else if (isDialog) { + loadedDialogsCount++; + if (index < minDialogsIndex) { + minDialogsIndex = index; + } + } + + var i, len = dialogs.length; + if (!len) { + dialogs.push(dialog); + } + else if (index >= dialogs[0].index) { + dialogs.unshift(dialog); + } + else if (index < dialogs[len - 1].index) { + dialogs.push(dialog); + } + else { + for (i = 0; i < len; i++) { + if (index > dialogs[i].index) { + dialogs.splice(i, 0, dialog); + break; + } + } + } + } + function requestHistory (inputPeer, maxID, limit, offset) { return MtpApiManager.invokeApi('messages.getHistory', { peer: inputPeer, @@ -1741,7 +1849,11 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) apiMessage.unread = apiMessage.flags & 1 ? true : false; apiMessage.out = apiMessage.flags & 2 ? true : false; apiMessage.media_unread = apiMessage.flags & 32 ? true : false; - messagesStorage[apiMessage.id] = apiMessage; + + var mid = isChannel ? toPeerID + '_' + apiMessage.id : apiMessage.id; + apiMessage.mid = mid; + + messagesStorage[mid] = apiMessage; apiMessage.date -= serverTimeOffset; @@ -1753,6 +1865,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) apiMessage.fwdFromID = AppPeersManager.getPeerID(apiMessage.fwd_from_id); } + var mediaContext = { user_id: apiMessage.from_id, date: apiMessage.date @@ -2402,13 +2515,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) return message; } - if (message.chatID = message.to_id.chat_id) { - message.peerID = -message.chatID; - message.peerData = AppChatsManager.getChat(message.chatID); - } else { - message.peerID = message.out ? message.to_id.user_id : message.from_id; - message.peerData = AppUsersManager.getUser(message.peerID); - } + message.peerID = getMessagePeer(message); + message.peerData = AppPeersManager.getPeer(message.peerID); message.peerString = AppPeersManager.getPeerString(message.peerID); message.peerPhoto = AppPeersManager.getPeerPhoto(message.peerID, 'User', 'Group'); message.unreadCount = unreadCount; @@ -2683,16 +2791,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) return wasUpdated; } - function getDialogByPeerID (peerID) { - for (var i = 0; i < dialogsStorage.dialogs.length; i++) { - if (dialogsStorage.dialogs[i].peerID == peerID) { - return [dialogsStorage.dialogs[i], i]; - } - } - - return []; - } - function incrementMaxSeenID (maxID) { if (maxSeenID !== false && maxID && maxID > maxSeenID) { Storage.set({ @@ -3173,7 +3271,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) }) return { - getDialogs: getDialogs, + getConversations: getConversations, getHistory: getHistory, getSearch: getSearch, getMessage: getMessage, @@ -3197,22 +3295,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) } }) -.service('AppChannelsManager', function () { - var AppMessagesManager = {}; - - function getDialogs () { - - } - - function setMessagesManager (messagesManager) { - AppMessagesManager = messagesManager; - } - - return { - setMessagesManager: setMessagesManager - } -}) - .service('AppPhotosManager', function ($modal, $window, $rootScope, MtpApiManager, MtpApiFileManager, AppUsersManager, FileManager) { var photos = {}, windowW = $(window).width(), diff --git a/app/partials/desktop/dialog.html b/app/partials/desktop/dialog.html index 4d19b2c4..bb1a477c 100644 --- a/app/partials/desktop/dialog.html +++ b/app/partials/desktop/dialog.html @@ -32,7 +32,7 @@
- + - +