mirror of
https://git.mirrors.martin98.com/https://github.com/open-webui/open-webui
synced 2025-08-20 19:29:06 +08:00
enh: chat landing ui option
This commit is contained in:
parent
5f74cfaa51
commit
8ad44cd690
@ -70,7 +70,7 @@
|
|||||||
import Navbar from '$lib/components/layout/Navbar.svelte';
|
import Navbar from '$lib/components/layout/Navbar.svelte';
|
||||||
import ChatControls from './ChatControls.svelte';
|
import ChatControls from './ChatControls.svelte';
|
||||||
import EventConfirmDialog from '../common/ConfirmDialog.svelte';
|
import EventConfirmDialog from '../common/ConfirmDialog.svelte';
|
||||||
import Placeholder from './Messages/Placeholder.svelte';
|
import Placeholder from './Placeholder.svelte';
|
||||||
|
|
||||||
export let chatIdProp = '';
|
export let chatIdProp = '';
|
||||||
|
|
||||||
@ -1954,7 +1954,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="flex flex-col flex-auto z-10 w-full">
|
<div class="flex flex-col flex-auto z-10 w-full">
|
||||||
{#if history.currentId}
|
{#if $settings?.landingPageMode === 'chat' || createMessagesList(history.currentId).length > 0}
|
||||||
<div
|
<div
|
||||||
class=" pb-2.5 flex flex-col justify-between w-full flex-auto overflow-auto h-0 max-w-full z-10 scrollbar-hidden"
|
class=" pb-2.5 flex flex-col justify-between w-full flex-auto overflow-auto h-0 max-w-full z-10 scrollbar-hidden"
|
||||||
id="messages-container"
|
id="messages-container"
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
import { blur, fade } from 'svelte/transition';
|
import { blur, fade } from 'svelte/transition';
|
||||||
|
|
||||||
import Suggestions from '../MessageInput/Suggestions.svelte';
|
import Suggestions from './Suggestions.svelte';
|
||||||
import { sanitizeResponseContent } from '$lib/utils';
|
import { sanitizeResponseContent } from '$lib/utils';
|
||||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
import EyeSlash from '$lib/components/icons/EyeSlash.svelte';
|
import EyeSlash from '$lib/components/icons/EyeSlash.svelte';
|
||||||
@ -128,7 +128,9 @@
|
|||||||
suggestionPrompts={models[selectedModelIdx]?.info?.meta?.suggestion_prompts ??
|
suggestionPrompts={models[selectedModelIdx]?.info?.meta?.suggestion_prompts ??
|
||||||
$config?.default_prompt_suggestions ??
|
$config?.default_prompt_suggestions ??
|
||||||
[]}
|
[]}
|
||||||
{submitPrompt}
|
on:select={(e) => {
|
||||||
|
submitPrompt(e.detail);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -8,11 +8,12 @@
|
|||||||
import { getChatList, updateChatById } from '$lib/apis/chats';
|
import { getChatList, updateChatById } from '$lib/apis/chats';
|
||||||
import { copyToClipboard, findWordIndices } from '$lib/utils';
|
import { copyToClipboard, findWordIndices } from '$lib/utils';
|
||||||
|
|
||||||
import Placeholder from './Messages/Placeholder.svelte';
|
|
||||||
import Message from './Messages/Message.svelte';
|
import Message from './Messages/Message.svelte';
|
||||||
import Loader from '../common/Loader.svelte';
|
import Loader from '../common/Loader.svelte';
|
||||||
import Spinner from '../common/Spinner.svelte';
|
import Spinner from '../common/Spinner.svelte';
|
||||||
|
|
||||||
|
import ChatPlaceholder from './ChatPlaceholder.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
export let chatId = '';
|
export let chatId = '';
|
||||||
@ -311,7 +312,43 @@
|
|||||||
|
|
||||||
<div class="h-full flex pt-8">
|
<div class="h-full flex pt-8">
|
||||||
{#if Object.keys(history?.messages ?? {}).length == 0}
|
{#if Object.keys(history?.messages ?? {}).length == 0}
|
||||||
<Placeholder {selectedModels} bind:prompt />
|
<ChatPlaceholder
|
||||||
|
modelIds={selectedModels}
|
||||||
|
submitPrompt={async (p) => {
|
||||||
|
let text = p;
|
||||||
|
|
||||||
|
if (p.includes('{{CLIPBOARD}}')) {
|
||||||
|
const clipboardText = await navigator.clipboard.readText().catch((err) => {
|
||||||
|
toast.error($i18n.t('Failed to read clipboard contents'));
|
||||||
|
return '{{CLIPBOARD}}';
|
||||||
|
});
|
||||||
|
|
||||||
|
text = p.replaceAll('{{CLIPBOARD}}', clipboardText);
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt = text;
|
||||||
|
|
||||||
|
await tick();
|
||||||
|
|
||||||
|
const chatInputElement = document.getElementById('chat-textarea');
|
||||||
|
if (chatInputElement) {
|
||||||
|
prompt = p;
|
||||||
|
|
||||||
|
chatInputElement.style.height = '';
|
||||||
|
chatInputElement.style.height = Math.min(chatInputElement.scrollHeight, 200) + 'px';
|
||||||
|
chatInputElement.focus();
|
||||||
|
|
||||||
|
const words = findWordIndices(prompt);
|
||||||
|
|
||||||
|
if (words.length > 0) {
|
||||||
|
const word = words.at(0);
|
||||||
|
chatInputElement.setSelectionRange(word?.startIndex, word.endIndex + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await tick();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="w-full pt-2">
|
<div class="w-full pt-2">
|
||||||
{#key chatId}
|
{#key chatId}
|
||||||
|
@ -11,10 +11,10 @@
|
|||||||
import { sanitizeResponseContent, findWordIndices } from '$lib/utils';
|
import { sanitizeResponseContent, findWordIndices } from '$lib/utils';
|
||||||
import { WEBUI_BASE_URL } from '$lib/constants';
|
import { WEBUI_BASE_URL } from '$lib/constants';
|
||||||
|
|
||||||
import Suggestions from '../MessageInput/Suggestions.svelte';
|
import Suggestions from './Suggestions.svelte';
|
||||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
import EyeSlash from '$lib/components/icons/EyeSlash.svelte';
|
import EyeSlash from '$lib/components/icons/EyeSlash.svelte';
|
||||||
import MessageInput from '../MessageInput.svelte';
|
import MessageInput from './MessageInput.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
@ -29,6 +29,7 @@
|
|||||||
let defaultModelId = '';
|
let defaultModelId = '';
|
||||||
let showUsername = false;
|
let showUsername = false;
|
||||||
|
|
||||||
|
let landingPageMode = '';
|
||||||
let chatBubble = true;
|
let chatBubble = true;
|
||||||
let chatDirection: 'LTR' | 'RTL' = 'LTR';
|
let chatDirection: 'LTR' | 'RTL' = 'LTR';
|
||||||
|
|
||||||
@ -56,6 +57,11 @@
|
|||||||
saveSettings({ chatBubble: chatBubble });
|
saveSettings({ chatBubble: chatBubble });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toggleLandingPageMode = async () => {
|
||||||
|
landingPageMode = landingPageMode === '' ? 'chat' : '';
|
||||||
|
saveSettings({ landingPageMode: landingPageMode });
|
||||||
|
};
|
||||||
|
|
||||||
const toggleShowUsername = async () => {
|
const toggleShowUsername = async () => {
|
||||||
showUsername = !showUsername;
|
showUsername = !showUsername;
|
||||||
saveSettings({ showUsername: showUsername });
|
saveSettings({ showUsername: showUsername });
|
||||||
@ -150,6 +156,7 @@
|
|||||||
showEmojiInCall = $settings.showEmojiInCall ?? false;
|
showEmojiInCall = $settings.showEmojiInCall ?? false;
|
||||||
voiceInterruption = $settings.voiceInterruption ?? false;
|
voiceInterruption = $settings.voiceInterruption ?? false;
|
||||||
|
|
||||||
|
landingPageMode = $settings.landingPageMode ?? '';
|
||||||
chatBubble = $settings.chatBubble ?? true;
|
chatBubble = $settings.chatBubble ?? true;
|
||||||
widescreenMode = $settings.widescreenMode ?? false;
|
widescreenMode = $settings.widescreenMode ?? false;
|
||||||
splitLargeChunks = $settings.splitLargeChunks ?? false;
|
splitLargeChunks = $settings.splitLargeChunks ?? false;
|
||||||
@ -229,6 +236,26 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class=" mb-1.5 text-sm font-medium">{$i18n.t('UI')}</div>
|
<div class=" mb-1.5 text-sm font-medium">{$i18n.t('UI')}</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class=" py-0.5 flex w-full justify-between">
|
||||||
|
<div class=" self-center text-xs">{$i18n.t('Landing Page Mode')}</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="p-1 px-3 text-xs flex rounded transition"
|
||||||
|
on:click={() => {
|
||||||
|
toggleLandingPageMode();
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
{#if landingPageMode === ''}
|
||||||
|
<span class="ml-2 self-center">{$i18n.t('Default')}</span>
|
||||||
|
{:else}
|
||||||
|
<span class="ml-2 self-center">{$i18n.t('Chat')}</span>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class=" py-0.5 flex w-full justify-between">
|
<div class=" py-0.5 flex w-full justify-between">
|
||||||
<div class=" self-center text-xs">{$i18n.t('Chat Bubble UI')}</div>
|
<div class=" self-center text-xs">{$i18n.t('Chat Bubble UI')}</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user