mirror of
https://github.com/element-hq/element-web
synced 2024-11-27 11:47:23 +03:00
Merge pull request #6229 from matrix-org/gsouquet/fix-17678
This commit is contained in:
commit
9dee75a7b1
11 changed files with 66 additions and 148 deletions
|
@ -123,7 +123,6 @@
|
||||||
@import "./views/elements/_EventListSummary.scss";
|
@import "./views/elements/_EventListSummary.scss";
|
||||||
@import "./views/elements/_FacePile.scss";
|
@import "./views/elements/_FacePile.scss";
|
||||||
@import "./views/elements/_Field.scss";
|
@import "./views/elements/_Field.scss";
|
||||||
@import "./views/elements/_FormButton.scss";
|
|
||||||
@import "./views/elements/_ImageView.scss";
|
@import "./views/elements/_ImageView.scss";
|
||||||
@import "./views/elements/_InfoTooltip.scss";
|
@import "./views/elements/_InfoTooltip.scss";
|
||||||
@import "./views/elements/_InlineSpinner.scss";
|
@import "./views/elements/_InlineSpinner.scss";
|
||||||
|
|
|
@ -134,8 +134,9 @@ limitations under the License.
|
||||||
.mx_Toast_buttons {
|
.mx_Toast_buttons {
|
||||||
float: right;
|
float: right;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: 5px;
|
||||||
|
|
||||||
.mx_FormButton {
|
.mx_AccessibleButton {
|
||||||
min-width: 96px;
|
min-width: 96px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2019 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.mx_FormButton {
|
|
||||||
line-height: $font-16px;
|
|
||||||
padding: 5px 15px;
|
|
||||||
font-size: $font-12px;
|
|
||||||
height: min-content;
|
|
||||||
|
|
||||||
&:not(:last-child) {
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.mx_AccessibleButton_kind_primary {
|
|
||||||
color: $accent-color;
|
|
||||||
background-color: $accent-bg-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.mx_AccessibleButton_kind_danger {
|
|
||||||
color: $notice-primary-color;
|
|
||||||
background-color: $notice-primary-bg-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.mx_AccessibleButton_kind_secondary {
|
|
||||||
color: $secondary-fg-color;
|
|
||||||
border: 1px solid $secondary-fg-color;
|
|
||||||
background-color: unset;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -259,16 +259,6 @@ limitations under the License.
|
||||||
|
|
||||||
.mx_AccessibleButton.mx_AccessibleButton_hasKind {
|
.mx_AccessibleButton.mx_AccessibleButton_hasKind {
|
||||||
padding: 8px 18px;
|
padding: 8px 18px;
|
||||||
|
|
||||||
&.mx_AccessibleButton_kind_primary {
|
|
||||||
color: $accent-color;
|
|
||||||
background-color: $accent-bg-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.mx_AccessibleButton_kind_danger {
|
|
||||||
color: $notice-primary-color;
|
|
||||||
background-color: $notice-primary-bg-color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_VerificationShowSas .mx_AccessibleButton,
|
.mx_VerificationShowSas .mx_AccessibleButton,
|
||||||
|
|
|
@ -58,7 +58,7 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_VerificationPanel_reciprocate_section {
|
.mx_VerificationPanel_reciprocate_section {
|
||||||
.mx_FormButton {
|
.mx_AccessibleButton {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
|
@ -73,7 +73,7 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_FormButton {
|
.mx_AccessibleButton {
|
||||||
padding: 8px 22px;
|
padding: 8px 22px;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2019 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 AccessibleButton from "./AccessibleButton";
|
|
||||||
|
|
||||||
export default function FormButton(props) {
|
|
||||||
const {className, label, kind, ...restProps} = props;
|
|
||||||
const newClassName = (className || "") + " mx_FormButton";
|
|
||||||
const allProps = Object.assign({}, restProps,
|
|
||||||
{className: newClassName, kind: kind || "primary", children: [label]});
|
|
||||||
return React.createElement(AccessibleButton, allProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
FormButton.propTypes = AccessibleButton.propTypes;
|
|
|
@ -15,41 +15,40 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import { MatrixEvent } from 'matrix-js-sdk/src';
|
||||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||||
import * as sdk from '../../../index';
|
import * as sdk from '../../../index';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import {getNameForEventRoom, userLabelForEventRoom}
|
import { getNameForEventRoom, userLabelForEventRoom }
|
||||||
from '../../../utils/KeyVerificationStateObserver';
|
from '../../../utils/KeyVerificationStateObserver';
|
||||||
import dis from "../../../dispatcher/dispatcher";
|
import dis from "../../../dispatcher/dispatcher";
|
||||||
import {RightPanelPhases} from "../../../stores/RightPanelStorePhases";
|
import { RightPanelPhases } from "../../../stores/RightPanelStorePhases";
|
||||||
import {Action} from "../../../dispatcher/actions";
|
import { Action } from "../../../dispatcher/actions";
|
||||||
import EventTileBubble from "./EventTileBubble";
|
import EventTileBubble from "./EventTileBubble";
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
mxEvent: MatrixEvent
|
||||||
|
}
|
||||||
|
|
||||||
@replaceableComponent("views.messages.MKeyVerificationRequest")
|
@replaceableComponent("views.messages.MKeyVerificationRequest")
|
||||||
export default class MKeyVerificationRequest extends React.Component {
|
export default class MKeyVerificationRequest extends React.Component<IProps> {
|
||||||
constructor(props) {
|
public componentDidMount() {
|
||||||
super(props);
|
|
||||||
this.state = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
const request = this.props.mxEvent.verificationRequest;
|
const request = this.props.mxEvent.verificationRequest;
|
||||||
if (request) {
|
if (request) {
|
||||||
request.on("change", this._onRequestChanged);
|
request.on("change", this.onRequestChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
public componentWillUnmount() {
|
||||||
const request = this.props.mxEvent.verificationRequest;
|
const request = this.props.mxEvent.verificationRequest;
|
||||||
if (request) {
|
if (request) {
|
||||||
request.off("change", this._onRequestChanged);
|
request.off("change", this.onRequestChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_openRequest = () => {
|
private openRequest = () => {
|
||||||
const {verificationRequest} = this.props.mxEvent;
|
const { verificationRequest } = this.props.mxEvent;
|
||||||
const member = MatrixClientPeg.get().getUser(verificationRequest.otherUserId);
|
const member = MatrixClientPeg.get().getUser(verificationRequest.otherUserId);
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: Action.SetRightPanelPhase,
|
action: Action.SetRightPanelPhase,
|
||||||
|
@ -58,15 +57,15 @@ export default class MKeyVerificationRequest extends React.Component {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
_onRequestChanged = () => {
|
private onRequestChanged = () => {
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
};
|
};
|
||||||
|
|
||||||
_onAcceptClicked = async () => {
|
private onAcceptClicked = async () => {
|
||||||
const request = this.props.mxEvent.verificationRequest;
|
const request = this.props.mxEvent.verificationRequest;
|
||||||
if (request) {
|
if (request) {
|
||||||
try {
|
try {
|
||||||
this._openRequest();
|
this.openRequest();
|
||||||
await request.accept();
|
await request.accept();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err.message);
|
console.error(err.message);
|
||||||
|
@ -74,7 +73,7 @@ export default class MKeyVerificationRequest extends React.Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_onRejectClicked = async () => {
|
private onRejectClicked = async () => {
|
||||||
const request = this.props.mxEvent.verificationRequest;
|
const request = this.props.mxEvent.verificationRequest;
|
||||||
if (request) {
|
if (request) {
|
||||||
try {
|
try {
|
||||||
|
@ -85,7 +84,7 @@ export default class MKeyVerificationRequest extends React.Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_acceptedLabel(userId) {
|
private acceptedLabel(userId: string) {
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
const myUserId = client.getUserId();
|
const myUserId = client.getUserId();
|
||||||
if (userId === myUserId) {
|
if (userId === myUserId) {
|
||||||
|
@ -95,7 +94,7 @@ export default class MKeyVerificationRequest extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_cancelledLabel(userId) {
|
private cancelledLabel(userId: string) {
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
const myUserId = client.getUserId();
|
const myUserId = client.getUserId();
|
||||||
const {cancellationCode} = this.props.mxEvent.verificationRequest;
|
const {cancellationCode} = this.props.mxEvent.verificationRequest;
|
||||||
|
@ -115,9 +114,8 @@ export default class MKeyVerificationRequest extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
public render() {
|
||||||
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
|
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
|
||||||
const FormButton = sdk.getComponent("elements.FormButton");
|
|
||||||
|
|
||||||
const {mxEvent} = this.props;
|
const {mxEvent} = this.props;
|
||||||
const request = mxEvent.verificationRequest;
|
const request = mxEvent.verificationRequest;
|
||||||
|
@ -134,11 +132,11 @@ export default class MKeyVerificationRequest extends React.Component {
|
||||||
let stateLabel;
|
let stateLabel;
|
||||||
const accepted = request.ready || request.started || request.done;
|
const accepted = request.ready || request.started || request.done;
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
stateLabel = (<AccessibleButton onClick={this._openRequest}>
|
stateLabel = (<AccessibleButton onClick={this.openRequest}>
|
||||||
{this._acceptedLabel(request.receivingUserId)}
|
{this.acceptedLabel(request.receivingUserId)}
|
||||||
</AccessibleButton>);
|
</AccessibleButton>);
|
||||||
} else if (request.cancelled) {
|
} else if (request.cancelled) {
|
||||||
stateLabel = this._cancelledLabel(request.cancellingUserId);
|
stateLabel = this.cancelledLabel(request.cancellingUserId);
|
||||||
} else if (request.accepting) {
|
} else if (request.accepting) {
|
||||||
stateLabel = _t("Accepting …");
|
stateLabel = _t("Accepting …");
|
||||||
} else if (request.declining) {
|
} else if (request.declining) {
|
||||||
|
@ -153,8 +151,12 @@ export default class MKeyVerificationRequest extends React.Component {
|
||||||
subtitle = userLabelForEventRoom(request.requestingUserId, mxEvent.getRoomId());
|
subtitle = userLabelForEventRoom(request.requestingUserId, mxEvent.getRoomId());
|
||||||
if (request.canAccept) {
|
if (request.canAccept) {
|
||||||
stateNode = (<div className="mx_cryptoEvent_buttons">
|
stateNode = (<div className="mx_cryptoEvent_buttons">
|
||||||
<FormButton kind="danger" onClick={this._onRejectClicked} label={_t("Decline")} />
|
<AccessibleButton kind="danger" onClick={this.onRejectClicked}>
|
||||||
<FormButton onClick={this._onAcceptClicked} label={_t("Accept")} />
|
{_t("Decline")}
|
||||||
|
</AccessibleButton>
|
||||||
|
<AccessibleButton onClick={this.onAcceptClicked}>
|
||||||
|
{_t("Accept")}
|
||||||
|
</AccessibleButton>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
} else { // request sent by us
|
} else { // request sent by us
|
||||||
|
@ -174,8 +176,3 @@ export default class MKeyVerificationRequest extends React.Component {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MKeyVerificationRequest.propTypes = {
|
|
||||||
/* the MatrixEvent to show */
|
|
||||||
mxEvent: PropTypes.object.isRequired,
|
|
||||||
};
|
|
|
@ -195,14 +195,7 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
|
||||||
|
|
||||||
private renderQRReciprocatePhase() {
|
private renderQRReciprocatePhase() {
|
||||||
const {member, request} = this.props;
|
const {member, request} = this.props;
|
||||||
let Button;
|
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
|
||||||
// a bit of a hack, but the FormButton should only be used in the right panel
|
|
||||||
// they should probably just be the same component with a css class applied to it?
|
|
||||||
if (this.props.inDialog) {
|
|
||||||
Button = sdk.getComponent("elements.AccessibleButton");
|
|
||||||
} else {
|
|
||||||
Button = sdk.getComponent("elements.FormButton");
|
|
||||||
}
|
|
||||||
const description = request.isSelfVerification ?
|
const description = request.isSelfVerification ?
|
||||||
_t("Almost there! Is your other session showing the same shield?") :
|
_t("Almost there! Is your other session showing the same shield?") :
|
||||||
_t("Almost there! Is %(displayName)s showing the same shield?", {
|
_t("Almost there! Is %(displayName)s showing the same shield?", {
|
||||||
|
@ -211,21 +204,24 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
|
||||||
let body: JSX.Element;
|
let body: JSX.Element;
|
||||||
if (this.state.reciprocateQREvent) {
|
if (this.state.reciprocateQREvent) {
|
||||||
// Element Web doesn't support scanning yet, so assume here we're the client being scanned.
|
// Element Web doesn't support scanning yet, so assume here we're the client being scanned.
|
||||||
//
|
|
||||||
// we're passing both a label and a child string to Button as
|
|
||||||
// FormButton and AccessibleButton expect this differently
|
|
||||||
body = <React.Fragment>
|
body = <React.Fragment>
|
||||||
<p>{description}</p>
|
<p>{description}</p>
|
||||||
<E2EIcon isUser={true} status="verified" size={128} hideTooltip={true} />
|
<E2EIcon isUser={true} status="verified" size={128} hideTooltip={true} />
|
||||||
<div className="mx_VerificationPanel_reciprocateButtons">
|
<div className="mx_VerificationPanel_reciprocateButtons">
|
||||||
<Button
|
<AccessibleButton
|
||||||
label={_t("No")} kind="danger"
|
kind="danger"
|
||||||
disabled={this.state.reciprocateButtonClicked}
|
disabled={this.state.reciprocateButtonClicked}
|
||||||
onClick={this.onReciprocateNoClick}>{_t("No")}</Button>
|
onClick={this.onReciprocateNoClick}
|
||||||
<Button
|
>
|
||||||
label={_t("Yes")} kind="primary"
|
{ _t("No") }
|
||||||
|
</AccessibleButton>
|
||||||
|
<AccessibleButton
|
||||||
|
kind="primary"
|
||||||
disabled={this.state.reciprocateButtonClicked}
|
disabled={this.state.reciprocateButtonClicked}
|
||||||
onClick={this.onReciprocateYesClick}>{_t("Yes")}</Button>
|
onClick={this.onReciprocateYesClick}
|
||||||
|
>
|
||||||
|
{ _t("Yes") }
|
||||||
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -15,8 +15,8 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {ReactNode} from "react";
|
import React, {ReactNode} from "react";
|
||||||
|
import AccessibleButton from "../elements/AccessibleButton";
|
||||||
|
|
||||||
import FormButton from "../elements/FormButton";
|
|
||||||
import {XOR} from "../../../@types/common";
|
import {XOR} from "../../../@types/common";
|
||||||
|
|
||||||
export interface IProps {
|
export interface IProps {
|
||||||
|
@ -50,8 +50,12 @@ const GenericToast: React.FC<XOR<IPropsExtended, IProps>> = ({
|
||||||
{detailContent}
|
{detailContent}
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Toast_buttons" aria-live="off">
|
<div className="mx_Toast_buttons" aria-live="off">
|
||||||
{onReject && rejectLabel && <FormButton label={rejectLabel} kind="danger" onClick={onReject} /> }
|
{onReject && rejectLabel && <AccessibleButton kind="danger" onClick={onReject}>
|
||||||
<FormButton label={acceptLabel} onClick={onAccept} />
|
{ rejectLabel }
|
||||||
|
</AccessibleButton> }
|
||||||
|
<AccessibleButton onClick={onAccept} kind="primary">
|
||||||
|
{ acceptLabel }
|
||||||
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { _t } from '../../../languageHandler';
|
||||||
import { ActionPayload } from '../../../dispatcher/payloads';
|
import { ActionPayload } from '../../../dispatcher/payloads';
|
||||||
import CallHandler, { AudioID } from '../../../CallHandler';
|
import CallHandler, { AudioID } from '../../../CallHandler';
|
||||||
import RoomAvatar from '../avatars/RoomAvatar';
|
import RoomAvatar from '../avatars/RoomAvatar';
|
||||||
import FormButton from '../elements/FormButton';
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
import { CallState } from 'matrix-js-sdk/src/webrtc/call';
|
import { CallState } from 'matrix-js-sdk/src/webrtc/call';
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||||
import AccessibleTooltipButton from '../elements/AccessibleTooltipButton';
|
import AccessibleTooltipButton from '../elements/AccessibleTooltipButton';
|
||||||
|
@ -143,21 +143,22 @@ export default class IncomingCallBox extends React.Component<IProps, IState> {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_IncomingCallBox_buttons">
|
<div className="mx_IncomingCallBox_buttons">
|
||||||
<FormButton
|
<AccessibleButton
|
||||||
className={"mx_IncomingCallBox_decline"}
|
className={"mx_IncomingCallBox_decline"}
|
||||||
onClick={this.onRejectClick}
|
onClick={this.onRejectClick}
|
||||||
kind="danger"
|
kind="danger"
|
||||||
label={_t("Decline")}
|
>
|
||||||
/>
|
{ _t("Decline") }
|
||||||
|
</AccessibleButton>
|
||||||
<div className="mx_IncomingCallBox_spacer" />
|
<div className="mx_IncomingCallBox_spacer" />
|
||||||
<FormButton
|
<AccessibleButton
|
||||||
className={"mx_IncomingCallBox_accept"}
|
className={"mx_IncomingCallBox_accept"}
|
||||||
onClick={this.onAnswerClick}
|
onClick={this.onAnswerClick}
|
||||||
kind="primary"
|
kind="primary"
|
||||||
label={_t("Accept")}
|
>
|
||||||
/>
|
{ _t("Accept") }
|
||||||
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue