diff --git a/app/assets/javascripts/discourse/components/composer-user-selector.js.es6 b/app/assets/javascripts/discourse/components/composer-user-selector.js.es6 new file mode 100644 index 00000000000..d977d6e3093 --- /dev/null +++ b/app/assets/javascripts/discourse/components/composer-user-selector.js.es6 @@ -0,0 +1,74 @@ +import { default as computed, observes } from 'ember-addons/ember-computed-decorators'; + +export default Ember.Component.extend({ + showSelector: true, + shouldHide: false, + defaultUsernameCount: 0, + + @observes('usernames') + _checkWidth() { + let width = 0; + const $acWrap = this.$().find('.ac-wrap'); + const limit = $acWrap.width(); + this.set('defaultUsernameCount', 0); + + $acWrap.find('.item').toArray().forEach(item => { + width += $(item).outerWidth(true); + const result = (width < limit); + + if (result) this.incrementProperty('defaultUsernameCount'); + return result; + }); + + if (width >= limit) { + this.set('shouldHide', true); + } else { + this.set('shouldHide', false); + }; + }, + + @observes('shouldHide') + _setFocus() { + const selector = '#reply-control #reply-title, #reply-control .d-editor-input'; + + if (this.get('shouldHide')) { + $(selector).on('focus.composer-user-selector', () => { + this.set('showSelector', false); + this.appEvents.trigger("composer:resize"); + }); + } else { + $(selector).off('focus.composer-user-selector'); + } + }, + + @computed('usernames') + splitUsernames(usernames) { + return usernames.split(','); + }, + + @computed('splitUsernames', 'defaultUsernameCount') + limitedUsernames(splitUsernames, count) { + return splitUsernames.slice(0, count).join(", "); + }, + + @computed('splitUsernames', 'defaultUsernameCount') + hiddenUsersCount(splitUsernames, count) { + return `${splitUsernames.length - count} ${I18n.t('more')}`; + }, + + actions: { + toggleSelector() { + this.set("showSelector", true); + + Ember.run.schedule('afterRender', () => { + this.$().find('input').focus(); + }); + }, + + triggerResize() { + this.appEvents.trigger("composer:resize"); + const $this = this.$().find('.ac-wrap'); + if ($this.height() >= 150) $this.scrollTop($this.height()); + }, + } +}); diff --git a/app/assets/javascripts/discourse/components/user-selector.js.es6 b/app/assets/javascripts/discourse/components/user-selector.js.es6 index ab695e8b2b0..862f0fae491 100644 --- a/app/assets/javascripts/discourse/components/user-selector.js.es6 +++ b/app/assets/javascripts/discourse/components/user-selector.js.es6 @@ -1,9 +1,11 @@ +import { observes } from 'ember-addons/ember-computed-decorators'; import TextField from 'discourse/components/text-field'; import userSearch from 'discourse/lib/user-search'; export default TextField.extend({ - _initializeAutocomplete: function() { + didInsertElement() { + this._super(); var self = this, selected = [], groups = [], @@ -63,6 +65,7 @@ export default TextField.extend({ self.set('hasGroups', hasGroups); selected = items; + if (self.get('onChangeCallback')) self.sendAction('onChangeCallback'); }, reverseTransform: function(i) { @@ -70,19 +73,21 @@ export default TextField.extend({ } }); - }.on('didInsertElement'), + }, - _removeAutocomplete: function() { + willDestroyElement() { + this._super(); this.$().autocomplete('destroy'); - }.on('willDestroyElement'), + }, // THIS IS A HUGE HACK TO SUPPORT CLEARING THE INPUT + @observes('usernames') _clearInput: function() { if (arguments.length > 1) { if (Em.isEmpty(this.get("usernames"))) { this.$().parent().find("a").click(); } } - }.observes("usernames") + } }); diff --git a/app/assets/javascripts/discourse/lib/autocomplete.js.es6 b/app/assets/javascripts/discourse/lib/autocomplete.js.es6 index a142947da65..a2edb6b886b 100644 --- a/app/assets/javascripts/discourse/lib/autocomplete.js.es6 +++ b/app/assets/javascripts/discourse/lib/autocomplete.js.es6 @@ -101,13 +101,16 @@ export default function(options) { transformed = _.isArray(transformedItem) ? transformedItem : [transformedItem || item]; var divs = transformed.map(function(itm) { - var d = $("
"); - var prev = me.parent().find('.item:last'); + let d = $(``); + const $parent = me.parent(); + const prev = $parent.find('.item:last'); + if (prev.length === 0) { me.parent().prepend(d); } else { prev.after(d); } + inputSelectedItems.push(itm); return d[0]; }); diff --git a/app/assets/javascripts/discourse/templates/components/composer-user-selector.hbs b/app/assets/javascripts/discourse/templates/components/composer-user-selector.hbs new file mode 100644 index 00000000000..71b5e8176d2 --- /dev/null +++ b/app/assets/javascripts/discourse/templates/components/composer-user-selector.hbs @@ -0,0 +1,17 @@ +{{#if showSelector}} + {{user-selector topicId=topicId + excludeCurrentUser='true' + onChangeCallback='triggerResize' + id="private-message-users" + includeMentionableGroups='true' + class="span8" + placeholderKey="composer.users_placeholder" + tabindex="1" + usernames=usernames + hasGroups=hasGroups}} +{{else}} +