@@ -41,7 +41,10 @@ const (
4141 PaneRight
4242)
4343
44- const settingShowHints = "tui_show_hints"
44+ const (
45+ settingShowHints = "tui_show_hints"
46+ settingShowRightPane = "tui_show_right_pane"
47+ )
4548
4649// AppModel is the top-level Bubble Tea model.
4750type AppModel struct {
@@ -61,6 +64,7 @@ type AppModel struct {
6164 height int
6265 activePane Pane
6366 showHints bool
67+ showRightPane bool
6468
6569 // Session-level navigation shared by the connection tabs.
6670 connectionQuery string
@@ -129,16 +133,20 @@ func newAppModel(connections []model.Connection, d *sql.DB, initialTab Tab, cfg
129133 activeSource : model .SourceSQLite ,
130134 activePane : PaneLeft ,
131135 showHints : true ,
136+ showRightPane : true ,
132137 groupPane : newGroupPaneModel (nil , 34 , 12 ),
133138 createAssignment : newGroupAssignmentModel (nil , nil , 0 , 34 , 12 ),
134139 editAssignment : newGroupAssignmentModel (nil , nil , 0 , 34 , 12 ),
135140 createAssignmentInitialized : initialTab == TabCreate ,
136141 }
137-
142+
138143 if d != nil {
139144 if value , err := db .GetSetting (d , settingShowHints ); err == nil && string (value ) == "false" {
140145 m .showHints = false
141146 }
147+ if value , err := db .GetSetting (d , settingShowRightPane ); err == nil && string (value ) == "false" {
148+ m .showRightPane = false
149+ }
142150 }
143151
144152 // Respect persisted view mode.
@@ -209,19 +217,7 @@ func (m AppModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
209217 case tea.WindowSizeMsg :
210218 m .width = msg .Width
211219 m .height = msg .Height
212- separator := m .width / 2
213- leftContentWidth := max (1 , separator - 5 )
214- rightContentWidth := max (1 , m .width - separator - 6 )
215- paneHeight := max (1 , m .height - 6 )
216- paneBodyHeight := max (1 , paneHeight - 2 )
217- m .connectModel .SetSize (leftContentWidth , paneBodyHeight )
218- m .createModel .SetSize (leftContentWidth , paneBodyHeight )
219- m .editModel .SetSize (leftContentWidth , paneBodyHeight )
220- m .deleteModel .SetSize (leftContentWidth , paneBodyHeight )
221- m .groupPane .SetSize (rightContentWidth , paneBodyHeight )
222- m .createAssignment .SetSize (rightContentWidth , paneBodyHeight )
223- m .editAssignment .SetSize (rightContentWidth , paneBodyHeight )
224- m .modal .SetSize (m .width , m .height )
220+ m .resizePanes ()
225221 return m , nil
226222
227223 case tea.KeyMsg :
@@ -287,6 +283,9 @@ func (m AppModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
287283 case "?" :
288284 m = m .toggleHints ()
289285 return m , nil
286+ case "ctrl+p" :
287+ m = m .toggleRightPane ()
288+ return m , nil
290289 case "ctrl+s" :
291290 switch {
292291 case m .activeTab == TabCreate :
@@ -326,6 +325,9 @@ func (m AppModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
326325 return m , nil
327326 }
328327 case "tab" , "shift+tab" :
328+ if ! m .showRightPane {
329+ return m , nil
330+ }
329331 if m .activePane == PaneLeft {
330332 m .activePane = PaneRight
331333 } else {
@@ -903,18 +905,31 @@ func (m AppModel) View() string {
903905 leftStatus = m .deleteModel .statusStyle .Render (m .deleteModel .statusMsg )
904906 }
905907
906- base := renderSplitScreen (
907- tabBar ,
908- leftContent ,
909- rightContent ,
910- leftStatus ,
911- rightStatus ,
912- m .leftPaneHints (),
913- m .rightPaneHints (),
914- m .width ,
915- m .height ,
916- accentColor ,
917- )
908+ var base string
909+ if m .showRightPane {
910+ base = renderSplitScreen (
911+ tabBar ,
912+ leftContent ,
913+ rightContent ,
914+ leftStatus ,
915+ rightStatus ,
916+ m .leftPaneHints (),
917+ m .rightPaneHints (),
918+ m .width ,
919+ m .height ,
920+ accentColor ,
921+ )
922+ } else {
923+ base = renderSinglePaneScreen (
924+ tabBar ,
925+ leftContent ,
926+ leftStatus ,
927+ m .leftPaneHints (),
928+ m .width ,
929+ m .height ,
930+ accentColor ,
931+ )
932+ }
918933 if m .showModal {
919934 return compositePopover (base , m .modal .BoxView (), m .width , m .height )
920935 }
@@ -931,6 +946,12 @@ func (m AppModel) leftPaneHints() string {
931946 if ! m .showHints {
932947 return statusStyle .Render ("? help" )
933948 }
949+ if m .width <= minimumTerminalWidth {
950+ if m .showRightPane {
951+ return statusStyle .Render ("CTRL+P hide panel • ? hide help" )
952+ }
953+ return statusStyle .Render ("CTRL+P show panel • ? hide help" )
954+ }
934955
935956 var hints string
936957 switch m .activeTab {
@@ -947,18 +968,26 @@ func (m AppModel) leftPaneHints() string {
947968 case TabDelete :
948969 hints = "TAB pane • ↑/↓ navigate • ENTER ×3 delete • ←/→ tabs • ESC exit"
949970 }
950- return statusStyle .Render (hints )
971+ if m .showRightPane {
972+ hints += " • CTRL+P hide panel"
973+ } else {
974+ hints += " • CTRL+P show panel"
975+ }
976+ return statusStyle .Render (hints + " • ? hide help" )
951977}
952978
953979func (m AppModel ) rightPaneHints () string {
954980 if ! m .showHints {
955981 return ""
956982 }
983+ if m .width <= minimumTerminalWidth {
984+ return statusStyle .Render ("CTRL+N new • CTRL+P hide panel • ? hide help" )
985+ }
957986
958987 if m .assignmentMode () {
959- return statusStyle .Render ("TAB pane • ↑/↓ navigate • SPACE assign • CTRL+N new • CTRL+S save" )
988+ return statusStyle .Render ("TAB pane • ↑/↓ navigate • SPACE assign • CTRL+N new • CTRL+S save • CTRL+P hide panel • ? hide help " )
960989 }
961- return statusStyle .Render ("TAB pane • ↑/↓ navigate • CTRL+N new • CTRL+R rename • CTRL+D delete" )
990+ return statusStyle .Render ("TAB pane • ↑/↓ navigate • CTRL+N new • CTRL+R rename • CTRL+D delete • CTRL+P hide panel • ? hide help " )
962991}
963992
964993func (m AppModel ) toggleHints () AppModel {
@@ -973,6 +1002,62 @@ func (m AppModel) toggleHints() AppModel {
9731002 return m
9741003}
9751004
1005+ func (m AppModel ) toggleRightPane () AppModel {
1006+ showRightPane := ! m .showRightPane
1007+ if m .database != nil {
1008+ if err := db .SetSetting (m .database , settingShowRightPane , []byte (strconv .FormatBool (showRightPane ))); err != nil {
1009+ m .setError ("save right pane visibility: %s" , err )
1010+ return m
1011+ }
1012+ }
1013+ m .showRightPane = showRightPane
1014+ if ! m .showRightPane {
1015+ m .activePane = PaneLeft
1016+ m .resetHiddenPaneState ()
1017+ }
1018+ m .resizePanes ()
1019+ m .applyPaneFocus ()
1020+ return m
1021+ }
1022+
1023+ func (m * AppModel ) resetHiddenPaneState () {
1024+ m .groupPane .SelectGroup (0 )
1025+ m .applyGroupFilter ()
1026+ m .createAssignment .Begin (m .groups , nil , 0 )
1027+
1028+ var editGroupIDs []int64
1029+ if m .activeTab == TabEdit && m .editModel .editing && m .database != nil {
1030+ ids , err := db .GroupIDsForConnection (m .database , m .connectionRef (m .editModel .origConn ))
1031+ if err != nil {
1032+ m .setError ("load connection groups: %s" , err )
1033+ } else {
1034+ editGroupIDs = ids
1035+ }
1036+ }
1037+ m .editAssignment .Begin (m .groups , editGroupIDs , 0 )
1038+ }
1039+
1040+ func (m * AppModel ) resizePanes () {
1041+ leftContentWidth , rightContentWidth := singlePaneContentWidth (m .width ), 0
1042+ if m .showRightPane {
1043+ separator := m .width / 2
1044+ leftContentWidth = max (1 , separator - 5 )
1045+ rightContentWidth = max (1 , m .width - separator - 6 )
1046+ }
1047+ paneHeight := max (1 , m .height - 6 )
1048+ paneBodyHeight := max (1 , paneHeight - 2 )
1049+ m .connectModel .SetSize (leftContentWidth , paneBodyHeight )
1050+ m .createModel .SetSize (leftContentWidth , paneBodyHeight )
1051+ m .editModel .SetSize (leftContentWidth , paneBodyHeight )
1052+ m .deleteModel .SetSize (leftContentWidth , paneBodyHeight )
1053+ if rightContentWidth > 0 {
1054+ m .groupPane .SetSize (rightContentWidth , paneBodyHeight )
1055+ m .createAssignment .SetSize (rightContentWidth , paneBodyHeight )
1056+ m .editAssignment .SetSize (rightContentWidth , paneBodyHeight )
1057+ }
1058+ m .modal .SetSize (m .width , m .height )
1059+ }
1060+
9761061// onConnectionEdited syncs all tab lists after an edit.
9771062func (m * AppModel ) onConnectionEdited (oldName , newName string , source model.Source ) {
9781063 m .connectModel .RemoveByName (oldName )
0 commit comments