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. 67
      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']) @@ -1761,6 +1761,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.$watch('draftMessage.text', onMessageChange);
$scope.$watch('draftMessage.files', onFilesSelected);
$scope.$watch('draftMessage.sticker', onStickerSelected);
$scope.$watch('draftMessage.command', onCommandSelected);
function sendMessage (e) {
$scope.$broadcast('ui_message_before_send');
@ -1866,7 +1867,6 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -1866,7 +1867,6 @@ angular.module('myApp.controllers', ['myApp.i18n'])
})
});
console.log(commandsList, commandsIndex);
safeReplaceObject($scope.commands, {
list: commandsList,
index: commandsIndex
@ -1970,6 +1970,17 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -1970,6 +1970,17 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}
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) {

29
app/js/directives.js

@ -563,7 +563,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -563,7 +563,7 @@ angular.module('myApp.directives', ['myApp.filters'])
onContentLoaded(function () {
var selectedDialog = $(scrollableWrap).find('.active a.im_dialog')[0];
if (selectedDialog) {
scrollToDialog(selectedDialog.parentNode);
scrollToNode(scrollableWrap, selectedDialog.parentNode, dialogsWrap);
}
});
});
@ -621,7 +621,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -621,7 +621,7 @@ angular.module('myApp.directives', ['myApp.filters'])
if (nextDialogWrap) {
$(nextDialogWrap).find('a').trigger('mousedown');
scrollToDialog(nextDialogWrap);
scrollToNode(scrollableWrap, nextDialogWrap, dialogsWrap);
}
return cancelEvent(e);
@ -681,29 +681,13 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -681,29 +681,13 @@ angular.module('myApp.directives', ['myApp.filters'])
}
if (nextDialogWrap) {
scrollToDialog(nextDialogWrap);
scrollToNode(scrollableWrap, nextDialogWrap, dialogsWrap);
}
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']) @@ -1379,7 +1363,12 @@ angular.module('myApp.directives', ['myApp.filters'])
mentions: $scope.mentions,
commands: $scope.commands,
onMessageSubmit: onMessageSubmit,
onFilePaste: onFilePaste
onFilePaste: onFilePaste,
onCommandSend: function (command) {
$scope.$apply(function () {
$scope.draftMessage.command = command;
});
}
});
var richTextarea = composer.richTextareaEl[0];

16
app/js/lib/utils.js

@ -222,6 +222,22 @@ function setRichFocus(field, selectNode) { @@ -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) {
setZeroTimeout(cb);
}

67
app/js/message_composer.js

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

2
app/less/app.less

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

Loading…
Cancel
Save