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
9b12cdcf
Commit
9b12cdcf
authored
Dec 13, 2023
by
Timothy J. Baek
Browse files
feat: image upload support
parent
fb1f8b16
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
84 additions
and
57 deletions
+84
-57
src/lib/components/chat/MessageInput.svelte
src/lib/components/chat/MessageInput.svelte
+32
-31
src/lib/components/chat/Messages.svelte
src/lib/components/chat/Messages.svelte
+26
-12
src/routes/(app)/+page.svelte
src/routes/(app)/+page.svelte
+15
-2
src/routes/(app)/c/[id]/+page.svelte
src/routes/(app)/c/[id]/+page.svelte
+11
-12
No files found.
src/lib/components/chat/MessageInput.svelte
View file @
9b12cdcf
...
...
@@ -14,7 +14,7 @@
export let files = [];
export let fileUploadEnabled =
fals
e;
export let fileUploadEnabled =
tru
e;
export let speechRecognitionEnabled = true;
export let speechRecognitionListening = false;
...
...
@@ -84,40 +84,40 @@
};
</script>
<div class="fixed bottom-0 w-full
bg-white dark:bg-gray-800
">
<div class="
absolute right-0 left-0 bottom-0 mb-20
">
<div class="max-w-3xl px-2.5 pt-2.5 -mb-0.5 mx-auto inset-x-0">
{#if messages.length == 0 && suggestionPrompts.length !== 0}
<div class="fixed bottom-0 w-full">
<div class="
px-2.5 pt-2.5 -mb-0.5 mx-auto inset-x-0 bg-transparent flex justify-center
">
{#if messages.length == 0 && suggestionPrompts.length !== 0}
<div class="max-w-3xl">
<Suggestions {suggestionPrompts} {submitPrompt} />
{/if}
</div>
{/if}
{#if autoScroll === false && messages.length > 0}
<div class=" flex justify-center mb-4">
<button
class=" bg-white border border-gray-100 dark:border-none dark:bg-white/20 p-1.5 rounded-full"
on:click={() => {
autoScroll = true;
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
}}
{#if autoScroll === false && messages.length > 0}
<div class=" flex justify-center mb-4">
<button
class=" bg-white border border-gray-100 dark:border-none dark:bg-white/20 p-1.5 rounded-full"
on:click={() => {
autoScroll = true;
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-5 h-5"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-5 h-5"
>
<path
fill-rule="evenodd"
d="M10 3a.75.75 0 01.75.75v10.638l3.96-4.158a.75.75 0 111.08 1.04l-5.25 5.5a.75.75 0 01-1.08 0l-5.25-5.5a.75.75 0 111.08-1.04l3.96 4.158V3.75A.75.75 0 0110 3z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
{/if}
</div>
<path
fill-rule="evenodd"
d="M10 3a.75.75 0 01.75.75v10.638l3.96-4.158a.75.75 0 111.08 1.04l-5.25 5.5a.75.75 0 01-1.08 0l-5.25-5.5a.75.75 0 111.08-1.04l3.96 4.158V3.75A.75.75 0 0110 3z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
{/if}
</div>
<div>
<div
class="bg-white dark:bg-gray-800"
>
<div class="max-w-3xl px-2.5 -mb-0.5 mx-auto inset-x-0">
<div class="bg-gradient-to-t from-white dark:from-gray-800 from-40% pb-2">
<input
...
...
@@ -136,6 +136,7 @@
}
];
inputFiles = null;
filesInputElement.value = '';
};
if (
...
...
src/lib/components/chat/Messages.svelte
View file @
9b12cdcf
...
...
@@ -15,6 +15,7 @@
export
let
sendPrompt
:
Function
;
export
let
regenerateResponse
:
Function
;
export
let
bottomPadding
=
false
;
export
let
autoScroll
;
export
let
selectedModels
;
export
let
history
=
{};
...
...
@@ -31,6 +32,13 @@
})();
}
$
:
if
(
autoScroll
&&
bottomPadding
)
{
(
async
()
=>
{
await
tick
();
window
.
scrollTo
({
top
:
document
.
body
.
scrollHeight
,
behavior
:
'
smooth
'
});
})();
}
const
speakMessage
=
(
message
)
=>
{
const
speak
=
new
SpeechSynthesisUtterance
(
message
);
speechSynthesis
.
speak
(
speak
);
...
...
@@ -184,7 +192,8 @@
parentId
:
history
.
messages
[
messageId
].
parentId
,
childrenIds
:
[],
role
:
'
user
'
,
content
:
userPrompt
content
:
userPrompt
,
...(
history
.
messages
[
messageId
].
files
&&
{
files
:
history
.
messages
[
messageId
].
files
})
};
let
messageParentId
=
history
.
messages
[
messageId
].
parentId
;
...
...
@@ -425,6 +434,18 @@
class=
"prose chat-{message.role} w-full max-w-full dark:prose-invert prose-headings:my-0 prose-p:my-0 prose-p:-mb-4 prose-pre:my-0 prose-table:my-0 prose-blockquote:my-0 prose-img:my-0 prose-ul:-my-4 prose-ol:-my-4 prose-li:-my-3 prose-ul:-mb-6 prose-ol:-mb-6 prose-li:-mb-4 whitespace-pre-line"
>
{#if message.role == 'user'}
{#if message.files}
<div
class=
"my-3 w-full flex overflow-x-auto space-x-2"
>
{#each message.files as file}
<div>
{#if file.type === 'image'}
<img
src=
{file.url}
alt=
"input"
class=
" max-h-96 rounded-lg"
/>
{/if}
</div>
{/each}
</div>
{/if}
{#if message?.edit === true}
<div
class=
" w-full"
>
<textarea
...
...
@@ -458,17 +479,6 @@
</div>
{:else}
<div
class=
"w-full"
>
{#if message.files}
<div
class=
"my-3"
>
{#each message.files as file}
<div>
{#if file.type === 'image'}
<img
src=
{file.url}
alt=
"input"
class=
" max-h-96"
/>
{/if}
</div>
{/each}
</div>
{/if}
<pre
id=
"user-message"
>
{message.content}
</pre>
<div
class=
" flex justify-start space-x-1"
>
...
...
@@ -889,4 +899,8 @@
</div>
</div>
{/each}
{#if bottomPadding}
<div
class=
" mb-10"
/>
{/if}
{/if}
src/routes/(app)/+page.svelte
View file @
9b12cdcf
...
...
@@ -50,6 +50,10 @@
messages = [];
}
$: if (files) {
console.log(files);
}
onMount(async () => {
await chatId.set(uuidv4());
...
...
@@ -146,7 +150,15 @@
...messages
]
.filter((message) => message)
.map((message) => ({ role: message.role, content: message.content })),
.map((message) => ({
role: message.role,
content: message.content,
...(message.files && {
images: message.files
.filter((file) => file.type === 'image')
.map((file) => file.url.slice(file.url.indexOf(',') + 1))
})
})),
options: {
seed: $settings.seed ?? undefined,
temperature: $settings.temperature ?? undefined,
...
...
@@ -548,6 +560,7 @@
bind:history
bind:messages
bind:autoScroll
bottomPadding={files.length > 0}
{sendPrompt}
{regenerateResponse}
/>
...
...
@@ -555,8 +568,8 @@
</div>
<MessageInput
bind:prompt
bind:files
bind:prompt
bind:autoScroll
suggestionPrompts={selectedModelfile?.suggestionPrompts ?? [
{
...
...
src/routes/(app)/c/[id]/+page.svelte
View file @
9b12cdcf
...
...
@@ -51,17 +51,6 @@
messages = [];
}
// onMount(async () => {
// let chat = await loadChat();
// await tick();
// if (chat) {
// loaded = true;
// } else {
// await goto('/');
// }
// });
$: if ($page.params.id) {
(async () => {
let chat = await loadChat();
...
...
@@ -173,7 +162,15 @@
...messages
]
.filter((message) => message)
.map((message) => ({ role: message.role, content: message.content })),
.map((message) => ({
role: message.role,
content: message.content,
...(message.files && {
images: message.files
.filter((file) => file.type === 'image')
.map((file) => file.url.slice(file.url.indexOf(',') + 1))
})
})),
options: {
seed: $settings.seed ?? undefined,
temperature: $settings.temperature ?? undefined,
...
...
@@ -579,6 +576,7 @@
bind:history
bind:messages
bind:autoScroll
bottomPadding={files.length > 0}
{sendPrompt}
{regenerateResponse}
/>
...
...
@@ -586,6 +584,7 @@
</div>
<MessageInput
bind:files
bind:prompt
bind:autoScroll
suggestionPrompts={selectedModelfile?.suggestionPrompts ?? [
...
...
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