diff --git a/go.mod b/go.mod index f174a32..278f645 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,11 @@ module github.com/illusionman1212/gorc go 1.16 +replace github.com/charmbracelet/bubbles => /home/illusion/Desktop/repos/bubbles + require ( github.com/charmbracelet/bubbles v0.9.0 - github.com/charmbracelet/bubbletea v0.19.1 // indirect - github.com/charmbracelet/lipgloss v0.4.0 // indirect + github.com/charmbracelet/bubbletea v0.19.1 + github.com/charmbracelet/lipgloss v0.4.0 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect ) diff --git a/go.sum b/go.sum index f2ca6c6..d7f58cb 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,6 @@ github.com/atotto/clipboard v0.1.2 h1:YZCtFu5Ie8qX2VmVTBnrqLSiU9XOWwqNRmdT3gIQzbY= github.com/atotto/clipboard v0.1.2/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= -github.com/charmbracelet/bubbles v0.9.0 h1:lqJ8FXwoLceQF2J0A+dWo1Cuu1dNyjbW4Opgdi2vkhw= -github.com/charmbracelet/bubbles v0.9.0/go.mod h1:NWT/c+0rYEnYChz5qCyX4Lj6fDw9gGToh9EFJPajghU= github.com/charmbracelet/bubbletea v0.14.1/go.mod h1:b5lOf5mLjMg1tRn1HVla54guZB+jvsyV0yYAQja95zE= -github.com/charmbracelet/bubbletea v0.17.0 h1:ABmd01l6K7Q8lSQxF7yG8yWayz5gXWSt3JfB/X1eYP4= -github.com/charmbracelet/bubbletea v0.17.0/go.mod h1:YTZSs2p3odhwYZdhqJheYHVUjU37c9OLgS85kw6NGQY= github.com/charmbracelet/bubbletea v0.19.1 h1:VHuzkJbnTAkxhOfi9+Lb5PYfNM9+Oh+qhP8uDX5ReOU= github.com/charmbracelet/bubbletea v0.19.1/go.mod h1:VuXF2pToRxDUHcBUcPmCRUHRvFATM4Ckb/ql1rBl3KA= github.com/charmbracelet/harmonica v0.1.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= @@ -17,22 +13,18 @@ github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8a github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b h1:1XF24mVaiu7u+CFywTdcDo2ie1pzzhwjt6RHqzpMU34= github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho= -github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 h1:y1p/ycavWjGT9FnmSjdbWUlLGvcxrY0Rw3ATltrxOhk= github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ= github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= -github.com/muesli/termenv v0.8.1 h1:9q230czSP3DHVpkaPDXGp0TOfAwyjyYwXlUCQxQSaBk= github.com/muesli/termenv v0.8.1/go.mod h1:kzt/D/4a88RoheZmwfqorY3A+tnsSMA9HJC/fQSFKo0= github.com/muesli/termenv v0.9.0 h1:wnbOaGz+LUR3jNT0zOzinPnyDaCZUQRZj9GxK8eRVl8= github.com/muesli/termenv v0.9.0/go.mod h1:R/LzAKf+suGs4IsO95y7+7DpFHO0KABgnZqtlyx2mBw= @@ -46,11 +38,9 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20210422114643-f5beecf764ed h1:Ei4bQjjpYUsS4efOUz+5Nz++IVkHk87n2zBA0NxBWc0= golang.org/x/term v0.0.0-20210422114643-f5beecf764ed/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/ui/app/app.go b/ui/app/app.go index a4c2cb5..181f51d 100644 --- a/ui/app/app.go +++ b/ui/app/app.go @@ -18,8 +18,6 @@ package app import ( "bufio" - "log" - "os" "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" @@ -27,7 +25,6 @@ import ( "github.com/illusionman1212/gorc/ui" "github.com/illusionman1212/gorc/ui/login" "github.com/illusionman1212/gorc/ui/mainscreen" - "golang.org/x/term" ) type Screen int @@ -38,8 +35,6 @@ const ( ) type UI struct { - windowWidth int - windowHeight int currentScreen Screen login login.State mainScreen mainscreen.State @@ -51,17 +46,9 @@ type State struct { } func initialUiState() UI { - width, height, err := term.GetSize(int(os.Stdout.Fd())) - if err != nil { - // TODO: properly handle this error - log.Fatal(err) - } - return UI{ - login: login.NewLogin(), - mainScreen: mainscreen.NewMainScreen(), - windowWidth: width, - windowHeight: height, + login: login.NewLogin(), + mainScreen: mainscreen.NewMainScreen(), } } @@ -94,15 +81,11 @@ func (s State) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } case tea.WindowSizeMsg: - s.ui.windowWidth = msg.Width - s.ui.windowHeight = msg.Height - ui.MainStyle = ui.MainStyle. Width(msg.Width). Height(msg.Height) - s.ui.mainScreen.Viewport.Width = msg.Width - s.ui.mainScreen.Viewport.Height = msg.Height - mainscreen.InputBoxHeight + s.ui.mainScreen.SetSize(msg.Width, msg.Height) return s, nil case login.ConnectingMsg: diff --git a/ui/mainscreen/input.go b/ui/mainscreen/input.go index 86baf3d..08cc983 100644 --- a/ui/mainscreen/input.go +++ b/ui/mainscreen/input.go @@ -19,24 +19,39 @@ package mainscreen import ( "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" ) type InputState struct { - input textinput.Model + Input textinput.Model + Style lipgloss.Style } func NewInputBox() InputState { - var input textinput.Model + input := textinput.NewModel() input.Placeholder = "Send a message..." - state := InputState{input} + // input.Focus() + state := InputState{input, InputboxStyle} return state } func (s InputState) Update(msg tea.Msg) (InputState, tea.Cmd) { - return s, nil + cmd := s.updateInputs(msg) + return s, cmd +} + +func (s *InputState) updateInputs(msg tea.Msg) tea.Cmd { + var cmd tea.Cmd + s.Input, cmd = s.Input.Update(msg) + + return cmd +} + +func (s *InputState) SetSize(width int) { + s.Style = s.Style.Width(width - s.Style.GetHorizontalBorderSize()) } func (s InputState) View() string { - return InputboxStyle.Render(s.input.View()) + return s.Style.Render(s.Input.View()) } diff --git a/ui/mainscreen/mainscreen.go b/ui/mainscreen/mainscreen.go index 7214fad..2978fec 100644 --- a/ui/mainscreen/mainscreen.go +++ b/ui/mainscreen/mainscreen.go @@ -34,12 +34,13 @@ type State struct { Reader *bufio.Reader Client *client.Client Viewport viewport.Model + Style lipgloss.Style - inputBox InputState + InputBox InputState } func NewMainScreen() State { - newViewport := viewport.Model{Width: ui.MainStyle.GetWidth(), Height: ui.MainStyle.GetHeight() - InputBoxHeight} + newViewport := viewport.Model{} newViewport.HighPerformanceRendering = false newViewport.SetContent("") @@ -48,13 +49,16 @@ func NewMainScreen() State { Reader: nil, Client: nil, Viewport: newViewport, - inputBox: NewInputBox(), + Style: MessagesStyle.Copy(), + InputBox: NewInputBox(), } return state } func (s State) Update(msg tea.Msg) (State, tea.Cmd) { var cmd tea.Cmd + var cmds []tea.Cmd + switch msg := msg.(type) { case InitialReadMsg: return s, s.readFromServer @@ -76,14 +80,27 @@ func (s State) Update(msg tea.Msg) (State, tea.Cmd) { } s.Viewport, cmd = s.Viewport.Update(msg) + cmds = append(cmds, cmd) - return s, cmd + s.InputBox, cmd = s.InputBox.Update(msg) + cmds = append(cmds, cmd) + + return s, tea.Batch(cmds...) +} + +func (s *State) SetSize(width, height int) { + s.InputBox.SetSize(width) + s.Viewport.Width = width - s.Style.GetVerticalFrameSize() + // copying the existing style is important here otherwise we'll end up with artifacting + s.Style = s.Style.Copy().Width(width - s.Style.GetVerticalFrameSize()) + s.Viewport.Height = height - s.InputBox.Style.GetHorizontalFrameSize() - s.Style.GetHorizontalFrameSize() + s.Style = s.Style.Copy().Height(height - s.InputBox.Style.GetHorizontalFrameSize() - s.Style.GetHorizontalFrameSize()) + // we need to re-set the content because words wrap differently on different sizes + s.Viewport.SetContent(s.Content) } func (s State) View() string { - mainscreen := s.Viewport.View() + screen := lipgloss.JoinVertical(0, s.Style.Render(s.Viewport.View()), s.InputBox.View()) - screen := lipgloss.JoinVertical(0, MessagesStyle.Render(mainscreen), s.inputBox.View()) - - return screen + return ui.MainStyle.Render(screen) } diff --git a/ui/mainscreen/styles.go b/ui/mainscreen/styles.go index b2c3d1f..f9960da 100644 --- a/ui/mainscreen/styles.go +++ b/ui/mainscreen/styles.go @@ -30,7 +30,6 @@ var ( MessagesStyle = lipgloss.NewStyle(). Border(lipgloss.NormalBorder(), true). Width(ui.MainStyle.GetWidth()). - Height(ui.MainStyle.GetHeight() - InputBoxHeight). BorderForeground(lipgloss.Color("105")) InputBoxHeight = 1 diff --git a/ui/styles.go b/ui/styles.go index c2b80eb..269bb38 100644 --- a/ui/styles.go +++ b/ui/styles.go @@ -19,23 +19,12 @@ package ui import "github.com/charmbracelet/lipgloss" var ( - BorderRound = lipgloss.Border{ - Top: "─", - Bottom: "─", - Left: "│", - Right: "│", - TopLeft: "╭", - TopRight: "╮", - BottomLeft: "╰", - BottomRight: "╯", - } - MainStyle = lipgloss.NewStyle(). Width(172). Height(40) DialogStyle = lipgloss.NewStyle(). - Border(BorderRound, true). + Border(lipgloss.RoundedBorder(), true). Align(lipgloss.Center). Width(50). Padding(3, 6).