From e8c21a341cf8dc96f3f57b8824bf5d78663ad660 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 7 Nov 2019 17:40:22 +0100 Subject: [PATCH] add key verification conclusion tile --- .../messages/MKeyVerificationConclusion.js | 130 ++++++++++++++++++ src/i18n/strings/en_EN.json | 10 ++ 2 files changed, 140 insertions(+) create mode 100644 src/components/views/messages/MKeyVerificationConclusion.js diff --git a/src/components/views/messages/MKeyVerificationConclusion.js b/src/components/views/messages/MKeyVerificationConclusion.js new file mode 100644 index 0000000000..e955d6159d --- /dev/null +++ b/src/components/views/messages/MKeyVerificationConclusion.js @@ -0,0 +1,130 @@ +/* +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 classNames from 'classnames'; +import PropTypes from 'prop-types'; +import MatrixClientPeg from '../../../MatrixClientPeg'; +import { _t } from '../../../languageHandler'; +import KeyVerificationStateObserver, {getNameForEventRoom, userLabelForEventRoom} + from '../../../utils/KeyVerificationStateObserver'; + +export default class MKeyVerificationConclusion extends React.Component { + constructor(props) { + super(props); + this.keyVerificationState = null; + this.state = { + done: false, + cancelled: false, + otherPartyUserId: null, + cancelPartyUserId: null, + }; + const rel = this.props.mxEvent.getRelation(); + if (rel) { + const client = MatrixClientPeg.get(); + const room = client.getRoom(this.props.mxEvent.getRoomId()); + const requestEvent = room.findEventById(rel.event_id); + if (requestEvent) { + this._createStateObserver(requestEvent, client); + this.state = this._copyState(); + } else { + const findEvent = event => { + if (event.getId() === rel.event_id) { + this._createStateObserver(event, client); + this.setState(this._copyState()); + room.removeListener("Room.timeline", findEvent); + } + }; + room.on("Room.timeline", findEvent); + } + } + } + + _createStateObserver(requestEvent, client) { + this.keyVerificationState = new KeyVerificationStateObserver(requestEvent, client, () => { + this.setState(this._copyState()); + }); + } + + _copyState() { + const {done, cancelled, otherPartyUserId, cancelPartyUserId} = this.keyVerificationState; + return {done, cancelled, otherPartyUserId, cancelPartyUserId}; + } + + componentDidMount() { + if (this.keyVerificationState) { + this.keyVerificationState.attach(); + } + } + + componentWillUnmount() { + if (this.keyVerificationState) { + this.keyVerificationState.detach(); + } + } + + _getName(userId) { + const roomId = this.props.mxEvent.getRoomId(); + const client = MatrixClientPeg.get(); + const room = client.getRoom(roomId); + const member = room.getMember(userId); + return member ? member.name : userId; + } + + _userLabel(userId) { + const name = this._getName(userId); + if (name !== userId) { + return _t("%(name)s (%(userId)s)", {name, userId}); + } else { + return userId; + } + } + + render() { + const {mxEvent} = this.props; + const client = MatrixClientPeg.get(); + const myUserId = client.getUserId(); + let title; + + if (this.state.done) { + title = _t("You verified %(name)s", {name: getNameForEventRoom(this.state.otherPartyUserId, mxEvent)}); + } else if (this.state.cancelled) { + if (mxEvent.getSender() === myUserId) { + title = _t("You cancelled verifying %(name)s", {name: getNameForEventRoom(this.state.otherPartyUserId, mxEvent)}); + } else if (mxEvent.getSender() === this.state.otherPartyUserId) { + title = _t("%(name)s cancelled verifying", {name: getNameForEventRoom(this.state.otherPartyUserId, mxEvent)}); + } + } + + if (title) { + const subtitle = userLabelForEventRoom(this.state.otherPartyUserId, mxEvent); + const classes = classNames("mx_EventTile_bubble", "mx_KeyVerification", "mx_KeyVerification_icon", { + mx_KeyVerification_icon_verified: this.state.done, + }); + return (
+
{title}
+
{subtitle}
+
); + } + + return null; + } +} + +MKeyVerificationConclusion.propTypes = { + /* the MatrixEvent to show */ + mxEvent: PropTypes.object.isRequired, +}; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index bcf68f8e4b..1dcd2a5129 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1065,6 +1065,16 @@ "Invalid file%(extra)s": "Invalid file%(extra)s", "Error decrypting image": "Error decrypting image", "Show image": "Show image", + "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", + "You verified %(name)s": "You verified %(name)s", + "You cancelled verifying %(name)s": "You cancelled verifying %(name)s", + "%(name)s cancelled verifying": "%(name)s cancelled verifying", + "You accepted": "You accepted", + "%(name)s accepted": "%(name)s accepted", + "You cancelled": "You cancelled", + "%(name)s cancelled": "%(name)s cancelled", + "%(name)s wants to verify": "%(name)s wants to verify", + "You sent a verification request": "You sent a verification request", "Error decrypting video": "Error decrypting video", "Show all": "Show all", "reacted with %(shortName)s": "reacted with %(shortName)s",