Browse Source

make commands autocomplete work

master
Igor Zhukov 10 years ago
parent
commit
74da0c8f55
  1. 13
      app/js/controllers.js
  2. 29
      app/js/directives.js
  3. 16
      app/js/lib/utils.js
  4. 73
      app/js/message_composer.js
  5. 2
      app/less/app.less

13
app/js/controllers.js

@ -1761,6 +1761,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.$watch('draftMessage.text', onMessageChange); $scope.$watch('draftMessage.text', onMessageChange);
$scope.$watch('draftMessage.files', onFilesSelected); $scope.$watch('draftMessage.files', onFilesSelected);
$scope.$watch('draftMessage.sticker', onStickerSelected); $scope.$watch('draftMessage.sticker', onStickerSelected);
$scope.$watch('draftMessage.command', onCommandSelected);
function sendMessage (e) { function sendMessage (e) {
$scope.$broadcast('ui_message_before_send'); $scope.$broadcast('ui_message_before_send');
@ -1866,7 +1867,6 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}) })
}); });
console.log(commandsList, commandsIndex);
safeReplaceObject($scope.commands, { safeReplaceObject($scope.commands, {
list: commandsList, list: commandsList,
index: commandsIndex index: commandsIndex
@ -1970,6 +1970,17 @@ angular.module('myApp.controllers', ['myApp.i18n'])
} }
delete $scope.draftMessage.sticker; delete $scope.draftMessage.sticker;
} }
function onCommandSelected (command) {
if (!command) {
return;
}
AppMessagesManager.sendText($scope.curDialog.peerID, command);
delete $scope.draftMessage.sticker;
delete $scope.draftMessage.text;
$scope.$broadcast('ui_message_send');
$scope.$broadcast('ui_peer_draft');
}
}) })
.controller('AppLangSelectController', function ($scope, _, Storage, ErrorService, AppRuntimeManager) { .controller('AppLangSelectController', function ($scope, _, Storage, ErrorService, AppRuntimeManager) {

29
app/js/directives.js

@ -563,7 +563,7 @@ angular.module('myApp.directives', ['myApp.filters'])
onContentLoaded(function () { onContentLoaded(function () {
var selectedDialog = $(scrollableWrap).find('.active a.im_dialog')[0]; var selectedDialog = $(scrollableWrap).find('.active a.im_dialog')[0];
if (selectedDialog) { if (selectedDialog) {
scrollToDialog(selectedDialog.parentNode); scrollToNode(scrollableWrap, selectedDialog.parentNode, dialogsWrap);
} }
}); });
}); });
@ -621,7 +621,7 @@ angular.module('myApp.directives', ['myApp.filters'])
if (nextDialogWrap) { if (nextDialogWrap) {
$(nextDialogWrap).find('a').trigger('mousedown'); $(nextDialogWrap).find('a').trigger('mousedown');
scrollToDialog(nextDialogWrap); scrollToNode(scrollableWrap, nextDialogWrap, dialogsWrap);
} }
return cancelEvent(e); return cancelEvent(e);
@ -681,29 +681,13 @@ angular.module('myApp.directives', ['myApp.filters'])
} }
if (nextDialogWrap) { if (nextDialogWrap) {
scrollToDialog(nextDialogWrap); scrollToNode(scrollableWrap, nextDialogWrap, dialogsWrap);
} }
return cancelEvent(e); return cancelEvent(e);
} }
} }
function scrollToDialog(dialogWrap) {
var elTop = dialogWrap.offsetTop - 15,
elHeight = dialogWrap.offsetHeight + 30,
scrollTop = scrollableWrap.scrollTop,
viewportHeight = scrollableWrap.clientHeight;
if (scrollTop > elTop) { // we are below the dialog to scroll
scrollableWrap.scrollTop = elTop;
$(dialogsWrap).nanoScroller({flash: true});
}
else if (scrollTop < elTop + elHeight - viewportHeight) { // we are over the dialog to scroll
scrollableWrap.scrollTop = elTop + elHeight - viewportHeight;
$(dialogsWrap).nanoScroller({flash: true});
}
}
} }
@ -1379,7 +1363,12 @@ angular.module('myApp.directives', ['myApp.filters'])
mentions: $scope.mentions, mentions: $scope.mentions,
commands: $scope.commands, commands: $scope.commands,
onMessageSubmit: onMessageSubmit, onMessageSubmit: onMessageSubmit,
onFilePaste: onFilePaste onFilePaste: onFilePaste,
onCommandSend: function (command) {
$scope.$apply(function () {
$scope.draftMessage.command = command;
});
}
}); });
var richTextarea = composer.richTextareaEl[0]; var richTextarea = composer.richTextareaEl[0];

16
app/js/lib/utils.js

@ -222,6 +222,22 @@ function setRichFocus(field, selectNode) {
} }
} }
function scrollToNode (scrollable, node, scroller) {
var elTop = node.offsetTop - 15,
elHeight = node.offsetHeight + 30,
scrollTop = scrollable.scrollTop,
viewportHeight = scrollable.clientHeight;
if (scrollTop > elTop) { // we are below the node to scroll
scrollable.scrollTop = elTop;
$(scroller).nanoScroller({flash: true});
}
else if (scrollTop < elTop + elHeight - viewportHeight) { // we are over the node to scroll
scrollable.scrollTop = elTop + elHeight - viewportHeight;
$(scroller).nanoScroller({flash: true});
}
}
function onContentLoaded (cb) { function onContentLoaded (cb) {
setZeroTimeout(cb); setZeroTimeout(cb);
} }

73
app/js/message_composer.js

@ -498,7 +498,7 @@ function MessageComposer (textarea, options) {
var self = this; var self = this;
this.autoCompleteEl.on('mousedown', function (e) { this.autoCompleteEl.on('mousedown', function (e) {
e = e.originalEvent || e; e = e.originalEvent || e;
var target = $(e.target), mention, code; var target = $(e.target), mention, code, command;
if (target[0].tagName != 'A') { if (target[0].tagName != 'A') {
target = $(target[0].parentNode); target = $(target[0].parentNode);
} }
@ -509,9 +509,13 @@ function MessageComposer (textarea, options) {
EmojiHelper.pushPopularEmoji(code); EmojiHelper.pushPopularEmoji(code);
} }
if (mention = target.attr('data-mention')) { if (mention = target.attr('data-mention')) {
if (self.onMentionSelected) { self.onMentionSelected(mention);
self.onMentionSelected(mention); }
if (command = target.attr('data-command')) {
if (self.onCommandSelected) {
self.onCommandSelected(command);
} }
self.hideSuggestions();
} }
return cancelEvent(e); return cancelEvent(e);
}); });
@ -525,6 +529,7 @@ function MessageComposer (textarea, options) {
this.mentions = options.mentions; this.mentions = options.mentions;
this.commands = options.commands; this.commands = options.commands;
this.getPeerImage = options.getPeerImage; this.getPeerImage = options.getPeerImage;
this.onCommandSend = options.onCommandSend;
} }
MessageComposer.prototype.setUpInput = function () { MessageComposer.prototype.setUpInput = function () {
@ -533,7 +538,7 @@ MessageComposer.prototype.setUpInput = function () {
} else { } else {
this.setUpPlaintext(); this.setUpPlaintext();
} }
this.autoCompleteRegEx = /(?:\s|^)(:|@|\/)([A-Za-z0-9\-\+\*@_]*)$/; this.autoCompleteRegEx = /(\s|^)(:|@|\/)([A-Za-z0-9\-\+\*@_]*)$/;
} }
MessageComposer.prototype.setUpRich = function () { MessageComposer.prototype.setUpRich = function () {
@ -610,7 +615,7 @@ MessageComposer.prototype.onKeyEvent = function (e) {
if (nextWrap) { if (nextWrap) {
$(nextWrap).find('a').addClass('composer_autocomplete_option_active'); $(nextWrap).find('a').addClass('composer_autocomplete_option_active');
if (!Config.Mobile) { if (!Config.Mobile) {
this.autoCompleteScrollerEl.nanoScroller({scrollTop: nextWrap.offsetTop}) scrollToNode(this.autoCompleteEl[0], nextWrap, this.autoCompleteScrollerEl);
} }
return cancelEvent(e); return cancelEvent(e);
} }
@ -619,7 +624,7 @@ MessageComposer.prototype.onKeyEvent = function (e) {
var childNodes = this.autoCompleteEl[0].childNodes; var childNodes = this.autoCompleteEl[0].childNodes;
var nextWrap = childNodes[next ? 0 : childNodes.length - 1]; var nextWrap = childNodes[next ? 0 : childNodes.length - 1];
if (!Config.Mobile) { if (!Config.Mobile) {
this.autoCompleteScrollerEl.nanoScroller({scrollTop: nextWrap.offsetTop}) scrollToNode(this.autoCompleteEl[0], nextWrap, this.autoCompleteScrollerEl);
} }
$(nextWrap).find('a').addClass('composer_autocomplete_option_active'); $(nextWrap).find('a').addClass('composer_autocomplete_option_active');
@ -631,17 +636,21 @@ MessageComposer.prototype.onKeyEvent = function (e) {
if (!currentSelected.length && e.keyCode == 9) { if (!currentSelected.length && e.keyCode == 9) {
currentSelected = $(this.autoCompleteEl[0].childNodes[0]).find('a'); currentSelected = $(this.autoCompleteEl[0].childNodes[0]).find('a');
} }
var code, mention; var code, mention, command;
if (code = currentSelected.attr('data-code')) { if (code = currentSelected.attr('data-code')) {
this.onEmojiSelected(code, true); this.onEmojiSelected(code, true);
EmojiHelper.pushPopularEmoji(code); EmojiHelper.pushPopularEmoji(code);
return cancelEvent(e); return cancelEvent(e);
} }
if (mention = currentSelected.attr('data-mention')) { if (mention = currentSelected.attr('data-mention')) {
if (this.onMentionSelected) { this.onMentionSelected(mention);
this.onMentionSelected(mention); return cancelEvent(e);
return cancelEvent(e); }
if (command = currentSelected.attr('data-command')) {
if (this.onCommandSelected) {
this.onCommandSelected(command, e.keyCode == 9);
} }
return cancelEvent(e);
} }
checkSubmit = true; checkSubmit = true;
} }
@ -729,9 +738,9 @@ MessageComposer.prototype.checkAutocomplete = function () {
return; return;
} }
this.previousQuery = matches[0]; this.previousQuery = matches[0];
var query = SearchIndexManager.cleanSearchText(matches[2]); var query = SearchIndexManager.cleanSearchText(matches[3]);
if (matches[1] == '@') { // mentions if (matches[2] == '@') { // mentions
if (this.mentions && this.mentions.index) { if (this.mentions && this.mentions.index) {
if (query.length) { if (query.length) {
var foundObject = SearchIndexManager.search(query, this.mentions.index); var foundObject = SearchIndexManager.search(query, this.mentions.index);
@ -755,7 +764,7 @@ MessageComposer.prototype.checkAutocomplete = function () {
this.hideSuggestions(); this.hideSuggestions();
} }
} }
else if (matches[1] == '/') { // commands else if (!matches[1] && matches[2] == '/') { // commands
if (this.commands && this.commands.index) { if (this.commands && this.commands.index) {
if (query.length) { if (query.length) {
var foundObject = SearchIndexManager.search(query, this.commands.index); var foundObject = SearchIndexManager.search(query, this.commands.index);
@ -779,7 +788,7 @@ MessageComposer.prototype.checkAutocomplete = function () {
this.hideSuggestions(); this.hideSuggestions();
} }
} }
else { // emoji else if (matches[2] == ':') { // emoji
EmojiHelper.getPopularEmoji((function (popular) { EmojiHelper.getPopularEmoji((function (popular) {
if (query.length) { if (query.length) {
var found = EmojiHelper.searchEmojis(query); var found = EmojiHelper.searchEmojis(query);
@ -1014,6 +1023,25 @@ MessageComposer.prototype.onMentionSelected = function (username) {
this.onChange(); this.onChange();
} }
MessageComposer.prototype.onCommandSelected = function (command, isTab) {
if (isTab) {
if (this.richTextareaEl) {
this.richTextareaEl.html(encodeEntities(command) + '&nbsp;');
setRichFocus(this.richTextareaEl[0]);
}
else {
var textarea = this.textareaEl[0];
textarea.value = command + ' ';
setFieldSelection(textarea);
}
} else {
this.onCommandSend(command);
}
this.hideSuggestions();
this.onChange();
}
MessageComposer.prototype.onChange = function (e) { MessageComposer.prototype.onChange = function (e) {
if (this.richTextareaEl) { if (this.richTextareaEl) {
delete this.keyupStarted; delete this.keyupStarted;
@ -1110,7 +1138,7 @@ MessageComposer.prototype.showEmojiSuggestions = function (codes) {
MessageComposer.prototype.showMentionSuggestions = function (users) { MessageComposer.prototype.showMentionSuggestions = function (users) {
var html = []; var html = [];
var user; var user;
var count = Math.min(5, users.length); var count = users.length;
var i; var i;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
@ -1128,12 +1156,12 @@ MessageComposer.prototype.showMentionSuggestions = function (users) {
MessageComposer.prototype.showCommandsSuggestions = function (commands) { MessageComposer.prototype.showCommandsSuggestions = function (commands) {
var html = []; var html = [];
var command; var command;
var count = Math.min(5, commands.length); var count = Math.min(200, commands.length);
var i; var i;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
command = commands[i]; command = commands[i];
html.push('<li><a class="composer_command_option" data-command="' + command.value + '"><span class="composer_user_photo" data-user-id="' + command.botID + '"></span><span class="composer_command_value">' + command.value + '</span><span class="composer_command_desc">' + command.description + '</span></a></li>'); html.push('<li><a class="composer_command_option" data-command="' + encodeEntities(command.value) + '"><span class="composer_user_photo" data-user-id="' + command.botID + '"></span><span class="composer_command_value">' + encodeEntities(command.value) + '</span><span class="composer_command_desc">' + encodeEntities(command.description) + '</span></a></li>');
} }
this.renderSuggestions(html); this.renderSuggestions(html);
@ -1153,13 +1181,18 @@ MessageComposer.prototype.showCommandsSuggestions = function (commands) {
MessageComposer.prototype.updatePosition = function () { MessageComposer.prototype.updatePosition = function () {
var offset = (this.richTextareaEl || this.textareaEl).offset(); var offset = (this.richTextareaEl || this.textareaEl).offset();
var height = this.autoCompleteWrapEl.outerHeight();
var width = (this.richTextareaEl || this.textareaEl).outerWidth(); var width = (this.richTextareaEl || this.textareaEl).outerWidth();
this.autoCompleteWrapEl.css({top: offset.top - height, left: offset.left, width: width - 2}); var contentHeight = this.autoCompleteEl[0].firstChild.clientHeight * this.autoCompleteEl[0].childNodes.length;
var height = Math.min(180, contentHeight);
this.autoCompleteWrapEl.css({
top: offset.top - height,
left: offset.left,
width: width - 2,
height: height
});
} }
MessageComposer.prototype.hideSuggestions = function () { MessageComposer.prototype.hideSuggestions = function () {
return;
this.autoCompleteWrapEl.hide(); this.autoCompleteWrapEl.hide();
delete this.autocompleteShown; delete this.autocompleteShown;
} }

2
app/less/app.less

@ -2424,7 +2424,7 @@ a.composer_emoji_btn {
border-radius: 0; border-radius: 0;
margin-top: -5px; margin-top: -5px;
height: 180px; margin-left: -1px;
} }
.composer_dropdown_scroller { .composer_dropdown_scroller {
} }

Loading…
Cancel
Save