feat: add friends!

This commit is contained in:
Radical 2025-07-10 15:37:38 +02:00
parent ac3e7e242b
commit e8b8b49643
13 changed files with 439 additions and 39 deletions

View file

@ -1,15 +1,40 @@
use chrono::{DateTime, Utc};
use diesel::{ExpressionMethods, QueryDsl, Queryable, Selectable, SelectableHelper};
use diesel_async::RunQueryDsl;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::{Conn, Data, error::Error, schema::users};
use crate::{error::Error, objects::Me, schema::users, Conn, Data};
use super::load_or_empty;
#[derive(Deserialize, Serialize, Clone, Queryable, Selectable)]
#[diesel(table_name = users)]
#[diesel(check_for_backend(diesel::pg::Pg))]
pub struct UserBuilder {
uuid: Uuid,
username: String,
display_name: Option<String>,
avatar: Option<String>,
pronouns: Option<String>,
about: Option<String>,
}
impl UserBuilder {
fn build(self) -> User {
User {
uuid: self.uuid,
username: self.username,
display_name: self.display_name,
avatar: self.avatar,
pronouns: self.pronouns,
about: self.about,
friends_since: None,
}
}
}
#[derive(Deserialize, Serialize, Clone)]
pub struct User {
uuid: Uuid,
username: String,
@ -17,6 +42,7 @@ pub struct User {
avatar: Option<String>,
pronouns: Option<String>,
about: Option<String>,
friends_since: Option<DateTime<Utc>>,
}
impl User {
@ -28,33 +54,49 @@ impl User {
}
use users::dsl;
let user: User = dsl::users
let user_builder: UserBuilder = dsl::users
.filter(dsl::uuid.eq(user_uuid))
.select(User::as_select())
.select(UserBuilder::as_select())
.get_result(&mut conn)
.await?;
let user = user_builder.build();
data.set_cache_key(user_uuid.to_string(), user.clone(), 1800)
.await?;
Ok(user)
}
pub async fn fetch_one_with_friendship(data: &Data, me: &Me, user_uuid: Uuid) -> Result<Self, Error> {
let mut conn = data.pool.get().await?;
let mut user = Self::fetch_one(data, user_uuid).await?;
if let Some(friend) = me.friends_with(&mut conn, user_uuid).await? {
user.friends_since = Some(friend.accepted_at);
}
Ok(user)
}
pub async fn fetch_amount(
conn: &mut Conn,
offset: i64,
amount: i64,
) -> Result<Vec<Self>, Error> {
use users::dsl;
let users: Vec<User> = load_or_empty(
let user_builders: Vec<UserBuilder> = load_or_empty(
dsl::users
.limit(amount)
.offset(offset)
.select(User::as_select())
.select(UserBuilder::as_select())
.load(conn)
.await,
)?;
let users: Vec<User> = user_builders.iter().map(|u| u.clone().build()).collect();
Ok(users)
}
}