Allow editing polls (#7806)

This commit is contained in:
Andy Balaam 2022-02-17 09:13:05 +00:00 committed by GitHub
parent fa9af44523
commit 7387f3c80a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 310 additions and 38 deletions

View file

@ -16,7 +16,8 @@ limitations under the License.
import React, { ChangeEvent, createRef } from "react";
import { Room } from "matrix-js-sdk/src/models/room";
import { M_POLL_KIND_DISCLOSED, PollStartEvent } from "matrix-events-sdk";
import { IPartialEvent, M_POLL_KIND_DISCLOSED, M_POLL_START, PollStartEvent } from "matrix-events-sdk";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import ScrollableBaseModal, { IScrollableBaseState } from "../dialogs/ScrollableBaseModal";
import { IDialogProps } from "../dialogs/IDialogProps";
@ -31,6 +32,7 @@ import Spinner from "./Spinner";
interface IProps extends IDialogProps {
room: Room;
threadId?: string;
editingMxEvent?: MatrixEvent; // Truthy if we are editing an existing poll
}
interface IState extends IScrollableBaseState {
@ -45,21 +47,42 @@ const DEFAULT_NUM_OPTIONS = 2;
const MAX_QUESTION_LENGTH = 340;
const MAX_OPTION_LENGTH = 340;
function creatingInitialState(): IState {
return {
title: _t("Create poll"),
actionLabel: _t("Create Poll"),
canSubmit: false, // need to add a question and at least one option first
question: "",
options: arraySeed("", DEFAULT_NUM_OPTIONS),
busy: false,
};
}
function editingInitialState(editingMxEvent: MatrixEvent): IState {
const poll = editingMxEvent.unstableExtensibleEvent as PollStartEvent;
if (!poll?.isEquivalentTo(M_POLL_START)) return creatingInitialState();
return {
title: _t("Edit poll"),
actionLabel: _t("Done"),
canSubmit: true,
question: poll.question.text,
options: poll.answers.map(ans => ans.text),
busy: false,
};
}
export default class PollCreateDialog extends ScrollableBaseModal<IProps, IState> {
private addOptionRef = createRef<HTMLDivElement>();
public constructor(props: IProps) {
super(props);
this.state = {
title: _t("Create poll"),
actionLabel: _t("Create Poll"),
canSubmit: false, // need to add a question and at least one option first
question: "",
options: arraySeed("", DEFAULT_NUM_OPTIONS),
busy: false,
};
this.state = (
props.editingMxEvent
? editingInitialState(props.editingMxEvent)
: creatingInitialState()
);
}
private checkCanSubmit() {
@ -97,13 +120,32 @@ export default class PollCreateDialog extends ScrollableBaseModal<IProps, IState
});
};
protected submit(): void {
this.setState({ busy: true, canSubmit: false });
const pollEvent = PollStartEvent.from(
private createEvent(): IPartialEvent<object> {
const pollStart = PollStartEvent.from(
this.state.question.trim(),
this.state.options.map(a => a.trim()).filter(a => !!a),
M_POLL_KIND_DISCLOSED,
).serialize();
if (!this.props.editingMxEvent) {
return pollStart;
} else {
return {
"content": {
"m.new_content": pollStart.content,
"m.relates_to": {
"rel_type": "m.replace",
"event_id": this.props.editingMxEvent.getId(),
},
},
"type": pollStart.type,
};
}
}
protected submit(): void {
this.setState({ busy: true, canSubmit: false });
const pollEvent = this.createEvent();
this.matrixClient.sendEvent(
this.props.room.roomId,
this.props.threadId,
@ -159,7 +201,10 @@ export default class PollCreateDialog extends ScrollableBaseModal<IProps, IState
maxLength={MAX_OPTION_LENGTH}
label={_t("Option %(number)s", { number: i + 1 })}
placeholder={_t("Write an option")}
onChange={e => this.onOptionChange(i, e)}
onChange={
(e: ChangeEvent<HTMLInputElement>) =>
this.onOptionChange(i, e)
}
usePlaceholderAsHint={true}
disabled={this.state.busy}
/>