11import { useSync } from "@tui/context/sync"
2- import { createMemo , For , Show , Switch , Match } from "solid-js"
2+ import { createMemo , For , Show , Switch , Match , createSignal } from "solid-js"
33import { useTheme } from "../../context/theme"
44import { Locale } from "@/util/locale"
55import path from "path"
@@ -13,6 +13,11 @@ export function Sidebar(props: { sessionID: string }) {
1313 const todo = createMemo ( ( ) => sync . data . todo [ props . sessionID ] ?? [ ] )
1414 const messages = createMemo ( ( ) => sync . data . message [ props . sessionID ] ?? [ ] )
1515
16+ const [ mcpExpanded , setMcpExpanded ] = createSignal ( true )
17+ const [ diffExpanded , setDiffExpanded ] = createSignal ( true )
18+ const [ todoExpanded , setTodoExpanded ] = createSignal ( true )
19+ const [ lspExpanded , setLspExpanded ] = createSignal ( true )
20+
1621 const cost = createMemo ( ( ) => {
1722 const total = messages ( ) . reduce ( ( sum , x ) => sum + ( x . role === "assistant" ? x . cost : 0 ) , 0 )
1823 return new Intl . NumberFormat ( "en-US" , {
@@ -55,110 +60,130 @@ export function Sidebar(props: { sessionID: string }) {
5560 </ box >
5661 < Show when = { Object . keys ( sync . data . mcp ) . length > 0 } >
5762 < box >
58- < text fg = { theme . text } >
59- < b > MCP</ b >
60- </ text >
61- < For each = { Object . entries ( sync . data . mcp ) } >
62- { ( [ key , item ] ) => (
63- < box flexDirection = "row" gap = { 1 } >
64- < text
65- flexShrink = { 0 }
66- style = { {
67- fg : {
68- connected : theme . success ,
69- failed : theme . error ,
70- disabled : theme . textMuted ,
71- } [ item . status ] ,
72- } }
73- >
74- •
75- </ text >
76- < text fg = { theme . text } wrapMode = "word" >
77- { key } { " " }
78- < span style = { { fg : theme . textMuted } } >
79- < Switch >
80- < Match when = { item . status === "connected" } > Connected</ Match >
81- < Match when = { item . status === "failed" && item } > { ( val ) => < i > { val ( ) . error } </ i > } </ Match >
82- < Match when = { item . status === "disabled" } > Disabled in configuration</ Match >
83- </ Switch >
84- </ span >
85- </ text >
86- </ box >
87- ) }
88- </ For >
63+ < box flexDirection = "row" gap = { 1 } onMouseDown = { ( ) => setMcpExpanded ( ! mcpExpanded ( ) ) } >
64+ < text fg = { theme . text } > { mcpExpanded ( ) ? "▼" : "▶" } </ text >
65+ < text fg = { theme . text } >
66+ < b > MCP</ b >
67+ </ text >
68+ </ box >
69+ < Show when = { mcpExpanded ( ) } >
70+ < For each = { Object . entries ( sync . data . mcp ) } >
71+ { ( [ key , item ] ) => (
72+ < box flexDirection = "row" gap = { 1 } >
73+ < text
74+ flexShrink = { 0 }
75+ style = { {
76+ fg : {
77+ connected : theme . success ,
78+ failed : theme . error ,
79+ disabled : theme . textMuted ,
80+ } [ item . status ] ,
81+ } }
82+ >
83+ •
84+ </ text >
85+ < text fg = { theme . text } wrapMode = "word" >
86+ { key } { " " }
87+ < span style = { { fg : theme . textMuted } } >
88+ < Switch >
89+ < Match when = { item . status === "connected" } > Connected</ Match >
90+ < Match when = { item . status === "failed" && item } > { ( val ) => < i > { val ( ) . error } </ i > } </ Match >
91+ < Match when = { item . status === "disabled" } > Disabled in configuration</ Match >
92+ </ Switch >
93+ </ span >
94+ </ text >
95+ </ box >
96+ ) }
97+ </ For >
98+ </ Show >
8999 </ box >
90100 </ Show >
91101 < Show when = { sync . data . lsp . length > 0 } >
92102 < box >
93- < text fg = { theme . text } >
94- < b > LSP</ b >
95- </ text >
96- < For each = { sync . data . lsp } >
97- { ( item ) => (
98- < box flexDirection = "row" gap = { 1 } >
99- < text
100- flexShrink = { 0 }
101- style = { {
102- fg : {
103- connected : theme . success ,
104- error : theme . error ,
105- } [ item . status ] ,
106- } }
107- >
108- •
109- </ text >
110- < text fg = { theme . textMuted } >
111- { item . id } { item . root }
112- </ text >
113- </ box >
114- ) }
115- </ For >
103+ < box flexDirection = "row" gap = { 1 } onMouseDown = { ( ) => setLspExpanded ( ! lspExpanded ( ) ) } >
104+ < text fg = { theme . text } > { lspExpanded ( ) ? "▼" : "▶" } </ text >
105+ < text fg = { theme . text } >
106+ < b > LSP</ b >
107+ </ text >
108+ </ box >
109+ < Show when = { lspExpanded ( ) } >
110+ < For each = { sync . data . lsp } >
111+ { ( item ) => (
112+ < box flexDirection = "row" gap = { 1 } >
113+ < text
114+ flexShrink = { 0 }
115+ style = { {
116+ fg : {
117+ connected : theme . success ,
118+ error : theme . error ,
119+ } [ item . status ] ,
120+ } }
121+ >
122+ •
123+ </ text >
124+ < text fg = { theme . textMuted } >
125+ { item . id } { item . root }
126+ </ text >
127+ </ box >
128+ ) }
129+ </ For >
130+ </ Show >
116131 </ box >
117132 </ Show >
118133 < Show when = { todo ( ) . length > 0 } >
119134 < box >
120- < text fg = { theme . text } >
121- < b > Todo</ b >
122- </ text >
123- < For each = { todo ( ) } >
124- { ( todo ) => (
125- < text style = { { fg : todo . status === "in_progress" ? theme . success : theme . textMuted } } >
126- [{ todo . status === "completed" ? "✓" : " " } ] { todo . content }
127- </ text >
128- ) }
129- </ For >
135+ < box flexDirection = "row" gap = { 1 } onMouseDown = { ( ) => setTodoExpanded ( ! todoExpanded ( ) ) } >
136+ < text fg = { theme . text } > { todoExpanded ( ) ? "▼" : "▶" } </ text >
137+ < text fg = { theme . text } >
138+ < b > Todo</ b >
139+ </ text >
140+ </ box >
141+ < Show when = { todoExpanded ( ) } >
142+ < For each = { todo ( ) } >
143+ { ( todo ) => (
144+ < text style = { { fg : todo . status === "in_progress" ? theme . success : theme . textMuted } } >
145+ [{ todo . status === "completed" ? "✓" : " " } ] { todo . content }
146+ </ text >
147+ ) }
148+ </ For >
149+ </ Show >
130150 </ box >
131151 </ Show >
132152 < Show when = { diff ( ) . length > 0 } >
133153 < box >
134- < text fg = { theme . text } >
135- < b > Modified Files</ b >
136- </ text >
137- < For each = { diff ( ) || [ ] } >
138- { ( item ) => {
139- const file = createMemo ( ( ) => {
140- const splits = item . file . split ( path . sep ) . filter ( Boolean )
141- const last = splits . at ( - 1 ) !
142- const rest = splits . slice ( 0 , - 1 ) . join ( path . sep )
143- return Locale . truncateMiddle ( rest , 30 - last . length ) + "/" + last
144- } )
145- return (
146- < box flexDirection = "row" gap = { 1 } justifyContent = "space-between" >
147- < text fg = { theme . textMuted } wrapMode = "char" >
148- { file ( ) }
149- </ text >
150- < box flexDirection = "row" gap = { 1 } flexShrink = { 0 } >
151- < Show when = { item . additions } >
152- < text fg = { theme . diffAdded } > +{ item . additions } </ text >
153- </ Show >
154- < Show when = { item . deletions } >
155- < text fg = { theme . diffRemoved } > -{ item . deletions } </ text >
156- </ Show >
154+ < box flexDirection = "row" gap = { 1 } onMouseDown = { ( ) => setDiffExpanded ( ! diffExpanded ( ) ) } >
155+ < text fg = { theme . text } > { diffExpanded ( ) ? "▼" : "▶" } </ text >
156+ < text fg = { theme . text } >
157+ < b > Modified Files</ b >
158+ </ text >
159+ </ box >
160+ < Show when = { diffExpanded ( ) } >
161+ < For each = { diff ( ) || [ ] } >
162+ { ( item ) => {
163+ const file = createMemo ( ( ) => {
164+ const splits = item . file . split ( path . sep ) . filter ( Boolean )
165+ const last = splits . at ( - 1 ) !
166+ const rest = splits . slice ( 0 , - 1 ) . join ( path . sep )
167+ return Locale . truncateMiddle ( rest , 30 - last . length ) + "/" + last
168+ } )
169+ return (
170+ < box flexDirection = "row" gap = { 1 } justifyContent = "space-between" >
171+ < text fg = { theme . textMuted } wrapMode = "char" >
172+ { file ( ) }
173+ </ text >
174+ < box flexDirection = "row" gap = { 1 } flexShrink = { 0 } >
175+ < Show when = { item . additions } >
176+ < text fg = { theme . diffAdded } > +{ item . additions } </ text >
177+ </ Show >
178+ < Show when = { item . deletions } >
179+ < text fg = { theme . diffRemoved } > -{ item . deletions } </ text >
180+ </ Show >
181+ </ box >
157182 </ box >
158- </ box >
159- )
160- } }
161- </ For >
183+ )
184+ } }
185+ </ For >
186+ </ Show >
162187 </ box >
163188 </ Show >
164189 </ box >
0 commit comments