mirror of
https://github.com/diamondburned/cchat-discord.git
synced 2024-11-01 12:24:15 +00:00
170 lines
4.2 KiB
Go
170 lines
4.2 KiB
Go
package message
|
|
|
|
import (
|
|
"github.com/diamondburned/arikawa/v2/discord"
|
|
"github.com/diamondburned/cchat"
|
|
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
|
"github.com/diamondburned/cchat-discord/internal/segments/colored"
|
|
"github.com/diamondburned/cchat-discord/internal/segments/mention"
|
|
"github.com/diamondburned/cchat-discord/internal/segments/reference"
|
|
"github.com/diamondburned/cchat-discord/internal/segments/segutil"
|
|
"github.com/diamondburned/cchat-discord/internal/urlutils"
|
|
"github.com/diamondburned/cchat/text"
|
|
)
|
|
|
|
type Author struct {
|
|
id discord.UserID
|
|
name text.Rich
|
|
avatar string
|
|
}
|
|
|
|
var _ cchat.Author = (*Author)(nil)
|
|
|
|
func NewUser(u discord.User, s *state.Instance) Author {
|
|
var rich text.Rich
|
|
richUser(&rich, u, s)
|
|
|
|
return Author{
|
|
id: u.ID,
|
|
name: rich,
|
|
avatar: urlutils.AvatarURL(u.AvatarURL()),
|
|
}
|
|
}
|
|
|
|
func NewGuildMember(m discord.Member, g discord.Guild, s *state.Instance) Author {
|
|
return Author{
|
|
id: m.User.ID,
|
|
name: RenderMemberName(m, g, s),
|
|
avatar: urlutils.AvatarURL(m.User.AvatarURL()),
|
|
}
|
|
}
|
|
|
|
func RenderMemberName(m discord.Member, g discord.Guild, s *state.Instance) text.Rich {
|
|
var rich text.Rich
|
|
richMember(&rich, m, g, s)
|
|
return rich
|
|
}
|
|
|
|
// richMember appends the member name directly into rich.
|
|
func richMember(
|
|
rich *text.Rich, m discord.Member, g discord.Guild, s *state.Instance) (start, end int) {
|
|
|
|
var displayName = m.User.Username
|
|
if m.Nick != "" {
|
|
displayName = m.Nick
|
|
}
|
|
|
|
start, end = segutil.Write(rich, displayName)
|
|
|
|
// Update the color.
|
|
if c := discord.MemberColor(g, m); c > 0 {
|
|
rich.Segments = append(rich.Segments,
|
|
colored.NewSegment(start, end, c.Uint32()),
|
|
)
|
|
}
|
|
|
|
// Append the bot prefix if the user is a bot.
|
|
if m.User.Bot {
|
|
rich.Content += " "
|
|
rich.Segments = append(rich.Segments,
|
|
colored.NewBlurple(segutil.Write(rich, "[BOT]")),
|
|
)
|
|
}
|
|
|
|
// Append a clickable user popup.
|
|
useg := mention.MemberSegment(start, end, g, m)
|
|
useg.WithState(s.State)
|
|
rich.Segments = append(rich.Segments, useg)
|
|
|
|
return
|
|
}
|
|
|
|
func richUser(
|
|
rich *text.Rich, u discord.User, s *state.Instance) (start, end int) {
|
|
|
|
start, end = segutil.Write(rich, u.Username)
|
|
|
|
// Append the bot prefix if the user is a bot.
|
|
if u.Bot {
|
|
rich.Content += " "
|
|
rich.Segments = append(rich.Segments,
|
|
colored.NewBlurple(segutil.Write(rich, "[BOT]")),
|
|
)
|
|
}
|
|
|
|
// Append a clickable user popup.
|
|
useg := mention.UserSegment(start, end, u)
|
|
useg.WithState(s.State)
|
|
rich.Segments = append(rich.Segments, useg)
|
|
|
|
return
|
|
}
|
|
|
|
func (a Author) ID() cchat.ID {
|
|
return a.id.String()
|
|
}
|
|
|
|
func (a Author) Name() text.Rich {
|
|
return a.name
|
|
}
|
|
|
|
func (a Author) Avatar() string {
|
|
return a.avatar
|
|
}
|
|
|
|
const authorReplyingTo = " replying to "
|
|
|
|
// AddUserReply modifies Author to make it appear like it's a message reply.
|
|
// Specifically, this function is used for direct messages.
|
|
func (a *Author) AddUserReply(user discord.User, s *state.Instance) {
|
|
a.name.Content += authorReplyingTo
|
|
richUser(&a.name, user, s)
|
|
}
|
|
|
|
func (a *Author) AddReply(name string) {
|
|
a.name.Content += authorReplyingTo + name
|
|
}
|
|
|
|
// // AddMemberReply modifies Author to make it appear like it's a message reply.
|
|
// // Specifically, this function is used for guild messages.
|
|
// func (a *Author) AddMemberReply(m discord.Member, g discord.Guild, s *state.Instance) {
|
|
// a.name.Content += authorReplyingTo
|
|
// richMember(&a.name, m, g, s)
|
|
// }
|
|
|
|
func (a *Author) addAuthorReference(msgref discord.Message, s *state.Instance) {
|
|
a.name.Content += authorReplyingTo
|
|
start, end := richUser(&a.name, msgref.Author, s)
|
|
|
|
a.name.Segments = append(a.name.Segments,
|
|
reference.NewMessageSegment(start, end, msgref.ID),
|
|
)
|
|
}
|
|
|
|
// AddMessageReference adds a message reference to the author.
|
|
func (a *Author) AddMessageReference(msgref discord.Message, s *state.Instance) {
|
|
if !msgref.GuildID.IsValid() {
|
|
a.addAuthorReference(msgref, s)
|
|
return
|
|
}
|
|
|
|
g, err := s.Cabinet.Guild(msgref.GuildID)
|
|
if err != nil {
|
|
a.addAuthorReference(msgref, s)
|
|
return
|
|
}
|
|
|
|
m, err := s.Cabinet.Member(g.ID, msgref.Author.ID)
|
|
if err != nil {
|
|
a.addAuthorReference(msgref, s)
|
|
return
|
|
}
|
|
|
|
a.name.Content += authorReplyingTo
|
|
start, end := richMember(&a.name, *m, *g, s)
|
|
|
|
a.name.Segments = append(a.name.Segments,
|
|
reference.NewMessageSegment(start, end, msgref.ID),
|
|
)
|
|
}
|