Use semantic headings for room settings content (#10734)
* split SettingsSection out of SettingsTab, replace usage * correct copyright * use semantic headings in GeneralRoomSettingsTab * use SettingsTab and SettingsSubsection in room settings * fix VoipRoomSettingsTab
This commit is contained in:
parent
e7f5261eda
commit
4736f0e44c
12 changed files with 439 additions and 380 deletions
|
@ -103,5 +103,5 @@ limitations under the License.
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
grid-gap: $spacing-32;
|
grid-gap: $spacing-32;
|
||||||
|
|
||||||
padding: $spacing-16 0;
|
padding-bottom: $spacing-16;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_RolesRoomSettingsTab ul {
|
.mx_RolesRoomSettingsTab_bannedList {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,14 +14,12 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_SecurityRoomSettingsTab {
|
.mx_SecurityRoomSettingsTab_advancedSection {
|
||||||
.mx_SettingsTab_showAdvanced {
|
margin-top: $spacing-16;
|
||||||
margin-bottom: $spacing-16;
|
}
|
||||||
}
|
|
||||||
|
.mx_SecurityRoomSettingsTab_warning {
|
||||||
.mx_SecurityRoomSettingsTab_warning {
|
display: flex;
|
||||||
display: flex;
|
align-items: center;
|
||||||
align-items: center;
|
column-gap: $spacing-4;
|
||||||
column-gap: $spacing-4;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,9 @@ import { Action } from "../../../../../dispatcher/actions";
|
||||||
import CopyableText from "../../../elements/CopyableText";
|
import CopyableText from "../../../elements/CopyableText";
|
||||||
import { ViewRoomPayload } from "../../../../../dispatcher/payloads/ViewRoomPayload";
|
import { ViewRoomPayload } from "../../../../../dispatcher/payloads/ViewRoomPayload";
|
||||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||||
|
import SettingsTab from "../SettingsTab";
|
||||||
|
import { SettingsSection } from "../../shared/SettingsSection";
|
||||||
|
import SettingsSubsection from "../../shared/SettingsSubsection";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
room: Room;
|
room: Room;
|
||||||
|
@ -154,30 +157,27 @@ export default class AdvancedRoomSettingsTab extends React.Component<IProps, ISt
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_SettingsTab">
|
<SettingsTab>
|
||||||
<div className="mx_SettingsTab_heading">{_t("Advanced")}</div>
|
<SettingsSection heading={_t("Advanced")}>
|
||||||
<div className="mx_SettingsTab_section mx_SettingsTab_subsectionText">
|
<SettingsSubsection heading={room.isSpaceRoom() ? _t("Space information") : _t("Room information")}>
|
||||||
<span className="mx_SettingsTab_subheading">
|
<div>
|
||||||
{room.isSpaceRoom() ? _t("Space information") : _t("Room information")}
|
<span>{_t("Internal room ID")}</span>
|
||||||
</span>
|
<CopyableText getTextToCopy={() => this.props.room.roomId}>
|
||||||
<div>
|
{this.props.room.roomId}
|
||||||
<span>{_t("Internal room ID")}</span>
|
</CopyableText>
|
||||||
<CopyableText getTextToCopy={() => this.props.room.roomId}>
|
</div>
|
||||||
{this.props.room.roomId}
|
{unfederatableSection}
|
||||||
</CopyableText>
|
</SettingsSubsection>
|
||||||
</div>
|
<SettingsSubsection heading={_t("Room version")}>
|
||||||
{unfederatableSection}
|
<div>
|
||||||
</div>
|
<span>{_t("Room version:")}</span>
|
||||||
<div className="mx_SettingsTab_section mx_SettingsTab_subsectionText">
|
{room.getVersion()}
|
||||||
<span className="mx_SettingsTab_subheading">{_t("Room version")}</span>
|
</div>
|
||||||
<div>
|
{oldRoomLink}
|
||||||
<span>{_t("Room version:")}</span>
|
{roomUpgradeButton}
|
||||||
{room.getVersion()}
|
</SettingsSubsection>
|
||||||
</div>
|
</SettingsSection>
|
||||||
{oldRoomLink}
|
</SettingsTab>
|
||||||
{roomUpgradeButton}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
import { _t } from "../../../../../languageHandler";
|
import { _t } from "../../../../../languageHandler";
|
||||||
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
||||||
import BridgeTile from "../../BridgeTile";
|
import BridgeTile from "../../BridgeTile";
|
||||||
|
import SettingsTab from "../SettingsTab";
|
||||||
|
import { SettingsSection } from "../../shared/SettingsSection";
|
||||||
|
|
||||||
const BRIDGE_EVENT_TYPES = [
|
const BRIDGE_EVENT_TYPES = [
|
||||||
"uk.half-shot.bridge",
|
"uk.half-shot.bridge",
|
||||||
|
@ -99,10 +101,9 @@ export default class BridgeSettingsTab extends React.Component<IProps> {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_SettingsTab">
|
<SettingsTab>
|
||||||
<div className="mx_SettingsTab_heading">{_t("Bridges")}</div>
|
<SettingsSection heading={_t("Bridges")}>{content}</SettingsSection>
|
||||||
<div className="mx_SettingsTab_section mx_SettingsTab_subsectionText">{content}</div>
|
</SettingsTab>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,9 @@ import { UIFeature } from "../../../../../settings/UIFeature";
|
||||||
import UrlPreviewSettings from "../../../room_settings/UrlPreviewSettings";
|
import UrlPreviewSettings from "../../../room_settings/UrlPreviewSettings";
|
||||||
import AliasSettings from "../../../room_settings/AliasSettings";
|
import AliasSettings from "../../../room_settings/AliasSettings";
|
||||||
import PosthogTrackers from "../../../../../PosthogTrackers";
|
import PosthogTrackers from "../../../../../PosthogTrackers";
|
||||||
|
import SettingsSubsection from "../../shared/SettingsSubsection";
|
||||||
|
import SettingsTab from "../SettingsTab";
|
||||||
|
import { SettingsSection } from "../../shared/SettingsSection";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
room: Room;
|
room: Room;
|
||||||
|
@ -72,35 +75,36 @@ export default class GeneralRoomSettingsTab extends React.Component<IProps, ISta
|
||||||
let leaveSection;
|
let leaveSection;
|
||||||
if (room.getMyMembership() === "join") {
|
if (room.getMyMembership() === "join") {
|
||||||
leaveSection = (
|
leaveSection = (
|
||||||
<>
|
<SettingsSubsection heading={_t("Leave room")}>
|
||||||
<span className="mx_SettingsTab_subheading">{_t("Leave room")}</span>
|
<AccessibleButton kind="danger" onClick={this.onLeaveClick}>
|
||||||
<div className="mx_SettingsTab_section">
|
{_t("Leave room")}
|
||||||
<AccessibleButton kind="danger" onClick={this.onLeaveClick}>
|
</AccessibleButton>
|
||||||
{_t("Leave room")}
|
</SettingsSubsection>
|
||||||
</AccessibleButton>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_SettingsTab mx_GeneralRoomSettingsTab">
|
<SettingsTab>
|
||||||
<div className="mx_SettingsTab_heading">{_t("General")}</div>
|
<SettingsSection heading={_t("General")}>
|
||||||
<div className="mx_SettingsTab_section mx_GeneralRoomSettingsTab_profileSection">
|
<div className="mx_SettingsTab_section mx_GeneralRoomSettingsTab_profileSection">
|
||||||
<RoomProfileSettings roomId={room.roomId} />
|
<RoomProfileSettings roomId={room.roomId} />
|
||||||
</div>
|
</div>
|
||||||
|
</SettingsSection>
|
||||||
|
|
||||||
<div className="mx_SettingsTab_heading">{_t("Room Addresses")}</div>
|
<SettingsSection heading={_t("Room Addresses")}>
|
||||||
<AliasSettings
|
<AliasSettings
|
||||||
roomId={room.roomId}
|
roomId={room.roomId}
|
||||||
canSetCanonicalAlias={canSetCanonical}
|
canSetCanonicalAlias={canSetCanonical}
|
||||||
canSetAliases={canSetAliases}
|
canSetAliases={canSetAliases}
|
||||||
canonicalAliasEvent={canonicalAliasEv}
|
canonicalAliasEvent={canonicalAliasEv}
|
||||||
/>
|
/>
|
||||||
<div className="mx_SettingsTab_heading">{_t("Other")}</div>
|
</SettingsSection>
|
||||||
{urlPreviewSettings}
|
|
||||||
{leaveSection}
|
<SettingsSection heading={_t("Other")}>
|
||||||
</div>
|
{urlPreviewSettings}
|
||||||
|
{leaveSection}
|
||||||
|
</SettingsSection>
|
||||||
|
</SettingsTab>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,9 @@ import defaultDispatcher from "../../../../../dispatcher/dispatcher";
|
||||||
import { Action } from "../../../../../dispatcher/actions";
|
import { Action } from "../../../../../dispatcher/actions";
|
||||||
import { UserTab } from "../../../dialogs/UserTab";
|
import { UserTab } from "../../../dialogs/UserTab";
|
||||||
import { chromeFileInputFix } from "../../../../../utils/BrowserWorkarounds";
|
import { chromeFileInputFix } from "../../../../../utils/BrowserWorkarounds";
|
||||||
|
import SettingsTab from "../SettingsTab";
|
||||||
|
import { SettingsSection } from "../../shared/SettingsSection";
|
||||||
|
import SettingsSubsection from "../../shared/SettingsSubsection";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
roomId: string;
|
roomId: string;
|
||||||
|
@ -168,149 +171,148 @@ export default class NotificationsSettingsTab extends React.Component<IProps, IS
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_SettingsTab">
|
<SettingsTab>
|
||||||
<div className="mx_SettingsTab_heading">{_t("Notifications")}</div>
|
<SettingsSection heading={_t("Notifications")}>
|
||||||
|
<div className="mx_NotificationSettingsTab_notificationsSection">
|
||||||
<div className="mx_SettingsTab_section mx_NotificationSettingsTab_notificationsSection">
|
<StyledRadioGroup
|
||||||
<StyledRadioGroup
|
name="roomNotificationSetting"
|
||||||
name="roomNotificationSetting"
|
definitions={[
|
||||||
definitions={[
|
{
|
||||||
{
|
value: RoomNotifState.AllMessages,
|
||||||
value: RoomNotifState.AllMessages,
|
className: "mx_NotificationSettingsTab_defaultEntry",
|
||||||
className: "mx_NotificationSettingsTab_defaultEntry",
|
label: (
|
||||||
label: (
|
<>
|
||||||
<>
|
{_t("Default")}
|
||||||
{_t("Default")}
|
<div className="mx_NotificationSettingsTab_microCopy">
|
||||||
<div className="mx_NotificationSettingsTab_microCopy">
|
{_t(
|
||||||
{_t(
|
"Get notifications as set up in your <a>settings</a>",
|
||||||
"Get notifications as set up in your <a>settings</a>",
|
{},
|
||||||
{},
|
{
|
||||||
{
|
a: (sub) => (
|
||||||
a: (sub) => (
|
<AccessibleButton
|
||||||
<AccessibleButton
|
kind="link_inline"
|
||||||
kind="link_inline"
|
onClick={this.onOpenSettingsClick}
|
||||||
onClick={this.onOpenSettingsClick}
|
>
|
||||||
>
|
{sub}
|
||||||
{sub}
|
</AccessibleButton>
|
||||||
</AccessibleButton>
|
),
|
||||||
),
|
},
|
||||||
},
|
)}
|
||||||
)}
|
</div>
|
||||||
</div>
|
</>
|
||||||
</>
|
),
|
||||||
),
|
},
|
||||||
},
|
{
|
||||||
{
|
value: RoomNotifState.AllMessagesLoud,
|
||||||
value: RoomNotifState.AllMessagesLoud,
|
className: "mx_NotificationSettingsTab_allMessagesEntry",
|
||||||
className: "mx_NotificationSettingsTab_allMessagesEntry",
|
label: (
|
||||||
label: (
|
<>
|
||||||
<>
|
{_t("All messages")}
|
||||||
{_t("All messages")}
|
<div className="mx_NotificationSettingsTab_microCopy">
|
||||||
<div className="mx_NotificationSettingsTab_microCopy">
|
{_t("Get notified for every message")}
|
||||||
{_t("Get notified for every message")}
|
</div>
|
||||||
</div>
|
</>
|
||||||
</>
|
),
|
||||||
),
|
},
|
||||||
},
|
{
|
||||||
{
|
value: RoomNotifState.MentionsOnly,
|
||||||
value: RoomNotifState.MentionsOnly,
|
className: "mx_NotificationSettingsTab_mentionsKeywordsEntry",
|
||||||
className: "mx_NotificationSettingsTab_mentionsKeywordsEntry",
|
label: (
|
||||||
label: (
|
<>
|
||||||
<>
|
{_t("@mentions & keywords")}
|
||||||
{_t("@mentions & keywords")}
|
<div className="mx_NotificationSettingsTab_microCopy">
|
||||||
<div className="mx_NotificationSettingsTab_microCopy">
|
{_t(
|
||||||
{_t(
|
"Get notified only with mentions and keywords " +
|
||||||
"Get notified only with mentions and keywords " +
|
"as set up in your <a>settings</a>",
|
||||||
"as set up in your <a>settings</a>",
|
{},
|
||||||
{},
|
{
|
||||||
{
|
a: (sub) => (
|
||||||
a: (sub) => (
|
<AccessibleButton
|
||||||
<AccessibleButton
|
kind="link_inline"
|
||||||
kind="link_inline"
|
onClick={this.onOpenSettingsClick}
|
||||||
onClick={this.onOpenSettingsClick}
|
>
|
||||||
>
|
{sub}
|
||||||
{sub}
|
</AccessibleButton>
|
||||||
</AccessibleButton>
|
),
|
||||||
),
|
},
|
||||||
},
|
)}
|
||||||
)}
|
</div>
|
||||||
</div>
|
</>
|
||||||
</>
|
),
|
||||||
),
|
},
|
||||||
},
|
{
|
||||||
{
|
value: RoomNotifState.Mute,
|
||||||
value: RoomNotifState.Mute,
|
className: "mx_NotificationSettingsTab_noneEntry",
|
||||||
className: "mx_NotificationSettingsTab_noneEntry",
|
label: (
|
||||||
label: (
|
<>
|
||||||
<>
|
{_t("Off")}
|
||||||
{_t("Off")}
|
<div className="mx_NotificationSettingsTab_microCopy">
|
||||||
<div className="mx_NotificationSettingsTab_microCopy">
|
{_t("You won't get any notifications")}
|
||||||
{_t("You won't get any notifications")}
|
</div>
|
||||||
</div>
|
</>
|
||||||
</>
|
),
|
||||||
),
|
},
|
||||||
},
|
]}
|
||||||
]}
|
onChange={this.onRoomNotificationChange}
|
||||||
onChange={this.onRoomNotificationChange}
|
value={this.roomProps.notificationVolume}
|
||||||
value={this.roomProps.notificationVolume}
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mx_SettingsTab_section mx_SettingsTab_subsectionText">
|
|
||||||
<span className="mx_SettingsTab_subheading">{_t("Sounds")}</span>
|
|
||||||
<div>
|
|
||||||
<div className="mx_SettingsTab_subsectionText">
|
|
||||||
<span>
|
|
||||||
{_t("Notification sound")}: <code>{this.state.currentSound}</code>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<AccessibleButton
|
|
||||||
className="mx_NotificationSound_resetSound"
|
|
||||||
disabled={this.state.currentSound == "default"}
|
|
||||||
onClick={this.clearSound}
|
|
||||||
kind="primary"
|
|
||||||
>
|
|
||||||
{_t("Reset")}
|
|
||||||
</AccessibleButton>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<h3>{_t("Set a new custom sound")}</h3>
|
|
||||||
<div className="mx_SettingsFlag">
|
|
||||||
<form autoComplete="off" noValidate={true}>
|
|
||||||
<input
|
|
||||||
ref={this.soundUpload}
|
|
||||||
className="mx_NotificationSound_soundUpload"
|
|
||||||
type="file"
|
|
||||||
onClick={chromeFileInputFix}
|
|
||||||
onChange={this.onSoundUploadChanged}
|
|
||||||
accept="audio/*"
|
|
||||||
aria-label={_t("Upload custom sound")}
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{currentUploadedFile}
|
<SettingsSubsection heading={_t("Sounds")}>
|
||||||
|
<div>
|
||||||
|
<div className="mx_SettingsTab_subsectionText">
|
||||||
|
<span>
|
||||||
|
{_t("Notification sound")}: <code>{this.state.currentSound}</code>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<AccessibleButton
|
||||||
|
className="mx_NotificationSound_resetSound"
|
||||||
|
disabled={this.state.currentSound == "default"}
|
||||||
|
onClick={this.clearSound}
|
||||||
|
kind="primary"
|
||||||
|
>
|
||||||
|
{_t("Reset")}
|
||||||
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>{_t("Set a new custom sound")}</h4>
|
||||||
|
<div className="mx_SettingsFlag">
|
||||||
|
<form autoComplete="off" noValidate={true}>
|
||||||
|
<input
|
||||||
|
ref={this.soundUpload}
|
||||||
|
className="mx_NotificationSound_soundUpload"
|
||||||
|
type="file"
|
||||||
|
onClick={chromeFileInputFix}
|
||||||
|
onChange={this.onSoundUploadChanged}
|
||||||
|
accept="audio/*"
|
||||||
|
aria-label={_t("Upload custom sound")}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
|
||||||
<AccessibleButton
|
{currentUploadedFile}
|
||||||
className="mx_NotificationSound_browse"
|
</div>
|
||||||
onClick={this.triggerUploader}
|
|
||||||
kind="primary"
|
|
||||||
>
|
|
||||||
{_t("Browse")}
|
|
||||||
</AccessibleButton>
|
|
||||||
|
|
||||||
<AccessibleButton
|
<AccessibleButton
|
||||||
className="mx_NotificationSound_save"
|
className="mx_NotificationSound_browse"
|
||||||
disabled={this.state.uploadedFile == null}
|
onClick={this.triggerUploader}
|
||||||
onClick={this.onClickSaveSound}
|
kind="primary"
|
||||||
kind="primary"
|
>
|
||||||
>
|
{_t("Browse")}
|
||||||
{_t("Save")}
|
</AccessibleButton>
|
||||||
</AccessibleButton>
|
|
||||||
<br />
|
<AccessibleButton
|
||||||
</div>
|
className="mx_NotificationSound_save"
|
||||||
</div>
|
disabled={this.state.uploadedFile == null}
|
||||||
</div>
|
onClick={this.onClickSaveSound}
|
||||||
|
kind="primary"
|
||||||
|
>
|
||||||
|
{_t("Save")}
|
||||||
|
</AccessibleButton>
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
</SettingsSubsection>
|
||||||
|
</SettingsSection>
|
||||||
|
</SettingsTab>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,8 @@ import { VoiceBroadcastInfoEventType } from "../../../../../voice-broadcast";
|
||||||
import { ElementCall } from "../../../../../models/Call";
|
import { ElementCall } from "../../../../../models/Call";
|
||||||
import SdkConfig, { DEFAULTS } from "../../../../../SdkConfig";
|
import SdkConfig, { DEFAULTS } from "../../../../../SdkConfig";
|
||||||
import { AddPrivilegedUsers } from "../../AddPrivilegedUsers";
|
import { AddPrivilegedUsers } from "../../AddPrivilegedUsers";
|
||||||
|
import SettingsTab from "../SettingsTab";
|
||||||
|
import { SettingsSection } from "../../shared/SettingsSection";
|
||||||
|
|
||||||
interface IEventShowOpts {
|
interface IEventShowOpts {
|
||||||
isState?: boolean;
|
isState?: boolean;
|
||||||
|
@ -399,7 +401,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
|
||||||
const canBanUsers = currentUserLevel >= banLevel;
|
const canBanUsers = currentUserLevel >= banLevel;
|
||||||
bannedUsersSection = (
|
bannedUsersSection = (
|
||||||
<SettingsFieldset legend={_t("Banned users")}>
|
<SettingsFieldset legend={_t("Banned users")}>
|
||||||
<ul>
|
<ul className="mx_RolesRoomSettingsTab_bannedList">
|
||||||
{banned.map((member) => {
|
{banned.map((member) => {
|
||||||
const banEvent = member.events.member?.getContent();
|
const banEvent = member.events.member?.getContent();
|
||||||
const bannedById = member.events.member?.getSender();
|
const bannedById = member.events.member?.getSender();
|
||||||
|
@ -479,24 +481,25 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_SettingsTab mx_RolesRoomSettingsTab">
|
<SettingsTab>
|
||||||
<div className="mx_SettingsTab_heading">{_t("Roles & Permissions")}</div>
|
<SettingsSection heading={_t("Roles & Permissions")}>
|
||||||
{privilegedUsersSection}
|
{privilegedUsersSection}
|
||||||
{canChangeLevels && <AddPrivilegedUsers room={room} defaultUserLevel={defaultUserLevel} />}
|
{canChangeLevels && <AddPrivilegedUsers room={room} defaultUserLevel={defaultUserLevel} />}
|
||||||
{mutedUsersSection}
|
{mutedUsersSection}
|
||||||
{bannedUsersSection}
|
{bannedUsersSection}
|
||||||
<SettingsFieldset
|
<SettingsFieldset
|
||||||
legend={_t("Permissions")}
|
legend={_t("Permissions")}
|
||||||
description={
|
description={
|
||||||
isSpaceRoom
|
isSpaceRoom
|
||||||
? _t("Select the roles required to change various parts of the space")
|
? _t("Select the roles required to change various parts of the space")
|
||||||
: _t("Select the roles required to change various parts of the room")
|
: _t("Select the roles required to change various parts of the room")
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{powerSelectors}
|
{powerSelectors}
|
||||||
{eventPowerSelectors}
|
{eventPowerSelectors}
|
||||||
</SettingsFieldset>
|
</SettingsFieldset>
|
||||||
</div>
|
</SettingsSection>
|
||||||
|
</SettingsTab>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,8 @@ import SettingsFieldset from "../../SettingsFieldset";
|
||||||
import ExternalLink from "../../../elements/ExternalLink";
|
import ExternalLink from "../../../elements/ExternalLink";
|
||||||
import PosthogTrackers from "../../../../../PosthogTrackers";
|
import PosthogTrackers from "../../../../../PosthogTrackers";
|
||||||
import MatrixClientContext from "../../../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../../../contexts/MatrixClientContext";
|
||||||
|
import { SettingsSection } from "../../shared/SettingsSection";
|
||||||
|
import SettingsTab from "../SettingsTab";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
room: Room;
|
room: Room;
|
||||||
|
@ -265,6 +267,23 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
||||||
roomName: room.name,
|
roomName: room.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let advanced: JSX.Element | undefined;
|
||||||
|
if (room.getJoinRule() === JoinRule.Public) {
|
||||||
|
advanced = (
|
||||||
|
<div>
|
||||||
|
<AccessibleButton
|
||||||
|
onClick={this.toggleAdvancedSection}
|
||||||
|
kind="link"
|
||||||
|
className="mx_SettingsTab_showAdvanced"
|
||||||
|
aria-expanded={this.state.showAdvancedSection}
|
||||||
|
>
|
||||||
|
{this.state.showAdvancedSection ? _t("Hide advanced") : _t("Show advanced")}
|
||||||
|
</AccessibleButton>
|
||||||
|
{this.state.showAdvancedSection && this.renderAdvanced()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingsFieldset legend={_t("Access")} description={description}>
|
<SettingsFieldset legend={_t("Access")} description={description}>
|
||||||
<JoinRuleSettings
|
<JoinRuleSettings
|
||||||
|
@ -275,6 +294,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
||||||
promptUpgrade={true}
|
promptUpgrade={true}
|
||||||
aliasWarning={aliasWarning}
|
aliasWarning={aliasWarning}
|
||||||
/>
|
/>
|
||||||
|
{advanced}
|
||||||
</SettingsFieldset>
|
</SettingsFieldset>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -399,7 +419,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
||||||
const canSetGuestAccess = state?.mayClientSendStateEvent(EventType.RoomGuestAccess, client);
|
const canSetGuestAccess = state?.mayClientSendStateEvent(EventType.RoomGuestAccess, client);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="mx_SecurityRoomSettingsTab_advancedSection">
|
||||||
<LabelledToggleSwitch
|
<LabelledToggleSwitch
|
||||||
value={guestAccess === GuestAccess.CanJoin}
|
value={guestAccess === GuestAccess.CanJoin}
|
||||||
onChange={this.onGuestAccessChange}
|
onChange={this.onGuestAccessChange}
|
||||||
|
@ -412,7 +432,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
||||||
"the room without having a registered account.",
|
"the room without having a registered account.",
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,45 +457,30 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
||||||
|
|
||||||
const historySection = this.renderHistory();
|
const historySection = this.renderHistory();
|
||||||
|
|
||||||
let advanced: JSX.Element | undefined;
|
|
||||||
if (room.getJoinRule() === JoinRule.Public) {
|
|
||||||
advanced = (
|
|
||||||
<div className="mx_SettingsTab_section">
|
|
||||||
<AccessibleButton
|
|
||||||
onClick={this.toggleAdvancedSection}
|
|
||||||
kind="link"
|
|
||||||
className="mx_SettingsTab_showAdvanced"
|
|
||||||
aria-expanded={this.state.showAdvancedSection}
|
|
||||||
>
|
|
||||||
{this.state.showAdvancedSection ? _t("Hide advanced") : _t("Show advanced")}
|
|
||||||
</AccessibleButton>
|
|
||||||
{this.state.showAdvancedSection && this.renderAdvanced()}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_SettingsTab mx_SecurityRoomSettingsTab">
|
<SettingsTab>
|
||||||
<div className="mx_SettingsTab_heading">{_t("Security & Privacy")}</div>
|
<SettingsSection heading={_t("Security & Privacy")}>
|
||||||
|
<SettingsFieldset
|
||||||
|
legend={_t("Encryption")}
|
||||||
|
description={_t("Once enabled, encryption cannot be disabled.")}
|
||||||
|
>
|
||||||
|
<LabelledToggleSwitch
|
||||||
|
value={isEncrypted}
|
||||||
|
onChange={this.onEncryptionChange}
|
||||||
|
label={_t("Encrypted")}
|
||||||
|
disabled={!canEnableEncryption}
|
||||||
|
/>
|
||||||
|
{encryptionSettings}
|
||||||
|
</SettingsFieldset>
|
||||||
|
|
||||||
<SettingsFieldset
|
{this.renderJoinRule()}
|
||||||
legend={_t("Encryption")}
|
{historySection}
|
||||||
description={_t("Once enabled, encryption cannot be disabled.")}
|
</SettingsSection>
|
||||||
>
|
</SettingsTab>
|
||||||
<LabelledToggleSwitch
|
// <div className="mx_SettingsTab mx_SecurityRoomSettingsTab">
|
||||||
value={isEncrypted}
|
// <div className="mx_SettingsTab_heading">{_t("Security & Privacy")}</div>
|
||||||
onChange={this.onEncryptionChange}
|
|
||||||
label={_t("Encrypted")}
|
|
||||||
disabled={!canEnableEncryption}
|
|
||||||
/>
|
|
||||||
{encryptionSettings}
|
|
||||||
</SettingsFieldset>
|
|
||||||
|
|
||||||
{this.renderJoinRule()}
|
// </div>
|
||||||
|
|
||||||
{advanced}
|
|
||||||
{historySection}
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,50 +6,78 @@ exports[`AdvancedRoomSettingsTab should render as expected 1`] = `
|
||||||
class="mx_SettingsTab"
|
class="mx_SettingsTab"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsTab_heading"
|
class="mx_SettingsTab_sections"
|
||||||
>
|
>
|
||||||
Advanced
|
<div
|
||||||
</div>
|
class="mx_SettingsSection"
|
||||||
<div
|
|
||||||
class="mx_SettingsTab_section mx_SettingsTab_subsectionText"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="mx_SettingsTab_subheading"
|
|
||||||
>
|
>
|
||||||
Room information
|
<h2
|
||||||
</span>
|
class="mx_Heading_h2"
|
||||||
<div>
|
>
|
||||||
<span>
|
Advanced
|
||||||
Internal room ID
|
</h2>
|
||||||
</span>
|
<div
|
||||||
<div
|
class="mx_SettingsSection_subSections"
|
||||||
class="mx_CopyableText mx_CopyableText_border"
|
|
||||||
>
|
>
|
||||||
!room:example.com
|
|
||||||
<div
|
<div
|
||||||
aria-label="Copy"
|
class="mx_SettingsSubsection"
|
||||||
class="mx_AccessibleButton mx_CopyableText_copyButton"
|
>
|
||||||
role="button"
|
<div
|
||||||
tabindex="0"
|
class="mx_SettingsSubsectionHeading"
|
||||||
/>
|
>
|
||||||
|
<h3
|
||||||
|
class="mx_Heading_h3 mx_SettingsSubsectionHeading_heading"
|
||||||
|
>
|
||||||
|
Room information
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSubsection_content"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<span>
|
||||||
|
Internal room ID
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
class="mx_CopyableText mx_CopyableText_border"
|
||||||
|
>
|
||||||
|
!room:example.com
|
||||||
|
<div
|
||||||
|
aria-label="Copy"
|
||||||
|
class="mx_AccessibleButton mx_CopyableText_copyButton"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSubsection"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSubsectionHeading"
|
||||||
|
>
|
||||||
|
<h3
|
||||||
|
class="mx_Heading_h3 mx_SettingsSubsectionHeading_heading"
|
||||||
|
>
|
||||||
|
Room version
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSubsection_content"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<span>
|
||||||
|
Room version:
|
||||||
|
</span>
|
||||||
|
1
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
class="mx_SettingsTab_section mx_SettingsTab_subsectionText"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="mx_SettingsTab_subheading"
|
|
||||||
>
|
|
||||||
Room version
|
|
||||||
</span>
|
|
||||||
<div>
|
|
||||||
<span>
|
|
||||||
Room version:
|
|
||||||
</span>
|
|
||||||
1
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</DocumentFragment>
|
</DocumentFragment>
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -6,75 +6,83 @@ exports[`<BridgeSettingsTab /> renders when room is bridging messages 1`] = `
|
||||||
class="mx_SettingsTab"
|
class="mx_SettingsTab"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsTab_heading"
|
class="mx_SettingsTab_sections"
|
||||||
>
|
>
|
||||||
Bridges
|
<div
|
||||||
</div>
|
class="mx_SettingsSection"
|
||||||
<div
|
>
|
||||||
class="mx_SettingsTab_section mx_SettingsTab_subsectionText"
|
<h2
|
||||||
>
|
class="mx_Heading_h2"
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
<span>
|
|
||||||
This room is bridging messages to the following platforms.
|
|
||||||
<a
|
|
||||||
href="https://matrix.org/bridges/"
|
|
||||||
rel="noreferrer noopener"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
Learn more.
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
<ul
|
|
||||||
class="mx_RoomSettingsDialog_BridgeList"
|
|
||||||
>
|
>
|
||||||
<li
|
Bridges
|
||||||
class="mx_RoomSettingsDialog_BridgeList_listItem"
|
</h2>
|
||||||
>
|
<div
|
||||||
<div
|
class="mx_SettingsSection_subSections"
|
||||||
class="mx_RoomSettingsDialog_column_icon"
|
>
|
||||||
>
|
<div>
|
||||||
<div
|
<p>
|
||||||
class="mx_RoomSettingsDialog_noProtocolIcon"
|
<span>
|
||||||
/>
|
This room is bridging messages to the following platforms.
|
||||||
</div>
|
<a
|
||||||
<div
|
href="https://matrix.org/bridges/"
|
||||||
class="mx_RoomSettingsDialog_column_data"
|
rel="noreferrer noopener"
|
||||||
>
|
target="_blank"
|
||||||
<h3
|
|
||||||
class="mx_RoomSettingsDialog_column_data_protocolName"
|
|
||||||
>
|
|
||||||
protocol-test
|
|
||||||
</h3>
|
|
||||||
<p
|
|
||||||
class="mx_RoomSettingsDialog_column_data_details mx_RoomSettingsDialog_workspace_channel_details"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="mx_RoomSettingsDialog_channel"
|
|
||||||
>
|
>
|
||||||
<span>
|
Learn more.
|
||||||
Channel:
|
</a>
|
||||||
<span>
|
</span>
|
||||||
channel-test
|
</p>
|
||||||
</span>
|
<ul
|
||||||
</span>
|
class="mx_RoomSettingsDialog_BridgeList"
|
||||||
</span>
|
>
|
||||||
</p>
|
<li
|
||||||
<ul
|
class="mx_RoomSettingsDialog_BridgeList_listItem"
|
||||||
class="mx_RoomSettingsDialog_column_data_metadata mx_RoomSettingsDialog_metadata"
|
|
||||||
>
|
>
|
||||||
|
<div
|
||||||
<li>
|
class="mx_RoomSettingsDialog_column_icon"
|
||||||
<span>
|
>
|
||||||
This bridge is managed by
|
<div
|
||||||
.
|
class="mx_RoomSettingsDialog_noProtocolIcon"
|
||||||
</span>
|
/>
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
<div
|
||||||
</div>
|
class="mx_RoomSettingsDialog_column_data"
|
||||||
</li>
|
>
|
||||||
</ul>
|
<h3
|
||||||
|
class="mx_RoomSettingsDialog_column_data_protocolName"
|
||||||
|
>
|
||||||
|
protocol-test
|
||||||
|
</h3>
|
||||||
|
<p
|
||||||
|
class="mx_RoomSettingsDialog_column_data_details mx_RoomSettingsDialog_workspace_channel_details"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="mx_RoomSettingsDialog_channel"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Channel:
|
||||||
|
<span>
|
||||||
|
channel-test
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<ul
|
||||||
|
class="mx_RoomSettingsDialog_column_data_metadata mx_RoomSettingsDialog_metadata"
|
||||||
|
>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span>
|
||||||
|
This bridge is managed by
|
||||||
|
.
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -87,25 +95,33 @@ exports[`<BridgeSettingsTab /> renders when room is not bridging messages to any
|
||||||
class="mx_SettingsTab"
|
class="mx_SettingsTab"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsTab_heading"
|
class="mx_SettingsTab_sections"
|
||||||
>
|
>
|
||||||
Bridges
|
<div
|
||||||
</div>
|
class="mx_SettingsSection"
|
||||||
<div
|
>
|
||||||
class="mx_SettingsTab_section mx_SettingsTab_subsectionText"
|
<h2
|
||||||
>
|
class="mx_Heading_h2"
|
||||||
<p>
|
>
|
||||||
<span>
|
Bridges
|
||||||
This room isn't bridging messages to any platforms.
|
</h2>
|
||||||
<a
|
<div
|
||||||
href="https://matrix.org/bridges/"
|
class="mx_SettingsSection_subSections"
|
||||||
rel="noreferrer noopener"
|
>
|
||||||
target="_blank"
|
<p>
|
||||||
>
|
<span>
|
||||||
Learn more.
|
This room isn't bridging messages to any platforms.
|
||||||
</a>
|
<a
|
||||||
</span>
|
href="https://matrix.org/bridges/"
|
||||||
</p>
|
rel="noreferrer noopener"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Learn more.
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,7 +9,9 @@ exports[`RolesRoomSettingsTab Banned users renders banned users 1`] = `
|
||||||
>
|
>
|
||||||
Banned users
|
Banned users
|
||||||
</legend>
|
</legend>
|
||||||
<ul>
|
<ul
|
||||||
|
class="mx_RolesRoomSettingsTab_bannedList"
|
||||||
|
>
|
||||||
<li>
|
<li>
|
||||||
<span
|
<span
|
||||||
title="Banned by @alice:server.org"
|
title="Banned by @alice:server.org"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue