summaryrefslogtreecommitdiffhomepage
path: root/src/features/markdown/ui
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-10-19 23:48:50 +0900
committerAdam Malczewski <[email protected]>2026-10-19 23:48:50 +0900
commitaa63d6b9f4cb14535fd0191ab358c27f0ee62ce8 (patch)
treed089ad4db3522d5ba8338f6badd4f78ab24fbd7f /src/features/markdown/ui
parent6122a90cf0c9f938945e684e19e74153b38e7b4b (diff)
downloaddispatch-web-aa63d6b9f4cb14535fd0191ab358c27f0ee62ce8.tar.gz
dispatch-web-aa63d6b9f4cb14535fd0191ab358c27f0ee62ce8.zip
feat(markdown): render local-path images inline via backend image route
Diffstat (limited to 'src/features/markdown/ui')
-rw-r--r--src/features/markdown/ui/Markdown.svelte19
1 files changed, 16 insertions, 3 deletions
diff --git a/src/features/markdown/ui/Markdown.svelte b/src/features/markdown/ui/Markdown.svelte
index da2c9ba..0adbbea 100644
--- a/src/features/markdown/ui/Markdown.svelte
+++ b/src/features/markdown/ui/Markdown.svelte
@@ -1,16 +1,29 @@
<script lang="ts">
- import { renderMarkdown } from "../logic/markdown";
+ import { type MarkdownImageOptions, renderMarkdown } from "../logic/markdown";
import { advance, createStreamingMarkdown } from "../logic/streaming-markdown";
let {
text,
streaming = false,
+ image = undefined,
}: {
text: string;
/** Balance dangling delimiters while the message is still generating. */
streaming?: boolean;
+ /**
+ * Per-conversation local-image context: the backend HTTP base and the
+ * conversation cwd. Markdown image srcs that are local paths are rewritten
+ * through `${apiBase}/local-image?path=…` (relative paths resolve against
+ * `cwd`); remote/data URLs are untouched. Omit it to render srcs as-is.
+ */
+ image?: MarkdownImageOptions;
} = $props();
+ // Keep the optional `image` out of the options object when absent
+ // (exactOptionalPropertyTypes). Identity is irrelevant: the streaming cache
+ // keys on apiBase/cwd values.
+ const renderOpts = $derived(image === undefined ? undefined : { image });
+
// Checkpoint streaming state: one per component instance (per streaming
// message). It caches the settled blocks' HTML so each delta re-renders only
// the live tail — never the settled prefix (see logic/streaming-markdown).
@@ -22,8 +35,8 @@
// chunk): ONE full authoritative render — today's exact behavior, so the
// final/persisted output is byte-identical by construction.
const rendered = $derived.by(() => {
- if (!streaming) return { prefixHtml: "", tailHtml: renderMarkdown(text) };
- return advance(streamingState, text);
+ if (!streaming) return { prefixHtml: "", tailHtml: renderMarkdown(text, renderOpts) };
+ return advance(streamingState, text, renderOpts);
});
let container: HTMLElement;