Files
bitvid/js/ui/initEditModal.js
T
thePR0M3TH3ANandClaude Opus 4.8 c8a63c57c6 feat(edit): thumbnail + video file upload in Edit modal (steps 2-3/3)
Brings the Edit modal to upload parity with the Upload modal: re-upload a
thumbnail or video file instead of only pasting URLs.

- Wire storage services (r2/s3/storageService) + pubkey/npub accessors into
  EditModal via ModalManager/initEditModal; EditModal constructs a shared
  MediaUploader.
- New editModalUpload.js holds all the upload glue (file-picker wiring, progress,
  storage-unlock checks, field write-back) to keep EditModal under its file-size
  budget. EditModal calls initEditModalUpload(this, context) in one line.
- edit-video-modal.html: "Replace video file…" (under the URL field) and
  "Replace thumbnail file…" (under the thumbnail field), each with a hidden file
  input + status line.
- On thumbnail upload: writes the new URL into the thumbnail field. On video
  upload: writes url + magnet (+ ws/xs hints). All written via setFieldUnlocked,
  which marks the field edited so EditModal.collect actually persists it (gated
  behind storage being configured + unlocked).

setFieldUnlocked is unit-tested (mutation-verified): without the unlock, the
re-upload would silently not save. Build + full lint + unit suite green.

NOTE: the upload/storage flow itself can't be unit-tested (browser + R2/S3);
pending manual verification of editing a video's thumbnail/file.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-20 09:09:07 -04:00

81 lines
1.9 KiB
JavaScript

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 = {},
r2Service = null,
s3Service = null,
storageService = null,
} = services;
const {
removeTrackingScripts: removeTrackingScriptsFn = null,
setGlobalModalState: setGlobalModalStateFn = null,
escapeHtml = null,
} = utilities;
const {
showError = null,
showSuccess = null,
getCurrentPubkey = null,
safeEncodeNpub = null,
onSubmit = null,
onCancel = null,
} = callbacks;
const modal =
(typeof editModalOverride === "function"
? editModalOverride({ app, eventTarget: events })
: editModalOverride) ||
new EditModal({
removeTrackingScripts: removeTrackingScriptsFn,
setGlobalModalState: setGlobalModalStateFn,
showError,
showSuccess,
getMode,
sanitizers,
escapeHtml,
r2Service,
s3Service,
storageService,
getCurrentPubkey,
safeEncodeNpub,
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;