mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Add NSFW and kids toggles to edit modal
This commit is contained in:
1 parent
4fad4eb1a8
commit
dd8b0b9907
3 files changed
+144
No files matched your search
@@ -818,6 +818,62 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1">
|
||||
<label for="editVideoIsNsfw" class="block text-sm font-medium text-gray-200">
|
||||
NSFW content
|
||||
</label>
|
||||
<div
|
||||
class="flex flex-col gap-2 rounded-md border border-gray-800 bg-black/30 p-3 sm:flex-row sm:items-center sm:justify-between"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="editVideoIsNsfw"
|
||||
class="h-5 w-5 rounded border-gray-600 bg-gray-800 text-blue-500 focus:ring-blue-500"
|
||||
data-default-checked="false"
|
||||
/>
|
||||
<span class="text-sm text-gray-300">
|
||||
Mark as sensitive to blur previews and gate playback.
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="edit-field-button hidden"
|
||||
data-edit-target="editVideoIsNsfw"
|
||||
>
|
||||
Edit field
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1">
|
||||
<label for="editVideoIsForKids" class="block text-sm font-medium text-gray-200">
|
||||
Made for kids
|
||||
</label>
|
||||
<div
|
||||
class="flex flex-col gap-2 rounded-md border border-gray-800 bg-black/30 p-3 sm:flex-row sm:items-center sm:justify-between"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="editVideoIsForKids"
|
||||
class="h-5 w-5 rounded border-gray-600 bg-gray-800 text-blue-500 focus:ring-blue-500"
|
||||
data-default-checked="false"
|
||||
/>
|
||||
<span class="text-sm text-gray-300">
|
||||
Flag kid-friendly videos to adjust recommendations and controls.
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="edit-field-button hidden"
|
||||
data-edit-target="editVideoIsForKids"
|
||||
>
|
||||
Edit field
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1">
|
||||
<label for="editEnableComments" class="block text-sm font-medium text-gray-200">
|
||||
Enable comments
|
||||
|
||||
@@ -160,6 +160,8 @@ export class EditModal {
|
||||
description: context.querySelector("#editVideoDescription") || null,
|
||||
isPrivate: context.querySelector("#editVideoIsPrivate") || null,
|
||||
enableComments: context.querySelector("#editEnableComments") || null,
|
||||
isNsfw: context.querySelector("#editVideoIsNsfw") || null,
|
||||
isForKids: context.querySelector("#editVideoIsForKids") || null,
|
||||
};
|
||||
|
||||
this.visibility = {
|
||||
@@ -320,6 +322,10 @@ export class EditModal {
|
||||
const enableCommentsValue =
|
||||
typeof video.enableComments === "boolean" ? video.enableComments : true;
|
||||
const isPrivateValue = video.isPrivate === true;
|
||||
const isNsfwValue =
|
||||
typeof video.isNsfw === "boolean" ? video.isNsfw : false;
|
||||
const isForKidsValue =
|
||||
typeof video.isForKids === "boolean" ? video.isForKids : false;
|
||||
|
||||
const editContext = {
|
||||
...video,
|
||||
@@ -327,6 +333,8 @@ export class EditModal {
|
||||
xs: effectiveXs,
|
||||
enableComments: enableCommentsValue,
|
||||
isPrivate: isPrivateValue,
|
||||
isNsfw: isNsfwValue,
|
||||
isForKids: isForKidsValue,
|
||||
};
|
||||
|
||||
this.applyVideoToForm(editContext);
|
||||
@@ -363,6 +371,8 @@ export class EditModal {
|
||||
description: editContext.description || "",
|
||||
isPrivate: editContext.isPrivate,
|
||||
enableComments: editContext.enableComments,
|
||||
isNsfw: editContext.isNsfw,
|
||||
isForKids: editContext.isForKids,
|
||||
};
|
||||
|
||||
Object.entries(fieldMap).forEach(([key, rawValue]) => {
|
||||
@@ -464,6 +474,10 @@ export class EditModal {
|
||||
return "editVideoIsPrivate";
|
||||
case "enableComments":
|
||||
return "editEnableComments";
|
||||
case "isNsfw":
|
||||
return "editVideoIsNsfw";
|
||||
case "isForKids":
|
||||
return "editVideoIsForKids";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -720,6 +734,8 @@ export class EditModal {
|
||||
const descriptionInput = this.fields.description;
|
||||
const commentsInput = this.fields.enableComments;
|
||||
const privateInput = this.fields.isPrivate;
|
||||
const nsfwInput = this.fields.isNsfw;
|
||||
const forKidsInput = this.fields.isForKids;
|
||||
|
||||
const newTitle = fieldValue("title");
|
||||
const newUrl = fieldValue("url");
|
||||
@@ -762,6 +778,8 @@ export class EditModal {
|
||||
const originalEnableComments =
|
||||
typeof original.enableComments === "boolean" ? original.enableComments : true;
|
||||
const originalIsPrivate = original.isPrivate === true;
|
||||
const originalIsNsfw = original.isNsfw === true;
|
||||
const originalIsForKids = original.isForKids === true;
|
||||
|
||||
const currentNip71 = this.cloneNip71Metadata(
|
||||
this.nip71FormManager.collectSection(this.nip71SectionKey)
|
||||
@@ -795,6 +813,24 @@ export class EditModal {
|
||||
}
|
||||
}
|
||||
|
||||
let finalIsNsfw = originalIsNsfw;
|
||||
if (nsfwInput) {
|
||||
if (nsfwInput.disabled) {
|
||||
finalIsNsfw = nsfwInput.dataset.originalValue === "true";
|
||||
} else {
|
||||
finalIsNsfw = this.sanitizers.checkbox(nsfwInput.checked);
|
||||
}
|
||||
}
|
||||
|
||||
let finalIsForKids = originalIsForKids;
|
||||
if (forKidsInput) {
|
||||
if (forKidsInput.disabled) {
|
||||
finalIsForKids = forKidsInput.dataset.originalValue === "true";
|
||||
} else {
|
||||
finalIsForKids = this.sanitizers.checkbox(forKidsInput.checked);
|
||||
}
|
||||
}
|
||||
|
||||
if (!finalTitle || (!finalUrl && !finalMagnet && !hasImetaSource)) {
|
||||
this.showError(
|
||||
"Title and at least one of URL, Magnet, or a NIP-71 media variant is required."
|
||||
@@ -837,6 +873,8 @@ export class EditModal {
|
||||
magnetEdited: magnetWasEdited,
|
||||
enableComments: finalEnableComments,
|
||||
isPrivate: finalIsPrivate,
|
||||
isNsfw: finalIsNsfw,
|
||||
isForKids: finalIsForKids,
|
||||
};
|
||||
|
||||
const currentNip71Json = JSON.stringify(currentNip71);
|
||||
|
||||
@@ -104,6 +104,8 @@ test('ignores additional submissions while pending without spurious errors', asy
|
||||
description: '',
|
||||
enableComments: true,
|
||||
isPrivate: false,
|
||||
isNsfw: true,
|
||||
isForKids: false,
|
||||
};
|
||||
|
||||
await modal.open(video);
|
||||
@@ -127,6 +129,19 @@ test('ignores additional submissions while pending without spurious errors', asy
|
||||
);
|
||||
assert.equal(modal.submitButton.disabled, true, 'button should disable while pending');
|
||||
|
||||
const firstSubmission = submissions[0];
|
||||
assert.ok(firstSubmission, 'expected first submission payload');
|
||||
assert.equal(
|
||||
firstSubmission.updatedData.isNsfw,
|
||||
true,
|
||||
'locked NSFW flag should persist in emitted payload',
|
||||
);
|
||||
assert.equal(
|
||||
firstSubmission.updatedData.isForKids,
|
||||
false,
|
||||
'locked kids flag should persist in emitted payload',
|
||||
);
|
||||
|
||||
modal.submit();
|
||||
|
||||
assert.equal(submissions.length, 1, 'duplicate submit should be ignored');
|
||||
@@ -140,4 +155,39 @@ test('ignores additional submissions while pending without spurious errors', asy
|
||||
|
||||
assert.equal(modal.pendingSubmit, false, 'pending flag should reset after release');
|
||||
assert.equal(modal.submitButton.disabled, false, 'button should re-enable after release');
|
||||
|
||||
const unlockButton = (selector) =>
|
||||
modal.root.querySelector(selector)?.dispatchEvent(
|
||||
new dom.window.Event('click', { bubbles: true }),
|
||||
);
|
||||
|
||||
unlockButton('[data-edit-target="editVideoIsNsfw"]');
|
||||
unlockButton('[data-edit-target="editVideoIsForKids"]');
|
||||
|
||||
const nsfwCheckbox = modal.fields.isNsfw;
|
||||
const kidsCheckbox = modal.fields.isForKids;
|
||||
|
||||
assert.ok(nsfwCheckbox, 'expected nsfw checkbox to be cached');
|
||||
assert.ok(kidsCheckbox, 'expected kids checkbox to be cached');
|
||||
|
||||
nsfwCheckbox.checked = false;
|
||||
kidsCheckbox.checked = true;
|
||||
|
||||
modal.submit();
|
||||
|
||||
assert.equal(submissions.length, 2, 'unlocked submit should emit again');
|
||||
const secondSubmission = submissions[1];
|
||||
assert.ok(secondSubmission, 'expected second submission payload');
|
||||
assert.equal(
|
||||
secondSubmission.updatedData.isNsfw,
|
||||
false,
|
||||
'updated NSFW flag should reflect unlocked checkbox state',
|
||||
);
|
||||
assert.equal(
|
||||
secondSubmission.updatedData.isForKids,
|
||||
true,
|
||||
'updated kids flag should reflect unlocked checkbox state',
|
||||
);
|
||||
|
||||
modal.setSubmitState({ pending: false });
|
||||
});
|
||||
Reference in new issue
Block a user