use crate::notifications::events::message::Create; use crate::notifications::events::Notification; use crate::routes::channel::ChannelType; use crate::database::channel::Channel; use super::get_collection; use crate::notifications; use mongodb::bson::{doc, to_bson, Bson, DateTime}; use serde::{Deserialize, Serialize}; use rocket::request::FromParam; use mongodb::bson::from_bson; use rocket::http::RawStr; #[derive(Serialize, Deserialize, Debug)] pub struct PreviousEntry { pub content: String, pub time: DateTime, } #[derive(Serialize, Deserialize, Debug)] pub struct Message { #[serde(rename = "_id")] pub id: String, pub nonce: Option<String>, pub channel: String, pub author: String, pub content: String, pub edited: Option<DateTime>, pub previous_content: Vec<PreviousEntry>, } // ? TODO: write global send message // ? pub fn send_message(); // ? handle websockets? impl Message { pub fn send(&self, target: &Channel) -> bool { if get_collection("messages") .insert_one(to_bson(&self).unwrap().as_document().unwrap().clone(), None) .is_ok() { notifications::send_message_given_channel( Notification::message_create(Create { id: self.id.clone(), nonce: self.nonce.clone(), channel: self.channel.clone(), author: self.author.clone(), content: self.content.clone(), }), &target, ); let short_content: String = self.content.chars().take(24).collect(); // !! this stuff can be async if target.channel_type == ChannelType::DM as u8 || target.channel_type == ChannelType::GROUPDM as u8 { let mut update = doc! { "$set": { "last_message": { "id": &self.id, "user_id": &self.author, "short_content": short_content, } } }; if target.channel_type == ChannelType::DM as u8 { update .get_document_mut("$set") .unwrap() .insert("active", true); } if get_collection("channels") .update_one(doc! { "_id": &target.id }, update, None) .is_ok() { true } else { false } } else { true } } else { false } } } impl<'r> FromParam<'r> for Message { type Error = &'r RawStr; fn from_param(param: &'r RawStr) -> Result<Self, Self::Error> { let col = get_collection("messages"); let result = col .find_one(doc! { "_id": param.to_string() }, None) .unwrap(); if let Some(message) = result { Ok(from_bson(Bson::Document(message)).expect("Failed to unwrap message.")) } else { Err(param) } } }