add: reposts/quotes pages

add: repost notification
This commit is contained in:
trisua 2025-04-23 16:46:13 -04:00
parent 41250ef7ed
commit 276f25a496
17 changed files with 601 additions and 50 deletions

View file

@ -121,6 +121,7 @@ impl DataManager {
pub async fn fill_posts(
&self,
posts: Vec<Post>,
ignore_users: &Vec<usize>,
) -> Result<Vec<(Post, User, Option<(User, Post)>, Option<(Question, User)>)>> {
let mut out: Vec<(Post, User, Option<(User, Post)>, Option<(Question, User)>)> = Vec::new();
@ -128,6 +129,10 @@ impl DataManager {
for post in posts {
let owner = post.owner;
if ignore_users.contains(&owner) {
continue;
}
if let Some(user) = users.get(&owner) {
out.push((
post.clone(),
@ -155,6 +160,7 @@ impl DataManager {
&self,
posts: Vec<Post>,
user_id: usize,
ignore_users: &Vec<usize>,
) -> Result<
Vec<(
Post,
@ -177,6 +183,11 @@ impl DataManager {
for post in posts {
let owner = post.owner;
if ignore_users.contains(&owner) {
continue;
}
let community = post.community;
if let Some((user, community)) = seen_before.get(&(owner, community)) {
@ -402,6 +413,82 @@ impl DataManager {
Ok(res.unwrap())
}
/// Get all quoting posts by the post their quoting.
///
/// Requires that the post has content. See [`Self::get_reposts_by_quoting`]
/// for the no-content version.
///
/// # Arguments
/// * `id` - the ID of the post that is being quoted
/// * `batch` - the limit of posts in each page
/// * `page` - the page number
pub async fn get_quoting_posts_by_quoting(
&self,
id: usize,
batch: usize,
page: usize,
) -> Result<Vec<Post>> {
let conn = match self.connect().await {
Ok(c) => c,
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
};
let res = query_rows!(
&conn,
"SELECT * FROM posts WHERE NOT content = '' AND context LIKE $1 ORDER BY created DESC LIMIT $2 OFFSET $3",
params![
&format!("%\"reposting\":{id}%"),
&(batch as i64),
&((page * batch) as i64)
],
|x| { Self::get_post_from_row(x) }
);
if res.is_err() {
return Err(Error::GeneralNotFound("post".to_string()));
}
Ok(res.unwrap())
}
/// Get all quoting posts by the post their quoting.
///
/// Requires that the post has no content. See [`Self::get_quoting_posts_by_quoting`]
/// for the content-required version.
///
/// # Arguments
/// * `id` - the ID of the post that is being quoted
/// * `batch` - the limit of posts in each page
/// * `page` - the page number
pub async fn get_reposts_by_quoting(
&self,
id: usize,
batch: usize,
page: usize,
) -> Result<Vec<Post>> {
let conn = match self.connect().await {
Ok(c) => c,
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
};
let res = query_rows!(
&conn,
"SELECT * FROM posts WHERE content = '' AND context LIKE $1 ORDER BY created DESC LIMIT $2 OFFSET $3",
params![
&format!("%\"reposting\":{id}%"),
&(batch as i64),
&((page * batch) as i64)
],
|x| { Self::get_post_from_row(x) }
);
if res.is_err() {
return Err(Error::GeneralNotFound("post".to_string()));
}
Ok(res.unwrap())
}
/// Get posts from all communities, sorted by likes.
///
/// # Arguments
@ -694,6 +781,25 @@ impl DataManager {
{
return Err(Error::NotAllowed);
}
// send notification
// this would look better if rustfmt didn't give up on this line
if owner.id != rt.owner {
self.create_notification(
Notification::new(
format!(
"[@{}](/api/v1/auth/user/find/{}) has [quoted](/post/{}) your [post](/post/{})",
owner.username,
owner.id,
data.id,
rt.id
),
format!("\"{}\"", data.content),
rt.owner
)
)
.await?;
}
}
// check if the post we're replying to allows commments
@ -729,8 +835,8 @@ impl DataManager {
self.create_notification(Notification::new(
"You've been mentioned in a post!".to_string(),
format!(
"[Somebody](/api/v1/auth/user/find/{}) mentioned you in their [post](/post/{}).",
data.owner, data.id
"[@{}](/api/v1/auth/user/find/{}) has mentioned you in their [post](/post/{}).",
owner.username, owner.id, data.id
),
user.id,
))