Wire up UI for requesting contacts and cancelling requests

Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
Nathan Sobo 2022-05-09 11:24:05 -06:00
parent e4f1952657
commit e3ee19b123
7 changed files with 212 additions and 32 deletions

View file

@ -19,6 +19,7 @@ pub trait Db: Send + Sync {
async fn get_contacts(&self, id: UserId) -> Result<Contacts>;
async fn send_contact_request(&self, requester_id: UserId, responder_id: UserId) -> Result<()>;
async fn remove_contact(&self, requester_id: UserId, responder_id: UserId) -> Result<()>;
async fn dismiss_contact_request(
&self,
responder_id: UserId,
@ -267,6 +268,30 @@ impl Db for PostgresDb {
}
}
async fn remove_contact(&self, requester_id: UserId, responder_id: UserId) -> Result<()> {
let (id_a, id_b, a_to_b) = if responder_id < requester_id {
(responder_id, requester_id, false)
} else {
(requester_id, responder_id, true)
};
let query = "
DELETE FROM contacts
WHERE user_id_a = $1 AND user_id_b = $2 AND a_to_b = $3;
";
let result = sqlx::query(query)
.bind(id_a.0)
.bind(id_b.0)
.bind(a_to_b)
.execute(&self.pool)
.await?;
if result.rows_affected() == 1 {
Ok(())
} else {
Err(anyhow!("no such contact"))
}
}
async fn respond_to_contact_request(
&self,
responder_id: UserId,
@ -1248,6 +1273,13 @@ pub mod tests {
Ok(())
}
async fn remove_contact(&self, requester_id: UserId, responder_id: UserId) -> Result<()> {
self.contacts.lock().retain(|contact| {
!(contact.requester_id == requester_id && contact.responder_id == responder_id)
});
Ok(())
}
async fn dismiss_contact_request(
&self,
responder_id: UserId,

View file

@ -155,6 +155,7 @@ impl Server {
.add_request_handler(Server::get_users)
.add_request_handler(Server::fuzzy_search_users)
.add_request_handler(Server::request_contact)
.add_request_handler(Server::remove_contact)
.add_request_handler(Server::respond_to_contact_request)
.add_request_handler(Server::join_channel)
.add_message_handler(Server::leave_channel)
@ -1048,6 +1049,43 @@ impl Server {
Ok(())
}
async fn remove_contact(
self: Arc<Server>,
request: TypedEnvelope<proto::RemoveContact>,
response: Response<proto::RemoveContact>,
) -> Result<()> {
let requester_id = self
.store()
.await
.user_id_for_connection(request.sender_id)?;
let responder_id = UserId::from_proto(request.payload.user_id);
self.app_state
.db
.remove_contact(requester_id, responder_id)
.await?;
// Update outgoing contact requests of requester
let mut update = proto::UpdateContacts::default();
update
.remove_outgoing_requests
.push(responder_id.to_proto());
for connection_id in self.store().await.connection_ids_for_user(requester_id) {
self.peer.send(connection_id, update.clone())?;
}
// Update incoming contact requests of responder
let mut update = proto::UpdateContacts::default();
update
.remove_incoming_requests
.push(requester_id.to_proto());
for connection_id in self.store().await.connection_ids_for_user(responder_id) {
self.peer.send(connection_id, update.clone())?;
}
response.send(proto::Ack {})?;
Ok(())
}
// #[instrument(skip(self, state, user_ids))]
// fn update_contacts_for_users<'a>(
// self: &Arc<Self>,
@ -5138,15 +5176,15 @@ mod tests {
// User A and User C request that user B become their contact.
client_a
.user_store
.read_with(cx_a, |store, _| {
store.request_contact(client_b.user_id().unwrap())
.update(cx_a, |store, cx| {
store.request_contact(client_b.user_id().unwrap(), cx)
})
.await
.unwrap();
client_c
.user_store
.read_with(cx_c, |store, _| {
store.request_contact(client_b.user_id().unwrap())
.update(cx_c, |store, cx| {
store.request_contact(client_b.user_id().unwrap(), cx)
})
.await
.unwrap();
@ -6460,8 +6498,8 @@ mod tests {
for (client_b, cx_b) in &mut clients {
client_a
.user_store
.update(cx_a, |store, _| {
store.request_contact(client_b.user_id().unwrap())
.update(cx_a, |store, cx| {
store.request_contact(client_b.user_id().unwrap(), cx)
})
.await
.unwrap();