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]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-06-20 09:09:07 -04:00
1 parent 7bbf0f08b1
commit c8a63c57c6
6 files changed
+287

No files matched your search

+8
View File
@@ -109,6 +109,11 @@ export default class ModalManager {
magnet: (value) => (typeof value === "string" ? value.trim() : ""),
checkbox: (value) => !!value,
},
// Storage services so the Edit modal can re-upload thumbnail/video files
// (same wiring as the Upload modal).
r2Service: app.r2Service,
s3Service: app.s3Service,
storageService: this.services.storageService,
},
utilities: {
removeTrackingScripts,
@@ -117,6 +122,9 @@ export default class ModalManager {
},
callbacks: {
showError: (message) => app.showError(message),
showSuccess: (message) => app.showSuccess(message),
getCurrentPubkey: () => app.pubkey,
safeEncodeNpub: (pubkey) => app.safeEncodeNpub(pubkey),
onSubmit: (event) => app.handleEditModalSubmit(event),
onCancel: () => app.showError(""),
},