Decorate Right Panel cards with Space header for when viewing it in that context
This commit is contained in:
parent
1a7a0e619d
commit
8efe7dcaa1
7 changed files with 98 additions and 25 deletions
|
@ -60,7 +60,9 @@ import QuestionDialog from "../dialogs/QuestionDialog";
|
|||
import ConfirmUserActionDialog from "../dialogs/ConfirmUserActionDialog";
|
||||
import InfoDialog from "../dialogs/InfoDialog";
|
||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||
import {SetRightPanelPhasePayload} from "../../../dispatcher/payloads/SetRightPanelPhasePayload";
|
||||
import { SetRightPanelPhasePayload } from "../../../dispatcher/payloads/SetRightPanelPhasePayload";
|
||||
import RoomAvatar from "../avatars/RoomAvatar";
|
||||
import RoomName from "../elements/RoomName";
|
||||
|
||||
interface IDevice {
|
||||
deviceId: string;
|
||||
|
@ -302,7 +304,8 @@ const UserOptionsSection: React.FC<{
|
|||
member: RoomMember;
|
||||
isIgnored: boolean;
|
||||
canInvite: boolean;
|
||||
}> = ({member, isIgnored, canInvite}) => {
|
||||
isSpace?: boolean;
|
||||
}> = ({member, isIgnored, canInvite, isSpace}) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
|
||||
let ignoreButton = null;
|
||||
|
@ -342,7 +345,7 @@ const UserOptionsSection: React.FC<{
|
|||
</AccessibleButton>
|
||||
);
|
||||
|
||||
if (member.roomId) {
|
||||
if (member.roomId && !isSpace) {
|
||||
const onReadReceiptButton = function() {
|
||||
const room = cli.getRoom(member.roomId);
|
||||
dis.dispatch({
|
||||
|
@ -434,14 +437,18 @@ const UserOptionsSection: React.FC<{
|
|||
);
|
||||
};
|
||||
|
||||
const warnSelfDemote = async () => {
|
||||
const warnSelfDemote = async (isSpace) => {
|
||||
const {finished} = Modal.createTrackedDialog('Demoting Self', '', QuestionDialog, {
|
||||
title: _t("Demote yourself?"),
|
||||
description:
|
||||
<div>
|
||||
{ _t("You will not be able to undo this change as you are demoting yourself, " +
|
||||
"if you are the last privileged user in the room it will be impossible " +
|
||||
"to regain privileges.") }
|
||||
{ isSpace
|
||||
? _t("You will not be able to undo this change as you are demoting yourself, " +
|
||||
"if you are the last privileged user in the space it will be impossible " +
|
||||
"to regain privileges.")
|
||||
: _t("You will not be able to undo this change as you are demoting yourself, " +
|
||||
"if you are the last privileged user in the room it will be impossible " +
|
||||
"to regain privileges.") }
|
||||
</div>,
|
||||
button: _t("Demote"),
|
||||
});
|
||||
|
@ -717,7 +724,7 @@ const MuteToggleButton: React.FC<IBaseRoomProps> = ({member, room, powerLevels,
|
|||
// if muting self, warn as it may be irreversible
|
||||
if (target === cli.getUserId()) {
|
||||
try {
|
||||
if (!(await warnSelfDemote())) return;
|
||||
if (!(await warnSelfDemote(room?.isSpaceRoom()))) return;
|
||||
} catch (e) {
|
||||
console.error("Failed to warn about self demotion: ", e);
|
||||
return;
|
||||
|
@ -806,7 +813,7 @@ const RoomAdminToolsContainer: React.FC<IBaseRoomProps> = ({
|
|||
if (canAffectUser && me.powerLevel >= kickPowerLevel) {
|
||||
kickButton = <RoomKickButton member={member} startUpdating={startUpdating} stopUpdating={stopUpdating} />;
|
||||
}
|
||||
if (me.powerLevel >= redactPowerLevel) {
|
||||
if (me.powerLevel >= redactPowerLevel && !room.isSpaceRoom()) {
|
||||
redactButton = (
|
||||
<RedactMessagesButton member={member} startUpdating={startUpdating} stopUpdating={stopUpdating} />
|
||||
);
|
||||
|
@ -1085,7 +1092,7 @@ const PowerLevelEditor: React.FC<{
|
|||
} else if (myUserId === target) {
|
||||
// If we are changing our own PL it can only ever be decreasing, which we cannot reverse.
|
||||
try {
|
||||
if (!(await warnSelfDemote())) return;
|
||||
if (!(await warnSelfDemote(room?.isSpaceRoom()))) return;
|
||||
} catch (e) {
|
||||
console.error("Failed to warn about self demotion: ", e);
|
||||
}
|
||||
|
@ -1315,12 +1322,10 @@ const BasicUserInfo: React.FC<{
|
|||
if (!isRoomEncrypted) {
|
||||
if (!cryptoEnabled) {
|
||||
text = _t("This client does not support end-to-end encryption.");
|
||||
} else if (room) {
|
||||
} else if (room && !room.isSpaceRoom()) {
|
||||
text = _t("Messages in this room are not end-to-end encrypted.");
|
||||
} else {
|
||||
// TODO what to render for GroupMember
|
||||
}
|
||||
} else {
|
||||
} else if (!room.isSpaceRoom()) {
|
||||
text = _t("Messages in this room are end-to-end encrypted.");
|
||||
}
|
||||
|
||||
|
@ -1381,7 +1386,9 @@ const BasicUserInfo: React.FC<{
|
|||
<UserOptionsSection
|
||||
canInvite={roomPermissions.canInvite}
|
||||
isIgnored={isIgnored}
|
||||
member={member} />
|
||||
member={member}
|
||||
isSpace={room?.isSpaceRoom()}
|
||||
/>
|
||||
|
||||
{ adminToolsContainer }
|
||||
|
||||
|
@ -1498,7 +1505,7 @@ interface IProps {
|
|||
user: Member;
|
||||
groupId?: string;
|
||||
room?: Room;
|
||||
phase: RightPanelPhases.RoomMemberInfo | RightPanelPhases.GroupMemberInfo;
|
||||
phase: RightPanelPhases.RoomMemberInfo | RightPanelPhases.GroupMemberInfo | RightPanelPhases.SpaceMemberInfo;
|
||||
onClose(): void;
|
||||
}
|
||||
|
||||
|
@ -1542,7 +1549,9 @@ const UserInfo: React.FC<Props> = ({
|
|||
previousPhase = RightPanelPhases.RoomMemberInfo;
|
||||
refireParams = {member: member};
|
||||
} else if (room) {
|
||||
previousPhase = RightPanelPhases.RoomMemberList;
|
||||
previousPhase = previousPhase = room.isSpaceRoom()
|
||||
? RightPanelPhases.SpaceMemberList
|
||||
: RightPanelPhases.RoomMemberList;
|
||||
}
|
||||
|
||||
const onEncryptionPanelClose = () => {
|
||||
|
@ -1557,6 +1566,7 @@ const UserInfo: React.FC<Props> = ({
|
|||
switch (phase) {
|
||||
case RightPanelPhases.RoomMemberInfo:
|
||||
case RightPanelPhases.GroupMemberInfo:
|
||||
case RightPanelPhases.SpaceMemberInfo:
|
||||
content = (
|
||||
<BasicUserInfo
|
||||
room={room}
|
||||
|
@ -1587,7 +1597,18 @@ const UserInfo: React.FC<Props> = ({
|
|||
}
|
||||
}
|
||||
|
||||
const header = <UserInfoHeader member={member} e2eStatus={e2eStatus} />;
|
||||
let scopeHeader;
|
||||
if (room?.isSpaceRoom()) {
|
||||
scopeHeader = <div className="mx_RightPanel_scopeHeader">
|
||||
<RoomAvatar room={room} height={32} width={32} />
|
||||
<RoomName room={room} />
|
||||
</div>;
|
||||
}
|
||||
|
||||
const header = <React.Fragment>
|
||||
{ scopeHeader }
|
||||
<UserInfoHeader member={member} e2eStatus={e2eStatus} />
|
||||
</React.Fragment>;
|
||||
return <BaseCard
|
||||
className={classes.join(" ")}
|
||||
header={header}
|
||||
|
|
|
@ -27,6 +27,8 @@ import * as sdk from "../../../index";
|
|||
import {CommunityPrototypeStore} from "../../../stores/CommunityPrototypeStore";
|
||||
import BaseCard from "../right_panel/BaseCard";
|
||||
import {RightPanelPhases} from "../../../stores/RightPanelStorePhases";
|
||||
import RoomAvatar from "../avatars/RoomAvatar";
|
||||
import RoomName from "../elements/RoomName";
|
||||
|
||||
const INITIAL_LOAD_NUM_MEMBERS = 30;
|
||||
const INITIAL_LOAD_NUM_INVITED = 5;
|
||||
|
@ -456,6 +458,8 @@ export default class MemberList extends React.Component {
|
|||
const chat = CommunityPrototypeStore.instance.getSelectedCommunityGeneralChat();
|
||||
if (chat && chat.roomId === this.props.roomId) {
|
||||
inviteButtonText = _t("Invite to this community");
|
||||
} else if (room.isSpaceRoom()) {
|
||||
inviteButtonText = _t("Invite to this space");
|
||||
}
|
||||
|
||||
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
|
||||
|
@ -483,12 +487,26 @@ export default class MemberList extends React.Component {
|
|||
onSearch={ this.onSearchQueryChanged } />
|
||||
);
|
||||
|
||||
let previousPhase = RightPanelPhases.RoomSummary;
|
||||
// We have no previousPhase for when viewing a MemberList from a Space
|
||||
let scopeHeader;
|
||||
if (room?.isSpaceRoom()) {
|
||||
previousPhase = undefined;
|
||||
scopeHeader = <div className="mx_RightPanel_scopeHeader">
|
||||
<RoomAvatar room={room} height={32} width={32} />
|
||||
<RoomName room={room} />
|
||||
</div>;
|
||||
}
|
||||
|
||||
return <BaseCard
|
||||
className="mx_MemberList"
|
||||
header={inviteButton}
|
||||
header={<React.Fragment>
|
||||
{ scopeHeader }
|
||||
{ inviteButton }
|
||||
</React.Fragment>}
|
||||
footer={footer}
|
||||
onClose={this.props.onClose}
|
||||
previousPhase={RightPanelPhases.RoomSummary}
|
||||
previousPhase={previousPhase}
|
||||
>
|
||||
<div className="mx_MemberList_wrapper">
|
||||
<TruncatedList className="mx_MemberList_section mx_MemberList_joined" truncateAt={this.state.truncateAtJoined}
|
||||
|
|
|
@ -23,6 +23,8 @@ import dis from "../../../dispatcher/dispatcher";
|
|||
import * as sdk from "../../../index";
|
||||
import Modal from "../../../Modal";
|
||||
import {isValid3pidInvite} from "../../../RoomInvite";
|
||||
import RoomAvatar from "../avatars/RoomAvatar";
|
||||
import RoomName from "../elements/RoomName";
|
||||
|
||||
export default class ThirdPartyMemberInfo extends React.Component {
|
||||
static propTypes = {
|
||||
|
@ -32,14 +34,14 @@ export default class ThirdPartyMemberInfo extends React.Component {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const room = MatrixClientPeg.get().getRoom(this.props.event.getRoomId());
|
||||
const me = room.getMember(MatrixClientPeg.get().getUserId());
|
||||
const powerLevels = room.currentState.getStateEvents("m.room.power_levels", "");
|
||||
this.room = MatrixClientPeg.get().getRoom(this.props.event.getRoomId());
|
||||
const me = this.room.getMember(MatrixClientPeg.get().getUserId());
|
||||
const powerLevels = this.room.currentState.getStateEvents("m.room.power_levels", "");
|
||||
|
||||
let kickLevel = powerLevels ? powerLevels.getContent().kick : 50;
|
||||
if (typeof(kickLevel) !== 'number') kickLevel = 50;
|
||||
|
||||
const sender = room.getMember(this.props.event.getSender());
|
||||
const sender = this.room.getMember(this.props.event.getSender());
|
||||
|
||||
this.state = {
|
||||
stateKey: this.props.event.getStateKey(),
|
||||
|
@ -119,9 +121,18 @@ export default class ThirdPartyMemberInfo extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
let scopeHeader;
|
||||
if (this.room.isSpaceRoom()) {
|
||||
scopeHeader = <div className="mx_RightPanel_scopeHeader">
|
||||
<RoomAvatar room={this.room} height={32} width={32} />
|
||||
<RoomName room={this.room} />
|
||||
</div>;
|
||||
}
|
||||
|
||||
// We shamelessly rip off the MemberInfo styles here.
|
||||
return (
|
||||
<div className="mx_MemberInfo" role="tabpanel">
|
||||
{ scopeHeader }
|
||||
<div className="mx_MemberInfo_name">
|
||||
<AccessibleButton className="mx_MemberInfo_cancel"
|
||||
onClick={this.onCancel}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue