diff --git a/apps/renderer/src/components/ui/markdown/Markdown.tsx b/apps/renderer/src/components/ui/markdown/Markdown.tsx index 881bf3b08..3c464c093 100644 --- a/apps/renderer/src/components/ui/markdown/Markdown.tsx +++ b/apps/renderer/src/components/ui/markdown/Markdown.tsx @@ -1,5 +1,6 @@ import { createElement, Fragment, memo, useEffect, useMemo, useState } from "react" +import type { MediaInfo } from "~/lib/parse-html" import { parseHtml } from "~/lib/parse-html" import type { RemarkOptions } from "~/lib/parse-markdown" import { parseMarkdown } from "~/lib/parse-markdown" @@ -42,15 +43,17 @@ const HTMLImpl = ( accessory?: React.ReactNode noMedia?: boolean + mediaInfo?: MediaInfo } & JSX.IntrinsicElements[A] & Partial<{ renderInlineStyle: boolean }>, ) => { - const { children, renderInlineStyle, as = "div", accessory, noMedia, ...rest } = props + const { children, renderInlineStyle, as = "div", accessory, noMedia, mediaInfo, ...rest } = props const [remarkOptions, setRemarkOptions] = useState({ renderInlineStyle, noMedia, + mediaInfo, }) const [shouldForceReMountKey, setShouldForceReMountKey] = useState(0) diff --git a/apps/renderer/src/components/ui/markdown/renderers/BlockImage.tsx b/apps/renderer/src/components/ui/markdown/renderers/BlockImage.tsx index 804789149..157cd2659 100644 --- a/apps/renderer/src/components/ui/markdown/renderers/BlockImage.tsx +++ b/apps/renderer/src/components/ui/markdown/renderers/BlockImage.tsx @@ -23,7 +23,7 @@ export const MarkdownBlockImage = ( )} showFallback popper - className="inline-flex justify-center" + className="flex justify-center" /> ) } diff --git a/apps/renderer/src/components/ui/media.tsx b/apps/renderer/src/components/ui/media.tsx index 8dcd4c7a5..db7ec6474 100644 --- a/apps/renderer/src/components/ui/media.tsx +++ b/apps/renderer/src/components/ui/media.tsx @@ -152,9 +152,11 @@ const MediaImpl: FC = ({ mediaLoadState, popper, previewImageUrl, - props, + props.height, + props.width, rest, src, + thumbnail, type, ]) diff --git a/apps/renderer/src/lib/parse-html.ts b/apps/renderer/src/lib/parse-html.ts index 641794d13..953882faf 100644 --- a/apps/renderer/src/lib/parse-html.ts +++ b/apps/renderer/src/lib/parse-html.ts @@ -23,11 +23,22 @@ import { BlockError } from "~/components/ui/markdown/renderers/BlockErrorBoundar import { createHeadingRenderer } from "~/components/ui/markdown/renderers/Heading" import { Media } from "~/components/ui/media" +function markInlineImage(node?: Element) { + for (const item of node?.children ?? []) { + if (item.type === "element" && item.tagName === "img") { + ;(item.properties as any).inline = true + } + } +} + +export type MediaInfo = Record + export const parseHtml = ( content: string, options?: Partial<{ renderInlineStyle: boolean noMedia?: boolean + mediaInfo?: MediaInfo }>, ) => { const file = new VFile(content) @@ -84,8 +95,17 @@ export const parseHtml = ( jsxs: (type, props, key) => jsxs(type as any, props, key), passNode: true, components: { - a: ({ node, ...props }) => createElement(MarkdownLink, { ...props } as any), - img: Img, + a: ({ node, ...props }) => { + markInlineImage(node) + return createElement(MarkdownLink, { ...props } as any) + }, + img: ({ ...props }) => { + return createElement(Img, { + ...props, + width: props.src ? options?.mediaInfo?.[props.src]?.width : props.width, + height: props.src ? options?.mediaInfo?.[props.src]?.height : props.height, + }) + }, h1: createHeadingRenderer(1), h2: createHeadingRenderer(2), @@ -107,6 +127,10 @@ export const parseHtml = ( } return createElement(MarkdownP, props, props.children) }, + span: ({ node, ...props }) => { + markInlineImage(node) + return createElement("span", props, props.children) + }, hr: ({ node, ...props }) => createElement("hr", { ...props, @@ -195,7 +219,7 @@ const Img: Components["img"] = ({ node, ...props }) => { type: "photo", ...nextProps, - mediaContainerClassName: tw`max-w-full inline size-auto`, + mediaContainerClassName: tw`max-w-full inline rounded-md`, popper: true, className: tw`inline`, showFallback: true, diff --git a/apps/renderer/src/modules/entry-content/index.tsx b/apps/renderer/src/modules/entry-content/index.tsx index c7376142c..017dd0351 100644 --- a/apps/renderer/src/modules/entry-content/index.tsx +++ b/apps/renderer/src/modules/entry-content/index.tsx @@ -148,6 +148,17 @@ export const EntryContentRender: Component<{ if (!entry) return null const content = entry?.entries.content ?? data?.entries.content + const mediaInfo = Object.fromEntries( + (entry.entries.media ?? data?.entries.media) + ?.filter((m) => m.type === "photo") + .map((cur) => [ + cur.url, + { + width: cur.width, + height: cur.height, + }, + ]) ?? [], + ) return (