diff --git a/app/js/controllers.js b/app/js/controllers.js index dab19f0d..cdafe7bd 100644 --- a/app/js/controllers.js +++ b/app/js/controllers.js @@ -566,7 +566,7 @@ angular.module('myApp.controllers', []) if (searchMessages) { searchTimeoutPromise = force ? $q.when() : $timeout(angular.noop, 500); promise = searchTimeoutPromise.then(function () { - return AppMessagesManager.getSearch({_: 'inputPeerEmpty'}, $scope.search.query, {_: 'inputMessagesFilterEmpty'}, maxID) + return AppMessagesManager.getSearch({_: 'inputPeerEmpty'}, $scope.search.query, {_: 'inputMessagesFilterEmpty'}, maxID); }); } else { promise = AppMessagesManager.getDialogs($scope.search.query, maxID); @@ -585,7 +585,7 @@ angular.module('myApp.controllers', []) dialogs.push({ peerID: peerID, top_message: messageID, - unread_count: 0 + unread_count: -1 }); }); @@ -644,7 +644,8 @@ angular.module('myApp.controllers', []) angular.forEach(dialogsResult.dialogs, function (dialog) { peersInDialogs[dialog.peerID] = true; - $scope.dialogs.push(AppMessagesManager.wrapForDialog(dialog.top_message, dialog.unread_count)); + var wrappedDialog = AppMessagesManager.wrapForDialog(dialog.top_message, dialog.unread_count); + $scope.dialogs.push(wrappedDialog); }); delete $scope.isEmpty.dialogs; } @@ -764,7 +765,11 @@ angular.module('myApp.controllers', []) }, jump = 0, moreJump = 0, - lessJump = 0; + moreActive = false, + morePending = false, + lessJump = 0, + lessActive = false, + lessPending = false; function applyDialogSelect (newDialog, oldDialog) { var newPeer = newDialog.peer || $scope.curDialog.peer || ''; @@ -867,10 +872,12 @@ angular.module('myApp.controllers', []) found = false, history = historiesQueueFind(); - for (i = 0; i < history.messages.length; i++) { - if ($scope.curDialog.messageID == history.messages[i].id) { - found = true; - break; + if (history) { + for (i = 0; i < history.messages.length; i++) { + if ($scope.curDialog.messageID == history.messages[i].id) { + found = true; + break; + } } } @@ -887,12 +894,19 @@ angular.module('myApp.controllers', []) if (!hasLess) { return; } + if (moreActive) { + lessPending = true; + return; + } + lessPending = false; + lessActive = true; var curJump = jump, curLessJump = ++lessJump, limit = 0, backLimit = 20; AppMessagesManager.getHistory($scope.curDialog.inputPeer, minID, limit, backLimit).then(function (historyResult) { + lessActive = false; if (curJump != jump || curLessJump != lessJump) return; var i, id; @@ -916,6 +930,10 @@ angular.module('myApp.controllers', []) minID = 0; } $scope.skippedHistory = hasLess = minID > 0; + + if (morePending) { + showMoreHistory(); + } }); } @@ -923,6 +941,12 @@ angular.module('myApp.controllers', []) if (!hasMore) { return; } + if (lessActive) { + morePending = true; + return; + } + morePending = false; + moreActive = true; var curJump = jump, curMoreJump = moreJump, @@ -933,6 +957,7 @@ angular.module('myApp.controllers', []) : AppMessagesManager.getHistory($scope.curDialog.inputPeer, maxID, limit); getMessagesPromise.then(function (historyResult) { + moreActive = false; if (curJump != jump || curMoreJump != moreJump) return; angular.forEach(historyResult.history, function (id) { @@ -950,6 +975,10 @@ angular.module('myApp.controllers', []) } $scope.$broadcast('ui_history_prepend'); } + + if (lessPending) { + showLessHistory(); + } }); }; @@ -967,8 +996,8 @@ angular.module('myApp.controllers', []) if ($scope.curDialog.messageID) { maxID = parseInt($scope.curDialog.messageID); - limit = 5; - backLimit = 5; + limit = 10; + backLimit = 10; } else if (forceRecent) { limit = 10; @@ -977,6 +1006,11 @@ angular.module('myApp.controllers', []) limit = 20; } + moreActive = false; + morePending = false; + lessActive = false; + lessPending = false; + var curJump = ++jump, inputMediaFilter = $scope.historyFilter.mediaType && {_: inputMediaFilters[$scope.historyFilter.mediaType]}, getMessagesPromise = inputMediaFilter @@ -1024,7 +1058,9 @@ angular.module('myApp.controllers', []) delete $scope.historyUnreadAfter; $scope.$broadcast('messages_unread_after'); } - $scope.$broadcast('messages_focus', $scope.curDialog.messageID || 0); + onContentLoaded(function () { + $scope.$broadcast('messages_focus', $scope.curDialog.messageID || 0); + }) $scope.$broadcast('ui_history_change'); AppMessagesManager.readHistory($scope.curDialog.inputPeer); diff --git a/app/js/directives.js b/app/js/directives.js index 83087f0c..ad23ec2c 100644 --- a/app/js/directives.js +++ b/app/js/directives.js @@ -629,10 +629,15 @@ angular.module('myApp.directives', ['myApp.filters']) function changeScroll () { var unreadSplit, focusMessage; - // console.log('change scroll'); + // console.trace('change scroll'); if (focusMessage = $('.im_message_focus:visible', scrollableWrap)[0]) { - // console.log('change scroll focus', focusMessage.offsetTop); - scrollableWrap.scrollTop = Math.max(0, focusMessage.offsetTop - Math.floor(scrollableWrap.clientHeight / 2) + 26); + var ch = scrollableWrap.clientHeight, + st = scrollableWrap.scrollTop, + ot = focusMessage.offsetTop, + h = focusMessage.clientHeight; + if (!st || st + ch < ot || st > ot + h) { + scrollableWrap.scrollTop = Math.max(0, ot - Math.floor(ch / 2) + 26); + } atBottom = false; } else if (unreadSplit = $('.im_message_unread_split:visible', scrollableWrap)[0]) { // console.log('change scroll unread', unreadSplit.offsetTop); @@ -646,6 +651,7 @@ angular.module('myApp.directives', ['myApp.filters']) updateScroller(); $timeout(function () { $(scrollableWrap).trigger('scroll'); + scrollTopInitial = scrollableWrap.scrollTop; }); }; @@ -689,7 +695,11 @@ angular.module('myApp.directives', ['myApp.filters']) var upd = function () { $(scrollableWrap).removeClass('im_history_to_bottom'); $(scrollable).css({bottom: '', marginLeft: ''}); - scrollableWrap.scrollTop = st + scrollableWrap.scrollHeight - sh; + if (scrollTopInitial >= 0) { + changeScroll(); + } else { + scrollableWrap.scrollTop = st + scrollableWrap.scrollHeight - sh; + } updateBottomizer(); moreNotified = false; @@ -714,6 +724,10 @@ angular.module('myApp.directives', ['myApp.filters']) updateBottomizer(); lessNotified = false; + if (scrollTopInitial >= 0) { + changeScroll(); + } + $timeout(function () { if (scrollableWrap.scrollHeight != sh) { $(scrollableWrap).trigger('scroll'); @@ -751,23 +765,28 @@ angular.module('myApp.directives', ['myApp.filters']) // updateSizes(); }); - var atBottom = true; + var atBottom = true, + scrollTopInitial = -1; $(scrollableWrap).on('scroll', function (e) { if (!element.is(':visible') || $(scrollableWrap).hasClass('im_history_to_bottom') || curAnimation) { return; } - atBottom = scrollableWrap.scrollTop >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight; - - if (!moreNotified && scrollableWrap.scrollTop <= 300) { - moreNotified = true; - $scope.$emit('history_need_more'); + var st = scrollableWrap.scrollTop; + atBottom = st >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight; + if (scrollTopInitial >= 0 && scrollTopInitial != st) { + scrollTopInitial = -1; } - else if (!lessNotified && scrollableWrap.scrollTop >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight - 300) { + + if (!lessNotified && st >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight - 300) { lessNotified = true; $scope.$emit('history_need_less'); } + else if (!moreNotified && st <= 300) { + moreNotified = true; + $scope.$emit('history_need_more'); + } }); function updateSizes (heightOnly) { diff --git a/app/js/services.js b/app/js/services.js index fb95c3f6..f6da174a 100644 --- a/app/js/services.js +++ b/app/js/services.js @@ -760,6 +760,8 @@ angular.module('myApp.services', []) } }); + var dateOrTimeFilter = $filter('dateOrTime'); + midnightOffseted.setHours(0); midnightOffseted.setMinutes(0); midnightOffseted.setSeconds(0); @@ -1744,7 +1746,9 @@ angular.module('myApp.services', []) } function wrapForDialog (msgID, unreadCount) { - if (messagesForDialogs[msgID] !== undefined) { + var useCache = unreadCount != -1; + + if (useCache && messagesForDialogs[msgID] !== undefined) { return messagesForDialogs[msgID]; } @@ -1773,10 +1777,13 @@ angular.module('myApp.services', []) message.richMessage = RichTextProcessor.wrapRichText(message.message.substr(0, 64), {noLinks: true, noLinebreaks: true}); } - message.dateText = $filter('dateOrTime')(message.date); + message.dateText = dateOrTimeFilter(message.date); + if (useCache) { + messagesForDialogs[msgID] = message; + } - return messagesForDialogs[msgID] = message; + return message; } function wrapForHistory (msgID) {