From fc51e5794c2515240e62b73686324a3ec2b40b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=9E=E3=83=AA=E3=82=A6=E3=82=B9?= Date: Sun, 1 Jan 2023 22:01:05 -0500 Subject: [PATCH] Refactored focus, implemented WM --- ui/views/posts/posts.go | 79 ++++++++++++++++++++++++++++------------- ui/views/posts/view.go | 13 ++++--- ui/views/posts/wm.go | 47 ++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 32 deletions(-) create mode 100644 ui/views/posts/wm.go diff --git a/ui/views/posts/posts.go b/ui/views/posts/posts.go index baa737b..afc98bc 100644 --- a/ui/views/posts/posts.go +++ b/ui/views/posts/posts.go @@ -2,6 +2,7 @@ package posts import ( "fmt" + "strconv" "github.com/charmbracelet/bubbles/key" "github.com/charmbracelet/bubbles/list" @@ -51,19 +52,21 @@ var DefaultKeyMap = KeyMap{ } type Model struct { + ctx *ctx.Ctx keymap KeyMap list list.Model items []list.Item viewport viewport.Model textarea textarea.Model - ctx *ctx.Ctx - a *aggregator.Aggregator + a *aggregator.Aggregator glam *glamour.TermRenderer - focused string - buffer string - replyIDs []string + wm []string + + buffer string + replyIDs []string + viewcache string viewcacheTextareaXY []int } @@ -76,10 +79,14 @@ func (m Model) Init() tea.Cmd { func NewModel(c *ctx.Ctx) Model { m := Model{ - ctx: c, - keymap: DefaultKeyMap, - focused: "list", - buffer: "", + ctx: c, + keymap: DefaultKeyMap, + + wm: []string{WM_ROOT_ID}, + + buffer: "", + replyIDs: []string{}, + viewcache: "", viewcacheTextareaXY: []int{0, 0, 0, 0}, } @@ -111,21 +118,35 @@ 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.Refresh): - if m.focused == "list" { + if m.WMisFocused("list") { m.ctx.Loading = true cmds = append(cmds, m.refresh()) } case key.Matches(msg, m.keymap.Select): - if m.focused == "list" { + switch m.WMFocused() { + + case "list": i, ok := m.list.SelectedItem().(post.Post) if ok { m.ctx.Loading = true cmds = append(cmds, m.loadItem(&i)) } - } else if m.focused == "post" { - m.focused = "reply" + + 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) @@ -135,28 +156,34 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } case key.Matches(msg, m.keymap.Esc), key.Matches(msg, m.keymap.Quit): - if m.focused == "list" { + switch m.WMFocused() { + + case "list": return m, tea.Quit - } else if m.focused == "post" { + + case "post": // Let's make sure we reset the texarea m.textarea.Reset() - m.focused = "list" - return m, nil - } else if m.focused == "reply" && key.Matches(msg, m.keymap.Esc) { - m.focused = "post" - m.buffer = "" + m.WMClose("post") return m, nil + + case "reply": + if key.Matches(msg, m.keymap.Esc) { + 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.focused == "post" { + if m.WMisFocused("post") { m.buffer += msg.String() return m, nil } default: - if m.focused != "reply" { + if m.WMFocused() != "reply" { m.buffer = "" } } @@ -192,6 +219,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case *post.Post: m.viewport.SetContent(m.renderViewport(msg)) + m.WMOpen("post") m.ctx.Loading = false return m, nil @@ -199,11 +227,12 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmd tea.Cmd - if m.focused == "list" { + switch m.WMFocused() { + case "list": m.list, cmd = m.list.Update(msg) - } else if m.focused == "post" { + case "post": m.viewport, cmd = m.viewport.Update(msg) - } else if m.focused == "reply" { + case "reply": if !m.textarea.Focused() { cmds = append(cmds, m.textarea.Focus()) } diff --git a/ui/views/posts/view.go b/ui/views/posts/view.go index 24b366b..b4f0948 100644 --- a/ui/views/posts/view.go +++ b/ui/views/posts/view.go @@ -18,7 +18,7 @@ func (m Model) View() string { func (m Model) buildView(cached bool) string { var view strings.Builder = strings.Builder{} - if cached && m.focused == "reply" && m.viewcache != "" { + if cached && m.WMisFocused("reply") && m.viewcache != "" { m.ctx.Logger.Debugln("Cached View()") m.textarea.SetWidth(m.viewcacheTextareaXY[2]) @@ -29,7 +29,7 @@ func (m Model) buildView(cached bool) string { m.ctx.Logger.Debugln("View()") var l string = "" - if m.focused == "list" { + if m.WMisFocused("list") { l = m.ctx.Theme.PostsList.List.Focused.Render(m.list.View()) } else { l = m.ctx.Theme.PostsList.List.Blurred.Render(m.list.View()) @@ -39,9 +39,9 @@ func (m Model) buildView(cached bool) string { l, )) - if m.focused == "post" || m.focused == "reply" { + if m.WMisOpen("post") { var style lipgloss.Style - if m.focused == "post" { + if m.WMisFocused("post") { style = m.ctx.Theme.DialogBox.Titlebar.Focused } else { style = m.ctx.Theme.DialogBox.Titlebar.Blurred @@ -62,7 +62,7 @@ func (m Model) buildView(cached bool) string { ) var tmp string - if m.focused == "post" { + if m.WMisFocused("post") { tmp = helpers.PlaceOverlay(3, 2, m.ctx.Theme.DialogBox.Window.Focused.Render(ui), view.String(), true) @@ -76,7 +76,7 @@ func (m Model) buildView(cached bool) string { view.WriteString(tmp) } - if m.focused == "reply" { + if m.WMisOpen("reply") { title := "Reply" if m.buffer != "" && m.buffer != "0" { title += " to reply #" + m.buffer @@ -157,7 +157,6 @@ func (m *Model) renderViewport(p *post.Post) string { m.replyIDs = []string{p.ID} out += m.renderReplies(0, p.Author.Name, &p.Replies) - m.focused = "post" return out } diff --git a/ui/views/posts/wm.go b/ui/views/posts/wm.go new file mode 100644 index 0000000..c8757af --- /dev/null +++ b/ui/views/posts/wm.go @@ -0,0 +1,47 @@ +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() +}