Autofocus correct composer after sending reaction (#7950)

pull/21833/head
Michael Telatynski 2022-03-02 16:31:34 +00:00 committed by GitHub
parent 61cd463a3b
commit c727942095
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 23 deletions

View File

@ -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<IRoomProps, IRoomState> {
}
case Action.FocusAComposer: {
// re-dispatch to the correct composer
dis.fire(this.state.editState ? Action.FocusEditMessageComposer : Action.FocusSendMessageComposer);
dis.dispatch<FocusComposerPayload>({
...(payload as FocusComposerPayload),
// re-dispatch to the correct composer
action: this.state.editState ? Action.FocusEditMessageComposer : Action.FocusSendMessageComposer,
});
break;
}

View File

@ -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<IProps, IState> {
constructor(props) {
super(props);
static contextType = RoomContext;
public context!: React.ContextType<typeof RoomContext>;
constructor(props: IProps, context: React.ContextType<typeof RoomContext>) {
super(props, context);
this.state = {
selectedEmojis: new Set(Object.keys(this.getReactions())),
@ -54,17 +61,17 @@ class ReactionPicker extends React.Component<IProps, IState> {
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<IProps, IState> {
});
};
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<FocusComposerPayload>({
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<FocusComposerPayload>({
action: Action.FocusAComposer,
context: this.context.timelineRenderingType,
});
return true;
}
};

View File

@ -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",

View File

@ -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
}