From 4580227e0181afe762f8e8e4dfdec33b91f4ab74 Mon Sep 17 00:00:00 2001 From: Silberengel Date: Mon, 8 Dec 2025 20:29:36 +0100 Subject: [PATCH] surppress redunant images in publications --- .../Note/AsciidocArticle/AsciidocArticle.tsx | 14 ++++++-- .../Note/MarkdownArticle/MarkdownArticle.tsx | 14 ++++++-- .../PublicationIndex/PublicationIndex.tsx | 32 ++++++++++++++++--- 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/components/Note/AsciidocArticle/AsciidocArticle.tsx b/src/components/Note/AsciidocArticle/AsciidocArticle.tsx index 479bc01..419e442 100644 --- a/src/components/Note/AsciidocArticle/AsciidocArticle.tsx +++ b/src/components/Note/AsciidocArticle/AsciidocArticle.tsx @@ -329,11 +329,13 @@ function convertMarkdownToAsciidoc(content: string): string { export default function AsciidocArticle({ event, className, - hideImagesAndInfo = false + hideImagesAndInfo = false, + parentImageUrl }: { event: Event className?: string hideImagesAndInfo?: boolean + parentImageUrl?: string }) { const { push } = useSecondaryPage() const { navigateToHashtag } = useSmartHashtagNavigation() @@ -560,6 +562,7 @@ export default function AsciidocArticle({ // Filter tag media to only show what's not in content const leftoverTagMedia = useMemo(() => { const metadataImageUrl = metadata.image ? cleanUrl(metadata.image) : null + const parentImageUrlCleaned = parentImageUrl ? cleanUrl(parentImageUrl) : null return tagMedia.filter(media => { const cleaned = cleanUrl(media.url) if (!cleaned) return false @@ -567,9 +570,11 @@ export default function AsciidocArticle({ if (mediaUrlsInContent.has(cleaned)) return false // Skip if this is the metadata image (shown separately) if (metadataImageUrl && cleaned === metadataImageUrl && !hideImagesAndInfo) return false + // Skip if this matches the parent publication's image (to avoid duplicate cover images) + if (parentImageUrlCleaned && cleaned === parentImageUrlCleaned) return false return true }) - }, [tagMedia, mediaUrlsInContent, metadata.image, hideImagesAndInfo]) + }, [tagMedia, mediaUrlsInContent, metadata.image, hideImagesAndInfo, parentImageUrl]) // Filter tag YouTube URLs to only show what's not in content const leftoverTagYouTubeUrls = useMemo(() => { @@ -1907,10 +1912,15 @@ export default function AsciidocArticle({ {/* Metadata image */} {!hideImagesAndInfo && metadata.image && (() => { const cleanedMetadataImage = cleanUrl(metadata.image) + const parentImageUrlCleaned = parentImageUrl ? cleanUrl(parentImageUrl) : null // Don't show if already in content if (cleanedMetadataImage && mediaUrlsInContent.has(cleanedMetadataImage)) { return null } + // Don't show if it matches the parent publication's image (to avoid duplicate cover images) + if (parentImageUrlCleaned && cleanedMetadataImage === parentImageUrlCleaned) { + return null + } const metadataImageIndex = imageIndexMap.get(cleanedMetadataImage) diff --git a/src/components/Note/MarkdownArticle/MarkdownArticle.tsx b/src/components/Note/MarkdownArticle/MarkdownArticle.tsx index df2009d..f3508ce 100644 --- a/src/components/Note/MarkdownArticle/MarkdownArticle.tsx +++ b/src/components/Note/MarkdownArticle/MarkdownArticle.tsx @@ -3022,11 +3022,13 @@ function parseInlineMarkdown(text: string, keyPrefix: string, _footnotes: Map { const metadataImageUrl = metadata.image ? cleanUrl(metadata.image) : null + const parentImageUrlCleaned = parentImageUrl ? cleanUrl(parentImageUrl) : null return tagMedia.filter(media => { const cleaned = cleanUrl(media.url) if (!cleaned) return false @@ -3286,9 +3289,12 @@ export default function MarkdownArticle({ // Skip if this is the metadata image (shown separately) if (metadataImageUrl && cleaned === metadataImageUrl && !hideMetadata) return false + + // Skip if this matches the parent publication's image (to avoid duplicate cover images) + if (parentImageUrlCleaned && cleaned === parentImageUrlCleaned) return false return true }) - }, [tagMedia, mediaUrlsInContent, metadata.image, hideMetadata]) + }, [tagMedia, mediaUrlsInContent, metadata.image, hideMetadata, parentImageUrl]) // Filter tag YouTube URLs to only show what's not in content const leftoverTagYouTubeUrls = useMemo(() => { @@ -3482,6 +3488,7 @@ export default function MarkdownArticle({ {/* Metadata image */} {!hideMetadata && metadata.image && (() => { const cleanedMetadataImage = cleanUrl(metadata.image) + const parentImageUrlCleaned = parentImageUrl ? cleanUrl(parentImageUrl) : null // Don't show if already in content (check by URL and by identifier) if (cleanedMetadataImage) { if (mediaUrlsInContent.has(cleanedMetadataImage)) return null @@ -3489,6 +3496,9 @@ export default function MarkdownArticle({ if (identifier && mediaUrlsInContent.has(`__img_id:${identifier}`)) return null } + // Don't show if it matches the parent publication's image (to avoid duplicate cover images) + if (parentImageUrlCleaned && cleanedMetadataImage === parentImageUrlCleaned) return null + const metadataImageIndex = imageIndexMap.get(cleanedMetadataImage) return ( diff --git a/src/components/Note/PublicationIndex/PublicationIndex.tsx b/src/components/Note/PublicationIndex/PublicationIndex.tsx index f4ee3ff..ff9791c 100644 --- a/src/components/Note/PublicationIndex/PublicationIndex.tsx +++ b/src/components/Note/PublicationIndex/PublicationIndex.tsx @@ -15,6 +15,7 @@ import { isReplaceableEvent } from '@/lib/event' import { useSecondaryPage } from '@/PageManager' import { extractBookMetadata } from '@/lib/bookstr-parser' import { dTagToTitleCase } from '@/lib/event-metadata' +import Image from '@/components/Image' interface PublicationReference { coordinate?: string @@ -49,11 +50,13 @@ interface PublicationMetadata { export default function PublicationIndex({ event, className, - isNested = false + isNested = false, + parentImageUrl }: { event: Event className?: string isNested?: boolean + parentImageUrl?: string }) { const { push } = useSecondaryPage() // Parse publication metadata from event tags @@ -1341,6 +1344,19 @@ export default function PublicationIndex({

{metadata.summary}

)} + {/* Display image for top-level 30040 publication */} + {metadata.image && ( +
+ +
+ )}
{metadata.author && (
@@ -1538,6 +1554,8 @@ export default function PublicationIndex({ if (eventKind === ExtendedKind.PUBLICATION) { // Recursively render nested 30040 publication index + // Use the top-level publication's image as parent for nested publications + const effectiveParentImageUrl = !isNested ? metadata.image : parentImageUrl return (
{!isNested && ( @@ -1552,11 +1570,14 @@ export default function PublicationIndex({ ToC )} - +
) } else if (eventKind === ExtendedKind.PUBLICATION_CONTENT || eventKind === ExtendedKind.WIKI_ARTICLE) { // Render 30041 or 30818 content as AsciidocArticle + // Pass parent image URL to avoid showing duplicate cover images + // Use the top-level publication's image as parent, or the passed parentImageUrl for nested publications + const effectiveParentImageUrl = !isNested ? metadata.image : parentImageUrl return (
{!isNested && ( @@ -1571,11 +1592,14 @@ export default function PublicationIndex({ ToC )} - +
) } else if (eventKind === ExtendedKind.WIKI_ARTICLE_MARKDOWN) { // Render 30817 content as MarkdownArticle + // Pass parent image URL to avoid showing duplicate cover images + // Use the top-level publication's image as parent, or the passed parentImageUrl for nested publications + const effectiveParentImageUrl = !isNested ? metadata.image : parentImageUrl return (
{!isNested && ( @@ -1590,7 +1614,7 @@ export default function PublicationIndex({ ToC )} - +
) } else {