FIX: improves emoji-picker handling of its different states

- closing modal with escape
- using modal less frequently
- closing the picker by clicking anywhere
This commit is contained in:
Joffrey JAFFEUX 2017-07-20 16:08:16 +02:00
parent bf6c3b7017
commit a5a3651cf3
3 changed files with 113 additions and 34 deletions

View File

@ -22,16 +22,21 @@ export default Ember.Component.extend({
this._super(); this._super();
this._unbindEvents(); this._unbindEvents();
this.appEvents.off('emoji-picker:close');
},
didDestroyElement() {
this._super();
$picker = null; $picker = null;
$modal = null;
}, },
didInsertElement() { didInsertElement() {
this._super(); this._super();
this.appEvents.on('emoji-picker:close', () => this.set("active", false));
$picker = this.$(".emoji-picker"); $picker = this.$(".emoji-picker");
$modal = this.$(".emoji-picker-modal");
if (!keyValueStore.getObject(EMOJI_USAGE)) { if (!keyValueStore.getObject(EMOJI_USAGE)) {
keyValueStore.setObject({ key: EMOJI_USAGE, value: [] }); keyValueStore.setObject({ key: EMOJI_USAGE, value: [] });
@ -97,7 +102,7 @@ export default Ember.Component.extend({
.css({width: "", left: "", bottom: "", display: "none"}) .css({width: "", left: "", bottom: "", display: "none"})
.empty(); .empty();
$modal.removeClass("fadeIn"); this.$().find(".emoji-picker-modal").remove();
this._unbindEvents(); this._unbindEvents();
}, },
@ -105,6 +110,7 @@ export default Ember.Component.extend({
show() { show() {
const template = pickerTemplate({ customEmojis }); const template = pickerTemplate({ customEmojis });
$picker.html(template); $picker.html(template);
this.$().append("<div class='emoji-picker-modal'></div>");
$filter = $picker.find(".filter"); $filter = $picker.find(".filter");
$results = $picker.find(".results"); $results = $picker.find(".results");
@ -138,13 +144,22 @@ export default Ember.Component.extend({
}, },
_bindModalClick() { _bindModalClick() {
$modal.on("click", () => this.set("active", false)); this.$(".emoji-picker-modal")
.on("click", () => this.set("active", false));
Ember.$(document).on("click", (event) => {
if(event.target.className.indexOf("grippie") === -1) {
this.set("active", false);
return false;
}
});
}, },
_unbindEvents() { _unbindEvents() {
this.$(window).off("resize"); this.$(window).off("resize");
$modal.off("click"); this.$(".emoji-picker-modal").off("click");
Ember.$("#reply-control").off("div-resizing"); Ember.$("#reply-control").off("div-resizing");
Ember.$(document).off("click");
}, },
_filterEmojisList() { _filterEmojisList() {
@ -215,11 +230,11 @@ export default Ember.Component.extend({
_bindResizing() { _bindResizing() {
this.$(window).on("resize", () => { this.$(window).on("resize", () => {
Ember.run.throttle(this, this._positionPicker, 50); Ember.run.throttle(this, this._positionPicker, 16);
}); });
Ember.$("#reply-control").on("div-resizing", () => { Ember.$("#reply-control").on("div-resizing", () => {
Ember.run.throttle(this, this._positionPicker, 50); Ember.run.throttle(this, this._positionPicker, 16);
}); });
}, },
@ -240,7 +255,7 @@ export default Ember.Component.extend({
this._trackEmojiUsage(code); this._trackEmojiUsage(code);
this.sendAction("emojiSelected", code); this.sendAction("emojiSelected", code);
if(this._isSmallViewport()) { if(this.$(".emoji-picker-modal").hasClass("fadeIn")) {
this.set("active", false); this.set("active", false);
} }
@ -273,6 +288,11 @@ export default Ember.Component.extend({
}, },
_checkVisibleSection() { _checkVisibleSection() {
// make sure we stop loading if picker has been removed
if(!$picker) {
return;
}
const $sections = $list.find(".section"); const $sections = $list.find(".section");
const sections = []; const sections = [];
let cumulatedHeight = 0; let cumulatedHeight = 0;
@ -336,43 +356,98 @@ export default Ember.Component.extend({
.addClass("selected"); .addClass("selected");
}, },
_isSmallViewport() { _isReplyControlExpanded() {
return this.site.isMobileDevice || this.$(window).width() <= 1024 || this.$(window).height() <= 768; const verticalSpace = this.$(window).height() -
Ember.$(".d-header").height() -
Ember.$("#reply-control").height();
return verticalSpace < $picker.height() - 48;
}, },
_positionPicker(){ _positionPicker(){
if(!this.get("active")) { return; } if(!this.get("active")) { return; }
let isLargePreview = this.$(window).height() - let windowWidth = this.$(window).width();
Ember.$(".d-header").height() -
Ember.$("#reply-control").height() <
$picker.height() + 16;
if(this._isSmallViewport()) { const desktopModalePositioning = options => {
$modal.addClass("fadeIn"); const attributes = {
width: windowWidth < 450 ? windowWidth - 12 : 400,
$picker.css({ marginLeft: -($picker.width() / 2) + 12,
width: this.site.isMobileDevice ? this.$(window).width() - 12 : 340,
marginLeft: this.site.isMobileDevice ? 5 : -170,
marginTop: -130, marginTop: -130,
left: this.site.isMobileDevice ? 0 : "50%", left: "50%",
bottom: "",
top: "50%", top: "50%",
display: "flex" display: "flex"
}); };
Object.assign(attributes, options);
this.$(".emoji-picker-modal").addClass("fadeIn");
$picker.css(attributes);
};
const mobilePositioning = options => {
const attributes = {
width: windowWidth - 12,
marginLeft: 5,
marginTop: -130,
left: 0,
bottom: "",
top: "50%",
display: "flex"
};
Object.assign(attributes, options);
this.$(".emoji-picker-modal").addClass("fadeIn");
$picker.css(attributes);
};
const desktopPositioning = options => {
const attributes = {
width: windowWidth < 450 ? windowWidth - 12 : 400,
marginLeft: "",
marginTop: "",
right: "",
left: "",
bottom: 32,
top: "",
display:
"flex"
};
Object.assign(attributes, options);
this.$(".emoji-picker-modal").removeClass("fadeIn");
$picker.css(attributes);
};
if(this.site.isMobileDevice) {
mobilePositioning();
} else { } else {
$modal.removeClass("fadeIn"); if(this._isReplyControlExpanded()) {
let $editorWrapper = Ember.$(".d-editor-preview-wrapper");
let cssAttributes = { width: 400, marginLeft: "", marginTop: "", left: "", top: "", display: "flex"}; if(($editorWrapper.is(":visible") && $editorWrapper.width() < 400) || windowWidth < 450) {
desktopModalePositioning();
if(isLargePreview) { } else {
cssAttributes.left = (Ember.$("#reply-control").width() - Ember.$(".d-editor").width() ) / 2 + Ember.$(".d-editor-preview-wrapper").position().left; if($editorWrapper.is(":visible")) {
cssAttributes.bottom = 32; let previewOffset = Ember.$(".d-editor-preview-wrapper").offset();
let replyControlOffset = Ember.$("#reply-control").offset();
let left = previewOffset.left - replyControlOffset.left;
desktopPositioning({left});
} else {
desktopPositioning({
right: (Ember.$("#reply-control").width() - Ember.$(".d-editor-container").width()) / 2
});
}
}
} else { } else {
cssAttributes.left = (Ember.$("#reply-control").width() - Ember.$(".d-editor").width() ) / 2 + Ember.$(".d-editor").position().left; if(windowWidth < 450) {
cssAttributes.bottom = Ember.$("#reply-control").height() - 48; desktopModalePositioning();
} else {
let previewInputOffset = Ember.$(".d-editor-input").offset();
let replyControlOffset = Ember.$("#reply-control").offset();
let left = previewInputOffset.left - replyControlOffset.left;
desktopPositioning({left, bottom: Ember.$("#reply-control").height() - 48});
}
} }
$picker.css(cssAttributes);
} }
const infoMaxWidth = $picker.width() - const infoMaxWidth = $picker.width() -

View File

@ -330,6 +330,11 @@ export default Ember.Controller.extend({
}, },
hitEsc() { hitEsc() {
if (Ember.$(".emoji-picker-modal").length === 1) {
this.appEvents.trigger('emoji-picker:close');
return;
}
if ((this.get('messageCount') || 0) > 0) { if ((this.get('messageCount') || 0) > 0) {
this.appEvents.trigger('composer-messages:close'); this.appEvents.trigger('composer-messages:close');
return; return;

View File

@ -1,2 +1 @@
<div class='emoji-picker'></div> <div class='emoji-picker'></div>
<div class='emoji-picker-modal'></div>