@@ -4,6 +4,7 @@ import { useSession } from "./hooks/useSession";
44import { usePicker } from "./hooks/usePicker" ;
55import { useCodexHomes } from "./hooks/useCodexHomes" ;
66import { useToggleSet } from "./hooks/useToggleSet" ;
7+ import { ThemeContext , useTheme } from "./hooks/useTheme" ;
78import { useKeyboard } from "./hooks/useKeyboard" ;
89import { SidebarTree } from "./components/SidebarTree" ;
910import { SessionPicker } from "./components/SessionPicker" ;
@@ -30,6 +31,7 @@ function findToolByCallId(tools: CodexToolCall[], callId: string): CodexToolCall
3031}
3132
3233export function App ( ) {
34+ const { theme, toggleTheme } = useTheme ( ) ;
3335 const [ view , setView ] = useState < ViewState > ( "homes" ) ;
3436 const [ selectedTurn , setSelectedTurn ] = useState ( 0 ) ;
3537 const [ pickerSelected , setPickerSelected ] = useState ( 0 ) ;
@@ -222,128 +224,132 @@ export function App() {
222224 } ) ;
223225
224226 return (
225- < div className = "app" >
226- { /* Info bar — only when session loaded and not in picker */ }
227- { session . sessionPath && view !== "picker" && session . session && (
228- < InfoBar session = { session . session } />
229- ) }
230-
231- { /* View toolbar */ }
232- < ViewToolbar
233- view = { view }
234- hasSession = { ! ! session . sessionPath }
235- activeHomeName = { codexHomes . activeHome ?. name ?? null }
236- canSwitchHomes = { codexHomes . homes . length > 1 }
237- canOpenSettings = { view !== "homes" && ! codexHomes . multiHomeEnabled }
238- onGoToSessions = { goToSessions }
239- onSwitchHomes = { ( ) => void handleSwitchHomes ( ) }
240- onExpandAll = { expandAll }
241- onCollapseAll = { collapseAll }
242- onOpenSettings = { ( ) => setShowSettings ( true ) }
243- />
244-
245- < div className = "app-body" >
246- { /* Left sidebar */ }
247- { view !== "homes" && (
248- < >
249- < div className = "app__sidebar" style = { { width : sidebarWidth , minWidth : sidebarWidth } } >
250- < div className = "app__sidebar-header" >
251- < span className = "app__sidebar-title" > SESSIONS</ span >
252- </ div >
253- < SidebarTree
254- sessions = { picker . allSessions }
255- selectedPath = { session . sessionPath || null }
256- collapsedDates = { collapsedDates }
257- onSelectSession = { handleSelectSession }
258- onToggleDate = { handleToggleDate }
259- />
260- </ div >
261-
262- < ResizeHandle onResize = { setSidebarWidth } />
263- </ >
227+ < ThemeContext . Provider value = { theme } >
228+ < div className = "app" >
229+ { /* Info bar — only when session loaded and not in picker */ }
230+ { session . sessionPath && view !== "picker" && session . session && (
231+ < InfoBar session = { session . session } />
264232 ) }
265233
266- { /* Main content */ }
267- < div className = "main-content" >
268- { view === "homes" && (
269- < CodexHomeSelector
270- homes = { codexHomes . homes }
271- loading = { codexHomes . loading }
272- error = { codexHomes . error }
273- selectedIndex = { codexHomes . selectedIndex }
274- onSelect = { ( home ) => void handleSelectHome ( home ) }
275- onRetry = { ( ) => void discoverHomes ( true ) }
276- />
277- ) }
278-
279- { view === "picker" && (
280- < SessionPicker
281- sessions = { picker . sessions }
282- loading = { picker . loading }
283- searchQuery = { picker . searchQuery }
284- selectedIndex = { pickerSelected }
285- onSelectSession = { handleSelectSession }
286- onSearchChange = { picker . setSearchQuery }
287- />
288- ) }
234+ { /* View toolbar */ }
235+ < ViewToolbar
236+ view = { view }
237+ hasSession = { ! ! session . sessionPath }
238+ activeHomeName = { codexHomes . activeHome ?. name ?? null }
239+ canSwitchHomes = { codexHomes . homes . length > 1 }
240+ canOpenSettings = { view !== "homes" && ! codexHomes . multiHomeEnabled }
241+ onGoToSessions = { goToSessions }
242+ onSwitchHomes = { ( ) => void handleSwitchHomes ( ) }
243+ onExpandAll = { expandAll }
244+ onCollapseAll = { collapseAll }
245+ onOpenSettings = { ( ) => setShowSettings ( true ) }
246+ theme = { theme }
247+ onToggleTheme = { toggleTheme }
248+ />
289249
290- { view === "list" && session . loading && (
291- < div className = "app__loading" > Loading session…</ div >
292- ) }
250+ < div className = "app-body" >
251+ { /* Left sidebar */ }
252+ { view !== "homes" && (
253+ < >
254+ < div className = "app__sidebar" style = { { width : sidebarWidth , minWidth : sidebarWidth } } >
255+ < div className = "app__sidebar-header" >
256+ < span className = "app__sidebar-title" > SESSIONS</ span >
257+ </ div >
258+ < SidebarTree
259+ sessions = { picker . allSessions }
260+ selectedPath = { session . sessionPath || null }
261+ collapsedDates = { collapsedDates }
262+ onSelectSession = { handleSelectSession }
263+ onToggleDate = { handleToggleDate }
264+ />
265+ </ div >
293266
294- { view === "list" && ! session . loading && session . session && (
295- < TurnList
296- turns = { turns }
297- selectedIndex = { selectedTurn }
298- onSelectTurn = { ( i ) => {
299- setSelectedTurn ( i ) ;
300- setView ( "detail" ) ;
301- } }
302- />
267+ < ResizeHandle onResize = { setSidebarWidth } />
268+ </ >
303269 ) }
304270
305- { view === "detail" && turns [ selectedTurn ] && (
306- < TurnDetail
307- turn = { turns [ selectedTurn ] }
308- expanded = { expandedTools }
309- onToggle = { toggleTool }
310- onBack = { ( ) => setView ( "list" ) }
311- openWorkerCallId = { workerPanelCallId }
312- onOpenWorkerPanel = { handleOpenWorkerPanel }
313- />
271+ { /* Main content */ }
272+ < div className = "main-content" >
273+ { view === "homes" && (
274+ < CodexHomeSelector
275+ homes = { codexHomes . homes }
276+ loading = { codexHomes . loading }
277+ error = { codexHomes . error }
278+ selectedIndex = { codexHomes . selectedIndex }
279+ onSelect = { ( home ) => void handleSelectHome ( home ) }
280+ onRetry = { ( ) => void discoverHomes ( true ) }
281+ />
282+ ) }
283+
284+ { view === "picker" && (
285+ < SessionPicker
286+ sessions = { picker . sessions }
287+ loading = { picker . loading }
288+ searchQuery = { picker . searchQuery }
289+ selectedIndex = { pickerSelected }
290+ onSelectSession = { handleSelectSession }
291+ onSearchChange = { picker . setSearchQuery }
292+ />
293+ ) }
294+
295+ { view === "list" && session . loading && (
296+ < div className = "app__loading" > Loading session…</ div >
297+ ) }
298+
299+ { view === "list" && ! session . loading && session . session && (
300+ < TurnList
301+ turns = { turns }
302+ selectedIndex = { selectedTurn }
303+ onSelectTurn = { ( i ) => {
304+ setSelectedTurn ( i ) ;
305+ setView ( "detail" ) ;
306+ } }
307+ />
308+ ) }
309+
310+ { view === "detail" && turns [ selectedTurn ] && (
311+ < TurnDetail
312+ turn = { turns [ selectedTurn ] }
313+ expanded = { expandedTools }
314+ onToggle = { toggleTool }
315+ onBack = { ( ) => setView ( "list" ) }
316+ openWorkerCallId = { workerPanelCallId }
317+ onOpenWorkerPanel = { handleOpenWorkerPanel }
318+ />
319+ ) }
320+ </ div >
321+
322+ { view === "detail" && workerPanelTool ?. worker_session && (
323+ < >
324+ < ResizeHandle onResize = { setWorkerPanelWidth } side = "right" />
325+ < WorkerPanel
326+ session = { workerPanelTool . worker_session }
327+ sourceTool = { workerPanelTool }
328+ activeWorkerCallId = { workerPanelCallId }
329+ style = { { flex : `0 0 ${ workerPanelWidth } px` , maxWidth : workerPanelWidth } }
330+ onClose = { closeWorkerPanel }
331+ onOpenWorker = { handleOpenWorkerPanel }
332+ />
333+ </ >
314334 ) }
315335 </ div >
316336
317- { view === "detail" && workerPanelTool ?. worker_session && (
318- < >
319- < ResizeHandle onResize = { setWorkerPanelWidth } side = "right" />
320- < WorkerPanel
321- session = { workerPanelTool . worker_session }
322- sourceTool = { workerPanelTool }
323- activeWorkerCallId = { workerPanelCallId }
324- style = { { flex : `0 0 ${ workerPanelWidth } px` , maxWidth : workerPanelWidth } }
325- onClose = { closeWorkerPanel }
326- onOpenWorker = { handleOpenWorkerPanel }
327- />
328- </ >
337+ { /* Bottom keybind bar */ }
338+ < KeybindBar
339+ view = { view }
340+ showHints = { showKeybinds }
341+ onToggle = { ( ) => setShowKeybinds ( ( p ) => ! p ) }
342+ />
343+
344+ { showSettings && ! codexHomes . multiHomeEnabled && (
345+ < SettingsModal
346+ onClose = { ( ) => setShowSettings ( false ) }
347+ onSaved = { ( dir ) => {
348+ discoverSessions ( dir ) ;
349+ } }
350+ />
329351 ) }
330352 </ div >
331-
332- { /* Bottom keybind bar */ }
333- < KeybindBar
334- view = { view }
335- showHints = { showKeybinds }
336- onToggle = { ( ) => setShowKeybinds ( ( p ) => ! p ) }
337- />
338-
339- { showSettings && ! codexHomes . multiHomeEnabled && (
340- < SettingsModal
341- onClose = { ( ) => setShowSettings ( false ) }
342- onSaved = { ( dir ) => {
343- discoverSessions ( dir ) ;
344- } }
345- />
346- ) }
347- </ div >
353+ </ ThemeContext . Provider >
348354 ) ;
349355}
0 commit comments