Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ const App: Component = () => {
binaryPath: string
instanceId: string
} | null>(null)

const phoneQuery = useMediaQuery("(max-width: 767px)")
const isPhoneLayout = createMemo(() => phoneQuery())

Expand Down
180 changes: 101 additions & 79 deletions packages/ui/src/components/instance/instance-shell2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,50 @@ const InstanceShell2: Component<InstanceShellProps> = (props) => {
}

const showingInfoView = createMemo(() => activeSessionIdForInstance() === "info")
const activeSessionTitle = createMemo(() => {
if (showingInfoView()) return null
const title = activeSessionForInstance()?.title?.trim()
return title || t("sessionList.session.untitled")
})
const showHeaderLeftSlot = createMemo(() => !leftPinned())
const showHeaderSessionTitle = createMemo(() => showHeaderLeftSlot() && Boolean(activeSessionTitle()))
const headerToolbarHorizontalInset = createMemo(() => (isPhoneLayout() ? 16 : 24))
const headerLeftSlotWidth = createMemo(() => Math.max(0, sessionSidebarWidth() - headerToolbarHorizontalInset()))
const headerLeftSlotStyle = createMemo(() =>
leftDrawerState() === "floating-open" || showHeaderSessionTitle() ? { width: `${headerLeftSlotWidth()}px` } : undefined,
)

const renderActiveSessionHeaderTitle = () => (
<Show when={showHeaderSessionTitle()}>
<div
class="session-header-active-title"
dir="auto"
title={activeSessionTitle() ?? undefined}
>
<span class="session-header-active-title-text">{activeSessionTitle()}</span>
</div>
</Show>
)

const renderHeaderLeftSlot = () => (
<Show when={showHeaderLeftSlot()}>
<div class="session-header-left-slot" style={headerLeftSlotStyle()}>
<Show when={leftDrawerState() === "floating-closed"}>
<IconButton
ref={setLeftToggleButtonEl}
color="inherit"
onClick={handleLeftAppBarButtonClick}
aria-label={leftAppBarButtonLabel()}
size="small"
aria-expanded={leftDrawerState() !== "floating-closed"}
>
{leftAppBarButtonIcon()}
</IconButton>
</Show>
{renderActiveSessionHeaderTitle()}
</div>
</Show>
)

const isLaunching = createMemo(() => props.instance.status === "starting")

Expand Down Expand Up @@ -926,33 +970,56 @@ const InstanceShell2: Component<InstanceShellProps> = (props) => {
fallback={
<div class="flex flex-col w-full gap-1.5">
<div class="flex flex-wrap items-center justify-between gap-2 w-full">
<Show when={leftDrawerState() === "floating-closed"}>
<IconButton
ref={setLeftToggleButtonEl}
color="inherit"
onClick={handleLeftAppBarButtonClick}
aria-label={leftAppBarButtonLabel()}
size="small"
aria-expanded={leftDrawerState() !== "floating-closed"}
>
{leftAppBarButtonIcon()}
</IconButton>
</Show>
{renderHeaderLeftSlot()}

<div class="flex-1 flex items-center justify-center min-w-0">
{renderSessionHeaderIndicators()}
</div>
<div class="flex-1 flex items-center justify-center min-w-0">
{renderSessionHeaderIndicators()}
</div>

<div class="flex flex-wrap items-center justify-center gap-1">
<Show when={!showingInfoView()}>
<div class="flex flex-wrap items-center justify-center gap-1">
<Show when={!showingInfoView()}>
<IconButton
color="inherit"
onClick={handleChatSearchClick}
aria-label={t("instanceShell.chatSearch.openAriaLabel")}
title={t("instanceShell.chatSearch.openAriaLabel")}
size="small"
>
<Search class="w-5 h-5" aria-hidden="true" />
</IconButton>
</Show>
<button
type="button"
class="connection-status-button command-palette-button"
onClick={handleCommandPaletteClick}
aria-label={t("instanceShell.commandPalette.openAriaLabel")}
style={{ flex: "0 0 auto", width: "auto" }}
>
{t("instanceShell.commandPalette.button")}
</button>
<span class="connection-status-shortcut-hint kbd-hint">
<Kbd shortcut="cmd+shift+p" />
</span>
</div>

<div class="flex-1 flex items-center justify-center min-w-0">
<span
class={`status-indicator ${connectionStatusClass()}`}
aria-label={t("instanceShell.connection.ariaLabel", { status: connectionStatusLabel() })}
>
<span class="status-dot" />
</span>
</div>

<Show when={isPhoneLayout() && !props.mobileFullscreenMode}>
<IconButton
color="inherit"
onClick={handleChatSearchClick}
aria-label={t("instanceShell.chatSearch.openAriaLabel")}
title={t("instanceShell.chatSearch.openAriaLabel")}
onClick={props.onEnterMobileFullscreen}
aria-label={t("instanceShell.fullscreen.enter")}
title={t("instanceShell.fullscreen.enter")}
size="small"
>
<Search class="w-5 h-5" aria-hidden="true" />
<Maximize2 class="w-5 h-5" aria-hidden="true" />
</IconButton>
<IconButton
color="inherit"
Expand All @@ -967,53 +1034,19 @@ const InstanceShell2: Component<InstanceShellProps> = (props) => {
})()}
</IconButton>
</Show>
<button
type="button"
class="connection-status-button command-palette-button"
onClick={handleCommandPaletteClick}
aria-label={t("instanceShell.commandPalette.openAriaLabel")}
style={{ flex: "0 0 auto", width: "auto" }}
>
{t("instanceShell.commandPalette.button")}
</button>
<span class="connection-status-shortcut-hint kbd-hint">
<Kbd shortcut="cmd+shift+p" />
</span>
</div>

