From d08fbb4872fb147ae0bbb81a706d830edca4aca6 Mon Sep 17 00:00:00 2001
From: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
Date: Sat, 6 Apr 2019 20:37:23 -0700
Subject: [PATCH 1/9] Make call buttons into separate components
Make the call/voice-call/hangup buttons separate react components
to reduce the amount of complexity on MessageComposer.
Signed-off-by: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
---
src/components/views/rooms/MessageComposer.js | 121 ++++++++++--------
1 file changed, 68 insertions(+), 53 deletions(-)
diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js
index 576f45a3bc..5c9ef3f15f 100644
--- a/src/components/views/rooms/MessageComposer.js
+++ b/src/components/views/rooms/MessageComposer.js
@@ -42,14 +42,76 @@ const formatButtonList = [
_td("numbered-list"),
];
+function CallButton(props) {
+ const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
+ const onVoiceCallClick = (ev) => {
+ dis.dispatch({
+ action: 'place_call',
+ type: "voice",
+ room_id: props.roomId,
+ });
+ };
+
+ return
+}
+
+CallButton.propTypes = {
+ roomId: PropTypes.string.isRequired
+}
+
+function VideoCallButton(props) {
+ const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
+ const onCallClick = (ev) => {
+ dis.dispatch({
+ action: 'place_call',
+ type: ev.shiftKey ? "screensharing" : "video",
+ room_id: props.roomId,
+ });
+ };
+
+ return ;
+}
+
+VideoCallButton.propTypes = {
+ roomId: PropTypes.string.isRequired,
+};
+
+function HangupButton(props) {
+ const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
+ const onHangupClick = () => {
+ const call = CallHandler.getCallForRoom(props.roomId);
+ if (!call) {
+ return;
+ }
+ dis.dispatch({
+ action: 'hangup',
+ // hangup the call for this room, which may not be the room in props
+ // (e.g. conferences which will hangup the 1:1 room instead)
+ room_id: call.roomId,
+ });
+ };
+ return ;
+}
+
+HangupButton.propTypes = {
+ roomId: PropTypes.string.isRequired,
+}
+
+
export default class MessageComposer extends React.Component {
constructor(props, context) {
super(props, context);
- this.onCallClick = this.onCallClick.bind(this);
- this.onHangupClick = this.onHangupClick.bind(this);
this.onUploadClick = this.onUploadClick.bind(this);
this._onUploadFileInputChange = this._onUploadFileInputChange.bind(this);
- this.onVoiceCallClick = this.onVoiceCallClick.bind(this);
this._onAutocompleteConfirm = this._onAutocompleteConfirm.bind(this);
this.onToggleFormattingClicked = this.onToggleFormattingClicked.bind(this);
this.onToggleMarkdownClicked = this.onToggleMarkdownClicked.bind(this);
@@ -166,35 +228,6 @@ export default class MessageComposer extends React.Component {
ev.target.value = '';
}
- onHangupClick() {
- const call = CallHandler.getCallForRoom(this.props.room.roomId);
- //var call = CallHandler.getAnyActiveCall();
- if (!call) {
- return;
- }
- dis.dispatch({
- action: 'hangup',
- // hangup the call for this room, which may not be the room in props
- // (e.g. conferences which will hangup the 1:1 room instead)
- room_id: call.roomId,
- });
- }
-
- onCallClick(ev) {
- dis.dispatch({
- action: 'place_call',
- type: ev.shiftKey ? "screensharing" : "video",
- room_id: this.props.room.roomId,
- });
- }
-
- onVoiceCallClick(ev) {
- dis.dispatch({
- action: 'place_call',
- type: "voice",
- room_id: this.props.room.roomId,
- });
- }
onInputStateChanged(inputState) {
// Merge the new input state with old to support partial updates
@@ -275,28 +308,10 @@ export default class MessageComposer extends React.Component {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
// Call buttons
if (this.props.callState && this.props.callState !== 'ended') {
- hangupButton =
-
- ;
+ hangupButton = ;
} else {
- callButton =
-
- ;
- videoCallButton =
-
- ;
+ callButton = ;
+ videoCallButton = ;
}
if (!this.state.tombstone && this.state.canSendMessages) {
From 6aa9f068b3bd3414ea47544585d465e19a90a408 Mon Sep 17 00:00:00 2001
From: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
Date: Sat, 6 Apr 2019 20:44:22 -0700
Subject: [PATCH 2/9] Tighten controls code in MessageComposer
Make the user avatar a separate function component, make the logic for
laying out components a little more concise
Signed-off-by: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
---
src/components/views/rooms/MessageComposer.js | 33 +++++++++----------
1 file changed, 15 insertions(+), 18 deletions(-)
diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js
index 5c9ef3f15f..089fbc13f4 100644
--- a/src/components/views/rooms/MessageComposer.js
+++ b/src/components/views/rooms/MessageComposer.js
@@ -42,6 +42,17 @@ const formatButtonList = [
_td("numbered-list"),
];
+function Avatar(props) {
+ const MemberStatusMessageAvatar = sdk.getComponent('avatars.MemberStatusMessageAvatar');
+ return
+
+
;
+}
+
+Avatar.propTypes = {
+ me: PropTypes.object.isRequired,
+}
+
function CallButton(props) {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const onVoiceCallClick = (ev) => {
@@ -280,26 +291,12 @@ export default class MessageComposer extends React.Component {
render() {
const uploadInputStyle = {display: 'none'};
- const MemberStatusMessageAvatar = sdk.getComponent('avatars.MemberStatusMessageAvatar');
const MessageComposerInput = sdk.getComponent("rooms.MessageComposerInput");
- const controls = [];
-
- if (this.state.me) {
- controls.push(
-
-
-
,
- );
- }
-
- if (this.props.e2eStatus) {
- controls.push(
- );
- }
+ const controls = [
+ this.state.me ? : null,
+ this.props.e2eStatus ? : null,
+ ];
let callButton;
let videoCallButton;
From cfb9172121d1415b58fddcc3cfc609edff5226a8 Mon Sep 17 00:00:00 2001
From: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
Date: Sat, 6 Apr 2019 20:48:13 -0700
Subject: [PATCH 3/9] Tighten up code around call buttons
Signed-off-by: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
---
src/components/views/rooms/MessageComposer.js | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)
diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js
index 089fbc13f4..353b7cc643 100644
--- a/src/components/views/rooms/MessageComposer.js
+++ b/src/components/views/rooms/MessageComposer.js
@@ -293,23 +293,14 @@ export default class MessageComposer extends React.Component {
const uploadInputStyle = {display: 'none'};
const MessageComposerInput = sdk.getComponent("rooms.MessageComposerInput");
+ const callInProgress = this.props.callState && this.props.callState !== 'ended';
+
const controls = [
this.state.me ? : null,
this.props.e2eStatus ? : null,
];
- let callButton;
- let videoCallButton;
- let hangupButton;
-
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
- // Call buttons
- if (this.props.callState && this.props.callState !== 'ended') {
- hangupButton = ;
- } else {
- callButton = ;
- videoCallButton = ;
- }
if (!this.state.tombstone && this.state.canSendMessages) {
// This also currently includes the call buttons. Really we should
@@ -367,9 +358,9 @@ export default class MessageComposer extends React.Component {
formattingButton,
stickerpickerButton,
uploadButton,
- hangupButton,
- callButton,
- videoCallButton,
+ callInProgress ? : null,
+ callInProgress ? null : ,
+ callInProgress ? null : ,
);
} else if (this.state.tombstone) {
const replacementRoomId = this.state.tombstone.getContent()['replacement_room'];
From 452f0e6dcc85f69151929bffe78c470a55040b05 Mon Sep 17 00:00:00 2001
From: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
Date: Sat, 6 Apr 2019 20:57:45 -0700
Subject: [PATCH 4/9] Generate placeholder text in separate method
To make the MessageComposer render() method a bit less busy
Signed-off-by: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
---
src/components/views/rooms/MessageComposer.js | 36 ++++++++++---------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js
index 353b7cc643..379c3f8ab2 100644
--- a/src/components/views/rooms/MessageComposer.js
+++ b/src/components/views/rooms/MessageComposer.js
@@ -131,6 +131,7 @@ export default class MessageComposer extends React.Component {
this._onRoomStateEvents = this._onRoomStateEvents.bind(this);
this._onRoomViewStoreUpdate = this._onRoomViewStoreUpdate.bind(this);
this._onTombstoneClick = this._onTombstoneClick.bind(this);
+ this.renderPlaceholderText = this.renderPlaceholderText.bind(this);
this.state = {
inputState: {
@@ -289,6 +290,23 @@ export default class MessageComposer extends React.Component {
});
}
+ renderPlaceholderText() {
+ const roomIsEncrypted = MatrixClientPeg.get().isRoomEncrypted(this.props.room.roomId);
+ if (this.state.isQuoting) {
+ if (roomIsEncrypted) {
+ return _t('Send an encrypted reply…');
+ } else {
+ return _t('Send a reply (unencrypted)…');
+ }
+ } else {
+ if (roomIsEncrypted) {
+ return _t('Send an encrypted message…');
+ } else {
+ return _t('Send a message (unencrypted)…');
+ }
+ }
+ }
+
render() {
const uploadInputStyle = {display: 'none'};
const MessageComposerInput = sdk.getComponent("rooms.MessageComposerInput");
@@ -329,22 +347,6 @@ export default class MessageComposer extends React.Component {
key="controls_formatting" />
) : null;
- const roomIsEncrypted = MatrixClientPeg.get().isRoomEncrypted(this.props.room.roomId);
- let placeholderText;
- if (this.state.isQuoting) {
- if (roomIsEncrypted) {
- placeholderText = _t('Send an encrypted reply…');
- } else {
- placeholderText = _t('Send a reply (unencrypted)…');
- }
- } else {
- if (roomIsEncrypted) {
- placeholderText = _t('Send an encrypted message…');
- } else {
- placeholderText = _t('Send a message (unencrypted)…');
- }
- }
-
const stickerpickerButton = ;
controls.push(
@@ -352,7 +354,7 @@ export default class MessageComposer extends React.Component {
ref={(c) => this.messageComposerInput = c}
key="controls_input"
room={this.props.room}
- placeholder={placeholderText}
+ placeholder={this.renderPlaceholderText()}
onInputStateChanged={this.onInputStateChanged}
permalinkCreator={this.props.permalinkCreator} />,
formattingButton,
From 485ad6a3f06da4594e9712272864f7555f11e0e9 Mon Sep 17 00:00:00 2001
From: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
Date: Sat, 6 Apr 2019 21:14:29 -0700
Subject: [PATCH 5/9] Make UploadButton a separate component
Signed-off-by: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
---
src/components/views/rooms/MessageComposer.js | 103 ++++++++++--------
1 file changed, 57 insertions(+), 46 deletions(-)
diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js
index 379c3f8ab2..b1ad3ae0a1 100644
--- a/src/components/views/rooms/MessageComposer.js
+++ b/src/components/views/rooms/MessageComposer.js
@@ -117,12 +117,66 @@ HangupButton.propTypes = {
roomId: PropTypes.string.isRequired,
}
+class UploadButton extends React.Component {
+ static propTypes = {
+ roomId: PropTypes.string.isRequired,
+ }
+ constructor(props, context) {
+ super(props, context);
+ this.onUploadClick = this.onUploadClick.bind(this);
+ this.onUploadFileInputChange = this.onUploadFileInputChange.bind(this);
+ }
+
+ onUploadClick(ev) {
+ if (MatrixClientPeg.get().isGuest()) {
+ dis.dispatch({action: 'require_registration'});
+ return;
+ }
+ this.refs.uploadInput.click();
+ }
+
+ onUploadFileInputChange(ev) {
+ if (ev.target.files.length === 0) return;
+
+ // take a copy so we can safely reset the value of the form control
+ // (Note it is a FileList: we can't use slice or sesnible iteration).
+ const tfiles = [];
+ for (let i = 0; i < ev.target.files.length; ++i) {
+ tfiles.push(ev.target.files[i]);
+ }
+
+ ContentMessages.sharedInstance().sendContentListToRoom(
+ tfiles, this.props.roomId, MatrixClientPeg.get(),
+ );
+
+ // This is the onChange handler for a file form control, but we're
+ // not keeping any state, so reset the value of the form control
+ // to empty.
+ // NB. we need to set 'value': the 'files' property is immutable.
+ ev.target.value = '';
+ }
+
+ render() {
+ const uploadInputStyle = {display: 'none'};
+ const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
+ return (
+
+
+
+ );
+ }
+}
export default class MessageComposer extends React.Component {
constructor(props, context) {
super(props, context);
- this.onUploadClick = this.onUploadClick.bind(this);
- this._onUploadFileInputChange = this._onUploadFileInputChange.bind(this);
this._onAutocompleteConfirm = this._onAutocompleteConfirm.bind(this);
this.onToggleFormattingClicked = this.onToggleFormattingClicked.bind(this);
this.onToggleMarkdownClicked = this.onToggleMarkdownClicked.bind(this);
@@ -210,36 +264,6 @@ export default class MessageComposer extends React.Component {
this.setState({ isQuoting });
}
- onUploadClick(ev) {
- if (MatrixClientPeg.get().isGuest()) {
- dis.dispatch({action: 'require_registration'});
- return;
- }
-
- this.refs.uploadInput.click();
- }
-
- _onUploadFileInputChange(ev) {
- if (ev.target.files.length === 0) return;
-
- // take a copy so we can safely reset the value of the form control
- // (Note it is a FileList: we can't use slice or sesnible iteration).
- const tfiles = [];
- for (let i = 0; i < ev.target.files.length; ++i) {
- tfiles.push(ev.target.files[i]);
- }
-
- ContentMessages.sharedInstance().sendContentListToRoom(
- tfiles, this.props.room.roomId, MatrixClientPeg.get(),
- );
-
- // This is the onChange handler for a file form control, but we're
- // not keeping any state, so reset the value of the form control
- // to empty.
- // NB. we need to set 'value': the 'files' property is immutable.
- ev.target.value = '';
- }
-
onInputStateChanged(inputState) {
// Merge the new input state with old to support partial updates
@@ -308,7 +332,6 @@ export default class MessageComposer extends React.Component {
}
render() {
- const uploadInputStyle = {display: 'none'};
const MessageComposerInput = sdk.getComponent("rooms.MessageComposerInput");
const callInProgress = this.props.callState && this.props.callState !== 'ended';
@@ -324,18 +347,6 @@ export default class MessageComposer extends React.Component {
// This also currently includes the call buttons. Really we should
// check separately for whether we can call, but this is slightly
// complex because of conference calls.
- const uploadButton = (
-
-
-
- );
const formattingButton = this.state.inputState.isRichTextEnabled ? (
,
formattingButton,
stickerpickerButton,
- uploadButton,
+ ,
callInProgress ? : null,
callInProgress ? null : ,
callInProgress ? null : ,
From 419cb4e8b20e9ac8068e11c774a65cc3f6b8c13e Mon Sep 17 00:00:00 2001
From: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
Date: Sat, 6 Apr 2019 21:19:18 -0700
Subject: [PATCH 6/9] Define Stickerpicker inline
Signed-off-by: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
---
src/components/views/rooms/MessageComposer.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js
index b1ad3ae0a1..689b549bc3 100644
--- a/src/components/views/rooms/MessageComposer.js
+++ b/src/components/views/rooms/MessageComposer.js
@@ -358,7 +358,6 @@ export default class MessageComposer extends React.Component {
key="controls_formatting" />
) : null;
- const stickerpickerButton = ;
controls.push(
,
formattingButton,
- stickerpickerButton,
+ ,
,
callInProgress ? : null,
callInProgress ? null : ,
From 817f1d482f088fd2e338881e1a344ce5e8f56ece Mon Sep 17 00:00:00 2001
From: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
Date: Sat, 6 Apr 2019 21:43:15 -0700
Subject: [PATCH 7/9] Move format bar rendering to separate method
To reduce the complexity in render(), move the format bar rendering to a
separate method
Signed-off-by: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
---
src/components/views/rooms/MessageComposer.js | 81 ++++++++++---------
1 file changed, 44 insertions(+), 37 deletions(-)
diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js
index 689b549bc3..3c7a5b077b 100644
--- a/src/components/views/rooms/MessageComposer.js
+++ b/src/components/views/rooms/MessageComposer.js
@@ -186,6 +186,7 @@ export default class MessageComposer extends React.Component {
this._onRoomViewStoreUpdate = this._onRoomViewStoreUpdate.bind(this);
this._onTombstoneClick = this._onTombstoneClick.bind(this);
this.renderPlaceholderText = this.renderPlaceholderText.bind(this);
+ this.renderFormatBar = this.renderFormatBar.bind(this);
this.state = {
inputState: {
@@ -331,6 +332,47 @@ export default class MessageComposer extends React.Component {
}
}
+ renderFormatBar() {
+ const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
+ const {marks, blockType} = this.state.inputState;
+ const formatButtons = formatButtonList.map((name) => {
+ // special-case to match the md serializer and the special-case in MessageComposerInput.js
+ const markName = name === 'inline-code' ? 'code' : name;
+ const active = marks.some(mark => mark.type === markName) || blockType === name;
+ const suffix = active ? '-on' : '';
+ const onFormatButtonClicked = this.onFormatButtonClicked.bind(this, name);
+ const className = 'mx_MessageComposer_format_button mx_filterFlipColor';
+ return (
+
+ );
+ })
+
+ return (
+
+
+ { formatButtons }
+
+
+
+
+
+ );
+ }
+
render() {
const MessageComposerInput = sdk.getComponent("rooms.MessageComposerInput");
@@ -403,42 +445,7 @@ export default class MessageComposer extends React.Component {
);
}
- let formatBar;
- if (this.state.showFormatting && this.state.inputState.isRichTextEnabled) {
- const {marks, blockType} = this.state.inputState;
- const formatButtons = formatButtonList.map((name) => {
- // special-case to match the md serializer and the special-case in MessageComposerInput.js
- const markName = name === 'inline-code' ? 'code' : name;
- const active = marks.some(mark => mark.type === markName) || blockType === name;
- const suffix = active ? '-on' : '';
- const onFormatButtonClicked = this.onFormatButtonClicked.bind(this, name);
- const className = 'mx_MessageComposer_format_button mx_filterFlipColor';
- return
;
- },
- );
-
- formatBar =
-
-
- { formatButtons }
-
-
-
-
-
;
- }
+ const showFormatBar = this.state.showFormatting && this.state.inputState.isRichTextEnabled;
const wrapperClasses = classNames({
mx_MessageComposer_wrapper: true,
@@ -451,7 +458,7 @@ export default class MessageComposer extends React.Component {
{ controls }
- { formatBar }
+ { showFormatBar ? this.renderFormatBar() : null }
);
}
From 3dae9f3d58f475e9c25b076e04fdb0987c1a5481 Mon Sep 17 00:00:00 2001
From: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
Date: Sat, 6 Apr 2019 21:58:05 -0700
Subject: [PATCH 8/9] Move FormattingButton to separate component
Signed-off-by: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
---
src/components/views/rooms/MessageComposer.js | 40 +++++++++++--------
1 file changed, 23 insertions(+), 17 deletions(-)
diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js
index 3c7a5b077b..51c7dbe710 100644
--- a/src/components/views/rooms/MessageComposer.js
+++ b/src/components/views/rooms/MessageComposer.js
@@ -117,6 +117,24 @@ HangupButton.propTypes = {
roomId: PropTypes.string.isRequired,
}
+function FormattingButton(props) {
+ const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
+ return ;
+}
+
+FormattingButton.propTypes = {
+ showFormatting: PropTypes.bool.isRequired,
+ onClickHandler: PropTypes.func.isRequired,
+}
+
class UploadButton extends React.Component {
static propTypes = {
roomId: PropTypes.string.isRequired,
@@ -374,32 +392,19 @@ export default class MessageComposer extends React.Component {
}
render() {
- const MessageComposerInput = sdk.getComponent("rooms.MessageComposerInput");
-
- const callInProgress = this.props.callState && this.props.callState !== 'ended';
-
const controls = [
this.state.me ? : null,
this.props.e2eStatus ? : null,
];
- const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
-
if (!this.state.tombstone && this.state.canSendMessages) {
// This also currently includes the call buttons. Really we should
// check separately for whether we can call, but this is slightly
// complex because of conference calls.
- const formattingButton = this.state.inputState.isRichTextEnabled ? (
-
- ) : null;
-
+ const MessageComposerInput = sdk.getComponent("rooms.MessageComposerInput");
+ const showFormattingButton = this.state.inputState.isRichTextEnabled;
+ const callInProgress = this.props.callState && this.props.callState !== 'ended';
controls.push(
,
- formattingButton,
+ showFormattingButton ? : null,
,
,
callInProgress ? : null,
From f7462371b1e955f269480d0b9c6956ed49c10125 Mon Sep 17 00:00:00 2001
From: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
Date: Sat, 13 Apr 2019 01:44:36 -0700
Subject: [PATCH 9/9] Rename: Avatar -> ComposerAvatar
To avoid confusion with other components that also might be named Avatar
Signed-off-by: YaoiFangirl420 <48789208+YaoiFangirl420@users.noreply.github.com>
---
src/components/views/rooms/MessageComposer.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js
index 51c7dbe710..5f9014db7a 100644
--- a/src/components/views/rooms/MessageComposer.js
+++ b/src/components/views/rooms/MessageComposer.js
@@ -42,14 +42,14 @@ const formatButtonList = [
_td("numbered-list"),
];
-function Avatar(props) {
+function ComposerAvatar(props) {
const MemberStatusMessageAvatar = sdk.getComponent('avatars.MemberStatusMessageAvatar');
return
;
}
-Avatar.propTypes = {
+ComposerAvatar.propTypes = {
me: PropTypes.object.isRequired,
}
@@ -393,7 +393,7 @@ export default class MessageComposer extends React.Component {
render() {
const controls = [
- this.state.me ? : null,
+ this.state.me ? : null,
this.props.e2eStatus ? : null,
];