FIX: allows custom groups updates to be reflected without recompilation (#9421)

This commit is contained in:
Joffrey JAFFEUX 2020-04-14 16:43:57 +02:00 committed by GitHub
parent f07c4a781c
commit d9db0e6691
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 121 additions and 113 deletions

View File

@ -1,4 +1,5 @@
import { inject as service } from "@ember/service";
import { schedule } from "@ember/runloop";
import Component from "@ember/component";
import { on, observes } from "discourse-common/utils/decorators";
import { findRawTemplate } from "discourse/lib/raw-templates";
@ -16,23 +17,16 @@ const { run } = Ember;
const PER_ROW = 11;
function customEmojis() {
const list = extendedEmojiList();
const emojis = Object.keys(list)
.map(code => {
const { group } = list[code];
return {
code,
src: emojiUrlFor(code),
group,
key: `emoji_picker.${group || "default"}`
};
})
.reduce((acc, curr) => {
if (!acc[curr.group]) acc[curr.group] = [];
acc[curr.group].push(curr);
return acc;
}, {});
return Object.values(emojis);
const groups = [];
Object.keys(list).forEach(code => {
const emoji = list[code];
groups[emoji.group] = groups[emoji.group] || [];
groups[emoji.group].push({
code,
src: emojiUrlFor(code)
});
});
return groups;
}
export default Component.extend({
@ -42,9 +36,8 @@ export default Component.extend({
close() {
this._unbindEvents();
this.$picker
.css({ width: "", left: "", bottom: "", display: "none" })
.empty();
this.$picker &&
this.$picker.css({ width: "", left: "", bottom: "", display: "none" });
this.$modal.removeClass("fadeIn");
@ -52,11 +45,6 @@ export default Component.extend({
},
show() {
const template = findRawTemplate("emoji-picker")({
customEmojis: customEmojis()
});
this.$picker.html(template);
this.$filter = this.$picker.find(".filter");
this.$results = this.$picker.find(".results");
this.$list = this.$picker.find(".list");
@ -84,6 +72,7 @@ export default Component.extend({
@on("init")
_setInitialValues() {
this.set("customEmojis", customEmojis());
this._checkTimeout = null;
this.scrollPosition = 0;
this.$visibleSections = [];
@ -100,14 +89,21 @@ export default Component.extend({
@on("didInsertElement")
_setup() {
this.$picker = $(this.element.querySelector(".emoji-picker"));
this.$modal = $(this.element.querySelector(".emoji-picker-modal"));
this.appEvents.on("emoji-picker:close", this, "_closeEmojiPicker");
},
@on("didUpdateAttrs")
_setState() {
this.active ? this.show() : this.close();
schedule("afterRender", () => {
if (!this.element) {
return;
}
this.$picker = $(this.element.querySelector(".emoji-picker"));
this.$modal = $(this.element.querySelector(".emoji-picker-modal"));
this.active ? this.show() : this.close();
});
},
@observes("filter")

View File

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

View File

@ -0,0 +1,88 @@
<div class="emoji-picker">
{{#if active}}
<div class='categories-column'>
<div class='category-icon'>
<button type="button" class="emoji" tabindex="-1" title="{{i18n 'emoji_picker.recent'}}" data-section="recent" data-tabicon="star"></button>
</div>
<% JSON.parse(File.read("lib/emoji/groups.json")).each.with_index do |group, group_index| %>
<div class='category-icon'>
<button type="button" class="emoji" tabindex="-1" data-tabicon="<%= group["tabicon"] %>" data-section="<%= group["name"] %>" title="{{i18n '<%= "emoji_picker.#{group["name"]}" %>'}}"></button>
</div>
<% end %>
{{#each-in customEmojis as |group emojis|}}
<div class='category-icon'>
<button data-tabicon={{emojis.firstObject.code}} type="button" class="emoji" tabindex="-1" data-section="custom-{{group}}" title="{{i18n (concat 'emoji_picker.' group)}}"></button>
</div>
{{/each-in}}
</div>
<div class='main-column'>
<div class='filter'>
{{d-icon 'search'}}
<input type='text' name="filter" placeholder="{{i18n 'emoji_picker.filter_placeholder'}}" autocomplete="discourse"/>
<button class='clear-filter'>
{{d-icon 'times'}}
</button>
</div>
<div class='results'></div>
<div class='list'>
<div class='section' data-section='recent'>
<div class='section-header'>
<span class="title">{{i18n 'emoji_picker.recent'}}</span>
<a href='#' class='clear-recent'>{{d-icon "trash-alt"}}</a>
</div>
<div class='section-group'></div>
</div>
<% JSON.parse(File.read("lib/emoji/groups.json")).each.with_index do |group, group_index| %>
<div class='section' data-section='<%= group["name"] %>'>
<div class='section-header'>
<span class="title">{{i18n 'emoji_picker.<%= group["name"] %>'}}</span>
</div>
<div class='section-group'>
<% group["icons"].each do |icon| %>
<button type="button" class="emoji <%= "diversity" if icon["diversity"] %>" tabindex="-1" title="<%= icon['name']%>"></button>
<% end %>
</div>
</div>
<% end %>
{{#each-in customEmojis as |group emojis|}}
<div class='section' data-section='custom-{{group}}'>
<div class='section-header'>
<span class="title">
{{i18n (concat 'emoji_picker.' group)}}
</span>
</div>
{{#if emojis.length}}
<div class='section-group'>
{{#each emojis as |emoji|}}
<button type="button" class="emoji" tabindex="-1" title=":{{emoji.code}}:">
<img loading="lazy" class="emoji" src="{{emoji.src}}">
</button>
{{/each}}
</div>
{{/if}}
</div>
{{/each-in}}
</div>
<div class='footer'>
<div class='info'></div>
<div class='diversity-picker'>
<% ['default', 'light', 'medium-light', 'medium', 'medium-dark', 'dark'].each.with_index do |diversity, index| %>
<a href='#' title="{{i18n 'emoji_picker.<%= diversity.gsub('-', '_') %>_tone'}}" class='diversity-scale <%= diversity %>' data-level="<%= index + 1 %>">
{{d-icon "check"}}
</a>
<% end %>
</div>
</div>
</div>
{{/if}}
</div>
<div class="emoji-picker-modal"></div>

View File

@ -1,81 +0,0 @@
<div class='categories-column'>
<div class='category-icon'>
<button type="button" class="emoji" tabindex="-1" title="{{i18n 'emoji_picker.recent'}}" data-section="recent" data-tabicon="star"></button>
</div>
<% JSON.parse(File.read("lib/emoji/groups.json")).each.with_index do |group, group_index| %>
<div class='category-icon'>
<button type="button" class="emoji" tabindex="-1" data-tabicon="<%= group["tabicon"] %>" data-section="<%= group["name"] %>" title="{{i18n '<%= "emoji_picker.#{group["name"]}" %>'}}"></button>
</div>
<% end %>
<% Emoji.custom.group_by { |emoji| emoji.group }.each do |group, emojis| %>
<% if emojis.present? %>
<div class='category-icon'>
<button data-tabicon="<%= emojis.first.name %>" type="button" class="emoji" tabindex="-1" data-section="custom-<%= group %>" title="{{i18n 'emoji_picker.<%= group %>'}}"></button>
</div>
<% end %>
<% end %>
</div>
<div class='main-column'>
<div class='filter'>
{{d-icon 'search'}}
<input type='text' name="filter" placeholder="{{i18n 'emoji_picker.filter_placeholder'}}" autocomplete="discourse"/>
<button class='clear-filter'>
{{d-icon 'times'}}
</button>
</div>
<div class='results'></div>
<div class='list'>
<div class='section' data-section='recent'>
<div class='section-header'>
<span class="title">{{i18n 'emoji_picker.recent'}}</span>
<a href='#' class='clear-recent'>{{d-icon "trash-alt"}}</a>
</div>
<div class='section-group'></div>
</div>
<% JSON.parse(File.read("lib/emoji/groups.json")).each.with_index do |group, group_index| %>
<div class='section' data-section='<%= group["name"] %>'>
<div class='section-header'>
<span class="title">{{i18n 'emoji_picker.<%= group["name"] %>'}}</span>
</div>
<div class='section-group'>
<% group["icons"].each do |icon| %>
<button type="button" class="emoji <%= "diversity" if icon["diversity"] %>" tabindex="-1" title="<%= icon['name']%>"></button>
<% end %>
</div>
</div>
<% end %>
{{#each customEmojis as |emojis|}}
{{#if emojis.length}}
<div class='section' data-section='custom-{{emojis.firstObject.group}}'>
<div class='section-header'>
<span class="title">
{{i18n emojis.firstObject.key}}
</span>
</div>
<div class='section-group'>
{{#each emojis as |emoji|}}
<button style="background-url: url("{{emoji.src}}")" type="button" class="emoji" tabindex="-1" title="{{emoji.code}}"></button>
{{/each}}
</div>
</div>
{{/if}}
{{/each}}
</div>
<div class='footer'>
<div class='info'></div>
<div class='diversity-picker'>
<% ['default', 'light', 'medium-light', 'medium', 'medium-dark', 'dark'].each.with_index do |diversity, index| %>
<a href='#' title="{{i18n 'emoji_picker.<%= diversity.gsub('-', '_') %>_tone'}}" class='diversity-scale <%= diversity %>' data-level="<%= index + 1 %>">
{{d-icon "check"}}
</a>
<% end %>
</div>
</div>
</div>

View File

@ -35,6 +35,13 @@ sup img.emoji {
color: $primary;
background-color: $secondary;
border: 1px solid $primary-low;
img.emoji {
// custom emojis might import images of various sizes
// we don't want the picker to be difformed
width: 20px !important;
height: 20px !important;
}
}
.emoji-picker .categories-column {

View File

@ -22,7 +22,7 @@ QUnit.test("emoji picker can be opened/closed", async assert => {
find(".emoji-picker")
.html()
.trim(),
"",
"<!---->",
"it opens the picker"
);
@ -31,7 +31,7 @@ QUnit.test("emoji picker can be opened/closed", async assert => {
find(".emoji-picker")
.html()
.trim(),
"",
"<!---->",
"it closes the picker"
);
});