From 1531d2b70916b3aff7293db411f472cb013cc4e7 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Thu, 5 Sep 2024 22:34:31 +0800 Subject: [PATCH] feat: render social media with full text --- src/hono.ts | 2 + .../src/components/ui/markdown/Markdown.tsx | 9 ++-- src/renderer/src/constants/tabs.tsx | 2 +- src/renderer/src/lib/parse-html.ts | 30 +++++++----- src/renderer/src/lib/utils.ts | 8 +++- .../entry-column/Items/social-media-item.tsx | 9 ++-- .../src/modules/entry-column/translation.tsx | 48 +++++++++++++++++-- .../src/modules/entry-column/types.ts | 1 + 8 files changed, 82 insertions(+), 27 deletions(-) diff --git a/src/hono.ts b/src/hono.ts index 4b9218c39..e392ef7dc 100644 --- a/src/hono.ts +++ b/src/hono.ts @@ -2752,6 +2752,7 @@ declare const _routes: hono_hono_base.HonoBase( as: A accessory?: React.ReactNode + noMedia?: boolean } & JSX.IntrinsicElements[A] & Partial<{ renderInlineStyle: boolean }>, ) => { - const { children, renderInlineStyle, as = "div", accessory, ...rest } = props - const [remarkOptions, setRemarkOptions] = useState({ renderInlineStyle }) + const { children, renderInlineStyle, as = "div", accessory, noMedia, ...rest } = props + const [remarkOptions, setRemarkOptions] = useState({ renderInlineStyle, noMedia }) const [shouldForceReMountKey, setShouldForceReMountKey] = useState(0) useEffect(() => { @@ -54,9 +55,9 @@ export const HTML = ( if (renderInlineStyle === options.renderInlineStyle) return options setShouldForceReMountKey((key) => key + 1) - return { ...options, renderInlineStyle } + return { ...options, renderInlineStyle, noMedia } }) - }, [renderInlineStyle]) + }, [renderInlineStyle, noMedia]) const [refElement, setRefElement] = useState(null) diff --git a/src/renderer/src/constants/tabs.tsx b/src/renderer/src/constants/tabs.tsx index c0b319bef..1ff26995b 100644 --- a/src/renderer/src/constants/tabs.tsx +++ b/src/renderer/src/constants/tabs.tsx @@ -15,7 +15,7 @@ export const views = [ className: "text-sky-600 dark:text-sky-500", peerClassName: "peer-checked:text-sky-600 peer-checked:dark:text-sky-500", wideMode: true, - translation: "description", + translation: "content", view: FeedViewType.SocialMedia, }, { diff --git a/src/renderer/src/lib/parse-html.ts b/src/renderer/src/lib/parse-html.ts index 727ac294c..5007238eb 100644 --- a/src/renderer/src/lib/parse-html.ts +++ b/src/renderer/src/lib/parse-html.ts @@ -27,26 +27,32 @@ export const parseHtml = ( content: string, options?: Partial<{ renderInlineStyle: boolean + noMedia?: boolean }>, ) => { const file = new VFile(content) - const { renderInlineStyle = false } = options || {} + const { renderInlineStyle = false, noMedia = false } = options || {} const pipeline = unified() .use(rehypeParse, { fragment: true }) - .use(rehypeSanitize, { - ...defaultSchema, - tagNames: [...defaultSchema.tagNames!, "video", "style"], - attributes: { - ...defaultSchema.attributes, + .use(rehypeSanitize, noMedia ? + { + ...defaultSchema, + tagNames: defaultSchema.tagNames?.filter((tag) => tag !== "img" && tag !== "picture"), + } : + { + ...defaultSchema, + tagNames: [...defaultSchema.tagNames!, "video", "style"], + attributes: { + ...defaultSchema.attributes, - "*": renderInlineStyle ? - [...defaultSchema.attributes!["*"], "style", "class"] : - defaultSchema.attributes!["*"], + "*": renderInlineStyle ? + [...defaultSchema.attributes!["*"], "style", "class"] : + defaultSchema.attributes!["*"], - "video": ["src", "poster"], - }, - }) + "video": ["src", "poster"], + }, + }) .use(rehypeInferDescriptionMeta) .use(rehypeStringify) diff --git a/src/renderer/src/lib/utils.ts b/src/renderer/src/lib/utils.ts index 387b2adb5..abf224c1c 100644 --- a/src/renderer/src/lib/utils.ts +++ b/src/renderer/src/lib/utils.ts @@ -26,13 +26,17 @@ export function getEntriesParams({ const params: { feedId?: string feedIdList?: string[] - collected?: boolean + isCollection?: boolean + withContent?: boolean } = {} if (id === FEED_COLLECTION_LIST) { - params.collected = true + params.isCollection = true } else if (id && id !== ROUTE_FEED_PENDING) { params.feedIdList = `${id}`.split(",") } + if (view === FeedViewType.SocialMedia) { + params.withContent = true + } return { view, ...params, diff --git a/src/renderer/src/modules/entry-column/Items/social-media-item.tsx b/src/renderer/src/modules/entry-column/Items/social-media-item.tsx index ed5dfe834..b124ada53 100644 --- a/src/renderer/src/modules/entry-column/Items/social-media-item.tsx +++ b/src/renderer/src/modules/entry-column/Items/social-media-item.tsx @@ -31,6 +31,8 @@ export const SocialMediaItem: EntryListItemFC = ({ // NOTE: prevent 0 height element, react virtuoso will not stop render any more if (!entry || !feed) return + const content = entry.entries.content || entry.entries.description + return (
@@ -69,8 +71,9 @@ export const SocialMediaItem: EntryListItemFC = ({ )} > {!!entry.collections && }
diff --git a/src/renderer/src/modules/entry-column/translation.tsx b/src/renderer/src/modules/entry-column/translation.tsx index 082d3190f..a807fe2af 100644 --- a/src/renderer/src/modules/entry-column/translation.tsx +++ b/src/renderer/src/modules/entry-column/translation.tsx @@ -1,4 +1,5 @@ import * as HoverCard from "@radix-ui/react-hover-card" +import { HTML } from "@renderer/components/ui/markdown" import { ScrollArea } from "@renderer/components/ui/scroll-area" import { tooltipStyle } from "@renderer/components/ui/tooltip/styles" import { useMeasure } from "@renderer/hooks/common" @@ -11,7 +12,8 @@ export const EntryTranslation: Component<{ side?: "top" | "bottom" useOverlay?: boolean -}> = ({ source, target, className, side, useOverlay }) => { + isHTML?: boolean +}> = ({ source, target, className, side, useOverlay, isHTML }) => { let nextTarget = target if (source === target) { nextTarget = undefined @@ -20,13 +22,31 @@ export const EntryTranslation: Component<{ const [ref, bounds] = useMeasure({ debounce: 60 }) if (!nextTarget && source) { - return
{source}
+ return isHTML ? + ( + + {source} + + ) : +
{source}
} return ( - {nextTarget} + {isHTML ? ( + + {nextTarget} + + ) : {nextTarget}} - {source} + {isHTML ? ( + + {source} + + ) : {source}}
) : ( - {source} + isHTML ? + ( + + {source} + + ) : + {source} )} diff --git a/src/renderer/src/modules/entry-column/types.ts b/src/renderer/src/modules/entry-column/types.ts index 659d4c6da..403b39bbe 100644 --- a/src/renderer/src/modules/entry-column/types.ts +++ b/src/renderer/src/modules/entry-column/types.ts @@ -10,6 +10,7 @@ export type UniversalItemProps = { translation?: { title?: string description?: string + content?: string } | null }