Fix: Space scope header overflow (#11933)
* fix spacing for scope header * extract scope header into component, apply line clamp * update ThirdPartyMemberInfo styles * pass onClose to ThirdPartyRoomMemberInfo * rethemendex * add View3pidInvite to actions enum, replace uses * extract out action handler * push card instead, test * comment * reinstate data-testid * fix typo in styles
This commit is contained in:
parent
4d0a34bb26
commit
1ffa1c9c18
14 changed files with 188 additions and 221 deletions
|
@ -65,8 +65,6 @@ import ShareDialog from "../dialogs/ShareDialog";
|
|||
import ErrorDialog from "../dialogs/ErrorDialog";
|
||||
import QuestionDialog from "../dialogs/QuestionDialog";
|
||||
import ConfirmUserActionDialog from "../dialogs/ConfirmUserActionDialog";
|
||||
import RoomAvatar from "../avatars/RoomAvatar";
|
||||
import RoomName from "../elements/RoomName";
|
||||
import { mediaFromMxc } from "../../../customisations/Media";
|
||||
import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInsertPayload";
|
||||
import ConfirmSpaceUserActionDialog from "../dialogs/ConfirmSpaceUserActionDialog";
|
||||
|
@ -83,6 +81,7 @@ import { DirectoryMember, startDmOnFirstMessage } from "../../../utils/direct-me
|
|||
import { SdkContextClass } from "../../../contexts/SDKContext";
|
||||
import { asyncSome } from "../../../utils/arrays";
|
||||
import UIStore from "../../../stores/UIStore";
|
||||
import { SpaceScopeHeader } from "../rooms/SpaceScopeHeader";
|
||||
|
||||
export interface IDevice extends Device {
|
||||
ambiguous?: boolean;
|
||||
|
@ -1744,26 +1743,15 @@ const UserInfo: React.FC<IProps> = ({ user, room, onClose, phase = RightPanelPha
|
|||
}
|
||||
}
|
||||
|
||||
let scopeHeader;
|
||||
if (room?.isSpaceRoom()) {
|
||||
scopeHeader = (
|
||||
<div data-testid="space-header" className="mx_RightPanel_scopeHeader">
|
||||
<RoomAvatar room={room} size="32px" />
|
||||
<RoomName room={room} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const header = (
|
||||
<>
|
||||
{scopeHeader}
|
||||
<UserInfoHeader member={member} e2eStatus={e2eStatus} roomId={room?.roomId} />
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<BaseCard
|
||||
className={classes.join(" ")}
|
||||
header={<span />}
|
||||
header={room ? <SpaceScopeHeader room={room} /> : undefined}
|
||||
onClose={onClose}
|
||||
closeLabel={closeLabel}
|
||||
cardState={cardState}
|
||||
|
|
|
@ -40,8 +40,6 @@ import dis from "../../../dispatcher/dispatcher";
|
|||
import { isValid3pidInvite } from "../../../RoomInvite";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import BaseCard from "../right_panel/BaseCard";
|
||||
import RoomAvatar from "../avatars/RoomAvatar";
|
||||
import RoomName from "../elements/RoomName";
|
||||
import TruncatedList from "../elements/TruncatedList";
|
||||
import Spinner from "../elements/Spinner";
|
||||
import SearchBox from "../../structures/SearchBox";
|
||||
|
@ -56,6 +54,7 @@ import { SDKContext } from "../../../contexts/SDKContext";
|
|||
import { canInviteTo } from "../../../utils/room/canInviteTo";
|
||||
import { inviteToRoom } from "../../../utils/room/inviteToRoom";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
import { SpaceScopeHeader } from "./SpaceScopeHeader";
|
||||
|
||||
const INITIAL_LOAD_NUM_MEMBERS = 30;
|
||||
const INITIAL_LOAD_NUM_INVITED = 5;
|
||||
|
@ -411,15 +410,7 @@ export default class MemberList extends React.Component<IProps, IState> {
|
|||
/>
|
||||
);
|
||||
|
||||
let scopeHeader;
|
||||
if (room?.isSpaceRoom()) {
|
||||
scopeHeader = (
|
||||
<div className="mx_RightPanel_scopeHeader">
|
||||
<RoomAvatar room={room} size="32px" />
|
||||
<RoomName room={room} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const scopeHeader = room ? <SpaceScopeHeader room={room} /> : undefined;
|
||||
|
||||
return (
|
||||
<BaseCard
|
||||
|
|
49
src/components/views/rooms/SpaceScopeHeader.tsx
Normal file
49
src/components/views/rooms/SpaceScopeHeader.tsx
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { Room } from "matrix-js-sdk/src/matrix";
|
||||
import { Text } from "@vector-im/compound-web";
|
||||
|
||||
import RoomAvatar from "../avatars/RoomAvatar";
|
||||
import { useRoomName } from "../../../hooks/useRoomName";
|
||||
|
||||
/**
|
||||
* Scope header used to decorate right panels that are scoped to a space.
|
||||
* When room is not a space renders nothing.
|
||||
* Otherwise renders room avatar and name.
|
||||
*/
|
||||
export const SpaceScopeHeader: React.FC<{ room: Room }> = ({ room }) => {
|
||||
const roomName = useRoomName(room);
|
||||
|
||||
if (!room.isSpaceRoom()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Text
|
||||
as="div"
|
||||
size="lg"
|
||||
weight="semibold"
|
||||
className="mx_SpaceScopeHeader"
|
||||
title={roomName}
|
||||
data-testid="space-header"
|
||||
>
|
||||
<RoomAvatar room={room} size="32px" />
|
||||
{roomName}
|
||||
</Text>
|
||||
);
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2021 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019-2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -17,20 +17,22 @@ limitations under the License.
|
|||
import React from "react";
|
||||
import { MatrixEvent, Room, RoomStateEvent, EventType } from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { Button, Text } from "@vector-im/compound-web";
|
||||
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
import Modal from "../../../Modal";
|
||||
import { isValid3pidInvite } from "../../../RoomInvite";
|
||||
import RoomAvatar from "../avatars/RoomAvatar";
|
||||
import RoomName from "../elements/RoomName";
|
||||
import ErrorDialog from "../dialogs/ErrorDialog";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
import ErrorDialog from "../dialogs/ErrorDialog";
|
||||
import BaseCard from "../right_panel/BaseCard";
|
||||
import { Flex } from "../../utils/Flex";
|
||||
import { SpaceScopeHeader } from "./SpaceScopeHeader";
|
||||
|
||||
interface IProps {
|
||||
event: MatrixEvent;
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
|
@ -120,42 +122,32 @@ export default class ThirdPartyMemberInfo extends React.Component<IProps, IState
|
|||
let adminTools: JSX.Element | undefined;
|
||||
if (this.state.canKick && this.state.invited) {
|
||||
adminTools = (
|
||||
<div className="mx_MemberInfo_container">
|
||||
<h3>{_t("user_info|admin_tools_section")}</h3>
|
||||
<AccessibleButton className="mx_MemberInfo_field" onClick={this.onKickClick}>
|
||||
<Flex direction="column" as="section" justify="start" gap="var(--cpd-space-2x)">
|
||||
<Text as="span" role="heading" size="lg" weight="semibold">
|
||||
{_t("user_info|admin_tools_section")}
|
||||
</Text>
|
||||
<Button size="sm" kind="destructive" className="mx_MemberInfo_field" onClick={this.onKickClick}>
|
||||
{_t("user_info|revoke_invite")}
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
</Button>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
let scopeHeader: JSX.Element | undefined;
|
||||
if (this.room?.isSpaceRoom()) {
|
||||
scopeHeader = (
|
||||
<div className="mx_RightPanel_scopeHeader">
|
||||
<RoomAvatar room={this.room} size="32px" />
|
||||
<RoomName room={this.room} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const scopeHeader: JSX.Element | undefined = this.room ? <SpaceScopeHeader room={this.room} /> : undefined;
|
||||
|
||||
// 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}
|
||||
title={_t("action|close")}
|
||||
/>
|
||||
<h2>{this.state.displayName}</h2>
|
||||
</div>
|
||||
<div className="mx_MemberInfo_container mx_MemberInfo_container--profile">
|
||||
{_t("user_info|invited_by", { sender: this.state.senderName })}
|
||||
</div>
|
||||
{adminTools}
|
||||
</div>
|
||||
<BaseCard header={scopeHeader} onClose={this.props.onClose}>
|
||||
<Flex className="mx_ThirdPartyMemberInfo" direction="column" gap="var(--cpd-space-4x)">
|
||||
<Flex direction="column" as="section" justify="start" gap="var(--cpd-space-2x)">
|
||||
{/* same as userinfo name style */}
|
||||
<Text as="span" role="heading" size="lg" weight="semibold">
|
||||
{this.state.displayName}
|
||||
</Text>
|
||||
<Text as="span">{_t("user_info|invited_by", { sender: this.state.senderName })}</Text>
|
||||
</Flex>
|
||||
{adminTools}
|
||||
</Flex>
|
||||
</BaseCard>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue