Skip to content
Merged
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
45 changes: 37 additions & 8 deletions apps/web/src/components/AppShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export function AppShell() {
const railCollapsed = useWorkspace((state) => state.railCollapsed);
const railWidth = useWorkspace((state) => state.railWidth);
const railOverlayOpen = useWorkspace((state) => state.railOverlayOpen);
const focusMode = useWorkspace((state) => state.focusMode);
const sessionListView = useWorkspace((state) => state.sessionListView);
const projectExpandedById = useWorkspace((state) => state.projectExpandedById);
const dismissedEmptyProjectIds = useWorkspace((state) => state.dismissedEmptyProjectIds);
Expand Down Expand Up @@ -105,7 +106,12 @@ export function AppShell() {
// Dialog-based surfaces (palette, sheets) close themselves; the
// docked pane is plain layout, so Escape peels it here.
const state = workspaceStore.getState();
if (state.paletteOpen || state.railOverlayOpen) return;
if (state.paletteOpen || (state.railOverlayOpen && !state.focusMode)) return;
if (state.focusMode) {
state.setFocusMode(false);
event.preventDefault();
return;
}
const activeId = state.activeSessionId;
if (activeId !== null && selectSessionView(state, activeId).paneOpen) {
state.setPaneOpen(activeId, false);
Expand All @@ -123,8 +129,26 @@ export function AppShell() {
if (action.kind === "palette") {
state.setPaletteOpen(!state.paletteOpen);
} else if (action.kind === "toggle-rail") {
if (railOverlaid) state.setRailOverlayOpen(!state.railOverlayOpen);
if (state.focusMode) {
state.setFocusMode(false);
state.setRailCollapsed(false);
} else if (railOverlaid) state.setRailOverlayOpen(!state.railOverlayOpen);
else state.setRailCollapsed(!state.railCollapsed);
} else if (action.kind === "toggle-terminal") {
const activeId = state.activeSessionId;
const activeSession =
activeId === null ? undefined : getShellData().sessions.find((session) => session.id === activeId);
if (activeId !== null && activeSession?.archivedAt === undefined) {
const view = selectSessionView(state, activeId);
if (state.focusMode) {
state.setFocusMode(false);
state.setTerminalDrawerOpen(activeId, true);
} else {
state.setTerminalDrawerOpen(activeId, !view.terminalDrawerOpen);
}
}
} else if (action.kind === "toggle-focus") {
state.setFocusMode(!state.focusMode);
} else if (action.kind === "settings") {
void navigate({ to: "/settings" });
} else {
Expand Down Expand Up @@ -153,24 +177,29 @@ export function AppShell() {
const railToggle = resolveRailTogglePresentation({
overlaid: railOverlaid,
overlayOpen: railOverlayOpen,
collapsed: railCollapsed,
collapsed: railCollapsed || focusMode,
});

return (
<div className="flex h-full min-h-0 min-w-0 max-w-full flex-col overflow-x-hidden bg-background text-foreground">
<Titlebar
focusMode={focusMode}
onExitFocus={() => workspaceStore.getState().setFocusMode(false)}
onToggleRail={() => {
const state = workspaceStore.getState();
if (railOverlaid) state.setRailOverlayOpen(!state.railOverlayOpen);
if (state.focusMode) {
state.setFocusMode(false);
state.setRailCollapsed(false);
} else if (railOverlaid) state.setRailOverlayOpen(!state.railOverlayOpen);
else state.setRailCollapsed(!state.railCollapsed);
}}
railToggle={railToggle}
/>
<div className="flex min-h-0 flex-1">
{!railOverlaid && (
{!railOverlaid && !focusMode && (
<>
<div
className="rail-dock flex h-full shrink-0 flex-col overflow-hidden bg-background"
className="rail-dock flex h-full shrink-0 flex-col overflow-hidden border-border/60 border-r bg-(--sidebar-background)"
style={{ width: railCollapsed ? RAIL_COLLAPSED_WIDTH : effectiveRailWidth }}
>
{railCollapsed ? (
Expand Down Expand Up @@ -219,7 +248,7 @@ export function AppShell() {
{railOverlaid && (
<Sheet
onOpenChange={(open) => workspaceStore.getState().setRailOverlayOpen(open)}
open={railOverlayOpen}
open={railOverlayOpen && !focusMode}
>
<SheetPopup
aria-label="Working folders and sessions"
Expand All @@ -229,7 +258,7 @@ export function AppShell() {
>
<div className="flex h-14 shrink-0 items-center border-border border-b px-3">
<SheetTitle className="text-sm">
<span aria-hidden="true">Sessions</span>
<span aria-hidden="true">T4 Code</span>
<span className="sr-only">Working folders and sessions</span>
</SheetTitle>
<SheetClose
Expand Down
Loading
Loading