diff --git a/go.mod b/go.mod index 4cbe6fb..667a85c 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,8 @@ module github.com/diamondburned/cchat-gtk go 1.14 replace github.com/gotk3/gotk3 => github.com/diamondburned/gotk3 v0.0.0-20200816224505-3cd69b83a48a +replace github.com/diamondburned/cchat-mock => ../cchat-mock +replace github.com/diamondburned/ningen => ../../ningen require ( github.com/Xuanwo/go-locale v1.0.0 diff --git a/go.sum b/go.sum index eaa077c..8d707a8 100644 --- a/go.sum +++ b/go.sum @@ -56,6 +56,7 @@ github.com/diamondburned/arikawa v1.2.0 h1:3dFmpk/G4UwO+Kto0tXd5AbaCKC9KH2ZfnA8U github.com/diamondburned/arikawa v1.2.0/go.mod h1:nIhVIatzTQhPUa7NB8w4koG1RF9gYbpAr8Fj8sKq660= github.com/diamondburned/arikawa v1.3.0 h1:up5q5Ya/QbiFqhMejvl+c03YdsgzkzspsJOWW30A2lk= github.com/diamondburned/arikawa v1.3.0/go.mod h1:nIhVIatzTQhPUa7NB8w4koG1RF9gYbpAr8Fj8sKq660= +github.com/diamondburned/arikawa v1.3.2/go.mod h1:nIhVIatzTQhPUa7NB8w4koG1RF9gYbpAr8Fj8sKq660= github.com/diamondburned/arikawa v1.3.6 h1:DhxWDO4fyXAZ4VFrWdJOqiiJKJRpkrehGJwPtZ2eos0= github.com/diamondburned/arikawa v1.3.6/go.mod h1:nIhVIatzTQhPUa7NB8w4koG1RF9gYbpAr8Fj8sKq660= github.com/diamondburned/cchat v0.0.43 h1:HetAujSaUSdnQgAUZgprNLARjf/MSWXpCfWdvX2wOCU= diff --git a/internal/ui/messages/container/grid.go b/internal/ui/messages/container/grid.go index fb46227..0fcc668 100644 --- a/internal/ui/messages/container/grid.go +++ b/internal/ui/messages/container/grid.go @@ -43,10 +43,19 @@ func (c *GridStore) MessagesLen() int { } func (c *GridStore) attachGrid(row int, widgets []gtk.IWidget) { - // Cover a special case with attaching to the 0th row. - if row == 0 { - c.Grid.InsertRow(0) - } + // // Cover a special case with attaching to the 0th row. + // switch row { + // case 0: + // c.Grid.InsertRow(0) + // case c.MessagesLen() - 1: + // row++ // ensure this doesn't try to write to the last message. + // c.Grid.InsertRow(row) + // } + + c.Grid.InsertRow(row) + + log.Println("Inserted row", row, "; length is", c.MessagesLen()) + for i, w := range widgets { c.Grid.Attach(w, i, row, 1, 1) } diff --git a/internal/ui/primitives/singlestack/singlestack.go b/internal/ui/primitives/singlestack/singlestack.go index cd27534..5d39b30 100644 --- a/internal/ui/primitives/singlestack/singlestack.go +++ b/internal/ui/primitives/singlestack/singlestack.go @@ -19,15 +19,15 @@ func (s *Stack) Add(w gtk.IWidget) { return } + if s.current != nil { + s.Stack.Remove(s.current) + } + if w != nil { s.Stack.Add(w) s.Stack.SetVisibleChild(w) } - if s.current != nil { - s.Stack.Remove(s.current) - } - s.current = w } diff --git a/internal/ui/primitives/spinner/spinner.go b/internal/ui/primitives/spinner/spinner.go index 7d9e752..afdcf34 100644 --- a/internal/ui/primitives/spinner/spinner.go +++ b/internal/ui/primitives/spinner/spinner.go @@ -23,6 +23,13 @@ func New() *Boxed { return &Boxed{box, spin} } +func NewVisible() *Boxed { + spin := New() + spin.Start() + spin.Show() + return spin +} + func (b *Boxed) SetSizeRequest(w, h int) { b.Spinner.SetSizeRequest(w, h) } diff --git a/internal/ui/service/list.go b/internal/ui/service/list.go index 790e987..30ef507 100644 --- a/internal/ui/service/list.go +++ b/internal/ui/service/list.go @@ -49,6 +49,7 @@ func NewList(vctl ViewController) *List { svlist.ScrolledWindow, _ = gtk.ScrolledWindowNew(nil, nil) svlist.ScrolledWindow.SetPolicy(gtk.POLICY_NEVER, gtk.POLICY_EXTERNAL) + svlist.ScrolledWindow.SetHExpand(false) svlist.ScrolledWindow.Add(svlist.ListBox) return svlist diff --git a/internal/ui/service/session/session.go b/internal/ui/service/session/session.go index 7ff9892..c11456e 100644 --- a/internal/ui/service/session/session.go +++ b/internal/ui/service/session/session.go @@ -186,6 +186,9 @@ func newRow(parent traverse.Breadcrumber, name text.Rich, ctrl Servicer) *Row { } }) + // Reset to bring states set in that method to a newly constructed widget. + row.Reset() + return row } @@ -209,6 +212,7 @@ func NewAddButton() *gtk.ListBoxRow { func (r *Row) Reset() { r.Servers.Reset() // wipe servers r.ActionsMenu.Reset() // wipe menu items + r.ActionsMenu.AddAction("Remove", r.RemoveSession) // Set a lame placeholder icon. r.icon.Icon.SetPlaceholderIcon("folder-remote-symbolic", IconSize) @@ -222,6 +226,9 @@ func (r *Row) ParentBreadcrumb() traverse.Breadcrumber { } func (r *Row) Breadcrumb() string { + if r.Session == nil { + return "" + } return r.Session.Name().Content } @@ -229,6 +236,9 @@ func (r *Row) Breadcrumb() string { // method will reconnect. If the row is already loaded, then SessionSelected // will be called. func (r *Row) Activate() { + // Display the empty server list first, then try and reconnect. + r.svcctrl.SessionSelected(r) + // If session is nil, then we've probably failed to load it. The row is // deactivated while loading, so this wouldn't have happened. if r.Session == nil { @@ -237,7 +247,6 @@ func (r *Row) Activate() { // Load all servers in this root node, then call the parent controller's // method. r.Servers.Children.LoadAll() - r.svcctrl.SessionSelected(r) } } @@ -292,7 +301,7 @@ func (r *Row) RestoreSession(res cchat.SessionRestorer, k keyring.Session) { go func() { s, err := res.RestoreSession(k.Data) if err != nil { - err = errors.Wrapf(err, "Failed to restore session %s (%s)", k.ID, k.Name) + err = errors.Wrapf(err, "failed to restore session %s (%s)", k.ID, k.Name) log.Error(err) gts.ExecAsync(func() { r.SetFailed(err) }) @@ -313,7 +322,7 @@ func (r *Row) SetSession(ses cchat.Session) { // If the session has an icon, then use it. if iconer := ses.AsIconer(); iconer != nil { - r.icon.Icon.AsyncSetIconer(iconer, "Failed to set session icon") + r.icon.Icon.AsyncSetIconer(iconer, "failed to set session icon") } // Update to indicate that we're done. @@ -402,7 +411,7 @@ func (r *Row) DisconnectSession() { // Try and disconnect asynchronously. gts.Async(func() (func(), error) { // Disconnect and wrap the error if any. Wrap works with a nil error. - err := errors.Wrap(session.Disconnect(), "Failed to disconnect.") + err := errors.Wrap(session.Disconnect(), "failed to disconnect.") return func() { // Re-enable access to the menu. r.SetSensitive(true) diff --git a/internal/ui/service/view.go b/internal/ui/service/view.go index d53dd5b..aea582d 100644 --- a/internal/ui/service/view.go +++ b/internal/ui/service/view.go @@ -4,6 +4,7 @@ import ( "github.com/diamondburned/cchat" "github.com/diamondburned/cchat-gtk/internal/ui/primitives" "github.com/diamondburned/cchat-gtk/internal/ui/primitives/singlestack" + "github.com/diamondburned/cchat-gtk/internal/ui/primitives/spinner" "github.com/diamondburned/cchat-gtk/internal/ui/service/session" "github.com/diamondburned/cchat-gtk/internal/ui/service/session/server" "github.com/gotk3/gotk3/gtk" @@ -95,7 +96,11 @@ func (v *View) SessionSelected(svc *Service, srow *session.Row) { // !!!: SHITTY HACK!!! // We can do this, as we're keeping all the server lists in memory by Go's // reference anyway. In fact, cchat REQUIRES us to do so. - v.ServerStack.SetVisibleChild(srow.Servers) + if srow.Session != nil { + v.ServerStack.SetVisibleChild(srow.Servers) + } else { + v.ServerStack.SetVisibleChild(spinner.NewVisible()) + } v.Header.SetSessionMenu(srow) v.Header.SetBreadcrumber(srow)