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

Add release announcement for the new room header #12802

Merged
merged 3 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 76 additions & 60 deletions src/components/views/rooms/RoomHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ import { isVideoRoom } from "../../../utils/video-rooms";
import { notificationLevelToIndicator } from "../../../utils/notifications";
import { CallGuestLinkButton } from "./RoomHeader/CallGuestLinkButton";
import { ButtonEvent } from "../elements/AccessibleButton";
import { ReleaseAnnouncement } from "../../structures/ReleaseAnnouncement";
import { useIsReleaseAnnouncementOpen } from "../../../hooks/useIsReleaseAnnouncementOpen";
import { ReleaseAnnouncementStore } from "../../../stores/ReleaseAnnouncementStore";

export default function RoomHeader({
room,
Expand Down Expand Up @@ -238,74 +241,87 @@ export default function RoomHeader({
voiceCallButton = undefined;
}

const isReleaseAnnouncementOpen = useIsReleaseAnnouncementOpen("newRoomHeader");

return (
<>
<Flex as="header" align="center" gap="var(--cpd-space-3x)" className="mx_RoomHeader light-panel">
<button
aria-label={_t("right_panel|room_summary_card|title")}
tabIndex={0}
onClick={() => {
RightPanelStore.instance.showOrHidePanel(RightPanelPhases.RoomSummary);
}}
className="mx_RoomHeader_infoWrapper"
<ReleaseAnnouncement
feature="newRoomHeader"
header={_t("room|header|release_announcement_header")}
description={_t("room|header|release_announcement_description")}
closeLabel={_t("action|ok")}
placement="bottom"
>
<RoomAvatar room={room} size="40px" />
<Box flex="1" className="mx_RoomHeader_info">
<BodyText
as="div"
size="lg"
weight="semibold"
dir="auto"
role="heading"
aria-level={1}
className="mx_RoomHeader_heading"
>
<span className="mx_RoomHeader_truncated mx_lineClamp">{roomName}</span>

{!isDirectMessage && roomState.getJoinRule() === JoinRule.Public && (
<Tooltip label={_t("common|public_room")} placement="right">
<PublicIcon
width="16px"
height="16px"
className="mx_RoomHeader_icon text-secondary"
aria-label={_t("common|public_room")}
/>
</Tooltip>
)}

{isDirectMessage && e2eStatus === E2EStatus.Verified && (
<Tooltip label={_t("common|verified")} placement="right">
<VerifiedIcon
width="16px"
height="16px"
className="mx_RoomHeader_icon mx_Verified"
aria-label={_t("common|verified")}
/>
</Tooltip>
)}

{isDirectMessage && e2eStatus === E2EStatus.Warning && (
<Tooltip label={_t("room|header_untrusted_label")} placement="right">
<ErrorIcon
width="16px"
height="16px"
className="mx_RoomHeader_icon mx_Untrusted"
aria-label={_t("room|header_untrusted_label")}
/>
</Tooltip>
)}
</BodyText>
{roomTopic && (
<button
aria-label={_t("right_panel|room_summary_card|title")}
tabIndex={0}
onClick={() => {
if (isReleaseAnnouncementOpen) {
ReleaseAnnouncementStore.instance.nextReleaseAnnouncement();
}
RightPanelStore.instance.showOrHidePanel(RightPanelPhases.RoomSummary);
}}
className="mx_RoomHeader_infoWrapper"
>
<RoomAvatar room={room} size="40px" />
<Box flex="1" className="mx_RoomHeader_info">
<BodyText
as="div"
size="sm"
className="mx_RoomHeader_topic mx_RoomHeader_truncated mx_lineClamp"
size="lg"
weight="semibold"
dir="auto"
role="heading"
aria-level={1}
className="mx_RoomHeader_heading"
>
<Linkify>{roomTopicBody}</Linkify>
<span className="mx_RoomHeader_truncated mx_lineClamp">{roomName}</span>

{!isDirectMessage && roomState.getJoinRule() === JoinRule.Public && (
<Tooltip label={_t("common|public_room")} placement="right">
<PublicIcon
width="16px"
height="16px"
className="mx_RoomHeader_icon text-secondary"
aria-label={_t("common|public_room")}
/>
</Tooltip>
)}

{isDirectMessage && e2eStatus === E2EStatus.Verified && (
<Tooltip label={_t("common|verified")} placement="right">
<VerifiedIcon
width="16px"
height="16px"
className="mx_RoomHeader_icon mx_Verified"
aria-label={_t("common|verified")}
/>
</Tooltip>
)}

{isDirectMessage && e2eStatus === E2EStatus.Warning && (
<Tooltip label={_t("room|header_untrusted_label")} placement="right">
<ErrorIcon
width="16px"
height="16px"
className="mx_RoomHeader_icon mx_Untrusted"
aria-label={_t("room|header_untrusted_label")}
/>
</Tooltip>
)}
</BodyText>
)}
</Box>
</button>
{roomTopic && (
<BodyText
as="div"
size="sm"
className="mx_RoomHeader_topic mx_RoomHeader_truncated mx_lineClamp"
>
<Linkify>{roomTopicBody}</Linkify>
</BodyText>
)}
</Box>
</button>
</ReleaseAnnouncement>
<Flex align="center" gap="var(--cpd-space-2x)">
{additionalButtons?.map((props) => {
const label = props.label();
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1950,6 +1950,8 @@
"one": "Asking to join",
"other": "%(count)s people asking to join"
},
"release_announcement_description": "Enjoy a simpler, more accessible room header.",
"release_announcement_header": "New design!",
"room_is_public": "This room is public",
"show_widgets_button": "Show Widgets",
"video_call_button_ec": "Video call (%(brand)s)",
Expand Down
2 changes: 1 addition & 1 deletion src/stores/ReleaseAnnouncementStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { Features } from "../settings/Settings";
/**
* The features are shown in the array order.
*/
const FEATURES = ["threadsActivityCentre"] as const;
const FEATURES = ["threadsActivityCentre", "newRoomHeader"] as const;
/**
* All the features that can be shown in the release announcements.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ exports[`RoomHeader does not show the face pile for DMs 1`] = `
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x);"
>
<button
aria-expanded="false"
aria-haspopup="dialog"
aria-label="Room info"
class="mx_RoomHeader_infoWrapper"
tabindex="0"
Expand Down
17 changes: 10 additions & 7 deletions test/stores/ReleaseAnnouncementStore-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,18 @@ describe("ReleaseAnnouncementStore", () => {
// Sanity check
expect(releaseAnnouncementStore.getReleaseAnnouncement()).toBe("threadsActivityCentre");

const promise = listenReleaseAnnouncementChanged();
let promise = listenReleaseAnnouncementChanged();
await releaseAnnouncementStore.nextReleaseAnnouncement();

expect(await promise).toBe("newRoomHeader");
expect(releaseAnnouncementStore.getReleaseAnnouncement()).toBe("newRoomHeader");

promise = listenReleaseAnnouncementChanged();
await releaseAnnouncementStore.nextReleaseAnnouncement();
// Currently there is only one feature, so the next feature should be null
expect(await promise).toBeNull();
expect(releaseAnnouncementStore.getReleaseAnnouncement()).toBeNull();

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

// Currently there is only one feature, so the next feature should be null
expect(await promise).toBeNull();
expect(releaseAnnouncementStore.getReleaseAnnouncement()).toBeNull();
expect(await promise).toBe("newRoomHeader");
expect(releaseAnnouncementStore.getReleaseAnnouncement()).toBe("newRoomHeader");
});
});
Loading