From 7b2e18ff7cabe4fd6a7752ed21a9b76890fea36f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 29 Jul 2019 12:13:23 +0100 Subject: [PATCH 1/7] Show MessageActionBar buttons conditionally on room state permissions Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../views/messages/MessageActionBar.js | 50 +++++++++++++++---- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/src/components/views/messages/MessageActionBar.js b/src/components/views/messages/MessageActionBar.js index 6f58dd7bef..231b7a03c3 100644 --- a/src/components/views/messages/MessageActionBar.js +++ b/src/components/views/messages/MessageActionBar.js @@ -1,5 +1,6 @@ /* Copyright 2019 New Vector Ltd +Copyright 2019 Michael Telatynski <7t3chguy@gmail.com> Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -23,6 +24,7 @@ import dis from '../../../dispatcher'; import Modal from '../../../Modal'; import { createMenu } from '../../structures/ContextualMenu'; import { isContentActionable, canEditContent } from '../../../utils/EventUtils'; +import MatrixClientPeg from "../../../MatrixClientPeg"; export default class MessageActionBar extends React.PureComponent { static propTypes = { @@ -35,26 +37,48 @@ export default class MessageActionBar extends React.PureComponent { onFocusChange: PropTypes.func, }; + state = { + canReact: true, + canReply: true, + }; + componentDidMount() { this.props.mxEvent.on("Event.decrypted", this.onDecrypted); + const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId()); + room.on("RoomMember.powerLevel", this.onPermissionsChange); + room.on("RoomMember.membership", this.onPermissionsChange); + this.onPermissionsChange(); } componentWillUnmount() { this.props.mxEvent.removeListener("Event.decrypted", this.onDecrypted); + const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId()); + room.removeListener("RoomMember.powerLevel", this.onPermissionsChange); + room.removeListener("RoomMember.membership", this.onPermissionsChange); + } + + onPermissionsChange() { + const cli = MatrixClientPeg.get(); + const room = cli.getRoom(this.props.mxEvent.getRoomId()); + const me = cli.credentials.userId; + const canReact = room.getMyMembership() === "join" && room.currentState.maySendEvent("m.reaction", me); + const canReply = room.maySendMessage(); + + this.setState({canReact, canReply}); } onDecrypted = () => { // When an event decrypts, it is likely to change the set of available // actions, so we force an update to check again. this.forceUpdate(); - } + }; onFocusChange = (focused) => { if (!this.props.onFocusChange) { return; } this.props.onFocusChange(focused); - } + }; onCryptoClick = () => { const event = this.props.mxEvent; @@ -62,21 +86,21 @@ export default class MessageActionBar extends React.PureComponent { import('../../../async-components/views/dialogs/EncryptedEventDialog'), {event}, ); - } + }; onReplyClick = (ev) => { dis.dispatch({ action: 'reply_to_event', event: this.props.mxEvent, }); - } + }; onEditClick = (ev) => { dis.dispatch({ action: 'edit_event', event: this.props.mxEvent, }); - } + }; onOptionsClick = (ev) => { const MessageContextMenu = sdk.getComponent('context_menus.MessageContextMenu'); @@ -120,7 +144,7 @@ export default class MessageActionBar extends React.PureComponent { createMenu(MessageContextMenu, menuOptions); this.onFocusChange(true); - } + }; renderReactButton() { const ReactMessageAction = sdk.getComponent('messages.ReactMessageAction'); @@ -139,11 +163,15 @@ export default class MessageActionBar extends React.PureComponent { let editButton; if (isContentActionable(this.props.mxEvent)) { - reactButton = this.renderReactButton(); - replyButton = ; + if (this.state.canReact) { + reactButton = this.renderReactButton(); + } + if (this.state.canReply) { + replyButton = ; + } } if (canEditContent(this.props.mxEvent)) { editButton = Date: Mon, 29 Jul 2019 12:28:30 +0100 Subject: [PATCH 2/7] null-guard Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../views/messages/MessageActionBar.js | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/components/views/messages/MessageActionBar.js b/src/components/views/messages/MessageActionBar.js index 231b7a03c3..6e47846d20 100644 --- a/src/components/views/messages/MessageActionBar.js +++ b/src/components/views/messages/MessageActionBar.js @@ -45,26 +45,32 @@ export default class MessageActionBar extends React.PureComponent { componentDidMount() { this.props.mxEvent.on("Event.decrypted", this.onDecrypted); const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId()); - room.on("RoomMember.powerLevel", this.onPermissionsChange); - room.on("RoomMember.membership", this.onPermissionsChange); - this.onPermissionsChange(); + if (room) { + room.on("RoomMember.powerLevel", this.onPermissionsChange); + room.on("RoomMember.membership", this.onPermissionsChange); + this.onPermissionsChange(); + } } componentWillUnmount() { this.props.mxEvent.removeListener("Event.decrypted", this.onDecrypted); const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId()); - room.removeListener("RoomMember.powerLevel", this.onPermissionsChange); - room.removeListener("RoomMember.membership", this.onPermissionsChange); + if (room) { + room.removeListener("RoomMember.powerLevel", this.onPermissionsChange); + room.removeListener("RoomMember.membership", this.onPermissionsChange); + } } onPermissionsChange() { const cli = MatrixClientPeg.get(); const room = cli.getRoom(this.props.mxEvent.getRoomId()); - const me = cli.credentials.userId; - const canReact = room.getMyMembership() === "join" && room.currentState.maySendEvent("m.reaction", me); - const canReply = room.maySendMessage(); + if (room) { + const me = cli.credentials.userId; + const canReact = room.getMyMembership() === "join" && room.currentState.maySendEvent("m.reaction", me); + const canReply = room.maySendMessage(); - this.setState({canReact, canReply}); + this.setState({canReact, canReply}); + } } onDecrypted = () => { From 856e161c8bc9e5a03d19d0ae1e41848d7e5331b1 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 29 Jul 2019 12:54:09 +0100 Subject: [PATCH 3/7] add Debug Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/messages/MessageActionBar.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/messages/MessageActionBar.js b/src/components/views/messages/MessageActionBar.js index 6e47846d20..1f27de0732 100644 --- a/src/components/views/messages/MessageActionBar.js +++ b/src/components/views/messages/MessageActionBar.js @@ -46,6 +46,7 @@ export default class MessageActionBar extends React.PureComponent { this.props.mxEvent.on("Event.decrypted", this.onDecrypted); const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId()); if (room) { + console.log("DEBUG", room); room.on("RoomMember.powerLevel", this.onPermissionsChange); room.on("RoomMember.membership", this.onPermissionsChange); this.onPermissionsChange(); From f45b1bfdda5043fbff9ce53b2c3b424ab233e6b5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 29 Jul 2019 13:18:02 +0100 Subject: [PATCH 4/7] Fix StubRoom for react-sdk tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/messages/MessageActionBar.js | 1 - test/test-utils.js | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/messages/MessageActionBar.js b/src/components/views/messages/MessageActionBar.js index 1f27de0732..6e47846d20 100644 --- a/src/components/views/messages/MessageActionBar.js +++ b/src/components/views/messages/MessageActionBar.js @@ -46,7 +46,6 @@ export default class MessageActionBar extends React.PureComponent { this.props.mxEvent.on("Event.decrypted", this.onDecrypted); const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId()); if (room) { - console.log("DEBUG", room); room.on("RoomMember.powerLevel", this.onPermissionsChange); room.on("RoomMember.membership", this.onPermissionsChange); this.onPermissionsChange(); diff --git a/test/test-utils.js b/test/test-utils.js index 5f78508f46..6dd9158b74 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -259,6 +259,8 @@ export function mkStubRoom(roomId = null) { }, }, setBlacklistUnverifiedDevices: sinon.stub(), + on: sinon.stub(), + removeListener: sinon.stub(), }; } From ac66388a7f71cc2dbbec31afbf9bc9807d29501f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 29 Jul 2019 13:27:49 +0100 Subject: [PATCH 5/7] Add missing stubs to stubRoom.currentState Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- test/test-utils.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test-utils.js b/test/test-utils.js index 6dd9158b74..5459895147 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -251,6 +251,8 @@ export function mkStubRoom(roomId = null) { getStateEvents: sinon.stub(), mayClientSendStateEvent: sinon.stub().returns(true), maySendStateEvent: sinon.stub().returns(true), + maySendEvent: sinon.stub().returns(true), + maySendMessage: sinon.stub().returns(true), members: [], }, tags: { From fd039431bc36d202e10b59d20a7c89958502612f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 29 Jul 2019 13:50:11 +0100 Subject: [PATCH 6/7] put maySendMessage stub on stubRoom in the right place Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- test/test-utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test-utils.js b/test/test-utils.js index 5459895147..f60cab3bc2 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -247,12 +247,12 @@ export function mkStubRoom(roomId = null) { getVersion: () => '1', shouldUpgradeToVersion: () => null, getMyMembership: () => "join", + maySendMessage: sinon.stub().returns(true), currentState: { getStateEvents: sinon.stub(), mayClientSendStateEvent: sinon.stub().returns(true), maySendStateEvent: sinon.stub().returns(true), maySendEvent: sinon.stub().returns(true), - maySendMessage: sinon.stub().returns(true), members: [], }, tags: { From 883b3d1563d101a78779ad4dc5926fae63e611a8 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 29 Jul 2019 22:30:07 +0100 Subject: [PATCH 7/7] iterate PR based on feedback Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/messages/MessageActionBar.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/components/views/messages/MessageActionBar.js b/src/components/views/messages/MessageActionBar.js index 6e47846d20..387a15d292 100644 --- a/src/components/views/messages/MessageActionBar.js +++ b/src/components/views/messages/MessageActionBar.js @@ -37,10 +37,14 @@ export default class MessageActionBar extends React.PureComponent { onFocusChange: PropTypes.func, }; - state = { - canReact: true, - canReply: true, - }; + constructor(props, context) { + super(props, context); + + this.state = { + canReact: true, + canReply: true, + }; + } componentDidMount() { this.props.mxEvent.on("Event.decrypted", this.onDecrypted); @@ -65,7 +69,7 @@ export default class MessageActionBar extends React.PureComponent { const cli = MatrixClientPeg.get(); const room = cli.getRoom(this.props.mxEvent.getRoomId()); if (room) { - const me = cli.credentials.userId; + const me = cli.getUserId(); const canReact = room.getMyMembership() === "join" && room.currentState.maySendEvent("m.reaction", me); const canReply = room.maySendMessage();