This commit is contained in:
Timothy Jaeryang Baek 2025-09-14 09:20:12 +02:00
parent 3ed0a6d11f
commit eadec9e86e
6 changed files with 397 additions and 305 deletions

View file

@ -1,13 +1,12 @@
<script lang="ts"> <script lang="ts">
import { DropdownMenu } from 'bits-ui'; import { DropdownMenu } from 'bits-ui';
import { flyAndScale } from '$lib/utils/transitions';
import { getContext, onMount, tick } from 'svelte'; import { getContext, onMount, tick } from 'svelte';
import { fly } from 'svelte/transition';
import { flyAndScale } from '$lib/utils/transitions';
import { config, user, tools as _tools, mobile, knowledge, chats } from '$lib/stores'; import { config, user, tools as _tools, mobile, knowledge, chats } from '$lib/stores';
import { createPicker } from '$lib/utils/google-drive-picker'; import { createPicker } from '$lib/utils/google-drive-picker';
import { getTools } from '$lib/apis/tools';
import Dropdown from '$lib/components/common/Dropdown.svelte'; import Dropdown from '$lib/components/common/Dropdown.svelte';
import Tooltip from '$lib/components/common/Tooltip.svelte'; import Tooltip from '$lib/components/common/Tooltip.svelte';
import DocumentArrowUp from '$lib/components/icons/DocumentArrowUp.svelte'; import DocumentArrowUp from '$lib/components/icons/DocumentArrowUp.svelte';
@ -19,6 +18,12 @@
import Agile from '$lib/components/icons/Agile.svelte'; import Agile from '$lib/components/icons/Agile.svelte';
import ClockRotateRight from '$lib/components/icons/ClockRotateRight.svelte'; import ClockRotateRight from '$lib/components/icons/ClockRotateRight.svelte';
import Database from '$lib/components/icons/Database.svelte'; import Database from '$lib/components/icons/Database.svelte';
import ChevronRight from '$lib/components/icons/ChevronRight.svelte';
import ChevronLeft from '$lib/components/icons/ChevronLeft.svelte';
import PageEdit from '$lib/components/icons/PageEdit.svelte';
import Chats from './InputMenu/Chats.svelte';
import Notes from './InputMenu/Notes.svelte';
import Knowledge from './InputMenu/Knowledge.svelte';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
@ -37,6 +42,7 @@
export let onClose: Function; export let onClose: Function;
let show = false; let show = false;
let tab = '';
let fileUploadEnabled = true; let fileUploadEnabled = true;
$: fileUploadEnabled = $: fileUploadEnabled =
@ -81,13 +87,15 @@
<div slot="content"> <div slot="content">
<DropdownMenu.Content <DropdownMenu.Content
class="w-full max-w-[240px] rounded-2xl px-1 py-1 border border-gray-100 dark:border-gray-800 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg transition" class="w-full max-w-[240px] rounded-2xl px-1 py-1 border border-gray-100 dark:border-gray-800 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg max-h-72 overflow-y-auto overflow-x-hidden scrollbar-thin transition"
sideOffset={4} sideOffset={4}
alignOffset={-6} alignOffset={-6}
side="bottom" side="bottom"
align="start" align="start"
transition={flyAndScale} transition={flyAndScale}
> >
{#if tab === ''}
<div in:fly={{ x: -20, duration: 150 }}>
<Tooltip <Tooltip
content={fileUploadCapableModels.length !== selectedModels.length content={fileUploadCapableModels.length !== selectedModels.length
? $i18n.t('Model(s) do not support file upload') ? $i18n.t('Model(s) do not support file upload')
@ -152,27 +160,26 @@
: ''} : ''}
className="w-full" className="w-full"
> >
<DropdownMenu.Item <button
class="flex gap-2 items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-xl {!fileUploadEnabled class="flex gap-2 w-full items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-xl {!fileUploadEnabled
? 'opacity-50' ? 'opacity-50'
: ''}" : ''}"
on:click={() => { on:click={() => {
if (fileUploadEnabled) { tab = 'notes';
if (!detectMobile()) {
screenCaptureHandler();
} else {
const cameraInputElement = document.getElementById('camera-input');
if (cameraInputElement) {
cameraInputElement.click();
}
}
}
}} }}
> >
<Note /> <PageEdit />
<div class=" line-clamp-1">{$i18n.t('Attach Notes')}</div>
</DropdownMenu.Item> <div class="flex items-center w-full justify-between">
<div class=" line-clamp-1">
{$i18n.t('Attach Notes')}
</div>
<div class="text-gray-500">
<ChevronRight />
</div>
</div>
</button>
</Tooltip> </Tooltip>
{/if} {/if}
@ -184,27 +191,26 @@
: ''} : ''}
className="w-full" className="w-full"
> >
<DropdownMenu.Item <button
class="flex gap-2 items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-xl {!fileUploadEnabled class="flex gap-2 w-full items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-xl {!fileUploadEnabled
? 'opacity-50' ? 'opacity-50'
: ''}" : ''}"
on:click={() => { on:click={() => {
if (fileUploadEnabled) { tab = 'knowledge';
if (!detectMobile()) {
screenCaptureHandler();
} else {
const cameraInputElement = document.getElementById('camera-input');
if (cameraInputElement) {
cameraInputElement.click();
}
}
}
}} }}
> >
<Database /> <Database />
<div class=" line-clamp-1">{$i18n.t('Attach Knowledge')}</div>
</DropdownMenu.Item> <div class="flex items-center w-full justify-between">
<div class=" line-clamp-1">
{$i18n.t('Attach Knowledge')}
</div>
<div class="text-gray-500">
<ChevronRight />
</div>
</div>
</button>
</Tooltip> </Tooltip>
{#if ($chats ?? []).length > 0} {#if ($chats ?? []).length > 0}
@ -216,27 +222,26 @@
: ''} : ''}
className="w-full" className="w-full"
> >
<DropdownMenu.Item <button
class="flex gap-2 items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-xl {!fileUploadEnabled class="flex gap-2 w-full items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-xl {!fileUploadEnabled
? 'opacity-50' ? 'opacity-50'
: ''}" : ''}"
on:click={() => { on:click={() => {
if (fileUploadEnabled) { tab = 'chats';
if (!detectMobile()) {
screenCaptureHandler();
} else {
const cameraInputElement = document.getElementById('camera-input');
if (cameraInputElement) {
cameraInputElement.click();
}
}
}
}} }}
> >
<ClockRotateRight /> <ClockRotateRight />
<div class=" line-clamp-1">{$i18n.t('Reference Chats')}</div>
</DropdownMenu.Item> <div class="flex items-center w-full justify-between">
<div class=" line-clamp-1">
{$i18n.t('Reference Chats')}
</div>
<div class="text-gray-500">
<ChevronRight />
</div>
</div>
</button>
</Tooltip> </Tooltip>
{/if} {/if}
@ -399,6 +404,65 @@
</DropdownMenu.Sub> </DropdownMenu.Sub>
{/if} {/if}
{/if} {/if}
</div>
{:else if tab === 'knowledge'}
<div in:fly={{ x: 20, duration: 150 }}>
<button
class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800"
on:click={() => {
tab = '';
}}
>
<ChevronLeft />
<div class="flex items-center w-full justify-between">
<div>
{$i18n.t('Knowledge')}
</div>
</div>
</button>
<Knowledge />
</div>
{:else if tab === 'notes'}
<div in:fly={{ x: 20, duration: 150 }}>
<button
class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800"
on:click={() => {
tab = '';
}}
>
<ChevronLeft />
<div class="flex items-center w-full justify-between">
<div>
{$i18n.t('Notes')}
</div>
</div>
</button>
<Notes />
</div>
{:else if tab === 'chats'}
<div in:fly={{ x: 20, duration: 150 }}>
<button
class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800"
on:click={() => {
tab = '';
}}
>
<ChevronLeft />
<div class="flex items-center w-full justify-between">
<div>
{$i18n.t('Chats')}
</div>
</div>
</button>
<Chats />
</div>
{/if}
</DropdownMenu.Content> </DropdownMenu.Content>
</div> </div>
</Dropdown> </Dropdown>

