Merge remote-tracking branch 'upstream/develop' into fix/user-info-dm/17877

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
Šimon Brandner 2021-09-15 15:28:05 +02:00
commit 8094a34384
No known key found for this signature in database
GPG key ID: 55C211A1226CB17D
839 changed files with 35725 additions and 16736 deletions

View file

@ -43,8 +43,8 @@ interface IGroupProps {
export const Group: React.FC<IGroupProps> = ({ className, title, children }) => {
return <div className={classNames("mx_BaseCard_Group", className)}>
<h1>{title}</h1>
{children}
<h1>{ title }</h1>
{ children }
</div>;
};

View file

@ -66,7 +66,7 @@ const EncryptionInfo: React.FC<IProps> = ({
} else {
content = (
<AccessibleButton kind="primary" className="mx_UserInfo_wideButton" onClick={onStartVerification}>
{_t("Start Verification")}
{ _t("Start Verification") }
</AccessibleButton>
);
}
@ -75,17 +75,17 @@ const EncryptionInfo: React.FC<IProps> = ({
if (isRoomEncrypted) {
description = (
<div>
<p>{_t("Messages in this room are end-to-end encrypted.")}</p>
<p>{_t("Your messages are secured and only you and the recipient have " +
"the unique keys to unlock them.")}</p>
<p>{ _t("Messages in this room are end-to-end encrypted.") }</p>
<p>{ _t("Your messages are secured and only you and the recipient have " +
"the unique keys to unlock them.") }</p>
</div>
);
} else {
description = (
<div>
<p>{_t("Messages in this room are not end-to-end encrypted.")}</p>
<p>{_t("In encrypted rooms, your messages are secured and only you and the recipient have " +
"the unique keys to unlock them.")}</p>
<p>{ _t("Messages in this room are not end-to-end encrypted.") }</p>
<p>{ _t("In encrypted rooms, your messages are secured and only you and the recipient have " +
"the unique keys to unlock them.") }</p>
</div>
);
}
@ -96,14 +96,14 @@ const EncryptionInfo: React.FC<IProps> = ({
return <React.Fragment>
<div className="mx_UserInfo_container">
<h3>{_t("Encryption")}</h3>
<h3>{ _t("Encryption") }</h3>
{ description }
</div>
<div className="mx_UserInfo_container">
<h3>{_t("Verify User")}</h3>
<h3>{ _t("Verify User") }</h3>
<div>
<p>{_t("For extra security, verify this user by checking a one-time code on both of your devices.")}</p>
<p>{_t("To be secure, do this in person or use a trusted way to communicate.")}</p>
<p>{ _t("For extra security, verify this user by checking a one-time code on both of your devices.") }</p>
<p>{ _t("To be secure, do this in person or use a trusted way to communicate.") }</p>
{ content }
</div>
</div>

View file

@ -57,7 +57,7 @@ const EncryptionPanel: React.FC<IProps> = (props: IProps) => {
// state to show a spinner immediately after clicking "start verification",
// before we have a request
const [isRequesting, setRequesting] = useState(false);
const [phase, setPhase] = useState(request && request.phase);
const [phase, setPhase] = useState(request?.phase);
useEffect(() => {
setRequest(verificationRequest);
if (verificationRequest) {
@ -87,12 +87,12 @@ const EncryptionPanel: React.FC<IProps> = (props: IProps) => {
headerImage: require("../../../../res/img/e2e/warning.svg"),
title: _t("Your messages are not secure"),
description: <div>
{_t("One of the following may be compromised:")}
{ _t("One of the following may be compromised:") }
<ul>
<li>{_t("Your homeserver")}</li>
<li>{_t("The homeserver the user youre verifying is connected to")}</li>
<li>{_t("Yours, or the other users internet connection")}</li>
<li>{_t("Yours, or the other users session")}</li>
<li>{ _t("Your homeserver") }</li>
<li>{ _t("The homeserver the user youre verifying is connected to") }</li>
<li>{ _t("Yours, or the other users internet connection") }</li>
<li>{ _t("Yours, or the other users session") }</li>
</ul>
</div>,
onFinished: onClose,

View file

@ -99,7 +99,7 @@ export default abstract class HeaderButtons<P = {}> extends React.Component<IPro
public render() {
return <div className="mx_HeaderButtons">
{this.renderButtons()}
{ this.renderButtons() }
</div>;
}
}

View file

@ -152,7 +152,7 @@ const PinnedMessagesCard = ({ room, onClose }: IProps) => {
<h2>{ _t("Nothing pinned, yet") }</h2>
{ _t("If you have permissions, open the menu on any message and select " +
"<b>Pin</b> to stick them here.", {}, {
b: sub => <b>{ sub }</b>,
b: sub => <b>{ sub }</b>,
}) }
</div>
</div>;

View file

@ -148,7 +148,7 @@ const AppRow: React.FC<IAppRowProps> = ({ app, room }) => {
yOffset={-48}
>
<WidgetAvatar app={app} />
<span>{name}</span>
<span>{ name }</span>
{ subtitle }
</AccessibleTooltipButton>
@ -220,6 +220,13 @@ const onRoomFilesClick = () => {
});
};
const onRoomThreadsClick = () => {
defaultDispatcher.dispatch<SetRightPanelPhasePayload>({
action: Action.SetRightPanelPhase,
phase: RightPanelPhases.ThreadPanel,
});
};
const onRoomSettingsClick = () => {
defaultDispatcher.dispatch({ action: "open_room_settings" });
};
@ -256,7 +263,7 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, onClose }) => {
<h2 title={name}>
{ name }
</h2>
)}
) }
</RoomName>
<div className="mx_RoomSummaryCard_alias" title={alias}>
{ alias }
@ -268,16 +275,21 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, onClose }) => {
return <BaseCard header={header} className="mx_RoomSummaryCard" onClose={onClose}>
<Group title={_t("About")} className="mx_RoomSummaryCard_aboutGroup">
<Button className="mx_RoomSummaryCard_icon_people" onClick={onRoomMembersClick}>
{_t("%(count)s people", { count: memberCount })}
{ _t("%(count)s people", { count: memberCount }) }
</Button>
<Button className="mx_RoomSummaryCard_icon_files" onClick={onRoomFilesClick}>
{_t("Show files")}
{ _t("Show files") }
</Button>
{ SettingsStore.getValue("feature_thread") && (
<Button className="mx_RoomSummaryCard_icon_threads" onClick={onRoomThreadsClick}>
{ _t("Show threads") }
</Button>
) }
<Button className="mx_RoomSummaryCard_icon_share" onClick={onShareRoomClick}>
{_t("Share room")}
{ _t("Share room") }
</Button>
<Button className="mx_RoomSummaryCard_icon_settings" onClick={onRoomSettingsClick}>
{_t("Room settings")}
{ _t("Room settings") }
</Button>
</Group>

View file

@ -69,6 +69,7 @@ import RoomName from "../elements/RoomName";
import { mediaFromMxc } from "../../../customisations/Media";
import UIStore from "../../../stores/UIStore";
import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInsertPayload";
import SpaceStore from "../../../stores/SpaceStore";
export interface IDevice {
deviceId: string;
@ -204,10 +205,10 @@ function DeviceItem({ userId, device }: {userId: string, device: IDevice}) {
if (isVerified) {
return (
<div className={classes} title={device.deviceId} >
<div className={classes} title={device.deviceId}>
<div className={iconClasses} />
<div className="mx_UserInfo_device_name">{deviceName}</div>
<div className="mx_UserInfo_device_trusted">{trustedLabel}</div>
<div className="mx_UserInfo_device_name">{ deviceName }</div>
<div className="mx_UserInfo_device_trusted">{ trustedLabel }</div>
</div>
);
} else {
@ -218,8 +219,8 @@ function DeviceItem({ userId, device }: {userId: string, device: IDevice}) {
onClick={onDeviceClick}
>
<div className={iconClasses} />
<div className="mx_UserInfo_device_name">{deviceName}</div>
<div className="mx_UserInfo_device_trusted">{trustedLabel}</div>
<div className="mx_UserInfo_device_name">{ deviceName }</div>
<div className="mx_UserInfo_device_trusted">{ trustedLabel }</div>
</AccessibleButton>
);
}
@ -236,7 +237,7 @@ function DevicesSection({ devices, userId, loading }: {devices: IDevice[], userI
return <Spinner />;
}
if (devices === null) {
return <>{_t("Unable to load session list")}</>;
return <>{ _t("Unable to load session list") }</>;
}
const isMe = userId === cli.getUserId();
const deviceTrusts = devices.map(d => cli.checkDeviceTrust(userId, d.deviceId));
@ -281,14 +282,14 @@ function DevicesSection({ devices, userId, loading }: {devices: IDevice[], userI
expandButton = (<AccessibleButton className="mx_UserInfo_expand mx_linkButton"
onClick={() => setExpanded(false)}
>
<div>{expandHideCaption}</div>
<div>{ expandHideCaption }</div>
</AccessibleButton>);
} else {
expandButton = (<AccessibleButton className="mx_UserInfo_expand mx_linkButton"
onClick={() => setExpanded(true)}
>
<div className={expandIconClasses} />
<div>{expandCountCaption}</div>
<div>{ expandCountCaption }</div>
</AccessibleButton>);
}
}
@ -305,8 +306,8 @@ function DevicesSection({ devices, userId, loading }: {devices: IDevice[], userI
return (
<div className="mx_UserInfo_devices">
<div>{deviceList}</div>
<div>{expandButton}</div>
<div>{ deviceList }</div>
<div>{ expandButton }</div>
</div>
);
}
@ -384,7 +385,7 @@ const UserOptionsSection: React.FC<{
}
insertPillButton = (
<AccessibleButton onClick={onInsertPillButton} className={"mx_UserInfo_field"}>
<AccessibleButton onClick={onInsertPillButton} className="mx_UserInfo_field">
{ _t('Mention') }
</AccessibleButton>
);
@ -427,7 +428,7 @@ const UserOptionsSection: React.FC<{
let directMessageButton;
if (!isMe) {
directMessageButton = (
<AccessibleButton onClick={() => openDMForUser(cli, member.userId)} className="mx_UserInfo_field">
<AccessibleButton onClick={() => { openDMForUser(cli, member.userId); }} className="mx_UserInfo_field">
{ findDMForUser(cli, member.userId) ? _t("Open chat") : _t('Direct message') }
</AccessibleButton>
);
@ -728,7 +729,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(SettingsStore.getValue("feature_spaces") && room?.isSpaceRoom()))) return;
if (!(await warnSelfDemote(SpaceStore.spacesEnabled && room?.isSpaceRoom()))) return;
} catch (e) {
console.error("Failed to warn about self demotion: ", e);
return;
@ -817,7 +818,7 @@ const RoomAdminToolsContainer: React.FC<IBaseRoomProps> = ({
if (canAffectUser && me.powerLevel >= kickPowerLevel) {
kickButton = <RoomKickButton member={member} startUpdating={startUpdating} stopUpdating={stopUpdating} />;
}
if (me.powerLevel >= redactPowerLevel && (!SettingsStore.getValue("feature_spaces") || !room.isSpaceRoom())) {
if (me.powerLevel >= redactPowerLevel && (!SpaceStore.spacesEnabled || !room.isSpaceRoom())) {
redactButton = (
<RedactMessagesButton member={member} startUpdating={startUpdating} stopUpdating={stopUpdating} />
);
@ -825,7 +826,7 @@ const RoomAdminToolsContainer: React.FC<IBaseRoomProps> = ({
if (canAffectUser && me.powerLevel >= banPowerLevel) {
banButton = <BanToggleButton member={member} startUpdating={startUpdating} stopUpdating={stopUpdating} />;
}
if (canAffectUser && me.powerLevel >= editPowerLevel) {
if (canAffectUser && me.powerLevel >= editPowerLevel && !room.isSpaceRoom()) {
muteButton = (
<MuteToggleButton
member={member}
@ -850,7 +851,7 @@ const RoomAdminToolsContainer: React.FC<IBaseRoomProps> = ({
return <div />;
};
interface GroupMember {
export interface GroupMember {
userId: string;
displayname?: string; // XXX: GroupMember objects are inconsistent :((
avatarUrl?: string;
@ -1037,7 +1038,7 @@ const PowerLevelSection: React.FC<{
const role = textualPowerLevel(powerLevel, powerLevelUsersDefault);
return (
<div className="mx_UserInfo_profileField">
<div className="mx_UserInfo_roleDescription">{role}</div>
<div className="mx_UserInfo_roleDescription">{ role }</div>
</div>
);
}
@ -1096,7 +1097,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(SettingsStore.getValue("feature_spaces") && room?.isSpaceRoom()))) return;
if (!(await warnSelfDemote(SpaceStore.spacesEnabled && room?.isSpaceRoom()))) return;
} catch (e) {
console.error("Failed to warn about self demotion: ", e);
}
@ -1266,7 +1267,7 @@ const BasicUserInfo: React.FC<{
if (isSynapseAdmin && member.userId.endsWith(`:${MatrixClientPeg.getHomeserverName()}`)) {
synapseDeactivateButton = (
<AccessibleButton onClick={onSynapseDeactivate} className="mx_UserInfo_field mx_UserInfo_destructive">
{_t("Deactivate user")}
{ _t("Deactivate user") }
</AccessibleButton>
);
}
@ -1277,7 +1278,9 @@ const BasicUserInfo: React.FC<{
// hide the Roles section for DMs as it doesn't make sense there
if (!DMRoomMap.shared().getUserIdForRoomId((member as RoomMember).roomId)) {
memberDetails = <div className="mx_UserInfo_container">
<h3>{ _t("Role") }</h3>
<h3>{ _t("Role in <RoomName/>", {}, {
RoomName: () => <b>{ room.name }</b>,
}) }</h3>
<PowerLevelSection
powerLevels={powerLevels}
user={member as RoomMember}
@ -1326,10 +1329,10 @@ const BasicUserInfo: React.FC<{
if (!isRoomEncrypted) {
if (!cryptoEnabled) {
text = _t("This client does not support end-to-end encryption.");
} else if (room && (!SettingsStore.getValue("feature_spaces") || !room.isSpaceRoom())) {
} else if (room && (!SpaceStore.spacesEnabled || !room.isSpaceRoom())) {
text = _t("Messages in this room are not end-to-end encrypted.");
}
} else if (!SettingsStore.getValue("feature_spaces") || !room.isSpaceRoom()) {
} else if (!SpaceStore.spacesEnabled || !room.isSpaceRoom()) {
text = _t("Messages in this room are end-to-end encrypted.");
}
@ -1352,14 +1355,17 @@ const BasicUserInfo: React.FC<{
if (hasCrossSigningKeys !== undefined) {
// Note: mx_UserInfo_verifyButton is for the end-to-end tests
verifyButton = (
<AccessibleButton className="mx_UserInfo_field mx_UserInfo_verifyButton" onClick={() => {
if (hasCrossSigningKeys) {
verifyUser(member as User);
} else {
legacyVerifyUser(member as User);
}
}}>
{_t("Verify")}
<AccessibleButton
className="mx_UserInfo_field mx_UserInfo_verifyButton"
onClick={() => {
if (hasCrossSigningKeys) {
verifyUser(member as User);
} else {
legacyVerifyUser(member as User);
}
}}
>
{ _t("Verify") }
</AccessibleButton>
);
} else if (!showDeviceListSpinner) {
@ -1373,12 +1379,15 @@ const BasicUserInfo: React.FC<{
let editDevices;
if (member.userId == cli.getUserId()) {
editDevices = (<p>
<AccessibleButton className="mx_UserInfo_field" onClick={() => {
dis.dispatch({
action: Action.ViewUserSettings,
initialTabId: UserTab.Security,
});
}}>
<AccessibleButton
className="mx_UserInfo_field"
onClick={() => {
dis.dispatch({
action: Action.ViewUserSettings,
initialTabId: UserTab.Security,
});
}}
>
{ _t("Edit devices") }
</AccessibleButton>
</p>);
@ -1405,7 +1414,7 @@ const BasicUserInfo: React.FC<{
canInvite={roomPermissions.canInvite}
isIgnored={isIgnored}
member={member as RoomMember}
isSpace={SettingsStore.getValue("feature_spaces") && room?.isSpaceRoom()}
isSpace={SpaceStore.spacesEnabled && room?.isSpaceRoom()}
/>
{ adminToolsContainer }
@ -1517,8 +1526,8 @@ const UserInfoHeader: React.FC<{
</div>
<div>{ member.userId }</div>
<div className="mx_UserInfo_profileStatus">
{presenceLabel}
{statusLabel}
{ presenceLabel }
{ statusLabel }
</div>
</div>
</div>
@ -1566,11 +1575,12 @@ const UserInfo: React.FC<IProps> = ({
// We have no previousPhase for when viewing a UserInfo from a Group or without a Room at this time
if (room && phase === RightPanelPhases.EncryptionPanel) {
previousPhase = RightPanelPhases.RoomMemberInfo;
refireParams = { member: member };
refireParams = { member };
} else if (room?.isSpaceRoom() && SpaceStore.spacesEnabled) {
previousPhase = previousPhase = RightPanelPhases.SpaceMemberList;
refireParams = { space: room };
} else if (room) {
previousPhase = previousPhase = SettingsStore.getValue("feature_spaces") && room.isSpaceRoom()
? RightPanelPhases.SpaceMemberList
: RightPanelPhases.RoomMemberList;
previousPhase = RightPanelPhases.RoomMemberList;
}
const onEncryptionPanelClose = () => {
@ -1617,7 +1627,7 @@ const UserInfo: React.FC<IProps> = ({
}
let scopeHeader;
if (SettingsStore.getValue("feature_spaces") && room?.isSpaceRoom()) {
if (SpaceStore.spacesEnabled && room?.isSpaceRoom()) {
scopeHeader = <div className="mx_RightPanel_scopeHeader">
<RoomAvatar room={room} height={32} width={32} />
<RoomName room={room} />

View file

@ -29,43 +29,27 @@ import VerificationQRCode from "../elements/crypto/VerificationQRCode";
import { _t } from "../../../languageHandler";
import SdkConfig from "../../../SdkConfig";
import E2EIcon from "../rooms/E2EIcon";
import {
PHASE_READY,
PHASE_DONE,
PHASE_STARTED,
PHASE_CANCELLED,
} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
import { Phase } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
import Spinner from "../elements/Spinner";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import AccessibleButton from "../elements/AccessibleButton";
import VerificationShowSas from "../verification/VerificationShowSas";
// XXX: Should be defined in matrix-js-sdk
enum VerificationPhase {
PHASE_UNSENT,
PHASE_REQUESTED,
PHASE_READY,
PHASE_DONE,
PHASE_STARTED,
PHASE_CANCELLED,
}
interface IProps {
layout: string;
request: VerificationRequest;
member: RoomMember | User;
phase: VerificationPhase;
phase: Phase;
onClose: () => void;
isRoomEncrypted: boolean;
inDialog: boolean;
key: number;
}
interface IState {
sasEvent?: SAS;
sasEvent?: SAS["sasEvent"];
emojiButtonClicked?: boolean;
reciprocateButtonClicked?: boolean;
reciprocateQREvent?: ReciprocateQRCode;
reciprocateQREvent?: ReciprocateQRCode["reciprocateQREvent"];
}
@replaceableComponent("views.right_panel.VerificationPanel")
@ -85,12 +69,12 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
const brand = SdkConfig.get().brand;
const noCommonMethodError: JSX.Element = !showSAS && !showQR ?
<p>{_t(
<p>{ _t(
"The session you are trying to verify doesn't support scanning a " +
"QR code or emoji verification, which is what %(brand)s supports. Try " +
"with a different client.",
{ brand },
)}</p> :
) }</p> :
null;
if (this.props.layout === 'dialog') {
@ -100,31 +84,31 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
if (showQR) {
qrBlockDialog =
<div className='mx_VerificationPanel_QRPhase_startOption'>
<p>{_t("Scan this unique code")}</p>
<p>{ _t("Scan this unique code") }</p>
<VerificationQRCode qrCodeData={request.qrCodeData} />
</div>;
}
if (showSAS) {
sasBlockDialog = <div className='mx_VerificationPanel_QRPhase_startOption'>
<p>{_t("Compare unique emoji")}</p>
<p>{ _t("Compare unique emoji") }</p>
<span className='mx_VerificationPanel_QRPhase_helpText'>
{_t("Compare a unique set of emoji if you don't have a camera on either device")}
{ _t("Compare a unique set of emoji if you don't have a camera on either device") }
</span>
<AccessibleButton disabled={this.state.emojiButtonClicked} onClick={this.startSAS} kind='primary'>
{_t("Start")}
{ _t("Start") }
</AccessibleButton>
</div>;
}
const or = qrBlockDialog && sasBlockDialog ?
<div className='mx_VerificationPanel_QRPhase_betweenText'>{_t("or")}</div> : null;
<div className='mx_VerificationPanel_QRPhase_betweenText'>{ _t("or") }</div> : null;
return (
<div>
{_t("Verify this session by completing one of the following:")}
{ _t("Verify this session by completing one of the following:") }
<div className='mx_VerificationPanel_QRPhase_startOptions'>
{qrBlockDialog}
{or}
{sasBlockDialog}
{noCommonMethodError}
{ qrBlockDialog }
{ or }
{ sasBlockDialog }
{ noCommonMethodError }
</div>
</div>
);
@ -133,10 +117,10 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
let qrBlock: JSX.Element;
if (showQR) {
qrBlock = <div className="mx_UserInfo_container">
<h3>{_t("Verify by scanning")}</h3>
<p>{_t("Ask %(displayName)s to scan your code:", {
<h3>{ _t("Verify by scanning") }</h3>
<p>{ _t("Ask %(displayName)s to scan your code:", {
displayName: (member as User).displayName || (member as RoomMember).name || member.userId,
})}</p>
}) }</p>
<div className="mx_VerificationPanel_qrCode">
<VerificationQRCode qrCodeData={request.qrCodeData} />
@ -153,28 +137,28 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
// Note: mx_VerificationPanel_verifyByEmojiButton is for the end-to-end tests
sasBlock = <div className="mx_UserInfo_container">
<h3>{_t("Verify by emoji")}</h3>
<p>{sasLabel}</p>
<h3>{ _t("Verify by emoji") }</h3>
<p>{ sasLabel }</p>
<AccessibleButton
disabled={disabled}
kind="primary"
className="mx_UserInfo_wideButton mx_VerificationPanel_verifyByEmojiButton"
onClick={this.startSAS}
>
{_t("Verify by emoji")}
{ _t("Verify by emoji") }
</AccessibleButton>
</div>;
}
const noCommonMethodBlock = noCommonMethodError ?
<div className="mx_UserInfo_container">{noCommonMethodError}</div> :
<div className="mx_UserInfo_container">{ noCommonMethodError }</div> :
null;
// TODO: add way to open camera to scan a QR code
return <React.Fragment>
{qrBlock}
{sasBlock}
{noCommonMethodBlock}
{ qrBlock }
{ sasBlock }
{ noCommonMethodBlock }
</React.Fragment>;
}
@ -204,7 +188,7 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
if (this.state.reciprocateQREvent) {
// Element Web doesn't support scanning yet, so assume here we're the client being scanned.
body = <React.Fragment>
<p>{description}</p>
<p>{ description }</p>
<E2EIcon isUser={true} status="verified" size={128} hideTooltip={true} />
<div className="mx_VerificationPanel_reciprocateButtons">
<AccessibleButton
@ -227,7 +211,7 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
body = <p><Spinner /></p>;
}
return <div className="mx_UserInfo_container mx_VerificationPanel_reciprocate_section">
<h3>{_t("Verify by scanning")}</h3>
<h3>{ _t("Verify by scanning") }</h3>
{ body }
</div>;
}
@ -266,12 +250,12 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
return (
<div className="mx_UserInfo_container mx_VerificationPanel_verified_section">
<h3>{_t("Verified")}</h3>
<p>{description}</p>
<h3>{ _t("Verified") }</h3>
<p>{ description }</p>
<E2EIcon isUser={true} status="verified" size={128} hideTooltip={true} />
{ text ? <p>{ text }</p> : null }
<AccessibleButton kind="primary" className="mx_UserInfo_wideButton" onClick={this.props.onClose}>
{_t("Got it")}
{ _t("Got it") }
</AccessibleButton>
</div>
);
@ -305,11 +289,11 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
return (
<div className="mx_UserInfo_container">
<h3>{_t("Verification cancelled")}</h3>
<h3>{ _t("Verification cancelled") }</h3>
<p>{ text }</p>
<AccessibleButton kind="primary" className="mx_UserInfo_wideButton" onClick={this.props.onClose}>
{_t("Got it")}
{ _t("Got it") }
</AccessibleButton>
</div>
);
@ -321,9 +305,9 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
const displayName = (member as User).displayName || (member as RoomMember).name || member.userId;
switch (phase) {
case PHASE_READY:
case Phase.Ready:
return this.renderQRPhase();
case PHASE_STARTED:
case Phase.Started:
switch (request.chosenMethod) {
case verificationMethods.RECIPROCATE_QR_CODE:
return this.renderQRReciprocatePhase();
@ -339,16 +323,16 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
isSelf={request.isSelfVerification}
/> : <Spinner />;
return <div className="mx_UserInfo_container">
<h3>{_t("Compare emoji")}</h3>
<h3>{ _t("Compare emoji") }</h3>
{ emojis }
</div>;
}
default:
return null;
}
case PHASE_DONE:
case Phase.Done:
return this.renderVerifiedPhase();
case PHASE_CANCELLED:
case Phase.Cancelled:
return this.renderCancelledPhase();
}
console.error("VerificationPanel unhandled phase:", phase);
@ -375,7 +359,8 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
private updateVerifierState = () => {
const { request } = this.props;
const { sasEvent, reciprocateQREvent } = request.verifier;
const sasEvent = (request.verifier as SAS).sasEvent;
const reciprocateQREvent = (request.verifier as ReciprocateQRCode).reciprocateQREvent;
request.verifier.off('show_sas', this.updateVerifierState);
request.verifier.off('show_reciprocate_qr', this.updateVerifierState);
this.setState({ sasEvent, reciprocateQREvent });
@ -402,7 +387,8 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
const { request } = this.props;
request.on("change", this.onRequestChange);
if (request.verifier) {
const { sasEvent, reciprocateQREvent } = request.verifier;
const sasEvent = (request.verifier as SAS).sasEvent;
const reciprocateQREvent = (request.verifier as ReciprocateQRCode).reciprocateQREvent;
this.setState({ sasEvent, reciprocateQREvent });
}
this.onRequestChange();