FIX: emoji-picker improvements

* fix a performance issue on mobile when modifying filtering query, thanks to David Taylor and Jorge Manrubia for the initial finding and solution
* minor refactoring
* better positioning of the picker on mobile
This commit is contained in:
Joffrey JAFFEUX 2018-01-29 11:05:35 +01:00 committed by GitHub
parent 8252f1e4ff
commit 52fbf9d3ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 16 deletions

View File

@ -4,6 +4,7 @@ import { emojiUrlFor } from "discourse/lib/text";
import KeyValueStore from "discourse/lib/key-value-store"; import KeyValueStore from "discourse/lib/key-value-store";
import { emojis } from "pretty-text/emoji/data"; import { emojis } from "pretty-text/emoji/data";
import { extendedEmojiList, isSkinTonableEmoji } from "pretty-text/emoji"; import { extendedEmojiList, isSkinTonableEmoji } from "pretty-text/emoji";
const { run } = Ember;
const keyValueStore = new KeyValueStore("discourse_emojis_"); const keyValueStore = new KeyValueStore("discourse_emojis_");
const EMOJI_USAGE = "emojiUsage"; const EMOJI_USAGE = "emojiUsage";
@ -44,7 +45,7 @@ export default Ember.Component.extend({
this.set("selectedDiversity", keyValueStore.getObject(EMOJI_SELECTED_DIVERSITY) || 1); this.set("selectedDiversity", keyValueStore.getObject(EMOJI_SELECTED_DIVERSITY) || 1);
this.set("recentEmojis", keyValueStore.getObject(EMOJI_USAGE) || []); this.set("recentEmojis", keyValueStore.getObject(EMOJI_USAGE) || []);
Ember.run.scheduleOnce("afterRender", this, function() { run.scheduleOnce("afterRender", this, function() {
this._bindEvents(); this._bindEvents();
this._sectionLoadingCheck(); this._sectionLoadingCheck();
this._loadCategoriesEmojis(); this._loadCategoriesEmojis();
@ -83,13 +84,14 @@ export default Ember.Component.extend({
@on("didUpdateAttrs") @on("didUpdateAttrs")
_setState() { _setState() {
this.get("active") === true ? this.show() : this.close(); this.get("active") ? this.show() : this.close();
}, },
@observes("filter") @observes("filter")
filterChanged() { filterChanged() {
this.$filter.find(".clear-filter").toggle(!_.isEmpty(this.get("filter"))); this.$filter.find(".clear-filter").toggle(!_.isEmpty(this.get("filter")));
Ember.run.debounce(this, this._filterEmojisList, 250); const filterDelay = this.site.isMobileDevice ? 400 : 250;
run.debounce(this, this._filterEmojisList, filterDelay);
}, },
@observes("selectedDiversity") @observes("selectedDiversity")
@ -148,7 +150,7 @@ export default Ember.Component.extend({
_sectionLoadingCheck() { _sectionLoadingCheck() {
this._checkTimeout = setTimeout(() => { this._sectionLoadingCheck(); }, 500); this._checkTimeout = setTimeout(() => { this._sectionLoadingCheck(); }, 500);
Ember.run.throttle(this, this._checkVisibleSection, 100); run.throttle(this, this._checkVisibleSection, 100);
}, },
_loadCategoriesEmojis() { _loadCategoriesEmojis() {
@ -200,7 +202,7 @@ export default Ember.Component.extend({
if (this.get("filter") === "") { if (this.get("filter") === "") {
this.$filter.find("input[name='filter']").val(""); this.$filter.find("input[name='filter']").val("");
this.$results.empty().hide(); this.$results.empty().hide();
this.$list.show(); this.$list.css("visibility", "visible");
} else { } else {
const lowerCaseFilter = this.get("filter").toLowerCase(); const lowerCaseFilter = this.get("filter").toLowerCase();
const filterableEmojis = emojis.concat(_.keys(extendedEmojiList())); const filterableEmojis = emojis.concat(_.keys(extendedEmojiList()));
@ -217,7 +219,7 @@ export default Ember.Component.extend({
).show(); ).show();
this._bindHover(this.$results); this._bindHover(this.$results);
this._bindEmojiClick(this.$results); this._bindEmojiClick(this.$results);
this.$list.hide(); this.$list.css("visibility", "hidden");
} }
}, },
@ -239,7 +241,7 @@ export default Ember.Component.extend({
this.$picker.find(".category-icon").on("click", "button.emoji", (event) => { this.$picker.find(".category-icon").on("click", "button.emoji", (event) => {
this.set("filter", ""); this.set("filter", "");
this.$results.empty(); this.$results.empty();
this.$list.show(); this.$list.css("visibility", "visible");
const section = $(event.currentTarget).data("section"); const section = $(event.currentTarget).data("section");
const $section = this.$list.find(`.section[data-section="${section}"]`); const $section = this.$list.find(`.section[data-section="${section}"]`);
@ -264,11 +266,11 @@ export default Ember.Component.extend({
_bindResizing() { _bindResizing() {
this.$(window).on("resize", () => { this.$(window).on("resize", () => {
Ember.run.throttle(this, this._positionPicker, 16); run.throttle(this, this._positionPicker, 16);
}); });
$("#reply-control").on("div-resizing", () => { $("#reply-control").on("div-resizing", () => {
Ember.run.throttle(this, this._positionPicker, 16); run.throttle(this, this._positionPicker, 16);
}); });
}, },
@ -320,7 +322,7 @@ export default Ember.Component.extend({
_bindSectionsScroll() { _bindSectionsScroll() {
this.$list.on("scroll", () => { this.$list.on("scroll", () => {
this.scrollPosition = this.$list.scrollTop(); this.scrollPosition = this.$list.scrollTop();
Ember.run.throttle(this, this._checkVisibleSection, 150); run.throttle(this, this._checkVisibleSection, 150);
}); });
}, },
@ -415,12 +417,12 @@ export default Ember.Component.extend({
const mobilePositioning = options => { const mobilePositioning = options => {
let attributes = { let attributes = {
width: windowWidth - 12, width: windowWidth,
marginLeft: 5, marginLeft: 0,
marginTop: -130, marginTop: "auto",
left: 0, left: 0,
bottom: "", bottom: "",
top: "50%", top: 0,
display: "flex" display: "flex"
}; };
@ -445,7 +447,7 @@ export default Ember.Component.extend({
this.$picker.css(_.merge(attributes, options)); this.$picker.css(_.merge(attributes, options));
}; };
if(Ember.testing || this.get("automaticPositioning") === false) { if(Ember.testing || !this.get("automaticPositioning")) {
desktopPositioning(); desktopPositioning();
return; return;
} }
@ -510,7 +512,7 @@ export default Ember.Component.extend({
this.$list.scrollTop(yPosition); this.$list.scrollTop(yPosition);
// if we dont actually scroll we need to force it // if we dont actually scroll we need to force it
if(yPosition === 0) { if (yPosition === 0) {
this.$list.scroll(); this.$list.scroll();
} }
}, },

View File

@ -0,0 +1,6 @@
.emoji-picker {
box-shadow: none;
height: 250px;
border-radius: 0;
border: none;
}