Skip to content

Commit

Permalink
feat: friend requests
Browse files Browse the repository at this point in the history
  • Loading branch information
infiniwave committed Jan 31, 2025
1 parent 16a1c9a commit 3bfcda7
Show file tree
Hide file tree
Showing 8 changed files with 322 additions and 62 deletions.
2 changes: 1 addition & 1 deletion crates/harmony/src/methods/channels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub async fn get_channel(
}
Channel::InformationChannel { ref space_id, .. }
| Channel::AnnouncementChannel { ref space_id, .. }
| Channel::ChatChannel { ref space_id, .. } => {
| Channel::StandardChannel { ref space_id, .. } => {
if let Some(request_space_id) = &data.space_id {
if request_space_id != space_id {
return Err(Error::NotFound);
Expand Down
52 changes: 18 additions & 34 deletions crates/harmony/src/methods/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@

use std::sync::Arc;

use dashmap::{mapref::multiple::RefMulti, DashMap};
use rapid::socket::{emit_one, RpcClient};
use serde::{Deserialize, Serialize};

use crate::services::database::messages::Message;
use crate::services::database::{messages::Message, users::User};

pub mod channels;
pub mod events;
Expand Down Expand Up @@ -63,35 +67,6 @@ pub mod webrtc;
// pub(crate) method: Method,
// }

#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AddFriendMethod {
channel_id: String,
friend_id: String,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RemoveFriendMethod {
channel_id: String,
friend_id: String,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetFriendsMethod {}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetFriendRequestsMethod {}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AcknowledgeFriendRequestMethod {
channel_id: String,
friend_id: String,
}

// #[derive(Clone, Debug, Deserialize, Serialize)]
// pub struct RpcApiResponse {
// #[serde(skip_serializing_if = "Option::is_none")]
Expand All @@ -105,13 +80,12 @@ pub struct AcknowledgeFriendRequestMethod {
// }

#[derive(Clone, Debug, Deserialize, Serialize)]
#[repr(i8)]
#[serde(tag = "type", content = "data", rename_all = "SCREAMING_SNAKE_CASE")]
pub enum Event {
Hello(HelloEvent) = 0,

// WebRTC: 10-19
NewMessage(NewMessageEvent) = 21,
NewMessage(NewMessageEvent),
RemoveFriend(String),
AddFriend(String),
}

#[derive(Clone, Debug, Deserialize, Serialize)]
Expand Down Expand Up @@ -158,3 +132,13 @@ pub enum CreateChannelType {
scope_id: String,
},
}

pub fn emit_to_id(clients: Arc<DashMap<String, RpcClient>>, user_id: &str, event: Event) {
let client: Vec<RefMulti<'_, String, RpcClient>> = clients.iter().filter(|client| {
let i = client.get_user::<User>().map(|u| u.id.clone());
i == Some(user_id.to_owned())
}).collect();
for client in client {
emit_one(client.value(), RpcApiEvent { event: event.clone() });
}
}
79 changes: 79 additions & 0 deletions crates/harmony/src/methods/users.rs
Original file line number Diff line number Diff line change
@@ -1 +1,80 @@

// 1. add friend
// 2. remove friend
// 3. get friends
// 4. get friend requests
// 5. create direct channel
// 6. get direct channels

use std::sync::Arc;

use dashmap::DashMap;
use rapid::socket::{RpcClient, RpcResponder, RpcValue};
use serde::{Deserialize, Serialize};

use crate::{authentication::check_authenticated, errors::Error, services::database::users::User};

#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AddFriendMethod {
id: String,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AddFriendUsernameMethod {
username: String,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct AddFriendResponse {}

pub async fn add_friend(
clients: Arc<DashMap<String, RpcClient>>,
id: String,
data: RpcValue<AddFriendMethod>,
) -> impl RpcResponder {
check_authenticated(clients, &id)?;
let data = data.into_inner();
let user = User::get(&id).await?;
let friend = User::get(&data.id).await?;
User::add_friend(&user, &friend.id).await?;
Ok::<_, Error>(RpcValue(AddFriendResponse { }))
}

pub async fn add_friend_username(
clients: Arc<DashMap<String, RpcClient>>,
id: String,
data: RpcValue<AddFriendUsernameMethod>,
) -> impl RpcResponder {
check_authenticated(clients, &id)?;
let data = data.into_inner();
let user = User::get(&id).await?;
let friend = User::get_by_username(&data.username).await?;
User::add_friend(&user, &friend.id).await?;
Ok::<_, Error>(RpcValue(AddFriendResponse { }))
}

pub async fn remove_friend(
clients: Arc<DashMap<String, RpcClient>>,
id: String,
data: RpcValue<AddFriendMethod>,
) -> impl RpcResponder {
check_authenticated(clients, &id)?;
let data = data.into_inner();
let user = User::get(&id).await?;
let friend = User::get(&data.id).await?;
user.remove_friend(&friend.id).await?;
Ok::<_, Error>(RpcValue(AddFriendResponse { }))
}

pub async fn get_friends(
clients: Arc<DashMap<String, RpcClient>>,
id: String,
_data: RpcValue<()>,
) -> impl RpcResponder {
check_authenticated(clients, &id)?;
let user = User::get(&id).await?;
let friends = user.get_affinities().await?;
Ok::<_, Error>(RpcValue(friends))
}

14 changes: 11 additions & 3 deletions crates/harmony/src/services/database/channels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub enum Channel {
scope_id: String,
permissions: Vec<PermissionOverride>,
},
ChatChannel {
StandardChannel {
id: String,
name: String,
description: String,
Expand All @@ -49,6 +49,14 @@ pub enum Channel {
// TODO: permission checks
permissions: Vec<PermissionOverride>,
},
// ForumChannel {
// id: String,
// name: String,
// description: String,
// space_id: String,
// scope_id: String,
// permissions: Vec<PermissionOverride>,
// },
}

impl Channel {
Expand All @@ -73,7 +81,7 @@ impl Channel {
after: Option<String>,
) -> Result<Vec<Message>> {
match self {
Channel::AnnouncementChannel { id, .. } | Channel::ChatChannel { id, .. } => {
Channel::AnnouncementChannel { id, .. } | Channel::StandardChannel { id, .. } => {
let database = super::get_database();
let limit = limit.unwrap_or(50);
let mut query = doc! { "channelId": id };
Expand Down Expand Up @@ -110,7 +118,7 @@ impl Channel {

pub async fn get_invites(&self) -> Result<Vec<Invite>> {
match self {
Channel::AnnouncementChannel { id, space_id, .. } | Channel::ChatChannel { id, space_id, .. } => {
Channel::AnnouncementChannel { id, space_id, .. } | Channel::StandardChannel { id, space_id, .. } => {
let database = super::get_database();
let query = doc! {
"channel_id": &id,
Expand Down
2 changes: 1 addition & 1 deletion crates/harmony/src/services/database/members.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl Member {
match channel {
Channel::InformationChannel { permissions, .. }
| Channel::AnnouncementChannel { permissions, .. }
| Channel::ChatChannel { permissions, .. } => {
| Channel::StandardChannel { permissions, .. } => {
let mut role_overrides = permissions
.iter()
.filter(|p| p.entity_type == EntityType::Role)
Expand Down
14 changes: 4 additions & 10 deletions crates/harmony/src/services/database/spaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,10 @@ pub struct Space {
// #[derive(Clone, Debug, Deserialize, Serialize)]
// #[serde(rename_all = "camelCase")]
// pub enum SpaceType {
// // Global,
// // Team,
// // Personal,
// // Organization,
// // Custom(String),
// Studio,
// Community,
// Personal,
// Organization,

// Global,
// Team,
// Studio,
// Community,
// }

impl Space {
Expand Down
Loading

0 comments on commit 3bfcda7

Please sign in to comment.