Skip to content

fix(frontend): make chat focus mode fullscreen#2578

Merged
rmusser01 merged 2 commits into
devfrom
codex/chat-focus-fullscreen
Jul 3, 2026
Merged

fix(frontend): make chat focus mode fullscreen#2578
rmusser01 merged 2 commits into
devfrom
codex/chat-focus-fullscreen

Conversation

@rmusser01

@rmusser01 rmusser01 commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Change summary

  • Added a shared OptionLayout shell override hook so route content can request the app header/sidebar be hidden without rendering a nested layout shell.
  • Wired chat focus mode to hide app shell chrome, cockpit rails, the top focus/shortcut/status strip, comparison breadcrumbs, and artifacts rail surfaces.
  • Added a fixed Exit focus control that returns the chat to cockpit mode.
  • Added regression coverage for the shell override hook and focus-mode UX.

Verification

  • bun run test:run ../packages/ui/src/components/Layouts/__tests__/Layout.shell-overrides.test.tsx ../packages/ui/src/components/Option/Playground/__tests__/Playground.cockpit-controls.test.tsx - 22 tests passed.
  • Browser verification on http://127.0.0.1:18001/chat: focus mode hides header/sidebar, chat sidebar, context/runtime rails, and top focus/shortcut controls while keeping transcript, composer, and Exit focus.
  • bun run typecheck still fails on existing unrelated baseline errors in AudioStudio, ScheduledTasks, Skills, scheduled-tasks services, MCP hub path typing, voice-cloning ArrayBuffer typing, knowledge QA fixtures, and flashcards E2E. No touched file appears in the rerun.

Notes

Bandit skipped because this touches frontend TypeScript/TSX tests and Markdown only.


Summary by cubic

Make chat focus mode truly fullscreen by hiding app chrome and cockpit rails, with a clear exit control. Export a shared shell override hook so routes can hide header/sidebar across shells without nesting; meets TASK-12115.

  • New Features
    • Added useOptionLayoutShellOverrides to let route content request hideHeader/hideSidebar across shells, and to clear the same setter on unmount/navigation; added tests for apply/cleanup and route-driven overrides.
    • Focus mode now shows only the chat transcript and composer; hides header, sidebar, chat sidebar, context/runtime rails, artifacts surfaces, top focus/shortcut strip, and breadcrumbs.
    • Added a fixed “Exit focus” button that returns to cockpit mode and clears shell overrides without losing state.

Written for commit 763c4e7. Summary will update on new commits.

Review in cubic

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed It clearly and concisely summarizes the main change: making chat focus mode fullscreen.
Description check ✅ Passed It covers the change, motivation, and verification, though it doesn't follow the template headings exactly.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/chat-focus-fullscreen

Comment @coderabbitai help to get the list of available commands.

@rmusser01 rmusser01 force-pushed the codex/chat-focus-fullscreen branch from 7c49496 to c62e5ad Compare July 3, 2026 01:43
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

fix(frontend): make chat focus mode fullscreen

🐞 Bug fix 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Add a shared hook to request OptionLayout shell chrome hiding from route content.
• Make chat focus mode hide header/sidebar, cockpit rails, and non-chat UI surfaces.
• Add a fixed “Exit focus” control and regression tests for the new behavior.
Diagram

graph TD
  A["Playground (Chat)"] --> B["focusModeActive"] --> C["useOptionLayoutShellOverrides"] --> D["Layout shell context"] --> E["Global shell (__tldwOptionShell)"] --> F["Header/Sidebar hidden"]
  B --> G["Focus-only UI"]
  G --> H["Exit focus button"]
  H --> A
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Route-level OptionLayout props only (nested layout)
  • ➕ No new exported hook/API surface
  • ➕ Keeps override logic entirely within OptionLayout rendering
  • ➖ Requires rendering a nested layout shell for route content
  • ➖ Harder to reuse across shells and deeper route trees
2. Router metadata / central UI store for shell chrome
  • ➕ Single source of truth for shell chrome state
  • ➕ Can be extended to other routes without per-component hooks
  • ➖ More architectural overhead and coupling to routing/store
  • ➖ Higher risk of stale state if not tied to component lifecycle cleanup

Recommendation: The hook-based approach is the best fit here: it reuses the existing override channel, keeps lifecycle cleanup automatic via React effects, and avoids the heavier architectural cost of central router/store-driven chrome state. The nested-layout-only approach was likely simplest but would keep forcing extra layout shells just to request chrome hiding.

Files changed (6) +245 / -32

Enhancement (1) +29 / -19
Layout.tsxExport shell override hook for OptionLayout consumers +29/-19

