Prevent conflicting audience flags in upload forms

This commit is contained in:
thePR0M3TH3AN committed 2025-10-09 22:03:58 -04:00
1 parent 1122c702af
commit d33ca197d7
3 files changed
+79 -7

No files matched your search

+4 -2
View File
@@ -2391,8 +2391,10 @@ class Application {
legacyPayload?.enableComments,
true
);
const isNsfw = normalizeBooleanFlag(legacyPayload?.isNsfw, false);
const isForKids = normalizeBooleanFlag(legacyPayload?.isForKids, false);
const rawIsNsfw = normalizeBooleanFlag(legacyPayload?.isNsfw, false);
const rawIsForKids = normalizeBooleanFlag(legacyPayload?.isForKids, false);
const isNsfw = rawIsNsfw;
const isForKids = rawIsNsfw ? false : rawIsForKids;
const legacyFormData = {
version: 3,
+4 -1
View File
@@ -674,7 +674,10 @@ class R2Service {
const xs = String(metadata.xs || "").trim();
const enableComments = metadata.enableComments !== false;
const isNsfw = metadata.isNsfw === true;
const isForKids = metadata.isForKids === true;
const isForKids = metadata.isForKids === true && !isNsfw;
metadata.isNsfw = isNsfw;
metadata.isForKids = isForKids;
const accountId = (this.cloudflareSettings?.accountId || "").trim();
const accessKeyId = (this.cloudflareSettings?.accessKeyId || "").trim();
+71 -4
View File
@@ -76,6 +76,7 @@ export class UploadModal {
this.r2BaseDomainInput = null;
this.nip71FormManager = new Nip71FormManager();
this.cleanupHandlers = [];
}
addEventListener(type, listener, options) {
@@ -242,6 +243,39 @@ export class UploadModal {
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;
@@ -318,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");
}
@@ -463,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() || "",
@@ -475,8 +527,7 @@ export class UploadModal {
this.customFormInputs.enableComments,
true
),
isNsfw: this.readCheckboxValue(this.customFormInputs.isNsfw, false),
isForKids: this.readCheckboxValue(this.customFormInputs.isForKids, false),
...audienceFlags,
};
if (this.customFormInputs.isPrivate) {
@@ -747,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() || "",
@@ -758,8 +813,7 @@ export class UploadModal {
this.cloudflareEnableCommentsInput,
true
),
isNsfw: this.readCheckboxValue(this.cloudflareIsNsfwInput, false),
isForKids: this.readCheckboxValue(this.cloudflareIsForKidsInput, false),
...audienceFlags,
};
const nip71Metadata = this.nip71FormManager.collectSection("cloudflare");
@@ -793,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 {