FEATURE: implements user based sidebar mode (#23078)
This commit is contained in:
parent
82b16f4f47
commit
b2b84cc957
|
@ -5,5 +5,6 @@
|
|||
@icon={{button.switchButtonIcon}}
|
||||
@disabled={{this.isSwitching}}
|
||||
@translatedLabel={{button.switchButtonLabel}}
|
||||
data-key={{button.key}}
|
||||
/>
|
||||
{{/each}}
|
|
@ -16,9 +16,13 @@ export default class SwitchPanelButtons extends Component {
|
|||
|
||||
const url = panel.lastKnownURL || panel.switchButtonDefaultUrl;
|
||||
const destination = url === "/" ? `discovery.${defaultHomepage()}` : url;
|
||||
this.router.transitionTo(destination).finally(() => {
|
||||
this.isSwitching = false;
|
||||
this.sidebarState.setPanel(panel.key);
|
||||
});
|
||||
this.router
|
||||
.transitionTo(destination)
|
||||
.then(() => {
|
||||
this.sidebarState.setPanel(panel.key);
|
||||
})
|
||||
.finally(() => {
|
||||
this.isSwitching = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -292,6 +292,7 @@ end
|
|||
# sidebar_link_to_filtered_list :boolean default(FALSE), not null
|
||||
# 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
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Chat
|
||||
class SeparateSidebarModeSiteSetting < EnumSiteSetting
|
||||
def self.valid_value?(val)
|
||||
values.any? { |v| v[:value] == val }
|
||||
end
|
||||
|
||||
def self.values
|
||||
@values ||= [
|
||||
{ name: "admin.site_settings.chat_separate_sidebar_mode.never", value: "never" },
|
||||
{ name: "admin.site_settings.chat_separate_sidebar_mode.always", value: "always" },
|
||||
{ name: "admin.site_settings.chat_separate_sidebar_mode.fullscreen", value: "fullscreen" },
|
||||
]
|
||||
end
|
||||
|
||||
def self.translate_names?
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
|
@ -171,8 +171,8 @@ export default Component.extend({
|
|||
@action
|
||||
openURL(url = null) {
|
||||
this.chat.activeChannel = null;
|
||||
this.chatStateManager.didOpenDrawer(url);
|
||||
this.chatDrawerRouter.stateFor(this._routeFromURL(url));
|
||||
this.chatStateManager.didOpenDrawer(url);
|
||||
},
|
||||
|
||||
_routeFromURL(url) {
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
href={{this.href}}
|
||||
tabindex="0"
|
||||
class={{concat-class "icon" "btn-flat" (if this.isActive "active")}}
|
||||
title={{i18n this.title}}
|
||||
>
|
||||
{{d-icon "d-chat"}}
|
||||
{{d-icon this.icon}}
|
||||
{{#unless this.currentUserInDnD}}
|
||||
<Chat::Header::Icon::UnreadIndicator
|
||||
@urgentCount={{@urgentCount}}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { inject as service } from "@ember/service";
|
||||
import Component from "@glimmer/component";
|
||||
import getURL from "discourse-common/lib/get-url";
|
||||
|
||||
import { getUserChatSeparateSidebarMode } from "discourse/plugins/chat/discourse/lib/get-user-chat-separate-sidebar-mode";
|
||||
export default class ChatHeaderIcon extends Component {
|
||||
@service currentUser;
|
||||
@service site;
|
||||
|
@ -12,6 +12,10 @@ export default class ChatHeaderIcon extends Component {
|
|||
return this.args.currentUserInDnD || this.currentUser.isInDoNotDisturb();
|
||||
}
|
||||
|
||||
get chatSeparateSidebarMode() {
|
||||
return getUserChatSeparateSidebarMode(this.currentUser);
|
||||
}
|
||||
|
||||
get isActive() {
|
||||
return (
|
||||
this.args.isActive ||
|
||||
|
@ -20,13 +24,38 @@ export default class ChatHeaderIcon extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
get title() {
|
||||
if (
|
||||
this.chatStateManager.isFullPageActive &&
|
||||
!this.chatSeparateSidebarMode.never
|
||||
) {
|
||||
return "sidebar.panels.forum.label";
|
||||
}
|
||||
|
||||
return "chat.title_capitalized";
|
||||
}
|
||||
|
||||
get icon() {
|
||||
if (
|
||||
this.chatStateManager.isFullPageActive &&
|
||||
!this.chatSeparateSidebarMode.never
|
||||
) {
|
||||
return "random";
|
||||
}
|
||||
|
||||
return "d-chat";
|
||||
}
|
||||
|
||||
get href() {
|
||||
if (this.chatStateManager.isFullPageActive) {
|
||||
if (this.site.mobileView) {
|
||||
return getURL("/chat");
|
||||
} else {
|
||||
return getURL(this.router.currentURL);
|
||||
}
|
||||
if (this.site.mobileView && this.chatStateManager.isFullPageActive) {
|
||||
return getURL("/chat");
|
||||
}
|
||||
|
||||
if (
|
||||
this.chatStateManager.isFullPageActive &&
|
||||
!this.chatSeparateSidebarMode.never
|
||||
) {
|
||||
return getURL(this.chatStateManager.lastKnownAppURL || "/");
|
||||
}
|
||||
|
||||
if (this.chatStateManager.isDrawerActive) {
|
||||
|
|
|
@ -14,38 +14,65 @@ const CHAT_ATTRS = [
|
|||
"chat_sound",
|
||||
"chat_email_frequency",
|
||||
"chat_header_indicator_preference",
|
||||
"chat_separate_sidebar_mode",
|
||||
];
|
||||
|
||||
const EMAIL_FREQUENCY_OPTIONS = [
|
||||
{ name: I18n.t("chat.email_frequency.never"), value: "never" },
|
||||
{ name: I18n.t("chat.email_frequency.when_away"), value: "when_away" },
|
||||
];
|
||||
|
||||
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";
|
||||
|
||||
const EMAIL_FREQUENCY_OPTIONS = [
|
||||
{ name: I18n.t(`chat.email_frequency.never`), value: "never" },
|
||||
{ name: I18n.t(`chat.email_frequency.when_away`), value: "when_away" },
|
||||
];
|
||||
|
||||
const HEADER_INDICATOR_OPTIONS = [
|
||||
{
|
||||
name: I18n.t(`chat.header_indicator_preference.all_new`),
|
||||
name: I18n.t("chat.header_indicator_preference.all_new"),
|
||||
value: HEADER_INDICATOR_PREFERENCE_ALL_NEW,
|
||||
},
|
||||
{
|
||||
name: I18n.t(`chat.header_indicator_preference.dm_and_mentions`),
|
||||
name: I18n.t("chat.header_indicator_preference.dm_and_mentions"),
|
||||
value: HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS,
|
||||
},
|
||||
{
|
||||
name: I18n.t(`chat.header_indicator_preference.never`),
|
||||
name: I18n.t("chat.header_indicator_preference.never"),
|
||||
value: HEADER_INDICATOR_PREFERENCE_NEVER,
|
||||
},
|
||||
];
|
||||
|
||||
const CHAT_SEPARATE_SIDEBAR_MODE_OPTIONS = [
|
||||
{
|
||||
name: I18n.t("admin.site_settings.chat_separate_sidebar_mode.always"),
|
||||
value: "always",
|
||||
},
|
||||
{
|
||||
name: I18n.t("admin.site_settings.chat_separate_sidebar_mode.fullscreen"),
|
||||
value: "fullscreen",
|
||||
},
|
||||
{
|
||||
name: I18n.t("admin.site_settings.chat_separate_sidebar_mode.never"),
|
||||
value: "never",
|
||||
},
|
||||
];
|
||||
|
||||
export default class PreferencesChatController extends Controller {
|
||||
@service chatAudioManager;
|
||||
@service siteSettings;
|
||||
|
||||
subpageTitle = I18n.t("chat.admin.title");
|
||||
|
||||
emailFrequencyOptions = EMAIL_FREQUENCY_OPTIONS;
|
||||
headerIndicatorOptions = HEADER_INDICATOR_OPTIONS;
|
||||
chatSeparateSidebarModeOptions = CHAT_SEPARATE_SIDEBAR_MODE_OPTIONS;
|
||||
|
||||
get chatSeparateSidebarMode() {
|
||||
const mode = this.model.get("user_option.chat_separate_sidebar_mode");
|
||||
if (mode === "default") {
|
||||
return this.siteSettings.chat_separate_sidebar_mode;
|
||||
} else {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
|
||||
@discourseComputed
|
||||
chatSounds() {
|
||||
|
|
|
@ -11,6 +11,7 @@ import { decorateUsername } from "discourse/helpers/decorate-username-selector";
|
|||
import { until } from "discourse/lib/formatter";
|
||||
import { inject as service } from "@ember/service";
|
||||
import ChatModalNewMessage from "discourse/plugins/chat/discourse/components/chat/modal/new-message";
|
||||
import getURL from "discourse-common/lib/get-url";
|
||||
|
||||
export default {
|
||||
name: "chat-sidebar",
|
||||
|
@ -23,6 +24,18 @@ export default {
|
|||
|
||||
this.siteSettings = container.lookup("service:site-settings");
|
||||
|
||||
withPluginApi("1.8.0", (api) => {
|
||||
api.addSidebarPanel(
|
||||
(BaseCustomSidebarPanel) =>
|
||||
class ChatSidebarPanel extends BaseCustomSidebarPanel {
|
||||
key = "chat";
|
||||
switchButtonLabel = I18n.t("sidebar.panels.chat.label");
|
||||
switchButtonIcon = "d-chat";
|
||||
switchButtonDefaultUrl = getURL("/chat");
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
withPluginApi("1.3.0", (api) => {
|
||||
if (this.siteSettings.enable_public_channels) {
|
||||
api.addSidebarSection(
|
||||
|
@ -180,7 +193,8 @@ export default {
|
|||
};
|
||||
|
||||
return SidebarChatChannelsSection;
|
||||
}
|
||||
},
|
||||
"chat"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -414,7 +428,8 @@ export default {
|
|||
};
|
||||
|
||||
return SidebarChatDirectMessagesSection;
|
||||
}
|
||||
},
|
||||
"chat"
|
||||
);
|
||||
});
|
||||
},
|
||||
|
|
|
@ -6,6 +6,7 @@ const IGNORE_CHANNEL_WIDE_MENTION = "ignore_channel_wide_mention";
|
|||
const CHAT_SOUND = "chat_sound";
|
||||
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";
|
||||
|
||||
export default {
|
||||
name: "chat-user-options",
|
||||
|
@ -20,6 +21,7 @@ export default {
|
|||
api.addSaveableUserOptionField(CHAT_SOUND);
|
||||
api.addSaveableUserOptionField(CHAT_EMAIL_FREQUENCY);
|
||||
api.addSaveableUserOptionField(CHAT_HEADER_INDICATOR_PREFERENCE);
|
||||
api.addSaveableUserOptionField(CHAT_SEPARATE_SIDEBAR_MODE);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
export function getUserChatSeparateSidebarMode(user) {
|
||||
const mode = user?.get("user_option.chat_separate_sidebar_mode");
|
||||
|
||||
return {
|
||||
never: "never" === mode,
|
||||
always: "always" === mode,
|
||||
fullscreen: "fullscreen" === mode,
|
||||
};
|
||||
}
|
|
@ -4,11 +4,13 @@ import { defaultHomepage } from "discourse/lib/utilities";
|
|||
import { inject as service } from "@ember/service";
|
||||
import { scrollTop } from "discourse/mixins/scroll-top";
|
||||
import { schedule } from "@ember/runloop";
|
||||
|
||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
import { getUserChatSeparateSidebarMode } from "discourse/plugins/chat/discourse/lib/get-user-chat-separate-sidebar-mode";
|
||||
export default class ChatRoute extends DiscourseRoute {
|
||||
@service chat;
|
||||
@service router;
|
||||
@service chatStateManager;
|
||||
@service currentUser;
|
||||
|
||||
titleToken() {
|
||||
return I18n.t("chat.title_capitalized");
|
||||
|
@ -57,6 +59,16 @@ export default class ChatRoute extends DiscourseRoute {
|
|||
}
|
||||
|
||||
activate() {
|
||||
withPluginApi("1.8.0", (api) => {
|
||||
api.setSidebarPanel("chat");
|
||||
if (getUserChatSeparateSidebarMode(this.currentUser).never) {
|
||||
api.setCombinedSidebarMode();
|
||||
api.hideSidebarSwitchPanelButtons();
|
||||
} else {
|
||||
api.setSeparatedSidebarMode();
|
||||
}
|
||||
});
|
||||
|
||||
this.chatStateManager.storeAppURL();
|
||||
this.chat.updatePresence();
|
||||
|
||||
|
@ -68,6 +80,23 @@ export default class ChatRoute extends DiscourseRoute {
|
|||
}
|
||||
|
||||
deactivate(transition) {
|
||||
withPluginApi("1.8.0", (api) => {
|
||||
api.setSidebarPanel("main");
|
||||
|
||||
const chatSeparateSidebarMode = getUserChatSeparateSidebarMode(
|
||||
this.currentUser
|
||||
);
|
||||
if (chatSeparateSidebarMode.fullscreen) {
|
||||
api.setCombinedSidebarMode();
|
||||
api.showSidebarSwitchPanelButtons();
|
||||
} else if (chatSeparateSidebarMode.always) {
|
||||
api.setSeparatedSidebarMode();
|
||||
} else {
|
||||
api.setCombinedSidebarMode();
|
||||
api.hideSidebarSwitchPanelButtons();
|
||||
}
|
||||
});
|
||||
|
||||
if (transition) {
|
||||
const url = this.router.urlFor(transition.from.name);
|
||||
this.chatStateManager.storeChatURL(url);
|
||||
|
|
|
@ -4,6 +4,8 @@ import { tracked } from "@glimmer/tracking";
|
|||
import KeyValueStore from "discourse/lib/key-value-store";
|
||||
import Site from "discourse/models/site";
|
||||
import getURL from "discourse-common/lib/get-url";
|
||||
import { getUserChatSeparateSidebarMode } from "discourse/plugins/chat/discourse/lib/get-user-chat-separate-sidebar-mode";
|
||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
|
||||
const PREFERRED_MODE_KEY = "preferred_mode";
|
||||
const PREFERRED_MODE_STORE_NAMESPACE = "discourse_chat_";
|
||||
|
@ -56,6 +58,16 @@ export default class ChatStateManager extends Service {
|
|||
}
|
||||
|
||||
didOpenDrawer(url = null) {
|
||||
withPluginApi("1.8.0", (api) => {
|
||||
if (getUserChatSeparateSidebarMode(this.currentUser).always) {
|
||||
api.setSidebarPanel("main");
|
||||
api.setSeparatedSidebarMode();
|
||||
api.hideSidebarSwitchPanelButtons();
|
||||
} else {
|
||||
api.setCombinedSidebarMode();
|
||||
}
|
||||
});
|
||||
|
||||
this.isDrawerActive = true;
|
||||
this.isDrawerExpanded = true;
|
||||
|
||||
|
@ -68,6 +80,24 @@ export default class ChatStateManager extends Service {
|
|||
}
|
||||
|
||||
didCloseDrawer() {
|
||||
withPluginApi("1.8.0", (api) => {
|
||||
api.setSidebarPanel("main");
|
||||
|
||||
const chatSeparateSidebarMode = getUserChatSeparateSidebarMode(
|
||||
this.currentUser
|
||||
);
|
||||
if (chatSeparateSidebarMode.fullscreen) {
|
||||
api.setCombinedSidebarMode();
|
||||
api.showSidebarSwitchPanelButtons();
|
||||
} else if (chatSeparateSidebarMode.always) {
|
||||
api.setSeparatedSidebarMode();
|
||||
api.showSidebarSwitchPanelButtons();
|
||||
} else {
|
||||
api.setCombinedSidebarMode();
|
||||
api.hideSidebarSwitchPanelButtons();
|
||||
}
|
||||
});
|
||||
|
||||
this.isDrawerActive = false;
|
||||
this.isDrawerExpanded = false;
|
||||
this.chat.updatePresence();
|
||||
|
|
|
@ -99,6 +99,23 @@
|
|||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="control-group chat-setting controls-dropdown"
|
||||
data-setting-name="user_chat_separate_sidebar_mode"
|
||||
>
|
||||
<label for="user_chat_separate_sidebar_mode">
|
||||
{{i18n "chat.separate_sidebar_mode.title"}}
|
||||
</label>
|
||||
|
||||
<ComboBox
|
||||
@valueProperty="value"
|
||||
@content={{this.chatSeparateSidebarModeOptions}}
|
||||
@value={{this.chatSeparateSidebarMode}}
|
||||
@id="user_chat_separate_sidebar_mode"
|
||||
@onChange={{action (mut this.model.user_option.chat_separate_sidebar_mode)}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<SaveControls
|
||||
@id="user_chat_preference_save"
|
||||
@model={{this.model}}
|
||||
|
|
|
@ -4,7 +4,6 @@ import { hbs } from "ember-cli-htmlbars";
|
|||
|
||||
export default createWidget("chat-header-icon", {
|
||||
tagName: "li.header-dropdown-toggle.chat-header-icon",
|
||||
title: "chat.title_capitalized",
|
||||
|
||||
services: ["chat"],
|
||||
|
||||
|
|
|
@ -4,6 +4,10 @@ en:
|
|||
site_settings:
|
||||
categories:
|
||||
chat: Chat
|
||||
chat_separate_sidebar_mode:
|
||||
always: "Always"
|
||||
fullscreen: "When chat is in fullscreen"
|
||||
never: "Never"
|
||||
logs:
|
||||
staff_actions:
|
||||
actions:
|
||||
|
@ -104,6 +108,8 @@ en:
|
|||
all_new: "All New Messages"
|
||||
dm_and_mentions: "Direct Messages and Mentions"
|
||||
never: "Never"
|
||||
separate_sidebar_mode:
|
||||
title: "Show separate sidebar modes for forum and chat"
|
||||
enable: "Enable chat"
|
||||
flag: "Flag"
|
||||
emoji: "Insert emoji"
|
||||
|
@ -685,3 +691,8 @@ en:
|
|||
sections:
|
||||
chat:
|
||||
title: Chat
|
||||
|
||||
sidebar:
|
||||
panels:
|
||||
chat:
|
||||
label: "Chat"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
en:
|
||||
site_settings:
|
||||
chat_separate_sidebar_mode: "Show separate sidebar modes for forum and chat."
|
||||
chat_enabled: "Enable the chat plugin."
|
||||
enable_public_channels: "Enable public channels based on categories."
|
||||
chat_allowed_groups: "Users in these groups can chat. Note that staff can always access chat."
|
||||
|
|
|
@ -116,3 +116,8 @@ chat:
|
|||
max_chat_draft_length:
|
||||
default: 50_000
|
||||
hidden: true
|
||||
chat_separate_sidebar_mode:
|
||||
client: true
|
||||
default: "never"
|
||||
type: enum
|
||||
enum: "Chat::SeparateSidebarModeSiteSetting"
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddChatSeparateSidebarModeUserOption < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
add_column :user_options, :chat_separate_sidebar_mode, :integer, default: 0, null: false
|
||||
end
|
||||
end
|
|
@ -14,19 +14,32 @@ module Chat
|
|||
@chat_email_frequencies ||= { never: 0, when_away: 1 }
|
||||
end
|
||||
|
||||
# Avoid attempting to override when autoloading
|
||||
if !base.method_defined?(:send_chat_email_never?)
|
||||
base.enum :chat_email_frequency, base.chat_email_frequencies, prefix: "send_chat_email"
|
||||
end
|
||||
|
||||
def base.chat_header_indicator_preferences
|
||||
@chat_header_indicator_preferences ||= { all_new: 0, dm_and_mentions: 1, never: 2 }
|
||||
end
|
||||
|
||||
if !base.method_defined?(:send_chat_email_never?) # Avoid attempting to override when autoloading
|
||||
base.enum :chat_email_frequency, base.chat_email_frequencies, prefix: "send_chat_email"
|
||||
end
|
||||
|
||||
if !base.method_defined?(:chat_header_indicator_never?) # Avoid attempting to override when autoloading
|
||||
# Avoid attempting to override when autoloading
|
||||
if !base.method_defined?(:chat_header_indicator_never?)
|
||||
base.enum :chat_header_indicator_preference,
|
||||
base.chat_header_indicator_preferences,
|
||||
prefix: "chat_header_indicator"
|
||||
end
|
||||
|
||||
def base.chat_separate_sidebar_mode
|
||||
@chat_separate_sidebar_mode ||= { default: 0, never: 1, always: 2, fullscreen: 3 }
|
||||
end
|
||||
|
||||
# Avoid attempting to override when autoloading
|
||||
if !base.method_defined?(:chat_separate_sidebar_mode_default?)
|
||||
base.enum :chat_separate_sidebar_mode,
|
||||
base.chat_separate_sidebar_mode,
|
||||
prefix: "chat_separate_sidebar_mode"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -47,6 +47,7 @@ after_initialize do
|
|||
UserUpdater::OPTION_ATTR.push(:ignore_channel_wide_mention)
|
||||
UserUpdater::OPTION_ATTR.push(:chat_email_frequency)
|
||||
UserUpdater::OPTION_ATTR.push(:chat_header_indicator_preference)
|
||||
UserUpdater::OPTION_ATTR.push(:chat_separate_sidebar_mode)
|
||||
|
||||
register_reviewable_type Chat::ReviewableMessage
|
||||
|
||||
|
@ -297,6 +298,12 @@ after_initialize do
|
|||
object.chat_header_indicator_preference
|
||||
end
|
||||
|
||||
add_to_serializer(:user_option, :chat_separate_sidebar_mode) { object.chat_separate_sidebar_mode }
|
||||
|
||||
add_to_serializer(:current_user_option, :chat_separate_sidebar_mode) do
|
||||
object.chat_separate_sidebar_mode
|
||||
end
|
||||
|
||||
RETENTION_SETTINGS_TO_USER_OPTION_FIELDS = {
|
||||
chat_channel_retention_days: :dismissed_channel_retention_reminder,
|
||||
chat_dm_retention_days: :dismissed_dm_retention_reminder,
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe UserOption do
|
||||
describe "#chat_separate_sidebar_mode" do
|
||||
it "is present" do
|
||||
expect(described_class.new.chat_separate_sidebar_mode).to eq("default")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -13,6 +13,12 @@ RSpec.describe CurrentUserSerializer do
|
|||
current_user.user_option.update(chat_enabled: true)
|
||||
end
|
||||
|
||||
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_drafts" do
|
||||
context "when user can't chat" do
|
||||
before { SiteSetting.chat_allowed_groups = Group::AUTO_GROUPS[:staff] }
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe UserSerializer do
|
||||
fab!(:current_user) { Fabricate(:user) }
|
||||
|
||||
let(:serializer) do
|
||||
described_class.new(current_user, scope: Guardian.new(current_user), root: false)
|
||||
end
|
||||
|
||||
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
|
||||
end
|
|
@ -19,6 +19,9 @@ RSpec.describe "Navigation", type: :system do
|
|||
|
||||
before do
|
||||
chat_system_bootstrap(current_user, [category_channel, category_channel_2])
|
||||
current_user.user_option.update(
|
||||
chat_separate_sidebar_mode: UserOption.chat_separate_sidebar_modes[:never],
|
||||
)
|
||||
sign_in(current_user)
|
||||
end
|
||||
|
||||
|
@ -36,7 +39,6 @@ RSpec.describe "Navigation", type: :system do
|
|||
|
||||
context "when clicking chat icon on mobile and is viewing channel" do
|
||||
it "navigates to index", mobile: true do
|
||||
visit("/chat")
|
||||
chat_page.visit_channel(category_channel_2)
|
||||
chat_page.open_from_header
|
||||
|
||||
|
@ -44,18 +46,6 @@ RSpec.describe "Navigation", type: :system do
|
|||
end
|
||||
end
|
||||
|
||||
context "when clicking chat icon on desktop and is viewing channel" do
|
||||
it "stays on channel page" do
|
||||
visit("/chat")
|
||||
chat_page.visit_channel(category_channel_2)
|
||||
chat_page.open_from_header
|
||||
|
||||
expect(page).to have_current_path(
|
||||
chat.channel_path(category_channel_2.slug, category_channel_2.id),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when visiting /chat" do
|
||||
it "opens full page" do
|
||||
chat_page.open
|
||||
|
|
|
@ -17,6 +17,12 @@ module PageObjects
|
|||
)
|
||||
end
|
||||
|
||||
def prefers_drawer
|
||||
page.execute_script(
|
||||
"window.localStorage.setItem('discourse_chat_preferred_mode', '\"DRAWER_CHAT\"');",
|
||||
)
|
||||
end
|
||||
|
||||
def open_from_header
|
||||
find(".chat-header-icon").click
|
||||
end
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module PageObjects
|
||||
module Components
|
||||
module Chat
|
||||
class Header < PageObjects::Components::Base
|
||||
def has_open_chat_button?
|
||||
has_css?(".d-header .chat-header-icon .d-icon-d-chat")
|
||||
end
|
||||
|
||||
def has_open_forum_button?
|
||||
has_css?(".d-header .chat-header-icon .d-icon-random")
|
||||
end
|
||||
|
||||
def has_no_chat_button?
|
||||
has_no_css?(".d-header .chat-header-icon")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,202 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe "Separate sidebar mode", type: :system do
|
||||
let(:chat_page) { PageObjects::Pages::Chat.new }
|
||||
let(:sidebar_page) { PageObjects::Pages::Sidebar.new }
|
||||
let(:sidebar_component) { PageObjects::Components::NavigationMenu::Sidebar.new }
|
||||
let(:chat_drawer_page) { PageObjects::Pages::ChatDrawer.new }
|
||||
let(:header_component) { PageObjects::Components::Chat::Header.new }
|
||||
|
||||
fab!(:current_user) { Fabricate(:user) }
|
||||
fab!(:channel_1) { Fabricate(:chat_channel) }
|
||||
|
||||
before do
|
||||
SiteSetting.navigation_menu = "sidebar"
|
||||
channel_1.add(current_user)
|
||||
chat_system_bootstrap
|
||||
sign_in(current_user)
|
||||
end
|
||||
|
||||
describe "when separate sidebar mode is never" do
|
||||
before do
|
||||
current_user.user_option.update!(
|
||||
chat_separate_sidebar_mode: UserOption.chat_separate_sidebar_modes[:never],
|
||||
)
|
||||
end
|
||||
|
||||
context "with drawer" do
|
||||
before { chat_page.prefers_drawer }
|
||||
|
||||
it "has the expected behavior" do
|
||||
visit("/")
|
||||
|
||||
expect(sidebar_component).to have_no_switch_button
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_section("Categories")
|
||||
expect(sidebar_component).to have_section("chat-channels")
|
||||
|
||||
sidebar_page.open_channel(channel_1)
|
||||
|
||||
expect(sidebar_component).to have_no_switch_button
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_section("Categories")
|
||||
expect(sidebar_component).to have_section("chat-channels")
|
||||
|
||||
chat_drawer_page.close
|
||||
|
||||
expect(sidebar_component).to have_no_switch_button
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_section("Categories")
|
||||
expect(sidebar_component).to have_section("chat-channels")
|
||||
end
|
||||
end
|
||||
|
||||
context "with full page" do
|
||||
before { chat_page.prefers_full_page }
|
||||
|
||||
it "has the expected behavior" do
|
||||
visit("/")
|
||||
|
||||
expect(sidebar_component).to have_no_switch_button
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_section("Categories")
|
||||
expect(sidebar_component).to have_section("chat-channels")
|
||||
|
||||
sidebar_page.open_channel(channel_1)
|
||||
|
||||
expect(sidebar_component).to have_no_switch_button
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_section("Categories")
|
||||
expect(sidebar_component).to have_section("chat-channels")
|
||||
|
||||
find("#site-logo").click
|
||||
|
||||
expect(sidebar_component).to have_no_switch_button
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_section("Categories")
|
||||
expect(sidebar_component).to have_section("chat-channels")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "when separate sidebar mode is always" do
|
||||
before do
|
||||
current_user.user_option.update(
|
||||
chat_separate_sidebar_mode: UserOption.chat_separate_sidebar_modes[:always],
|
||||
)
|
||||
end
|
||||
|
||||
context "with drawer" do
|
||||
before { chat_page.prefers_drawer }
|
||||
|
||||
it "has the expected behavior" do
|
||||
visit("/")
|
||||
|
||||
expect(sidebar_component).to have_switch_button("chat")
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_no_section("chat-channels")
|
||||
|
||||
chat_page.open_from_header
|
||||
|
||||
expect(sidebar_component).to have_no_switch_button
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_no_section("chat-channels")
|
||||
|
||||
chat_drawer_page.close
|
||||
|
||||
expect(sidebar_component).to have_switch_button("chat")
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_no_section("chat-channels")
|
||||
end
|
||||
end
|
||||
|
||||
context "with full page" do
|
||||
before { chat_page.prefers_full_page }
|
||||
|
||||
it "has the expected behavior" do
|
||||
visit("/")
|
||||
|
||||
expect(sidebar_component).to have_switch_button("chat")
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_no_section("chat-channels")
|
||||
expect(sidebar_component).to have_section("Categories")
|
||||
|
||||
chat_page.open_from_header
|
||||
|
||||
expect(sidebar_component).to have_switch_button("main")
|
||||
expect(header_component).to have_open_forum_button
|
||||
expect(sidebar_component).to have_section("chat-channels")
|
||||
expect(sidebar_component).to have_no_section("Categories")
|
||||
|
||||
find("#site-logo").click
|
||||
|
||||
expect(sidebar_component).to have_switch_button("chat")
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_no_section("chat-channels")
|
||||
expect(sidebar_component).to have_section("Categories")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "when separate sidebar mode is fullscreen" do
|
||||
before do
|
||||
current_user.user_option.update(
|
||||
chat_separate_sidebar_mode: UserOption.chat_separate_sidebar_modes[:fullscreen],
|
||||
)
|
||||
end
|
||||
|
||||
context "with drawer" do
|
||||
before { chat_page.prefers_drawer }
|
||||
|
||||
it "has the expected behavior" do
|
||||
visit("/")
|
||||
|
||||
expect(sidebar_component).to have_switch_button
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_section("Categories")
|
||||
expect(sidebar_component).to have_section("chat-channels")
|
||||
|
||||
sidebar_page.open_channel(channel_1)
|
||||
|
||||
expect(sidebar_component).to have_no_switch_button
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_section("Categories")
|
||||
expect(sidebar_component).to have_section("chat-channels")
|
||||
|
||||
chat_drawer_page.close
|
||||
|
||||
expect(sidebar_component).to have_switch_button
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_section("Categories")
|
||||
expect(sidebar_component).to have_section("chat-channels")
|
||||
end
|
||||
end
|
||||
|
||||
context "with full page" do
|
||||
before { chat_page.prefers_full_page }
|
||||
|
||||
it "has the expected behavior" do
|
||||
visit("/")
|
||||
|
||||
expect(sidebar_component).to have_switch_button("chat")
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_section("chat-channels")
|
||||
expect(sidebar_component).to have_section("Categories")
|
||||
|
||||
sidebar_page.open_channel(channel_1)
|
||||
|
||||
expect(sidebar_component).to have_switch_button("main")
|
||||
expect(header_component).to have_open_forum_button
|
||||
expect(sidebar_component).to have_section("chat-channels")
|
||||
expect(sidebar_component).to have_no_section("Categories")
|
||||
|
||||
find("#site-logo").click
|
||||
|
||||
expect(sidebar_component).to have_switch_button("chat")
|
||||
expect(header_component).to have_open_chat_button
|
||||
expect(sidebar_component).to have_section("chat-channels")
|
||||
expect(sidebar_component).to have_section("Categories")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -25,22 +25,32 @@ RSpec.describe "User chat preferences", type: :system do
|
|||
|
||||
it "can select chat sound" do
|
||||
visit("/u/#{current_user.username}/preferences/chat")
|
||||
find("#user_chat_sounds .select-kit-header[data-value]").click
|
||||
find("[data-value='bell']").click
|
||||
select_kit = PageObjects::Components::SelectKit.new("#user_chat_sounds")
|
||||
select_kit.expand
|
||||
select_kit.select_row_by_value("bell")
|
||||
find(".save-changes").click
|
||||
|
||||
expect(page).to have_css("#user_chat_sounds .select-kit-header[data-value='bell']")
|
||||
expect(select_kit).to have_selected_value("bell")
|
||||
end
|
||||
|
||||
it "can select header_indicator_preference" do
|
||||
visit("/u/#{current_user.username}/preferences/chat")
|
||||
find("#user_chat_header_indicator_preference .select-kit-header[data-value]").click
|
||||
find("[data-value='dm_and_mentions']").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
|
||||
|
||||
expect(page).to have_css(
|
||||
"#user_chat_header_indicator_preference .select-kit-header[data-value='dm_and_mentions']",
|
||||
)
|
||||
expect(select_kit).to have_selected_value("dm_and_mentions")
|
||||
end
|
||||
|
||||
it "can select separate sidebar mode" do
|
||||
visit("/u/#{current_user.username}/preferences/chat")
|
||||
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
|
||||
|
||||
expect(select_kit).to have_selected_value("fullscreen")
|
||||
end
|
||||
|
||||
context "as an admin on another user's preferences" do
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
import { module, test } from "qunit";
|
||||
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
||||
import { render } from "@ember/test-helpers";
|
||||
import { hbs } from "ember-cli-htmlbars";
|
||||
import sinon from "sinon";
|
||||
import I18n from "I18n";
|
||||
|
||||
module("Discourse Chat | Component | chat-header-icon", function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {});
|
||||
|
||||
test("full page - never separated sidebar mode", async function (assert) {
|
||||
this.currentUser.user_option.chat_separate_sidebar_mode = "never";
|
||||
sinon
|
||||
.stub(this.owner.lookup("service:chat-state-manager"), "isFullPageActive")
|
||||
.value(true);
|
||||
|
||||
await render(hbs`<Chat::Header::Icon />`);
|
||||
|
||||
assert
|
||||
.dom(".icon.btn-flat")
|
||||
.hasAttribute("title", I18n.t("chat.title_capitalized"))
|
||||
.hasAttribute("href", "/chat");
|
||||
|
||||
assert.dom(".d-icon-d-chat").exists();
|
||||
});
|
||||
|
||||
test("full page - always separated mode", async function (assert) {
|
||||
this.currentUser.user_option.chat_separate_sidebar_mode = "always";
|
||||
sinon
|
||||
.stub(this.owner.lookup("service:chat-state-manager"), "isFullPageActive")
|
||||
.value(true);
|
||||
|
||||
await render(hbs`<Chat::Header::Icon />`);
|
||||
|
||||
assert
|
||||
.dom(".icon.btn-flat")
|
||||
.hasAttribute("title", I18n.t("sidebar.panels.forum.label"))
|
||||
.hasAttribute("href", "/latest");
|
||||
|
||||
assert.dom(".d-icon-random").exists();
|
||||
});
|
||||
});
|
|
@ -34,6 +34,22 @@ module PageObjects
|
|||
has_no_css?(".sidebar-sections [data-section-name='#{name.parameterize}']")
|
||||
end
|
||||
|
||||
def has_switch_button?(key = nil)
|
||||
if key
|
||||
page.has_css?(".sidebar__panel-switch-button[data-key='#{key.parameterize}']")
|
||||
else
|
||||
page.has_css?(".sidebar__panel-switch-button")
|
||||
end
|
||||
end
|
||||
|
||||
def has_no_switch_button?(key = nil)
|
||||
if key
|
||||
page.has_no_css?(".sidebar__panel-switch-button[data-key='#{key.parameterize}']")
|
||||
else
|
||||
page.has_no_css?(".sidebar__panel-switch-button")
|
||||
end
|
||||
end
|
||||
|
||||
def has_categories_section?
|
||||
has_section?("Categories")
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue