1
0
Fork 0
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:
diamondburned 2020-07-11 23:37:36 -07:00
parent e50f72a01d
commit b8c92a56d8
5 changed files with 59 additions and 58 deletions

2
go.mod
View file

@ -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
View file

@ -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=

View file

@ -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'
}

View file

@ -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
}

View file

@ -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()))
}
}