From 3792b4078eb793e67defffe20ba113927d7e4289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=9E=E3=83=AA=E3=82=A6=E3=82=B9?= Date: Mon, 2 Jan 2023 13:25:09 -0500 Subject: [PATCH] Refactored dialog/window handling, impl draft --- ui/ui.go | 69 ++++++-- ui/views/posts/posts.go | 304 +++++++++++++++++--------------- ui/views/posts/view.go | 375 ++++++++++++++++++++-------------------- ui/views/posts/wm.go | 91 +++++----- 4 files changed, 450 insertions(+), 389 deletions(-) diff --git a/ui/ui.go b/ui/ui.go index 05c2045..a48afa2 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -5,9 +5,12 @@ import ( "strings" + "github.com/mrusme/gobbs/ui/cmd" "github.com/mrusme/gobbs/ui/ctx" "github.com/mrusme/gobbs/ui/header" "github.com/mrusme/gobbs/ui/views/posts" + "github.com/mrusme/gobbs/ui/windowmanager" + "github.com/mrusme/gobbs/ui/windows/postdialog" "github.com/mrusme/gobbs/ui/views" @@ -16,9 +19,9 @@ import ( ) type KeyMap struct { - Up key.Binding - Down key.Binding - Quit key.Binding + Up key.Binding + Down key.Binding + Close key.Binding } var DefaultKeyMap = KeyMap{ @@ -30,10 +33,10 @@ var DefaultKeyMap = KeyMap{ // key.WithKeys("j", "down"), // key.WithHelp("↓/j", "move down"), // ), - // Quit: key.NewBinding( - // key.WithKeys("q", "ctrl+q", "escape"), - // key.WithHelp("q/esc", "quit"), - // ), + Close: key.NewBinding( + key.WithKeys("q", "esc"), + key.WithHelp("q/esc", "close"), + ), } type Model struct { @@ -41,6 +44,7 @@ type Model struct { header header.Model views []views.View currentView int + wm *windowmanager.WM ctx *ctx.Ctx } @@ -48,6 +52,7 @@ func NewModel(c *ctx.Ctx) Model { m := Model{ keymap: DefaultKeyMap, currentView: 0, + wm: windowmanager.New(), ctx: c, } @@ -58,7 +63,11 @@ func NewModel(c *ctx.Ctx) Model { } func (m Model) Init() tea.Cmd { - return tea.Batch(tea.EnterAltScreen) + return tea.Batch( + tea.EnterAltScreen, + cmd.New(cmd.ViewFocus, "*").Tea(), + cmd.New(cmd.ViewRefreshData, "*").Tea(), + ) } func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { @@ -67,8 +76,13 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch { - // case key.Matches(msg, m.keymap.Quit): - // return m, tea.Quit + case key.Matches(msg, m.keymap.Close): + m.ctx.Logger.Debug("close received") + if !m.wm.CloseFocused() { + m.ctx.Logger.Debug("CloseFocused() was false, quitting") + return m, tea.Quit + } + return m, nil } case tea.WindowSizeMsg: @@ -78,15 +92,39 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.views[i] = v cmds = append(cmds, cmd) } + ccmds := m.wm.UpdateAll(tea.WindowSizeMsg{ + Width: m.ctx.Content[0], + Height: m.ctx.Content[1], + }) + cmds = append(cmds, ccmds...) + + case cmd.Command: + var ccmds []tea.Cmd + + switch msg.Call { + case cmd.WinOpen: + m.ctx.Logger.Debugln("received WinOpen") + ccmds = m.wm.Open( + msg.Target, + postdialog.NewModel(m.ctx), + [4]int{3, 2, 10, 6}, + ) + m.ctx.Logger.Debugf("got back ccmds: %v\n", ccmds) + default: + m.ctx.Logger.Debugf("updating all with cmd: %v\n", msg) + ccmds = m.wm.UpdateAll(msg) + } + + cmds = append(cmds, ccmds...) } - v, cmd := m.views[m.currentView].Update(msg) + v, vcmd := m.views[m.currentView].Update(msg) m.views[m.currentView] = v - cmds = append(cmds, cmd) + cmds = append(cmds, vcmd) - header, cmd := m.header.Update(msg) + header, hcmd := m.header.Update(msg) m.header = header - cmds = append(cmds, cmd) + cmds = append(cmds, hcmd) return m, tea.Batch(cmds...) } @@ -95,7 +133,8 @@ func (m Model) View() string { s := strings.Builder{} s.WriteString(m.header.View() + "\n") s.WriteString(m.views[m.currentView].View()) - return s.String() + + return m.wm.View(s.String()) } func (m Model) setSizes(winWidth int, winHeight int) { diff --git a/ui/views/posts/posts.go b/ui/views/posts/posts.go index 5bcddc8..e749f9c 100644 --- a/ui/views/posts/posts.go +++ b/ui/views/posts/posts.go @@ -2,7 +2,6 @@ package posts import ( "fmt" - "strconv" "github.com/charmbracelet/bubbles/key" "github.com/charmbracelet/bubbles/list" @@ -14,6 +13,7 @@ import ( "github.com/mrusme/gobbs/aggregator" "github.com/mrusme/gobbs/models/post" "github.com/mrusme/gobbs/models/reply" + "github.com/mrusme/gobbs/ui/cmd" "github.com/mrusme/gobbs/ui/ctx" ) @@ -30,9 +30,9 @@ var ( type KeyMap struct { Refresh key.Binding Select key.Binding - Esc key.Binding - Quit key.Binding - Reply key.Binding + // Esc key.Binding + // Quit key.Binding + Reply key.Binding } var DefaultKeyMap = KeyMap{ @@ -44,13 +44,13 @@ var DefaultKeyMap = KeyMap{ key.WithKeys("r", "enter"), key.WithHelp("r/enter", "read"), ), - Esc: key.NewBinding( - key.WithKeys("esc"), - key.WithHelp("esc", "close"), - ), - Quit: key.NewBinding( - key.WithKeys("q"), - ), + // Esc: key.NewBinding( + // key.WithKeys("esc"), + // key.WithHelp("esc", "close"), + // ), + // Quit: key.NewBinding( + // key.WithKeys("q"), + // ), Reply: key.NewBinding( key.WithKeys("ctrl+s"), key.WithHelp("ctrl+s", "reply"), @@ -60,6 +60,7 @@ var DefaultKeyMap = KeyMap{ type Model struct { ctx *ctx.Ctx keymap KeyMap + focused bool list list.Model items []list.Item viewport viewport.Model @@ -68,7 +69,7 @@ type Model struct { a *aggregator.Aggregator glam *glamour.TermRenderer - wm []string + // wm []string buffer string replyIDs []string @@ -89,10 +90,11 @@ func (m Model) Init() tea.Cmd { func NewModel(c *ctx.Ctx) Model { m := Model{ - ctx: c, - keymap: DefaultKeyMap, + ctx: c, + keymap: DefaultKeyMap, + focused: false, - wm: []string{WM_ROOT_ID}, + // wm: []string{WM_ROOT_ID}, buffer: "", replyIDs: []string{}, @@ -130,117 +132,122 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch { case key.Matches(msg, m.keymap.Refresh): - if m.WMisFocused("list") { - m.ctx.Loading = true - cmds = append(cmds, m.refresh()) - } + // if m.WMisFocused("list") { + m.ctx.Loading = true + cmds = append(cmds, m.refresh()) + // } case key.Matches(msg, m.keymap.Select): - switch m.WMFocused() { - - case "list": - i, ok := m.list.SelectedItem().(post.Post) - if ok { - m.ctx.Loading = true - cmds = append(cmds, m.loadItem(&i)) - } - - case "post": - if m.buffer != "" { - replyToID, err := strconv.Atoi(m.buffer) - if err != nil { - // TODO: Handle error - } - - if replyToID >= len(m.replyIDs) { - // TODO: Handle error - } - } - m.WMOpen("reply") - - m.ctx.Logger.Debugln("caching view") - m.ctx.Logger.Debugf("buffer: %s", m.buffer) - m.viewcache = m.buildView(false) - - return m, m.textarea.Focus() + // switch m.WMFocused() { + // + // case "list": + i, ok := m.list.SelectedItem().(post.Post) + if ok { + // m.ctx.Loading = true + // cmds = append(cmds, m.loadItem(&i)) + cmd := cmd.New(cmd.WinOpen, "post", cmd.Arg{ + Name: "post", + Value: &i, + }) + cmds = append(cmds, cmd.Tea()) } + // + // case "post": + // if m.buffer != "" { + // replyToID, err := strconv.Atoi(m.buffer) + // if err != nil { + // // TODO: Handle error + // } + // + // if replyToID >= len(m.replyIDs) { + // // TODO: Handle error + // } + // } + // m.WMOpen("reply") + // + // m.ctx.Logger.Debugln("caching view") + // m.ctx.Logger.Debugf("buffer: %s", m.buffer) + // m.viewcache = m.buildView(false) + // + // return m, m.textarea.Focus() + // } - case key.Matches(msg, m.keymap.Esc), key.Matches(msg, m.keymap.Quit): - switch m.WMFocused() { - - case "list": - return m, tea.Quit - - case "post": - // Let's make sure we reset the texarea - m.textarea.Reset() - m.WMClose("post") - return m, nil - - case "reply": - if key.Matches(msg, m.keymap.Esc) { - m.buffer = "" - m.WMClose("reply") - return m, nil - } - } + // case key.Matches(msg, m.keymap.Esc), key.Matches(msg, m.keymap.Quit): + // switch m.WMFocused() { + // + // case "list": + // return m, tea.Quit + // + // case "post": + // // Let's make sure we reset the texarea + // m.textarea.Reset() + // m.WMClose("post") + // return m, nil + // + // case "reply": + // if key.Matches(msg, m.keymap.Esc) { + // m.buffer = "" + // m.WMClose("reply") + // return m, nil + // } + // } case key.Matches(msg, m.keymap.Reply): - if m.WMisFocused("reply") { - replyToIdx, _ := strconv.Atoi(m.buffer) + // if m.WMisFocused("reply") { + // replyToIdx, _ := strconv.Atoi(m.buffer) + // + // m.ctx.Logger.Debugf("replyToIdx: %d", replyToIdx) + // + // var irtID string = "" + // var irtIRT string = "" + // var irtSysIDX int = 0 + // + // if replyToIdx == 0 { + // irtID = m.activePost.ID + // irtSysIDX = m.activePost.SysIDX + // } else { + // irt := m.allReplies[(replyToIdx - 1)] + // irtID = strconv.Itoa(replyToIdx + 1) + // irtIRT = irt.InReplyTo + // irtSysIDX = irt.SysIDX + // } + // + // r := reply.Reply{ + // ID: irtID, + // InReplyTo: irtIRT, + // Body: m.textarea.Value(), + // SysIDX: irtSysIDX, + // } + // err := m.a.CreateReply(&r) + // if err != nil { + // m.ctx.Logger.Error(err) + // } + // + // m.textarea.Reset() + // m.buffer = "" + // m.WMClose("reply") + // return m, nil + // } - m.ctx.Logger.Debugf("replyToIdx: %d", replyToIdx) - - var irtID string = "" - var irtIRT string = "" - var irtSysIDX int = 0 - - if replyToIdx == 0 { - irtID = m.activePost.ID - irtSysIDX = m.activePost.SysIDX - } else { - irt := m.allReplies[(replyToIdx - 1)] - irtID = strconv.Itoa(replyToIdx + 1) - irtIRT = irt.InReplyTo - irtSysIDX = irt.SysIDX - } - - r := reply.Reply{ - ID: irtID, - InReplyTo: irtIRT, - Body: m.textarea.Value(), - SysIDX: irtSysIDX, - } - err := m.a.CreateReply(&r) - if err != nil { - m.ctx.Logger.Error(err) - } - - m.textarea.Reset() - m.buffer = "" - m.WMClose("reply") - return m, nil - } - - default: - switch msg.String() { - case "1", "2", "3", "4", "5", "6", "7", "8", "9", "0": - if m.WMisFocused("post") { - m.buffer += msg.String() - return m, nil - } - default: - if m.WMFocused() != "reply" { - m.buffer = "" - } - } + // default: + // switch msg.String() { + // case "1", "2", "3", "4", "5", "6", "7", "8", "9", "0": + // if m.WMisFocused("post") { + // m.buffer += msg.String() + // return m, nil + // } + // default: + // if m.WMFocused() != "reply" { + // m.buffer = "" + // } + // } } case tea.WindowSizeMsg: listWidth := m.ctx.Content[0] - 2 listHeight := m.ctx.Content[1] - 1 - viewportWidth := m.ctx.Content[0] - 9 - viewportHeight := m.ctx.Content[1] - 10 + // viewportWidth := m.ctx.Content[0] - 9 + // viewportHeight := m.ctx.Content[1] - 10 m.ctx.Theme.PostsList.List.Focused.Width(listWidth) m.ctx.Theme.PostsList.List.Blurred.Width(listWidth) @@ -251,12 +258,12 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { listHeight-2, ) - viewportStyle.Width(viewportWidth) - viewportStyle.Height(viewportHeight) - m.viewport = viewport.New(viewportWidth-4, viewportHeight-4) - m.viewport.Width = viewportWidth - 4 - m.viewport.Height = viewportHeight + 1 - // cmds = append(cmds, viewport.Sync(m.viewport)) + // viewportStyle.Width(viewportWidth) + // viewportStyle.Height(viewportHeight) + // m.viewport = viewport.New(viewportWidth-4, viewportHeight-4) + // m.viewport.Width = viewportWidth - 4 + // m.viewport.Height = viewportHeight + 1 + // // cmds = append(cmds, viewport.Sync(m.viewport)) case []list.Item: m.items = msg @@ -264,28 +271,47 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.ctx.Loading = false return m, nil - case *post.Post: - m.viewport.SetContent(m.renderViewport(msg)) - m.WMOpen("post") - m.ctx.Loading = false - return m, nil + // case *post.Post: + // m.viewport.SetContent(m.renderViewport(msg)) + // m.WMOpen("post") + // m.ctx.Loading = false + // return m, nil - } - - var cmd tea.Cmd - - switch m.WMFocused() { - case "list": - m.list, cmd = m.list.Update(msg) - case "post": - m.viewport, cmd = m.viewport.Update(msg) - case "reply": - if !m.textarea.Focused() { - cmds = append(cmds, m.textarea.Focus()) + case cmd.Command: + switch msg.Call { + case cmd.ViewFocus: + if msg.Target == "*" { + m.focused = true + } + return m, nil + case cmd.ViewBlur: + if msg.Target == "*" { + m.focused = false + } + return m, nil + case cmd.ViewRefreshData: + if msg.Target == "*" { + m.ctx.Loading = true + cmds = append(cmds, m.refresh()) + } } - m.textarea, cmd = m.textarea.Update(msg) + } - cmds = append(cmds, cmd) + + var lcmd tea.Cmd + + // switch m.WMFocused() { + // case "list": + m.list, lcmd = m.list.Update(msg) + // case "post": + // m.viewport, lcmd = m.viewport.Update(msg) + // case "reply": + // if !m.textarea.Focused() { + // cmds = append(cmds, m.textarea.Focus()) + // } + // m.textarea, lcmd = m.textarea.Update(msg) + // } + cmds = append(cmds, lcmd) return m, tea.Batch(cmds...) } diff --git a/ui/views/posts/view.go b/ui/views/posts/view.go index a885400..e3128f7 100644 --- a/ui/views/posts/view.go +++ b/ui/views/posts/view.go @@ -1,14 +1,9 @@ package posts import ( - "fmt" "strings" - "github.com/charmbracelet/glamour" "github.com/charmbracelet/lipgloss" - "github.com/mrusme/gobbs/models/post" - "github.com/mrusme/gobbs/models/reply" - "github.com/mrusme/gobbs/ui/helpers" ) func (m Model) View() string { @@ -18,21 +13,21 @@ func (m Model) View() string { func (m Model) buildView(cached bool) string { var view strings.Builder = strings.Builder{} - if cached && m.WMisFocused("reply") && m.viewcache != "" { - m.ctx.Logger.Debugln("Cached View()") - - m.textarea.SetWidth(m.viewcacheTextareaXY[2]) - m.textarea.SetHeight(m.viewcacheTextareaXY[3]) - - return helpers.PlaceOverlay( - m.viewcacheTextareaXY[0], m.viewcacheTextareaXY[1], - m.textarea.View(), m.viewcache, - false) - } - - m.ctx.Logger.Debugln("View()") + // if cached && m.WMisFocused("reply") && m.viewcache != "" { + // m.ctx.Logger.Debugln("Cached View()") + // + // m.textarea.SetWidth(m.viewcacheTextareaXY[2]) + // m.textarea.SetHeight(m.viewcacheTextareaXY[3]) + // + // return helpers.PlaceOverlay( + // m.viewcacheTextareaXY[0], m.viewcacheTextareaXY[1], + // m.textarea.View(), m.viewcache, + // false) + // } + // + m.ctx.Logger.Debugln("Posts.View()") var l string = "" - if m.WMisFocused("list") { + if m.focused { l = m.ctx.Theme.PostsList.List.Focused.Render(m.list.View()) } else { l = m.ctx.Theme.PostsList.List.Blurred.Render(m.list.View()) @@ -42,179 +37,179 @@ func (m Model) buildView(cached bool) string { l, )) - if m.WMisOpen("post") { - var style lipgloss.Style - if m.WMisFocused("post") { - style = m.ctx.Theme.DialogBox.Titlebar.Focused - } else { - style = m.ctx.Theme.DialogBox.Titlebar.Blurred - } - titlebar := style.Align(lipgloss.Center). - Width(m.viewport.Width + 4). - Render("Post") - - bottombar := m.ctx.Theme.DialogBox.Bottombar. - Width(m.viewport.Width + 4). - Render("[#]r reply · esc close") - - ui := lipgloss.JoinVertical( - lipgloss.Center, - titlebar, - viewportStyle.Render(m.viewport.View()), - bottombar, - ) - - var tmp string - if m.WMisFocused("post") { - tmp = helpers.PlaceOverlay(3, 2, - m.ctx.Theme.DialogBox.Window.Focused.Render(ui), - view.String(), true) - } else { - tmp = helpers.PlaceOverlay(3, 2, - m.ctx.Theme.DialogBox.Window.Blurred.Render(ui), - view.String(), true) - } - - view = strings.Builder{} - view.WriteString(tmp) - } - - if m.WMisOpen("reply") { - title := "Reply" - if m.buffer != "" && m.buffer != "0" { - title += " to reply #" + m.buffer - } - titlebar := m.ctx.Theme.DialogBox.Titlebar.Focused. - Align(lipgloss.Center). - Width(m.viewport.Width - 2). - Render(title) - - textareaWidth := m.viewport.Width - 2 - textareaHeight := 6 - m.textarea.SetWidth(textareaWidth) - m.textarea.SetHeight(textareaHeight) - - bottombar := m.ctx.Theme.DialogBox.Bottombar. - Width(m.viewport.Width - 2). - Render("ctrl+enter reply · esc close") - - replyWindow := lipgloss.JoinVertical( - lipgloss.Center, - titlebar, - m.textarea.View(), - bottombar, - ) - - replyWindowX := 5 - replyWindowY := m.ctx.Screen[1] - 21 - - tmp := helpers.PlaceOverlay(replyWindowX, replyWindowY, - m.ctx.Theme.DialogBox.Window.Focused.Render(replyWindow), - view.String(), true) - - m.viewcacheTextareaXY[0] = replyWindowX + 1 - m.viewcacheTextareaXY[1] = replyWindowY + 2 - m.viewcacheTextareaXY[2] = textareaWidth - m.viewcacheTextareaXY[3] = textareaHeight - - view = strings.Builder{} - view.WriteString(tmp) - } + // if m.WMisOpen("post") { + // var style lipgloss.Style + // if m.WMisFocused("post") { + // style = m.ctx.Theme.DialogBox.Titlebar.Focused + // } else { + // style = m.ctx.Theme.DialogBox.Titlebar.Blurred + // } + // titlebar := style.Align(lipgloss.Center). + // Width(m.viewport.Width + 4). + // Render("Post") + // + // bottombar := m.ctx.Theme.DialogBox.Bottombar. + // Width(m.viewport.Width + 4). + // Render("[#]r reply · esc close") + // + // ui := lipgloss.JoinVertical( + // lipgloss.Center, + // titlebar, + // viewportStyle.Render(m.viewport.View()), + // bottombar, + // ) + // + // var tmp string + // if m.WMisFocused("post") { + // tmp = helpers.PlaceOverlay(3, 2, + // m.ctx.Theme.DialogBox.Window.Focused.Render(ui), + // view.String(), true) + // } else { + // tmp = helpers.PlaceOverlay(3, 2, + // m.ctx.Theme.DialogBox.Window.Blurred.Render(ui), + // view.String(), true) + // } + // + // view = strings.Builder{} + // view.WriteString(tmp) + // } + // + // if m.WMisOpen("reply") { + // title := "Reply" + // if m.buffer != "" && m.buffer != "0" { + // title += " to reply #" + m.buffer + // } + // titlebar := m.ctx.Theme.DialogBox.Titlebar.Focused. + // Align(lipgloss.Center). + // Width(m.viewport.Width - 2). + // Render(title) + // + // textareaWidth := m.viewport.Width - 2 + // textareaHeight := 6 + // m.textarea.SetWidth(textareaWidth) + // m.textarea.SetHeight(textareaHeight) + // + // bottombar := m.ctx.Theme.DialogBox.Bottombar. + // Width(m.viewport.Width - 2). + // Render("ctrl+enter reply · esc close") + // + // replyWindow := lipgloss.JoinVertical( + // lipgloss.Center, + // titlebar, + // m.textarea.View(), + // bottombar, + // ) + // + // replyWindowX := 5 + // replyWindowY := m.ctx.Screen[1] - 21 + // + // tmp := helpers.PlaceOverlay(replyWindowX, replyWindowY, + // m.ctx.Theme.DialogBox.Window.Focused.Render(replyWindow), + // view.String(), true) + // + // m.viewcacheTextareaXY[0] = replyWindowX + 1 + // m.viewcacheTextareaXY[1] = replyWindowY + 2 + // m.viewcacheTextareaXY[2] = textareaWidth + // m.viewcacheTextareaXY[3] = textareaHeight + // + // view = strings.Builder{} + // view.WriteString(tmp) + // } m.viewcache = view.String() return m.viewcache } -func (m *Model) renderViewport(p *post.Post) string { - var out string = "" - - var err error - m.glam, err = glamour.NewTermRenderer( - glamour.WithAutoStyle(), - glamour.WithWordWrap(m.viewport.Width), - ) - if err != nil { - m.ctx.Logger.Error(err) - m.glam = nil - } - - adj := "writes" - if p.Subject[len(p.Subject)-1:] == "?" { - adj = "asks" - } - - body, err := m.glam.Render(p.Body) - if err != nil { - m.ctx.Logger.Error(err) - body = p.Body - } - out += fmt.Sprintf( - " %s\n\n %s\n%s", - m.ctx.Theme.Post.Author.Render( - fmt.Sprintf("%s %s:", p.Author.Name, adj), - ), - m.ctx.Theme.Post.Subject.Render(p.Subject), - body, - ) - - m.replyIDs = []string{p.ID} - m.activePost = p - out += m.renderReplies(0, p.Author.Name, &p.Replies) - - return out -} - -func (m *Model) renderReplies( - level int, - inReplyTo string, - replies *[]reply.Reply, -) string { - var out string = "" - - if replies == nil { - return "" - } - - for ri, re := range *replies { - var err error = nil - var body string = "" - var author string = "" - - if re.Deleted { - body = "\n DELETED\n\n" - author = "DELETED" - } else { - body, err = m.glam.Render(re.Body) - if err != nil { - m.ctx.Logger.Error(err) - body = re.Body - } - - author = re.Author.Name - } - - m.replyIDs = append(m.replyIDs, re.ID) - m.allReplies = append(m.allReplies, &(*replies)[ri]) - idx := len(m.replyIDs) - 1 - - out += fmt.Sprintf( - "\n\n %s %s%s%s\n%s", - m.ctx.Theme.Reply.Author.Render( - author, - ), - lipgloss.NewStyle(). - Foreground(m.ctx.Theme.Reply.Author.GetBackground()). - Render(fmt.Sprintf("writes in reply to %s:", inReplyTo)), - strings.Repeat(" ", (m.viewport.Width-len(author)-len(inReplyTo)-28)), - lipgloss.NewStyle(). - Foreground(lipgloss.Color("#777777")). - Render(fmt.Sprintf("#%d", idx)), - body, - ) - - idx++ - out += m.renderReplies(level+1, re.Author.Name, &re.Replies) - } - - return out -} +// func (m *Model) renderViewport(p *post.Post) string { +// var out string = "" +// +// var err error +// m.glam, err = glamour.NewTermRenderer( +// glamour.WithAutoStyle(), +// glamour.WithWordWrap(m.viewport.Width), +// ) +// if err != nil { +// m.ctx.Logger.Error(err) +// m.glam = nil +// } +// +// adj := "writes" +// if p.Subject[len(p.Subject)-1:] == "?" { +// adj = "asks" +// } +// +// body, err := m.glam.Render(p.Body) +// if err != nil { +// m.ctx.Logger.Error(err) +// body = p.Body +// } +// out += fmt.Sprintf( +// " %s\n\n %s\n%s", +// m.ctx.Theme.Post.Author.Render( +// fmt.Sprintf("%s %s:", p.Author.Name, adj), +// ), +// m.ctx.Theme.Post.Subject.Render(p.Subject), +// body, +// ) +// +// m.replyIDs = []string{p.ID} +// m.activePost = p +// out += m.renderReplies(0, p.Author.Name, &p.Replies) +// +// return out +// } +// +// func (m *Model) renderReplies( +// level int, +// inReplyTo string, +// replies *[]reply.Reply, +// ) string { +// var out string = "" +// +// if replies == nil { +// return "" +// } +// +// for ri, re := range *replies { +// var err error = nil +// var body string = "" +// var author string = "" +// +// if re.Deleted { +// body = "\n DELETED\n\n" +// author = "DELETED" +// } else { +// body, err = m.glam.Render(re.Body) +// if err != nil { +// m.ctx.Logger.Error(err) +// body = re.Body +// } +// +// author = re.Author.Name +// } +// +// m.replyIDs = append(m.replyIDs, re.ID) +// m.allReplies = append(m.allReplies, &(*replies)[ri]) +// idx := len(m.replyIDs) - 1 +// +// out += fmt.Sprintf( +// "\n\n %s %s%s%s\n%s", +// m.ctx.Theme.Reply.Author.Render( +// author, +// ), +// lipgloss.NewStyle(). +// Foreground(m.ctx.Theme.Reply.Author.GetBackground()). +// Render(fmt.Sprintf("writes in reply to %s:", inReplyTo)), +// strings.Repeat(" ", (m.viewport.Width-len(author)-len(inReplyTo)-28)), +// lipgloss.NewStyle(). +// Foreground(lipgloss.Color("#777777")). +// Render(fmt.Sprintf("#%d", idx)), +// body, +// ) +// +// idx++ +// out += m.renderReplies(level+1, re.Author.Name, &re.Replies) +// } +// +// return out +// } diff --git a/ui/views/posts/wm.go b/ui/views/posts/wm.go index c8757af..62e9eb0 100644 --- a/ui/views/posts/wm.go +++ b/ui/views/posts/wm.go @@ -1,47 +1,48 @@ package posts -var WM_ROOT_ID = "list" - -func (m *Model) WMOpen(id string) bool { - if m.WMisOpen(id) { - if m.WMisFocused(id) { - return true - } - return false - } - - m.wm = append(m.wm, id) - return true -} - -func (m *Model) WMCloseFocused() bool { - return m.WMClose(m.WMFocused()) -} - -func (m *Model) WMClose(id string) bool { - for i := len(m.wm) - 1; i > 0; i-- { - if m.wm[i] == id { - m.wm = append(m.wm[:i], m.wm[i+1:]...) - return true - } - } - - return false -} - -func (m *Model) WMFocused() string { - return m.wm[len(m.wm)-1] -} - -func (m *Model) WMisOpen(id string) bool { - for _, openID := range m.wm { - if openID == id { - return true - } - } - return false -} - -func (m *Model) WMisFocused(id string) bool { - return id == m.WMFocused() -} +// +// var WM_ROOT_ID = "list" +// +// func (m *Model) WMOpen(id string) bool { +// if m.WMisOpen(id) { +// if m.WMisFocused(id) { +// return true +// } +// return false +// } +// +// m.wm = append(m.wm, id) +// return true +// } +// +// func (m *Model) WMCloseFocused() bool { +// return m.WMClose(m.WMFocused()) +// } +// +// func (m *Model) WMClose(id string) bool { +// for i := len(m.wm) - 1; i > 0; i-- { +// if m.wm[i] == id { +// m.wm = append(m.wm[:i], m.wm[i+1:]...) +// return true +// } +// } +// +// return false +// } +// +// func (m *Model) WMFocused() string { +// return m.wm[len(m.wm)-1] +// } +// +// func (m *Model) WMisOpen(id string) bool { +// for _, openID := range m.wm { +// if openID == id { +// return true +// } +// } +// return false +// } +// +// func (m *Model) WMisFocused(id string) bool { +// return id == m.WMFocused() +// }