use sea_orm::{ColumnTrait, ConnectionTrait, EntityTrait, QueryFilter};
use serde::{Deserialize, Serialize};
use crate::{
SignerDaemon, SignerDaemonCore,
entity::{chat, message},
model::viewobject::Null,
};
use super::ChatVO;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "poem-openapi", derive(poem_openapi::Object))]
pub struct MessageVO {
pub chat: ChatVO,
pub id: String,
pub user_key: String,
pub parent_id: Option<String>,
pub parent_user_key: Option<String>,
pub content: MessageContent,
pub receiver_keys: Vec<String>,
pub create_time: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "poem-openapi", derive(poem_openapi::Union))]
pub enum MessageContent {
Text(String),
Image(String),
Video(String),
File(String),
Check(Null),
}
impl MessageVO {
pub async fn create(
core: &SignerDaemonCore,
chat_vo: &ChatVO,
content: &MessageContent,
) -> crate::DaemonResult<Self> {
Ok(Self {
chat: chat_vo.clone(),
id: uuid::Uuid::new_v4().to_string(),
parent_id: None,
parent_user_key: None,
content: content.clone(),
user_key: core.pub_key.clone(),
receiver_keys: chat_vo.receiver_keys(&core).await?,
create_time: chrono::Utc::now().timestamp_millis(),
})
}
pub async fn from_model(
c: &impl ConnectionTrait,
model: &message::Model,
) -> crate::DaemonResult<Self> {
let chat_model = chat::Entity::find()
.filter(
chat::Column::ChatKey
.eq(&model.chat_key)
.and(chat::Column::ChatVariant.eq(&model.chat_variant)),
)
.one(c)
.await?
.expect("chat not found");
let chat_vo = serde_json::from_str(&chat_model.view_object)?;
Ok(Self {
chat: chat_vo,
id: model.id.clone(),
parent_id: model.parent_id.clone(),
parent_user_key: model.parent_user_key.clone(),
content: serde_json::from_str(&model.content)?,
user_key: model.user_key.clone(),
receiver_keys: model
.receiver_keys
.split(',')
.map(|s| s.to_string())
.collect(),
create_time: model.create_time.and_utc().timestamp_millis(),
})
}
pub async fn create_check_message(
&self,
daemon: &SignerDaemon,
) -> crate::DaemonResult<MessageVO> {
let user = daemon.state.user.clone();
let message = MessageVO {
chat: self.chat.clone(),
id: uuid::Uuid::new_v4().to_string(),
parent_id: Some(self.id.clone()),
parent_user_key: Some(self.user_key.clone()),
content: MessageContent::Check(Null {}),
user_key: user.public.pub_key.clone(),
receiver_keys: vec![],
create_time: chrono::Utc::now().timestamp_millis(),
};
Ok(message)
}
}
impl MessageContent {
pub fn ty(&self) -> String {
match self {
MessageContent::Text(_) => "text".to_string(),
MessageContent::Image(_) => "image".to_string(),
MessageContent::Video(_) => "video".to_string(),
MessageContent::File(_) => "file".to_string(),
MessageContent::Check(_) => "check".to_string(),
}
}
}