mirror of
https://github.com/diamondburned/cchat-gtk.git
synced 2025-03-22 09:59:37 +00:00
Minor graphical tweaks, added Disconnection
This commit is contained in:
parent
adeffc7717
commit
0d8d3609be
4
go.mod
4
go.mod
|
@ -6,8 +6,8 @@ replace github.com/gotk3/gotk3 => github.com/diamondburned/gotk3 v0.0.0-20200612
|
|||
|
||||
require (
|
||||
github.com/Xuanwo/go-locale v0.2.0
|
||||
github.com/diamondburned/cchat v0.0.25
|
||||
github.com/diamondburned/cchat-mock v0.0.0-20200613003444-b36f8f47debe
|
||||
github.com/diamondburned/cchat v0.0.26
|
||||
github.com/diamondburned/cchat-mock v0.0.0-20200613233949-1e7651c8dd84
|
||||
github.com/diamondburned/imgutil v0.0.0-20200611215339-650ac7cfaf64
|
||||
github.com/goodsign/monday v1.0.0
|
||||
github.com/google/btree v1.0.0 // indirect
|
||||
|
|
4
go.sum
4
go.sum
|
@ -9,8 +9,12 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/diamondburned/cchat v0.0.25 h1:+kf2gQu5TQs1vD/gCaVlzKu5vOqZz/1Qw87xHdeFYj4=
|
||||
github.com/diamondburned/cchat v0.0.25/go.mod h1:+zXktogE45A0om4fT6B/z6Ii7FXNafjxsNspI0rlhbU=
|
||||
github.com/diamondburned/cchat v0.0.26 h1:QBt4d65uzUPJz3jF8b2pJ09Jz8LeBRyG2ol47FOy0g0=
|
||||
github.com/diamondburned/cchat v0.0.26/go.mod h1:+zXktogE45A0om4fT6B/z6Ii7FXNafjxsNspI0rlhbU=
|
||||
github.com/diamondburned/cchat-mock v0.0.0-20200613003444-b36f8f47debe h1:OoTLxpryxB9iQyu3bjw5N9N/3Bvu6FwklJ85X9erCAY=
|
||||
github.com/diamondburned/cchat-mock v0.0.0-20200613003444-b36f8f47debe/go.mod h1:vitBma+rd/ah+ujQsp6lPm/AfS2KtLKEh+Owxbv5BQM=
|
||||
github.com/diamondburned/cchat-mock v0.0.0-20200613233949-1e7651c8dd84 h1:NSuksZ9HiLiau93qAz4yNba6Xd7ExOFc956dumONDQ0=
|
||||
github.com/diamondburned/cchat-mock v0.0.0-20200613233949-1e7651c8dd84/go.mod h1:JxTay4MVEqmDisGqDGk8TG0UnKX7wDEImFywyoPfGjk=
|
||||
github.com/diamondburned/gotk3 v0.0.0-20200612012846-9df87fea4f6d h1:NFTuwBU+CNZDB1iaGC3gDuBRf9FTd1h2WnIh6NF7elg=
|
||||
github.com/diamondburned/gotk3 v0.0.0-20200612012846-9df87fea4f6d/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q=
|
||||
github.com/diamondburned/imgutil v0.0.0-20200611215339-650ac7cfaf64 h1:/ykUYHuYyj+NN/aaqe6lfaCZQc3EMZs93wAGVJTh5j0=
|
||||
|
|
|
@ -39,7 +39,7 @@ type Session struct {
|
|||
Data map[string]string
|
||||
}
|
||||
|
||||
func GetSession(ses cchat.Session, name string) *Session {
|
||||
func ConvertSession(ses cchat.Session, name string) *Session {
|
||||
saver, ok := ses.(cchat.SessionSaver)
|
||||
if !ok {
|
||||
return nil
|
||||
|
@ -79,3 +79,13 @@ func RestoreSessions(serviceName text.Rich) (sessions []Session) {
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
func RestoreSession(serviceName text.Rich, id string) *Session {
|
||||
var sessions = RestoreSessions(serviceName)
|
||||
for _, session := range sessions {
|
||||
if session.ID == id {
|
||||
return &session
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -50,15 +50,15 @@ func New(parent gtk.IWidget, placeholder WidgetUnreferencer) *FaceView {
|
|||
|
||||
// Reset brings the view to an empty box.
|
||||
func (v *FaceView) Reset() {
|
||||
v.Stack.SetVisibleChildName("empty")
|
||||
v.ensurePlaceholderDestroyed()
|
||||
v.Loading.Spinner.Stop()
|
||||
v.Stack.SetVisibleChildName("empty")
|
||||
}
|
||||
|
||||
func (v *FaceView) SetMain() {
|
||||
v.Stack.SetVisibleChildName("main")
|
||||
v.ensurePlaceholderDestroyed()
|
||||
v.Loading.Spinner.Stop()
|
||||
v.Stack.SetVisibleChildName("main")
|
||||
}
|
||||
|
||||
func (v *FaceView) SetLoading() {
|
||||
|
@ -68,10 +68,10 @@ func (v *FaceView) SetLoading() {
|
|||
}
|
||||
|
||||
func (v *FaceView) SetError(err error) {
|
||||
v.Face.SetError(err)
|
||||
v.Stack.SetVisibleChildName("face")
|
||||
v.ensurePlaceholderDestroyed()
|
||||
v.Loading.Spinner.Stop()
|
||||
v.Stack.SetVisibleChildName("face")
|
||||
v.Face.SetError(err)
|
||||
}
|
||||
|
||||
func (v *FaceView) ensurePlaceholderDestroyed() {
|
||||
|
|
|
@ -106,7 +106,13 @@ func SetImageIcon(img *gtk.Image, icon string, sizepx int) {
|
|||
img.SetSizeRequest(sizepx, sizepx)
|
||||
}
|
||||
|
||||
func AppendMenuItems(menu interface{ Append(gtk.IMenuItem) }, items []*gtk.MenuItem) {
|
||||
func PrependMenuItems(menu interface{ Prepend(gtk.IMenuItem) }, items []gtk.IMenuItem) {
|
||||
for i := len(items) - 1; i >= 0; i-- {
|
||||
menu.Prepend(items[i])
|
||||
}
|
||||
}
|
||||
|
||||
func AppendMenuItems(menu interface{ Append(gtk.IMenuItem) }, items []gtk.IMenuItem) {
|
||||
for _, item := range items {
|
||||
menu.Append(item)
|
||||
}
|
||||
|
@ -118,6 +124,12 @@ func HiddenMenuItem(label string, fn interface{}) *gtk.MenuItem {
|
|||
return mb
|
||||
}
|
||||
|
||||
func HiddenDisabledMenuItem(label string, fn interface{}) *gtk.MenuItem {
|
||||
mb := HiddenMenuItem(label, fn)
|
||||
mb.SetSensitive(false)
|
||||
return mb
|
||||
}
|
||||
|
||||
func MenuItem(label string, fn interface{}) *gtk.MenuItem {
|
||||
menuitem := HiddenMenuItem(label, fn)
|
||||
menuitem.Show()
|
||||
|
@ -128,7 +140,7 @@ type Connector interface {
|
|||
Connect(string, interface{}, ...interface{}) (glib.SignalHandle, error)
|
||||
}
|
||||
|
||||
func BindMenu(menu *gtk.Menu, connector Connector) {
|
||||
func BindMenu(connector Connector, menu *gtk.Menu) {
|
||||
connector.Connect("event", func(_ *gtk.ToggleButton, ev *gdk.Event) {
|
||||
if gts.EventIsRightClick(ev) {
|
||||
menu.PopupAtPointer(ev)
|
||||
|
@ -136,6 +148,16 @@ func BindMenu(menu *gtk.Menu, connector Connector) {
|
|||
})
|
||||
}
|
||||
|
||||
func BindDynamicMenu(connector Connector, constr func(menu *gtk.Menu)) {
|
||||
connector.Connect("event", func(_ *gtk.ToggleButton, ev *gdk.Event) {
|
||||
if gts.EventIsRightClick(ev) {
|
||||
menu, _ := gtk.MenuNew()
|
||||
constr(menu)
|
||||
menu.PopupAtPointer(ev)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func NewTargetEntry(target string) gtk.TargetEntry {
|
||||
e, _ := gtk.TargetEntryNew(target, gtk.TARGET_SAME_APP, 0)
|
||||
return *e
|
||||
|
|
|
@ -47,7 +47,7 @@ func newHeader(svc cchat.Service) *header {
|
|||
|
||||
// Spawn the menu on right click.
|
||||
menu, _ := gtk.MenuNew()
|
||||
primitives.BindMenu(menu, reveal)
|
||||
primitives.BindMenu(reveal, menu)
|
||||
|
||||
return &header{box, reveal, add, menu}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-gtk/internal/gts"
|
||||
"github.com/diamondburned/cchat-gtk/internal/keyring"
|
||||
|
@ -55,6 +57,8 @@ type Controller interface {
|
|||
// OnSessionRemove is called to remove a session. This should also clear out
|
||||
// the message view in the parent package.
|
||||
OnSessionRemove(id string)
|
||||
// OnSessionDisconnect is here to satisfy session's controller.
|
||||
OnSessionDisconnect(id string)
|
||||
}
|
||||
|
||||
// Container represents a single service, including the button header and the
|
||||
|
@ -114,7 +118,7 @@ func NewContainer(svc cchat.Service, ctrl Controller) *Container {
|
|||
})
|
||||
|
||||
// Make menu items.
|
||||
primitives.AppendMenuItems(header.Menu, []*gtk.MenuItem{
|
||||
primitives.AppendMenuItems(header.Menu, []gtk.IMenuItem{
|
||||
primitives.MenuItem("Save Sessions", func() {
|
||||
container.SaveAllSessions()
|
||||
}),
|
||||
|
@ -131,7 +135,7 @@ func (c *Container) AddSession(ses cchat.Session) *session.Row {
|
|||
}
|
||||
|
||||
func (c *Container) AddLoadingSession(id, name string) *session.Row {
|
||||
srow := session.NewLoading(c, name, c)
|
||||
srow := session.NewLoading(c, id, name, c)
|
||||
c.children.AddSessionRow(id, srow)
|
||||
return srow
|
||||
}
|
||||
|
@ -149,15 +153,31 @@ func (c *Container) MoveSession(rowID, beneathRowID string) {
|
|||
c.SaveAllSessions()
|
||||
}
|
||||
|
||||
func (c *Container) OnSessionDisconnect(ses *session.Row) {
|
||||
c.Controller.OnSessionDisconnect(ses.ID())
|
||||
}
|
||||
|
||||
// RestoreSession tries to restore sessions asynchronously. This satisfies
|
||||
// session.Controller.
|
||||
func (c *Container) RestoreSession(row *session.Row, krs keyring.Session) {
|
||||
func (c *Container) RestoreSession(row *session.Row, id string) {
|
||||
// Can this session be restored? If not, exit.
|
||||
restorer, ok := c.Service.(cchat.SessionRestorer)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
c.restoreSession(row, restorer, krs)
|
||||
|
||||
// Do we even have a session stored?
|
||||
krs := keyring.RestoreSession(c.Service.Name(), id)
|
||||
if krs == nil {
|
||||
log.Error(fmt.Errorf(
|
||||
"Missing keyring for service %s, session ID %s",
|
||||
c.Service.Name().Content, id,
|
||||
))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
c.restoreSession(row, restorer, *krs)
|
||||
}
|
||||
|
||||
// internal method called on AddService.
|
||||
|
@ -186,7 +206,7 @@ func (c *Container) restoreSession(r *session.Row, res cchat.SessionRestorer, k
|
|||
err = errors.Wrapf(err, "Failed to restore session %s (%s)", k.ID, k.Name)
|
||||
log.Error(err)
|
||||
|
||||
gts.ExecAsync(func() { r.SetFailed(k, err) })
|
||||
gts.ExecAsync(func() { r.SetFailed(err) })
|
||||
} else {
|
||||
gts.ExecAsync(func() { r.SetSession(s) })
|
||||
}
|
||||
|
|
|
@ -115,21 +115,17 @@ func (r *Row) Breadcrumb() breadcrumb.Breadcrumb {
|
|||
type Children struct {
|
||||
*gtk.Revealer
|
||||
Main *gtk.Box
|
||||
load *loading.Button // nil after init
|
||||
List cchat.ServerList
|
||||
|
||||
rowctrl Controller
|
||||
|
||||
load *loading.Button // nil after init
|
||||
Rows []*Row
|
||||
Parent breadcrumb.Breadcrumber
|
||||
}
|
||||
|
||||
func NewChildren(parent breadcrumb.Breadcrumber, ctrl Controller) *Children {
|
||||
load := loading.NewButton()
|
||||
load.Show()
|
||||
|
||||
main, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0)
|
||||
main.Add(load)
|
||||
main.SetMarginStart(ChildrenMargin)
|
||||
main.Show()
|
||||
|
||||
|
@ -141,12 +137,38 @@ func NewChildren(parent breadcrumb.Breadcrumber, ctrl Controller) *Children {
|
|||
return &Children{
|
||||
Revealer: rev,
|
||||
Main: main,
|
||||
load: load,
|
||||
rowctrl: ctrl,
|
||||
Parent: parent,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Children) SetLoading() {
|
||||
// If we're already loading, then exit.
|
||||
if c.load != nil {
|
||||
return
|
||||
}
|
||||
|
||||
c.load = loading.NewButton()
|
||||
c.load.Show()
|
||||
c.Main.Add(c.load)
|
||||
}
|
||||
|
||||
func (c *Children) Reset() {
|
||||
// Do we have the spinning circle button? If yes, remove it.
|
||||
if c.load != nil {
|
||||
c.Main.Remove(c.load)
|
||||
c.load = nil
|
||||
}
|
||||
|
||||
// Remove old servers from the list.
|
||||
for _, row := range c.Rows {
|
||||
c.Main.Remove(row)
|
||||
}
|
||||
|
||||
// Wipe the list empty.
|
||||
c.Rows = nil
|
||||
}
|
||||
|
||||
func (c *Children) SetServerList(list cchat.ServerList) {
|
||||
c.List = list
|
||||
|
||||
|
@ -159,12 +181,6 @@ func (c *Children) SetServerList(list cchat.ServerList) {
|
|||
|
||||
func (c *Children) SetServers(servers []cchat.Server) {
|
||||
gts.ExecAsync(func() {
|
||||
// Do we have the spinning circle button? If yes, remove it.
|
||||
if c.load != nil {
|
||||
c.Main.Remove(c.load)
|
||||
c.load = nil
|
||||
}
|
||||
|
||||
// Save the current state.
|
||||
var oldID string
|
||||
for _, row := range c.Rows {
|
||||
|
@ -174,10 +190,8 @@ func (c *Children) SetServers(servers []cchat.Server) {
|
|||
}
|
||||
}
|
||||
|
||||
// Update the server list.
|
||||
for _, row := range c.Rows {
|
||||
c.Main.Remove(row)
|
||||
}
|
||||
// Reset before inserting new servers.
|
||||
c.Reset()
|
||||
|
||||
c.Rows = make([]*Row, len(servers))
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@ package session
|
|||
|
||||
import (
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-gtk/internal/gts"
|
||||
"github.com/diamondburned/cchat-gtk/internal/keyring"
|
||||
"github.com/diamondburned/cchat-gtk/internal/log"
|
||||
"github.com/diamondburned/cchat-gtk/internal/ui/primitives"
|
||||
"github.com/diamondburned/cchat-gtk/internal/ui/rich"
|
||||
"github.com/diamondburned/cchat-gtk/internal/ui/service/breadcrumb"
|
||||
|
@ -11,15 +13,27 @@ import (
|
|||
"github.com/diamondburned/imgutil"
|
||||
"github.com/gotk3/gotk3/gdk"
|
||||
"github.com/gotk3/gotk3/gtk"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const IconSize = 32
|
||||
|
||||
// Controller extends server.RowController to add session.
|
||||
type Controller interface {
|
||||
// OnSessionDisconnect is called before a session is disconnected. This
|
||||
// function is used for cleanups.
|
||||
OnSessionDisconnect(*Row)
|
||||
// MessageRowSelected is called when a server that can display messages (aka
|
||||
// implements ServerMessage) is called.
|
||||
MessageRowSelected(*Row, *server.Row, cchat.ServerMessage)
|
||||
RestoreSession(*Row, keyring.Session) // async
|
||||
// RestoreSession is called with the session ID to ask the controller to
|
||||
// restore it from keyring information.
|
||||
RestoreSession(*Row, string) // ID string, async
|
||||
// RemoveSession is called to ask the controller to remove the session from
|
||||
// the list of sessions.
|
||||
RemoveSession(*Row)
|
||||
// MoveSession is called to ask the controller to move the session to
|
||||
// somewhere else in the list of sessions.
|
||||
MoveSession(id, movingID string)
|
||||
}
|
||||
|
||||
|
@ -31,24 +45,24 @@ type Row struct {
|
|||
Session cchat.Session
|
||||
Servers *server.Children
|
||||
|
||||
menu *gtk.Menu
|
||||
retry *gtk.MenuItem
|
||||
|
||||
ctrl Controller
|
||||
parent breadcrumb.Breadcrumber
|
||||
menuconstr func(*gtk.Menu)
|
||||
sessionID string // used for reconnection
|
||||
|
||||
// nil after calling SetSession()
|
||||
krs keyring.Session
|
||||
// krs keyring.Session
|
||||
}
|
||||
|
||||
func New(parent breadcrumb.Breadcrumber, ses cchat.Session, ctrl Controller) *Row {
|
||||
row := new(parent, ctrl)
|
||||
row := newRow(parent, ctrl)
|
||||
row.SetSession(ses)
|
||||
return row
|
||||
}
|
||||
|
||||
func NewLoading(parent breadcrumb.Breadcrumber, name string, ctrl Controller) *Row {
|
||||
row := new(parent, ctrl)
|
||||
func NewLoading(parent breadcrumb.Breadcrumber, id, name string, ctrl Controller) *Row {
|
||||
row := newRow(parent, ctrl)
|
||||
row.sessionID = id
|
||||
row.Button.SetLabelUnsafe(text.Rich{Content: name})
|
||||
row.setLoading()
|
||||
|
||||
|
@ -60,12 +74,13 @@ var dragEntries = []gtk.TargetEntry{
|
|||
}
|
||||
var dragAtom = gdk.GdkAtomIntern("GTK_TOGGLE_BUTTON", true)
|
||||
|
||||
func new(parent breadcrumb.Breadcrumber, ctrl Controller) *Row {
|
||||
func newRow(parent breadcrumb.Breadcrumber, ctrl Controller) *Row {
|
||||
row := &Row{
|
||||
ctrl: ctrl,
|
||||
parent: parent,
|
||||
}
|
||||
row.Servers = server.NewChildren(parent, row)
|
||||
row.Servers.SetLoading()
|
||||
|
||||
row.Button = rich.NewToggleButtonImage(text.Rich{})
|
||||
row.Button.Box.SetHAlign(gtk.ALIGN_START)
|
||||
|
@ -86,33 +101,86 @@ func new(parent breadcrumb.Breadcrumber, ctrl Controller) *Row {
|
|||
row.Box.PackStart(row.Button, false, false, 0)
|
||||
row.Box.Show()
|
||||
|
||||
// Bind the box to .session in CSS.
|
||||
primitives.AddClass(row.Box, "session")
|
||||
|
||||
row.menu, _ = gtk.MenuNew()
|
||||
primitives.BindMenu(row.menu, row.Button)
|
||||
|
||||
row.retry = primitives.HiddenMenuItem("Retry", func() {
|
||||
// Show the loading stuff.
|
||||
row.setLoading()
|
||||
// Reuse the failed keyring session provided. As this variable is reset
|
||||
// after a success, it relies of the button not triggering.
|
||||
ctrl.RestoreSession(row, row.krs)
|
||||
// Bind the button to create a new menu.
|
||||
primitives.BindDynamicMenu(row.Button, func(menu *gtk.Menu) {
|
||||
row.menuconstr(menu)
|
||||
})
|
||||
row.retry.SetSensitive(false)
|
||||
|
||||
primitives.AppendMenuItems(row.menu, []*gtk.MenuItem{
|
||||
row.retry,
|
||||
primitives.MenuItem("Remove", func() {
|
||||
ctrl.RemoveSession(row)
|
||||
}),
|
||||
})
|
||||
// noop, empty menu
|
||||
row.menuconstr = func(menu *gtk.Menu) {}
|
||||
|
||||
return row
|
||||
}
|
||||
|
||||
// RemoveSession removes itself from the session list.
|
||||
func (r *Row) RemoveSession() {
|
||||
// Remove the session off the list.
|
||||
r.ctrl.RemoveSession(r)
|
||||
|
||||
// Asynchrously disconnect.
|
||||
go func() {
|
||||
if err := r.Session.Disconnect(); err != nil {
|
||||
log.Error(errors.Wrap(err, "Non-fatal, failed to disconnect removed session"))
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// ReconnectSession tries to reconnect with the keyring data. This is a slow
|
||||
// method but it's also a very cold path.
|
||||
func (r *Row) ReconnectSession() {
|
||||
// If we haven't ever connected:
|
||||
if r.sessionID == "" {
|
||||
return
|
||||
}
|
||||
|
||||
r.setLoading()
|
||||
r.ctrl.RestoreSession(r, r.sessionID)
|
||||
}
|
||||
|
||||
// DisconnectSession disconnects the current session.
|
||||
func (r *Row) DisconnectSession() {
|
||||
// Call the disconnect function from the controller first.
|
||||
r.ctrl.OnSessionDisconnect(r)
|
||||
|
||||
// Show visually that we're disconnected first by wiping all servers.
|
||||
r.Box.Remove(r.Servers)
|
||||
r.Servers.Reset()
|
||||
|
||||
// Set the offline icon to the button.
|
||||
r.Button.Image.SetPlaceholderIcon("user-invisible-symbolic", IconSize)
|
||||
// Also unselect the button.
|
||||
r.Button.SetActive(false)
|
||||
|
||||
// Disable the button because we're busy disconnecting. We'll re-enable them
|
||||
// once we're done reconnecting.
|
||||
r.SetSensitive(false)
|
||||
|
||||
// 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(r.Session.Disconnect(), "Failed to disconnect.")
|
||||
return func() {
|
||||
// allow access to the menu
|
||||
r.SetSensitive(true)
|
||||
|
||||
// set the menu to allow disconnection.
|
||||
r.menuconstr = func(menu *gtk.Menu) {
|
||||
primitives.AppendMenuItems(menu, []gtk.IMenuItem{
|
||||
primitives.MenuItem("Connect", r.ReconnectSession),
|
||||
primitives.MenuItem("Remove", r.RemoveSession),
|
||||
})
|
||||
}
|
||||
}, err
|
||||
})
|
||||
}
|
||||
|
||||
func (r *Row) setLoading() {
|
||||
// set the loading icon
|
||||
r.Button.Image.SetPlaceholderIcon("content-loading-symbolic", IconSize)
|
||||
// set the loading icon in the servers list
|
||||
r.Servers.SetLoading()
|
||||
// restore the old label's color
|
||||
r.Button.SetLabelUnsafe(r.Button.GetLabel())
|
||||
// clear the tooltip
|
||||
|
@ -124,19 +192,24 @@ func (r *Row) setLoading() {
|
|||
// KeyringSession returns a keyring session, or nil if the session cannot be
|
||||
// saved.
|
||||
func (r *Row) KeyringSession() *keyring.Session {
|
||||
return keyring.GetSession(r.Session, r.Button.GetText())
|
||||
return keyring.ConvertSession(r.Session, r.Button.GetText())
|
||||
}
|
||||
|
||||
// ID returns the session ID.
|
||||
func (r *Row) ID() string {
|
||||
return r.sessionID
|
||||
}
|
||||
|
||||
func (r *Row) SetSession(ses cchat.Session) {
|
||||
// Disable the retry button.
|
||||
r.retry.SetSensitive(false)
|
||||
r.retry.Hide()
|
||||
|
||||
r.Session = ses
|
||||
r.sessionID = ses.ID()
|
||||
|
||||
r.Servers.SetServerList(ses)
|
||||
r.Box.PackStart(r.Servers, false, false, 0)
|
||||
|
||||
r.Button.SetLabelUnsafe(ses.Name())
|
||||
r.Button.Image.SetPlaceholderIcon("user-available-symbolic", IconSize)
|
||||
r.Box.PackStart(r.Servers, false, false, 0)
|
||||
|
||||
r.SetSensitive(true)
|
||||
r.SetTooltipText("") // reset
|
||||
|
||||
|
@ -145,22 +218,30 @@ func (r *Row) SetSession(ses cchat.Session) {
|
|||
r.Button.Image.AsyncSetIcon(iconer.Icon, "Error fetching session icon URL")
|
||||
}
|
||||
|
||||
// Wipe the keyring session off.
|
||||
r.krs = keyring.Session{}
|
||||
// Set the menu with the disconnect button.
|
||||
r.menuconstr = func(menu *gtk.Menu) {
|
||||
primitives.AppendMenuItems(menu, []gtk.IMenuItem{
|
||||
primitives.MenuItem("Disconnect", r.DisconnectSession),
|
||||
primitives.MenuItem("Remove", r.RemoveSession),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Row) SetFailed(krs keyring.Session, err error) {
|
||||
// Set the failed keyring session.
|
||||
r.krs = krs
|
||||
|
||||
func (r *Row) SetFailed(err error) {
|
||||
// Allow the retry button to be pressed.
|
||||
r.retry.SetSensitive(true)
|
||||
r.retry.Show()
|
||||
r.menuconstr = func(menu *gtk.Menu) {
|
||||
primitives.AppendMenuItems(menu, []gtk.IMenuItem{
|
||||
primitives.MenuItem("Retry", r.ReconnectSession),
|
||||
primitives.MenuItem("Remove", r.RemoveSession),
|
||||
})
|
||||
}
|
||||
|
||||
r.SetSensitive(true)
|
||||
r.SetTooltipText(err.Error())
|
||||
// Intentional side-effect of not changing the actual label state.
|
||||
r.Button.Label.SetMarkup(rich.MakeRed(r.Button.GetLabel()))
|
||||
// Set the icon to a failed one.
|
||||
r.Button.Image.SetPlaceholderIcon("computer-fail-symbolic", IconSize)
|
||||
}
|
||||
|
||||
func (r *Row) MessageRowSelected(server *server.Row, smsg cchat.ServerMessage) {
|
||||
|
|
|
@ -79,6 +79,12 @@ func (app *App) OnSessionRemove(id string) {
|
|||
}
|
||||
}
|
||||
|
||||
func (app *App) OnSessionDisconnect(id string) {
|
||||
// We're basically doing the same thing as removing a session. Check
|
||||
// OnSessionRemove above.
|
||||
app.OnSessionRemove(id)
|
||||
}
|
||||
|
||||
func (app *App) MessageRowSelected(ses *session.Row, srv *server.Row, smsg cchat.ServerMessage) {
|
||||
// Is there an old row that we should deactivate?
|
||||
if app.lastDeactivator != nil {
|
||||
|
|
Loading…
Reference in a new issue