({
action: Action.ComposerInsert,
text: emoji,
timelineRenderingType: this.context.timelineRenderingType,
});
return true;
};
private sendMessage = async () => {
if (this.state.haveRecording && this.voiceRecordingButton.current) {
// There shouldn't be any text message to send when a voice recording is active, so
// just send out the voice recording.
await this.voiceRecordingButton.current?.send();
return;
}
this.messageComposerInput.current?.sendMessage();
};
private onChange = (model: EditorModel) => {
this.setState({
isComposerEmpty: model.isEmpty,
});
};
private onVoiceStoreUpdate = () => {
this.updateRecordingState();
};
private updateRecordingState() {
this.voiceRecording = VoiceRecordingStore.instance.getActiveRecording(this.props.room.roomId);
if (this.voiceRecording) {
// If the recording has already started, it's probably a cached one.
if (this.voiceRecording.hasRecording && !this.voiceRecording.isRecording) {
this.setState({ haveRecording: true });
}
// Note: Listeners for recording states are set by the `this.voiceRecording` setter.
} else {
this.setState({ haveRecording: false });
}
}
private onRecordingStarted = () => {
// update the recording instance, just in case
this.voiceRecording = VoiceRecordingStore.instance.getActiveRecording(this.props.room.roomId);
this.setState({
haveRecording: !!this.voiceRecording,
});
};
private onRecordingEndingSoon = ({ secondsLeft }) => {
this.setState({ recordingTimeLeftSeconds: secondsLeft });
setTimeout(() => this.setState({ recordingTimeLeftSeconds: null }), 3000);
};
private setStickerPickerOpen = (isStickerPickerOpen: boolean) => {
this.setState({
isStickerPickerOpen,
isMenuOpen: false,
});
};
private toggleStickerPickerOpen = () => {
this.setStickerPickerOpen(!this.state.isStickerPickerOpen);
};
private toggleButtonMenu = (): void => {
this.setState({
isMenuOpen: !this.state.isMenuOpen,
});
};
public render() {
const controls = [];
let menuPosition: AboveLeftOf | undefined;
if (this.ref.current) {
const contentRect = this.ref.current.getBoundingClientRect();
menuPosition = aboveLeftOf(contentRect);
}
const roomReplaced = !!this.context.tombstone;
const canSendMessages = this.context.canSendMessages && !this.context.tombstone;
if (canSendMessages) {
controls.push(
,
);
} else if (roomReplaced) {
const replacementRoomId = this.context.tombstone.getContent()['replacement_room'];
controls.push(
{ _t("This room has been replaced and is no longer active.") }
{ replacementRoomId && (
{ _t("The conversation continues here.") }
) }
);
} else {
controls.push(
{ _t('You do not have permission to post to this room') }
,
);
}
let recordingTooltip;
const secondsLeft = Math.round(this.state.recordingTimeLeftSeconds);
if (secondsLeft) {
recordingTooltip = ;
}
const threadId = this.props.relation?.rel_type === THREAD_RELATION_TYPE.name
? this.props.relation.event_id
: null;
controls.push(
,
);
const showSendButton = !this.state.isComposerEmpty || this.state.haveRecording;
if (this.props.e2eStatus) {
controls.push(
,
);
}
const classes = classNames({
"mx_MessageComposer": true,
"mx_GroupLayout": true,
"mx_MessageComposer--compact": this.props.compact,
"mx_MessageComposer_e2eStatus": this.props.e2eStatus != undefined,
});
return (
{ recordingTooltip }
{ controls }
{ canSendMessages &&
}
{ canSendMessages &&
{
this.voiceRecordingButton.current?.onRecordStartEndClick();
if (this.context.narrow) {
this.toggleButtonMenu();
}
}}
setStickerPickerOpen={this.setStickerPickerOpen}
showLocationButton={!window.electron}
showPollsButton={this.state.showPollsButton}
showStickersButton={this.state.showStickersButton}
toggleButtonMenu={this.toggleButtonMenu}
/> }
{}}
>
);
}
}