fix(app): keep composer focus after attaching files (#50864)

This commit is contained in:
Luke Parker
2026-09-23 18:04:39 +10:00
committed by GitHub
parent fabf56781c
commit 9c8a63e852
3 changed files with 34 additions and 11 deletions
@@ -201,12 +201,15 @@ export function createComposerAttachments(
cancel(id: string) {
uploads.items().find((item) => item.id === id)?.cancel()
},
pick(fallback: () => void) {
pick(fallback: () => void, done: () => void) {
if (!input.picker) {
fallback()
return
}
void input.picker({ defaultPath: input.directory(), multiple: true }, (file) => add(file)).catch(input.onError)
void input
.picker({ defaultPath: input.directory(), multiple: true }, (file) => add(file))
.then(done)
.catch(input.onError)
},
}
}
+21 -7
View File
@@ -1,4 +1,15 @@
import { createEffect, createMemo, createResource, createSignal, For, onCleanup, onMount, Show, type JSX } from "solid-js"
import {
createEffect,
createMemo,
createResource,
createSignal,
For,
onCleanup,
onMount,
Show,
Suspense,
type JSX,
} from "solid-js"
import { createStore } from "solid-js/store"
import { FileIcon } from "@opencode/ui/file-icon"
import { Icon } from "@opencode/ui/icon"
@@ -551,12 +562,15 @@ export function ComposerAttachments(props: {
const [url] = createResource(() => image().blob, resolveBlobUrl)
return (
<>
<img
src={url() ?? ""}
alt={attachment.filename}
class="w-[58px] h-[46px] rounded-[6px] object-cover"
onClick={() => props.onAttachmentClick?.(attachment)}
/>
{/* Keep loading local; the route boundary would detach the screen and drop editor focus. */}
<Suspense fallback={<div class="w-[58px] h-[46px]" />}>
<img
src={url() ?? ""}
alt={attachment.filename}
class="w-[58px] h-[46px] rounded-[6px] object-cover"
onClick={() => props.onAttachmentClick?.(attachment)}
/>
</Suspense>
<div class="absolute inset-0 rounded-[6px] shadow-[inset_0_0_0_0.5px_var(--v2-border-border-base)] pointer-events-none" />
</>
)
@@ -102,7 +102,11 @@ export function createComposerEditor(input: {
input.view.add?.onAttach()
return
}
attachments.pick(() => fileInput?.click())
// The add menu leaves focus on its trigger, so return it to the editor once files are picked.
attachments.pick(
() => fileInput?.click(),
() => restoreFocus(),
)
}
const contextList = useFilteredList<ComposerSuggestion>({
items: async (query) => {
@@ -449,7 +453,9 @@ export function createComposerEditor(input: {
fileInput = element
},
addAttachments(files: File[]) {
if (attachments) void attachments.addAttachments(files)
if (!attachments) return
void attachments.addAttachments(files)
restoreFocus()
},
setQuery(value: string) {
dispatch({ type: "popover.query", value })