diff --git a/plugins/chat/app/controllers/chat/api/channels_controller.rb b/plugins/chat/app/controllers/chat/api/channels_controller.rb index 47283654fee..c4d99c44cbb 100644 --- a/plugins/chat/app/controllers/chat/api/channels_controller.rb +++ b/plugins/chat/app/controllers/chat/api/channels_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true CHANNEL_EDITABLE_PARAMS = %i[name description slug] -CATEGORY_CHANNEL_EDITABLE_PARAMS = %i[auto_join_users allow_channel_wide_mentions] +CATEGORY_CHANNEL_EDITABLE_PARAMS = %i[auto_join_users allow_channel_wide_mentions threading_enabled] class Chat::Api::ChannelsController < Chat::ApiController def index @@ -36,7 +36,14 @@ class Chat::Api::ChannelsController < Chat::ApiController def create channel_params = - params.require(:channel).permit(:chatable_id, :name, :slug, :description, :auto_join_users) + params.require(:channel).permit( + :chatable_id, + :name, + :slug, + :description, + :auto_join_users, + :threading_enabled, + ) # NOTE: We don't allow creating channels for anything but category chatable types # at the moment. This may change in future, at which point we will need to pass in diff --git a/plugins/chat/app/services/chat/create_category_channel.rb b/plugins/chat/app/services/chat/create_category_channel.rb index 0d25cd3c749..e13a35fb449 100644 --- a/plugins/chat/app/services/chat/create_category_channel.rb +++ b/plugins/chat/app/services/chat/create_category_channel.rb @@ -10,6 +10,7 @@ module Chat # description: "This is the best channel", # slug: "super-channel", # category_id: category.id, + # threading_enabled: true, # ) # class CreateCategoryChannel @@ -23,6 +24,7 @@ module Chat # @option params_to_create [String] slug # @option params_to_create [Boolean] auto_join_users # @option params_to_create [Integer] category_id + # @option params_to_create [Boolean] threading_enabled # @return [Service::Base::Context] policy :can_create_channel @@ -42,8 +44,12 @@ module Chat attribute :slug, :string attribute :category_id, :integer attribute :auto_join_users, :boolean, default: false + attribute :threading_enabled, :boolean, default: false - before_validation { self.auto_join_users = auto_join_users.presence || false } + before_validation do + self.auto_join_users = auto_join_users.presence || false + self.threading_enabled = threading_enabled.presence || false + end validates :category_id, presence: true validates :name, length: { maximum: SiteSetting.max_topic_title_length } @@ -70,6 +76,7 @@ module Chat description: contract.description, user_count: 1, auto_join_users: contract.auto_join_users, + threading_enabled: contract.threading_enabled, ) end diff --git a/plugins/chat/app/services/chat/update_channel.rb b/plugins/chat/app/services/chat/update_channel.rb index 08534a291d8..93a64447f2d 100644 --- a/plugins/chat/app/services/chat/update_channel.rb +++ b/plugins/chat/app/services/chat/update_channel.rb @@ -3,8 +3,8 @@ module Chat # Service responsible for updating a chat channel's name, slug, and description. # - # For a CategoryChannel, the settings for auto_join_users and allow_channel_wide_mentions - # are also editable. + # For a CategoryChannel, the settings for auto_join_users, allow_channel_wide_mentions + # and threading_enabled are also editable. # # @example # Service::Chat::UpdateChannel.call( @@ -13,6 +13,7 @@ module Chat # name: "SuperChannel", # description: "This is the best channel", # slug: "super-channel", + # threading_enaled: true, # ) # class UpdateChannel @@ -43,6 +44,7 @@ module Chat attribute :name, :string attribute :description, :string attribute :slug, :string + attribute :threading_enabled, :boolean, default: false attribute :auto_join_users, :boolean, default: false attribute :allow_channel_wide_mentions, :boolean, default: true 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 a27c3aec80d..78ca5ba2726 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 @@ -1,36 +1,36 @@
-
+
- {{#unless this.channel.currentUserMembership.muted}} -
+ {{#unless @channel.currentUserMembership.muted}} +
-
+
{{d-icon "info-circle"}} - +
@@ -72,28 +72,29 @@

{{i18n "chat.settings.admin_title"}}

+ {{#if this.autoJoinAvailable}} -
+
-

+

{{i18n "chat.settings.auto_join_users_info" - category=this.channel.chatable.name + category=@channel.chatable.name }}

@@ -101,36 +102,62 @@ {{/if}} {{#if this.togglingChannelWideMentionsAvailable}} -
+
-

+

{{i18n "chat.settings.channel_wide_mentions_description" - channel=this.channel.title + channel=@channel.title }}

{{/if}} + + {{#if this.togglingThreadingAvailable}} +
+
+ + +
+
+ {{/if}} {{/if}} -{{#unless this.channel.isDirectMessageChannel}} +{{#unless @channel.isDirectMessageChannel}}
{{#if (chat-guardian "can-edit-chat-channel")}} - {{#if (chat-guardian "can-archive-channel" this.channel)}} + {{#if (chat-guardian "can-archive-channel" @channel)}}
{{/if}} - {{#if this.channel.isClosed}} + {{#if @channel.isClosed}}
0 && - this.channel.isCategoryChannel + this.siteSettings.enable_experimental_chat_threaded_discussions && + this.args.channel.isCategoryChannel && + this.currentUser?.admin + ); + } + + get autoJoinAvailable() { + return ( + this.siteSettings.max_chat_auto_joined_users > 0 && + this.args.channel.isCategoryChannel ); } - @computed("autoJoinAvailable", "togglingChannelWideMentionsAvailable") get adminSectionAvailable() { return ( this.chatGuardian.canEditChatChannel() && @@ -65,30 +78,29 @@ export default class ChatChannelSettingsView extends Component { ); } - @computed( - "siteSettings.chat_allow_archiving_channels", - "channel.{isArchived,isReadOnly}" - ) get canArchiveChannel() { return ( this.siteSettings.chat_allow_archiving_channels && - !this.channel.isArchived && - !this.channel.isReadOnly + !this.args.channel.isArchived && + !this.args.channel.isReadOnly ); } @action saveNotificationSettings(frontendKey, backendKey, newValue) { - if (this.channel.currentUserMembership[frontendKey] === newValue) { + if (this.args.channel.currentUserMembership[frontendKey] === newValue) { return; } const settings = {}; settings[backendKey] = newValue; return this.chatApi - .updateCurrentUserChannelNotificationsSettings(this.channel.id, settings) + .updateCurrentUserChannelNotificationsSettings( + this.args.channel.id, + settings + ) .then((result) => { - this.channel.currentUserMembership[frontendKey] = + this.args.channel.currentUserMembership[frontendKey] = result.membership[backendKey]; }); } @@ -96,76 +108,89 @@ export default class ChatChannelSettingsView extends Component { @action onArchiveChannel() { const controller = showModal("chat-channel-archive-modal"); - controller.set("chatChannel", this.channel); + controller.set("chatChannel", this.args.channel); } @action onDeleteChannel() { const controller = showModal("chat-channel-delete-modal"); - controller.set("chatChannel", this.channel); + controller.set("chatChannel", this.args.channel); } @action onToggleChannelState() { const controller = showModal("chat-channel-toggle"); - controller.set("chatChannel", this.channel); + controller.set("chatChannel", this.args.channel); } @action onToggleAutoJoinUsers() { - if (!this.channel.autoJoinUsers) { + if (!this.args.channel.autoJoinUsers) { this.onEnableAutoJoinUsers(); } else { this.onDisableAutoJoinUsers(); } } + @action + onToggleThreadingEnabled(value) { + return this._updateChannelProperty( + this.args.channel, + "threading_enabled", + value + ).then((result) => { + this.args.channel.threadingEnabled = result.channel.threading_enabled; + }); + } + @action onToggleChannelWideMentions() { - const newValue = !this.channel.allowChannelWideMentions; - if (this.channel.allowChannelWideMentions === newValue) { + const newValue = !this.args.channel.allowChannelWideMentions; + if (this.args.channel.allowChannelWideMentions === newValue) { return; } return this._updateChannelProperty( - this.channel, + this.args.channel, "allow_channel_wide_mentions", newValue ).then((result) => { - this.channel.allowChannelWideMentions = + this.args.channel.allowChannelWideMentions = result.channel.allow_channel_wide_mentions; }); } onDisableAutoJoinUsers() { - if (this.channel.autoJoinUsers === false) { + if (this.args.channel.autoJoinUsers === false) { return; } return this._updateChannelProperty( - this.channel, + this.args.channel, "auto_join_users", false ).then((result) => { - this.channel.autoJoinUsers = result.channel.auto_join_users; + this.args.channel.autoJoinUsers = result.channel.auto_join_users; }); } onEnableAutoJoinUsers() { - if (this.channel.autoJoinUsers === true) { + if (this.args.channel.autoJoinUsers === true) { return; } this.dialog.confirm({ message: I18n.t("chat.settings.auto_join_users_warning", { - category: this.channel.chatable.name, + category: this.args.channel.chatable.name, }), didConfirm: () => - this._updateChannelProperty(this.channel, "auto_join_users", true).then( - (result) => { - this.channel.autoJoinUsers = result.channel.auto_join_users; - } - ), + this._updateChannelProperty( + this.args.channel, + "auto_join_users", + true + ).then((result) => { + this.args.channel.autoJoinUsers = result.channel.auto_join_users; + }), }); } diff --git a/plugins/chat/assets/javascripts/discourse/controllers/create-channel.js b/plugins/chat/assets/javascripts/discourse/controllers/create-channel.js index 48de049f1f5..d4e464a0105 100644 --- a/plugins/chat/assets/javascripts/discourse/controllers/create-channel.js +++ b/plugins/chat/assets/javascripts/discourse/controllers/create-channel.js @@ -26,6 +26,8 @@ export default class CreateChannelController extends Controller.extend( @service chatChannelsManager; @service chatApi; @service router; + @service currentUser; + @service siteSettings; category = null; categoryId = null; @@ -37,10 +39,18 @@ export default class CreateChannelController extends Controller.extend( autoJoinUsers = false; autoJoinWarning = ""; loadingPermissionHint = false; + threadingEnabled = false; @notEmpty("category") categorySelected; @gt("siteSettings.max_chat_auto_joined_users", 0) autoJoinAvailable; + get threadingAvailable() { + return ( + this.siteSettings.enable_experimental_chat_threaded_discussions && + this.categorySelected + ); + } + @computed("categorySelected", "name") get createDisabled() { return !this.categorySelected || isBlank(this.name); @@ -78,6 +88,7 @@ export default class CreateChannelController extends Controller.extend( slug: this.slug || this.autoGeneratedSlug, description: this.description, auto_join_users: this.autoJoinUsers, + threading_enabled: this.threadingEnabled, }; return this.chatApi diff --git a/plugins/chat/assets/javascripts/discourse/templates/modal/create-channel.hbs b/plugins/chat/assets/javascripts/discourse/templates/modal/create-channel.hbs index ecc01d51c09..278f03c1c6a 100644 --- a/plugins/chat/assets/javascripts/discourse/templates/modal/create-channel.hbs +++ b/plugins/chat/assets/javascripts/discourse/templates/modal/create-channel.hbs @@ -1,50 +1,50 @@ -
-