mirror of
https://github.com/vector-im/element-web.git
synced 2026-01-14 21:11:19 +01:00
Update history visibility UX (#31635)
* Update history visibility UX * don't change voip strings
This commit is contained in:
parent
5d1cb24a6c
commit
05e7203f1b
@ -74,9 +74,7 @@ test.describe("Roles & Permissions room settings tab", () => {
|
||||
|
||||
await settingsGroupAccess.getByText("Private (invite only)").click();
|
||||
// Element should have automatically set the room to "sharing" history visibility
|
||||
await expect(
|
||||
settingsGroupHistory.getByText("Members only (since the point in time of selecting this option)"),
|
||||
).toBeChecked();
|
||||
await expect(settingsGroupHistory.getByText("Members (full history)")).toBeChecked();
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 82 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 90 KiB |
@ -419,36 +419,60 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
||||
const state = this.props.room.currentState;
|
||||
const canChangeHistory = state?.mayClientSendStateEvent(EventType.RoomHistoryVisibility, client);
|
||||
|
||||
const options = [
|
||||
{
|
||||
value: HistoryVisibility.Shared,
|
||||
label: _t("room_settings|security|history_visibility_shared"),
|
||||
},
|
||||
{
|
||||
// Map 'joined' to 'invited' for display purposes
|
||||
const displayHistory = history === HistoryVisibility.Joined ? HistoryVisibility.Invited : history;
|
||||
|
||||
const isPublicRoom = this.props.room.getJoinRule() === JoinRule.Public;
|
||||
const isEncrypted = this.state.encrypted;
|
||||
|
||||
const options: Array<{ value: HistoryVisibility; label: string }> = [];
|
||||
|
||||
// Show "invited" when room's join rule is NOT public OR E2EE is turned on, or if currently selected
|
||||
if (
|
||||
!isPublicRoom ||
|
||||
isEncrypted ||
|
||||
history === HistoryVisibility.Invited ||
|
||||
history === HistoryVisibility.Joined
|
||||
) {
|
||||
options.push({
|
||||
value: HistoryVisibility.Invited,
|
||||
label: _t("room_settings|security|history_visibility_invited"),
|
||||
},
|
||||
{
|
||||
value: HistoryVisibility.Joined,
|
||||
label: _t("room_settings|security|history_visibility_joined"),
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
// World readable doesn't make sense for encrypted rooms
|
||||
if (!this.state.encrypted || history === HistoryVisibility.WorldReadable) {
|
||||
options.unshift({
|
||||
// Always show "shared" option
|
||||
options.push({
|
||||
value: HistoryVisibility.Shared,
|
||||
label: _t("room_settings|security|history_visibility_shared"),
|
||||
});
|
||||
|
||||
// Show "world_readable" when (is public AND not encrypted) OR currently selected
|
||||
if ((isPublicRoom && !isEncrypted) || history === HistoryVisibility.WorldReadable) {
|
||||
options.push({
|
||||
value: HistoryVisibility.WorldReadable,
|
||||
label: _t("room_settings|security|history_visibility_world_readable"),
|
||||
});
|
||||
}
|
||||
|
||||
const description = _t("room_settings|security|history_visibility_warning");
|
||||
const description = (
|
||||
<>
|
||||
{_t(
|
||||
"room_settings|security|history_visibility_warning",
|
||||
{},
|
||||
{
|
||||
a: (sub) => (
|
||||
<ExternalLink href="https://element.io/en/help#e2ee-history-sharing">{sub}</ExternalLink>
|
||||
),
|
||||
},
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<SettingsFieldset legend={_t("room_settings|security|history_visibility_legend")} description={description}>
|
||||
<StyledRadioGroup
|
||||
name="historyVis"
|
||||
value={history}
|
||||
value={displayHistory}
|
||||
onChange={this.onHistoryRadioToggle}
|
||||
disabled={!canChangeHistory}
|
||||
definitions={options}
|
||||
|
||||
@ -2431,12 +2431,11 @@
|
||||
"error_join_rule_change_title": "Failed to update the join rules",
|
||||
"error_join_rule_change_unknown": "Unknown failure",
|
||||
"guest_access_warning": "People with supported clients will be able to join the room without having a registered account.",
|
||||
"history_visibility_invited": "Members only (since they were invited)",
|
||||
"history_visibility_joined": "Members only (since they joined)",
|
||||
"history_visibility_invited": "Members since invited",
|
||||
"history_visibility_legend": "Who can read history?",
|
||||
"history_visibility_shared": "Members only (since the point in time of selecting this option)",
|
||||
"history_visibility_warning": "The visibility of existing history will not be changed.",
|
||||
"history_visibility_world_readable": "Anyone",
|
||||
"history_visibility_shared": "Members (full history)",
|
||||
"history_visibility_warning": "Changes won't affect past messages, only new ones. <a>Learn more</a>",
|
||||
"history_visibility_world_readable": "Anyone (history is public)\n",
|
||||
"join_rule_description": "Decide who can join %(roomName)s.",
|
||||
"join_rule_invite": "Private (invite only)",
|
||||
"join_rule_invite_description": "Only invited people can join.",
|
||||
|
||||
@ -377,6 +377,76 @@ describe("<SecurityRoomSettingsTab />", () => {
|
||||
expect(screen.getByDisplayValue(HistoryVisibility.Shared)).toBeChecked();
|
||||
expect(logger.error).toHaveBeenCalledWith("oups");
|
||||
});
|
||||
|
||||
it("maps 'joined' history visibility to 'invited' for display", () => {
|
||||
const room = new Room(roomId, client, userId);
|
||||
setRoomStateEvents(room, undefined, undefined, HistoryVisibility.Joined);
|
||||
|
||||
getComponent(room);
|
||||
|
||||
// Should display as 'invited' even though underlying value is 'joined'
|
||||
expect(screen.getByDisplayValue(HistoryVisibility.Invited)).toBeChecked();
|
||||
// Should not have a 'joined' option visible
|
||||
expect(screen.queryByDisplayValue(HistoryVisibility.Joined)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows 'invited' option for non-public rooms", () => {
|
||||
const room = new Room(roomId, client, userId);
|
||||
setRoomStateEvents(room, JoinRule.Invite);
|
||||
|
||||
getComponent(room);
|
||||
|
||||
expect(screen.getByDisplayValue(HistoryVisibility.Invited)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows 'invited' option for encrypted rooms even if public", async () => {
|
||||
const room = new Room(roomId, client, userId);
|
||||
jest.spyOn(client.getCrypto()!, "isEncryptionEnabledInRoom").mockResolvedValue(true);
|
||||
setRoomStateEvents(room, JoinRule.Public);
|
||||
|
||||
getComponent(room);
|
||||
|
||||
await waitFor(() => expect(screen.getByDisplayValue(HistoryVisibility.Invited)).toBeInTheDocument());
|
||||
});
|
||||
|
||||
it("does not show 'invited' option for public unencrypted rooms unless selected", async () => {
|
||||
const room = new Room(roomId, client, userId);
|
||||
setRoomStateEvents(room, JoinRule.Public, undefined, HistoryVisibility.Shared);
|
||||
|
||||
getComponent(room);
|
||||
|
||||
await waitFor(() => expect(screen.queryByDisplayValue(HistoryVisibility.Invited)).not.toBeInTheDocument());
|
||||
});
|
||||
|
||||
it("shows 'world_readable' option for public unencrypted rooms", async () => {
|
||||
const room = new Room(roomId, client, userId);
|
||||
setRoomStateEvents(room, JoinRule.Public);
|
||||
|
||||
getComponent(room);
|
||||
|
||||
await waitFor(() => expect(screen.getByDisplayValue(HistoryVisibility.WorldReadable)).toBeInTheDocument());
|
||||
});
|
||||
|
||||
it("does not show 'world_readable' option for private encrypted rooms unless selected", async () => {
|
||||
const room = new Room(roomId, client, userId);
|
||||
jest.spyOn(client.getCrypto()!, "isEncryptionEnabledInRoom").mockResolvedValue(true);
|
||||
setRoomStateEvents(room, JoinRule.Invite);
|
||||
|
||||
getComponent(room);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(screen.queryByDisplayValue(HistoryVisibility.WorldReadable)).not.toBeInTheDocument(),
|
||||
);
|
||||
});
|
||||
|
||||
it("always shows 'shared' option", () => {
|
||||
const room = new Room(roomId, client, userId);
|
||||
setRoomStateEvents(room);
|
||||
|
||||
getComponent(room);
|
||||
|
||||
expect(screen.getByDisplayValue(HistoryVisibility.Shared)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe("encryption", () => {
|
||||
|
||||
@ -15,7 +15,32 @@ exports[`<SecurityRoomSettingsTab /> history visibility uses shared as default h
|
||||
<div
|
||||
class="mx_SettingsSubsection_text"
|
||||
>
|
||||
The visibility of existing history will not be changed.
|
||||
<span>
|
||||
Changes won't affect past messages, only new ones.
|
||||
<a
|
||||
class="mx_ExternalLink"
|
||||
href="https://element.io/en/help#e2ee-history-sharing"
|
||||
rel="noreferrer noopener"
|
||||
target="_blank"
|
||||
>
|
||||
Learn more
|
||||
<svg
|
||||
class="mx_ExternalLink_icon"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M5 3h6a1 1 0 1 1 0 2H5v14h14v-6a1 1 0 1 1 2 0v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2"
|
||||
/>
|
||||
<path
|
||||
d="M15 3h5a1 1 0 0 1 1 1v5a1 1 0 1 1-2 0V6.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L17.586 5H15a1 1 0 1 1 0-2"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@ -25,10 +50,10 @@ exports[`<SecurityRoomSettingsTab /> history visibility uses shared as default h
|
||||
class="mx_StyledRadioButton mx_StyledRadioButton_enabled"
|
||||
>
|
||||
<input
|
||||
id="historyVis-world_readable"
|
||||
id="historyVis-invited"
|
||||
name="historyVis"
|
||||
type="radio"
|
||||
value="world_readable"
|
||||
value="invited"
|
||||
/>
|
||||
<div>
|
||||
<div />
|
||||
@ -36,7 +61,7 @@ exports[`<SecurityRoomSettingsTab /> history visibility uses shared as default h
|
||||
<div
|
||||
class="mx_StyledRadioButton_content"
|
||||
>
|
||||
Anyone
|
||||
Members since invited
|
||||
</div>
|
||||
<div
|
||||
class="mx_StyledRadioButton_spacer"
|
||||
@ -58,49 +83,7 @@ exports[`<SecurityRoomSettingsTab /> history visibility uses shared as default h
|
||||
<div
|
||||
class="mx_StyledRadioButton_content"
|
||||
>
|
||||
Members only (since the point in time of selecting this option)
|
||||
</div>
|
||||
<div
|
||||
class="mx_StyledRadioButton_spacer"
|
||||
/>
|
||||
</label>
|
||||
<label
|
||||
class="mx_StyledRadioButton mx_StyledRadioButton_enabled"
|
||||
>
|
||||
<input
|
||||
id="historyVis-invited"
|
||||
name="historyVis"
|
||||
type="radio"
|
||||
value="invited"
|
||||
/>
|
||||
<div>
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
class="mx_StyledRadioButton_content"
|
||||
>
|
||||
Members only (since they were invited)
|
||||
</div>
|
||||
<div
|
||||
class="mx_StyledRadioButton_spacer"
|
||||
/>
|
||||
</label>
|
||||
<label
|
||||
class="mx_StyledRadioButton mx_StyledRadioButton_enabled"
|
||||
>
|
||||
<input
|
||||
id="historyVis-joined"
|
||||
name="historyVis"
|
||||
type="radio"
|
||||
value="joined"
|
||||
/>
|
||||
<div>
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
class="mx_StyledRadioButton_content"
|
||||
>
|
||||
Members only (since they joined)
|
||||
Members (full history)
|
||||
</div>
|
||||
<div
|
||||
class="mx_StyledRadioButton_spacer"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user