Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 49 additions & 9 deletions src/commands/search/vndb/character.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,61 @@
use crate::structs::{
api::vndb::Vndb,
command_context::{AeonCommandContext, AeonCommandInput},
select_menu::SelectMenu,
use crate::{
functions::limit_strings,
structs::{
api::vndb::Vndb,
command_context::{AeonCommandContext, AeonCommandInput},
components_v2::ComponentsV2Embed,
select_menu::SelectMenu,
},
};
use anyhow::Result;
use slashook::commands::MessageResponse;
use slashook::structs::components::{ActionRow, Button, Components, Section, Separator, TextDisplay, Thumbnail};
use std::sync::Arc;

pub async fn run(ctx: Arc<AeonCommandContext>) -> Result<()> {
if let AeonCommandInput::ApplicationCommand(..) = &ctx.command_input
&& ctx.get_bool_arg("search").unwrap_or(false)
{
let characters = Vndb::search_character(ctx.get_string_arg("character", 0, true)?).await?;
let options = characters.iter().map(|character| (&character.name, &character.id, Some(&character.vns[0].title)));
let select_menu = SelectMenu::new("vndb", "character", "Select a character…", None::<String>).add_options(options);
let mut embed = ComponentsV2Embed::new().set_title("Select a character");
let mut components = Components::empty();

return ctx.respond(select_menu, false).await;
let iter = characters.into_iter().take(6).enumerate();
let total = iter.len();

for (i, character) in iter {
let aliases = character.aliases.iter().map(|alias| format!("_{alias}_")).collect::<Vec<String>>();
let text_display = TextDisplay::new(format!(
"### [{}](https://vndb.org/{}){}\n-# {}",
limit_strings(character.name.split(""), "", 300),
character.id,
if aliases.is_empty() { "".into() } else { format!("\n{}", aliases.join("\n")) },
character.vns[0].title,
));

if let Some(image) = &character.image
&& image.sexual == 0.
&& image.violence == 0.
{
let thumbnail = Thumbnail::new(&image.url);
let section = Section::new().add_component(text_display).set_accessory(thumbnail);
components = components.add_component(section);
} else {
components = components.add_component(text_display);
}

let button = Button::new().set_id("vndb", format!("character/{}", character.id)).set_label("Select");
let action_row = ActionRow::new().add_component(button);
components = components.add_component(action_row);

if i != total - 1 {
let separator = Separator::new();
components = components.add_component(separator);
}
}

embed = embed.set_components(components);

return ctx.respond(embed, false).await;
}

let (query, section) = ctx.get_query_and_section("character")?;
Expand All @@ -31,5 +71,5 @@ pub async fn run(ctx: Arc<AeonCommandContext>) -> Result<()> {
_ => character.format(),
};

ctx.respond(MessageResponse::from(select_menu).add_embed(embed), false).await
ctx.respond(embed.set_select_menu(select_menu), false).await
}
7 changes: 4 additions & 3 deletions src/commands/search/vndb/character_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ use crate::structs::{
select_menu::SelectMenu,
};
use anyhow::Result;
use slashook::commands::MessageResponse;
use std::sync::Arc;

pub async fn run(ctx: Arc<AeonCommandContext>) -> Result<()> {
if let AeonCommandInput::ApplicationCommand(input, _) = &ctx.command_input
&& input.is_string_select()
{
return ctx.respond(Vndb::search_trait(&input.values.as_ref().unwrap()[0]).await?[0].format(), false).await;
return ctx
.respond(Vndb::search_trait(&input.values.as_ref().unwrap()[0]).await?[0].format().set_select_menu_from_input(input), false)
.await;
}

let results = Vndb::search_trait(ctx.get_string_arg("trait", 0, true)?).await?;
let options = results.iter().map(|result| (&result.name, &result.id, result.group_name.as_ref()));
let select_menu = SelectMenu::new("vndb", "trait", "View other traits…", None::<String>).add_options(options);

ctx.respond(MessageResponse::from(select_menu).add_embed(results[0].format()), false).await
ctx.respond(results[0].format().set_select_menu(select_menu), false).await
}
6 changes: 3 additions & 3 deletions src/commands/search/vndb/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ use crate::structs::{
select_menu::SelectMenu,
};
use anyhow::Result;
use slashook::commands::MessageResponse;
use std::sync::Arc;

pub async fn run(ctx: Arc<AeonCommandContext>) -> Result<()> {
if let AeonCommandInput::ApplicationCommand(input, _) = &ctx.command_input
&& input.is_string_select()
{
return ctx.respond(Vndb::search_tag(&input.values.as_ref().unwrap()[0]).await?[0].format(), false).await;
let embed = Vndb::search_tag(&input.values.as_ref().unwrap()[0]).await?[0].format();
return ctx.respond(embed.set_select_menu_from_input(input), false).await;
}

let tags = Vndb::search_tag(ctx.get_string_arg("tag", 0, true)?).await?;
let options = tags.iter().map(|tag| (&tag.name, &tag.id, Some(&tag.category)));
let select_menu = SelectMenu::new("vndb", "tag", "View other tags…", None::<String>).add_options(options);

ctx.respond(MessageResponse::from(select_menu).add_embed(tags[0].format()), false).await
ctx.respond(tags[0].format().set_select_menu(select_menu), false).await
}
65 changes: 56 additions & 9 deletions src/commands/search/vndb/visual_novel.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,71 @@
use crate::structs::{
api::vndb::Vndb,
command_context::{AeonCommandContext, AeonCommandInput},
select_menu::SelectMenu,
use crate::{
functions::limit_strings,
structs::{
api::vndb::Vndb,
command_context::{AeonCommandContext, AeonCommandInput},
components_v2::ComponentsV2Embed,
select_menu::SelectMenu,
},
};
use anyhow::Result;
use slashook::commands::MessageResponse;
use slashook::structs::components::{ActionRow, Button, Components, Section, Separator, TextDisplay, Thumbnail};
use std::sync::Arc;

pub async fn run(ctx: Arc<AeonCommandContext>) -> Result<()> {
if let AeonCommandInput::ApplicationCommand(..) = &ctx.command_input
&& ctx.get_bool_arg("search").unwrap_or(false)
{
let visual_novels = Vndb::search_visual_novel(ctx.get_string_arg("visual-novel", 0, true)?).await?;
let options = visual_novels.iter().map(|visual_novel| (&visual_novel.title, &visual_novel.id, Some(&visual_novel.dev_status)));
let select_menu = SelectMenu::new("vndb", "visual-novel", "Select a visual novel…", None::<String>).add_options(options);
let mut embed = ComponentsV2Embed::new().set_title("Select a visual novel");
let mut components = Components::empty();

return ctx.respond(select_menu, false).await;
let iter = visual_novels.into_iter().take(7).enumerate();
let total = iter.len();

for (i, visual_novel) in iter {
let mut aliases = vec![];
if let Some(alt_title) = &visual_novel.alt_title {
aliases.push(format!("_{alt_title}_"));
}
for alias in &visual_novel.aliases {
aliases.push(format!("_{alias}_"));
}
let text_display = TextDisplay::new(format!(
"### [{} ({})](https://vndb.org/{}){}",
limit_strings(visual_novel.title.split(""), "", 300),
visual_novel.dev_status,
visual_novel.id,
if aliases.is_empty() { "".into() } else { format!("\n{}", aliases.join("\n")) },
));

if let Some(image) = &visual_novel.image
&& image.sexual == 0.
&& image.violence == 0.
{
let thumbnail = Thumbnail::new(&image.url);
let section = Section::new().add_component(text_display).set_accessory(thumbnail);
components = components.add_component(section);
} else {
components = components.add_component(text_display);
}

let button = Button::new().set_id("vndb", format!("visual-novel/{}", visual_novel.id)).set_label("Select");
let action_row = ActionRow::new().add_component(button);
components = components.add_component(action_row);

if i != total - 1 {
let separator = Separator::new();
components = components.add_component(separator);
}
}

embed = embed.set_components(components);

return ctx.respond(embed, false).await;
}

let (query, section) = ctx.get_query_and_section("visual-novel")?;

let visual_novel = Vndb::search_visual_novel(query).await?.remove(0);
let id = &visual_novel.id;
let select_menu = SelectMenu::new("vndb", "visual-novel", "View other sections…", Some(&section))
Expand All @@ -31,5 +78,5 @@ pub async fn run(ctx: Arc<AeonCommandContext>) -> Result<()> {
_ => visual_novel.format(),
};

ctx.respond(MessageResponse::from(select_menu).add_embed(embed), false).await
ctx.respond(embed.set_select_menu(select_menu), false).await
}
16 changes: 13 additions & 3 deletions src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,21 @@ pub fn limit_strings<T: IntoIterator<Item = U>, U: Display, V: Display>(iterable
let delimiter = delimiter.to_string();
let mut strings = iterable.into_iter().map(|to_string| to_string.to_string()).collect::<Vec<String>>();

while strings.join(&delimiter).len() > limit {
strings.pop();
let join_full = strings.join(&delimiter);

if join_full.len() > limit {
while strings.join(&delimiter).len() > limit - delimiter.len() - 1 {
strings.pop();
}
}

let mut join_limited = strings.join(&delimiter);

if join_full.len() != join_limited.len() {
join_limited += &format!("{delimiter}…");
}

strings.join(&delimiter)
join_limited
}

pub fn label_num<T: Display, U: Display, V: Display>(amount: T, singular: U, plural: V) -> String {
Expand Down
Loading