import { prepareRequest } from "WoltLabSuite/Core/Ajax/Backend";
import { ApiResult, apiResultFromError, apiResultFromValue } from "../../Result";
-export type Response =
- | {
- completed: false;
- }
- | {
- completed: true;
- generateThumbnails: boolean;
- fileID: number;
- typeName: string;
- mimeType: string;
- link: string;
- data: Record<string, unknown>;
- };
+export type ResponseIncomplete = {
+ completed: false;
+};
+export type ResponseCompleted = {
+ completed: true;
+ generateThumbnails: boolean;
+ fileID: number;
+ typeName: string;
+ mimeType: string;
+ link: string;
+ data: Record<string, unknown>;
+};
+
+export type Response = ResponseIncomplete | ResponseCompleted;
export async function uploadChunk(
identifier: string,
import { deleteFile } from "WoltLabSuite/Core/Api/Files/DeleteFile";
-import { dispatchToCkeditor } from "../Ckeditor/Event";
+import { dispatchToCkeditor, listenToCkeditor } from "../Ckeditor/Event";
import WoltlabCoreFileElement from "../File/woltlab-core-file";
import "../File/woltlab-core-file";
+import { CkeditorDropEvent } from "../File/Upload";
type FileProcessorData = {
attachmentID: number;
return;
}
+ const editor = document.getElementById(editorId);
+ if (editor === null) {
+ // TODO: error handling
+ return;
+ }
+
const uploadButton = container.querySelector("woltlab-core-file-upload");
if (uploadButton === null) {
throw new Error("Expected the container to contain an upload button", {
upload(fileList!, event.detail, editorId);
});
+ listenToCkeditor(editor).uploadAttachment((payload) => {
+ const event = new CustomEvent<CkeditorDropEvent>("ckeditorDrop", {
+ detail: payload,
+ });
+ uploadButton.dispatchEvent(event);
+ });
+
const existingFiles = container.querySelector<HTMLElement>(".attachment__list__existingFiles");
if (existingFiles !== null) {
existingFiles.querySelectorAll("woltlab-core-file").forEach((file) => {
};
};
-type AttachmentData = {
+export type AttachmentData = {
attachmentId: number;
url: string;
};
dispatchToCkeditor(element).uploadAttachment(payload);
return new Promise<UploadResult>((resolve) => {
- void payload.promise!.then(({ attachmentId, url }) => {
- resolve({
- "data-attachment-id": attachmentId.toString(),
- urls: {
- default: url,
- },
- });
- });
+ void payload
+ .promise!.then(({ attachmentId, url }) => {
+ resolve({
+ "data-attachment-id": attachmentId.toString(),
+ urls: {
+ default: url,
+ },
+ });
+ })
+ .catch(() => {});
});
}
import { wheneverFirstSeen } from "WoltLabSuite/Core/Helper/Selector";
import { upload as filesUpload } from "WoltLabSuite/Core/Api/Files/Upload";
import WoltlabCoreFileElement from "./woltlab-core-file";
-import { Response as UploadChunkResponse, uploadChunk } from "WoltLabSuite/Core/Api/Files/Chunk/Chunk";
+import {
+ ResponseCompleted,
+ Response as UploadChunkResponse,
+ uploadChunk,
+} from "WoltLabSuite/Core/Api/Files/Chunk/Chunk";
import { generateThumbnails } from "WoltLabSuite/Core/Api/Files/GenerateThumbnails";
import ImageResizer from "WoltLabSuite/Core/Image/Resizer";
+import { AttachmentData } from "../Ckeditor/Attachment";
+
+export type CkeditorDropEvent = {
+ file: File;
+ promise?: Promise<unknown>;
+};
export type ThumbnailsGenerated = {
data: GenerateThumbnailsResponse;
quality: number;
};
-async function upload(element: WoltlabCoreFileUploadElement, file: File): Promise<void> {
+async function upload(element: WoltlabCoreFileUploadElement, file: File): Promise<ResponseCompleted | undefined> {
const typeName = element.dataset.typeName!;
const fileHash = await getSha256Hash(await file.arrayBuffer());
}
console.log(validationError);
- return;
+ return undefined;
}
const { identifier, numberOfChunks } = response.value;
}
await chunkUploadCompleted(fileElement, response.value);
+
+ if (response.value.completed) {
+ return response.value;
+ }
}
}
void upload(element, resizedFile);
});
});
+
+ element.addEventListener("ckeditorDrop", (event: CustomEvent<CkeditorDropEvent>) => {
+ const { file } = event.detail;
+
+ let promiseResolve: (data: AttachmentData) => void;
+ let promiseReject: () => void;
+ event.detail.promise = new Promise<AttachmentData>((resolve, reject) => {
+ promiseResolve = resolve;
+ promiseReject = reject;
+ });
+
+ clearPreviousErrors(element);
+
+ if (!validateFile(element, file)) {
+ promiseReject!();
+
+ return;
+ }
+
+ void resizeImage(element, file).then(async (resizeFile) => {
+ try {
+ const data = await upload(element, resizeFile);
+ if (data === undefined || typeof data.data.attachmentID !== "number") {
+ promiseReject();
+ } else {
+ const attachmentData: AttachmentData = {
+ attachmentId: data.data.attachmentID,
+ url: data.link,
+ };
+
+ promiseResolve(attachmentData);
+ }
+ } catch (e) {
+ promiseReject();
+
+ throw e;
+ }
+ });
+ });
});
}
// TODO: error handling
return;
}
+ const editor = document.getElementById(editorId);
+ if (editor === null) {
+ // TODO: error handling
+ return;
+ }
const uploadButton = container.querySelector("woltlab-core-file-upload");
if (uploadButton === null) {
throw new Error("Expected the container to contain an upload button", {
uploadButton.addEventListener("uploadStart", (event) => {
upload(fileList, event.detail, editorId);
});
+ (0, Event_1.listenToCkeditor)(editor).uploadAttachment((payload) => {
+ const event = new CustomEvent("ckeditorDrop", {
+ detail: payload,
+ });
+ uploadButton.dispatchEvent(event);
+ });
const existingFiles = container.querySelector(".attachment__list__existingFiles");
if (existingFiles !== null) {
existingFiles.querySelectorAll("woltlab-core-file").forEach((file) => {
const payload = { abortController, file };
(0, Event_1.dispatchToCkeditor)(element).uploadAttachment(payload);
return new Promise((resolve) => {
- void payload.promise.then(({ attachmentId, url }) => {
+ void payload
+ .promise.then(({ attachmentId, url }) => {
resolve({
"data-attachment-id": attachmentId.toString(),
urls: {
default: url,
},
});
- });
+ })
+ .catch(() => { });
});
}
function setupInsertAttachment(ckeditor) {
throw response.error;
}
console.log(validationError);
- return;
+ return undefined;
}
const { identifier, numberOfChunks } = response.value;
const chunkSize = Math.ceil(file.size / numberOfChunks);
throw response.error;
}
await chunkUploadCompleted(fileElement, response.value);
+ if (response.value.completed) {
+ return response.value;
+ }
}
}
async function chunkUploadCompleted(fileElement, result) {
void upload(element, resizedFile);
});
});
+ element.addEventListener("ckeditorDrop", (event) => {
+ const { file } = event.detail;
+ let promiseResolve;
+ let promiseReject;
+ event.detail.promise = new Promise((resolve, reject) => {
+ promiseResolve = resolve;
+ promiseReject = reject;
+ });
+ clearPreviousErrors(element);
+ if (!validateFile(element, file)) {
+ promiseReject();
+ return;
+ }
+ void resizeImage(element, file).then(async (resizeFile) => {
+ try {
+ const data = await upload(element, resizeFile);
+ if (data === undefined || typeof data.data.attachmentID !== "number") {
+ promiseReject();
+ }
+ else {
+ const attachmentData = {
+ attachmentId: data.data.attachmentID,
+ url: data.link,
+ };
+ promiseResolve(attachmentData);
+ }
+ }
+ catch (e) {
+ promiseReject();
+ throw e;
+ }
+ });
+ });
});
}
exports.setup = setup;