View file

@ -1,7 +1,8 @@
<script lang="ts"> <script lang="ts">
import { DropdownMenu } from 'bits-ui'; import { DropdownMenu } from 'bits-ui';
import { flyAndScale } from '$lib/utils/transitions';
import { getContext, onMount, tick } from 'svelte'; import { getContext, onMount, tick } from 'svelte';
import { fly } from 'svelte/transition';
import { flyAndScale } from '$lib/utils/transitions';
import { config, user, tools as _tools, mobile, settings } from '$lib/stores'; import { config, user, tools as _tools, mobile, settings } from '$lib/stores';
@ -18,7 +19,6 @@
import Terminal from '$lib/components/icons/Terminal.svelte'; import Terminal from '$lib/components/icons/Terminal.svelte';
import ChevronRight from '$lib/components/icons/ChevronRight.svelte'; import ChevronRight from '$lib/components/icons/ChevronRight.svelte';
import ChevronLeft from '$lib/components/icons/ChevronLeft.svelte'; import ChevronLeft from '$lib/components/icons/ChevronLeft.svelte';
import { crossfade, fade, fly, slide } from 'svelte/transition';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
@ -103,7 +103,7 @@
<Wrench /> <Wrench />
<div class="flex items-center w-full justify-between"> <div class="flex items-center w-full justify-between">
<div> <div class=" line-clamp-1">
{$i18n.t('Tools')} {$i18n.t('Tools')}
<span class="ml-0.5 text-gray-500">{Object.keys(tools).length}</span> <span class="ml-0.5 text-gray-500">{Object.keys(tools).length}</span>
</div> </div>

View file

@ -0,0 +1,28 @@
<script lang="ts">
export let className = 'w-4 h-4';
export let strokeWidth = '1.5';
</script>
<svg
class={className}
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
stroke-width={strokeWidth}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
><path
d="M20 12V5.74853C20 5.5894 19.9368 5.43679 19.8243 5.32426L16.6757 2.17574C16.5632 2.06321 16.4106 2 16.2515 2H4.6C4.26863 2 4 2.26863 4 2.6V21.4C4 21.7314 4.26863 22 4.6 22H11"
stroke-linecap="round"
stroke-linejoin="round"
></path><path d="M8 10H16M8 6H12M8 14H11" stroke-linecap="round" stroke-linejoin="round"
></path><path
d="M17.9541 16.9394L18.9541 15.9394C19.392 15.5015 20.102 15.5015 20.5399 15.9394V15.9394C20.9778 16.3773 20.9778 17.0873 20.5399 17.5252L19.5399 18.5252M17.9541 16.9394L14.963 19.9305C14.8131 20.0804 14.7147 20.2741 14.6821 20.4835L14.4394 22.0399L15.9957 21.7973C16.2052 21.7646 16.3988 21.6662 16.5487 21.5163L19.5399 18.5252M17.9541 16.9394L19.5399 18.5252"
stroke-linecap="round"
stroke-linejoin="round"
></path><path
d="M16 2V5.4C16 5.73137 16.2686 6 16.6 6H20"
stroke-linecap="round"
stroke-linejoin="round"
></path></svg
>