add: mail ui
This commit is contained in:
parent
2e60cbc464
commit
b2a73d286b
24 changed files with 993 additions and 259 deletions
|
@ -5,5 +5,6 @@ CREATE TABLE IF NOT EXISTS letters (
|
|||
receivers TEXT NOT NULL,
|
||||
subject TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
read_by TEXT NOT NULL
|
||||
read_by TEXT NOT NULL,
|
||||
replying_to BIGINT NOT NULL
|
||||
)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::model::{auth::User, mail::Letter, permissions::SecondaryPermission, Error, Result};
|
||||
use crate::{auto_method, DataManager};
|
||||
use oiseau::{cache::Cache, execute, get, params, query_rows, PostgresRow};
|
||||
|
@ -13,7 +15,7 @@ impl DataManager {
|
|||
subject: get!(x->4(String)),
|
||||
content: get!(x->5(String)),
|
||||
read_by: serde_json::from_str(&get!(x->6(String))).unwrap(),
|
||||
replying_to: get!(x->7(i32)) as usize,
|
||||
replying_to: get!(x->7(i64)) as usize,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +25,14 @@ impl DataManager {
|
|||
///
|
||||
/// # Arguments
|
||||
/// * `id` - the ID of the user to fetch letters for
|
||||
pub async fn get_letters_by_user(&self, id: usize) -> Result<Vec<Letter>> {
|
||||
/// * `batch` - the limit of items in each page
|
||||
/// * `page` - the page number
|
||||
pub async fn get_letters_by_user(
|
||||
&self,
|
||||
id: usize,
|
||||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Letter>> {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
|
@ -31,8 +40,8 @@ impl DataManager {
|
|||
|
||||
let res = query_rows!(
|
||||
&conn,
|
||||
"SELECT * FROM letters WHERE owner = $1 ORDER BY created DESC",
|
||||
&[&(id as i64)],
|
||||
"SELECT * FROM letters WHERE owner = $1 ORDER BY created DESC LIMIT $2 OFFSET $3",
|
||||
&[&(id as i64), &(batch as i64), &((page * batch) as i64)],
|
||||
|x| { Self::get_letter_from_row(x) }
|
||||
);
|
||||
|
||||
|
@ -47,7 +56,14 @@ impl DataManager {
|
|||
///
|
||||
/// # Arguments
|
||||
/// * `id` - the ID of the user to fetch letters for
|
||||
pub async fn get_received_letters_by_user(&self, id: usize) -> Result<Vec<Letter>> {
|
||||
/// * `batch` - the limit of items in each page
|
||||
/// * `page` - the page number
|
||||
pub async fn get_received_letters_by_user(
|
||||
&self,
|
||||
id: usize,
|
||||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Letter>> {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
|
@ -55,8 +71,12 @@ impl DataManager {
|
|||
|
||||
let res = query_rows!(
|
||||
&conn,
|
||||
"SELECT * FROM letters WHERE receivers LIKE $1 ORDER BY created DESC",
|
||||
&[&format!("%\"{id}\"%")],
|
||||
"SELECT * FROM letters WHERE receivers LIKE $1 ORDER BY created DESC LIMIT $2 OFFSET $3",
|
||||
&[
|
||||
&format!("%{id}%"),
|
||||
&(batch as i64),
|
||||
&((page * batch) as i64)
|
||||
],
|
||||
|x| { Self::get_letter_from_row(x) }
|
||||
);
|
||||
|
||||
|
@ -71,7 +91,14 @@ impl DataManager {
|
|||
///
|
||||
/// # Arguments
|
||||
/// * `id` - the ID of the letter to fetch letters for
|
||||
pub async fn get_letters_by_replying_to(&self, id: usize) -> Result<Vec<Letter>> {
|
||||
/// * `batch` - the limit of items in each page
|
||||
/// * `page` - the page number
|
||||
pub async fn get_letters_by_replying_to(
|
||||
&self,
|
||||
id: usize,
|
||||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Letter>> {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
|
@ -79,8 +106,8 @@ impl DataManager {
|
|||
|
||||
let res = query_rows!(
|
||||
&conn,
|
||||
"SELECT * FROM letters WHERE replying_to = $1 ORDER BY created DESC",
|
||||
&[&(id as i64)],
|
||||
"SELECT * FROM letters WHERE replying_to = $1 ORDER BY created DESC LIMIT $2 OFFSET $3",
|
||||
&[&(id as i64), &(batch as i64), &((page * batch) as i64)],
|
||||
|x| { Self::get_letter_from_row(x) }
|
||||
);
|
||||
|
||||
|
@ -91,6 +118,24 @@ impl DataManager {
|
|||
Ok(res.unwrap())
|
||||
}
|
||||
|
||||
/// Fill a list of letters with their owner.
|
||||
pub async fn fill_letters(&self, letters: Vec<Letter>) -> Result<Vec<(User, Letter)>> {
|
||||
let mut seen_users: HashMap<usize, User> = HashMap::new();
|
||||
let mut out = Vec::new();
|
||||
|
||||
for letter in letters {
|
||||
out.push(if let Some(ua) = seen_users.get(&letter.owner) {
|
||||
(ua.to_owned(), letter)
|
||||
} else {
|
||||
let user = self.get_user_by_id(letter.owner).await?;
|
||||
seen_users.insert(letter.owner, user.clone());
|
||||
(user, letter)
|
||||
})
|
||||
}
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
/// Create a new letter in the database.
|
||||
///
|
||||
/// # Arguments
|
||||
|
@ -109,6 +154,12 @@ impl DataManager {
|
|||
return Err(Error::DataTooLong("content".to_string()));
|
||||
}
|
||||
|
||||
if data.receivers.len() < 1 {
|
||||
return Err(Error::DataTooShort("receivers".to_string()));
|
||||
} else if data.receivers.len() > 10 {
|
||||
return Err(Error::DataTooLong("receivers".to_string()));
|
||||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue