From 64f32a9fc154cb274b2e8bb75ea64f77f87f7491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 8 Jul 2021 13:12:57 +0200 Subject: [PATCH 1/6] Focus composer after reacting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/views/emojipicker/ReactionPicker.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/views/emojipicker/ReactionPicker.tsx b/src/components/views/emojipicker/ReactionPicker.tsx index d8f8b7f2ff..d5a2277ab2 100644 --- a/src/components/views/emojipicker/ReactionPicker.tsx +++ b/src/components/views/emojipicker/ReactionPicker.tsx @@ -22,6 +22,7 @@ import EmojiPicker from "./EmojiPicker"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import dis from "../../../dispatcher/dispatcher"; import { replaceableComponent } from "../../../utils/replaceableComponent"; +import { Action } from '../../../dispatcher/actions'; interface IProps { mxEvent: MatrixEvent; @@ -93,6 +94,7 @@ class ReactionPicker extends React.Component { this.props.mxEvent.getRoomId(), myReactions[reaction], ); + dis.dispatch({ action: Action.FocusComposer }); // Tell the emoji picker not to bump this in the more frequently used list. return false; } else { @@ -104,6 +106,7 @@ class ReactionPicker extends React.Component { }, }); dis.dispatch({ action: "message_sent" }); + dis.dispatch({ action: Action.FocusComposer }); return true; } }; From 7734f8aeefcbbc2d9186f6efa88a537d6040c253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 8 Jul 2021 17:33:49 +0200 Subject: [PATCH 2/6] Handle focusing multiple composers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/structures/RoomView.tsx | 16 ++++++++++++++++ .../views/emojipicker/ReactionPicker.tsx | 4 ++-- .../views/rooms/EditMessageComposer.tsx | 2 ++ src/dispatcher/actions.ts | 14 +++++++++++++- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 0e77c301fd..0b345de49f 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -832,6 +832,22 @@ export default class RoomView extends React.Component { break; } + case Action.FocusAComposer: { + // re-dispatch to the correct composer + if (this.state.editState) { + dis.dispatch({ + ...payload, + action: Action.FocusEditMessageComposer, + }); + } else { + dis.dispatch({ + ...payload, + action: Action.FocusComposer, + }); + } + break; + } + case "scroll_to_bottom": this.messagePanel?.jumpToLiveTimeline(); break; diff --git a/src/components/views/emojipicker/ReactionPicker.tsx b/src/components/views/emojipicker/ReactionPicker.tsx index d5a2277ab2..e129b45c9a 100644 --- a/src/components/views/emojipicker/ReactionPicker.tsx +++ b/src/components/views/emojipicker/ReactionPicker.tsx @@ -94,7 +94,7 @@ class ReactionPicker extends React.Component { this.props.mxEvent.getRoomId(), myReactions[reaction], ); - dis.dispatch({ action: Action.FocusComposer }); + dis.dispatch({ action: Action.FocusAComposer }); // Tell the emoji picker not to bump this in the more frequently used list. return false; } else { @@ -106,7 +106,7 @@ class ReactionPicker extends React.Component { }, }); dis.dispatch({ action: "message_sent" }); - dis.dispatch({ action: Action.FocusComposer }); + dis.dispatch({ action: Action.FocusAComposer }); return true; } }; diff --git a/src/components/views/rooms/EditMessageComposer.tsx b/src/components/views/rooms/EditMessageComposer.tsx index fea6499dd8..3bfa121799 100644 --- a/src/components/views/rooms/EditMessageComposer.tsx +++ b/src/components/views/rooms/EditMessageComposer.tsx @@ -452,6 +452,8 @@ export default class EditMessageComposer extends React.Component } else if (payload.text) { this.editorRef.current?.insertPlaintext(payload.text); } + } else if (payload.action === Action.FocusEditMessageComposer && this.editorRef.current) { + this.editorRef.current.focus(); } }; diff --git a/src/dispatcher/actions.ts b/src/dispatcher/actions.ts index 6438ecc0f2..d376560ace 100644 --- a/src/dispatcher/actions.ts +++ b/src/dispatcher/actions.ts @@ -56,10 +56,22 @@ export enum Action { CheckUpdates = "check_updates", /** - * Focuses the user's cursor to the composer. No additional payload information required. + * Focuses the user's cursor to the send message composer. No additional payload information required. */ FocusComposer = "focus_composer", + /** + * Focuses the user's cursor to the edit message composer. No additional payload information required. + */ + FocusEditMessageComposer = "focus_edit_message_composer", + + /** + * Focuses the user's cursor to the edit message composer or send message + * composer based on the current edit state. No additional payload + * information required. + */ + FocusAComposer = "focus_a_composer", + /** * Opens the user menu (previously known as the top left menu). No additional payload information required. */ From 68d194444a907b5dafcc88f7271a48cdb9310485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 8 Jul 2021 17:36:31 +0200 Subject: [PATCH 3/6] FocusComposer -> FocusSendMessageComposer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/ContentMessages.tsx | 2 +- src/components/structures/LoggedInView.tsx | 4 ++-- src/components/structures/MatrixChat.tsx | 4 ++-- src/components/structures/RoomSearch.tsx | 2 +- src/components/structures/RoomStatusBar.js | 4 ++-- src/components/structures/RoomView.tsx | 6 +++--- src/components/views/elements/ReplyThread.js | 2 +- src/components/views/rooms/EditMessageComposer.tsx | 6 +++--- src/components/views/rooms/SendMessageComposer.tsx | 2 +- src/dispatcher/actions.ts | 2 +- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/ContentMessages.tsx b/src/ContentMessages.tsx index 670c175a48..0ab193081b 100644 --- a/src/ContentMessages.tsx +++ b/src/ContentMessages.tsx @@ -569,7 +569,7 @@ export default class ContentMessages { dis.dispatch({ action: Action.UploadStarted, upload }); // Focus the composer view - dis.fire(Action.FocusComposer); + dis.fire(Action.FocusSendMessageComposer); function onProgress(ev) { upload.total = ev.total; diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 5a26967cb0..89fa8db376 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -398,7 +398,7 @@ class LoggedInView extends React.Component { // refocusing during a paste event will make the // paste end up in the newly focused element, // so dispatch synchronously before paste happens - dis.fire(Action.FocusComposer, true); + dis.fire(Action.FocusSendMessageComposer, true); } }; @@ -552,7 +552,7 @@ class LoggedInView extends React.Component { if (!isClickShortcut && ev.key !== Key.TAB && !canElementReceiveInput(ev.target)) { // synchronous dispatch so we focus before key generates input - dis.fire(Action.FocusComposer, true); + dis.fire(Action.FocusSendMessageComposer, true); ev.stopPropagation(); // we should *not* preventDefault() here as // that would prevent typing in the now-focussed composer diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index c7a200239c..d692b0fa7f 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -443,7 +443,7 @@ export default class MatrixChat extends React.PureComponent { CountlyAnalytics.instance.trackPageChange(durationMs); } if (this.focusComposer) { - dis.fire(Action.FocusComposer); + dis.fire(Action.FocusSendMessageComposer); this.focusComposer = false; } } @@ -1427,7 +1427,7 @@ export default class MatrixChat extends React.PureComponent { showNotificationsToast(false); } - dis.fire(Action.FocusComposer); + dis.fire(Action.FocusSendMessageComposer); this.setState({ ready: true, }); diff --git a/src/components/structures/RoomSearch.tsx b/src/components/structures/RoomSearch.tsx index 9cdd1efe7e..e8080b4f7b 100644 --- a/src/components/structures/RoomSearch.tsx +++ b/src/components/structures/RoomSearch.tsx @@ -131,7 +131,7 @@ export default class RoomSearch extends React.PureComponent { switch (action) { case RoomListAction.ClearSearch: this.clearInput(); - defaultDispatcher.fire(Action.FocusComposer); + defaultDispatcher.fire(Action.FocusSendMessageComposer); break; case RoomListAction.NextRoom: case RoomListAction.PrevRoom: diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index f6e42a4f9c..80ea26c3f2 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -118,12 +118,12 @@ export default class RoomStatusBar extends React.PureComponent { this.setState({ isResending: false }); }); this.setState({ isResending: true }); - dis.fire(Action.FocusComposer); + dis.fire(Action.FocusSendMessageComposer); }; _onCancelAllClick = () => { Resend.cancelUnsentEvents(this.props.room); - dis.fire(Action.FocusComposer); + dis.fire(Action.FocusSendMessageComposer); }; _onRoomLocalEchoUpdated = (event, room, oldEventId, oldStatus) => { diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 0b345de49f..0f8d7189b7 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -842,7 +842,7 @@ export default class RoomView extends React.Component { } else { dis.dispatch({ ...payload, - action: Action.FocusComposer, + action: Action.FocusSendMessageComposer, }); } break; @@ -1262,7 +1262,7 @@ export default class RoomView extends React.Component { ContentMessages.sharedInstance().sendContentListToRoom( ev.dataTransfer.files, this.state.room.roomId, this.context, ); - dis.fire(Action.FocusComposer); + dis.fire(Action.FocusSendMessageComposer); this.setState({ draggingFile: false, @@ -1564,7 +1564,7 @@ export default class RoomView extends React.Component { } else { // Otherwise we have to jump manually this.messagePanel.jumpToLiveTimeline(); - dis.fire(Action.FocusComposer); + dis.fire(Action.FocusSendMessageComposer); } }; diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index aea447c9b1..2047de6c58 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -334,7 +334,7 @@ export default class ReplyThread extends React.Component { events, }); - dis.fire(Action.FocusComposer); + dis.fire(Action.FocusSendMessageComposer); } render() { diff --git a/src/components/views/rooms/EditMessageComposer.tsx b/src/components/views/rooms/EditMessageComposer.tsx index 3bfa121799..e4b13e2155 100644 --- a/src/components/views/rooms/EditMessageComposer.tsx +++ b/src/components/views/rooms/EditMessageComposer.tsx @@ -181,7 +181,7 @@ export default class EditMessageComposer extends React.Component } else { this.clearStoredEditorState(); dis.dispatch({ action: 'edit_event', event: null }); - dis.fire(Action.FocusComposer); + dis.fire(Action.FocusSendMessageComposer); } event.preventDefault(); break; @@ -200,7 +200,7 @@ export default class EditMessageComposer extends React.Component private cancelEdit = (): void => { this.clearStoredEditorState(); dis.dispatch({ action: "edit_event", event: null }); - dis.fire(Action.FocusComposer); + dis.fire(Action.FocusSendMessageComposer); }; private get shouldSaveStoredEditorState(): boolean { @@ -375,7 +375,7 @@ export default class EditMessageComposer extends React.Component // close the event editing and focus composer dis.dispatch({ action: "edit_event", event: null }); - dis.fire(Action.FocusComposer); + dis.fire(Action.FocusSendMessageComposer); }; private cancelPreviousPendingEdit(): void { diff --git a/src/components/views/rooms/SendMessageComposer.tsx b/src/components/views/rooms/SendMessageComposer.tsx index 2c45c1bbf8..0639c20fef 100644 --- a/src/components/views/rooms/SendMessageComposer.tsx +++ b/src/components/views/rooms/SendMessageComposer.tsx @@ -497,7 +497,7 @@ export default class SendMessageComposer extends React.Component { switch (payload.action) { case 'reply_to_event': - case Action.FocusComposer: + case Action.FocusSendMessageComposer: this.editorRef.current?.focus(); break; case "send_composer_insert": diff --git a/src/dispatcher/actions.ts b/src/dispatcher/actions.ts index d376560ace..26011063b7 100644 --- a/src/dispatcher/actions.ts +++ b/src/dispatcher/actions.ts @@ -58,7 +58,7 @@ export enum Action { /** * Focuses the user's cursor to the send message composer. No additional payload information required. */ - FocusComposer = "focus_composer", + FocusSendMessageComposer = "focus_composer", /** * Focuses the user's cursor to the edit message composer. No additional payload information required. From 6401577fe49ea2e81a26299cc96dc56a0af7a72f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 8 Jul 2021 17:37:39 +0200 Subject: [PATCH 4/6] focus_composer -> focus_send_message_composer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/dispatcher/actions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dispatcher/actions.ts b/src/dispatcher/actions.ts index 26011063b7..a4bfa171cd 100644 --- a/src/dispatcher/actions.ts +++ b/src/dispatcher/actions.ts @@ -58,7 +58,7 @@ export enum Action { /** * Focuses the user's cursor to the send message composer. No additional payload information required. */ - FocusSendMessageComposer = "focus_composer", + FocusSendMessageComposer = "focus_send_message_composer", /** * Focuses the user's cursor to the edit message composer. No additional payload information required. From 27db0da43738dfed89028044f0032d895c7dc28d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 8 Jul 2021 17:40:41 +0200 Subject: [PATCH 5/6] Simpler code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/structures/RoomView.tsx | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 0f8d7189b7..3ba14b32fb 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -834,17 +834,7 @@ export default class RoomView extends React.Component { case Action.FocusAComposer: { // re-dispatch to the correct composer - if (this.state.editState) { - dis.dispatch({ - ...payload, - action: Action.FocusEditMessageComposer, - }); - } else { - dis.dispatch({ - ...payload, - action: Action.FocusSendMessageComposer, - }); - } + dis.fire(this.state.editState ? Action.FocusEditMessageComposer : Action.FocusSendMessageComposer); break; } From 7a1381135aab49837215ead81f963682f5fdf61e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 8 Jul 2021 18:31:47 +0200 Subject: [PATCH 6/6] Simplifie some code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/components/structures/RoomView.tsx | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 3ba14b32fb..8e0b8a5f4a 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -818,17 +818,10 @@ export default class RoomView extends React.Component { case Action.ComposerInsert: { // re-dispatch to the correct composer - if (this.state.editState) { - dis.dispatch({ - ...payload, - action: "edit_composer_insert", - }); - } else { - dis.dispatch({ - ...payload, - action: "send_composer_insert", - }); - } + dis.dispatch({ + ...payload, + action: this.state.editState ? "edit_composer_insert" : "send_composer_insert", + }); break; }