Add profile command

This commit is contained in:
Natsu Kagami 2024-12-31 02:38:43 +01:00
parent 6176c205d9
commit 8a8faae44c
Signed by: nki
GPG key ID: 55A032EB38B49ADB
3 changed files with 65 additions and 30 deletions

View file

@ -4,7 +4,7 @@ use serenity::all::User;
use youmubot_prelude::*; use youmubot_prelude::*;
/// osu!-related command group. /// osu!-related command group.
#[poise::command(slash_command, subcommands("top"))] #[poise::command(slash_command, subcommands("profile", "top"))]
pub async fn osu<U: HasOsuEnv>(_ctx: CmdContext<'_, U>) -> Result<()> { pub async fn osu<U: HasOsuEnv>(_ctx: CmdContext<'_, U>) -> Result<()> {
Ok(()) Ok(())
} }
@ -22,14 +22,10 @@ async fn top<U: HasOsuEnv>(
#[description = "Score listing style"] style: Option<ScoreListStyle>, #[description = "Score listing style"] style: Option<ScoreListStyle>,
#[description = "Game mode"] mode: Option<Mode>, #[description = "Game mode"] mode: Option<Mode>,
#[description = "osu! username"] username: Option<String>, #[description = "osu! username"] username: Option<String>,
#[description = "Discord username"] user: Option<User>, #[description = "Discord username"] discord_name: Option<User>,
) -> Result<()> { ) -> Result<()> {
let env = ctx.data().osu_env(); let env = ctx.data().osu_env();
let username_arg = match (username, user) { let username_arg = arg_from_username_or_discord(username, discord_name);
(Some(v), _) => Some(UsernameArg::Raw(v)),
(_, Some(u)) => Some(UsernameArg::Tagged(u.id)),
(None, None) => None,
};
let ListingArgs { let ListingArgs {
nth, nth,
style, style,
@ -68,10 +64,9 @@ async fn top<U: HasOsuEnv>(
ctx.send({ ctx.send({
CreateReply::default() CreateReply::default()
.content(format!( .content(format!(
"Here is the #{} top play by [`{}`](<{}>)", "Here is the #{} top play by {}",
nth + 1, nth + 1,
user.username, user.mention()
user.link()
)) ))
.embed( .embed(
score_embed(&play, &beatmap, &content, user) score_embed(&play, &beatmap, &content, user)
@ -88,11 +83,7 @@ async fn top<U: HasOsuEnv>(
Nth::All => { Nth::All => {
let reply = ctx let reply = ctx
.clone() .clone()
.reply(format!( .reply(format!("Here are the top plays by {}!", user.mention()))
"Here are the top plays by [`{}`](<{}>)!",
user.username,
user.link()
))
.await? .await?
.into_message() .into_message()
.await?; .await?;
@ -103,3 +94,53 @@ async fn top<U: HasOsuEnv>(
} }
Ok(()) Ok(())
} }
/// Get an user's profile.
#[poise::command(slash_command)]
async fn profile<U: HasOsuEnv>(
ctx: CmdContext<'_, U>,
#[description = "Game mode"]
#[rename = "mode"]
mode_override: Option<Mode>,
#[description = "osu! username"] username: Option<String>,
#[description = "Discord username"] discord_name: Option<User>,
) -> Result<()> {
let env = ctx.data().osu_env();
let username_arg = arg_from_username_or_discord(username, discord_name);
let (mode, user) = user_header_or_default_id(username_arg, env, ctx.author().id).await?;
let mode = mode_override.unwrap_or(mode);
ctx.defer().await?;
let user = env
.client
.user(&UserID::ID(user.id), |f| f.mode(mode))
.await?;
match user {
Some(u) => {
let ex = UserExtras::from_user(env, &u, mode).await?;
ctx.send(
CreateReply::default()
.content(format!("Here is {}'s **{}** profile!", u.mention(), mode))
.embed(user_embed(u, ex)),
)
.await?;
}
None => {
ctx.reply("🔍 user not found!").await?;
}
};
Ok(())
}
fn arg_from_username_or_discord(
username: Option<String>,
discord_name: Option<User>,
) -> Option<UsernameArg> {
match (username, discord_name) {
(Some(v), _) => Some(UsernameArg::Raw(v)),
(_, Some(u)) => Some(UsernameArg::Tagged(u.id)),
(None, None) => None,
}
}

View file

@ -1007,10 +1007,9 @@ pub async fn top(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
.send_message(&ctx, { .send_message(&ctx, {
CreateMessage::new() CreateMessage::new()
.content(format!( .content(format!(
"Here is the #{} top play by [`{}`](<{}>)", "Here is the #{} top play by {}",
nth + 1, nth + 1,
user.username, user.mention()
user.link()
)) ))
.embed( .embed(
score_embed(&play, &beatmap, &content, user) score_embed(&play, &beatmap, &content, user)
@ -1028,11 +1027,7 @@ pub async fn top(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
let reply = msg let reply = msg
.reply( .reply(
&ctx, &ctx,
format!( format!("Here are the top plays by {}!", user.mention()),
"Here are the top plays by [`{}`](<{}>)!",
user.username,
user.link()
),
) )
.await?; .await?;
style style
@ -1080,10 +1075,7 @@ async fn get_user(
.send_message( .send_message(
&ctx, &ctx,
CreateMessage::new() CreateMessage::new()
.content(format!( .content(format!("Here is {}'s **{}** profile!", u.mention(), mode))
"{}: here is the user that you requested",
msg.author
))
.embed(user_embed(u, ex)), .embed(user_embed(u, ex)),
) )
.await?; .await?;

View file

@ -247,12 +247,14 @@ async fn main() {
Box::pin(async move { Box::pin(async move {
if let poise::FrameworkError::Command { error, ctx, .. } = err { if let poise::FrameworkError::Command { error, ctx, .. } = err {
let reply = format!( let reply = format!(
"Command '{}' returned error {:?}", "Command '{}' returned error: {:?}",
ctx.invoked_command_name(), ctx.invoked_command_name(),
error error
); );
ctx.reply(&reply).await.pls_ok(); println!("{}", reply);
println!("{}", reply) ctx.send(poise::CreateReply::default().content(reply).ephemeral(true))
.await
.pls_ok();
} else { } else {
eprintln!("Poise error: {:?}", err) eprintln!("Poise error: {:?}", err)
} }