forked from open-webui/open-webui
feat: tooltip
Co-Authored-By: Jannik S. <69747628+jannikstdl@users.noreply.github.com>
This commit is contained in:
parent
edb63c2280
commit
63c0927022
2 changed files with 139 additions and 95 deletions
|
@ -12,6 +12,7 @@
|
||||||
import Documents from './MessageInput/Documents.svelte';
|
import Documents from './MessageInput/Documents.svelte';
|
||||||
import Models from './MessageInput/Models.svelte';
|
import Models from './MessageInput/Models.svelte';
|
||||||
import { transcribeAudio } from '$lib/apis/audio';
|
import { transcribeAudio } from '$lib/apis/audio';
|
||||||
|
import Tooltip from '../common/Tooltip.svelte';
|
||||||
|
|
||||||
export let submitPrompt: Function;
|
export let submitPrompt: Function;
|
||||||
export let stopResponse: Function;
|
export let stopResponse: Function;
|
||||||
|
@ -637,24 +638,26 @@
|
||||||
<div class=" flex">
|
<div class=" flex">
|
||||||
{#if fileUploadEnabled}
|
{#if fileUploadEnabled}
|
||||||
<div class=" self-end mb-2 ml-1">
|
<div class=" self-end mb-2 ml-1">
|
||||||
<button
|
<Tooltip content="Upload files">
|
||||||
class="bg-gray-50 hover:bg-gray-100 text-gray-800 dark:bg-gray-850 dark:text-white dark:hover:bg-gray-800 transition rounded-full p-1.5"
|
<button
|
||||||
type="button"
|
class="bg-gray-50 hover:bg-gray-100 text-gray-800 dark:bg-gray-850 dark:text-white dark:hover:bg-gray-800 transition rounded-full p-1.5"
|
||||||
on:click={() => {
|
type="button"
|
||||||
filesInputElement.click();
|
on:click={() => {
|
||||||
}}
|
filesInputElement.click();
|
||||||
>
|
}}
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 16 16"
|
|
||||||
fill="currentColor"
|
|
||||||
class="w-[1.2rem] h-[1.2rem]"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M8.75 3.75a.75.75 0 0 0-1.5 0v3.5h-3.5a.75.75 0 0 0 0 1.5h3.5v3.5a.75.75 0 0 0 1.5 0v-3.5h3.5a.75.75 0 0 0 0-1.5h-3.5v-3.5Z"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
/>
|
viewBox="0 0 16 16"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
</button>
|
class="w-[1.2rem] h-[1.2rem]"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M8.75 3.75a.75.75 0 0 0-1.5 0v3.5h-3.5a.75.75 0 0 0 0 1.5h3.5v3.5a.75.75 0 0 0 1.5 0v-3.5h3.5a.75.75 0 0 0 0-1.5h-3.5v-3.5Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
@ -806,87 +809,97 @@
|
||||||
|
|
||||||
<div class="self-end mb-2 flex space-x-1 mr-1">
|
<div class="self-end mb-2 flex space-x-1 mr-1">
|
||||||
{#if messages.length == 0 || messages.at(-1).done == true}
|
{#if messages.length == 0 || messages.at(-1).done == true}
|
||||||
{#if speechRecognitionEnabled}
|
<Tooltip content="Record voice">
|
||||||
|
{#if speechRecognitionEnabled}
|
||||||
|
<button
|
||||||
|
id="voice-input-button"
|
||||||
|
class=" text-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-850 transition rounded-full p-1.5 mr-0.5 self-center"
|
||||||
|
type="button"
|
||||||
|
on:click={() => {
|
||||||
|
speechRecognitionHandler();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{#if isRecording}
|
||||||
|
<svg
|
||||||
|
class=" w-5 h-5 translate-y-[0.5px]"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
><style>
|
||||||
|
.spinner_qM83 {
|
||||||
|
animation: spinner_8HQG 1.05s infinite;
|
||||||
|
}
|
||||||
|
.spinner_oXPr {
|
||||||
|
animation-delay: 0.1s;
|
||||||
|
}
|
||||||
|
.spinner_ZTLf {
|
||||||
|
animation-delay: 0.2s;
|
||||||
|
}
|
||||||
|
@keyframes spinner_8HQG {
|
||||||
|
0%,
|
||||||
|
57.14% {
|
||||||
|
animation-timing-function: cubic-bezier(0.33, 0.66, 0.66, 1);
|
||||||
|
transform: translate(0);
|
||||||
|
}
|
||||||
|
28.57% {
|
||||||
|
animation-timing-function: cubic-bezier(0.33, 0, 0.66, 0.33);
|
||||||
|
transform: translateY(-6px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translate(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style><circle class="spinner_qM83" cx="4" cy="12" r="2.5" /><circle
|
||||||
|
class="spinner_qM83 spinner_oXPr"
|
||||||
|
cx="12"
|
||||||
|
cy="12"
|
||||||
|
r="2.5"
|
||||||
|
/><circle
|
||||||
|
class="spinner_qM83 spinner_ZTLf"
|
||||||
|
cx="20"
|
||||||
|
cy="12"
|
||||||
|
r="2.5"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
{:else}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor"
|
||||||
|
class="w-5 h-5 translate-y-[0.5px]"
|
||||||
|
>
|
||||||
|
<path d="M7 4a3 3 0 016 0v6a3 3 0 11-6 0V4z" />
|
||||||
|
<path
|
||||||
|
d="M5.5 9.643a.75.75 0 00-1.5 0V10c0 3.06 2.29 5.585 5.25 5.954V17.5h-1.5a.75.75 0 000 1.5h4.5a.75.75 0 000-1.5h-1.5v-1.546A6.001 6.001 0 0016 10v-.357a.75.75 0 00-1.5 0V10a4.5 4.5 0 01-9 0v-.357z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
<Tooltip content="Send message">
|
||||||
<button
|
<button
|
||||||
id="voice-input-button"
|
class="{prompt !== ''
|
||||||
class=" text-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-850 transition rounded-full p-1.5 mr-0.5 self-center"
|
? 'bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100 '
|
||||||
type="button"
|
: 'text-white bg-gray-100 dark:text-gray-900 dark:bg-gray-800 disabled'} transition rounded-full p-1.5 self-center"
|
||||||
on:click={() => {
|
type="submit"
|
||||||
speechRecognitionHandler();
|
disabled={prompt === ''}
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{#if isRecording}
|
<svg
|
||||||
<svg
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class=" w-5 h-5 translate-y-[0.5px]"
|
viewBox="0 0 16 16"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
viewBox="0 0 24 24"
|
class="w-5 h-5"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
>
|
||||||
><style>
|
<path
|
||||||
.spinner_qM83 {
|
fill-rule="evenodd"
|
||||||
animation: spinner_8HQG 1.05s infinite;
|
d="M8 14a.75.75 0 0 1-.75-.75V4.56L4.03 7.78a.75.75 0 0 1-1.06-1.06l4.5-4.5a.75.75 0 0 1 1.06 0l4.5 4.5a.75.75 0 0 1-1.06 1.06L8.75 4.56v8.69A.75.75 0 0 1 8 14Z"
|
||||||
}
|
clip-rule="evenodd"
|
||||||
.spinner_oXPr {
|
/>
|
||||||
animation-delay: 0.1s;
|
</svg>
|
||||||
}
|
|
||||||
.spinner_ZTLf {
|
|
||||||
animation-delay: 0.2s;
|
|
||||||
}
|
|
||||||
@keyframes spinner_8HQG {
|
|
||||||
0%,
|
|
||||||
57.14% {
|
|
||||||
animation-timing-function: cubic-bezier(0.33, 0.66, 0.66, 1);
|
|
||||||
transform: translate(0);
|
|
||||||
}
|
|
||||||
28.57% {
|
|
||||||
animation-timing-function: cubic-bezier(0.33, 0, 0.66, 0.33);
|
|
||||||
transform: translateY(-6px);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translate(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style><circle class="spinner_qM83" cx="4" cy="12" r="2.5" /><circle
|
|
||||||
class="spinner_qM83 spinner_oXPr"
|
|
||||||
cx="12"
|
|
||||||
cy="12"
|
|
||||||
r="2.5"
|
|
||||||
/><circle class="spinner_qM83 spinner_ZTLf" cx="20" cy="12" r="2.5" /></svg
|
|
||||||
>
|
|
||||||
{:else}
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
fill="currentColor"
|
|
||||||
class="w-5 h-5 translate-y-[0.5px]"
|
|
||||||
>
|
|
||||||
<path d="M7 4a3 3 0 016 0v6a3 3 0 11-6 0V4z" />
|
|
||||||
<path
|
|
||||||
d="M5.5 9.643a.75.75 0 00-1.5 0V10c0 3.06 2.29 5.585 5.25 5.954V17.5h-1.5a.75.75 0 000 1.5h4.5a.75.75 0 000-1.5h-1.5v-1.546A6.001 6.001 0 0016 10v-.357a.75.75 0 00-1.5 0V10a4.5 4.5 0 01-9 0v-.357z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
{/if}
|
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
</Tooltip>
|
||||||
<button
|
|
||||||
class="{prompt !== ''
|
|
||||||
? 'bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100 '
|
|
||||||
: 'text-white bg-gray-100 dark:text-gray-900 dark:bg-gray-800 disabled'} transition rounded-full p-1.5 self-center"
|
|
||||||
type="submit"
|
|
||||||
disabled={prompt === ''}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 16 16"
|
|
||||||
fill="currentColor"
|
|
||||||
class="w-5 h-5"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill-rule="evenodd"
|
|
||||||
d="M8 14a.75.75 0 0 1-.75-.75V4.56L4.03 7.78a.75.75 0 0 1-1.06-1.06l4.5-4.5a.75.75 0 0 1 1.06 0l4.5 4.5a.75.75 0 0 1-1.06 1.06L8.75 4.56v8.69A.75.75 0 0 1 8 14Z"
|
|
||||||
clip-rule="evenodd"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
{:else}
|
{:else}
|
||||||
<button
|
<button
|
||||||
class="bg-white hover:bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-800 transition rounded-full p-1.5"
|
class="bg-white hover:bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-800 transition rounded-full p-1.5"
|
||||||
|
|
31
src/lib/components/common/Tooltip.svelte
Normal file
31
src/lib/components/common/Tooltip.svelte
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { onDestroy } from 'svelte';
|
||||||
|
import tippy from 'tippy.js';
|
||||||
|
|
||||||
|
export let placement = 'top';
|
||||||
|
export let content = `I'm a tooltip!`;
|
||||||
|
|
||||||
|
let tooltipElement;
|
||||||
|
let tooltipInstance;
|
||||||
|
|
||||||
|
$: if (tooltipElement && content) {
|
||||||
|
if (tooltipInstance) {
|
||||||
|
tooltipInstance[0]?.destroy();
|
||||||
|
}
|
||||||
|
tooltipInstance = tippy(tooltipElement, {
|
||||||
|
content: content,
|
||||||
|
placement: placement,
|
||||||
|
allowHTML: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
if (tooltipInstance) {
|
||||||
|
tooltipInstance[0]?.destroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div bind:this={tooltipElement}>
|
||||||
|
<slot />
|
||||||
|
</div>
|
Loading…
Reference in a new issue