2022-07-05 20:26:44 +02:00
|
|
|
/*
|
2024-09-09 14:57:16 +01:00
|
|
|
Copyright 2024 New Vector Ltd.
|
2022-07-05 20:26:44 +02:00
|
|
|
Copyright 2022 The Matrix.org Foundation C.I.C.
|
|
|
|
|
|
2025-01-06 11:18:54 +00:00
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
2024-09-09 14:57:16 +01:00
|
|
|
Please see LICENSE files in the repository root for full details.
|
2022-07-05 20:26:44 +02:00
|
|
|
*/
|
|
|
|
|
|
2025-04-09 19:03:09 +00:00
|
|
|
import React, { createRef, type RefObject } from "react";
|
2025-02-05 13:25:06 +00:00
|
|
|
import { type DialogContent, type DialogProps } from "@matrix-org/react-sdk-module-api/lib/components/DialogContent";
|
2022-07-05 20:26:44 +02:00
|
|
|
import { logger } from "matrix-js-sdk/src/logger";
|
2025-02-05 13:25:06 +00:00
|
|
|
import { type ModuleApi } from "@matrix-org/react-sdk-module-api/lib/ModuleApi";
|
|
|
|
|
import { type ModuleUiDialogOptions } from "@matrix-org/react-sdk-module-api/lib/types/ModuleUiDialogOptions";
|
2022-07-05 20:26:44 +02:00
|
|
|
|
2025-02-05 13:25:06 +00:00
|
|
|
import ScrollableBaseModal, { type IScrollableBaseState } from "./ScrollableBaseModal";
|
2022-07-05 20:26:44 +02:00
|
|
|
import { _t } from "../../../languageHandler";
|
|
|
|
|
|
2023-07-07 13:37:26 +01:00
|
|
|
interface IProps<P extends DialogProps, C extends DialogContent<P>> {
|
2025-03-28 10:07:41 +00:00
|
|
|
contentFactory: (props: P, ref: React.RefObject<C | null>) => React.ReactNode;
|
2023-08-21 14:09:17 +02:00
|
|
|
additionalContentProps: Omit<P, keyof DialogProps> | undefined;
|
|
|
|
|
initialOptions: ModuleUiDialogOptions;
|
|
|
|
|
moduleApi: ModuleApi;
|
|
|
|
|
onFinished(ok?: boolean, model?: Awaited<ReturnType<DialogContent<P & DialogProps>["trySubmit"]>>): void;
|
2022-07-05 20:26:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface IState extends IScrollableBaseState {
|
|
|
|
|
// nothing special
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-09 19:03:09 +00:00
|
|
|
export class ModuleUiDialog<
|
|
|
|
|
P extends DialogProps = DialogProps,
|
|
|
|
|
C extends DialogContent<P> = DialogContent<P>,
|
|
|
|
|
> extends ScrollableBaseModal<IProps<P, C>, IState> {
|
2023-07-07 13:37:26 +01:00
|
|
|
private contentRef = createRef<C>();
|
2022-07-05 20:26:44 +02:00
|
|
|
|
2023-07-07 13:37:26 +01:00
|
|
|
public constructor(props: IProps<P, C>) {
|
2022-07-05 20:26:44 +02:00
|
|
|
super(props);
|
|
|
|
|
|
|
|
|
|
this.state = {
|
2023-08-21 14:09:17 +02:00
|
|
|
title: this.props.initialOptions.title,
|
2023-08-22 20:55:15 +01:00
|
|
|
actionLabel: this.props.initialOptions.actionLabel ?? _t("action|ok"),
|
2023-08-21 14:09:17 +02:00
|
|
|
cancelLabel: this.props.initialOptions.cancelLabel,
|
|
|
|
|
canSubmit: this.props.initialOptions.canSubmit ?? true,
|
2022-07-05 20:26:44 +02:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-12 13:25:14 +00:00
|
|
|
protected async submit(): Promise<void> {
|
2022-07-05 20:26:44 +02:00
|
|
|
try {
|
2023-04-28 09:45:36 +01:00
|
|
|
const model = await this.contentRef.current!.trySubmit();
|
2022-07-05 20:26:44 +02:00
|
|
|
this.props.onFinished(true, model);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
logger.error("Error during submission of module dialog:", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected cancel(): void {
|
|
|
|
|
this.props.onFinished(false);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-21 14:09:17 +02:00
|
|
|
private setOptions(options: ModuleUiDialogOptions): void {
|
|
|
|
|
this.setState((state) => ({ ...state, ...options }));
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-05 20:26:44 +02:00
|
|
|
protected renderContent(): React.ReactNode {
|
2023-08-21 14:09:17 +02:00
|
|
|
const dialogProps: DialogProps = {
|
|
|
|
|
moduleApi: this.props.moduleApi,
|
|
|
|
|
setOptions: this.setOptions.bind(this),
|
|
|
|
|
cancel: this.cancel.bind(this),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Typescript isn't very happy understanding that `contentProps` satisfies `P`
|
|
|
|
|
const contentProps: P = {
|
|
|
|
|
...this.props.additionalContentProps,
|
|
|
|
|
...dialogProps,
|
|
|
|
|
} as unknown as P;
|
|
|
|
|
|
2025-04-09 19:03:09 +00:00
|
|
|
// XXX: we have to fudge the types here a little as the react-sdk-module-api lacks React 19 support
|
|
|
|
|
return (
|
|
|
|
|
<div className="mx_ModuleUiDialog">
|
|
|
|
|
{this.props.contentFactory(contentProps, this.contentRef as RefObject<C>)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2022-07-05 20:26:44 +02:00
|
|
|
}
|
|
|
|
|
}
|