dbus: Smaller GetMessages buffers, avoid encoding attachment paths.
This commit is contained in:
@@ -264,16 +264,34 @@ impl<'a> Repository<'a> {
|
|||||||
.order_by(schema::messages::date.asc())
|
.order_by(schema::messages::date.asc())
|
||||||
.load::<MessageRecord>(self.connection)?;
|
.load::<MessageRecord>(self.connection)?;
|
||||||
|
|
||||||
|
let sender_handles: Vec<String> = message_records
|
||||||
|
.iter()
|
||||||
|
.filter_map(|record| record.sender_participant_handle.clone())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let participant_map: HashMap<String, Participant> = if sender_handles.is_empty() {
|
||||||
|
HashMap::new()
|
||||||
|
} else {
|
||||||
|
participants
|
||||||
|
.filter(handle.eq_any(&sender_handles))
|
||||||
|
.load::<ParticipantRecord>(self.connection)?
|
||||||
|
.into_iter()
|
||||||
|
.map(|participant| {
|
||||||
|
let key = participant.handle.clone();
|
||||||
|
(key, participant.into())
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
for message_record in message_records {
|
for message_record in message_records {
|
||||||
let mut message: Message = message_record.clone().into();
|
let mut message: Message = message_record.clone().into();
|
||||||
|
|
||||||
// If the message references a sender participant, load the participant info
|
// If the message references a sender participant, load the participant info
|
||||||
if let Some(sender_handle) = message_record.sender_participant_handle {
|
if let Some(sender_handle) = message_record.sender_participant_handle {
|
||||||
let participant = participants
|
if let Some(participant) = participant_map.get(&sender_handle) {
|
||||||
.find(sender_handle)
|
message.sender = participant.clone();
|
||||||
.first::<ParticipantRecord>(self.connection)?;
|
}
|
||||||
message.sender = participant.into();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result.push(message);
|
result.push(message);
|
||||||
@@ -307,8 +325,8 @@ impl<'a> Repository<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_all_messages(&mut self) -> Result<()> {
|
pub fn delete_all_messages(&mut self) -> Result<()> {
|
||||||
use crate::schema::messages::dsl as messages_dsl;
|
|
||||||
use crate::schema::message_aliases::dsl as aliases_dsl;
|
use crate::schema::message_aliases::dsl as aliases_dsl;
|
||||||
|
use crate::schema::messages::dsl as messages_dsl;
|
||||||
|
|
||||||
diesel::delete(messages_dsl::messages).execute(self.connection)?;
|
diesel::delete(messages_dsl::messages).execute(self.connection)?;
|
||||||
diesel::delete(aliases_dsl::message_aliases).execute(self.connection)?;
|
diesel::delete(aliases_dsl::message_aliases).execute(self.connection)?;
|
||||||
|
|||||||
@@ -73,14 +73,13 @@
|
|||||||
'sender' (string): Sender display name
|
'sender' (string): Sender display name
|
||||||
'attachments' (array of dictionaries): List of attachments
|
'attachments' (array of dictionaries): List of attachments
|
||||||
'guid' (string): Attachment GUID
|
'guid' (string): Attachment GUID
|
||||||
'path' (string): Attachment path
|
|
||||||
'preview_path' (string): Preview attachment path
|
|
||||||
'downloaded' (boolean): Whether the attachment is downloaded
|
'downloaded' (boolean): Whether the attachment is downloaded
|
||||||
'preview_downloaded' (boolean): Whether the preview is downloaded
|
'preview_downloaded' (boolean): Whether the preview is downloaded
|
||||||
'metadata' (dictionary, optional): Attachment metadata
|
'metadata' (dictionary, optional): Attachment metadata
|
||||||
'attribution_info' (dictionary, optional): Attribution info
|
'attribution_info' (dictionary, optional): Attribution info
|
||||||
'width' (int32, optional): Width
|
'width' (int32, optional): Width
|
||||||
'height' (int32, optional): Height"/>
|
'height' (int32, optional): Height
|
||||||
|
Use GetAttachmentInfo for full/preview paths."/>
|
||||||
</arg>
|
</arg>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ use std::collections::HashMap;
|
|||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
const LOOKUP_TIMEOUT: Duration = Duration::from_secs(2);
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct EDSContactResolverBackend;
|
pub struct EDSContactResolverBackend;
|
||||||
|
|
||||||
@@ -189,11 +191,10 @@ impl ContactResolverBackend for EDSContactResolverBackend {
|
|||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let address_book_proxy = handle.connection.with_proxy(
|
let address_book_proxy =
|
||||||
&handle.bus_name,
|
handle
|
||||||
&handle.object_path,
|
.connection
|
||||||
Duration::from_secs(60),
|
.with_proxy(&handle.bus_name, &handle.object_path, LOOKUP_TIMEOUT);
|
||||||
);
|
|
||||||
|
|
||||||
ensure_address_book_open(&address_book_proxy);
|
ensure_address_book_open(&address_book_proxy);
|
||||||
|
|
||||||
@@ -255,11 +256,10 @@ impl ContactResolverBackend for EDSContactResolverBackend {
|
|||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let address_book_proxy = handle.connection.with_proxy(
|
let address_book_proxy =
|
||||||
&handle.bus_name,
|
handle
|
||||||
&handle.object_path,
|
.connection
|
||||||
Duration::from_secs(60),
|
.with_proxy(&handle.bus_name, &handle.object_path, LOOKUP_TIMEOUT);
|
||||||
);
|
|
||||||
|
|
||||||
ensure_address_book_open(&address_book_proxy);
|
ensure_address_book_open(&address_book_proxy);
|
||||||
|
|
||||||
|
|||||||
@@ -185,14 +185,14 @@ impl Daemon {
|
|||||||
async fn handle_event(&mut self, event: Event) {
|
async fn handle_event(&mut self, event: Event) {
|
||||||
match event {
|
match event {
|
||||||
Event::GetVersion(reply) => {
|
Event::GetVersion(reply) => {
|
||||||
reply.send(self.version.clone()).unwrap();
|
let _ = reply.send(self.version.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::SyncConversationList(reply) => {
|
Event::SyncConversationList(reply) => {
|
||||||
self.spawn_conversation_list_sync();
|
self.spawn_conversation_list_sync();
|
||||||
|
|
||||||
// This is a background operation, so return right away.
|
// This is a background operation, so return right away.
|
||||||
reply.send(()).unwrap();
|
let _ = reply.send(());
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::SyncAllConversations(reply) => {
|
Event::SyncAllConversations(reply) => {
|
||||||
@@ -207,7 +207,7 @@ impl Daemon {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// This is a background operation, so return right away.
|
// This is a background operation, so return right away.
|
||||||
reply.send(()).unwrap();
|
let _ = reply.send(());
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::SyncConversation(conversation_id, reply) => {
|
Event::SyncConversation(conversation_id, reply) => {
|
||||||
@@ -225,7 +225,7 @@ impl Daemon {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
reply.send(()).unwrap();
|
let _ = reply.send(());
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::MarkConversationAsRead(conversation_id, reply) => {
|
Event::MarkConversationAsRead(conversation_id, reply) => {
|
||||||
@@ -237,7 +237,7 @@ impl Daemon {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
reply.send(()).unwrap();
|
let _ = reply.send(());
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::UpdateConversationMetadata(conversation, reply) => {
|
Event::UpdateConversationMetadata(conversation, reply) => {
|
||||||
@@ -250,7 +250,7 @@ impl Daemon {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
reply.send(()).unwrap();
|
let _ = reply.send(());
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::UpdateStreamReconnected => {
|
Event::UpdateStreamReconnected => {
|
||||||
@@ -268,7 +268,7 @@ impl Daemon {
|
|||||||
|
|
||||||
Event::GetAllConversations(limit, offset, reply) => {
|
Event::GetAllConversations(limit, offset, reply) => {
|
||||||
let conversations = self.get_conversations_limit_offset(limit, offset).await;
|
let conversations = self.get_conversations_limit_offset(limit, offset).await;
|
||||||
reply.send(conversations).unwrap();
|
let _ = reply.send(conversations);
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::GetAllSettings(reply) => {
|
Event::GetAllSettings(reply) => {
|
||||||
@@ -277,7 +277,7 @@ impl Daemon {
|
|||||||
Settings::default()
|
Settings::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
reply.send(settings).unwrap();
|
let _ = reply.send(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::UpdateSettings(settings, reply) => {
|
Event::UpdateSettings(settings, reply) => {
|
||||||
@@ -309,12 +309,12 @@ impl Daemon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reply.send(()).unwrap();
|
let _ = reply.send(());
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::GetMessages(conversation_id, last_message_id, reply) => {
|
Event::GetMessages(conversation_id, last_message_id, reply) => {
|
||||||
let messages = self.get_messages(conversation_id, last_message_id).await;
|
let messages = self.get_messages(conversation_id, last_message_id).await;
|
||||||
reply.send(messages).unwrap();
|
let _ = reply.send(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::DeleteAllConversations(reply) => {
|
Event::DeleteAllConversations(reply) => {
|
||||||
@@ -322,7 +322,7 @@ impl Daemon {
|
|||||||
log::error!(target: target::SYNC, "Failed to delete all conversations: {}", e);
|
log::error!(target: target::SYNC, "Failed to delete all conversations: {}", e);
|
||||||
});
|
});
|
||||||
|
|
||||||
reply.send(()).unwrap();
|
let _ = reply.send(());
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::SendMessage(conversation_id, text, attachment_guids, reply) => {
|
Event::SendMessage(conversation_id, text, attachment_guids, reply) => {
|
||||||
@@ -330,7 +330,7 @@ impl Daemon {
|
|||||||
let uuid = self
|
let uuid = self
|
||||||
.enqueue_outgoing_message(text, conversation_id.clone(), attachment_guids)
|
.enqueue_outgoing_message(text, conversation_id.clone(), attachment_guids)
|
||||||
.await;
|
.await;
|
||||||
reply.send(uuid).unwrap();
|
let _ = reply.send(uuid);
|
||||||
|
|
||||||
// Send message updated signal, we have a placeholder message we will return.
|
// Send message updated signal, we have a placeholder message we will return.
|
||||||
self.signal_sender
|
self.signal_sender
|
||||||
@@ -395,7 +395,7 @@ impl Daemon {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
reply.send(()).unwrap();
|
let _ = reply.send(());
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::AttachmentDownloaded(attachment_id) => {
|
Event::AttachmentDownloaded(attachment_id) => {
|
||||||
|
|||||||
@@ -176,9 +176,8 @@ impl DBusAgent {
|
|||||||
&self,
|
&self,
|
||||||
make_event: impl FnOnce(Reply<T>) -> Event + Send,
|
make_event: impl FnOnce(Reply<T>) -> Event + Send,
|
||||||
) -> Result<T, MethodErr> {
|
) -> Result<T, MethodErr> {
|
||||||
run_sync_future(self.send_event(make_event))
|
let daemon_result = run_sync_future(self.send_event(make_event))?;
|
||||||
.unwrap()
|
daemon_result.map_err(|e| MethodErr::failed(&format!("Daemon error: {}", e)))
|
||||||
.map_err(|e| MethodErr::failed(&format!("Daemon error: {}", e)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_participant_display_name(&mut self, participant: &Participant) -> String {
|
fn resolve_participant_display_name(&mut self, participant: &Participant) -> String {
|
||||||
@@ -284,104 +283,86 @@ impl DbusRepository for DBusAgent {
|
|||||||
Some(last_message_id)
|
Some(last_message_id)
|
||||||
};
|
};
|
||||||
|
|
||||||
self.send_event_sync(|r| Event::GetMessages(conversation_id, last_message_id_opt, r))
|
let messages =
|
||||||
.map(|messages| {
|
self.send_event_sync(|r| Event::GetMessages(conversation_id, last_message_id_opt, r))?;
|
||||||
messages
|
|
||||||
|
let mapped: Vec<arg::PropMap> = messages
|
||||||
|
.into_iter()
|
||||||
|
.map(|msg| {
|
||||||
|
let mut map = arg::PropMap::new();
|
||||||
|
map.insert("id".into(), arg::Variant(Box::new(msg.id)));
|
||||||
|
|
||||||
|
// Remove the attachment placeholder here.
|
||||||
|
let text = msg.text.replace("\u{FFFC}", "");
|
||||||
|
|
||||||
|
map.insert("text".into(), arg::Variant(Box::new(text)));
|
||||||
|
map.insert(
|
||||||
|
"date".into(),
|
||||||
|
arg::Variant(Box::new(msg.date.and_utc().timestamp())),
|
||||||
|
);
|
||||||
|
map.insert(
|
||||||
|
"sender".into(),
|
||||||
|
arg::Variant(Box::new(msg.sender.display_name())),
|
||||||
|
);
|
||||||
|
|
||||||
|
let attachments: Vec<arg::PropMap> = msg
|
||||||
|
.attachments
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|msg| {
|
.map(|attachment| {
|
||||||
let mut map = arg::PropMap::new();
|
let mut attachment_map = arg::PropMap::new();
|
||||||
map.insert("id".into(), arg::Variant(Box::new(msg.id)));
|
attachment_map.insert(
|
||||||
|
"guid".into(),
|
||||||
// Remove the attachment placeholder here.
|
arg::Variant(Box::new(attachment.guid.clone())),
|
||||||
let text = msg.text.replace("\u{FFFC}", "");
|
|
||||||
|
|
||||||
map.insert("text".into(), arg::Variant(Box::new(text)));
|
|
||||||
map.insert(
|
|
||||||
"date".into(),
|
|
||||||
arg::Variant(Box::new(msg.date.and_utc().timestamp())),
|
|
||||||
);
|
);
|
||||||
map.insert(
|
attachment_map.insert(
|
||||||
"sender".into(),
|
"downloaded".into(),
|
||||||
arg::Variant(Box::new(
|
arg::Variant(Box::new(attachment.is_downloaded(false))),
|
||||||
self.resolve_participant_display_name(&msg.sender.into()),
|
);
|
||||||
)),
|
attachment_map.insert(
|
||||||
|
"preview_downloaded".into(),
|
||||||
|
arg::Variant(Box::new(attachment.is_downloaded(true))),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Attachments array
|
if let Some(ref metadata) = attachment.metadata {
|
||||||
let attachments: Vec<arg::PropMap> = msg
|
let mut metadata_map = arg::PropMap::new();
|
||||||
.attachments
|
|
||||||
.into_iter()
|
|
||||||
.map(|attachment| {
|
|
||||||
let mut attachment_map = arg::PropMap::new();
|
|
||||||
attachment_map.insert(
|
|
||||||
"guid".into(),
|
|
||||||
arg::Variant(Box::new(attachment.guid.clone())),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Paths and download status
|
if let Some(ref attribution_info) = metadata.attribution_info {
|
||||||
let path = attachment.get_path_for_preview(false);
|
let mut attribution_map = arg::PropMap::new();
|
||||||
let preview_path = attachment.get_path_for_preview(true);
|
if let Some(width) = attribution_info.width {
|
||||||
let downloaded = attachment.is_downloaded(false);
|
attribution_map.insert(
|
||||||
let preview_downloaded = attachment.is_downloaded(true);
|
"width".into(),
|
||||||
|
arg::Variant(Box::new(width as i32)),
|
||||||
attachment_map.insert(
|
|
||||||
"path".into(),
|
|
||||||
arg::Variant(Box::new(path.to_string_lossy().to_string())),
|
|
||||||
);
|
|
||||||
attachment_map.insert(
|
|
||||||
"preview_path".into(),
|
|
||||||
arg::Variant(Box::new(
|
|
||||||
preview_path.to_string_lossy().to_string(),
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
attachment_map.insert(
|
|
||||||
"downloaded".into(),
|
|
||||||
arg::Variant(Box::new(downloaded)),
|
|
||||||
);
|
|
||||||
attachment_map.insert(
|
|
||||||
"preview_downloaded".into(),
|
|
||||||
arg::Variant(Box::new(preview_downloaded)),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Metadata
|
|
||||||
if let Some(ref metadata) = attachment.metadata {
|
|
||||||
let mut metadata_map = arg::PropMap::new();
|
|
||||||
|
|
||||||
if let Some(ref attribution_info) = metadata.attribution_info {
|
|
||||||
let mut attribution_map = arg::PropMap::new();
|
|
||||||
if let Some(width) = attribution_info.width {
|
|
||||||
attribution_map.insert(
|
|
||||||
"width".into(),
|
|
||||||
arg::Variant(Box::new(width as i32)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if let Some(height) = attribution_info.height {
|
|
||||||
attribution_map.insert(
|
|
||||||
"height".into(),
|
|
||||||
arg::Variant(Box::new(height as i32)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
metadata_map.insert(
|
|
||||||
"attribution_info".into(),
|
|
||||||
arg::Variant(Box::new(attribution_map)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
attachment_map.insert(
|
|
||||||
"metadata".into(),
|
|
||||||
arg::Variant(Box::new(metadata_map)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if let Some(height) = attribution_info.height {
|
||||||
|
attribution_map.insert(
|
||||||
|
"height".into(),
|
||||||
|
arg::Variant(Box::new(height as i32)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
metadata_map.insert(
|
||||||
|
"attribution_info".into(),
|
||||||
|
arg::Variant(Box::new(attribution_map)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
attachment_map
|
attachment_map.insert(
|
||||||
})
|
"metadata".into(),
|
||||||
.collect();
|
arg::Variant(Box::new(metadata_map)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
map.insert("attachments".into(), arg::Variant(Box::new(attachments)));
|
attachment_map
|
||||||
map
|
|
||||||
})
|
})
|
||||||
.collect()
|
.collect();
|
||||||
|
|
||||||
|
map.insert("attachments".into(), arg::Variant(Box::new(attachments)));
|
||||||
|
|
||||||
|
map
|
||||||
})
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(mapped)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_all_conversations(&mut self) -> Result<(), MethodErr> {
|
fn delete_all_conversations(&mut self) -> Result<(), MethodErr> {
|
||||||
@@ -496,7 +477,7 @@ where
|
|||||||
T: Send,
|
T: Send,
|
||||||
F: Future<Output = T> + Send,
|
F: Future<Output = T> + Send,
|
||||||
{
|
{
|
||||||
thread::scope(move |s| {
|
let joined = thread::scope(move |s| {
|
||||||
s.spawn(move || {
|
s.spawn(move || {
|
||||||
let rt = tokio::runtime::Builder::new_current_thread()
|
let rt = tokio::runtime::Builder::new_current_thread()
|
||||||
.enable_all()
|
.enable_all()
|
||||||
@@ -507,6 +488,10 @@ where
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
})
|
})
|
||||||
.join()
|
.join()
|
||||||
})
|
});
|
||||||
.expect("Error joining runtime thread")
|
|
||||||
|
match joined {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(_) => Err(MethodErr::failed("Error joining runtime thread")),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ impl DBusDaemonInterface {
|
|||||||
|
|
||||||
fn proxy(&self) -> Proxy<&Connection> {
|
fn proxy(&self) -> Proxy<&Connection> {
|
||||||
self.conn
|
self.conn
|
||||||
.with_proxy(DBUS_NAME, DBUS_PATH, std::time::Duration::from_millis(5000))
|
.with_proxy(DBUS_NAME, DBUS_PATH, std::time::Duration::from_secs(30))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn print_settings(&mut self) -> Result<()> {
|
async fn print_settings(&mut self) -> Result<()> {
|
||||||
|
|||||||
@@ -44,11 +44,11 @@ public class AttachmentInfo : Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class Attachment : Object {
|
public class Attachment : Object {
|
||||||
public string guid;
|
public string guid = "";
|
||||||
public string path;
|
public string path = "";
|
||||||
public string preview_path;
|
public string preview_path = "";
|
||||||
public bool downloaded;
|
public bool downloaded = false;
|
||||||
public bool preview_downloaded;
|
public bool preview_downloaded = false;
|
||||||
public AttachmentMetadata? metadata;
|
public AttachmentMetadata? metadata;
|
||||||
|
|
||||||
public Attachment(string guid, AttachmentMetadata? metadata) {
|
public Attachment(string guid, AttachmentMetadata? metadata) {
|
||||||
|
|||||||
@@ -73,14 +73,13 @@
|
|||||||
'sender' (string): Sender display name
|
'sender' (string): Sender display name
|
||||||
'attachments' (array of dictionaries): List of attachments
|
'attachments' (array of dictionaries): List of attachments
|
||||||
'guid' (string): Attachment GUID
|
'guid' (string): Attachment GUID
|
||||||
'path' (string): Attachment path
|
|
||||||
'preview_path' (string): Preview attachment path
|
|
||||||
'downloaded' (boolean): Whether the attachment is downloaded
|
'downloaded' (boolean): Whether the attachment is downloaded
|
||||||
'preview_downloaded' (boolean): Whether the preview is downloaded
|
'preview_downloaded' (boolean): Whether the preview is downloaded
|
||||||
'metadata' (dictionary, optional): Attachment metadata
|
'metadata' (dictionary, optional): Attachment metadata
|
||||||
'attribution_info' (dictionary, optional): Attribution info
|
'attribution_info' (dictionary, optional): Attribution info
|
||||||
'width' (int32, optional): Width
|
'width' (int32, optional): Width
|
||||||
'height' (int32, optional): Height"/>
|
'height' (int32, optional): Height
|
||||||
|
Use GetAttachmentInfo for full/preview paths."/>
|
||||||
</arg>
|
</arg>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
|||||||
@@ -363,6 +363,21 @@ private class TranscriptDrawingArea : Widget
|
|||||||
|
|
||||||
// Check for attachments. For each one, add an image layout bubble
|
// Check for attachments. For each one, add an image layout bubble
|
||||||
foreach (var attachment in message.attachments) {
|
foreach (var attachment in message.attachments) {
|
||||||
|
string preview_path = attachment.preview_path;
|
||||||
|
bool preview_downloaded = attachment.preview_downloaded;
|
||||||
|
|
||||||
|
if (preview_path == null || preview_path == "") {
|
||||||
|
try {
|
||||||
|
var attachment_info = Repository.get_instance().get_attachment_info(attachment.guid);
|
||||||
|
if (attachment_info.preview_path != null) {
|
||||||
|
preview_path = attachment_info.preview_path;
|
||||||
|
}
|
||||||
|
preview_downloaded = attachment_info.preview_downloaded == true;
|
||||||
|
} catch (GLib.Error e) {
|
||||||
|
warning("Failed to load attachment info for %s: %s", attachment.guid, e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Graphene.Size? image_size = null;
|
Graphene.Size? image_size = null;
|
||||||
if (attachment.metadata != null) {
|
if (attachment.metadata != null) {
|
||||||
image_size = Graphene.Size() {
|
image_size = Graphene.Size() {
|
||||||
@@ -371,7 +386,7 @@ private class TranscriptDrawingArea : Widget
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var image_layout = new ImageBubbleLayout(attachment.preview_path, message.from_me, this, max_width, image_size);
|
var image_layout = new ImageBubbleLayout(preview_path, message.from_me, this, max_width, image_size);
|
||||||
image_layout.id = @"image-$(attachment.guid)";
|
image_layout.id = @"image-$(attachment.guid)";
|
||||||
image_layout.attachment_guid = attachment.guid;
|
image_layout.attachment_guid = attachment.guid;
|
||||||
|
|
||||||
@@ -379,12 +394,12 @@ private class TranscriptDrawingArea : Widget
|
|||||||
start_animation(image_layout.id);
|
start_animation(image_layout.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
image_layout.is_downloaded = attachment.preview_downloaded;
|
image_layout.is_downloaded = preview_downloaded;
|
||||||
items.add(image_layout);
|
items.add(image_layout);
|
||||||
|
|
||||||
// If the attachment isn't downloaded, queue a download since we are going to be showing it here.
|
// If the attachment isn't downloaded, queue a download since we are going to be showing it here.
|
||||||
// TODO: Probably would be better if we only did this for stuff in the viewport.
|
// TODO: Probably would be better if we only did this for stuff in the viewport.
|
||||||
if (!attachment.preview_downloaded) {
|
if (!preview_downloaded) {
|
||||||
try {
|
try {
|
||||||
Repository.get_instance().download_attachment(attachment.guid, true);
|
Repository.get_instance().download_attachment(attachment.guid, true);
|
||||||
} catch (GLib.Error e) {
|
} catch (GLib.Error e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user