forked from jmug/stoatchat
chore(core): flesh out implementations for channels / servers
This commit is contained in:
@@ -2,8 +2,9 @@ use authifier::AuthifierEvent;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use revolt_models::v0::{
|
use revolt_models::v0::{
|
||||||
Channel, Emoji, FieldsChannel, FieldsWebhook, PartialChannel, PartialWebhook, UserSettings,
|
Channel, Emoji, FieldsChannel, FieldsMember, FieldsRole, FieldsServer, FieldsWebhook,
|
||||||
Webhook,
|
MemberCompositeKey, PartialChannel, PartialMember, PartialRole, PartialServer, PartialWebhook,
|
||||||
|
Server, UserSettings, Webhook,
|
||||||
};
|
};
|
||||||
use revolt_result::Error;
|
use revolt_result::Error;
|
||||||
|
|
||||||
@@ -102,8 +103,7 @@ pub enum EventV1 {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/// Bulk delete messages
|
/// Bulk delete messages
|
||||||
BulkMessageDelete { channel: String, ids: Vec<String> },
|
BulkMessageDelete { channel: String, ids: Vec<String> },*/
|
||||||
|
|
||||||
/// New server
|
/// New server
|
||||||
ServerCreate {
|
ServerCreate {
|
||||||
id: String,
|
id: String,
|
||||||
@@ -145,7 +145,7 @@ pub enum EventV1 {
|
|||||||
/// Server role deleted
|
/// Server role deleted
|
||||||
ServerRoleDelete { id: String, role_id: String },
|
ServerRoleDelete { id: String, role_id: String },
|
||||||
|
|
||||||
/// Update existing user
|
/*/// Update existing user
|
||||||
UserUpdate {
|
UserUpdate {
|
||||||
id: String,
|
id: String,
|
||||||
data: PartialUser,
|
data: PartialUser,
|
||||||
|
|||||||
@@ -169,6 +169,19 @@ impl Channel {
|
|||||||
pub async fn create(&self, db: &Database) -> Result<()> {
|
pub async fn create(&self, db: &Database) -> Result<()> {
|
||||||
db.insert_channel(self).await?;
|
db.insert_channel(self).await?;
|
||||||
|
|
||||||
|
let event = EventV1::ChannelCreate(self.clone().into());
|
||||||
|
match self {
|
||||||
|
Self::SavedMessages { user, .. } => event.private(user.clone()).await,
|
||||||
|
Self::DirectMessage { recipients, .. } | Self::Group { recipients, .. } => {
|
||||||
|
for recipient in recipients {
|
||||||
|
event.clone().private(recipient.clone()).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::TextChannel { server, .. } | Self::VoiceChannel { server, .. } => {
|
||||||
|
event.p(server.clone()).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,7 +306,7 @@ impl Channel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Update channel data
|
/// Update channel data
|
||||||
pub async fn update<'a>(
|
pub async fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
db: &Database,
|
db: &Database,
|
||||||
partial: PartialChannel,
|
partial: PartialChannel,
|
||||||
@@ -305,8 +318,19 @@ impl Channel {
|
|||||||
|
|
||||||
self.apply_options(partial.clone());
|
self.apply_options(partial.clone());
|
||||||
|
|
||||||
db.update_channel(&self.id(), &partial, remove.clone())
|
let id = self.id().to_string();
|
||||||
.await?;
|
db.update_channel(&id, &partial, remove.clone()).await?;
|
||||||
|
|
||||||
|
EventV1::ChannelUpdate {
|
||||||
|
id: id.clone(),
|
||||||
|
data: partial.into(),
|
||||||
|
clear: remove.into_iter().map(|v| v.into()).collect(),
|
||||||
|
}
|
||||||
|
.p(match self {
|
||||||
|
Self::TextChannel { server, .. } | Self::VoiceChannel { server, .. } => server.clone(),
|
||||||
|
_ => id,
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -514,6 +538,8 @@ impl Channel {
|
|||||||
|
|
||||||
/// Delete a channel
|
/// Delete a channel
|
||||||
pub async fn delete(&self, db: &Database) -> Result<()> {
|
pub async fn delete(&self, db: &Database) -> Result<()> {
|
||||||
|
let id = self.id().to_string();
|
||||||
|
EventV1::ChannelDelete { id: id.clone() }.p(id).await;
|
||||||
db.delete_channel(self).await
|
db.delete_channel(self).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use revolt_permissions::OverrideField;
|
|||||||
use revolt_result::Result;
|
use revolt_result::Result;
|
||||||
use ulid::Ulid;
|
use ulid::Ulid;
|
||||||
|
|
||||||
use crate::{Database, File};
|
use crate::{events::client::EventV1, Database, File};
|
||||||
|
|
||||||
auto_derived_partial!(
|
auto_derived_partial!(
|
||||||
/// Server
|
/// Server
|
||||||
@@ -149,24 +149,24 @@ impl Server {
|
|||||||
|
|
||||||
db.update_server(&self.id, &partial, remove.clone()).await?;
|
db.update_server(&self.id, &partial, remove.clone()).await?;
|
||||||
|
|
||||||
/* // TODO: EventV1::ServerUpdate {
|
EventV1::ServerUpdate {
|
||||||
id: self.id.clone(),
|
id: self.id.clone(),
|
||||||
data: partial,
|
data: partial.into(),
|
||||||
clear: remove,
|
clear: remove.into_iter().map(|v| v.into()).collect(),
|
||||||
}
|
}
|
||||||
.p(self.id.clone())
|
.p(self.id.clone())
|
||||||
.await; */
|
.await;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete a server
|
/// Delete a server
|
||||||
pub async fn delete(self, db: &Database) -> Result<()> {
|
pub async fn delete(self, db: &Database) -> Result<()> {
|
||||||
/* // TODO: EventV1::ServerDelete {
|
EventV1::ServerDelete {
|
||||||
id: self.id.clone(),
|
id: self.id.clone(),
|
||||||
}
|
}
|
||||||
.p(self.id.clone())
|
.p(self.id.clone())
|
||||||
.await; */
|
.await;
|
||||||
|
|
||||||
db.delete_server(&self.id).await
|
db.delete_server(&self.id).await
|
||||||
}
|
}
|
||||||
@@ -364,14 +364,14 @@ impl Role {
|
|||||||
let role_id = Ulid::new().to_string();
|
let role_id = Ulid::new().to_string();
|
||||||
db.insert_role(server_id, &role_id, self).await?;
|
db.insert_role(server_id, &role_id, self).await?;
|
||||||
|
|
||||||
/* // TODO: EventV1::ServerRoleUpdate {
|
EventV1::ServerRoleUpdate {
|
||||||
id: server_id.to_string(),
|
id: server_id.to_string(),
|
||||||
role_id: role_id.to_string(),
|
role_id: role_id.to_string(),
|
||||||
data: self.clone().into_optional(),
|
data: self.clone().into_optional().into(),
|
||||||
clear: vec![],
|
clear: vec![],
|
||||||
}
|
}
|
||||||
.p(server_id.to_string())
|
.p(server_id.to_string())
|
||||||
.await; */
|
.await;
|
||||||
|
|
||||||
Ok(role_id)
|
Ok(role_id)
|
||||||
}
|
}
|
||||||
@@ -394,14 +394,14 @@ impl Role {
|
|||||||
db.update_role(server_id, role_id, &partial, remove.clone())
|
db.update_role(server_id, role_id, &partial, remove.clone())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
/* // TODO: EventV1::ServerRoleUpdate {
|
EventV1::ServerRoleUpdate {
|
||||||
id: server_id.to_string(),
|
id: server_id.to_string(),
|
||||||
role_id: role_id.to_string(),
|
role_id: role_id.to_string(),
|
||||||
data: partial,
|
data: partial.into(),
|
||||||
clear: vec![],
|
clear: vec![],
|
||||||
}
|
}
|
||||||
.p(server_id.to_string())
|
.p(server_id.to_string())
|
||||||
.await; */
|
.await;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -415,12 +415,12 @@ impl Role {
|
|||||||
|
|
||||||
/// Delete a role
|
/// Delete a role
|
||||||
pub async fn delete(self, db: &Database, server_id: &str, role_id: &str) -> Result<()> {
|
pub async fn delete(self, db: &Database, server_id: &str, role_id: &str) -> Result<()> {
|
||||||
/* // TODO: EventV1::ServerRoleDelete {
|
EventV1::ServerRoleDelete {
|
||||||
id: server_id.to_string(),
|
id: server_id.to_string(),
|
||||||
role_id: role_id.to_string(),
|
role_id: role_id.to_string(),
|
||||||
}
|
}
|
||||||
.p(server_id.to_string())
|
.p(server_id.to_string())
|
||||||
.await; */
|
.await;
|
||||||
|
|
||||||
db.delete_role(server_id, role_id).await
|
db.delete_role(server_id, role_id).await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -316,6 +316,19 @@ impl From<crate::Member> for Member {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<crate::PartialMember> for PartialMember {
|
||||||
|
fn from(value: crate::PartialMember) -> Self {
|
||||||
|
PartialMember {
|
||||||
|
id: value.id.map(|id| id.into()),
|
||||||
|
joined_at: value.joined_at,
|
||||||
|
nickname: value.nickname,
|
||||||
|
avatar: value.avatar.map(|f| f.into()),
|
||||||
|
roles: value.roles,
|
||||||
|
timeout: value.timeout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<crate::MemberCompositeKey> for MemberCompositeKey {
|
impl From<crate::MemberCompositeKey> for MemberCompositeKey {
|
||||||
fn from(value: crate::MemberCompositeKey) -> Self {
|
fn from(value: crate::MemberCompositeKey) -> Self {
|
||||||
MemberCompositeKey {
|
MemberCompositeKey {
|
||||||
@@ -325,6 +338,27 @@ impl From<crate::MemberCompositeKey> for MemberCompositeKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<crate::FieldsMember> for FieldsMember {
|
||||||
|
fn from(value: crate::FieldsMember) -> Self {
|
||||||
|
match value {
|
||||||
|
crate::FieldsMember::Avatar => FieldsMember::Avatar,
|
||||||
|
crate::FieldsMember::Nickname => FieldsMember::Nickname,
|
||||||
|
crate::FieldsMember::Roles => FieldsMember::Roles,
|
||||||
|
crate::FieldsMember::Timeout => FieldsMember::Timeout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<crate::RemovalIntention> for RemovalIntention {
|
||||||
|
fn from(value: crate::RemovalIntention) -> Self {
|
||||||
|
match value {
|
||||||
|
crate::RemovalIntention::Ban => RemovalIntention::Ban,
|
||||||
|
crate::RemovalIntention::Kick => RemovalIntention::Kick,
|
||||||
|
crate::RemovalIntention::Leave => RemovalIntention::Leave,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<crate::Server> for Server {
|
impl From<crate::Server> for Server {
|
||||||
fn from(value: crate::Server) -> Self {
|
fn from(value: crate::Server) -> Self {
|
||||||
Server {
|
Server {
|
||||||
@@ -353,6 +387,44 @@ impl From<crate::Server> for Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<crate::PartialServer> for PartialServer {
|
||||||
|
fn from(value: crate::PartialServer) -> Self {
|
||||||
|
PartialServer {
|
||||||
|
id: value.id,
|
||||||
|
owner: value.owner,
|
||||||
|
name: value.name,
|
||||||
|
description: value.description,
|
||||||
|
channels: value.channels,
|
||||||
|
categories: value
|
||||||
|
.categories
|
||||||
|
.map(|categories| categories.into_iter().map(|v| v.into()).collect()),
|
||||||
|
system_messages: value.system_messages.map(|v| v.into()),
|
||||||
|
roles: value
|
||||||
|
.roles
|
||||||
|
.map(|roles| roles.into_iter().map(|(k, v)| (k, v.into())).collect()),
|
||||||
|
default_permissions: value.default_permissions,
|
||||||
|
icon: value.icon.map(|f| f.into()),
|
||||||
|
banner: value.banner.map(|f| f.into()),
|
||||||
|
flags: value.flags.map(|v| v as u32),
|
||||||
|
nsfw: value.nsfw,
|
||||||
|
analytics: value.analytics,
|
||||||
|
discoverable: value.discoverable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<crate::FieldsServer> for FieldsServer {
|
||||||
|
fn from(value: crate::FieldsServer) -> Self {
|
||||||
|
match value {
|
||||||
|
crate::FieldsServer::Banner => FieldsServer::Banner,
|
||||||
|
crate::FieldsServer::Categories => FieldsServer::Categories,
|
||||||
|
crate::FieldsServer::Description => FieldsServer::Description,
|
||||||
|
crate::FieldsServer::Icon => FieldsServer::Icon,
|
||||||
|
crate::FieldsServer::SystemMessages => FieldsServer::SystemMessages,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<crate::Category> for Category {
|
impl From<crate::Category> for Category {
|
||||||
fn from(value: crate::Category) -> Self {
|
fn from(value: crate::Category) -> Self {
|
||||||
Category {
|
Category {
|
||||||
@@ -386,6 +458,26 @@ impl From<crate::Role> for Role {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<crate::PartialRole> for PartialRole {
|
||||||
|
fn from(value: crate::PartialRole) -> Self {
|
||||||
|
PartialRole {
|
||||||
|
name: value.name,
|
||||||
|
permissions: value.permissions,
|
||||||
|
colour: value.colour,
|
||||||
|
hoist: value.hoist,
|
||||||
|
rank: value.rank,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<crate::FieldsRole> for FieldsRole {
|
||||||
|
fn from(value: crate::FieldsRole) -> Self {
|
||||||
|
match value {
|
||||||
|
crate::FieldsRole::Colour => FieldsRole::Colour,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl crate::User {
|
impl crate::User {
|
||||||
pub async fn into<P>(self, perspective: P) -> User
|
pub async fn into<P>(self, perspective: P) -> User
|
||||||
where
|
where
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use super::File;
|
|||||||
|
|
||||||
use iso8601_timestamp::Timestamp;
|
use iso8601_timestamp::Timestamp;
|
||||||
|
|
||||||
auto_derived!(
|
auto_derived_partial!(
|
||||||
/// Server Member
|
/// Server Member
|
||||||
pub struct Member {
|
pub struct Member {
|
||||||
/// Unique member id
|
/// Unique member id
|
||||||
@@ -29,8 +29,11 @@ auto_derived!(
|
|||||||
/// Timestamp this member is timed out until
|
/// Timestamp this member is timed out until
|
||||||
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
||||||
pub timeout: Option<Timestamp>,
|
pub timeout: Option<Timestamp>,
|
||||||
}
|
},
|
||||||
|
"PartialMember"
|
||||||
|
);
|
||||||
|
|
||||||
|
auto_derived!(
|
||||||
/// Composite primary key consisting of server and user id
|
/// Composite primary key consisting of server and user id
|
||||||
#[derive(Hash, Default)]
|
#[derive(Hash, Default)]
|
||||||
pub struct MemberCompositeKey {
|
pub struct MemberCompositeKey {
|
||||||
@@ -39,4 +42,19 @@ auto_derived!(
|
|||||||
/// User Id
|
/// User Id
|
||||||
pub user: String,
|
pub user: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Optional fields on server member object
|
||||||
|
pub enum FieldsMember {
|
||||||
|
Nickname,
|
||||||
|
Avatar,
|
||||||
|
Roles,
|
||||||
|
Timeout,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Member removal intention
|
||||||
|
pub enum RemovalIntention {
|
||||||
|
Leave,
|
||||||
|
Kick,
|
||||||
|
Ban,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use super::File;
|
|||||||
use revolt_permissions::OverrideField;
|
use revolt_permissions::OverrideField;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
auto_derived!(
|
auto_derived_partial!(
|
||||||
/// Server
|
/// Server
|
||||||
pub struct Server {
|
pub struct Server {
|
||||||
/// Unique Id
|
/// Unique Id
|
||||||
@@ -72,18 +72,11 @@ auto_derived!(
|
|||||||
serde(skip_serializing_if = "crate::if_false", default)
|
serde(skip_serializing_if = "crate::if_false", default)
|
||||||
)]
|
)]
|
||||||
pub discoverable: bool,
|
pub discoverable: bool,
|
||||||
}
|
},
|
||||||
|
"PartialServer"
|
||||||
/// Channel category
|
);
|
||||||
pub struct Category {
|
|
||||||
/// Unique ID for this category
|
|
||||||
pub id: String,
|
|
||||||
/// Title for this category
|
|
||||||
pub title: String,
|
|
||||||
/// Channels in this category
|
|
||||||
pub channels: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
auto_derived_partial!(
|
||||||
/// Role
|
/// Role
|
||||||
pub struct Role {
|
pub struct Role {
|
||||||
/// Role name
|
/// Role name
|
||||||
@@ -104,6 +97,33 @@ auto_derived!(
|
|||||||
/// Ranking of this role
|
/// Ranking of this role
|
||||||
#[cfg_attr(feature = "serde", serde(default))]
|
#[cfg_attr(feature = "serde", serde(default))]
|
||||||
pub rank: i64,
|
pub rank: i64,
|
||||||
|
},
|
||||||
|
"PartialRole"
|
||||||
|
);
|
||||||
|
|
||||||
|
auto_derived!(
|
||||||
|
/// Optional fields on server object
|
||||||
|
pub enum FieldsServer {
|
||||||
|
Description,
|
||||||
|
Categories,
|
||||||
|
SystemMessages,
|
||||||
|
Icon,
|
||||||
|
Banner,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Optional fields on server object
|
||||||
|
pub enum FieldsRole {
|
||||||
|
Colour,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Channel category
|
||||||
|
pub struct Category {
|
||||||
|
/// Unique ID for this category
|
||||||
|
pub id: String,
|
||||||
|
/// Title for this category
|
||||||
|
pub title: String,
|
||||||
|
/// Channels in this category
|
||||||
|
pub channels: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// System message channel assignments
|
/// System message channel assignments
|
||||||
|
|||||||
Reference in New Issue
Block a user