Add setting to hide bold notifications (#9705)

This commit is contained in:
Germain 2022-12-06 09:59:17 +00:00 committed by GitHub
parent 474f464e48
commit 3a501003e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 65 additions and 13 deletions

View file

@ -20,6 +20,7 @@ import classNames from "classnames";
import { formatCount } from "../../../../utils/FormattingUtils";
import AccessibleButton from "../../elements/AccessibleButton";
import { NotificationColor } from "../../../../stores/notifications/NotificationColor";
import { useSettingValue } from "../../../../hooks/useSettings";
interface Props {
symbol: string | null;
@ -37,8 +38,12 @@ export function StatelessNotificationBadge({
count,
color,
...props }: Props) {
const hideBold = useSettingValue("feature_hidebold");
// Don't show a badge if we don't need to
if (color === NotificationColor.None) return null;
if (color === NotificationColor.None || (hideBold && color == NotificationColor.Bold)) {
return null;
}
const hasUnreadCount = color >= NotificationColor.Grey && (!!count || !!symbol);

View file

@ -960,6 +960,7 @@
"Show stickers button": "Show stickers button",
"Show polls button": "Show polls button",
"Insert a trailing colon after user mentions at the start of a message": "Insert a trailing colon after user mentions at the start of a message",
"Hide notification dot (only display counters badges)": "Hide notification dot (only display counters badges)",
"Use a more compact 'Modern' layout": "Use a more compact 'Modern' layout",
"Show a placeholder for removed messages": "Show a placeholder for removed messages",
"Show join/leave messages (invites/removes/bans unaffected)": "Show join/leave messages (invites/removes/bans unaffected)",

View file

@ -556,11 +556,18 @@ export const SETTINGS: {[setting: string]: ISetting} = {
supportedLevels: LEVELS_ROOM_OR_ACCOUNT,
default: false,
},
"feature_hidebold": {
isFeature: true,
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
displayName: _td("Hide notification dot (only display counters badges)"),
labsGroup: LabGroup.Rooms,
default: false,
},
"useCompactLayout": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
displayName: _td("Use a more compact 'Modern' layout"),
default: false,
controller: new IncompatibleController("layout", false, v => v !== Layout.Group),
controller: new IncompatibleController("layout", false, (v: Layout) => v !== Layout.Group),
},
"showRedactions": {
supportedLevels: LEVELS_ROOM_SETTINGS_WITH_ROOM,

View file

@ -31,7 +31,7 @@ export class ListNotificationState extends NotificationState {
super();
}
public get symbol(): string {
public get symbol(): string | null {
return this._color === NotificationColor.Unsent ? "!" : null;
}

View file

@ -18,6 +18,7 @@ import { TypedEventEmitter } from "matrix-js-sdk/src/models/typed-event-emitter"
import { NotificationColor } from "./NotificationColor";
import { IDestroyable } from "../../utils/IDestroyable";
import SettingsStore from "../../settings/SettingsStore";
export interface INotificationStateSnapshotParams {
symbol: string | null;
@ -37,11 +38,22 @@ export abstract class NotificationState
extends TypedEventEmitter<NotificationStateEvents, EventHandlerMap>
implements INotificationStateSnapshotParams, IDestroyable {
//
protected _symbol: string | null;
protected _count: number;
protected _color: NotificationColor;
protected _symbol: string | null = null;
protected _count = 0;
protected _color: NotificationColor = NotificationColor.None;
public get symbol(): string {
private watcherReferences: string[] = [];
constructor() {
super();
this.watcherReferences.push(
SettingsStore.watchSetting("feature_hidebold", null, () => {
this.emit(NotificationStateEvents.Update);
}),
);
}
public get symbol(): string | null {
return this._symbol;
}
@ -58,7 +70,12 @@ export abstract class NotificationState
}
public get isUnread(): boolean {
return this.color >= NotificationColor.Bold;
if (this.color > NotificationColor.Bold) {
return true;
} else {
const hideBold = SettingsStore.getValue("feature_hidebold");
return this.color === NotificationColor.Bold && !hideBold;
}
}
public get hasUnreadCount(): boolean {
@ -81,11 +98,15 @@ export abstract class NotificationState
public destroy(): void {
this.removeAllListeners(NotificationStateEvents.Update);
for (const watcherReference of this.watcherReferences) {
SettingsStore.unwatchSetting(watcherReference);
}
this.watcherReferences = [];
}
}
export class NotificationStateSnapshot {
private readonly symbol: string;
private readonly symbol: string | null;
private readonly count: number;
private readonly color: NotificationColor;

View file

@ -98,8 +98,8 @@ export class RoomNotificationState extends NotificationState implements IDestroy
this.updateNotificationState();
};
private handleRoomEventUpdate = (event: MatrixEvent, room: Room | null) => {
if (room?.roomId !== this.room.roomId) return; // ignore - not for us or notifications timeline
private handleRoomEventUpdate = (event: MatrixEvent) => {
if (event?.getRoomId() !== this.room.roomId) return; // ignore - not for us or notifications timeline
this.updateNotificationState();
};

View file

@ -32,7 +32,7 @@ export class SpaceNotificationState extends NotificationState {
super();
}
public get symbol(): string {
public get symbol(): string | null {
return this._color === NotificationColor.Unsent ? "!" : null;
}

View file

@ -20,7 +20,7 @@ import { NotificationState } from "./NotificationState";
export class StaticNotificationState extends NotificationState {
public static readonly RED_EXCLAMATION = StaticNotificationState.forSymbol("!", NotificationColor.Red);
constructor(symbol: string, count: number, color: NotificationColor) {
constructor(symbol: string | null, count: number, color: NotificationColor) {
super();
this._symbol = symbol;
this._count = count;

View file

@ -20,6 +20,7 @@ import React from "react";
import {
StatelessNotificationBadge,
} from "../../../../../src/components/views/rooms/NotificationBadge/StatelessNotificationBadge";
import SettingsStore from "../../../../../src/settings/SettingsStore";
import { NotificationColor } from "../../../../../src/stores/notifications/NotificationColor";
describe("NotificationBadge", () => {
@ -45,5 +46,19 @@ describe("NotificationBadge", () => {
fireEvent.mouseLeave(container.firstChild);
expect(cb).toHaveBeenCalledTimes(3);
});
it("hides the bold icon when the settings is set", () => {
jest.spyOn(SettingsStore, "getValue").mockImplementation((name: string) => {
return name === "feature_hidebold";
});
const { container } = render(<StatelessNotificationBadge
symbol=""
color={NotificationColor.Bold}
count={1}
/>);
expect(container.firstChild).toBeNull();
});
});
});

View file

@ -38,6 +38,7 @@ jest.mock('../../../../src/settings/SettingsStore', () => ({
setValue: jest.fn(),
getValue: jest.fn(),
monitorSetting: jest.fn(),
watchSetting: jest.fn(),
}));
jest.mock('../../../../src/dispatcher/dispatcher', () => ({

View file

@ -25,6 +25,7 @@ import { TestSdkContext } from "../TestSdkContext";
jest.mock("../../src/settings/SettingsStore", () => ({
getValue: jest.fn(),
monitorSetting: jest.fn(),
watchSetting: jest.fn(),
}));
describe("TypingStore", () => {

View file

@ -42,6 +42,7 @@ jest.mock('../../src/Modal', () => ({
jest.mock('../../src/settings/SettingsStore', () => ({
getValue: jest.fn(),
monitorSetting: jest.fn(),
watchSetting: jest.fn(),
}));
const mockPromptBeforeInviteUnknownUsers = (value: boolean) => {