mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 17:46:05 -05:00
Merge pull request #4295 from tgxworld/ux_collapse_users_on_om
UX: Collapse users when composing a private message.
This commit is contained in:
commit
717d606430
8 changed files with 135 additions and 14 deletions
|
@ -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());
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,9 +1,11 @@
|
||||||
|
import { observes } from 'ember-addons/ember-computed-decorators';
|
||||||
import TextField from 'discourse/components/text-field';
|
import TextField from 'discourse/components/text-field';
|
||||||
import userSearch from 'discourse/lib/user-search';
|
import userSearch from 'discourse/lib/user-search';
|
||||||
|
|
||||||
export default TextField.extend({
|
export default TextField.extend({
|
||||||
|
|
||||||
_initializeAutocomplete: function() {
|
didInsertElement() {
|
||||||
|
this._super();
|
||||||
var self = this,
|
var self = this,
|
||||||
selected = [],
|
selected = [],
|
||||||
groups = [],
|
groups = [],
|
||||||
|
@ -63,6 +65,7 @@ export default TextField.extend({
|
||||||
self.set('hasGroups', hasGroups);
|
self.set('hasGroups', hasGroups);
|
||||||
|
|
||||||
selected = items;
|
selected = items;
|
||||||
|
if (self.get('onChangeCallback')) self.sendAction('onChangeCallback');
|
||||||
},
|
},
|
||||||
|
|
||||||
reverseTransform: function(i) {
|
reverseTransform: function(i) {
|
||||||
|
@ -70,19 +73,21 @@ export default TextField.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}.on('didInsertElement'),
|
},
|
||||||
|
|
||||||
_removeAutocomplete: function() {
|
willDestroyElement() {
|
||||||
|
this._super();
|
||||||
this.$().autocomplete('destroy');
|
this.$().autocomplete('destroy');
|
||||||
}.on('willDestroyElement'),
|
},
|
||||||
|
|
||||||
// THIS IS A HUGE HACK TO SUPPORT CLEARING THE INPUT
|
// THIS IS A HUGE HACK TO SUPPORT CLEARING THE INPUT
|
||||||
|
@observes('usernames')
|
||||||
_clearInput: function() {
|
_clearInput: function() {
|
||||||
if (arguments.length > 1) {
|
if (arguments.length > 1) {
|
||||||
if (Em.isEmpty(this.get("usernames"))) {
|
if (Em.isEmpty(this.get("usernames"))) {
|
||||||
this.$().parent().find("a").click();
|
this.$().parent().find("a").click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.observes("usernames")
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -101,13 +101,16 @@ export default function(options) {
|
||||||
transformed = _.isArray(transformedItem) ? transformedItem : [transformedItem || item];
|
transformed = _.isArray(transformedItem) ? transformedItem : [transformedItem || item];
|
||||||
|
|
||||||
var divs = transformed.map(function(itm) {
|
var divs = transformed.map(function(itm) {
|
||||||
var d = $("<div class='item'><span>" + itm + "<a class='remove' href><i class='fa fa-times'></i></a></span></div>");
|
let d = $(`<div class='item'><span>${itm}<a class='remove' href><i class='fa fa-times'></i></a></span></div>`);
|
||||||
var prev = me.parent().find('.item:last');
|
const $parent = me.parent();
|
||||||
|
const prev = $parent.find('.item:last');
|
||||||
|
|
||||||
if (prev.length === 0) {
|
if (prev.length === 0) {
|
||||||
me.parent().prepend(d);
|
me.parent().prepend(d);
|
||||||
} else {
|
} else {
|
||||||
prev.after(d);
|
prev.after(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
inputSelectedItems.push(itm);
|
inputSelectedItems.push(itm);
|
||||||
return d[0];
|
return d[0];
|
||||||
});
|
});
|
||||||
|
|
|
@ -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}}
|
||||||
|
<div class='ac-wrap composer-user-selector-limited' {{action "toggleSelector"}}>
|
||||||
|
<span>{{limitedUsernames}}</span>
|
||||||
|
<span class='btn-small btn-primary'>{{hiddenUsersCount}}</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
|
@ -48,13 +48,7 @@
|
||||||
{{#if model.canEditTitle}}
|
{{#if model.canEditTitle}}
|
||||||
<div class='form-element clearfix'>
|
<div class='form-element clearfix'>
|
||||||
{{#if model.creatingPrivateMessage}}
|
{{#if model.creatingPrivateMessage}}
|
||||||
{{user-selector topicId=topicModel.id
|
{{composer-user-selector topicId=topicModel.id
|
||||||
excludeCurrentUser="true"
|
|
||||||
id="private-message-users"
|
|
||||||
includeMentionableGroups="true"
|
|
||||||
class="span8"
|
|
||||||
placeholderKey="composer.users_placeholder"
|
|
||||||
tabindex="1"
|
|
||||||
usernames=model.targetUsernames
|
usernames=model.targetUsernames
|
||||||
hasGroups=model.hasTargetGroups
|
hasGroups=model.hasTargetGroups
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -103,6 +103,13 @@ const ComposerView = Ember.View.extend({
|
||||||
triggerOpen();
|
triggerOpen();
|
||||||
});
|
});
|
||||||
positioningWorkaround(this.$());
|
positioningWorkaround(this.$());
|
||||||
|
|
||||||
|
this.appEvents.on('composer:resize', this, this.resize);
|
||||||
|
},
|
||||||
|
|
||||||
|
willDestroyElement() {
|
||||||
|
this._super();
|
||||||
|
this.appEvents.off('composer:resize', this, this.resize);
|
||||||
},
|
},
|
||||||
|
|
||||||
click() {
|
click() {
|
||||||
|
|
|
@ -97,6 +97,8 @@ div.ac-wrap div.item a.remove, .remove-link {
|
||||||
}
|
}
|
||||||
|
|
||||||
div.ac-wrap {
|
div.ac-wrap {
|
||||||
|
overflow: auto;
|
||||||
|
max-height: 150px;
|
||||||
background-color: $secondary;
|
background-color: $secondary;
|
||||||
border: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
|
border: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
|
||||||
padding: 5px 4px 1px 4px;
|
padding: 5px 4px 1px 4px;
|
||||||
|
@ -110,6 +112,15 @@ div.ac-wrap {
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ac-collapsed-button {
|
||||||
|
float: left;
|
||||||
|
border-radius: 20px;
|
||||||
|
position: relative;
|
||||||
|
top: -2px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
input[type="text"] {
|
input[type="text"] {
|
||||||
float: left;
|
float: left;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
div.ac-wrap.composer-user-selector-limited {
|
||||||
|
width: 400px;
|
||||||
|
|
||||||
|
.btn-small {
|
||||||
|
border-radius: 10px;
|
||||||
|
position: relative;
|
||||||
|
top: -2px;
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue