Skip to content

Commit af55def

Browse files
authored
Add badge for history visibiltity to room info panel (#31927)
* Add `HistoryVisibilityBadge` shared component * Add `historyVisibility` to `RoomSummaryCardViewModel` * Add a history visibility badge to the room info panel * Allow roominfo panel badges to wrap Now that we have an extra one, it's quite likely we'll have to spill onto more lines. * update screenshots * Set icons in badges to be 16px Having discussed this with the design team, the icons in badges should be 16px, not 13px, at default font size settings. * Add stories for all history visibility states * fix incorrect use of useRoomState * fix snapshots * more snapshot updates * Update screenshots
1 parent 9261527 commit af55def

File tree

19 files changed

+317
-18
lines changed

19 files changed

+317
-18
lines changed
Loading
Loading
Loading
Loading

packages/shared-components/src/i18n/strings/en_EN.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
"context_menu": {
3030
"title": "Room options"
3131
},
32+
"history_visibility_badge": {
33+
"private": "New members don't see history",
34+
"shared": "New members see history",
35+
"world_readable": "Anyone can see history"
36+
},
3237
"status_bar": {
3338
"delete_all": "Delete all",
3439
"exceeded_resource_limit_description": "Please contact your service administrator to continue using the service.",

packages/shared-components/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export * from "./message-body/ReactionsRowButtonTooltip";
2020
export * from "./pill-input/Pill";
2121
export * from "./pill-input/PillInput";
2222
export * from "./room/RoomStatusBar";
23+
export * from "./room/HistoryVisibilityBadge";
2324
export * from "./rich-list/RichItem";
2425
export * from "./rich-list/RichList";
2526
export * from "./room-list/RoomListHeaderView";
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) 2026 Element Creations Ltd.
3+
*
4+
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
5+
* Please see LICENSE files in the repository root for full details.
6+
*/
7+
8+
import type { Meta, StoryObj } from "@storybook/react-vite";
9+
import { HistoryVisibilityBadge } from "./HistoryVisibilityBadge";
10+
11+
const meta = {
12+
title: "Room/HistoryVisibilityBadge",
13+
component: HistoryVisibilityBadge,
14+
tags: ["autodocs"],
15+
parameters: {
16+
design: {
17+
type: "figma",
18+
url: "https://www.figma.com/design/IXcnmuaIwtm3F3vBuFCPUp/Room-History-Sharing?node-id=39-10758&t=MKC8KCGCpykDbrcX-1",
19+
},
20+
},
21+
} satisfies Meta<typeof HistoryVisibilityBadge>;
22+
23+
export default meta;
24+
25+
type Story = StoryObj<typeof meta>;
26+
export const InvitedHistoryVisibility: Story = { args: { historyVisibility: "invited" } };
27+
export const JoinedHistoryVisibility: Story = { args: { historyVisibility: "joined" } };
28+
export const SharedHistoryVisibility: Story = { args: { historyVisibility: "shared" } };
29+
export const WorldReadableHistoryVisibility: Story = { args: { historyVisibility: "world_readable" } };
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright (c) 2026 Element Creations Ltd.
3+
*
4+
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
5+
* Please see LICENSE files in the repository root for full details.
6+
*/
7+
8+
import React from "react";
9+
import { describe, expect, it } from "vitest";
10+
import { render } from "@testing-library/react";
11+
12+
import { HistoryVisibilityBadge } from "./HistoryVisibilityBadge.tsx";
13+
14+
describe("HistoryVisibilityBadge", () => {
15+
for (const visibility of ["invited", "joined", "shared", "world_readable"]) {
16+
it(`renders the badge for ${visibility}`, () => {
17+
const { container } = render(<HistoryVisibilityBadge historyVisibility={visibility as any} />);
18+
expect(container).toMatchSnapshot();
19+
});
20+
}
21+
});
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (c) 2026 Element Creations Ltd.
3+
*
4+
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
5+
* Please see LICENSE files in the repository root for full details.
6+
*/
7+
8+
import React, { type JSX } from "react";
9+
import { Badge } from "@vector-im/compound-web";
10+
import {
11+
HistoryIcon,
12+
UserProfileSolidIcon,
13+
VisibilityOffIcon,
14+
} from "@vector-im/compound-design-tokens/assets/web/icons";
15+
16+
import { _t } from "../../utils/i18n";
17+
18+
interface Props {
19+
/** The history visibility of the room, according to the room state. */
20+
historyVisibility: "invited" | "joined" | "shared" | "world_readable";
21+
}
22+
23+
/** A badge showing the history visibility of a room. */
24+
export function HistoryVisibilityBadge({ historyVisibility }: Props): JSX.Element | null {
25+
const iconProps = {
26+
color: "var(--cpd-color-icon-info-primary)",
27+
width: "1rem", // 16px at the default font size, per the design
28+
height: "1rem",
29+
};
30+
switch (historyVisibility) {
31+
case "invited":
32+
case "joined":
33+
return (
34+
<Badge kind="blue">
35+
<VisibilityOffIcon {...iconProps} />
36+
{_t("room|history_visibility_badge|private")}
37+
</Badge>
38+
);
39+
case "shared":
40+
return (
41+
<Badge kind="blue">
42+
<HistoryIcon {...iconProps} />
43+
{_t("room|history_visibility_badge|shared")}
44+
</Badge>
45+
);
46+
case "world_readable":
47+
return (
48+
<Badge kind="blue">
49+
<UserProfileSolidIcon {...iconProps} />
50+
{_t("room|history_visibility_badge|world_readable")}
51+
</Badge>
52+
);
53+
default:
54+
return null;
55+
}
56+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`HistoryVisibilityBadge > renders the badge for invited 1`] = `
4+
<div>
5+
<span
6+
class="_typography_6v6n8_153 _font-body-sm-medium_6v6n8_41 _badge_18gm1_8"
7+
data-kind="blue"
8+
>
9+
<svg
10+
color="var(--cpd-color-icon-info-primary)"
11+
fill="currentColor"
12+
height="1rem"
13+
viewBox="0 0 24 24"
14+
width="1rem"
15+
xmlns="http://www.w3.org/2000/svg"
16+
>
17+
<path
18+
d="m16.1 13.3-1.45-1.45q.225-1.175-.675-2.2t-2.325-.8L10.2 7.4q.424-.2.863-.3A4.2 4.2 0 0 1 12 7q1.875 0 3.188 1.312Q16.5 9.625 16.5 11.5q0 .5-.1.938t-.3.862m3.2 3.15-1.45-1.4a11 11 0 0 0 1.688-1.588A9 9 0 0 0 20.8 11.5q-1.25-2.524-3.588-4.013Q14.875 6 12 6q-.724 0-1.425.1a10 10 0 0 0-1.375.3L7.65 4.85A11.1 11.1 0 0 1 12 4q3.575 0 6.425 1.887T22.7 10.8a.8.8 0 0 1 .1.313q.025.188.025.387a2 2 0 0 1-.125.7 10.9 10.9 0 0 1-3.4 4.25m-.2 5.45-3.5-3.45q-.874.274-1.762.413Q12.95 19 12 19q-3.575 0-6.425-1.887T1.3 12.2a.8.8 0 0 1-.1-.312 3 3 0 0 1 0-.763.8.8 0 0 1 .1-.3Q1.825 9.7 2.55 8.75A13.3 13.3 0 0 1 4.15 7L2.075 4.9a.93.93 0 0 1-.275-.688q0-.412.3-.712a.95.95 0 0 1 .7-.275q.425 0 .7.275l17 17q.275.275.288.688a.93.93 0 0 1-.288.712.95.95 0 0 1-.7.275.95.95 0 0 1-.7-.275M5.55 8.4q-.725.65-1.325 1.425A9 9 0 0 0 3.2 11.5q1.25 2.524 3.588 4.012T12 17q.5 0 .975-.062.475-.063.975-.138l-.9-.95q-.274.075-.525.113A3.5 3.5 0 0 1 12 16q-1.875 0-3.187-1.312Q7.5 13.375 7.5 11.5q0-.274.038-.525.037-.25.112-.525z"
19+
/>
20+
</svg>
21+
New members don't see history
22+
</span>
23+
</div>
24+
`;
25+
26+
exports[`HistoryVisibilityBadge > renders the badge for joined 1`] = `
27+
<div>
28+
<span
29+
class="_typography_6v6n8_153 _font-body-sm-medium_6v6n8_41 _badge_18gm1_8"
30+
data-kind="blue"
31+
>
32+
<svg
33+
color="var(--cpd-color-icon-info-primary)"
34+
fill="currentColor"
35+
height="1rem"
36+
viewBox="0 0 24 24"
37+
width="1rem"
38+
xmlns="http://www.w3.org/2000/svg"
39+
>
40+
<path
41+
d="m16.1 13.3-1.45-1.45q.225-1.175-.675-2.2t-2.325-.8L10.2 7.4q.424-.2.863-.3A4.2 4.2 0 0 1 12 7q1.875 0 3.188 1.312Q16.5 9.625 16.5 11.5q0 .5-.1.938t-.3.862m3.2 3.15-1.45-1.4a11 11 0 0 0 1.688-1.588A9 9 0 0 0 20.8 11.5q-1.25-2.524-3.588-4.013Q14.875 6 12 6q-.724 0-1.425.1a10 10 0 0 0-1.375.3L7.65 4.85A11.1 11.1 0 0 1 12 4q3.575 0 6.425 1.887T22.7 10.8a.8.8 0 0 1 .1.313q.025.188.025.387a2 2 0 0 1-.125.7 10.9 10.9 0 0 1-3.4 4.25m-.2 5.45-3.5-3.45q-.874.274-1.762.413Q12.95 19 12 19q-3.575 0-6.425-1.887T1.3 12.2a.8.8 0 0 1-.1-.312 3 3 0 0 1 0-.763.8.8 0 0 1 .1-.3Q1.825 9.7 2.55 8.75A13.3 13.3 0 0 1 4.15 7L2.075 4.9a.93.93 0 0 1-.275-.688q0-.412.3-.712a.95.95 0 0 1 .7-.275q.425 0 .7.275l17 17q.275.275.288.688a.93.93 0 0 1-.288.712.95.95 0 0 1-.7.275.95.95 0 0 1-.7-.275M5.55 8.4q-.725.65-1.325 1.425A9 9 0 0 0 3.2 11.5q1.25 2.524 3.588 4.012T12 17q.5 0 .975-.062.475-.063.975-.138l-.9-.95q-.274.075-.525.113A3.5 3.5 0 0 1 12 16q-1.875 0-3.187-1.312Q7.5 13.375 7.5 11.5q0-.274.038-.525.037-.25.112-.525z"
42+
/>
43+
</svg>
44+
New members don't see history
45+
</span>
46+
</div>
47+
`;
48+
49+
exports[`HistoryVisibilityBadge > renders the badge for shared 1`] = `
50+
<div>
51+
<span
52+
class="_typography_6v6n8_153 _font-body-sm-medium_6v6n8_41 _badge_18gm1_8"
53+
data-kind="blue"
54+
>
55+
<svg
56+
color="var(--cpd-color-icon-info-primary)"
57+
fill="currentColor"
58+
height="1rem"
59+
viewBox="0 0 24 24"
60+
width="1rem"
61+
xmlns="http://www.w3.org/2000/svg"
62+
>
63+
<path
64+
d="M18.93 8A8 8 0 1 1 4 12a1 1 0 1 0-2 0c0 5.523 4.477 10 10 10s10-4.477 10-10a10 10 0 0 0-.832-4A10 10 0 0 0 12 2a9.99 9.99 0 0 0-8 3.999V4a1 1 0 0 0-2 0v4a1 1 0 0 0 1 1h4a1 1 0 0 0 0-2H5.755A7.99 7.99 0 0 1 12 4a8 8 0 0 1 6.93 4"
65+
/>
66+
<path
67+
d="M13 8a1 1 0 1 0-2 0v4a1 1 0 0 0 .293.707l2.83 2.83a1 1 0 0 0 1.414-1.414L13 11.586z"
68+
/>
69+
</svg>
70+
New members see history
71+
</span>
72+
</div>
73+
`;
74+
75+
exports[`HistoryVisibilityBadge > renders the badge for world_readable 1`] = `
76+
<div>
77+
<span
78+
class="_typography_6v6n8_153 _font-body-sm-medium_6v6n8_41 _badge_18gm1_8"
79+
data-kind="blue"
80+
>
81+
<svg
82+
color="var(--cpd-color-icon-info-primary)"
83+
fill="currentColor"
84+
height="1rem"
85+
viewBox="0 0 24 24"
86+
width="1rem"
87+
xmlns="http://www.w3.org/2000/svg"
88+
>
89+
<path
90+
d="M12 15q-1.65 0-2.825-1.175T8 11t1.175-2.825T12 7t2.825 1.175T16 11t-1.175 2.825T12 15"
91+
/>
92+
<path
93+
d="M19.528 18.583A9.96 9.96 0 0 0 22 12c0-5.523-4.477-10-10-10S2 6.477 2 12c0 2.52.933 4.824 2.472 6.583A9.98 9.98 0 0 0 12 22a9.98 9.98 0 0 0 7.528-3.417M8.75 16.388q-1.373.332-2.709.95a8 8 0 1 1 11.918 0 14.7 14.7 0 0 0-2.709-.95A13.8 13.8 0 0 0 12 16q-1.65 0-3.25.387"
94+
/>
95+
</svg>
96+
Anyone can see history
97+
</span>
98+
</div>
99+
`;

0 commit comments

Comments
 (0)