diff --git a/src/lib/components/chat/ContentRenderer/FloatingButtons.svelte b/src/lib/components/chat/ContentRenderer/FloatingButtons.svelte index e919bc57d4..a2119b2152 100644 --- a/src/lib/components/chat/ContentRenderer/FloatingButtons.svelte +++ b/src/lib/components/chat/ContentRenderer/FloatingButtons.svelte @@ -1,5 +1,6 @@ - -
{#if output?.length} ('i18n'); let selection: ReturnType = null; let account: string | null = null; @@ -23,13 +24,15 @@ !$page.url.pathname.startsWith('/s/') ); let preparing = false; + let selectionButton: HTMLButtonElement; + let usingSelectionButton = false; $: if (($user?.id ?? null) !== account) { account = $user?.id ?? null; commentSelectionDraft.set(null); selection = null; } const select = () => { - if (!preparing) selection = commentsAllowed ? selectedComment() : null; + if (!preparing && !usingSelectionButton) selection = commentsAllowed ? selectedComment() : null; }; const commentSelection = async () => { const selected = selection; @@ -50,15 +53,21 @@ } }; onMount(() => { - document.addEventListener('mouseup', select); - document.addEventListener('keyup', select); + document.addEventListener('selectionchange', select); return () => { - document.removeEventListener('mouseup', select); - document.removeEventListener('keyup', select); + document.removeEventListener('selectionchange', select); }; }); + { + usingSelectionButton = !!selectionButton?.contains(event.target as Node); + }} + on:pointerdown|capture={(event) => { + usingSelectionButton = !!selectionButton?.contains(event.target as Node); + }} +/> { if (event.key === 'Escape') { @@ -70,15 +79,15 @@ selection = null; } }} - on:scroll|capture={() => (selection = null)} /> {#if commentsAllowed} {#key account}{/key} {#if selection && !selection.options.toolbar_id} {}; + const update = (range: Range | null) => { + cleanup(); + if (!range) return; + let active = true; + const reference = { + getBoundingClientRect: () => range.getBoundingClientRect(), + contextElement: range.commonAncestorContainer.parentElement ?? undefined + }; + const stop = autoUpdate(reference, node, () => { + void computePosition(reference, node, { + strategy: 'fixed', + placement: 'bottom-start', + middleware: [offset(12), flip(), shift({ padding: 8 })] + }).then(({ x, y }) => { + if (!active) return; + node.style.left = `${x}px`; + node.style.top = `${y}px`; + }); + }); + cleanup = () => { + active = false; + stop(); + }; + }; + update(range); + return { update, destroy: () => cleanup() }; +}