UNPKG

on-codemerge

Version:

A WYSIWYG editor for on-codemerge is a user-friendly interface that allows users to edit and view their code in real time, exactly as it will appear in the final product

134 lines (133 loc) 5.96 kB
var p = Object.defineProperty; var h = (o, e, t) => e in o ? p(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t; var l = (o, e, t) => h(o, typeof e != "symbol" ? e + "" : e, t); import { PopupManager as u } from "../../../core/ui/PopupManager.mjs"; import c from "../../../icons/upload-message.svg.mjs"; import { createContainer as r, createP as n, createInputField as g } from "../../../utils/helpers.mjs"; class w { constructor(e, t, a, s) { l(this, "editor"); l(this, "popup"); l(this, "uploader"); l(this, "config"); l(this, "onUpload", null); // Ссылки на элементы l(this, "uploadArea", null); l(this, "uploadMessage", null); l(this, "uploadProgress", null); l(this, "progressFill", null); l(this, "filename", null); this.onUpload = s, this.editor = e, this.uploader = t, this.config = a, this.popup = new u(e, { title: "Upload File", className: "file-upload-menu", closeOnClickOutside: !0, buttons: [ { label: e.t("Cancel"), variant: "secondary", onClick: () => this.popup.hide() } ], items: [ { type: "custom", id: "upload-content", content: () => this.createUploadContent() } ] }); } createUploadContent() { const e = r("p-4"); this.uploadArea = r( "upload-area border-2 border-dashed border-gray-300 rounded-lg p-8 text-center" ), this.uploadMessage = r("upload-message"), this.uploadMessage.insertAdjacentHTML("afterbegin", c); const t = n("p"); t.className = "mt-2 text-sm text-gray-600", t.innerHTML = ` ${this.editor.t("Drag and drop your file here, or")} <button type="button" class="browse-button text-blue-500 hover:text-blue-700"> ${this.editor.t("browse")} </button> `, this.uploadMessage.appendChild(t); const a = n( "mt-1 text-xs text-gray-500", this.editor.t("Maximum file size: ") + this.uploader.formatFileSize(this.config.maxFileSize ?? 10 * 1024 * 1024) ); this.uploadMessage.appendChild(a), this.uploadProgress = r("upload-progress hidden"); const s = r( "progress-bar h-2 bg-gray-200 rounded-full overflow-hidden" ); this.progressFill = r( "progress-fill h-full bg-blue-500 transition-all duration-300" ), this.progressFill.style.width = "0%", s.appendChild(this.progressFill), this.uploadProgress.appendChild(s), this.filename = n( "mt-2 text-sm text-gray-600", `${this.editor.t("Uploading")} <span class="filename"></span>...` ), this.uploadProgress.appendChild(this.filename); const i = g("file"); return i.className = "hidden", this.uploadArea.appendChild(this.uploadMessage), this.uploadArea.appendChild(this.uploadProgress), e.appendChild(this.uploadArea), e.appendChild(i), this.setupEventListeners(this.uploadArea, i), e; } setupEventListeners(e, t) { const a = e.querySelector(".browse-button"); this.editor.on( "file-drop", async (s) => { var i; if (!s.type.startsWith("image/")) { if ((i = this.editor) == null || i.ensureEditorFocus(), s.content instanceof File) await this.handleFileUpload(s.content); else if (s.content instanceof ArrayBuffer) { const d = new File([s.content], s.name, { type: s.type }); await this.handleFileUpload(d); } else if (typeof s.content == "string") { const d = new File([s.content], s.name, { type: "text/plain" }); await this.handleFileUpload(d); } } } ), a.addEventListener("click", () => { t.click(); }), t.addEventListener("change", async () => { var i; const s = (i = t.files) == null ? void 0 : i[0]; s && (await this.handleFileUpload(s), t.value = ""); }); } async handleFileUpload(e) { this.popup.show(), setTimeout(async () => { if (e.size > 10 * 1024 * 1024) { alert( this.editor.t("File size exceeds 10MB limit", { max: this.uploader.formatFileSize(this.config.maxFileSize ?? 10 * 1024 * 1024) }) ); return; } if (!this.uploadMessage || !this.uploadProgress || !this.progressFill || !this.filename) { console.error("UI elements are not initialized"); return; } this.uploadMessage.classList.add("hidden"), this.uploadProgress.classList.remove("hidden"), this.filename.textContent = e.name; let t = 0; const a = setInterval(() => { t = Math.min(95, t + 5), this.progressFill.style.width = `${t}%`; }, 50); try { const s = await this.uploader.uploadFile(e); clearInterval(a), this.progressFill.style.width = "100%", await new Promise((i) => setTimeout(i, 500)), this.onUpload && this.onUpload(s), this.popup.hide(), setTimeout(() => { this.uploadMessage.classList.remove("hidden"), this.uploadProgress.classList.add("hidden"), this.progressFill.style.width = "0%"; }, 300); } catch { clearInterval(a), alert(this.editor.t("Upload failed. Please try again.")), this.uploadMessage.classList.remove("hidden"), this.uploadProgress.classList.add("hidden"), this.progressFill.style.width = "0%"; } }, 100); } show() { this.uploadMessage && this.uploadProgress && this.progressFill && (this.uploadMessage.classList.remove("hidden"), this.uploadProgress.classList.add("hidden"), this.progressFill.style.width = "0%"), this.popup.show(); } destroy() { this.popup.hide(), this.uploadArea && (this.editor.off("drag-enter"), this.editor.off("drag-leave"), this.editor.off("drop")), this.uploadArea = null, this.uploadMessage = null, this.uploadProgress = null, this.progressFill = null, this.filename = null, this.editor = null, this.uploader = null, this.popup = null, this.onUpload = null; } } export { w as FileUploadMenu };