From 72789897a0780f3ca2f2bdc7be7b2f3760325456 Mon Sep 17 00:00:00 2001 From: Zoe Date: Fri, 21 Feb 2020 17:15:53 +0000 Subject: [PATCH 1/6] Quick n dirty verificatio request viewer in devtools --- res/css/views/dialogs/_DevtoolsDialog.scss | 34 ++++++++ .../views/dialogs/DevtoolsDialog.js | 82 ++++++++++++++++++- src/i18n/strings/en_EN.json | 1 + 3 files changed, 116 insertions(+), 1 deletion(-) diff --git a/res/css/views/dialogs/_DevtoolsDialog.scss b/res/css/views/dialogs/_DevtoolsDialog.scss index 9d58c999c3..22975f0c52 100644 --- a/res/css/views/dialogs/_DevtoolsDialog.scss +++ b/res/css/views/dialogs/_DevtoolsDialog.scss @@ -189,3 +189,37 @@ limitations under the License. } } } + +.mx_DevTools_VerificationRequest { + border: 1px solid #cccccc; + border-radius: 3px; + padding: 1px 5px; + margin-bottom: 6px; + font-family: "Inconsolata", courier; + + dl { + display: grid; + grid-template-columns: max-content auto; + margin: 0; + } + + dd { + grid-column-start: 2; + } + + dd:empty { + color: #666666; + &::after { + content: "(empty)"; + } + } + + dt { + font-weight: bold; + grid-column-start: 1; + } + + dt::after { + content: ":"; + } +} \ No newline at end of file diff --git a/src/components/views/dialogs/DevtoolsDialog.js b/src/components/views/dialogs/DevtoolsDialog.js index 34b2f5a52b..ade23c90f1 100644 --- a/src/components/views/dialogs/DevtoolsDialog.js +++ b/src/components/views/dialogs/DevtoolsDialog.js @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React from 'react'; +import React, {useState, useEffect} from 'react'; import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import SyntaxHighlight from '../elements/SyntaxHighlight'; @@ -23,6 +23,15 @@ import { Room } from "matrix-js-sdk"; import Field from "../elements/Field"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; +import { + PHASE_UNSENT, + PHASE_REQUESTED, + PHASE_READY, + PHASE_DONE, + PHASE_STARTED, + PHASE_CANCELLED, +} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest" + class GenericEditor extends React.PureComponent { // static propTypes = {onBack: PropTypes.func.isRequired}; @@ -605,12 +614,83 @@ class ServersInRoomList extends React.PureComponent { } } +const PHASE_MAP = { + [PHASE_UNSENT]: "unsent", + [PHASE_REQUESTED]: "requested", + [PHASE_READY]: "ready", + [PHASE_DONE]: "done", + [PHASE_STARTED]: "started", + [PHASE_CANCELLED]: "cancelled", +} + +function VerificationRequest({txnId, request}) { + const [, updateState] = useState(); + const [timeout, setTimeout] = useState(request.timeout); + + /* Re-render if something changes state */ + useEffect(() => { + request.on("change", updateState); + return () => request.off("change", updateState); + }, []); + + /* Keep re-rendering if there's a timeout */ + useEffect(() => { + if (timeout == 0) return; + + const id = setInterval(() => { + setTimeout(request.timeout); + }, 500); + + return () => { clearInterval(id); } + }, []); + + return (
+
+
Transaction
+
{txnId}
+
Phase
+
{PHASE_MAP[request.phase] || request.phase}
+
Timeout
+
{Math.floor(timeout / 1000)}
+
Methods
+
{request.methods && request.methods.join(", ")}
+
requestingUserId
+
{request.requestingUserId}
+
+
); +} + +class VerificationExplorer extends React.PureComponent { + static getLabel() { + return _t("Verification Requests"); + } + + /* Ensure this.context is the cli */ + static contextType = MatrixClientContext; + + render() { + const cli = this.context; + const room = this.props.room; + const inRoomChannel = cli._crypto._inRoomVerificationRequests; + const inRoomRequests = (inRoomChannel._requestsByRoomId || new Map()).get(room.roomId) || new Map(); + + return (
+
+ {Array.from(inRoomRequests.entries()).reverse().map(([txnId, request]) => + + )} +
+
); + } +} + const Entries = [ SendCustomEvent, RoomStateExplorer, SendAccountData, AccountDataExplorer, ServersInRoomList, + VerificationExplorer, ]; export default class DevtoolsDialog extends React.PureComponent { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index b55b28ce97..82eb660d9d 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1524,6 +1524,7 @@ "Explore Room State": "Explore Room State", "Explore Account Data": "Explore Account Data", "View Servers in Room": "View Servers in Room", + "Verification Requests": "Verification Requests", "Toolbox": "Toolbox", "Developer Tools": "Developer Tools", "An error has occurred.": "An error has occurred.", From 0663ab3b87455de6dac8d21337e30c68e294492b Mon Sep 17 00:00:00 2001 From: Zoe Date: Mon, 24 Feb 2020 10:17:33 +0000 Subject: [PATCH 2/6] lint, and detect new requests --- res/css/views/dialogs/_DevtoolsDialog.scss | 4 +-- .../views/dialogs/DevtoolsDialog.js | 30 ++++++++++++++----- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/res/css/views/dialogs/_DevtoolsDialog.scss b/res/css/views/dialogs/_DevtoolsDialog.scss index 22975f0c52..500c46b5fd 100644 --- a/res/css/views/dialogs/_DevtoolsDialog.scss +++ b/res/css/views/dialogs/_DevtoolsDialog.scss @@ -195,7 +195,7 @@ limitations under the License. border-radius: 3px; padding: 1px 5px; margin-bottom: 6px; - font-family: "Inconsolata", courier; + font-family: $monospace-font-family; dl { display: grid; @@ -222,4 +222,4 @@ limitations under the License. dt::after { content: ":"; } -} \ No newline at end of file +} diff --git a/src/components/views/dialogs/DevtoolsDialog.js b/src/components/views/dialogs/DevtoolsDialog.js index ade23c90f1..0452e88dfa 100644 --- a/src/components/views/dialogs/DevtoolsDialog.js +++ b/src/components/views/dialogs/DevtoolsDialog.js @@ -30,7 +30,7 @@ import { PHASE_DONE, PHASE_STARTED, PHASE_CANCELLED, -} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest" +} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; class GenericEditor extends React.PureComponent { // static propTypes = {onBack: PropTypes.func.isRequired}; @@ -621,7 +621,7 @@ const PHASE_MAP = { [PHASE_DONE]: "done", [PHASE_STARTED]: "started", [PHASE_CANCELLED]: "cancelled", -} +}; function VerificationRequest({txnId, request}) { const [, updateState] = useState(); @@ -631,18 +631,18 @@ function VerificationRequest({txnId, request}) { useEffect(() => { request.on("change", updateState); return () => request.off("change", updateState); - }, []); + }, [request]); /* Keep re-rendering if there's a timeout */ useEffect(() => { - if (timeout == 0) return; + if (request.timeout == 0) return; const id = setInterval(() => { setTimeout(request.timeout); }, 500); - return () => { clearInterval(id); } - }, []); + return () => { clearInterval(id); }; + }, [request]); return (
@@ -660,7 +660,7 @@ function VerificationRequest({txnId, request}) {
); } -class VerificationExplorer extends React.PureComponent { +class VerificationExplorer extends React.Component { static getLabel() { return _t("Verification Requests"); } @@ -668,6 +668,20 @@ class VerificationExplorer extends React.PureComponent { /* Ensure this.context is the cli */ static contextType = MatrixClientContext; + onNewRequest = () => { + this.forceUpdate(); + } + + componentDidMount() { + const cli = this.context; + cli.on("crypto.verification.request", this.onNewRequest); + } + + componentWillUnmount() { + const cli = this.context; + cli.off("crypto.verification.request", this.onNewRequest); + } + render() { const cli = this.context; const room = this.props.room; @@ -677,7 +691,7 @@ class VerificationExplorer extends React.PureComponent { return (
{Array.from(inRoomRequests.entries()).reverse().map(([txnId, request]) => - + , )}
); From 71bdc5987bf94012f8f10243cdd64b9ba67d9bf7 Mon Sep 17 00:00:00 2001 From: Zoe Date: Mon, 24 Feb 2020 11:33:49 +0000 Subject: [PATCH 3/6] added clarifying comment --- src/components/views/dialogs/DevtoolsDialog.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/dialogs/DevtoolsDialog.js b/src/components/views/dialogs/DevtoolsDialog.js index 0452e88dfa..53edf88698 100644 --- a/src/components/views/dialogs/DevtoolsDialog.js +++ b/src/components/views/dialogs/DevtoolsDialog.js @@ -637,6 +637,7 @@ function VerificationRequest({txnId, request}) { useEffect(() => { if (request.timeout == 0) return; + /* Note that request.timeout is a getter, so its value changes */ const id = setInterval(() => { setTimeout(request.timeout); }, 500); From af514385b2fa0d343df153385a35be9e51a50ef9 Mon Sep 17 00:00:00 2001 From: Zoe Date: Mon, 24 Feb 2020 11:53:12 +0000 Subject: [PATCH 4/6] Avoid shadowing window.setTimeout --- src/components/views/dialogs/DevtoolsDialog.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/DevtoolsDialog.js b/src/components/views/dialogs/DevtoolsDialog.js index 53edf88698..dc99ed680c 100644 --- a/src/components/views/dialogs/DevtoolsDialog.js +++ b/src/components/views/dialogs/DevtoolsDialog.js @@ -625,7 +625,7 @@ const PHASE_MAP = { function VerificationRequest({txnId, request}) { const [, updateState] = useState(); - const [timeout, setTimeout] = useState(request.timeout); + const [timeout, setRequestTimeout] = useState(request.timeout); /* Re-render if something changes state */ useEffect(() => { @@ -639,7 +639,7 @@ function VerificationRequest({txnId, request}) { /* Note that request.timeout is a getter, so its value changes */ const id = setInterval(() => { - setTimeout(request.timeout); + setRequestTimeout(request.timeout); }, 500); return () => { clearInterval(id); }; From 0d3d837871518200f7ad2d01894b93cd5cd66611 Mon Sep 17 00:00:00 2001 From: Zoe Date: Mon, 24 Feb 2020 13:44:04 +0000 Subject: [PATCH 5/6] useEventEmitter hook instead of manually using code --- src/components/views/dialogs/DevtoolsDialog.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/views/dialogs/DevtoolsDialog.js b/src/components/views/dialogs/DevtoolsDialog.js index dc99ed680c..0420c038ca 100644 --- a/src/components/views/dialogs/DevtoolsDialog.js +++ b/src/components/views/dialogs/DevtoolsDialog.js @@ -22,6 +22,7 @@ import { _t } from '../../../languageHandler'; import { Room } from "matrix-js-sdk"; import Field from "../elements/Field"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; +import {useEventEmitter} from "../../../hooks/useEventEmitter"; import { PHASE_UNSENT, @@ -628,10 +629,7 @@ function VerificationRequest({txnId, request}) { const [timeout, setRequestTimeout] = useState(request.timeout); /* Re-render if something changes state */ - useEffect(() => { - request.on("change", updateState); - return () => request.off("change", updateState); - }, [request]); + useEventEmitter(request, "change", updateState); /* Keep re-rendering if there's a timeout */ useEffect(() => { From f3ac3554a9ad13d0d56f1b70500e890b758941ad Mon Sep 17 00:00:00 2001 From: Zoe Date: Mon, 24 Feb 2020 14:17:34 +0000 Subject: [PATCH 6/6] include observeOnly --- src/components/views/dialogs/DevtoolsDialog.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/views/dialogs/DevtoolsDialog.js b/src/components/views/dialogs/DevtoolsDialog.js index 0420c038ca..348965582b 100644 --- a/src/components/views/dialogs/DevtoolsDialog.js +++ b/src/components/views/dialogs/DevtoolsDialog.js @@ -655,6 +655,8 @@ function VerificationRequest({txnId, request}) {
{request.methods && request.methods.join(", ")}
requestingUserId
{request.requestingUserId}
+
observeOnly
+
{JSON.stringify(request.observeOnly)}
); }