Extend user reminder API endpoints
This commit is contained in:
parent
8f4810b532
commit
3190738fc5
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2359,7 +2359,7 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reminder-rs"
|
name = "reminder-rs"
|
||||||
version = "1.7.1"
|
version = "1.7.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "reminder-rs"
|
name = "reminder-rs"
|
||||||
version = "1.7.1"
|
version = "1.7.2"
|
||||||
authors = ["Jude Southworth <judesouthworth@pm.me>"]
|
authors = ["Jude Southworth <judesouthworth@pm.me>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "AGPL-3.0 only"
|
license = "AGPL-3.0 only"
|
||||||
|
@ -144,9 +144,9 @@ export const postGuildReminder = (guild: string) => ({
|
|||||||
axios.post(`/dashboard/api/guild/${guild}/reminders`, reminder).then((resp) => resp.data),
|
axios.post(`/dashboard/api/guild/${guild}/reminders`, reminder).then((resp) => resp.data),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const deleteGuildReminder = (guild: string) => ({
|
export const deleteReminder = () => ({
|
||||||
mutationFn: (reminder: Reminder) =>
|
mutationFn: (reminder: Reminder) =>
|
||||||
axios.delete(`/dashboard/api/guild/${guild}/reminders`, {
|
axios.delete(`/dashboard/api/reminders`, {
|
||||||
data: {
|
data: {
|
||||||
uid: reminder.uid,
|
uid: reminder.uid,
|
||||||
},
|
},
|
||||||
@ -187,3 +187,7 @@ export const postUserReminder = () => ({
|
|||||||
mutationFn: (reminder: Reminder) =>
|
mutationFn: (reminder: Reminder) =>
|
||||||
axios.post(`/dashboard/api/user/reminders`, reminder).then((resp) => resp.data),
|
axios.post(`/dashboard/api/user/reminders`, reminder).then((resp) => resp.data),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const patchUserReminder = () => ({
|
||||||
|
mutationFn: (reminder: Reminder) => axios.patch(`/dashboard/api/user/reminders`, reminder),
|
||||||
|
});
|
||||||
|
@ -2,7 +2,6 @@ import { LoadTemplate } from "../LoadTemplate";
|
|||||||
import { useReminder } from "../ReminderContext";
|
import { useReminder } from "../ReminderContext";
|
||||||
import { useMutation, useQueryClient } from "react-query";
|
import { useMutation, useQueryClient } from "react-query";
|
||||||
import { postGuildReminder, postGuildTemplate, postUserReminder } from "../../../api";
|
import { postGuildReminder, postGuildTemplate, postUserReminder } from "../../../api";
|
||||||
import { useParams } from "wouter";
|
|
||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
import { ICON_FLASH_TIME } from "../../../consts";
|
import { ICON_FLASH_TIME } from "../../../consts";
|
||||||
import { useFlash } from "../../App/FlashContext";
|
import { useFlash } from "../../App/FlashContext";
|
||||||
@ -96,34 +95,36 @@ export const CreateButtonRow = () => {
|
|||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-row-template">
|
{guild && (
|
||||||
<div>
|
<div class="button-row-template">
|
||||||
<button
|
<div>
|
||||||
class="button is-success is-outlined"
|
<button
|
||||||
onClick={() => {
|
class="button is-success is-outlined"
|
||||||
templateMutation.mutate(reminder);
|
onClick={() => {
|
||||||
}}
|
templateMutation.mutate(reminder);
|
||||||
>
|
}}
|
||||||
<span>Create Template</span>{" "}
|
>
|
||||||
{templateMutation.isLoading ? (
|
<span>Create Template</span>{" "}
|
||||||
<span class="icon">
|
{templateMutation.isLoading ? (
|
||||||
<i class="fas fa-spin fa-cog"></i>
|
<span class="icon">
|
||||||
</span>
|
<i class="fas fa-spin fa-cog"></i>
|
||||||
) : templateRecentlyCreated ? (
|
</span>
|
||||||
<span class="icon">
|
) : templateRecentlyCreated ? (
|
||||||
<i class="fas fa-check"></i>
|
<span class="icon">
|
||||||
</span>
|
<i class="fas fa-check"></i>
|
||||||
) : (
|
</span>
|
||||||
<span class="icon">
|
) : (
|
||||||
<i class="fas fa-file-spreadsheet"></i>
|
<span class="icon">
|
||||||
</span>
|
<i class="fas fa-file-spreadsheet"></i>
|
||||||
)}
|
</span>
|
||||||
</button>
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<LoadTemplate />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
)}
|
||||||
<LoadTemplate />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -2,9 +2,10 @@ import { useState } from "preact/hooks";
|
|||||||
import { Modal } from "../../Modal";
|
import { Modal } from "../../Modal";
|
||||||
import { useMutation, useQueryClient } from "react-query";
|
import { useMutation, useQueryClient } from "react-query";
|
||||||
import { useReminder } from "../ReminderContext";
|
import { useReminder } from "../ReminderContext";
|
||||||
import { deleteGuildReminder } from "../../../api";
|
import { deleteReminder } from "../../../api";
|
||||||
import { useParams } from "wouter";
|
import { useParams } from "wouter";
|
||||||
import { useFlash } from "../../App/FlashContext";
|
import { useFlash } from "../../App/FlashContext";
|
||||||
|
import { useGuild } from "../../App/useGuild";
|
||||||
|
|
||||||
export const DeleteButton = () => {
|
export const DeleteButton = () => {
|
||||||
const [modalOpen, setModalOpen] = useState(false);
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
@ -26,20 +27,26 @@ export const DeleteButton = () => {
|
|||||||
|
|
||||||
const DeleteModal = ({ setModalOpen }) => {
|
const DeleteModal = ({ setModalOpen }) => {
|
||||||
const [reminder] = useReminder();
|
const [reminder] = useReminder();
|
||||||
const { guild } = useParams();
|
const guild = useGuild();
|
||||||
|
|
||||||
const flash = useFlash();
|
const flash = useFlash();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
...deleteGuildReminder(guild),
|
...deleteReminder(),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
flash({
|
flash({
|
||||||
message: "Reminder deleted",
|
message: "Reminder deleted",
|
||||||
type: "success",
|
type: "success",
|
||||||
});
|
});
|
||||||
queryClient.invalidateQueries({
|
if (guild) {
|
||||||
queryKey: ["GUILD_REMINDERS", guild],
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: ["GUILD_REMINDERS", guild],
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: ["USER_REMINDERS"],
|
||||||
|
});
|
||||||
|
}
|
||||||
setModalOpen(false);
|
setModalOpen(false);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import { useRef, useState } from "preact/hooks";
|
import { useRef, useState } from "preact/hooks";
|
||||||
import { useMutation, useQueryClient } from "react-query";
|
import { useMutation, useQueryClient } from "react-query";
|
||||||
import { patchGuildReminder } from "../../../api";
|
import { patchGuildReminder, patchUserReminder } from "../../../api";
|
||||||
import { useParams } from "wouter";
|
|
||||||
import { ICON_FLASH_TIME } from "../../../consts";
|
import { ICON_FLASH_TIME } from "../../../consts";
|
||||||
import { DeleteButton } from "./DeleteButton";
|
import { DeleteButton } from "./DeleteButton";
|
||||||
import { useReminder } from "../ReminderContext";
|
import { useReminder } from "../ReminderContext";
|
||||||
import { useFlash } from "../../App/FlashContext";
|
import { useFlash } from "../../App/FlashContext";
|
||||||
|
import { useGuild } from "../../App/useGuild";
|
||||||
|
|
||||||
export const EditButtonRow = () => {
|
export const EditButtonRow = () => {
|
||||||
const { guild } = useParams();
|
const guild = useGuild();
|
||||||
const [reminder, setReminder] = useReminder();
|
const [reminder, setReminder] = useReminder();
|
||||||
|
|
||||||
const [recentlySaved, setRecentlySaved] = useState(false);
|
const [recentlySaved, setRecentlySaved] = useState(false);
|
||||||
@ -18,11 +18,17 @@ export const EditButtonRow = () => {
|
|||||||
|
|
||||||
const flash = useFlash();
|
const flash = useFlash();
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
...patchGuildReminder(guild),
|
...(guild ? patchGuildReminder(guild) : patchUserReminder()),
|
||||||
onSuccess: (response) => {
|
onSuccess: (response) => {
|
||||||
queryClient.invalidateQueries({
|
if (guild) {
|
||||||
queryKey: ["GUILD_REMINDERS", guild],
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: ["GUILD_REMINDERS", guild],
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: ["USER_REMINDERS"],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (iconFlashTimeout.current !== null) {
|
if (iconFlashTimeout.current !== null) {
|
||||||
clearTimeout(iconFlashTimeout.current);
|
clearTimeout(iconFlashTimeout.current);
|
||||||
|
@ -131,6 +131,7 @@ pub async fn initialize(
|
|||||||
routes![
|
routes![
|
||||||
routes::dashboard::dashboard,
|
routes::dashboard::dashboard,
|
||||||
routes::dashboard::dashboard_home,
|
routes::dashboard::dashboard_home,
|
||||||
|
routes::dashboard::api::delete_reminder,
|
||||||
routes::dashboard::api::user::get_user_info,
|
routes::dashboard::api::user::get_user_info,
|
||||||
routes::dashboard::api::user::update_user_info,
|
routes::dashboard::api::user::update_user_info,
|
||||||
routes::dashboard::api::user::get_user_guilds,
|
routes::dashboard::api::user::get_user_guilds,
|
||||||
@ -145,7 +146,6 @@ pub async fn initialize(
|
|||||||
routes::dashboard::api::guild::create_guild_reminder,
|
routes::dashboard::api::guild::create_guild_reminder,
|
||||||
routes::dashboard::api::guild::get_reminders,
|
routes::dashboard::api::guild::get_reminders,
|
||||||
routes::dashboard::api::guild::edit_reminder,
|
routes::dashboard::api::guild::edit_reminder,
|
||||||
routes::dashboard::api::guild::delete_reminder,
|
|
||||||
routes::dashboard::export::export_reminders,
|
routes::dashboard::export::export_reminders,
|
||||||
routes::dashboard::export::export_reminder_templates,
|
routes::dashboard::export::export_reminder_templates,
|
||||||
routes::dashboard::export::export_todos,
|
routes::dashboard::export::export_todos,
|
||||||
|
@ -14,9 +14,7 @@ use crate::{
|
|||||||
consts::MIN_INTERVAL,
|
consts::MIN_INTERVAL,
|
||||||
guards::transaction::Transaction,
|
guards::transaction::Transaction,
|
||||||
routes::{
|
routes::{
|
||||||
dashboard::{
|
dashboard::{create_database_channel, create_reminder, PatchReminder, Reminder},
|
||||||
create_database_channel, create_reminder, DeleteReminder, PatchReminder, Reminder,
|
|
||||||
},
|
|
||||||
JsonResult,
|
JsonResult,
|
||||||
},
|
},
|
||||||
Database,
|
Database,
|
||||||
@ -364,27 +362,3 @@ pub async fn edit_reminder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[delete("/api/guild/<id>/reminders", data = "<reminder>")]
|
|
||||||
pub async fn delete_reminder(
|
|
||||||
cookies: &CookieJar<'_>,
|
|
||||||
id: u64,
|
|
||||||
reminder: Json<DeleteReminder>,
|
|
||||||
ctx: &State<Context>,
|
|
||||||
pool: &State<Pool<MySql>>,
|
|
||||||
) -> JsonResult {
|
|
||||||
check_authorization(cookies, ctx.inner(), id).await?;
|
|
||||||
|
|
||||||
match sqlx::query!("UPDATE reminders SET `status` = 'deleted' WHERE uid = ?", reminder.uid)
|
|
||||||
.execute(pool.inner())
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(_) => Ok(json!({})),
|
|
||||||
|
|
||||||
Err(e) => {
|
|
||||||
warn!("Error in `delete_reminder`: {:?}", e);
|
|
||||||
|
|
||||||
Err(json!({"error": "Could not delete reminder"}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,2 +1,41 @@
|
|||||||
pub mod guild;
|
pub mod guild;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
|
|
||||||
|
use rocket::{
|
||||||
|
http::CookieJar,
|
||||||
|
serde::json::{json, Json},
|
||||||
|
State,
|
||||||
|
};
|
||||||
|
use serenity::client::Context;
|
||||||
|
use sqlx::{MySql, Pool};
|
||||||
|
|
||||||
|
use crate::routes::{dashboard::DeleteReminder, JsonResult};
|
||||||
|
|
||||||
|
#[delete("/api/reminders", data = "<reminder>")]
|
||||||
|
pub async fn delete_reminder(
|
||||||
|
cookies: &CookieJar<'_>,
|
||||||
|
reminder: Json<DeleteReminder>,
|
||||||
|
pool: &State<Pool<MySql>>,
|
||||||
|
) -> JsonResult {
|
||||||
|
match cookies.get_private("userid").map(|c| c.value().parse::<u64>().ok()).flatten() {
|
||||||
|
Some(_) => {
|
||||||
|
match sqlx::query!(
|
||||||
|
"UPDATE reminders SET `status` = 'deleted' WHERE uid = ?",
|
||||||
|
reminder.uid
|
||||||
|
)
|
||||||
|
.execute(pool.inner())
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(_) => Ok(json!({})),
|
||||||
|
|
||||||
|
Err(e) => {
|
||||||
|
warn!("Error in `delete_reminder`: {:?}", e);
|
||||||
|
|
||||||
|
Err(json!({"error": "Could not delete reminder"}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None => Err(json!({"error": "User not authorized"})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -15,7 +15,10 @@ use crate::{
|
|||||||
},
|
},
|
||||||
guards::transaction::Transaction,
|
guards::transaction::Transaction,
|
||||||
routes::{
|
routes::{
|
||||||
dashboard::{create_database_channel, generate_uid, name_default, Attachment, EmbedField},
|
dashboard::{
|
||||||
|
create_database_channel, deserialize_optional_field, generate_uid, interval_default,
|
||||||
|
name_default, Attachment, EmbedField, Unset,
|
||||||
|
},
|
||||||
JsonResult,
|
JsonResult,
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
@ -228,3 +231,60 @@ pub async fn create_reminder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct PatchReminder {
|
||||||
|
pub uid: String,
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_optional_field")]
|
||||||
|
pub attachment: Unset<Option<Attachment>>,
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_optional_field")]
|
||||||
|
pub attachment_name: Unset<Option<String>>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub content: Unset<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub embed_author: Unset<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_optional_field")]
|
||||||
|
pub embed_author_url: Unset<Option<String>>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub embed_color: Unset<u32>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub embed_description: Unset<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub embed_footer: Unset<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_optional_field")]
|
||||||
|
pub embed_footer_url: Unset<Option<String>>,
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_optional_field")]
|
||||||
|
pub embed_image_url: Unset<Option<String>>,
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_optional_field")]
|
||||||
|
pub embed_thumbnail_url: Unset<Option<String>>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub embed_title: Unset<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub embed_fields: Unset<Json<Vec<EmbedField>>>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub enabled: Unset<bool>,
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_optional_field")]
|
||||||
|
pub expires: Unset<Option<NaiveDateTime>>,
|
||||||
|
#[serde(default = "interval_default")]
|
||||||
|
#[serde(deserialize_with = "deserialize_optional_field")]
|
||||||
|
pub interval_seconds: Unset<Option<u32>>,
|
||||||
|
#[serde(default = "interval_default")]
|
||||||
|
#[serde(deserialize_with = "deserialize_optional_field")]
|
||||||
|
pub interval_days: Unset<Option<u32>>,
|
||||||
|
#[serde(default = "interval_default")]
|
||||||
|
#[serde(deserialize_with = "deserialize_optional_field")]
|
||||||
|
pub interval_months: Unset<Option<u32>>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub name: Unset<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub tts: Unset<bool>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub utc_time: Unset<NaiveDateTime>,
|
||||||
|
}
|
||||||
|
@ -7,11 +7,16 @@ use serenity::{client::Context, model::id::UserId};
|
|||||||
use sqlx::{MySql, Pool};
|
use sqlx::{MySql, Pool};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
check_subscription,
|
||||||
guards::transaction::Transaction,
|
guards::transaction::Transaction,
|
||||||
routes::{
|
routes::{
|
||||||
dashboard::api::user::models::{create_reminder, Reminder},
|
dashboard::{
|
||||||
|
api::user::models::{create_reminder, Reminder},
|
||||||
|
PatchReminder, MIN_INTERVAL,
|
||||||
|
},
|
||||||
JsonResult,
|
JsonResult,
|
||||||
},
|
},
|
||||||
|
Database,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[post("/api/user/reminders", data = "<reminder>")]
|
#[post("/api/user/reminders", data = "<reminder>")]
|
||||||
@ -103,3 +108,174 @@ pub async fn get_reminders(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[patch("/api/user/reminders", data = "<reminder>")]
|
||||||
|
pub async fn edit_reminder(
|
||||||
|
reminder: Json<PatchReminder>,
|
||||||
|
ctx: &State<Context>,
|
||||||
|
mut transaction: Transaction<'_>,
|
||||||
|
pool: &State<Pool<Database>>,
|
||||||
|
cookies: &CookieJar<'_>,
|
||||||
|
) -> JsonResult {
|
||||||
|
let user_id_cookie =
|
||||||
|
cookies.get_private("userid").map(|c| c.value().parse::<u64>().ok()).flatten();
|
||||||
|
|
||||||
|
if user_id_cookie.is_none() {
|
||||||
|
return Err(json!({"error": "User not authorized"}));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut error = vec![];
|
||||||
|
let user_id = user_id_cookie.unwrap();
|
||||||
|
|
||||||
|
if reminder.message_ok() {
|
||||||
|
update_field!(transaction.executor(), error, reminder.[
|
||||||
|
content,
|
||||||
|
embed_author,
|
||||||
|
embed_description,
|
||||||
|
embed_footer,
|
||||||
|
embed_title,
|
||||||
|
embed_fields
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
error.push("Message exceeds limits.".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
update_field!(transaction.executor(), error, reminder.[
|
||||||
|
attachment,
|
||||||
|
attachment_name,
|
||||||
|
embed_author_url,
|
||||||
|
embed_color,
|
||||||
|
embed_footer_url,
|
||||||
|
embed_image_url,
|
||||||
|
embed_thumbnail_url,
|
||||||
|
enabled,
|
||||||
|
expires,
|
||||||
|
name,
|
||||||
|
tts,
|
||||||
|
utc_time
|
||||||
|
]);
|
||||||
|
|
||||||
|
if reminder.interval_days.flatten().is_some()
|
||||||
|
|| reminder.interval_months.flatten().is_some()
|
||||||
|
|| reminder.interval_seconds.flatten().is_some()
|
||||||
|
{
|
||||||
|
if check_subscription(&ctx.inner(), user_id).await {
|
||||||
|
let new_interval_length = match reminder.interval_days {
|
||||||
|
Some(interval) => interval.unwrap_or(0),
|
||||||
|
None => sqlx::query!(
|
||||||
|
"SELECT interval_days AS days FROM reminders WHERE uid = ?",
|
||||||
|
reminder.uid
|
||||||
|
)
|
||||||
|
.fetch_one(transaction.executor())
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
warn!("Error updating reminder interval: {:?}", e);
|
||||||
|
json!({ "reminder": Option::<Reminder>::None, "errors": vec!["Unknown error"] })
|
||||||
|
})?
|
||||||
|
.days
|
||||||
|
.unwrap_or(0),
|
||||||
|
} * 86400 + match reminder.interval_months {
|
||||||
|
Some(interval) => interval.unwrap_or(0),
|
||||||
|
None => sqlx::query!(
|
||||||
|
"SELECT interval_months AS months FROM reminders WHERE uid = ?",
|
||||||
|
reminder.uid
|
||||||
|
)
|
||||||
|
.fetch_one(transaction.executor())
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
warn!("Error updating reminder interval: {:?}", e);
|
||||||
|
json!({ "reminder": Option::<Reminder>::None, "errors": vec!["Unknown error"] })
|
||||||
|
})?
|
||||||
|
.months
|
||||||
|
.unwrap_or(0),
|
||||||
|
} * 2592000 + match reminder.interval_seconds {
|
||||||
|
Some(interval) => interval.unwrap_or(0),
|
||||||
|
None => sqlx::query!(
|
||||||
|
"SELECT interval_seconds AS seconds FROM reminders WHERE uid = ?",
|
||||||
|
reminder.uid
|
||||||
|
)
|
||||||
|
.fetch_one(transaction.executor())
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
warn!("Error updating reminder interval: {:?}", e);
|
||||||
|
json!({ "reminder": Option::<Reminder>::None, "errors": vec!["Unknown error"] })
|
||||||
|
})?
|
||||||
|
.seconds
|
||||||
|
.unwrap_or(0),
|
||||||
|
};
|
||||||
|
|
||||||
|
if new_interval_length < *MIN_INTERVAL {
|
||||||
|
error.push(String::from("New interval is too short."));
|
||||||
|
} else {
|
||||||
|
update_field!(transaction.executor(), error, reminder.[
|
||||||
|
interval_days,
|
||||||
|
interval_months,
|
||||||
|
interval_seconds
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sqlx::query!(
|
||||||
|
"
|
||||||
|
UPDATE reminders
|
||||||
|
SET interval_seconds = NULL, interval_days = NULL, interval_months = NULL
|
||||||
|
WHERE uid = ?
|
||||||
|
",
|
||||||
|
reminder.uid
|
||||||
|
)
|
||||||
|
.execute(transaction.executor())
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
warn!("Error updating reminder interval: {:?}", e);
|
||||||
|
json!({ "reminder": Option::<Reminder>::None, "errors": vec!["Unknown error"] })
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(e) = transaction.commit().await {
|
||||||
|
warn!("Couldn't commit transaction: {:?}", e);
|
||||||
|
return json_err!("Couldn't commit transaction");
|
||||||
|
}
|
||||||
|
|
||||||
|
match sqlx::query_as_unchecked!(
|
||||||
|
Reminder,
|
||||||
|
"
|
||||||
|
SELECT reminders.attachment,
|
||||||
|
reminders.attachment_name,
|
||||||
|
reminders.content,
|
||||||
|
reminders.embed_author,
|
||||||
|
reminders.embed_author_url,
|
||||||
|
reminders.embed_color,
|
||||||
|
reminders.embed_description,
|
||||||
|
reminders.embed_footer,
|
||||||
|
reminders.embed_footer_url,
|
||||||
|
reminders.embed_image_url,
|
||||||
|
reminders.embed_thumbnail_url,
|
||||||
|
reminders.embed_title,
|
||||||
|
reminders.embed_fields,
|
||||||
|
reminders.enabled,
|
||||||
|
reminders.expires,
|
||||||
|
reminders.interval_seconds,
|
||||||
|
reminders.interval_days,
|
||||||
|
reminders.interval_months,
|
||||||
|
reminders.name,
|
||||||
|
reminders.tts,
|
||||||
|
reminders.uid,
|
||||||
|
reminders.utc_time
|
||||||
|
FROM reminders
|
||||||
|
LEFT JOIN channels ON channels.id = reminders.channel_id
|
||||||
|
WHERE uid = ?
|
||||||
|
",
|
||||||
|
reminder.uid
|
||||||
|
)
|
||||||
|
.fetch_one(pool.inner())
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(reminder) => Ok(json!({"reminder": reminder, "errors": error})),
|
||||||
|
|
||||||
|
Err(e) => {
|
||||||
|
warn!("Error exiting `edit_reminder': {:?}", e);
|
||||||
|
|
||||||
|
Err(json!({"reminder": Option::<Reminder>::None, "errors": vec!["Unknown error"]}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user