Merge branch 'feature/pagination-embed' into develop
This commit is contained in:
commit
53fb345e36
9 changed files with 304 additions and 22 deletions
|
@ -119,7 +119,7 @@ func deleteLearnedDataRun(c *Command, s *discordgo.Session, m any, args *[]strin
|
||||||
options = append(options, discordgo.SelectMenuOption{
|
options = append(options, discordgo.SelectMenuOption{
|
||||||
Label: fmt.Sprintf("%d번 지식", i+1),
|
Label: fmt.Sprintf("%d번 지식", i+1),
|
||||||
Description: data.Result,
|
Description: data.Result,
|
||||||
Value: fmt.Sprintf("%s%s&No.%d", utils.DeleteLearnedData, data.Id.Hex(), i+1),
|
Value: utils.MakeDeleteLearnedData(data.Id.Hex(), i+1),
|
||||||
})
|
})
|
||||||
description += fmt.Sprintf("%d. %s\n", i+1, data.Result)
|
description += fmt.Sprintf("%d. %s\n", i+1, data.Result)
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ func deleteLearnedDataRun(c *Command, s *discordgo.Session, m any, args *[]strin
|
||||||
Components: []discordgo.MessageComponent{
|
Components: []discordgo.MessageComponent{
|
||||||
discordgo.SelectMenu{
|
discordgo.SelectMenu{
|
||||||
MenuType: discordgo.StringSelectMenu,
|
MenuType: discordgo.StringSelectMenu,
|
||||||
CustomID: utils.DeleteLearnedDataUserId + userId,
|
CustomID: utils.MakeDeleteLearnedDataUserId(userId),
|
||||||
Options: options,
|
Options: options,
|
||||||
Placeholder: "ㅈ지울 응답을 선택해주세요.",
|
Placeholder: "ㅈ지울 응답을 선택해주세요.",
|
||||||
},
|
},
|
||||||
|
@ -144,7 +144,7 @@ func deleteLearnedDataRun(c *Command, s *discordgo.Session, m any, args *[]strin
|
||||||
discordgo.ActionsRow{
|
discordgo.ActionsRow{
|
||||||
Components: []discordgo.MessageComponent{
|
Components: []discordgo.MessageComponent{
|
||||||
discordgo.Button{
|
discordgo.Button{
|
||||||
CustomID: utils.DeleteLearnedDataCancel + userId,
|
CustomID: utils.MakeDeleteLearnedDataCancel(userId),
|
||||||
Label: "취소하기",
|
Label: "취소하기",
|
||||||
Style: discordgo.DangerButton,
|
Style: discordgo.DangerButton,
|
||||||
Disabled: false,
|
Disabled: false,
|
||||||
|
|
|
@ -51,6 +51,9 @@ var LearnedDataListCommand *Command = &Command{
|
||||||
|
|
||||||
func getDescriptions(data *[]databases.Learn) (descriptions []string) {
|
func getDescriptions(data *[]databases.Learn) (descriptions []string) {
|
||||||
MAX_LENGTH := 100
|
MAX_LENGTH := 100
|
||||||
|
MAX_ITEM_LENGTH := 25
|
||||||
|
|
||||||
|
tempDesc := []string{}
|
||||||
|
|
||||||
for _, data := range *data {
|
for _, data := range *data {
|
||||||
command := data.Command
|
command := data.Command
|
||||||
|
@ -64,7 +67,22 @@ func getDescriptions(data *[]databases.Learn) (descriptions []string) {
|
||||||
result = string(runeResult[:MAX_LENGTH]) + "..."
|
result = string(runeResult[:MAX_LENGTH]) + "..."
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptions = append(descriptions, fmt.Sprintf("- %s: %s", command, result))
|
tempDesc = append(tempDesc, fmt.Sprintf("- %s: %s\n", command, result))
|
||||||
|
}
|
||||||
|
|
||||||
|
var builder strings.Builder
|
||||||
|
|
||||||
|
for i, s := range tempDesc {
|
||||||
|
builder.WriteString(s)
|
||||||
|
|
||||||
|
if (i+1)%MAX_ITEM_LENGTH == 0 {
|
||||||
|
descriptions = append(descriptions, builder.String())
|
||||||
|
builder.Reset()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if builder.Len() > 0 {
|
||||||
|
descriptions = append(descriptions, builder.String())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -171,20 +189,12 @@ func learnedDataListRun(s *discordgo.Session, m any, args *[]string) {
|
||||||
cur.All(context.TODO(), &data)
|
cur.All(context.TODO(), &data)
|
||||||
|
|
||||||
embed := &discordgo.MessageEmbed{
|
embed := &discordgo.MessageEmbed{
|
||||||
Title: fmt.Sprintf("%s님이 알려주신 지식", globalName),
|
Title: fmt.Sprintf("%s님이 알려주신 지식", globalName),
|
||||||
Description: utils.CodeBlock("md", fmt.Sprintf("# 총 %d개에요.\n%s", len(data), strings.Join(getDescriptions(&data), "\n"))),
|
Color: utils.EmbedDefault,
|
||||||
Color: utils.EmbedDefault,
|
|
||||||
Thumbnail: &discordgo.MessageEmbedThumbnail{
|
Thumbnail: &discordgo.MessageEmbedThumbnail{
|
||||||
URL: avatarUrl,
|
URL: avatarUrl,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
switch m := m.(type) {
|
utils.StartPaginationEmbed(s, m, embed, getDescriptions(&data), utils.CodeBlock("md", fmt.Sprintf("# 총 %d개에요.\n", len(data))+"%s"))
|
||||||
case *discordgo.MessageCreate:
|
|
||||||
s.ChannelMessageSendEmbedReply(m.ChannelID, embed, m.Reference())
|
|
||||||
case *utils.InteractionCreate:
|
|
||||||
m.EditReply(&discordgo.WebhookEdit{
|
|
||||||
Embeds: &[]*discordgo.MessageEmbed{embed},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ var DeleteLearnedDataComponent *commands.Component = &commands.Component{
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
userId = customId[len(utils.DeleteLearnedDataCancel):]
|
userId = utils.GetDeleteLearnedDataUserId(customId)
|
||||||
if i.Member.User.ID == userId {
|
if i.Member.User.ID == userId {
|
||||||
i.Update(&discordgo.InteractionResponseData{
|
i.Update(&discordgo.InteractionResponseData{
|
||||||
Embeds: []*discordgo.MessageEmbed{
|
Embeds: []*discordgo.MessageEmbed{
|
||||||
|
@ -41,7 +41,7 @@ var DeleteLearnedDataComponent *commands.Component = &commands.Component{
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
userId = customId[len(utils.DeleteLearnedDataUserId):]
|
userId = utils.GetDeleteLearnedDataUserId(customId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if i.Member.User.ID != userId {
|
if i.Member.User.ID != userId {
|
||||||
|
@ -66,8 +66,7 @@ var DeleteLearnedDataComponent *commands.Component = &commands.Component{
|
||||||
|
|
||||||
i.DeferUpdate()
|
i.DeferUpdate()
|
||||||
|
|
||||||
id, _ := bson.ObjectIDFromHex(strings.ReplaceAll(utils.ItemIdRegexp.ReplaceAllString(i.MessageComponentData().Values[0][len(utils.DeleteLearnedData):], ""), "&", ""))
|
id, itemId := utils.GetDeleteLearnedDataId(i.MessageComponentData().Values[0])
|
||||||
itemId := strings.ReplaceAll(utils.ItemIdRegexp.FindAllString(i.MessageComponentData().Values[0], 1)[0], "No.", "")
|
|
||||||
|
|
||||||
databases.Database.Learns.DeleteOne(context.TODO(), bson.D{{Key: "_id", Value: id}})
|
databases.Database.Learns.DeleteOne(context.TODO(), bson.D{{Key: "_id", Value: id}})
|
||||||
|
|
||||||
|
@ -75,7 +74,7 @@ var DeleteLearnedDataComponent *commands.Component = &commands.Component{
|
||||||
Embeds: &[]*discordgo.MessageEmbed{
|
Embeds: &[]*discordgo.MessageEmbed{
|
||||||
{
|
{
|
||||||
Title: "✅ 삭제 완료",
|
Title: "✅ 삭제 완료",
|
||||||
Description: fmt.Sprintf("%s번을 삭ㅈ제했어요.", itemId),
|
Description: fmt.Sprintf("%d번을 삭ㅈ제했어요.", itemId),
|
||||||
Color: utils.EmbedSuccess,
|
Color: utils.EmbedSuccess,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
48
components/paginationEmbed.go
Normal file
48
components/paginationEmbed.go
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package components
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.wh64.net/muffin/goMuffin/commands"
|
||||||
|
"git.wh64.net/muffin/goMuffin/utils"
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
|
)
|
||||||
|
|
||||||
|
var PaginationEmbedComponent *commands.Component = &commands.Component{
|
||||||
|
Parse: func(ctx *commands.ComponentContext) bool {
|
||||||
|
i := ctx.Inter
|
||||||
|
|
||||||
|
if i.MessageComponentData().ComponentType == discordgo.ButtonComponent {
|
||||||
|
customId := i.MessageComponentData().CustomID
|
||||||
|
|
||||||
|
if !strings.HasPrefix(customId, utils.PaginationEmbedPrev) && !strings.HasPrefix(customId, utils.PaginationEmbedNext) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
id := utils.GetPaginationEmbedId(customId)
|
||||||
|
userId := utils.GetPaginationEmbedUserId(id)
|
||||||
|
|
||||||
|
if i.Member.User.ID != userId {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if utils.GetPaginationEmbed(id) == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
Run: func(ctx *commands.ComponentContext) {
|
||||||
|
customId := ctx.Inter.MessageComponentData().CustomID
|
||||||
|
id := utils.GetPaginationEmbedId(customId)
|
||||||
|
p := utils.GetPaginationEmbed(id)
|
||||||
|
|
||||||
|
if strings.HasPrefix(customId, utils.PaginationEmbedPrev) {
|
||||||
|
p.Prev(ctx.Inter)
|
||||||
|
} else {
|
||||||
|
p.Next(ctx.Inter)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"git.wh64.net/muffin/goMuffin/utils"
|
"git.wh64.net/muffin/goMuffin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
const MUFFIN_VERSION = "5.1.0-gopher_dev.250512a"
|
const MUFFIN_VERSION = "5.1.0-gopher_dev.250513b-paginated_embed"
|
||||||
|
|
||||||
var updatedString string = utils.Decimals.FindAllStringSubmatch(MUFFIN_VERSION, -1)[3][0]
|
var updatedString string = utils.Decimals.FindAllStringSubmatch(MUFFIN_VERSION, -1)[3][0]
|
||||||
|
|
||||||
|
|
1
main.go
1
main.go
|
@ -75,6 +75,7 @@ func main() {
|
||||||
go commands.Discommand.LoadCommand(commands.DeleteLearnedDataCommand)
|
go commands.Discommand.LoadCommand(commands.DeleteLearnedDataCommand)
|
||||||
|
|
||||||
go commands.Discommand.LoadComponent(components.DeleteLearnedDataComponent)
|
go commands.Discommand.LoadComponent(components.DeleteLearnedDataComponent)
|
||||||
|
go commands.Discommand.LoadComponent(components.PaginationEmbedComponent)
|
||||||
|
|
||||||
go dg.AddHandler(handler.MessageCreate)
|
go dg.AddHandler(handler.MessageCreate)
|
||||||
go dg.AddHandler(handler.InteractionCreate)
|
go dg.AddHandler(handler.InteractionCreate)
|
||||||
|
|
|
@ -1,7 +1,72 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"go.mongodb.org/mongo-driver/v2/bson"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DeleteLearnedData = "#muffin/deleteLearnedData$"
|
DeleteLearnedData = "#muffin/deleteLearnedData@"
|
||||||
DeleteLearnedDataUserId = "#muffin/deleteLearnedData@"
|
DeleteLearnedDataUserId = "#muffin/deleteLearnedData@"
|
||||||
DeleteLearnedDataCancel = "#muffin/deleteLearnedData/cancel@"
|
DeleteLearnedDataCancel = "#muffin/deleteLearnedData/cancel@"
|
||||||
|
|
||||||
|
PaginationEmbedPrev = "#muffin-pages/prev$"
|
||||||
|
PaginationEmbedPages = "#muffin-pages/pages$"
|
||||||
|
PaginationEmbedNext = "#muffin-pages/next$"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func MakeDeleteLearnedData(id string, number int) string {
|
||||||
|
return fmt.Sprintf("%s%s&No.%d", DeleteLearnedData, id, number)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeDeleteLearnedDataUserId(userId string) string {
|
||||||
|
return fmt.Sprintf("%s%s", DeleteLearnedDataUserId, userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeDeleteLearnedDataCancel(id string) string {
|
||||||
|
return fmt.Sprintf("%s%s", DeleteLearnedDataCancel, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDeleteLearnedDataId(customId string) (id bson.ObjectID, itemId int) {
|
||||||
|
id, _ = bson.ObjectIDFromHex(strings.ReplaceAll(ItemIdRegexp.ReplaceAllString(customId[len(DeleteLearnedData):], ""), "&", ""))
|
||||||
|
stringItemId := strings.ReplaceAll(ItemIdRegexp.FindAllString(customId, 1)[0], "No.", "")
|
||||||
|
itemId, _ = strconv.Atoi(stringItemId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDeleteLearnedDataUserId(customId string) string {
|
||||||
|
if strings.HasPrefix(customId, DeleteLearnedDataCancel) {
|
||||||
|
return customId[len(DeleteLearnedDataCancel):]
|
||||||
|
} else {
|
||||||
|
return customId[len(DeleteLearnedDataUserId):]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakePaginationEmbedPrev(id string) string {
|
||||||
|
return fmt.Sprintf("%s%s", PaginationEmbedPrev, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakePaginationEmbedPages(id string, total, current int) string {
|
||||||
|
return fmt.Sprintf("%s%s/%d/%d", PaginationEmbedPages, id, total, current)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakePaginationEmbedNext(id string) string {
|
||||||
|
return fmt.Sprintf("%s%s", PaginationEmbedNext, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPaginationEmbedId(customId string) string {
|
||||||
|
if strings.HasPrefix(customId, PaginationEmbedPrev) {
|
||||||
|
return customId[len(PaginationEmbedPrev):]
|
||||||
|
} else if strings.HasPrefix(customId, PaginationEmbedPages) {
|
||||||
|
return customId[len(PaginationEmbedPages):]
|
||||||
|
} else {
|
||||||
|
return customId[len(PaginationEmbedNext):]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPaginationEmbedUserId(id string) string {
|
||||||
|
return PaginationEmbedId.FindAllStringSubmatch(id, 1)[0][1]
|
||||||
|
}
|
||||||
|
|
158
utils/paginationEmbed.go
Normal file
158
utils/paginationEmbed.go
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PaginationEmbed is embed with page
|
||||||
|
type PaginationEmbed struct {
|
||||||
|
Embed *discordgo.MessageEmbed
|
||||||
|
Data []string
|
||||||
|
Current int
|
||||||
|
Total int
|
||||||
|
id string
|
||||||
|
s *discordgo.Session
|
||||||
|
desc string
|
||||||
|
}
|
||||||
|
|
||||||
|
var PaginationEmbeds = make(map[string]*PaginationEmbed)
|
||||||
|
|
||||||
|
func makeComponents(id string, current, total int) *[]discordgo.MessageComponent {
|
||||||
|
|
||||||
|
return &[]discordgo.MessageComponent{
|
||||||
|
discordgo.ActionsRow{
|
||||||
|
Components: []discordgo.MessageComponent{
|
||||||
|
discordgo.Button{
|
||||||
|
Style: discordgo.PrimaryButton,
|
||||||
|
Label: "이전",
|
||||||
|
CustomID: MakePaginationEmbedPrev(id),
|
||||||
|
Disabled: false,
|
||||||
|
},
|
||||||
|
discordgo.Button{
|
||||||
|
Style: discordgo.SecondaryButton,
|
||||||
|
Label: fmt.Sprintf("(%d/%d)", current, total),
|
||||||
|
CustomID: MakePaginationEmbedPages(id, current, total),
|
||||||
|
Disabled: true,
|
||||||
|
},
|
||||||
|
discordgo.Button{
|
||||||
|
Style: discordgo.PrimaryButton,
|
||||||
|
Label: "다음",
|
||||||
|
CustomID: MakePaginationEmbedNext(id),
|
||||||
|
Disabled: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeDesc(desc, item string) string {
|
||||||
|
var newDesc string
|
||||||
|
|
||||||
|
if desc == "" {
|
||||||
|
newDesc = item
|
||||||
|
} else {
|
||||||
|
newDesc = fmt.Sprintf(desc, item)
|
||||||
|
}
|
||||||
|
return newDesc
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartPaginationEmbed starts new PaginationEmbed struct
|
||||||
|
func StartPaginationEmbed(s *discordgo.Session, m any, e *discordgo.MessageEmbed, data []string, defaultDesc string) {
|
||||||
|
var userId string
|
||||||
|
|
||||||
|
switch m := m.(type) {
|
||||||
|
case *discordgo.MessageCreate:
|
||||||
|
userId = m.Author.ID
|
||||||
|
case *InteractionCreate:
|
||||||
|
userId = m.Member.User.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
id := fmt.Sprintf("%s/%d", userId, rand.Intn(12))
|
||||||
|
p := &PaginationEmbed{
|
||||||
|
Embed: e,
|
||||||
|
Data: data,
|
||||||
|
Current: 1,
|
||||||
|
Total: len(data),
|
||||||
|
id: id,
|
||||||
|
s: s,
|
||||||
|
desc: defaultDesc,
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Embed.Description = makeDesc(p.desc, data[0])
|
||||||
|
|
||||||
|
switch m := m.(type) {
|
||||||
|
case *discordgo.MessageCreate:
|
||||||
|
s.ChannelMessageSendComplex(m.ChannelID, &discordgo.MessageSend{
|
||||||
|
Reference: m.Reference(),
|
||||||
|
Embeds: []*discordgo.MessageEmbed{p.Embed},
|
||||||
|
Components: *makeComponents(id, 1, len(data)),
|
||||||
|
})
|
||||||
|
case *InteractionCreate:
|
||||||
|
m.Reply(&discordgo.InteractionResponseData{
|
||||||
|
Embeds: []*discordgo.MessageEmbed{p.Embed},
|
||||||
|
Components: *makeComponents(id, 1, len(data)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
PaginationEmbeds[id] = p
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPaginationEmbed(id string) *PaginationEmbed {
|
||||||
|
if p, ok := PaginationEmbeds[id]; ok {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PaginationEmbed) Prev(i *InteractionCreate) {
|
||||||
|
if p.Current == 1 {
|
||||||
|
i.Reply(&discordgo.InteractionResponseData{
|
||||||
|
Embeds: []*discordgo.MessageEmbed{
|
||||||
|
{
|
||||||
|
Title: "❌ 오류",
|
||||||
|
Description: "해당 페이지가 처음ㅇ이에요.",
|
||||||
|
Color: EmbedFail,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Flags: discordgo.MessageFlagsEphemeral,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Current -= 1
|
||||||
|
|
||||||
|
p.Embed.Description = makeDesc(p.desc, p.Data[p.Current-1])
|
||||||
|
|
||||||
|
i.Update(&discordgo.InteractionResponseData{
|
||||||
|
Embeds: []*discordgo.MessageEmbed{p.Embed},
|
||||||
|
Components: *makeComponents(p.id, p.Current, p.Total),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PaginationEmbed) Next(i *InteractionCreate) {
|
||||||
|
if p.Current >= p.Total {
|
||||||
|
i.Reply(&discordgo.InteractionResponseData{
|
||||||
|
Embeds: []*discordgo.MessageEmbed{
|
||||||
|
{
|
||||||
|
Title: "❌ 오류",
|
||||||
|
Description: "해당 페이지가 마지막ㅇ이에요.",
|
||||||
|
Color: EmbedFail,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Flags: discordgo.MessageFlagsEphemeral,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Current += 1
|
||||||
|
|
||||||
|
p.Embed.Description = makeDesc(p.desc, p.Data[p.Current-1])
|
||||||
|
|
||||||
|
i.Update(&discordgo.InteractionResponseData{
|
||||||
|
Embeds: []*discordgo.MessageEmbed{p.Embed},
|
||||||
|
Components: *makeComponents(p.id, p.Current, p.Total),
|
||||||
|
})
|
||||||
|
}
|
|
@ -9,4 +9,5 @@ var (
|
||||||
EmojiRegexp = regexp.MustCompile(`<a?:\w+:\d+>`)
|
EmojiRegexp = regexp.MustCompile(`<a?:\w+:\d+>`)
|
||||||
LearnQueryCommand = regexp.MustCompile(`^단어:`)
|
LearnQueryCommand = regexp.MustCompile(`^단어:`)
|
||||||
LearnQueryResult = regexp.MustCompile(`^대답:`)
|
LearnQueryResult = regexp.MustCompile(`^대답:`)
|
||||||
|
PaginationEmbedId = regexp.MustCompile(`^(\d+)/(\d+)$`)
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue