Merge pull request #11508 from matrix-org/germain-gg/notifications-labs
Move notifications bell back in labs
This commit is contained in:
commit
0b50e02790
10 changed files with 61 additions and 43 deletions
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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(() => {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.",
|
||||||
|
|
|
@ -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"),
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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()!),
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue