mirror of
https://github.com/diamondburned/cchat-discord.git
synced 2024-11-25 23:52:48 +00:00
Minor appearance tweaks and bug fixes
This commit is contained in:
parent
e50f72a01d
commit
b8c92a56d8
2
go.mod
2
go.mod
|
@ -5,7 +5,7 @@ go 1.14
|
|||
require (
|
||||
github.com/diamondburned/arikawa v0.10.2
|
||||
github.com/diamondburned/cchat v0.0.43
|
||||
github.com/diamondburned/ningen v0.1.1-0.20200711215126-d4b8a17e818d
|
||||
github.com/diamondburned/ningen v0.1.1-0.20200712031630-349ee2c3f01c
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/go-test/deep v1.0.6
|
||||
github.com/pkg/errors v0.9.1
|
||||
|
|
2
go.sum
2
go.sum
|
@ -57,6 +57,8 @@ github.com/diamondburned/ningen v0.1.1-0.20200708211706-57c712372ede h1:qRmfQCOS
|
|||
github.com/diamondburned/ningen v0.1.1-0.20200708211706-57c712372ede/go.mod h1:FNezDLQIhoDS+RkXLSQ7dJNrt6BW/nVl1krzDgWMQwg=
|
||||
github.com/diamondburned/ningen v0.1.1-0.20200711215126-d4b8a17e818d h1:XgG/KRbAwu8v2/YZWimjXo0dgdD69E38ollCfbFtU7s=
|
||||
github.com/diamondburned/ningen v0.1.1-0.20200711215126-d4b8a17e818d/go.mod h1:NVneOJDUDEIC3cnyeh2vpeAPVtBdC2Kcy+uwDy4o2qk=
|
||||
github.com/diamondburned/ningen v0.1.1-0.20200712031630-349ee2c3f01c h1:CpYhIGiRzee7Jm0H4c0fLvRe/08QitDNo8KHYtrOmFE=
|
||||
github.com/diamondburned/ningen v0.1.1-0.20200712031630-349ee2c3f01c/go.mod h1:NVneOJDUDEIC3cnyeh2vpeAPVtBdC2Kcy+uwDy4o2qk=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
|
|
|
@ -34,8 +34,15 @@ func (r *TextRenderer) blockquote(n *ast.Blockquote, enter bool) ast.WalkStatus
|
|||
})
|
||||
}
|
||||
|
||||
// Write the end of the segment.
|
||||
seg.end = r.buf.Len()
|
||||
// Search until the last non-whitespace.
|
||||
var i = r.buf.Len() - 1
|
||||
for bytes := r.buf.Bytes(); i > 0 && isSpace(bytes[i]); i-- {
|
||||
}
|
||||
|
||||
// The ending will have a trailing character that's not covered, so
|
||||
// we'll need to do that ourselves.
|
||||
// End the codeblock at that non-whitespace location.
|
||||
seg.end = i + 1
|
||||
r.append(seg)
|
||||
}
|
||||
|
||||
|
@ -47,3 +54,9 @@ func (b BlockquoteSegment) Bounds() (start, end int) {
|
|||
}
|
||||
|
||||
func (b BlockquoteSegment) Quote() {}
|
||||
|
||||
// isSpace is a quick function that matches if the byte is a space, a new line
|
||||
// or a return carriage.
|
||||
func isSpace(b byte) bool {
|
||||
return b == ' ' || b == '\n' || b == '\r'
|
||||
}
|
||||
|
|
|
@ -168,6 +168,7 @@ type AvatarSegment struct {
|
|||
start int
|
||||
url string
|
||||
text string
|
||||
size int
|
||||
}
|
||||
|
||||
func EmbedAuthor(start int, a discord.EmbedAuthor) AvatarSegment {
|
||||
|
@ -198,6 +199,9 @@ func (a AvatarSegment) Avatar() (url string) {
|
|||
|
||||
// AvatarSize returns the size of a small emoji.
|
||||
func (a AvatarSegment) AvatarSize() int {
|
||||
if a.size > 0 {
|
||||
return a.size
|
||||
}
|
||||
return InlineEmojiSize
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,10 @@ package segments
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/cchat-discord/urlutils"
|
||||
"github.com/diamondburned/arikawa/state"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/ningen/md"
|
||||
"github.com/yuin/goldmark/ast"
|
||||
|
@ -15,47 +14,12 @@ import (
|
|||
|
||||
const blurple = 0x7289DA
|
||||
|
||||
type roleInfo struct {
|
||||
name string
|
||||
color uint32
|
||||
position int // used for sorting
|
||||
}
|
||||
|
||||
func (r *TextRenderer) userRoles(user *discord.GuildUser) []roleInfo {
|
||||
if user.Member == nil || r.msg == nil || !r.msg.GuildID.Valid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
var roles = make([]roleInfo, 0, len(user.Member.RoleIDs))
|
||||
|
||||
for _, roleID := range user.Member.RoleIDs {
|
||||
r, err := r.store.Role(r.msg.GuildID, roleID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
roles = append(roles, roleInfo{
|
||||
name: r.Name,
|
||||
color: r.Color.Uint32(), // default 0
|
||||
position: r.Position,
|
||||
})
|
||||
}
|
||||
|
||||
// Sort the roles so the first roles stay in front. We need to do this to
|
||||
// both render properly and to get the right role color.
|
||||
sort.Slice(roles, func(i, j int) bool {
|
||||
return roles[i].position < roles[j].position
|
||||
})
|
||||
|
||||
return roles
|
||||
}
|
||||
|
||||
type MentionSegment struct {
|
||||
start, end int
|
||||
*md.Mention
|
||||
|
||||
// only non-nil if GuildUser is not nil and is in a guild.
|
||||
roles []roleInfo
|
||||
store state.Store
|
||||
guild discord.Snowflake
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -66,14 +30,17 @@ var (
|
|||
|
||||
func (r *TextRenderer) mention(n *md.Mention, enter bool) ast.WalkStatus {
|
||||
if enter {
|
||||
var seg = MentionSegment{Mention: n}
|
||||
var seg = MentionSegment{
|
||||
Mention: n,
|
||||
store: r.store,
|
||||
guild: r.msg.GuildID,
|
||||
}
|
||||
|
||||
switch {
|
||||
case n.Channel != nil:
|
||||
seg.start, seg.end = r.writeString("#" + n.Channel.Name)
|
||||
case n.GuildUser != nil:
|
||||
seg.start, seg.end = r.writeString("@" + n.GuildUser.Username)
|
||||
seg.roles = r.userRoles(n.GuildUser) // get roles as well
|
||||
case n.GuildRole != nil:
|
||||
seg.start, seg.end = r.writeString("@" + n.GuildRole.Name)
|
||||
default:
|
||||
|
@ -96,12 +63,14 @@ func (m MentionSegment) Bounds() (start, end int) {
|
|||
func (m MentionSegment) Color() uint32 {
|
||||
// Try digging through what we have for a color.
|
||||
switch {
|
||||
case len(m.roles) > 0:
|
||||
for _, role := range m.roles {
|
||||
if role.color > 0 {
|
||||
return role.color
|
||||
}
|
||||
case m.GuildUser != nil && m.GuildUser.Member != nil:
|
||||
g, err := m.store.Guild(m.guild)
|
||||
if err != nil {
|
||||
return blurple
|
||||
}
|
||||
|
||||
return discord.MemberColor(*g, *m.GuildUser.Member).Uint32()
|
||||
|
||||
case m.GuildRole != nil && m.GuildRole.Color > 0:
|
||||
return m.GuildRole.Color.Uint32()
|
||||
}
|
||||
|
@ -148,16 +117,24 @@ func (m MentionSegment) userInfo() text.Rich {
|
|||
var segment text.Rich
|
||||
|
||||
// Make a large avatar if there's one.
|
||||
if m.GuildUser != nil {
|
||||
segment.Segments = append(segment.Segments, AvatarSegment{
|
||||
if m.GuildUser.Avatar != "" {
|
||||
segmentadd(&segment, AvatarSegment{
|
||||
start: 0,
|
||||
url: urlutils.AvatarURL(m.GuildUser.AvatarURL()),
|
||||
url: m.GuildUser.AvatarURL(), // full URL
|
||||
text: "Avatar",
|
||||
size: 72, // large
|
||||
})
|
||||
// Space out.
|
||||
content.WriteByte(' ')
|
||||
}
|
||||
|
||||
// We should have a member if there's nil. Sometimes when the members aren't
|
||||
// prefetched, the markdown parser can miss them. We can check this again.
|
||||
if m.GuildUser.Member == nil && m.guild.Valid() {
|
||||
// Best effort; fine if it's nil.
|
||||
m.GuildUser.Member, _ = m.store.Member(m.guild, m.GuildUser.ID)
|
||||
}
|
||||
|
||||
// Write the nickname if there's one; else, write the username only.
|
||||
if m.GuildUser.Member != nil && m.GuildUser.Member.Nick != "" {
|
||||
content.WriteString(m.GuildUser.Member.Nick)
|
||||
|
@ -180,18 +157,23 @@ func (m MentionSegment) userInfo() text.Rich {
|
|||
content.WriteString(m.GuildUser.Discriminator)
|
||||
}
|
||||
|
||||
// Write roles, if any.
|
||||
if len(m.roles) > 0 {
|
||||
// Write extra information if any.
|
||||
if m.GuildUser.Member != nil && len(m.GuildUser.Member.RoleIDs) > 0 {
|
||||
// Write a prepended new line, as role writes will always prepend a new
|
||||
// line. This is to prevent a trailing new line.
|
||||
content.WriteString("\n---\nRoles")
|
||||
content.WriteString("\n\n--- Roles ---")
|
||||
|
||||
for _, id := range m.GuildUser.Member.RoleIDs {
|
||||
r, err := m.store.Role(m.guild, id)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, role := range m.roles {
|
||||
// Prepend a new line before each item.
|
||||
content.WriteByte('\n')
|
||||
// Write exactly the role name, then grab the segment and color it.
|
||||
start, end := writestringbuf(&content, role.name)
|
||||
segmentadd(&segment, NewColoredSegment(start, end, role.color))
|
||||
start, end := writestringbuf(&content, "@"+r.Name)
|
||||
segmentadd(&segment, NewColoredSegment(start, end, r.Color.Uint32()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue