Implemented history search
History search: added 2 tabs while searching, scroll to found message in history Move to 15th layer Improve typing event (now only on value change) Fixed styles from https://github.com/zhukov/webogram/issues/286#issuecomment-45406436 Closes #137
This commit is contained in:
parent
b996717644
commit
8556d03d9f
@ -910,7 +910,7 @@ a.tg_radio_on:hover i.icon-radio {
|
||||
}
|
||||
|
||||
.im_dialogs_panel {
|
||||
padding: 14px 12px;
|
||||
padding: 12px 12px 6px;
|
||||
position: relative;
|
||||
}
|
||||
.im_dialogs_search {
|
||||
@ -927,8 +927,7 @@ a.tg_radio_on:hover i.icon-radio {
|
||||
border: 1px solid #F2F2F2;
|
||||
border-radius: 3px;
|
||||
padding: 6px 20px 6px 30px;
|
||||
margin-bottom: 0;
|
||||
margin: 0;
|
||||
margin: 0 0 6px;
|
||||
}
|
||||
.is_1x .im_dialogs_search_field {
|
||||
background-image: url(../img/icons/IconsetW_1x.png);
|
||||
@ -941,7 +940,7 @@ a.tg_radio_on:hover i.icon-radio {
|
||||
.im_dialogs_search_clear {
|
||||
position: absolute;
|
||||
right: 9px;
|
||||
margin-top: -23px;
|
||||
margin-top: -30px;
|
||||
color: #999;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
@ -957,6 +956,37 @@ a.tg_radio_on:hover i.icon-radio {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.im_dialogs_tabs {
|
||||
padding: 4px 0;
|
||||
position: relative;
|
||||
}
|
||||
.im_dialogs_tab {
|
||||
color: #8c8c8c;
|
||||
background: #f2f2f2;
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
width: 50%;
|
||||
float: left;
|
||||
padding: 7px 0;
|
||||
}
|
||||
.im_dialogs_tab:hover,
|
||||
.im_dialogs_tab:active {
|
||||
color: #8c8c8c;
|
||||
text-decoration: none;
|
||||
}
|
||||
.im_dialogs_tab.active {
|
||||
color: #FFF;
|
||||
background: #6490b1;
|
||||
}
|
||||
.im_dialogs_tab:first-child {
|
||||
border-radius: 2px 0 0 2px;
|
||||
}
|
||||
.im_dialogs_tab:last-child {
|
||||
border-radius: 0 2px 2px 0;
|
||||
}
|
||||
|
||||
|
||||
.im_dialogs_panel_dropdown {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
@ -1499,7 +1529,8 @@ div.im_message_video_thumb {
|
||||
overflow: hidden;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.im_message_iframe_video iframe {
|
||||
.im_message_iframe_video iframe,
|
||||
.im_message_iframe_video webview {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@ -2937,6 +2968,15 @@ a.contacts_modal_contact:hover .contacts_modal_contact_status {
|
||||
.im_message_selected {
|
||||
background: #f2f6fa;
|
||||
}
|
||||
.im_message_focus {
|
||||
background-color: #f2f6fa;
|
||||
-webkit-transition: background-color linear 1s;
|
||||
transition: background-color linear 1s;
|
||||
}
|
||||
/*.im_message_focus.inactive {
|
||||
background-color: none;
|
||||
}*/
|
||||
|
||||
.im_history_selectable .im_message_outer_wrap {
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -3103,7 +3143,8 @@ a.contacts_modal_contact:hover .contacts_modal_contact_status {
|
||||
margin-top: 1px;
|
||||
border: 0;
|
||||
}
|
||||
.im_message_grouped .icon-message-status {
|
||||
.im_message_grouped1 .icon-message-status,
|
||||
.im_message_grouped2 .icon-message-status {
|
||||
margin-top: -8px;
|
||||
}
|
||||
}
|
||||
|
@ -216,10 +216,10 @@ angular.module('myApp.controllers', [])
|
||||
|
||||
$scope.$on('history_focus', function (e, peerData) {
|
||||
$modalStack.dismissAll();
|
||||
if (peerData.peerString == $scope.curDialog.peer) {
|
||||
if (peerData.peerString == $scope.curDialog.peer && !peerData.messageID) {
|
||||
$scope.$broadcast('ui_history_focus');
|
||||
} else {
|
||||
$location.url('/im?p=' + peerData.peerString);
|
||||
$location.url('/im?p=' + peerData.peerString + (peerData.messageID ? '&m=' + peerData.messageID : ''));
|
||||
}
|
||||
});
|
||||
|
||||
@ -261,8 +261,12 @@ angular.module('myApp.controllers', [])
|
||||
});
|
||||
}
|
||||
|
||||
$scope.dialogSelect = function (peerString) {
|
||||
$rootScope.$broadcast('history_focus', {peerString: peerString});
|
||||
$scope.dialogSelect = function (peerString, messageID) {
|
||||
var params = {peerString: peerString};
|
||||
if (messageID) {
|
||||
params.messageID = messageID;
|
||||
}
|
||||
$rootScope.$broadcast('history_focus', params);
|
||||
};
|
||||
|
||||
$scope.logOut = function () {
|
||||
@ -278,16 +282,15 @@ angular.module('myApp.controllers', [])
|
||||
|
||||
function updateCurDialog() {
|
||||
$scope.curDialog = {
|
||||
peer: $routeParams.p || false
|
||||
peer: $routeParams.p || false,
|
||||
messageID: $routeParams.m || false
|
||||
};
|
||||
}
|
||||
|
||||
ChangelogNotifyService.checkUpdate();
|
||||
})
|
||||
|
||||
.controller('AppImDialogsController', function ($scope, $location, MtpApiManager, AppUsersManager, AppChatsManager, AppMessagesManager, AppPeersManager, PhonebookContactsService, ErrorService) {
|
||||
|
||||
// console.log('init controller');
|
||||
.controller('AppImDialogsController', function ($scope, $location, $q, $timeout, MtpApiManager, AppUsersManager, AppChatsManager, AppMessagesManager, AppPeersManager, PhonebookContactsService, ErrorService) {
|
||||
|
||||
$scope.dialogs = [];
|
||||
$scope.contacts = [];
|
||||
@ -298,6 +301,7 @@ angular.module('myApp.controllers', [])
|
||||
var offset = 0,
|
||||
maxID = 0,
|
||||
hasMore = false,
|
||||
jump = 0,
|
||||
peersInDialogs = {},
|
||||
contactsShown;
|
||||
|
||||
@ -345,7 +349,84 @@ angular.module('myApp.controllers', [])
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$watch('search.query', loadDialogs);
|
||||
$scope.$watchCollection('search', loadDialogs);
|
||||
|
||||
$scope.importContact = function () {
|
||||
AppUsersManager.openImportContact().then(function (foundContact) {
|
||||
if (contactsShown && foundContact) {
|
||||
loadDialogs();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.importPhonebook = function () {
|
||||
PhonebookContactsService.openPhonebookImport().result.then(function (foundContacts) {
|
||||
if (contactsShown && foundContacts.length) {
|
||||
loadDialogs();
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
var searchTimeoutPromise;
|
||||
function getDialogs() {
|
||||
var searchMessages = $scope.search.messages && $scope.search.query.length > 0,
|
||||
curJump = ++jump,
|
||||
promise;
|
||||
|
||||
$timeout.cancel(searchTimeoutPromise);
|
||||
if (searchMessages) {
|
||||
searchTimeoutPromise = $timeout(angular.noop, 500);
|
||||
promise = searchTimeoutPromise.then(function () {
|
||||
return AppMessagesManager.getSearch({_: 'inputPeerEmpty'}, $scope.search.query, {_: 'inputMessagesFilterEmpty'}, maxID)
|
||||
});
|
||||
} else {
|
||||
promise = AppMessagesManager.getDialogs($scope.search.query, maxID);
|
||||
}
|
||||
|
||||
return promise.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: 0
|
||||
});
|
||||
});
|
||||
|
||||
result = {
|
||||
count: result.count,
|
||||
dialogs: dialogs
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
}, function (error) {
|
||||
if (error.type == 'NETWORK_BAD_REQUEST') {
|
||||
if (location.protocol == 'https:') {
|
||||
ErrorService.confirm({type: 'HTTPS_MIXED_FAIL'}).then(function () {
|
||||
location = location.toString().replace(/^https:/, 'http:');
|
||||
});
|
||||
error.handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (error.code == 401) {
|
||||
MtpApiManager.logOut()['finally'](function () {
|
||||
$location.url('/login');
|
||||
});
|
||||
error.handled = true;
|
||||
}
|
||||
|
||||
return $q.reject();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.importContact = function () {
|
||||
AppUsersManager.openImportContact().then(function (foundContact) {
|
||||
@ -370,7 +451,7 @@ angular.module('myApp.controllers', [])
|
||||
peersInDialogs = {};
|
||||
contactsShown = false;
|
||||
|
||||
AppMessagesManager.getDialogs($scope.search.query, maxID).then(function (dialogsResult) {
|
||||
getDialogs().then(function (dialogsResult) {
|
||||
$scope.dialogs = [];
|
||||
$scope.contacts = [];
|
||||
|
||||
@ -398,22 +479,6 @@ angular.module('myApp.controllers', [])
|
||||
showMoreDialogs();
|
||||
}
|
||||
|
||||
}, function (error) {
|
||||
if (error.type == 'NETWORK_BAD_REQUEST') {
|
||||
if (location.protocol == 'https:') {
|
||||
ErrorService.confirm({type: 'HTTPS_MIXED_FAIL'}).then(function () {
|
||||
location = location.toString().replace(/^https:/, 'http:');
|
||||
});
|
||||
error.handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (error.code == 401) {
|
||||
MtpApiManager.logOut()['finally'](function () {
|
||||
$location.url('/login');
|
||||
});
|
||||
error.handled = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -422,10 +487,12 @@ angular.module('myApp.controllers', [])
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasMore && ($scope.search.query || !$scope.dialogs.length)) {
|
||||
if (!hasMore && !$scope.search.messages && ($scope.search.query || !$scope.dialogs.length)) {
|
||||
contactsShown = true;
|
||||
|
||||
var curJump = ++jump;
|
||||
AppUsersManager.getContacts($scope.search.query).then(function (contactsList) {
|
||||
if (curJump != jump) return;
|
||||
$scope.contacts = [];
|
||||
angular.forEach(contactsList, function(userID) {
|
||||
if (peersInDialogs[userID] === undefined) {
|
||||
@ -448,7 +515,7 @@ angular.module('myApp.controllers', [])
|
||||
return;
|
||||
}
|
||||
|
||||
AppMessagesManager.getDialogs($scope.search.query, maxID).then(function (dialogsResult) {
|
||||
getDialogs().then(function (dialogsResult) {
|
||||
if (dialogsResult.dialogs.length) {
|
||||
offset += dialogsResult.dialogs.length;
|
||||
maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message;
|
||||
@ -468,10 +535,9 @@ angular.module('myApp.controllers', [])
|
||||
|
||||
.controller('AppImHistoryController', function ($scope, $location, $timeout, $rootScope, MtpApiManager, AppUsersManager, AppChatsManager, AppMessagesManager, AppPeersManager, ApiUpdatesManager, PeersSelectService, IdleManager, StatusManager, ErrorService) {
|
||||
|
||||
$scope.$watch('curDialog.peer', applyDialogSelect);
|
||||
$scope.$watch('curDialog', applyDialogSelect);
|
||||
|
||||
ApiUpdatesManager.attach();
|
||||
|
||||
IdleManager.start();
|
||||
StatusManager.start();
|
||||
|
||||
@ -494,9 +560,10 @@ angular.module('myApp.controllers', [])
|
||||
$scope.showPeerInfo = showPeerInfo;
|
||||
|
||||
var peerID,
|
||||
offset = 0,
|
||||
hasMore = false,
|
||||
hasLess = false,
|
||||
maxID = 0,
|
||||
minID = 0,
|
||||
lastSelectID = false,
|
||||
inputMediaFilters = {
|
||||
photos: 'inputMessagesFilterPhotos',
|
||||
@ -504,22 +571,32 @@ angular.module('myApp.controllers', [])
|
||||
documents: 'inputMessagesFilterDocument',
|
||||
audio: 'inputMessagesFilterAudio'
|
||||
},
|
||||
jump = 0;
|
||||
|
||||
function applyDialogSelect (newPeer) {
|
||||
selectedCancel(true);
|
||||
newPeer = newPeer || $scope.curDialog.peer || '';
|
||||
jump = 0,
|
||||
moreJump = 0,
|
||||
lessJump = 0;
|
||||
|
||||
function applyDialogSelect (newDialog, oldDialog) {
|
||||
var newPeer = newDialog.peer || $scope.curDialog.peer || '';
|
||||
peerID = AppPeersManager.getPeerID(newPeer);
|
||||
|
||||
if (peerID == $scope.curDialog.peerID && oldDialog.messageID == newDialog.messageID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$scope.curDialog.peerID = peerID;
|
||||
$scope.curDialog.inputPeer = AppPeersManager.getInputPeer(newPeer);
|
||||
$scope.mediaType = false;
|
||||
|
||||
if (peerID) {
|
||||
selectedCancel(true);
|
||||
|
||||
if (oldDialog.peer && oldDialog.peer == newDialog.peer && newDialog.messageID) {
|
||||
messageFocusHistory();
|
||||
}
|
||||
else if (peerID) {
|
||||
updateHistoryPeer(true);
|
||||
loadHistory();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
showEmptyHistory();
|
||||
}
|
||||
}
|
||||
@ -581,56 +658,119 @@ angular.module('myApp.controllers', [])
|
||||
}
|
||||
}
|
||||
|
||||
function showMoreHistory () {
|
||||
if (!hasMore || !offset) {
|
||||
function messageFocusHistory () {
|
||||
var i, found = false;
|
||||
for (i = 0; i < $scope.history.length; i++) {
|
||||
if ($scope.curDialog.messageID == $scope.history[i].id) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
$scope.historyUnread = {};
|
||||
$scope.historyFocus = $scope.curDialog.messageID;
|
||||
$scope.$broadcast('ui_history_change_scroll');
|
||||
} else {
|
||||
loadHistory();
|
||||
}
|
||||
}
|
||||
|
||||
function showLessHistory () {
|
||||
if (!hasLess) {
|
||||
return;
|
||||
}
|
||||
// console.trace('load history');
|
||||
|
||||
var curJump = ++jump,
|
||||
var curJump = jump,
|
||||
curLessJump = ++lessJump,
|
||||
limit = 0,
|
||||
backLimit = 20;
|
||||
AppMessagesManager.getHistory($scope.curDialog.inputPeer, minID, limit, backLimit).then(function (historyResult) {
|
||||
if (curJump != jump || curLessJump != lessJump) return;
|
||||
|
||||
angular.forEach(historyResult.history, function (id) {
|
||||
if (id > minID) {
|
||||
$scope.history.push(AppMessagesManager.wrapForHistory(id));
|
||||
}
|
||||
});
|
||||
|
||||
if (historyResult.history.length) {
|
||||
minID = historyResult.history.length >= backLimit
|
||||
? historyResult.history[0]
|
||||
: 0;
|
||||
updateHistoryGroups(-backLimit);
|
||||
$scope.$broadcast('ui_history_append');
|
||||
} else {
|
||||
minID = 0;
|
||||
}
|
||||
hasLess = minID > 0;
|
||||
});
|
||||
}
|
||||
|
||||
function showMoreHistory () {
|
||||
if (!hasMore) {
|
||||
return;
|
||||
}
|
||||
|
||||
var curJump = jump,
|
||||
curMoreJump = moreJump,
|
||||
inputMediaFilter = $scope.mediaType && {_: inputMediaFilters[$scope.mediaType]},
|
||||
getMessagesPromise = inputMediaFilter
|
||||
? AppMessagesManager.getSearch($scope.curDialog.inputPeer, '', inputMediaFilter, maxID)
|
||||
: AppMessagesManager.getHistory($scope.curDialog.inputPeer, maxID);
|
||||
|
||||
getMessagesPromise.then(function (historyResult) {
|
||||
if (curJump != jump) return;
|
||||
|
||||
offset += historyResult.history.length;
|
||||
hasMore = historyResult.count === null || offset < historyResult.count;
|
||||
maxID = historyResult.history[historyResult.history.length - 1];
|
||||
if (curJump != jump || curMoreJump != moreJump) return;
|
||||
|
||||
angular.forEach(historyResult.history, function (id) {
|
||||
$scope.history.unshift(AppMessagesManager.wrapForHistory(id));
|
||||
});
|
||||
|
||||
updateHistoryGroups(historyResult.history.length + 1);
|
||||
hasMore = historyResult.count === null ||
|
||||
historyResult.history.length && $scope.history.length < historyResult.count;
|
||||
|
||||
if (historyResult.history.length) {
|
||||
maxID = historyResult.history[historyResult.history.length - 1];
|
||||
updateHistoryGroups(historyResult.history.length + 1);
|
||||
$scope.$broadcast('ui_history_prepend');
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function loadHistory () {
|
||||
hasMore = false;
|
||||
offset = 0;
|
||||
hasLess = false;
|
||||
maxID = 0;
|
||||
minID = 0;
|
||||
|
||||
var limit = 0, backLimit = 0;
|
||||
|
||||
if ($scope.curDialog.messageID) {
|
||||
maxID = parseInt($scope.curDialog.messageID);
|
||||
limit = 5;
|
||||
backLimit = 5;
|
||||
}
|
||||
|
||||
var curJump = ++jump,
|
||||
inputMediaFilter = $scope.mediaType && {_: inputMediaFilters[$scope.mediaType]},
|
||||
getMessagesPromise = inputMediaFilter
|
||||
? AppMessagesManager.getSearch($scope.curDialog.inputPeer, '', inputMediaFilter, maxID)
|
||||
: AppMessagesManager.getHistory($scope.curDialog.inputPeer, maxID);
|
||||
: AppMessagesManager.getHistory($scope.curDialog.inputPeer, maxID, limit, backLimit);
|
||||
|
||||
|
||||
$scope.state.mayBeHasMore = true;
|
||||
getMessagesPromise.then(function (historyResult) {
|
||||
if (curJump != jump) return;
|
||||
|
||||
offset += historyResult.history.length;
|
||||
|
||||
hasMore = historyResult.count === null || offset < historyResult.count;
|
||||
minID = maxID && historyResult.history.indexOf(maxID)>= backLimit - 1
|
||||
? historyResult.history[0]
|
||||
: 0;
|
||||
maxID = historyResult.history[historyResult.history.length - 1];
|
||||
|
||||
hasLess = minID > 0;
|
||||
hasMore = historyResult.count === null ||
|
||||
historyResult.history.length && historyResult.history.length < historyResult.count;
|
||||
|
||||
updateHistoryPeer();
|
||||
safeReplaceObject($scope.state, {loaded: true});
|
||||
|
||||
@ -651,6 +791,8 @@ angular.module('myApp.controllers', [])
|
||||
$scope.historyUnread = {};
|
||||
}
|
||||
|
||||
$scope.historyFocus = $scope.curDialog.messageID || 0;
|
||||
|
||||
$scope.$broadcast('ui_history_change');
|
||||
|
||||
AppMessagesManager.readHistory($scope.curDialog.inputPeer);
|
||||
@ -805,6 +947,14 @@ angular.module('myApp.controllers', [])
|
||||
|
||||
$scope.$on('history_append', function (e, addedMessage) {
|
||||
if (addedMessage.peerID == $scope.curDialog.peerID) {
|
||||
if (minID) {
|
||||
if (addedMessage.my) {
|
||||
$rootScope.$broadcast('history_focus', {peerString: $scope.curDialog.peer});
|
||||
} else {
|
||||
$scope.missedCount++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ($scope.mediaType) {
|
||||
if (addedMessage.my) {
|
||||
toggleMedia();
|
||||
@ -818,7 +968,7 @@ angular.module('myApp.controllers', [])
|
||||
$scope.history.push(AppMessagesManager.wrapForHistory(addedMessage.messageID));
|
||||
updateHistoryGroups(-3);
|
||||
$scope.typing = {};
|
||||
$scope.$broadcast('ui_history_append', {my: addedMessage.my});
|
||||
$scope.$broadcast('ui_history_append_new', {my: addedMessage.my});
|
||||
if (addedMessage.my) {
|
||||
$scope.historyUnread = {};
|
||||
}
|
||||
@ -889,9 +1039,8 @@ angular.module('myApp.controllers', [])
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$on('history_need_more', function () {
|
||||
showMoreHistory();
|
||||
});
|
||||
$scope.$on('history_need_less', showLessHistory);
|
||||
$scope.$on('history_need_more', showMoreHistory);
|
||||
|
||||
$rootScope.$watch('idle.isIDLE', function (newVal) {
|
||||
if (!newVal && $scope.curDialog && $scope.curDialog.peerID) {
|
||||
@ -976,9 +1125,10 @@ angular.module('myApp.controllers', [])
|
||||
function onMessageChange(newVal) {
|
||||
// console.log('ctrl text changed', newVal);
|
||||
// console.trace('ctrl text changed', newVal);
|
||||
AppMessagesManager.readHistory($scope.curDialog.inputPeer);
|
||||
|
||||
if (newVal && newVal.length) {
|
||||
AppMessagesManager.readHistory($scope.curDialog.inputPeer);
|
||||
|
||||
var backupDraftObj = {};
|
||||
backupDraftObj['draft' + $scope.curDialog.peerID] = newVal;
|
||||
AppConfigManager.set(backupDraftObj);
|
||||
|
@ -329,7 +329,8 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
headWrap = $('.tg_page_head')[0],
|
||||
footer = $('.im_page_footer')[0],
|
||||
sendForm = $('.im_send_form', element)[0],
|
||||
moreNotified = false;
|
||||
moreNotified = false,
|
||||
lessNotified = false;
|
||||
|
||||
onContentLoaded(function () {
|
||||
scrollableWrap.scrollTop = scrollableWrap.scrollHeight;
|
||||
@ -337,6 +338,7 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
});
|
||||
|
||||
var updateScroller = function (delay) {
|
||||
// console.trace('scroller update', delay);
|
||||
$timeout(function () {
|
||||
if (!$(scrollableWrap).hasClass('im_history_to_bottom')) {
|
||||
$(historyWrap).nanoScroller();
|
||||
@ -357,7 +359,7 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
var animated = transform ? true : false,
|
||||
curAnimation = false;
|
||||
|
||||
$scope.$on('ui_history_append', function (e, options) {
|
||||
$scope.$on('ui_history_append_new', function (e, options) {
|
||||
if (!atBottom && !options.my) {
|
||||
return;
|
||||
}
|
||||
@ -392,6 +394,24 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
});
|
||||
});
|
||||
|
||||
function changeScroll () {
|
||||
var unreadSplit, focusMessage;
|
||||
|
||||
if (focusMessage = $('.im_message_focus', scrollableWrap)[0]) {
|
||||
scrollableWrap.scrollTop = Math.max(0, focusMessage.offsetTop - 52);
|
||||
atBottom = false;
|
||||
} else if (unreadSplit = $('.im_message_unread_split', scrollableWrap)[0]) {
|
||||
scrollableWrap.scrollTop = Math.max(0, unreadSplit.offsetTop - 52);
|
||||
atBottom = false;
|
||||
} else {
|
||||
scrollableWrap.scrollTop = scrollableWrap.scrollHeight;
|
||||
}
|
||||
updateScroller();
|
||||
$timeout(function () {
|
||||
$(scrollableWrap).trigger('scroll');
|
||||
});
|
||||
};
|
||||
|
||||
$scope.$on('ui_history_change', function () {
|
||||
$(scrollableWrap).addClass('im_history_to_bottom');
|
||||
$(scrollable).css({bottom: 0});
|
||||
@ -399,22 +419,14 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
$(scrollableWrap).removeClass('im_history_to_bottom');
|
||||
$(scrollable).css({bottom: ''});
|
||||
updateSizes(true);
|
||||
|
||||
var unreadSplit = $('.im_message_unread_split', scrollableWrap);
|
||||
if (unreadSplit[0]) {
|
||||
scrollableWrap.scrollTop = Math.max(0, unreadSplit[0].offsetTop - 52);
|
||||
atBottom = false;
|
||||
} else {
|
||||
scrollableWrap.scrollTop = scrollableWrap.scrollHeight;
|
||||
}
|
||||
|
||||
updateScroller();
|
||||
moreNotified = false;
|
||||
lessNotified = false;
|
||||
changeScroll();
|
||||
});
|
||||
});
|
||||
|
||||
$timeout(function () {
|
||||
$(scrollableWrap).trigger('scroll');
|
||||
});
|
||||
});
|
||||
$scope.$on('ui_history_change_scroll', function () {
|
||||
onContentLoaded(changeScroll)
|
||||
});
|
||||
|
||||
$scope.$on('ui_history_focus', function () {
|
||||
@ -450,6 +462,20 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
});
|
||||
});
|
||||
|
||||
$scope.$on('ui_history_append', function () {
|
||||
var sh = scrollableWrap.scrollHeight;
|
||||
onContentLoaded(function () {
|
||||
updateBottomizer();
|
||||
lessNotified = false;
|
||||
|
||||
$timeout(function () {
|
||||
if (scrollableWrap.scrollHeight != sh) {
|
||||
$(scrollableWrap).trigger('scroll');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$scope.$on('ui_panel_update', function () {
|
||||
onContentLoaded(function () {
|
||||
updateSizes();
|
||||
@ -493,6 +519,10 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
moreNotified = true;
|
||||
$scope.$emit('history_need_more');
|
||||
}
|
||||
else if (!lessNotified && scrollableWrap.scrollTop >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight - 300) {
|
||||
lessNotified = true;
|
||||
$scope.$emit('history_need_less');
|
||||
}
|
||||
});
|
||||
|
||||
function updateSizes (heightOnly) {
|
||||
@ -623,6 +653,7 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
if (submit) {
|
||||
$(element).trigger('submit');
|
||||
$(element).trigger('message_send');
|
||||
resetAfterSubmit();
|
||||
return cancelEvent(e);
|
||||
}
|
||||
}
|
||||
@ -632,19 +663,28 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
$('.im_submit', element).on('mousedown', function (e) {
|
||||
$(element).trigger('submit');
|
||||
$(element).trigger('message_send');
|
||||
resetAfterSubmit();
|
||||
return cancelEvent(e);
|
||||
});
|
||||
|
||||
var lastTyping = 0;
|
||||
var lastTyping = 0,
|
||||
lastLength;
|
||||
$(editorElement).on('keyup', function (e) {
|
||||
var now = tsNow();
|
||||
if (now - lastTyping < 5000) {
|
||||
return;
|
||||
}
|
||||
var now = tsNow(),
|
||||
length = (editorElement[richTextarea ? 'innerText' : 'value']).length;
|
||||
|
||||
if (now - lastTyping > 5000 && length != lastLength) {
|
||||
lastTyping = now;
|
||||
lastLength = length;
|
||||
$scope.$emit('ui_typing');
|
||||
}
|
||||
});
|
||||
|
||||
function resetAfterSubmit () {
|
||||
lastTyping = 0;
|
||||
lastLength = 0;
|
||||
};
|
||||
|
||||
function updateField () {
|
||||
if (richTextarea) {
|
||||
$timeout.cancel(updatePromise);
|
||||
|
@ -22,7 +22,7 @@
|
||||
setTimeout(function () {callback(result)}, 10);
|
||||
};
|
||||
|
||||
if (!window.applicationCache || Config.App.packaged || !window.addEventListener) {
|
||||
if (!window.applicationCache || Config.Modes.packed || !window.addEventListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -1785,7 +1785,7 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato
|
||||
var serializer = new TLSerialization(options);
|
||||
|
||||
if (!this.connectionInited) {
|
||||
serializer.storeInt(0x2b9b08fa, 'invokeWithLayer14');
|
||||
serializer.storeInt(0xb4418b64, 'invokeWithLayer15');
|
||||
serializer.storeInt(0x69796de9, 'initConnection');
|
||||
serializer.storeInt(Config.App.id, 'api_id');
|
||||
serializer.storeString(navigator.userAgent || 'Unknown UserAgent', 'device_model');
|
||||
|
@ -750,7 +750,6 @@ angular.module('myApp.services', [])
|
||||
}
|
||||
|
||||
function search (query, searchIndex) {
|
||||
console.time('search');
|
||||
var shortIndexes = searchIndex.shortIndexes,
|
||||
fullTexts = searchIndex.fullTexts;
|
||||
|
||||
@ -787,7 +786,6 @@ angular.module('myApp.services', [])
|
||||
}
|
||||
}
|
||||
|
||||
console.timeEnd('search');
|
||||
return newFoundObjs;
|
||||
}
|
||||
})
|
||||
@ -873,9 +871,7 @@ angular.module('myApp.services', [])
|
||||
}
|
||||
}
|
||||
|
||||
curDialogStorage.count = dialogsResult._ == 'messages.dialogsSlice'
|
||||
? dialogsResult.count
|
||||
: dialogsResult.dialogs.length;
|
||||
curDialogStorage.count = dialogsResult.count || dialogsResult.dialogs.length;
|
||||
|
||||
curDialogStorage.dialogs.splice(offset, curDialogStorage.dialogs.length - offset);
|
||||
angular.forEach(dialogsResult.dialogs, function (dialog) {
|
||||
@ -904,21 +900,29 @@ angular.module('myApp.services', [])
|
||||
});
|
||||
}
|
||||
|
||||
function fillHistoryStorage (inputPeer, maxID, fullLimit, historyStorage) {
|
||||
console.log('fill history storage', inputPeer, maxID, fullLimit, angular.copy(historyStorage));
|
||||
function requestHistory (inputPeer, maxID, limit, backLimit) {
|
||||
maxID = maxID || 0;
|
||||
limit = limit || 0;
|
||||
backLimit = backLimit || 0;
|
||||
|
||||
return MtpApiManager.invokeApi('messages.getHistory', {
|
||||
peer: inputPeer,
|
||||
offset: 0,
|
||||
limit: fullLimit,
|
||||
offset: -backLimit,
|
||||
limit: limit + backLimit,
|
||||
max_id: maxID || 0
|
||||
}).then(function (historyResult) {
|
||||
AppUsersManager.saveApiUsers(historyResult.users);
|
||||
AppChatsManager.saveApiChats(historyResult.chats);
|
||||
saveMessages(historyResult.messages);
|
||||
|
||||
historyStorage.count = historyResult._ == 'messages.messagesSlice'
|
||||
? historyResult.count
|
||||
: historyResult.messages.length;
|
||||
return historyResult;
|
||||
});
|
||||
}
|
||||
|
||||
function fillHistoryStorage (inputPeer, maxID, fullLimit, historyStorage) {
|
||||
console.log('fill history storage', inputPeer, maxID, fullLimit, angular.copy(historyStorage));
|
||||
return requestHistory (inputPeer, maxID, fullLimit).then(function (historyResult) {
|
||||
historyStorage.count = historyResult.count || historyResult.messages.length;
|
||||
|
||||
var offset = 0;
|
||||
if (maxID > 0) {
|
||||
@ -945,8 +949,7 @@ angular.module('myApp.services', [])
|
||||
});
|
||||
};
|
||||
|
||||
function getHistory (inputPeer, maxID, limit) {
|
||||
|
||||
function getHistory (inputPeer, maxID, limit, backLimit) {
|
||||
var peerID = AppPeersManager.getPeerID(inputPeer),
|
||||
historyStorage = historiesStorage[peerID],
|
||||
offset = 0,
|
||||
@ -979,9 +982,17 @@ angular.module('myApp.services', [])
|
||||
if (historyStorage.count !== null && historyStorage.history.length == historyStorage.count ||
|
||||
historyStorage.history.length >= offset + (limit || 1)
|
||||
) {
|
||||
if (backLimit) {
|
||||
backLimit = Math.min(offset, backLimit);
|
||||
offset = Math.max(0, offset - backLimit);
|
||||
limit += backLimit;
|
||||
} else {
|
||||
limit = limit || 20;
|
||||
}
|
||||
|
||||
return $q.when({
|
||||
count: historyStorage.count,
|
||||
history: resultPending.concat(historyStorage.history.slice(offset, offset + (limit || 20))),
|
||||
history: resultPending.concat(historyStorage.history.slice(offset, offset + limit)),
|
||||
unreadLimit: unreadLimit
|
||||
});
|
||||
}
|
||||
@ -989,8 +1000,26 @@ angular.module('myApp.services', [])
|
||||
if (unreadLimit) {
|
||||
limit = Math.max(20, unreadLimit + 2);
|
||||
}
|
||||
else if (!backLimit && !limit) {
|
||||
limit = 20;
|
||||
}
|
||||
|
||||
limit = limit || 20;
|
||||
if (backLimit || maxID && historyStorage.history.indexOf(maxID) == -1) {
|
||||
return requestHistory(inputPeer, maxID, limit, backLimit).then(function (historyResult) {
|
||||
historyStorage.count = historyResult.count || historyResult.messages.length;
|
||||
|
||||
var history = [];
|
||||
angular.forEach(historyResult.messages, function (message) {
|
||||
history.push(message.id);
|
||||
});
|
||||
|
||||
return {
|
||||
count: historyStorage.count,
|
||||
history: resultPending.concat(history),
|
||||
unreadLimit: unreadLimit
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
return fillHistoryStorage(inputPeer, maxID, limit, historyStorage).then(function () {
|
||||
offset = 0;
|
||||
@ -1102,9 +1131,7 @@ angular.module('myApp.services', [])
|
||||
AppChatsManager.saveApiChats(searchResult.chats);
|
||||
saveMessages(searchResult.messages);
|
||||
|
||||
var foundCount = searchResult._ == 'messages.messagesSlice'
|
||||
? searchResult.count
|
||||
: searchResult.messages.length;
|
||||
var foundCount = searchResult.count || searchResult.messages.length;
|
||||
|
||||
foundMsgs = [];
|
||||
angular.forEach(searchResult.messages, function (message) {
|
||||
@ -1186,6 +1213,10 @@ angular.module('myApp.services', [])
|
||||
}
|
||||
}
|
||||
|
||||
if (historyStorage.readPromise) {
|
||||
return historyStorage.readPromise;
|
||||
}
|
||||
|
||||
var promise = MtpApiManager.invokeApi('messages.readHistory', {
|
||||
peer: inputPeer,
|
||||
offset: 0,
|
||||
@ -1198,6 +1229,8 @@ angular.module('myApp.services', [])
|
||||
foundDialog[0].unread_count = 0;
|
||||
$rootScope.$broadcast('dialog_unread', {peerID: peerID, count: 0});
|
||||
}
|
||||
})['finally'](function () {
|
||||
delete historyStorage.readPromise;
|
||||
});
|
||||
|
||||
|
||||
@ -3125,9 +3158,10 @@ angular.module('myApp.services', [])
|
||||
videoID = youtubeMatches && youtubeMatches[1];
|
||||
|
||||
if (videoID) {
|
||||
text = text + '<div class="im_message_iframe_video"><iframe type="text/html" frameborder="0" ' +
|
||||
var tag = Config.Modes.chrome_packed ? 'webview' : 'iframe';
|
||||
text = text + '<div class="im_message_iframe_video"><' + tag + ' type="text/html" frameborder="0" ' +
|
||||
'src="http://www.youtube.com/embed/' + videoID +
|
||||
'?autoplay=0&controls=2"></iframe></div>'
|
||||
'?autoplay=0&controls=2"></' + tag + '></div>'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<a class="im_dialog" ng-click="dialogSelect(dialogMessage.peerString)">
|
||||
<a class="im_dialog" ng-click="dialogSelect(dialogMessage.peerString, search.messages && dialogMessage.id)">
|
||||
|
||||
<div class="im_dialog_meta pull-right text-right">
|
||||
<div class="im_dialog_date" ng-bind="dialogMessage.dateText"></div>
|
||||
|
@ -23,7 +23,15 @@
|
||||
<input class="form-control im_dialogs_search_field" type="search" placeholder="Search" ng-model="search.query"/>
|
||||
<a class="im_dialogs_search_clear" ng-click="search.query = ''" ng-show="search.query.length"></a>
|
||||
</div>
|
||||
|
||||
<div class="im_dialogs_tabs_wrap" ng-show="search.query.length">
|
||||
<div class="im_dialogs_tabs clearfix">
|
||||
<a href="" class="im_dialogs_tab" ng-class="{active: !search.messages}" ng-click="search.messages = false">Conversations</a>
|
||||
<a href="" class="im_dialogs_tab" ng-class="{active: search.messages}" ng-click="search.messages = true">Messages</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div my-dialogs-list class="im_dialogs_col">
|
||||
<div class="im_dialogs_wrap nano">
|
||||
<div class="im_dialogs_scrollable_wrap content">
|
||||
@ -35,9 +43,14 @@
|
||||
<button ng-if="phonebookAvailable" type="button" class="btn btn-primary btn-sm im_dialogs_import_phonebook" ng-click="importPhonebook()">Import phonebook</button>
|
||||
</div>
|
||||
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<div ng-switch="search.messages">
|
||||
<ul ng-switch-when="true" class="nav nav-pills nav-stacked">
|
||||
<li class="im_dialog_wrap" my-dialog dialog-message="dialogMessage" ng-repeat="dialogMessage in dialogs track by dialogMessage.id" ng-class="{active: curDialog.peerID == dialogMessage.peerID && curDialog.messageID == dialogMessage.id}"></li>
|
||||
</ul>
|
||||
<ul ng-switch-default class="nav nav-pills nav-stacked">
|
||||
<li class="im_dialog_wrap" my-dialog dialog-message="dialogMessage" ng-repeat="dialogMessage in dialogs track by dialogMessage.peerID" ng-class="{active: curDialog.peerID == dialogMessage.peerID}"></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="im_dialogs_contacts_wrap" ng-show="contacts.length > 0">
|
||||
<h5>Contacts</h5>
|
||||
|
@ -4,7 +4,7 @@
|
||||
</ng-pluralize>
|
||||
</div>
|
||||
|
||||
<div class="im_message_outer_wrap" ng-class="[ selectedMsgs[historyMessage.id] && 'im_message_selected', historyMessage.grouped && ('im_message_grouped' + historyMessage.grouped) ]" ng-click="toggleMessage(historyMessage.id, $event)">
|
||||
<div class="im_message_outer_wrap" ng-class="[ selectedMsgs[historyMessage.id] && 'im_message_selected', historyMessage.grouped && ('im_message_grouped' + historyMessage.grouped) , historyFocus == historyMessage.id && 'im_message_focus']" ng-click="toggleMessage(historyMessage.id, $event)">
|
||||
|
||||
|
||||
<div class="im_message_wrap clearfix" bindonce>
|
||||
|
Loading…
Reference in New Issue
Block a user