mirror of
https://github.com/open-webui/open-webui.git
synced 2025-12-14 13:25:20 +00:00
enh: formatting toolbar for chat
This commit is contained in:
parent
0acd78049d
commit
bfa42c6277
5 changed files with 256 additions and 211 deletions
|
|
@ -60,7 +60,7 @@
|
|||
export let scrollToBottom: Function = () => {};
|
||||
|
||||
export let acceptFiles = true;
|
||||
export let showFormattingButtons = true;
|
||||
export let showFormattingToolbar = true;
|
||||
|
||||
let showInputVariablesModal = false;
|
||||
let inputVariables: Record<string, any> = {};
|
||||
|
|
@ -700,7 +700,7 @@
|
|||
bind:this={chatInputElement}
|
||||
json={true}
|
||||
messageInput={true}
|
||||
{showFormattingButtons}
|
||||
{showFormattingToolbar}
|
||||
shiftEnter={!($settings?.ctrlEnterToSend ?? false) &&
|
||||
(!$mobile ||
|
||||
!(
|
||||
|
|
|
|||
|
|
@ -1086,6 +1086,7 @@
|
|||
class="scrollbar-hidden rtl:text-right ltr:text-left bg-transparent dark:text-gray-100 outline-hidden w-full pt-2.5 pb-[5px] px-1 resize-none h-fit max-h-80 overflow-auto"
|
||||
id="chat-input-container"
|
||||
>
|
||||
{#key $settings?.showFormattingToolbar ?? false}
|
||||
<RichTextInput
|
||||
bind:this={chatInputElement}
|
||||
id="chat-input"
|
||||
|
|
@ -1095,7 +1096,8 @@
|
|||
}}
|
||||
json={true}
|
||||
messageInput={true}
|
||||
showFormattingButtons={false}
|
||||
showFormattingToolbar={$settings?.showFormattingToolbar ?? false}
|
||||
floatingMenuPlacement={'top-start'}
|
||||
insertPromptAsRichText={$settings?.insertPromptAsRichText ?? false}
|
||||
shiftEnter={!($settings?.ctrlEnterToSend ?? false) &&
|
||||
(!$mobile ||
|
||||
|
|
@ -1183,7 +1185,9 @@
|
|||
commandsElement.selectUp();
|
||||
|
||||
const commandOptionButton = [
|
||||
...document.getElementsByClassName('selected-command-option-button')
|
||||
...document.getElementsByClassName(
|
||||
'selected-command-option-button'
|
||||
)
|
||||
]?.at(-1);
|
||||
commandOptionButton.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
|
|
@ -1193,7 +1197,9 @@
|
|||
commandsElement.selectDown();
|
||||
|
||||
const commandOptionButton = [
|
||||
...document.getElementsByClassName('selected-command-option-button')
|
||||
...document.getElementsByClassName(
|
||||
'selected-command-option-button'
|
||||
)
|
||||
]?.at(-1);
|
||||
commandOptionButton.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
|
|
@ -1202,7 +1208,9 @@
|
|||
e.preventDefault();
|
||||
|
||||
const commandOptionButton = [
|
||||
...document.getElementsByClassName('selected-command-option-button')
|
||||
...document.getElementsByClassName(
|
||||
'selected-command-option-button'
|
||||
)
|
||||
]?.at(-1);
|
||||
|
||||
commandOptionButton?.click();
|
||||
|
|
@ -1212,7 +1220,9 @@
|
|||
e.preventDefault();
|
||||
|
||||
const commandOptionButton = [
|
||||
...document.getElementsByClassName('selected-command-option-button')
|
||||
...document.getElementsByClassName(
|
||||
'selected-command-option-button'
|
||||
)
|
||||
]?.at(-1);
|
||||
|
||||
if (commandOptionButton) {
|
||||
|
|
@ -1300,9 +1310,13 @@
|
|||
if (text.length > PASTED_TEXT_CHARACTER_LIMIT) {
|
||||
e.preventDefault();
|
||||
const blob = new Blob([text], { type: 'text/plain' });
|
||||
const file = new File([blob], `Pasted_Text_${Date.now()}.txt`, {
|
||||
const file = new File(
|
||||
[blob],
|
||||
`Pasted_Text_${Date.now()}.txt`,
|
||||
{
|
||||
type: 'text/plain'
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
await uploadFileHandler(file, true);
|
||||
}
|
||||
|
|
@ -1312,6 +1326,7 @@
|
|||
}
|
||||
}}
|
||||
/>
|
||||
{/key}
|
||||
</div>
|
||||
{:else}
|
||||
<textarea
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
let detectArtifacts = true;
|
||||
|
||||
let richTextInput = true;
|
||||
let showFormattingToolbar = false;
|
||||
let insertPromptAsRichText = false;
|
||||
let promptAutocomplete = false;
|
||||
|
||||
|
|
@ -228,6 +229,11 @@
|
|||
saveSettings({ richTextInput });
|
||||
};
|
||||
|
||||
const toggleShowFormattingToolbar = async () => {
|
||||
showFormattingToolbar = !showFormattingToolbar;
|
||||
saveSettings({ showFormattingToolbar });
|
||||
};
|
||||
|
||||
const toggleInsertPromptAsRichText = async () => {
|
||||
insertPromptAsRichText = !insertPromptAsRichText;
|
||||
saveSettings({ insertPromptAsRichText });
|
||||
|
|
@ -335,6 +341,7 @@
|
|||
chatFadeStreamingText = $settings?.chatFadeStreamingText ?? true;
|
||||
|
||||
richTextInput = $settings?.richTextInput ?? true;
|
||||
showFormattingToolbar = $settings?.showFormattingToolbar ?? false;
|
||||
insertPromptAsRichText = $settings?.insertPromptAsRichText ?? false;
|
||||
promptAutocomplete = $settings?.promptAutocomplete ?? false;
|
||||
|
||||
|
|
@ -863,6 +870,29 @@
|
|||
</div>
|
||||
|
||||
{#if richTextInput}
|
||||
<div>
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div id="rich-input-label" class=" self-center text-xs">
|
||||
{$i18n.t('Show Formatting Toolbar')}
|
||||
</div>
|
||||
|
||||
<button
|
||||
aria-labelledby="rich-input-label"
|
||||
class="p-1 px-3 text-xs flex rounded-sm transition"
|
||||
on:click={() => {
|
||||
toggleShowFormattingToolbar();
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
{#if showFormattingToolbar === true}
|
||||
<span class="ml-2 self-center">{$i18n.t('On')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div id="rich-input-label" class=" self-center text-xs">
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@
|
|||
export let editable = true;
|
||||
export let collaboration = false;
|
||||
|
||||
export let showFormattingButtons = true;
|
||||
export let showFormattingToolbar = true;
|
||||
|
||||
export let preserveBreaks = false;
|
||||
export let generateAutoCompletion: Function = async () => null;
|
||||
|
|
@ -1003,7 +1003,7 @@
|
|||
]
|
||||
: []),
|
||||
|
||||
...(showFormattingButtons
|
||||
...(showFormattingToolbar
|
||||
? [
|
||||
BubbleMenu.configure({
|
||||
element: bubbleMenuElement,
|
||||
|
|
@ -1316,7 +1316,7 @@
|
|||
};
|
||||
</script>
|
||||
|
||||
{#if showFormattingButtons}
|
||||
{#if showFormattingToolbar}
|
||||
<div bind:this={bubbleMenuElement} id="bubble-menu" class="p-0">
|
||||
<FormattingButtons {editor} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -390,7 +390,7 @@ Based on the user's instruction, update and enhance the existing notes or select
|
|||
bind:chatInputElement
|
||||
acceptFiles={false}
|
||||
inputLoading={loading}
|
||||
showFormattingButtons={false}
|
||||
showFormattingToolbar={false}
|
||||
onSubmit={submitHandler}
|
||||
{onStop}
|
||||
>
|
||||
|
|
|
|||
Loading…
Reference in a new issue