Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
open-webui
Commits
e7588555
Commit
e7588555
authored
Jan 22, 2024
by
Timothy J. Baek
Browse files
refac: response message
parent
1abe5a54
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
67 additions
and
72 deletions
+67
-72
src/lib/components/chat/Messages/CodeBlock.svelte
src/lib/components/chat/Messages/CodeBlock.svelte
+36
-0
src/lib/components/chat/Messages/ResponseMessage.svelte
src/lib/components/chat/Messages/ResponseMessage.svelte
+31
-72
No files found.
src/lib/components/chat/Messages/CodeBlock.svelte
0 → 100644
View file @
e7588555
<script lang="ts">
import { copyToClipboard } from '$lib/utils';
import hljs from 'highlight.js';
import 'highlight.js/styles/github-dark.min.css';
export let lang = '';
export let code = '';
let copied = false;
const copyCode = async () => {
copied = true;
await copyToClipboard(code);
setTimeout(() => {
copied = false;
}, 1000);
};
$: highlightedCode = code ? hljs.highlightAuto(code, hljs.getLanguage(lang)?.aliases).value : '';
</script>
<div class="mb-3">
<div
class="flex justify-between bg-[#202123] text-white text-xs px-4 pt-1 rounded-t-lg overflow-x-auto"
>
<div class="p-1">{lang}</div>
<button class="copy-code-button bg-none border-none p-1" on:click={copyCode}
>{copied ? 'Copied' : 'Copy Code'}</button
>
</div>
<pre class=" rounded-b-lg hljs p-4 overflow-x-auto rounded-t-none"><code
class="language-{lang} rounded-t-none whitespace-pre">{@html highlightedCode || code}</code
></pre>
</div>
src/lib/components/chat/Messages/ResponseMessage.svelte
View file @
e7588555
<script lang="ts">
import dayjs from 'dayjs';
import { marked } from 'marked';
import tippy from 'tippy.js';
import
hljs
from
'
highlight.js
'
;
import
'
highlight.js/styles/github-dark.min.css
'
;
import auto_render from 'katex/dist/contrib/auto-render.mjs';
import 'katex/dist/katex.min.css';
import { onMount, tick } from 'svelte';
import Name from './Name.svelte';
import ProfileImage from './ProfileImage.svelte';
import Skeleton from './Skeleton.svelte';
import
{
onMount
,
tick
}
from
'
svelte
'
;
import
CodeBlock from './CodeBlock.
svelte';
export let modelfiles = [];
export let message;
...
...
@@ -33,6 +32,20 @@
let tooltipInstance = null;
let speaking = null;
$: tokens = marked.lexer(message.content);
const renderer = new marked.Renderer();
// For code blocks with simple backticks
renderer.codespan = (code) => {
return `<code>${code.replaceAll('&', '&')}</code>`;
};
const { extensions, ...defaults } = marked.getDefaults() as marked.MarkedOptions & {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
extensions: any;
};
$: if (message) {
renderStyling();
}
...
...
@@ -45,8 +58,6 @@
}
renderLatex();
hljs
.
highlightAll
();
createCopyCodeBlockButton
();
if (message.info) {
tooltipInstance = tippy(`#info-${message.id}`, {
...
...
@@ -78,71 +89,6 @@
}
};
const
createCopyCodeBlockButton
=
()
=>
{
// use a class selector if available
let
blocks
=
document
.
querySelectorAll
(
'
pre
'
);
blocks
.
forEach
((
block
)
=>
{
// only add button if browser supports Clipboard API
if
(
block
.
childNodes
.
length
<
2
&&
block
.
id
!==
'
user-message
'
)
{
let
code
=
block
.
querySelector
(
'
code
'
);
code
.
style
.
borderTopRightRadius
=
0
;
code
.
style
.
borderTopLeftRadius
=
0
;
code
.
style
.
whiteSpace
=
'
pre
'
;
let
topBarDiv
=
document
.
createElement
(
'
div
'
);
topBarDiv
.
style
.
backgroundColor
=
'
#202123
'
;
topBarDiv
.
style
.
overflowX
=
'
auto
'
;
topBarDiv
.
style
.
display
=
'
flex
'
;
topBarDiv
.
style
.
justifyContent
=
'
space-between
'
;
topBarDiv
.
style
.
padding
=
'
0 1rem
'
;
topBarDiv
.
style
.
paddingTop
=
'
4px
'
;
topBarDiv
.
style
.
borderTopRightRadius
=
'
8px
'
;
topBarDiv
.
style
.
borderTopLeftRadius
=
'
8px
'
;
let
langDiv
=
document
.
createElement
(
'
div
'
);
let
codeClassNames
=
code
?.
className
.
split
(
'
'
);
langDiv
.
textContent
=
codeClassNames
[
0
]
===
'
hljs
'
?
codeClassNames
[
1
].
slice
(
9
)
:
codeClassNames
[
0
].
slice
(
9
);
langDiv
.
style
.
color
=
'
white
'
;
langDiv
.
style
.
margin
=
'
4px
'
;
langDiv
.
style
.
fontSize
=
'
0.75rem
'
;
let
button
=
document
.
createElement
(
'
button
'
);
button
.
className
=
'
copy-code-button
'
;
button
.
textContent
=
'
Copy Code
'
;
button
.
style
.
background
=
'
none
'
;
button
.
style
.
fontSize
=
'
0.75rem
'
;
button
.
style
.
border
=
'
none
'
;
button
.
style
.
margin
=
'
4px
'
;
button
.
style
.
cursor
=
'
pointer
'
;
button
.
style
.
color
=
'
#ddd
'
;
button
.
addEventListener
(
'
click
'
,
()
=>
copyCode
(
block
,
button
));
topBarDiv
.
appendChild
(
langDiv
);
topBarDiv
.
appendChild
(
button
);
block
.
prepend
(
topBarDiv
);
}
});
async
function
copyCode
(
block
,
button
)
{
let
code
=
block
.
querySelector
(
'
code
'
);
let
text
=
code
.
innerText
;
await
copyToClipboard
(
text
);
// visual feedback that task is completed
button
.
innerText
=
'
Copied!
'
;
setTimeout
(()
=>
{
button
.
innerText
=
'
Copy Code
'
;
},
1000
);
}
};
const renderLatex = () => {
let chatMessageElements = document.getElementsByClassName('chat-assistant');
// let lastChatMessageElement = chatMessageElements[chatMessageElements.length - 1];
...
...
@@ -292,7 +238,20 @@
</div>
</div>
{:else}
{@html marked(message.content.replaceAll('\\', '\\\\'))}
{#each tokens as token}
{#if token.type === 'code'}
<CodeBlock lang={token.lang} code={token.text} />
{:else}
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
{@html marked.parse(token.raw, {
...defaults,
gfm: true,
breaks: true,
renderer
})}
{/if}
{/each}
<!-- {@html marked(message.content.replaceAll('\\', '\\\\'))} -->
{/if}
{#if message.done}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment