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
b8d153eb
Commit
b8d153eb
authored
Jul 08, 2024
by
Timothy J. Baek
Browse files
feat: chat controls ui
parent
781ad705
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
158 additions
and
66 deletions
+158
-66
src/lib/components/chat/Chat.svelte
src/lib/components/chat/Chat.svelte
+31
-22
src/lib/components/chat/ChatControls.svelte
src/lib/components/chat/ChatControls.svelte
+61
-0
src/lib/components/chat/Controls/Controls.svelte
src/lib/components/chat/Controls/Controls.svelte
+24
-0
src/lib/components/chat/ModelSelector.svelte
src/lib/components/chat/ModelSelector.svelte
+1
-1
src/lib/components/icons/AdjustmentsHorizontal.svelte
src/lib/components/icons/AdjustmentsHorizontal.svelte
+17
-0
src/lib/components/layout/Navbar.svelte
src/lib/components/layout/Navbar.svelte
+19
-1
src/lib/components/layout/Sidebar.svelte
src/lib/components/layout/Sidebar.svelte
+4
-41
src/lib/components/layout/Sidebar/UserMenu.svelte
src/lib/components/layout/Sidebar/UserMenu.svelte
+1
-1
No files found.
src/lib/components/chat/Chat.svelte
View file @
b8d153eb
...
@@ -60,14 +60,15 @@
...
@@ -60,14 +60,15 @@
import Navbar from '$lib/components/layout/Navbar.svelte';
import Navbar from '$lib/components/layout/Navbar.svelte';
import CallOverlay from './MessageInput/CallOverlay.svelte';
import CallOverlay from './MessageInput/CallOverlay.svelte';
import { error } from '@sveltejs/kit';
import { error } from '@sveltejs/kit';
import ChatControls from './ChatControls.svelte';
const i18n: Writable<i18nType> = getContext('i18n');
const i18n: Writable<i18nType> = getContext('i18n');
export let chatIdProp = '';
export let chatIdProp = '';
let loaded = false;
let loaded = false;
const eventTarget = new EventTarget();
const eventTarget = new EventTarget();
let showControls = false;
let stopResponseFlag = false;
let stopResponseFlag = false;
let autoScroll = true;
let autoScroll = true;
let processing = '';
let processing = '';
...
@@ -1424,6 +1425,7 @@
...
@@ -1424,6 +1425,7 @@
{title}
{title}
bind:selectedModels
bind:selectedModels
bind:showModelSelector
bind:showModelSelector
bind:showControls
shareEnabled={messages.length > 0}
shareEnabled={messages.length > 0}
{chat}
{chat}
{initNewChat}
{initNewChat}
...
@@ -1460,7 +1462,9 @@
...
@@ -1460,7 +1462,9 @@
<div class="flex flex-col flex-auto z-10">
<div class="flex flex-col flex-auto z-10">
<div
<div
class=" pb-2.5 flex flex-col justify-between w-full flex-auto overflow-auto h-0 max-w-full z-10"
class=" pb-2.5 flex flex-col justify-between w-full flex-auto overflow-auto h-0 max-w-full z-10 scrollbar-hidden {showControls
? 'lg:pr-[28rem]'
: ''} "
id="messages-container"
id="messages-container"
bind:this={messagesContainerElement}
bind:this={messagesContainerElement}
on:scroll={(e) => {
on:scroll={(e) => {
...
@@ -1485,6 +1489,8 @@
...
@@ -1485,6 +1489,8 @@
/>
/>
</div>
</div>
</div>
</div>
<div class={showControls ? 'lg:pr-[28rem]' : ''}>
<MessageInput
<MessageInput
bind:files
bind:files
bind:prompt
bind:prompt
...
@@ -1507,4 +1513,7 @@
...
@@ -1507,4 +1513,7 @@
/>
/>
</div>
</div>
</div>
</div>
<ChatControls bind:show={showControls} />
</div>
{/if}
{/if}
src/lib/components/chat/ChatControls.svelte
0 → 100644
View file @
b8d153eb
<script lang="ts">
import { slide } from 'svelte/transition';
import Modal from '../common/Modal.svelte';
import Controls from './Controls/Controls.svelte';
import { onMount } from 'svelte';
export let show = false;
let largeScreen = false;
onMount(() => {
// listen to resize 1024px
const mediaQuery = window.matchMedia('(min-width: 1024px)');
const handleMediaQuery = (e) => {
if (e.matches) {
largeScreen = true;
} else {
largeScreen = false;
}
};
mediaQuery.addEventListener('change', handleMediaQuery);
handleMediaQuery(mediaQuery);
return () => {
mediaQuery.removeEventListener('change', handleMediaQuery);
};
});
</script>
{#if largeScreen}
<div
class="fixed h-screen max-h-[100dvh] min-h-screen z-50 top-0 right-0 {show
? 'w-[28rem]'
: 'w-0 translate-x-[28rem] '} transition"
>
<div class="px-6 pt-14 pb-8 h-full">
<div
class=" px-5 py-4 h-full dark:bg-gray-850 border border-gray-100 dark:border-gray-800 rounded-xl shadow-lg"
>
<Controls
on:close={() => {
show = false;
}}
/>
</div>
</div>
</div>
{:else}
<Modal bind:show>
<div class=" px-5 py-4 h-full">
<Controls
on:close={() => {
show = false;
}}
/>
</div>
</Modal>
{/if}
src/lib/components/chat/Controls/Controls.svelte
0 → 100644
View file @
b8d153eb
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
import XMark from '$lib/components/icons/XMark.svelte';
</script>
<div class=" dark:text-white">
<div class="mb-2 flex justify-between items-center">
<div class=" text-xl font-medium font-primary">Chat Controls</div>
<div>
<button
on:click={() => {
dispatch('close');
}}
>
<XMark className="size-4" />
</button>
</div>
</div>
<div>coming soon</div>
</div>
src/lib/components/chat/ModelSelector.svelte
View file @
b8d153eb
...
@@ -34,7 +34,7 @@
...
@@ -34,7 +34,7 @@
}
}
</script>
</script>
<div class="flex flex-col w-full
items-center md:
items-start">
<div class="flex flex-col w-full items-start">
{#each selectedModels as selectedModel, selectedModelIdx}
{#each selectedModels as selectedModel, selectedModelIdx}
<div class="flex w-full max-w-fit">
<div class="flex w-full max-w-fit">
<div class="overflow-hidden w-full">
<div class="overflow-hidden w-full">
...
...
src/lib/components/icons/AdjustmentsHorizontal.svelte
0 → 100644
View file @
b8d153eb
<script lang="ts">
export let className = 'w-4 h-4';
export let strokeWidth = '1.5';
</script>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
stroke="currentColor"
fill="currentColor"
class={className}
stroke-width={strokeWidth}
>
<path
d="M18.75 12.75h1.5a.75.75 0 0 0 0-1.5h-1.5a.75.75 0 0 0 0 1.5ZM12 6a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 12 6ZM12 18a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 12 18ZM3.75 6.75h1.5a.75.75 0 1 0 0-1.5h-1.5a.75.75 0 0 0 0 1.5ZM5.25 18.75h-1.5a.75.75 0 0 1 0-1.5h1.5a.75.75 0 0 1 0 1.5ZM3 12a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 3 12ZM9 3.75a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5ZM12.75 12a2.25 2.25 0 1 1 4.5 0 2.25 2.25 0 0 1-4.5 0ZM9 15.75a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5Z"
/>
</svg>
src/lib/components/layout/Navbar.svelte
View file @
b8d153eb
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
import { page } from '$app/stores';
import { page } from '$app/stores';
import UserMenu from './Sidebar/UserMenu.svelte';
import UserMenu from './Sidebar/UserMenu.svelte';
import MenuLines from '../icons/MenuLines.svelte';
import MenuLines from '../icons/MenuLines.svelte';
import AdjustmentsHorizontal from '../icons/AdjustmentsHorizontal.svelte';
const i18n = getContext('i18n');
const i18n = getContext('i18n');
...
@@ -32,6 +33,7 @@
...
@@ -32,6 +33,7 @@
export let selectedModels;
export let selectedModels;
export let showModelSelector = true;
export let showModelSelector = true;
export let showControls = false;
let showShareChatModal = false;
let showShareChatModal = false;
let showDownloadChatModal = false;
let showDownloadChatModal = false;
...
@@ -58,6 +60,7 @@
...
@@ -58,6 +60,7 @@
</div>
</div>
</button>
</button>
</div>
</div>
<div class="flex-1 overflow-hidden max-w-full">
<div class="flex-1 overflow-hidden max-w-full">
{#if showModelSelector}
{#if showModelSelector}
<ModelSelector bind:selectedModels showSetDefault={!shareEnabled} />
<ModelSelector bind:selectedModels showSetDefault={!shareEnabled} />
...
@@ -101,12 +104,27 @@
...
@@ -101,12 +104,27 @@
</button>
</button>
</Menu>
</Menu>
{/if}
{/if}
<Tooltip content={$i18n.t('Controls')}>
<button
id="new-chat-button"
class=" flex cursor-pointer px-2 py-2 rounded-xl hover:bg-gray-100 dark:hover:bg-gray-850 transition"
on:click={() => {
showControls = !showControls;
}}
>
<div class=" m-auto self-center">
<AdjustmentsHorizontal className=" size-5" strokeWidth="0.5" />
</div>
</button>
</Tooltip>
<Tooltip content={$i18n.t('New Chat')}>
<Tooltip content={$i18n.t('New Chat')}>
<button
<button
id="new-chat-button"
id="new-chat-button"
class=" flex {$showSidebar
class=" flex {$showSidebar
? 'md:hidden'
? 'md:hidden'
: ''} cursor-pointer px-2 py-2 rounded-xl hover:bg-gray-100 dark:hover:bg-gray-850 transition"
: ''} cursor-pointer px-2 py-2 rounded-xl
text-gray-600 dark:text-gray-400
hover:bg-gray-100 dark:hover:bg-gray-850 transition"
on:click={() => {
on:click={() => {
initNewChat();
initNewChat();
}}
}}
...
...
src/lib/components/layout/Sidebar.svelte
View file @
b8d153eb
...
@@ -261,7 +261,7 @@
...
@@ -261,7 +261,7 @@
alt="logo"
alt="logo"
/>
/>
</div>
</div>
<div class=" self-center font-medium text-sm text-gray-850 dark:text-white">
<div class=" self-center font-medium text-sm text-gray-850 dark:text-white
font-primary
">
{$i18n.t('New Chat')}
{$i18n.t('New Chat')}
</div>
</div>
<div class="self-center ml-auto">
<div class="self-center ml-auto">
...
@@ -339,7 +339,7 @@
...
@@ -339,7 +339,7 @@
</div>
</div>
<div class="flex self-center">
<div class="flex self-center">
<div class=" self-center font-medium text-sm">{$i18n.t('Workspace')}</div>
<div class=" self-center font-medium text-sm
font-primary
">{$i18n.t('Workspace')}</div>
</div>
</div>
</a>
</a>
</div>
</div>
...
@@ -533,7 +533,7 @@
...
@@ -533,7 +533,7 @@
<div class="px-2.5">
<div class="px-2.5">
<!-- <hr class=" border-gray-900 mb-1 w-full" /> -->
<!-- <hr class=" border-gray-900 mb-1 w-full" /> -->
<div class="flex flex-col">
<div class="flex flex-col
font-primary
">
{#if $user !== undefined}
{#if $user !== undefined}
<UserMenu
<UserMenu
role={$user.role}
role={$user.role}
...
@@ -556,50 +556,13 @@
...
@@ -556,50 +556,13 @@
alt="User profile"
alt="User profile"
/>
/>
</div>
</div>
<div class=" self-center font-
semibold
">{$user.name}</div>
<div class=" self-center font-
medium
">{$user.name}</div>
</button>
</button>
</UserMenu>
</UserMenu>
{/if}
{/if}
</div>
</div>
</div>
</div>
</div>
</div>
<!-- <div
id="sidebar-handle"
class=" hidden md:fixed left-0 top-[50dvh] -translate-y-1/2 transition-transform translate-x-[255px] md:translate-x-[260px] rotate-0"
>
<Tooltip
placement="right"
content={`${$showSidebar ? $i18n.t('Close') : $i18n.t('Open')} ${$i18n.t('sidebar')}`}
touch={false}
>
<button
id="sidebar-toggle-button"
class=" group"
on:click={() => {
showSidebar.set(!$showSidebar);
}}
><span class="" data-state="closed"
><div
class="flex h-[72px] w-8 items-center justify-center opacity-50 group-hover:opacity-100 transition"
>
<div class="flex h-6 w-6 flex-col items-center">
<div
class="h-3 w-1 rounded-full bg-[#0f0f0f] dark:bg-white rotate-0 translate-y-[0.15rem] {$showSidebar
? 'group-hover:rotate-[15deg]'
: 'group-hover:rotate-[-15deg]'}"
/>
<div
class="h-3 w-1 rounded-full bg-[#0f0f0f] dark:bg-white rotate-0 translate-y-[-0.15rem] {$showSidebar
? 'group-hover:rotate-[-15deg]'
: 'group-hover:rotate-[15deg]'}"
/>
</div>
</div>
</span>
</button>
</Tooltip>
</div> -->
</div>
</div>
<style>
<style>
...
...
src/lib/components/layout/Sidebar/UserMenu.svelte
View file @
b8d153eb
...
@@ -30,7 +30,7 @@
...
@@ -30,7 +30,7 @@
<slot name="content">
<slot name="content">
<DropdownMenu.Content
<DropdownMenu.Content
class="w-full {className} text-sm rounded-xl px-1 py-1.5 border border-gray-300/30 dark:border-gray-700/50 z-50 bg-white dark:bg-gray-850 dark:text-white shadow"
class="w-full {className} text-sm rounded-xl px-1 py-1.5 border border-gray-300/30 dark:border-gray-700/50 z-50 bg-white dark:bg-gray-850 dark:text-white shadow
font-primary
"
sideOffset={8}
sideOffset={8}
side="bottom"
side="bottom"
align="start"
align="start"
...
...
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