diff --git a/plugins/chat/app/controllers/api/chat_channels_controller.rb b/plugins/chat/app/controllers/api/chat_channels_controller.rb
index b073936cf48..4e66d16aae4 100644
--- a/plugins/chat/app/controllers/api/chat_channels_controller.rb
+++ b/plugins/chat/app/controllers/api/chat_channels_controller.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
CHAT_CHANNEL_EDITABLE_PARAMS = %i[name description]
-CATEGORY_CHAT_CHANNEL_EDITABLE_PARAMS = %i[auto_join_users]
+CATEGORY_CHAT_CHANNEL_EDITABLE_PARAMS = %i[auto_join_users allow_channel_wide_mentions]
class Chat::Api::ChatChannelsController < Chat::Api
def index
diff --git a/plugins/chat/app/models/chat_channel.rb b/plugins/chat/app/models/chat_channel.rb
index a8e4fdfec7f..b87cf6c9709 100644
--- a/plugins/chat/app/models/chat_channel.rb
+++ b/plugins/chat/app/models/chat_channel.rb
@@ -121,24 +121,25 @@ end
#
# Table name: chat_channels
#
-# id :bigint not null, primary key
-# chatable_id :integer not null
-# deleted_at :datetime
-# deleted_by_id :integer
-# featured_in_category_id :integer
-# delete_after_seconds :integer
-# chatable_type :string not null
-# created_at :datetime not null
-# updated_at :datetime not null
-# name :string
-# description :text
-# status :integer default("open"), not null
-# user_count :integer default(0), not null
-# last_message_sent_at :datetime not null
-# auto_join_users :boolean default(FALSE), not null
-# user_count_stale :boolean default(FALSE), not null
-# slug :string
-# type :string
+# id :bigint not null, primary key
+# chatable_id :integer not null
+# deleted_at :datetime
+# deleted_by_id :integer
+# featured_in_category_id :integer
+# delete_after_seconds :integer
+# chatable_type :string not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# name :string
+# description :text
+# status :integer default("open"), not null
+# user_count :integer default(0), not null
+# last_message_sent_at :datetime not null
+# auto_join_users :boolean default(FALSE), not null
+# allow_channel_wide_mentions :boolean default(TRUE), not null
+# user_count_stale :boolean default(FALSE), not null
+# slug :string
+# type :string
#
# Indexes
#
diff --git a/plugins/chat/app/serializers/chat_channel_serializer.rb b/plugins/chat/app/serializers/chat_channel_serializer.rb
index d3fedfa9c41..4b7b2c5a8e6 100644
--- a/plugins/chat/app/serializers/chat_channel_serializer.rb
+++ b/plugins/chat/app/serializers/chat_channel_serializer.rb
@@ -3,6 +3,7 @@
class ChatChannelSerializer < ApplicationSerializer
attributes :id,
:auto_join_users,
+ :allow_channel_wide_mentions,
:chatable,
:chatable_id,
:chatable_type,
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-saved-indicator.hbs b/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-saved-indicator.hbs
new file mode 100644
index 00000000000..78a6af82fea
--- /dev/null
+++ b/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-saved-indicator.hbs
@@ -0,0 +1,11 @@
+
+ {{#if this.isActive}}
+ {{d-icon "check"}}
+ {{i18n "saved"}}
+ {{/if}}
+
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-saved-indicator.js b/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-saved-indicator.js
new file mode 100644
index 00000000000..292e3af2308
--- /dev/null
+++ b/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-saved-indicator.js
@@ -0,0 +1,28 @@
+import discourseLater from "discourse-common/lib/later";
+import Component from "@glimmer/component";
+import { action } from "@ember/object";
+import { tracked } from "@glimmer/tracking";
+import { cancel } from "@ember/runloop";
+
+const ACTIVE_DURATION = 2000;
+
+export default class ChatChannelSettingsSavedIndicator extends Component {
+ @tracked isActive = false;
+ property = null;
+
+ @action
+ activate() {
+ cancel(this._deactivateHandler);
+
+ this.isActive = true;
+
+ this._deactivateHandler = discourseLater(() => {
+ this.isActive = false;
+ }, ACTIVE_DURATION);
+ }
+
+ @action
+ teardown() {
+ cancel(this._deactivateHandler);
+ }
+}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-view.hbs b/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-view.hbs
index 39b46b4091a..5597f74a5c9 100644
--- a/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-view.hbs
+++ b/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-view.hbs
@@ -2,58 +2,122 @@
+
{{#unless this.channel.current_user_membership.muted}}
{{/unless}}
- {{d-icon "info-circle"}}{{i18n "chat.settings.retention_info" days=this.siteSettings.chat_channel_retention_days}}
+
+ {{d-icon "info-circle"}}
+ {{i18n
+ "chat.settings.retention_info"
+ days=this.siteSettings.chat_channel_retention_days
+ }}
+
-{{#if (chat-guardian "can-edit-chat-channel")}}
-
+{{#if this.adminSectionAvailable}}
+
{{#if this.autoJoinAvailable}}
+ {{/if}}
+
+ {{#if this.togglingChannelWideMentionsAvailable}}
+
{{/if}}
@@ -64,22 +128,42 @@
{{#if (chat-guardian "can-edit-chat-channel")}}
{{#if (chat-guardian "can-archive-channel" this.channel)}}
-
+
{{/if}}
{{#if this.channel.isClosed}}
-
+
{{else}}
-
+
{{/if}}
-
+
{{/if}}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-view.js b/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-view.js
index 5bcea9b3829..1dc4f4d3c31 100644
--- a/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-view.js
+++ b/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-view.js
@@ -4,8 +4,8 @@ import { inject as service } from "@ember/service";
import ChatApi from "discourse/plugins/chat/discourse/lib/chat-api";
import showModal from "discourse/lib/show-modal";
import I18n from "I18n";
-import { camelize } from "@ember/string";
-import discourseLater from "discourse-common/lib/later";
+import { Promise } from "rsvp";
+import { reads } from "@ember/object/computed";
const NOTIFICATION_LEVELS = [
{ name: I18n.t("chat.notification_levels.never"), value: "never" },
@@ -23,8 +23,17 @@ const AUTO_ADD_USERS_OPTIONS = [
{ name: I18n.t("no_value"), value: false },
];
+const CHANNEL_WIDE_MENTIONS_OPTIONS = [
+ { name: I18n.t("yes_value"), value: true },
+ {
+ name: I18n.t("no_value"),
+ value: false,
+ },
+];
+
export default class ChatChannelSettingsView extends Component {
@service chat;
+ @service chatGuardian;
@service router;
@service dialog;
tagName = "";
@@ -33,57 +42,28 @@ export default class ChatChannelSettingsView extends Component {
notificationLevels = NOTIFICATION_LEVELS;
mutedOptions = MUTED_OPTIONS;
autoAddUsersOptions = AUTO_ADD_USERS_OPTIONS;
+ channelWideMentionsOptions = CHANNEL_WIDE_MENTIONS_OPTIONS;
isSavingNotificationSetting = false;
savedDesktopNotificationLevel = false;
savedMobileNotificationLevel = false;
savedMuted = false;
- _updateAutoJoinUsers(value) {
- return ChatApi.modifyChatChannel(this.channel.id, {
- auto_join_users: value,
- })
- .then((chatChannel) => {
- this.channel.set("auto_join_users", chatChannel.auto_join_users);
- })
- .catch((event) => {
- if (event.jqXHR?.responseJSON?.errors) {
- this.flash(event.jqXHR.responseJSON.errors.join("\n"), "error");
- }
- });
+ @reads("channel.isCategoryChannel") togglingChannelWideMentionsAvailable;
+
+ @computed("channel.isCategoryChannel")
+ get autoJoinAvailable() {
+ return (
+ this.siteSettings.max_chat_auto_joined_users > 0 &&
+ this.channel.isCategoryChannel
+ );
}
- @action
- saveNotificationSettings(key, value) {
- if (this.channel[key] === value) {
- return;
- }
-
- const camelizedKey = camelize(`saved_${key}`);
- this.set(camelizedKey, false);
-
- const settings = {};
- settings[key] = value;
- return ChatApi.updateChatChannelNotificationsSettings(
- this.channel.id,
- settings
- )
- .then((membership) => {
- this.channel.current_user_membership.setProperties({
- muted: membership.muted,
- desktop_notification_level: membership.desktop_notification_level,
- mobile_notification_level: membership.mobile_notification_level,
- });
- this.set(camelizedKey, true);
- })
- .finally(() => {
- discourseLater(() => {
- if (this.isDestroying || this.isDestroyed) {
- return;
- }
-
- this.set(camelizedKey, false);
- }, 2000);
- });
+ @computed("autoJoinAvailable", "togglingChannelWideMentionsAvailable")
+ get adminSectionAvailable() {
+ return (
+ this.chatGuardian.canEditChatChannel &&
+ (this.autoJoinAvailable || this.togglingChannelWideMentionsAvailable)
+ );
}
@computed(
@@ -98,12 +78,24 @@ export default class ChatChannelSettingsView extends Component {
);
}
- @computed("channel.isCategoryChannel")
- get autoJoinAvailable() {
- return (
- this.siteSettings.max_chat_auto_joined_users > 0 &&
- this.channel.isCategoryChannel
- );
+ @action
+ saveNotificationSettings(key, value) {
+ if (this.channel[key] === value) {
+ return;
+ }
+
+ const settings = {};
+ settings[key] = value;
+ return ChatApi.updateChatChannelNotificationsSettings(
+ this.channel.id,
+ settings
+ ).then((membership) => {
+ this.channel.current_user_membership.setProperties({
+ muted: membership.muted,
+ desktop_notification_level: membership.desktop_notification_level,
+ mobile_notification_level: membership.mobile_notification_level,
+ });
+ });
}
@action
@@ -133,8 +125,17 @@ export default class ChatChannelSettingsView extends Component {
}
}
+ @action
+ onToggleChannelWideMentions() {
+ return this._updateChannelProperty(
+ this.channel,
+ "allow_channel_wide_mentions",
+ !this.channel.allow_channel_wide_mentions
+ );
+ }
+
onDisableAutoJoinUsers() {
- this._updateAutoJoinUsers(false);
+ return this._updateChannelProperty(this.channel, "auto_join_users", false);
}
onEnableAutoJoinUsers() {
@@ -142,7 +143,26 @@ export default class ChatChannelSettingsView extends Component {
message: I18n.t("chat.settings.auto_join_users_warning", {
category: this.channel.chatable.name,
}),
- didConfirm: () => this._updateAutoJoinUsers(true),
+ didConfirm: () =>
+ this._updateChannelProperty(this.channel, "auto_join_users", true),
});
}
+
+ _updateChannelProperty(channel, property, value) {
+ if (channel[property] === value) {
+ return Promise.resolve();
+ }
+
+ const payload = {};
+ payload[property] = value;
+ return ChatApi.modifyChatChannel(channel.id, payload)
+ .then((updatedChannel) => {
+ channel.set(property, updatedChannel[property]);
+ })
+ .catch((event) => {
+ if (event.jqXHR?.responseJSON?.errors) {
+ this.flash(event.jqXHR.responseJSON.errors.join("\n"), "error");
+ }
+ });
+ }
}
diff --git a/plugins/chat/assets/javascripts/discourse/initializers/chat-setup.js b/plugins/chat/assets/javascripts/discourse/initializers/chat-setup.js
index e00ee2b59b6..333a026f38f 100644
--- a/plugins/chat/assets/javascripts/discourse/initializers/chat-setup.js
+++ b/plugins/chat/assets/javascripts/discourse/initializers/chat-setup.js
@@ -130,15 +130,15 @@ export default {
api.addToHeaderIcons("header-chat-link");
- api.decorateChatMessage(function (chatMessage) {
+ api.decorateChatMessage(function (chatMessage, chatChannel) {
if (!this.currentUser) {
return;
}
- const highlightable = [
- `@${this.currentUser.username}`,
- ...MENTION_KEYWORDS.map((k) => `@${k}`),
- ];
+ const highlightable = [`@${this.currentUser.username}`];
+ if (chatChannel.allow_channel_wide_mentions) {
+ highlightable.push(...MENTION_KEYWORDS.map((k) => `@${k}`));
+ }
chatMessage.querySelectorAll(".mention").forEach((node) => {
const mention = node.textContent.trim();
diff --git a/plugins/chat/assets/stylesheets/common/chat-channel-info.scss b/plugins/chat/assets/stylesheets/common/chat-channel-info.scss
index ca997c77258..29f3cb30cda 100644
--- a/plugins/chat/assets/stylesheets/common/chat-channel-info.scss
+++ b/plugins/chat/assets/stylesheets/common/chat-channel-info.scss
@@ -32,20 +32,11 @@
color: var(--primary-medium);
}
-// Settings view
-.channel-settings-view__saved {
- color: var(--success);
- padding-left: 0.5rem;
-
- .d-icon-check {
- margin-right: 0.25rem;
- }
-}
-
.channel-settings-view__desktop-notification-level-selector,
.channel-settings-view__mobile-notification-level-selector,
.channel-settings-view__muted-selector,
-.channel-settings-view__auto-join-selector {
+.channel-settings-view__auto-join-selector,
+.channel-settings-view__channel-wide-mentions-selector {
width: 220px;
}
diff --git a/plugins/chat/assets/stylesheets/common/chat-channel-settings-saved-indicator.scss b/plugins/chat/assets/stylesheets/common/chat-channel-settings-saved-indicator.scss
new file mode 100644
index 00000000000..e28129f3e17
--- /dev/null
+++ b/plugins/chat/assets/stylesheets/common/chat-channel-settings-saved-indicator.scss
@@ -0,0 +1,9 @@
+.chat-channel-settings-saved-indicator {
+ padding-left: 0.5rem;
+ color: var(--success);
+ font-weight: normal;
+
+ .d-icon-check {
+ margin-right: 0.25rem;
+ }
+}
diff --git a/plugins/chat/assets/stylesheets/desktop/desktop.scss b/plugins/chat/assets/stylesheets/desktop/desktop.scss
index 7515793b304..da4b054ce10 100644
--- a/plugins/chat/assets/stylesheets/desktop/desktop.scss
+++ b/plugins/chat/assets/stylesheets/desktop/desktop.scss
@@ -148,7 +148,8 @@
}
.chat-form {
- &__description.-autojoin {
+ &__description.-autojoin,
+ &__description.-channel-wide-mentions {
max-width: 50%;
}
}
diff --git a/plugins/chat/config/locales/client.en.yml b/plugins/chat/config/locales/client.en.yml
index 4a5f3b61d4a..93215b1a59c 100644
--- a/plugins/chat/config/locales/client.en.yml
+++ b/plugins/chat/config/locales/client.en.yml
@@ -289,6 +289,8 @@ en:
always: "For all activity"
settings:
+ channel_wide_mentions_label: "Allow @all and @here mentions"
+ channel_wide_mentions_description: "Allow users to notify all members of #%{channel} with @all or only those who are active in the moment with @here"
auto_join_users_label: "Automatically add users"
auto_join_users_info: "Check hourly which users have been active in the last 3 months and, if they have access to the %{category} category, add them to this channel."
enable_auto_join_users: "Automatically add all recently active users"
diff --git a/plugins/chat/db/migrate/20221118104708_add_allow_channel_wide_mentions_to_chat_channels.rb b/plugins/chat/db/migrate/20221118104708_add_allow_channel_wide_mentions_to_chat_channels.rb
new file mode 100644
index 00000000000..b06642af164
--- /dev/null
+++ b/plugins/chat/db/migrate/20221118104708_add_allow_channel_wide_mentions_to_chat_channels.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddAllowChannelWideMentionsToChatChannels < ActiveRecord::Migration[7.0]
+ def change
+ add_column :chat_channels, :allow_channel_wide_mentions, :boolean, null: false, default: true
+ end
+end
diff --git a/plugins/chat/lib/chat_notifier.rb b/plugins/chat/lib/chat_notifier.rb
index d2fcc4496ad..e8a8d662978 100644
--- a/plugins/chat/lib/chat_notifier.rb
+++ b/plugins/chat/lib/chat_notifier.rb
@@ -164,7 +164,7 @@ class Chat::ChatNotifier
def expand_global_mention(to_notify, already_covered_ids)
typed_global_mention = direct_mentions_from_cooked.include?("@all")
- if typed_global_mention
+ if typed_global_mention && @chat_channel.allow_channel_wide_mentions
to_notify[:global_mentions] = members_accepting_channel_wide_notifications
.where.not(username_lower: normalized_mentions(direct_mentions_from_cooked))
.where.not(id: already_covered_ids)
@@ -179,7 +179,7 @@ class Chat::ChatNotifier
def expand_here_mention(to_notify, already_covered_ids)
typed_here_mention = direct_mentions_from_cooked.include?("@here")
- if typed_here_mention
+ if typed_here_mention && @chat_channel.allow_channel_wide_mentions
to_notify[:here_mentions] = members_accepting_channel_wide_notifications
.where("last_seen_at > ?", 5.minutes.ago)
.where.not(username_lower: normalized_mentions(direct_mentions_from_cooked))
diff --git a/plugins/chat/plugin.rb b/plugins/chat/plugin.rb
index e8958816dfa..c2f7c56ee44 100644
--- a/plugins/chat/plugin.rb
+++ b/plugins/chat/plugin.rb
@@ -66,6 +66,7 @@ register_asset "stylesheets/common/chat-onebox.scss"
register_asset "stylesheets/common/chat-skeleton.scss"
register_asset "stylesheets/colors.scss", :color_definitions
register_asset "stylesheets/common/reviewable-chat-message.scss"
+register_asset "stylesheets/common/chat-channel-settings-saved-indicator.scss"
register_svg_icon "comments"
register_svg_icon "comment-slash"
diff --git a/plugins/chat/spec/lib/chat_notifier_spec.rb b/plugins/chat/spec/lib/chat_notifier_spec.rb
index fa787797d7a..44837775673 100644
--- a/plugins/chat/spec/lib/chat_notifier_spec.rb
+++ b/plugins/chat/spec/lib/chat_notifier_spec.rb
@@ -49,6 +49,15 @@ describe Chat::ChatNotifier do
expect(to_notify[list_key]).to be_empty
end
+ it "will never mention when channel is not accepting channel wide mentions" do
+ channel.update!(allow_channel_wide_mentions: false)
+ msg = build_cooked_msg(mention, user_1)
+
+ to_notify = described_class.new(msg, msg.created_at).notify_new
+
+ expect(to_notify[list_key]).to be_empty
+ end
+
it "includes all members of a channel except the sender" do
msg = build_cooked_msg(mention, user_1)
diff --git a/plugins/chat/spec/models/chat_channel_spec.rb b/plugins/chat/spec/models/chat_channel_spec.rb
index 475390a07a9..3e1d6ec3529 100644
--- a/plugins/chat/spec/models/chat_channel_spec.rb
+++ b/plugins/chat/spec/models/chat_channel_spec.rb
@@ -13,13 +13,25 @@ RSpec.describe ChatChannel do
end
context "when the slug is not nil" do
- before do
- category_channel.update!(slug: "some-cool-channel")
- end
+ before { category_channel.update!(slug: "some-cool-channel") }
it "includes the slug for the channel" do
- expect(category_channel.relative_url).to eq("/chat/channel/#{category_channel.id}/some-cool-channel")
+ expect(category_channel.relative_url).to eq(
+ "/chat/channel/#{category_channel.id}/some-cool-channel",
+ )
end
end
end
+
+ describe "#allow_channel_wide_mentions" do
+ it "defaults to true" do
+ expect(category_channel.allow_channel_wide_mentions).to be(true)
+ end
+
+ it "cant be nullified" do
+ expect { category_channel.update!(allow_channel_wide_mentions: nil) }.to raise_error(
+ ActiveRecord::NotNullViolation,
+ )
+ end
+ end
end
diff --git a/plugins/chat/spec/requests/api/chat_channels_controller_spec.rb b/plugins/chat/spec/requests/api/chat_channels_controller_spec.rb
index 4083ab0c6ba..f3da20c1d77 100644
--- a/plugins/chat/spec/requests/api/chat_channels_controller_spec.rb
+++ b/plugins/chat/spec/requests/api/chat_channels_controller_spec.rb
@@ -277,6 +277,17 @@ describe Chat::Api::ChatChannelsController do
expect(response.parsed_body).to match_response_schema("category_chat_channel")
end
+ describe "when updating allow_channel_wide_mentions" do
+ it "sets the new value" do
+ put "/chat/api/chat_channels/#{chat_channel.id}.json",
+ params: {
+ allow_channel_wide_mentions: false,
+ }
+
+ expect(response.parsed_body["allow_channel_wide_mentions"]).to eq(false)
+ end
+ end
+
describe "Updating a channel to add users automatically" do
it "sets the channel to auto-update users automatically" do
put "/chat/api/chat_channels/#{chat_channel.id}.json", params: { auto_join_users: true }
diff --git a/plugins/chat/spec/serializer/chat_channel_serializer_spec.rb b/plugins/chat/spec/serializer/chat_channel_serializer_spec.rb
index 4a164ae8720..86ccea5c3fb 100644
--- a/plugins/chat/spec/serializer/chat_channel_serializer_spec.rb
+++ b/plugins/chat/spec/serializer/chat_channel_serializer_spec.rb
@@ -17,6 +17,10 @@ describe ChatChannelSerializer do
it "does not return any sort of archive status" do
expect(subject.as_json.key?(:archive_completed)).to eq(false)
end
+
+ it "includes allow_channel_wide_mentions" do
+ expect(subject.as_json.key?(:allow_channel_wide_mentions)).to eq(true)
+ end
end
context "when user is staff" do
@@ -37,6 +41,10 @@ describe ChatChannelSerializer do
chat_channel.reload
expect(subject.as_json.key?(:archive_completed)).to eq(true)
end
+
+ it "includes allow_channel_wide_mentions" do
+ expect(subject.as_json.key?(:allow_channel_wide_mentions)).to eq(true)
+ end
end
end
end
diff --git a/plugins/chat/test/javascripts/chat-fixtures.js b/plugins/chat/test/javascripts/chat-fixtures.js
index e91f5b563a4..df68bc1597a 100644
--- a/plugins/chat/test/javascripts/chat-fixtures.js
+++ b/plugins/chat/test/javascripts/chat-fixtures.js
@@ -31,6 +31,7 @@ export const directMessageChannels = [
muted: false,
following: true,
},
+ allow_channel_wide_mentions: true,
last_message_sent_at: "2021-07-20T08:14:16.950Z",
message_bus_last_ids: {
new_mentions: 0,
@@ -66,6 +67,7 @@ export const directMessageChannels = [
muted: false,
following: true,
},
+ allow_channel_wide_mentions: true,
last_message_sent_at: "2021-07-05T12:04:00.850Z",
message_bus_last_ids: {
new_mentions: 0,
@@ -107,6 +109,7 @@ export const chatChannels = {
title: "Site",
status: "open",
chatable: chatables[1],
+ allow_channel_wide_mentions: true,
last_message_sent_at: "2021-07-24T08:14:16.950Z",
current_user_membership: {
unread_count: 0,
@@ -126,6 +129,7 @@ export const chatChannels = {
title: "Bug",
status: "open",
chatable: chatables[1],
+ allow_channel_wide_mentions: true,
last_message_sent_at: "2021-07-15T08:14:16.950Z",
current_user_membership: {
unread_count: 0,
@@ -145,6 +149,7 @@ export const chatChannels = {
title: "Public category",
status: "open",
chatable: chatables[8],
+ allow_channel_wide_mentions: true,
last_message_sent_at: "2021-07-14T08:14:16.950Z",
current_user_membership: {
unread_count: 0,
@@ -164,6 +169,7 @@ export const chatChannels = {
title: "Public category (read-only)",
status: "read_only",
chatable: chatables[8],
+ allow_channel_wide_mentions: true,
last_message_sent_at: "2021-07-10T08:14:16.950Z",
current_user_membership: {
unread_count: 0,
@@ -183,6 +189,7 @@ export const chatChannels = {
title: "Public category (closed)",
status: "closed",
chatable: chatables[8],
+ allow_channel_wide_mentions: true,
last_message_sent_at: "2021-07-21T08:14:16.950Z",
current_user_membership: {
unread_count: 0,
@@ -202,6 +209,7 @@ export const chatChannels = {
title: "Public category (archived)",
status: "archived",
chatable: chatables[8],
+ allow_channel_wide_mentions: true,
last_message_sent_at: "2021-07-25T08:14:16.950Z",
current_user_membership: {
unread_count: 0,
@@ -221,6 +229,7 @@ export const chatChannels = {
title: "Another Category",
status: "open",
chatable: chatables[12],
+ allow_channel_wide_mentions: true,
last_message_sent_at: "2021-07-02T08:14:16.950Z",
current_user_membership: {
unread_count: 0,
diff --git a/plugins/chat/test/javascripts/components/chat-channel-settings-saved-indicator-test.js b/plugins/chat/test/javascripts/components/chat-channel-settings-saved-indicator-test.js
new file mode 100644
index 00000000000..6f03050cb05
--- /dev/null
+++ b/plugins/chat/test/javascripts/components/chat-channel-settings-saved-indicator-test.js
@@ -0,0 +1,31 @@
+import { module, test } from "qunit";
+import { setupRenderingTest } from "discourse/tests/helpers/component-test";
+import { render, settled } from "@ember/test-helpers";
+import { hbs } from "ember-cli-htmlbars";
+
+module(
+ "Discourse Chat | Component | chat-channel-settings-saved-indicator",
+ function (hooks) {
+ setupRenderingTest(hooks);
+
+ test("when property changes", async function (assert) {
+ await render(
+ hbs``
+ );
+
+ assert
+ .dom(".chat-channel-settings-saved-indicator.is-active")
+ .doesNotExist();
+
+ this.set("property", 1);
+
+ assert.dom(".chat-channel-settings-saved-indicator.is-active").exists();
+
+ await settled();
+
+ assert
+ .dom(".chat-channel-settings-saved-indicator.is-active")
+ .doesNotExist();
+ });
+ }
+);
diff --git a/plugins/chat/test/javascripts/components/chat-channel-settings-view-test.js b/plugins/chat/test/javascripts/components/chat-channel-settings-view-test.js
index 73dce053f4f..4a97c2d31ac 100644
--- a/plugins/chat/test/javascripts/components/chat-channel-settings-view-test.js
+++ b/plugins/chat/test/javascripts/components/chat-channel-settings-view-test.js
@@ -9,7 +9,14 @@ import { CHATABLE_TYPES } from "discourse/plugins/chat/discourse/models/chat-cha
import { module } from "qunit";
function membershipFixture(id, options = {}) {
- options = Object.assign({}, options, { muted: false, following: true });
+ options = Object.assign(
+ {},
+ {
+ muted: false,
+ following: true,
+ },
+ options
+ );
return {
following: options.following,
@@ -99,7 +106,7 @@ module(
return [
200,
{ "Content-Type": "application/json" },
- membershipFixture(this.channel.id, { muted: true }),
+ membershipFixture(this.channel.id, { muted: false }),
];
}
);
@@ -111,6 +118,34 @@ module(
assert.equal(sk.header().value(), "false");
},
});
+
+ componentTest("allow channel wide mentions", {
+ template: hbs`{{chat-channel-settings-view channel=channel}}`,
+
+ beforeEach() {
+ this.set("channel", fabricators.chatChannel());
+ },
+
+ async test(assert) {
+ pretender.put(`/chat/api/chat_channels/${this.channel.id}.json`, () => {
+ return [
+ 200,
+ { "Content-Type": "application/json" },
+ {
+ allow_channel_wide_mentions: false,
+ },
+ ];
+ });
+
+ const sk = selectKit(
+ ".channel-settings-view__channel-wide-mentions-selector"
+ );
+ await sk.expand();
+ await sk.selectRowByName("No");
+
+ assert.equal(sk.header().value(), "false");
+ },
+ });
}
);
@@ -205,7 +240,7 @@ module(
return [
200,
{ "Content-Type": "application/json" },
- membershipFixture(this.channel.id, { muted: true }),
+ membershipFixture(this.channel.id, { muted: false }),
];
}
);
@@ -217,5 +252,24 @@ module(
assert.equal(sk.header().value(), "false");
},
});
+
+ componentTest("allow channel wide mentions", {
+ template: hbs`{{chat-channel-settings-view channel=channel}}`,
+
+ beforeEach() {
+ this.set(
+ "channel",
+ fabricators.chatChannel({
+ chatable_type: CHATABLE_TYPES.directMessageChannel,
+ })
+ );
+ },
+
+ async test(assert) {
+ assert
+ .dom(".channel-settings-view__channel-wide-mentions-selector")
+ .doesNotExist();
+ },
+ });
}
);
diff --git a/plugins/chat/test/javascripts/helpers/fabricators.js b/plugins/chat/test/javascripts/helpers/fabricators.js
index fdc766f2c15..924685b6e6e 100644
--- a/plugins/chat/test/javascripts/helpers/fabricators.js
+++ b/plugins/chat/test/javascripts/helpers/fabricators.js
@@ -31,6 +31,7 @@ export default {
name: "My category name",
chatable: categoryChatableFabricator(),
last_message_sent_at: "2021-11-08T21:26:05.710Z",
+ allow_channel_wide_mentions: true,
message_bus_last_ids: {
new_mentions: 0,
new_messages: 0,