fix(tui): match gitcrawl resize breakpoints

This commit is contained in:
Vincent Koc 2026-05-03 04:40:45 -07:00
parent 91553b6618
commit c372c19edf
No known key found for this signature in database
3 changed files with 22 additions and 29 deletions

View File

@ -26,4 +26,5 @@
- Start the shared `tui` in full detail mode like `gitcrawl`, while keeping `d` as the compact/full detail toggle.
- Trim redundant chat member columns so message panes prioritize time, age, author, and title instead of repeating the selected channel/kind on every row.
- Default single-channel chat archives to a people/group view so the left pane stays useful for Discord and Slack data.
- Match `gitcrawl` TUI resize breakpoints: 140+ columns use three panes, 100-139 uses top split plus full-width detail, and narrow terminals stack.
- Rename the public package nouns to `config`, `store`, `snapshot`, `mirror`, `state`, `output`, `tui`, and `cache`.

View File

@ -2440,12 +2440,12 @@ func (m model) layout() archiveLayout {
if height <= 0 {
height = 24
}
bodyH := maxInt(1, height-3)
if width >= 120 {
bodyH := maxInt(8, height-3)
if width >= 140 {
if m.layoutMode == layoutModeRightStack {
rowsW := maxInt(56, width*44/100)
rightW := width - rowsW
contextH := clampInt(maxInt(3, bodyH*42/100), 1, maxInt(1, bodyH-1))
contextH := clampInt(maxInt(8, bodyH*42/100), 1, maxInt(1, bodyH-1))
return archiveLayout{
rows: rect{x: 0, y: 1, w: rowsW, h: bodyH},
context: rect{x: rowsW, y: 1, w: rightW, h: contextH},
@ -2453,26 +2453,18 @@ func (m model) layout() archiveLayout {
mode: string(layoutModeRightStack),
}
}
rowsW := maxInt(42, width*34/100)
contextW := maxInt(38, width*30/100)
detailW := width - rowsW - contextW
if detailW < 40 {
deficit := 40 - detailW
shrinkRows := minInt(deficit, maxInt(0, rowsW-42))
rowsW -= shrinkRows
deficit -= shrinkRows
shrinkContext := minInt(deficit, maxInt(0, contextW-38))
contextW -= shrinkContext
}
rowsW := maxInt(48, width*34/100)
contextW := maxInt(40, width*30/100)
detailW := maxInt(42, width-rowsW-contextW)
return archiveLayout{
rows: rect{x: 0, y: 1, w: rowsW, h: bodyH},
context: rect{x: rowsW, y: 1, w: contextW, h: bodyH},
detail: rect{x: rowsW + contextW, y: 1, w: width - rowsW - contextW, h: bodyH},
detail: rect{x: rowsW + contextW, y: 1, w: detailW, h: bodyH},
mode: string(layoutModeColumns),
}
}
if width >= 100 {
topH := clampInt(maxInt(4, bodyH/2), 1, maxInt(1, bodyH-1))
topH := clampInt(maxInt(8, bodyH/2), 1, maxInt(1, bodyH-1))
rowsW := width / 2
return archiveLayout{
rows: rect{x: 0, y: 1, w: rowsW, h: topH},
@ -2482,9 +2474,9 @@ func (m model) layout() archiveLayout {
mode: "split",
}
}
rowsH := clampInt(maxInt(3, bodyH*36/100), 1, maxInt(1, bodyH-2))
contextH := clampInt(maxInt(2, bodyH*28/100), 1, maxInt(1, bodyH-rowsH-1))
detailH := maxInt(1, bodyH-rowsH-contextH)
rowsH := clampInt(maxInt(7, bodyH*36/100), 1, maxInt(1, bodyH-2))
contextH := clampInt(maxInt(6, bodyH*28/100), 1, maxInt(1, bodyH-rowsH-1))
detailH := maxInt(6, bodyH-rowsH-contextH)
return archiveLayout{
rows: rect{x: 0, y: 1, w: width, h: rowsH},
context: rect{x: 0, y: 1 + rowsH, w: width, h: contextH},

View File

@ -679,7 +679,7 @@ func TestFocusedDetailPaneScrollsIndependently(t *testing.T) {
}},
})
m.width = 80
m.height = 24
m.height = 30
m.focus = focusDetail
m.scrollFocused(1)
if m.selected != 0 {
@ -1428,7 +1428,7 @@ func TestLayoutToggleUsesRightStackMode(t *testing.T) {
}
}
func TestWideTmuxPanesPreferThreeColumns(t *testing.T) {
func TestMediumTmuxPanesUseGitcrawlSplitLayout(t *testing.T) {
m := newModel(Options{
Title: "archive",
Items: []Item{{Title: "alpha", Tags: []string{"page"}}},
@ -1436,17 +1436,17 @@ func TestWideTmuxPanesPreferThreeColumns(t *testing.T) {
m.width = 122
m.height = 34
layout := m.layout()
if layout.mode != string(layoutModeColumns) || layout.stacked {
t.Fatalf("layout = %#v, want three columns", layout)
if layout.mode != "split" || !layout.stacked {
t.Fatalf("layout = %#v, want gitcrawl-style split", layout)
}
if layout.rows.h != layout.context.h || layout.context.h != layout.detail.h {
t.Fatalf("panes should share height in column mode: %#v", layout)
if layout.rows.y != layout.context.y || layout.detail.y <= layout.rows.y {
t.Fatalf("split panes should put rows/context above detail: %#v", layout)
}
if paneContentWidth(layout.context.w) < 34 {
t.Fatalf("context pane too narrow for useful columns: %#v", layout)
if layout.rows.w+layout.context.w != 122 {
t.Fatalf("split top panes should fill terminal width: %#v", layout)
}
if paneContentWidth(layout.rows.w) < 36 {
t.Fatalf("rows pane too narrow for date/age columns: %#v", layout)
if paneContentWidth(layout.context.w) < 52 || paneContentWidth(layout.rows.w) < 52 {
t.Fatalf("split panes too narrow for useful columns: %#v", layout)
}
}