diff --git a/crates/quark/src/events/impl.rs b/crates/quark/src/events/impl.rs index 1c7e3e4a..d8bb85bf 100644 --- a/crates/quark/src/events/impl.rs +++ b/crates/quark/src/events/impl.rs @@ -23,8 +23,7 @@ impl Cache { pub async fn can_view_channel(&self, db: &Database, channel: &Channel) -> bool { match &channel { Channel::TextChannel { server, .. } | Channel::VoiceChannel { server, .. } => { - let member = self.members.values().find(|x| &x.id.server == server); - + let member = self.members.get(server); let server = self.servers.get(server); let mut perms = perms(self.users.get(&self.user_id).unwrap()).channel(channel); @@ -107,9 +106,15 @@ impl State { // Fetch all memberships with their corresponding servers. let members: Vec = db.fetch_all_memberships(&user.id).await?; + self.cache.members = members + .iter() + .cloned() + .map(|x| (x.id.server.clone(), x)) + .collect(); let server_ids: Vec = members.iter().map(|x| x.id.server.clone()).collect(); let servers = db.fetch_servers(&server_ids).await?; + self.cache.servers = servers.iter().cloned().map(|x| (x.id.clone(), x)).collect(); // Collect channel ids from servers. let mut channel_ids = vec![]; @@ -164,17 +169,11 @@ impl State { self.cache .users .insert(self.cache.user_id.clone(), user.clone()); - self.cache.servers = servers.iter().cloned().map(|x| (x.id.clone(), x)).collect(); self.cache.channels = channels .iter() .cloned() .map(|x| (x.id().to_string(), x)) .collect(); - self.cache.members = members - .iter() - .cloned() - .map(|x| (x.id.server.clone(), x)) - .collect(); // Make all users appear from our perspective. let mut users: Vec = users @@ -353,7 +352,7 @@ impl State { let could_view: bool = if let Some(channel) = self.cache.channels.get(id) { self.cache.can_view_channel(db, channel).await } else { - true + false }; if let Some(channel) = self.cache.channels.get_mut(id) { @@ -364,6 +363,12 @@ impl State { channel.apply_options(data.clone()); } + if !self.cache.channels.contains_key(id) { + if let Ok(channel) = db.fetch_channel(id).await { + self.cache.channels.insert(id.clone(), channel); + } + } + if let Some(channel) = self.cache.channels.get(id) { let can_view = self.cache.can_view_channel(db, channel).await; if could_view != can_view { @@ -398,7 +403,9 @@ impl State { channels, } => { self.insert_subscription(id.clone()); - self.cache.servers.insert(id.to_string(), server.clone()); + self.cache.servers.insert(id.clone(), server.clone()); + let member = Member::new(id.clone(), self.cache.user_id.clone()); + self.cache.members.insert(id.clone(), member); for channel in channels { self.cache @@ -436,6 +443,7 @@ impl State { self.cache.channels.remove(channel); } } + self.cache.members.remove(id); } } EventV1::ServerDelete { id } => { @@ -447,6 +455,7 @@ impl State { self.cache.channels.remove(channel); } } + self.cache.members.remove(id); } EventV1::ServerMemberUpdate { id, data, clear } => { if id.user == self.cache.user_id { diff --git a/crates/quark/src/impl/dummy/servers/server_member.rs b/crates/quark/src/impl/dummy/servers/server_member.rs index f0b9eff4..87aaf033 100644 --- a/crates/quark/src/impl/dummy/servers/server_member.rs +++ b/crates/quark/src/impl/dummy/servers/server_member.rs @@ -3,22 +3,10 @@ use crate::{AbstractServerMember, Result}; use super::super::DummyDb; -use iso8601_timestamp::Timestamp; - #[async_trait] impl AbstractServerMember for DummyDb { async fn fetch_member(&self, server: &str, user: &str) -> Result { - Ok(Member { - id: MemberCompositeKey { - server: server.into(), - user: user.into(), - }, - joined_at: Timestamp::now_utc(), - nickname: None, - avatar: None, - roles: vec![], - timeout: None, - }) + Ok(Member::new(server.into(), user.into())) } async fn insert_member(&self, member: &Member) -> Result<()> { diff --git a/crates/quark/src/impl/generic/servers/server.rs b/crates/quark/src/impl/generic/servers/server.rs index 20b88f06..8131eecd 100644 --- a/crates/quark/src/impl/generic/servers/server.rs +++ b/crates/quark/src/impl/generic/servers/server.rs @@ -1,6 +1,5 @@ use std::collections::HashSet; -use iso8601_timestamp::Timestamp; use ulid::Ulid; use crate::{ @@ -186,18 +185,7 @@ impl Server { return Err(Error::Banned); } - let member = Member { - id: MemberCompositeKey { - server: self.id.clone(), - user: user.id.clone(), - }, - joined_at: Timestamp::now_utc(), - nickname: None, - avatar: None, - roles: vec![], - timeout: None, - }; - + let member = Member::new(self.id.clone(), user.id.clone()); db.insert_member(&member).await?; let should_fetch = channels.is_none(); diff --git a/crates/quark/src/impl/generic/servers/server_member.rs b/crates/quark/src/impl/generic/servers/server_member.rs index 8ec6ea83..217fbd04 100644 --- a/crates/quark/src/impl/generic/servers/server_member.rs +++ b/crates/quark/src/impl/generic/servers/server_member.rs @@ -3,13 +3,27 @@ use iso8601_timestamp::Timestamp; use crate::{ events::client::EventV1, models::{ - server_member::{FieldsMember, PartialMember}, + server_member::{FieldsMember, MemberCompositeKey, PartialMember}, Member, Server, }, Database, Result, }; impl Member { + pub fn new(server_id: String, user_id: String) -> Self { + Self { + id: MemberCompositeKey { + server: server_id, + user: user_id, + }, + joined_at: Timestamp::now_utc(), + nickname: None, + avatar: None, + roles: vec![], + timeout: None, + } + } + /// Update member data pub async fn update<'a>( &mut self,