Every workspace split into real panes: 19 panes across 7 workspaces, one program per panel

This commit is contained in:
Sam
2026-11-10 16:29:27 +11:00
parent 2640049f1f
commit 32fa2752af
19 changed files with 972 additions and 58 deletions

View File

@@ -28,6 +28,7 @@ type replyThreadMsg struct {
type replySentMsg struct{ task paperclip.Issue }
type replyModel struct {
panel string
client *paperclip.Client
folder string
issue string
@@ -50,8 +51,9 @@ type replyModel struct {
height int
}
func newReplyModel(c *paperclip.Client, folder, issueID string) replyModel {
return replyModel{client: c, folder: folder, issue: issueID, explicit: issueID != ""}
func newReplyModel(c *paperclip.Client, folder, issueID, panel string) replyModel {
return replyModel{client: c, folder: folder, issue: issueID, explicit: issueID != "",
panel: panel, inBox: panel == "reply"}
}
func (m replyModel) Init() tea.Cmd {
@@ -227,7 +229,62 @@ func (m replyModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, nil
}
// singleView is one panel filling the pane: the task, the thread, or the box.
func (m replyModel) singleView() string {
title := "thread"
var body []string
footer := ""
switch m.panel {
case "task":
title = "the task"
body = m.headerLines(m.width - 3)
footer = hintLine([]string{keyHint("r", "read again"), keyHint("R", "rebuild")}, m.width)
case "reply":
title = "reply · " + m.statusNote()
body = m.composerLines(m.width-3, m.height-3)
footer = hintLine([]string{
keyHint("enter", "send"),
keyHint("alt+enter", "new line"),
keyHint("s", "status"),
}, m.width)
if m.notice != "" {
footer = lipgloss.NewStyle().Foreground(lipgloss.Color(active.Success)).Render(m.notice)
}
if m.err != nil {
footer = lipgloss.NewStyle().Foreground(lipgloss.Color(active.Error)).Render(truncateVisible("error: "+m.err.Error(), m.width))
}
default:
body = m.threadLines(m.width - 3)
footer = hintLine([]string{
keyHint("↑↓ j k", "scroll"),
keyHint("r", "read again"),
keyHint("R", "rebuild"),
keyHint("?", "keys"),
}, m.width)
}
if m.showHelp {
return helpOverlay(title, [][2]string{
{"enter", "write a reply"}, {"s", "status to send with it"},
{"↑ ↓ j k", "scroll"}, {"r / R", "read again / rebuild"},
}, m.width, m.height)
}
return singlePanel(title, nil, 0, body, m.width, m.height, footer, m.scroll)
}
func (m replyModel) statusNote() string {
if m.next == "" {
return "leaves the status alone"
}
return "also sets the status to " + m.next
}
func (m replyModel) View() string {
if m.panel != "" {
if m.width == 0 {
return "reading…"
}
return m.singleView()
}
if m.width == 0 || m.height == 0 {
return "reading…"
}