mirror of
https://github.com/IllusionMan1212/gorc.git
synced 2026-10-24 02:12:33 +00:00
feat/fix: properly layout the messages viewport and the inputbox
This commit is contained in:
@@ -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
|
||||
)
|
||||
|
||||
@@ -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=
|
||||
|
||||
+3
-20
@@ -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:
|
||||
|
||||
+20
-5
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-12
@@ -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).
|
||||
|
||||
Reference in New Issue
Block a user