Don't reference the notification levels by colour (#12138)
* Don't reference the notification levels by colour We're about to change what colours they are so either we'd have to rename a bunch of constants. We may as well make things not reference what colour anything is in the actual UI. Hopefully these constants are clear enough. * Rename NotificationColor -> NotificationLevel * Red -> Highlight * Grey -> Notification * Bold -> Activity * Anywhere else that calls it 'color' -> 'level' Also fixes some weird mixes of US & UK English. It turns out this is referenced in... quite a lot of places, so this is quite a large PR. It can't really be much smaller, sorry. * One test rename & some hiding due to ts-ignore * More hiding behind ts-ignore * Damn you, @ts-ignore... * Fix test CSS values * Missed some colour -> level Co-authored-by: Florian Duros <florianduros@element.io> * Change other instances of variables renamed in suggestion * Update new test for renames --------- Co-authored-by: Florian Duros <florianduros@element.io>
This commit is contained in:
parent
97339ee2f6
commit
9254e9562e
42 changed files with 268 additions and 265 deletions
|
@ -212,17 +212,17 @@ limitations under the License.
|
||||||
top: var(--RoomHeader-indicator-dot-offset);
|
top: var(--RoomHeader-indicator-dot-offset);
|
||||||
margin: 4px;
|
margin: 4px;
|
||||||
|
|
||||||
&.mx_Indicator_red {
|
&.mx_Indicator_highlight {
|
||||||
background: $alert;
|
background: $alert;
|
||||||
box-shadow: $alert;
|
box-shadow: $alert;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.mx_Indicator_gray {
|
&.mx_Indicator_notification {
|
||||||
background: $room-icon-unread-color;
|
background: $room-icon-unread-color;
|
||||||
box-shadow: $room-icon-unread-color;
|
box-shadow: $room-icon-unread-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.mx_Indicator_bold {
|
&.mx_Indicator_activity {
|
||||||
background: $primary-content;
|
background: $primary-content;
|
||||||
box-shadow: $primary-content;
|
box-shadow: $primary-content;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,11 +83,6 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&::before {
|
|
||||||
@mixin ThreadSummaryIcon;
|
|
||||||
align-self: center; /* v-align the threads icon */
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_ThreadSummary_sender,
|
.mx_ThreadSummary_sender,
|
||||||
.mx_ThreadSummary_content,
|
.mx_ThreadSummary_content,
|
||||||
.mx_ThreadSummary_replies_amount {
|
.mx_ThreadSummary_replies_amount {
|
||||||
|
|
|
@ -24,7 +24,7 @@ import {
|
||||||
} from "matrix-js-sdk/src/matrix";
|
} from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
import type { IPushRule, Room, MatrixClient } from "matrix-js-sdk/src/matrix";
|
import type { IPushRule, Room, MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||||
import { NotificationColor } from "./stores/notifications/NotificationColor";
|
import { NotificationLevel } from "./stores/notifications/NotificationLevel";
|
||||||
import { getUnsentMessages } from "./components/structures/RoomStatusBar";
|
import { getUnsentMessages } from "./components/structures/RoomStatusBar";
|
||||||
import { doesRoomHaveUnreadMessages, doesRoomOrThreadHaveUnreadMessages } from "./Unread";
|
import { doesRoomHaveUnreadMessages, doesRoomOrThreadHaveUnreadMessages } from "./Unread";
|
||||||
import { EffectiveMembership, getEffectiveMembership, isKnockDenied } from "./utils/membership";
|
import { EffectiveMembership, getEffectiveMembership, isKnockDenied } from "./utils/membership";
|
||||||
|
@ -227,25 +227,25 @@ function isMuteRule(rule: IPushRule): boolean {
|
||||||
export function determineUnreadState(
|
export function determineUnreadState(
|
||||||
room?: Room,
|
room?: Room,
|
||||||
threadId?: string,
|
threadId?: string,
|
||||||
): { color: NotificationColor; symbol: string | null; count: number } {
|
): { level: NotificationLevel; symbol: string | null; count: number } {
|
||||||
if (!room) {
|
if (!room) {
|
||||||
return { symbol: null, count: 0, color: NotificationColor.None };
|
return { symbol: null, count: 0, level: NotificationLevel.None };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getUnsentMessages(room, threadId).length > 0) {
|
if (getUnsentMessages(room, threadId).length > 0) {
|
||||||
return { symbol: "!", count: 1, color: NotificationColor.Unsent };
|
return { symbol: "!", count: 1, level: NotificationLevel.Unsent };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getEffectiveMembership(room.getMyMembership()) === EffectiveMembership.Invite) {
|
if (getEffectiveMembership(room.getMyMembership()) === EffectiveMembership.Invite) {
|
||||||
return { symbol: "!", count: 1, color: NotificationColor.Red };
|
return { symbol: "!", count: 1, level: NotificationLevel.Highlight };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SettingsStore.getValue("feature_ask_to_join") && isKnockDenied(room)) {
|
if (SettingsStore.getValue("feature_ask_to_join") && isKnockDenied(room)) {
|
||||||
return { symbol: "!", count: 1, color: NotificationColor.Red };
|
return { symbol: "!", count: 1, level: NotificationLevel.Highlight };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getRoomNotifsState(room.client, room.roomId) === RoomNotifState.Mute) {
|
if (getRoomNotifsState(room.client, room.roomId) === RoomNotifState.Mute) {
|
||||||
return { symbol: null, count: 0, color: NotificationColor.None };
|
return { symbol: null, count: 0, level: NotificationLevel.None };
|
||||||
}
|
}
|
||||||
|
|
||||||
const redNotifs = getUnreadNotificationCount(room, NotificationCountType.Highlight, threadId);
|
const redNotifs = getUnreadNotificationCount(room, NotificationCountType.Highlight, threadId);
|
||||||
|
@ -253,11 +253,11 @@ export function determineUnreadState(
|
||||||
|
|
||||||
const trueCount = greyNotifs || redNotifs;
|
const trueCount = greyNotifs || redNotifs;
|
||||||
if (redNotifs > 0) {
|
if (redNotifs > 0) {
|
||||||
return { symbol: null, count: trueCount, color: NotificationColor.Red };
|
return { symbol: null, count: trueCount, level: NotificationLevel.Highlight };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (greyNotifs > 0) {
|
if (greyNotifs > 0) {
|
||||||
return { symbol: null, count: trueCount, color: NotificationColor.Grey };
|
return { symbol: null, count: trueCount, level: NotificationLevel.Notification };
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't have any notified messages, but we might have unread messages. Let's find out.
|
// We don't have any notified messages, but we might have unread messages. Let's find out.
|
||||||
|
@ -275,6 +275,6 @@ export function determineUnreadState(
|
||||||
return {
|
return {
|
||||||
symbol: null,
|
symbol: null,
|
||||||
count: trueCount,
|
count: trueCount,
|
||||||
color: hasUnread ? NotificationColor.Bold : NotificationColor.None,
|
level: hasUnread ? NotificationLevel.Activity : NotificationLevel.None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,7 @@ import GenericToast from "../views/toasts/GenericToast";
|
||||||
import RovingSpotlightDialog from "../views/dialogs/spotlight/SpotlightDialog";
|
import RovingSpotlightDialog from "../views/dialogs/spotlight/SpotlightDialog";
|
||||||
import { findDMForUser } from "../../utils/dm/findDMForUser";
|
import { findDMForUser } from "../../utils/dm/findDMForUser";
|
||||||
import { Linkify } from "../../HtmlUtils";
|
import { Linkify } from "../../HtmlUtils";
|
||||||
import { NotificationColor } from "../../stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../stores/notifications/NotificationLevel";
|
||||||
import { UserTab } from "../views/dialogs/UserTab";
|
import { UserTab } from "../views/dialogs/UserTab";
|
||||||
import { shouldSkipSetupEncryption } from "../../utils/crypto/shouldSkipSetupEncryption";
|
import { shouldSkipSetupEncryption } from "../../utils/crypto/shouldSkipSetupEncryption";
|
||||||
import { Filter } from "../views/dialogs/spotlight/Filter";
|
import { Filter } from "../views/dialogs/spotlight/Filter";
|
||||||
|
@ -2019,7 +2019,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
if (numUnreadRooms > 0) {
|
if (numUnreadRooms > 0) {
|
||||||
this.subTitleStatus += `[${numUnreadRooms}]`;
|
this.subTitleStatus += `[${numUnreadRooms}]`;
|
||||||
} else if (notificationState.color >= NotificationColor.Bold) {
|
} else if (notificationState.level >= NotificationLevel.Activity) {
|
||||||
this.subTitleStatus += `*`;
|
this.subTitleStatus += `*`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ import { useEventEmitterState } from "../../../hooks/useEventEmitter";
|
||||||
import { useUnreadNotifications } from "../../../hooks/useUnreadNotifications";
|
import { useUnreadNotifications } from "../../../hooks/useUnreadNotifications";
|
||||||
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
|
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
|
||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../stores/notifications/NotificationLevel";
|
||||||
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
|
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
|
||||||
import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore";
|
import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore";
|
||||||
import DMRoomMap from "../../../utils/DMRoomMap";
|
import DMRoomMap from "../../../utils/DMRoomMap";
|
||||||
|
@ -212,9 +212,9 @@ export const RoomGeneralContextMenu: React.FC<RoomGeneralContextMenuProps> = ({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { color } = useUnreadNotifications(room);
|
const { level } = useUnreadNotifications(room);
|
||||||
const markAsReadOption: JSX.Element | null =
|
const markAsReadOption: JSX.Element | null =
|
||||||
color > NotificationColor.None ? (
|
level > NotificationLevel.None ? (
|
||||||
<IconizedContextMenuCheckbox
|
<IconizedContextMenuCheckbox
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
clearRoomNotification(room, cli);
|
clearRoomNotification(room, cli);
|
||||||
|
|
|
@ -22,7 +22,7 @@ import MatrixClientContext from "../../../../contexts/MatrixClientContext";
|
||||||
import { useNotificationState } from "../../../../hooks/useRoomNotificationState";
|
import { useNotificationState } from "../../../../hooks/useRoomNotificationState";
|
||||||
import { _t, _td } from "../../../../languageHandler";
|
import { _t, _td } from "../../../../languageHandler";
|
||||||
import { determineUnreadState } from "../../../../RoomNotifs";
|
import { determineUnreadState } from "../../../../RoomNotifs";
|
||||||
import { humanReadableNotificationColor } from "../../../../stores/notifications/NotificationColor";
|
import { humanReadableNotificationLevel } from "../../../../stores/notifications/NotificationLevel";
|
||||||
import { doesRoomOrThreadHaveUnreadMessages } from "../../../../Unread";
|
import { doesRoomOrThreadHaveUnreadMessages } from "../../../../Unread";
|
||||||
import BaseTool, { DevtoolsContext, IDevtoolsProps } from "./BaseTool";
|
import BaseTool, { DevtoolsContext, IDevtoolsProps } from "./BaseTool";
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ export default function RoomNotifications({ onBack }: IDevtoolsProps): JSX.Eleme
|
||||||
const { room } = useContext(DevtoolsContext);
|
const { room } = useContext(DevtoolsContext);
|
||||||
const cli = useContext(MatrixClientContext);
|
const cli = useContext(MatrixClientContext);
|
||||||
|
|
||||||
const { color, count } = determineUnreadState(room);
|
const { level, count } = determineUnreadState(room);
|
||||||
const [notificationState] = useNotificationState(room);
|
const [notificationState] = useNotificationState(room);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -81,7 +81,7 @@ export default function RoomNotifications({ onBack }: IDevtoolsProps): JSX.Eleme
|
||||||
? _t(
|
? _t(
|
||||||
"devtools|room_unread_status_count",
|
"devtools|room_unread_status_count",
|
||||||
{
|
{
|
||||||
status: humanReadableNotificationColor(color),
|
status: humanReadableNotificationLevel(level),
|
||||||
count,
|
count,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -91,7 +91,7 @@ export default function RoomNotifications({ onBack }: IDevtoolsProps): JSX.Eleme
|
||||||
: _t(
|
: _t(
|
||||||
"devtools|room_unread_status",
|
"devtools|room_unread_status",
|
||||||
{
|
{
|
||||||
status: humanReadableNotificationColor(color),
|
status: humanReadableNotificationLevel(level),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
strong: (sub) => <strong>{sub}</strong>,
|
strong: (sub) => <strong>{sub}</strong>,
|
||||||
|
|
|
@ -24,7 +24,7 @@ import dis from "../../../dispatcher/dispatcher";
|
||||||
import RightPanelStore from "../../../stores/right-panel/RightPanelStore";
|
import RightPanelStore from "../../../stores/right-panel/RightPanelStore";
|
||||||
import { RightPanelPhases } from "../../../stores/right-panel/RightPanelStorePhases";
|
import { RightPanelPhases } from "../../../stores/right-panel/RightPanelStorePhases";
|
||||||
import { UPDATE_EVENT } from "../../../stores/AsyncStore";
|
import { UPDATE_EVENT } from "../../../stores/AsyncStore";
|
||||||
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../stores/notifications/NotificationLevel";
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
|
|
||||||
export enum HeaderKind {
|
export enum HeaderKind {
|
||||||
|
@ -34,8 +34,8 @@ export enum HeaderKind {
|
||||||
interface IState {
|
interface IState {
|
||||||
headerKind: HeaderKind;
|
headerKind: HeaderKind;
|
||||||
phase: RightPanelPhases | null;
|
phase: RightPanelPhases | null;
|
||||||
threadNotificationColor: NotificationColor;
|
threadNotificationLevel: NotificationLevel;
|
||||||
globalNotificationColor: NotificationColor;
|
globalNotificationLevel: NotificationLevel;
|
||||||
notificationsEnabled?: boolean;
|
notificationsEnabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ export default abstract class HeaderButtons<P = {}> extends React.Component<IPro
|
||||||
this.state = {
|
this.state = {
|
||||||
headerKind: kind,
|
headerKind: kind,
|
||||||
phase: rps.currentCard.phase,
|
phase: rps.currentCard.phase,
|
||||||
threadNotificationColor: NotificationColor.None,
|
threadNotificationLevel: NotificationLevel.None,
|
||||||
globalNotificationColor: NotificationColor.None,
|
globalNotificationLevel: NotificationLevel.None,
|
||||||
notificationsEnabled: SettingsStore.getValue("feature_notifications"),
|
notificationsEnabled: SettingsStore.getValue("feature_notifications"),
|
||||||
};
|
};
|
||||||
this.watcherRef = SettingsStore.watchSetting("feature_notifications", null, (...[, , , value]) =>
|
this.watcherRef = SettingsStore.watchSetting("feature_notifications", null, (...[, , , value]) =>
|
||||||
|
|
|
@ -35,7 +35,7 @@ import {
|
||||||
RoomNotificationStateStore,
|
RoomNotificationStateStore,
|
||||||
UPDATE_STATUS_INDICATOR,
|
UPDATE_STATUS_INDICATOR,
|
||||||
} from "../../../stores/notifications/RoomNotificationStateStore";
|
} from "../../../stores/notifications/RoomNotificationStateStore";
|
||||||
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../stores/notifications/NotificationLevel";
|
||||||
import { SummarizedNotificationState } from "../../../stores/notifications/SummarizedNotificationState";
|
import { SummarizedNotificationState } from "../../../stores/notifications/SummarizedNotificationState";
|
||||||
import PosthogTrackers from "../../../PosthogTrackers";
|
import PosthogTrackers from "../../../PosthogTrackers";
|
||||||
import { ButtonEvent } from "../elements/AccessibleButton";
|
import { ButtonEvent } from "../elements/AccessibleButton";
|
||||||
|
@ -52,20 +52,20 @@ const ROOM_INFO_PHASES = [
|
||||||
];
|
];
|
||||||
|
|
||||||
interface IUnreadIndicatorProps {
|
interface IUnreadIndicatorProps {
|
||||||
color?: NotificationColor;
|
color?: NotificationLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
const UnreadIndicator: React.FC<IUnreadIndicatorProps> = ({ color }) => {
|
const UnreadIndicator: React.FC<IUnreadIndicatorProps> = ({ color }) => {
|
||||||
if (color === NotificationColor.None) {
|
if (color === NotificationLevel.None) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const classes = classNames({
|
const classes = classNames({
|
||||||
mx_Indicator: true,
|
mx_Indicator: true,
|
||||||
mx_LegacyRoomHeader_button_unreadIndicator: true,
|
mx_LegacyRoomHeader_button_unreadIndicator: true,
|
||||||
mx_Indicator_bold: color === NotificationColor.Bold,
|
mx_Indicator_activity: color === NotificationLevel.Activity,
|
||||||
mx_Indicator_gray: color === NotificationColor.Grey,
|
mx_Indicator_notification: color === NotificationLevel.Notification,
|
||||||
mx_Indicator_red: color === NotificationColor.Red,
|
mx_Indicator_highlight: color === NotificationLevel.Highlight,
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -106,11 +106,11 @@ const PinnedMessagesHeaderButton: React.FC<IHeaderButtonProps> = ({ room, isHigh
|
||||||
|
|
||||||
const TimelineCardHeaderButton: React.FC<IHeaderButtonProps> = ({ room, isHighlighted, onClick }) => {
|
const TimelineCardHeaderButton: React.FC<IHeaderButtonProps> = ({ room, isHighlighted, onClick }) => {
|
||||||
let unreadIndicator;
|
let unreadIndicator;
|
||||||
const color = RoomNotificationStateStore.instance.getRoomState(room).color;
|
const color = RoomNotificationStateStore.instance.getRoomState(room).level;
|
||||||
switch (color) {
|
switch (color) {
|
||||||
case NotificationColor.Bold:
|
case NotificationLevel.Activity:
|
||||||
case NotificationColor.Grey:
|
case NotificationLevel.Notification:
|
||||||
case NotificationColor.Red:
|
case NotificationLevel.Highlight:
|
||||||
unreadIndicator = <UnreadIndicator color={color} />;
|
unreadIndicator = <UnreadIndicator color={color} />;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
@ -174,36 +174,36 @@ export default class LegacyRoomHeaderButtons extends HeaderButtons<IProps> {
|
||||||
|
|
||||||
private onNotificationUpdate = (): void => {
|
private onNotificationUpdate = (): void => {
|
||||||
// console.log
|
// console.log
|
||||||
// XXX: why don't we read from this.state.threadNotificationColor in the render methods?
|
// XXX: why don't we read from this.state.threadNotificationLevel in the render methods?
|
||||||
this.setState({
|
this.setState({
|
||||||
threadNotificationColor: this.notificationColor,
|
threadNotificationLevel: this.notificationLevel,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
private get notificationColor(): NotificationColor {
|
private get notificationLevel(): NotificationLevel {
|
||||||
switch (this.props.room?.threadsAggregateNotificationType) {
|
switch (this.props.room?.threadsAggregateNotificationType) {
|
||||||
case NotificationCountType.Highlight:
|
case NotificationCountType.Highlight:
|
||||||
return NotificationColor.Red;
|
return NotificationLevel.Highlight;
|
||||||
case NotificationCountType.Total:
|
case NotificationCountType.Total:
|
||||||
return NotificationColor.Grey;
|
return NotificationLevel.Notification;
|
||||||
}
|
}
|
||||||
// We don't have any notified messages, but we might have unread messages. Let's
|
// We don't have any notified messages, but we might have unread messages. Let's
|
||||||
// find out.
|
// find out.
|
||||||
for (const thread of this.props.room!.getThreads()) {
|
for (const thread of this.props.room!.getThreads()) {
|
||||||
// If the current thread has unread messages, we're done.
|
// If the current thread has unread messages, we're done.
|
||||||
if (doesRoomOrThreadHaveUnreadMessages(thread)) {
|
if (doesRoomOrThreadHaveUnreadMessages(thread)) {
|
||||||
return NotificationColor.Bold;
|
return NotificationLevel.Activity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Otherwise, no notification color.
|
// Otherwise, no notification color.
|
||||||
return NotificationColor.None;
|
return NotificationLevel.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
private onUpdateStatus = (notificationState: SummarizedNotificationState): void => {
|
private onUpdateStatus = (notificationState: SummarizedNotificationState): void => {
|
||||||
// XXX: why don't we read from this.state.globalNotificationCount in the render methods?
|
// XXX: why don't we read from this.state.globalNotificationCount in the render methods?
|
||||||
this.globalNotificationState = notificationState;
|
this.globalNotificationState = notificationState;
|
||||||
this.setState({
|
this.setState({
|
||||||
globalNotificationColor: notificationState.color,
|
globalNotificationLevel: notificationState.level,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -282,9 +282,9 @@ export default class LegacyRoomHeaderButtons extends HeaderButtons<IProps> {
|
||||||
title={_t("common|threads")}
|
title={_t("common|threads")}
|
||||||
onClick={this.onThreadsPanelClicked}
|
onClick={this.onThreadsPanelClicked}
|
||||||
isHighlighted={this.isPhase(LegacyRoomHeaderButtons.THREAD_PHASES)}
|
isHighlighted={this.isPhase(LegacyRoomHeaderButtons.THREAD_PHASES)}
|
||||||
isUnread={this.state.threadNotificationColor > NotificationColor.None}
|
isUnread={this.state.threadNotificationLevel > NotificationLevel.None}
|
||||||
>
|
>
|
||||||
<UnreadIndicator color={this.state.threadNotificationColor} />
|
<UnreadIndicator color={this.state.threadNotificationLevel} />
|
||||||
</HeaderButton>,
|
</HeaderButton>,
|
||||||
);
|
);
|
||||||
if (this.state.notificationsEnabled) {
|
if (this.state.notificationsEnabled) {
|
||||||
|
@ -296,10 +296,10 @@ export default class LegacyRoomHeaderButtons extends HeaderButtons<IProps> {
|
||||||
title={_t("notifications|enable_prompt_toast_title")}
|
title={_t("notifications|enable_prompt_toast_title")}
|
||||||
isHighlighted={this.isPhase(RightPanelPhases.NotificationPanel)}
|
isHighlighted={this.isPhase(RightPanelPhases.NotificationPanel)}
|
||||||
onClick={this.onNotificationsClicked}
|
onClick={this.onNotificationsClicked}
|
||||||
isUnread={this.globalNotificationState.color === NotificationColor.Red}
|
isUnread={this.globalNotificationState.level === NotificationLevel.Highlight}
|
||||||
>
|
>
|
||||||
{this.globalNotificationState.color === NotificationColor.Red ? (
|
{this.globalNotificationState.level === NotificationLevel.Highlight ? (
|
||||||
<UnreadIndicator color={this.globalNotificationState.color} />
|
<UnreadIndicator color={this.globalNotificationState.level} />
|
||||||
) : null}
|
) : null}
|
||||||
</HeaderButton>,
|
</HeaderButton>,
|
||||||
);
|
);
|
||||||
|
|
|
@ -21,7 +21,7 @@ import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import { XOR } from "../../../@types/common";
|
import { XOR } from "../../../@types/common";
|
||||||
import { NotificationState, NotificationStateEvents } from "../../../stores/notifications/NotificationState";
|
import { NotificationState, NotificationStateEvents } from "../../../stores/notifications/NotificationState";
|
||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../stores/notifications/NotificationLevel";
|
||||||
import { StatelessNotificationBadge } from "./NotificationBadge/StatelessNotificationBadge";
|
import { StatelessNotificationBadge } from "./NotificationBadge/StatelessNotificationBadge";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
|
@ -107,7 +107,7 @@ export default class NotificationBadge extends React.PureComponent<XOR<IProps, I
|
||||||
const commonProps: React.ComponentProps<typeof StatelessNotificationBadge> = {
|
const commonProps: React.ComponentProps<typeof StatelessNotificationBadge> = {
|
||||||
symbol: notification.symbol,
|
symbol: notification.symbol,
|
||||||
count: notification.count,
|
count: notification.count,
|
||||||
color: notification.color,
|
level: notification.level,
|
||||||
knocked: notification.knocked,
|
knocked: notification.knocked,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ export default class NotificationBadge extends React.PureComponent<XOR<IProps, I
|
||||||
badge = <StatelessNotificationBadge {...commonProps} />;
|
badge = <StatelessNotificationBadge {...commonProps} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showUnsentTooltip && notification.color === NotificationColor.Unsent) {
|
if (showUnsentTooltip && notification.level === NotificationLevel.Unsent) {
|
||||||
return (
|
return (
|
||||||
<Tooltip label={_t("notifications|message_didnt_send")} side="right">
|
<Tooltip label={_t("notifications|message_didnt_send")} side="right">
|
||||||
{badge}
|
{badge}
|
||||||
|
|
|
@ -19,14 +19,14 @@ import classNames from "classnames";
|
||||||
|
|
||||||
import { formatCount } from "../../../../utils/FormattingUtils";
|
import { formatCount } from "../../../../utils/FormattingUtils";
|
||||||
import AccessibleButton, { ButtonEvent } from "../../elements/AccessibleButton";
|
import AccessibleButton, { ButtonEvent } from "../../elements/AccessibleButton";
|
||||||
import { NotificationColor } from "../../../../stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../../stores/notifications/NotificationLevel";
|
||||||
import { useSettingValue } from "../../../../hooks/useSettings";
|
import { useSettingValue } from "../../../../hooks/useSettings";
|
||||||
import { XOR } from "../../../../@types/common";
|
import { XOR } from "../../../../@types/common";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
symbol: string | null;
|
symbol: string | null;
|
||||||
count: number;
|
count: number;
|
||||||
color: NotificationColor;
|
level: NotificationLevel;
|
||||||
knocked?: boolean;
|
knocked?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,15 +39,15 @@ interface ClickableProps extends Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const StatelessNotificationBadge = forwardRef<HTMLDivElement, XOR<Props, ClickableProps>>(
|
export const StatelessNotificationBadge = forwardRef<HTMLDivElement, XOR<Props, ClickableProps>>(
|
||||||
({ symbol, count, color, knocked, ...props }, ref) => {
|
({ symbol, count, level, knocked, ...props }, ref) => {
|
||||||
const hideBold = useSettingValue("feature_hidebold");
|
const hideBold = useSettingValue("feature_hidebold");
|
||||||
|
|
||||||
// Don't show a badge if we don't need to
|
// Don't show a badge if we don't need to
|
||||||
if ((color === NotificationColor.None || (hideBold && color == NotificationColor.Bold)) && !knocked) {
|
if ((level === NotificationLevel.None || (hideBold && level == NotificationLevel.Activity)) && !knocked) {
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasUnreadCount = color >= NotificationColor.Grey && (!!count || !!symbol);
|
const hasUnreadCount = level >= NotificationLevel.Notification && (!!count || !!symbol);
|
||||||
|
|
||||||
const isEmptyBadge = symbol === null && count === 0;
|
const isEmptyBadge = symbol === null && count === 0;
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ export const StatelessNotificationBadge = forwardRef<HTMLDivElement, XOR<Props,
|
||||||
const classes = classNames({
|
const classes = classNames({
|
||||||
mx_NotificationBadge: true,
|
mx_NotificationBadge: true,
|
||||||
mx_NotificationBadge_visible: isEmptyBadge || knocked ? true : hasUnreadCount,
|
mx_NotificationBadge_visible: isEmptyBadge || knocked ? true : hasUnreadCount,
|
||||||
mx_NotificationBadge_highlighted: color >= NotificationColor.Red,
|
mx_NotificationBadge_highlighted: level >= NotificationLevel.Highlight,
|
||||||
mx_NotificationBadge_dot: isEmptyBadge && !knocked,
|
mx_NotificationBadge_dot: isEmptyBadge && !knocked,
|
||||||
mx_NotificationBadge_knocked: knocked,
|
mx_NotificationBadge_knocked: knocked,
|
||||||
mx_NotificationBadge_2char: symbol && symbol.length > 0 && symbol.length < 3,
|
mx_NotificationBadge_2char: symbol && symbol.length > 0 && symbol.length < 3,
|
||||||
|
|
|
@ -26,7 +26,7 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function UnreadNotificationBadge({ room, threadId }: Props): JSX.Element {
|
export function UnreadNotificationBadge({ room, threadId }: Props): JSX.Element {
|
||||||
const { symbol, count, color } = useUnreadNotifications(room, threadId);
|
const { symbol, count, level } = useUnreadNotifications(room, threadId);
|
||||||
|
|
||||||
return <StatelessNotificationBadge symbol={symbol} count={count} color={color} />;
|
return <StatelessNotificationBadge symbol={symbol} count={count} level={level} />;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ import { Flex } from "../../utils/Flex";
|
||||||
import { Box } from "../../utils/Box";
|
import { Box } from "../../utils/Box";
|
||||||
import { useRoomCall } from "../../../hooks/room/useRoomCall";
|
import { useRoomCall } from "../../../hooks/room/useRoomCall";
|
||||||
import { useRoomThreadNotifications } from "../../../hooks/room/useRoomThreadNotifications";
|
import { useRoomThreadNotifications } from "../../../hooks/room/useRoomThreadNotifications";
|
||||||
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../stores/notifications/NotificationLevel";
|
||||||
import { useGlobalNotificationState } from "../../../hooks/useGlobalNotificationState";
|
import { useGlobalNotificationState } from "../../../hooks/useGlobalNotificationState";
|
||||||
import SdkConfig from "../../../SdkConfig";
|
import SdkConfig from "../../../SdkConfig";
|
||||||
import { useFeatureEnabled } from "../../../hooks/useSettings";
|
import { useFeatureEnabled } from "../../../hooks/useSettings";
|
||||||
|
@ -57,10 +57,10 @@ import { RoomKnocksBar } from "./RoomKnocksBar";
|
||||||
* A helper to transform a notification color to the what the Compound Icon Button
|
* A helper to transform a notification color to the what the Compound Icon Button
|
||||||
* expects
|
* expects
|
||||||
*/
|
*/
|
||||||
function notificationColorToIndicator(color: NotificationColor): React.ComponentProps<typeof IconButton>["indicator"] {
|
function notificationLevelToIndicator(color: NotificationLevel): React.ComponentProps<typeof IconButton>["indicator"] {
|
||||||
if (color <= NotificationColor.None) {
|
if (color <= NotificationLevel.None) {
|
||||||
return undefined;
|
return undefined;
|
||||||
} else if (color <= NotificationColor.Grey) {
|
} else if (color <= NotificationLevel.Notification) {
|
||||||
return "default";
|
return "default";
|
||||||
} else {
|
} else {
|
||||||
return "highlight";
|
return "highlight";
|
||||||
|
@ -230,7 +230,7 @@ export default function RoomHeader({
|
||||||
|
|
||||||
<Tooltip label={_t("common|threads")}>
|
<Tooltip label={_t("common|threads")}>
|
||||||
<IconButton
|
<IconButton
|
||||||
indicator={notificationColorToIndicator(threadNotifications)}
|
indicator={notificationLevelToIndicator(threadNotifications)}
|
||||||
onClick={(evt) => {
|
onClick={(evt) => {
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
RightPanelStore.instance.showOrHidePanel(RightPanelPhases.ThreadPanel);
|
RightPanelStore.instance.showOrHidePanel(RightPanelPhases.ThreadPanel);
|
||||||
|
@ -244,7 +244,7 @@ export default function RoomHeader({
|
||||||
{notificationsEnabled && (
|
{notificationsEnabled && (
|
||||||
<Tooltip label={_t("notifications|enable_prompt_toast_title")}>
|
<Tooltip label={_t("notifications|enable_prompt_toast_title")}>
|
||||||
<IconButton
|
<IconButton
|
||||||
indicator={notificationColorToIndicator(globalNotificationState.color)}
|
indicator={notificationLevelToIndicator(globalNotificationState.level)}
|
||||||
onClick={(evt) => {
|
onClick={(evt) => {
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
RightPanelStore.instance.showOrHidePanel(RightPanelPhases.NotificationPanel);
|
RightPanelStore.instance.showOrHidePanel(RightPanelPhases.NotificationPanel);
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { isVideoRoom as calcIsVideoRoom } from "../../../../utils/video-rooms";
|
||||||
import { _t } from "../../../../languageHandler";
|
import { _t } from "../../../../languageHandler";
|
||||||
import { useEventEmitterState } from "../../../../hooks/useEventEmitter";
|
import { useEventEmitterState } from "../../../../hooks/useEventEmitter";
|
||||||
import { NotificationStateEvents } from "../../../../stores/notifications/NotificationState";
|
import { NotificationStateEvents } from "../../../../stores/notifications/NotificationState";
|
||||||
import { NotificationColor } from "../../../../stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../../stores/notifications/NotificationLevel";
|
||||||
import { RightPanelPhases } from "../../../../stores/right-panel/RightPanelStorePhases";
|
import { RightPanelPhases } from "../../../../stores/right-panel/RightPanelStorePhases";
|
||||||
import { SDKContext } from "../../../../contexts/SDKContext";
|
import { SDKContext } from "../../../../contexts/SDKContext";
|
||||||
import { ButtonEvent } from "../../elements/AccessibleButton";
|
import { ButtonEvent } from "../../elements/AccessibleButton";
|
||||||
|
@ -43,7 +43,7 @@ export const VideoRoomChatButton: React.FC<{ room: Room }> = ({ room }) => {
|
||||||
const notificationColor = useEventEmitterState(
|
const notificationColor = useEventEmitterState(
|
||||||
notificationState,
|
notificationState,
|
||||||
NotificationStateEvents.Update,
|
NotificationStateEvents.Update,
|
||||||
() => notificationState?.color,
|
() => notificationState?.level,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!isVideoRoom) {
|
if (!isVideoRoom) {
|
||||||
|
@ -52,7 +52,9 @@ export const VideoRoomChatButton: React.FC<{ room: Room }> = ({ room }) => {
|
||||||
|
|
||||||
const displayUnreadIndicator =
|
const displayUnreadIndicator =
|
||||||
!!notificationColor &&
|
!!notificationColor &&
|
||||||
[NotificationColor.Bold, NotificationColor.Grey, NotificationColor.Red].includes(notificationColor);
|
[NotificationLevel.Activity, NotificationLevel.Notification, NotificationLevel.Highlight].includes(
|
||||||
|
notificationColor,
|
||||||
|
);
|
||||||
|
|
||||||
const onClick = (event: ButtonEvent): void => {
|
const onClick = (event: ButtonEvent): void => {
|
||||||
// stop event propagating up and triggering RoomHeader bar click
|
// stop event propagating up and triggering RoomHeader bar click
|
||||||
|
|
|
@ -421,7 +421,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
||||||
// find the first room with a count of the same colour as the badge count
|
// find the first room with a count of the same colour as the badge count
|
||||||
room = RoomListStore.instance.orderedLists[this.props.tagId].find((r: Room) => {
|
room = RoomListStore.instance.orderedLists[this.props.tagId].find((r: Room) => {
|
||||||
const notifState = this.notificationState.getForRoom(r);
|
const notifState = this.notificationState.getForRoom(r);
|
||||||
return notifState.count > 0 && notifState.color === this.notificationState.color;
|
return notifState.count > 0 && notifState.level === this.notificationState.level;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ import ErrorDialog from "../dialogs/ErrorDialog";
|
||||||
import MediaDeviceHandler, { MediaDeviceKindEnum } from "../../../MediaDeviceHandler";
|
import MediaDeviceHandler, { MediaDeviceKindEnum } from "../../../MediaDeviceHandler";
|
||||||
import NotificationBadge from "./NotificationBadge";
|
import NotificationBadge from "./NotificationBadge";
|
||||||
import { StaticNotificationState } from "../../../stores/notifications/StaticNotificationState";
|
import { StaticNotificationState } from "../../../stores/notifications/StaticNotificationState";
|
||||||
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../stores/notifications/NotificationLevel";
|
||||||
import InlineSpinner from "../elements/InlineSpinner";
|
import InlineSpinner from "../elements/InlineSpinner";
|
||||||
import { PlaybackManager } from "../../../audio/PlaybackManager";
|
import { PlaybackManager } from "../../../audio/PlaybackManager";
|
||||||
import { doMaybeLocalRoomAction } from "../../../utils/local-room";
|
import { doMaybeLocalRoomAction } from "../../../utils/local-room";
|
||||||
|
@ -305,7 +305,7 @@ export default class VoiceRecordComposerTile extends React.PureComponent<IProps,
|
||||||
<span className="mx_VoiceRecordComposerTile_uploadState_badge">
|
<span className="mx_VoiceRecordComposerTile_uploadState_badge">
|
||||||
{/* Need to stick the badge in a span to ensure it doesn't create a block component */}
|
{/* Need to stick the badge in a span to ensure it doesn't create a block component */}
|
||||||
<NotificationBadge
|
<NotificationBadge
|
||||||
notification={StaticNotificationState.forSymbol("!", NotificationColor.Red)}
|
notification={StaticNotificationState.forSymbol("!", NotificationLevel.Highlight)}
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span className="text-warning">{_t("timeline|send_state_failed")}</span>
|
<span className="text-warning">{_t("timeline|send_state_failed")}</span>
|
||||||
|
|
|
@ -28,7 +28,7 @@ import {
|
||||||
import { RoomNotifState } from "../../../../RoomNotifs";
|
import { RoomNotifState } from "../../../../RoomNotifs";
|
||||||
import { SettingLevel } from "../../../../settings/SettingLevel";
|
import { SettingLevel } from "../../../../settings/SettingLevel";
|
||||||
import SettingsStore from "../../../../settings/SettingsStore";
|
import SettingsStore from "../../../../settings/SettingsStore";
|
||||||
import { NotificationColor } from "../../../../stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../../stores/notifications/NotificationLevel";
|
||||||
import { clearAllNotifications } from "../../../../utils/notifications";
|
import { clearAllNotifications } from "../../../../utils/notifications";
|
||||||
import AccessibleButton from "../../elements/AccessibleButton";
|
import AccessibleButton from "../../elements/AccessibleButton";
|
||||||
import ExternalLink from "../../elements/ExternalLink";
|
import ExternalLink from "../../elements/ExternalLink";
|
||||||
|
@ -278,7 +278,13 @@ export default function NotificationSettings2(): JSX.Element {
|
||||||
"settings|notifications|keywords",
|
"settings|notifications|keywords",
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
badge: <StatelessNotificationBadge symbol="1" count={1} color={NotificationColor.Grey} />,
|
badge: (
|
||||||
|
<StatelessNotificationBadge
|
||||||
|
symbol="1"
|
||||||
|
count={1}
|
||||||
|
level={NotificationLevel.Notification}
|
||||||
|
/>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
|
@ -40,7 +40,7 @@ import { toRightOf, useContextMenu } from "../../structures/ContextMenu";
|
||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
|
import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
|
||||||
import { StaticNotificationState } from "../../../stores/notifications/StaticNotificationState";
|
import { StaticNotificationState } from "../../../stores/notifications/StaticNotificationState";
|
||||||
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../stores/notifications/NotificationLevel";
|
||||||
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
|
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
|
||||||
import { NotificationState } from "../../../stores/notifications/NotificationState";
|
import { NotificationState } from "../../../stores/notifications/NotificationState";
|
||||||
import SpaceContextMenu from "../context_menus/SpaceContextMenu";
|
import SpaceContextMenu from "../context_menus/SpaceContextMenu";
|
||||||
|
@ -329,7 +329,7 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
||||||
const isInvite = space.getMyMembership() === "invite";
|
const isInvite = space.getMyMembership() === "invite";
|
||||||
|
|
||||||
const notificationState = isInvite
|
const notificationState = isInvite
|
||||||
? StaticNotificationState.forSymbol("!", NotificationColor.Red)
|
? StaticNotificationState.forSymbol("!", NotificationLevel.Highlight)
|
||||||
: SpaceStore.instance.getNotificationState(space.roomId);
|
: SpaceStore.instance.getNotificationState(space.roomId);
|
||||||
|
|
||||||
const hasChildren = this.state.childSpaces?.length;
|
const hasChildren = this.state.childSpaces?.length;
|
||||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
||||||
import { NotificationCountType, Room, RoomEvent, ThreadEvent } from "matrix-js-sdk/src/matrix";
|
import { NotificationCountType, Room, RoomEvent, ThreadEvent } from "matrix-js-sdk/src/matrix";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
import { NotificationColor } from "../../stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../stores/notifications/NotificationLevel";
|
||||||
import { doesRoomOrThreadHaveUnreadMessages } from "../../Unread";
|
import { doesRoomOrThreadHaveUnreadMessages } from "../../Unread";
|
||||||
import { useEventEmitter } from "../useEventEmitter";
|
import { useEventEmitter } from "../useEventEmitter";
|
||||||
|
|
||||||
|
@ -26,16 +26,16 @@ import { useEventEmitter } from "../useEventEmitter";
|
||||||
* @param room the room to track
|
* @param room the room to track
|
||||||
* @returns the type of notification for this room
|
* @returns the type of notification for this room
|
||||||
*/
|
*/
|
||||||
export const useRoomThreadNotifications = (room: Room): NotificationColor => {
|
export const useRoomThreadNotifications = (room: Room): NotificationLevel => {
|
||||||
const [notificationColor, setNotificationColor] = useState(NotificationColor.None);
|
const [notificationLevel, setNotificationLevel] = useState(NotificationLevel.None);
|
||||||
|
|
||||||
const updateNotification = useCallback(() => {
|
const updateNotification = useCallback(() => {
|
||||||
switch (room?.threadsAggregateNotificationType) {
|
switch (room?.threadsAggregateNotificationType) {
|
||||||
case NotificationCountType.Highlight:
|
case NotificationCountType.Highlight:
|
||||||
setNotificationColor(NotificationColor.Red);
|
setNotificationLevel(NotificationLevel.Highlight);
|
||||||
break;
|
break;
|
||||||
case NotificationCountType.Total:
|
case NotificationCountType.Total:
|
||||||
setNotificationColor(NotificationColor.Grey);
|
setNotificationLevel(NotificationLevel.Notification);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// We don't have any notified messages, but we might have unread messages. Let's
|
// We don't have any notified messages, but we might have unread messages. Let's
|
||||||
|
@ -43,7 +43,7 @@ export const useRoomThreadNotifications = (room: Room): NotificationColor => {
|
||||||
for (const thread of room!.getThreads()) {
|
for (const thread of room!.getThreads()) {
|
||||||
// If the current thread has unread messages, we're done.
|
// If the current thread has unread messages, we're done.
|
||||||
if (doesRoomOrThreadHaveUnreadMessages(thread)) {
|
if (doesRoomOrThreadHaveUnreadMessages(thread)) {
|
||||||
setNotificationColor(NotificationColor.Bold);
|
setNotificationLevel(NotificationLevel.Activity);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,5 +63,5 @@ export const useRoomThreadNotifications = (room: Room): NotificationColor => {
|
||||||
updateNotification();
|
updateNotification();
|
||||||
}, [updateNotification]);
|
}, [updateNotification]);
|
||||||
|
|
||||||
return notificationColor;
|
return notificationLevel;
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,7 +19,7 @@ import { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
import type { NotificationCount, Room } from "matrix-js-sdk/src/matrix";
|
import type { NotificationCount, Room } from "matrix-js-sdk/src/matrix";
|
||||||
import { determineUnreadState } from "../RoomNotifs";
|
import { determineUnreadState } from "../RoomNotifs";
|
||||||
import { NotificationColor } from "../stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../stores/notifications/NotificationLevel";
|
||||||
import { useEventEmitter } from "./useEventEmitter";
|
import { useEventEmitter } from "./useEventEmitter";
|
||||||
|
|
||||||
export const useUnreadNotifications = (
|
export const useUnreadNotifications = (
|
||||||
|
@ -28,11 +28,11 @@ export const useUnreadNotifications = (
|
||||||
): {
|
): {
|
||||||
symbol: string | null;
|
symbol: string | null;
|
||||||
count: number;
|
count: number;
|
||||||
color: NotificationColor;
|
level: NotificationLevel;
|
||||||
} => {
|
} => {
|
||||||
const [symbol, setSymbol] = useState<string | null>(null);
|
const [symbol, setSymbol] = useState<string | null>(null);
|
||||||
const [count, setCount] = useState<number>(0);
|
const [count, setCount] = useState<number>(0);
|
||||||
const [color, setColor] = useState<NotificationColor>(NotificationColor.None);
|
const [level, setLevel] = useState<NotificationLevel>(NotificationLevel.None);
|
||||||
|
|
||||||
useEventEmitter(
|
useEventEmitter(
|
||||||
room,
|
room,
|
||||||
|
@ -50,10 +50,10 @@ export const useUnreadNotifications = (
|
||||||
useEventEmitter(room, RoomEvent.MyMembership, () => updateNotificationState());
|
useEventEmitter(room, RoomEvent.MyMembership, () => updateNotificationState());
|
||||||
|
|
||||||
const updateNotificationState = useCallback(() => {
|
const updateNotificationState = useCallback(() => {
|
||||||
const { symbol, count, color } = determineUnreadState(room, threadId);
|
const { symbol, count, level } = determineUnreadState(room, threadId);
|
||||||
setSymbol(symbol);
|
setSymbol(symbol);
|
||||||
setCount(count);
|
setCount(count);
|
||||||
setColor(color);
|
setLevel(level);
|
||||||
}, [room, threadId]);
|
}, [room, threadId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -63,6 +63,6 @@ export const useUnreadNotifications = (
|
||||||
return {
|
return {
|
||||||
symbol,
|
symbol,
|
||||||
count,
|
count,
|
||||||
color,
|
level,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1603,12 +1603,6 @@
|
||||||
"all_messages_description": "Get notified for every message",
|
"all_messages_description": "Get notified for every message",
|
||||||
"class_global": "Global",
|
"class_global": "Global",
|
||||||
"class_other": "Other",
|
"class_other": "Other",
|
||||||
"colour_bold": "Bold",
|
|
||||||
"colour_grey": "Grey",
|
|
||||||
"colour_muted": "Muted",
|
|
||||||
"colour_none": "None",
|
|
||||||
"colour_red": "Red",
|
|
||||||
"colour_unsent": "Unsent",
|
|
||||||
"default": "Default",
|
"default": "Default",
|
||||||
"email_pusher_app_display_name": "Email Notifications",
|
"email_pusher_app_display_name": "Email Notifications",
|
||||||
"enable_prompt_toast_description": "Enable desktop notifications",
|
"enable_prompt_toast_description": "Enable desktop notifications",
|
||||||
|
@ -1617,6 +1611,12 @@
|
||||||
"error_change_title": "Change notification settings",
|
"error_change_title": "Change notification settings",
|
||||||
"keyword": "Keyword",
|
"keyword": "Keyword",
|
||||||
"keyword_new": "New keyword",
|
"keyword_new": "New keyword",
|
||||||
|
"level_activity": "Activity",
|
||||||
|
"level_highlight": "Highlight",
|
||||||
|
"level_muted": "Muted",
|
||||||
|
"level_none": "None",
|
||||||
|
"level_notification": "Notification",
|
||||||
|
"level_unsent": "Unsent",
|
||||||
"mark_all_read": "Mark all as read",
|
"mark_all_read": "Mark all as read",
|
||||||
"mentions_and_keywords": "@mentions & keywords",
|
"mentions_and_keywords": "@mentions & keywords",
|
||||||
"mentions_and_keywords_description": "Get notified only with mentions and keywords as set up in your <a>settings</a>",
|
"mentions_and_keywords_description": "Get notified only with mentions and keywords as set up in your <a>settings</a>",
|
||||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
import { Room } from "matrix-js-sdk/src/matrix";
|
import { Room } from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
import { NotificationColor } from "./NotificationColor";
|
import { NotificationLevel } from "./NotificationLevel";
|
||||||
import { arrayDiff } from "../../utils/arrays";
|
import { arrayDiff } from "../../utils/arrays";
|
||||||
import { RoomNotificationState } from "./RoomNotificationState";
|
import { RoomNotificationState } from "./RoomNotificationState";
|
||||||
import { NotificationState, NotificationStateEvents } from "./NotificationState";
|
import { NotificationState, NotificationStateEvents } from "./NotificationState";
|
||||||
|
@ -35,7 +35,7 @@ export class ListNotificationState extends NotificationState {
|
||||||
}
|
}
|
||||||
|
|
||||||
public get symbol(): string | null {
|
public get symbol(): string | null {
|
||||||
return this._color === NotificationColor.Unsent ? "!" : null;
|
return this._level === NotificationLevel.Unsent ? "!" : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setRooms(rooms: Room[]): void {
|
public setRooms(rooms: Room[]): void {
|
||||||
|
@ -86,14 +86,14 @@ export class ListNotificationState extends NotificationState {
|
||||||
const snapshot = this.snapshot();
|
const snapshot = this.snapshot();
|
||||||
|
|
||||||
if (this.byTileCount) {
|
if (this.byTileCount) {
|
||||||
this._color = NotificationColor.Red;
|
this._level = NotificationLevel.Highlight;
|
||||||
this._count = this.rooms.length;
|
this._count = this.rooms.length;
|
||||||
} else {
|
} else {
|
||||||
this._count = 0;
|
this._count = 0;
|
||||||
this._color = NotificationColor.None;
|
this._level = NotificationLevel.None;
|
||||||
for (const state of Object.values(this.states)) {
|
for (const state of Object.values(this.states)) {
|
||||||
this._count += state.count;
|
this._count += state.count;
|
||||||
this._color = Math.max(this.color, state.color);
|
this._level = Math.max(this.level, state.level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,30 +16,30 @@ limitations under the License.
|
||||||
|
|
||||||
import { _t } from "../../languageHandler";
|
import { _t } from "../../languageHandler";
|
||||||
|
|
||||||
export enum NotificationColor {
|
export enum NotificationLevel {
|
||||||
Muted,
|
Muted,
|
||||||
// Inverted (None -> Red) because we do integer comparisons on this
|
// Inverted (None -> Red) because we do integer comparisons on this
|
||||||
None, // nothing special
|
None, // nothing special
|
||||||
// TODO: Remove bold with notifications: https://github.com/vector-im/element-web/issues/14227
|
// TODO: Remove bold with notifications: https://github.com/vector-im/element-web/issues/14227
|
||||||
Bold, // no badge, show as unread
|
Activity, // no badge, show as unread
|
||||||
Grey, // unread notified messages
|
Notification, // unread notified messages
|
||||||
Red, // unread pings
|
Highlight, // unread pings
|
||||||
Unsent, // some messages failed to send
|
Unsent, // some messages failed to send
|
||||||
}
|
}
|
||||||
|
|
||||||
export function humanReadableNotificationColor(color: NotificationColor): string {
|
export function humanReadableNotificationLevel(level: NotificationLevel): string {
|
||||||
switch (color) {
|
switch (level) {
|
||||||
case NotificationColor.None:
|
case NotificationLevel.None:
|
||||||
return _t("notifications|colour_none");
|
return _t("notifications|level_none");
|
||||||
case NotificationColor.Bold:
|
case NotificationLevel.Activity:
|
||||||
return _t("notifications|colour_bold");
|
return _t("notifications|level_activity");
|
||||||
case NotificationColor.Grey:
|
case NotificationLevel.Notification:
|
||||||
return _t("notifications|colour_grey");
|
return _t("notifications|level_notification");
|
||||||
case NotificationColor.Red:
|
case NotificationLevel.Highlight:
|
||||||
return _t("notifications|colour_red");
|
return _t("notifications|level_highlight");
|
||||||
case NotificationColor.Unsent:
|
case NotificationLevel.Unsent:
|
||||||
return _t("notifications|colour_unsent");
|
return _t("notifications|level_unsent");
|
||||||
case NotificationColor.Muted:
|
case NotificationLevel.Muted:
|
||||||
return _t("notifications|colour_muted");
|
return _t("notifications|level_muted");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,14 +16,14 @@ limitations under the License.
|
||||||
|
|
||||||
import { TypedEventEmitter } from "matrix-js-sdk/src/matrix";
|
import { TypedEventEmitter } from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
import { NotificationColor } from "./NotificationColor";
|
import { NotificationLevel } from "./NotificationLevel";
|
||||||
import { IDestroyable } from "../../utils/IDestroyable";
|
import { IDestroyable } from "../../utils/IDestroyable";
|
||||||
import SettingsStore from "../../settings/SettingsStore";
|
import SettingsStore from "../../settings/SettingsStore";
|
||||||
|
|
||||||
export interface INotificationStateSnapshotParams {
|
export interface INotificationStateSnapshotParams {
|
||||||
symbol: string | null;
|
symbol: string | null;
|
||||||
count: number;
|
count: number;
|
||||||
color: NotificationColor;
|
level: NotificationLevel;
|
||||||
muted: boolean;
|
muted: boolean;
|
||||||
knocked: boolean;
|
knocked: boolean;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ export abstract class NotificationState
|
||||||
//
|
//
|
||||||
protected _symbol: string | null = null;
|
protected _symbol: string | null = null;
|
||||||
protected _count = 0;
|
protected _count = 0;
|
||||||
protected _color: NotificationColor = NotificationColor.None;
|
protected _level: NotificationLevel = NotificationLevel.None;
|
||||||
protected _muted = false;
|
protected _muted = false;
|
||||||
protected _knocked = false;
|
protected _knocked = false;
|
||||||
|
|
||||||
|
@ -66,8 +66,8 @@ export abstract class NotificationState
|
||||||
return this._count;
|
return this._count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get color(): NotificationColor {
|
public get level(): NotificationLevel {
|
||||||
return this._color;
|
return this._level;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get muted(): boolean {
|
public get muted(): boolean {
|
||||||
|
@ -79,24 +79,24 @@ export abstract class NotificationState
|
||||||
}
|
}
|
||||||
|
|
||||||
public get isIdle(): boolean {
|
public get isIdle(): boolean {
|
||||||
return this.color <= NotificationColor.None;
|
return this.level <= NotificationLevel.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get isUnread(): boolean {
|
public get isUnread(): boolean {
|
||||||
if (this.color > NotificationColor.Bold) {
|
if (this.level > NotificationLevel.Activity) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
const hideBold = SettingsStore.getValue("feature_hidebold");
|
const hideBold = SettingsStore.getValue("feature_hidebold");
|
||||||
return this.color === NotificationColor.Bold && !hideBold;
|
return this.level === NotificationLevel.Activity && !hideBold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public get hasUnreadCount(): boolean {
|
public get hasUnreadCount(): boolean {
|
||||||
return this.color >= NotificationColor.Grey && (!!this.count || !!this.symbol);
|
return this.level >= NotificationLevel.Notification && (!!this.count || !!this.symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get hasMentions(): boolean {
|
public get hasMentions(): boolean {
|
||||||
return this.color >= NotificationColor.Red;
|
return this.level >= NotificationLevel.Highlight;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected emitIfUpdated(snapshot: NotificationStateSnapshot): void {
|
protected emitIfUpdated(snapshot: NotificationStateSnapshot): void {
|
||||||
|
@ -121,14 +121,14 @@ export abstract class NotificationState
|
||||||
export class NotificationStateSnapshot {
|
export class NotificationStateSnapshot {
|
||||||
private readonly symbol: string | null;
|
private readonly symbol: string | null;
|
||||||
private readonly count: number;
|
private readonly count: number;
|
||||||
private readonly color: NotificationColor;
|
private readonly level: NotificationLevel;
|
||||||
private readonly muted: boolean;
|
private readonly muted: boolean;
|
||||||
private readonly knocked: boolean;
|
private readonly knocked: boolean;
|
||||||
|
|
||||||
public constructor(state: INotificationStateSnapshotParams) {
|
public constructor(state: INotificationStateSnapshotParams) {
|
||||||
this.symbol = state.symbol;
|
this.symbol = state.symbol;
|
||||||
this.count = state.count;
|
this.count = state.count;
|
||||||
this.color = state.color;
|
this.level = state.level;
|
||||||
this.muted = state.muted;
|
this.muted = state.muted;
|
||||||
this.knocked = state.knocked;
|
this.knocked = state.knocked;
|
||||||
}
|
}
|
||||||
|
@ -137,14 +137,14 @@ export class NotificationStateSnapshot {
|
||||||
const before = {
|
const before = {
|
||||||
count: this.count,
|
count: this.count,
|
||||||
symbol: this.symbol,
|
symbol: this.symbol,
|
||||||
color: this.color,
|
level: this.level,
|
||||||
muted: this.muted,
|
muted: this.muted,
|
||||||
knocked: this.knocked,
|
knocked: this.knocked,
|
||||||
};
|
};
|
||||||
const after = {
|
const after = {
|
||||||
count: other.count,
|
count: other.count,
|
||||||
symbol: other.symbol,
|
symbol: other.symbol,
|
||||||
color: other.color,
|
level: other.level,
|
||||||
muted: other.muted,
|
muted: other.muted,
|
||||||
knocked: other.knocked,
|
knocked: other.knocked,
|
||||||
};
|
};
|
||||||
|
|
|
@ -90,11 +90,11 @@ export class RoomNotificationState extends NotificationState implements IDestroy
|
||||||
private updateNotificationState(): void {
|
private updateNotificationState(): void {
|
||||||
const snapshot = this.snapshot();
|
const snapshot = this.snapshot();
|
||||||
|
|
||||||
const { color, symbol, count } = RoomNotifs.determineUnreadState(this.room);
|
const { level, symbol, count } = RoomNotifs.determineUnreadState(this.room);
|
||||||
const muted =
|
const muted =
|
||||||
RoomNotifs.getRoomNotifsState(this.room.client, this.room.roomId) === RoomNotifs.RoomNotifState.Mute;
|
RoomNotifs.getRoomNotifsState(this.room.client, this.room.roomId) === RoomNotifs.RoomNotifState.Mute;
|
||||||
const knocked = SettingsStore.getValue("feature_ask_to_join") && this.room.getMyMembership() === "knock";
|
const knocked = SettingsStore.getValue("feature_ask_to_join") && this.room.getMyMembership() === "knock";
|
||||||
this._color = color;
|
this._level = level;
|
||||||
this._symbol = symbol;
|
this._symbol = symbol;
|
||||||
this._count = count;
|
this._count = count;
|
||||||
this._muted = muted;
|
this._muted = muted;
|
||||||
|
|
|
@ -138,7 +138,7 @@ export class RoomNotificationStateStore extends AsyncStoreWithClient<IState> {
|
||||||
if (
|
if (
|
||||||
this.globalState.symbol !== globalState.symbol ||
|
this.globalState.symbol !== globalState.symbol ||
|
||||||
this.globalState.count !== globalState.count ||
|
this.globalState.count !== globalState.count ||
|
||||||
this.globalState.color !== globalState.color ||
|
this.globalState.level !== globalState.level ||
|
||||||
this.globalState.numUnreadStates !== globalState.numUnreadStates ||
|
this.globalState.numUnreadStates !== globalState.numUnreadStates ||
|
||||||
forceEmit
|
forceEmit
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
import { Room } from "matrix-js-sdk/src/matrix";
|
import { Room } from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
import { NotificationColor } from "./NotificationColor";
|
import { NotificationLevel } from "./NotificationLevel";
|
||||||
import { arrayDiff } from "../../utils/arrays";
|
import { arrayDiff } from "../../utils/arrays";
|
||||||
import { RoomNotificationState } from "./RoomNotificationState";
|
import { RoomNotificationState } from "./RoomNotificationState";
|
||||||
import { NotificationState, NotificationStateEvents } from "./NotificationState";
|
import { NotificationState, NotificationStateEvents } from "./NotificationState";
|
||||||
|
@ -33,7 +33,7 @@ export class SpaceNotificationState extends NotificationState {
|
||||||
}
|
}
|
||||||
|
|
||||||
public get symbol(): string | null {
|
public get symbol(): string | null {
|
||||||
return this._color === NotificationColor.Unsent ? "!" : null;
|
return this._level === NotificationLevel.Unsent ? "!" : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setRooms(rooms: Room[]): void {
|
public setRooms(rooms: Room[]): void {
|
||||||
|
@ -56,7 +56,7 @@ export class SpaceNotificationState extends NotificationState {
|
||||||
}
|
}
|
||||||
|
|
||||||
public getFirstRoomWithNotifications(): string | undefined {
|
public getFirstRoomWithNotifications(): string | undefined {
|
||||||
return Object.values(this.states).find((state) => state.color >= this.color)?.room.roomId;
|
return Object.values(this.states).find((state) => state.level >= this.level)?.room.roomId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public destroy(): void {
|
public destroy(): void {
|
||||||
|
@ -75,16 +75,16 @@ export class SpaceNotificationState extends NotificationState {
|
||||||
const snapshot = this.snapshot();
|
const snapshot = this.snapshot();
|
||||||
|
|
||||||
this._count = 0;
|
this._count = 0;
|
||||||
this._color = NotificationColor.None;
|
this._level = NotificationLevel.None;
|
||||||
for (const [roomId, state] of Object.entries(this.states)) {
|
for (const [roomId, state] of Object.entries(this.states)) {
|
||||||
const room = this.rooms.find((r) => r.roomId === roomId);
|
const room = this.rooms.find((r) => r.roomId === roomId);
|
||||||
const roomTags = room ? RoomListStore.instance.getTagsForRoom(room) : [];
|
const roomTags = room ? RoomListStore.instance.getTagsForRoom(room) : [];
|
||||||
|
|
||||||
// We ignore unreads in LowPriority rooms, see https://github.com/vector-im/element-web/issues/16836
|
// We ignore unreads in LowPriority rooms, see https://github.com/vector-im/element-web/issues/16836
|
||||||
if (roomTags.includes(DefaultTagID.LowPriority) && state.color === NotificationColor.Bold) continue;
|
if (roomTags.includes(DefaultTagID.LowPriority) && state.level === NotificationLevel.Activity) continue;
|
||||||
|
|
||||||
this._count += state.count;
|
this._count += state.count;
|
||||||
this._color = Math.max(this.color, state.color);
|
this._level = Math.max(this.level, state.level);
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally, publish an update if needed
|
// finally, publish an update if needed
|
||||||
|
|
|
@ -14,24 +14,24 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { NotificationColor } from "./NotificationColor";
|
import { NotificationLevel } from "./NotificationLevel";
|
||||||
import { NotificationState } from "./NotificationState";
|
import { NotificationState } from "./NotificationState";
|
||||||
|
|
||||||
export class StaticNotificationState extends NotificationState {
|
export class StaticNotificationState extends NotificationState {
|
||||||
public static readonly RED_EXCLAMATION = StaticNotificationState.forSymbol("!", NotificationColor.Red);
|
public static readonly RED_EXCLAMATION = StaticNotificationState.forSymbol("!", NotificationLevel.Highlight);
|
||||||
|
|
||||||
public constructor(symbol: string | null, count: number, color: NotificationColor) {
|
public constructor(symbol: string | null, count: number, level: NotificationLevel) {
|
||||||
super();
|
super();
|
||||||
this._symbol = symbol;
|
this._symbol = symbol;
|
||||||
this._count = count;
|
this._count = count;
|
||||||
this._color = color;
|
this._level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static forCount(count: number, color: NotificationColor): StaticNotificationState {
|
public static forCount(count: number, level: NotificationLevel): StaticNotificationState {
|
||||||
return new StaticNotificationState(null, count, color);
|
return new StaticNotificationState(null, count, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static forSymbol(symbol: string, color: NotificationColor): StaticNotificationState {
|
public static forSymbol(symbol: string, level: NotificationLevel): StaticNotificationState {
|
||||||
return new StaticNotificationState(symbol, 0, color);
|
return new StaticNotificationState(symbol, 0, level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { NotificationColor } from "./NotificationColor";
|
import { NotificationLevel } from "./NotificationLevel";
|
||||||
import { NotificationState } from "./NotificationState";
|
import { NotificationState } from "./NotificationState";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,7 +30,7 @@ export class SummarizedNotificationState extends NotificationState {
|
||||||
super();
|
super();
|
||||||
this._symbol = null;
|
this._symbol = null;
|
||||||
this._count = 0;
|
this._count = 0;
|
||||||
this._color = NotificationColor.None;
|
this._level = NotificationLevel.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get numUnreadStates(): number {
|
public get numUnreadStates(): number {
|
||||||
|
@ -52,8 +52,8 @@ export class SummarizedNotificationState extends NotificationState {
|
||||||
if (other.count) {
|
if (other.count) {
|
||||||
this._count += other.count;
|
this._count += other.count;
|
||||||
}
|
}
|
||||||
if (other.color > this.color) {
|
if (other.level > this.level) {
|
||||||
this._color = other.color;
|
this._level = other.level;
|
||||||
}
|
}
|
||||||
if (other.hasUnreadCount) {
|
if (other.hasUnreadCount) {
|
||||||
this.totalStatesWithUnread++;
|
this.totalStatesWithUnread++;
|
||||||
|
|
|
@ -22,27 +22,27 @@ import { RoomUpdateCause, TagID } from "../../models";
|
||||||
import { SortAlgorithm } from "../models";
|
import { SortAlgorithm } from "../models";
|
||||||
import { sortRoomsWithAlgorithm } from "../tag-sorting";
|
import { sortRoomsWithAlgorithm } from "../tag-sorting";
|
||||||
import { OrderingAlgorithm } from "./OrderingAlgorithm";
|
import { OrderingAlgorithm } from "./OrderingAlgorithm";
|
||||||
import { NotificationColor } from "../../../notifications/NotificationColor";
|
import { NotificationLevel } from "../../../notifications/NotificationLevel";
|
||||||
import { RoomNotificationStateStore } from "../../../notifications/RoomNotificationStateStore";
|
import { RoomNotificationStateStore } from "../../../notifications/RoomNotificationStateStore";
|
||||||
|
|
||||||
type CategorizedRoomMap = {
|
type CategorizedRoomMap = {
|
||||||
[category in NotificationColor]: Room[];
|
[category in NotificationLevel]: Room[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type CategoryIndex = Partial<{
|
type CategoryIndex = Partial<{
|
||||||
[category in NotificationColor]: number; // integer
|
[category in NotificationLevel]: number; // integer
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
// Caution: changing this means you'll need to update a bunch of assumptions and
|
// Caution: changing this means you'll need to update a bunch of assumptions and
|
||||||
// comments! Check the usage of Category carefully to figure out what needs changing
|
// comments! Check the usage of Category carefully to figure out what needs changing
|
||||||
// if you're going to change this array's order.
|
// if you're going to change this array's order.
|
||||||
const CATEGORY_ORDER = [
|
const CATEGORY_ORDER = [
|
||||||
NotificationColor.Unsent,
|
NotificationLevel.Unsent,
|
||||||
NotificationColor.Red,
|
NotificationLevel.Highlight,
|
||||||
NotificationColor.Grey,
|
NotificationLevel.Notification,
|
||||||
NotificationColor.Bold,
|
NotificationLevel.Activity,
|
||||||
NotificationColor.None, // idle
|
NotificationLevel.None, // idle
|
||||||
NotificationColor.Muted,
|
NotificationLevel.Muted,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,12 +77,12 @@ export class ImportanceAlgorithm extends OrderingAlgorithm {
|
||||||
// noinspection JSMethodCanBeStatic
|
// noinspection JSMethodCanBeStatic
|
||||||
private categorizeRooms(rooms: Room[]): CategorizedRoomMap {
|
private categorizeRooms(rooms: Room[]): CategorizedRoomMap {
|
||||||
const map: CategorizedRoomMap = {
|
const map: CategorizedRoomMap = {
|
||||||
[NotificationColor.Unsent]: [],
|
[NotificationLevel.Unsent]: [],
|
||||||
[NotificationColor.Red]: [],
|
[NotificationLevel.Highlight]: [],
|
||||||
[NotificationColor.Grey]: [],
|
[NotificationLevel.Notification]: [],
|
||||||
[NotificationColor.Bold]: [],
|
[NotificationLevel.Activity]: [],
|
||||||
[NotificationColor.None]: [],
|
[NotificationLevel.None]: [],
|
||||||
[NotificationColor.Muted]: [],
|
[NotificationLevel.Muted]: [],
|
||||||
};
|
};
|
||||||
for (const room of rooms) {
|
for (const room of rooms) {
|
||||||
const category = this.getRoomCategory(room);
|
const category = this.getRoomCategory(room);
|
||||||
|
@ -92,11 +92,11 @@ export class ImportanceAlgorithm extends OrderingAlgorithm {
|
||||||
}
|
}
|
||||||
|
|
||||||
// noinspection JSMethodCanBeStatic
|
// noinspection JSMethodCanBeStatic
|
||||||
private getRoomCategory(room: Room): NotificationColor {
|
private getRoomCategory(room: Room): NotificationLevel {
|
||||||
// It's fine for us to call this a lot because it's cached, and we shouldn't be
|
// It's fine for us to call this a lot because it's cached, and we shouldn't be
|
||||||
// wasting anything by doing so as the store holds single references
|
// wasting anything by doing so as the store holds single references
|
||||||
const state = RoomNotificationStateStore.instance.getRoomState(room);
|
const state = RoomNotificationStateStore.instance.getRoomState(room);
|
||||||
return this.isMutedToBottom && state.muted ? NotificationColor.Muted : state.color;
|
return this.isMutedToBottom && state.muted ? NotificationLevel.Muted : state.level;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setRooms(rooms: Room[]): void {
|
public setRooms(rooms: Room[]): void {
|
||||||
|
@ -106,7 +106,7 @@ export class ImportanceAlgorithm extends OrderingAlgorithm {
|
||||||
// Every other sorting type affects the categories, not the whole tag.
|
// Every other sorting type affects the categories, not the whole tag.
|
||||||
const categorized = this.categorizeRooms(rooms);
|
const categorized = this.categorizeRooms(rooms);
|
||||||
for (const category of Object.keys(categorized)) {
|
for (const category of Object.keys(categorized)) {
|
||||||
const notificationColor = category as unknown as NotificationColor;
|
const notificationColor = category as unknown as NotificationLevel;
|
||||||
const roomsToOrder = categorized[notificationColor];
|
const roomsToOrder = categorized[notificationColor];
|
||||||
categorized[notificationColor] = sortRoomsWithAlgorithm(
|
categorized[notificationColor] = sortRoomsWithAlgorithm(
|
||||||
roomsToOrder,
|
roomsToOrder,
|
||||||
|
@ -128,7 +128,7 @@ export class ImportanceAlgorithm extends OrderingAlgorithm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getCategoryIndex(category: NotificationColor): number {
|
private getCategoryIndex(category: NotificationLevel): number {
|
||||||
const categoryIndex = this.indices[category];
|
const categoryIndex = this.indices[category];
|
||||||
|
|
||||||
if (categoryIndex === undefined) {
|
if (categoryIndex === undefined) {
|
||||||
|
@ -213,7 +213,7 @@ export class ImportanceAlgorithm extends OrderingAlgorithm {
|
||||||
return true; // change made
|
return true; // change made
|
||||||
}
|
}
|
||||||
|
|
||||||
private sortCategory(category: NotificationColor): void {
|
private sortCategory(category: NotificationLevel): void {
|
||||||
// This should be relatively quick because the room is usually inserted at the top of the
|
// This should be relatively quick because the room is usually inserted at the top of the
|
||||||
// category, and most popular sorting algorithms will deal with trying to keep the active
|
// category, and most popular sorting algorithms will deal with trying to keep the active
|
||||||
// room at the top/start of the category. For the few algorithms that will have to move the
|
// room at the top/start of the category. For the few algorithms that will have to move the
|
||||||
|
@ -231,7 +231,7 @@ export class ImportanceAlgorithm extends OrderingAlgorithm {
|
||||||
}
|
}
|
||||||
|
|
||||||
// noinspection JSMethodCanBeStatic
|
// noinspection JSMethodCanBeStatic
|
||||||
private getCategoryFromIndices(index: number, indices: CategoryIndex): NotificationColor {
|
private getCategoryFromIndices(index: number, indices: CategoryIndex): NotificationLevel {
|
||||||
for (let i = 0; i < CATEGORY_ORDER.length; i++) {
|
for (let i = 0; i < CATEGORY_ORDER.length; i++) {
|
||||||
const category = CATEGORY_ORDER[i];
|
const category = CATEGORY_ORDER[i];
|
||||||
const isLast = i === CATEGORY_ORDER.length - 1;
|
const isLast = i === CATEGORY_ORDER.length - 1;
|
||||||
|
@ -252,8 +252,8 @@ export class ImportanceAlgorithm extends OrderingAlgorithm {
|
||||||
// noinspection JSMethodCanBeStatic
|
// noinspection JSMethodCanBeStatic
|
||||||
private moveRoomIndexes(
|
private moveRoomIndexes(
|
||||||
nRooms: number,
|
nRooms: number,
|
||||||
fromCategory: NotificationColor,
|
fromCategory: NotificationLevel,
|
||||||
toCategory: NotificationColor,
|
toCategory: NotificationLevel,
|
||||||
indices: CategoryIndex,
|
indices: CategoryIndex,
|
||||||
): void {
|
): void {
|
||||||
// We have to update the index of the category *after* the from/toCategory variables
|
// We have to update the index of the category *after* the from/toCategory variables
|
||||||
|
@ -266,7 +266,7 @@ export class ImportanceAlgorithm extends OrderingAlgorithm {
|
||||||
this.alterCategoryPositionBy(toCategory, +nRooms, indices);
|
this.alterCategoryPositionBy(toCategory, +nRooms, indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
private alterCategoryPositionBy(category: NotificationColor, n: number, indices: CategoryIndex): void {
|
private alterCategoryPositionBy(category: NotificationLevel, n: number, indices: CategoryIndex): void {
|
||||||
// Note: when we alter a category's index, we actually have to modify the ones following
|
// Note: when we alter a category's index, we actually have to modify the ones following
|
||||||
// the target and not the target itself.
|
// the target and not the target itself.
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ import {
|
||||||
getUnreadNotificationCount,
|
getUnreadNotificationCount,
|
||||||
determineUnreadState,
|
determineUnreadState,
|
||||||
} from "../src/RoomNotifs";
|
} from "../src/RoomNotifs";
|
||||||
import { NotificationColor } from "../src/stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../src/stores/notifications/NotificationLevel";
|
||||||
import SettingsStore from "../src/settings/SettingsStore";
|
import SettingsStore from "../src/settings/SettingsStore";
|
||||||
import { MatrixClientPeg } from "../src/MatrixClientPeg";
|
import { MatrixClientPeg } from "../src/MatrixClientPeg";
|
||||||
|
|
||||||
|
@ -252,10 +252,10 @@ describe("RoomNotifs test", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("shows nothing by default", async () => {
|
it("shows nothing by default", async () => {
|
||||||
const { color, symbol, count } = determineUnreadState(room);
|
const { level, symbol, count } = determineUnreadState(room);
|
||||||
|
|
||||||
expect(symbol).toBe(null);
|
expect(symbol).toBe(null);
|
||||||
expect(color).toBe(NotificationColor.None);
|
expect(level).toBe(NotificationLevel.None);
|
||||||
expect(count).toBe(0);
|
expect(count).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -269,20 +269,20 @@ describe("RoomNotifs test", () => {
|
||||||
event.status = EventStatus.NOT_SENT;
|
event.status = EventStatus.NOT_SENT;
|
||||||
room.addPendingEvent(event, "txn");
|
room.addPendingEvent(event, "txn");
|
||||||
|
|
||||||
const { color, symbol, count } = determineUnreadState(room);
|
const { level, symbol, count } = determineUnreadState(room);
|
||||||
|
|
||||||
expect(symbol).toBe("!");
|
expect(symbol).toBe("!");
|
||||||
expect(color).toBe(NotificationColor.Unsent);
|
expect(level).toBe(NotificationLevel.Unsent);
|
||||||
expect(count).toBeGreaterThan(0);
|
expect(count).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("indicates the user has been invited to a channel", async () => {
|
it("indicates the user has been invited to a channel", async () => {
|
||||||
room.updateMyMembership("invite");
|
room.updateMyMembership("invite");
|
||||||
|
|
||||||
const { color, symbol, count } = determineUnreadState(room);
|
const { level, symbol, count } = determineUnreadState(room);
|
||||||
|
|
||||||
expect(symbol).toBe("!");
|
expect(symbol).toBe("!");
|
||||||
expect(color).toBe(NotificationColor.Red);
|
expect(level).toBe(NotificationLevel.Highlight);
|
||||||
expect(count).toBeGreaterThan(0);
|
expect(count).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -294,10 +294,10 @@ describe("RoomNotifs test", () => {
|
||||||
membership: "knock",
|
membership: "knock",
|
||||||
});
|
});
|
||||||
jest.spyOn(room, "getMember").mockReturnValue(roomMember);
|
jest.spyOn(room, "getMember").mockReturnValue(roomMember);
|
||||||
const { color, symbol, count } = determineUnreadState(room);
|
const { level, symbol, count } = determineUnreadState(room);
|
||||||
|
|
||||||
expect(symbol).toBe("!");
|
expect(symbol).toBe("!");
|
||||||
expect(color).toBe(NotificationColor.Red);
|
expect(level).toBe(NotificationLevel.Highlight);
|
||||||
expect(count).toBeGreaterThan(0);
|
expect(count).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -306,27 +306,27 @@ describe("RoomNotifs test", () => {
|
||||||
room.setUnreadNotificationCount(NotificationCountType.Total, 99);
|
room.setUnreadNotificationCount(NotificationCountType.Total, 99);
|
||||||
muteRoom(room);
|
muteRoom(room);
|
||||||
|
|
||||||
const { color, count } = determineUnreadState(room);
|
const { level, count } = determineUnreadState(room);
|
||||||
|
|
||||||
expect(color).toBe(NotificationColor.None);
|
expect(level).toBe(NotificationLevel.None);
|
||||||
expect(count).toBe(0);
|
expect(count).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("uses the correct number of unreads", async () => {
|
it("uses the correct number of unreads", async () => {
|
||||||
room.setUnreadNotificationCount(NotificationCountType.Total, 999);
|
room.setUnreadNotificationCount(NotificationCountType.Total, 999);
|
||||||
|
|
||||||
const { color, count } = determineUnreadState(room);
|
const { level, count } = determineUnreadState(room);
|
||||||
|
|
||||||
expect(color).toBe(NotificationColor.Grey);
|
expect(level).toBe(NotificationLevel.Notification);
|
||||||
expect(count).toBe(999);
|
expect(count).toBe(999);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("uses the correct number of highlights", async () => {
|
it("uses the correct number of highlights", async () => {
|
||||||
room.setUnreadNotificationCount(NotificationCountType.Highlight, 888);
|
room.setUnreadNotificationCount(NotificationCountType.Highlight, 888);
|
||||||
|
|
||||||
const { color, count } = determineUnreadState(room);
|
const { level, count } = determineUnreadState(room);
|
||||||
|
|
||||||
expect(color).toBe(NotificationColor.Red);
|
expect(level).toBe(NotificationLevel.Highlight);
|
||||||
expect(count).toBe(888);
|
expect(count).toBe(888);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -56,7 +56,7 @@ describe("LegacyRoomHeaderButtons-test.tsx", function () {
|
||||||
return container.querySelector(".mx_RightPanel_threadsButton");
|
return container.querySelector(".mx_RightPanel_threadsButton");
|
||||||
}
|
}
|
||||||
|
|
||||||
function isIndicatorOfType(container: HTMLElement, type: "red" | "gray" | "bold") {
|
function isIndicatorOfType(container: HTMLElement, type: "highlight" | "notification" | "activity") {
|
||||||
return container.querySelector(".mx_RightPanel_threadsButton .mx_Indicator")!.className.includes(type);
|
return container.querySelector(".mx_RightPanel_threadsButton .mx_Indicator")!.className.includes(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,10 +85,10 @@ describe("LegacyRoomHeaderButtons-test.tsx", function () {
|
||||||
|
|
||||||
room.setThreadUnreadNotificationCount("$123", NotificationCountType.Total, 1);
|
room.setThreadUnreadNotificationCount("$123", NotificationCountType.Total, 1);
|
||||||
expect(getThreadButton(container)!.className.includes("mx_LegacyRoomHeader_button--unread")).toBeTruthy();
|
expect(getThreadButton(container)!.className.includes("mx_LegacyRoomHeader_button--unread")).toBeTruthy();
|
||||||
expect(isIndicatorOfType(container, "gray")).toBe(true);
|
expect(isIndicatorOfType(container, "notification")).toBe(true);
|
||||||
|
|
||||||
room.setThreadUnreadNotificationCount("$123", NotificationCountType.Highlight, 1);
|
room.setThreadUnreadNotificationCount("$123", NotificationCountType.Highlight, 1);
|
||||||
expect(isIndicatorOfType(container, "red")).toBe(true);
|
expect(isIndicatorOfType(container, "highlight")).toBe(true);
|
||||||
|
|
||||||
room.setThreadUnreadNotificationCount("$123", NotificationCountType.Total, 0);
|
room.setThreadUnreadNotificationCount("$123", NotificationCountType.Total, 0);
|
||||||
room.setThreadUnreadNotificationCount("$123", NotificationCountType.Highlight, 0);
|
room.setThreadUnreadNotificationCount("$123", NotificationCountType.Highlight, 0);
|
||||||
|
@ -122,7 +122,7 @@ describe("LegacyRoomHeaderButtons-test.tsx", function () {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
room.addReceipt(receipt);
|
room.addReceipt(receipt);
|
||||||
expect(isIndicatorOfType(container, "bold")).toBe(true);
|
expect(isIndicatorOfType(container, "activity")).toBe(true);
|
||||||
|
|
||||||
// Sending the last event should clear the notification.
|
// Sending the last event should clear the notification.
|
||||||
let event = mkEvent({
|
let event = mkEvent({
|
||||||
|
@ -158,7 +158,7 @@ describe("LegacyRoomHeaderButtons-test.tsx", function () {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
room.addLiveEvents([event]);
|
room.addLiveEvents([event]);
|
||||||
expect(isIndicatorOfType(container, "bold")).toBe(true);
|
expect(isIndicatorOfType(container, "activity")).toBe(true);
|
||||||
|
|
||||||
// Sending a read receipt on an earlier event shouldn't do anything.
|
// Sending a read receipt on an earlier event shouldn't do anything.
|
||||||
receipt = new MatrixEvent({
|
receipt = new MatrixEvent({
|
||||||
|
@ -173,7 +173,7 @@ describe("LegacyRoomHeaderButtons-test.tsx", function () {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
room.addReceipt(receipt);
|
room.addReceipt(receipt);
|
||||||
expect(isIndicatorOfType(container, "bold")).toBe(true);
|
expect(isIndicatorOfType(container, "activity")).toBe(true);
|
||||||
|
|
||||||
// Sending a receipt on the latest event should clear the notification.
|
// Sending a receipt on the latest event should clear the notification.
|
||||||
receipt = new MatrixEvent({
|
receipt = new MatrixEvent({
|
||||||
|
|
|
@ -19,7 +19,7 @@ import React from "react";
|
||||||
|
|
||||||
import { StatelessNotificationBadge } from "../../../../../src/components/views/rooms/NotificationBadge/StatelessNotificationBadge";
|
import { StatelessNotificationBadge } from "../../../../../src/components/views/rooms/NotificationBadge/StatelessNotificationBadge";
|
||||||
import SettingsStore from "../../../../../src/settings/SettingsStore";
|
import SettingsStore from "../../../../../src/settings/SettingsStore";
|
||||||
import { NotificationColor } from "../../../../../src/stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../../../src/stores/notifications/NotificationLevel";
|
||||||
|
|
||||||
describe("NotificationBadge", () => {
|
describe("NotificationBadge", () => {
|
||||||
describe("StatelessNotificationBadge", () => {
|
describe("StatelessNotificationBadge", () => {
|
||||||
|
@ -27,7 +27,7 @@ describe("NotificationBadge", () => {
|
||||||
const cb = jest.fn();
|
const cb = jest.fn();
|
||||||
|
|
||||||
const { getByRole } = render(
|
const { getByRole } = render(
|
||||||
<StatelessNotificationBadge symbol="" color={NotificationColor.Red} count={5} onClick={cb} />,
|
<StatelessNotificationBadge symbol="" level={NotificationLevel.Highlight} count={5} onClick={cb} />,
|
||||||
);
|
);
|
||||||
|
|
||||||
fireEvent.click(getByRole("button")!);
|
fireEvent.click(getByRole("button")!);
|
||||||
|
@ -40,7 +40,7 @@ describe("NotificationBadge", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<StatelessNotificationBadge symbol="" color={NotificationColor.Bold} count={1} />,
|
<StatelessNotificationBadge symbol="" level={NotificationLevel.Activity} count={1} />,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(container.firstChild).toBeNull();
|
expect(container.firstChild).toBeNull();
|
||||||
|
|
|
@ -18,19 +18,19 @@ import React from "react";
|
||||||
import { render } from "@testing-library/react";
|
import { render } from "@testing-library/react";
|
||||||
|
|
||||||
import { StatelessNotificationBadge } from "../../../../../src/components/views/rooms/NotificationBadge/StatelessNotificationBadge";
|
import { StatelessNotificationBadge } from "../../../../../src/components/views/rooms/NotificationBadge/StatelessNotificationBadge";
|
||||||
import { NotificationColor } from "../../../../../src/stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../../../src/stores/notifications/NotificationLevel";
|
||||||
|
|
||||||
describe("StatelessNotificationBadge", () => {
|
describe("StatelessNotificationBadge", () => {
|
||||||
it("is highlighted when unsent", () => {
|
it("is highlighted when unsent", () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<StatelessNotificationBadge symbol="!" count={0} color={NotificationColor.Unsent} />,
|
<StatelessNotificationBadge symbol="!" count={0} level={NotificationLevel.Unsent} />,
|
||||||
);
|
);
|
||||||
expect(container.querySelector(".mx_NotificationBadge_highlighted")).not.toBe(null);
|
expect(container.querySelector(".mx_NotificationBadge_highlighted")).not.toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("has knock style", () => {
|
it("has knock style", () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<StatelessNotificationBadge symbol="!" count={0} color={NotificationColor.Red} knocked={true} />,
|
<StatelessNotificationBadge symbol="!" count={0} level={NotificationLevel.Highlight} knocked={true} />,
|
||||||
);
|
);
|
||||||
expect(container.querySelector(".mx_NotificationBadge_dot")).not.toBeInTheDocument();
|
expect(container.querySelector(".mx_NotificationBadge_dot")).not.toBeInTheDocument();
|
||||||
expect(container.querySelector(".mx_NotificationBadge_knocked")).toBeInTheDocument();
|
expect(container.querySelector(".mx_NotificationBadge_knocked")).toBeInTheDocument();
|
||||||
|
|
|
@ -25,7 +25,7 @@ import { SDKContext, SdkContextClass } from "../../../../../src/contexts/SDKCont
|
||||||
import RightPanelStore from "../../../../../src/stores/right-panel/RightPanelStore";
|
import RightPanelStore from "../../../../../src/stores/right-panel/RightPanelStore";
|
||||||
import { getMockClientWithEventEmitter, mockClientMethodsUser } from "../../../../test-utils";
|
import { getMockClientWithEventEmitter, mockClientMethodsUser } from "../../../../test-utils";
|
||||||
import { RoomNotificationState } from "../../../../../src/stores/notifications/RoomNotificationState";
|
import { RoomNotificationState } from "../../../../../src/stores/notifications/RoomNotificationState";
|
||||||
import { NotificationColor } from "../../../../../src/stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../../../src/stores/notifications/NotificationLevel";
|
||||||
import { NotificationStateEvents } from "../../../../../src/stores/notifications/NotificationState";
|
import { NotificationStateEvents } from "../../../../../src/stores/notifications/NotificationState";
|
||||||
import { RightPanelPhases } from "../../../../../src/stores/right-panel/RightPanelStorePhases";
|
import { RightPanelPhases } from "../../../../../src/stores/right-panel/RightPanelStorePhases";
|
||||||
|
|
||||||
|
@ -46,11 +46,11 @@ describe("<VideoRoomChatButton />", () => {
|
||||||
return room;
|
return room;
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockRoomNotificationState = (room: Room, color: NotificationColor): RoomNotificationState => {
|
const mockRoomNotificationState = (room: Room, level: NotificationLevel): RoomNotificationState => {
|
||||||
const roomNotificationState = new RoomNotificationState(room);
|
const roomNotificationState = new RoomNotificationState(room);
|
||||||
|
|
||||||
// @ts-ignore ugly mocking
|
// @ts-ignore ugly mocking
|
||||||
roomNotificationState._color = color;
|
roomNotificationState._level = level;
|
||||||
jest.spyOn(sdkContext.roomNotificationStateStore, "getRoomState").mockReturnValue(roomNotificationState);
|
jest.spyOn(sdkContext.roomNotificationStateStore, "getRoomState").mockReturnValue(roomNotificationState);
|
||||||
return roomNotificationState;
|
return roomNotificationState;
|
||||||
};
|
};
|
||||||
|
@ -105,7 +105,7 @@ describe("<VideoRoomChatButton />", () => {
|
||||||
|
|
||||||
it("renders button with an unread marker when room is unread", () => {
|
it("renders button with an unread marker when room is unread", () => {
|
||||||
const room = makeRoom();
|
const room = makeRoom();
|
||||||
mockRoomNotificationState(room, NotificationColor.Bold);
|
mockRoomNotificationState(room, NotificationLevel.Activity);
|
||||||
getComponent(room);
|
getComponent(room);
|
||||||
|
|
||||||
// snapshot includes `data-indicator` attribute
|
// snapshot includes `data-indicator` attribute
|
||||||
|
@ -116,14 +116,14 @@ describe("<VideoRoomChatButton />", () => {
|
||||||
it("adds unread marker when room notification state changes to unread", () => {
|
it("adds unread marker when room notification state changes to unread", () => {
|
||||||
const room = makeRoom();
|
const room = makeRoom();
|
||||||
// start in read state
|
// start in read state
|
||||||
const notificationState = mockRoomNotificationState(room, NotificationColor.None);
|
const notificationState = mockRoomNotificationState(room, NotificationLevel.None);
|
||||||
getComponent(room);
|
getComponent(room);
|
||||||
|
|
||||||
// no unread marker
|
// no unread marker
|
||||||
expect(screen.getByLabelText("Chat").hasAttribute("data-indicator")).toBeFalsy();
|
expect(screen.getByLabelText("Chat").hasAttribute("data-indicator")).toBeFalsy();
|
||||||
|
|
||||||
// @ts-ignore ugly mocking
|
// @ts-ignore ugly mocking
|
||||||
notificationState._color = NotificationColor.Red;
|
notificationState._level = NotificationLevel.Highlight;
|
||||||
notificationState.emit(NotificationStateEvents.Update);
|
notificationState.emit(NotificationStateEvents.Update);
|
||||||
|
|
||||||
// unread marker
|
// unread marker
|
||||||
|
@ -133,14 +133,14 @@ describe("<VideoRoomChatButton />", () => {
|
||||||
it("clears unread marker when room notification state changes to read", () => {
|
it("clears unread marker when room notification state changes to read", () => {
|
||||||
const room = makeRoom();
|
const room = makeRoom();
|
||||||
// start in unread state
|
// start in unread state
|
||||||
const notificationState = mockRoomNotificationState(room, NotificationColor.Red);
|
const notificationState = mockRoomNotificationState(room, NotificationLevel.Highlight);
|
||||||
getComponent(room);
|
getComponent(room);
|
||||||
|
|
||||||
// unread marker
|
// unread marker
|
||||||
expect(screen.getByLabelText("Chat").hasAttribute("data-indicator")).toBeTruthy();
|
expect(screen.getByLabelText("Chat").hasAttribute("data-indicator")).toBeTruthy();
|
||||||
|
|
||||||
// @ts-ignore ugly mocking
|
// @ts-ignore ugly mocking
|
||||||
notificationState._color = NotificationColor.None;
|
notificationState._level = NotificationLevel.None;
|
||||||
notificationState.emit(NotificationStateEvents.Update);
|
notificationState.emit(NotificationStateEvents.Update);
|
||||||
|
|
||||||
// unread marker cleared
|
// unread marker cleared
|
||||||
|
|
|
@ -26,7 +26,7 @@ import { SpaceButton } from "../../../../src/components/views/spaces/SpaceTreeLe
|
||||||
import { MetaSpace, SpaceKey } from "../../../../src/stores/spaces";
|
import { MetaSpace, SpaceKey } from "../../../../src/stores/spaces";
|
||||||
import SpaceStore from "../../../../src/stores/spaces/SpaceStore";
|
import SpaceStore from "../../../../src/stores/spaces/SpaceStore";
|
||||||
import { StaticNotificationState } from "../../../../src/stores/notifications/StaticNotificationState";
|
import { StaticNotificationState } from "../../../../src/stores/notifications/StaticNotificationState";
|
||||||
import { NotificationColor } from "../../../../src/stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../../src/stores/notifications/NotificationLevel";
|
||||||
|
|
||||||
jest.mock("../../../../src/stores/spaces/SpaceStore", () => {
|
jest.mock("../../../../src/stores/spaces/SpaceStore", () => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
@ -117,7 +117,7 @@ describe("SpaceButton", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should render notificationState if one is provided", () => {
|
it("should render notificationState if one is provided", () => {
|
||||||
const notificationState = new StaticNotificationState(null, 8, NotificationColor.Grey);
|
const notificationState = new StaticNotificationState(null, 8, NotificationLevel.Notification);
|
||||||
|
|
||||||
const { container, asFragment } = render(
|
const { container, asFragment } = render(
|
||||||
<SpaceButton
|
<SpaceButton
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { MatrixClient, NotificationCountType, Room } from "matrix-js-sdk/src/mat
|
||||||
import { useRoomThreadNotifications } from "../../../src/hooks/room/useRoomThreadNotifications";
|
import { useRoomThreadNotifications } from "../../../src/hooks/room/useRoomThreadNotifications";
|
||||||
import { stubClient } from "../../test-utils";
|
import { stubClient } from "../../test-utils";
|
||||||
import { MatrixClientPeg } from "../../../src/MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../src/MatrixClientPeg";
|
||||||
import { NotificationColor } from "../../../src/stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../src/stores/notifications/NotificationLevel";
|
||||||
import { populateThread } from "../../test-utils/threads";
|
import { populateThread } from "../../test-utils/threads";
|
||||||
|
|
||||||
function render(room: Room) {
|
function render(room: Room) {
|
||||||
|
@ -41,21 +41,21 @@ describe("useRoomThreadNotifications", () => {
|
||||||
it("returns none if no thread in the room has notifications", async () => {
|
it("returns none if no thread in the room has notifications", async () => {
|
||||||
const { result } = render(room);
|
const { result } = render(room);
|
||||||
|
|
||||||
expect(result.current).toBe(NotificationColor.None);
|
expect(result.current).toBe(NotificationLevel.None);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns red if a thread in the room has a highlight notification", async () => {
|
it("returns red if a thread in the room has a highlight notification", async () => {
|
||||||
room.setThreadUnreadNotificationCount("flooble", NotificationCountType.Highlight, 1);
|
room.setThreadUnreadNotificationCount("flooble", NotificationCountType.Highlight, 1);
|
||||||
const { result } = render(room);
|
const { result } = render(room);
|
||||||
|
|
||||||
expect(result.current).toBe(NotificationColor.Red);
|
expect(result.current).toBe(NotificationLevel.Highlight);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns grey if a thread in the room has a normal notification", async () => {
|
it("returns grey if a thread in the room has a normal notification", async () => {
|
||||||
room.setThreadUnreadNotificationCount("flooble", NotificationCountType.Total, 1);
|
room.setThreadUnreadNotificationCount("flooble", NotificationCountType.Total, 1);
|
||||||
const { result } = render(room);
|
const { result } = render(room);
|
||||||
|
|
||||||
expect(result.current).toBe(NotificationColor.Grey);
|
expect(result.current).toBe(NotificationLevel.Notification);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns bold if a thread in the room unread messages", async () => {
|
it("returns bold if a thread in the room unread messages", async () => {
|
||||||
|
@ -68,6 +68,6 @@ describe("useRoomThreadNotifications", () => {
|
||||||
|
|
||||||
const { result } = render(room);
|
const { result } = render(room);
|
||||||
|
|
||||||
expect(result.current).toBe(NotificationColor.Bold);
|
expect(result.current).toBe(NotificationLevel.Activity);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,7 +19,7 @@ import { EventStatus, NotificationCountType, PendingEventOrdering, Room } from "
|
||||||
|
|
||||||
import type { MatrixClient } from "matrix-js-sdk/src/matrix";
|
import type { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||||
import { useUnreadNotifications } from "../../src/hooks/useUnreadNotifications";
|
import { useUnreadNotifications } from "../../src/hooks/useUnreadNotifications";
|
||||||
import { NotificationColor } from "../../src/stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../src/stores/notifications/NotificationLevel";
|
||||||
import { mkEvent, muteRoom, stubClient } from "../test-utils";
|
import { mkEvent, muteRoom, stubClient } from "../test-utils";
|
||||||
|
|
||||||
describe("useUnreadNotifications", () => {
|
describe("useUnreadNotifications", () => {
|
||||||
|
@ -40,10 +40,10 @@ describe("useUnreadNotifications", () => {
|
||||||
|
|
||||||
it("shows nothing by default", async () => {
|
it("shows nothing by default", async () => {
|
||||||
const { result } = renderHook(() => useUnreadNotifications(room));
|
const { result } = renderHook(() => useUnreadNotifications(room));
|
||||||
const { color, symbol, count } = result.current;
|
const { level, symbol, count } = result.current;
|
||||||
|
|
||||||
expect(symbol).toBe(null);
|
expect(symbol).toBe(null);
|
||||||
expect(color).toBe(NotificationColor.None);
|
expect(level).toBe(NotificationLevel.None);
|
||||||
expect(count).toBe(0);
|
expect(count).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -58,10 +58,10 @@ describe("useUnreadNotifications", () => {
|
||||||
room.addPendingEvent(event, "txn");
|
room.addPendingEvent(event, "txn");
|
||||||
|
|
||||||
const { result } = renderHook(() => useUnreadNotifications(room));
|
const { result } = renderHook(() => useUnreadNotifications(room));
|
||||||
const { color, symbol, count } = result.current;
|
const { level, symbol, count } = result.current;
|
||||||
|
|
||||||
expect(symbol).toBe("!");
|
expect(symbol).toBe("!");
|
||||||
expect(color).toBe(NotificationColor.Unsent);
|
expect(level).toBe(NotificationLevel.Unsent);
|
||||||
expect(count).toBeGreaterThan(0);
|
expect(count).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -69,10 +69,10 @@ describe("useUnreadNotifications", () => {
|
||||||
room.updateMyMembership("invite");
|
room.updateMyMembership("invite");
|
||||||
|
|
||||||
const { result } = renderHook(() => useUnreadNotifications(room));
|
const { result } = renderHook(() => useUnreadNotifications(room));
|
||||||
const { color, symbol, count } = result.current;
|
const { level, symbol, count } = result.current;
|
||||||
|
|
||||||
expect(symbol).toBe("!");
|
expect(symbol).toBe("!");
|
||||||
expect(color).toBe(NotificationColor.Red);
|
expect(level).toBe(NotificationLevel.Highlight);
|
||||||
expect(count).toBeGreaterThan(0);
|
expect(count).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -81,9 +81,9 @@ describe("useUnreadNotifications", () => {
|
||||||
muteRoom(room);
|
muteRoom(room);
|
||||||
|
|
||||||
const { result } = renderHook(() => useUnreadNotifications(room));
|
const { result } = renderHook(() => useUnreadNotifications(room));
|
||||||
const { color, count } = result.current;
|
const { level, count } = result.current;
|
||||||
|
|
||||||
expect(color).toBe(NotificationColor.None);
|
expect(level).toBe(NotificationLevel.None);
|
||||||
expect(count).toBe(0);
|
expect(count).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -91,9 +91,9 @@ describe("useUnreadNotifications", () => {
|
||||||
setUnreads(999, 0);
|
setUnreads(999, 0);
|
||||||
|
|
||||||
const { result } = renderHook(() => useUnreadNotifications(room));
|
const { result } = renderHook(() => useUnreadNotifications(room));
|
||||||
const { color, count } = result.current;
|
const { level, count } = result.current;
|
||||||
|
|
||||||
expect(color).toBe(NotificationColor.Grey);
|
expect(level).toBe(NotificationLevel.Notification);
|
||||||
expect(count).toBe(999);
|
expect(count).toBe(999);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -101,9 +101,9 @@ describe("useUnreadNotifications", () => {
|
||||||
setUnreads(0, 888);
|
setUnreads(0, 888);
|
||||||
|
|
||||||
const { result } = renderHook(() => useUnreadNotifications(room));
|
const { result } = renderHook(() => useUnreadNotifications(room));
|
||||||
const { color, count } = result.current;
|
const { level, count } = result.current;
|
||||||
|
|
||||||
expect(color).toBe(NotificationColor.Red);
|
expect(level).toBe(NotificationLevel.Highlight);
|
||||||
expect(count).toBe(888);
|
expect(count).toBe(888);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -46,7 +46,7 @@ import { MatrixClientPeg } from "../../src/MatrixClientPeg";
|
||||||
import RoomListStore from "../../src/stores/room-list/RoomListStore";
|
import RoomListStore from "../../src/stores/room-list/RoomListStore";
|
||||||
import { DefaultTagID } from "../../src/stores/room-list/models";
|
import { DefaultTagID } from "../../src/stores/room-list/models";
|
||||||
import { RoomNotificationStateStore } from "../../src/stores/notifications/RoomNotificationStateStore";
|
import { RoomNotificationStateStore } from "../../src/stores/notifications/RoomNotificationStateStore";
|
||||||
import { NotificationColor } from "../../src/stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../src/stores/notifications/NotificationLevel";
|
||||||
|
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
@ -1467,7 +1467,7 @@ describe("SpaceStore", () => {
|
||||||
const room = mkRoom(room1);
|
const room = mkRoom(room1);
|
||||||
const state = RoomNotificationStateStore.instance.getRoomState(room);
|
const state = RoomNotificationStateStore.instance.getRoomState(room);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
state._color = NotificationColor.Grey;
|
state._level = NotificationLevel.Notification;
|
||||||
jest.spyOn(RoomListStore.instance, "orderedLists", "get").mockReturnValue({
|
jest.spyOn(RoomListStore.instance, "orderedLists", "get").mockReturnValue({
|
||||||
[DefaultTagID.Untagged]: [room],
|
[DefaultTagID.Untagged]: [room],
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,18 +14,18 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { humanReadableNotificationColor, NotificationColor } from "../../../src/stores/notifications/NotificationColor";
|
import { humanReadableNotificationLevel, NotificationLevel } from "../../../src/stores/notifications/NotificationLevel";
|
||||||
|
|
||||||
describe("NotificationColor", () => {
|
describe("NotificationLevel", () => {
|
||||||
describe("humanReadableNotificationColor", () => {
|
describe("humanReadableNotificationLevel", () => {
|
||||||
it.each([
|
it.each([
|
||||||
[NotificationColor.None, "None"],
|
[NotificationLevel.None, "None"],
|
||||||
[NotificationColor.Bold, "Bold"],
|
[NotificationLevel.Activity, "Activity"],
|
||||||
[NotificationColor.Grey, "Grey"],
|
[NotificationLevel.Notification, "Notification"],
|
||||||
[NotificationColor.Red, "Red"],
|
[NotificationLevel.Highlight, "Highlight"],
|
||||||
[NotificationColor.Unsent, "Unsent"],
|
[NotificationLevel.Unsent, "Unsent"],
|
||||||
])("correctly maps the output", (color, output) => {
|
])("correctly maps the output", (color, output) => {
|
||||||
expect(humanReadableNotificationColor(color)).toBe(output);
|
expect(humanReadableNotificationLevel(color)).toBe(output);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -28,7 +28,7 @@ import type { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||||
import { mkEvent, muteRoom, stubClient } from "../../test-utils";
|
import { mkEvent, muteRoom, stubClient } from "../../test-utils";
|
||||||
import { RoomNotificationState } from "../../../src/stores/notifications/RoomNotificationState";
|
import { RoomNotificationState } from "../../../src/stores/notifications/RoomNotificationState";
|
||||||
import { NotificationStateEvents } from "../../../src/stores/notifications/NotificationState";
|
import { NotificationStateEvents } from "../../../src/stores/notifications/NotificationState";
|
||||||
import { NotificationColor } from "../../../src/stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../src/stores/notifications/NotificationLevel";
|
||||||
import { createMessageEventContent } from "../../test-utils/events";
|
import { createMessageEventContent } from "../../test-utils/events";
|
||||||
|
|
||||||
describe("RoomNotificationState", () => {
|
describe("RoomNotificationState", () => {
|
||||||
|
@ -109,7 +109,7 @@ describe("RoomNotificationState", () => {
|
||||||
event.status = EventStatus.NOT_SENT;
|
event.status = EventStatus.NOT_SENT;
|
||||||
room.addPendingEvent(event, "txn");
|
room.addPendingEvent(event, "txn");
|
||||||
|
|
||||||
expect(roomNotifState.color).toBe(NotificationColor.Unsent);
|
expect(roomNotifState.level).toBe(NotificationLevel.Unsent);
|
||||||
expect(roomNotifState.symbol).toBe("!");
|
expect(roomNotifState.symbol).toBe("!");
|
||||||
expect(roomNotifState.count).toBeGreaterThan(0);
|
expect(roomNotifState.count).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
@ -121,7 +121,7 @@ describe("RoomNotificationState", () => {
|
||||||
setUnreads(room, 1234, 0);
|
setUnreads(room, 1234, 0);
|
||||||
room.updateMyMembership("join"); // emit
|
room.updateMyMembership("join"); // emit
|
||||||
|
|
||||||
expect(roomNotifState.color).toBe(NotificationColor.None);
|
expect(roomNotifState.level).toBe(NotificationLevel.None);
|
||||||
expect(roomNotifState.symbol).toBe(null);
|
expect(roomNotifState.symbol).toBe(null);
|
||||||
expect(roomNotifState.count).toBe(0);
|
expect(roomNotifState.count).toBe(0);
|
||||||
});
|
});
|
||||||
|
@ -131,7 +131,7 @@ describe("RoomNotificationState", () => {
|
||||||
|
|
||||||
room.updateMyMembership("invite"); // emit
|
room.updateMyMembership("invite"); // emit
|
||||||
|
|
||||||
expect(roomNotifState.color).toBe(NotificationColor.Red);
|
expect(roomNotifState.level).toBe(NotificationLevel.Highlight);
|
||||||
expect(roomNotifState.symbol).toBe("!");
|
expect(roomNotifState.symbol).toBe("!");
|
||||||
expect(roomNotifState.count).toBeGreaterThan(0);
|
expect(roomNotifState.count).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
@ -142,7 +142,7 @@ describe("RoomNotificationState", () => {
|
||||||
setUnreads(room, 4321, 0);
|
setUnreads(room, 4321, 0);
|
||||||
room.updateMyMembership("join"); // emit
|
room.updateMyMembership("join"); // emit
|
||||||
|
|
||||||
expect(roomNotifState.color).toBe(NotificationColor.Grey);
|
expect(roomNotifState.level).toBe(NotificationLevel.Notification);
|
||||||
expect(roomNotifState.symbol).toBe(null);
|
expect(roomNotifState.symbol).toBe(null);
|
||||||
expect(roomNotifState.count).toBe(4321);
|
expect(roomNotifState.count).toBe(4321);
|
||||||
});
|
});
|
||||||
|
@ -153,7 +153,7 @@ describe("RoomNotificationState", () => {
|
||||||
setUnreads(room, 0, 69);
|
setUnreads(room, 0, 69);
|
||||||
room.updateMyMembership("join"); // emit
|
room.updateMyMembership("join"); // emit
|
||||||
|
|
||||||
expect(roomNotifState.color).toBe(NotificationColor.Red);
|
expect(roomNotifState.level).toBe(NotificationLevel.Highlight);
|
||||||
expect(roomNotifState.symbol).toBe(null);
|
expect(roomNotifState.symbol).toBe(null);
|
||||||
expect(roomNotifState.count).toBe(69);
|
expect(roomNotifState.count).toBe(69);
|
||||||
});
|
});
|
||||||
|
@ -173,7 +173,7 @@ describe("RoomNotificationState", () => {
|
||||||
addThread(room);
|
addThread(room);
|
||||||
room.updateMyMembership("join"); // emit
|
room.updateMyMembership("join"); // emit
|
||||||
|
|
||||||
expect(roomNotifState.color).toBe(NotificationColor.Bold);
|
expect(roomNotifState.level).toBe(NotificationLevel.Activity);
|
||||||
expect(roomNotifState.symbol).toBe(null);
|
expect(roomNotifState.symbol).toBe(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { ImportanceAlgorithm } from "../../../../../src/stores/room-list/algorit
|
||||||
import { SortAlgorithm } from "../../../../../src/stores/room-list/algorithms/models";
|
import { SortAlgorithm } from "../../../../../src/stores/room-list/algorithms/models";
|
||||||
import * as RoomNotifs from "../../../../../src/RoomNotifs";
|
import * as RoomNotifs from "../../../../../src/RoomNotifs";
|
||||||
import { DefaultTagID, RoomUpdateCause } from "../../../../../src/stores/room-list/models";
|
import { DefaultTagID, RoomUpdateCause } from "../../../../../src/stores/room-list/models";
|
||||||
import { NotificationColor } from "../../../../../src/stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../../../src/stores/notifications/NotificationLevel";
|
||||||
import { AlphabeticAlgorithm } from "../../../../../src/stores/room-list/algorithms/tag-sorting/AlphabeticAlgorithm";
|
import { AlphabeticAlgorithm } from "../../../../../src/stores/room-list/algorithms/tag-sorting/AlphabeticAlgorithm";
|
||||||
import { getMockClientWithEventEmitter, mockClientMethodsUser } from "../../../../test-utils";
|
import { getMockClientWithEventEmitter, mockClientMethodsUser } from "../../../../test-utils";
|
||||||
import { RecentAlgorithm } from "../../../../../src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm";
|
import { RecentAlgorithm } from "../../../../../src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm";
|
||||||
|
@ -75,16 +75,16 @@ describe("ImportanceAlgorithm", () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const unreadStates: Record<string, ReturnType<(typeof RoomNotifs)["determineUnreadState"]>> = {
|
const unreadStates: Record<string, ReturnType<(typeof RoomNotifs)["determineUnreadState"]>> = {
|
||||||
red: { symbol: null, count: 1, color: NotificationColor.Red },
|
red: { symbol: null, count: 1, level: NotificationLevel.Highlight },
|
||||||
grey: { symbol: null, count: 1, color: NotificationColor.Grey },
|
grey: { symbol: null, count: 1, level: NotificationLevel.Notification },
|
||||||
none: { symbol: null, count: 0, color: NotificationColor.None },
|
none: { symbol: null, count: 0, level: NotificationLevel.None },
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.spyOn(RoomNotifs, "determineUnreadState").mockReturnValue({
|
jest.spyOn(RoomNotifs, "determineUnreadState").mockReturnValue({
|
||||||
symbol: null,
|
symbol: null,
|
||||||
count: 0,
|
count: 0,
|
||||||
color: NotificationColor.None,
|
level: NotificationLevel.None,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ describe("ImportanceAlgorithm", () => {
|
||||||
jest.spyOn(RoomNotifs, "determineUnreadState").mockReturnValue({
|
jest.spyOn(RoomNotifs, "determineUnreadState").mockReturnValue({
|
||||||
symbol: null,
|
symbol: null,
|
||||||
count: 0,
|
count: 0,
|
||||||
color: NotificationColor.None,
|
level: NotificationLevel.None,
|
||||||
});
|
});
|
||||||
const algorithm = setupAlgorithm(sortAlgorithm);
|
const algorithm = setupAlgorithm(sortAlgorithm);
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ describe("ImportanceAlgorithm", () => {
|
||||||
jest.spyOn(RoomNotifs, "determineUnreadState").mockReturnValue({
|
jest.spyOn(RoomNotifs, "determineUnreadState").mockReturnValue({
|
||||||
symbol: null,
|
symbol: null,
|
||||||
count: 0,
|
count: 0,
|
||||||
color: NotificationColor.None,
|
level: NotificationLevel.None,
|
||||||
});
|
});
|
||||||
const algorithm = setupAlgorithm(sortAlgorithm);
|
const algorithm = setupAlgorithm(sortAlgorithm);
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ import { RoomNotificationStateStore } from "../../../../../src/stores/notificati
|
||||||
import * as RoomNotifs from "../../../../../src/RoomNotifs";
|
import * as RoomNotifs from "../../../../../src/RoomNotifs";
|
||||||
import { getMockClientWithEventEmitter, mockClientMethodsUser } from "../../../../test-utils";
|
import { getMockClientWithEventEmitter, mockClientMethodsUser } from "../../../../test-utils";
|
||||||
import { DEFAULT_PUSH_RULES, makePushRule } from "../../../../test-utils/pushRules";
|
import { DEFAULT_PUSH_RULES, makePushRule } from "../../../../test-utils/pushRules";
|
||||||
import { NotificationColor } from "../../../../../src/stores/notifications/NotificationColor";
|
import { NotificationLevel } from "../../../../../src/stores/notifications/NotificationLevel";
|
||||||
|
|
||||||
describe("NaturalAlgorithm", () => {
|
describe("NaturalAlgorithm", () => {
|
||||||
const userId = "@alice:server.org";
|
const userId = "@alice:server.org";
|
||||||
|
@ -197,7 +197,7 @@ describe("NaturalAlgorithm", () => {
|
||||||
jest.spyOn(RoomNotifs, "determineUnreadState").mockReturnValue({
|
jest.spyOn(RoomNotifs, "determineUnreadState").mockReturnValue({
|
||||||
symbol: null,
|
symbol: null,
|
||||||
count: 0,
|
count: 0,
|
||||||
color: NotificationColor.None,
|
level: NotificationLevel.None,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue