mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Keep moderation actions inline and add hide toggle
This commit is contained in:
1 parent
7228da739c
commit
31cb2821e4
7 files changed
+868
-93
No files matched your search
@@ -96,13 +96,19 @@
|
||||
Content or user blocked by a trusted contact.
|
||||
</span>
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
class="moderation-badge__action flex-shrink-0"
|
||||
data-moderation-action="override"
|
||||
<div
|
||||
class="moderation-badge__actions"
|
||||
data-moderation-actions
|
||||
>
|
||||
Show anyway
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="moderation-badge__action flex-shrink-0"
|
||||
data-moderation-action="override"
|
||||
aria-pressed="false"
|
||||
>
|
||||
Show anyway
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<video
|
||||
|
||||
@@ -802,6 +802,10 @@
|
||||
@apply inline-flex flex-col items-start gap-sm rounded-xl border px-3 py-1.5 text-xs font-semibold normal-case tracking-tight shadow-sm;
|
||||
}
|
||||
|
||||
.moderation-badge__actions {
|
||||
@apply inline-flex flex-nowrap items-center gap-sm;
|
||||
}
|
||||
|
||||
.moderation-badge__label {
|
||||
@apply inline-flex items-center gap-xs whitespace-nowrap;
|
||||
}
|
||||
@@ -1486,6 +1490,20 @@
|
||||
}
|
||||
|
||||
#playerModal .video-modal__moderation-overlay .moderation-badge {
|
||||
@apply pb-4;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
#playerModal .video-modal__moderation-overlay[data-overlay-state="override"] {
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
background: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#playerModal
|
||||
.video-modal__moderation-overlay[data-overlay-state="override"]
|
||||
.moderation-badge {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
|
||||
@@ -886,6 +886,92 @@ class Application {
|
||||
"video:moderation-override",
|
||||
this.boundVideoModalModerationOverrideHandler,
|
||||
);
|
||||
this.boundVideoModalModerationBlockHandler = (event) => {
|
||||
const detail = event?.detail || {};
|
||||
const targetVideo =
|
||||
detail && typeof detail.video === "object"
|
||||
? detail.video
|
||||
: this.currentVideo || null;
|
||||
const trigger = detail?.trigger || null;
|
||||
|
||||
if (!targetVideo) {
|
||||
if (trigger) {
|
||||
trigger.disabled = false;
|
||||
trigger.removeAttribute("aria-busy");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Promise.resolve(
|
||||
this.handleModerationBlock({
|
||||
video: targetVideo,
|
||||
card: detail?.card || null,
|
||||
}),
|
||||
)
|
||||
.then((handled) => {
|
||||
if (handled === false && trigger) {
|
||||
trigger.disabled = false;
|
||||
trigger.removeAttribute("aria-busy");
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
devLogger.warn(
|
||||
"[Application] Failed to handle modal moderation block:",
|
||||
error,
|
||||
);
|
||||
if (trigger) {
|
||||
trigger.disabled = false;
|
||||
trigger.removeAttribute("aria-busy");
|
||||
}
|
||||
});
|
||||
};
|
||||
this.videoModal.addEventListener(
|
||||
"video:moderation-block",
|
||||
this.boundVideoModalModerationBlockHandler,
|
||||
);
|
||||
this.boundVideoModalModerationHideHandler = (event) => {
|
||||
const detail = event?.detail || {};
|
||||
const targetVideo =
|
||||
detail && typeof detail.video === "object"
|
||||
? detail.video
|
||||
: this.currentVideo || null;
|
||||
const trigger = detail?.trigger || null;
|
||||
|
||||
if (!targetVideo) {
|
||||
if (trigger) {
|
||||
trigger.disabled = false;
|
||||
trigger.removeAttribute("aria-busy");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Promise.resolve(
|
||||
this.handleModerationHide({
|
||||
video: targetVideo,
|
||||
card: detail?.card || null,
|
||||
}),
|
||||
)
|
||||
.then((handled) => {
|
||||
if (handled === false && trigger) {
|
||||
trigger.disabled = false;
|
||||
trigger.removeAttribute("aria-busy");
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
devLogger.warn(
|
||||
"[Application] Failed to handle modal moderation hide:",
|
||||
error,
|
||||
);
|
||||
if (trigger) {
|
||||
trigger.disabled = false;
|
||||
trigger.removeAttribute("aria-busy");
|
||||
}
|
||||
});
|
||||
};
|
||||
this.videoModal.addEventListener(
|
||||
"video:moderation-hide",
|
||||
this.boundVideoModalModerationHideHandler,
|
||||
);
|
||||
this.boundVideoModalTagActivateHandler = (event) => {
|
||||
const detail = event?.detail || {};
|
||||
const nativeEvent = detail?.nativeEvent || null;
|
||||
@@ -1392,6 +1478,9 @@ class Application {
|
||||
this.videoListView.setModerationBlockHandler((detail = {}) =>
|
||||
this.handleModerationBlock(detail)
|
||||
);
|
||||
this.videoListView.setModerationHideHandler((detail = {}) =>
|
||||
this.handleModerationHide(detail)
|
||||
);
|
||||
|
||||
if (this.moreMenuController) {
|
||||
this.moreMenuController.attachVideoListView(this.videoListView);
|
||||
@@ -7800,8 +7889,77 @@ class Application {
|
||||
return true;
|
||||
}
|
||||
|
||||
handleModerationHide(detail) {
|
||||
return this.handleModerationBlock(detail);
|
||||
handleModerationHide({ video, card }) {
|
||||
if (!video || typeof video !== "object" || !video.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
clearModerationOverride(video.id);
|
||||
} catch (error) {
|
||||
devLogger.warn("[Application] Failed to clear moderation override:", error);
|
||||
}
|
||||
|
||||
const storedVideo =
|
||||
this.videosMap instanceof Map && video.id
|
||||
? this.videosMap.get(video.id)
|
||||
: null;
|
||||
const target = storedVideo || video;
|
||||
|
||||
const resetOverrideState = (subject) => {
|
||||
if (!subject || typeof subject !== "object") {
|
||||
return;
|
||||
}
|
||||
const moderation =
|
||||
subject.moderation && typeof subject.moderation === "object"
|
||||
? subject.moderation
|
||||
: null;
|
||||
if (!moderation) {
|
||||
return;
|
||||
}
|
||||
if (moderation.viewerOverride) {
|
||||
delete moderation.viewerOverride;
|
||||
}
|
||||
};
|
||||
|
||||
if (target) {
|
||||
resetOverrideState(target);
|
||||
this.decorateVideoModeration(target);
|
||||
}
|
||||
|
||||
if (this.currentVideo && this.currentVideo.id === video.id) {
|
||||
resetOverrideState(this.currentVideo);
|
||||
this.decorateVideoModeration(this.currentVideo);
|
||||
}
|
||||
|
||||
if (card && typeof card.refreshModerationUi === "function") {
|
||||
try {
|
||||
card.refreshModerationUi();
|
||||
} catch (error) {
|
||||
devLogger.warn(
|
||||
"[Application] Failed to refresh moderation UI after hide:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const doc =
|
||||
(this.videoModal && this.videoModal.document) ||
|
||||
(typeof document !== "undefined" ? document : null);
|
||||
if (doc && typeof doc.dispatchEvent === "function") {
|
||||
try {
|
||||
doc.dispatchEvent(
|
||||
new CustomEvent("video:moderation-hide", { detail: { video: target } }),
|
||||
);
|
||||
} catch (eventError) {
|
||||
devLogger.warn(
|
||||
"[Application] Failed to dispatch moderation hide event:",
|
||||
eventError,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
getVideoAddressPointer(video) {
|
||||
|
||||
@@ -4314,6 +4314,14 @@ export async function renderChannelVideosFromList({
|
||||
})
|
||||
: false;
|
||||
|
||||
videoCard.onModerationHide = ({ video: hideVideo, card: hideCard }) =>
|
||||
typeof app?.handleModerationHide === "function"
|
||||
? app.handleModerationHide({
|
||||
video: hideVideo,
|
||||
card: hideCard,
|
||||
})
|
||||
: false;
|
||||
|
||||
videoCard.onEdit = ({ video: editVideo, index: editIndex }) => {
|
||||
app?.handleEditVideo?.({
|
||||
eventId: editVideo?.id || "",
|
||||
|
||||
+274
-41
@@ -120,6 +120,7 @@ export class VideoCard {
|
||||
onCloseSettingsMenu: null,
|
||||
onModerationOverride: null,
|
||||
onModerationBlock: null,
|
||||
onModerationHide: null,
|
||||
};
|
||||
|
||||
this.moderationBadgeEl = null;
|
||||
@@ -129,6 +130,8 @@ export class VideoCard {
|
||||
this.moderationBadgeIconSvg = null;
|
||||
this.moderationActionButton = null;
|
||||
this.moderationBlockButton = null;
|
||||
this.moderationActionsContainer = null;
|
||||
this.moderationActionButtonMode = "";
|
||||
this.moderationBadgeId = "";
|
||||
this.badgesContainerEl = null;
|
||||
this.moderationBadgeSlot = null;
|
||||
@@ -136,6 +139,8 @@ export class VideoCard {
|
||||
this.boundShowAnywayHandler = (event) => this.handleShowAnywayClick(event);
|
||||
this.boundModerationBlockHandler = (event) =>
|
||||
this.handleModerationBlockClick(event);
|
||||
this.boundModerationHideHandler = (event) =>
|
||||
this.handleModerationHideClick(event);
|
||||
|
||||
this.root = null;
|
||||
this.anchorEl = null;
|
||||
@@ -216,6 +221,11 @@ export class VideoCard {
|
||||
typeof fn === "function" ? fn : null;
|
||||
}
|
||||
|
||||
set onModerationHide(fn) {
|
||||
this.callbacks.onModerationHide =
|
||||
typeof fn === "function" ? fn : null;
|
||||
}
|
||||
|
||||
set onMoreAction(fn) {
|
||||
this.callbacks.onMoreAction = typeof fn === "function" ? fn : null;
|
||||
}
|
||||
@@ -1004,6 +1014,20 @@ export class VideoCard {
|
||||
return button;
|
||||
}
|
||||
|
||||
createModerationHideButton() {
|
||||
const button = this.createElement("button", {
|
||||
classNames: ["moderation-badge__action", "flex-shrink-0"],
|
||||
attrs: {
|
||||
type: "button",
|
||||
"data-moderation-action": "hide",
|
||||
"aria-describedby": this.getModerationBadgeId(),
|
||||
},
|
||||
textContent: "Hide",
|
||||
});
|
||||
button.addEventListener("click", this.boundModerationHideHandler);
|
||||
return button;
|
||||
}
|
||||
|
||||
createModerationBlockButton() {
|
||||
const button = this.createElement("button", {
|
||||
classNames: ["moderation-badge__action", "flex-shrink-0"],
|
||||
@@ -1118,6 +1142,66 @@ export class VideoCard {
|
||||
return;
|
||||
}
|
||||
|
||||
Promise.resolve(result)
|
||||
.then((handled) => {
|
||||
if (handled === false) {
|
||||
if (button) {
|
||||
button.disabled = false;
|
||||
button.removeAttribute("aria-busy");
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.refreshModerationUi();
|
||||
})
|
||||
.catch((error) => {
|
||||
userLogger.warn("[VideoCard] Moderation override failed", error);
|
||||
if (button) {
|
||||
button.disabled = false;
|
||||
button.removeAttribute("aria-busy");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
handleModerationHideClick(event) {
|
||||
if (event) {
|
||||
if (typeof event.preventDefault === "function") {
|
||||
event.preventDefault();
|
||||
}
|
||||
if (typeof event.stopPropagation === "function") {
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
const button = this.moderationActionButton;
|
||||
if (button) {
|
||||
button.disabled = true;
|
||||
button.setAttribute("aria-busy", "true");
|
||||
}
|
||||
|
||||
if (!this.callbacks.onModerationHide) {
|
||||
if (button) {
|
||||
button.disabled = false;
|
||||
button.removeAttribute("aria-busy");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let result;
|
||||
try {
|
||||
result = this.callbacks.onModerationHide({
|
||||
event,
|
||||
video: this.video,
|
||||
card: this,
|
||||
});
|
||||
} catch (error) {
|
||||
userLogger.warn("[VideoCard] onModerationHide callback threw", error);
|
||||
if (button) {
|
||||
button.disabled = false;
|
||||
button.removeAttribute("aria-busy");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Promise.resolve(result)
|
||||
.then((handled) => {
|
||||
if (handled === false) {
|
||||
@@ -1130,7 +1214,7 @@ export class VideoCard {
|
||||
this.refreshModerationUi();
|
||||
})
|
||||
.catch((error) => {
|
||||
userLogger.warn("[VideoCard] Moderation override failed", error);
|
||||
userLogger.warn("[VideoCard] Moderation hide failed", error);
|
||||
if (button) {
|
||||
button.disabled = false;
|
||||
button.removeAttribute("aria-busy");
|
||||
@@ -1221,12 +1305,21 @@ export class VideoCard {
|
||||
this.moderationBadgeIconWrapper = null;
|
||||
this.moderationBadgeIconSvg = null;
|
||||
if (this.moderationActionButton) {
|
||||
this.moderationActionButton.removeEventListener(
|
||||
"click",
|
||||
this.boundShowAnywayHandler,
|
||||
);
|
||||
if (this.moderationActionButtonMode === "override") {
|
||||
this.moderationActionButton.removeEventListener(
|
||||
"click",
|
||||
this.boundShowAnywayHandler,
|
||||
);
|
||||
} else if (this.moderationActionButtonMode === "hide") {
|
||||
this.moderationActionButton.removeEventListener(
|
||||
"click",
|
||||
this.boundModerationHideHandler,
|
||||
);
|
||||
}
|
||||
this.moderationActionButton.remove();
|
||||
}
|
||||
this.moderationActionButton = null;
|
||||
this.moderationActionButtonMode = "";
|
||||
if (this.moderationBlockButton) {
|
||||
this.moderationBlockButton.removeEventListener(
|
||||
"click",
|
||||
@@ -1234,6 +1327,10 @@ export class VideoCard {
|
||||
);
|
||||
}
|
||||
this.moderationBlockButton = null;
|
||||
if (this.moderationActionsContainer) {
|
||||
this.moderationActionsContainer.remove();
|
||||
this.moderationActionsContainer = null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1325,32 +1422,68 @@ export class VideoCard {
|
||||
this.moderationBadgeLabelEl = label;
|
||||
this.moderationBadgeTextEl = text;
|
||||
|
||||
if (!context.overrideActive && context.allowOverride) {
|
||||
const button = this.createModerationOverrideButton();
|
||||
badge.appendChild(button);
|
||||
this.moderationActionButton = button;
|
||||
const actions = this.createElement("div", {
|
||||
classNames: ["moderation-badge__actions"],
|
||||
});
|
||||
let hasActions = false;
|
||||
|
||||
if (context.allowOverride) {
|
||||
if (context.overrideActive) {
|
||||
const hideButton = this.createModerationHideButton();
|
||||
actions.appendChild(hideButton);
|
||||
this.moderationActionButton = hideButton;
|
||||
this.moderationActionButtonMode = "hide";
|
||||
} else {
|
||||
const showButton = this.createModerationOverrideButton();
|
||||
actions.appendChild(showButton);
|
||||
this.moderationActionButton = showButton;
|
||||
this.moderationActionButtonMode = "override";
|
||||
}
|
||||
hasActions = true;
|
||||
} else {
|
||||
if (this.moderationActionButton) {
|
||||
if (this.moderationActionButtonMode === "override") {
|
||||
this.moderationActionButton.removeEventListener(
|
||||
"click",
|
||||
this.boundShowAnywayHandler,
|
||||
);
|
||||
} else if (this.moderationActionButtonMode === "hide") {
|
||||
this.moderationActionButton.removeEventListener(
|
||||
"click",
|
||||
this.boundModerationHideHandler,
|
||||
);
|
||||
}
|
||||
this.moderationActionButton.remove();
|
||||
}
|
||||
this.moderationActionButton = null;
|
||||
this.moderationActionButtonMode = "";
|
||||
}
|
||||
|
||||
if (this.shouldShowModerationBlockButton(context)) {
|
||||
if (!this.moderationBlockButton) {
|
||||
const blockButton = this.createModerationBlockButton();
|
||||
badge.appendChild(blockButton);
|
||||
this.moderationBlockButton = blockButton;
|
||||
} else {
|
||||
this.moderationBlockButton.disabled = false;
|
||||
this.moderationBlockButton.removeAttribute("aria-busy");
|
||||
const blockButton = this.createModerationBlockButton();
|
||||
actions.appendChild(blockButton);
|
||||
this.moderationBlockButton = blockButton;
|
||||
this.moderationBlockButton.disabled = false;
|
||||
this.moderationBlockButton.removeAttribute("aria-busy");
|
||||
hasActions = true;
|
||||
} else {
|
||||
if (this.moderationBlockButton) {
|
||||
this.moderationBlockButton.removeEventListener(
|
||||
"click",
|
||||
this.boundModerationBlockHandler,
|
||||
);
|
||||
this.moderationBlockButton.remove();
|
||||
}
|
||||
} else if (this.moderationBlockButton) {
|
||||
this.moderationBlockButton.removeEventListener(
|
||||
"click",
|
||||
this.boundModerationBlockHandler,
|
||||
);
|
||||
this.moderationBlockButton.remove();
|
||||
this.moderationBlockButton = null;
|
||||
}
|
||||
|
||||
if (hasActions) {
|
||||
badge.appendChild(actions);
|
||||
this.moderationActionsContainer = actions;
|
||||
} else {
|
||||
this.moderationActionsContainer = null;
|
||||
}
|
||||
|
||||
return badge;
|
||||
}
|
||||
|
||||
@@ -1409,16 +1542,25 @@ export class VideoCard {
|
||||
slot.setAttribute("aria-hidden", "true");
|
||||
}
|
||||
if (this.moderationActionButton) {
|
||||
this.moderationActionButton.removeEventListener(
|
||||
"click",
|
||||
this.boundShowAnywayHandler,
|
||||
);
|
||||
if (this.moderationActionButtonMode === "override") {
|
||||
this.moderationActionButton.removeEventListener(
|
||||
"click",
|
||||
this.boundShowAnywayHandler,
|
||||
);
|
||||
} else if (this.moderationActionButtonMode === "hide") {
|
||||
this.moderationActionButton.removeEventListener(
|
||||
"click",
|
||||
this.boundModerationHideHandler,
|
||||
);
|
||||
}
|
||||
this.moderationActionButton.remove();
|
||||
}
|
||||
if (this.moderationBlockButton) {
|
||||
this.moderationBlockButton.removeEventListener(
|
||||
"click",
|
||||
this.boundModerationBlockHandler,
|
||||
);
|
||||
this.moderationBlockButton.remove();
|
||||
this.moderationBlockButton = null;
|
||||
}
|
||||
this.moderationBadgeEl = null;
|
||||
@@ -1427,6 +1569,11 @@ export class VideoCard {
|
||||
this.moderationBadgeIconWrapper = null;
|
||||
this.moderationBadgeIconSvg = null;
|
||||
this.moderationActionButton = null;
|
||||
this.moderationActionButtonMode = "";
|
||||
if (this.moderationActionsContainer) {
|
||||
this.moderationActionsContainer.remove();
|
||||
this.moderationActionsContainer = null;
|
||||
}
|
||||
if (this.hiddenSummaryEl && this.hiddenSummaryEl.parentElement === this.root) {
|
||||
this.hiddenSummaryEl.remove();
|
||||
}
|
||||
@@ -1515,33 +1662,106 @@ export class VideoCard {
|
||||
}
|
||||
}
|
||||
|
||||
if (context.overrideActive || !context.allowOverride) {
|
||||
let actions = this.moderationActionsContainer;
|
||||
if ((!actions || !actions.isConnected) && badge) {
|
||||
const existing = badge.querySelector(".moderation-badge__actions");
|
||||
actions = existing || this.createElement("div", {
|
||||
classNames: ["moderation-badge__actions"],
|
||||
});
|
||||
this.moderationActionsContainer = actions;
|
||||
}
|
||||
|
||||
const badgeId = this.getModerationBadgeId();
|
||||
let actionsAttached = false;
|
||||
|
||||
if (context.allowOverride) {
|
||||
const desiredMode = context.overrideActive ? "hide" : "override";
|
||||
|
||||
if (!this.moderationActionButton) {
|
||||
this.moderationActionButton =
|
||||
desiredMode === "hide"
|
||||
? this.createModerationHideButton()
|
||||
: this.createModerationOverrideButton();
|
||||
this.moderationActionButtonMode = desiredMode;
|
||||
} else if (this.moderationActionButtonMode !== desiredMode) {
|
||||
if (this.moderationActionButtonMode === "override") {
|
||||
this.moderationActionButton.removeEventListener(
|
||||
"click",
|
||||
this.boundShowAnywayHandler,
|
||||
);
|
||||
} else if (this.moderationActionButtonMode === "hide") {
|
||||
this.moderationActionButton.removeEventListener(
|
||||
"click",
|
||||
this.boundModerationHideHandler,
|
||||
);
|
||||
}
|
||||
|
||||
if (desiredMode === "hide") {
|
||||
this.moderationActionButton.textContent = "Hide";
|
||||
this.moderationActionButton.dataset.moderationAction = "hide";
|
||||
this.moderationActionButton.removeAttribute("aria-pressed");
|
||||
this.moderationActionButton.addEventListener(
|
||||
"click",
|
||||
this.boundModerationHideHandler,
|
||||
);
|
||||
} else {
|
||||
this.moderationActionButton.textContent = "Show anyway";
|
||||
this.moderationActionButton.dataset.moderationAction = "override";
|
||||
this.moderationActionButton.setAttribute("aria-pressed", "false");
|
||||
this.moderationActionButton.addEventListener(
|
||||
"click",
|
||||
this.boundShowAnywayHandler,
|
||||
);
|
||||
}
|
||||
|
||||
this.moderationActionButtonMode = desiredMode;
|
||||
}
|
||||
|
||||
if (this.moderationActionButton) {
|
||||
this.moderationActionButton.disabled = false;
|
||||
this.moderationActionButton.removeAttribute("aria-busy");
|
||||
if (badgeId) {
|
||||
this.moderationActionButton.setAttribute("aria-describedby", badgeId);
|
||||
} else {
|
||||
this.moderationActionButton.removeAttribute("aria-describedby");
|
||||
}
|
||||
if (actions && this.moderationActionButton.parentElement !== actions) {
|
||||
actions.appendChild(this.moderationActionButton);
|
||||
}
|
||||
actionsAttached = true;
|
||||
}
|
||||
} else if (this.moderationActionButton) {
|
||||
if (this.moderationActionButtonMode === "override") {
|
||||
this.moderationActionButton.removeEventListener(
|
||||
"click",
|
||||
this.boundShowAnywayHandler,
|
||||
);
|
||||
this.moderationActionButton.remove();
|
||||
} else if (this.moderationActionButtonMode === "hide") {
|
||||
this.moderationActionButton.removeEventListener(
|
||||
"click",
|
||||
this.boundModerationHideHandler,
|
||||
);
|
||||
}
|
||||
this.moderationActionButton.remove();
|
||||
this.moderationActionButton = null;
|
||||
} else if (!this.moderationActionButton) {
|
||||
const button = this.createModerationOverrideButton();
|
||||
badge.appendChild(button);
|
||||
this.moderationActionButton = button;
|
||||
} else {
|
||||
this.moderationActionButton.disabled = false;
|
||||
this.moderationActionButton.removeAttribute("aria-busy");
|
||||
this.moderationActionButtonMode = "";
|
||||
}
|
||||
|
||||
if (this.shouldShowModerationBlockButton(context)) {
|
||||
if (!this.moderationBlockButton) {
|
||||
const blockButton = this.createModerationBlockButton();
|
||||
badge.appendChild(blockButton);
|
||||
this.moderationBlockButton = blockButton;
|
||||
} else {
|
||||
this.moderationBlockButton.disabled = false;
|
||||
this.moderationBlockButton.removeAttribute("aria-busy");
|
||||
this.moderationBlockButton = this.createModerationBlockButton();
|
||||
}
|
||||
this.moderationBlockButton.disabled = false;
|
||||
this.moderationBlockButton.removeAttribute("aria-busy");
|
||||
if (badgeId) {
|
||||
this.moderationBlockButton.setAttribute("aria-describedby", badgeId);
|
||||
} else {
|
||||
this.moderationBlockButton.removeAttribute("aria-describedby");
|
||||
}
|
||||
if (actions && this.moderationBlockButton.parentElement !== actions) {
|
||||
actions.appendChild(this.moderationBlockButton);
|
||||
}
|
||||
actionsAttached = true;
|
||||
} else if (this.moderationBlockButton) {
|
||||
this.moderationBlockButton.removeEventListener(
|
||||
"click",
|
||||
@@ -1550,6 +1770,19 @@ export class VideoCard {
|
||||
this.moderationBlockButton.remove();
|
||||
this.moderationBlockButton = null;
|
||||
}
|
||||
|
||||
if (actions) {
|
||||
if (actionsAttached) {
|
||||
if (badge && actions.parentElement !== badge) {
|
||||
badge.appendChild(actions);
|
||||
}
|
||||
} else if (actions.parentElement) {
|
||||
actions.parentElement.removeChild(actions);
|
||||
this.moderationActionsContainer = null;
|
||||
} else {
|
||||
this.moderationActionsContainer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ensureHiddenSummaryContainer() {
|
||||
|
||||
+376
-44
@@ -243,7 +243,10 @@ export class VideoModal {
|
||||
this.moderationOverlay = null;
|
||||
this.moderationBadge = null;
|
||||
this.moderationBadgeText = null;
|
||||
this.moderationOverrideButton = null;
|
||||
this.moderationActionsContainer = null;
|
||||
this.moderationPrimaryButton = null;
|
||||
this.moderationBlockButton = null;
|
||||
this.moderationPrimaryMode = "";
|
||||
this.moderationBadgeId = "";
|
||||
|
||||
this.handleCopyRequest = this.handleCopyRequest.bind(this);
|
||||
@@ -254,6 +257,10 @@ export class VideoModal {
|
||||
this.handleVideoTagActivate = this.handleVideoTagActivate.bind(this);
|
||||
this.handleModerationOverrideClick =
|
||||
this.handleModerationOverrideClick.bind(this);
|
||||
this.handleModerationHideClick =
|
||||
this.handleModerationHideClick.bind(this);
|
||||
this.handleModerationBlockClick =
|
||||
this.handleModerationBlockClick.bind(this);
|
||||
this.handleGlobalModerationOverride =
|
||||
this.handleGlobalModerationOverride.bind(this);
|
||||
this.handleGlobalModerationBlock =
|
||||
@@ -275,6 +282,10 @@ export class VideoModal {
|
||||
"video:moderation-block",
|
||||
this.handleGlobalModerationBlock,
|
||||
);
|
||||
this.document.addEventListener(
|
||||
"video:moderation-hide",
|
||||
this.handleGlobalModerationHide,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,16 +441,32 @@ export class VideoModal {
|
||||
|
||||
this.teardownAmbientGlow({ clear: false });
|
||||
|
||||
if (this.moderationOverrideButton) {
|
||||
this.moderationOverrideButton.removeEventListener(
|
||||
if (this.moderationPrimaryButton) {
|
||||
if (this.moderationPrimaryMode === "override") {
|
||||
this.moderationPrimaryButton.removeEventListener(
|
||||
"click",
|
||||
this.handleModerationOverrideClick,
|
||||
);
|
||||
} else if (this.moderationPrimaryMode === "hide") {
|
||||
this.moderationPrimaryButton.removeEventListener(
|
||||
"click",
|
||||
this.handleModerationHideClick,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (this.moderationBlockButton) {
|
||||
this.moderationBlockButton.removeEventListener(
|
||||
"click",
|
||||
this.handleModerationOverrideClick,
|
||||
this.handleModerationBlockClick,
|
||||
);
|
||||
}
|
||||
this.moderationOverlay = null;
|
||||
this.moderationBadge = null;
|
||||
this.moderationBadgeText = null;
|
||||
this.moderationOverrideButton = null;
|
||||
this.moderationActionsContainer = null;
|
||||
this.moderationPrimaryButton = null;
|
||||
this.moderationPrimaryMode = "";
|
||||
this.moderationBlockButton = null;
|
||||
|
||||
const previousScrollRegion = this.scrollRegion;
|
||||
if (previousScrollRegion && this.modalNavScrollHandler) {
|
||||
@@ -530,12 +557,45 @@ export class VideoModal {
|
||||
this.moderationOverlay?.querySelector("[data-moderation-badge='true']") || null;
|
||||
this.moderationBadgeText =
|
||||
this.moderationOverlay?.querySelector("[data-moderation-text]") || null;
|
||||
const overrideButton =
|
||||
this.moderationOverlay?.querySelector("[data-moderation-action='override']") || null;
|
||||
if (overrideButton) {
|
||||
overrideButton.addEventListener("click", this.handleModerationOverrideClick);
|
||||
this.moderationOverrideButton = overrideButton;
|
||||
if (this.moderationPrimaryButton) {
|
||||
if (this.moderationPrimaryMode === "override") {
|
||||
this.moderationPrimaryButton.removeEventListener(
|
||||
"click",
|
||||
this.handleModerationOverrideClick,
|
||||
);
|
||||
} else if (this.moderationPrimaryMode === "hide") {
|
||||
this.moderationPrimaryButton.removeEventListener(
|
||||
"click",
|
||||
this.handleModerationHideClick,
|
||||
);
|
||||
}
|
||||
}
|
||||
this.moderationActionsContainer =
|
||||
this.moderationOverlay?.querySelector("[data-moderation-actions]") ||
|
||||
this.moderationBadge?.querySelector(".moderation-badge__actions") ||
|
||||
null;
|
||||
const overrideButton =
|
||||
this.moderationActionsContainer?.querySelector(
|
||||
"[data-moderation-action='override']",
|
||||
) || null;
|
||||
if (overrideButton) {
|
||||
overrideButton.addEventListener(
|
||||
"click",
|
||||
this.handleModerationOverrideClick,
|
||||
);
|
||||
this.moderationPrimaryButton = overrideButton;
|
||||
this.moderationPrimaryMode = "override";
|
||||
} else {
|
||||
this.moderationPrimaryButton = null;
|
||||
this.moderationPrimaryMode = "";
|
||||
}
|
||||
if (this.moderationBlockButton) {
|
||||
this.moderationBlockButton.removeEventListener(
|
||||
"click",
|
||||
this.handleModerationBlockClick,
|
||||
);
|
||||
}
|
||||
this.moderationBlockButton = null;
|
||||
|
||||
this.modalVideo = playerModal.querySelector("#modalVideo") || null;
|
||||
this.modalStatus = playerModal.querySelector("#modalStatus") || null;
|
||||
@@ -2086,18 +2146,21 @@ export class VideoModal {
|
||||
"video:moderation-block",
|
||||
this.handleGlobalModerationBlock,
|
||||
);
|
||||
}
|
||||
|
||||
if (this.moderationOverrideButton) {
|
||||
this.moderationOverrideButton.removeEventListener(
|
||||
"click",
|
||||
this.handleModerationOverrideClick,
|
||||
this.document.removeEventListener(
|
||||
"video:moderation-hide",
|
||||
this.handleGlobalModerationHide,
|
||||
);
|
||||
}
|
||||
|
||||
this.removeModerationPrimaryButton();
|
||||
this.removeModerationBlockButton();
|
||||
this.moderationOverlay = null;
|
||||
this.moderationBadge = null;
|
||||
this.moderationBadgeText = null;
|
||||
this.moderationOverrideButton = null;
|
||||
this.moderationActionsContainer = null;
|
||||
this.moderationPrimaryButton = null;
|
||||
this.moderationPrimaryMode = "";
|
||||
this.moderationBlockButton = null;
|
||||
this.moderationBadgeId = "";
|
||||
this.activeModerationContext = null;
|
||||
|
||||
@@ -3922,46 +3985,54 @@ export class VideoModal {
|
||||
const overlay = this.moderationOverlay;
|
||||
const badge = this.moderationBadge;
|
||||
const textEl = this.moderationBadgeText;
|
||||
const button = this.moderationOverrideButton;
|
||||
|
||||
const shouldShow = Boolean(context?.shouldShow);
|
||||
const shouldBlur = Boolean(context?.activeBlur && !context?.overrideActive);
|
||||
const hiddenActive = Boolean(context?.activeHidden && !context?.overrideActive);
|
||||
|
||||
if (!shouldBlur) {
|
||||
if (!shouldShow) {
|
||||
if (stage && stage.dataset.visualState === "blurred") {
|
||||
delete stage.dataset.visualState;
|
||||
}
|
||||
if (overlay) {
|
||||
overlay.setAttribute("hidden", "");
|
||||
if (overlay.dataset.overlayState) {
|
||||
delete overlay.dataset.overlayState;
|
||||
}
|
||||
}
|
||||
if (badge) {
|
||||
badge.dataset.variant = context?.overrideActive ? "neutral" : "warning";
|
||||
if (badge.dataset.moderationState) {
|
||||
delete badge.dataset.moderationState;
|
||||
}
|
||||
if (badge.dataset.moderationHideReason) {
|
||||
delete badge.dataset.moderationHideReason;
|
||||
}
|
||||
badge.removeAttribute("title");
|
||||
if (badge.id && !this.activeVideo) {
|
||||
badge.removeAttribute("id");
|
||||
}
|
||||
if (badge.hasAttribute("aria-label")) {
|
||||
badge.removeAttribute("aria-label");
|
||||
}
|
||||
}
|
||||
if (button) {
|
||||
button.disabled = false;
|
||||
button.removeAttribute("aria-busy");
|
||||
badge.removeAttribute("aria-label");
|
||||
}
|
||||
this.removeModerationPrimaryButton();
|
||||
this.removeModerationBlockButton();
|
||||
return;
|
||||
}
|
||||
|
||||
if (stage) {
|
||||
stage.dataset.visualState = "blurred";
|
||||
if (shouldBlur) {
|
||||
stage.dataset.visualState = "blurred";
|
||||
} else if (stage.dataset.visualState === "blurred") {
|
||||
delete stage.dataset.visualState;
|
||||
}
|
||||
}
|
||||
|
||||
if (overlay) {
|
||||
overlay.removeAttribute("hidden");
|
||||
overlay.dataset.overlayState = context?.overrideActive ? "override" : "active";
|
||||
}
|
||||
|
||||
if (this.modalVideo && typeof this.modalVideo.pause === "function") {
|
||||
if (shouldBlur && this.modalVideo && typeof this.modalVideo.pause === "function") {
|
||||
try {
|
||||
this.modalVideo.pause();
|
||||
} catch (error) {
|
||||
@@ -3969,27 +4040,42 @@ export class VideoModal {
|
||||
}
|
||||
}
|
||||
|
||||
const badgeId = this.getModerationBadgeId();
|
||||
const textContent = buildModerationBadgeText(context, { variant: "modal" });
|
||||
|
||||
if (badge) {
|
||||
const state = context?.trustedMuted ? "trusted-mute" : "blocked";
|
||||
badge.dataset.variant = "warning";
|
||||
const state = context?.overrideActive
|
||||
? "override"
|
||||
: hiddenActive
|
||||
? "hidden"
|
||||
: context?.trustedMuted
|
||||
? "trusted-mute"
|
||||
: "blocked";
|
||||
badge.dataset.variant = context?.overrideActive ? "neutral" : "warning";
|
||||
badge.dataset.moderationState = state;
|
||||
|
||||
const badgeId = this.getModerationBadgeId();
|
||||
if (hiddenActive && context?.effectiveHideReason) {
|
||||
badge.dataset.moderationHideReason = context.effectiveHideReason;
|
||||
} else if (badge.dataset.moderationHideReason) {
|
||||
delete badge.dataset.moderationHideReason;
|
||||
}
|
||||
|
||||
if (badgeId) {
|
||||
badge.id = badgeId;
|
||||
} else if (badge.id && !this.activeVideo) {
|
||||
badge.removeAttribute("id");
|
||||
}
|
||||
|
||||
const textContent = buildModerationBadgeText(context, { variant: "modal" });
|
||||
if (textEl) {
|
||||
textEl.textContent = textContent;
|
||||
}
|
||||
|
||||
const muteNames = Array.isArray(context.trustedMuteDisplayNames)
|
||||
const muteNames = Array.isArray(context?.trustedMuteDisplayNames)
|
||||
? context.trustedMuteDisplayNames
|
||||
.map((name) => (typeof name === "string" ? name.trim() : ""))
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
const reporterNames = Array.isArray(context.reporterDisplayNames)
|
||||
const reporterNames = Array.isArray(context?.reporterDisplayNames)
|
||||
? context.reporterDisplayNames
|
||||
.map((name) => (typeof name === "string" ? name.trim() : ""))
|
||||
.filter(Boolean)
|
||||
@@ -4020,7 +4106,7 @@ export class VideoModal {
|
||||
? "Muted by"
|
||||
: "Reported by";
|
||||
badge.title = `${prefix} ${joined}`;
|
||||
const baseLabel = textEl?.textContent?.trim() || textContent || "";
|
||||
const baseLabel = textContent?.trim() || textEl?.textContent?.trim() || "";
|
||||
if (baseLabel) {
|
||||
badge.setAttribute("aria-label", `${baseLabel}. ${prefix} ${joined}.`);
|
||||
} else {
|
||||
@@ -4028,7 +4114,7 @@ export class VideoModal {
|
||||
}
|
||||
} else {
|
||||
badge.removeAttribute("title");
|
||||
const baseLabel = textEl?.textContent?.trim();
|
||||
const baseLabel = textContent?.trim() || textEl?.textContent?.trim();
|
||||
if (baseLabel) {
|
||||
badge.setAttribute("aria-label", `${baseLabel}.`);
|
||||
} else {
|
||||
@@ -4037,23 +4123,205 @@ export class VideoModal {
|
||||
}
|
||||
}
|
||||
|
||||
if (button) {
|
||||
button.disabled = false;
|
||||
button.removeAttribute("aria-busy");
|
||||
const badgeId = this.getModerationBadgeId();
|
||||
if (badgeId) {
|
||||
button.setAttribute("aria-describedby", badgeId);
|
||||
const actions = this.ensureModerationActionsContainer();
|
||||
let actionsAttached = false;
|
||||
|
||||
if (context?.allowOverride) {
|
||||
const mode = context.overrideActive ? "hide" : "override";
|
||||
const primaryButton = this.ensureModerationPrimaryButton(mode);
|
||||
if (primaryButton) {
|
||||
primaryButton.disabled = false;
|
||||
primaryButton.removeAttribute("aria-busy");
|
||||
if (badgeId) {
|
||||
primaryButton.setAttribute("aria-describedby", badgeId);
|
||||
} else {
|
||||
primaryButton.removeAttribute("aria-describedby");
|
||||
}
|
||||
if (actions && primaryButton.parentElement !== actions) {
|
||||
actions.appendChild(primaryButton);
|
||||
}
|
||||
actionsAttached = true;
|
||||
}
|
||||
} else {
|
||||
this.removeModerationPrimaryButton();
|
||||
}
|
||||
|
||||
if (this.shouldShowModerationBlockAction(context)) {
|
||||
const blockButton = this.ensureModerationBlockButton();
|
||||
if (blockButton) {
|
||||
blockButton.disabled = false;
|
||||
blockButton.removeAttribute("aria-busy");
|
||||
if (badgeId) {
|
||||
blockButton.setAttribute("aria-describedby", badgeId);
|
||||
} else {
|
||||
blockButton.removeAttribute("aria-describedby");
|
||||
}
|
||||
if (actions && blockButton.parentElement !== actions) {
|
||||
actions.appendChild(blockButton);
|
||||
}
|
||||
actionsAttached = true;
|
||||
}
|
||||
} else {
|
||||
this.removeModerationBlockButton();
|
||||
}
|
||||
|
||||
if (actions) {
|
||||
if (actionsAttached) {
|
||||
if (badge && actions.parentElement !== badge) {
|
||||
badge.appendChild(actions);
|
||||
}
|
||||
} else if (actions.parentElement) {
|
||||
actions.parentElement.removeChild(actions);
|
||||
this.moderationActionsContainer = null;
|
||||
} else {
|
||||
button.removeAttribute("aria-describedby");
|
||||
this.moderationActionsContainer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shouldShowModerationBlockAction(context = this.activeModerationContext) {
|
||||
if (!context || !context.trustedMuted) {
|
||||
return false;
|
||||
}
|
||||
if (context.activeHidden && !context.overrideActive) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ensureModerationActionsContainer() {
|
||||
const badge = this.moderationBadge;
|
||||
if (!badge) {
|
||||
this.moderationActionsContainer = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
let container = this.moderationActionsContainer;
|
||||
if (container && container.isConnected) {
|
||||
return container;
|
||||
}
|
||||
|
||||
const existing =
|
||||
badge.querySelector("[data-moderation-actions]") ||
|
||||
badge.querySelector(".moderation-badge__actions");
|
||||
|
||||
if (existing) {
|
||||
this.moderationActionsContainer = existing;
|
||||
return existing;
|
||||
}
|
||||
|
||||
if (!this.document) {
|
||||
this.moderationActionsContainer = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
const created = this.document.createElement("div");
|
||||
created.className = "moderation-badge__actions";
|
||||
this.moderationActionsContainer = created;
|
||||
return created;
|
||||
}
|
||||
|
||||
ensureModerationPrimaryButton(mode) {
|
||||
if (mode !== "override" && mode !== "hide") {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!this.moderationPrimaryButton) {
|
||||
if (!this.document) {
|
||||
return null;
|
||||
}
|
||||
const button = this.document.createElement("button");
|
||||
button.type = "button";
|
||||
button.className = "moderation-badge__action flex-shrink-0";
|
||||
this.moderationPrimaryButton = button;
|
||||
this.moderationPrimaryMode = "";
|
||||
}
|
||||
|
||||
const button = this.moderationPrimaryButton;
|
||||
|
||||
if (this.moderationPrimaryMode !== mode) {
|
||||
if (this.moderationPrimaryMode === "override") {
|
||||
button.removeEventListener("click", this.handleModerationOverrideClick);
|
||||
} else if (this.moderationPrimaryMode === "hide") {
|
||||
button.removeEventListener("click", this.handleModerationHideClick);
|
||||
}
|
||||
|
||||
if (mode === "override") {
|
||||
button.textContent = "Show anyway";
|
||||
button.dataset.moderationAction = "override";
|
||||
button.setAttribute("aria-pressed", "false");
|
||||
button.addEventListener("click", this.handleModerationOverrideClick);
|
||||
} else {
|
||||
button.textContent = "Hide";
|
||||
button.dataset.moderationAction = "hide";
|
||||
button.removeAttribute("aria-pressed");
|
||||
button.addEventListener("click", this.handleModerationHideClick);
|
||||
}
|
||||
|
||||
this.moderationPrimaryMode = mode;
|
||||
}
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
removeModerationPrimaryButton() {
|
||||
const button = this.moderationPrimaryButton;
|
||||
if (!button) {
|
||||
this.moderationPrimaryMode = "";
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.moderationPrimaryMode === "override") {
|
||||
button.removeEventListener("click", this.handleModerationOverrideClick);
|
||||
} else if (this.moderationPrimaryMode === "hide") {
|
||||
button.removeEventListener("click", this.handleModerationHideClick);
|
||||
}
|
||||
|
||||
if (button.parentElement) {
|
||||
button.parentElement.removeChild(button);
|
||||
}
|
||||
|
||||
this.moderationPrimaryButton = null;
|
||||
this.moderationPrimaryMode = "";
|
||||
}
|
||||
|
||||
ensureModerationBlockButton() {
|
||||
if (!this.document) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!this.moderationBlockButton) {
|
||||
const button = this.document.createElement("button");
|
||||
button.type = "button";
|
||||
button.className = "moderation-badge__action flex-shrink-0";
|
||||
button.dataset.moderationAction = "block";
|
||||
button.textContent = "Block";
|
||||
button.addEventListener("click", this.handleModerationBlockClick);
|
||||
this.moderationBlockButton = button;
|
||||
}
|
||||
|
||||
return this.moderationBlockButton;
|
||||
}
|
||||
|
||||
removeModerationBlockButton() {
|
||||
const button = this.moderationBlockButton;
|
||||
if (!button) {
|
||||
return;
|
||||
}
|
||||
|
||||
button.removeEventListener("click", this.handleModerationBlockClick);
|
||||
if (button.parentElement) {
|
||||
button.parentElement.removeChild(button);
|
||||
}
|
||||
|
||||
this.moderationBlockButton = null;
|
||||
}
|
||||
|
||||
handleModerationOverrideClick(event) {
|
||||
event?.preventDefault?.();
|
||||
event?.stopPropagation?.();
|
||||
|
||||
const button = event?.currentTarget || this.moderationOverrideButton;
|
||||
const button = event?.currentTarget || this.moderationPrimaryButton;
|
||||
if (button) {
|
||||
button.disabled = true;
|
||||
button.setAttribute("aria-busy", "true");
|
||||
@@ -4081,6 +4349,70 @@ export class VideoModal {
|
||||
}
|
||||
}
|
||||
|
||||
handleModerationHideClick(event) {
|
||||
event?.preventDefault?.();
|
||||
event?.stopPropagation?.();
|
||||
|
||||
const button = event?.currentTarget || this.moderationPrimaryButton;
|
||||
if (button) {
|
||||
button.disabled = true;
|
||||
button.setAttribute("aria-busy", "true");
|
||||
}
|
||||
|
||||
if (!this.activeVideo) {
|
||||
if (button) {
|
||||
button.disabled = false;
|
||||
button.removeAttribute("aria-busy");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const detail = {
|
||||
video: this.activeVideo,
|
||||
event,
|
||||
trigger: button || null,
|
||||
context: this.activeModerationContext || null,
|
||||
};
|
||||
|
||||
const handled = this.dispatch("video:moderation-hide", detail);
|
||||
if (!handled && button) {
|
||||
button.disabled = false;
|
||||
button.removeAttribute("aria-busy");
|
||||
}
|
||||
}
|
||||
|
||||
handleModerationBlockClick(event) {
|
||||
event?.preventDefault?.();
|
||||
event?.stopPropagation?.();
|
||||
|
||||
const button = event?.currentTarget || this.moderationBlockButton;
|
||||
if (button) {
|
||||
button.disabled = true;
|
||||
button.setAttribute("aria-busy", "true");
|
||||
}
|
||||
|
||||
if (!this.activeVideo) {
|
||||
if (button) {
|
||||
button.disabled = false;
|
||||
button.removeAttribute("aria-busy");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const detail = {
|
||||
video: this.activeVideo,
|
||||
event,
|
||||
trigger: button || null,
|
||||
context: this.activeModerationContext || null,
|
||||
};
|
||||
|
||||
const handled = this.dispatch("video:moderation-block", detail);
|
||||
if (!handled && button) {
|
||||
button.disabled = false;
|
||||
button.removeAttribute("aria-busy");
|
||||
}
|
||||
}
|
||||
|
||||
handleGlobalModerationOverride(event) {
|
||||
const detail = event?.detail || {};
|
||||
const video = detail && typeof detail === "object" ? detail.video : null;
|
||||
|
||||
@@ -190,6 +190,7 @@ export class VideoListView {
|
||||
blacklist: null,
|
||||
moderationOverride: null,
|
||||
moderationBlock: null,
|
||||
moderationHide: null,
|
||||
tagActivate: null,
|
||||
};
|
||||
|
||||
@@ -304,6 +305,11 @@ export class VideoListView {
|
||||
typeof handler === "function" ? handler : null;
|
||||
}
|
||||
|
||||
setModerationHideHandler(handler) {
|
||||
this.handlers.moderationHide =
|
||||
typeof handler === "function" ? handler : null;
|
||||
}
|
||||
|
||||
setTagActivationHandler(handler) {
|
||||
this.handlers.tagActivate = typeof handler === "function" ? handler : null;
|
||||
}
|
||||
@@ -621,6 +627,20 @@ export class VideoListView {
|
||||
});
|
||||
};
|
||||
|
||||
videoCard.onModerationHide = ({ event: hideEvent }) => {
|
||||
if (!this.handlers.moderationHide) {
|
||||
return false;
|
||||
}
|
||||
const trigger =
|
||||
hideEvent?.currentTarget || hideEvent?.target || null;
|
||||
return this.handlers.moderationHide({
|
||||
event: hideEvent,
|
||||
video,
|
||||
card: videoCard,
|
||||
trigger,
|
||||
});
|
||||
};
|
||||
|
||||
videoCard.onEdit = ({ event: editEvent, video: editVideo, index: editIndex }) => {
|
||||
if (this.handlers.edit) {
|
||||
const trigger = editEvent?.currentTarget || editEvent?.target || null;
|
||||
|
||||
Reference in new issue
Block a user