From 3e52076aebadcee5d8cb32113928ad0f11f7a21a Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Wed, 22 Oct 2025 22:13:23 -0400 Subject: [PATCH] Refactor modal initialization into dedicated helpers --- js/app.js | 131 +++++++++++++++++---------------------- js/ui/initDeleteModal.js | 58 +++++++++++++++++ js/ui/initEditModal.js | 68 ++++++++++++++++++++ js/ui/initUploadModal.js | 67 ++++++++++++++++++++ 4 files changed, 251 insertions(+), 73 deletions(-) create mode 100644 js/ui/initDeleteModal.js create mode 100644 js/ui/initEditModal.js create mode 100644 js/ui/initUploadModal.js diff --git a/js/app.js b/js/app.js index 91c2e421..06368ed0 100644 --- a/js/app.js +++ b/js/app.js @@ -78,10 +78,7 @@ import { removeTrackingScripts, } from "./utils/domUtils.js"; import { VideoModal } from "./ui/components/VideoModal.js"; -import { UploadModal } from "./ui/components/UploadModal.js"; -import { EditModal } from "./ui/components/EditModal.js"; import { RevertModal } from "./ui/components/RevertModal.js"; -import { DeleteModal } from "./ui/components/DeleteModal.js"; import { prepareStaticModal, openStaticModal, @@ -92,6 +89,9 @@ import MoreMenuController from "./ui/moreMenuController.js"; import ProfileModalController from "./ui/profileModalController.js"; import LoginModalController from "./ui/loginModalController.js"; import ZapController from "./ui/zapController.js"; +import initUploadModal from "./ui/initUploadModal.js"; +import initEditModal from "./ui/initEditModal.js"; +import initDeleteModal from "./ui/initDeleteModal.js"; import { MediaLoader } from "./utils/mediaLoader.js"; import { pointerArrayToKey } from "./utils/pointer.js"; import { resolveVideoPointer } from "./utils/videoPointer.js"; @@ -424,44 +424,41 @@ class Application { this.profileButton = document.getElementById("profileButton") || null; this.profileAvatar = document.getElementById("profileAvatar") || null; + const modalContainer = document.getElementById("modalContainer") || null; + // Upload modal component this.uploadButton = document.getElementById("uploadButton") || null; - const uploadModalEvents = new EventTarget(); - this.uploadModal = - (typeof ui.uploadModal === "function" - ? ui.uploadModal({ app: this, eventTarget: uploadModalEvents }) - : ui.uploadModal) || - new UploadModal({ + const uploadModalSetup = initUploadModal({ + app: this, + uploadModalOverride: ui.uploadModal, + container: modalContainer, + services: { authService: this.authService, r2Service: this.r2Service, - publishVideoNote: (payload, options) => - this.publishVideoNote(payload, options), + }, + utilities: { removeTrackingScripts, setGlobalModalState, + }, + callbacks: { + publishVideoNote: (payload, options) => + this.publishVideoNote(payload, options), showError: (message) => this.showError(message), showSuccess: (message) => this.showSuccess(message), getCurrentPubkey: () => this.pubkey, safeEncodeNpub: (pubkey) => this.safeEncodeNpub(pubkey), - eventTarget: uploadModalEvents, - container: document.getElementById("modalContainer") || null, - }); - this.boundUploadSubmitHandler = (event) => { - this.handleUploadSubmitEvent(event); - }; - this.uploadModal.addEventListener( - "upload:submit", - this.boundUploadSubmitHandler - ); + onSubmit: (event) => this.handleUploadSubmitEvent(event), + }, + }); + this.uploadModal = uploadModalSetup.modal; + this.uploadModalEvents = uploadModalSetup.events; + this.boundUploadSubmitHandler = uploadModalSetup.handlers.submit; - const editModalEvents = new EventTarget(); - this.editModal = - (typeof ui.editModal === "function" - ? ui.editModal({ app: this, eventTarget: editModalEvents }) - : ui.editModal) || - new EditModal({ - removeTrackingScripts, - setGlobalModalState, - showError: (message) => this.showError(message), + const editModalSetup = initEditModal({ + app: this, + editModalOverride: ui.editModal, + container: modalContainer, + services: { getMode: () => (isDevMode ? "dev" : "live"), sanitizers: { text: (value) => (typeof value === "string" ? value.trim() : ""), @@ -469,26 +466,23 @@ class Application { magnet: (value) => (typeof value === "string" ? value.trim() : ""), checkbox: (value) => !!value, }, + }, + utilities: { + removeTrackingScripts, + setGlobalModalState, escapeHtml: (value) => escapeHtml(value), - eventTarget: editModalEvents, - container: document.getElementById("modalContainer") || null, - }); + }, + callbacks: { + showError: (message) => this.showError(message), + onSubmit: (event) => this.handleEditModalSubmit(event), + onCancel: () => this.showError(""), + }, + }); - this.boundEditModalSubmitHandler = (event) => { - this.handleEditModalSubmit(event); - }; - this.editModal.addEventListener( - "video:edit-submit", - this.boundEditModalSubmitHandler - ); - - this.boundEditModalCancelHandler = () => { - this.showError(""); - }; - this.editModal.addEventListener( - "video:edit-cancel", - this.boundEditModalCancelHandler - ); + this.editModal = editModalSetup.modal; + this.editModalEvents = editModalSetup.events; + this.boundEditModalSubmitHandler = editModalSetup.handlers.submit; + this.boundEditModalCancelHandler = editModalSetup.handlers.cancel; this.revertModal = (typeof ui.revertModal === "function" @@ -504,7 +498,7 @@ class Application { truncateMiddle, formatShortNpub: (value) => formatShortNpub(value), fallbackThumbnailSrc: FALLBACK_THUMBNAIL_SRC, - container: document.getElementById("modalContainer") || null, + container: modalContainer, }); this.boundRevertConfirmHandler = (event) => { @@ -515,34 +509,25 @@ class Application { this.boundRevertConfirmHandler ); - const deleteModalEvents = new EventTarget(); - this.deleteModal = - (typeof ui.deleteModal === "function" - ? ui.deleteModal({ app: this, eventTarget: deleteModalEvents }) - : ui.deleteModal) || - new DeleteModal({ + const deleteModalSetup = initDeleteModal({ + app: this, + deleteModalOverride: ui.deleteModal, + container: modalContainer, + utilities: { removeTrackingScripts, setGlobalModalState, truncateMiddle, - container: document.getElementById("modalContainer") || null, - eventTarget: deleteModalEvents, - }); + }, + callbacks: { + onConfirm: (event) => this.handleDeleteModalConfirm(event), + onCancel: () => this.showError(""), + }, + }); - this.boundDeleteConfirmHandler = (event) => { - this.handleDeleteModalConfirm(event); - }; - this.deleteModal.addEventListener( - "video:delete-confirm", - this.boundDeleteConfirmHandler - ); - - this.boundDeleteCancelHandler = () => { - this.showError(""); - }; - this.deleteModal.addEventListener( - "video:delete-cancel", - this.boundDeleteCancelHandler - ); + this.deleteModal = deleteModalSetup.modal; + this.deleteModalEvents = deleteModalSetup.events; + this.boundDeleteConfirmHandler = deleteModalSetup.handlers.confirm; + this.boundDeleteCancelHandler = deleteModalSetup.handlers.cancel; try { const profileModalContainer = document.getElementById("modalContainer") || null; diff --git a/js/ui/initDeleteModal.js b/js/ui/initDeleteModal.js new file mode 100644 index 00000000..b8c111bc --- /dev/null +++ b/js/ui/initDeleteModal.js @@ -0,0 +1,58 @@ +import { DeleteModal } from "./components/DeleteModal.js"; + +export function initDeleteModal({ + app = null, + deleteModalOverride = null, + container = null, + utilities = {}, + callbacks = {}, + eventTarget = null, +} = {}) { + const events = eventTarget instanceof EventTarget ? eventTarget : new EventTarget(); + + const { + removeTrackingScripts: removeTrackingScriptsFn = null, + setGlobalModalState: setGlobalModalStateFn = null, + truncateMiddle = null, + } = utilities; + + const { + onConfirm = null, + onCancel = null, + } = callbacks; + + const modal = + (typeof deleteModalOverride === "function" + ? deleteModalOverride({ app, eventTarget: events }) + : deleteModalOverride) || + new DeleteModal({ + removeTrackingScripts: removeTrackingScriptsFn, + setGlobalModalState: setGlobalModalStateFn, + truncateMiddle, + container, + eventTarget: events, + }); + + const boundConfirmHandler = + typeof onConfirm === "function" ? (event) => onConfirm(event) : null; + const boundCancelHandler = typeof onCancel === "function" ? () => onCancel() : null; + + if (boundConfirmHandler && typeof modal?.addEventListener === "function") { + modal.addEventListener("video:delete-confirm", boundConfirmHandler); + } + + if (boundCancelHandler && typeof modal?.addEventListener === "function") { + modal.addEventListener("video:delete-cancel", boundCancelHandler); + } + + return { + modal, + events, + handlers: { + confirm: boundConfirmHandler, + cancel: boundCancelHandler, + }, + }; +} + +export default initDeleteModal; diff --git a/js/ui/initEditModal.js b/js/ui/initEditModal.js new file mode 100644 index 00000000..6e63103e --- /dev/null +++ b/js/ui/initEditModal.js @@ -0,0 +1,68 @@ +import { EditModal } from "./components/EditModal.js"; + +export function initEditModal({ + app = null, + editModalOverride = null, + container = null, + services = {}, + utilities = {}, + callbacks = {}, + eventTarget = null, +} = {}) { + const events = eventTarget instanceof EventTarget ? eventTarget : new EventTarget(); + + const { + getMode = null, + sanitizers = {}, + } = services; + + const { + removeTrackingScripts: removeTrackingScriptsFn = null, + setGlobalModalState: setGlobalModalStateFn = null, + escapeHtml = null, + } = utilities; + + const { + showError = null, + onSubmit = null, + onCancel = null, + } = callbacks; + + const modal = + (typeof editModalOverride === "function" + ? editModalOverride({ app, eventTarget: events }) + : editModalOverride) || + new EditModal({ + removeTrackingScripts: removeTrackingScriptsFn, + setGlobalModalState: setGlobalModalStateFn, + showError, + getMode, + sanitizers, + escapeHtml, + eventTarget: events, + container, + }); + + const boundSubmitHandler = + typeof onSubmit === "function" ? (event) => onSubmit(event) : null; + const boundCancelHandler = typeof onCancel === "function" ? () => onCancel() : null; + + if (boundSubmitHandler && typeof modal?.addEventListener === "function") { + modal.addEventListener("video:edit-submit", boundSubmitHandler); + } + + if (boundCancelHandler && typeof modal?.addEventListener === "function") { + modal.addEventListener("video:edit-cancel", boundCancelHandler); + } + + return { + modal, + events, + handlers: { + submit: boundSubmitHandler, + cancel: boundCancelHandler, + }, + }; +} + +export default initEditModal; diff --git a/js/ui/initUploadModal.js b/js/ui/initUploadModal.js new file mode 100644 index 00000000..c33fefc4 --- /dev/null +++ b/js/ui/initUploadModal.js @@ -0,0 +1,67 @@ +import { UploadModal } from "./components/UploadModal.js"; + +export function initUploadModal({ + app = null, + uploadModalOverride = null, + container = null, + services = {}, + utilities = {}, + callbacks = {}, + eventTarget = null, +} = {}) { + const events = eventTarget instanceof EventTarget ? eventTarget : new EventTarget(); + + const { + authService = null, + r2Service = null, + } = services; + + const { + removeTrackingScripts: removeTrackingScriptsFn = null, + setGlobalModalState: setGlobalModalStateFn = null, + } = utilities; + + const { + publishVideoNote = null, + showError = null, + showSuccess = null, + getCurrentPubkey = null, + safeEncodeNpub = null, + onSubmit = null, + } = callbacks; + + const modal = + (typeof uploadModalOverride === "function" + ? uploadModalOverride({ app, eventTarget: events }) + : uploadModalOverride) || + new UploadModal({ + authService, + r2Service, + publishVideoNote, + removeTrackingScripts: removeTrackingScriptsFn, + setGlobalModalState: setGlobalModalStateFn, + showError, + showSuccess, + getCurrentPubkey, + safeEncodeNpub, + eventTarget: events, + container, + }); + + const boundSubmitHandler = + typeof onSubmit === "function" ? (event) => onSubmit(event) : null; + + if (boundSubmitHandler && typeof modal?.addEventListener === "function") { + modal.addEventListener("upload:submit", boundSubmitHandler); + } + + return { + modal, + events, + handlers: { + submit: boundSubmitHandler, + }, + }; +} + +export default initUploadModal;