Skip to content
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
51 changes: 36 additions & 15 deletions src/components/views/rooms/RoomHeader/RoomHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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 (
<Tooltip label={_t("room|header|shared_history_tooltip")} placement="right">
<HistoryIcon
width="16px"
height="16px"
className="mx_RoomHeader_icon"
color="var(--cpd-color-icon-info-primary)"
aria-label={_t("room|header|shared_history_tooltip")}
/>
</Tooltip>
);
} else if (historyVisibility === HistoryVisibility.WorldReadable) {
return (
<Tooltip label={_t("room|header|world_readable_history_tooltip")} placement="right">
<UserProfileSolidIcon
width="16px"
height="16px"
className="mx_RoomHeader_icon"
color="var(--cpd-color-icon-info-primary)"
aria-label={_t("room|header|world_readable_history_tooltip")}
/>
</Tooltip>
);
} else {
return null;
}
}

export default function RoomHeader({
room,
additionalButtons,
Expand Down Expand Up @@ -490,20 +524,7 @@ export default function RoomHeader({
</Tooltip>
)}

{isRoomEncrypted &&
historySharingEnabled &&
(historyVisibility === HistoryVisibility.Shared ||
historyVisibility === HistoryVisibility.WorldReadable) && (
<Tooltip label={_t("room|header|shared_history_tooltip")} placement="right">
<HistoryIcon
width="16px"
height="16px"
className="mx_RoomHeader_icon"
color="var(--cpd-color-icon-info-primary)"
aria-label={_t("room|header|shared_history_tooltip")}
/>
</Tooltip>
)}
{isRoomEncrypted && historySharingEnabled && historyVisibilityIcon(historyVisibility)}
</Text>
</Box>
</button>
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this true? Unless it really means Anyone can see [undecryptable] history

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the explanation in the description. Specifically, @mxandreas said:

I would keep it simple and always communicate just the history visibility setting. Then, yes, there are cases where somebody can't actually see the history - because they did not join via invite, because they did not have keys because they were not part of room, etc. It is not feasible to put all of that on UI and expect users to understand that. The next best approach is that we have a FAQ that explain those cases if some of them become more popular.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having discussed this with the tea

/me pictures vdh talking to his pg tips

},
"header_avatar_open_settings_label": "Open room settings",
"header_face_pile_tooltip": "People",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(<RoomHeader room={room} />, getWrapper());
await waitFor(() => getByLabelText(document.body, "Anyone can see history"));
});

describe("dm", () => {
beforeEach(() => {
// Make the mocked room a DM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="_r_134_"
aria-labelledby="_r_13s_"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
Expand All @@ -83,7 +83,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
style="--cpd-icon-button-size: 100%;"
>
<svg
aria-labelledby="_r_139_"
aria-labelledby="_r_141_"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
Expand All @@ -98,7 +98,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
</button>
<button
aria-label="Threads"
aria-labelledby="_r_13e_"
aria-labelledby="_r_146_"
class="_icon-button_1215g_8"
data-kind="primary"
role="button"
Expand All @@ -125,7 +125,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
</button>
<button
aria-label="Room info"
aria-labelledby="_r_13j_"
aria-labelledby="_r_14b_"
class="_icon-button_1215g_8"
data-kind="primary"
role="button"
Expand Down
Loading