Merge pull request #838 from PR0M3TH3AN/codex/add-variant-option-for-compact-layout

Add compact VideoCard variant
This commit is contained in:
thePR0M3TH3AN authored and GitHub committed 2025-10-23 16:06:01 -04:00
commit decbcfb4ce
2 files changed
+114 -29

No files matched your search

+28
View File
@@ -960,6 +960,34 @@
z-index: 1; z-index: 1;
} }
.card--compact {
@apply flex flex-row items-stretch gap-md;
}
.card--compact .video-card__media {
@apply block w-40 shrink-0 overflow-hidden rounded-lg sm:w-56;
}
.card--compact .video-card__content {
@apply flex min-w-0 flex-1 flex-col gap-sm p-md;
}
.card--compact .video-card__title {
@apply text-base font-semibold leading-snug;
}
.card--compact .video-card__author-name {
@apply text-xs;
}
.card--compact .video-card__meta {
@apply mt-0 flex items-center gap-2 text-2xs text-muted-strong;
}
.card--compact .video-card__meta .view-count-text {
@apply text-2xs;
}
.card:hover, .card:hover,
.card:focus-within { .card:focus-within {
--video-card-lift-translate-y: -0.35rem; --video-card-lift-translate-y: -0.35rem;
+86 -29
View File
@@ -20,6 +20,7 @@ export class VideoCard {
helpers = {}, helpers = {},
assets = {}, assets = {},
state = {}, state = {},
variant = "default",
ensureGlobalMoreMenuHandlers, ensureGlobalMoreMenuHandlers,
onRequestCloseAllMenus, onRequestCloseAllMenus,
nsfwContext = null, nsfwContext = null,
@@ -85,6 +86,12 @@ export class VideoCard {
this.designSystem = normalizeDesignSystemContext(designSystem); this.designSystem = normalizeDesignSystemContext(designSystem);
const normalizedVariant =
typeof variant === "string" && variant.trim().toLowerCase() === "compact"
? "compact"
: "default";
this.variant = normalizedVariant;
this.nsfwContext = { this.nsfwContext = {
isNsfw: Boolean(nsfwContext?.isNsfw), isNsfw: Boolean(nsfwContext?.isNsfw),
allowNsfw: nsfwContext?.allowNsfw !== false, allowNsfw: nsfwContext?.allowNsfw !== false,
@@ -324,8 +331,14 @@ export class VideoCard {
build() { build() {
const doc = this.document; const doc = this.document;
const isCompact = this.variant === "compact";
const cardClassNames = ["card"];
if (isCompact) {
cardClassNames.push("card--compact");
}
const root = this.createElement("div", { const root = this.createElement("div", {
classNames: ["card"] classNames: cardClassNames,
}); });
this.root = root; this.root = root;
@@ -343,15 +356,22 @@ export class VideoCard {
this.applySourceDatasets(); this.applySourceDatasets();
this.applyModerationDatasets(); this.applyModerationDatasets();
const anchorClassNames = [
"block",
"cursor-pointer",
"relative",
"group",
"overflow-hidden",
"video-card__media",
];
if (isCompact) {
anchorClassNames.push("rounded-lg", "flex-shrink-0");
} else {
anchorClassNames.push("rounded-t-lg");
}
const anchor = this.createElement("a", { const anchor = this.createElement("a", {
classNames: [ classNames: anchorClassNames,
"block",
"cursor-pointer",
"relative",
"group",
"rounded-t-lg",
"overflow-hidden"
],
attrs: { attrs: {
href: this.shareUrl href: this.shareUrl
} }
@@ -360,33 +380,48 @@ export class VideoCard {
this.anchorEl = anchor; this.anchorEl = anchor;
const ratio = this.createElement("div", { const ratio = this.createElement("div", {
classNames: ["ratio-16-9"] classNames: ["ratio-16-9", "video-card__media-ratio"],
}); });
const thumbnail = this.buildThumbnail(); const thumbnail = this.buildThumbnail();
ratio.appendChild(thumbnail); ratio.appendChild(thumbnail);
anchor.appendChild(ratio); anchor.appendChild(ratio);
const contentClassNames = [
"video-card__content",
"p-md",
"bv-stack",
"bv-stack--tight",
];
if (isCompact) {
contentClassNames.push("flex-1");
}
const content = this.createElement("div", { const content = this.createElement("div", {
classNames: ["p-md", "bv-stack", "bv-stack--tight"] classNames: contentClassNames,
}); });
this.contentEl = content; this.contentEl = content;
const titleClassNames = [
"video-card__title",
isCompact ? "text-base" : "text-lg",
isCompact ? "font-semibold" : "font-bold",
"text-text",
"line-clamp-2",
"cursor-pointer",
];
if (isCompact) {
titleClassNames.push("leading-snug");
}
const title = this.createElement("h3", { const title = this.createElement("h3", {
classNames: [ classNames: titleClassNames,
"video-card__title",
"text-lg",
"font-bold",
"text-text",
"line-clamp-2",
"cursor-pointer"
],
textContent: this.video.title textContent: this.video.title
}); });
title.dataset.videoId = this.video.id; title.dataset.videoId = this.video.id;
this.titleEl = title; this.titleEl = title;
const header = this.createElement("div", { const header = this.createElement("div", {
classNames: ["flex", "items-center", "justify-between"] classNames: ["flex", "items-center", "justify-between"],
}); });
const authorSection = this.buildAuthorSection(); const authorSection = this.buildAuthorSection();
@@ -642,8 +677,13 @@ export class VideoCard {
} }
buildAuthorSection() { buildAuthorSection() {
const isCompact = this.variant === "compact";
const wrapper = this.createElement("div", { const wrapper = this.createElement("div", {
classNames: ["flex", "items-center", "space-x-3"] classNames: [
"flex",
"items-center",
isCompact ? "space-x-2" : "space-x-3",
],
}); });
const avatarWrapper = this.createElement("div", { const avatarWrapper = this.createElement("div", {
@@ -683,8 +723,14 @@ export class VideoCard {
const authorMeta = this.createElement("div", { classNames: ["min-w-0"] }); const authorMeta = this.createElement("div", { classNames: ["min-w-0"] });
const authorName = this.createElement("p", { const authorName = this.createElement("p", {
classNames: ["text-sm", "text-muted", "author-name", "cursor-pointer"], classNames: [
textContent: "Loading name..." isCompact ? "text-xs" : "text-sm",
"text-muted",
"author-name",
"cursor-pointer",
"video-card__author-name",
],
textContent: "Loading name...",
}); });
if (this.video.pubkey) { if (this.video.pubkey) {
authorName.dataset.pubkey = this.video.pubkey; authorName.dataset.pubkey = this.video.pubkey;
@@ -694,10 +740,11 @@ export class VideoCard {
classNames: [ classNames: [
"flex", "flex",
"items-center", "items-center",
"text-xs", isCompact ? "gap-2" : "mt-1",
isCompact ? "text-2xs" : "text-xs",
"text-muted-strong", "text-muted-strong",
"mt-1" "video-card__meta",
] ],
}); });
const timeEl = this.createElement("span", { const timeEl = this.createElement("span", {
@@ -707,8 +754,13 @@ export class VideoCard {
this.timestampEl = timeEl; this.timestampEl = timeEl;
if (this.pointerInfo && this.pointerInfo.key) { if (this.pointerInfo && this.pointerInfo.key) {
const dotClassNames = ["text-muted-strong"];
if (!isCompact) {
dotClassNames.push("mx-1");
}
const dot = this.createElement("span", { const dot = this.createElement("span", {
classNames: ["mx-1", "text-muted-strong"], classNames: dotClassNames,
textContent: "•" textContent: "•"
}); });
dot.setAttribute("aria-hidden", "true"); dot.setAttribute("aria-hidden", "true");
@@ -851,9 +903,10 @@ export class VideoCard {
} }
buildBadgesContainer() { buildBadgesContainer() {
const isCompact = this.variant === "compact";
const pieces = []; const pieces = [];
if (this.playbackUrl) { if (!isCompact && this.playbackUrl) {
const badge = this.createElement("span", { const badge = this.createElement("span", {
classNames: ["badge", "url-health-badge"] classNames: ["badge", "url-health-badge"]
}); });
@@ -864,7 +917,7 @@ export class VideoCard {
pieces.push(badge); pieces.push(badge);
} }
if (this.magnetSupported && this.magnetProvided) { if (!isCompact && this.magnetSupported && this.magnetProvided) {
const badge = this.createElement("span", { const badge = this.createElement("span", {
classNames: ["badge", "torrent-health-badge"] classNames: ["badge", "torrent-health-badge"]
}); });
@@ -1904,6 +1957,10 @@ export class VideoCard {
} }
buildDiscussionCount() { buildDiscussionCount() {
if (this.variant === "compact") {
return null;
}
if (this.video.enableComments === false) { if (this.video.enableComments === false) {
return null; return null;
} }