Export shell override hook for OptionLayout consumers

• Adds an exported 'useOptionLayoutShellOverrides' hook that allows route content to request 'hideHeader'/'hideSidebar' without rendering a nested OptionLayout shell. Refactors the existing nested layout content to call the hook using props-derived override requests.

apps/packages/ui/src/components/Layouts/Layout.tsx

Bug fix (1) +41 / -11
Playground.tsxMake focus mode fullscreen and add fixed Exit focus control +41/-11

Make focus mode fullscreen and add fixed Exit focus control

• Wires focus mode to call 'useOptionLayoutShellOverrides' so the app header/sidebar are hidden while focusing. Hides cockpit-only UI surfaces (top strips, breadcrumbs, artifacts rail controls) and adds a fixed “Exit focus” button that returns to cockpit mode.

apps/packages/ui/src/components/Option/Playground/Playground.tsx

Tests (2) +81 / -2
Layout.shell-overrides.test.tsxTest route-content shell override requests +47/-2

Test route-content shell override requests

• Extends shell override tests to verify that route content can call the new hook and drive '__tldwOptionShell.setOverrides' with 'hideHeader'/'hideSidebar' plus 'sourcePath'. Verifies cleanup behavior on unmount (overrides reset to null).

apps/packages/ui/src/components/Layouts/tests/Layout.shell-overrides.test.tsx

Playground.cockpit-controls.test.tsxAdd regression coverage for focus-mode fullscreen UX +34/-0

Add regression coverage for focus-mode fullscreen UX

• Mocks the new layout hook to capture requested overrides and asserts focus mode requests header/sidebar hiding. Verifies cockpit controls are hidden in focus mode, asserts the Exit focus control is present, and confirms clicking it returns layout mode to cockpit.

apps/packages/ui/src/components/Option/Playground/tests/Playground.cockpit-controls.test.tsx

Documentation (2) +94 / -0
2026-07-03-chat-focus-fullscreen.mdAdd staged implementation plan for fullscreen chat focus mode +27/-0

Add staged implementation plan for fullscreen chat focus mode

• Introduces a step-by-step plan capturing regression-first testing, the shared shell override hook, focus-mode UX, and verification steps. Serves as a written checklist for implementation and validation.

Docs/superpowers/plans/2026-07-03-chat-focus-fullscreen.md

task-12115 - Make-chat-focus-mode-truly-fullscreen.mdDocument task, acceptance criteria, and verification evidence +67/-0

Document task, acceptance criteria, and verification evidence

• Adds a backlog task capturing the problem statement, acceptance criteria, and verification notes (targeted tests and browser checks). Links to the implementation plan and records known unrelated typecheck baseline failures.

backlog/tasks/task-12115 - Make-chat-focus-mode-truly-fullscreen.md

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements a truly fullscreen chat focus mode by introducing a shared useOptionLayoutShellOverrides hook to hide the application header and sidebar shell chrome. In the Playground, focus mode now hides cockpit rails, artifacts panels, and shortcut strips, leaving only the chat transcript, composer, and a new 'Exit focus' button. The review feedback suggests minor improvements: destructuring properties in the new hook to clean up the useMemo dependency array, using the dynamic focusModeActive state instead of a hardcoded false for the aria-pressed attribute, and adding an assertion in the tests to verify that overrides are cleared upon exiting focus mode.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread apps/packages/ui/src/components/Layouts/Layout.tsx Outdated
Comment thread apps/packages/ui/src/components/Option/Playground/Playground.tsx Outdated
@qodo-code-review

qodo-code-review Bot commented Jul 3, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 74 rules

Grey Divider


Remediation recommended

1. bun run typecheck still fails ✗ Dismissed 📘 Rule violation ≡ Correctness
Description
The PR adds documentation stating that bun run typecheck is currently failing, which indicates the
standard compile/typecheck step is not green. If typecheck is part of the project’s required
build/test gate, this violates the requirement that changes compile and all existing tests pass.
Code

backlog/tasks/task-12115 - Make-chat-focus-mode-truly-fullscreen.md[42]

+Known skip/failure: bun run typecheck still fails on existing unrelated files (AudioStudio TimelineEditor referrerPolicy, ScheduledTasks response typing, Skills Checkbox props, scheduled-tasks service params, mcp-hub path typing, voice-cloning ArrayBuffer, knowledge QA fixture assertions, flashcards E2E never callable). The touched Playground type error found during the first typecheck was fixed and absent in the rerun.
Evidence
Rule 380650 requires that changes compile and all existing tests pass. The newly added task note
explicitly states bun run typecheck still fails, indicating the build/typecheck step is not
passing.

