Browse Source

channel conversations in list

master
Igor Zhukov 9 years ago
parent
commit
e1def614cb
  1. 58
      app/js/controllers.js
  2. 238
      app/js/services.js
  3. 4
      app/partials/desktop/dialog.html

58
app/js/controllers.js

@ -632,6 +632,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.phonebookAvailable = PhonebookContactsService.isAvailable(); $scope.phonebookAvailable = PhonebookContactsService.isAvailable();
var searchMessages = false; var searchMessages = false;
var offsetIndex = 0;
var maxID = 0; var maxID = 0;
var hasMore = false; var hasMore = false;
var jump = 0; var jump = 0;
@ -791,28 +792,17 @@ angular.module('myApp.controllers', ['myApp.i18n'])
var searchTimeoutPromise; var searchTimeoutPromise;
function getDialogs(force) { function getDialogs(force) {
var curJump = ++jump, var curJump = ++jump;
promise;
$timeout.cancel(searchTimeoutPromise); $timeout.cancel(searchTimeoutPromise);
if (searchMessages) { if (searchMessages) {
searchTimeoutPromise = (force || maxID) ? $q.when() : $timeout(angular.noop, 500); searchTimeoutPromise = (force || maxID) ? $q.when() : $timeout(angular.noop, 500);
promise = searchTimeoutPromise.then(function () { return searchTimeoutPromise.then(function () {
return AppMessagesManager.getSearch({_: 'inputPeerEmpty'}, $scope.search.query, {_: 'inputMessagesFilterEmpty'}, maxID); return AppMessagesManager.getSearch({_: 'inputPeerEmpty'}, $scope.search.query, {_: 'inputMessagesFilterEmpty'}, maxID).then(function (result) {
});
} else {
var query = $scope.search.query;
if ($scope.noUsers) {
query = '%pg ' + (query || '');
}
promise = AppMessagesManager.getDialogs(query, maxID);
}
return promise.then(function (result) {
if (curJump != jump) { if (curJump != jump) {
return $q.reject(); return $q.reject();
} }
if (searchMessages) {
var dialogs = []; var dialogs = [];
angular.forEach(result.history, function (messageID) { angular.forEach(result.history, function (messageID) {
var message = AppMessagesManager.getMessage(messageID), var message = AppMessagesManager.getMessage(messageID),
@ -825,18 +815,27 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}); });
}); });
result = { return {
count: result.count,
dialogs: dialogs dialogs: dialogs
}; };
})
});
} }
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();
}
return result; return result;
}); });
}; };
function loadDialogs (force) { function loadDialogs (force) {
maxID = 0; offsetIndex = 0;
hasMore = false; hasMore = false;
if (!searchMessages) { if (!searchMessages) {
peersInDialogs = {}; peersInDialogs = {};
@ -862,18 +861,21 @@ angular.module('myApp.controllers', ['myApp.i18n'])
dialogsList.push(wrappedDialog); dialogsList.push(wrappedDialog);
}); });
if (searchMessages) {
maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message; maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message;
hasMore = dialogsResult.count === null || dialogsList.length < dialogsResult.count; } else {
offsetIndex = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].index;
if (!searchMessages) {
delete $scope.isEmpty.dialogs; delete $scope.isEmpty.dialogs;
} }
hasMore = true;
} else {
hasMore = false;
} }
$scope.$broadcast('ui_dialogs_change'); $scope.$broadcast('ui_dialogs_change');
if (!$scope.search.query) { if (!$scope.search.query) {
AppMessagesManager.getDialogs('', maxID, 100); AppMessagesManager.getConversations('', offsetIndex, 100);
if (!dialogsResult.dialogs.length) { if (!dialogsResult.dialogs.length) {
$scope.isEmpty.dialogs = true; $scope.isEmpty.dialogs = true;
showMoreDialogs(); showMoreDialogs();
@ -886,7 +888,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
} }
function showMoreDialogs () { function showMoreDialogs () {
if (contactsShown && (!hasMore || !maxID)) { if (contactsShown && (!hasMore || !offsetIndex && !maxID)) {
return; return;
} }
@ -910,10 +912,18 @@ angular.module('myApp.controllers', ['myApp.i18n'])
dialogsList.push(wrappedDialog); dialogsList.push(wrappedDialog);
}); });
if (searchMessages) {
maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message; maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message;
hasMore = dialogsResult.count === null || dialogsList.length < dialogsResult.count; } else {
offsetIndex = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].index;
}
$scope.$broadcast('ui_dialogs_append'); $scope.$broadcast('ui_dialogs_append');
hasMore = true;
}
else {
hasMore = false;
} }
}); });
}; };

238
app/js/services.js

