summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-11-07 12:56:07 -0600
committerAdam <[email protected]>2025-11-07 12:56:07 -0600
commit89922a8598bf344ed24fb1b472307f383ef2b18a (patch)
treef7f60d91e4be965710dfe8bedc9c8de3b056be46
parent3a1d1a6284b66aaf385c3c97bb842a8e1d8985cb (diff)
downloadopencode-89922a8598bf344ed24fb1b472307f383ef2b18a.tar.gz
opencode-89922a8598bf344ed24fb1b472307f383ef2b18a.zip
fix(desktop): prompt input missing on new session
-rw-r--r--packages/desktop/src/pages/session.tsx728
1 files changed, 361 insertions, 367 deletions
diff --git a/packages/desktop/src/pages/session.tsx b/packages/desktop/src/pages/session.tsx
index 3dcc24e61..b872c1434 100644
--- a/packages/desktop/src/pages/session.tsx
+++ b/packages/desktop/src/pages/session.tsx
@@ -330,142 +330,39 @@ export default function Page() {
</Tabs.List>
</div>
<Tabs.Content value="chat" class="@container select-text flex flex-col flex-1 min-h-0 overflow-y-hidden">
- <Show
- when={session.id}
- fallback={
- <div class="size-full max-w-2xl mx-auto flex flex-col pb-45 px-6 justify-end items-start gap-4 flex-[1_0_0] self-stretch">
- <div class="text-20-medium text-text-weaker">New session</div>
- <div class="flex justify-center items-center gap-3">
- <Icon name="folder" size="small" />
- <div class="text-12-medium text-text-weak">
- {getDirectory(sync.data.path.directory)}
- <span class="text-text-strong">{getFilename(sync.data.path.directory)}</span>
- </div>
- </div>
- <div class="flex justify-center items-center gap-3">
- <Icon name="pencil-line" size="small" />
- <div class="text-12-medium text-text-weak">
- Last modified&nbsp;
- <span class="text-text-strong">
- {DateTime.fromMillis(sync.data.project.time.created).toRelative()}
- </span>
- </div>
- </div>
- </div>
- }
+ <div
+ classList={{
+ "w-full grid flex-1 min-h-0": true,
+ "grid-cols-2": local.layout.review.state() === "open",
+ }}
>
- {(_) => {
- return (
- <div
- classList={{
- "w-full grid flex-1 min-h-0": true,
- "grid-cols-2": local.layout.review.state() === "open",
- "max-w-2xl mx-auto": local.layout.review.state() !== "open",
- }}
- >
- <div class="relative px-6 py-2 w-full flex flex-col gap-6 flex-1 min-h-0 max-w-2xl mx-auto">
- <div class="h-8 flex shrink-0 self-stretch items-center justify-end">
- <Show when={local.layout.review.state() === "closed" && session.diffs().length}>
- <Button icon="layout-right" onClick={local.layout.review.open}>
- Review
- </Button>
- </Show>
- </div>
- <div
- classList={{
- "flex-1 min-h-0 pb-20": true,
- "flex items-start justify-start": local.layout.review.state() === "open",
- }}
- >
- <Show when={session.messages.user().length > 1}>
- <ul
- role="list"
- classList={{
- "mr-8 shrink-0 flex flex-col items-start": true,
- "absolute right-full w-60 @7xl:gap-2": true, // local.layout.review.state() !== "open",
- "": local.layout.review.state() === "open",
- }}
- >
- <For each={session.messages.user()}>
- {(message) => {
- const assistantMessages = createMemo(() => {
- if (!session.id) return []
- return sync.data.message[session.id]?.filter(
- (m) => m.role === "assistant" && m.parentID == message.id,
- ) as AssistantMessageType[]
- })
- const error = createMemo(() => assistantMessages().find((m) => m?.error)?.error)
- const working = createMemo(() => !message.summary?.body && !error())
-
- const handleClick = () => session.messages.setActive(message.id)
-
- return (
- <li
- classList={{
- "group/li flex items-center self-stretch justify-end": true,
- "@7xl:justify-start": local.layout.review.state() !== "open",
- }}
- >
- <Tooltip
- placement="right"
- gutter={8}
- value={
- <div class="flex items-center gap-2">
- <DiffChanges changes={message.summary?.diffs ?? []} variant="bars" />
- {message.summary?.title}
- </div>
- }
- >
- <button
- data-active={session.messages.active()?.id === message.id}
- onClick={handleClick}
- classList={{
- "group/tick flex items-center justify-start h-2 w-8 -mr-3": true,
- "data-[active=true]:[&>div]:bg-icon-strong-base data-[active=true]:[&>div]:w-full": true,
- "@7xl:hidden": local.layout.review.state() !== "open",
- }}
- >
- <div class="h-px w-5 bg-icon-base group-hover/tick:w-full group-hover/tick:bg-icon-strong-base" />
- </button>
- </Tooltip>
- <button
- classList={{
- "hidden items-center self-stretch w-full gap-x-2 cursor-default": true,
- "@7xl:flex": local.layout.review.state() !== "open",
- }}
- onClick={handleClick}
- >
- <Switch>
- <Match when={working()}>
- <Spinner class="text-text-base shrink-0 w-[18px] aspect-square" />
- </Match>
- <Match when={true}>
- <DiffChanges changes={message.summary?.diffs ?? []} variant="bars" />
- </Match>
- </Switch>
- <div
- data-active={session.messages.active()?.id === message.id}
- classList={{
- "text-14-regular text-text-weak whitespace-nowrap truncate min-w-0": true,
- "text-text-weak data-[active=true]:text-text-strong group-hover/li:text-text-base": true,
- }}
- >
- <Show when={message.summary?.title} fallback="New message">
- {message.summary?.title}
- </Show>
- </div>
- </button>
- </li>
- )
- }}
- </For>
- </ul>
- </Show>
- <div ref={messageScrollElement} class="grow w-full min-w-0 h-full overflow-y-auto no-scrollbar">
+ <div class="relative px-6 py-2 w-full flex flex-col gap-6 flex-1 min-h-0 max-w-2xl mx-auto">
+ <Switch>
+ <Match when={session.id}>
+ <div class="h-8 flex shrink-0 self-stretch items-center justify-end">
+ <Show when={local.layout.review.state() === "closed" && session.diffs().length}>
+ <Button icon="layout-right" onClick={local.layout.review.open}>
+ Review
+ </Button>
+ </Show>
+ </div>
+ <div
+ classList={{
+ "flex-1 min-h-0 pb-20": true,
+ "flex items-start justify-start": local.layout.review.state() === "open",
+ }}
+ >
+ <Show when={session.messages.user().length > 1}>
+ <ul
+ role="list"
+ classList={{
+ "mr-8 shrink-0 flex flex-col items-start": true,
+ "absolute right-full w-60 @7xl:gap-2": true, // local.layout.review.state() !== "open",
+ "": local.layout.review.state() === "open",
+ }}
+ >
<For each={session.messages.user()}>
{(message) => {
- const isActive = createMemo(() => session.messages.active()?.id === message.id)
- const [titled, setTitled] = createSignal(!!message.summary?.title)
const assistantMessages = createMemo(() => {
if (!session.id) return []
return sync.data.message[session.id]?.filter(
@@ -473,261 +370,358 @@ export default function Page() {
) as AssistantMessageType[]
})
const error = createMemo(() => assistantMessages().find((m) => m?.error)?.error)
- const [completed, setCompleted] = createSignal(!!message.summary?.body || !!error())
- const [detailsExpanded, setDetailsExpanded] = createSignal(false)
- const parts = createMemo(() => sync.data.part[message.id])
- const hasToolPart = createMemo(() =>
- assistantMessages()
- ?.flatMap((m) => sync.data.part[m.id])
- .some((p) => p?.type === "tool"),
- )
const working = createMemo(() => !message.summary?.body && !error())
- // allowing time for the animations to finish
- createEffect(() => {
- const title = message.summary?.title
- setTimeout(() => setTitled(!!title), 10_000)
- })
- createEffect(() => {
- const summary = message.summary?.body
- const complete = !!summary || !!error()
- setTimeout(() => setCompleted(complete), 1200)
- })
+ const handleClick = () => session.messages.setActive(message.id)
return (
- <Show when={isActive()}>
- <div
- data-message={message.id}
- class="flex flex-col items-start self-stretch gap-8 pb-20"
+ <li
+ classList={{
+ "group/li flex items-center self-stretch justify-end": true,
+ "@7xl:justify-start": local.layout.review.state() !== "open",
+ }}
+ >
+ <Tooltip
+ placement="right"
+ gutter={8}
+ value={
+ <div class="flex items-center gap-2">
+ <DiffChanges changes={message.summary?.diffs ?? []} variant="bars" />
+ {message.summary?.title}
+ </div>
+ }
>
- {/* Title */}
- <div class="flex flex-col items-start gap-2 self-stretch sticky top-0 bg-background-stronger z-10 pb-1">
- <div class="w-full text-14-medium text-text-strong">
- <Show
- when={titled()}
- fallback={
- <Typewriter
- as="h1"
- text={message.summary?.title}
- class="overflow-hidden text-ellipsis min-w-0 text-nowrap"
+ <button
+ data-active={session.messages.active()?.id === message.id}
+ onClick={handleClick}
+ classList={{
+ "group/tick flex items-center justify-start h-2 w-8 -mr-3": true,
+ "data-[active=true]:[&>div]:bg-icon-strong-base data-[active=true]:[&>div]:w-full": true,
+ "@7xl:hidden": local.layout.review.state() !== "open",
+ }}
+ >
+ <div class="h-px w-5 bg-icon-base group-hover/tick:w-full group-hover/tick:bg-icon-strong-base" />
+ </button>
+ </Tooltip>
+ <button
+ classList={{
+ "hidden items-center self-stretch w-full gap-x-2 cursor-default": true,
+ "@7xl:flex": local.layout.review.state() !== "open",
+ }}
+ onClick={handleClick}
+ >
+ <Switch>
+ <Match when={working()}>
+ <Spinner class="text-text-base shrink-0 w-[18px] aspect-square" />
+ </Match>
+ <Match when={true}>
+ <DiffChanges changes={message.summary?.diffs ?? []} variant="bars" />
+ </Match>
+ </Switch>
+ <div
+ data-active={session.messages.active()?.id === message.id}
+ classList={{
+ "text-14-regular text-text-weak whitespace-nowrap truncate min-w-0": true,
+ "text-text-weak data-[active=true]:text-text-strong group-hover/li:text-text-base": true,
+ }}
+ >
+ <Show when={message.summary?.title} fallback="New message">
+ {message.summary?.title}
+ </Show>
+ </div>
+ </button>
+ </li>
+ )
+ }}
+ </For>
+ </ul>
+ </Show>
+ <div ref={messageScrollElement} class="grow w-full min-w-0 h-full overflow-y-auto no-scrollbar">
+ <For each={session.messages.user()}>
+ {(message) => {
+ const isActive = createMemo(() => session.messages.active()?.id === message.id)
+ const [titled, setTitled] = createSignal(!!message.summary?.title)
+ const assistantMessages = createMemo(() => {
+ if (!session.id) return []
+ return sync.data.message[session.id]?.filter(
+ (m) => m.role === "assistant" && m.parentID == message.id,
+ ) as AssistantMessageType[]
+ })
+ const error = createMemo(() => assistantMessages().find((m) => m?.error)?.error)
+ const [completed, setCompleted] = createSignal(!!message.summary?.body || !!error())
+ const [detailsExpanded, setDetailsExpanded] = createSignal(false)
+ const parts = createMemo(() => sync.data.part[message.id])
+ const hasToolPart = createMemo(() =>
+ assistantMessages()
+ ?.flatMap((m) => sync.data.part[m.id])
+ .some((p) => p?.type === "tool"),
+ )
+ const working = createMemo(() => !message.summary?.body && !error())
+
+ // allowing time for the animations to finish
+ createEffect(() => {
+ const title = message.summary?.title
+ setTimeout(() => setTitled(!!title), 10_000)
+ })
+ createEffect(() => {
+ const summary = message.summary?.body
+ const complete = !!summary || !!error()
+ setTimeout(() => setCompleted(complete), 1200)
+ })
+
+ return (
+ <Show when={isActive()}>
+ <div
+ data-message={message.id}
+ class="flex flex-col items-start self-stretch gap-8 pb-20"
+ >
+ {/* Title */}
+ <div class="flex flex-col items-start gap-2 self-stretch sticky top-0 bg-background-stronger z-10 pb-1">
+ <div class="w-full text-14-medium text-text-strong">
+ <Show
+ when={titled()}
+ fallback={
+ <Typewriter
+ as="h1"
+ text={message.summary?.title}
+ class="overflow-hidden text-ellipsis min-w-0 text-nowrap"
+ />
+ }
+ >
+ <h1 class="overflow-hidden text-ellipsis min-w-0 text-nowrap">
+ {message.summary?.title}
+ </h1>
+ </Show>
+ </div>
+ </div>
+ <div class="-mt-9">
+ <Message message={message} parts={parts()} />
+ </div>
+ {/* Summary */}
+ <Show when={completed()}>
+ <div class="w-full flex flex-col gap-6 items-start self-stretch">
+ <div class="flex flex-col items-start gap-1 self-stretch">
+ <h2 class="text-12-medium text-text-weak">
+ <Switch>
+ <Match when={message.summary?.diffs?.length}>Summary</Match>
+ <Match when={true}>Response</Match>
+ </Switch>
+ </h2>
+ <Show when={message.summary?.body}>
+ {(summary) => (
+ <Markdown
+ classList={{
+ "text-14-regular": !!message.summary?.diffs?.length,
+ "[&>*]:fade-up-text": !message.summary?.diffs?.length,
+ }}
+ text={summary()}
/>
- }
- >
- <h1 class="overflow-hidden text-ellipsis min-w-0 text-nowrap">
- {message.summary?.title}
- </h1>
+ )}
</Show>
</div>
- </div>
- <div class="-mt-9">
- <Message message={message} parts={parts()} />
- </div>
- {/* Summary */}
- <Show when={completed()}>
- <div class="w-full flex flex-col gap-6 items-start self-stretch">
- <div class="flex flex-col items-start gap-1 self-stretch">
- <h2 class="text-12-medium text-text-weak">
- <Switch>
- <Match when={message.summary?.diffs?.length}>Summary</Match>
- <Match when={true}>Response</Match>
- </Switch>
- </h2>
- <Show when={message.summary?.body}>
- {(summary) => (
- <Markdown
- classList={{
- "text-14-regular": !!message.summary?.diffs?.length,
- "[&>*]:fade-up-text": !message.summary?.diffs?.length,
- }}
- text={summary()}
- />
- )}
- </Show>
- </div>
- <Accordion class="w-full" multiple>
- <For each={message.summary?.diffs ?? []}>
- {(diff) => (
- <Accordion.Item value={diff.file}>
- <Accordion.Header>
- <Accordion.Trigger>
- <div class="flex items-center justify-between w-full gap-5">
- <div class="grow flex items-center gap-5 min-w-0">
- <FileIcon
- node={{ path: diff.file, type: "file" }}
- class="shrink-0 size-4"
- />
- <div class="flex grow min-w-0">
- <Show when={diff.file.includes("/")}>
- <span class="text-text-base truncate-start">
- {getDirectory(diff.file)}&lrm;
- </span>
- </Show>
- <span class="text-text-strong shrink-0">
- {getFilename(diff.file)}
+ <Accordion class="w-full" multiple>
+ <For each={message.summary?.diffs ?? []}>
+ {(diff) => (
+ <Accordion.Item value={diff.file}>
+ <Accordion.Header>
+ <Accordion.Trigger>
+ <div class="flex items-center justify-between w-full gap-5">
+ <div class="grow flex items-center gap-5 min-w-0">
+ <FileIcon
+ node={{ path: diff.file, type: "file" }}
+ class="shrink-0 size-4"
+ />
+ <div class="flex grow min-w-0">
+ <Show when={diff.file.includes("/")}>
+ <span class="text-text-base truncate-start">
+ {getDirectory(diff.file)}&lrm;
</span>
- </div>
- </div>
- <div class="shrink-0 flex gap-4 items-center justify-end">
- <DiffChanges changes={diff} />
- <Icon name="chevron-grabber-vertical" size="small" />
+ </Show>
+ <span class="text-text-strong shrink-0">
+ {getFilename(diff.file)}
+ </span>
</div>
</div>
- </Accordion.Trigger>
- </Accordion.Header>
- <Accordion.Content class="max-h-[360px] overflow-y-auto no-scrollbar">
- <Diff
- before={{
- name: diff.file!,
- contents: diff.before!,
- }}
- after={{
- name: diff.file!,
- contents: diff.after!,
- }}
- />
- </Accordion.Content>
- </Accordion.Item>
- )}
- </For>
- </Accordion>
- </div>
- </Show>
- <Show when={error() && !detailsExpanded()}>
- <Card variant="error" class="text-text-on-critical-base">
- {error()?.data?.message as string}
- </Card>
- </Show>
- {/* Response */}
- <div class="w-full">
- <Switch>
- <Match when={!completed()}>
- <MessageProgress assistantMessages={assistantMessages} done={!working()} />
- </Match>
- <Match when={completed() && hasToolPart()}>
- <Collapsible
- variant="ghost"
- open={detailsExpanded()}
- onOpenChange={setDetailsExpanded}
- >
- <Collapsible.Trigger class="text-text-weak hover:text-text-strong">
- <div class="flex items-center gap-1 self-stretch">
- <div class="text-12-medium">
- <Switch>
- <Match when={detailsExpanded()}>Hide details</Match>
- <Match when={!detailsExpanded()}>Show details</Match>
- </Switch>
- </div>
- <Collapsible.Arrow />
- </div>
- </Collapsible.Trigger>
- <Collapsible.Content>
- <div class="w-full flex flex-col items-start self-stretch gap-3">
- <For each={assistantMessages()}>
- {(assistantMessage) => {
- const parts = createMemo(() => sync.data.part[assistantMessage.id])
- return <Message message={assistantMessage} parts={parts()} />
+ <div class="shrink-0 flex gap-4 items-center justify-end">
+ <DiffChanges changes={diff} />
+ <Icon name="chevron-grabber-vertical" size="small" />
+ </div>
+ </div>
+ </Accordion.Trigger>
+ </Accordion.Header>
+ <Accordion.Content class="max-h-[360px] overflow-y-auto no-scrollbar">
+ <Diff
+ before={{
+ name: diff.file!,
+ contents: diff.before!,
}}
- </For>
- <Show when={error()}>
- <Card variant="error" class="text-text-on-critical-base">
- {error()?.data?.message as string}
- </Card>
- </Show>
- </div>
- </Collapsible.Content>
- </Collapsible>
- </Match>
- </Switch>
+ after={{
+ name: diff.file!,
+ contents: diff.after!,
+ }}
+ />
+ </Accordion.Content>
+ </Accordion.Item>
+ )}
+ </For>
+ </Accordion>
</div>
+ </Show>
+ <Show when={error() && !detailsExpanded()}>
+ <Card variant="error" class="text-text-on-critical-base">
+ {error()?.data?.message as string}
+ </Card>
+ </Show>
+ {/* Response */}
+ <div class="w-full">
+ <Switch>
+ <Match when={!completed()}>
+ <MessageProgress assistantMessages={assistantMessages} done={!working()} />
+ </Match>
+ <Match when={completed() && hasToolPart()}>
+ <Collapsible
+ variant="ghost"
+ open={detailsExpanded()}
+ onOpenChange={setDetailsExpanded}
+ >
+ <Collapsible.Trigger class="text-text-weak hover:text-text-strong">
+ <div class="flex items-center gap-1 self-stretch">
+ <div class="text-12-medium">
+ <Switch>
+ <Match when={detailsExpanded()}>Hide details</Match>
+ <Match when={!detailsExpanded()}>Show details</Match>
+ </Switch>
+ </div>
+ <Collapsible.Arrow />
+ </div>
+ </Collapsible.Trigger>
+ <Collapsible.Content>
+ <div class="w-full flex flex-col items-start self-stretch gap-3">
+ <For each={assistantMessages()}>
+ {(assistantMessage) => {
+ const parts = createMemo(() => sync.data.part[assistantMessage.id])
+ return <Message message={assistantMessage} parts={parts()} />
+ }}
+ </For>
+ <Show when={error()}>
+ <Card variant="error" class="text-text-on-critical-base">
+ {error()?.data?.message as string}
+ </Card>
+ </Show>
+ </div>
+ </Collapsible.Content>
+ </Collapsible>
+ </Match>
+ </Switch>
</div>
- </Show>
- )
- }}
- </For>
+ </div>
+ </Show>
+ )
+ }}
+ </For>
+ </div>
+ </div>
+ </Match>
+ <Match when={true}>
+ <div class="size-full flex flex-col pb-45 justify-end items-start gap-4 flex-[1_0_0] self-stretch">
+ <div class="text-20-medium text-text-weaker">New session</div>
+ <div class="flex justify-center items-center gap-3">
+ <Icon name="folder" size="small" />
+ <div class="text-12-medium text-text-weak">
+ {getDirectory(sync.data.path.directory)}
+ <span class="text-text-strong">{getFilename(sync.data.path.directory)}</span>
</div>
-
- <div class="absolute inset-x-0 px-6 max-w-2xl flex flex-col justify-center items-center z-50 mx-auto bottom-8">
- <PromptInput
- ref={(el) => {
- inputRef = el
- }}
- />
+ </div>
+ <div class="flex justify-center items-center gap-3">
+ <Icon name="pencil-line" size="small" />
+ <div class="text-12-medium text-text-weak">
+ Last modified&nbsp;
+ <span class="text-text-strong">
+ {DateTime.fromMillis(sync.data.project.time.created).toRelative()}
+ </span>
</div>
</div>
</div>
- <Show when={local.layout.review.state() === "open"}>
- <div
- classList={{
- "relative px-6 py-2 w-full flex flex-col gap-6 flex-1 min-h-0 border-l border-border-weak-base": true,
- }}
- >
- <div class="h-8 w-full flex items-center justify-between shrink-0 self-stretch">
- <div class="flex items-center gap-x-3">
- <Tooltip value="Close">
- <IconButton icon="align-right" variant="ghost" onClick={local.layout.review.close} />
- </Tooltip>
- <Tooltip value="Open in tab">
- <IconButton
- icon="expand"
- variant="ghost"
- onClick={() => {
- local.layout.review.tab()
- session.layout.setActiveTab("review")
+ </Match>
+ </Switch>
+ <div class="absolute inset-x-0 px-6 max-w-2xl flex flex-col justify-center items-center z-50 mx-auto bottom-8">
+ <PromptInput
+ ref={(el) => {
+ inputRef = el
+ }}
+ />
+ </div>
+ </div>
+ <Show when={local.layout.review.state() === "open"}>
+ <div
+ classList={{
+ "relative px-6 py-2 w-full flex flex-col gap-6 flex-1 min-h-0 border-l border-border-weak-base": true,
+ }}
+ >
+ <div class="h-8 w-full flex items-center justify-between shrink-0 self-stretch">
+ <div class="flex items-center gap-x-3">
+ <Tooltip value="Close">
+ <IconButton icon="align-right" variant="ghost" onClick={local.layout.review.close} />
+ </Tooltip>
+ <Tooltip value="Open in tab">
+ <IconButton
+ icon="expand"
+ variant="ghost"
+ onClick={() => {
+ local.layout.review.tab()
+ session.layout.setActiveTab("review")
+ }}
+ />
+ </Tooltip>
+ </div>
+ </div>
+ <div class="text-14-medium text-text-strong">All changes</div>
+ <div class="h-full pb-40 overflow-y-auto no-scrollbar">
+ <Accordion class="w-full" multiple>
+ <For each={session.diffs()}>
+ {(diff) => (
+ <Accordion.Item value={diff.file} defaultOpen>
+ <Accordion.Header>
+ <Accordion.Trigger>
+ <div class="flex items-center justify-between w-full gap-5">
+ <div class="grow flex items-center gap-5 min-w-0">
+ <FileIcon node={{ path: diff.file, type: "file" }} class="shrink-0 size-4" />
+ <div class="flex grow min-w-0">
+ <Show when={diff.file.includes("/")}>
+ <span class="text-text-base truncate-start">
+ {getDirectory(diff.file)}&lrm;
+ </span>
+ </Show>
+ <span class="text-text-strong shrink-0">{getFilename(diff.file)}</span>
+ </div>
+ </div>
+ <div class="shrink-0 flex gap-4 items-center justify-end">
+ <DiffChanges changes={diff} />
+ <Icon name="chevron-grabber-vertical" size="small" />
+ </div>
+ </div>
+ </Accordion.Trigger>
+ </Accordion.Header>
+ <Accordion.Content>
+ <Diff
+ before={{
+ name: diff.file!,
+ contents: diff.before!,
+ }}
+ after={{
+ name: diff.file!,
+ contents: diff.after!,
}}
/>
- </Tooltip>
- </div>
- </div>
- <div class="text-14-medium text-text-strong">All changes</div>
- <div class="h-full pb-40 overflow-y-auto no-scrollbar">
- <Accordion class="w-full" multiple>
- <For each={session.diffs()}>
- {(diff) => (
- <Accordion.Item value={diff.file} defaultOpen>
- <Accordion.Header>
- <Accordion.Trigger>
- <div class="flex items-center justify-between w-full gap-5">
- <div class="grow flex items-center gap-5 min-w-0">
- <FileIcon node={{ path: diff.file, type: "file" }} class="shrink-0 size-4" />
- <div class="flex grow min-w-0">
- <Show when={diff.file.includes("/")}>
- <span class="text-text-base truncate-start">
- {getDirectory(diff.file)}&lrm;
- </span>
- </Show>
- <span class="text-text-strong shrink-0">{getFilename(diff.file)}</span>
- </div>
- </div>
- <div class="shrink-0 flex gap-4 items-center justify-end">
- <DiffChanges changes={diff} />
- <Icon name="chevron-grabber-vertical" size="small" />
- </div>
- </div>
- </Accordion.Trigger>
- </Accordion.Header>
- <Accordion.Content>
- <Diff
- before={{
- name: diff.file!,
- contents: diff.before!,
- }}
- after={{
- name: diff.file!,
- contents: diff.after!,
- }}
- />
- </Accordion.Content>
- </Accordion.Item>
- )}
- </For>
- </Accordion>
- </div>
- </div>
- </Show>
+ </Accordion.Content>
+ </Accordion.Item>
+ )}
+ </For>
+ </Accordion>
</div>
- )
- }}
- </Show>
+ </div>
+ </Show>
+ </div>
</Tabs.Content>
<Show when={local.layout.review.state() === "tab" && session.diffs().length}>
<Tabs.Content value="review" class="select-text">