FIX: Emoji autocomplete “more” button not working in chat (#20113)
* FIX: Emoji autocomplete “more” button not working * Rely on setting an intial value on the filter input This commit removes custom logic applied on initial filter and instead gives a param to use as value for the input, automatically triggering the existing filtering handler. Other notes: - Slightly changes the API to be able to set a filter and open the composer in one go - Adds a very simple service spec - Adds a system spec to fully validate the behavior --------- Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
This commit is contained in:
parent
e4fd3d9850
commit
6325e641d8
|
@ -464,7 +464,9 @@ export default Component.extend(TextareaTextManipulation, {
|
|||
return `${v.code}:`;
|
||||
} else {
|
||||
$textarea.autocomplete({ cancel: true });
|
||||
this.set("emojiPickerIsActive", true);
|
||||
this.chatEmojiPickerManager.startFromComposer(this.emojiSelected, {
|
||||
filter: v.term,
|
||||
});
|
||||
return "";
|
||||
}
|
||||
},
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
<div class="chat-emoji-picker__filter-container">
|
||||
<DcFilterInput
|
||||
@class="chat-emoji-picker__filter"
|
||||
@value={{this.chatEmojiPickerManager.initialFilter}}
|
||||
@filterAction={{this.didInputFilter}}
|
||||
@icons={{hash left="search"}}
|
||||
placeholder={{i18n "chat.emoji_picker.search_placeholder"}}
|
||||
|
|
|
@ -518,8 +518,8 @@ export default Component.extend({
|
|||
startReactionForMessageActions() {
|
||||
this.chatEmojiPickerManager.startFromMessageActions(
|
||||
this.message,
|
||||
this.site.desktopView,
|
||||
this.selectReaction
|
||||
this.selectReaction,
|
||||
{ desktop: this.site.desktopView }
|
||||
);
|
||||
},
|
||||
|
||||
|
@ -527,8 +527,8 @@ export default Component.extend({
|
|||
startReactionForReactionList() {
|
||||
this.chatEmojiPickerManager.startFromMessageReactionList(
|
||||
this.message,
|
||||
this.site.desktopView,
|
||||
this.selectReaction
|
||||
this.selectReaction,
|
||||
{ desktop: this.site.desktopView }
|
||||
);
|
||||
},
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
<Input
|
||||
class="dc-filter-input"
|
||||
@value={{@value}}
|
||||
{{on "input" (if @filterAction @filterAction (noop))}}
|
||||
{{on "focusin" (action (mut this.isFocused) true)}}
|
||||
{{on "focusout" (action (mut this.isFocused) false)}}
|
||||
|
|
|
@ -23,6 +23,7 @@ export default class ChatEmojiPickerManager extends Service {
|
|||
@tracked emojis = null;
|
||||
@tracked visibleSections = DEFAULT_VISIBLE_SECTIONS;
|
||||
@tracked lastVisibleSection = DEFAULT_LAST_SECTION;
|
||||
@tracked initialFilter = null;
|
||||
@tracked element = null;
|
||||
@tracked callback;
|
||||
|
||||
|
@ -35,6 +36,7 @@ export default class ChatEmojiPickerManager extends Service {
|
|||
closeExisting() {
|
||||
this.callback = null;
|
||||
this.opened = false;
|
||||
this.initialFilter = null;
|
||||
this.visibleSections = DEFAULT_VISIBLE_SECTIONS;
|
||||
this.lastVisibleSection = DEFAULT_LAST_SECTION;
|
||||
}
|
||||
|
@ -51,6 +53,7 @@ export default class ChatEmojiPickerManager extends Service {
|
|||
|
||||
this.visibleSections = DEFAULT_VISIBLE_SECTIONS;
|
||||
this.lastVisibleSection = DEFAULT_LAST_SECTION;
|
||||
this.initialFilter = null;
|
||||
this.closing = false;
|
||||
this.opened = false;
|
||||
}, TRANSITION_TIME);
|
||||
|
@ -68,27 +71,32 @@ export default class ChatEmojiPickerManager extends Service {
|
|||
this.close();
|
||||
}
|
||||
|
||||
startFromMessageReactionList(message, isDesktop, callback) {
|
||||
startFromMessageReactionList(message, callback, options = {}) {
|
||||
const trigger = document.querySelector(
|
||||
`.chat-message-container[data-id="${message.id}"] .chat-message-react-btn`
|
||||
);
|
||||
this.startFromMessage(callback, isDesktop, trigger);
|
||||
this.startFromMessage(callback, trigger, options);
|
||||
}
|
||||
|
||||
startFromMessageActions(message, isDesktop, callback) {
|
||||
startFromMessageActions(message, callback, options = {}) {
|
||||
const trigger = document.querySelector(
|
||||
`.chat-message-actions-container[data-id="${message.id}"] .chat-message-actions`
|
||||
);
|
||||
this.startFromMessage(callback, isDesktop, trigger);
|
||||
this.startFromMessage(callback, trigger, options);
|
||||
}
|
||||
|
||||
startFromMessage(callback, isDesktop, trigger) {
|
||||
startFromMessage(
|
||||
callback,
|
||||
trigger,
|
||||
options = { filter: null, desktop: true }
|
||||
) {
|
||||
this.initialFilter = options.filter;
|
||||
this.context = "chat-message";
|
||||
this.element = document.querySelector(".chat-message-emoji-picker-anchor");
|
||||
this.open(callback);
|
||||
this._popper?.destroy();
|
||||
|
||||
if (isDesktop) {
|
||||
if (options.desktop) {
|
||||
schedule("afterRender", () => {
|
||||
this._popper = createPopper(trigger, this.element, {
|
||||
placement: "top",
|
||||
|
@ -112,7 +120,8 @@ export default class ChatEmojiPickerManager extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
startFromComposer(callback) {
|
||||
startFromComposer(callback, options = { filter: null }) {
|
||||
this.initialFilter = options.filter;
|
||||
this.context = "chat-composer";
|
||||
this.element = document.querySelector(".chat-composer-emoji-picker-anchor");
|
||||
this.open(callback);
|
||||
|
@ -140,7 +149,6 @@ export default class ChatEmojiPickerManager extends Service {
|
|||
.then((emojis) => {
|
||||
this.emojis = emojis;
|
||||
})
|
||||
|
||||
.catch(popupAjaxError)
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
|
|
|
@ -94,6 +94,22 @@ RSpec.describe "Chat composer", type: :system, js: true do
|
|||
end
|
||||
end
|
||||
|
||||
context "when opening emoji picker through more button of the autocomplete" do
|
||||
before do
|
||||
channel_1.add(current_user)
|
||||
sign_in(current_user)
|
||||
end
|
||||
|
||||
it "prefills the emoji picker filter input" do
|
||||
chat.visit_channel(channel_1)
|
||||
find(".chat-composer-input").fill_in(with: ":gri")
|
||||
|
||||
click_link(I18n.t("js.composer.more_emoji"))
|
||||
|
||||
expect(find(".chat-emoji-picker .dc-filter-input").value).to eq("gri")
|
||||
end
|
||||
end
|
||||
|
||||
context "when typing on keyboard" do
|
||||
before do
|
||||
channel_1.add(current_user)
|
||||
|
|
|
@ -24,7 +24,7 @@ module(
|
|||
|
||||
test("startFromMessageReactionList", async function (assert) {
|
||||
const callback = () => {};
|
||||
this.manager.startFromMessageReactionList({ id: 1 }, false, callback);
|
||||
this.manager.startFromMessageReactionList({ id: 1 }, callback);
|
||||
|
||||
assert.ok(this.manager.loading);
|
||||
assert.ok(this.manager.opened);
|
||||
|
@ -44,7 +44,7 @@ module(
|
|||
|
||||
test("startFromMessageActions", async function (assert) {
|
||||
const callback = () => {};
|
||||
this.manager.startFromMessageReactionList({ id: 1 }, false, callback);
|
||||
this.manager.startFromMessageReactionList({ id: 1 }, callback);
|
||||
|
||||
assert.ok(this.manager.loading);
|
||||
assert.ok(this.manager.opened);
|
||||
|
@ -104,6 +104,14 @@ module(
|
|||
assert.strictEqual(this.manager.loading, false);
|
||||
});
|
||||
|
||||
test("startFromComposer with filter option", async function (assert) {
|
||||
const callback = () => {};
|
||||
this.manager.startFromComposer(callback, { filter: "foofilter" });
|
||||
await settled();
|
||||
|
||||
assert.strictEqual(this.manager.initialFilter, "foofilter");
|
||||
});
|
||||
|
||||
test("closeExisting", async function (assert) {
|
||||
const callback = () => {
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue