mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-04 11:52:25 +00:00
Merge pull request #398 from PR0M3TH3AN/codex/add-nsfw-and-kids-checkboxes-to-upload-modal
Add NSFW and kid-friendly toggles to upload flows
This commit is contained in:
4 files changed
+218
-16
No files matched your search
+121
-10
@@ -62,6 +62,8 @@ export class UploadModal {
|
||||
this.cloudflareWsInput = null;
|
||||
this.cloudflareXsInput = null;
|
||||
this.cloudflareEnableCommentsInput = null;
|
||||
this.cloudflareIsNsfwInput = null;
|
||||
this.cloudflareIsForKidsInput = null;
|
||||
this.cloudflareAdvancedToggle = null;
|
||||
this.cloudflareAdvancedToggleLabel = null;
|
||||
this.cloudflareAdvancedToggleIcon = null;
|
||||
@@ -74,6 +76,7 @@ export class UploadModal {
|
||||
this.r2BaseDomainInput = null;
|
||||
|
||||
this.nip71FormManager = new Nip71FormManager();
|
||||
this.cleanupHandlers = [];
|
||||
}
|
||||
|
||||
addEventListener(type, listener, options) {
|
||||
@@ -167,6 +170,8 @@ export class UploadModal {
|
||||
thumbnail: context.querySelector("#uploadThumbnail") || null,
|
||||
description: context.querySelector("#uploadDescription") || null,
|
||||
enableComments: context.querySelector("#uploadEnableComments") || null,
|
||||
isNsfw: context.querySelector("#uploadIsNsfw") || null,
|
||||
isForKids: context.querySelector("#uploadIsForKids") || null,
|
||||
isPrivate: context.querySelector("#uploadIsPrivate") || null,
|
||||
};
|
||||
|
||||
@@ -196,6 +201,9 @@ export class UploadModal {
|
||||
this.cloudflareXsInput = context.querySelector("#cloudflareXs") || null;
|
||||
this.cloudflareEnableCommentsInput =
|
||||
context.querySelector("#cloudflareEnableComments") || null;
|
||||
this.cloudflareIsNsfwInput = context.querySelector("#cloudflareIsNsfw") || null;
|
||||
this.cloudflareIsForKidsInput =
|
||||
context.querySelector("#cloudflareIsForKids") || null;
|
||||
this.cloudflareAdvancedToggle =
|
||||
context.querySelector("#cloudflareAdvancedToggle") || null;
|
||||
this.cloudflareAdvancedToggleLabel =
|
||||
@@ -215,6 +223,59 @@ export class UploadModal {
|
||||
this.nip71FormManager.registerSection("cloudflare", this.cloudflareSection);
|
||||
}
|
||||
|
||||
readCheckboxValue(input, defaultValue = false) {
|
||||
if (!input) {
|
||||
return Boolean(defaultValue);
|
||||
}
|
||||
return input.checked === true;
|
||||
}
|
||||
|
||||
resetCheckbox(input, defaultValue = false) {
|
||||
if (!input) {
|
||||
return;
|
||||
}
|
||||
let fallback = Boolean(defaultValue);
|
||||
if (input.dataset && typeof input.dataset.defaultChecked === "string") {
|
||||
fallback = input.dataset.defaultChecked === "true";
|
||||
} else if (typeof input.defaultChecked === "boolean") {
|
||||
fallback = input.defaultChecked;
|
||||
}
|
||||
input.checked = fallback;
|
||||
}
|
||||
|
||||
sanitizeAudienceFlags(flags = {}) {
|
||||
const isNsfw = flags?.isNsfw === true;
|
||||
const isForKids = flags?.isForKids === true && !isNsfw;
|
||||
return { isNsfw, isForKids };
|
||||
}
|
||||
|
||||
setupMutuallyExclusiveCheckboxes(firstInput, secondInput) {
|
||||
if (!firstInput || !secondInput) {
|
||||
return;
|
||||
}
|
||||
|
||||
const enforceExclusion = (primary, secondary) => {
|
||||
if (primary.checked) {
|
||||
secondary.checked = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleFirstChange = () => enforceExclusion(firstInput, secondInput);
|
||||
const handleSecondChange = () => enforceExclusion(secondInput, firstInput);
|
||||
|
||||
if (firstInput.checked && secondInput.checked) {
|
||||
secondInput.checked = false;
|
||||
}
|
||||
|
||||
firstInput.addEventListener("change", handleFirstChange);
|
||||
secondInput.addEventListener("change", handleSecondChange);
|
||||
|
||||
this.cleanupHandlers.push(() => {
|
||||
firstInput.removeEventListener("change", handleFirstChange);
|
||||
secondInput.removeEventListener("change", handleSecondChange);
|
||||
});
|
||||
}
|
||||
|
||||
buildAutoGeneratedImetaVariant(file) {
|
||||
if (!file) {
|
||||
return null;
|
||||
@@ -291,6 +352,20 @@ export class UploadModal {
|
||||
});
|
||||
}
|
||||
|
||||
if (this.customFormInputs?.isNsfw && this.customFormInputs?.isForKids) {
|
||||
this.setupMutuallyExclusiveCheckboxes(
|
||||
this.customFormInputs.isNsfw,
|
||||
this.customFormInputs.isForKids
|
||||
);
|
||||
}
|
||||
|
||||
if (this.cloudflareIsNsfwInput && this.cloudflareIsForKidsInput) {
|
||||
this.setupMutuallyExclusiveCheckboxes(
|
||||
this.cloudflareIsNsfwInput,
|
||||
this.cloudflareIsForKidsInput
|
||||
);
|
||||
}
|
||||
|
||||
this.nip71FormManager.bindSection("custom");
|
||||
this.nip71FormManager.bindSection("cloudflare");
|
||||
}
|
||||
@@ -436,6 +511,10 @@ export class UploadModal {
|
||||
}
|
||||
|
||||
handleCustomSubmit() {
|
||||
const audienceFlags = this.sanitizeAudienceFlags({
|
||||
isNsfw: this.readCheckboxValue(this.customFormInputs.isNsfw, false),
|
||||
isForKids: this.readCheckboxValue(this.customFormInputs.isForKids, false),
|
||||
});
|
||||
const payload = {
|
||||
title: this.customFormInputs.title?.value?.trim() || "",
|
||||
url: this.customFormInputs.url?.value?.trim() || "",
|
||||
@@ -444,13 +523,18 @@ export class UploadModal {
|
||||
xs: this.customFormInputs.xs?.value?.trim() || "",
|
||||
thumbnail: this.customFormInputs.thumbnail?.value?.trim() || "",
|
||||
description: this.customFormInputs.description?.value?.trim() || "",
|
||||
enableComments: this.customFormInputs.enableComments
|
||||
? !!this.customFormInputs.enableComments.checked
|
||||
: true,
|
||||
enableComments: this.readCheckboxValue(
|
||||
this.customFormInputs.enableComments,
|
||||
true
|
||||
),
|
||||
...audienceFlags,
|
||||
};
|
||||
|
||||
if (this.customFormInputs.isPrivate) {
|
||||
payload.isPrivate = !!this.customFormInputs.isPrivate.checked;
|
||||
payload.isPrivate = this.readCheckboxValue(
|
||||
this.customFormInputs.isPrivate,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
const nip71Metadata = this.nip71FormManager.collectSection("custom");
|
||||
@@ -631,7 +715,11 @@ export class UploadModal {
|
||||
if (this.cloudflareWsInput) this.cloudflareWsInput.value = "";
|
||||
if (this.cloudflareXsInput) this.cloudflareXsInput.value = "";
|
||||
if (this.cloudflareEnableCommentsInput)
|
||||
this.cloudflareEnableCommentsInput.checked = true;
|
||||
this.resetCheckbox(this.cloudflareEnableCommentsInput, true);
|
||||
if (this.cloudflareIsNsfwInput)
|
||||
this.resetCheckbox(this.cloudflareIsNsfwInput, false);
|
||||
if (this.cloudflareIsForKidsInput)
|
||||
this.resetCheckbox(this.cloudflareIsForKidsInput, false);
|
||||
if (this.cloudflareFileInput) this.cloudflareFileInput.value = "";
|
||||
this.nip71FormManager.resetSection("cloudflare");
|
||||
this.updateCloudflareProgress(Number.NaN);
|
||||
@@ -647,9 +735,13 @@ export class UploadModal {
|
||||
if (this.customFormInputs.description)
|
||||
this.customFormInputs.description.value = "";
|
||||
if (this.customFormInputs.enableComments)
|
||||
this.customFormInputs.enableComments.checked = true;
|
||||
this.resetCheckbox(this.customFormInputs.enableComments, true);
|
||||
if (this.customFormInputs.isNsfw)
|
||||
this.resetCheckbox(this.customFormInputs.isNsfw, false);
|
||||
if (this.customFormInputs.isForKids)
|
||||
this.resetCheckbox(this.customFormInputs.isForKids, false);
|
||||
if (this.customFormInputs.isPrivate)
|
||||
this.customFormInputs.isPrivate.checked = false;
|
||||
this.resetCheckbox(this.customFormInputs.isPrivate, false);
|
||||
this.nip71FormManager.resetSection("custom");
|
||||
}
|
||||
|
||||
@@ -706,6 +798,10 @@ export class UploadModal {
|
||||
|
||||
const npub = this.safeEncodeNpub(pubkey) || "";
|
||||
const file = this.cloudflareFileInput?.files?.[0] || null;
|
||||
const audienceFlags = this.sanitizeAudienceFlags({
|
||||
isNsfw: this.readCheckboxValue(this.cloudflareIsNsfwInput, false),
|
||||
isForKids: this.readCheckboxValue(this.cloudflareIsForKidsInput, false),
|
||||
});
|
||||
const metadata = {
|
||||
title: this.cloudflareTitleInput?.value?.trim() || "",
|
||||
description: this.cloudflareDescriptionInput?.value?.trim() || "",
|
||||
@@ -713,9 +809,11 @@ export class UploadModal {
|
||||
magnet: this.cloudflareMagnetInput?.value?.trim() || "",
|
||||
ws: this.cloudflareWsInput?.value?.trim() || "",
|
||||
xs: this.cloudflareXsInput?.value?.trim() || "",
|
||||
enableComments: this.cloudflareEnableCommentsInput
|
||||
? !!this.cloudflareEnableCommentsInput.checked
|
||||
: true,
|
||||
enableComments: this.readCheckboxValue(
|
||||
this.cloudflareEnableCommentsInput,
|
||||
true
|
||||
),
|
||||
...audienceFlags,
|
||||
};
|
||||
|
||||
const nip71Metadata = this.nip71FormManager.collectSection("cloudflare");
|
||||
@@ -749,6 +847,19 @@ export class UploadModal {
|
||||
}
|
||||
|
||||
destroy() {
|
||||
if (Array.isArray(this.cleanupHandlers)) {
|
||||
this.cleanupHandlers.forEach((cleanup) => {
|
||||
try {
|
||||
if (typeof cleanup === "function") {
|
||||
cleanup();
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("[UploadModal] Failed to remove handler", error);
|
||||
}
|
||||
});
|
||||
this.cleanupHandlers = [];
|
||||
}
|
||||
|
||||
if (Array.isArray(this.r2Unsubscribes)) {
|
||||
this.r2Unsubscribes.forEach((unsubscribe) => {
|
||||
try {
|
||||
|
||||
Reference in new issue
Block a user