functional editing notes
This commit is contained in:
@@ -59,14 +59,14 @@ public class Main {
|
||||
jda.upsertCommand(Commands.slash("note", "Get a note")
|
||||
.setIntegrationTypes(IntegrationType.GUILD_INSTALL, IntegrationType.USER_INSTALL)
|
||||
.addOptions(
|
||||
new OptionData(OptionType.STRING, "note-id", "The ID of the note", true, true),
|
||||
new OptionData(OptionType.BOOLEAN, "ephermeal", "Whether the note should be ephermal", true)
|
||||
new OptionData(OptionType.STRING, "alias", "The ID of the note", true, true),
|
||||
new OptionData(OptionType.BOOLEAN, "ephermeal", "Whether the note should be ephermal", false)
|
||||
)
|
||||
.setContexts(InteractionContextType.BOT_DM, InteractionContextType.GUILD, InteractionContextType.PRIVATE_CHANNEL)
|
||||
).queue();
|
||||
|
||||
jda.upsertCommand(Commands.slash("add-note", "Add a note")
|
||||
.setIntegrationTypes(IntegrationType.GUILD_INSTALL, IntegrationType.USER_INSTALL)
|
||||
.setIntegrationTypes(IntegrationType.USER_INSTALL)
|
||||
.addOptions(
|
||||
new OptionData(OptionType.STRING, "alias", "An alias for the note")
|
||||
.setMinLength(1)
|
||||
@@ -80,6 +80,10 @@ public class Main {
|
||||
.setMinLength(1)
|
||||
.setMaxLength(4096)
|
||||
.setRequired(true),
|
||||
new OptionData(OptionType.STRING, "title-url", "The image URL of the note")
|
||||
.setMinLength(1)
|
||||
.setMaxLength(2000)
|
||||
.setRequired(false),
|
||||
new OptionData(OptionType.STRING, "image-url", "The image URL of the note")
|
||||
.setMinLength(1)
|
||||
.setMaxLength(2000)
|
||||
@@ -89,7 +93,7 @@ public class Main {
|
||||
.setMaxLength(2000)
|
||||
.setRequired(false),
|
||||
new OptionData(OptionType.STRING, "color", "The color of the note")
|
||||
.setMinLength(1)
|
||||
.setMinLength(7)
|
||||
.setMaxLength(7)
|
||||
.setRequired(false),
|
||||
new OptionData(OptionType.STRING, "author", "The author of the note")
|
||||
@@ -112,6 +116,56 @@ public class Main {
|
||||
.setContexts(InteractionContextType.BOT_DM)
|
||||
).queue();
|
||||
|
||||
jda.upsertCommand(Commands.slash("edit-note", "Edit a note")
|
||||
.setIntegrationTypes(IntegrationType.USER_INSTALL)
|
||||
.addOptions(
|
||||
new OptionData(OptionType.STRING, "alias", "An alias for the note")
|
||||
.setMinLength(1)
|
||||
.setMaxLength(256)
|
||||
.setRequired(true),
|
||||
new OptionData(OptionType.STRING, "title", "The title of the note")
|
||||
.setMinLength(1)
|
||||
.setMaxLength(256)
|
||||
.setRequired(false),
|
||||
new OptionData(OptionType.STRING, "content", "The content of the note")
|
||||
.setMinLength(1)
|
||||
.setMaxLength(4096)
|
||||
.setRequired(false),
|
||||
new OptionData(OptionType.STRING, "title-url", "The image URL of the note")
|
||||
.setMinLength(1)
|
||||
.setMaxLength(2000)
|
||||
.setRequired(false),
|
||||
new OptionData(OptionType.STRING, "image-url", "The image URL of the note")
|
||||
.setMinLength(1)
|
||||
.setMaxLength(2000)
|
||||
.setRequired(false),
|
||||
new OptionData(OptionType.STRING, "thumbnail-url", "The thumbnail URL of the note")
|
||||
.setMinLength(1)
|
||||
.setMaxLength(2000)
|
||||
.setRequired(false),
|
||||
new OptionData(OptionType.STRING, "color", "The color of the note")
|
||||
.setMinLength(7)
|
||||
.setMaxLength(7)
|
||||
.setRequired(false),
|
||||
new OptionData(OptionType.STRING, "author", "The author of the note")
|
||||
.setMinLength(1)
|
||||
.setMaxLength(256)
|
||||
.setRequired(false),
|
||||
new OptionData(OptionType.STRING, "author-url", "The author URL of the note")
|
||||
.setMinLength(1)
|
||||
.setMaxLength(2000)
|
||||
.setRequired(false),
|
||||
new OptionData(OptionType.STRING, "footer", "The footer of the note")
|
||||
.setMinLength(1)
|
||||
.setMaxLength(256)
|
||||
.setRequired(false),
|
||||
new OptionData(OptionType.STRING, "footer-url", "The footer URL of the note")
|
||||
.setMinLength(1)
|
||||
.setMaxLength(2000)
|
||||
.setRequired(false)
|
||||
)
|
||||
.setContexts(InteractionContextType.BOT_DM)
|
||||
).queue();
|
||||
}
|
||||
|
||||
private static void loadProperties() {
|
||||
|
||||
@@ -18,8 +18,6 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
|
||||
public class Storage {
|
||||
|
||||
public final List<String> aliases = new ArrayList<>();
|
||||
@@ -110,8 +108,7 @@ public class Storage {
|
||||
statement.executeUpdate();
|
||||
|
||||
statement = connection.prepareStatement("""
|
||||
INSERT INTO aliases (alias, note_id)
|
||||
VALUES (?, ?)
|
||||
INSERT INTO aliases (alias, note_id) VALUES (?, ?)
|
||||
""");
|
||||
statement.setString(1, alias);
|
||||
statement.setString(2, note.id.toString());
|
||||
@@ -128,6 +125,31 @@ public class Storage {
|
||||
}
|
||||
}
|
||||
|
||||
public Status editNote(UUID noteId, Note note) {
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
PreparedStatement statement = connection.prepareStatement("""
|
||||
UPDATE notes
|
||||
SET title = ?, title_url = ?, description = ?, image_url = ?, thumbnail_url = ?, color = ?, author = ?, author_url = ?, footer = ?, footer_url = ?
|
||||
WHERE id = ?
|
||||
""");
|
||||
statement.setString(1, note.title);
|
||||
statement.setString(2, note.titleUrl);
|
||||
statement.setString(3, note.content);
|
||||
statement.setString(4, note.imageUrl);
|
||||
statement.setString(5, note.thumbnailUrl);
|
||||
statement.setInt(6, note.color != null ? note.color.getRGB() : 0);
|
||||
statement.setString(7, note.author);
|
||||
statement.setString(8, note.authorUrl);
|
||||
statement.setString(9, note.footer);
|
||||
statement.setString(10, note.footerUrl);
|
||||
statement.setString(11, noteId.toString());
|
||||
statement.executeUpdate();
|
||||
return Status.SUCCESS;
|
||||
} catch (SQLException e) {
|
||||
return Status.ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
public Status addAlias(@NotNull String alias, @NotNull UUID noteId) throws RuntimeException {
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
PreparedStatement statement = connection.prepareStatement("""
|
||||
|
||||
@@ -6,39 +6,55 @@ import me.youhavetrouble.noted.note.Note;
|
||||
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import net.dv8tion.jda.api.interactions.InteractionType;
|
||||
import net.dv8tion.jda.api.interactions.commands.Command;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SlashCommandListener extends ListenerAdapter {
|
||||
|
||||
private final List<String> optionMappingIds = List.of(
|
||||
"title",
|
||||
"content",
|
||||
"title-url",
|
||||
"image-url",
|
||||
"thumbnail-url",
|
||||
"color",
|
||||
"author",
|
||||
"author-url",
|
||||
"footer",
|
||||
"footer-url"
|
||||
);
|
||||
|
||||
@Override
|
||||
public void onCommandAutoCompleteInteraction(CommandAutoCompleteInteractionEvent event) {
|
||||
if (event.getName().equals("note") && event.getFocusedOption().getName().equals("note-id")) {
|
||||
List<Command.Choice> options = Main.getStorage().aliases.stream()
|
||||
.filter(word -> word.startsWith(event.getFocusedOption().getValue()))
|
||||
.map(word -> new Command.Choice(word, word))
|
||||
.limit(25)
|
||||
.collect(Collectors.toList());
|
||||
event.replyChoices(options).queue();
|
||||
}
|
||||
if (!event.getName().equals("note") || event.getName().equals("edit-note")) return;
|
||||
if (!event.getFocusedOption().getName().equals("alias")) return;
|
||||
List<Command.Choice> options = Main.getStorage().aliases.stream()
|
||||
.filter(word -> word.startsWith(event.getFocusedOption().getValue()))
|
||||
.map(word -> new Command.Choice(word, word))
|
||||
.limit(25)
|
||||
.collect(Collectors.toList());
|
||||
event.replyChoices(options).queue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
|
||||
switch (event.getName()) {
|
||||
case "note" -> {
|
||||
OptionMapping noteIdOption = event.getOption("note-id");
|
||||
OptionMapping noteIdOption = event.getOption("alias");
|
||||
OptionMapping ephemeralOption = event.getOption("ephemeral");
|
||||
if (noteIdOption == null) {
|
||||
event.reply("Please provide a note ID.")
|
||||
event.reply("Please provide a note alias.")
|
||||
.setEphemeral(true)
|
||||
.queue();
|
||||
return;
|
||||
}
|
||||
boolean ephemeral;
|
||||
boolean ephemeral = false;
|
||||
try {
|
||||
ephemeral = ephemeralOption != null && ephemeralOption.getAsBoolean();
|
||||
} catch (IllegalArgumentException e) {
|
||||
@@ -58,20 +74,17 @@ public class SlashCommandListener extends ListenerAdapter {
|
||||
.queue();
|
||||
return;
|
||||
}
|
||||
|
||||
OptionMapping aliasOption = event.getOption("alias");
|
||||
OptionMapping titleOption = event.getOption("title");
|
||||
OptionMapping contentOption = event.getOption("content");
|
||||
if (titleOption == null || contentOption == null || aliasOption == null) {
|
||||
event.reply("Please provide a alias, title and content.")
|
||||
addNote(event);
|
||||
}
|
||||
case "edit-note" -> {
|
||||
Long adminId = Main.getAdminId();
|
||||
if (adminId == null || !adminId.equals(event.getUser().getIdLong())) {
|
||||
event.reply("You do not have permission to use this command.")
|
||||
.setEphemeral(true)
|
||||
.queue();
|
||||
return;
|
||||
}
|
||||
String alias = aliasOption.getAsString();
|
||||
String title = titleOption.getAsString();
|
||||
String content = contentOption.getAsString();
|
||||
addNote(event, alias, title, content);
|
||||
editNote(event);
|
||||
}
|
||||
|
||||
default -> event.reply("Unknown command.")
|
||||
@@ -94,26 +107,189 @@ public class SlashCommandListener extends ListenerAdapter {
|
||||
.queue();
|
||||
}
|
||||
|
||||
private void addNote(SlashCommandInteractionEvent event, String noteAlias, String title, String description) {
|
||||
Note note = Note.createNew(title, description);
|
||||
Storage.Status status = Main.getStorage().addNote(note, noteAlias);
|
||||
private void addNote(SlashCommandInteractionEvent event) {
|
||||
OptionMapping aliasOption = event.getOption("alias");
|
||||
OptionMapping titleOption = event.getOption("title");
|
||||
OptionMapping contentOption = event.getOption("content");
|
||||
|
||||
if (status == Storage.Status.ALIAS_EXISTS) {
|
||||
if (titleOption == null || contentOption == null || aliasOption == null) {
|
||||
event.reply("Please provide a alias, title and content.")
|
||||
.setEphemeral(true)
|
||||
.queue();
|
||||
return;
|
||||
}
|
||||
|
||||
Note note = Note.createNew(titleOption.getAsString(), contentOption.getAsString());
|
||||
|
||||
OptionMapping titleUrlOption = event.getOption("title-url");
|
||||
if (titleUrlOption != null) {
|
||||
note = note.withTitleUrl(titleUrlOption.getAsString());
|
||||
}
|
||||
|
||||
OptionMapping imageUrlOption = event.getOption("image-url");
|
||||
if (imageUrlOption != null) {
|
||||
note = note.withImageUrl(imageUrlOption.getAsString());
|
||||
}
|
||||
|
||||
OptionMapping thumbnailUrlOption = event.getOption("thumbnail-url");
|
||||
if (thumbnailUrlOption != null) {
|
||||
note = note.withThumbnailUrl(thumbnailUrlOption.getAsString());
|
||||
}
|
||||
|
||||
OptionMapping colorOption = event.getOption("color");
|
||||
if (colorOption != null) {
|
||||
try {
|
||||
note = note.withColor(Color.decode(colorOption.getAsString()));
|
||||
} catch (NumberFormatException e) {
|
||||
event.reply("Invalid color.")
|
||||
.setEphemeral(true)
|
||||
.queue();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
OptionMapping authorOption = event.getOption("author");
|
||||
if (authorOption != null) {
|
||||
note = note.withAuthor(authorOption.getAsString());
|
||||
}
|
||||
|
||||
OptionMapping authorUrlOption = event.getOption("author-url");
|
||||
if (authorUrlOption != null) {
|
||||
note = note.withAuthorUrl(authorUrlOption.getAsString());
|
||||
}
|
||||
|
||||
OptionMapping footerOption = event.getOption("footer");
|
||||
if (footerOption != null) {
|
||||
note = note.withFooter(footerOption.getAsString());
|
||||
}
|
||||
|
||||
OptionMapping footerUrlOption = event.getOption("footer-url");
|
||||
if (footerUrlOption != null) {
|
||||
note = note.withFooterUrl(footerUrlOption.getAsString());
|
||||
}
|
||||
|
||||
Storage.Status status = Main.getStorage().addNote(note, aliasOption.getAsString());
|
||||
|
||||
if (status == Storage.Status.SUCCESS) {
|
||||
event.reply("Note added.")
|
||||
.setEphemeral(true)
|
||||
.queue();
|
||||
} else if (status == Storage.Status.ALIAS_EXISTS) {
|
||||
event.reply("Alias already exists.")
|
||||
.setEphemeral(true)
|
||||
.queue();
|
||||
} else {
|
||||
event.reply("Failed to add note.")
|
||||
.setEphemeral(true)
|
||||
.queue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void editNote(SlashCommandInteractionEvent event) {
|
||||
OptionMapping noteAliasMapping = event.getOption("alias");
|
||||
if (noteAliasMapping == null) {
|
||||
event.reply("Please provide a note alias.")
|
||||
.setEphemeral(true)
|
||||
.queue();
|
||||
return;
|
||||
}
|
||||
if (status == Storage.Status.ERROR) {
|
||||
event.reply("An error occurred.")
|
||||
String noteAlias = noteAliasMapping.getAsString();
|
||||
|
||||
Note note = Main.getStorage().getNote(noteAlias);
|
||||
if (note == null) {
|
||||
event.reply("Note with alias %s not found.".formatted(noteAlias))
|
||||
.setEphemeral(true)
|
||||
.queue();
|
||||
return;
|
||||
}
|
||||
|
||||
event.reply("Note added.")
|
||||
.setEphemeral(true)
|
||||
.queue();
|
||||
boolean shouldOpenModal = true;
|
||||
|
||||
for (String optionMappingId : optionMappingIds) {
|
||||
if (event.getOption(optionMappingId) != null) {
|
||||
shouldOpenModal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldOpenModal) {
|
||||
// TODO open modal with few basic fields
|
||||
event.reply("Here a modal should open. After I make it.")
|
||||
.setEphemeral(true)
|
||||
.queue();
|
||||
return;
|
||||
}
|
||||
|
||||
OptionMapping titleOption = event.getOption("title");
|
||||
if (titleOption != null) {
|
||||
note = note.withTitle(titleOption.getAsString());
|
||||
}
|
||||
|
||||
OptionMapping titleUrlOption = event.getOption("title-url");
|
||||
if (titleUrlOption != null) {
|
||||
note = note.withTitleUrl(titleUrlOption.getAsString());
|
||||
}
|
||||
|
||||
OptionMapping contentOption = event.getOption("content");
|
||||
if (contentOption != null) {
|
||||
note = note.withContent(contentOption.getAsString());
|
||||
}
|
||||
|
||||
OptionMapping imageUrlOption = event.getOption("image-url");
|
||||
if (imageUrlOption != null) {
|
||||
note = note.withImageUrl(imageUrlOption.getAsString());
|
||||
}
|
||||
|
||||
OptionMapping thumbnailUrlOption = event.getOption("thumbnail-url");
|
||||
if (thumbnailUrlOption != null) {
|
||||
note = note.withThumbnailUrl(thumbnailUrlOption.getAsString());
|
||||
}
|
||||
|
||||
OptionMapping colorOption = event.getOption("color");
|
||||
if (colorOption != null) {
|
||||
try {
|
||||
note = note.withColor(Color.decode(colorOption.getAsString()));
|
||||
} catch (NumberFormatException e) {
|
||||
event.reply("Invalid color.")
|
||||
.setEphemeral(true)
|
||||
.queue();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
OptionMapping authorOption = event.getOption("author");
|
||||
if (authorOption != null) {
|
||||
note = note.withAuthor(authorOption.getAsString());
|
||||
}
|
||||
|
||||
OptionMapping authorUrlOption = event.getOption("author-url");
|
||||
if (authorUrlOption != null) {
|
||||
note = note.withAuthorUrl(authorUrlOption.getAsString());
|
||||
}
|
||||
|
||||
OptionMapping footerOption = event.getOption("footer");
|
||||
if (footerOption != null) {
|
||||
note = note.withFooter(footerOption.getAsString());
|
||||
}
|
||||
|
||||
OptionMapping footerUrlOption = event.getOption("footer-url");
|
||||
if (footerUrlOption != null) {
|
||||
note = note.withFooterUrl(footerUrlOption.getAsString());
|
||||
}
|
||||
|
||||
Storage.Status status = Main.getStorage().editNote(note.id, note);
|
||||
|
||||
if (status == Storage.Status.SUCCESS) {
|
||||
event.reply("Note edited.")
|
||||
.setEphemeral(true)
|
||||
.queue();
|
||||
} else {
|
||||
event.reply("Failed to edit note.")
|
||||
.setEphemeral(true)
|
||||
.queue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,6 +48,165 @@ public class Note {
|
||||
this.footerUrl = footerUrl;
|
||||
}
|
||||
|
||||
public Note withTitle(@NotNull String title) {
|
||||
return new Note(
|
||||
id,
|
||||
title,
|
||||
titleUrl,
|
||||
content,
|
||||
imageUrl,
|
||||
thumbnailUrl,
|
||||
color,
|
||||
author,
|
||||
authorUrl,
|
||||
footer,
|
||||
footerUrl
|
||||
);
|
||||
}
|
||||
|
||||
public Note withTitleUrl(@Nullable String titleUrl) {
|
||||
return new Note(
|
||||
id,
|
||||
title,
|
||||
titleUrl,
|
||||
content,
|
||||
imageUrl,
|
||||
thumbnailUrl,
|
||||
color,
|
||||
author,
|
||||
authorUrl,
|
||||
footer,
|
||||
footerUrl
|
||||
);
|
||||
}
|
||||
|
||||
public Note withContent(@NotNull String content) {
|
||||
return new Note(
|
||||
id,
|
||||
title,
|
||||
titleUrl,
|
||||
content,
|
||||
imageUrl,
|
||||
thumbnailUrl,
|
||||
color,
|
||||
author,
|
||||
authorUrl,
|
||||
footer,
|
||||
footerUrl
|
||||
);
|
||||
}
|
||||
|
||||
public Note withImageUrl(@Nullable String imageUrl) {
|
||||
return new Note(
|
||||
id,
|
||||
title,
|
||||
titleUrl,
|
||||
content,
|
||||
imageUrl,
|
||||
thumbnailUrl,
|
||||
color,
|
||||
author,
|
||||
authorUrl,
|
||||
footer,
|
||||
footerUrl
|
||||
);
|
||||
}
|
||||
|
||||
public Note withThumbnailUrl(@Nullable String thumbnailUrl) {
|
||||
return new Note(
|
||||
id,
|
||||
title,
|
||||
titleUrl,
|
||||
content,
|
||||
imageUrl,
|
||||
thumbnailUrl,
|
||||
color,
|
||||
author,
|
||||
authorUrl,
|
||||
footer,
|
||||
footerUrl
|
||||
);
|
||||
}
|
||||
|
||||
public Note withColor(@Nullable Color color) {
|
||||
return new Note(
|
||||
id,
|
||||
title,
|
||||
titleUrl,
|
||||
content,
|
||||
imageUrl,
|
||||
thumbnailUrl,
|
||||
color,
|
||||
author,
|
||||
authorUrl,
|
||||
footer,
|
||||
footerUrl
|
||||
);
|
||||
}
|
||||
|
||||
public Note withAuthor(@Nullable String author) {
|
||||
return new Note(
|
||||
id,
|
||||
title,
|
||||
titleUrl,
|
||||
content,
|
||||
imageUrl,
|
||||
thumbnailUrl,
|
||||
color,
|
||||
author,
|
||||
authorUrl,
|
||||
footer,
|
||||
footerUrl
|
||||
);
|
||||
}
|
||||
public Note withAuthorUrl(@Nullable String authorUrl) {
|
||||
return new Note(
|
||||
id,
|
||||
title,
|
||||
titleUrl,
|
||||
content,
|
||||
imageUrl,
|
||||
thumbnailUrl,
|
||||
color,
|
||||
author,
|
||||
authorUrl,
|
||||
footer,
|
||||
footerUrl
|
||||
);
|
||||
}
|
||||
|
||||
public Note withFooter(@Nullable String footer) {
|
||||
return new Note(
|
||||
id,
|
||||
title,
|
||||
titleUrl,
|
||||
content,
|
||||
imageUrl,
|
||||
thumbnailUrl,
|
||||
color,
|
||||
author,
|
||||
authorUrl,
|
||||
footer,
|
||||
footerUrl
|
||||
);
|
||||
}
|
||||
|
||||
public Note withFooterUrl(@Nullable String footerUrl) {
|
||||
return new Note(
|
||||
id,
|
||||
title,
|
||||
titleUrl,
|
||||
content,
|
||||
imageUrl,
|
||||
thumbnailUrl,
|
||||
color,
|
||||
author,
|
||||
authorUrl,
|
||||
footer,
|
||||
footerUrl
|
||||
);
|
||||
}
|
||||
|
||||
public MessageEmbed toEmbed() {
|
||||
return new EmbedBuilder()
|
||||
.setTitle(title, titleUrl)
|
||||
|
||||
Reference in New Issue
Block a user