1
0
Fork 0
mirror of https://github.com/diamondburned/cchat-gtk.git synced 2024-10-31 19:44:23 +00:00
cchat-gtk/internal/ui/service/session/session.go

177 lines
4.8 KiB
Go
Raw Normal View History

2020-05-26 06:51:06 +00:00
package session
import (
"github.com/diamondburned/cchat"
2020-06-07 04:27:28 +00:00
"github.com/diamondburned/cchat-gtk/internal/keyring"
2020-05-28 19:26:55 +00:00
"github.com/diamondburned/cchat-gtk/internal/ui/primitives"
2020-06-04 23:00:41 +00:00
"github.com/diamondburned/cchat-gtk/internal/ui/rich"
2020-06-06 00:47:28 +00:00
"github.com/diamondburned/cchat-gtk/internal/ui/service/breadcrumb"
2020-05-26 06:51:06 +00:00
"github.com/diamondburned/cchat-gtk/internal/ui/service/session/server"
2020-06-04 23:00:41 +00:00
"github.com/diamondburned/cchat/text"
2020-06-07 04:27:28 +00:00
"github.com/diamondburned/imgutil"
"github.com/gotk3/gotk3/gdk"
2020-05-26 06:51:06 +00:00
"github.com/gotk3/gotk3/gtk"
)
2020-06-04 23:00:41 +00:00
const IconSize = 32
// Controller extends server.RowController to add session.
type Controller interface {
MessageRowSelected(*Row, *server.Row, cchat.ServerMessage)
2020-06-07 07:06:13 +00:00
RestoreSession(*Row, keyring.Session) // async
RemoveSession(*Row)
MoveSession(id, movingID string)
2020-06-04 23:00:41 +00:00
}
// Row represents a single session, including the button header and the
// children servers.
2020-05-26 06:51:06 +00:00
type Row struct {
*gtk.Box
2020-06-04 23:00:41 +00:00
Button *rich.ToggleButtonImage
2020-05-26 06:51:06 +00:00
Session cchat.Session
Servers *server.Children
2020-06-04 23:00:41 +00:00
2020-06-07 07:06:13 +00:00
menu *gtk.Menu
retry *gtk.MenuItem
2020-06-06 00:47:28 +00:00
ctrl Controller
parent breadcrumb.Breadcrumber
2020-06-07 07:06:13 +00:00
// nil after calling SetSession()
krs keyring.Session
2020-05-26 06:51:06 +00:00
}
2020-06-06 00:47:28 +00:00
func New(parent breadcrumb.Breadcrumber, ses cchat.Session, ctrl Controller) *Row {
2020-06-07 04:27:28 +00:00
row := new(parent, ctrl)
row.SetSession(ses)
return row
}
func NewLoading(parent breadcrumb.Breadcrumber, name string, ctrl Controller) *Row {
row := new(parent, ctrl)
row.Button.SetLabelUnsafe(text.Rich{Content: name})
2020-06-07 07:06:13 +00:00
row.setLoading()
2020-06-07 04:27:28 +00:00
return row
}
var dragEntries = []gtk.TargetEntry{
primitives.NewTargetEntry("GTK_TOGGLE_BUTTON"),
}
var dragAtom = gdk.GdkAtomIntern("GTK_TOGGLE_BUTTON", true)
2020-06-07 04:27:28 +00:00
func new(parent breadcrumb.Breadcrumber, ctrl Controller) *Row {
2020-06-04 23:00:41 +00:00
row := &Row{
2020-06-07 04:27:28 +00:00
ctrl: ctrl,
parent: parent,
2020-05-26 06:51:06 +00:00
}
2020-06-07 07:06:13 +00:00
row.Servers = server.NewChildren(parent, row)
2020-05-26 06:51:06 +00:00
2020-06-06 07:44:36 +00:00
row.Button = rich.NewToggleButtonImage(text.Rich{})
2020-06-04 23:00:41 +00:00
row.Button.Box.SetHAlign(gtk.ALIGN_START)
2020-06-07 04:27:28 +00:00
row.Button.Image.AddProcessors(imgutil.Round(true))
// Set the loading icon.
2020-06-04 23:00:41 +00:00
row.Button.SetRelief(gtk.RELIEF_NONE)
row.Button.Show()
2020-06-04 23:00:41 +00:00
// On click, toggle reveal.
row.Button.Connect("clicked", func() {
revealed := !row.Servers.GetRevealChild()
row.Servers.SetRevealChild(revealed)
row.Button.SetActive(revealed)
})
2020-05-28 19:26:55 +00:00
2020-06-04 23:00:41 +00:00
row.Box, _ = gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0)
row.Box.SetMarginStart(server.ChildrenMargin)
row.Box.PackStart(row.Button, false, false, 0)
row.Box.Show()
2020-05-28 19:26:55 +00:00
2020-06-04 23:00:41 +00:00
primitives.AddClass(row.Box, "session")
2020-05-26 06:51:06 +00:00
2020-06-07 07:06:13 +00:00
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)
})
row.retry.SetSensitive(false)
primitives.AppendMenuItems(row.menu, []*gtk.MenuItem{
row.retry,
primitives.MenuItem("Remove", func() {
ctrl.RemoveSession(row)
2020-06-07 07:06:13 +00:00
}),
})
2020-06-04 23:00:41 +00:00
return row
}
2020-05-26 06:51:06 +00:00
2020-06-07 07:06:13 +00:00
func (r *Row) setLoading() {
// set the loading icon
r.Button.Image.SetPlaceholderIcon("content-loading-symbolic", IconSize)
// restore the old label's color
r.Button.SetLabelUnsafe(r.Button.GetLabel())
// blur - set the color darker
r.SetSensitive(false)
}
2020-06-07 04:27:28 +00:00
// KeyringSession returns a keyring session, or nil if the session cannot be
2020-06-07 07:06:13 +00:00
// saved.
2020-06-07 04:27:28 +00:00
func (r *Row) KeyringSession() *keyring.Session {
2020-06-07 07:06:13 +00:00
return keyring.GetSession(r.Session, r.Button.GetText())
2020-06-07 04:27:28 +00:00
}
func (r *Row) SetSession(ses cchat.Session) {
2020-06-07 07:06:13 +00:00
// Disable the retry button.
r.retry.SetSensitive(false)
r.retry.Hide()
2020-06-07 04:27:28 +00:00
r.Session = ses
2020-06-07 07:06:13 +00:00
r.Servers.SetServerList(ses)
r.Button.SetLabelUnsafe(ses.Name())
2020-06-07 04:27:28 +00:00
r.Button.Image.SetPlaceholderIcon("user-available-symbolic", IconSize)
r.Box.PackStart(r.Servers, false, false, 0)
r.SetSensitive(true)
r.SetTooltipText("") // reset
2020-06-07 04:27:28 +00:00
// Try and set the session's icon.
if iconer, ok := ses.(cchat.Icon); ok {
r.Button.Image.AsyncSetIcon(iconer.Icon, "Error fetching session icon URL")
}
2020-06-07 07:06:13 +00:00
// Wipe the keyring session off.
r.krs = keyring.Session{}
2020-06-07 04:27:28 +00:00
}
2020-06-07 07:06:13 +00:00
func (r *Row) SetFailed(krs keyring.Session, err error) {
// Set the failed keyring session.
r.krs = krs
// Allow the retry button to be pressed.
r.retry.SetSensitive(true)
r.retry.Show()
r.SetSensitive(true)
2020-06-07 04:27:28 +00:00
r.SetTooltipText(err.Error())
2020-06-07 07:06:13 +00:00
// Intentional side-effect of not changing the actual label state.
2020-06-07 04:27:28 +00:00
r.Button.Label.SetMarkup(rich.MakeRed(r.Button.GetLabel()))
}
2020-06-04 23:00:41 +00:00
func (r *Row) MessageRowSelected(server *server.Row, smsg cchat.ServerMessage) {
r.ctrl.MessageRowSelected(r, server, smsg)
2020-05-26 06:51:06 +00:00
}
2020-06-06 00:47:28 +00:00
func (r *Row) Breadcrumb() breadcrumb.Breadcrumb {
return breadcrumb.Try(r.parent, r.Button.GetLabel().Content)
}
// BindMover binds with the ID stored in the parent container to be used in the
// method itself. The ID may or may not have to do with session.
func (r *Row) BindMover(id string) {
primitives.BindDragSortable(r.Button, "GTK_TOGGLE_BUTTON", id, r.ctrl.MoveSession)
}