mirror of
https://github.com/open-webui/open-webui
synced 2025-06-12 17:33:11 +00:00
feat: preview html
This commit is contained in:
parent
07b5e84221
commit
54dc24986f
@ -4,7 +4,7 @@
|
||||
const i18n = getContext('i18n');
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
import { chatId, settings, showArtifacts, showControls } from '$lib/stores';
|
||||
import { artifactCode, chatId, settings, showArtifacts, showControls } from '$lib/stores';
|
||||
import XMark from '../icons/XMark.svelte';
|
||||
import { copyToClipboard, createMessagesList } from '$lib/utils';
|
||||
import ArrowsPointingOut from '../icons/ArrowsPointingOut.svelte';
|
||||
@ -180,7 +180,14 @@
|
||||
}
|
||||
};
|
||||
|
||||
onMount(() => {});
|
||||
onMount(() => {
|
||||
artifactCode.subscribe((value) => {
|
||||
if (contents) {
|
||||
const codeIdx = contents.findIndex((content) => content.content.includes(value));
|
||||
selectedContentIdx = codeIdx !== -1 ? codeIdx : 0;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class=" w-full h-full relative flex flex-col bg-gray-50 dark:bg-gray-850">
|
||||
|
@ -957,8 +957,6 @@
|
||||
? (e.key === 'Enter' || e.keyCode === 13) && isCtrlPressed
|
||||
: (e.key === 'Enter' || e.keyCode === 13) && !e.shiftKey;
|
||||
|
||||
console.log('Enter pressed:', enterPressed);
|
||||
|
||||
if (enterPressed) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
import ChevronUp from '$lib/components/icons/ChevronUp.svelte';
|
||||
import ChevronUpDown from '$lib/components/icons/ChevronUpDown.svelte';
|
||||
import CommandLine from '$lib/components/icons/CommandLine.svelte';
|
||||
import Cube from '$lib/components/icons/Cube.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
@ -24,9 +25,11 @@
|
||||
|
||||
export let onSave = (e) => {};
|
||||
export let onCode = (e) => {};
|
||||
export let onPreview = (e) => {};
|
||||
|
||||
export let save = false;
|
||||
export let run = true;
|
||||
export let preview = false;
|
||||
export let collapsed = false;
|
||||
|
||||
export let token;
|
||||
@ -88,6 +91,10 @@
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
const previewCode = () => {
|
||||
onPreview(code);
|
||||
};
|
||||
|
||||
const checkPythonCode = (str) => {
|
||||
// Check if the string contains typical Python syntax characters
|
||||
const pythonSyntax = [
|
||||
@ -430,7 +437,7 @@
|
||||
class="flex gap-1 items-center bg-none border-none bg-gray-50 hover:bg-gray-100 dark:bg-gray-850 dark:hover:bg-gray-800 transition rounded-md px-1.5 py-0.5"
|
||||
on:click={collapseCodeBlock}
|
||||
>
|
||||
<div>
|
||||
<div class=" -translate-y-[0.5px]">
|
||||
<ChevronUpDown className="size-3" />
|
||||
</div>
|
||||
|
||||
@ -439,6 +446,21 @@
|
||||
</div>
|
||||
</button>
|
||||
|
||||
{#if preview && ['html', 'svg'].includes(lang)}
|
||||
<button
|
||||
class="flex gap-1 items-center run-code-button bg-none border-none bg-gray-50 hover:bg-gray-100 dark:bg-gray-850 dark:hover:bg-gray-800 transition rounded-md px-1.5 py-0.5"
|
||||
on:click={previewCode}
|
||||
>
|
||||
<div class=" -translate-y-[0.5px]">
|
||||
<Cube className="size-3" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{$i18n.t('Preview')}
|
||||
</div>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
{#if ($config?.features?.enable_code_execution ?? true) && (lang.toLowerCase() === 'python' || lang.toLowerCase() === 'py' || (lang === '' && checkPythonCode(code)))}
|
||||
{#if executing}
|
||||
<div class="run-code-button bg-none border-none p-1 cursor-not-allowed">
|
||||
@ -453,7 +475,7 @@
|
||||
executePython(code);
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<div class=" -translate-y-[0.5px]">
|
||||
<CommandLine className="size-3" />
|
||||
</div>
|
||||
|
||||
|
@ -1,10 +1,17 @@
|
||||
<script>
|
||||
import { onDestroy, onMount, tick, getContext, createEventDispatcher } from 'svelte';
|
||||
import { onDestroy, onMount, tick, getContext } from 'svelte';
|
||||
const i18n = getContext('i18n');
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
import Markdown from './Markdown.svelte';
|
||||
import { chatId, mobile, settings, showArtifacts, showControls, showOverview } from '$lib/stores';
|
||||
import {
|
||||
artifactCode,
|
||||
chatId,
|
||||
mobile,
|
||||
settings,
|
||||
showArtifacts,
|
||||
showControls,
|
||||
showOverview
|
||||
} from '$lib/stores';
|
||||
import FloatingButtons from '../ContentRenderer/FloatingButtons.svelte';
|
||||
import { createMessagesList } from '$lib/utils';
|
||||
|
||||
@ -15,8 +22,10 @@
|
||||
export let sources = null;
|
||||
|
||||
export let save = false;
|
||||
export let preview = false;
|
||||
export let floatingButtons = true;
|
||||
|
||||
export let onUpdate = () => {};
|
||||
export let onSourceClick = () => {};
|
||||
export let onTaskClick = () => {};
|
||||
|
||||
@ -122,6 +131,7 @@
|
||||
{content}
|
||||
{model}
|
||||
{save}
|
||||
{preview}
|
||||
sourceIds={(sources ?? []).reduce((acc, s) => {
|
||||
let ids = [];
|
||||
s.document.forEach((document, index) => {
|
||||
@ -154,8 +164,12 @@
|
||||
}, [])}
|
||||
{onSourceClick}
|
||||
{onTaskClick}
|
||||
onUpdate={(value) => {
|
||||
dispatch('update', value);
|
||||
{onUpdate}
|
||||
onPreview={async (value) => {
|
||||
await artifactCode.set(value);
|
||||
await showControls.set(true);
|
||||
await showArtifacts.set(true);
|
||||
await showOverview.set(false);
|
||||
}}
|
||||
onCode={(value) => {
|
||||
const { lang, code } = value;
|
||||
|
@ -12,11 +12,13 @@
|
||||
export let content;
|
||||
export let model = null;
|
||||
export let save = false;
|
||||
export let preview = false;
|
||||
|
||||
export let sourceIds = [];
|
||||
|
||||
export let onUpdate = () => {};
|
||||
export let onCode = () => {};
|
||||
export let onPreview = () => {};
|
||||
|
||||
export let onSourceClick = () => {};
|
||||
export let onTaskClick = () => {};
|
||||
@ -40,5 +42,15 @@
|
||||
</script>
|
||||
|
||||
{#key id}
|
||||
<MarkdownTokens {tokens} {id} {save} {onTaskClick} {onSourceClick} {onUpdate} {onCode} />
|
||||
<MarkdownTokens
|
||||
{tokens}
|
||||
{id}
|
||||
{save}
|
||||
{preview}
|
||||
{onTaskClick}
|
||||
{onSourceClick}
|
||||
{onUpdate}
|
||||
{onCode}
|
||||
{onPreview}
|
||||
/>
|
||||
{/key}
|
||||
|
@ -29,9 +29,11 @@
|
||||
export let attributes = {};
|
||||
|
||||
export let save = false;
|
||||
export let preview = false;
|
||||
|
||||
export let onUpdate: Function = () => {};
|
||||
export let onCode: Function = () => {};
|
||||
export let onPreview: Function = () => {};
|
||||
|
||||
export let onTaskClick: Function = () => {};
|
||||
export let onSourceClick: Function = () => {};
|
||||
@ -95,7 +97,9 @@
|
||||
code={token?.text ?? ''}
|
||||
{attributes}
|
||||
{save}
|
||||
{preview}
|
||||
{onCode}
|
||||
{onPreview}
|
||||
onSave={(value) => {
|
||||
onUpdate({
|
||||
raw: token.raw,
|
||||
|
@ -806,6 +806,7 @@
|
||||
sources={message.sources}
|
||||
floatingButtons={message?.done && !readOnly}
|
||||
save={!readOnly}
|
||||
preview={!readOnly}
|
||||
{model}
|
||||
onTaskClick={async (e) => {
|
||||
console.log(e);
|
||||
@ -840,28 +841,13 @@
|
||||
onAddMessages={({ modelId, parentId, messages }) => {
|
||||
addMessages({ modelId, parentId, messages });
|
||||
}}
|
||||
on:update={(e) => {
|
||||
const { raw, oldContent, newContent } = e.detail;
|
||||
|
||||
onUpdate={({ raw, oldContent, newContent }) => {
|
||||
history.messages[message.id].content = history.messages[
|
||||
message.id
|
||||
].content.replace(raw, raw.replace(oldContent, newContent));
|
||||
|
||||
updateChat();
|
||||
}}
|
||||
on:select={(e) => {
|
||||
const { type, content } = e.detail;
|
||||
|
||||
if (type === 'explain') {
|
||||
submitMessage(
|
||||
message.id,
|
||||
`Explain this section to me in more detail\n\n\`\`\`\n${content}\n\`\`\``
|
||||
);
|
||||
} else if (type === 'ask') {
|
||||
const input = e.detail?.input ?? '';
|
||||
submitMessage(message.id, `\`\`\`\n${content}\n\`\`\`\n${input}`);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
|
@ -74,6 +74,8 @@ export const showOverview = writable(false);
|
||||
export const showArtifacts = writable(false);
|
||||
export const showCallOverlay = writable(false);
|
||||
|
||||
export const artifactCode = writable(null);
|
||||
|
||||
export const temporaryChatEnabled = writable(false);
|
||||
export const scrollPaginationEnabled = writable(false);
|
||||
export const currentChatPage = writable(1);
|
||||
|
Loading…
Reference in New Issue
Block a user