134 lines
4.0 KiB
Rust
134 lines
4.0 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
use crate::db::{SledModel, Storable, SledDB, SledDBResult};
|
|
use chrono::{DateTime, Utc};
|
|
|
|
/// MessageStatus represents the status of a message
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub enum MessageStatus {
|
|
Sent,
|
|
Delivered,
|
|
Read,
|
|
Failed,
|
|
}
|
|
|
|
/// MessageMeta contains metadata for a chat message
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct MessageMeta {
|
|
pub created_at: DateTime<Utc>,
|
|
pub updated_at: DateTime<Utc>,
|
|
pub status: MessageStatus,
|
|
pub is_edited: bool,
|
|
pub reactions: Vec<String>,
|
|
}
|
|
|
|
/// Message represents a chat message
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Message {
|
|
pub id: u32, // Unique identifier
|
|
pub thread_id: String, // Thread/conversation identifier
|
|
pub sender_id: String, // Sender identifier
|
|
pub recipients: Vec<String>, // List of recipient identifiers
|
|
pub content: String, // Message content
|
|
pub attachments: Vec<String>, // References to attachments
|
|
pub groups: Vec<u32>, // Groups this message belongs to (references Circle IDs)
|
|
pub meta: MessageMeta, // Message metadata
|
|
}
|
|
|
|
impl Message {
|
|
/// Create a new message
|
|
pub fn new(id: u32, thread_id: String, sender_id: String, content: String) -> Self {
|
|
let now = Utc::now();
|
|
Self {
|
|
id,
|
|
thread_id,
|
|
sender_id,
|
|
recipients: Vec::new(),
|
|
content,
|
|
attachments: Vec::new(),
|
|
groups: Vec::new(),
|
|
meta: MessageMeta {
|
|
created_at: now,
|
|
updated_at: now,
|
|
status: MessageStatus::Sent,
|
|
is_edited: false,
|
|
reactions: Vec::new(),
|
|
},
|
|
}
|
|
}
|
|
|
|
/// Add a recipient to this message
|
|
pub fn add_recipient(&mut self, recipient: String) {
|
|
self.recipients.push(recipient);
|
|
}
|
|
|
|
/// Add an attachment to this message
|
|
pub fn add_attachment(&mut self, attachment: String) {
|
|
self.attachments.push(attachment);
|
|
}
|
|
|
|
/// Add a group to this message
|
|
pub fn add_group(&mut self, group_id: u32) {
|
|
if !self.groups.contains(&group_id) {
|
|
self.groups.push(group_id);
|
|
}
|
|
}
|
|
|
|
/// Remove a group from this message
|
|
pub fn remove_group(&mut self, group_id: u32) {
|
|
self.groups.retain(|&id| id != group_id);
|
|
}
|
|
|
|
/// Filter by groups - returns true if this message belongs to any of the specified groups
|
|
pub fn filter_by_groups(&self, groups: &[u32]) -> bool {
|
|
groups.iter().any(|g| self.groups.contains(g))
|
|
}
|
|
|
|
/// Search by content - returns true if the content contains the query (case-insensitive)
|
|
pub fn search_by_content(&self, query: &str) -> bool {
|
|
self.content.to_lowercase().contains(&query.to_lowercase())
|
|
}
|
|
|
|
/// Update message status
|
|
pub fn update_status(&mut self, status: MessageStatus) {
|
|
self.meta.status = status;
|
|
self.meta.updated_at = Utc::now();
|
|
}
|
|
|
|
/// Edit message content
|
|
pub fn edit_content(&mut self, new_content: String) {
|
|
self.content = new_content;
|
|
self.meta.is_edited = true;
|
|
self.meta.updated_at = Utc::now();
|
|
}
|
|
|
|
/// Add a reaction to the message
|
|
pub fn add_reaction(&mut self, reaction: String) {
|
|
self.meta.reactions.push(reaction);
|
|
self.meta.updated_at = Utc::now();
|
|
}
|
|
|
|
/// Get all messages in the same thread
|
|
pub fn get_thread_messages(&self, db: &SledDB<Message>) -> SledDBResult<Vec<Message>> {
|
|
let all_messages = db.list()?;
|
|
let thread_messages = all_messages
|
|
.into_iter()
|
|
.filter(|msg| msg.thread_id == self.thread_id)
|
|
.collect();
|
|
|
|
Ok(thread_messages)
|
|
}
|
|
}
|
|
|
|
// Implement Storable trait (provides default dump/load)
|
|
impl Storable for Message {}
|
|
|
|
// Implement SledModel trait
|
|
impl SledModel for Message {
|
|
fn get_id(&self) -> String {
|
|
self.id.to_string()
|
|
}
|
|
|
|
fn db_prefix() -> &'static str {
|
|
"message"
|
|
}
|
|
} |