open-webui/src/lib/components/chat/Messages/ContentRenderer.svelte

94 lines
2.4 KiB
Svelte
Raw Normal View History

2024-10-05 08:37:39 +00:00
<script>
import { onDestroy, onMount, tick, createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
import Markdown from './Markdown.svelte';
import LightBlub from '$lib/components/icons/LightBlub.svelte';
export let id;
export let content;
export let model = null;
2024-10-05 19:07:45 +00:00
export let save = false;
2024-10-05 08:37:39 +00:00
export let floatingButtons = true;
let contentContainerElement;
let buttonsContainerElement;
const updateButtonPosition = () => {
setTimeout(async () => {
await tick();
let selection = window.getSelection();
if (selection.toString().trim().length > 0) {
const range = selection.getRangeAt(0);
const rect = range.getBoundingClientRect();
const parentRect = contentContainerElement.getBoundingClientRect();
// Adjust based on parent rect
const top = rect.bottom - parentRect.top;
const left = rect.left - parentRect.left;
2024-10-05 10:21:22 +00:00
if (buttonsContainerElement) {
buttonsContainerElement.style.display = 'block';
buttonsContainerElement.style.left = `${left}px`;
buttonsContainerElement.style.top = `${top + 5}px`; // +5 to add some spacing
}
2024-10-05 08:37:39 +00:00
} else {
2024-10-05 10:21:22 +00:00
if (buttonsContainerElement) {
buttonsContainerElement.style.display = 'none';
}
2024-10-05 08:37:39 +00:00
}
}, 0);
};
onMount(() => {
if (floatingButtons) {
contentContainerElement?.addEventListener('mouseup', updateButtonPosition);
2024-10-05 10:19:55 +00:00
document.addEventListener('mouseup', updateButtonPosition);
2024-10-05 08:37:39 +00:00
}
});
onDestroy(() => {
if (floatingButtons) {
contentContainerElement?.removeEventListener('mouseup', updateButtonPosition);
2024-10-05 10:19:55 +00:00
document.removeEventListener('mouseup', updateButtonPosition);
2024-10-05 08:37:39 +00:00
}
});
</script>
<div bind:this={contentContainerElement}>
2024-10-05 19:04:36 +00:00
<Markdown
{id}
{content}
{model}
2024-10-05 19:07:45 +00:00
{save}
2024-10-05 19:04:36 +00:00
on:update={(e) => {
dispatch('update', e.detail);
}}
/>
2024-10-05 08:37:39 +00:00
</div>
{#if floatingButtons}
<div
bind:this={buttonsContainerElement}
class="absolute rounded-lg mt-1 p-1 bg-white dark:bg-gray-850 text-xs text-medium shadow-lg"
style="display: none"
>
<button
2024-10-06 02:03:39 +00:00
class="px-1 hover:bg-gray-50 dark:hover:bg-gray-800 rounded flex items-center gap-0.5 min-w-fit"
2024-10-05 08:37:39 +00:00
on:click={() => {
const selection = window.getSelection();
dispatch('explain', selection.toString());
// Clear selection
selection.removeAllRanges();
buttonsContainerElement.style.display = 'none';
}}
>
2024-10-06 02:03:39 +00:00
<LightBlub className="size-3 shrink-0" />
2024-10-05 08:37:39 +00:00
2024-10-06 02:03:39 +00:00
<div class="shrink-0">Explain</div>
2024-10-05 08:37:39 +00:00
</button>
</div>
{/if}