You've already forked AstralRinth
forked from didirus/AstralRinth
Small friends fixes (#4270)
* Ensure that fetch errors are properly propagated * Handle user not found errors better in add_friend * Cargo fmt * Introduce new LabrinthError returnable by fetch_advanced * Allow enter key to send a friend request
This commit is contained in:
@@ -250,7 +250,13 @@ onUnmounted(() => {
|
||||
<div class="mb-4">
|
||||
<h2 class="m-0 text-lg font-extrabold text-contrast">Username</h2>
|
||||
<p class="m-0 mt-1 leading-tight">You can add friends with their Modrinth username.</p>
|
||||
<input v-model="username" class="mt-2 w-full" type="text" placeholder="Enter username..." />
|
||||
<input
|
||||
v-model="username"
|
||||
class="mt-2 w-full"
|
||||
type="text"
|
||||
placeholder="Enter username..."
|
||||
@keyup.enter="addFriendFromModal"
|
||||
/>
|
||||
</div>
|
||||
<ButtonStyled color="brand">
|
||||
<button :disabled="username.length === 0" @click="addFriendFromModal">
|
||||
|
||||
@@ -189,7 +189,7 @@ impl Role {
|
||||
pub struct UserFriend {
|
||||
// The user who accepted the friend request
|
||||
pub id: UserId,
|
||||
/// THe user who sent the friend request
|
||||
/// The user who sent the friend request
|
||||
pub friend_id: UserId,
|
||||
pub accepted: bool,
|
||||
pub created: DateTime<Utc>,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::auth::get_user_from_headers;
|
||||
use crate::database::models::DBUserId;
|
||||
use crate::database::models::friend_item::DBFriend;
|
||||
use crate::database::models::{DBUser, DBUserId};
|
||||
use crate::database::redis::RedisPool;
|
||||
use crate::models::pats::Scopes;
|
||||
use crate::models::users::UserFriend;
|
||||
@@ -42,102 +43,94 @@ pub async fn add_friend(
|
||||
.1;
|
||||
|
||||
let string = info.into_inner().0;
|
||||
let friend =
|
||||
crate::database::models::DBUser::get(&string, &**pool, &redis).await?;
|
||||
let Some(friend) = DBUser::get(&string, &**pool, &redis).await? else {
|
||||
return Err(ApiError::NotFound);
|
||||
};
|
||||
|
||||
if let Some(friend) = friend {
|
||||
let mut transaction = pool.begin().await?;
|
||||
let mut transaction = pool.begin().await?;
|
||||
|
||||
if let Some(friend) =
|
||||
crate::database::models::friend_item::DBFriend::get_friend(
|
||||
user.id.into(),
|
||||
friend.id,
|
||||
&**pool,
|
||||
)
|
||||
.await?
|
||||
{
|
||||
if friend.accepted {
|
||||
return Err(ApiError::InvalidInput(
|
||||
"You are already friends with this user!".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
if !friend.accepted && user.id != friend.friend_id.into() {
|
||||
return Err(ApiError::InvalidInput(
|
||||
"You cannot accept your own friend request!".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
crate::database::models::friend_item::DBFriend::update_friend(
|
||||
friend.user_id,
|
||||
friend.friend_id,
|
||||
true,
|
||||
&mut transaction,
|
||||
)
|
||||
.await?;
|
||||
|
||||
async fn send_friend_status(
|
||||
user_id: DBUserId,
|
||||
friend_id: DBUserId,
|
||||
sockets: &ActiveSockets,
|
||||
redis: &RedisPool,
|
||||
) -> Result<(), ApiError> {
|
||||
if let Some(friend_status) =
|
||||
get_user_status(user_id.into(), sockets, redis).await
|
||||
{
|
||||
broadcast_friends_message(
|
||||
redis,
|
||||
RedisFriendsMessage::DirectStatusUpdate {
|
||||
to_user: friend_id.into(),
|
||||
status: friend_status,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
send_friend_status(friend.user_id, friend.friend_id, &db, &redis)
|
||||
.await?;
|
||||
send_friend_status(friend.friend_id, friend.user_id, &db, &redis)
|
||||
.await?;
|
||||
} else {
|
||||
if friend.id == user.id.into() {
|
||||
return Err(ApiError::InvalidInput(
|
||||
"You cannot add yourself as a friend!".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
if !friend.allow_friend_requests {
|
||||
return Err(ApiError::InvalidInput(
|
||||
"Friend requests are disabled for this user!".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
crate::database::models::friend_item::DBFriend {
|
||||
user_id: user.id.into(),
|
||||
friend_id: friend.id,
|
||||
created: Utc::now(),
|
||||
accepted: false,
|
||||
}
|
||||
.insert(&mut transaction)
|
||||
.await?;
|
||||
|
||||
send_message_to_user(
|
||||
&db,
|
||||
friend.id.into(),
|
||||
&ServerToClientMessage::FriendRequest { from: user.id },
|
||||
)
|
||||
.await?;
|
||||
if let Some(friend) =
|
||||
DBFriend::get_friend(user.id.into(), friend.id, &**pool).await?
|
||||
{
|
||||
if friend.accepted {
|
||||
return Err(ApiError::InvalidInput(
|
||||
"You are already friends with this user!".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
transaction.commit().await?;
|
||||
if !friend.accepted && user.id != friend.friend_id.into() {
|
||||
return Err(ApiError::InvalidInput(
|
||||
"You cannot accept your own friend request!".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(HttpResponse::NoContent().body(""))
|
||||
DBFriend::update_friend(
|
||||
friend.user_id,
|
||||
friend.friend_id,
|
||||
true,
|
||||
&mut transaction,
|
||||
)
|
||||
.await?;
|
||||
|
||||
async fn send_friend_status(
|
||||
user_id: DBUserId,
|
||||
friend_id: DBUserId,
|
||||
sockets: &ActiveSockets,
|
||||
redis: &RedisPool,
|
||||
) -> Result<(), ApiError> {
|
||||
if let Some(friend_status) =
|
||||
get_user_status(user_id.into(), sockets, redis).await
|
||||
{
|
||||
broadcast_friends_message(
|
||||
redis,
|
||||
RedisFriendsMessage::DirectStatusUpdate {
|
||||
to_user: friend_id.into(),
|
||||
status: friend_status,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
send_friend_status(friend.user_id, friend.friend_id, &db, &redis)
|
||||
.await?;
|
||||
send_friend_status(friend.friend_id, friend.user_id, &db, &redis)
|
||||
.await?;
|
||||
} else {
|
||||
Err(ApiError::NotFound)
|
||||
if friend.id == user.id.into() {
|
||||
return Err(ApiError::InvalidInput(
|
||||
"You cannot add yourself as a friend!".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
if !friend.allow_friend_requests {
|
||||
return Err(ApiError::InvalidInput(
|
||||
"Friend requests are disabled for this user!".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
DBFriend {
|
||||
user_id: user.id.into(),
|
||||
friend_id: friend.id,
|
||||
created: Utc::now(),
|
||||
accepted: false,
|
||||
}
|
||||
.insert(&mut transaction)
|
||||
.await?;
|
||||
|
||||
send_message_to_user(
|
||||
&db,
|
||||
friend.id.into(),
|
||||
&ServerToClientMessage::FriendRequest { from: user.id },
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
transaction.commit().await?;
|
||||
|
||||
Ok(HttpResponse::NoContent().body(""))
|
||||
}
|
||||
|
||||
#[delete("friend/{id}")]
|
||||
@@ -160,18 +153,12 @@ pub async fn remove_friend(
|
||||
.1;
|
||||
|
||||
let string = info.into_inner().0;
|
||||
let friend =
|
||||
crate::database::models::DBUser::get(&string, &**pool, &redis).await?;
|
||||
let friend = DBUser::get(&string, &**pool, &redis).await?;
|
||||
|
||||
if let Some(friend) = friend {
|
||||
let mut transaction = pool.begin().await?;
|
||||
|
||||
crate::database::models::friend_item::DBFriend::remove(
|
||||
user.id.into(),
|
||||
friend.id,
|
||||
&mut transaction,
|
||||
)
|
||||
.await?;
|
||||
DBFriend::remove(user.id.into(), friend.id, &mut transaction).await?;
|
||||
|
||||
send_message_to_user(
|
||||
&db,
|
||||
@@ -205,12 +192,7 @@ pub async fn friends(
|
||||
.await?
|
||||
.1;
|
||||
|
||||
let friends =
|
||||
crate::database::models::friend_item::DBFriend::get_user_friends(
|
||||
user.id.into(),
|
||||
None,
|
||||
&**pool,
|
||||
)
|
||||
let friends = DBFriend::get_user_friends(user.id.into(), None, &**pool)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(UserFriend::from)
|
||||
|
||||
Reference in New Issue
Block a user