ui : close the manager and focus the composer on a new chat

Assisted-by: pi:llama.cpp/DeepSeek-V4.1-Flash
This commit is contained in:
Aleksander Grygier
2026-09-28 12:10:13 +02:00
parent ba8d2ef84a
commit dce4a6d3ce
4 changed files with 31 additions and 3 deletions
@@ -3,7 +3,7 @@
import { page } from '$app/state';
import { ChatForm } from '$lib/components/app';
import { useDraftMessages } from '$lib/hooks/use-draft-messages.svelte';
import { deviceStore } from '$lib/stores';
import { deviceStore, uiStore } from '$lib/stores';
import { onMount } from 'svelte';
interface Props {
@@ -33,6 +33,15 @@
}: Props = $props();
let chatFormRef: ChatForm | undefined = $state(undefined);
// a dialog that closed onto the chat asks for the composer to take focus
$effect(() => {
if (!uiStore.consumeComposerFocus()) return;
const frame = requestAnimationFrame(() => chatFormRef?.focus());
return () => cancelAnimationFrame(frame);
});
let formWrapperEl: HTMLDivElement | undefined = $state();
let chatId = $derived(page.params.id as string | undefined);
@@ -21,6 +21,7 @@
<Dialog.Root onOpenChange={handleOpenChange} {open}>
<Dialog.Content
class="md:h-[calc(100vh-4rem)]! md:max-h-240! md:w-[calc(100vw-4rem)]! md:max-w-360! flex flex-col p-4"
onCloseAutoFocus={(event) => event.preventDefault()}
onOpenAutoFocus={(event) => event.preventDefault()}
>
<Dialog.Header class="flex flex-row items-center justify-between p-2 pr-8">
@@ -37,6 +38,6 @@
</Button>
</Dialog.Header>
<ModelsManager class="mt-4" />
<ModelsManager class="mt-4" onClose={() => handleOpenChange(false)} />
</Dialog.Content>
</Dialog.Root>
@@ -260,6 +260,8 @@
async function useInNewChat(option: ModelOption): Promise<void> {
await modelsStore.selectModelById(option.id);
await conversationsStore.openNewChat();
// the chat is behind the dialog, so it takes focus once the dialog is out of the way
uiStore.requestComposerFocus();
onClose?.();
}
+17 -1
View File
@@ -7,14 +7,25 @@
*/
class UiStore {
discoverModelsOpen = $state(false);
/** Set when a flow outside the chat wants the composer focused once it can take it. */
composerFocusRequested = $state(false);
discoverModelsOpen = $state(false);
/** Whether the desktop sidebar is expanded (open). */
isSidebarExpanded = $state(false);
/** Model the manager reveals when it opens, a qualified id or a raw model name. */
manageModelFocus = $state<string | null>(null);
/** Open state of the models manager, driven from the sidebar and from model rows. */
manageModelsOpen = $state(false);
/** Read and clear the request, so it fires once. */
consumeComposerFocus(): boolean {
const requested = this.composerFocusRequested;
this.composerFocusRequested = false;
return requested;
}
openDiscoverModels(): void {
this.discoverModelsOpen = true;
}
@@ -24,6 +35,11 @@ class UiStore {
this.manageModelFocus = focus ?? null;
this.manageModelsOpen = true;
}
/** Ask the composer to take focus, e.g. after a dialog closes onto the chat. */
requestComposerFocus(): void {
this.composerFocusRequested = true;
}
}
export const uiStore = new UiStore();