cchat-discord/internal/discord/message/author.go

122 lines
3.3 KiB
Go
Raw Normal View History

2020-09-08 04:44:09 +00:00
package message
import (
2021-03-15 04:30:05 +00:00
"context"
2020-12-20 05:44:26 +00:00
"github.com/diamondburned/arikawa/v2/discord"
2020-09-08 04:44:09 +00:00
"github.com/diamondburned/cchat"
"github.com/diamondburned/cchat-discord/internal/discord/state"
2020-10-07 01:53:15 +00:00
"github.com/diamondburned/cchat-discord/internal/segments/colored"
"github.com/diamondburned/cchat-discord/internal/segments/mention"
2020-12-19 05:46:12 +00:00
"github.com/diamondburned/cchat-discord/internal/segments/reference"
2020-10-07 01:53:15 +00:00
"github.com/diamondburned/cchat-discord/internal/segments/segutil"
2020-09-08 04:44:09 +00:00
"github.com/diamondburned/cchat/text"
)
type Author struct {
2021-03-15 04:30:05 +00:00
name text.Rich
user *mention.User // same pointer as in name
state *state.Instance
2020-09-08 04:44:09 +00:00
}
2021-03-13 08:21:12 +00:00
var _ cchat.User = (*Author)(nil)
2021-01-06 04:53:49 +00:00
// NewAuthor creates a new message author.
2021-03-15 04:30:05 +00:00
func NewAuthor(s *state.Instance, user *mention.User) Author {
user.WithState(s.State)
2020-09-08 04:44:09 +00:00
return Author{
2021-03-15 04:30:05 +00:00
name: RenderUserName(user),
user: user,
state: s,
2020-09-08 04:44:09 +00:00
}
}
2021-03-15 04:30:05 +00:00
// RenderUserName renders the given user mention into a text segment.
func RenderUserName(user *mention.User) text.Rich {
2020-12-19 05:46:12 +00:00
var rich text.Rich
2021-01-06 04:53:49 +00:00
richUser(&rich, user)
2020-12-19 05:46:12 +00:00
return rich
}
2020-09-08 04:44:09 +00:00
2020-12-19 05:46:12 +00:00
// richMember appends the member name directly into rich.
2021-01-06 04:53:49 +00:00
func richUser(rich *text.Rich, user *mention.User) (start, end int) {
start, end = segutil.Write(rich, user.DisplayName())
2020-12-19 05:46:12 +00:00
// Append the bot prefix if the user is a bot.
2021-01-06 04:53:49 +00:00
if user.User().Bot {
2020-12-19 05:46:12 +00:00
rich.Content += " "
rich.Segments = append(rich.Segments,
colored.NewBlurple(segutil.Write(rich, "[BOT]")),
)
}
2021-03-15 04:30:05 +00:00
rich.Segments = append(rich.Segments, mention.Segment{
Start: start,
End: end,
User: user,
})
2020-12-19 05:46:12 +00:00
return
2020-09-08 04:44:09 +00:00
}
func (a Author) ID() cchat.ID {
2021-01-06 04:53:49 +00:00
return a.user.UserID().String()
2020-09-08 04:44:09 +00:00
}
2021-03-15 04:30:05 +00:00
// Name subscribes the author to the global name label registry.
func (a Author) Name(_ context.Context, l cchat.LabelContainer) (func(), error) {
2021-03-26 06:32:15 +00:00
return a.state.Labels.AddMemberLabel(a.user.GuildID(), a.user.UserID(), l), nil
2020-09-08 04:44:09 +00:00
}
2020-12-19 05:46:12 +00:00
const authorReplyingTo = " replying to "
2021-03-15 04:30:05 +00:00
// AddUserReply modifies User to make it appear like it's a message reply.
2021-01-06 04:53:49 +00:00
// Specifically, this function is used for direct messages in virtual channels.
2020-12-19 05:46:12 +00:00
func (a *Author) AddUserReply(user discord.User, s *state.Instance) {
a.name.Content += authorReplyingTo
2021-01-06 04:53:49 +00:00
userMention := mention.NewUser(user)
userMention.WithState(s.State)
userMention.Prefetch()
richUser(&a.name, userMention)
2020-12-19 05:46:12 +00:00
}
2021-01-06 04:53:49 +00:00
// AddChannelReply adds a reply pointing to a channel. If the given channel is a
// direct message channel, then the first recipient will be used instead, and
// the function will operate similar to AddUserReply.
func (a *Author) AddChannelReply(ch discord.Channel, s *state.Instance) {
if ch.Type == discord.DirectMessage && len(ch.DMRecipients) > 0 {
a.AddUserReply(ch.DMRecipients[0], s)
return
}
2020-12-19 05:46:12 +00:00
2020-12-20 05:44:26 +00:00
a.name.Content += authorReplyingTo
2021-03-15 04:30:05 +00:00
start, end := segutil.Write(&a.name, mention.ChannelName(ch))
2020-12-20 05:44:26 +00:00
a.name.Segments = append(a.name.Segments,
2021-01-06 04:53:49 +00:00
mention.Segment{
Start: start,
End: end,
Channel: mention.NewChannel(ch),
},
2020-12-20 05:44:26 +00:00
)
}
2021-03-15 04:30:05 +00:00
// AddMessageReference adds a message reference to the user.
2021-01-02 08:52:53 +00:00
func (a *Author) AddMessageReference(ref discord.Message, s *state.Instance) {
2021-01-06 04:53:49 +00:00
a.name.Content += authorReplyingTo
2020-12-19 05:46:12 +00:00
2021-01-06 04:53:49 +00:00
userMention := mention.NewUser(ref.Author)
userMention.WithGuildID(ref.GuildID)
userMention.WithState(s.State)
userMention.Prefetch()
2020-12-19 05:46:12 +00:00
2021-01-06 04:53:49 +00:00
start, end := richUser(&a.name, userMention)
2020-12-19 05:46:12 +00:00
a.name.Segments = append(a.name.Segments,
2021-01-02 08:52:53 +00:00
reference.NewMessageSegment(start, end, ref.ID),
2020-12-19 05:46:12 +00:00
)
}