signer-daemon 0.2.1

Signer daemon package.
Documentation
use sea_orm::{ColumnTrait, ConnectionTrait, EntityTrait, QueryFilter};
use serde::{Deserialize, Serialize};

use crate::{
  SignerDaemon,
  entity::{chat, message},
};

use super::ChatVO;

#[derive(Debug, Clone, Serialize, Deserialize)]
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)]
pub enum MessageContent {
  // 文本内容
  Text(String),
  // 图像链接
  Image(String),
  // 视频链接
  Video(String),
  // 文件链接
  File(String),
  // 已读
  Check,
}

impl MessageVO {
  pub async fn create(
    daemon: &SignerDaemon,
    chat_vo: &ChatVO,
    content: &MessageContent,
  ) -> anyhow::Result<Self> {
    let user = daemon.user.lock().await.clone();

    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: user.public.pub_key.clone(),
      receiver_keys: chat_vo.receiver_keys(daemon).await?,
      create_time: chrono::Utc::now().timestamp_millis(),
    })
  }

  pub async fn from_model(
    c: &impl ConnectionTrait,
    model: &message::Model,
  ) -> anyhow::Result<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,
  ) -> anyhow::Result<MessageVO> {
    let user = daemon.user.lock().await.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,
      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(),
    }
  }
}