Module API for adding new file upload mechanisms (#33355)
* Initial reword of upload to MVVM. * Update tests * More incremental improvements * Refactor tests to use helper method for composer uploads. * Add drag and drop tests * lint * Add commentary * fixup test * More precise selector * Retarget uploads * lint * fixup * one more type * update snap * Fixup composerUploadFiles * fix import * lint * Copy and paste fixes too * Add tests for pasting * Add tests for pasting files. * Remove redundant fn * rm comment * tidy up * Test cleanup * More clean up * another fix * Begin fleshing out * Park changes * More stuff * Use condensed version * Cleanup tests * more cleaning * last bity * Add a test for the composer * Park up changes * Rewrite Measured to be a functional component * Add tests to cover narrow viewports * lint * breakpoint is optional * Cleanup * Support narrow mode * fixup * begone * Provide default value * add label * fixup test * update copyright * cleanup * Be a bit more lazy with FileDropTarget * remove a debug statement * Fixup * fix two snaps * Update screenshot * and the other one * Update snaps * unfake CIDER * update screens again * remove extra test * Undo accidental snapshots * Bit of tidyup * fixup * even more tidyup * may drag and drop file * tidy up again * snap snap snap * Use load to make sonarQube happy * Bunch of refactors * More cleanup * cleanup debug code * tweaks * remove a test we no longer need * make it happy * fix import * fixup * Update snaps * typo * one off * Add tests * lint * remove only * Reduce screenshot scope * fix snapshot usage * cleanup
This commit is contained in:
@@ -5,19 +5,76 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { type ComposerApi as ModuleComposerApi } from "@element-hq/element-web-module-api";
|
||||
import {
|
||||
type ComposerApi as ModuleComposerApi,
|
||||
type ComposerApiFileUploadOption,
|
||||
type ComposerApiTarget,
|
||||
} from "@element-hq/element-web-module-api";
|
||||
import { TypedEventEmitter } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import type { MatrixDispatcher } from "../dispatcher/dispatcher";
|
||||
import { Action } from "../dispatcher/actions";
|
||||
import type { ComposerInsertPayload } from "../dispatcher/payloads/ComposerInsertPayload";
|
||||
import { ComposerType, type ComposerInsertPayload } from "../dispatcher/payloads/ComposerInsertPayload";
|
||||
import { TimelineRenderingType } from "../contexts/RoomContext";
|
||||
import type { ComposerInsertFilesPayload } from "../dispatcher/payloads/ComposerInsertFilePayload";
|
||||
|
||||
export class ComposerApi implements ModuleComposerApi {
|
||||
public constructor(private readonly dispatcher: MatrixDispatcher) {}
|
||||
export enum ModuleComposerApiEvents {
|
||||
UploaderOptionsChanged = "uploaderOptionsChanged",
|
||||
}
|
||||
|
||||
public insertPlaintextIntoComposer(plaintext: string): void {
|
||||
interface ModuleComposerApiEventsMap {
|
||||
[ModuleComposerApiEvents.UploaderOptionsChanged]: (option: ComposerApiFileUploadOption) => void;
|
||||
}
|
||||
|
||||
export class ComposerApi
|
||||
extends TypedEventEmitter<ModuleComposerApiEvents, ModuleComposerApiEventsMap>
|
||||
implements ModuleComposerApi
|
||||
{
|
||||
private readonly configuredFileUploadOptions = new Map<string, ComposerApiFileUploadOption>();
|
||||
|
||||
public constructor(private readonly dispatcher: MatrixDispatcher) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* List of possible file upload options.
|
||||
*/
|
||||
public get fileUploadOptions(): ComposerApiFileUploadOption[] {
|
||||
return [...this.configuredFileUploadOptions.values()];
|
||||
}
|
||||
|
||||
public addFileUploadOption(option: ComposerApiFileUploadOption): void {
|
||||
if (this.configuredFileUploadOptions.has(option.type)) {
|
||||
throw new Error(`Option "${option.type}" already exists`);
|
||||
}
|
||||
if (option.type === "local") {
|
||||
throw new Error(`Option "local" is reserved`);
|
||||
}
|
||||
this.configuredFileUploadOptions.set(option.type, option);
|
||||
this.emit(ModuleComposerApiEvents.UploaderOptionsChanged, option);
|
||||
}
|
||||
|
||||
public openFileUploadConfirmation(files: File[], view: ComposerApiTarget = { view: "room" }): void {
|
||||
if (!["room", "thread"].includes(view.view)) {
|
||||
throw new Error(`Invalid view '${view.view}'`);
|
||||
}
|
||||
this.dispatcher.dispatch({
|
||||
action: Action.ComposerFileInsert,
|
||||
files,
|
||||
timelineRenderingType: view.view === "room" ? TimelineRenderingType.Room : TimelineRenderingType.Thread,
|
||||
} satisfies ComposerInsertFilesPayload);
|
||||
}
|
||||
|
||||
public insertPlaintextIntoComposer(plaintext: string, view: ComposerApiTarget = { view: "room" }): void {
|
||||
if (!["room", "thread"].includes(view.view)) {
|
||||
throw new Error(`Invalid view '${view.view}'`);
|
||||
}
|
||||
this.dispatcher.dispatch({
|
||||
action: Action.ComposerInsert,
|
||||
text: plaintext,
|
||||
timelineRenderingType: view.view === "room" ? TimelineRenderingType.Room : TimelineRenderingType.Thread,
|
||||
// We only support send.
|
||||
composerType: ComposerType.Send,
|
||||
} satisfies ComposerInsertPayload);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user