mirror of
https://github.com/open-webui/open-webui
synced 2025-06-26 18:26:48 +00:00
revert
This commit is contained in:
parent
b414fde6ca
commit
bf6c6627e8
@ -38,6 +38,7 @@
|
|||||||
import Spinner from '$lib/components/common/Spinner.svelte';
|
import Spinner from '$lib/components/common/Spinner.svelte';
|
||||||
import WebSearchResults from './ResponseMessage/WebSearchResults.svelte';
|
import WebSearchResults from './ResponseMessage/WebSearchResults.svelte';
|
||||||
import Sparkles from '$lib/components/icons/Sparkles.svelte';
|
import Sparkles from '$lib/components/icons/Sparkles.svelte';
|
||||||
|
import TokenRenderer from './TokenRenderer.svelte';
|
||||||
|
|
||||||
export let message;
|
export let message;
|
||||||
export let siblings;
|
export let siblings;
|
||||||
@ -80,25 +81,6 @@
|
|||||||
replaceTokens(sanitizeResponseContent(message?.content), model?.name, $user?.name)
|
replaceTokens(sanitizeResponseContent(message?.content), model?.name, $user?.name)
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderer = new marked.Renderer();
|
|
||||||
|
|
||||||
// For code blocks with simple backticks
|
|
||||||
renderer.codespan = (code) => {
|
|
||||||
return `<code>${code.replaceAll('&', '&')}</code>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Open all links in a new tab/window (from https://github.com/markedjs/marked/issues/655#issuecomment-383226346)
|
|
||||||
const origLinkRenderer = renderer.link;
|
|
||||||
renderer.link = (href, title, text) => {
|
|
||||||
const html = origLinkRenderer.call(renderer, href, title, text);
|
|
||||||
return html.replace(/^<a /, '<a target="_blank" rel="nofollow" ');
|
|
||||||
};
|
|
||||||
|
|
||||||
const { extensions, ...defaults } = marked.getDefaults() as marked.MarkedOptions & {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
extensions: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
$: if (message) {
|
$: if (message) {
|
||||||
renderStyling();
|
renderStyling();
|
||||||
}
|
}
|
||||||
@ -417,6 +399,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</Name>
|
</Name>
|
||||||
|
|
||||||
|
<div>
|
||||||
{#if (message?.files ?? []).filter((f) => f.type === 'image').length > 0}
|
{#if (message?.files ?? []).filter((f) => f.type === 'image').length > 0}
|
||||||
<div class="my-2.5 w-full flex overflow-x-auto gap-2 flex-wrap">
|
<div class="my-2.5 w-full flex overflow-x-auto gap-2 flex-wrap">
|
||||||
{#each message.files as file}
|
{#each message.files as file}
|
||||||
@ -517,46 +500,7 @@
|
|||||||
<!-- always show message contents even if there's an error -->
|
<!-- always show message contents even if there's an error -->
|
||||||
<!-- unless message.error === true which is legacy error handling, where the error message is stored in message.content -->
|
<!-- unless message.error === true which is legacy error handling, where the error message is stored in message.content -->
|
||||||
{#each tokens as token, tokenIdx}
|
{#each tokens as token, tokenIdx}
|
||||||
{#if token.type === 'code'}
|
<TokenRenderer {token} {tokenIdx} id={message.id} />
|
||||||
{#if token.lang === 'mermaid'}
|
|
||||||
<pre class="mermaid">{revertSanitizedResponseContent(token.text)}</pre>
|
|
||||||
{:else}
|
|
||||||
<CodeBlock
|
|
||||||
id={`${message.id}-${tokenIdx}`}
|
|
||||||
lang={token?.lang ?? ''}
|
|
||||||
code={revertSanitizedResponseContent(token?.text ?? '')}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
{:else if token.type === 'paragraph'}
|
|
||||||
{#if token.tokens}
|
|
||||||
{#each token.tokens as inlineToken}
|
|
||||||
{#if inlineToken.type === 'image'}
|
|
||||||
<Image src={inlineToken.href} alt={inlineToken.text} />
|
|
||||||
{:else}
|
|
||||||
{@html marked.parse(inlineToken.raw, {
|
|
||||||
...defaults,
|
|
||||||
gfm: true,
|
|
||||||
breaks: true,
|
|
||||||
renderer
|
|
||||||
})}
|
|
||||||
{/if}
|
|
||||||
{/each}
|
|
||||||
{:else}
|
|
||||||
{@html marked.parse(token.raw, {
|
|
||||||
...defaults,
|
|
||||||
gfm: true,
|
|
||||||
breaks: true,
|
|
||||||
renderer
|
|
||||||
})}
|
|
||||||
{/if}
|
|
||||||
{:else}
|
|
||||||
{@html marked.parse(token.raw, {
|
|
||||||
...defaults,
|
|
||||||
gfm: true,
|
|
||||||
breaks: true,
|
|
||||||
renderer
|
|
||||||
})}
|
|
||||||
{/if}
|
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@ -632,7 +576,12 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if !edit}
|
||||||
{#if message.done || siblings.length > 1}
|
{#if message.done || siblings.length > 1}
|
||||||
<div
|
<div
|
||||||
class=" flex justify-start overflow-x-auto buttons text-gray-600 dark:text-gray-500"
|
class=" flex justify-start overflow-x-auto buttons text-gray-600 dark:text-gray-500"
|
||||||
@ -786,12 +735,7 @@
|
|||||||
cx="12"
|
cx="12"
|
||||||
cy="12"
|
cy="12"
|
||||||
r="3"
|
r="3"
|
||||||
/><circle
|
/><circle class="spinner_S1WN spinner_JApP" cx="20" cy="12" r="3" /></svg
|
||||||
class="spinner_S1WN spinner_JApP"
|
|
||||||
cx="20"
|
|
||||||
cy="12"
|
|
||||||
r="3"
|
|
||||||
/></svg
|
|
||||||
>
|
>
|
||||||
{:else if speaking}
|
{:else if speaking}
|
||||||
<svg
|
<svg
|
||||||
@ -867,12 +811,7 @@
|
|||||||
cx="12"
|
cx="12"
|
||||||
cy="12"
|
cy="12"
|
||||||
r="3"
|
r="3"
|
||||||
/><circle
|
/><circle class="spinner_S1WN spinner_JApP" cx="20" cy="12" r="3" /></svg
|
||||||
class="spinner_S1WN spinner_JApP"
|
|
||||||
cx="20"
|
|
||||||
cy="12"
|
|
||||||
r="3"
|
|
||||||
/></svg
|
|
||||||
>
|
>
|
||||||
{:else}
|
{:else}
|
||||||
<svg
|
<svg
|
||||||
@ -1096,12 +1035,10 @@
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{/key}
|
{/key}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
75
src/lib/components/chat/Messages/TokenRenderer.svelte
Normal file
75
src/lib/components/chat/Messages/TokenRenderer.svelte
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { revertSanitizedResponseContent } from '$lib/utils';
|
||||||
|
|
||||||
|
import { marked } from 'marked';
|
||||||
|
import CodeBlock from './CodeBlock.svelte';
|
||||||
|
import Image from '$lib/components/common/Image.svelte';
|
||||||
|
import { stringify } from 'postcss';
|
||||||
|
|
||||||
|
export let token;
|
||||||
|
export let tokenIdx = 0;
|
||||||
|
export let id;
|
||||||
|
|
||||||
|
const renderer = new marked.Renderer();
|
||||||
|
|
||||||
|
// For code blocks with simple backticks
|
||||||
|
renderer.codespan = (code) => {
|
||||||
|
return `<code>${code.replaceAll('&', '&')}</code>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
// renderer.code = (code, lang) => {
|
||||||
|
// const element = document.createElement('div');
|
||||||
|
// new CodeBlock({
|
||||||
|
// target: element,
|
||||||
|
// props: {
|
||||||
|
// id: `${id}-${tokenIdx}`,
|
||||||
|
// lang: lang ?? '',
|
||||||
|
// code: revertSanitizedResponseContent(code ?? '')
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// return element.innerHTML;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// renderer.image = (href, title, text) => {
|
||||||
|
// const element = document.createElement('pre');
|
||||||
|
// new Image({
|
||||||
|
// target: element,
|
||||||
|
// props: {
|
||||||
|
// src: href,
|
||||||
|
// alt: text
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// return element.innerHTML;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Open all links in a new tab/window (from https://github.com/markedjs/marked/issues/655#issuecomment-383226346)
|
||||||
|
const origLinkRenderer = renderer.link;
|
||||||
|
renderer.link = (href, title, text) => {
|
||||||
|
const html = origLinkRenderer.call(renderer, href, title, text);
|
||||||
|
return html.replace(/^<a /, '<a target="_blank" rel="nofollow" ');
|
||||||
|
};
|
||||||
|
|
||||||
|
const { extensions, ...defaults } = marked.getDefaults() as marked.MarkedOptions & {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
extensions: any;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if token.type === 'code'}
|
||||||
|
{#if token.lang === 'mermaid'}
|
||||||
|
<pre class="mermaid">{revertSanitizedResponseContent(token.text)}</pre>
|
||||||
|
{:else}
|
||||||
|
<CodeBlock
|
||||||
|
id={`${id}-${tokenIdx}`}
|
||||||
|
lang={token?.lang ?? ''}
|
||||||
|
code={revertSanitizedResponseContent(token?.text ?? '')}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
{:else}
|
||||||
|
{@html marked.parse(token.raw, {
|
||||||
|
...defaults,
|
||||||
|
gfm: true,
|
||||||
|
breaks: true,
|
||||||
|
renderer
|
||||||
|
})}
|
||||||
|
{/if}
|
@ -12,9 +12,7 @@
|
|||||||
let showImagePreview = false;
|
let showImagePreview = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ImagePreview bind:show={showImagePreview} src={_src} {alt} />
|
<div class="w-full py-3">
|
||||||
|
|
||||||
<div class="w-full">
|
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
showImagePreview = true;
|
showImagePreview = true;
|
||||||
@ -23,3 +21,5 @@
|
|||||||
<img src={_src} {alt} class=" max-h-96 rounded-lg" draggable="false" data-cy="image" />
|
<img src={_src} {alt} class=" max-h-96 rounded-lg" draggable="false" data-cy="image" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<ImagePreview bind:show={showImagePreview} src={_src} {alt} />
|
||||||
|
Loading…
Reference in New Issue
Block a user