Private
Public Access
1
0
Files
Kordophone/kordophoned/src/daemon/models/message.rs
2025-08-01 12:26:17 -07:00

187 lines
5.5 KiB
Rust

use chrono::DateTime;
use chrono::NaiveDateTime;
use crate::daemon::attachment_store::AttachmentStore;
use crate::daemon::models::Attachment;
use kordophone::model::message::AttachmentMetadata;
use kordophone::model::outgoing_message::OutgoingMessage;
use kordophone_db::models::participant::Participant as DbParticipant;
use std::collections::HashMap;
#[derive(Clone, Debug)]
pub enum Participant {
Me,
Remote {
handle: String,
contact_id: Option<String>,
},
}
impl From<String> for Participant {
fn from(display_name: String) -> Self {
Participant::Remote {
handle: display_name,
contact_id: None,
}
}
}
impl From<&str> for Participant {
fn from(display_name: &str) -> Self {
Participant::Remote {
handle: display_name.to_string(),
contact_id: None,
}
}
}
impl From<kordophone_db::models::Participant> for Participant {
fn from(participant: kordophone_db::models::Participant) -> Self {
match participant {
kordophone_db::models::Participant::Me => Participant::Me,
kordophone_db::models::Participant::Remote { handle, contact_id } => {
Participant::Remote { handle, contact_id }
}
}
}
}
impl Participant {
pub fn display_name(&self) -> String {
match self {
Participant::Me => "(Me)".to_string(),
Participant::Remote { handle, .. } => handle.clone(),
}
}
}
#[derive(Clone, Debug)]
pub struct Message {
pub id: String,
pub sender: Participant,
pub text: String,
pub date: NaiveDateTime,
pub attachments: Vec<Attachment>,
}
fn attachments_from(
file_transfer_guids: &Vec<String>,
attachment_metadata: &Option<HashMap<String, AttachmentMetadata>>,
) -> Vec<Attachment> {
file_transfer_guids
.iter()
.map(|guid| {
let mut attachment = AttachmentStore::get_attachment_impl(
&AttachmentStore::get_default_store_path(),
guid,
);
attachment.metadata = match attachment_metadata {
Some(attachment_metadata) => attachment_metadata
.get(guid)
.cloned()
.map(|metadata| metadata.into()),
None => None,
};
attachment
})
.collect()
}
impl From<kordophone_db::models::Message> for Message {
fn from(message: kordophone_db::models::Message) -> Self {
let attachments =
attachments_from(&message.file_transfer_guids, &message.attachment_metadata);
Self {
id: message.id,
sender: message.sender.into(),
text: message.text,
date: message.date,
attachments,
}
}
}
impl From<Message> for kordophone_db::models::Message {
fn from(message: Message) -> Self {
Self {
id: message.id,
sender: match message.sender {
Participant::Me => kordophone_db::models::Participant::Me,
Participant::Remote { handle, contact_id } => {
kordophone_db::models::Participant::Remote { handle, contact_id }
}
},
text: message.text,
date: message.date,
file_transfer_guids: message.attachments.iter().map(|a| a.guid.clone()).collect(),
attachment_metadata: {
let metadata_map: HashMap<String, kordophone::model::message::AttachmentMetadata> =
message
.attachments
.iter()
.filter_map(|a| {
a.metadata
.as_ref()
.map(|m| (a.guid.clone(), m.clone().into()))
})
.collect();
if metadata_map.is_empty() {
None
} else {
Some(metadata_map)
}
},
}
}
}
impl From<kordophone::model::Message> for Message {
fn from(message: kordophone::model::Message) -> Self {
let attachments =
attachments_from(&message.file_transfer_guids, &message.attachment_metadata);
Self {
id: message.guid,
sender: match message.sender {
Some(sender) => Participant::Remote {
handle: sender,
contact_id: None,
},
None => Participant::Me,
},
text: message.text,
date: DateTime::from_timestamp(
message.date.unix_timestamp(),
message.date.unix_timestamp_nanos().try_into().unwrap_or(0),
)
.unwrap()
.naive_local(),
attachments,
}
}
}
impl From<&OutgoingMessage> for Message {
fn from(value: &OutgoingMessage) -> Self {
Self {
id: value.guid.to_string(),
sender: Participant::Me,
text: value.text.clone(),
date: value.date,
attachments: Vec::new(), // Outgoing messages don't have attachments initially
}
}
}
impl From<Participant> for DbParticipant {
fn from(participant: Participant) -> Self {
match participant {
Participant::Me => DbParticipant::Me,
Participant::Remote { handle, contact_id } => DbParticipant::Remote {
handle,
contact_id: contact_id.clone(),
},
}
}
}