forked from jmug/stoatchat
Merge branch 'main' into main
Signed-off-by: Tom <iamtomahawkx@gmail.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
use async_tungstenite::tungstenite::{handshake, Message};
|
use async_tungstenite::tungstenite::{handshake, Message};
|
||||||
use futures::channel::oneshot::Sender;
|
use futures::channel::oneshot::Sender;
|
||||||
|
use revolt_database::events::client::ReadyPayloadFields;
|
||||||
use revolt_result::{create_error, Result};
|
use revolt_result::{create_error, Result};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@@ -83,6 +84,17 @@ impl ProtocolConfiguration {
|
|||||||
pub fn get_protocol_format(&self) -> &ProtocolFormat {
|
pub fn get_protocol_format(&self) -> &ProtocolFormat {
|
||||||
&self.format
|
&self.format
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get ready payload fields
|
||||||
|
pub fn get_ready_payload_fields(&self) -> Vec<ReadyPayloadFields> {
|
||||||
|
vec![
|
||||||
|
ReadyPayloadFields::Users,
|
||||||
|
ReadyPayloadFields::Servers,
|
||||||
|
ReadyPayloadFields::Channels,
|
||||||
|
ReadyPayloadFields::Members,
|
||||||
|
ReadyPayloadFields::Emoji,
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Object holding one side of a channel for receiving the parsed information
|
/// Object holding one side of a channel for receiving the parsed information
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use revolt_database::{
|
use revolt_database::{
|
||||||
events::client::EventV1, util::permissions::DatabasePermissionQuery, Channel, Database, Member,
|
events::client::{EventV1, ReadyPayloadFields},
|
||||||
MemberCompositeKey, Presence, RelationshipStatus,
|
util::permissions::DatabasePermissionQuery,
|
||||||
|
Channel, Database, Member, MemberCompositeKey, Presence, RelationshipStatus,
|
||||||
};
|
};
|
||||||
use revolt_models::v0;
|
use revolt_models::v0;
|
||||||
use revolt_permissions::{calculate_channel_permissions, ChannelPermission};
|
use revolt_permissions::{calculate_channel_permissions, ChannelPermission};
|
||||||
@@ -90,7 +91,11 @@ impl Cache {
|
|||||||
/// State Manager
|
/// State Manager
|
||||||
impl State {
|
impl State {
|
||||||
/// Generate a Ready packet for the current user
|
/// Generate a Ready packet for the current user
|
||||||
pub async fn generate_ready_payload(&mut self, db: &Database) -> Result<EventV1> {
|
pub async fn generate_ready_payload(
|
||||||
|
&mut self,
|
||||||
|
db: &Database,
|
||||||
|
fields: Vec<ReadyPayloadFields>,
|
||||||
|
) -> Result<EventV1> {
|
||||||
let user = self.clone_user();
|
let user = self.clone_user();
|
||||||
self.cache.is_bot = user.bot.is_some();
|
self.cache.is_bot = user.bot.is_some();
|
||||||
|
|
||||||
@@ -150,14 +155,36 @@ impl State {
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Fetch customisations.
|
// Fetch customisations.
|
||||||
let emojis = db
|
let emojis = if fields.contains(&ReadyPayloadFields::Emoji) {
|
||||||
.fetch_emoji_by_parent_ids(
|
Some(
|
||||||
&servers
|
db.fetch_emoji_by_parent_ids(
|
||||||
.iter()
|
&servers
|
||||||
.map(|x| x.id.to_string())
|
.iter()
|
||||||
.collect::<Vec<String>>(),
|
.map(|x| x.id.to_string())
|
||||||
|
.collect::<Vec<String>>(),
|
||||||
|
)
|
||||||
|
.await?,
|
||||||
)
|
)
|
||||||
.await?;
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fetch user settings
|
||||||
|
let user_settings = if let Some(ReadyPayloadFields::UserSettings(keys)) = fields
|
||||||
|
.iter()
|
||||||
|
.find(|e| matches!(e, ReadyPayloadFields::UserSettings(_)))
|
||||||
|
{
|
||||||
|
Some(db.fetch_user_settings(&user.id, &keys).await?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fetch channel unreads
|
||||||
|
let channel_unreads = if fields.contains(&ReadyPayloadFields::ChannelUnreads) {
|
||||||
|
Some(db.fetch_unreads(&user.id).await?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
// Copy data into local state cache.
|
// Copy data into local state cache.
|
||||||
self.cache.users = users.iter().cloned().map(|x| (x.id.clone(), x)).collect();
|
self.cache.users = users.iter().cloned().map(|x| (x.id.clone(), x)).collect();
|
||||||
@@ -201,13 +228,31 @@ impl State {
|
|||||||
for channel in &channels {
|
for channel in &channels {
|
||||||
self.insert_subscription(channel.id().to_string()).await;
|
self.insert_subscription(channel.id().to_string()).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(EventV1::Ready {
|
Ok(EventV1::Ready {
|
||||||
users,
|
users: if fields.contains(&ReadyPayloadFields::Users) {
|
||||||
servers: servers.into_iter().map(Into::into).collect(),
|
Some(users)
|
||||||
channels: channels.into_iter().map(Into::into).collect(),
|
} else {
|
||||||
members: members.into_iter().map(Into::into).collect(),
|
None
|
||||||
emojis: emojis.into_iter().map(Into::into).collect(),
|
},
|
||||||
|
servers: if fields.contains(&ReadyPayloadFields::Servers) {
|
||||||
|
Some(servers.into_iter().map(Into::into).collect())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
channels: if fields.contains(&ReadyPayloadFields::Channels) {
|
||||||
|
Some(channels.into_iter().map(Into::into).collect())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
members: if fields.contains(&ReadyPayloadFields::Members) {
|
||||||
|
Some(members.into_iter().map(Into::into).collect())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
emojis: emojis.map(|vec| vec.into_iter().map(Into::into).collect()),
|
||||||
|
|
||||||
|
user_settings,
|
||||||
|
channel_unreads: channel_unreads.map(|vec| vec.into_iter().map(Into::into).collect()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -106,7 +106,10 @@ pub async fn client(db: &'static Database, stream: TcpStream, addr: SocketAddr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Download required data to local cache and send Ready payload.
|
// Download required data to local cache and send Ready payload.
|
||||||
let ready_payload = match state.generate_ready_payload(db).await {
|
let ready_payload = match state
|
||||||
|
.generate_ready_payload(db, config.get_ready_payload_fields())
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(ready_payload) => ready_payload,
|
Ok(ready_payload) => ready_payload,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
sentry::capture_error(&err);
|
sentry::capture_error(&err);
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ use authifier::AuthifierEvent;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use revolt_models::v0::{
|
use revolt_models::v0::{
|
||||||
AppendMessage, Channel, Emoji, FieldsChannel, FieldsMember, FieldsRole, FieldsServer,
|
AppendMessage, Channel, ChannelUnread, Emoji, FieldsChannel, FieldsMember, FieldsRole,
|
||||||
FieldsUser, FieldsWebhook, Member, MemberCompositeKey, Message, PartialChannel, PartialMember,
|
FieldsServer, FieldsUser, FieldsWebhook, Member, MemberCompositeKey, Message, PartialChannel,
|
||||||
PartialMessage, PartialRole, PartialServer, PartialUser, PartialWebhook, RemovalIntention,
|
PartialMember, PartialMessage, PartialRole, PartialServer, PartialUser, PartialWebhook,
|
||||||
Report, Server, User, UserSettings, Webhook,
|
RemovalIntention, Report, Server, User, UserSettings, Webhook,
|
||||||
};
|
};
|
||||||
use revolt_result::Error;
|
use revolt_result::Error;
|
||||||
|
|
||||||
@@ -39,6 +39,19 @@ pub enum ErrorEvent {
|
|||||||
APIError(Error),
|
APIError(Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fields provided in Ready payload
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub enum ReadyPayloadFields {
|
||||||
|
Users,
|
||||||
|
Servers,
|
||||||
|
Channels,
|
||||||
|
Members,
|
||||||
|
Emoji,
|
||||||
|
|
||||||
|
UserSettings(Vec<String>),
|
||||||
|
ChannelUnreads,
|
||||||
|
}
|
||||||
|
|
||||||
/// Protocol Events
|
/// Protocol Events
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
@@ -52,11 +65,21 @@ pub enum EventV1 {
|
|||||||
Logout,
|
Logout,
|
||||||
/// Basic data to cache
|
/// Basic data to cache
|
||||||
Ready {
|
Ready {
|
||||||
users: Vec<User>,
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
servers: Vec<Server>,
|
users: Option<Vec<User>>,
|
||||||
channels: Vec<Channel>,
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
members: Vec<Member>,
|
servers: Option<Vec<Server>>,
|
||||||
emojis: Vec<Emoji>,
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
channels: Option<Vec<Channel>>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
members: Option<Vec<Member>>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
emojis: Option<Vec<Emoji>>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
user_settings: Option<UserSettings>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
channel_unreads: Option<Vec<ChannelUnread>>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Ping response
|
/// Ping response
|
||||||
|
|||||||
@@ -1024,6 +1024,8 @@ impl crate::User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Convert user object into user model assuming mutual connection
|
/// Convert user object into user model assuming mutual connection
|
||||||
|
///
|
||||||
|
/// Relations will never be included, i.e. when we process ourselves
|
||||||
pub fn into_known<'a, P>(self, perspective: P, is_online: bool) -> User
|
pub fn into_known<'a, P>(self, perspective: P, is_online: bool) -> User
|
||||||
where
|
where
|
||||||
P: Into<Option<&'a crate::User>>,
|
P: Into<Option<&'a crate::User>>,
|
||||||
@@ -1059,19 +1061,7 @@ impl crate::User {
|
|||||||
discriminator: self.discriminator,
|
discriminator: self.discriminator,
|
||||||
display_name: self.display_name,
|
display_name: self.display_name,
|
||||||
avatar: self.avatar.map(|file| file.into()),
|
avatar: self.avatar.map(|file| file.into()),
|
||||||
relations: if let Some(crate::User { id, .. }) = perspective {
|
relations: vec![],
|
||||||
if id == &self.id {
|
|
||||||
self.relations
|
|
||||||
.unwrap_or_default()
|
|
||||||
.into_iter()
|
|
||||||
.map(|relation| relation.into())
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
vec![]
|
|
||||||
},
|
|
||||||
badges: self.badges.unwrap_or_default() as u32,
|
badges: self.badges.unwrap_or_default() as u32,
|
||||||
online: can_see_profile
|
online: can_see_profile
|
||||||
&& is_online
|
&& is_online
|
||||||
|
|||||||
Reference in New Issue
Block a user