@ -1068,10 +1068,18 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
NotificationsManager.start(); 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 curDialogStorage = dialogsStorage;
var isSearch = angular.isString(query) && query.length;
if (angular.isString(query) && query.length) { if (isSearch) {
if (!limit || cachedResults.query !== query) { if (!limit || cachedResults.query !== query) {
cachedResults.query = query; cachedResults.query = query;
@ -1091,73 +1099,136 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
} }
var offset = 0; var offset = 0;
if (maxID > 0) { if (offsetIndex > 0) {
for (offset = 0; offset < curDialogStorage.dialogs.length; offset++) { for (offset = 0; offset < curDialogStorage.dialogs.length; offset++) {
if (maxID > curDialogStorage.dialogs[offset].top_message) { if (offsetIndex > curDialogStorage.dialogs[offset].index) {
break; break;
} }
} }
} }
if (curDialogStorage.count !== null && curDialogStorage.dialogs.length == curDialogStorage.count || limit = limit || 20;
curDialogStorage.dialogs.length >= offset + (limit || 1)
if (
isSearch ||
(allChannelsLoaded && allDialogsLoaded) ||
(
curDialogStorage.dialogs.length >= offset + limit &&
curDialogStorage.dialogs[offset + limit - 1].index >= minDialogsIndex
)
) { ) {
return $q.when({ return $q.when({
count: curDialogStorage.count, dialogs: curDialogStorage.dialogs.slice(offset, offset + limit)
dialogs: curDialogStorage.dialogs.slice(offset, offset + (limit || 20))
}); });
} }
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;
}
}
}
return MtpApiManager.invokeApi('messages.getDialogs', { console.log(curDialogStorage.dialogs.slice(offset, offset + limit));
offset: offset, return {
limit: limit, // count: curDialogStorage.count,
max_id: maxID || 0 dialogs: curDialogStorage.dialogs.slice(offset, offset + limit)
}).then(function (dialogsResult) { }
TelegramMeWebService.setAuthorized(true); });
}
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); AppUsersManager.saveApiUsers(dialogsResult.users);
AppChatsManager.saveApiChats(dialogsResult.chats); AppChatsManager.saveApiChats(dialogsResult.chats);
saveMessages(dialogsResult.messages);
// return { angular.forEach(dialogsResult.dialogs, function (dialog) {
// count: 0, var peerID = AppPeersManager.getPeerID(dialog.peer);
// dialogs: [] var peerText = AppPeersManager.getPeerSearchText(peerID);
// }; SearchIndexManager.indexObject(peerID, peerText, dialogsIndex);
saveMessages(dialogsResult.messages); dialog.top_message = dialog.top_important_message;
if (maxID > 0) { var message = getMessage(peerID + '_' + dialog.top_message);
for (offset = 0; offset < curDialogStorage.dialogs.length; offset++) { var topDate = message.date;
if (maxID > curDialogStorage.dialogs[offset].top_message) { var channel = AppChatsManager.getChat(-peerID);
break; 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;
});
} }
curDialogStorage.count = dialogsResult.count || dialogsResult.dialogs.length; function getTopMessages (offset, limit) {
return MtpApiManager.invokeApi('messages.getDialogs', {
offset: offset,
limit: limit
}).then(function (dialogsResult) {
TelegramMeWebService.setAuthorized(true);
if (!maxID && curDialogStorage.dialogs.length) { AppUsersManager.saveApiUsers(dialogsResult.users);
incrementMaxSeenID(curDialogStorage.dialogs[0].top_message); AppChatsManager.saveApiChats(dialogsResult.chats);
saveMessages(dialogsResult.messages);
if (!dialogsResult.dialogs.length) {
allDialogsLoaded = true;
}
else if (!offset) {
incrementMaxSeenID(dialogsResult.dialogs[0].top_message);
} }
curDialogStorage.dialogs.splice(offset, curDialogStorage.dialogs.length - offset);
angular.forEach(dialogsResult.dialogs, function (dialog) { angular.forEach(dialogsResult.dialogs, function (dialog) {
var peerID = AppPeersManager.getPeerID(dialog.peer), var peerID = AppPeersManager.getPeerID(dialog.peer);
peerText = AppPeersManager.getPeerSearchText(peerID); var peerText = AppPeersManager.getPeerSearchText(peerID);
SearchIndexManager.indexObject(peerID, peerText, dialogsIndex); SearchIndexManager.indexObject(peerID, peerText, dialogsIndex);
curDialogStorage.dialogs.push({ var message = getMessage(dialog.top_message);
peerID: peerID,
top_message: dialog.top_message, dialog.index = generateDialogIndex(message.date);
unread_count: dialog.unread_count if (dialog.index < 0) {
}); console.log('ind', dialog.index, message.date);
}
dialog.peerID = peerID;
pushDialogToStorage(dialog);
if (historiesStorage[peerID] === undefined) { if (historiesStorage[peerID] === undefined) {
var historyStorage = {count: null, history: [dialog.top_message], pending: []}; var historyStorage = {count: null, history: [dialog.top_message], pending: []};
historiesStorage[peerID] = historyStorage; historiesStorage[peerID] = historyStorage;
var message = getMessage(dialog.top_message);
if (mergeReplyKeyboard(historyStorage, message)) { if (mergeReplyKeyboard(historyStorage, message)) {
$rootScope.$broadcast('history_reply_markup', {peerID: peerID}); $rootScope.$broadcast('history_reply_markup', {peerID: peerID});
} }
@ -1170,7 +1241,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
maxSeenID && maxSeenID &&
dialog.top_message > maxSeenID dialog.top_message > maxSeenID
) { ) {
var message = getMessage(dialog.top_message);
var notifyPeer = message.flags & 16 ? message.from_id : peerID; var notifyPeer = message.flags & 16 ? message.from_id : peerID;
if (message.unread && !message.out) { if (message.unread && !message.out) {
NotificationsManager.getPeerMuted(notifyPeer).then(function (muted) { 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) { function requestHistory (inputPeer, maxID, limit, offset) {
return MtpApiManager.invokeApi('messages.getHistory', { return MtpApiManager.invokeApi('messages.getHistory', {
peer: inputPeer, peer: inputPeer,
@ -1741,7 +1849,11 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
apiMessage.unread = apiMessage.flags & 1 ? true : false; 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;
messagesStorage[apiMessage.id] = apiMessage;
var mid = isChannel ? toPeerID + '_' + apiMessage.id : apiMessage.id;
apiMessage.mid = mid;
messagesStorage[mid] = apiMessage;
apiMessage.date -= serverTimeOffset; apiMessage.date -= serverTimeOffset;
@ -1753,6 +1865,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
apiMessage.fwdFromID = AppPeersManager.getPeerID(apiMessage.fwd_from_id); apiMessage.fwdFromID = AppPeersManager.getPeerID(apiMessage.fwd_from_id);
} }
var mediaContext = { var mediaContext = {
user_id: apiMessage.from_id, user_id: apiMessage.from_id,
date: apiMessage.date date: apiMessage.date
@ -2402,13 +2515,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
return message; return message;
} }
if (message.chatID = message.to_id.chat_id) { message.peerID = getMessagePeer(message);
message.peerID = -message.chatID; message.peerData = AppPeersManager.getPeer(message.peerID);
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.peerString = AppPeersManager.getPeerString(message.peerID); message.peerString = AppPeersManager.getPeerString(message.peerID);
message.peerPhoto = AppPeersManager.getPeerPhoto(message.peerID, 'User', 'Group'); message.peerPhoto = AppPeersManager.getPeerPhoto(message.peerID, 'User', 'Group');
message.unreadCount = unreadCount; message.unreadCount = unreadCount;
@ -2683,16 +2791,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
return wasUpdated; 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) { function incrementMaxSeenID (maxID) {
if (maxSeenID !== false && maxID && maxID > maxSeenID) { if (maxSeenID !== false && maxID && maxID > maxSeenID) {
Storage.set({ Storage.set({
@ -3173,7 +3271,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}) })
return { return {
getDialogs: getDialogs, getConversations: getConversations,
getHistory: getHistory, getHistory: getHistory,
getSearch: getSearch, getSearch: getSearch,
getMessage: getMessage, 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) { .service('AppPhotosManager', function ($modal, $window, $rootScope, MtpApiManager, MtpApiFileManager, AppUsersManager, FileManager) {
var photos = {}, var photos = {},
windowW = $(window).width(), windowW = $(window).width(),

4
app/partials/desktop/dialog.html

@ -32,7 +32,7 @@
<span class="im_dialog_message_text" my-i18n="conversation_message_deleted"></span> <span class="im_dialog_message_text" my-i18n="conversation_message_deleted"></span>
</div> </div>
<div ng-switch-default class="im_dialog_message"> <div ng-switch-default class="im_dialog_message">
<span ng-switch="::dialogMessage.peerID > 0"> <span ng-switch="dialogMessage.peerID > 0 || dialogMessage.fromID < 0">
<span ng-switch-when="true"> <span ng-switch-when="true">
<span class="im_dialog_chat_from_wrap" ng-if="dialogMessage.out"> <span class="im_dialog_chat_from_wrap" ng-if="dialogMessage.out">
<span <span
@ -59,7 +59,7 @@
<span class="im_dialog_message_media" ng-if="dialogMessage.media" ng-switch="dialogMessage.media._"> <span class="im_dialog_message_media" ng-if="dialogMessage.media" ng-switch="dialogMessage.media._">
<span ng-switch-when="messageMediaPhoto" my-i18n="conversation_media_photo"></span> <span ng-switch-when="messageMediaPhoto" my-i18n="conversation_media_photo"></span>
<span ng-switch-when="messageMediaVideo" my-i18n="conversation_media_video"></span> <span ng-switch-when="messageMediaVideo" my-i18n="conversation_media_video"></span>
<span ng-switch-when="messageMediaDocument" ng-switch="::dialogMessage.media.document.sticker || false"> <span ng-switch-when="messageMediaDocument" ng-switch="dialogMessage.media.document.sticker || false">
<span ng-switch-when="1" my-i18n="conversation_media_sticker"></span> <span ng-switch-when="1" my-i18n="conversation_media_sticker"></span>
<span ng-switch-when="2"> <span ng-switch-when="2">
<span ng-bind-html="dialogMessage.media.document.stickerEmoji"></span> <span ng-bind-html="dialogMessage.media.document.stickerEmoji"></span>

Loading…
Cancel
Save