Rule 380650: Changes must compile and all existing tests must pass
backlog/tasks/task-12115 - Make-chat-focus-mode-truly-fullscreen.md[42-42]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The PR documents that `bun run typecheck` fails; if typecheck is a required gate, the change set is not compliant until typecheck is green.

## Issue Context
The note claims failures are unrelated baseline errors, but the compliance requirement is that changes compile and tests pass.

## Fix Focus Areas
- backlog/tasks/task-12115 - Make-chat-focus-mode-truly-fullscreen.md[42-42]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Wrong shell cleanup ✓ Resolved 🐞 Bug ☼ Reliability
Description
useOptionLayoutShellOverrides resolves the overrides setter again during effect cleanup instead of
using the exact setter that was used when applying overrides, so if the mutable global shell swaps
owners/setters, cleanup can clear a different shell’s overrides. This can cause cross-route UI
chrome to unexpectedly reappear/disappear during navigation or shell remounts.
Code

apps/packages/ui/src/components/Layouts/Layout.tsx[R695-696]

  React.useEffect(() => {
    if (!requestedOverrides) return
Evidence
The hook’s cleanup recomputes setOverrides from the (mutable) context/global singleton at cleanup
time, which can differ from the setter used during apply if the global shell swaps owners; this is
exactly the situation the existing global-shell ownerId/mounted mechanism enables. In contrast,
WebLayout’s nested override logic captures setOverrides once and uses that captured function in
cleanup, preventing clearing a different shell’s overrides.

apps/packages/ui/src/components/Layouts/Layout.tsx[695-720]
apps/tldw-frontend/components/layout/WebLayout.tsx[700-705]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`useOptionLayoutShellOverrides` applies overrides using `shell.setOverrides || globalShell?.setOverrides`, but in the cleanup it recomputes the setter from `shell/globalShell` again. Because `globalShell` is a shared mutable singleton whose `setOverrides` can be replaced when a new shell owner mounts, cleanup may call `setOverrides(null)` on a different (new) shell than the one that was originally overridden.

## Issue Context
This hook is exported for use by route content, increasing the likelihood it will be used across layout boundaries where the global shell setter can change. There is a safer pattern elsewhere in the repo (`WebLayout.tsx`) that captures the setter once and uses that same function in cleanup.

## Fix Focus Areas
- apps/packages/ui/src/components/Layouts/Layout.tsx[695-720]

### Suggested implementation approach
- When overrides are successfully applied, capture the exact `setOverrides` function used (e.g., into a `useRef` or local variable closed over by cleanup).
- In cleanup, call `capturedSetOverrides(null)` (optionally only if it still matches `shell.setOverrides` or `globalShell.setOverrides`) rather than re-resolving from `shell/globalShell`.
- Keep the existing `appliedOverrides` guard so you don’t clear if nothing was applied.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread backlog/tasks/task-12115 - Make-chat-focus-mode-truly-fullscreen.md Outdated
Comment thread apps/packages/ui/src/components/Layouts/Layout.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backlog/tasks/task-12115` - Make-chat-focus-mode-truly-fullscreen.md:
- Around line 57-59: The task document has duplicate final-summary end markers,
leaving the section tags unbalanced. Update the final summary area to keep
exactly one matching FINAL_SUMMARY:END for the existing FINAL_SUMMARY:BEGIN
block, and remove the extra repeated end markers in the same section so the
marker structure is consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5a1f8a2d-212f-4488-a03b-b7e094d9548a

📥 Commits

Reviewing files that changed from the base of the PR and between 6eb3330 and c62e5ad.

⛔ Files ignored due to path filters (1)
  • Docs/superpowers/plans/2026-07-03-chat-focus-fullscreen.md is excluded by !docs/**
📒 Files selected for processing (5)
  • apps/packages/ui/src/components/Layouts/Layout.tsx
  • apps/packages/ui/src/components/Layouts/__tests__/Layout.shell-overrides.test.tsx
  • apps/packages/ui/src/components/Option/Playground/Playground.tsx
  • apps/packages/ui/src/components/Option/Playground/__tests__/Playground.cockpit-controls.test.tsx
  • backlog/tasks/task-12115 - Make-chat-focus-mode-truly-fullscreen.md

Comment thread backlog/tasks/task-12115 - Make-chat-focus-mode-truly-fullscreen.md Outdated
@rmusser01 rmusser01 merged commit 30c8460 into dev Jul 3, 2026
19 of 21 checks passed
@rmusser01 rmusser01 deleted the codex/chat-focus-fullscreen branch July 3, 2026 02:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant