120 lines
2.7 KiB
Go
120 lines
2.7 KiB
Go
package memberlist
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/diamondburned/arikawa/v2/discord"
|
|
"github.com/diamondburned/arikawa/v2/gateway"
|
|
"github.com/diamondburned/cchat"
|
|
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
|
"github.com/diamondburned/cchat-discord/internal/segments/emoji"
|
|
"github.com/diamondburned/cchat-discord/internal/segments/mention"
|
|
"github.com/diamondburned/cchat/text"
|
|
)
|
|
|
|
type Member struct {
|
|
channel shared.Channel
|
|
mention mention.User
|
|
presence gateway.Presence
|
|
}
|
|
|
|
// New creates a new list member. it.Member must not be nil.
|
|
func NewMember(ch shared.Channel, opItem gateway.GuildMemberListOpItem) cchat.ListMember {
|
|
user := mention.NewUser(opItem.Member.User)
|
|
user.WithState(ch.State.State)
|
|
user.SetMember(ch.GuildID, &opItem.Member.Member)
|
|
user.SetPresence(opItem.Member.Presence)
|
|
|
|
return &Member{
|
|
channel: ch,
|
|
presence: opItem.Member.Presence,
|
|
mention: *user,
|
|
}
|
|
}
|
|
|
|
func (l *Member) ID() cchat.ID {
|
|
return l.mention.UserID().String()
|
|
}
|
|
|
|
func (l *Member) Name() text.Rich {
|
|
content := l.mention.DisplayName()
|
|
|
|
return text.Rich{
|
|
Content: content,
|
|
Segments: []text.Segment{
|
|
mention.NewSegment(0, len(content), &l.mention),
|
|
},
|
|
}
|
|
}
|
|
|
|
func (l *Member) AsIconer() cchat.Iconer { return l }
|
|
|
|
func (l *Member) Icon(ctx context.Context, c cchat.IconContainer) (func(), error) {
|
|
c.SetIcon(l.mention.Avatar())
|
|
return func() {}, nil
|
|
}
|
|
|
|
func (l *Member) Status() cchat.Status {
|
|
switch l.presence.Status {
|
|
case gateway.OnlineStatus:
|
|
return cchat.StatusOnline
|
|
case gateway.DoNotDisturbStatus:
|
|
return cchat.StatusBusy
|
|
case gateway.IdleStatus:
|
|
return cchat.StatusAway
|
|
case gateway.OfflineStatus, gateway.InvisibleStatus:
|
|
return cchat.StatusOffline
|
|
default:
|
|
return cchat.StatusUnknown
|
|
}
|
|
}
|
|
|
|
func (l *Member) Secondary() text.Rich {
|
|
if len(l.presence.Activities) == 0 {
|
|
return text.Rich{}
|
|
}
|
|
|
|
return formatSmallActivity(l.presence.Activities[0])
|
|
}
|
|
|
|
func formatSmallActivity(ac discord.Activity) text.Rich {
|
|
switch ac.Type {
|
|
case discord.GameActivity:
|
|
return text.Plain(fmt.Sprintf("Playing %s", ac.Name))
|
|
|
|
case discord.ListeningActivity:
|
|
return text.Plain(fmt.Sprintf("Listening to %s", ac.Name))
|
|
|
|
case discord.StreamingActivity:
|
|
return text.Plain(fmt.Sprintf("Streaming on %s", ac.Name))
|
|
|
|
case discord.CustomActivity:
|
|
var status strings.Builder
|
|
var segmts []text.Segment
|
|
|
|
if ac.Emoji != nil {
|
|
if !ac.Emoji.ID.IsValid() {
|
|
status.WriteString(ac.Emoji.Name)
|
|
status.WriteByte(' ')
|
|
} else {
|
|
segmts = append(segmts, emoji.Segment{
|
|
Start: status.Len(),
|
|
Emoji: emoji.EmojiFromDiscord(*ac.Emoji, ac.State == ""),
|
|
})
|
|
}
|
|
}
|
|
|
|
status.WriteString(ac.State)
|
|
|
|
return text.Rich{
|
|
Content: status.String(),
|
|
Segments: segmts,
|
|
}
|
|
|
|
default:
|
|
return text.Rich{}
|
|
}
|
|
}
|