1
0
Fork 0
mirror of https://github.com/diamondburned/cchat-discord.git synced 2024-12-27 14:27:43 +00:00
cchat-discord/internal/segments/mention/mention.go

114 lines
2.1 KiB
Go

package mention
import (
"github.com/diamondburned/arikawa/v2/discord"
"github.com/diamondburned/cchat-discord/internal/segments/renderer"
"github.com/diamondburned/cchat/text"
"github.com/diamondburned/cchat/utils/empty"
"github.com/diamondburned/ningen/v2/md"
"github.com/yuin/goldmark/ast"
)
func init() {
renderer.Register(md.KindMention, mention)
}
func mention(r *renderer.Text, node ast.Node, enter bool) ast.WalkStatus {
n := node.(*md.Mention)
if enter {
var seg = Segment{}
switch {
case n.Channel != nil:
seg.Start, seg.End = r.WriteString("#" + n.Channel.Name)
seg.Channel = NewChannel(*n.Channel)
case n.GuildUser != nil:
seg.Start, seg.End = r.WriteString("@" + n.GuildUser.Username)
seg.User = NewUser(n.GuildUser.User)
seg.User.store = r.Store
seg.User.WithGuildID(r.Message.GuildID)
if n.GuildUser.Member != nil {
seg.User.WithMember(*n.GuildUser.Member)
}
seg.User.Prefetch()
case n.GuildRole != nil:
seg.Start, seg.End = r.WriteString("@" + n.GuildRole.Name)
seg.Role = NewRole(*n.GuildRole)
default:
// Unexpected error; skip.
return ast.WalkSkipChildren
}
r.Append(seg)
}
return ast.WalkContinue
}
type Segment struct {
empty.TextSegment
Start, End int
// enums?
Channel *Channel
User *User
Role *Role
}
func (s Segment) Bounds() (start, end int) {
return s.Start, s.End
}
func (s Segment) AsColorer() text.Colorer {
switch {
case s.User != nil && s.User.HasColor():
return s.User
case s.Role != nil:
return s.Role
}
return nil
}
func (s Segment) AsAvatarer() text.Avatarer {
switch {
case s.User != nil:
return s.User
}
return nil
}
func (s Segment) AsMentioner() text.Mentioner {
switch {
case s.Channel != nil:
return s.Channel
case s.User != nil:
return s.User
}
return nil
}
func MemberColor(guild discord.Guild, member discord.Member) (c uint32, ok bool) {
var pos int
for _, r := range guild.Roles {
for _, mr := range member.RoleIDs {
if mr != r.ID {
continue
}
if r.Color > 0 && r.Position > pos {
c = r.Color.Uint32()
ok = true
pos = r.Position
}
}
}
return
}