@@ -21,6 +21,9 @@ import { ABCompare } from './ABCompare'
2121import { useCompareStore } from '../../stores/compareStore'
2222import { exportConversation } from '../../lib/chat-export'
2323import { PermissionOverrideBar } from './PermissionOverrideBar'
24+ import { RealtimeCounter } from './RealtimeCounter'
25+ import { CodexView } from './CodexView'
26+ import { useCodexStore } from '../../stores/codexStore'
2427
2528export function ChatView ( ) {
2629 const { sendMessage, stopGeneration, isGenerating, isLoadingModel, regenerateMessage, editAndResend, pendingApproval, approveToolCall, rejectToolCall } = useChat ( )
@@ -37,6 +40,7 @@ export function ChatView() {
3740 const allPersonas = useSettingsStore ( ( s ) => s . personas )
3841 const thinkingEnabled = useSettingsStore ( ( s ) => s . settings . thinkingEnabled )
3942 const updateSettings = useSettingsStore ( ( s ) => s . updateSettings )
43+ const chatMode = useCodexStore ( ( s ) => s . chatMode )
4044
4145 const docCount = useRAGStore ( ( s ) =>
4246 activeConversationId ? ( s . documents [ activeConversationId ] || [ ] ) . length : 0
@@ -85,15 +89,23 @@ export function ChatView() {
8589 animate = { { opacity : 1 , y : 0 } }
8690 transition = { { duration : 0.25 , ease : 'easeOut' } }
8791 >
88- < div className = "flex-1 flex flex-col min-w-0" >
89- { /* Top bar — compact */ }
92+ < div className = "flex-1 flex flex-col min-w-0 relative" >
93+ { /* Codex mode */ }
94+ { chatMode === 'codex' ? (
95+ < CodexView />
96+ ) : chatMode === 'openclaw' ? (
97+ < div className = "flex-1 flex items-center justify-center" >
98+ < p className = "text-[0.7rem] text-gray-600" > OpenClaw — Coming Soon</ p >
99+ </ div >
100+ ) : ( < >
101+ { /* Top bar — compact (LU mode) */ }
90102 < div className = "flex items-center gap-1.5 px-2 pt-0.5" >
91103 { /* Left: Tools Active dropdown (only when agent is active) */ }
92104 { isAgentActive && (
93105 < div className = "relative" >
94106 < button
95107 onClick = { ( ) => setToolsDropdownOpen ( ! toolsDropdownOpen ) }
96- className = "flex items-center gap-1 px-2 py-0.5 rounded border border-white/[0.06] text-gray-500 hover:border-white/15 transition-colors text-[0.55rem]"
108+ className = "flex items-center gap-1 px-2 py-0.5 rounded border border-gray-200 dark:border- white/[0.06] text-gray-500 hover:border-gray-400 dark: hover:border-white/15 transition-colors text-[0.55rem]"
97109 >
98110 < Wrench size = { 9 } className = "text-green-400" />
99111 < span > Tools</ span >
@@ -102,7 +114,7 @@ export function ChatView() {
102114 { toolsDropdownOpen && (
103115 < >
104116 < div className = "fixed inset-0 z-40" onClick = { ( ) => setToolsDropdownOpen ( false ) } />
105- < div className = "absolute left-0 top-full mt-0.5 z-50 w-28 rounded-md bg-[#1a1a1a] border border-white/10 shadow-xl py-0.5 px-0.5" >
117+ < div className = "absolute left-0 top-full mt-0.5 z-50 w-28 rounded-md bg-white dark:bg- [#1a1a1a] border border-gray-200 dark: border-white/10 shadow-xl py-0.5 px-0.5" >
106118 < PermissionOverrideBar />
107119 </ div >
108120 </ >
@@ -116,7 +128,7 @@ export function ChatView() {
116128 className = { `flex items-center gap-1 px-2 py-0.5 rounded border transition-colors text-[0.55rem] ${
117129 thinkingEnabled
118130 ? 'border-blue-500/30 text-blue-400'
119- : 'border-white/[0.06] text-gray-600'
131+ : 'border-gray-200 dark:border- white/[0.06] text-gray-600'
120132 } `}
121133 title = "Toggle thinking mode — model reasons before answering"
122134 >
@@ -137,15 +149,15 @@ export function ChatView() {
137149 < div className = "relative" >
138150 < button
139151 onClick = { ( ) => setExportOpen ( ! exportOpen ) }
140- className = "flex items-center gap-1 px-2 py-0.5 rounded border border-white/[0.06] hover:border-white/15 text-gray-500 transition-colors text-[0.55rem]"
152+ className = "flex items-center gap-1 px-2 py-0.5 rounded border border-gray-200 dark:border- white/[0.06] hover:border-gray-400 dark: hover:border-white/15 text-gray-500 transition-colors text-[0.55rem]"
141153 title = "Export chat"
142154 >
143155 < Download size = { 10 } />
144156 </ button >
145157 { exportOpen && (
146158 < >
147159 < div className = "fixed inset-0 z-40" onClick = { ( ) => setExportOpen ( false ) } />
148- < div className = "absolute right-0 top-full mt-1 z-50 w-32 rounded-lg bg-[#1a1a1a] border border-white/10 shadow-xl py-1" >
160+ < div className = "absolute right-0 top-full mt-1 z-50 w-32 rounded-lg bg-white dark:bg- [#1a1a1a] border border-gray-200 dark: border-white/10 shadow-xl py-1" >
149161 { ( [ 'markdown' , 'json' ] as const ) . map ( fmt => (
150162 < button
151163 key = { fmt }
@@ -168,7 +180,7 @@ export function ChatView() {
168180 < div className = "relative" >
169181 < button
170182 onClick = { ( ) => setPersonaOpen ( ! personaOpen ) }
171- className = "flex items-center gap-1 px-2 py-0.5 rounded border border-white/[0.06] hover:border-white/15 text-gray-500 transition-colors text-[0.55rem]"
183+ className = "flex items-center gap-1 px-2 py-0.5 rounded border border-gray-200 dark:border- white/[0.06] hover:border-gray-400 dark: hover:border-white/15 text-gray-500 transition-colors text-[0.55rem]"
172184 >
173185 < User size = { 10 } />
174186 < span className = "max-w-[60px] truncate" > { activePersona ?. name || 'No Filter' } </ span >
@@ -177,9 +189,9 @@ export function ChatView() {
177189 { personaOpen && (
178190 < >
179191 < div className = "fixed inset-0 z-40" onClick = { ( ) => setPersonaOpen ( false ) } />
180- < div className = "absolute right-0 top-full mt-1 z-50 w-44 max-h-[220px] overflow-y-auto scrollbar-thin rounded-lg bg-[#1a1a1a] border border-white/10 shadow-xl py-1" >
192+ < div className = "absolute right-0 top-full mt-1 z-50 w-44 max-h-[220px] overflow-y-auto scrollbar-thin rounded-lg bg-white dark:bg- [#1a1a1a] border border-gray-200 dark: border-white/10 shadow-xl py-1" >
181193 { activePersona && (
182- < div className = "px-2 pb-1 mb-1 border-b border-white/[0.06]" >
194+ < div className = "px-2 pb-1 mb-1 border-b border-gray-200 dark:border- white/[0.06]" >
183195 < div className = "px-2 py-1 rounded-md bg-white/[0.06] border border-white/10 text-[0.55rem] text-white font-medium flex items-center gap-1.5" >
184196 < div className = "w-1 h-1 rounded-full bg-green-400 shrink-0" />
185197 { activePersona . name }
@@ -207,7 +219,7 @@ export function ChatView() {
207219 'flex items-center gap-1 px-2 py-0.5 rounded border transition-colors text-[0.55rem] ' +
208220 ( ragPanelOpen || ragEnabled
209221 ? 'border-green-500/30 text-green-400'
210- : 'border-white/[0.06] hover:border-white/15 text-gray-500' )
222+ : 'border-gray-200 dark:border- white/[0.06] hover:border-gray-400 dark: hover:border-white/15 text-gray-500' )
211223 }
212224 title = "Document Chat (RAG)"
213225 >
@@ -231,7 +243,7 @@ export function ChatView() {
231243 ? 'border-green-500/30 text-green-400'
232244 : activeModel && ! isAgentCompatible ( activeModel )
233245 ? 'border-white/[0.04] text-gray-600 opacity-50'
234- : 'border-white/[0.06] text-gray-500' )
246+ : 'border-gray-200 dark:border- white/[0.06] text-gray-500' )
235247 } >
236248 < Bot size = { 10 } />
237249 < div className = "flex flex-col items-start leading-none" >
@@ -249,6 +261,7 @@ export function ChatView() {
249261 onRegenerate = { regenerateMessage }
250262 onEdit = { editAndResend }
251263 />
264+ < RealtimeCounter isRunning = { isGenerating } />
252265 < ChatInput
253266 onSend = { sendMessage }
254267 onStop = { stopGeneration }
@@ -257,6 +270,7 @@ export function ChatView() {
257270 onApprove = { approveToolCall }
258271 onReject = { rejectToolCall }
259272 />
273+ </ > ) }
260274 </ div >
261275
262276 { /* RAG Panel */ }
0 commit comments