enh: custom action buttons

This commit is contained in:
Timothy Jaeryang Baek 2025-08-07 02:11:27 +04:00
parent 5d670cb7ce
commit 2e733b46b0
2 changed files with 26 additions and 18 deletions

View file

@ -17,6 +17,7 @@
export let id = ''; export let id = '';
export let model = null; export let model = null;
export let messages = []; export let messages = [];
export let actions = [];
export let onAdd = (e) => {}; export let onAdd = (e) => {};
let floatingInput = false; let floatingInput = false;
@ -30,20 +31,11 @@
let responseDone = false; let responseDone = false;
let controller = null; let controller = null;
const autoScroll = async () => { $: if (actions.length === 0) {
const responseContainer = document.getElementById('response-container'); actions = DEFAULT_ACTIONS;
if (responseContainer) { }
// Scroll to bottom only if the scroll is at the bottom give 50px buffer
if (
responseContainer.scrollHeight - responseContainer.clientHeight <=
responseContainer.scrollTop + 50
) {
responseContainer.scrollTop = responseContainer.scrollHeight;
}
}
};
const ACTIONS = [ const DEFAULT_ACTIONS = [
{ {
id: 'ask', id: 'ask',
label: $i18n.t('Ask'), label: $i18n.t('Ask'),
@ -59,6 +51,19 @@
} }
]; ];
const autoScroll = async () => {
const responseContainer = document.getElementById('response-container');
if (responseContainer) {
// Scroll to bottom only if the scroll is at the bottom give 50px buffer
if (
responseContainer.scrollHeight - responseContainer.clientHeight <=
responseContainer.scrollTop + 50
) {
responseContainer.scrollTop = responseContainer.scrollHeight;
}
}
};
const actionHandler = async (actionId) => { const actionHandler = async (actionId) => {
if (!model) { if (!model) {
toast.error('Model not selected'); toast.error('Model not selected');
@ -70,14 +75,14 @@
.map((line) => `> ${line}`) .map((line) => `> ${line}`)
.join('\n'); .join('\n');
let selectedAction = ACTIONS.find((action) => action.id === actionId); let selectedAction = actions.find((action) => action.id === actionId);
if (!selectedAction) { if (!selectedAction) {
toast.error('Action not found'); toast.error('Action not found');
return; return;
} }
let prompt = selectedAction?.prompt ?? ''; let prompt = selectedAction?.prompt ?? '';
if (selectedAction.input) { if (prompt.includes('{{INPUT_CONTENT}}') && !floatingInput) {
prompt = prompt.replace('{{INPUT_CONTENT}}', floatingInputValue); prompt = prompt.replace('{{INPUT_CONTENT}}', floatingInputValue);
floatingInputValue = ''; floatingInputValue = '';
} }
@ -212,14 +217,14 @@
<div <div
class="flex flex-row gap-0.5 shrink-0 p-1 bg-white dark:bg-gray-850 dark:text-gray-100 text-medium rounded-lg shadow-xl" class="flex flex-row gap-0.5 shrink-0 p-1 bg-white dark:bg-gray-850 dark:text-gray-100 text-medium rounded-lg shadow-xl"
> >
{#each ACTIONS as action} {#each actions as action}
<button <button
class="px-1 hover:bg-gray-50 dark:hover:bg-gray-800 rounded-sm flex items-center gap-1 min-w-fit" class="px-1 hover:bg-gray-50 dark:hover:bg-gray-800 rounded-sm flex items-center gap-1 min-w-fit"
on:click={async () => { on:click={async () => {
selectedText = window.getSelection().toString(); selectedText = window.getSelection().toString();
selectedAction = action; selectedAction = action;
if (action.input) { if (action.prompt.includes('{{INPUT_CONTENT}}')) {
floatingInput = true; floatingInput = true;
floatingInputValue = ''; floatingInputValue = '';
@ -235,7 +240,9 @@
} }
}} }}
> >
<svelte:component this={action.icon} className="size-3 shrink-0" /> {#if action.icon}
<svelte:component this={action.icon} className="size-3 shrink-0" />
{/if}
<div class="shrink-0">{action.label}</div> <div class="shrink-0">{action.label}</div>
</button> </button>
{/each} {/each}

View file

@ -194,6 +194,7 @@
<FloatingButtons <FloatingButtons
bind:this={floatingButtonsElement} bind:this={floatingButtonsElement}
{id} {id}
actions={$settings?.floatingActionButtons ?? []}
model={(selectedModels ?? []).includes(model?.id) model={(selectedModels ?? []).includes(model?.id)
? model?.id ? model?.id
: (selectedModels ?? []).length > 0 : (selectedModels ?? []).length > 0