diff --git a/plugins/chat/app/controllers/chat/api/current_user_threads_controller.rb b/plugins/chat/app/controllers/chat/api/current_user_threads_controller.rb index 5a2b5577990..f8bc218ab7c 100644 --- a/plugins/chat/app/controllers/chat/api/current_user_threads_controller.rb +++ b/plugins/chat/app/controllers/chat/api/current_user_threads_controller.rb @@ -21,4 +21,11 @@ class Chat::Api::CurrentUserThreadsController < Chat::ApiController on_model_not_found(:threads) { render json: success_json.merge(threads: []) } end end + + def thread_count + with_service(::Chat::LookupUserThreads) do + on_success { render json: success_json.merge(thread_count: result.threads.size) } + on_model_not_found(:threads) { render json: success_json.merge(thread_count: 0) } + end + end end diff --git a/plugins/chat/assets/javascripts/discourse/chat-route-map.js b/plugins/chat/assets/javascripts/discourse/chat-route-map.js index e795d21a2c4..50c8a11a568 100644 --- a/plugins/chat/assets/javascripts/discourse/chat-route-map.js +++ b/plugins/chat/assets/javascripts/discourse/chat-route-map.js @@ -8,6 +8,8 @@ export default function () { }); }); + this.route("direct-messages", { path: "/direct-messages" }); + this.route("channels", { path: "/channels" }); this.route("threads", { path: "/threads" }); this.route( diff --git a/plugins/chat/assets/javascripts/discourse/components/channels-list-direct.gjs b/plugins/chat/assets/javascripts/discourse/components/channels-list-direct.gjs new file mode 100644 index 00000000000..50b38c6dfd9 --- /dev/null +++ b/plugins/chat/assets/javascripts/discourse/components/channels-list-direct.gjs @@ -0,0 +1,133 @@ +import Component from "@glimmer/component"; +import { fn, hash } from "@ember/helper"; +import { on } from "@ember/modifier"; +import { action } from "@ember/object"; +import { inject as service } from "@ember/service"; +import DButton from "discourse/components/d-button"; +import PluginOutlet from "discourse/components/plugin-outlet"; +import dIcon from "discourse-common/helpers/d-icon"; +import i18n from "discourse-common/helpers/i18n"; +import ChatModalNewMessage from "discourse/plugins/chat/discourse/components/chat/modal/new-message"; +import ChatChannelRow from "./chat-channel-row"; + +export default class ChannelsListDirect extends Component { + @service chat; + @service chatChannelsManager; + @service site; + @service modal; + + @action + openNewMessageModal() { + this.modal.show(ChatModalNewMessage); + } + + get inSidebar() { + return this.args.inSidebar ?? false; + } + + get createDirectMessageChannelLabel() { + if (!this.canCreateDirectMessageChannel) { + return "chat.direct_messages.cannot_create"; + } + + return "chat.direct_messages.new"; + } + + get showDirectMessageChannels() { + return ( + this.canCreateDirectMessageChannel || !this.directMessageChannelsEmpty + ); + } + + get canCreateDirectMessageChannel() { + return this.chat.userCanDirectMessage; + } + + get directMessageChannelClasses() { + return `channels-list-container direct-message-channels ${ + this.inSidebar ? "collapsible-sidebar-section" : "" + }`; + } + + get directMessageChannelsEmpty() { + return this.chatChannelsManager.directMessageChannels?.length === 0; + } + + @action + toggleChannelSection(section) { + this.args.toggleSection(section); + } + + +} diff --git a/plugins/chat/assets/javascripts/discourse/components/channels-list-public.gjs b/plugins/chat/assets/javascripts/discourse/components/channels-list-public.gjs new file mode 100644 index 00000000000..7c45c836785 --- /dev/null +++ b/plugins/chat/assets/javascripts/discourse/components/channels-list-public.gjs @@ -0,0 +1,141 @@ +import Component from "@glimmer/component"; +import { fn, hash } from "@ember/helper"; +import { on } from "@ember/modifier"; +import { action } from "@ember/object"; +import { LinkTo } from "@ember/routing"; +import { inject as service } from "@ember/service"; +import PluginOutlet from "discourse/components/plugin-outlet"; +import concatClass from "discourse/helpers/concat-class"; +import dIcon from "discourse-common/helpers/d-icon"; +import i18n from "discourse-common/helpers/i18n"; +import ChatChannelRow from "./chat-channel-row"; + +export default class ChannelsListPublic extends Component { + @service chatChannelsManager; + @service site; + @service siteSettings; + @service currentUser; + + get inSidebar() { + return this.args.inSidebar ?? false; + } + + get publicMessageChannelsEmpty() { + return this.chatChannelsManager.publicMessageChannels?.length === 0; + } + + get displayPublicChannels() { + if (!this.siteSettings.enable_public_channels) { + return false; + } + + if (this.publicMessageChannelsEmpty) { + return ( + this.currentUser?.staff || + this.currentUser?.has_joinable_public_channels + ); + } + + return true; + } + + get hasUnreadThreads() { + return this.chatChannelsManager.publicMessageChannels.some( + (channel) => channel.unreadThreadsCount > 0 + ); + } + + @action + toggleChannelSection(section) { + this.args.toggleSection(section); + } + + +} diff --git a/plugins/chat/assets/javascripts/discourse/components/channels-list.gjs b/plugins/chat/assets/javascripts/discourse/components/channels-list.gjs index b8db884bc28..15cbe11d26b 100644 --- a/plugins/chat/assets/javascripts/discourse/components/channels-list.gjs +++ b/plugins/chat/assets/javascripts/discourse/components/channels-list.gjs @@ -1,298 +1,16 @@ import Component from "@glimmer/component"; -import { tracked } from "@glimmer/tracking"; -import { fn, hash } from "@ember/helper"; -import { on } from "@ember/modifier"; -import { action } from "@ember/object"; -import didInsert from "@ember/render-modifiers/modifiers/did-insert"; -import { LinkTo } from "@ember/routing"; -import { schedule } from "@ember/runloop"; import { inject as service } from "@ember/service"; -import DButton from "discourse/components/d-button"; -import PluginOutlet from "discourse/components/plugin-outlet"; -import concatClass from "discourse/helpers/concat-class"; -import noop from "discourse/helpers/noop"; -import dIcon from "discourse-common/helpers/d-icon"; -import i18n from "discourse-common/helpers/i18n"; -import { bind } from "discourse-common/utils/decorators"; -import and from "truth-helpers/helpers/and"; -import not from "truth-helpers/helpers/not"; -import ChatModalNewMessage from "discourse/plugins/chat/discourse/components/chat/modal/new-message"; -import onResize from "../modifiers/chat/on-resize"; -import ChatChannelRow from "./chat-channel-row"; +import ChannelsListDirect from "discourse/plugins/chat/discourse/components/channels-list-direct"; +import ChannelsListPublic from "discourse/plugins/chat/discourse/components/channels-list-public"; export default class ChannelsList extends Component { @service chat; - @service router; - @service chatStateManager; - @service chatChannelsManager; - @service site; - @service siteSettings; - @service session; - @service currentUser; - @service modal; - - @tracked hasScrollbar = false; - - @action - computeHasScrollbar(element) { - this.hasScrollbar = element.scrollHeight > element.clientHeight; - } - - @action - computeResizedEntries(entries) { - this.computeHasScrollbar(entries[0].target); - } - - @action - openNewMessageModal() { - this.modal.show(ChatModalNewMessage); - } - - get showMobileDirectMessageButton() { - return this.site.mobileView && this.canCreateDirectMessageChannel; - } - - get inSidebar() { - return this.args.inSidebar ?? false; - } - - get publicMessageChannelsEmpty() { - return this.chatChannelsManager.publicMessageChannels?.length === 0; - } - - get createDirectMessageChannelLabel() { - if (!this.canCreateDirectMessageChannel) { - return "chat.direct_messages.cannot_create"; - } - - return "chat.direct_messages.new"; - } - - get showDirectMessageChannels() { - return ( - this.canCreateDirectMessageChannel || - this.chatChannelsManager.directMessageChannels?.length > 0 - ); - } - - get canCreateDirectMessageChannel() { - return this.chat.userCanDirectMessage; - } - - get displayPublicChannels() { - if (!this.siteSettings.enable_public_channels) { - return false; - } - - if (this.publicMessageChannelsEmpty) { - return ( - this.currentUser?.staff || - this.currentUser?.has_joinable_public_channels - ); - } - - return true; - } - - get directMessageChannelClasses() { - return `channels-list-container direct-message-channels ${ - this.inSidebar ? "collapsible-sidebar-section" : "" - }`; - } - - get hasUnreadThreads() { - return this.chatChannelsManager.publicMessageChannels.some( - (channel) => channel.unreadThreadsCount > 0 - ); - } - - @action - toggleChannelSection(section) { - this.args.toggleSection(section); - } - - didRender() { - super.didRender(...arguments); - - schedule("afterRender", this._applyScrollPosition); - } - - @action - storeScrollPosition() { - if (this.chatStateManager.isDrawerActive) { - return; - } - - const scrollTop = document.querySelector(".channels-list")?.scrollTop || 0; - this.session.channelsListPosition = scrollTop; - } - - @bind - _applyScrollPosition() { - if (this.chatStateManager.isDrawerActive) { - return; - } - - const position = this.chatStateManager.isFullPageActive - ? this.session.channelsListPosition || 0 - : 0; - const scroller = document.querySelector(".channels-list"); - scroller.scrollTo(0, position); - } } diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-footer.gjs b/plugins/chat/assets/javascripts/discourse/components/chat-footer.gjs new file mode 100644 index 00000000000..a7906c2069c --- /dev/null +++ b/plugins/chat/assets/javascripts/discourse/components/chat-footer.gjs @@ -0,0 +1,93 @@ +import Component from "@glimmer/component"; +import { tracked } from "@glimmer/tracking"; +import { inject as service } from "@ember/service"; +import { modifier } from "ember-modifier"; +import DButton from "discourse/components/d-button"; +import concatClass from "discourse/helpers/concat-class"; +import { popupAjaxError } from "discourse/lib/ajax-error"; +import i18n from "discourse-common/helpers/i18n"; +import eq from "truth-helpers/helpers/eq"; + +export default class ChatFooter extends Component { + @service router; + @service chat; + @service chatApi; + + @tracked threadsEnabled = false; + + updateThreadCount = modifier(() => { + const ajax = this.chatApi.userThreadCount(); + + ajax + .then((result) => { + this.threadsEnabled = result.thread_count > 0; + }) + .catch((error) => { + popupAjaxError(error); + }); + + return () => { + ajax?.abort(); + }; + }); + + get directMessagesEnabled() { + return this.chat.userCanAccessDirectMessages; + } + + get shouldRenderFooter() { + return this.directMessagesEnabled || this.threadsEnabled; + } + + +} diff --git a/plugins/chat/assets/javascripts/discourse/components/chat/navbar/actions.gjs b/plugins/chat/assets/javascripts/discourse/components/chat/navbar/actions.gjs index 791dc986bb7..255e2e3cac0 100644 --- a/plugins/chat/assets/javascripts/discourse/components/chat/navbar/actions.gjs +++ b/plugins/chat/assets/javascripts/discourse/components/chat/navbar/actions.gjs @@ -1,9 +1,11 @@ import { hash } from "@ember/helper"; +import BrowseChannelsButton from "./browse-channels-button"; import CloseDrawerButton from "./close-drawer-button"; import CloseThreadButton from "./close-thread-button"; import CloseThreadsButton from "./close-threads-button"; import FullPageButton from "./full-page-button"; import NewChannelButton from "./new-channel-button"; +import NewDirectMessageButton from "./new-direct-message-button"; import OpenDrawerButton from "./open-drawer-button"; import ThreadSettingsButton from "./thread-settings-button"; import ThreadTrackingDropdown from "./thread-tracking-dropdown"; @@ -15,6 +17,8 @@ const ChatNavbarActions =