diff --git a/ui/ui.go b/ui/ui.go index d739598..2822143 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -10,6 +10,7 @@ import ( "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/msgerror" "github.com/mrusme/gobbs/ui/windows/postcreate" "github.com/mrusme/gobbs/ui/windows/postshow" @@ -151,6 +152,15 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { cmds = append(cmds, clcmds...) } + case cmd.MsgError: + m.ctx.Logger.Debugln("received MsgError") + ccmds = m.wm.Open( + msgerror.WIN_ID, + msgerror.NewModel(m.ctx), + [4]int{9, int(m.ctx.Content[1] / 3), 12, int(m.ctx.Content[1] / 3)}, + &msg, + ) + default: if msg.Call < cmd.ViewFocus { m.ctx.Logger.Debugf("updating all with cmd: %v\n", msg) diff --git a/ui/windows/msgerror/msgerror.go b/ui/windows/msgerror/msgerror.go new file mode 100644 index 0000000..372c5bb --- /dev/null +++ b/ui/windows/msgerror/msgerror.go @@ -0,0 +1,183 @@ +package msgerror + +import ( + "strings" + + "github.com/charmbracelet/bubbles/viewport" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" + "github.com/mrusme/gobbs/aggregator" + "github.com/mrusme/gobbs/ui/cmd" + "github.com/mrusme/gobbs/ui/ctx" +) + +var ( + WIN_ID = "msgerror" + + viewportStyle = lipgloss.NewStyle(). + Margin(0, 0, 0, 0). + Padding(0, 0). + BorderTop(false). + BorderLeft(false). + BorderRight(false). + BorderBottom(false) +) + +type KeyMap struct { +} + +var DefaultKeyMap = KeyMap{} + +type Model struct { + ctx *ctx.Ctx + keymap KeyMap + wh [2]int + focused bool + xywh [4]int + viewport viewport.Model + + a *aggregator.Aggregator + + err error + + viewcache string + viewcacheTextareaXY []int +} + +func (m Model) Init() tea.Cmd { + return nil +} + +func (m Model) Focus() { + m.focused = true +} + +func (m Model) Blur() { + m.focused = false +} + +func NewModel(c *ctx.Ctx) Model { + m := Model{ + ctx: c, + keymap: DefaultKeyMap, + focused: false, + xywh: [4]int{0, 0, 0, 0}, + + err: nil, + + viewcache: "", + viewcacheTextareaXY: []int{0, 0, 0, 0}, + } + + m.a, _ = aggregator.New(m.ctx) + + return m +} + +func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + var cmds []tea.Cmd + + switch msg := msg.(type) { + + case tea.WindowSizeMsg: + m.wh[0] = msg.Width + m.wh[1] = msg.Height + m.ctx.Logger.Debugf("received WindowSizeMsg: %v\n", m.wh) + viewportWidth := m.wh[0] - 2 + viewportHeight := m.wh[1] - 5 + + viewportStyle.Width(viewportWidth) + viewportStyle.Height(viewportHeight) + m.viewport = viewport.New(viewportWidth-4, viewportHeight-4) + m.viewport.Width = viewportWidth - 4 + m.viewport.Height = viewportHeight + 1 + + case cmd.Command: + m.ctx.Logger.Debugf("got command: %v\n", msg) + switch msg.Call { + case cmd.MsgError: + m.err = msg.GetArg("error").(error) + if m.err != nil { + m.viewport.SetContent(m.err.Error()) + m.viewcache = m.buildView(false) + } + return m, nil + case cmd.WinClose: + if msg.Target == WIN_ID { + m.err = nil + return m, nil + } + case cmd.WinFocus: + if msg.Target == WIN_ID || + msg.Target == "*" { + m.focused = true + m.viewcache = m.buildView(false) + } + return m, nil + case cmd.WinBlur: + if msg.Target == WIN_ID || + msg.Target == "*" { + m.focused = false + } + return m, nil + default: + m.ctx.Logger.Debugf("received unhandled command: %v\n", msg) + } + + // default: + // m.ctx.Logger.Debugf("received unhandled msg: %v\n", msg) + } + + var vcmd tea.Cmd + + m.ctx.Logger.Debugf("ERROR IS: %v\n", m.err) + if m.err != nil { + m.viewport.SetContent(m.err.Error()) + } + m.viewport, vcmd = m.viewport.Update(msg) + cmds = append(cmds, vcmd) + + return m, tea.Batch(cmds...) +} + +func (m Model) View() string { + return m.buildView(true) +} + +func (m Model) buildView(cached bool) string { + var view strings.Builder = strings.Builder{} + + if cached && m.focused == false && m.viewcache != "" { + m.ctx.Logger.Debugln("Cached View()") + + return m.viewcache + } + + title := "Error" + titlebar := m.ctx.Theme.DialogBox.Titlebar.Focused. + Align(lipgloss.Center). + Width(m.wh[0]). + Render(title) + + bottombar := m.ctx.Theme.DialogBox.Bottombar. + Width(m.wh[0]). + Render("esc close") + + ui := lipgloss.JoinVertical( + lipgloss.Center, + titlebar, + viewportStyle.Render(m.viewport.View()), + bottombar, + ) + + var tmp string + if m.focused { + tmp = m.ctx.Theme.DialogBox.Window.Focused.Render(ui) + } else { + tmp = m.ctx.Theme.DialogBox.Window.Blurred.Render(ui) + } + + view.WriteString(tmp) + + return view.String() +} diff --git a/ui/windows/postcreate/postcreate.go b/ui/windows/postcreate/postcreate.go index 4d2bd5f..b18f2e8 100644 --- a/ui/windows/postcreate/postcreate.go +++ b/ui/windows/postcreate/postcreate.go @@ -1,7 +1,6 @@ package postcreate import ( - "encoding/json" "fmt" "strconv" "strings" @@ -35,7 +34,7 @@ type KeyMap struct { var DefaultKeyMap = KeyMap{ Reply: key.NewBinding( key.WithKeys("ctrl+s"), - key.WithHelp("ctrl+s", "reply"), + key.WithHelp("ctrl+s", "send"), ), } @@ -113,8 +112,6 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { irtSysIDX = pst.SysIDX } else { rply := m.replyToIface.(reply.Reply) - b, _ := json.Marshal(rply) - m.ctx.Logger.Debug(string(b)) irtID = strconv.Itoa(m.replyToIdx + 1) irtIRT = rply.InReplyTo // TODO: THis is empty? Why? irtSysIDX = rply.SysIDX @@ -127,13 +124,14 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { SysIDX: irtSysIDX, } - b, _ := json.Marshal(r) - m.ctx.Logger.Debug(string(b)) - err := m.a.CreateReply(&r) if err != nil { m.ctx.Logger.Error(err) - // TODO + return m, cmd.New( + cmd.MsgError, + WIN_ID, + cmd.Arg{Name: "error", Value: err}, + ).Tea() } m.textarea.Reset() @@ -243,7 +241,7 @@ func (m Model) buildView(cached bool) string { bottombar := m.ctx.Theme.DialogBox.Bottombar. Width(m.wh[0]). - Render("ctrl+enter reply · esc close") + Render("ctrl+s send · esc close") replyWindow := lipgloss.JoinVertical( lipgloss.Center, diff --git a/ui/windows/postshow/postshow.go b/ui/windows/postshow/postshow.go index 2eb23ab..f65df8f 100644 --- a/ui/windows/postshow/postshow.go +++ b/ui/windows/postshow/postshow.go @@ -220,7 +220,7 @@ func (m *Model) loadPost(p *post.Post) tea.Cmd { m.ctx.Logger.Error(err) c := cmd.New( cmd.MsgError, - "*", + WIN_ID, cmd.Arg{Name: "error", Value: err}, ) return *c