зеркало из https://github.com/nextcloud/spreed.git
Add basic UI for autocompletion
CSS styles were directly copied from "apps/comments/css/autocomplete.scss". JavaScript code in the chat view was slightly simplified from "apps/comments/js/commentstabview.js". Currently mentions are not formatted when a message is being composed; "@" followed by the user name is added to the message so it can be directly sent without further processing. Formatted mentions will be introduced in another commit. Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Родитель
790bddd06d
Коммит
85cd8181e5
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* based upon apps/comments/js/vendor/At.js/dist/css/jquery.atwho.css,
|
||||
* only changed colors and font-weight
|
||||
*/
|
||||
|
||||
.atwho-view {
|
||||
position:absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: none;
|
||||
margin-top: 18px;
|
||||
background: $color-main-background;
|
||||
color: $color-main-text;
|
||||
border: 1px solid $color-border;
|
||||
border-radius: $border-radius;
|
||||
box-shadow: 0 0 5px $color-box-shadow;
|
||||
min-width: 120px;
|
||||
z-index: 11110 !important;
|
||||
}
|
||||
|
||||
.atwho-view .atwho-header {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
cursor: pointer;
|
||||
border-bottom: solid 1px $color-border;
|
||||
color: $color-main-text;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.atwho-view .atwho-header .small {
|
||||
color: $color-main-text;
|
||||
float: right;
|
||||
padding-top: 2px;
|
||||
margin-right: -5px;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.atwho-view .atwho-header:hover {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.atwho-view .cur {
|
||||
background: $color-primary;
|
||||
color: $color-primary-text;
|
||||
}
|
||||
.atwho-view .cur small {
|
||||
color: $color-primary-text;
|
||||
}
|
||||
.atwho-view strong {
|
||||
color: $color-main-text;
|
||||
font-weight: normal;
|
||||
}
|
||||
.atwho-view .cur strong {
|
||||
color: $color-primary-text;
|
||||
font-weight: normal;
|
||||
}
|
||||
.atwho-view ul {
|
||||
/* width: 100px; */
|
||||
list-style:none;
|
||||
padding:0;
|
||||
margin:auto;
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.atwho-view ul li {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
border-bottom: 1px solid $color-border;
|
||||
cursor: pointer;
|
||||
}
|
||||
.atwho-view small {
|
||||
font-size: smaller;
|
||||
color: $color-main-text;
|
||||
font-weight: normal;
|
||||
}
|
|
@ -95,6 +95,7 @@
|
|||
width: 32px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#commentsTabView .comment .message .avatar,
|
||||
|
@ -151,6 +152,9 @@
|
|||
.atwho-view-ul * .avatar-name-wrapper,
|
||||
#commentsTabView .comment .authorRow {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#commentsTabView .comment .authorRow .avatar:not(.currentUser),
|
||||
|
@ -159,6 +163,12 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.atwho-view-ul .avatar-name-wrapper,
|
||||
.atwho-view-ul .avatar-name-wrapper .avatar,
|
||||
.atwho-view-ul .avatar-name-wrapper .avatar img {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.atwho-view-ul * .avatar-name-wrapper {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
|
|
@ -96,6 +96,67 @@
|
|||
inputPlaceholder: t('spreed', 'Name'),
|
||||
buttonTitle: t('spreed', 'Rename')
|
||||
});
|
||||
|
||||
_.bindAll(this, '_onAutoComplete');
|
||||
},
|
||||
|
||||
_initAutoComplete: function($target) {
|
||||
var s = this;
|
||||
var limit = 20;
|
||||
$target.atwho({
|
||||
at: '@',
|
||||
limit: limit,
|
||||
callbacks: {
|
||||
remoteFilter: s._onAutoComplete,
|
||||
highlighter: function (li) {
|
||||
// misuse the highlighter callback to instead of
|
||||
// highlighting loads the avatars.
|
||||
var $li = $(li);
|
||||
$li.find('.avatar').avatar(undefined, 32);
|
||||
return $li;
|
||||
},
|
||||
sorter: function (q, items) { return items; }
|
||||
},
|
||||
displayTpl: '<li>'
|
||||
+ '<span class="avatar-name-wrapper">'
|
||||
+ '<div class="avatar" '
|
||||
+ 'data-username="${id}"' // for avatars
|
||||
+ ' data-user="${id}"' // for contactsmenu
|
||||
+ ' data-user-display-name="${label}"></div>'
|
||||
+ ' <strong>${label}</strong>'
|
||||
+ '</span></li>',
|
||||
insertTpl: ''
|
||||
+ '@${id}',
|
||||
searchKey: "label"
|
||||
});
|
||||
},
|
||||
|
||||
_onAutoComplete: function(query, callback) {
|
||||
var self = this;
|
||||
|
||||
if(_.isEmpty(query)) {
|
||||
return;
|
||||
}
|
||||
if(!_.isUndefined(this._autoCompleteRequestTimer)) {
|
||||
clearTimeout(this._autoCompleteRequestTimer);
|
||||
}
|
||||
this._autoCompleteRequestTimer = _.delay(function() {
|
||||
if(!_.isUndefined(this._autoCompleteRequestCall)) {
|
||||
this._autoCompleteRequestCall.abort();
|
||||
}
|
||||
this._autoCompleteRequestCall = $.ajax({
|
||||
url: OC.linkToOCS('apps/spreed/api/v1/chat', 2) + self.collection.token + '/autocomplete',
|
||||
data: {
|
||||
search: query
|
||||
},
|
||||
beforeSend: function (request) {
|
||||
request.setRequestHeader('Accept', 'application/json');
|
||||
},
|
||||
success: function (result) {
|
||||
callback(result.ocs.data);
|
||||
}
|
||||
});
|
||||
}.bind(this), 400);
|
||||
},
|
||||
|
||||
template: Handlebars.compile(TEMPLATE),
|
||||
|
@ -166,6 +227,8 @@
|
|||
}
|
||||
});
|
||||
|
||||
this._initAutoComplete($message);
|
||||
|
||||
autosize(this.$el.find('.newCommentRow .message'));
|
||||
},
|
||||
|
||||
|
@ -398,8 +461,11 @@
|
|||
$field.data('submitButtonEl', $submitButton);
|
||||
}
|
||||
|
||||
// Submits form with Enter, but Shift+Enter is a new line
|
||||
if (ev.keyCode === 13 && !ev.shiftKey) {
|
||||
// Submits form with Enter, but Shift+Enter is a new line. If the
|
||||
// autocomplete popover is being shown Enter does not submit the
|
||||
// form either; it will be handled by At.js which will add the
|
||||
// currently selected item to the message.
|
||||
if (ev.keyCode === 13 && !ev.shiftKey && !$field.atwho('isSelecting')) {
|
||||
$submitButton.click();
|
||||
ev.preventDefault();
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ vendor_style('select2/select2');
|
|||
|
||||
style('spreed', 'style');
|
||||
style('spreed', 'comments');
|
||||
style('spreed', 'autocomplete');
|
||||
script(
|
||||
'spreed',
|
||||
[
|
||||
|
@ -14,6 +15,8 @@ script(
|
|||
'vendor/backbone.radio/build/backbone.radio.min',
|
||||
'vendor/backbone.marionette/lib/backbone.marionette.min',
|
||||
'vendor/jshashes/hashes.min',
|
||||
'vendor/Caret.js/dist/jquery.caret.min',
|
||||
'vendor/At.js/dist/js/jquery.atwho.min',
|
||||
'models/chatmessage',
|
||||
'models/chatmessagecollection',
|
||||
'models/localstoragemodel',
|
||||
|
|
|
@ -7,6 +7,7 @@ vendor_style('select2/select2');
|
|||
|
||||
style('spreed', 'style');
|
||||
style('spreed', 'comments');
|
||||
style('spreed', 'autocomplete');
|
||||
script(
|
||||
'spreed',
|
||||
[
|
||||
|
@ -14,6 +15,8 @@ script(
|
|||
'vendor/backbone.radio/build/backbone.radio.min',
|
||||
'vendor/backbone.marionette/lib/backbone.marionette.min',
|
||||
'vendor/jshashes/hashes.min',
|
||||
'vendor/Caret.js/dist/jquery.caret.min',
|
||||
'vendor/At.js/dist/js/jquery.atwho.min',
|
||||
'models/chatmessage',
|
||||
'models/chatmessagecollection',
|
||||
'models/room',
|
||||
|
|
Загрузка…
Ссылка в новой задаче