Merge pull request #3255 from matrix-org/t3chguy/hide_msg_action_buttons_on_perms
Show MessageActionBar buttons conditionally on room state permissions
This commit is contained in:
commit
106af39a82
2 changed files with 53 additions and 11 deletions
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2019 New Vector Ltd
|
Copyright 2019 New Vector Ltd
|
||||||
|
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with 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 Modal from '../../../Modal';
|
||||||
import { createMenu } from '../../structures/ContextualMenu';
|
import { createMenu } from '../../structures/ContextualMenu';
|
||||||
import { isContentActionable, canEditContent } from '../../../utils/EventUtils';
|
import { isContentActionable, canEditContent } from '../../../utils/EventUtils';
|
||||||
|
import MatrixClientPeg from "../../../MatrixClientPeg";
|
||||||
|
|
||||||
export default class MessageActionBar extends React.PureComponent {
|
export default class MessageActionBar extends React.PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
@ -35,26 +37,58 @@ export default class MessageActionBar extends React.PureComponent {
|
||||||
onFocusChange: PropTypes.func,
|
onFocusChange: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
canReact: true,
|
||||||
|
canReply: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.mxEvent.on("Event.decrypted", this.onDecrypted);
|
this.props.mxEvent.on("Event.decrypted", this.onDecrypted);
|
||||||
|
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||||
|
if (room) {
|
||||||
|
room.on("RoomMember.powerLevel", this.onPermissionsChange);
|
||||||
|
room.on("RoomMember.membership", this.onPermissionsChange);
|
||||||
|
this.onPermissionsChange();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.props.mxEvent.removeListener("Event.decrypted", this.onDecrypted);
|
this.props.mxEvent.removeListener("Event.decrypted", this.onDecrypted);
|
||||||
|
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||||
|
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());
|
||||||
|
if (room) {
|
||||||
|
const me = cli.getUserId();
|
||||||
|
const canReact = room.getMyMembership() === "join" && room.currentState.maySendEvent("m.reaction", me);
|
||||||
|
const canReply = room.maySendMessage();
|
||||||
|
|
||||||
|
this.setState({canReact, canReply});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onDecrypted = () => {
|
onDecrypted = () => {
|
||||||
// When an event decrypts, it is likely to change the set of available
|
// When an event decrypts, it is likely to change the set of available
|
||||||
// actions, so we force an update to check again.
|
// actions, so we force an update to check again.
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
}
|
};
|
||||||
|
|
||||||
onFocusChange = (focused) => {
|
onFocusChange = (focused) => {
|
||||||
if (!this.props.onFocusChange) {
|
if (!this.props.onFocusChange) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.props.onFocusChange(focused);
|
this.props.onFocusChange(focused);
|
||||||
}
|
};
|
||||||
|
|
||||||
onCryptoClick = () => {
|
onCryptoClick = () => {
|
||||||
const event = this.props.mxEvent;
|
const event = this.props.mxEvent;
|
||||||
|
@ -62,21 +96,21 @@ export default class MessageActionBar extends React.PureComponent {
|
||||||
import('../../../async-components/views/dialogs/EncryptedEventDialog'),
|
import('../../../async-components/views/dialogs/EncryptedEventDialog'),
|
||||||
{event},
|
{event},
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
onReplyClick = (ev) => {
|
onReplyClick = (ev) => {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'reply_to_event',
|
action: 'reply_to_event',
|
||||||
event: this.props.mxEvent,
|
event: this.props.mxEvent,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
onEditClick = (ev) => {
|
onEditClick = (ev) => {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'edit_event',
|
action: 'edit_event',
|
||||||
event: this.props.mxEvent,
|
event: this.props.mxEvent,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
onOptionsClick = (ev) => {
|
onOptionsClick = (ev) => {
|
||||||
const MessageContextMenu = sdk.getComponent('context_menus.MessageContextMenu');
|
const MessageContextMenu = sdk.getComponent('context_menus.MessageContextMenu');
|
||||||
|
@ -120,7 +154,7 @@ export default class MessageActionBar extends React.PureComponent {
|
||||||
createMenu(MessageContextMenu, menuOptions);
|
createMenu(MessageContextMenu, menuOptions);
|
||||||
|
|
||||||
this.onFocusChange(true);
|
this.onFocusChange(true);
|
||||||
}
|
};
|
||||||
|
|
||||||
renderReactButton() {
|
renderReactButton() {
|
||||||
const ReactMessageAction = sdk.getComponent('messages.ReactMessageAction');
|
const ReactMessageAction = sdk.getComponent('messages.ReactMessageAction');
|
||||||
|
@ -139,11 +173,15 @@ export default class MessageActionBar extends React.PureComponent {
|
||||||
let editButton;
|
let editButton;
|
||||||
|
|
||||||
if (isContentActionable(this.props.mxEvent)) {
|
if (isContentActionable(this.props.mxEvent)) {
|
||||||
reactButton = this.renderReactButton();
|
if (this.state.canReact) {
|
||||||
replyButton = <span className="mx_MessageActionBar_maskButton mx_MessageActionBar_replyButton"
|
reactButton = this.renderReactButton();
|
||||||
title={_t("Reply")}
|
}
|
||||||
onClick={this.onReplyClick}
|
if (this.state.canReply) {
|
||||||
/>;
|
replyButton = <span className="mx_MessageActionBar_maskButton mx_MessageActionBar_replyButton"
|
||||||
|
title={_t("Reply")}
|
||||||
|
onClick={this.onReplyClick}
|
||||||
|
/>;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (canEditContent(this.props.mxEvent)) {
|
if (canEditContent(this.props.mxEvent)) {
|
||||||
editButton = <span className="mx_MessageActionBar_maskButton mx_MessageActionBar_editButton"
|
editButton = <span className="mx_MessageActionBar_maskButton mx_MessageActionBar_editButton"
|
||||||
|
|
|
@ -247,10 +247,12 @@ export function mkStubRoom(roomId = null) {
|
||||||
getVersion: () => '1',
|
getVersion: () => '1',
|
||||||
shouldUpgradeToVersion: () => null,
|
shouldUpgradeToVersion: () => null,
|
||||||
getMyMembership: () => "join",
|
getMyMembership: () => "join",
|
||||||
|
maySendMessage: sinon.stub().returns(true),
|
||||||
currentState: {
|
currentState: {
|
||||||
getStateEvents: sinon.stub(),
|
getStateEvents: sinon.stub(),
|
||||||
mayClientSendStateEvent: sinon.stub().returns(true),
|
mayClientSendStateEvent: sinon.stub().returns(true),
|
||||||
maySendStateEvent: sinon.stub().returns(true),
|
maySendStateEvent: sinon.stub().returns(true),
|
||||||
|
maySendEvent: sinon.stub().returns(true),
|
||||||
members: [],
|
members: [],
|
||||||
},
|
},
|
||||||
tags: {
|
tags: {
|
||||||
|
@ -259,6 +261,8 @@ export function mkStubRoom(roomId = null) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setBlacklistUnverifiedDevices: sinon.stub(),
|
setBlacklistUnverifiedDevices: sinon.stub(),
|
||||||
|
on: sinon.stub(),
|
||||||
|
removeListener: sinon.stub(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue