This commit is contained in:
thePR0M3TH3AN committed 2025-11-12 11:06:10 -05:00
1 parent 000127f88c
commit 071d78dd6c
194 files changed
+28793 -3944

No files matched your search

+29 -7
View File
@@ -891,11 +891,29 @@ export class EditModal {
const finalTitle = titleWasEdited ? newTitle : original.title || "";
const finalUrl = urlWasEdited ? newUrl : original.url || "";
const shouldUseOriginalWs = wsInput ? wsInput.readOnly !== false : true;
const shouldUseOriginalXs = xsInput ? xsInput.readOnly !== false : true;
let finalWs = shouldUseOriginalWs ? original.ws || "" : newWs;
let finalXs = shouldUseOriginalXs ? original.xs || "" : newXs;
let finalMagnet = magnetWasEdited ? newMagnet : original.magnet || "";
const originalMagnetValue =
typeof original.magnet === "string" ? original.magnet.trim() : "";
const originalWsValue =
typeof original.ws === "string" ? original.ws.trim() : "";
const originalXsValue =
typeof original.xs === "string" ? original.xs.trim() : "";
const wsWasManuallyEdited = wsInput ? wsInput.readOnly === false : false;
const xsWasManuallyEdited = xsInput ? xsInput.readOnly === false : false;
let finalMagnet = magnetWasEdited ? newMagnet : originalMagnetValue;
let finalWs = wsWasManuallyEdited ? newWs : originalWsValue;
let finalXs = xsWasManuallyEdited ? newXs : originalXsValue;
if (magnetWasEdited) {
const magnetHintCandidates = extractMagnetHints(finalMagnet);
if (!wsWasManuallyEdited) {
finalWs = magnetHintCandidates.ws || "";
}
if (!xsWasManuallyEdited) {
finalXs = magnetHintCandidates.xs || "";
}
}
const finalThumbnail = isEditing(thumbnailInput)
? newThumbnail
: original.thumbnail || "";
@@ -990,6 +1008,10 @@ export class EditModal {
finalXs = "";
}
const magnetChanged = magnetWasEdited && finalMagnet !== originalMagnetValue;
const wsEditedFlag = wsWasManuallyEdited || magnetChanged;
const xsEditedFlag = xsWasManuallyEdited || magnetChanged;
const updatedData = {
version: original.version || 2,
title: finalTitle,
@@ -1000,8 +1022,8 @@ export class EditModal {
mode: this.resolveModeForSubmit(),
ws: finalWs,
xs: finalXs,
wsEdited: !shouldUseOriginalWs,
xsEdited: !shouldUseOriginalXs,
wsEdited: wsEditedFlag,
xsEdited: xsEditedFlag,
urlEdited: urlWasEdited,
magnetEdited: magnetWasEdited,
enableComments: finalEnableComments,
+16 -4
View File
@@ -1,5 +1,6 @@
import { normalizeDesignSystemContext } from "../../designSystem.js";
import { formatShortNpub } from "../../utils/formatters.js";
import { sanitizeProfileMediaUrl } from "../../utils/profileMedia.js";
const DEFAULT_PROFILE_AVATAR = "assets/svg/default-profile.svg";
@@ -213,15 +214,26 @@ export class SimilarContentCard {
continue;
}
const trimmed = entry.trim();
if (trimmed) {
return trimmed;
if (!trimmed) {
continue;
}
const sanitized = sanitizeProfileMediaUrl(trimmed);
if (sanitized) {
return sanitized;
}
}
return "";
const fallback =
typeof baseline.picture === "string" && baseline.picture.trim()
? sanitizeProfileMediaUrl(baseline.picture) || baseline.picture.trim()
: "";
return fallback;
})();
return { name, npub, shortNpub, pubkey, picture };
const resolvedPicture = picture || DEFAULT_PROFILE_AVATAR;
return { name, npub, shortNpub, pubkey, picture: resolvedPicture };
}
applyIdentityToElements() {
+136
View File
@@ -1,5 +1,6 @@
import { normalizeDesignSystemContext } from "../../designSystem.js";
import { updateVideoCardSourceVisibility } from "../../utils/cardSourceVisibility.js";
import { sanitizeProfileMediaUrl } from "../../utils/profileMedia.js";
import { userLogger } from "../../utils/logger.js";
import {
applyModerationContextDatasets,
@@ -9,6 +10,8 @@ import {
import { buildModerationBadgeText } from "../moderationCopy.js";
const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
const DEFAULT_PROFILE_AVATAR = "assets/svg/default-profile.svg";
const HEX64_REGEX = /^[0-9a-f]{64}$/i;
export class VideoCard {
constructor({
@@ -27,6 +30,7 @@ export class VideoCard {
assets = {},
state = {},
variant = "default",
identity = null,
ensureGlobalMoreMenuHandlers,
onRequestCloseAllMenus,
nsfwContext = null,
@@ -91,6 +95,7 @@ export class VideoCard {
: null;
this.designSystem = normalizeDesignSystemContext(designSystem);
this.identity = this.normalizeIdentity(identity);
const normalizedVariant =
typeof variant === "string" && variant.trim().toLowerCase() === "compact"
@@ -461,6 +466,8 @@ export class VideoCard {
header.appendChild(controls);
}
this.applyIdentityToAuthorElements();
content.appendChild(title);
content.appendChild(header);
@@ -501,6 +508,135 @@ export class VideoCard {
this.refreshModerationUi();
}
normalizeIdentity(nextIdentity = {}, fallback = null) {
const baseline = fallback && typeof fallback === "object" ? fallback : {};
const candidate =
nextIdentity && typeof nextIdentity === "object" ? nextIdentity : {};
const video = this.video && typeof this.video === "object" ? this.video : {};
const pickFirstString = (
entries = [],
{ allowHex = true, sanitizer = (value) => value } = {},
) => {
for (const entry of entries) {
if (typeof entry !== "string") {
continue;
}
const trimmed = entry.trim();
if (!trimmed) {
continue;
}
if (!allowHex && HEX64_REGEX.test(trimmed)) {
continue;
}
const sanitized = sanitizer(trimmed);
if (!sanitized) {
continue;
}
return sanitized;
}
return "";
};
const pubkey = pickFirstString([
candidate.pubkey,
baseline.pubkey,
video.pubkey,
video.author?.pubkey,
video.creator?.pubkey,
video.profile?.pubkey,
]);
const npub = pickFirstString([
candidate.npub,
baseline.npub,
video.npub,
video.authorNpub,
video.profile?.npub,
]);
const shortNpub = pickFirstString([
candidate.shortNpub,
baseline.shortNpub,
video.shortNpub,
video.creatorNpub,
]);
const name = pickFirstString(
[
candidate.name,
candidate.display_name,
candidate.displayName,
candidate.username,
baseline.name,
baseline.display_name,
baseline.displayName,
baseline.username,
video.creatorName,
video.authorName,
video.creator?.name,
video.author?.name,
video.profile?.display_name,
video.profile?.name,
video.profile?.username,
],
{ allowHex: false },
);
const picture = pickFirstString(
[
candidate.picture,
candidate.image,
candidate.photo,
baseline.picture,
baseline.image,
baseline.photo,
video.creatorPicture,
video.authorPicture,
video.creator?.picture,
video.author?.picture,
video.profile?.picture,
video.profile?.image,
video.profile?.photo,
],
{ sanitizer: (value) => sanitizeProfileMediaUrl(value) },
);
const resolvedName = name || shortNpub || npub || pubkey || "";
const resolvedPicture = picture || DEFAULT_PROFILE_AVATAR;
return {
name: resolvedName,
npub,
shortNpub,
pubkey,
picture: resolvedPicture,
};
}
updateIdentity(nextIdentity = {}) {
this.identity = this.normalizeIdentity(nextIdentity, this.identity);
this.applyIdentityToAuthorElements();
}
applyIdentityToAuthorElements() {
const nameLabel = this.identity?.name || "Unknown";
if (this.authorNameEl) {
this.authorNameEl.textContent = nameLabel || "Unknown";
}
if (this.authorPicEl) {
const picture = this.identity?.picture || DEFAULT_PROFILE_AVATAR;
if (this.authorPicEl.getAttribute("src") !== picture) {
this.authorPicEl.src = picture;
}
const altFallback =
nameLabel || this.identity?.shortNpub || this.identity?.npub || "Channel";
this.authorPicEl.alt = `${altFallback}'s avatar`;
}
}
setCardBackdropImage(src) {
if (!this.root || !this.root.style) {
return;
+304 -29
View File
@@ -16,6 +16,7 @@ import {
import {
renderTagPillStrip,
applyTagPreferenceState,
trimTagPillStripToFit,
} from "./tagPillList.js";
import { SimilarContentCard } from "./SimilarContentCard.js";
import {
@@ -129,6 +130,10 @@ export class VideoModal {
this.videoViewCountEl = null;
this.videoTagsRoot = null;
this.videoTagsData = Object.freeze([]);
this.videoTagsSourceData = this.videoTagsData;
this.videoTagsResizeObserver = null;
this.videoTagsLastObservedWidth = 0;
this.handleVideoTagsResize = this.handleVideoTagsResize.bind(this);
this.creatorAvatar = null;
this.creatorName = null;
this.creatorNpub = null;
@@ -390,6 +395,7 @@ export class VideoModal {
} else {
this.loaded = false;
this.cleanupVideoTags();
this.teardownVideoTagsResizeObserver();
this.videoTagsRoot = null;
this.playerModal = null;
}
@@ -509,6 +515,7 @@ export class VideoModal {
if (this.videoTagsRoot && this.videoTagsRoot !== nextVideoTagsRoot) {
this.cleanupVideoTags(this.videoTagsRoot);
}
this.teardownVideoTagsResizeObserver();
this.videoTagsRoot = nextVideoTagsRoot;
if (this.videoTagsRoot) {
this.cleanupVideoTags(this.videoTagsRoot);
@@ -540,10 +547,11 @@ export class VideoModal {
statsContainer: statsContainerCandidate,
});
const previousTags = Array.isArray(this.videoTagsData)
? [...this.videoTagsData]
const previousTags = Array.isArray(this.videoTagsSourceData)
? [...this.videoTagsSourceData]
: [];
this.videoTagsData = null;
this.videoTagsSourceData = Object.freeze([]);
this.moderationController.initialize({ playerModal });
@@ -1807,7 +1815,12 @@ export class VideoModal {
}
if (typeof value === "string") {
const trimmed = value.trim();
if (!trimmed || trimmed === "null" || trimmed === "undefined") {
if (
!trimmed ||
trimmed === "null" ||
trimmed === "undefined" ||
trimmed === "__root__"
) {
return null;
}
return trimmed;
@@ -1930,6 +1943,7 @@ export class VideoModal {
destroy() {
this.close();
this.teardownVideoTagsResizeObserver();
this.commentsController.destroy();
this.reactionsController.destroy();
this.similarContentController.destroy();
@@ -2585,6 +2599,19 @@ export class VideoModal {
return;
}
// Ensure title element reference is available
if (!this.videoTitle) {
this.videoTitle = this.playerModal.querySelector("#videoTitle") || null;
}
// Set title immediately when opening if video has a title
if (this.videoTitle && video && typeof video.title === "string" && video.title.trim()) {
this.videoTitle.textContent = video.title.trim();
this.videoTitle.hidden = false;
} else if (this.videoTitle) {
this.videoTitle.textContent = "Untitled";
this.videoTitle.hidden = false;
}
this.resetReactions();
this.playerModal.classList.remove("hidden");
@@ -2795,21 +2822,29 @@ export class VideoModal {
return true;
}
renderVideoTags(tags = []) {
renderVideoTags(tags = [], options = {}) {
const { force = false } = options || {};
const normalized = this.normalizeVideoTags(tags);
const hasTags = normalized.length > 0;
const root = this.videoTagsRoot;
if (root) {
if (this.areVideoTagsEqual(normalized, this.videoTagsData)) {
this.toggleVideoTagsVisibility(hasTags);
this.refreshTagPreferenceStates();
if (!force && this.areVideoTagsEqual(normalized, this.videoTagsData)) {
const hasVisibleButtons =
root.querySelector("button[data-tag]") !== null;
this.toggleVideoTagsVisibility(hasVisibleButtons);
if (hasVisibleButtons) {
this.ensureVideoTagsResizeObserver();
this.refreshTagPreferenceStates();
} else {
this.teardownVideoTagsResizeObserver();
}
return;
}
this.cleanupVideoTags(root);
if (hasTags) {
let hasVisibleButtons = false;
if (normalized.length > 0) {
const { root: strip } = renderTagPillStrip({
document: root.ownerDocument || this.document,
tags: normalized,
@@ -2819,13 +2854,119 @@ export class VideoModal {
if (strip) {
root.appendChild(strip);
trimTagPillStripToFit({ strip, container: root });
if (strip.querySelector("button[data-tag]")) {
hasVisibleButtons = true;
} else if (strip.parentNode === root) {
root.removeChild(strip);
}
}
}
this.toggleVideoTagsVisibility(hasTags);
this.toggleVideoTagsVisibility(hasVisibleButtons);
if (hasVisibleButtons) {
this.ensureVideoTagsResizeObserver();
this.refreshTagPreferenceStates();
} else {
this.teardownVideoTagsResizeObserver();
}
} else {
this.teardownVideoTagsResizeObserver();
}
this.videoTagsData = Object.freeze([...normalized]);
const stored = Object.freeze([...normalized]);
this.videoTagsData = stored;
this.videoTagsSourceData = stored;
}
reflowVideoTags() {
if (!Array.isArray(this.videoTagsSourceData)) {
return;
}
if (this.videoTagsSourceData.length === 0) {
return;
}
this.renderVideoTags([...this.videoTagsSourceData], { force: true });
}
ensureVideoTagsResizeObserver() {
const root = this.videoTagsRoot;
if (!root) {
return;
}
const ResizeObserverCtor =
(this.window && this.window.ResizeObserver) ||
globalThis.ResizeObserver ||
null;
if (typeof ResizeObserverCtor !== "function") {
return;
}
if (!this.videoTagsResizeObserver) {
this.videoTagsResizeObserver = new ResizeObserverCtor(
this.handleVideoTagsResize,
);
} else if (typeof this.videoTagsResizeObserver.disconnect === "function") {
this.videoTagsResizeObserver.disconnect();
}
try {
this.videoTagsResizeObserver.observe(root);
} catch (error) {
// Ignore observer errors (e.g., observing a detached node).
}
}
teardownVideoTagsResizeObserver() {
if (this.videoTagsResizeObserver) {
try {
this.videoTagsResizeObserver.disconnect();
} catch (error) {
// Ignore teardown errors.
}
}
this.videoTagsResizeObserver = null;
this.videoTagsLastObservedWidth = 0;
}
handleVideoTagsResize(entries = []) {
if (!this.videoTagsRoot) {
return;
}
const entry =
Array.isArray(entries) && entries.length > 0
? entries.find((item) => item?.target === this.videoTagsRoot) ||
entries[0]
: null;
const measuredWidthRaw = entry
? entry.contentRect && typeof entry.contentRect.width === "number"
? entry.contentRect.width
: typeof entry.contentBoxSize?.[0]?.inlineSize === "number"
? entry.contentBoxSize[0].inlineSize
: this.videoTagsRoot.clientWidth || 0
: this.videoTagsRoot.clientWidth || 0;
const measuredWidth = Number.isFinite(measuredWidthRaw)
? Math.max(0, Math.round(measuredWidthRaw))
: 0;
if (measuredWidth <= 0) {
this.videoTagsLastObservedWidth = 0;
return;
}
if (this.videoTagsLastObservedWidth === measuredWidth) {
return;
}
this.videoTagsLastObservedWidth = measuredWidth;
this.reflowVideoTags();
}
handleVideoTagActivate(tag, { event, button } = {}) {
@@ -3506,7 +3647,43 @@ export class VideoModal {
return;
}
receipts.forEach((receipt) => {
const normalized = receipts.filter(
(receipt) => receipt && typeof receipt === "object"
);
const validatedReceipts = normalized.filter(
(receipt) => receipt?.validation?.status === "passed" && receipt.validation.event
);
const paymentFailures = normalized.filter((receipt) => {
if (!receipt) {
return false;
}
const status =
typeof receipt.status === "string" ? receipt.status.toLowerCase() : "";
return status && status !== "success";
});
const unvalidatedReceipts = normalized.filter((receipt) => {
if (!receipt) {
return false;
}
const status =
typeof receipt.status === "string" ? receipt.status.toLowerCase() : "success";
if (status !== "success" && status !== "") {
return false;
}
const validationStatus =
typeof receipt.validation?.status === "string"
? receipt.validation.status.toLowerCase()
: "";
if (!validationStatus || validationStatus === "skipped") {
return false;
}
return validationStatus !== "passed";
});
const renderReceiptItem = ({ receipt, tone }) => {
const li = this.document.createElement("li");
li.className = "rounded border border-border p-3 bg-overlay-panel-soft";
@@ -3528,11 +3705,16 @@ export class VideoModal {
)} sats`;
const status = this.document.createElement("span");
const isSuccess = receipt.status
? receipt.status === "success"
: !receipt.error;
status.textContent = isSuccess ? "Success" : "Failed";
status.className = isSuccess ? "text-info" : "text-critical";
if (tone === "validated") {
status.textContent = "Validated";
status.className = "text-info";
} else if (tone === "failed") {
status.textContent = "Failed";
status.className = "text-critical";
} else {
status.textContent = "Pending";
status.className = "text-muted";
}
header.appendChild(shareLabel);
header.appendChild(status);
@@ -3547,7 +3729,14 @@ export class VideoModal {
const detail = this.document.createElement("p");
detail.className = "mt-2 text-xs text-muted";
if (isSuccess) {
if (tone === "failed") {
const errorMessage =
(receipt.error && receipt.error.message) ||
(typeof receipt.error === "string"
? receipt.error
: "Payment failed.");
detail.textContent = errorMessage;
} else {
let detailMessage = "Invoice settled.";
const preimage = receipt.payment?.result?.preimage;
if (typeof preimage === "string" && preimage) {
@@ -3556,18 +3745,59 @@ export class VideoModal {
}`;
}
detail.textContent = detailMessage;
} else {
const errorMessage =
(receipt.error && receipt.error.message) ||
(typeof receipt.error === "string"
? receipt.error
: "Payment failed.");
detail.textContent = errorMessage;
}
li.appendChild(detail);
this.modalZapReceipts.appendChild(li);
};
validatedReceipts.forEach((receipt) => {
renderReceiptItem({ receipt, tone: "validated" });
});
paymentFailures.forEach((receipt) => {
renderReceiptItem({ receipt, tone: "failed" });
});
if (!validatedReceipts.length && !paymentFailures.length && !unvalidatedReceipts.length) {
const empty = this.document.createElement("li");
empty.className = "text-sm text-text";
empty.textContent = partial
? "No zap receipts available."
: "No zap receipts published yet.";
this.modalZapReceipts.appendChild(empty);
return;
}
if (unvalidatedReceipts.length) {
const warning = this.document.createElement("li");
warning.className =
"rounded border border-border p-3 bg-overlay-panel-soft text-xs text-warning-strong";
const summaries = unvalidatedReceipts.map((receipt) => {
const shareType = receipt.recipientType || receipt.type || "creator";
const label =
shareType === "platform"
? "Platform"
: shareType === "creator"
? "Creator"
: "Lightning";
const address =
typeof receipt.address === "string" && receipt.address
? ` (${receipt.address})`
: "";
const reason =
typeof receipt.validation?.reason === "string" && receipt.validation.reason
? ` — ${receipt.validation.reason}`
: " — Awaiting compliant receipt.";
return `${label}${address}${reason}`;
});
const intro = validatedReceipts.length
? "Awaiting validated zap receipt for remaining share(s)."
: "No validated zap receipts yet.";
warning.textContent = `${intro} ${summaries.join(" ")}`.trim();
this.modalZapReceipts.appendChild(warning);
}
}
setZapPending(pending) {
@@ -3715,8 +3945,35 @@ export class VideoModal {
creator,
tags,
} = {}) {
if (this.videoTitle && title !== undefined) {
this.videoTitle.textContent = title || "Untitled";
if (title !== undefined) {
// Try to find the title element if not already cached
if (!this.videoTitle) {
if (this.playerModal) {
this.videoTitle = this.playerModal.querySelector("#videoTitle") || null;
}
// Fallback: try document query if playerModal query failed
if (!this.videoTitle) {
this.videoTitle = this.document.getElementById("videoTitle") || null;
}
}
if (this.videoTitle) {
const titleText =
typeof title === "string" && title.trim()
? title.trim()
: "Untitled";
this.videoTitle.textContent = titleText;
// Ensure element is visible
this.videoTitle.hidden = false;
if (this.videoTitle.style) {
this.videoTitle.style.display = "";
}
} else {
// Log for debugging if element cannot be found
this.logger?.log?.(
"[VideoModal] Could not find #videoTitle element to set title:",
title
);
}
}
if (this.videoDescription && description !== undefined) {
this.renderVideoDescription(description);
@@ -5063,12 +5320,30 @@ export class VideoModal {
continue;
}
const trimmed = candidate.trim();
if (trimmed) {
picture = trimmed;
if (!trimmed) {
continue;
}
const sanitized = sanitizeProfileMediaUrl(trimmed);
if (sanitized) {
picture = sanitized;
break;
}
}
if (!picture && pubkey) {
const robohash = `https://robohash.org/${pubkey}`;
picture = sanitizeProfileMediaUrl(robohash) || robohash;
}
if (!picture) {
const fallbackAvatar =
typeof this.DEFAULT_PROFILE_AVATAR === "string" &&
this.DEFAULT_PROFILE_AVATAR.trim()
? this.DEFAULT_PROFILE_AVATAR.trim()
: "assets/svg/default-profile.svg";
picture = sanitizeProfileMediaUrl(fallbackAvatar) || fallbackAvatar;
}
return {
name,
npub,
+25 -1
View File
@@ -199,6 +199,8 @@ export class Nip71FormManager {
this.setFieldValue(entry, "dim", value.dim);
this.setFieldValue(entry, "url", value.url);
this.setFieldValue(entry, "x", value.x);
this.setFieldValue(entry, "duration", value.duration);
this.setFieldValue(entry, "bitrate", value.bitrate);
this.hydrateNested(entry, "image", value.image);
this.hydrateNested(entry, "fallback", value.fallback);
this.hydrateNested(entry, "service", value.service);
@@ -302,6 +304,26 @@ export class Nip71FormManager {
service: this.collectNestedValues(entry, "service"),
};
const durationValue = this.getFieldValue(entry, "duration");
if (durationValue !== "") {
const parsed = this.normalizeNumber(durationValue);
if (parsed != null && parsed >= 0) {
variant.duration = parsed;
} else {
variant.duration = durationValue;
}
}
const bitrateValue = this.getFieldValue(entry, "bitrate");
if (bitrateValue !== "") {
const parsed = this.normalizeNumber(bitrateValue);
if (parsed != null && parsed >= 0) {
variant.bitrate = parsed;
} else {
variant.bitrate = bitrateValue;
}
}
const hasContent =
variant.m ||
variant.dim ||
@@ -309,7 +331,9 @@ export class Nip71FormManager {
variant.x ||
variant.image.length > 0 ||
variant.fallback.length > 0 ||
variant.service.length > 0;
variant.service.length > 0 ||
variant.duration !== undefined ||
variant.bitrate !== undefined;
return hasContent ? variant : null;
});
+87 -5
View File
@@ -115,17 +115,99 @@ function createTagButton({ doc, tag, onTagActivate, getTagState }) {
return button;
}
function cleanupButtonHandler(button) {
if (!button || typeof button !== "object" || button.nodeType !== 1) {
return;
}
const handler = button.__tagPillClickHandler;
if (handler) {
button.removeEventListener("click", handler);
delete button.__tagPillClickHandler;
}
}
function removeTagButton(button) {
if (!button || typeof button !== "object" || button.nodeType !== 1) {
return;
}
cleanupButtonHandler(button);
if (typeof button.remove === "function") {
button.remove();
} else if (button.parentNode) {
button.parentNode.removeChild(button);
}
}
function cleanupExistingButtons(root) {
for (const button of root.querySelectorAll("button")) {
const handler = button.__tagPillClickHandler;
if (handler) {
button.removeEventListener("click", handler);
delete button.__tagPillClickHandler;
}
cleanupButtonHandler(button);
}
root.textContent = "";
}
function getAvailableContainerWidth(container) {
if (!container || container.nodeType !== 1) {
return 0;
}
const clientWidth = Number(container.clientWidth || 0);
if (Number.isFinite(clientWidth) && clientWidth > 0) {
return clientWidth;
}
if (typeof container.getBoundingClientRect === "function") {
try {
const rect = container.getBoundingClientRect();
if (rect && typeof rect.width === "number" && rect.width > 0) {
return rect.width;
}
} catch (error) {
// Ignore measurement errors and fall through to return 0.
}
}
return 0;
}
export function trimTagPillStripToFit({ strip, container } = {}) {
if (!strip || typeof strip !== "object" || strip.nodeType !== 1) {
return { removedButtons: [] };
}
const host =
container && typeof container === "object" && container.nodeType === 1
? container
: strip.parentElement;
const availableWidth = Math.max(0, getAvailableContainerWidth(host));
const removedButtons = [];
const buttons = Array.from(strip.querySelectorAll("button"));
if (!buttons.length) {
return { removedButtons };
}
if (availableWidth <= 0) {
return { removedButtons };
}
let currentButtons = buttons.length;
while (currentButtons > 0 && strip.scrollWidth > availableWidth) {
const button = buttons[currentButtons - 1];
if (!button) {
break;
}
removeTagButton(button);
removedButtons.push(button);
currentButtons -= 1;
}
return { removedButtons };
}
export function renderTagPillStrip({
document: doc,
tags = [],
+5 -1
View File
@@ -288,7 +288,11 @@ export function createVideoMoreMenuPanel({
appendMenuAction(doc, list, {
text: "Report",
action: "report",
dataset: { eventId: metadata.id },
dataset: {
eventId: metadata.id,
author: metadata.pubkey,
pointerRelay: pointer && pointer.relay ? pointer.relay : "",
},
});
return panel;