mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
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]>
50 lines
1.7 KiB
JavaScript
50 lines
1.7 KiB
JavaScript
// When the Edit modal re-uploads a thumbnail/video file, the new URL/magnet must
|
|
// be written into the field AND the field marked "edited" — otherwise
|
|
// EditModal.collect (which gates each field on isEditing: readOnly===false ||
|
|
// dataset.isEditing==="true") would keep the ORIGINAL value and the re-upload
|
|
// would silently not save. setFieldUnlocked encodes that contract.
|
|
|
|
import "./test-helpers/setup-localstorage.mjs";
|
|
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import { setFieldUnlocked } from "../js/ui/components/editModalUpload.js";
|
|
|
|
// Minimal input-element stand-in matching what setFieldUnlocked touches.
|
|
function makeInput() {
|
|
return {
|
|
value: "original",
|
|
readOnly: true,
|
|
dataset: {},
|
|
removeAttribute(name) {
|
|
this._removed = this._removed || [];
|
|
this._removed.push(name);
|
|
},
|
|
};
|
|
}
|
|
|
|
// Mirror of EditModal.collect's isEditing() gate.
|
|
function isEditing(input) {
|
|
if (!input) return true;
|
|
if (input.dataset?.isEditing === "true") return true;
|
|
return input.readOnly === false;
|
|
}
|
|
|
|
test("setFieldUnlocked sets the value and marks the field edited so it persists", () => {
|
|
const input = makeInput();
|
|
setFieldUnlocked(input, "https://cdn.example.com/new.mp4");
|
|
|
|
assert.equal(input.value, "https://cdn.example.com/new.mp4", "value updated");
|
|
assert.equal(input.readOnly, false, "field unlocked");
|
|
assert.equal(input.dataset.isEditing, "true", "marked as user-edited");
|
|
assert.equal(
|
|
isEditing(input),
|
|
true,
|
|
"EditModal.collect would treat it as edited (so the upload persists)",
|
|
);
|
|
});
|
|
|
|
test("setFieldUnlocked is a no-op on a missing field", () => {
|
|
assert.doesNotThrow(() => setFieldUnlocked(null, "x"));
|
|
assert.doesNotThrow(() => setFieldUnlocked(undefined, "x"));
|
|
});
|