summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/pages/session
diff options
context:
space:
mode:
authorDavid Hill <[email protected]>2026-03-06 21:39:31 +0000
committerGitHub <[email protected]>2026-03-06 15:39:31 -0600
commit091cf25de8d95f0eae460f92b9f9adebc3b0e634 (patch)
tree4c75075388a39b0bc5734485964f788fb29a2689 /packages/app/src/pages/session
parent7a071eff5cfc94cc45095d0cee96acbb97317d8c (diff)
downloadopencode-091cf25de8d95f0eae460f92b9f9adebc3b0e634.tar.gz
opencode-091cf25de8d95f0eae460f92b9f9adebc3b0e634.zip
fix(app): better review/filetree empty states (#16221)
Co-authored-by: Adam <[email protected]>
Diffstat (limited to 'packages/app/src/pages/session')
-rw-r--r--packages/app/src/pages/session/session-side-panel.tsx68
1 files changed, 31 insertions, 37 deletions
diff --git a/packages/app/src/pages/session/session-side-panel.tsx b/packages/app/src/pages/session/session-side-panel.tsx
index ad802d15d..66d4382c0 100644
--- a/packages/app/src/pages/session/session-side-panel.tsx
+++ b/packages/app/src/pages/session/session-side-panel.tsx
@@ -87,6 +87,21 @@ export function SessionSidePanel(props: {
return out
})
+ const empty = (msg: string) => (
+ <div class="h-full flex flex-col">
+ <div class="h-12 shrink-0" aria-hidden />
+ <div class="flex-1 pb-30 flex items-center justify-center text-center">
+ <div class="text-12-regular text-text-weak">{msg}</div>
+ </div>
+ </div>
+ )
+
+ const nofiles = createMemo(() => {
+ const state = file.tree.state("")
+ if (!state?.loaded) return false
+ return file.tree.children("").length === 0
+ })
+
const normalizeTab = (tab: string) => {
if (!tab.startsWith("file://")) return tab
return file.tab(tab)
@@ -145,17 +160,8 @@ export function SessionSidePanel(props: {
const [store, setStore] = createStore({
activeDraggable: undefined as string | undefined,
- fileTreeScrolled: false,
})
- let changesEl: HTMLDivElement | undefined
- let allEl: HTMLDivElement | undefined
-
- const syncFileTreeScrolled = (el?: HTMLDivElement) => {
- const next = (el?.scrollTop ?? 0) > 0
- setStore("fileTreeScrolled", (current) => (current === next ? current : next))
- }
-
const handleDragStart = (event: unknown) => {
const id = getDraggableId(event)
if (!id) return
@@ -177,11 +183,6 @@ export function SessionSidePanel(props: {
}
createEffect(() => {
- if (!layout.fileTree.opened()) return
- syncFileTreeScrolled(fileTreeTab() === "changes" ? changesEl : allEl)
- })
-
- createEffect(() => {
if (!file.ready()) return
setSessionHandoff(sessionKey(), {
@@ -354,7 +355,7 @@ export function SessionSidePanel(props: {
class="h-full"
data-scope="filetree"
>
- <Tabs.List data-scrolled={store.fileTreeScrolled ? "" : undefined}>
+ <Tabs.List>
<Tabs.Trigger value="changes" class="flex-1" classes={{ button: "w-full" }}>
{reviewCount()}{" "}
{language.t(reviewCount() === 1 ? "session.review.change.one" : "session.review.change.other")}
@@ -363,12 +364,7 @@ export function SessionSidePanel(props: {
{language.t("session.files.all")}
</Tabs.Trigger>
</Tabs.List>
- <Tabs.Content
- value="changes"
- ref={(el: HTMLDivElement) => (changesEl = el)}
- onScroll={(e: UIEvent & { currentTarget: HTMLDivElement }) => syncFileTreeScrolled(e.currentTarget)}
- class="bg-background-stronger px-3 py-0"
- >
+ <Tabs.Content value="changes" class="bg-background-stronger px-3 py-0">
<Switch>
<Match when={hasReview()}>
<Show
@@ -382,6 +378,7 @@ export function SessionSidePanel(props: {
>
<FileTree
path=""
+ class="pt-3"
allowed={diffFiles()}
kinds={kinds()}
draggable={false}
@@ -390,26 +387,23 @@ export function SessionSidePanel(props: {
/>
</Show>
</Match>
+ <Match when={true}>{empty(language.t("session.review.noChanges"))}</Match>
+ </Switch>
+ </Tabs.Content>
+ <Tabs.Content value="all" class="bg-background-stronger px-3 py-0">
+ <Switch>
+ <Match when={nofiles()}>{empty(language.t("session.files.empty"))}</Match>
<Match when={true}>
- <div class="mt-8 text-center text-12-regular text-text-weak">
- {language.t("session.review.noChanges")}
- </div>
+ <FileTree
+ path=""
+ class="pt-3"
+ modified={diffFiles()}
+ kinds={kinds()}
+ onFileClick={(node) => openTab(file.tab(node.path))}
+ />
</Match>
</Switch>
</Tabs.Content>
- <Tabs.Content
- value="all"
- ref={(el: HTMLDivElement) => (allEl = el)}
- onScroll={(e: UIEvent & { currentTarget: HTMLDivElement }) => syncFileTreeScrolled(e.currentTarget)}
- class="bg-background-stronger px-3 py-0"
- >
- <FileTree
- path=""
- modified={diffFiles()}
- kinds={kinds()}
- onFileClick={(node) => openTab(file.tab(node.path))}
- />
- </Tabs.Content>
</Tabs>
</div>
<ResizeHandle