<div class="flex-1 flex items-center justify-center min-w-0">
<span
class={`status-indicator ${connectionStatusClass()}`}
aria-label={t("instanceShell.connection.ariaLabel", { status: connectionStatusLabel() })}
>
<span class="status-dot" />
</span>
</div>

<Show when={isPhoneLayout() && !props.mobileFullscreenMode}>
<IconButton
color="inherit"
onClick={props.onEnterMobileFullscreen}
aria-label={t("instanceShell.fullscreen.enter")}
title={t("instanceShell.fullscreen.enter")}
size="small"
>
<Maximize2 class="w-5 h-5" aria-hidden="true" />
</IconButton>
</Show>

<Show when={rightDrawerState() === "floating-closed"}>
<IconButton
ref={setRightToggleButtonEl}
color="inherit"
onClick={handleRightAppBarButtonClick}
aria-label={rightAppBarButtonLabel()}
size="small"
aria-expanded={rightDrawerState() !== "floating-closed"}
>
{rightAppBarButtonIcon()}
</IconButton>
</Show>
<Show when={rightDrawerState() === "floating-closed"}>
<IconButton
ref={setRightToggleButtonEl}
color="inherit"
onClick={handleRightAppBarButtonClick}
aria-label={rightAppBarButtonLabel()}
size="small"
aria-expanded={rightDrawerState() !== "floating-closed"}
>
{rightAppBarButtonIcon()}
</IconButton>
</Show>
</div>

<div class="flex flex-wrap items-center justify-center gap-2 pb-1">
Expand All @@ -1031,18 +1064,7 @@ const InstanceShell2: Component<InstanceShellProps> = (props) => {
}
>
<div class="session-toolbar-left flex-1 flex items-center gap-3 min-w-0">
<Show when={leftDrawerState() === "floating-closed"}>
<IconButton
ref={setLeftToggleButtonEl}
color="inherit"
onClick={handleLeftAppBarButtonClick}
aria-label={leftAppBarButtonLabel()}
size="small"
aria-expanded={leftDrawerState() !== "floating-closed"}
>
{leftAppBarButtonIcon()}
</IconButton>
</Show>
{renderHeaderLeftSlot()}

<Show when={!showingInfoView()}>
<ContextMeter
Expand Down
26 changes: 26 additions & 0 deletions packages/ui/src/styles/panels/session-layout.css
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,32 @@
color: var(--text-primary);
}

.session-header-left-slot {
@apply flex items-center gap-2 min-w-0;
flex: 0 0 auto;
}

.session-header-active-title {
display: flex;
align-items: center;
flex: 1 1 auto;
min-width: 0;
align-self: stretch;
padding-inline: 0.75rem;
border-inline: 1px solid color-mix(in oklab, var(--border-base) 72%, transparent);
color: var(--text-secondary);
}

.session-header-active-title-text {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
font-size: 0.8125rem;
font-weight: 500;
line-height: 1.15;
}

.session-sidebar-shortcuts {
@apply flex flex-col gap-1;
}
Expand Down
Loading