diff --git a/keys.go b/keys.go index 9ad2460..047a7cc 100644 --- a/keys.go +++ b/keys.go @@ -12,15 +12,21 @@ type Binding struct { Handler func(g *gocui.Gui, v *gocui.View) error } -func (vc *View) CursorUp(g *gocui.Gui, v *gocui.View) error { - return MoveCursor(-1, g, v) +func (vc *ViewController) CursorUp(g *gocui.Gui, v *gocui.View) error { + return MoveCursor(-1, v) } -func (vc *View) CursorDown(g *gocui.Gui, v *gocui.View) error { - return MoveCursor(1, g, v) +func (vc *ViewController) CursorDown(g *gocui.Gui, v *gocui.View) error { + peers := vc.Data.(*PeersState).list + _, cy := v.Cursor() + // Don't go beyond available list of peers + if cy+1 >= len(peers) { + return nil + } + return MoveCursor(1, v) } -func MoveCursor(mod int, g *gocui.Gui, v *gocui.View) error { +func MoveCursor(mod int, v *gocui.View) error { if v == nil { return nil } diff --git a/main.go b/main.go index 9599b14..7143bab 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "github.com/jroimartin/gocui" "log" "os" @@ -28,7 +27,9 @@ func main() { } defer g.Close() - mainView := &View{ + peers := NewPeersState(host, port) + + mainView := &ViewController{ Name: "main", Title: "Peers", Placeholder: "Loading peers...", @@ -37,6 +38,7 @@ func main() { Current: true, SelFgColor: gocui.ColorBlack, SelBgColor: gocui.ColorGreen, + Data: peers, TopLeft: func(mx, my int) (int, int) { return 0, 0 }, @@ -50,7 +52,7 @@ func main() { Binding{gocui.KeyArrowUp, gocui.ModNone, mainView.CursorUp}, Binding{gocui.KeyArrowDown, gocui.ModNone, mainView.CursorDown}, } - infoView := &View{ + infoView := &ViewController{ Name: "info", Title: "Details", Placeholder: "Loading details...", @@ -62,20 +64,14 @@ func main() { }, } - views := []*View{mainView, infoView} + views := []*ViewController{mainView, infoView} vm := NewViewManager(g, views) g.SetManagerFunc(vm.Layout) - url := fmt.Sprintf("http://%s:%d", host, port) - c, err := newClient(url) - if err != nil { - log.Panicln(err) - } - // Start RPC calling routine - go FetchPeers(c, g) + go peers.Fetch(g) if err := g.MainLoop(); err != nil && err != gocui.ErrQuit { log.Panicln(err) diff --git a/peers.go b/peers.go index ed532ac..243b9ab 100644 --- a/peers.go +++ b/peers.go @@ -8,23 +8,38 @@ import ( "time" ) -func FetchPeers(c *client, g *gocui.Gui) { +type PeersState struct { + c *client + list []Peer +} + +func NewPeersState(host string, port int) *PeersState { + url := fmt.Sprintf("http://%s:%d", host, port) + c, err := newClient(url) + if err != nil { + log.Panicln(err) + } + return &PeersState{c: c} +} + +func (p *PeersState) Fetch(g *gocui.Gui) { for { select { case <-threadDone: return default: - peers, err := c.getPeers() + peers, err := p.c.getPeers() if err != nil { log.Panicln(err) } - WritePeers(g, peers) + p.list = peers + writePeers(g, peers) } <-time.After(interval * time.Second) } } -func WritePeers(g *gocui.Gui, peers []Peer) { +func writePeers(g *gocui.Gui, peers []Peer) { g.Update(func(g *gocui.Gui) error { v, err := g.View("main") if err != nil { diff --git a/view.go b/view.go index 30b8f5c..328adc1 100644 --- a/view.go +++ b/view.go @@ -6,7 +6,7 @@ import ( "github.com/jroimartin/gocui" ) -type View struct { +type ViewController struct { Name string Title string Placeholder string @@ -19,14 +19,15 @@ type View struct { SelFgColor gocui.Attribute Keybindings []Binding Manager ViewManager + Data interface{} } type ViewManager struct { g *gocui.Gui - views []*View + views []*ViewController } -func NewViewManager(g *gocui.Gui, views []*View) *ViewManager { +func NewViewManager(g *gocui.Gui, views []*ViewController) *ViewManager { vm := ViewManager{ g: g, views: views, @@ -66,7 +67,7 @@ func (m *ViewManager) Layout(g *gocui.Gui) error { return nil } -func (v *View) SetKeybindings(g *gocui.Gui) error { +func (v *ViewController) SetKeybindings(g *gocui.Gui) error { for _, b := range v.Keybindings { // IDEA: I can pass a method instead of a function here if err := g.SetKeybinding("", b.Key, b.Mod, b.Handler); err != nil {