From c72794209508ef16ecf4f39d9b1d1af63f96fa5d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 2 Mar 2022 16:31:34 +0000 Subject: [PATCH] Autofocus correct composer after sending reaction (#7950) --- src/components/structures/RoomView.tsx | 8 +++- .../views/emojipicker/ReactionPicker.tsx | 46 +++++++++++-------- src/dispatcher/actions.ts | 3 +- .../payloads/FocusComposerPayload.ts | 5 +- 4 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 46f14a53cc..8c2e886077 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -107,6 +107,7 @@ import { JoinRoomPayload } from "../../dispatcher/payloads/JoinRoomPayload"; import { DoAfterSyncPreparedPayload } from '../../dispatcher/payloads/DoAfterSyncPreparedPayload'; import FileDropTarget from './FileDropTarget'; import Measured from '../views/elements/Measured'; +import { FocusComposerPayload } from '../../dispatcher/payloads/FocusComposerPayload'; const DEBUG = false; let debuglog = function(msg: string) {}; @@ -918,8 +919,11 @@ export class RoomView extends React.Component { } case Action.FocusAComposer: { - // re-dispatch to the correct composer - dis.fire(this.state.editState ? Action.FocusEditMessageComposer : Action.FocusSendMessageComposer); + dis.dispatch({ + ...(payload as FocusComposerPayload), + // re-dispatch to the correct composer + action: this.state.editState ? Action.FocusEditMessageComposer : Action.FocusSendMessageComposer, + }); break; } diff --git a/src/components/views/emojipicker/ReactionPicker.tsx b/src/components/views/emojipicker/ReactionPicker.tsx index 1f74879681..df18949233 100644 --- a/src/components/views/emojipicker/ReactionPicker.tsx +++ b/src/components/views/emojipicker/ReactionPicker.tsx @@ -17,16 +17,20 @@ limitations under the License. import React from 'react'; import { MatrixEvent } from "matrix-js-sdk/src/models/event"; +import { Relations, RelationsEvent } from 'matrix-js-sdk/src/models/relations'; +import { EventType, RelationType } from 'matrix-js-sdk/src/@types/event'; import EmojiPicker from "./EmojiPicker"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import dis from "../../../dispatcher/dispatcher"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import { Action } from '../../../dispatcher/actions'; +import RoomContext from "../../../contexts/RoomContext"; +import { FocusComposerPayload } from '../../../dispatcher/payloads/FocusComposerPayload'; interface IProps { mxEvent: MatrixEvent; - reactions: any; // TODO type this once js-sdk is more typescripted + reactions?: Relations; onFinished(): void; } @@ -36,8 +40,11 @@ interface IState { @replaceableComponent("views.emojipicker.ReactionPicker") class ReactionPicker extends React.Component { - constructor(props) { - super(props); + static contextType = RoomContext; + public context!: React.ContextType; + + constructor(props: IProps, context: React.ContextType) { + super(props, context); this.state = { selectedEmojis: new Set(Object.keys(this.getReactions())), @@ -54,17 +61,17 @@ class ReactionPicker extends React.Component { private addListeners() { if (this.props.reactions) { - this.props.reactions.on("Relations.add", this.onReactionsChange); - this.props.reactions.on("Relations.remove", this.onReactionsChange); - this.props.reactions.on("Relations.redaction", this.onReactionsChange); + this.props.reactions.on(RelationsEvent.Add, this.onReactionsChange); + this.props.reactions.on(RelationsEvent.Remove, this.onReactionsChange); + this.props.reactions.on(RelationsEvent.Redaction, this.onReactionsChange); } } componentWillUnmount() { if (this.props.reactions) { - this.props.reactions.removeListener("Relations.add", this.onReactionsChange); - this.props.reactions.removeListener("Relations.remove", this.onReactionsChange); - this.props.reactions.removeListener("Relations.redaction", this.onReactionsChange); + this.props.reactions.removeListener(RelationsEvent.Add, this.onReactionsChange); + this.props.reactions.removeListener(RelationsEvent.Remove, this.onReactionsChange); + this.props.reactions.removeListener(RelationsEvent.Redaction, this.onReactionsChange); } } @@ -85,28 +92,31 @@ class ReactionPicker extends React.Component { }); }; - onChoose = (reaction: string) => { + private onChoose = (reaction: string) => { this.componentWillUnmount(); this.props.onFinished(); const myReactions = this.getReactions(); if (myReactions.hasOwnProperty(reaction)) { - MatrixClientPeg.get().redactEvent( - this.props.mxEvent.getRoomId(), - myReactions[reaction], - ); - dis.fire(Action.FocusAComposer); + MatrixClientPeg.get().redactEvent(this.props.mxEvent.getRoomId(), myReactions[reaction]); + dis.dispatch({ + action: Action.FocusAComposer, + context: this.context.timelineRenderingType, + }); // Tell the emoji picker not to bump this in the more frequently used list. return false; } else { - MatrixClientPeg.get().sendEvent(this.props.mxEvent.getRoomId(), "m.reaction", { + MatrixClientPeg.get().sendEvent(this.props.mxEvent.getRoomId(), EventType.Reaction, { "m.relates_to": { - "rel_type": "m.annotation", + "rel_type": RelationType.Annotation, "event_id": this.props.mxEvent.getId(), "key": reaction, }, }); dis.dispatch({ action: "message_sent" }); - dis.fire(Action.FocusAComposer); + dis.dispatch({ + action: Action.FocusAComposer, + context: this.context.timelineRenderingType, + }); return true; } }; diff --git a/src/dispatcher/actions.ts b/src/dispatcher/actions.ts index 9a4341cfc0..80e01bfaaf 100644 --- a/src/dispatcher/actions.ts +++ b/src/dispatcher/actions.ts @@ -77,8 +77,7 @@ export enum Action { /** * 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. + * composer based on the current edit state. Should be used with a FocusComposerPayload. */ FocusAComposer = "focus_a_composer", diff --git a/src/dispatcher/payloads/FocusComposerPayload.ts b/src/dispatcher/payloads/FocusComposerPayload.ts index 29655a4b7a..3c3d7fa619 100644 --- a/src/dispatcher/payloads/FocusComposerPayload.ts +++ b/src/dispatcher/payloads/FocusComposerPayload.ts @@ -19,7 +19,10 @@ import { Action } from "../actions"; import { TimelineRenderingType } from "../../contexts/RoomContext"; export interface FocusComposerPayload extends ActionPayload { - action: Action.FocusEditMessageComposer | Action.FocusSendMessageComposer | "reply_to_event"; + action: Action.FocusAComposer + | Action.FocusEditMessageComposer + | Action.FocusSendMessageComposer + | "reply_to_event"; context?: TimelineRenderingType; // defaults to Room type for backwards compatibility }