Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit dafc97f

Browse files
Add release announcement for the new room header (#12802)
1 parent bb1b7f1 commit dafc97f

File tree

5 files changed

+91
-68
lines changed

5 files changed

+91
-68
lines changed

src/components/views/rooms/RoomHeader.tsx

+76-60
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ import { isVideoRoom } from "../../../utils/video-rooms";
5757
import { notificationLevelToIndicator } from "../../../utils/notifications";
5858
import { CallGuestLinkButton } from "./RoomHeader/CallGuestLinkButton";
5959
import { ButtonEvent } from "../elements/AccessibleButton";
60+
import { ReleaseAnnouncement } from "../../structures/ReleaseAnnouncement";
61+
import { useIsReleaseAnnouncementOpen } from "../../../hooks/useIsReleaseAnnouncementOpen";
62+
import { ReleaseAnnouncementStore } from "../../../stores/ReleaseAnnouncementStore";
6063

6164
export default function RoomHeader({
6265
room,
@@ -238,74 +241,87 @@ export default function RoomHeader({
238241
voiceCallButton = undefined;
239242
}
240243

244+
const isReleaseAnnouncementOpen = useIsReleaseAnnouncementOpen("newRoomHeader");
245+
241246
return (
242247
<>
243248
<Flex as="header" align="center" gap="var(--cpd-space-3x)" className="mx_RoomHeader light-panel">
244-
<button
245-
aria-label={_t("right_panel|room_summary_card|title")}
246-
tabIndex={0}
247-
onClick={() => {
248-
RightPanelStore.instance.showOrHidePanel(RightPanelPhases.RoomSummary);
249-
}}
250-
className="mx_RoomHeader_infoWrapper"
249+
<ReleaseAnnouncement
250+
feature="newRoomHeader"
251+
header={_t("room|header|release_announcement_header")}
252+
description={_t("room|header|release_announcement_description")}
253+
closeLabel={_t("action|ok")}
254+
placement="bottom"
251255
>
252-
<RoomAvatar room={room} size="40px" />
253-
<Box flex="1" className="mx_RoomHeader_info">
254-
<BodyText
255-
as="div"
256-
size="lg"
257-
weight="semibold"
258-
dir="auto"
259-
role="heading"
260-
aria-level={1}
261-
className="mx_RoomHeader_heading"
262-
>
263-
<span className="mx_RoomHeader_truncated mx_lineClamp">{roomName}</span>
264-
265-
{!isDirectMessage && roomState.getJoinRule() === JoinRule.Public && (
266-
<Tooltip label={_t("common|public_room")} placement="right">
267-
<PublicIcon
268-
width="16px"
269-
height="16px"
270-
className="mx_RoomHeader_icon text-secondary"
271-
aria-label={_t("common|public_room")}
272-
/>
273-
</Tooltip>
274-
)}
275-
276-
{isDirectMessage && e2eStatus === E2EStatus.Verified && (
277-
<Tooltip label={_t("common|verified")} placement="right">
278-
<VerifiedIcon
279-
width="16px"
280-
height="16px"
281-
className="mx_RoomHeader_icon mx_Verified"
282-
aria-label={_t("common|verified")}
283-
/>
284-
</Tooltip>
285-
)}
286-
287-
{isDirectMessage && e2eStatus === E2EStatus.Warning && (
288-
<Tooltip label={_t("room|header_untrusted_label")} placement="right">
289-
<ErrorIcon
290-
width="16px"
291-
height="16px"
292-
className="mx_RoomHeader_icon mx_Untrusted"
293-
aria-label={_t("room|header_untrusted_label")}
294-
/>
295-
</Tooltip>
296-
)}
297-
</BodyText>
298-
{roomTopic && (
256+
<button
257+
aria-label={_t("right_panel|room_summary_card|title")}
258+
tabIndex={0}
259+
onClick={() => {
260+
if (isReleaseAnnouncementOpen) {
261+
ReleaseAnnouncementStore.instance.nextReleaseAnnouncement();
262+
}
263+
RightPanelStore.instance.showOrHidePanel(RightPanelPhases.RoomSummary);
264+
}}
265+
className="mx_RoomHeader_infoWrapper"
266+
>
267+
<RoomAvatar room={room} size="40px" />
268+
<Box flex="1" className="mx_RoomHeader_info">
299269
<BodyText
300270
as="div"
301-
size="sm"
302-
className="mx_RoomHeader_topic mx_RoomHeader_truncated mx_lineClamp"
271+
size="lg"
272+
weight="semibold"
273+
dir="auto"
274+
role="heading"
275+
aria-level={1}
276+
className="mx_RoomHeader_heading"
303277
>
304-
<Linkify>{roomTopicBody}</Linkify>
278+
<span className="mx_RoomHeader_truncated mx_lineClamp">{roomName}</span>
279+
280+
{!isDirectMessage && roomState.getJoinRule() === JoinRule.Public && (
281+
<Tooltip label={_t("common|public_room")} placement="right">
282+
<PublicIcon
283+
width="16px"
284+
height="16px"
285+
className="mx_RoomHeader_icon text-secondary"
286+
aria-label={_t("common|public_room")}
287+
/>
288+
</Tooltip>
289+
)}
290+
291+
{isDirectMessage && e2eStatus === E2EStatus.Verified && (
292+
<Tooltip label={_t("common|verified")} placement="right">
293+
<VerifiedIcon
294+
width="16px"
295+
height="16px"
296+
className="mx_RoomHeader_icon mx_Verified"
297+
aria-label={_t("common|verified")}
298+
/>
299+
</Tooltip>
300+
)}
301+
302+
{isDirectMessage && e2eStatus === E2EStatus.Warning && (
303+
<Tooltip label={_t("room|header_untrusted_label")} placement="right">
304+
<ErrorIcon
305+
width="16px"
306+
height="16px"
307+
className="mx_RoomHeader_icon mx_Untrusted"
308+
aria-label={_t("room|header_untrusted_label")}
309+
/>
310+
</Tooltip>
311+
)}
305312
</BodyText>
306-
)}
307-
</Box>
308-
</button>
313+
{roomTopic && (
314+
<BodyText
315+
as="div"
316+
size="sm"
317+
className="mx_RoomHeader_topic mx_RoomHeader_truncated mx_lineClamp"
318+
>
319+
<Linkify>{roomTopicBody}</Linkify>
320+
</BodyText>
321+
)}
322+
</Box>
323+
</button>
324+
</ReleaseAnnouncement>
309325
<Flex align="center" gap="var(--cpd-space-2x)">
310326
{additionalButtons?.map((props) => {
311327
const label = props.label();

src/i18n/strings/en_EN.json

+2
Original file line numberDiff line numberDiff line change
@@ -1950,6 +1950,8 @@
19501950
"one": "Asking to join",
19511951
"other": "%(count)s people asking to join"
19521952
},
1953+
"release_announcement_description": "Enjoy a simpler, more accessible room header.",
1954+
"release_announcement_header": "New design!",
19531955
"room_is_public": "This room is public",
19541956
"show_widgets_button": "Show Widgets",
19551957
"video_call_button_ec": "Video call (%(brand)s)",

src/stores/ReleaseAnnouncementStore.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { Features } from "../settings/Settings";
2727
/**
2828
* The features are shown in the array order.
2929
*/
30-
const FEATURES = ["threadsActivityCentre"] as const;
30+
const FEATURES = ["threadsActivityCentre", "newRoomHeader"] as const;
3131
/**
3232
* All the features that can be shown in the release announcements.
3333
*/

test/components/views/rooms/__snapshots__/RoomHeader-test.tsx.snap

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ exports[`RoomHeader does not show the face pile for DMs 1`] = `
77
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x);"
88
>
99
<button
10+
aria-expanded="false"
11+
aria-haspopup="dialog"
1012
aria-label="Room info"
1113
class="mx_RoomHeader_infoWrapper"
1214
tabindex="0"

test/stores/ReleaseAnnouncementStore-test.tsx

+10-7
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,18 @@ describe("ReleaseAnnouncementStore", () => {
9999
// Sanity check
100100
expect(releaseAnnouncementStore.getReleaseAnnouncement()).toBe("threadsActivityCentre");
101101

102-
const promise = listenReleaseAnnouncementChanged();
102+
let promise = listenReleaseAnnouncementChanged();
103+
await releaseAnnouncementStore.nextReleaseAnnouncement();
104+
105+
expect(await promise).toBe("newRoomHeader");
106+
expect(releaseAnnouncementStore.getReleaseAnnouncement()).toBe("newRoomHeader");
107+
108+
promise = listenReleaseAnnouncementChanged();
103109
await releaseAnnouncementStore.nextReleaseAnnouncement();
104-
// Currently there is only one feature, so the next feature should be null
105110
expect(await promise).toBeNull();
106-
expect(releaseAnnouncementStore.getReleaseAnnouncement()).toBeNull();
107111

108112
const secondStore = new ReleaseAnnouncementStore();
109-
// The TAC release announcement has been viewed, so it should be updated in the store account
113+
// All the release announcements have been viewed, so it should be updated in the store account
110114
// The release announcement viewing states should be share among all instances (devices in the same account)
111115
expect(secondStore.getReleaseAnnouncement()).toBeNull();
112116
});
@@ -118,8 +122,7 @@ describe("ReleaseAnnouncementStore", () => {
118122
const promise = listenReleaseAnnouncementChanged();
119123
await secondStore.nextReleaseAnnouncement();
120124

121-
// Currently there is only one feature, so the next feature should be null
122-
expect(await promise).toBeNull();
123-
expect(releaseAnnouncementStore.getReleaseAnnouncement()).toBeNull();
125+
expect(await promise).toBe("newRoomHeader");
126+
expect(releaseAnnouncementStore.getReleaseAnnouncement()).toBe("newRoomHeader");
124127
});
125128
});

0 commit comments

Comments
 (0)