Better webhook usernames, fix configs

This commit is contained in:
diamondburned 2021-05-01 00:24:34 -07:00
parent deb4ccb32b
commit cc2b2ee4c7
6 changed files with 42 additions and 32 deletions

View File

@ -14,7 +14,7 @@ type boolStamp struct {
var _ customType = (*boolStamp)(nil) var _ customType = (*boolStamp)(nil)
func (bs boolStamp) Marshal() string { func (bs *boolStamp) Marshal() string {
if bs.stamp > 0 { if bs.stamp > 0 {
return bs.stamp.String() return bs.stamp.String()
} }

View File

@ -25,6 +25,8 @@ func (c config) Marshal(dst map[string]string) error {
dst[c.Name] = strconv.FormatBool(v) dst[c.Name] = strconv.FormatBool(v)
case string: case string:
dst[c.Name] = v dst[c.Name] = v
case customType:
dst[c.Name] = v.Marshal()
default: default:
return cchat.ErrInvalidConfigAtField{ return cchat.ErrInvalidConfigAtField{
Key: c.Name, Key: c.Name,
@ -50,7 +52,6 @@ func (c *config) Unmarshal(src map[string]string) (err error) {
c.Value = strVal c.Value = strVal
case customType: case customType:
err = v.Unmarshal(strVal) err = v.Unmarshal(strVal)
c.Value = v
default: default:
err = fmt.Errorf("unknown type %T", c.Value) err = fmt.Errorf("unknown type %T", c.Value)
} }
@ -81,7 +82,7 @@ func (reg *registry) Configuration() (map[string]string, error) {
reg.mutex.RLock() reg.mutex.RLock()
defer reg.mutex.RUnlock() defer reg.mutex.RUnlock()
var configMap = map[string]string{} configMap := make(map[string]string, len(reg.configs))
for _, config := range reg.configs { for _, config := range reg.configs {
if err := config.Marshal(configMap); err != nil { if err := config.Marshal(configMap); err != nil {

View File

@ -17,7 +17,7 @@ var world = &registry{
// MentionOnReply returns true if message replies should mention users. // MentionOnReply returns true if message replies should mention users.
func MentionOnReply(timestamp time.Time) bool { func MentionOnReply(timestamp time.Time) bool {
v := world.get(0).(boolStamp) v := world.get(0).(*boolStamp)
if v.stamp > 0 { if v.stamp > 0 {
return timestamp.Add(v.stamp).Before(time.Now()) return timestamp.Add(v.stamp).Before(time.Now())

View File

@ -60,13 +60,25 @@ func richUser(rich *text.Rich, user *mention.User) (start, end int) {
return return
} }
// ID returns the author's ID. The ID may not be a valid Discord user ID if the
// user is not a valid (real) user (e.g. webhooks).
func (a Author) ID() cchat.ID { func (a Author) ID() cchat.ID {
return a.user.UserID().String() user := a.user.User()
id := user.ID.String()
// Treat pseudo-users specially.
if user.Discriminator == "0000" {
id += "_" + user.Username
}
return id
} }
// Name subscribes the author to the global name label registry. // Name subscribes the author to the global name label registry.
func (a Author) Name(_ context.Context, l cchat.LabelContainer) (func(), error) { func (a Author) Name(_ context.Context, l cchat.LabelContainer) (func(), error) {
return a.state.Labels.AddMemberLabel(a.user.GuildID(), a.user.UserID(), l), nil l.SetLabel(a.name)
return func() {}, nil
} }
const authorReplyingTo = " replying to " const authorReplyingTo = " replying to "

View File

@ -2,7 +2,6 @@ package messenger
import ( import (
"context" "context"
"sort"
"github.com/diamondburned/arikawa/v2/discord" "github.com/diamondburned/arikawa/v2/discord"
"github.com/diamondburned/arikawa/v2/gateway" "github.com/diamondburned/arikawa/v2/gateway"
@ -38,7 +37,7 @@ func (msgr *Messenger) JoinServer(ctx context.Context, ct cchat.MessagesContaine
return nil, err return nil, err
} }
var addcancel = funcutil.NewCancels() addcancel := funcutil.NewCancels()
if msgr.GuildID.IsValid() { if msgr.GuildID.IsValid() {
// Subscribe to typing events. // Subscribe to typing events.
@ -62,19 +61,9 @@ func (msgr *Messenger) JoinServer(ctx context.Context, ct cchat.MessagesContaine
})) }))
} }
// Only do all this if we even have any messages. // Iterate from the earliest messages to the latest messages.
if len(m) > 0 { for _, m := range m {
// Sort messages chronologically using the ID so that the oldest messages ct.CreateMessage(message.NewBacklogMessage(m, msgr.State))
// (ones with the smallest snowflake) is in front.
sort.Slice(m, func(i, j int) bool { return m[i].ID < m[j].ID })
// Iterate from the earliest messages to the latest messages.
for _, m := range m {
ct.CreateMessage(message.NewBacklogMessage(m, msgr.State))
}
// Mark this channel as read.
msgr.State.ReadState.MarkRead(msgr.ID, m[len(m)-1].ID)
} }
// Bind the handler. // Bind the handler.
@ -82,7 +71,6 @@ func (msgr *Messenger) JoinServer(ctx context.Context, ct cchat.MessagesContaine
msgr.State.AddHandler(func(m *gateway.MessageCreateEvent) { msgr.State.AddHandler(func(m *gateway.MessageCreateEvent) {
if m.ChannelID == msgr.ID { if m.ChannelID == msgr.ID {
ct.CreateMessage(message.NewGuildMessageCreate(m, msgr.State)) ct.CreateMessage(message.NewGuildMessageCreate(m, msgr.State))
msgr.State.ReadState.MarkRead(msgr.ID, m.ID)
} }
}), }),
msgr.State.AddHandler(func(m *gateway.MessageUpdateEvent) { msgr.State.AddHandler(func(m *gateway.MessageUpdateEvent) {

View File

@ -52,13 +52,22 @@ func NewMemberText(s *ningen.State, g discord.GuildID, u discord.UserID) text.Ri
// NewUserText creates a new rich text describing a Discord user using the // NewUserText creates a new rich text describing a Discord user using the
// Presence API. // Presence API.
func NewUserText(s *ningen.State, u discord.UserID) text.Rich { func NewUserText(s *ningen.State, u discord.UserID) text.Rich {
var discordUser discord.User
p, err := s.Presence(0, u) p, err := s.Presence(0, u)
if err != nil { if err != nil {
return text.Plain(u.Mention()) ready := s.Ready()
if ready.User.ID != u {
return text.Plain("Unknown user " + u.String())
}
discordUser = ready.User
} }
user := NewUser(p.User) user := NewUser(discordUser)
user.WithPresence(*p) if p != nil {
user.WithPresence(*p)
}
user.WithState(s) user.WithState(s)
user.Prefetch() user.Prefetch()
@ -71,7 +80,7 @@ func NewUserText(s *ningen.State, u discord.UserID) text.Rich {
}, },
} }
if p.User.Bot { if discordUser.Bot {
rich.Content += " " rich.Content += " "
rich.Segments = append(rich.Segments, rich.Segments = append(rich.Segments,
colored.NewBlurple(segutil.Write(&rich, "[BOT]")), colored.NewBlurple(segutil.Write(&rich, "[BOT]")),
@ -164,11 +173,8 @@ func (um *User) Prefetch() {
// DisplayName returns either the nickname or the username. // DisplayName returns either the nickname or the username.
func (um *User) DisplayName() string { func (um *User) DisplayName() string {
if um.guildID.IsValid() { if m := um.getMember(); m != nil && m.Nick != "" {
m, err := um.store.Member(um.guildID, um.user.ID) return m.Nick
if err == nil && m.Nick != "" {
return m.Nick
}
} }
return um.user.Username return um.user.Username
@ -310,7 +316,9 @@ func (um *User) getGuild() *discord.Guild {
} }
func (um *User) getMember() *discord.Member { func (um *User) getMember() *discord.Member {
if !um.guildID.IsValid() { // 0000 isn't a valid discriminator; the user is probably a webhook.
// Fallback to the actual user.
if !um.guildID.IsValid() || (um.user.Discriminator == "0000" && um.user.Bot) {
return nil return nil
} }
@ -327,6 +335,7 @@ func (um *User) getMember() *discord.Member {
return nil return nil
} }
um.user = m.User
um.member = m um.member = m
return m return m
} }