2024-01-02 08:55:28 +00:00
|
|
|
<script lang="ts">
|
2025-03-31 07:48:09 +00:00
|
|
|
import { prompts, settings, user } from '$lib/stores';
|
2024-09-21 22:02:07 +00:00
|
|
|
import {
|
2025-04-04 15:11:54 +00:00
|
|
|
extractCurlyBraceWords,
|
2024-09-21 22:02:07 +00:00
|
|
|
getUserPosition,
|
|
|
|
|
getFormattedDate,
|
|
|
|
|
getFormattedTime,
|
|
|
|
|
getCurrentDateTime,
|
|
|
|
|
getUserTimezone,
|
|
|
|
|
getWeekday
|
|
|
|
|
} from '$lib/utils';
|
2025-07-01 11:57:01 +00:00
|
|
|
import { tick, getContext, onMount, onDestroy } from 'svelte';
|
2024-03-01 09:18:07 +00:00
|
|
|
import { toast } from 'svelte-sonner';
|
2024-01-02 08:55:28 +00:00
|
|
|
|
2024-03-02 20:38:51 +00:00
|
|
|
const i18n = getContext('i18n');
|
|
|
|
|
|
2024-08-23 12:31:39 +00:00
|
|
|
export let command = '';
|
2025-07-04 16:26:01 +00:00
|
|
|
export let onSelect = (e) => {};
|
2024-08-23 12:31:39 +00:00
|
|
|
|
|
|
|
|
let selectedPromptIdx = 0;
|
|
|
|
|
let filteredPrompts = [];
|
2024-01-02 08:55:28 +00:00
|
|
|
|
2024-08-23 12:31:39 +00:00
|
|
|
$: filteredPrompts = $prompts
|
|
|
|
|
.filter((p) => p.command.toLowerCase().includes(command.toLowerCase()))
|
2024-01-02 09:12:49 +00:00
|
|
|
.sort((a, b) => a.title.localeCompare(b.title));
|
2024-01-02 08:55:28 +00:00
|
|
|
|
2024-08-23 12:31:39 +00:00
|
|
|
$: if (command) {
|
|
|
|
|
selectedPromptIdx = 0;
|
2024-01-02 08:55:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const selectUp = () => {
|
2024-08-23 12:31:39 +00:00
|
|
|
selectedPromptIdx = Math.max(0, selectedPromptIdx - 1);
|
2024-01-02 08:55:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const selectDown = () => {
|
2024-08-23 12:31:39 +00:00
|
|
|
selectedPromptIdx = Math.min(selectedPromptIdx + 1, filteredPrompts.length - 1);
|
2024-01-02 08:55:28 +00:00
|
|
|
};
|
|
|
|
|
|
2025-07-01 11:57:01 +00:00
|
|
|
let container;
|
|
|
|
|
let adjustHeightDebounce;
|
|
|
|
|
|
|
|
|
|
const adjustHeight = () => {
|
|
|
|
|
if (container) {
|
|
|
|
|
if (adjustHeightDebounce) {
|
|
|
|
|
clearTimeout(adjustHeightDebounce);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
adjustHeightDebounce = setTimeout(() => {
|
|
|
|
|
if (!container) return;
|
|
|
|
|
|
|
|
|
|
// Ensure the container is visible before adjusting height
|
|
|
|
|
const rect = container.getBoundingClientRect();
|
2025-07-04 16:55:31 +00:00
|
|
|
container.style.maxHeight = Math.max(Math.min(240, rect.bottom - 80), 100) + 'px';
|
2025-07-01 11:57:01 +00:00
|
|
|
}, 100);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2024-08-23 12:31:39 +00:00
|
|
|
const confirmPrompt = async (command) => {
|
2025-07-04 16:26:01 +00:00
|
|
|
onSelect({ type: 'prompt', data: command });
|
2024-01-02 08:55:28 +00:00
|
|
|
};
|
2025-07-01 11:57:01 +00:00
|
|
|
|
|
|
|
|
onMount(() => {
|
|
|
|
|
window.addEventListener('resize', adjustHeight);
|
|
|
|
|
adjustHeight();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onDestroy(() => {
|
|
|
|
|
window.removeEventListener('resize', adjustHeight);
|
|
|
|
|
});
|
2024-01-02 08:55:28 +00:00
|
|
|
</script>
|
|
|
|
|
|
2024-08-23 12:31:39 +00:00
|
|
|
{#if filteredPrompts.length > 0}
|
|
|
|
|
<div
|
|
|
|
|
id="commands-container"
|
2024-12-02 07:16:00 +00:00
|
|
|
class="px-2 mb-2 text-left w-full absolute bottom-0 left-0 right-0 z-10"
|
2024-08-23 12:31:39 +00:00
|
|
|
>
|
2025-02-16 03:50:40 +00:00
|
|
|
<div class="flex w-full rounded-xl border border-gray-100 dark:border-gray-850">
|
2025-05-16 11:39:26 +00:00
|
|
|
<div class="flex flex-col w-full rounded-xl bg-white dark:bg-gray-900 dark:text-gray-100">
|
|
|
|
|
<div
|
|
|
|
|
class="m-1 overflow-y-auto p-1 space-y-0.5 scrollbar-hidden max-h-60"
|
|
|
|
|
id="command-options-container"
|
2025-07-01 11:57:01 +00:00
|
|
|
bind:this={container}
|
2025-05-16 11:39:26 +00:00
|
|
|
>
|
2025-07-04 16:26:01 +00:00
|
|
|
{#each filteredPrompts as promptItem, promptIdx}
|
2024-01-03 04:41:37 +00:00
|
|
|
<button
|
2024-08-23 12:31:39 +00:00
|
|
|
class=" px-3 py-1.5 rounded-xl w-full text-left {promptIdx === selectedPromptIdx
|
2024-06-16 16:24:16 +00:00
|
|
|
? ' bg-gray-50 dark:bg-gray-850 selected-command-option-button'
|
2024-01-03 04:41:37 +00:00
|
|
|
: ''}"
|
|
|
|
|
type="button"
|
|
|
|
|
on:click={() => {
|
2025-07-04 16:26:01 +00:00
|
|
|
confirmPrompt(promptItem);
|
2024-01-03 04:41:37 +00:00
|
|
|
}}
|
|
|
|
|
on:mousemove={() => {
|
2024-08-23 12:31:39 +00:00
|
|
|
selectedPromptIdx = promptIdx;
|
2024-01-03 04:41:37 +00:00
|
|
|
}}
|
|
|
|
|
on:focus={() => {}}
|
|
|
|
|
>
|
2024-06-16 01:55:27 +00:00
|
|
|
<div class=" font-medium text-black dark:text-gray-100">
|
2025-07-04 16:26:01 +00:00
|
|
|
{promptItem.command}
|
2024-01-03 04:41:37 +00:00
|
|
|
</div>
|
|
|
|
|
|
2024-06-16 01:55:27 +00:00
|
|
|
<div class=" text-xs text-gray-600 dark:text-gray-100">
|
2025-07-04 16:26:01 +00:00
|
|
|
{promptItem.title}
|
2024-01-03 04:41:37 +00:00
|
|
|
</div>
|
|
|
|
|
</button>
|
|
|
|
|
{/each}
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-01-03 05:35:47 +00:00
|
|
|
<div
|
2024-10-12 08:27:55 +00:00
|
|
|
class=" px-2 pt-0.5 pb-1 text-xs text-gray-600 dark:text-gray-100 bg-white dark:bg-gray-900 rounded-b-xl flex items-center space-x-1"
|
2024-01-03 05:35:47 +00:00
|
|
|
>
|
2024-01-03 04:41:37 +00:00
|
|
|
<div>
|
|
|
|
|
<svg
|
|
|
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
|
|
|
fill="none"
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
stroke-width="1.5"
|
|
|
|
|
stroke="currentColor"
|
|
|
|
|
class="w-3 h-3"
|
|
|
|
|
>
|
|
|
|
|
<path
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"
|
|
|
|
|
/>
|
|
|
|
|
</svg>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="line-clamp-1">
|
2024-03-02 20:38:51 +00:00
|
|
|
{$i18n.t(
|
|
|
|
|
'Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.'
|
|
|
|
|
)}
|
2024-01-03 04:41:37 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-01-02 08:55:28 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{/if}
|