mirror of
https://github.com/discourse/discourse.git
synced 2025-03-04 10:19:40 +00:00
FEATURE: Add new chat indicator preference for Only Mentions (#23848)
Add new chat indicator preference within chat user preferences. Enabling this option will mean that green notifications will only appear for mentions (within channels and DMs. This change also enables mentions within direct messages.
This commit is contained in:
parent
f9f9cf0bf4
commit
8465324168
@ -1,9 +1,11 @@
|
|||||||
import Component from "@glimmer/component";
|
import Component from "@glimmer/component";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import { hasChatIndicator } from "../lib/chat-user-preferences";
|
||||||
|
|
||||||
export default class ChatChannelUnreadIndicator extends Component {
|
export default class ChatChannelUnreadIndicator extends Component {
|
||||||
@service chat;
|
@service chat;
|
||||||
@service site;
|
@service site;
|
||||||
|
@service currentUser;
|
||||||
|
|
||||||
get showUnreadIndicator() {
|
get showUnreadIndicator() {
|
||||||
return (
|
return (
|
||||||
@ -16,17 +18,33 @@ export default class ChatChannelUnreadIndicator extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get unreadCount() {
|
get unreadCount() {
|
||||||
|
if (this.#onlyMentions() && this.#hasChannelMentions()) {
|
||||||
|
return this.args.channel.tracking.mentionCount;
|
||||||
|
}
|
||||||
return this.args.channel.tracking.unreadCount;
|
return this.args.channel.tracking.unreadCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isUrgent() {
|
get isUrgent() {
|
||||||
|
if (this.#onlyMentions()) {
|
||||||
|
return this.#hasChannelMentions();
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
this.args.channel.isDirectMessageChannel ||
|
this.args.channel.isDirectMessageChannel || this.#hasChannelMentions()
|
||||||
this.args.channel.tracking.mentionCount > 0
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get showUnreadCount() {
|
get showUnreadCount() {
|
||||||
|
if (this.#onlyMentions()) {
|
||||||
|
return this.#hasChannelMentions();
|
||||||
|
}
|
||||||
return this.args.channel.isDirectMessageChannel || this.isUrgent;
|
return this.args.channel.isDirectMessageChannel || this.isUrgent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#hasChannelMentions() {
|
||||||
|
return this.args.channel.tracking.mentionCount > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#onlyMentions() {
|
||||||
|
return hasChatIndicator(this.currentUser).ONLY_MENTIONS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import {
|
|||||||
HEADER_INDICATOR_PREFERENCE_ALL_NEW,
|
HEADER_INDICATOR_PREFERENCE_ALL_NEW,
|
||||||
HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS,
|
HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS,
|
||||||
HEADER_INDICATOR_PREFERENCE_NEVER,
|
HEADER_INDICATOR_PREFERENCE_NEVER,
|
||||||
|
HEADER_INDICATOR_PREFERENCE_ONLY_MENTIONS,
|
||||||
} from "discourse/plugins/chat/discourse/controllers/preferences-chat";
|
} from "discourse/plugins/chat/discourse/controllers/preferences-chat";
|
||||||
|
|
||||||
const MAX_UNREAD_COUNT = 99;
|
const MAX_UNREAD_COUNT = 99;
|
||||||
@ -19,6 +20,13 @@ export default class ChatHeaderIconUnreadIndicator extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get mentionCount() {
|
||||||
|
return (
|
||||||
|
this.args.mentionCount ||
|
||||||
|
this.chatTrackingStateManager.allChannelMentionCount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
get unreadCount() {
|
get unreadCount() {
|
||||||
return (
|
return (
|
||||||
this.args.unreadCount ||
|
this.args.unreadCount ||
|
||||||
@ -34,6 +42,10 @@ export default class ChatHeaderIconUnreadIndicator extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get showUrgentIndicator() {
|
get showUrgentIndicator() {
|
||||||
|
if (this.onlyMentions) {
|
||||||
|
return this.mentionCount > 0;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
this.urgentCount > 0 &&
|
this.urgentCount > 0 &&
|
||||||
this.#hasAnyIndicatorPreference([
|
this.#hasAnyIndicatorPreference([
|
||||||
@ -50,10 +62,15 @@ export default class ChatHeaderIconUnreadIndicator extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get unreadCountLabel() {
|
get urgentCountLabel() {
|
||||||
return this.urgentCount > MAX_UNREAD_COUNT
|
let totalCount = this.onlyMentions ? this.mentionCount : this.urgentCount;
|
||||||
? `${MAX_UNREAD_COUNT}+`
|
return totalCount > MAX_UNREAD_COUNT ? `${MAX_UNREAD_COUNT}+` : totalCount;
|
||||||
: this.urgentCount;
|
}
|
||||||
|
|
||||||
|
get onlyMentions() {
|
||||||
|
return this.#hasAnyIndicatorPreference([
|
||||||
|
HEADER_INDICATOR_PREFERENCE_ONLY_MENTIONS,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#hasAnyIndicatorPreference(preferences) {
|
#hasAnyIndicatorPreference(preferences) {
|
||||||
@ -71,7 +88,7 @@ export default class ChatHeaderIconUnreadIndicator extends Component {
|
|||||||
{{#if this.showUrgentIndicator}}
|
{{#if this.showUrgentIndicator}}
|
||||||
<div class="chat-channel-unread-indicator -urgent">
|
<div class="chat-channel-unread-indicator -urgent">
|
||||||
<div class="chat-channel-unread-indicator__number">
|
<div class="chat-channel-unread-indicator__number">
|
||||||
{{this.unreadCountLabel}}
|
{{this.urgentCountLabel}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{else if this.showUnreadIndicator}}
|
{{else if this.showUnreadIndicator}}
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
HEADER_INDICATOR_PREFERENCE_ALL_NEW,
|
HEADER_INDICATOR_PREFERENCE_ALL_NEW,
|
||||||
HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS,
|
HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS,
|
||||||
HEADER_INDICATOR_PREFERENCE_NEVER,
|
HEADER_INDICATOR_PREFERENCE_NEVER,
|
||||||
|
HEADER_INDICATOR_PREFERENCE_ONLY_MENTIONS,
|
||||||
} from "discourse/plugins/chat/discourse/controllers/preferences-chat";
|
} from "discourse/plugins/chat/discourse/controllers/preferences-chat";
|
||||||
|
|
||||||
export default class ChatStyleguideChatHeaderIcon extends Component {
|
export default class ChatStyleguideChatHeaderIcon extends Component {
|
||||||
@ -18,6 +19,7 @@ export default class ChatStyleguideChatHeaderIcon extends Component {
|
|||||||
return [
|
return [
|
||||||
HEADER_INDICATOR_PREFERENCE_ALL_NEW,
|
HEADER_INDICATOR_PREFERENCE_ALL_NEW,
|
||||||
HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS,
|
HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS,
|
||||||
|
HEADER_INDICATOR_PREFERENCE_ONLY_MENTIONS,
|
||||||
HEADER_INDICATOR_PREFERENCE_NEVER,
|
HEADER_INDICATOR_PREFERENCE_NEVER,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ const EMAIL_FREQUENCY_OPTIONS = [
|
|||||||
export const HEADER_INDICATOR_PREFERENCE_NEVER = "never";
|
export const HEADER_INDICATOR_PREFERENCE_NEVER = "never";
|
||||||
export const HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS = "dm_and_mentions";
|
export const HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS = "dm_and_mentions";
|
||||||
export const HEADER_INDICATOR_PREFERENCE_ALL_NEW = "all_new";
|
export const HEADER_INDICATOR_PREFERENCE_ALL_NEW = "all_new";
|
||||||
|
export const HEADER_INDICATOR_PREFERENCE_ONLY_MENTIONS = "only_mentions";
|
||||||
const HEADER_INDICATOR_OPTIONS = [
|
const HEADER_INDICATOR_OPTIONS = [
|
||||||
{
|
{
|
||||||
name: I18n.t("chat.header_indicator_preference.all_new"),
|
name: I18n.t("chat.header_indicator_preference.all_new"),
|
||||||
@ -34,6 +35,10 @@ const HEADER_INDICATOR_OPTIONS = [
|
|||||||
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,
|
value: HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: I18n.t("chat.header_indicator_preference.only_mentions"),
|
||||||
|
value: HEADER_INDICATOR_PREFERENCE_ONLY_MENTIONS,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: I18n.t("chat.header_indicator_preference.never"),
|
name: I18n.t("chat.header_indicator_preference.never"),
|
||||||
value: HEADER_INDICATOR_PREFERENCE_NEVER,
|
value: HEADER_INDICATOR_PREFERENCE_NEVER,
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
import {
|
||||||
|
HEADER_INDICATOR_PREFERENCE_ALL_NEW,
|
||||||
|
HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS,
|
||||||
|
HEADER_INDICATOR_PREFERENCE_NEVER,
|
||||||
|
HEADER_INDICATOR_PREFERENCE_ONLY_MENTIONS,
|
||||||
|
} from "discourse/plugins/chat/discourse/controllers/preferences-chat";
|
||||||
|
|
||||||
|
export function hasChatIndicator(user) {
|
||||||
|
const pref = user.user_option.chat_header_indicator_preference;
|
||||||
|
|
||||||
|
return {
|
||||||
|
ALL_NEW: pref === HEADER_INDICATOR_PREFERENCE_ALL_NEW,
|
||||||
|
DM_AND_MENTIONS: pref === HEADER_INDICATOR_PREFERENCE_DM_AND_MENTIONS,
|
||||||
|
ONLY_MENTIONS: pref === HEADER_INDICATOR_PREFERENCE_ONLY_MENTIONS,
|
||||||
|
NEVER: pref === HEADER_INDICATOR_PREFERENCE_NEVER,
|
||||||
|
};
|
||||||
|
}
|
@ -25,9 +25,9 @@ export default class ChatSubscriptionsManager extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._channelSubscriptions.add(channel.id);
|
this._channelSubscriptions.add(channel.id);
|
||||||
|
this._startChannelMentionsSubscription(channel);
|
||||||
|
|
||||||
if (!channel.isDirectMessageChannel) {
|
if (!channel.isDirectMessageChannel) {
|
||||||
this._startChannelMentionsSubscription(channel);
|
|
||||||
this._startKickFromChannelSubscription(channel);
|
this._startKickFromChannelSubscription(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,20 +42,38 @@ export default class ChatTrackingStateManager extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get publicChannelUnreadCount() {
|
get publicChannelUnreadCount() {
|
||||||
return this.#publicChannels().reduce((unreadCount, channel) => {
|
return this.#publicChannels.reduce((unreadCount, channel) => {
|
||||||
return unreadCount + channel.tracking.unreadCount;
|
return unreadCount + channel.tracking.unreadCount;
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get allChannelMentionCount() {
|
||||||
|
let totalPublicMentions = this.#publicChannels.reduce(
|
||||||
|
(channelMentionCount, channel) => {
|
||||||
|
return channelMentionCount + channel.tracking.mentionCount;
|
||||||
|
},
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
let totalPrivateMentions = this.#directMessageChannels.reduce(
|
||||||
|
(dmMentionCount, channel) => {
|
||||||
|
return dmMentionCount + channel.tracking.mentionCount;
|
||||||
|
},
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
return totalPublicMentions + totalPrivateMentions;
|
||||||
|
}
|
||||||
|
|
||||||
get allChannelUrgentCount() {
|
get allChannelUrgentCount() {
|
||||||
let publicChannelMentionCount = this.#publicChannels().reduce(
|
let publicChannelMentionCount = this.#publicChannels.reduce(
|
||||||
(mentionCount, channel) => {
|
(mentionCount, channel) => {
|
||||||
return mentionCount + channel.tracking.mentionCount;
|
return mentionCount + channel.tracking.mentionCount;
|
||||||
},
|
},
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
let dmChannelUnreadCount = this.#directMessageChannels().reduce(
|
let dmChannelUnreadCount = this.#directMessageChannels.reduce(
|
||||||
(unreadCount, channel) => {
|
(unreadCount, channel) => {
|
||||||
return unreadCount + channel.tracking.unreadCount;
|
return unreadCount + channel.tracking.unreadCount;
|
||||||
},
|
},
|
||||||
@ -96,11 +114,11 @@ export default class ChatTrackingStateManager extends Service {
|
|||||||
model.tracking.mentionCount = state.mention_count;
|
model.tracking.mentionCount = state.mention_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#publicChannels() {
|
get #publicChannels() {
|
||||||
return this.chatChannelsManager.publicMessageChannels;
|
return this.chatChannelsManager.publicMessageChannels;
|
||||||
}
|
}
|
||||||
|
|
||||||
#directMessageChannels() {
|
get #directMessageChannels() {
|
||||||
return this.chatChannelsManager.directMessageChannels;
|
return this.chatChannelsManager.directMessageChannels;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,6 +118,7 @@ en:
|
|||||||
title: "Show activity indicator in header"
|
title: "Show activity indicator in header"
|
||||||
all_new: "All New Messages"
|
all_new: "All New Messages"
|
||||||
dm_and_mentions: "Direct Messages and Mentions"
|
dm_and_mentions: "Direct Messages and Mentions"
|
||||||
|
only_mentions: "Only Mentions"
|
||||||
never: "Never"
|
never: "Never"
|
||||||
separate_sidebar_mode:
|
separate_sidebar_mode:
|
||||||
title: "Show separate sidebar modes for forum and chat"
|
title: "Show separate sidebar modes for forum and chat"
|
||||||
|
@ -20,7 +20,12 @@ module Chat
|
|||||||
end
|
end
|
||||||
|
|
||||||
def base.chat_header_indicator_preferences
|
def base.chat_header_indicator_preferences
|
||||||
@chat_header_indicator_preferences ||= { all_new: 0, dm_and_mentions: 1, never: 2 }
|
@chat_header_indicator_preferences ||= {
|
||||||
|
all_new: 0,
|
||||||
|
dm_and_mentions: 1,
|
||||||
|
never: 2,
|
||||||
|
only_mentions: 3,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
# Avoid attempting to override when autoloading
|
# Avoid attempting to override when autoloading
|
||||||
|
@ -12,7 +12,7 @@ RSpec.describe "Message notifications - with sidebar", type: :system do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create_message(text: nil, channel:, creator: Fabricate(:user))
|
def create_message(text: nil, channel:, creator: Fabricate(:user))
|
||||||
Fabricate(:chat_message_with_service, chat_channel: channel, user: creator, message: text)
|
Fabricate(:chat_message_with_service, chat_channel: channel, message: text, user: creator)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "as a user" do
|
context "as a user" do
|
||||||
@ -165,6 +165,33 @@ RSpec.describe "Message notifications - with sidebar", type: :system do
|
|||||||
fab!(:dm_channel_1) { Fabricate(:direct_message_channel, users: [current_user, user_1]) }
|
fab!(:dm_channel_1) { Fabricate(:direct_message_channel, users: [current_user, user_1]) }
|
||||||
fab!(:dm_channel_2) { Fabricate(:direct_message_channel, users: [current_user, user_2]) }
|
fab!(:dm_channel_2) { Fabricate(:direct_message_channel, users: [current_user, user_2]) }
|
||||||
|
|
||||||
|
context "when chat_header_indicator_preference is 'only_mentions'" do
|
||||||
|
before do
|
||||||
|
current_user.user_option.update!(
|
||||||
|
chat_header_indicator_preference:
|
||||||
|
UserOption.chat_header_indicator_preferences[:only_mentions],
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't show indicator on chat-header-icon for messages" do
|
||||||
|
visit("/")
|
||||||
|
create_message(channel: dm_channel_1, creator: user_1)
|
||||||
|
expect(page).to have_no_css(".chat-header-icon .chat-channel-unread-indicator.-urgent")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does show an indicator on chat-header-icon for mentions" do
|
||||||
|
Jobs.run_immediately!
|
||||||
|
visit("/")
|
||||||
|
create_message(
|
||||||
|
text: "hey what's up @#{current_user.username}?",
|
||||||
|
channel: dm_channel_1,
|
||||||
|
creator: user_1,
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(page).to have_css(".chat-header-icon .chat-channel-unread-indicator.-urgent")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "when a message is created" do
|
context "when a message is created" do
|
||||||
it "correctly renders notifications" do
|
it "correctly renders notifications" do
|
||||||
visit("/")
|
visit("/")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user