Extract trait
This commit is contained in:
@ -1,17 +1,13 @@
|
||||
use crate::{consts::MINUTE, models::CtxData, Context, Error};
|
||||
|
||||
/// Nudge all future reminders on this channel by a certain amount (don't use for DST! See `/offset`)
|
||||
#[poise::command(
|
||||
slash_command,
|
||||
identifying_name = "nudge",
|
||||
default_member_permissions = "MANAGE_GUILD"
|
||||
)]
|
||||
pub async fn nudge(
|
||||
ctx: Context<'_>,
|
||||
#[description = "Number of minutes to nudge new reminders by"] minutes: Option<isize>,
|
||||
#[description = "Number of seconds to nudge new reminders by"] seconds: Option<isize>,
|
||||
) -> Result<(), Error> {
|
||||
let combined_time = minutes.map_or(0, |m| m * MINUTE as isize) + seconds.map_or(0, |s| s);
|
||||
pub struct Options {
|
||||
minutes: Option<isize>,
|
||||
seconds: Option<isize>,
|
||||
}
|
||||
|
||||
pub async fn nudge(ctx: Context<'_>, options: Options) -> Result<(), Error> {
|
||||
let combined_time =
|
||||
options.minutes.map_or(0, |m| m * MINUTE as isize) + options.seconds.map_or(0, |s| s);
|
||||
|
||||
if combined_time < i16::MIN as isize || combined_time > i16::MAX as isize {
|
||||
ctx.say("Nudge times must be less than 500 minutes").await?;
|
||||
@ -26,3 +22,17 @@ pub async fn nudge(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Nudge all future reminders on this channel by a certain amount (don't use for DST! See `/offset`)
|
||||
#[poise::command(
|
||||
slash_command,
|
||||
identifying_name = "nudge",
|
||||
default_member_permissions = "MANAGE_GUILD"
|
||||
)]
|
||||
pub async fn command(
|
||||
ctx: Context<'_>,
|
||||
#[description = "Number of minutes to nudge new reminders by"] minutes: Option<isize>,
|
||||
#[description = "Number of seconds to nudge new reminders by"] seconds: Option<isize>,
|
||||
) -> Result<(), Error> {
|
||||
nudge(ctx, Options { minutes, seconds }).await
|
||||
}
|
||||
|
@ -1,25 +1,23 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
consts::{HOUR, MINUTE},
|
||||
Context, Error,
|
||||
};
|
||||
|
||||
/// Move all reminders in the current server by a certain amount of time. Times get added together
|
||||
#[poise::command(
|
||||
slash_command,
|
||||
identifying_name = "offset",
|
||||
default_member_permissions = "MANAGE_GUILD"
|
||||
)]
|
||||
pub async fn offset(
|
||||
ctx: Context<'_>,
|
||||
#[description = "Number of hours to offset by"] hours: Option<isize>,
|
||||
#[description = "Number of minutes to offset by"] minutes: Option<isize>,
|
||||
#[description = "Number of seconds to offset by"] seconds: Option<isize>,
|
||||
) -> Result<(), Error> {
|
||||
#[derive(Serialize, Deserialize, Default)]
|
||||
pub struct Options {
|
||||
hours: Option<isize>,
|
||||
minutes: Option<isize>,
|
||||
seconds: Option<isize>,
|
||||
}
|
||||
|
||||
async fn offset(ctx: Context<'_>, options: Options) -> Result<(), Error> {
|
||||
ctx.defer().await?;
|
||||
|
||||
let combined_time = hours.map_or(0, |h| h * HOUR as isize)
|
||||
+ minutes.map_or(0, |m| m * MINUTE as isize)
|
||||
+ seconds.map_or(0, |s| s);
|
||||
let combined_time = options.hours.map_or(0, |h| h * HOUR as isize)
|
||||
+ options.minutes.map_or(0, |m| m * MINUTE as isize)
|
||||
+ options.seconds.map_or(0, |s| s);
|
||||
|
||||
if combined_time == 0 {
|
||||
ctx.say("Please specify one of `hours`, `minutes` or `seconds`").await?;
|
||||
@ -69,3 +67,18 @@ pub async fn offset(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Move all reminders in the current server by a certain amount of time. Times get added together
|
||||
#[poise::command(
|
||||
slash_command,
|
||||
identifying_name = "offset",
|
||||
default_member_permissions = "MANAGE_GUILD"
|
||||
)]
|
||||
pub async fn command(
|
||||
ctx: Context<'_>,
|
||||
#[description = "Number of hours to offset by"] hours: Option<isize>,
|
||||
#[description = "Number of minutes to offset by"] minutes: Option<isize>,
|
||||
#[description = "Number of seconds to offset by"] seconds: Option<isize>,
|
||||
) -> Result<(), Error> {
|
||||
offset(ctx, Options { hours, minutes, seconds }).await
|
||||
}
|
||||
|
@ -1,22 +1,28 @@
|
||||
use chrono::NaiveDateTime;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{models::CtxData, time_parser::natural_parser, Context, Error};
|
||||
use crate::{
|
||||
models::CtxData, time_parser::natural_parser, utils::Extract, ApplicationContext, Context,
|
||||
Error,
|
||||
};
|
||||
|
||||
/// Pause all reminders on the current channel until a certain time or indefinitely
|
||||
#[poise::command(
|
||||
slash_command,
|
||||
identifying_name = "pause",
|
||||
default_member_permissions = "MANAGE_GUILD"
|
||||
)]
|
||||
pub async fn pause(
|
||||
ctx: Context<'_>,
|
||||
#[description = "When to pause until"] until: Option<String>,
|
||||
) -> Result<(), Error> {
|
||||
#[derive(Serialize, Deserialize, Extract)]
|
||||
pub struct Options {
|
||||
until: Option<String>,
|
||||
}
|
||||
|
||||
impl Extract for Options {
|
||||
fn extract(ctx: ApplicationContext) -> Self {
|
||||
Self { until: extract_arg!(ctx, "until", Option<String>) }
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn pause(ctx: Context<'_>, options: Options) -> Result<(), Error> {
|
||||
let timezone = ctx.timezone().await;
|
||||
|
||||
let mut channel = ctx.channel_data().await.unwrap();
|
||||
|
||||
match until {
|
||||
match options.until {
|
||||
Some(until) => {
|
||||
let parsed = natural_parser(&until, &timezone.to_string()).await;
|
||||
|
||||
@ -65,3 +71,16 @@ pub async fn pause(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Pause all reminders on the current channel until a certain time or indefinitely
|
||||
#[poise::command(
|
||||
slash_command,
|
||||
identifying_name = "pause",
|
||||
default_member_permissions = "MANAGE_GUILD"
|
||||
)]
|
||||
pub async fn command(
|
||||
ctx: Context<'_>,
|
||||
#[description = "When to pause until"] until: Option<String>,
|
||||
) -> Result<(), Error> {
|
||||
pause(ctx, Options { until }).await
|
||||
}
|
||||
|
@ -4,18 +4,49 @@ use serde::{Deserialize, Serialize};
|
||||
use crate::{
|
||||
commands::autocomplete::{time_hint_autocomplete, timezone_autocomplete},
|
||||
models::reminder::create_reminder,
|
||||
utils::{extract_arg, Extract},
|
||||
ApplicationContext, Context, Error,
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize, Default)]
|
||||
pub struct RemindOptions {
|
||||
pub time: String,
|
||||
pub content: String,
|
||||
pub channels: Option<String>,
|
||||
pub interval: Option<String>,
|
||||
pub expires: Option<String>,
|
||||
pub tts: Option<bool>,
|
||||
pub timezone: Option<Tz>,
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Options {
|
||||
time: String,
|
||||
content: String,
|
||||
channels: Option<String>,
|
||||
interval: Option<String>,
|
||||
expires: Option<String>,
|
||||
tts: Option<bool>,
|
||||
timezone: Option<String>,
|
||||
}
|
||||
|
||||
impl Extract for Options {
|
||||
fn extract(ctx: ApplicationContext) -> Self {
|
||||
Self {
|
||||
time: extract_arg!(ctx, "time", String),
|
||||
content: extract_arg!(ctx, "content", String),
|
||||
channels: extract_arg!(ctx, "channels", Option<String>),
|
||||
interval: extract_arg!(ctx, "interval", Option<String>),
|
||||
expires: extract_arg!(ctx, "expires", Option<String>),
|
||||
tts: extract_arg!(ctx, "tts", Option<bool>),
|
||||
timezone: extract_arg!(ctx, "timezone", Option<String>),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn remind(ctx: Context<'_>, options: Options) -> Result<(), Error> {
|
||||
let tz = options.timezone.map(|t| t.parse::<Tz>().ok()).flatten();
|
||||
|
||||
create_reminder(
|
||||
ctx,
|
||||
options.time,
|
||||
options.content,
|
||||
options.channels,
|
||||
options.interval,
|
||||
options.expires,
|
||||
options.tts,
|
||||
tz,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Create a reminder. Press "+4 more" for other options. Use "/multiline" for multiline content.
|
||||
@ -24,8 +55,8 @@ pub struct RemindOptions {
|
||||
identifying_name = "remind",
|
||||
default_member_permissions = "MANAGE_GUILD"
|
||||
)]
|
||||
pub async fn remind(
|
||||
ctx: ApplicationContext<'_>,
|
||||
pub async fn command(
|
||||
ctx: Context<'_>,
|
||||
#[description = "The time (and optionally date) to set the reminder for"]
|
||||
#[autocomplete = "time_hint_autocomplete"]
|
||||
time: String,
|
||||
@ -41,8 +72,5 @@ pub async fn remind(
|
||||
#[autocomplete = "timezone_autocomplete"]
|
||||
timezone: Option<String>,
|
||||
) -> Result<(), Error> {
|
||||
let tz = timezone.map(|t| t.parse::<Tz>().ok()).flatten();
|
||||
|
||||
create_reminder(Context::Application(ctx), time, content, channels, interval, expires, tts, tz)
|
||||
.await
|
||||
remind(ctx, Options { time, content, channels, interval, expires, tts, timezone }).await
|
||||
}
|
||||
|
@ -5,25 +5,24 @@ use poise::{
|
||||
serenity_prelude::{CreateEmbed, CreateEmbedFooter},
|
||||
CreateReply,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
commands::autocomplete::timezone_autocomplete, consts::THEME_COLOR, models::CtxData, Context,
|
||||
Error,
|
||||
};
|
||||
|
||||
/// Select your timezone
|
||||
#[poise::command(slash_command, identifying_name = "timezone")]
|
||||
pub async fn timezone(
|
||||
ctx: Context<'_>,
|
||||
#[description = "Timezone to use from this list: https://gist.github.com/JellyWX/913dfc8b63d45192ad6cb54c829324ee"]
|
||||
#[autocomplete = "timezone_autocomplete"]
|
||||
timezone: Option<String>,
|
||||
) -> Result<(), Error> {
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Options {
|
||||
pub timezone: Option<String>,
|
||||
}
|
||||
|
||||
pub async fn timezone_fn(ctx: Context<'_>, options: Options) -> Result<(), Error> {
|
||||
let mut user_data = ctx.author_data().await.unwrap();
|
||||
|
||||
let footer_text = format!("Current timezone: {}", user_data.timezone);
|
||||
|
||||
if let Some(timezone) = timezone {
|
||||
if let Some(timezone) = options.timezone {
|
||||
match timezone.parse::<Tz>() {
|
||||
Ok(tz) => {
|
||||
user_data.timezone = timezone.clone();
|
||||
@ -115,3 +114,14 @@ You may want to use one of the popular timezones below, otherwise click [here](h
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Select your timezone
|
||||
#[poise::command(slash_command, identifying_name = "timezone")]
|
||||
pub async fn command(
|
||||
ctx: Context<'_>,
|
||||
#[description = "Timezone to use from this list: https://gist.github.com/JellyWX/913dfc8b63d45192ad6cb54c829324ee"]
|
||||
#[autocomplete = "timezone_autocomplete"]
|
||||
timezone: Option<String>,
|
||||
) -> Result<(), Error> {
|
||||
timezone_fn(ctx, Options { timezone }).await
|
||||
}
|
||||
|
@ -1,15 +1,19 @@
|
||||
use log::warn;
|
||||
use poise::CreateReply;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{models::CtxData, Context, Error};
|
||||
use crate::{models::CtxData, utils::Extract, ApplicationContext, Context, Error};
|
||||
|
||||
/// View the webhook being used to send reminders to this channel
|
||||
#[poise::command(
|
||||
slash_command,
|
||||
identifying_name = "webhook_url",
|
||||
required_permissions = "ADMINISTRATOR"
|
||||
)]
|
||||
pub async fn webhook(ctx: Context<'_>) -> Result<(), Error> {
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Options;
|
||||
|
||||
impl Extract for Options {
|
||||
fn extract(_ctx: ApplicationContext) -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn webhook(ctx: Context<'_>, _options: Options) -> Result<(), Error> {
|
||||
match ctx.channel_data().await {
|
||||
Ok(data) => {
|
||||
if let (Some(id), Some(token)) = (data.webhook_id, data.webhook_token) {
|
||||
@ -34,3 +38,13 @@ Do not share it!
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// View the webhook being used to send reminders to this channel
|
||||
#[poise::command(
|
||||
slash_command,
|
||||
identifying_name = "webhook_url",
|
||||
required_permissions = "ADMINISTRATOR"
|
||||
)]
|
||||
pub async fn command(ctx: Context<'_>) -> Result<(), Error> {
|
||||
webhook(ctx, Options {}).await
|
||||
}
|
||||
|
Reference in New Issue
Block a user