mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-01 02:12:26 +00:00
Extract moderation helpers for video card
This commit is contained in:
1 parent
37c1238dc2
commit
9b18c9b0ba
3 files changed
+410
-271
No files matched your search
+11
-264
@@ -1,6 +1,10 @@
|
||||
import { normalizeDesignSystemContext } from "../../designSystem.js";
|
||||
import { updateVideoCardSourceVisibility } from "../../utils/cardSourceVisibility.js";
|
||||
import { userLogger } from "../../utils/logger.js";
|
||||
import {
|
||||
applyModerationContextDatasets,
|
||||
normalizeVideoModerationContext,
|
||||
} from "../moderationUiHelpers.js";
|
||||
|
||||
const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
||||
|
||||
@@ -974,162 +978,7 @@ export class VideoCard {
|
||||
}
|
||||
|
||||
getModerationContext() {
|
||||
const moderation =
|
||||
this.video?.moderation && typeof this.video.moderation === "object"
|
||||
? this.video.moderation
|
||||
: null;
|
||||
|
||||
const summary =
|
||||
moderation?.summary && typeof moderation.summary === "object"
|
||||
? moderation.summary
|
||||
: null;
|
||||
|
||||
let reportType = "";
|
||||
if (typeof moderation?.reportType === "string" && moderation.reportType.trim()) {
|
||||
reportType = moderation.reportType.trim().toLowerCase();
|
||||
}
|
||||
|
||||
if (!reportType && summary && summary.types && typeof summary.types === "object") {
|
||||
for (const [type, stats] of Object.entries(summary.types)) {
|
||||
if (stats && Number.isFinite(stats.trusted) && Math.floor(stats.trusted) > 0) {
|
||||
reportType = String(type).toLowerCase();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let trustedCount = Number.isFinite(moderation?.trustedCount)
|
||||
? Math.max(0, Math.floor(moderation.trustedCount))
|
||||
: 0;
|
||||
|
||||
if (!trustedCount && summary && summary.types && typeof summary.types === "object") {
|
||||
for (const stats of Object.values(summary.types)) {
|
||||
if (stats && Number.isFinite(stats.trusted)) {
|
||||
trustedCount = Math.max(trustedCount, Math.floor(stats.trusted));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const reporterDisplayNames = Array.isArray(moderation?.reporterDisplayNames)
|
||||
? moderation.reporterDisplayNames
|
||||
.map((name) => (typeof name === "string" ? name.trim() : ""))
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
|
||||
const trustedMuted = moderation?.trustedMuted === true;
|
||||
let trustedMuteCount = Number.isFinite(moderation?.trustedMuteCount)
|
||||
? Math.max(0, Math.floor(moderation.trustedMuteCount))
|
||||
: 0;
|
||||
|
||||
if (!trustedMuteCount && Array.isArray(moderation?.trustedMuters)) {
|
||||
const muters = moderation.trustedMuters
|
||||
.map((value) => (typeof value === "string" ? value.trim() : ""))
|
||||
.filter(Boolean);
|
||||
trustedMuteCount = muters.length;
|
||||
}
|
||||
|
||||
const trustedMuteDisplayNames = Array.isArray(moderation?.trustedMuterDisplayNames)
|
||||
? moderation.trustedMuterDisplayNames
|
||||
.map((name) => (typeof name === "string" ? name.trim() : ""))
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
|
||||
const original =
|
||||
moderation?.original && typeof moderation.original === "object"
|
||||
? moderation.original
|
||||
: {};
|
||||
|
||||
const activeHidden = moderation?.hidden === true;
|
||||
const originalHidden = original.hidden === true;
|
||||
const hideReasonActive =
|
||||
typeof moderation?.hideReason === "string" ? moderation.hideReason.trim() : "";
|
||||
const hideBypassActive =
|
||||
typeof moderation?.hideBypass === "string" ? moderation.hideBypass.trim() : "";
|
||||
const originalHideReason =
|
||||
typeof original.hideReason === "string" ? original.hideReason.trim() : "";
|
||||
const originalHideBypass =
|
||||
typeof original.hideBypass === "string" ? original.hideBypass.trim() : "";
|
||||
const originalHideTriggered = original.hideTriggered === true;
|
||||
|
||||
const normalizeHideCounts = (input) => {
|
||||
if (!input || typeof input !== "object") {
|
||||
return null;
|
||||
}
|
||||
const normalized = {};
|
||||
let hasValue = false;
|
||||
if (Number.isFinite(input.trustedMuteCount)) {
|
||||
normalized.trustedMuteCount = Math.max(0, Math.floor(input.trustedMuteCount));
|
||||
hasValue = true;
|
||||
}
|
||||
if (Number.isFinite(input.trustedReportCount)) {
|
||||
normalized.trustedReportCount = Math.max(0, Math.floor(input.trustedReportCount));
|
||||
hasValue = true;
|
||||
}
|
||||
return hasValue ? normalized : null;
|
||||
};
|
||||
|
||||
const baseHideCounts = {
|
||||
trustedMuteCount,
|
||||
trustedReportCount: trustedCount,
|
||||
};
|
||||
|
||||
const activeHideCounts =
|
||||
normalizeHideCounts(moderation?.hideCounts) ||
|
||||
(activeHidden || hideReasonActive ? { ...baseHideCounts } : null);
|
||||
const originalHideCounts =
|
||||
normalizeHideCounts(original?.hideCounts) ||
|
||||
(originalHideTriggered ? { ...baseHideCounts } : null);
|
||||
|
||||
const effectiveHideReason = hideReasonActive || originalHideReason;
|
||||
const effectiveHideCounts = activeHideCounts || originalHideCounts;
|
||||
|
||||
const blurReason =
|
||||
typeof moderation?.blurReason === "string" ? moderation.blurReason.trim() : "";
|
||||
const originalBlurReason =
|
||||
typeof original?.blurReason === "string" ? original.blurReason.trim() : "";
|
||||
|
||||
const context = {
|
||||
reportType,
|
||||
friendlyType: reportType ? reportType.replace(/[_-]+/g, " ").trim() : "",
|
||||
trustedCount,
|
||||
reporterDisplayNames,
|
||||
trustedMuted,
|
||||
trustedMuteCount,
|
||||
trustedMuteDisplayNames,
|
||||
blurReason,
|
||||
originalBlurReason,
|
||||
originalBlur: original.blurThumbnail === true,
|
||||
originalBlockAutoplay: original.blockAutoplay === true,
|
||||
activeBlur: moderation?.blurThumbnail === true,
|
||||
activeBlockAutoplay: moderation?.blockAutoplay === true,
|
||||
overrideActive: moderation?.viewerOverride?.showAnyway === true,
|
||||
activeHidden,
|
||||
originalHidden,
|
||||
originalHideTriggered,
|
||||
hideReason: hideReasonActive,
|
||||
hideCounts: activeHideCounts,
|
||||
hideBypass: hideBypassActive,
|
||||
originalHideReason,
|
||||
originalHideCounts,
|
||||
originalHideBypass,
|
||||
effectiveHideReason,
|
||||
effectiveHideCounts,
|
||||
};
|
||||
|
||||
context.shouldShow =
|
||||
context.originalBlur ||
|
||||
context.originalBlockAutoplay ||
|
||||
context.trustedCount > 0 ||
|
||||
context.trustedMuted ||
|
||||
context.overrideActive ||
|
||||
context.originalHidden ||
|
||||
context.activeHidden ||
|
||||
context.originalHideTriggered;
|
||||
|
||||
context.allowOverride =
|
||||
context.originalBlur || context.originalBlockAutoplay || context.originalHidden;
|
||||
|
||||
return context;
|
||||
return normalizeVideoModerationContext(this.video?.moderation);
|
||||
}
|
||||
|
||||
buildModerationReasonText(context) {
|
||||
@@ -2372,114 +2221,12 @@ export class VideoCard {
|
||||
}
|
||||
|
||||
applyModerationDatasets(context = this.getModerationContext()) {
|
||||
if (!this.root) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (context.originalBlockAutoplay && !context.overrideActive) {
|
||||
this.root.dataset.autoplayPolicy = "blocked";
|
||||
} else if (this.root.dataset.autoplayPolicy) {
|
||||
delete this.root.dataset.autoplayPolicy;
|
||||
}
|
||||
|
||||
if (context.overrideActive) {
|
||||
this.root.dataset.moderationOverride = "show-anyway";
|
||||
} else if (this.root.dataset.moderationOverride) {
|
||||
delete this.root.dataset.moderationOverride;
|
||||
}
|
||||
|
||||
if (this.thumbnailEl && !this.shouldMaskNsfwForOwner) {
|
||||
if (context.activeBlur) {
|
||||
this.thumbnailEl.dataset.thumbnailState = "blurred";
|
||||
} else if (this.thumbnailEl.dataset.thumbnailState === "blurred") {
|
||||
delete this.thumbnailEl.dataset.thumbnailState;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.authorPicEl && !this.shouldMaskNsfwForOwner) {
|
||||
if (context.activeBlur) {
|
||||
this.authorPicEl.dataset.visualState = "blurred";
|
||||
} else if (this.authorPicEl.dataset.visualState) {
|
||||
delete this.authorPicEl.dataset.visualState;
|
||||
}
|
||||
}
|
||||
|
||||
const reportCount = Math.max(0, Number(context.trustedCount) || 0);
|
||||
if (reportCount > 0) {
|
||||
this.root.dataset.moderationReportCount = String(reportCount);
|
||||
if (context.reportType) {
|
||||
this.root.dataset.moderationReportType = context.reportType;
|
||||
} else if (this.root.dataset.moderationReportType) {
|
||||
delete this.root.dataset.moderationReportType;
|
||||
}
|
||||
} else {
|
||||
if (this.root.dataset.moderationReportType) {
|
||||
delete this.root.dataset.moderationReportType;
|
||||
}
|
||||
if (this.root.dataset.moderationReportCount) {
|
||||
delete this.root.dataset.moderationReportCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (context.trustedMuted) {
|
||||
this.root.dataset.moderationTrustedMute = "true";
|
||||
const muteCount = Math.max(0, Number(context.trustedMuteCount) || 0);
|
||||
if (muteCount > 0) {
|
||||
this.root.dataset.moderationTrustedMuteCount = String(muteCount);
|
||||
} else if (this.root.dataset.moderationTrustedMuteCount) {
|
||||
delete this.root.dataset.moderationTrustedMuteCount;
|
||||
}
|
||||
} else {
|
||||
if (this.root.dataset.moderationTrustedMute) {
|
||||
delete this.root.dataset.moderationTrustedMute;
|
||||
}
|
||||
if (this.root.dataset.moderationTrustedMuteCount) {
|
||||
delete this.root.dataset.moderationTrustedMuteCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (context.activeHidden && !context.overrideActive) {
|
||||
this.root.dataset.moderationHidden = "true";
|
||||
const reason = context.effectiveHideReason || context.hideReason;
|
||||
if (reason) {
|
||||
this.root.dataset.moderationHideReason = reason;
|
||||
} else if (this.root.dataset.moderationHideReason) {
|
||||
delete this.root.dataset.moderationHideReason;
|
||||
}
|
||||
|
||||
const counts = context.hideCounts || context.effectiveHideCounts || null;
|
||||
const muteCount = counts && Number.isFinite(counts.trustedMuteCount)
|
||||
? Math.max(0, Number(counts.trustedMuteCount))
|
||||
: null;
|
||||
const reportCountHide = counts && Number.isFinite(counts.trustedReportCount)
|
||||
? Math.max(0, Number(counts.trustedReportCount))
|
||||
: null;
|
||||
|
||||
if (muteCount !== null) {
|
||||
this.root.dataset.moderationHideTrustedMuteCount = String(muteCount);
|
||||
} else if (this.root.dataset.moderationHideTrustedMuteCount) {
|
||||
delete this.root.dataset.moderationHideTrustedMuteCount;
|
||||
}
|
||||
|
||||
if (reportCountHide !== null) {
|
||||
this.root.dataset.moderationHideTrustedReportCount = String(reportCountHide);
|
||||
} else if (this.root.dataset.moderationHideTrustedReportCount) {
|
||||
delete this.root.dataset.moderationHideTrustedReportCount;
|
||||
}
|
||||
} else {
|
||||
if (this.root.dataset.moderationHidden) {
|
||||
delete this.root.dataset.moderationHidden;
|
||||
}
|
||||
if (this.root.dataset.moderationHideReason) {
|
||||
delete this.root.dataset.moderationHideReason;
|
||||
}
|
||||
if (this.root.dataset.moderationHideTrustedMuteCount) {
|
||||
delete this.root.dataset.moderationHideTrustedMuteCount;
|
||||
}
|
||||
if (this.root.dataset.moderationHideTrustedReportCount) {
|
||||
delete this.root.dataset.moderationHideTrustedReportCount;
|
||||
}
|
||||
}
|
||||
applyModerationContextDatasets(context, {
|
||||
root: this.root,
|
||||
thumbnail: this.thumbnailEl,
|
||||
avatar: this.authorPicEl,
|
||||
shouldMaskNsfwForOwner: this.shouldMaskNsfwForOwner,
|
||||
});
|
||||
}
|
||||
|
||||
applyPlaybackDatasets() {
|
||||
|
||||
@@ -0,0 +1,329 @@
|
||||
export function normalizeVideoModerationContext(moderationInput) {
|
||||
const moderation =
|
||||
moderationInput && typeof moderationInput === "object"
|
||||
? moderationInput
|
||||
: null;
|
||||
|
||||
const summary =
|
||||
moderation?.summary && typeof moderation.summary === "object"
|
||||
? moderation.summary
|
||||
: null;
|
||||
|
||||
let reportType = "";
|
||||
if (typeof moderation?.reportType === "string" && moderation.reportType.trim()) {
|
||||
reportType = moderation.reportType.trim().toLowerCase();
|
||||
}
|
||||
|
||||
if (!reportType && summary && summary.types && typeof summary.types === "object") {
|
||||
for (const [type, stats] of Object.entries(summary.types)) {
|
||||
if (stats && Number.isFinite(stats.trusted) && Math.floor(stats.trusted) > 0) {
|
||||
reportType = String(type).toLowerCase();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let trustedCount = Number.isFinite(moderation?.trustedCount)
|
||||
? Math.max(0, Math.floor(moderation.trustedCount))
|
||||
: 0;
|
||||
|
||||
if (!trustedCount && summary && summary.types && typeof summary.types === "object") {
|
||||
for (const stats of Object.values(summary.types)) {
|
||||
if (stats && Number.isFinite(stats.trusted)) {
|
||||
trustedCount = Math.max(trustedCount, Math.floor(stats.trusted));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const reporterDisplayNames = Array.isArray(moderation?.reporterDisplayNames)
|
||||
? moderation.reporterDisplayNames
|
||||
.map((name) => (typeof name === "string" ? name.trim() : ""))
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
|
||||
const trustedMuted = moderation?.trustedMuted === true;
|
||||
let trustedMuteCount = Number.isFinite(moderation?.trustedMuteCount)
|
||||
? Math.max(0, Math.floor(moderation.trustedMuteCount))
|
||||
: 0;
|
||||
|
||||
if (!trustedMuteCount && Array.isArray(moderation?.trustedMuters)) {
|
||||
const muters = moderation.trustedMuters
|
||||
.map((value) => (typeof value === "string" ? value.trim() : ""))
|
||||
.filter(Boolean);
|
||||
trustedMuteCount = muters.length;
|
||||
}
|
||||
|
||||
const trustedMuteDisplayNames = Array.isArray(moderation?.trustedMuterDisplayNames)
|
||||
? moderation.trustedMuterDisplayNames
|
||||
.map((name) => (typeof name === "string" ? name.trim() : ""))
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
|
||||
const original =
|
||||
moderation?.original && typeof moderation.original === "object"
|
||||
? moderation.original
|
||||
: {};
|
||||
|
||||
const activeHidden = moderation?.hidden === true;
|
||||
const originalHidden = original.hidden === true;
|
||||
const hideReasonActive =
|
||||
typeof moderation?.hideReason === "string" ? moderation.hideReason.trim() : "";
|
||||
const hideBypassActive =
|
||||
typeof moderation?.hideBypass === "string" ? moderation.hideBypass.trim() : "";
|
||||
const originalHideReason =
|
||||
typeof original.hideReason === "string" ? original.hideReason.trim() : "";
|
||||
const originalHideBypass =
|
||||
typeof original.hideBypass === "string" ? original.hideBypass.trim() : "";
|
||||
const originalHideTriggered = original.hideTriggered === true;
|
||||
|
||||
const normalizeHideCounts = (input) => {
|
||||
if (!input || typeof input !== "object") {
|
||||
return null;
|
||||
}
|
||||
const normalized = {};
|
||||
let hasValue = false;
|
||||
if (Number.isFinite(input.trustedMuteCount)) {
|
||||
normalized.trustedMuteCount = Math.max(0, Math.floor(input.trustedMuteCount));
|
||||
hasValue = true;
|
||||
}
|
||||
if (Number.isFinite(input.trustedReportCount)) {
|
||||
normalized.trustedReportCount = Math.max(0, Math.floor(input.trustedReportCount));
|
||||
hasValue = true;
|
||||
}
|
||||
return hasValue ? normalized : null;
|
||||
};
|
||||
|
||||
const baseHideCounts = {
|
||||
trustedMuteCount,
|
||||
trustedReportCount: trustedCount,
|
||||
};
|
||||
|
||||
const activeHideCounts =
|
||||
normalizeHideCounts(moderation?.hideCounts) ||
|
||||
(activeHidden || hideReasonActive ? { ...baseHideCounts } : null);
|
||||
const originalHideCounts =
|
||||
normalizeHideCounts(original?.hideCounts) ||
|
||||
(originalHideTriggered ? { ...baseHideCounts } : null);
|
||||
|
||||
const effectiveHideReason = hideReasonActive || originalHideReason;
|
||||
const effectiveHideCounts = activeHideCounts || originalHideCounts;
|
||||
|
||||
const blurReason =
|
||||
typeof moderation?.blurReason === "string" ? moderation.blurReason.trim() : "";
|
||||
const originalBlurReason =
|
||||
typeof original?.blurReason === "string" ? original.blurReason.trim() : "";
|
||||
|
||||
const context = {
|
||||
reportType,
|
||||
friendlyType: reportType ? reportType.replace(/[_-]+/g, " ").trim() : "",
|
||||
trustedCount,
|
||||
reporterDisplayNames,
|
||||
trustedMuted,
|
||||
trustedMuteCount,
|
||||
trustedMuteDisplayNames,
|
||||
blurReason,
|
||||
originalBlurReason,
|
||||
originalBlur: original.blurThumbnail === true,
|
||||
originalBlockAutoplay: original.blockAutoplay === true,
|
||||
activeBlur: moderation?.blurThumbnail === true,
|
||||
activeBlockAutoplay: moderation?.blockAutoplay === true,
|
||||
overrideActive: moderation?.viewerOverride?.showAnyway === true,
|
||||
activeHidden,
|
||||
originalHidden,
|
||||
originalHideTriggered,
|
||||
hideReason: hideReasonActive,
|
||||
hideCounts: activeHideCounts,
|
||||
hideBypass: hideBypassActive,
|
||||
originalHideReason,
|
||||
originalHideCounts,
|
||||
originalHideBypass,
|
||||
effectiveHideReason,
|
||||
effectiveHideCounts,
|
||||
};
|
||||
|
||||
context.shouldShow =
|
||||
context.originalBlur ||
|
||||
context.originalBlockAutoplay ||
|
||||
context.trustedCount > 0 ||
|
||||
context.trustedMuted ||
|
||||
context.overrideActive ||
|
||||
context.originalHidden ||
|
||||
context.activeHidden ||
|
||||
context.originalHideTriggered;
|
||||
|
||||
context.allowOverride =
|
||||
context.originalBlur || context.originalBlockAutoplay || context.originalHidden;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
function collectElements(...inputs) {
|
||||
const result = [];
|
||||
const seen = new Set();
|
||||
inputs.forEach((input) => {
|
||||
if (!input) {
|
||||
return;
|
||||
}
|
||||
const values = Array.isArray(input) ? input : [input];
|
||||
values.forEach((value) => {
|
||||
if (!value || typeof value !== "object") {
|
||||
return;
|
||||
}
|
||||
if (!("dataset" in value)) {
|
||||
return;
|
||||
}
|
||||
if (seen.has(value)) {
|
||||
return;
|
||||
}
|
||||
seen.add(value);
|
||||
result.push(value);
|
||||
});
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
export function applyModerationContextDatasets(
|
||||
context,
|
||||
{
|
||||
root,
|
||||
roots,
|
||||
thumbnail,
|
||||
thumbnails,
|
||||
avatar,
|
||||
avatars,
|
||||
shouldMaskNsfwForOwner = false,
|
||||
} = {},
|
||||
) {
|
||||
if (!context || typeof context !== "object") {
|
||||
return;
|
||||
}
|
||||
|
||||
const rootElements = collectElements(root, roots);
|
||||
const thumbnailElements = shouldMaskNsfwForOwner
|
||||
? []
|
||||
: collectElements(thumbnail, thumbnails);
|
||||
const avatarElements = shouldMaskNsfwForOwner ? [] : collectElements(avatar, avatars);
|
||||
|
||||
const shouldBlur = context.activeBlur && !context.overrideActive;
|
||||
|
||||
thumbnailElements.forEach((el) => {
|
||||
if (shouldBlur) {
|
||||
el.dataset.thumbnailState = "blurred";
|
||||
} else if (el.dataset.thumbnailState === "blurred") {
|
||||
delete el.dataset.thumbnailState;
|
||||
}
|
||||
});
|
||||
|
||||
avatarElements.forEach((el) => {
|
||||
if (shouldBlur) {
|
||||
el.dataset.visualState = "blurred";
|
||||
} else if (el.dataset.visualState) {
|
||||
delete el.dataset.visualState;
|
||||
}
|
||||
});
|
||||
|
||||
const applyToRoots = (callback) => {
|
||||
rootElements.forEach((el) => {
|
||||
if (el) {
|
||||
callback(el);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
applyToRoots((el) => {
|
||||
if (context.originalBlockAutoplay && !context.overrideActive) {
|
||||
el.dataset.autoplayPolicy = "blocked";
|
||||
} else if (el.dataset.autoplayPolicy) {
|
||||
delete el.dataset.autoplayPolicy;
|
||||
}
|
||||
|
||||
if (context.overrideActive) {
|
||||
el.dataset.moderationOverride = "show-anyway";
|
||||
} else if (el.dataset.moderationOverride) {
|
||||
delete el.dataset.moderationOverride;
|
||||
}
|
||||
});
|
||||
|
||||
const reportCount = Math.max(0, Number(context.trustedCount) || 0);
|
||||
applyToRoots((el) => {
|
||||
if (reportCount > 0) {
|
||||
el.dataset.moderationReportCount = String(reportCount);
|
||||
if (context.reportType) {
|
||||
el.dataset.moderationReportType = context.reportType;
|
||||
} else if (el.dataset.moderationReportType) {
|
||||
delete el.dataset.moderationReportType;
|
||||
}
|
||||
} else {
|
||||
if (el.dataset.moderationReportType) {
|
||||
delete el.dataset.moderationReportType;
|
||||
}
|
||||
if (el.dataset.moderationReportCount) {
|
||||
delete el.dataset.moderationReportCount;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
applyToRoots((el) => {
|
||||
if (context.trustedMuted) {
|
||||
el.dataset.moderationTrustedMute = "true";
|
||||
const muteCount = Math.max(0, Number(context.trustedMuteCount) || 0);
|
||||
if (muteCount > 0) {
|
||||
el.dataset.moderationTrustedMuteCount = String(muteCount);
|
||||
} else if (el.dataset.moderationTrustedMuteCount) {
|
||||
delete el.dataset.moderationTrustedMuteCount;
|
||||
}
|
||||
} else {
|
||||
if (el.dataset.moderationTrustedMute) {
|
||||
delete el.dataset.moderationTrustedMute;
|
||||
}
|
||||
if (el.dataset.moderationTrustedMuteCount) {
|
||||
delete el.dataset.moderationTrustedMuteCount;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
applyToRoots((el) => {
|
||||
if (context.activeHidden && !context.overrideActive) {
|
||||
el.dataset.moderationHidden = "true";
|
||||
const reason = context.effectiveHideReason || context.hideReason;
|
||||
if (reason) {
|
||||
el.dataset.moderationHideReason = reason;
|
||||
} else if (el.dataset.moderationHideReason) {
|
||||
delete el.dataset.moderationHideReason;
|
||||
}
|
||||
|
||||
const counts = context.hideCounts || context.effectiveHideCounts || null;
|
||||
const muteCount = counts && Number.isFinite(counts.trustedMuteCount)
|
||||
? Math.max(0, Number(counts.trustedMuteCount))
|
||||
: null;
|
||||
const reportCountHide = counts && Number.isFinite(counts.trustedReportCount)
|
||||
? Math.max(0, Number(counts.trustedReportCount))
|
||||
: null;
|
||||
|
||||
if (muteCount !== null) {
|
||||
el.dataset.moderationHideTrustedMuteCount = String(muteCount);
|
||||
} else if (el.dataset.moderationHideTrustedMuteCount) {
|
||||
delete el.dataset.moderationHideTrustedMuteCount;
|
||||
}
|
||||
|
||||
if (reportCountHide !== null) {
|
||||
el.dataset.moderationHideTrustedReportCount = String(reportCountHide);
|
||||
} else if (el.dataset.moderationHideTrustedReportCount) {
|
||||
delete el.dataset.moderationHideTrustedReportCount;
|
||||
}
|
||||
} else {
|
||||
if (el.dataset.moderationHidden) {
|
||||
delete el.dataset.moderationHidden;
|
||||
}
|
||||
if (el.dataset.moderationHideReason) {
|
||||
delete el.dataset.moderationHideReason;
|
||||
}
|
||||
if (el.dataset.moderationHideTrustedMuteCount) {
|
||||
delete el.dataset.moderationHideTrustedMuteCount;
|
||||
}
|
||||
if (el.dataset.moderationHideTrustedReportCount) {
|
||||
delete el.dataset.moderationHideTrustedReportCount;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -9,6 +9,10 @@ import {
|
||||
withMockedNostrTools,
|
||||
createModerationAppHarness,
|
||||
} from "../helpers/moderation-test-helpers.mjs";
|
||||
import {
|
||||
applyModerationContextDatasets,
|
||||
normalizeVideoModerationContext,
|
||||
} from "../../js/ui/moderationUiHelpers.js";
|
||||
|
||||
function setupDom(t) {
|
||||
const dom = new JSDOM("<!DOCTYPE html><html><body></body></html>", {
|
||||
@@ -159,7 +163,9 @@ test("VideoCard renders moderation badges and respects viewer override", async (
|
||||
card.moderationActionButton.click();
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
const contextAfterOverride = card.getModerationContext();
|
||||
const contextAfterOverride = normalizeVideoModerationContext(
|
||||
card.video?.moderation,
|
||||
);
|
||||
assert.equal(contextAfterOverride.overrideActive, true);
|
||||
assert.equal(contextAfterOverride.activeBlockAutoplay, false);
|
||||
|
||||
@@ -223,7 +229,9 @@ test(
|
||||
|
||||
document.body.appendChild(card.getRoot());
|
||||
|
||||
const contextBeforeOverride = card.getModerationContext();
|
||||
const contextBeforeOverride = normalizeVideoModerationContext(
|
||||
card.video?.moderation,
|
||||
);
|
||||
assert.equal(contextBeforeOverride.activeHidden, true);
|
||||
assert.equal(contextBeforeOverride.effectiveHideReason, "trusted-report-hide");
|
||||
assert.equal(contextBeforeOverride.allowOverride, true);
|
||||
@@ -243,7 +251,9 @@ test(
|
||||
card.moderationActionButton.click();
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
const contextAfterOverride = card.getModerationContext();
|
||||
const contextAfterOverride = normalizeVideoModerationContext(
|
||||
card.video?.moderation,
|
||||
);
|
||||
assert.equal(contextAfterOverride.overrideActive, true);
|
||||
assert.equal(contextAfterOverride.activeHidden, false);
|
||||
assert.equal(contextAfterOverride.effectiveHideReason, "trusted-report-hide");
|
||||
@@ -305,7 +315,10 @@ test("VideoCard blurs thumbnails when trusted mute triggers without reports", as
|
||||
|
||||
assert.equal(video.moderation.blurThumbnail, true);
|
||||
assert.equal(video.moderation.blurReason, "trusted-mute");
|
||||
assert.equal(card.getModerationContext().activeBlur, true);
|
||||
assert.equal(
|
||||
normalizeVideoModerationContext(card.video?.moderation).activeBlur,
|
||||
true,
|
||||
);
|
||||
assert.equal(card.thumbnailEl.dataset.thumbnailState, "blurred");
|
||||
assert.equal(card.authorPicEl.dataset.visualState, "blurred");
|
||||
assert.equal(card.getRoot().dataset.autoplayPolicy, "blocked");
|
||||
@@ -364,7 +377,10 @@ test("VideoCard hide action restores trusted mute hide state after override", as
|
||||
|
||||
document.body.appendChild(card.getRoot());
|
||||
|
||||
assert.equal(card.getModerationContext().activeHidden, true);
|
||||
assert.equal(
|
||||
normalizeVideoModerationContext(card.video?.moderation).activeHidden,
|
||||
true,
|
||||
);
|
||||
assert.equal(card.getRoot().dataset.moderationHidden, "true");
|
||||
|
||||
card.onModerationOverride = ({ video: overrideVideo, card: overrideCard }) =>
|
||||
@@ -373,7 +389,9 @@ test("VideoCard hide action restores trusted mute hide state after override", as
|
||||
card.moderationActionButton.click();
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
const contextAfterOverride = card.getModerationContext();
|
||||
const contextAfterOverride = normalizeVideoModerationContext(
|
||||
card.video?.moderation,
|
||||
);
|
||||
assert.equal(contextAfterOverride.overrideActive, true);
|
||||
assert.equal(contextAfterOverride.activeHidden, false);
|
||||
assert.ok(card.moderationHideButton);
|
||||
@@ -384,9 +402,54 @@ test("VideoCard hide action restores trusted mute hide state after override", as
|
||||
card.moderationHideButton.click();
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
const contextAfterHide = card.getModerationContext();
|
||||
const contextAfterHide = normalizeVideoModerationContext(card.video?.moderation);
|
||||
assert.equal(contextAfterHide.overrideActive, false);
|
||||
assert.equal(contextAfterHide.activeHidden, true);
|
||||
assert.equal(card.getRoot().dataset.moderationHidden, "true");
|
||||
assert.equal(card.moderationHideButton, null);
|
||||
});
|
||||
|
||||
test("applyModerationContextDatasets clears blur when overrides are active", (t) => {
|
||||
const { document } = setupDom(t);
|
||||
|
||||
const root = document.createElement("div");
|
||||
const thumbnail = document.createElement("div");
|
||||
const avatar = document.createElement("div");
|
||||
|
||||
const baselineContext = normalizeVideoModerationContext({
|
||||
blurThumbnail: true,
|
||||
reportType: "nudity",
|
||||
trustedCount: 1,
|
||||
original: { blockAutoplay: true },
|
||||
});
|
||||
|
||||
applyModerationContextDatasets(baselineContext, {
|
||||
root,
|
||||
thumbnail,
|
||||
avatar,
|
||||
});
|
||||
|
||||
assert.equal(root.dataset.autoplayPolicy, "blocked");
|
||||
assert.equal(root.dataset.moderationOverride, undefined);
|
||||
assert.equal(thumbnail.dataset.thumbnailState, "blurred");
|
||||
assert.equal(avatar.dataset.visualState, "blurred");
|
||||
|
||||
const overrideContext = normalizeVideoModerationContext({
|
||||
blurThumbnail: true,
|
||||
reportType: "nudity",
|
||||
trustedCount: 1,
|
||||
viewerOverride: { showAnyway: true },
|
||||
original: { blockAutoplay: true },
|
||||
});
|
||||
|
||||
applyModerationContextDatasets(overrideContext, {
|
||||
root,
|
||||
thumbnail,
|
||||
avatar,
|
||||
});
|
||||
|
||||
assert.equal(root.dataset.autoplayPolicy, undefined);
|
||||
assert.equal(root.dataset.moderationOverride, "show-anyway");
|
||||
assert.equal(thumbnail.dataset.thumbnailState, undefined);
|
||||
assert.equal(avatar.dataset.visualState, undefined);
|
||||
});
|
||||
Reference in new issue
Block a user