From 520686204e343058138a96ce7de2d347310a15aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=9E=E3=83=AA=E3=82=A6=E3=82=B9?= Date: Thu, 5 Jan 2023 19:44:14 -0500 Subject: [PATCH] Implemented first draft of create post UI --- ui/views/posts/posts.go | 25 +++++++++++++++ ui/windows/postcreate/handlers.go | 44 ++++++++++++++++++++++---- ui/windows/postcreate/postcreate.go | 49 ++++++++++++++++++++++------- ui/windows/postcreate/view.go | 31 +++++++++++++++--- ui/windows/postshow/handlers.go | 3 +- 5 files changed, 130 insertions(+), 22 deletions(-) diff --git a/ui/views/posts/posts.go b/ui/views/posts/posts.go index 2897c24..4eae7f8 100644 --- a/ui/views/posts/posts.go +++ b/ui/views/posts/posts.go @@ -11,6 +11,7 @@ import ( "github.com/mrusme/gobbs/models/post" "github.com/mrusme/gobbs/ui/cmd" "github.com/mrusme/gobbs/ui/ctx" + "github.com/mrusme/gobbs/ui/windows/postcreate" "github.com/mrusme/gobbs/ui/windows/postshow" ) @@ -20,6 +21,7 @@ var ( type KeyMap struct { Refresh key.Binding + NewPost key.Binding Select key.Binding } @@ -28,6 +30,10 @@ var DefaultKeyMap = KeyMap{ key.WithKeys("ctrl+r"), key.WithHelp("ctrl+r", "refresh"), ), + NewPost: key.NewBinding( + key.WithKeys("n"), + key.WithHelp("n", "new post"), + ), Select: key.NewBinding( key.WithKeys("r", "enter"), key.WithHelp("r/enter", "read"), @@ -100,6 +106,25 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { }) cmds = append(cmds, cmd.Tea()) } + + case key.Matches(msg, m.keymap.NewPost): + i, ok := m.list.SelectedItem().(post.Post) + if ok { + m.viewcache = m.buildView(false) + cmd := cmd.New( + cmd.WinOpen, + postcreate.WIN_ID, + cmd.Arg{ + Name: "action", + Value: "post", + }, + cmd.Arg{ + Name: "post", + Value: &i, + }, + ) + cmds = append(cmds, cmd.Tea()) + } } case tea.WindowSizeMsg: diff --git a/ui/windows/postcreate/handlers.go b/ui/windows/postcreate/handlers.go index 015bde7..749cd52 100644 --- a/ui/windows/postcreate/handlers.go +++ b/ui/windows/postcreate/handlers.go @@ -7,6 +7,27 @@ import ( "github.com/mrusme/gobbs/ui/cmd" ) +func handleTab(mi interface{}) (bool, []tea.Cmd) { + var m *Model = mi.(*Model) + var cmds []tea.Cmd + + if m.action == "reply" { + return false, cmds + } + + if m.inputFocused == 0 { + m.inputFocused = 1 + m.textinput.Blur() + cmds = append(cmds, m.textarea.Focus()) + } else { + m.inputFocused = 0 + m.textarea.Blur() + cmds = append(cmds, m.textinput.Focus()) + } + + return true, cmds +} + func handleSubmit(mi interface{}) (bool, []tea.Cmd) { var m *Model = mi.(*Model) var cmds []tea.Cmd @@ -15,7 +36,7 @@ func handleSubmit(mi interface{}) (bool, []tea.Cmd) { if m.replyToIdx == 0 { // No numbers were typed before hitting `r` so we're replying to the actual // Post - x := m.replyToIface.(post.Post) + x := m.iface.(post.Post) r = reply.Reply{ ID: x.ID, InReplyTo: "", @@ -25,7 +46,7 @@ func handleSubmit(mi interface{}) (bool, []tea.Cmd) { } else { // Numbers were typed before hitting `r`, so we're taking the actual reply // here - r = m.replyToIface.(reply.Reply) + r = m.iface.(reply.Reply) } r.Body = m.textarea.Value() @@ -53,10 +74,21 @@ func handleWinOpenCmd(mi interface{}, c cmd.Command) (bool, []tea.Cmd) { if c.Target == WIN_ID { m.xywh = c.GetArg("xywh").([4]int) - m.replyToIdx = c.GetArg("replyToIdx").(int) - m.replyTo = c.GetArg("replyTo").(string) - m.replyToIface = c.GetArg(m.replyTo) - cmds = append(cmds, m.textarea.Focus()) + + m.action = c.GetArg("action").(string) + + if m.action == "post" { + m.iface = c.GetArg("post").(*post.Post) + m.inputFocused = 0 + cmds = append(cmds, m.textinput.Focus()) + } else if m.action == "reply" { + m.replyToIdx = c.GetArg("replyToIdx").(int) + m.replyTo = c.GetArg("replyTo").(string) + m.iface = c.GetArg(m.replyTo) + m.inputFocused = 1 + cmds = append(cmds, m.textarea.Focus()) + } + return true, cmds } diff --git a/ui/windows/postcreate/postcreate.go b/ui/windows/postcreate/postcreate.go index c816403..afdd72e 100644 --- a/ui/windows/postcreate/postcreate.go +++ b/ui/windows/postcreate/postcreate.go @@ -2,6 +2,7 @@ package postcreate import ( "github.com/charmbracelet/bubbles/textarea" + "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" "github.com/mrusme/gobbs/aggregator" "github.com/mrusme/gobbs/ui/ctx" @@ -18,13 +19,16 @@ type Model struct { xywh [4]int - textarea textarea.Model + textinput textinput.Model + textarea textarea.Model + inputFocused int a *aggregator.Aggregator - replyToIdx int - replyTo string - replyToIface interface{} + action string + iface interface{} + replyToIdx int + replyTo string viewcache string viewcacheTextareaXY []int @@ -44,18 +48,26 @@ func NewModel(c *ctx.Ctx) Model { ), xywh: [4]int{0, 0, 0, 0}, - replyToIdx: 0, - replyTo: "", - replyToIface: nil, + inputFocused: 0, + + action: "", + iface: nil, + replyToIdx: 0, + replyTo: "", viewcache: "", viewcacheTextareaXY: []int{0, 0, 0, 0}, } + m.textinput = textinput.New() + m.textinput.Placeholder = "Subject goes here" + m.textinput.Prompt = "" + m.textarea = textarea.New() - m.textarea.Placeholder = "Type in your reply ..." + m.textarea.Placeholder = "Type in your post ..." m.textarea.Prompt = "" + m.tk.KeymapAdd("tab", "tab", "tab") // TODO CONTINUE HERE m.tk.KeymapAdd("submit", "submit", "ctrl+s") m.a, _ = aggregator.New(m.ctx) @@ -63,6 +75,10 @@ func NewModel(c *ctx.Ctx) Model { m.tk.SetViewFunc(buildView) m.tk.SetMsgHandling(toolkit.MsgHandling{ OnKeymapKey: []toolkit.MsgHandlingKeymapKey{ + { + ID: "tab", + Handler: handleTab, + }, { ID: "submit", Handler: handleSubmit, @@ -85,10 +101,21 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var tcmd tea.Cmd - if !m.textarea.Focused() { - cmds = append(cmds, m.textarea.Focus()) + switch m.inputFocused { + + case 0: + if !m.textinput.Focused() { + cmds = append(cmds, m.textinput.Focus()) + } + m.textinput, tcmd = m.textinput.Update(msg) + + case 1: + if !m.textarea.Focused() { + cmds = append(cmds, m.textarea.Focus()) + } + m.textarea, tcmd = m.textarea.Update(msg) + } - m.textarea, tcmd = m.textarea.Update(msg) cmds = append(cmds, tcmd) return m, tea.Batch(cmds...) diff --git a/ui/windows/postcreate/view.go b/ui/windows/postcreate/view.go index 412c62c..ead6b47 100644 --- a/ui/windows/postcreate/view.go +++ b/ui/windows/postcreate/view.go @@ -3,6 +3,8 @@ package postcreate import ( "fmt" + "github.com/charmbracelet/lipgloss" + "github.com/mrusme/gobbs/models/post" "github.com/mrusme/gobbs/ui/helpers" ) @@ -25,11 +27,20 @@ func buildView(mi interface{}, cached bool) string { false) } - title := "Reply" - if m.replyToIdx != 0 { - title += fmt.Sprintf(" to reply #%d", m.replyToIdx) + title := "" + + if m.action == "reply" { + title = "Reply" + if m.replyToIdx != 0 { + title += fmt.Sprintf(" to reply #%d", m.replyToIdx) + } + } else if m.action == "post" { + title = fmt.Sprintf("New Post in %s", m.iface.(*post.Post).Forum.Name) } + // textinputWidth := m.tk.ViewWidth() - 2 + // m.textinput.SetWidth(textinputWidth) + textareaWidth := m.tk.ViewWidth() - 2 textareaHeight := 6 m.textarea.SetWidth(textareaWidth) @@ -43,9 +54,21 @@ func buildView(mi interface{}, cached bool) string { m.ctx.Logger.Debugln("View()") m.ctx.Logger.Debugf("IsFocused: %v\n", m.tk.IsFocused()) + var tmp string = "" + if m.action == "post" { + tmp = lipgloss.JoinVertical( + lipgloss.Left, + m.textinput.View(), + "", + m.textarea.View(), + ) + } else if m.action == "reply" { + tmp = m.textarea.View() + } + return m.tk.Dialog( title, - m.textarea.View(), + tmp, true, ) diff --git a/ui/windows/postshow/handlers.go b/ui/windows/postshow/handlers.go index d986bbd..9a5976f 100644 --- a/ui/windows/postshow/handlers.go +++ b/ui/windows/postshow/handlers.go @@ -65,6 +65,7 @@ func handleReply(mi interface{}) (bool, []tea.Cmd) { } m.ctx.Logger.Debugf("replyToIdx: %d", replyToIdx) + var ract cmd.Arg = cmd.Arg{Name: "action", Value: "reply"} var rtype cmd.Arg = cmd.Arg{Name: "replyTo"} var rarg cmd.Arg var ridx cmd.Arg = cmd.Arg{Name: "replyToIdx", Value: replyToIdx} @@ -79,7 +80,7 @@ func handleReply(mi interface{}) (bool, []tea.Cmd) { rarg.Value = *m.allReplies[(replyToIdx - 1)] } - cmd := cmd.New(cmd.WinOpen, postcreate.WIN_ID, rtype, rarg, ridx) + cmd := cmd.New(cmd.WinOpen, postcreate.WIN_ID, ract, rtype, rarg, ridx) cmds = append(cmds, cmd.Tea()) m.ctx.Logger.Debugln("caching view")