206 lines
5.8 KiB
Go
206 lines
5.8 KiB
Go
package features
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/disgoorg/disgo/discord"
|
|
"github.com/disgoorg/disgo/events"
|
|
"github.com/disgoorg/snowflake/v2"
|
|
|
|
"github.com/elisiei/unbot/db"
|
|
)
|
|
|
|
type Dictionary struct {
|
|
db *db.DB
|
|
config DictionaryConfig
|
|
}
|
|
|
|
type DictionaryConfig struct {
|
|
Enabled bool
|
|
}
|
|
|
|
func NewDictionary(database *db.DB, enabled bool) *Dictionary {
|
|
return &Dictionary{db: database, config: DictionaryConfig{Enabled: enabled}}
|
|
}
|
|
|
|
func (d *Dictionary) Command() discord.SlashCommandCreate {
|
|
return discord.SlashCommandCreate{
|
|
Name: "dict",
|
|
Description: "Urban dictionary for the server",
|
|
Options: []discord.ApplicationCommandOption{
|
|
discord.ApplicationCommandOptionSubCommand{
|
|
Name: "add",
|
|
Description: "Add a definition",
|
|
Options: []discord.ApplicationCommandOption{
|
|
discord.ApplicationCommandOptionString{
|
|
Name: "word",
|
|
Description: "The word to define",
|
|
Required: true,
|
|
},
|
|
discord.ApplicationCommandOptionString{
|
|
Name: "definition",
|
|
Description: "The definition",
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
discord.ApplicationCommandOptionSubCommand{
|
|
Name: "get",
|
|
Description: "Get a definition",
|
|
Options: []discord.ApplicationCommandOption{
|
|
discord.ApplicationCommandOptionString{
|
|
Name: "word",
|
|
Description: "The word to look up",
|
|
Required: true,
|
|
Autocomplete: true,
|
|
},
|
|
},
|
|
},
|
|
discord.ApplicationCommandOptionSubCommand{
|
|
Name: "remove",
|
|
Description: "Remove your definition",
|
|
Options: []discord.ApplicationCommandOption{
|
|
discord.ApplicationCommandOptionString{
|
|
Name: "word",
|
|
Description: "The word to remove",
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
discord.ApplicationCommandOptionSubCommand{
|
|
Name: "list",
|
|
Description: "List all defined words",
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func (d *Dictionary) HandleAutocomplete(e *events.AutocompleteInteractionCreate) {
|
|
focused := e.Data.Focused()
|
|
input := strings.ToLower(focused.String())
|
|
allWords, err := d.db.ListWords()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var choices []discord.AutocompleteChoice
|
|
for _, w := range allWords {
|
|
if strings.HasPrefix(strings.ToLower(w.Word), input) {
|
|
if len(choices) >= 25 {
|
|
break
|
|
}
|
|
choices = append(choices, discord.AutocompleteChoiceString{
|
|
Name: w.Word,
|
|
Value: w.Word,
|
|
})
|
|
}
|
|
}
|
|
e.AutocompleteResult(choices)
|
|
}
|
|
|
|
func (d *Dictionary) HandleAdd(e *events.ApplicationCommandInteractionCreate) {
|
|
data := e.SlashCommandInteractionData()
|
|
word := strings.ToLower(strings.TrimSpace(data.String("word")))
|
|
definition := strings.TrimSpace(data.String("definition"))
|
|
|
|
if word == "" || definition == "" {
|
|
e.CreateMessage(discord.NewMessageCreate().WithContent("Word and definition cannot be empty.").WithEphemeral(true))
|
|
return
|
|
}
|
|
|
|
err := d.db.AddDefinition(word, definition, e.User().ID.String())
|
|
if err != nil {
|
|
e.CreateMessage(discord.NewMessageCreate().WithContent("Failed to save definition.").WithEphemeral(true))
|
|
return
|
|
}
|
|
|
|
e.CreateMessage(discord.NewMessageCreate().WithContent(fmt.Sprintf("Added definition for **%s**", word)))
|
|
}
|
|
|
|
func (d *Dictionary) HandleGet(e *events.ApplicationCommandInteractionCreate) {
|
|
data := e.SlashCommandInteractionData()
|
|
word := strings.ToLower(strings.TrimSpace(data.String("word")))
|
|
|
|
entry, err := d.db.GetDefinition(word)
|
|
if err != nil {
|
|
e.CreateMessage(discord.NewMessageCreate().WithContent("Failed to look up definition.").WithEphemeral(true))
|
|
return
|
|
}
|
|
if entry == nil {
|
|
e.CreateMessage(discord.NewMessageCreate().WithContent(fmt.Sprintf("No definition found for **%s**", word)).WithEphemeral(true))
|
|
return
|
|
}
|
|
|
|
var footerText string
|
|
authorID, parseErr := snowflake.Parse(entry.AuthorID)
|
|
if parseErr == nil && authorID != 0 {
|
|
footerText = "Added by <@" + authorID.String() + ">"
|
|
}
|
|
|
|
embed := discord.Embed{
|
|
Title: entry.Word,
|
|
Description: entry.Definition,
|
|
Color: 0x00AE86,
|
|
Fields: []discord.EmbedField{
|
|
{Name: "Rating", Value: fmt.Sprintf("👍 %d | 👎 %d", entry.Upvotes, entry.Downvotes), Inline: new(true)},
|
|
},
|
|
Footer: &discord.EmbedFooter{Text: footerText},
|
|
}
|
|
|
|
e.CreateMessage(discord.NewMessageCreate().AddEmbeds(embed))
|
|
}
|
|
|
|
func (d *Dictionary) HandleRemove(e *events.ApplicationCommandInteractionCreate) {
|
|
data := e.SlashCommandInteractionData()
|
|
word := strings.ToLower(strings.TrimSpace(data.String("word")))
|
|
|
|
entry, err := d.db.GetDefinition(word)
|
|
if err != nil {
|
|
e.CreateMessage(discord.NewMessageCreate().WithContent("Failed to look up definition.").WithEphemeral(true))
|
|
return
|
|
}
|
|
if entry == nil {
|
|
e.CreateMessage(discord.NewMessageCreate().WithContent(fmt.Sprintf("No definition found for **%s**", word)).WithEphemeral(true))
|
|
return
|
|
}
|
|
|
|
if entry.AuthorID != e.User().ID.String() {
|
|
e.CreateMessage(discord.NewMessageCreate().WithContent("You can only remove your own definitions.").WithEphemeral(true))
|
|
return
|
|
}
|
|
|
|
if err := d.db.RemoveDefinition(word); err != nil {
|
|
e.CreateMessage(discord.NewMessageCreate().WithContent("Failed to remove definition.").WithEphemeral(true))
|
|
return
|
|
}
|
|
|
|
e.CreateMessage(discord.NewMessageCreate().WithContent(fmt.Sprintf("Removed definition for **%s**", word)))
|
|
}
|
|
|
|
func (d *Dictionary) HandleList(e *events.ApplicationCommandInteractionCreate) {
|
|
words, err := d.db.ListWords()
|
|
if err != nil {
|
|
e.CreateMessage(discord.NewMessageCreate().WithContent("Failed to list words.").WithEphemeral(true))
|
|
return
|
|
}
|
|
|
|
if len(words) == 0 {
|
|
e.CreateMessage(discord.NewMessageCreate().WithContent("No words defined yet.").WithEphemeral(true))
|
|
return
|
|
}
|
|
|
|
var sb strings.Builder
|
|
for i, w := range words {
|
|
if i > 0 {
|
|
sb.WriteString(", ")
|
|
}
|
|
fmt.Fprintf(&sb, "**%s**", w.Word)
|
|
if i >= 50 {
|
|
sb.WriteString("...")
|
|
break
|
|
}
|
|
}
|
|
|
|
e.CreateMessage(discord.NewMessageCreate().WithContent(fmt.Sprintf("Defined words (%d): %s", len(words), sb.String())))
|
|
}
|