This repository has been archived on 2022-10-02. You can view files and clone it, but cannot push or open issues or pull requests.
dcbot-old/discord/embed.go

317 lines
5.7 KiB
Go

package discord
import (
"strconv"
"sync"
"github.com/bwmarrin/discordgo"
)
const (
EmbedColor = 0x00ff00
EmbedLimitTitle = 256
EmbedLimitDescription = 2048
EmbedLimitFieldValue = 1024
EmbedLimitFieldName = 256
EmbedLimitField = 25
EmbedLimitFooter = 2048
EmbedSizeLimit = 4500
)
type Embed struct {
*discordgo.MessageEmbed
}
//NewEmbed returns a new embed object
func NewEmbed() *Embed {
return &Embed{&discordgo.MessageEmbed{
Color: EmbedColor,
}}
}
func (e *Embed) SetTitle(name string) *Embed {
e.Title = name
return e
}
func (e *Embed) SetTimestamp(timestamp string) *Embed {
e.Timestamp = timestamp
return e
}
func (e *Embed) SetDescription(description string) *Embed {
if len(description) > EmbedLimitDescription {
description = description[:EmbedLimitDescription]
}
e.Description = description
return e
}
func (e *Embed) AddField(name, value string) *Embed {
if len(value) > EmbedLimitFieldValue {
value = value[:EmbedLimitFieldValue]
}
if len(name) > EmbedLimitFieldName {
name = name[:EmbedLimitFieldName]
}
e.Fields = append(e.Fields, &discordgo.MessageEmbedField{
Name: name,
Value: value,
})
return e
}
func (e *Embed) SetFields(fields []*discordgo.MessageEmbedField) *Embed {
e.Fields = fields
return e
}
func (e *Embed) SetFooter(args ...string) *Embed {
iconURL := ""
text := ""
proxyURL := ""
switch {
case len(args) > 2:
proxyURL = args[2]
fallthrough
case len(args) > 1:
iconURL = args[1]
fallthrough
case len(args) > 0:
text = args[0]
case len(args) == 0:
return e
}
e.Footer = &discordgo.MessageEmbedFooter{
IconURL: iconURL,
Text: text,
ProxyIconURL: proxyURL,
}
return e
}
func (e *Embed) SetImage(args ...string) *Embed {
var URL string
var proxyURL string
if len(args) == 0 {
return e
}
if len(args) > 0 {
URL = args[0]
}
if len(args) > 1 {
proxyURL = args[1]
}
e.Image = &discordgo.MessageEmbedImage{
URL: URL,
ProxyURL: proxyURL,
}
return e
}
func (e *Embed) SetThumbnail(args ...string) *Embed {
var URL string
var proxyURL string
if len(args) == 0 {
return e
}
if len(args) > 0 {
URL = args[0]
}
if len(args) > 1 {
proxyURL = args[1]
}
e.Thumbnail = &discordgo.MessageEmbedThumbnail{
URL: URL,
ProxyURL: proxyURL,
}
return e
}
func (e *Embed) SetAuthor(args ...string) *Embed {
var (
name string
iconURL string
URL string
proxyURL string
)
if len(args) == 0 {
return e
}
if len(args) > 0 {
name = args[0]
}
if len(args) > 1 {
iconURL = args[1]
}
if len(args) > 2 {
URL = args[2]
}
if len(args) > 3 {
proxyURL = args[3]
}
e.Author = &discordgo.MessageEmbedAuthor{
Name: name,
IconURL: iconURL,
URL: URL,
ProxyIconURL: proxyURL,
}
return e
}
func (e *Embed) SetURL(URL string) *Embed {
e.URL = URL
return e
}
func (e *Embed) SetColor(clr int) *Embed {
e.Color = clr
return e
}
func (e *Embed) InlineAllFields() *Embed {
for _, v := range e.Fields {
v.Inline = true
}
return e
}
func (e *Embed) Truncate() *Embed {
e.TruncateDescription()
e.TruncateFields()
e.TruncateFooter()
e.TruncateTitle()
return e
}
func (e *Embed) TruncateFields() *Embed {
if len(e.Fields) > 25 {
e.Fields = e.Fields[:EmbedLimitField]
}
for _, v := range e.Fields {
if len(v.Name) > EmbedLimitFieldName {
v.Name = v.Name[:EmbedLimitFieldName]
}
if len(v.Value) > EmbedLimitFieldValue {
v.Value = v.Value[:EmbedLimitFieldValue]
}
}
return e
}
func (e *Embed) TruncateDescription() *Embed {
if len(e.Description) > EmbedLimitDescription {
e.Description = e.Description[:EmbedLimitDescription]
}
return e
}
func (e *Embed) TruncateTitle() *Embed {
if len(e.Title) > EmbedLimitTitle {
e.Title = e.Title[:EmbedLimitTitle]
}
return e
}
func (e *Embed) TruncateFooter() *Embed {
if e.Footer != nil && len(e.Footer.Text) > EmbedLimitFooter {
e.Footer.Text = e.Footer.Text[:EmbedLimitFooter]
}
return e
}
type MessageEmbedFieldBuilder struct {
chunks []string
index int
name string
mutex sync.Mutex
}
func (b *MessageEmbedFieldBuilder) SetName(name string) {
b.mutex.Lock()
defer b.mutex.Unlock()
b.name = name
}
func (b *MessageEmbedFieldBuilder) IsEmpty() bool {
return len(b.chunks) == 0
}
func (b *MessageEmbedFieldBuilder) Append(m string) {
b.mutex.Lock()
defer b.mutex.Unlock()
for len(b.chunks) < b.index+1 {
b.chunks = append(b.chunks, "")
}
if len(m)+len(b.chunks[b.index]) > EmbedLimitFieldValue {
b.chunks = append(b.chunks, m)
b.index++
return
}
b.chunks[b.index] += m
}
func (b *MessageEmbedFieldBuilder) ToMessageEmbedFields() []*discordgo.MessageEmbedField {
b.mutex.Lock()
defer b.mutex.Unlock()
var fields []*discordgo.MessageEmbedField
name := b.name
if name == "" {
name = "Field"
}
for i, chunk := range b.chunks {
fields = append(fields, &discordgo.MessageEmbedField{
Name: name + " " + strconv.Itoa(i+1),
Value: chunk,
})
}
return fields
}
func splitEmbedFields(e *Embed) [][]*discordgo.MessageEmbedField {
fields := e.Fields
baseNumberOfCharacters := len(e.Description) + len(e.Title)
if e.Author != nil {
baseNumberOfCharacters += len(e.Author.Name)
}
if e.Footer != nil {
baseNumberOfCharacters += len(e.Footer.Text)
}
var splitFields [][]*discordgo.MessageEmbedField
characters := baseNumberOfCharacters
fromIndex := 0
fieldsLen := len(fields)
for index, field := range fields {
fNameLen := len(field.Name)
fValLen := len(field.Value)
if characters+fNameLen+fValLen > EmbedSizeLimit || index == fieldsLen-1 {
splitFields = append(splitFields, fields[fromIndex:index+1])
fromIndex = index + 1
characters = baseNumberOfCharacters
}
characters += fNameLen
characters += fValLen
}
return splitFields
}