Merge branch 'develop' into travis/media-customization
This commit is contained in:
commit
a9a4bd50ca
19 changed files with 357 additions and 194 deletions
|
@ -1913,7 +1913,7 @@ export default class RoomView extends React.Component<IProps, IState> {
|
|||
);
|
||||
}
|
||||
|
||||
if (this.state.room?.isSpaceRoom()) {
|
||||
if (SettingsStore.getValue("feature_spaces") && this.state.room?.isSpaceRoom()) {
|
||||
return <SpaceRoomView
|
||||
space={this.state.room}
|
||||
justCreatedOpts={this.props.justCreatedOpts}
|
||||
|
|
|
@ -94,26 +94,95 @@ const useMyRoomMembership = (room: Room) => {
|
|||
return membership;
|
||||
};
|
||||
|
||||
const SpaceLanding = ({ space, onJoinButtonClicked, onRejectButtonClicked }) => {
|
||||
const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
const myMembership = useMyRoomMembership(space);
|
||||
const joinRule = space.getJoinRule();
|
||||
const userId = cli.getUserId();
|
||||
|
||||
let inviterSection;
|
||||
let joinButtons;
|
||||
if (myMembership === "invite") {
|
||||
joinButtons = <div className="mx_SpaceRoomView_landing_joinButtons">
|
||||
<FormButton label={_t("Accept Invite")} onClick={onJoinButtonClicked} />
|
||||
<AccessibleButton kind="link" onClick={onRejectButtonClicked}>
|
||||
{_t("Decline")}
|
||||
</AccessibleButton>
|
||||
</div>;
|
||||
} else if (myMembership !== "join" && joinRule === "public") {
|
||||
joinButtons = <div className="mx_SpaceRoomView_landing_joinButtons">
|
||||
<FormButton label={_t("Join")} onClick={onJoinButtonClicked} />
|
||||
</div>;
|
||||
const inviteSender = space.getMember(cli.getUserId())?.events.member?.getSender();
|
||||
const inviter = inviteSender && space.getMember(inviteSender);
|
||||
|
||||
if (inviteSender) {
|
||||
inviterSection = <div className="mx_SpaceRoomView_preview_inviter">
|
||||
<MemberAvatar member={inviter} width={32} height={32} />
|
||||
<div>
|
||||
<div className="mx_SpaceRoomView_preview_inviter_name">
|
||||
{ _t("<inviter/> invites you", {}, {
|
||||
inviter: () => <b>{ inviter.name || inviteSender }</b>,
|
||||
}) }
|
||||
</div>
|
||||
{ inviter ? <div className="mx_SpaceRoomView_preview_inviter_mxid">
|
||||
{ inviteSender }
|
||||
</div> : null }
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
joinButtons = <>
|
||||
<FormButton label={_t("Reject")} kind="secondary" onClick={onRejectButtonClicked} />
|
||||
<FormButton label={_t("Accept")} onClick={onJoinButtonClicked} />
|
||||
</>;
|
||||
} else {
|
||||
joinButtons = <FormButton label={_t("Join")} onClick={onJoinButtonClicked} />
|
||||
}
|
||||
|
||||
let visibilitySection;
|
||||
if (space.getJoinRule() === "public") {
|
||||
visibilitySection = <span className="mx_SpaceRoomView_preview_info_public">
|
||||
{ _t("Public space") }
|
||||
</span>;
|
||||
} else {
|
||||
visibilitySection = <span className="mx_SpaceRoomView_preview_info_private">
|
||||
{ _t("Private space") }
|
||||
</span>;
|
||||
}
|
||||
|
||||
return <div className="mx_SpaceRoomView_preview">
|
||||
{ inviterSection }
|
||||
<RoomAvatar room={space} height={80} width={80} viewAvatarOnClick={true} />
|
||||
<h1 className="mx_SpaceRoomView_preview_name">
|
||||
<RoomName room={space} />
|
||||
</h1>
|
||||
<div className="mx_SpaceRoomView_preview_info">
|
||||
{ visibilitySection }
|
||||
<RoomMemberCount room={space}>
|
||||
{(count) => count > 0 ? (
|
||||
<AccessibleButton
|
||||
className="mx_SpaceRoomView_preview_memberCount"
|
||||
kind="link"
|
||||
onClick={() => {
|
||||
defaultDispatcher.dispatch<SetRightPanelPhasePayload>({
|
||||
action: Action.SetRightPanelPhase,
|
||||
phase: RightPanelPhases.RoomMemberList,
|
||||
refireParams: { space },
|
||||
});
|
||||
}}
|
||||
>
|
||||
{ _t("%(count)s members", { count }) }
|
||||
</AccessibleButton>
|
||||
) : null}
|
||||
</RoomMemberCount>
|
||||
</div>
|
||||
<RoomTopic room={space}>
|
||||
{(topic, ref) =>
|
||||
<div className="mx_SpaceRoomView_preview_topic" ref={ref}>
|
||||
{ topic }
|
||||
</div>
|
||||
}
|
||||
</RoomTopic>
|
||||
<div className="mx_SpaceRoomView_preview_joinButtons">
|
||||
{ joinButtons }
|
||||
</div>
|
||||
</div>;
|
||||
};
|
||||
|
||||
const SpaceLanding = ({ space }) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
const myMembership = useMyRoomMembership(space);
|
||||
const userId = cli.getUserId();
|
||||
|
||||
let inviteButton;
|
||||
if (myMembership === "join" && space.canInvite(userId)) {
|
||||
inviteButton = (
|
||||
|
@ -227,26 +296,7 @@ const SpaceLanding = ({ space, onJoinButtonClicked, onRejectButtonClicked }) =>
|
|||
) : null}
|
||||
</RoomMemberCount>
|
||||
</div> };
|
||||
if (myMembership === "invite") {
|
||||
const inviteSender = space.getMember(userId)?.events.member?.getSender();
|
||||
const inviter = inviteSender && space.getMember(inviteSender);
|
||||
|
||||
if (inviteSender) {
|
||||
return _t("<inviter/> invited you to <name/>", {}, {
|
||||
name: tags.name,
|
||||
inviter: () => inviter
|
||||
? <span className="mx_SpaceRoomView_landing_inviter">
|
||||
<MemberAvatar member={inviter} width={26} height={26} viewUserOnClick={true} />
|
||||
{ inviter.name }
|
||||
</span>
|
||||
: <span className="mx_SpaceRoomView_landing_inviter">
|
||||
{ inviteSender }
|
||||
</span>,
|
||||
}) as JSX.Element;
|
||||
} else {
|
||||
return _t("You have been invited to <name/>", {}, tags) as JSX.Element;
|
||||
}
|
||||
} else if (shouldShowSpaceSettings(cli, space)) {
|
||||
if (shouldShowSpaceSettings(cli, space)) {
|
||||
if (space.getJoinRule() === "public") {
|
||||
return _t("Your public space <name/>", {}, tags) as JSX.Element;
|
||||
} else {
|
||||
|
@ -260,7 +310,6 @@ const SpaceLanding = ({ space, onJoinButtonClicked, onRejectButtonClicked }) =>
|
|||
<div className="mx_SpaceRoomView_landing_topic">
|
||||
<RoomTopic room={space} />
|
||||
</div>
|
||||
{ joinButtons }
|
||||
<div className="mx_SpaceRoomView_landing_adminButtons">
|
||||
{ inviteButton }
|
||||
{ addRoomButtons }
|
||||
|
@ -548,12 +597,15 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
|
|||
private renderBody() {
|
||||
switch (this.state.phase) {
|
||||
case Phase.Landing:
|
||||
return <SpaceLanding
|
||||
space={this.props.space}
|
||||
onJoinButtonClicked={this.props.onJoinButtonClicked}
|
||||
onRejectButtonClicked={this.props.onRejectButtonClicked}
|
||||
/>;
|
||||
|
||||
if (this.props.space.getMyMembership() === "join") {
|
||||
return <SpaceLanding space={this.props.space} />;
|
||||
} else {
|
||||
return <SpacePreview
|
||||
space={this.props.space}
|
||||
onJoinButtonClicked={this.props.onJoinButtonClicked}
|
||||
onRejectButtonClicked={this.props.onRejectButtonClicked}
|
||||
/>;
|
||||
}
|
||||
case Phase.PublicCreateRooms:
|
||||
return <SpaceSetupFirstRooms
|
||||
space={this.props.space}
|
||||
|
|
|
@ -20,6 +20,7 @@ import { _t } from '../../../languageHandler';
|
|||
import * as sdk from '../../../index';
|
||||
import {
|
||||
SetupEncryptionStore,
|
||||
PHASE_LOADING,
|
||||
PHASE_INTRO,
|
||||
PHASE_BUSY,
|
||||
PHASE_DONE,
|
||||
|
@ -60,7 +61,9 @@ export default class CompleteSecurity extends React.Component {
|
|||
let icon;
|
||||
let title;
|
||||
|
||||
if (phase === PHASE_INTRO) {
|
||||
if (phase === PHASE_LOADING) {
|
||||
return null;
|
||||
} else if (phase === PHASE_INTRO) {
|
||||
icon = <span className="mx_CompleteSecurity_headerIcon mx_E2EIcon_warning" />;
|
||||
title = _t("Verify this login");
|
||||
} else if (phase === PHASE_DONE) {
|
||||
|
|
|
@ -17,11 +17,13 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import SdkConfig from '../../../SdkConfig';
|
||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||
import Modal from '../../../Modal';
|
||||
import VerificationRequestDialog from '../../views/dialogs/VerificationRequestDialog';
|
||||
import * as sdk from '../../../index';
|
||||
import {
|
||||
SetupEncryptionStore,
|
||||
PHASE_LOADING,
|
||||
PHASE_INTRO,
|
||||
PHASE_BUSY,
|
||||
PHASE_DONE,
|
||||
|
@ -83,6 +85,22 @@ export default class SetupEncryptionBody extends React.Component {
|
|||
store.usePassPhrase();
|
||||
}
|
||||
|
||||
_onVerifyClick = () => {
|
||||
const cli = MatrixClientPeg.get();
|
||||
const userId = cli.getUserId();
|
||||
const requestPromise = cli.requestVerification(userId);
|
||||
|
||||
this.props.onFinished(true);
|
||||
Modal.createTrackedDialog('New Session Verification', 'Starting dialog', VerificationRequestDialog, {
|
||||
verificationRequestPromise: requestPromise,
|
||||
member: cli.getUser(userId),
|
||||
onFinished: async () => {
|
||||
const request = await requestPromise;
|
||||
request.cancel();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
onSkipClick = () => {
|
||||
const store = SetupEncryptionStore.sharedInstance();
|
||||
store.skip();
|
||||
|
@ -134,32 +152,22 @@ export default class SetupEncryptionBody extends React.Component {
|
|||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
const brand = SdkConfig.get().brand;
|
||||
let verifyButton;
|
||||
if (store.hasDevicesToVerifyAgainst) {
|
||||
verifyButton = <AccessibleButton kind="primary" onClick={this._onVerifyClick}>
|
||||
{ _t("Verify with another session") }
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>{_t(
|
||||
"Confirm your identity by verifying this login from one of your other sessions, " +
|
||||
"granting it access to encrypted messages.",
|
||||
"Verify this login to access your encrypted messages and " +
|
||||
"prove to others that this login is really you.",
|
||||
)}</p>
|
||||
<p>{_t(
|
||||
"This requires the latest %(brand)s on your other devices:",
|
||||
{ brand },
|
||||
)}</p>
|
||||
|
||||
<div className="mx_CompleteSecurity_clients">
|
||||
<div className="mx_CompleteSecurity_clients_desktop">
|
||||
<div>{_t("%(brand)s Web", { brand })}</div>
|
||||
<div>{_t("%(brand)s Desktop", { brand })}</div>
|
||||
</div>
|
||||
<div className="mx_CompleteSecurity_clients_mobile">
|
||||
<div>{_t("%(brand)s iOS", { brand })}</div>
|
||||
<div>{_t("%(brand)s Android", { brand })}</div>
|
||||
</div>
|
||||
<p>{_t("or another cross-signing capable Matrix client")}</p>
|
||||
</div>
|
||||
|
||||
<div className="mx_CompleteSecurity_actionRow">
|
||||
{verifyButton}
|
||||
{useRecoveryKeyButton}
|
||||
<AccessibleButton kind="danger" onClick={this.onSkipClick}>
|
||||
{_t("Skip")}
|
||||
|
@ -217,7 +225,7 @@ export default class SetupEncryptionBody extends React.Component {
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
} else if (phase === PHASE_BUSY) {
|
||||
} else if (phase === PHASE_BUSY || phase === PHASE_LOADING) {
|
||||
const Spinner = sdk.getComponent('views.elements.Spinner');
|
||||
return <Spinner />;
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue