Merge pull request #11508 from matrix-org/germain-gg/notifications-labs

Move notifications bell back in labs
This commit is contained in:
Andy Balaam 2023-09-15 14:19:47 +01:00 committed by GitHub
commit 0b50e02790
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 61 additions and 43 deletions

View file

@ -38,6 +38,7 @@ describe("NotificationPanel", () => {
}); });
it("should render empty state", () => { it("should render empty state", () => {
cy.enableLabsFeature("feature_notifications");
cy.viewRoomByName(ROOM_NAME); cy.viewRoomByName(ROOM_NAME);
cy.findByRole("button", { name: "Notifications" }).click(); cy.findByRole("button", { name: "Notifications" }).click();

View file

@ -36,6 +36,7 @@ describe("Room Header", () => {
}); });
it("should render default buttons properly", () => { it("should render default buttons properly", () => {
cy.enableLabsFeature("feature_notifications");
cy.createRoom({ name: "Test Room" }).viewRoomByName("Test Room"); cy.createRoom({ name: "Test Room" }).viewRoomByName("Test Room");
cy.get(".mx_LegacyRoomHeader").within(() => { cy.get(".mx_LegacyRoomHeader").within(() => {
@ -79,6 +80,7 @@ describe("Room Header", () => {
}); });
it("should render a very long room name without collapsing the buttons", () => { it("should render a very long room name without collapsing the buttons", () => {
cy.enableLabsFeature("feature_notifications");
const LONG_ROOM_NAME = const LONG_ROOM_NAME =
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore " + "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore " +
"et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + "et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " +
@ -109,6 +111,7 @@ describe("Room Header", () => {
}); });
it("should have buttons highlighted by being clicked", () => { it("should have buttons highlighted by being clicked", () => {
cy.enableLabsFeature("feature_notifications");
cy.createRoom({ name: "Test Room" }).viewRoomByName("Test Room"); cy.createRoom({ name: "Test Room" }).viewRoomByName("Test Room");
cy.get(".mx_LegacyRoomHeader").within(() => { cy.get(".mx_LegacyRoomHeader").within(() => {
@ -142,6 +145,7 @@ describe("Room Header", () => {
}; };
it("should render buttons for room options, beta pill, invite, chat, and room info", () => { it("should render buttons for room options, beta pill, invite, chat, and room info", () => {
cy.enableLabsFeature("feature_notifications");
createVideoRoom(); createVideoRoom();
cy.get(".mx_LegacyRoomHeader").within(() => { cy.get(".mx_LegacyRoomHeader").within(() => {

View file

@ -25,6 +25,7 @@ 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 { NotificationColor } from "../../../stores/notifications/NotificationColor";
import SettingsStore from "../../../settings/SettingsStore";
export enum HeaderKind { export enum HeaderKind {
Room = "room", Room = "room",
@ -35,6 +36,7 @@ interface IState {
phase: RightPanelPhases | null; phase: RightPanelPhases | null;
threadNotificationColor: NotificationColor; threadNotificationColor: NotificationColor;
globalNotificationColor: NotificationColor; globalNotificationColor: NotificationColor;
notificationsEnabled?: boolean;
} }
interface IProps {} interface IProps {}
@ -42,6 +44,7 @@ interface IProps {}
export default abstract class HeaderButtons<P = {}> extends React.Component<IProps & P, IState> { export default abstract class HeaderButtons<P = {}> extends React.Component<IProps & P, IState> {
private unmounted = false; private unmounted = false;
private dispatcherRef?: string = undefined; private dispatcherRef?: string = undefined;
private readonly watcherRef: string;
public constructor(props: IProps & P, kind: HeaderKind) { public constructor(props: IProps & P, kind: HeaderKind) {
super(props); super(props);
@ -52,7 +55,11 @@ export default abstract class HeaderButtons<P = {}> extends React.Component<IPro
phase: rps.currentCard.phase, phase: rps.currentCard.phase,
threadNotificationColor: NotificationColor.None, threadNotificationColor: NotificationColor.None,
globalNotificationColor: NotificationColor.None, globalNotificationColor: NotificationColor.None,
notificationsEnabled: SettingsStore.getValue("feature_notifications"),
}; };
this.watcherRef = SettingsStore.watchSetting("feature_notifications", null, (...[, , , value]) =>
this.setState({ notificationsEnabled: value }),
);
} }
public componentDidMount(): void { public componentDidMount(): void {
@ -63,6 +70,7 @@ export default abstract class HeaderButtons<P = {}> extends React.Component<IPro
this.unmounted = true; this.unmounted = true;
RightPanelStore.instance.off(UPDATE_EVENT, this.onRightPanelStoreUpdate); RightPanelStore.instance.off(UPDATE_EVENT, this.onRightPanelStoreUpdate);
if (this.dispatcherRef) dis.unregister(this.dispatcherRef); if (this.dispatcherRef) dis.unregister(this.dispatcherRef);
if (this.watcherRef) SettingsStore.unwatchSetting(this.watcherRef);
} }
public isPhase(phases: string | string[]): boolean { public isPhase(phases: string | string[]): boolean {

View file

@ -282,21 +282,23 @@ export default class LegacyRoomHeaderButtons extends HeaderButtons<IProps> {
<UnreadIndicator color={this.state.threadNotificationColor} /> <UnreadIndicator color={this.state.threadNotificationColor} />
</HeaderButton>, </HeaderButton>,
); );
rightPanelPhaseButtons.set( if (this.state.notificationsEnabled) {
RightPanelPhases.NotificationPanel, rightPanelPhaseButtons.set(
<HeaderButton RightPanelPhases.NotificationPanel,
key="notifsButton" <HeaderButton
name="notifsButton" key="notifsButton"
title={_t("Notifications")} name="notifsButton"
isHighlighted={this.isPhase(RightPanelPhases.NotificationPanel)} title={_t("Notifications")}
onClick={this.onNotificationsClicked} isHighlighted={this.isPhase(RightPanelPhases.NotificationPanel)}
isUnread={this.globalNotificationState.color === NotificationColor.Red} onClick={this.onNotificationsClicked}
> isUnread={this.globalNotificationState.color === NotificationColor.Red}
{this.globalNotificationState.color === NotificationColor.Red ? ( >
<UnreadIndicator color={this.globalNotificationState.color} /> {this.globalNotificationState.color === NotificationColor.Red ? (
) : null} <UnreadIndicator color={this.globalNotificationState.color} />
</HeaderButton>, ) : null}
); </HeaderButton>,
);
}
rightPanelPhaseButtons.set( rightPanelPhaseButtons.set(
RightPanelPhases.RoomSummary, RightPanelPhases.RoomSummary,
<HeaderButton <HeaderButton

View file

@ -100,6 +100,8 @@ export default function RoomHeader({ room }: { room: Room }): JSX.Element {
}, [room, directRoomsList]); }, [room, directRoomsList]);
const e2eStatus = useEncryptionStatus(client, room); const e2eStatus = useEncryptionStatus(client, room);
const notificationsEnabled = useFeatureEnabled("feature_notifications");
return ( return (
<Flex <Flex
as="header" as="header"
@ -202,18 +204,20 @@ export default function RoomHeader({ room }: { room: Room }): JSX.Element {
<ThreadsIcon /> <ThreadsIcon />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
<Tooltip label={_t("Notifications")}> {notificationsEnabled && (
<IconButton <Tooltip label={_t("Notifications")}>
indicator={notificationColorToIndicator(globalNotificationState.color)} <IconButton
onClick={(evt) => { indicator={notificationColorToIndicator(globalNotificationState.color)}
evt.stopPropagation(); onClick={(evt) => {
RightPanelStore.instance.showOrHidePanel(RightPanelPhases.NotificationPanel); evt.stopPropagation();
}} RightPanelStore.instance.showOrHidePanel(RightPanelPhases.NotificationPanel);
title={_t("Notifications")} }}
> title={_t("Notifications")}
<NotificationsIcon /> >
</IconButton> <NotificationsIcon />
</Tooltip> </IconButton>
</Tooltip>
)}
</Flex> </Flex>
{!isDirectMessage && ( {!isDirectMessage && (
<BodyText <BodyText

View file

@ -1161,7 +1161,9 @@
"rust_crypto": "Rust cryptography implementation", "rust_crypto": "Rust cryptography implementation",
"hidebold": "Hide notification dot (only display counters badges)", "hidebold": "Hide notification dot (only display counters badges)",
"ask_to_join": "Enable ask to join", "ask_to_join": "Enable ask to join",
"new_room_decoration_ui": "New room header & details interface", "new_room_decoration_ui": "Under active development, new room header & details interface",
"notifications": "Enable the notifications panel in the room header",
"unrealiable_e2e": "Unreliable in encrypted rooms",
"beta_feature": "This is a beta feature", "beta_feature": "This is a beta feature",
"click_for_info": "Click for more info", "click_for_info": "Click for more info",
"leave_beta_reload": "Leaving the beta will reload %(brand)s.", "leave_beta_reload": "Leaving the beta will reload %(brand)s.",

View file

@ -547,6 +547,14 @@ export const SETTINGS: { [setting: string]: ISetting } = {
default: false, default: false,
controller: new ReloadOnChangeController(), controller: new ReloadOnChangeController(),
}, },
"feature_notifications": {
isFeature: true,
labsGroup: LabGroup.Messaging,
displayName: _td("labs|notifications"),
description: _td("labs|unrealiable_e2e"),
supportedLevels: LEVELS_FEATURE,
default: false,
},
"useCompactLayout": { "useCompactLayout": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS, supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
displayName: _td("Use a more compact 'Modern' layout"), displayName: _td("Use a more compact 'Modern' layout"),

View file

@ -17,13 +17,6 @@ exports[`LegacyRoomHeaderButtons-test.tsx should render 1`] = `
role="button" role="button"
tabindex="0" tabindex="0"
/> />
<div
aria-current="false"
aria-label="Notifications"
class="mx_AccessibleButton mx_LegacyRoomHeader_button mx_RightPanel_notifsButton"
role="button"
tabindex="0"
/>
<div <div
aria-current="false" aria-current="false"
aria-label="Room info" aria-label="Room info"

View file

@ -200,6 +200,10 @@ describe("RoomHeader", () => {
}); });
it("opens the notifications panel", async () => { it("opens the notifications panel", async () => {
jest.spyOn(SettingsStore, "getValue").mockImplementation((name: string) => {
if (name === "feature_notifications") return true;
});
const { container } = render( const { container } = render(
<RoomHeader room={room} />, <RoomHeader room={room} />,
withClientContextRenderOptions(MatrixClientPeg.get()!), withClientContextRenderOptions(MatrixClientPeg.get()!),

View file

@ -60,14 +60,6 @@ exports[`RoomHeader does not show the face pile for DMs 1`] = `
> >
<div /> <div />
</button> </button>
<button
class="_icon-button_1segd_17"
data-state="closed"
style="--cpd-icon-button-size: 32px;"
title="Notifications"
>
<div />
</button>
</nav> </nav>
</header> </header>
</DocumentFragment> </DocumentFragment>