Revert "Every workspace split into real panes: 19 panes across 7 workspaces, one program per panel"
This reverts commit 32fa2752af.
This commit is contained in:
85
tui/board.go
85
tui/board.go
@@ -49,8 +49,6 @@ type boardModel struct {
|
||||
activity []paperclip.Activity
|
||||
needsTab int
|
||||
|
||||
panel string
|
||||
scroll int
|
||||
zones *zone.Manager
|
||||
filter string
|
||||
typing bool
|
||||
@@ -66,10 +64,10 @@ const (
|
||||
focusCount
|
||||
)
|
||||
|
||||
func newBoardModel(c *paperclip.Client, proj paperclip.Project, folder, panel string) boardModel {
|
||||
func newBoardModel(c *paperclip.Client, proj paperclip.Project, folder string) boardModel {
|
||||
// One click-zone manager for the whole program, created once. Wrapping each
|
||||
// panel separately drifts as soon as a pane is resized.
|
||||
return boardModel{client: c, project: proj, folder: folder, panel: panel, loading: true, zones: zone.New()}
|
||||
return boardModel{client: c, project: proj, folder: folder, loading: true, zones: zone.New()}
|
||||
}
|
||||
|
||||
func (m boardModel) Init() tea.Cmd {
|
||||
@@ -230,28 +228,14 @@ func (m boardModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
return m, tea.Quit
|
||||
case "up", "k":
|
||||
if m.panel == "detail" || m.panel == "needs" {
|
||||
m.scroll--
|
||||
return m, nil
|
||||
}
|
||||
if m.cursor > 0 {
|
||||
m.cursor--
|
||||
if m.panel != "" {
|
||||
_ = rememberTask(m.folder, m.visible()[m.cursor].Issue.Identifier)
|
||||
}
|
||||
return m, m.loadDetail(m.selectedID())
|
||||
}
|
||||
return m, nil
|
||||
case "down", "j":
|
||||
if m.panel == "detail" || m.panel == "needs" {
|
||||
m.scroll++
|
||||
return m, nil
|
||||
}
|
||||
if m.cursor < len(m.visible())-1 {
|
||||
m.cursor++
|
||||
if m.panel != "" {
|
||||
_ = rememberTask(m.folder, m.visible()[m.cursor].Issue.Identifier)
|
||||
}
|
||||
return m, m.loadDetail(m.selectedID())
|
||||
}
|
||||
return m, nil
|
||||
@@ -280,12 +264,12 @@ func (m boardModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
return m, nil
|
||||
case "[", "h":
|
||||
if (m.panel == "needs" || m.focus == focusNeeds) && m.needsTab > 0 {
|
||||
if m.focus == focusNeeds && m.needsTab > 0 {
|
||||
m.needsTab--
|
||||
}
|
||||
return m, nil
|
||||
case "]", "l":
|
||||
if (m.panel == "needs" || m.focus == focusNeeds) && m.needsTab < 1 {
|
||||
if m.focus == focusNeeds && m.needsTab < 1 {
|
||||
m.needsTab++
|
||||
}
|
||||
return m, nil
|
||||
@@ -339,9 +323,6 @@ func (m boardModel) View() string {
|
||||
m.width, m.height))
|
||||
}
|
||||
|
||||
if m.panel != "" {
|
||||
return m.singleView()
|
||||
}
|
||||
if m.showHelp {
|
||||
return helpOverlay("keys on this panel", [][2]string{
|
||||
{"↑ ↓ j k", "choose a task"},
|
||||
@@ -414,64 +395,6 @@ func (m boardModel) View() string {
|
||||
return m.zones.Scan(strings.Join([]string{header, page, footer}, "\n"))
|
||||
}
|
||||
|
||||
// singleView is one panel filling the pane, for when the Board workspace is
|
||||
// split into real panes: tasks, the chosen task, and what needs a person.
|
||||
func (m boardModel) singleView() string {
|
||||
width := m.width
|
||||
height := m.height
|
||||
var body []string
|
||||
title := "tasks"
|
||||
tabs := []string(nil)
|
||||
active := 0
|
||||
footer := ""
|
||||
|
||||
switch m.panel {
|
||||
case "detail":
|
||||
title = "the chosen task"
|
||||
body = m.summaryLines(width - 3)
|
||||
footer = hintLine([]string{
|
||||
keyHint("r", "read again"),
|
||||
keyHint("R", "rebuild"),
|
||||
keyHint("?", "keys"),
|
||||
}, width)
|
||||
case "needs":
|
||||
title = "needs you"
|
||||
tabs = []string{"decisions", "activity"}
|
||||
active = m.needsTab
|
||||
if m.needsTab == 0 {
|
||||
body = m.needsLines(width-3, height-3)
|
||||
} else {
|
||||
body = m.activityLines(width-3, height-3)
|
||||
}
|
||||
footer = hintLine([]string{
|
||||
keyHint("[ ]", "switch tab"),
|
||||
keyHint("r", "read again"),
|
||||
keyHint("R", "rebuild"),
|
||||
}, width)
|
||||
default:
|
||||
body = m.treeLines(width - 3)
|
||||
footer = hintLine([]string{
|
||||
keyHint("↑↓ j k", "choose"),
|
||||
keyHint("enter", "show everywhere"),
|
||||
keyHint("a", "assign"),
|
||||
keyHint("u", "unblock"),
|
||||
keyHint("/", "filter"),
|
||||
keyHint("?", "keys"),
|
||||
}, width)
|
||||
}
|
||||
|
||||
if m.showHelp {
|
||||
return helpOverlay(title, [][2]string{
|
||||
{"↑ ↓ j k", "choose a task"},
|
||||
{"enter", "show it in every workspace"},
|
||||
{"a / u", "assign / unblock"},
|
||||
{"/", "filter"}, {"[ ]", "switch tab"},
|
||||
{"r / R", "read again / rebuild"}, {"q", "leave"},
|
||||
}, width, height)
|
||||
}
|
||||
return singlePanel(title, tabs, active, body, width, height, footer, m.scroll)
|
||||
}
|
||||
|
||||
func (m boardModel) headerLine() string {
|
||||
left := panelTitleStyle().Render("Board") + mutedStyle2().Render(" · "+m.project.Name)
|
||||
state := "reading…"
|
||||
|
||||
25
tui/frame.go
25
tui/frame.go
@@ -289,28 +289,3 @@ func helpOverlay(title string, entries [][2]string, w, h int) string {
|
||||
p := panel{title: title, width: boxW, height: boxH, focused: true}
|
||||
return lipgloss.Place(w, h, lipgloss.Center, lipgloss.Center, p.render(lines))
|
||||
}
|
||||
|
||||
// singlePanel draws one panel filling the whole pane: a title, optional tabs,
|
||||
// a scrolling body, and one line of keys. It is what a pane shows when a
|
||||
// workspace has been split into real panes instead of one program drawing
|
||||
// several panels inside itself.
|
||||
func singlePanel(title string, tabs []string, active int, body []string, w, h int, footer string, scroll int) string {
|
||||
if w < 12 || h < 4 {
|
||||
return fmt.Sprintf("this pane is %d × %d; it needs 12 × 4", w, h)
|
||||
}
|
||||
p := panel{title: title, tabs: tabs, active: active, width: w, height: h - 1, focused: true}
|
||||
visible := p.bodyHeight()
|
||||
maxScroll := max(0, len(body)-visible)
|
||||
if scroll > maxScroll {
|
||||
scroll = maxScroll
|
||||
}
|
||||
if scroll < 0 {
|
||||
scroll = 0
|
||||
}
|
||||
from := scroll
|
||||
to := min(len(body), from+visible)
|
||||
if to < from {
|
||||
to = from
|
||||
}
|
||||
return p.render(body[from:to]) + "\n" + truncateVisible(footer, w)
|
||||
}
|
||||
|
||||
13
tui/main.go
13
tui/main.go
@@ -20,7 +20,6 @@ const defaultAgent = "403de1f7-645c-4d35-bc7e-19b01d77bacc"
|
||||
|
||||
func main() {
|
||||
screen := flag.String("screen", "board", "which screen to run: board, work, reply, new, project, repair")
|
||||
panelName := flag.String("panel", "", "run one panel of that screen, for a workspace split into real panes")
|
||||
folder := flag.String("folder", "", "project folder, for the board screen (defaults to the current directory)")
|
||||
light := flag.String("theme", "", "colour variant: dark, light, or empty to follow the terminal")
|
||||
ascii := flag.Bool("ascii", false, "plain characters instead of Nerd Font icons")
|
||||
@@ -53,21 +52,21 @@ func main() {
|
||||
if dir == "" {
|
||||
dir, _ = os.Getwd()
|
||||
}
|
||||
m = newBoardModel(client, proj, dir, *panelName)
|
||||
m = newBoardModel(client, proj, dir)
|
||||
|
||||
case "project":
|
||||
dir := *folder
|
||||
if dir == "" {
|
||||
dir, _ = os.Getwd()
|
||||
}
|
||||
m = newProjectModel(client, dir, *panelName)
|
||||
m = newProjectModel(client, dir)
|
||||
|
||||
case "repair":
|
||||
dir := *folder
|
||||
if dir == "" {
|
||||
dir, _ = os.Getwd()
|
||||
}
|
||||
m = newRepairModel(client, dir, *panelName)
|
||||
m = newRepairModel(client, dir)
|
||||
|
||||
case "work":
|
||||
dir := *folder
|
||||
@@ -78,7 +77,7 @@ func main() {
|
||||
if issue == "" {
|
||||
issue = watchedTask(dir)
|
||||
}
|
||||
m = newWorkModel(client, dir, issue, *panelName)
|
||||
m = newWorkModel(client, dir, issue)
|
||||
|
||||
case "tree":
|
||||
proj, err := client.ResolveProject(*project)
|
||||
@@ -101,7 +100,7 @@ func main() {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
m = newTaskForm(client, proj, *agent, *panelName)
|
||||
m = newTaskForm(client, proj, *agent)
|
||||
|
||||
case "log":
|
||||
task, err := resolveIssue(client, *issue)
|
||||
@@ -125,7 +124,7 @@ func main() {
|
||||
}
|
||||
id = task.ID
|
||||
}
|
||||
m = newReplyModel(client, dir, id, *panelName)
|
||||
m = newReplyModel(client, dir, id)
|
||||
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "unknown screen %q: use board, work, reply, new, project or repair\n", *screen)
|
||||
|
||||
@@ -27,7 +27,6 @@ type createdMsg struct {
|
||||
}
|
||||
|
||||
type newTaskModel struct {
|
||||
panel string
|
||||
client *paperclip.Client
|
||||
proj paperclip.Project
|
||||
agent string
|
||||
@@ -62,8 +61,8 @@ var fieldHints = []string{
|
||||
"yes, to hand it to the configured agent after the blocker is set",
|
||||
}
|
||||
|
||||
func newTaskForm(c *paperclip.Client, proj paperclip.Project, agentID, panel string) newTaskModel {
|
||||
m := newTaskModel{client: c, proj: proj, agent: agentID, panel: panel}
|
||||
func newTaskForm(c *paperclip.Client, proj paperclip.Project, agentID string) newTaskModel {
|
||||
m := newTaskModel{client: c, proj: proj, agent: agentID}
|
||||
for range fieldNames {
|
||||
ti := textinput.New()
|
||||
ti.Placeholder = ""
|
||||
@@ -241,39 +240,7 @@ func (m newTaskModel) guidanceLines(width int) []string {
|
||||
return out
|
||||
}
|
||||
|
||||
// singleView is one panel filling the pane: the form, the guidance, or what
|
||||
// will be sent. The form keeps the keyboard, because its letters are text.
|
||||
func (m newTaskModel) singleView() string {
|
||||
title := "new task"
|
||||
var body []string
|
||||
footer := ""
|
||||
switch m.panel {
|
||||
case "guidance":
|
||||
title = "what a task needs"
|
||||
body = m.guidanceLines(m.width - 3)
|
||||
footer = hintLine([]string{keyHint("r", "nothing to read here"), keyHint("R", "rebuild")}, m.width)
|
||||
case "preview":
|
||||
title = "what will be sent"
|
||||
body = m.previewLines(m.width - 3)
|
||||
footer = hintLine([]string{keyHint("tab", "back to the form"), keyHint("R", "rebuild")}, m.width)
|
||||
default:
|
||||
body = m.formLines(m.width - 3)
|
||||
footer = hintLine([]string{
|
||||
keyHint("tab", "next field"),
|
||||
keyHint("enter", "next, and create on the last"),
|
||||
keyHint("esc", "cancel"),
|
||||
}, m.width)
|
||||
}
|
||||
return singlePanel(title, nil, 0, body, m.width, m.height, footer, 0)
|
||||
}
|
||||
|
||||
func (m newTaskModel) View() string {
|
||||
if m.panel != "" {
|
||||
if m.width == 0 {
|
||||
return "reading…"
|
||||
}
|
||||
return m.singleView()
|
||||
}
|
||||
if m.width == 0 || m.height == 0 {
|
||||
return "reading…"
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ type taskCost struct {
|
||||
}
|
||||
|
||||
type projectModel struct {
|
||||
panel string
|
||||
client *paperclip.Client
|
||||
folder string
|
||||
|
||||
@@ -56,8 +55,8 @@ type projectModel struct {
|
||||
|
||||
var projectTabs = []string{"facts", "costs", "settings"}
|
||||
|
||||
func newProjectModel(c *paperclip.Client, folder, panel string) projectModel {
|
||||
return projectModel{client: c, folder: folder, panel: panel}
|
||||
func newProjectModel(c *paperclip.Client, folder string) projectModel {
|
||||
return projectModel{client: c, folder: folder}
|
||||
}
|
||||
|
||||
func (m projectModel) Init() tea.Cmd {
|
||||
@@ -194,46 +193,7 @@ func (m projectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// singleView is one panel filling the pane: facts, costs or settings.
|
||||
func (m projectModel) singleView() string {
|
||||
titles := map[string]string{"facts": "the project", "costs": "what it has cost", "settings": "settings and limits"}
|
||||
title := titles[m.panel]
|
||||
if title == "" {
|
||||
title = "the project"
|
||||
}
|
||||
var body []string
|
||||
switch m.panel {
|
||||
case "costs":
|
||||
body = m.costLines()
|
||||
case "settings":
|
||||
body = m.settingLines()
|
||||
default:
|
||||
body = m.factLines()
|
||||
}
|
||||
if m.err != nil {
|
||||
body = append([]string{lipgloss.NewStyle().Foreground(lipgloss.Color(active.Error)).Render("error: " + m.err.Error()), ""}, body...)
|
||||
}
|
||||
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{
|
||||
{"↑ ↓ j k", "scroll"}, {"r / R", "read again / rebuild"}, {"q", "leave"},
|
||||
}, m.width, m.height)
|
||||
}
|
||||
return singlePanel(title, nil, 0, body, m.width, m.height, footer, m.scroll)
|
||||
}
|
||||
|
||||
func (m projectModel) View() string {
|
||||
if m.panel != "" {
|
||||
if m.width == 0 {
|
||||
return "reading…"
|
||||
}
|
||||
return m.singleView()
|
||||
}
|
||||
if m.width == 0 || m.height == 0 {
|
||||
return "reading…"
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ type layoutRow struct {
|
||||
}
|
||||
|
||||
type repairModel struct {
|
||||
panel string
|
||||
client *paperclip.Client
|
||||
folder string
|
||||
|
||||
@@ -59,8 +58,8 @@ type repairModel struct {
|
||||
|
||||
var repairTabs = []string{"health", "layout", "rebuild log"}
|
||||
|
||||
func newRepairModel(c *paperclip.Client, folder, panel string) repairModel {
|
||||
return repairModel{client: c, folder: folder, panel: panel}
|
||||
func newRepairModel(c *paperclip.Client, folder string) repairModel {
|
||||
return repairModel{client: c, folder: folder}
|
||||
}
|
||||
|
||||
func (m repairModel) Init() tea.Cmd {
|
||||
@@ -255,45 +254,7 @@ func (m repairModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// singleView is one panel filling the pane: health, layout or the rebuild log.
|
||||
func (m repairModel) singleView() string {
|
||||
titles := map[string]string{"health": "checks", "layout": "the layout as TUIOS has it", "log": "the last rebuild"}
|
||||
title := titles[m.panel]
|
||||
if title == "" {
|
||||
title = "checks"
|
||||
}
|
||||
var body []string
|
||||
switch m.panel {
|
||||
case "layout":
|
||||
body = m.layoutLines()
|
||||
case "log":
|
||||
body = m.logLines()
|
||||
default:
|
||||
body = m.healthLines()
|
||||
}
|
||||
footer := hintLine([]string{
|
||||
keyHint("↑↓ j k", "scroll"),
|
||||
keyHint("R", "rebuild every pane"),
|
||||
keyHint("B", "add missing panes"),
|
||||
keyHint("r", "check again"),
|
||||
keyHint("?", "keys"),
|
||||
}, m.width)
|
||||
if m.showHelp {
|
||||
return helpOverlay(title, [][2]string{
|
||||
{"R", "rebuild every pane"}, {"B", "add only the missing panes"},
|
||||
{"↑ ↓ j k", "scroll"}, {"r", "check again"}, {"q", "leave"},
|
||||
}, m.width, m.height)
|
||||
}
|
||||
return singlePanel(title, nil, 0, body, m.width, m.height, footer, m.scroll)
|
||||
}
|
||||
|
||||
func (m repairModel) View() string {
|
||||
if m.panel != "" {
|
||||
if m.width == 0 {
|
||||
return "checking…"
|
||||
}
|
||||
return m.singleView()
|
||||
}
|
||||
if m.width == 0 || m.height == 0 {
|
||||
return "reading…"
|
||||
}
|
||||
|
||||
61
tui/reply.go
61
tui/reply.go
@@ -28,7 +28,6 @@ type replyThreadMsg struct {
|
||||
type replySentMsg struct{ task paperclip.Issue }
|
||||
|
||||
type replyModel struct {
|
||||
panel string
|
||||
client *paperclip.Client
|
||||
folder string
|
||||
issue string
|
||||
@@ -51,9 +50,8 @@ type replyModel struct {
|
||||
height int
|
||||
}
|
||||
|
||||
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 newReplyModel(c *paperclip.Client, folder, issueID string) replyModel {
|
||||
return replyModel{client: c, folder: folder, issue: issueID, explicit: issueID != ""}
|
||||
}
|
||||
|
||||
func (m replyModel) Init() tea.Cmd {
|
||||
@@ -229,62 +227,7 @@ 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…"
|
||||
}
|
||||
|
||||
47
tui/work.go
47
tui/work.go
@@ -29,7 +29,6 @@ type workMsg struct {
|
||||
}
|
||||
|
||||
type workModel struct {
|
||||
panel string
|
||||
client *paperclip.Client
|
||||
folder string
|
||||
issue string
|
||||
@@ -53,8 +52,8 @@ type workModel struct {
|
||||
|
||||
var workTabs = []string{"runs", "change", "facts"}
|
||||
|
||||
func newWorkModel(c *paperclip.Client, folder, issueID, panel string) workModel {
|
||||
return workModel{client: c, folder: folder, issue: issueID, explicit: issueID != "", panel: panel}
|
||||
func newWorkModel(c *paperclip.Client, folder, issueID string) workModel {
|
||||
return workModel{client: c, folder: folder, issue: issueID, explicit: issueID != ""}
|
||||
}
|
||||
|
||||
func (m workModel) Init() tea.Cmd {
|
||||
@@ -188,49 +187,7 @@ func (m workModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// singleView is one panel filling the pane: runs, change or facts.
|
||||
func (m workModel) singleView() string {
|
||||
titles := map[string]string{"runs": "runs and activity", "change": "the change", "facts": "worktree facts"}
|
||||
title, ok := titles[m.panel]
|
||||
if !ok {
|
||||
title = "runs and activity"
|
||||
}
|
||||
var body []string
|
||||
switch m.panel {
|
||||
case "change":
|
||||
body = m.diffLines(m.width - 3)
|
||||
case "facts":
|
||||
body = m.factsLines(m.width - 3)
|
||||
default:
|
||||
body = m.runsLines(m.width - 3)
|
||||
}
|
||||
head := m.task.Identifier
|
||||
if head == "" {
|
||||
head = "no task chosen"
|
||||
}
|
||||
footer := hintLine([]string{
|
||||
keyHint("↑↓ j k", "scroll"),
|
||||
keyHint("g G", "top / bottom"),
|
||||
keyHint("r", "read again"),
|
||||
keyHint("R", "rebuild"),
|
||||
keyHint("?", "keys"),
|
||||
}, m.width)
|
||||
if m.showHelp {
|
||||
return helpOverlay(title, [][2]string{
|
||||
{"↑ ↓ j k", "scroll"}, {"g / G", "top / bottom"},
|
||||
{"r / R", "read again / rebuild"}, {"q", "leave"},
|
||||
}, m.width, m.height)
|
||||
}
|
||||
return singlePanel(title+" · "+head, nil, 0, body, m.width, m.height, footer, m.scroll)
|
||||
}
|
||||
|
||||
func (m workModel) View() string {
|
||||
if m.panel != "" {
|
||||
if m.width == 0 {
|
||||
return "reading…"
|
||||
}
|
||||
return m.singleView()
|
||||
}
|
||||
if m.width == 0 || m.height == 0 {
|
||||
return "reading…"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user