From 1f11a8a6ea46867e2ad199c987bf14696a1b91d8 Mon Sep 17 00:00:00 2001
From: Adam <2363879+adamdotdevin@users.noreply.github.com>
Date: Thu, 15 Jan 2026 13:32:15 -0600
Subject: [PATCH] feat(app): improved session layout
---
packages/app/src/pages/layout.tsx | 140 ++++++++++++------
packages/app/src/pages/session.tsx | 20 +--
.../enterprise/src/routes/share/[shareID].tsx | 21 +--
packages/ui/src/components/hover-card.css | 5 +-
packages/ui/src/components/message-nav.css | 4 +
packages/ui/src/components/message-nav.tsx | 24 ++-
.../src/components/session-message-rail.css | 44 ------
.../src/components/session-message-rail.tsx | 46 ------
8 files changed, 121 insertions(+), 183 deletions(-)
delete mode 100644 packages/ui/src/components/session-message-rail.css
delete mode 100644 packages/ui/src/components/session-message-rail.tsx
diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx
index 39ca39b67..2f71570f4 100644
--- a/packages/app/src/pages/layout.tsx
+++ b/packages/app/src/pages/layout.tsx
@@ -28,13 +28,14 @@ import { IconButton } from "@opencode-ai/ui/icon-button"
import { InlineInput } from "@opencode-ai/ui/inline-input"
import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip"
import { HoverCard } from "@opencode-ai/ui/hover-card"
+import { MessageNav } from "@opencode-ai/ui/message-nav"
import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
import { Collapsible } from "@opencode-ai/ui/collapsible"
import { DiffChanges } from "@opencode-ai/ui/diff-changes"
import { Spinner } from "@opencode-ai/ui/spinner"
import { Dialog } from "@opencode-ai/ui/dialog"
import { getFilename } from "@opencode-ai/util/path"
-import { Session } from "@opencode-ai/sdk/v2/client"
+import { Session, type Message, type TextPart } from "@opencode-ai/sdk/v2/client"
import { usePlatform } from "@/context/platform"
import { createStore, produce, reconcile } from "solid-js/store"
import {
@@ -1329,63 +1330,104 @@ export default function Layout(props: ParentProps) {
return agent?.color
})
+ const hoverMessages = createMemo(() =>
+ sessionStore.message[props.session.id]?.filter((message) => message.role === "user"),
+ )
+ const hoverReady = createMemo(() => sessionStore.message[props.session.id] !== undefined)
+ const hoverAllowed = createMemo(() => !props.mobile && layout.sidebar.opened())
+ const isActive = createMemo(() => props.session.id === params.id)
+
+ const messageLabel = (message: Message) => {
+ const parts = sessionStore.part[message.id] ?? []
+ const text = parts.find((part): part is TextPart => part?.type === "text" && !part.synthetic && !part.ignored)
+ return text?.text
+ }
+
+ const item = (
+ prefetchSession(props.session, "high")}
+ onFocus={() => prefetchSession(props.session, "high")}
+ >
+