diff --git a/src/components/views/rooms/RoomHeader/RoomHeader.tsx b/src/components/views/rooms/RoomHeader/RoomHeader.tsx index 2434d5900e7..b6c00868000 100644 --- a/src/components/views/rooms/RoomHeader/RoomHeader.tsx +++ b/src/components/views/rooms/RoomHeader/RoomHeader.tsx @@ -22,7 +22,7 @@ import { HistoryVisibility, JoinRule, type Room } from "matrix-js-sdk/src/matrix import { type ViewRoomOpts } from "@matrix-org/react-sdk-module-api/lib/lifecycles/RoomViewLifecycle"; import { Flex, Box } from "@element-hq/web-shared-components"; import { CallType } from "matrix-js-sdk/src/webrtc/call"; -import { HistoryIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; +import { HistoryIcon, UserProfileSolidIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; import { useRoomName } from "../../../../hooks/useRoomName.ts"; import { RightPanelPhases } from "../../../../stores/right-panel/RightPanelStorePhases.ts"; @@ -391,6 +391,40 @@ function RoomHeaderButtons({ ); } +/** Create an icon to warn the user about shared history visibility, in encrypted rooms. + * + * Note that we use the same icon as in the room summary card and elsewhere, to aid user recognition. + */ +function historyVisibilityIcon(historyVisibility: HistoryVisibility): JSX.Element | null { + if (historyVisibility === HistoryVisibility.Shared) { + return ( + + + + ); + } else if (historyVisibility === HistoryVisibility.WorldReadable) { + return ( + + + + ); + } else { + return null; + } +} + export default function RoomHeader({ room, additionalButtons, @@ -490,20 +524,7 @@ export default function RoomHeader({ )} - {isRoomEncrypted && - historySharingEnabled && - (historyVisibility === HistoryVisibility.Shared || - historyVisibility === HistoryVisibility.WorldReadable) && ( - - - - )} + {isRoomEncrypted && historySharingEnabled && historyVisibilityIcon(historyVisibility)} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 03989ab9eaa..c9e5e1e0281 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2032,7 +2032,8 @@ "other": "%(count)s people asking to join" }, "room_is_public": "This room is public", - "shared_history_tooltip": "New members see history" + "shared_history_tooltip": "New members see history", + "world_readable_history_tooltip": "Anyone can see history" }, "header_avatar_open_settings_label": "Open room settings", "header_face_pile_tooltip": "People", diff --git a/test/unit-tests/components/views/rooms/RoomHeader/RoomHeader-test.tsx b/test/unit-tests/components/views/rooms/RoomHeader/RoomHeader-test.tsx index 7c1b5429cdc..7de539ed545 100644 --- a/test/unit-tests/components/views/rooms/RoomHeader/RoomHeader-test.tsx +++ b/test/unit-tests/components/views/rooms/RoomHeader/RoomHeader-test.tsx @@ -744,6 +744,29 @@ describe("RoomHeader", () => { expect(queryByLabelText(document.body, "New members see history")).not.toBeInTheDocument(); }); + it("shows a user icon if the room is encrypted and has world readable history", async () => { + mocked(client.getCrypto()!).isEncryptionEnabledInRoom.mockResolvedValue(true); + await room.addLiveEvents( + [ + new MatrixEvent({ + type: "m.room.history_visibility", + content: { history_visibility: "world_readable" }, + sender: MatrixClientPeg.get()!.getSafeUserId(), + state_key: "", + room_id: room.roomId, + }), + ], + { addToState: true }, + ); + const featureEnabled = true; + jest.spyOn(SettingsStore, "getValue").mockImplementation( + (flag) => flag === "feature_share_history_on_invite" && featureEnabled, + ); + + render(, getWrapper()); + await waitFor(() => getByLabelText(document.body, "Anyone can see history")); + }); + describe("dm", () => { beforeEach(() => { // Make the mocked room a DM diff --git a/test/unit-tests/components/views/rooms/RoomHeader/__snapshots__/RoomHeader-test.tsx.snap b/test/unit-tests/components/views/rooms/RoomHeader/__snapshots__/RoomHeader-test.tsx.snap index 404edd3c6aa..e3ff02aeaf2 100644 --- a/test/unit-tests/components/views/rooms/RoomHeader/__snapshots__/RoomHeader-test.tsx.snap +++ b/test/unit-tests/components/views/rooms/RoomHeader/__snapshots__/RoomHeader-test.tsx.snap @@ -56,7 +56,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = ` style="--cpd-icon-button-size: 100%;" >