mirror of
https://github.com/diamondburned/cchat-discord.git
synced 2024-11-01 04:14:21 +00:00
141 lines
3.5 KiB
Go
141 lines
3.5 KiB
Go
package session
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/diamondburned/arikawa/gateway"
|
|
"github.com/diamondburned/arikawa/session"
|
|
"github.com/diamondburned/cchat"
|
|
"github.com/diamondburned/cchat-discord/internal/discord/folder"
|
|
"github.com/diamondburned/cchat-discord/internal/discord/guild"
|
|
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
|
"github.com/diamondburned/cchat-discord/internal/urlutils"
|
|
"github.com/diamondburned/cchat/text"
|
|
"github.com/diamondburned/cchat/utils/empty"
|
|
"github.com/diamondburned/ningen"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
var ErrMFA = session.ErrMFA
|
|
|
|
type Session struct {
|
|
empty.Session
|
|
*state.Instance
|
|
}
|
|
|
|
func NewFromInstance(i *state.Instance) (cchat.Session, error) {
|
|
return &Session{Instance: i}, nil
|
|
}
|
|
|
|
func (s *Session) ID() cchat.ID {
|
|
return s.UserID.String()
|
|
}
|
|
|
|
func (s *Session) Name() text.Rich {
|
|
u, err := s.Store.Me()
|
|
if err != nil {
|
|
// This shouldn't happen, ever.
|
|
return text.Rich{Content: "<@" + s.UserID.String() + ">"}
|
|
}
|
|
|
|
return text.Rich{Content: u.Username + "#" + u.Discriminator}
|
|
}
|
|
|
|
func (s *Session) AsIconer() cchat.Iconer { return s }
|
|
|
|
func (s *Session) Icon(ctx context.Context, iconer cchat.IconContainer) (func(), error) {
|
|
u, err := s.Me()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "Failed to get the current user")
|
|
}
|
|
|
|
// Thanks to arikawa, AvatarURL is never empty.
|
|
iconer.SetIcon(urlutils.AvatarURL(u.AvatarURL()))
|
|
|
|
return s.AddHandler(func(*gateway.UserUpdateEvent) {
|
|
// Bypass the event and use the state cache.
|
|
if u, err := s.Store.Me(); err == nil {
|
|
iconer.SetIcon(urlutils.AvatarURL(u.AvatarURL()))
|
|
}
|
|
}), nil
|
|
}
|
|
|
|
func (s *Session) Disconnect() error {
|
|
return s.Close()
|
|
}
|
|
|
|
func (s *Session) AsSessionSaver() cchat.SessionSaver { return s.Instance }
|
|
|
|
func (s *Session) Servers(container cchat.ServersContainer) error {
|
|
// Reset the entire container when the session is closed.
|
|
s.AddHandler(func(*session.Closed) {
|
|
container.SetServers(nil)
|
|
})
|
|
|
|
// Set the entire container again once reconnected.
|
|
s.AddHandler(func(*ningen.Connected) {
|
|
s.servers(container)
|
|
})
|
|
|
|
return s.servers(container)
|
|
}
|
|
|
|
func (s *Session) servers(container cchat.ServersContainer) error {
|
|
switch {
|
|
// If the user has guild folders:
|
|
case len(s.Ready.Settings.GuildFolders) > 0:
|
|
// TODO: account for missing guilds.
|
|
var toplevels = make([]cchat.Server, 0, len(s.Ready.Settings.GuildFolders))
|
|
|
|
for _, guildFolder := range s.Ready.Settings.GuildFolders {
|
|
// TODO: correct.
|
|
switch {
|
|
case guildFolder.ID != 0:
|
|
fallthrough
|
|
case len(guildFolder.GuildIDs) > 1:
|
|
toplevels = append(toplevels, folder.New(s.Instance, guildFolder))
|
|
|
|
case len(guildFolder.GuildIDs) == 1:
|
|
g, err := guild.NewFromID(s.Instance, guildFolder.GuildIDs[0])
|
|
if err != nil {
|
|
continue
|
|
}
|
|
toplevels = append(toplevels, g)
|
|
}
|
|
}
|
|
|
|
container.SetServers(toplevels)
|
|
|
|
// If the user doesn't have guild folders but has sorted their guilds
|
|
// before:
|
|
case len(s.Ready.Settings.GuildPositions) > 0:
|
|
var guilds = make([]cchat.Server, 0, len(s.Ready.Settings.GuildPositions))
|
|
|
|
for _, id := range s.Ready.Settings.GuildPositions {
|
|
g, err := guild.NewFromID(s.Instance, id)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
guilds = append(guilds, g)
|
|
}
|
|
|
|
container.SetServers(guilds)
|
|
|
|
// None of the above:
|
|
default:
|
|
g, err := s.Guilds()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var servers = make([]cchat.Server, len(g))
|
|
for i := range g {
|
|
servers[i] = guild.New(s.Instance, &g[i])
|
|
}
|
|
|
|
container.SetServers(servers)
|
|
}
|
|
|
|
return nil
|
|
}
|