diff --git a/app/models/user_option.rb b/app/models/user_option.rb
index 84b0c2d463b..c93d7aea6f6 100644
--- a/app/models/user_option.rb
+++ b/app/models/user_option.rb
@@ -266,8 +266,6 @@ end
# homepage_id :integer
# theme_ids :integer default([]), not null, is an Array
# hide_profile_and_presence :boolean default(FALSE), not null
-# hide_profile :boolean default(FALSE), not null
-# hide_presence :boolean default(FALSE), not null
# text_size_key :integer default(0), not null
# text_size_seq :integer default(0), not null
# email_level :integer default(1), not null
@@ -296,10 +294,14 @@ end
# sidebar_show_count_of_new_items :boolean default(FALSE), not null
# watched_precedence_over_muted :boolean
# chat_separate_sidebar_mode :integer default(0), not null
-# chat_send_shortcut :integer default(0), not null
# topics_unread_when_closed :boolean default(TRUE), not null
# show_thread_title_prompts :boolean default(TRUE), not null
# enable_smart_lists :boolean default(TRUE), not null
+# hide_profile :boolean default(FALSE), not null
+# hide_presence :boolean default(FALSE), not null
+# chat_send_shortcut :integer default(0), not null
+# chat_quick_reaction_type :integer default(0), not null
+# chat_quick_reactions_custom :string
#
# Indexes
#
diff --git a/plugins/chat/assets/javascripts/discourse/controllers/preferences-chat.js b/plugins/chat/assets/javascripts/discourse/controllers/preferences-chat.js
index 3af87360378..658cf0f4949 100644
--- a/plugins/chat/assets/javascripts/discourse/controllers/preferences-chat.js
+++ b/plugins/chat/assets/javascripts/discourse/controllers/preferences-chat.js
@@ -19,8 +19,12 @@ const CHAT_ATTRS = [
"chat_header_indicator_preference",
"chat_separate_sidebar_mode",
"chat_send_shortcut",
+ "chat_quick_reaction_type",
+ "chat_quick_reactions_custom",
];
+export const CHAT_QUICK_REACTIONS_CUSTOM_DEFAULT = "heart|+1|smile";
+
export const HEADER_INDICATOR_PREFERENCE_NEVER = "never";
export const HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS = "dm_and_mentions";
export const HEADER_INDICATOR_PREFERENCE_ALL_NEW = "all_new";
@@ -32,6 +36,17 @@ export default class PreferencesChatController extends Controller {
subpageTitle = i18n("chat.admin.title");
+ chatQuickReactionTypes = [
+ {
+ label: i18n("chat.quick_reaction_type.options.frequent"),
+ value: "frequent",
+ },
+ {
+ label: i18n("chat.quick_reaction_type.options.custom"),
+ value: "custom",
+ },
+ ];
+
chatSendShortcutOptions = [
{
label: i18n("chat.send_shortcut.enter.label"),
@@ -99,6 +114,13 @@ export default class PreferencesChatController extends Controller {
return this.model.get("user_option.chat_send_shortcut");
}
+ get chatQuickReactionsCustom() {
+ const emojis =
+ this.model.get("user_option.chat_quick_reactions_custom") ||
+ CHAT_QUICK_REACTIONS_CUSTOM_DEFAULT;
+ return emojis.split("|");
+ }
+
@discourseComputed
chatSounds() {
return Object.keys(CHAT_SOUNDS).map((value) => {
@@ -114,6 +136,24 @@ export default class PreferencesChatController extends Controller {
this.model.set("user_option.chat_sound", sound);
}
+ @action
+ onChangeQuickReactionType(value) {
+ this.model.set("user_option.chat_quick_reaction_type", value);
+ if (value === "custom") {
+ this.model.set(
+ "user_option.chat_quick_reactions_custom",
+ this.chatQuickReactionsCustom.join("|")
+ );
+ }
+ }
+
+ @action
+ didSelectEmoji(index, selected) {
+ let emoji = this.chatQuickReactionsCustom;
+ emoji[index] = selected;
+ this.model.set("user_option.chat_quick_reactions_custom", emoji.join("|"));
+ }
+
@action
save() {
this.set("saved", false);
diff --git a/plugins/chat/assets/javascripts/discourse/initializers/chat-user-options.js b/plugins/chat/assets/javascripts/discourse/initializers/chat-user-options.js
index 79cf1be0250..b63da14b9c8 100644
--- a/plugins/chat/assets/javascripts/discourse/initializers/chat-user-options.js
+++ b/plugins/chat/assets/javascripts/discourse/initializers/chat-user-options.js
@@ -9,6 +9,8 @@ const CHAT_EMAIL_FREQUENCY = "chat_email_frequency";
const CHAT_HEADER_INDICATOR_PREFERENCE = "chat_header_indicator_preference";
const CHAT_SEPARATE_SIDEBAR_MODE = "chat_separate_sidebar_mode";
const CHAT_SEND_SHORTCUT = "chat_send_shortcut";
+const CHAT_QUICK_REACTION_TYPE = "chat_quick_reaction_type";
+const CHAT_QUICK_REACTIONS_CUSTOM = "chat_quick_reactions_custom";
export default {
name: "chat-user-options",
@@ -26,6 +28,8 @@ export default {
api.addSaveableUserOptionField(CHAT_HEADER_INDICATOR_PREFERENCE);
api.addSaveableUserOptionField(CHAT_SEPARATE_SIDEBAR_MODE);
api.addSaveableUserOptionField(CHAT_SEND_SHORTCUT);
+ api.addSaveableUserOptionField(CHAT_QUICK_REACTION_TYPE);
+ api.addSaveableUserOptionField(CHAT_QUICK_REACTIONS_CUSTOM);
}
});
},
diff --git a/plugins/chat/assets/javascripts/discourse/lib/chat-message-interactor.js b/plugins/chat/assets/javascripts/discourse/lib/chat-message-interactor.js
index 2afa8281bef..8546e13094f 100644
--- a/plugins/chat/assets/javascripts/discourse/lib/chat-message-interactor.js
+++ b/plugins/chat/assets/javascripts/discourse/lib/chat-message-interactor.js
@@ -60,13 +60,28 @@ export default class ChatemojiReactions {
}
get emojiReactions() {
- const defaultReactions = this.siteSettings.default_emoji_reactions
+ const userQuickReactionsCustom = (
+ (this.currentUser.user_option.chat_quick_reaction_type === "custom" &&
+ this.currentUser.user_option.chat_quick_reactions_custom) ||
+ ""
+ )
.split("|")
.filter(Boolean);
- return this.emojiStore
- .favoritesForContext("chat")
- .concat(defaultReactions)
+ const frequentReactions = this.emojiStore.favoritesForContext("chat");
+
+ const defaultReactions =
+ this.siteSettings.default_emoji_reactions.split("|");
+
+ const allReactionsInOrder = userQuickReactionsCustom
+ .concat(frequentReactions)
+ .concat(defaultReactions);
+
+ return allReactionsInOrder
+ .filter((item, index) => {
+ return allReactionsInOrder.indexOf(item) === index;
+ })
+ .filter(Boolean)
.slice(0, 3)
.map(
(emoji) =>
diff --git a/plugins/chat/assets/javascripts/discourse/templates/preferences/chat.gjs b/plugins/chat/assets/javascripts/discourse/templates/preferences/chat.gjs
index bfdca1fbb2d..dd374b473e7 100644
--- a/plugins/chat/assets/javascripts/discourse/templates/preferences/chat.gjs
+++ b/plugins/chat/assets/javascripts/discourse/templates/preferences/chat.gjs
@@ -1,8 +1,9 @@
import { Input } from "@ember/component";
-import { concat, fn, hash } from "@ember/helper";
+import { array, concat, fn, get, hash } from "@ember/helper";
import { on } from "@ember/modifier";
import RouteTemplate from "ember-route-template";
import { eq } from "truth-helpers";
+import EmojiPicker from "discourse/components/emoji-picker";
import SaveControls from "discourse/components/save-controls";
import withEventValue from "discourse/helpers/with-event-value";
import { i18n } from "discourse-i18n";
@@ -26,6 +27,52 @@ export default RouteTemplate(
+
+
%{username} invited you to join a chat channel"
diff --git a/plugins/chat/db/migrate/20250307185912_add_chat_quick_reaction_preferences.rb b/plugins/chat/db/migrate/20250307185912_add_chat_quick_reaction_preferences.rb
new file mode 100644
index 00000000000..aef4b3a8f22
--- /dev/null
+++ b/plugins/chat/db/migrate/20250307185912_add_chat_quick_reaction_preferences.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+class AddChatQuickReactionPreferences < ActiveRecord::Migration[7.2]
+ def change
+ add_column :user_options, :chat_quick_reaction_type, :integer, default: 0, null: false
+ add_column :user_options, :chat_quick_reactions_custom, :string
+ end
+end
diff --git a/plugins/chat/lib/chat/user_option_extension.rb b/plugins/chat/lib/chat/user_option_extension.rb
index 78ba5a52957..cc7730f72c2 100644
--- a/plugins/chat/lib/chat/user_option_extension.rb
+++ b/plugins/chat/lib/chat/user_option_extension.rb
@@ -57,6 +57,10 @@ module Chat
if !base.method_defined?(:show_thread_title_prompts?)
base.attribute :show_thread_title_prompts, :boolean, default: true
end
+
+ if !base.method_defined?(:chat_quick_reaction_type_frequent?)
+ base.enum :chat_quick_reaction_type, { frequent: 0, custom: 1 }, prefix: true
+ end
end
end
end
diff --git a/plugins/chat/plugin.rb b/plugins/chat/plugin.rb
index 312b9d358fa..7a5834e1150 100644
--- a/plugins/chat/plugin.rb
+++ b/plugins/chat/plugin.rb
@@ -54,6 +54,8 @@ after_initialize do
DiscoursePluginRegistry.register_flag_applies_to_type("Chat::Message", self)
UserUpdater::OPTION_ATTR.push(:chat_enabled)
+ UserUpdater::OPTION_ATTR.push(:chat_quick_reaction_type)
+ UserUpdater::OPTION_ATTR.push(:chat_quick_reactions_custom)
UserUpdater::OPTION_ATTR.push(:only_chat_push_notifications)
UserUpdater::OPTION_ATTR.push(:chat_sound)
UserUpdater::OPTION_ATTR.push(:ignore_channel_wide_mention)
@@ -251,6 +253,18 @@ after_initialize do
add_to_serializer(:current_user_option, :chat_send_shortcut) { object.chat_send_shortcut }
+ add_to_serializer(:user_option, :chat_quick_reaction_type) { object.chat_quick_reaction_type }
+ add_to_serializer(:current_user_option, :chat_quick_reaction_type) do
+ object.chat_quick_reaction_type
+ end
+
+ add_to_serializer(:user_option, :chat_quick_reactions_custom) do
+ object.chat_quick_reactions_custom
+ end
+ add_to_serializer(:current_user_option, :chat_quick_reactions_custom) do
+ object.chat_quick_reactions_custom
+ end
+
on(:site_setting_changed) do |name, old_value, new_value|
user_option_field = Chat::RETENTION_SETTINGS_TO_USER_OPTION_FIELDS[name.to_sym]
begin
diff --git a/plugins/chat/spec/models/user_option_spec.rb b/plugins/chat/spec/models/user_option_spec.rb
index 016676691c6..8a622a3b476 100644
--- a/plugins/chat/spec/models/user_option_spec.rb
+++ b/plugins/chat/spec/models/user_option_spec.rb
@@ -11,4 +11,9 @@ RSpec.describe UserOption do
expect(described_class.new.show_thread_title_prompts).to eq(true)
end
end
+ describe "#chat_quick_reaction_type" do
+ it "is present with frequent as default" do
+ expect(described_class.new.chat_quick_reaction_type).to eq("frequent")
+ end
+ end
end
diff --git a/plugins/chat/spec/serializer/current_user_serializer_spec.rb b/plugins/chat/spec/serializer/current_user_serializer_spec.rb
index d1a2a7c52ed..2be628e8428 100644
--- a/plugins/chat/spec/serializer/current_user_serializer_spec.rb
+++ b/plugins/chat/spec/serializer/current_user_serializer_spec.rb
@@ -19,6 +19,26 @@ RSpec.describe CurrentUserSerializer do
end
end
+ describe "#chat_quick_reaction_type" do
+ it "is present with default enum string" do
+ expect(serializer.as_json[:user_option][:chat_quick_reaction_type]).to eq("frequent")
+ end
+ end
+
+ describe "#chat_quick_reactions_custom" do
+ it "is present with default enum string" do
+ expect(serializer.as_json[:user_option][:chat_quick_reactions_custom]).to eq(nil)
+ end
+
+ context "with custom quick reactions" do
+ before { current_user.user_option.update!(chat_quick_reactions_custom: "tada|smiley") }
+
+ it "is present" do
+ expect(serializer.as_json[:user_option][:chat_quick_reactions_custom]).to eq("tada|smiley")
+ end
+ end
+ end
+
describe "#chat_drafts" do
context "when user can't chat" do
before { SiteSetting.chat_allowed_groups = Group::AUTO_GROUPS[:staff] }
diff --git a/plugins/chat/spec/serializer/user_serializer_spec.rb b/plugins/chat/spec/serializer/user_serializer_spec.rb
index f4b1ed28c05..78667489b0a 100644
--- a/plugins/chat/spec/serializer/user_serializer_spec.rb
+++ b/plugins/chat/spec/serializer/user_serializer_spec.rb
@@ -1,15 +1,33 @@
# frozen_string_literal: true
RSpec.describe UserSerializer do
- fab!(:current_user) { Fabricate(:user) }
+ fab!(:user)
- let(:serializer) do
- described_class.new(current_user, scope: Guardian.new(current_user), root: false)
- end
+ let(:serializer) { described_class.new(user, scope: Guardian.new(user), root: false) }
describe "#chat_separate_sidebar_mode" do
it "is present" do
expect(serializer.as_json[:user_option][:chat_separate_sidebar_mode]).to eq("default")
end
end
+
+ describe "#chat_quick_reaction_type" do
+ it "is present with default enum string" do
+ expect(serializer.as_json[:user_option][:chat_quick_reaction_type]).to eq("frequent")
+ end
+ end
+
+ describe "#chat_quick_reactions_custom" do
+ it "is present with default enum string" do
+ expect(serializer.as_json[:user_option][:chat_quick_reactions_custom]).to eq(nil)
+ end
+
+ context "with custom quick reactions" do
+ before { user.user_option.update!(chat_quick_reactions_custom: "tada|smiley") }
+
+ it "is present" do
+ expect(serializer.as_json[:user_option][:chat_quick_reactions_custom]).to eq("tada|smiley")
+ end
+ end
+ end
end
diff --git a/plugins/chat/spec/system/page_objects/chat/chat_channel.rb b/plugins/chat/spec/system/page_objects/chat/chat_channel.rb
index 7fe5a8f2498..bf98e177660 100644
--- a/plugins/chat/spec/system/page_objects/chat/chat_channel.rb
+++ b/plugins/chat/spec/system/page_objects/chat/chat_channel.rb
@@ -151,6 +151,10 @@ module PageObjects
within(message_reactions_list(message)) { return find("[data-emoji-name=\"#{emoji}\"]") }
end
+ def find_quick_reaction(emoji_name)
+ find(".chat-message-actions [data-emoji-name=\"#{emoji_name}\"]")
+ end
+
def has_reaction?(message, emoji, text = nil)
within(message_reactions_list(message)) do
has_css?("[data-emoji-name=\"#{emoji}\"]", text: text)
diff --git a/plugins/chat/spec/system/page_objects/pages/user_preferences_chat.rb b/plugins/chat/spec/system/page_objects/pages/user_preferences_chat.rb
new file mode 100644
index 00000000000..6dfb20d3813
--- /dev/null
+++ b/plugins/chat/spec/system/page_objects/pages/user_preferences_chat.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module PageObjects
+ module Pages
+ class UserPreferencesChat < PageObjects::Pages::Base
+ def visit
+ page.visit("/my/preferences/chat")
+ self
+ end
+
+ def emoji_picker_triggers
+ all(".emoji-picker-trigger", visible: true)
+ end
+
+ def reaction_buttons
+ all(".emoji-pickers button")
+ end
+
+ def reactions_selected
+ reaction_buttons.map { |b| b.find("img")[:title] }
+ end
+
+ def select_option_value(selector, value)
+ select_kit = PageObjects::Components::SelectKit.new(selector)
+ select_kit.expand
+ select_kit.select_row_by_value(value)
+ end
+
+ def selected_option_value(selector)
+ PageObjects::Components::SelectKit.new(selector).value
+ end
+
+ def save_changes_and_refresh
+ page.find(".save-changes").click
+ # reloading the page happens in JS on save but capybara doesnt wait for it
+ # which can mess up navigating away too soon in tests
+ # so doing a manual refresh here to mimic
+ page.refresh
+ end
+ end
+ end
+end
diff --git a/plugins/chat/spec/system/user_chat_preferences_spec.rb b/plugins/chat/spec/system/user_chat_preferences_spec.rb
index e682ae8933e..5e7bcb79b1f 100644
--- a/plugins/chat/spec/system/user_chat_preferences_spec.rb
+++ b/plugins/chat/spec/system/user_chat_preferences_spec.rb
@@ -3,7 +3,10 @@
RSpec.describe "User chat preferences", type: :system do
fab!(:current_user) { Fabricate(:user) }
+ let(:user_preferences_chat_page) { PageObjects::Pages::UserPreferencesChat.new }
+ let(:emoji_picker) { PageObjects::Components::EmojiPicker.new }
let(:chat) { PageObjects::Pages::Chat.new }
+ let(:channel) { PageObjects::Pages::ChatChannel.new }
before do
chat_system_bootstrap
@@ -23,50 +26,89 @@ RSpec.describe "User chat preferences", type: :system do
end
it "shows a not found page" do
- visit("/my/preferences/chat")
+ user_preferences_chat_page.visit
expect(page).to have_content(I18n.t("page_not_found.title"))
end
end
- it "can select chat sound" do
- visit("/my/preferences")
- find(".user-nav__preferences-chat", visible: :all).click
- select_kit = PageObjects::Components::SelectKit.new("#user_chat_sounds")
- select_kit.expand
- select_kit.select_row_by_value("bell")
- find(".save-changes").click
+ it "can change chat quick reaction type to custom and select emoji" do
+ user_preferences_chat_page.visit
+ find("#user_chat_quick_reaction_type_custom").click
- expect(select_kit).to have_selected_value("bell")
+ expect(user_preferences_chat_page.emoji_picker_triggers.count).to eq 3
+ expect(user_preferences_chat_page.reactions_selected.first).to eq "heart"
+
+ user_preferences_chat_page.reaction_buttons.first.click
+ emoji_picker.select_emoji(":sweat_smile:")
+ user_preferences_chat_page.save_changes_and_refresh
+
+ expect(page).to have_checked_field("user_chat_quick_reaction_type_custom")
+ expect(user_preferences_chat_page.reactions_selected.first).to eq "sweat_smile"
end
- it "can select header_indicator_preference" do
- visit("/my/preferences")
- find(".user-nav__preferences-chat", visible: :all).click
- select_kit = PageObjects::Components::SelectKit.new("#user_chat_header_indicator_preference")
- select_kit.expand
- select_kit.select_row_by_value("dm_and_mentions")
- find(".save-changes").click
+ describe "chat interface" do
+ fab!(:category_channel_1) { Fabricate(:category_channel) }
+ fab!(:message_1) { Fabricate(:chat_message, chat_channel: category_channel_1) }
- expect(select_kit).to have_selected_value("dm_and_mentions")
+ it "sees expected quick-reactions on hover" do
+ sign_in(current_user)
+
+ # save custom and look for reaction
+ user_preferences_chat_page.visit
+ find("#user_chat_quick_reaction_type_custom").click
+ user_preferences_chat_page.save_changes_and_refresh
+ chat.visit_channel(category_channel_1)
+ channel.hover_message(message_1)
+
+ expect(channel.find_quick_reaction("smile")).to be_present
+
+ # save frequent and look for reaction
+ user_preferences_chat_page.visit
+ find("#user_chat_quick_reaction_type_frequent").click
+ user_preferences_chat_page.save_changes_and_refresh
+ chat.visit_channel(category_channel_1)
+ channel.hover_message(message_1)
+
+ expect(channel.find_quick_reaction("tada")).to be_present
+ end
end
- it "can select separate sidebar mode" do
- visit("/my/preferences")
- find(".user-nav__preferences-chat", visible: :all).click
- select_kit = PageObjects::Components::SelectKit.new("#user_chat_separate_sidebar_mode")
- select_kit.expand
- select_kit.select_row_by_value("fullscreen")
- find(".save-changes").click
+ shared_examples "select and save" do
+ it "can select and save" do
+ user_preferences_chat_page.visit
+ user_preferences_chat_page.select_option_value(sel, val)
+ user_preferences_chat_page.save_changes_and_refresh
- expect(select_kit).to have_selected_value("fullscreen")
+ expect(user_preferences_chat_page.selected_option_value(sel)).to eq val
+ end
+ end
+
+ describe "chat sound" do
+ include_examples "select and save" do
+ let(:sel) { "#user_chat_sounds" }
+ let(:val) { "bell" }
+ end
+ end
+
+ describe "header_indicator_preference" do
+ include_examples "select and save" do
+ let(:sel) { "#user_chat_header_indicator_preference" }
+ let(:val) { "dm_and_mentions" }
+ end
+ end
+
+ describe "separate sidebar mode" do
+ include_examples "select and save" do
+ let(:sel) { "#user_chat_separate_sidebar_mode" }
+ let(:val) { "fullscreen" }
+ end
end
it "can select send shorcut sidebar mode" do
- visit("/my/preferences")
- find(".user-nav__preferences-chat", visible: :all).click
+ user_preferences_chat_page.visit
find("#chat_send_shortcut_meta_enter").click
- find(".save-changes").click
+ user_preferences_chat_page.save_changes_and_refresh
expect(page).to have_checked_field("chat_send_shortcut_meta_enter")
end
diff --git a/plugins/chat/test/javascripts/unit/lib/chat-message-interactor-test.js b/plugins/chat/test/javascripts/unit/lib/chat-message-interactor-test.js
new file mode 100644
index 00000000000..8f8f26361c6
--- /dev/null
+++ b/plugins/chat/test/javascripts/unit/lib/chat-message-interactor-test.js
@@ -0,0 +1,122 @@
+import { getOwner } from "@ember/owner";
+import { setupTest } from "ember-qunit";
+import { module, test } from "qunit";
+import {
+ logIn,
+ updateCurrentUser,
+} from "discourse/tests/helpers/qunit-helpers";
+import ChatMessageInteractor from "discourse/plugins/chat/discourse/lib/chat-message-interactor";
+import ChatFabricators from "discourse/plugins/chat/discourse/lib/fabricators";
+
+module("Discourse Chat | Unit | chat-message-interactor", function (hooks) {
+ setupTest(hooks);
+
+ hooks.beforeEach(function () {
+ logIn(getOwner(this));
+ const message = new ChatFabricators(getOwner(this)).message();
+ this.messageInteractor = new ChatMessageInteractor(getOwner(this), message);
+ this.emojiStore = getOwner(this).lookup("service:emoji-store");
+ this.siteSettings = getOwner(this).lookup("service:site-settings");
+ });
+
+ test("emojiReactions with no option uses site default", function (assert) {
+ assert.deepEqual(
+ this.messageInteractor.emojiReactions.map((r) => r.emoji),
+ ["+1", "heart", "tada"]
+ );
+ });
+
+ test("emojiReactions empty when no frequent or site defaults", function (assert) {
+ this.siteSettings.default_emoji_reactions = "";
+
+ assert.deepEqual(this.messageInteractor.emojiReactions, []);
+ });
+
+ test("emojiReactions with user option frequent falls back to site defaults", function (assert) {
+ updateCurrentUser({
+ user_option: {
+ chat_quick_reaction_type: "frequent",
+ },
+ });
+
+ assert.deepEqual(
+ this.messageInteractor.emojiReactions.map((r) => r.emoji),
+ ["+1", "heart", "tada"]
+ );
+ });
+
+ test("emojiReactions with top 3 frequent", function (assert) {
+ this.emojiStore.trackEmojiForContext("eyes", "chat");
+ this.emojiStore.trackEmojiForContext("camera", "chat");
+ this.emojiStore.trackEmojiForContext("butterfly", "chat");
+ this.emojiStore.trackEmojiForContext("butterfly", "chat");
+ this.emojiStore.trackEmojiForContext("laptop", "chat");
+
+ assert.deepEqual(
+ this.messageInteractor.emojiReactions.map((r) => r.emoji),
+ ["butterfly", "laptop", "camera"]
+ );
+ });
+
+ test("emojiReactions with 1 frequent falls back to system", function (assert) {
+ this.emojiStore.trackEmojiForContext("butterfly", "chat");
+
+ assert.deepEqual(
+ this.messageInteractor.emojiReactions.map((r) => r.emoji),
+ ["butterfly", "+1", "heart"]
+ );
+ });
+
+ test("emojiReactions uses custom user option", function (assert) {
+ updateCurrentUser({
+ user_option: {
+ chat_quick_reaction_type: "custom",
+ chat_quick_reactions_custom: "grin|fearful|angry",
+ },
+ });
+
+ assert.deepEqual(
+ this.messageInteractor.emojiReactions.map((r) => r.emoji),
+ ["grin", "fearful", "angry"]
+ );
+ });
+
+ test("emojiReactions does not use custom if set to frequent", function (assert) {
+ updateCurrentUser({
+ user_option: {
+ chat_quick_reaction_type: "frequent",
+ chat_quick_reactions_custom: "grin|fearful|angry",
+ },
+ });
+
+ assert.deepEqual(
+ this.messageInteractor.emojiReactions.map((r) => r.emoji),
+ ["+1", "heart", "tada"]
+ );
+ });
+
+ test("emojiReactions avoids duplicates from frequent and site", function (assert) {
+ this.emojiStore.trackEmojiForContext("+1", "chat");
+
+ assert.deepEqual(
+ this.messageInteractor.emojiReactions.map((r) => r.emoji),
+ ["+1", "heart", "tada"]
+ );
+ });
+
+ test("emojiReactions avoids duplicates from custom + frequent + site", function (assert) {
+ updateCurrentUser({
+ user_option: {
+ chat_quick_reaction_type: "custom",
+ chat_quick_reactions_custom: "+1|+1|+1",
+ },
+ });
+ this.emojiStore.trackEmojiForContext("+1", "chat");
+ this.emojiStore.trackEmojiForContext("butterfly", "chat");
+
+ assert.deepEqual(
+ this.messageInteractor.emojiReactions.map((r) => r.emoji),
+ ["+1", "butterfly", "heart"]
+ );
+ });
+});