Implements attachments display in transcript
This commit is contained in:
@@ -7,8 +7,6 @@ private class ImageBubbleLayout : BubbleLayout
|
||||
|
||||
private Graphene.Size image_size;
|
||||
private Gdk.Texture? cached_texture = null;
|
||||
private const float max_image_width = 300.0f;
|
||||
private const float max_image_height = 400.0f;
|
||||
|
||||
public ImageBubbleLayout(string image_path, bool from_me, Widget parent, float max_width, Graphene.Size? image_size = null) {
|
||||
base(parent, max_width);
|
||||
@@ -29,18 +27,13 @@ private class ImageBubbleLayout : BubbleLayout
|
||||
|
||||
// Try to load the image to get its dimensions
|
||||
try {
|
||||
warning("No image size provided, loading image to get dimensions");
|
||||
|
||||
var texture = Gdk.Texture.from_filename(image_path);
|
||||
var original_width = (float)texture.get_width();
|
||||
var original_height = (float)texture.get_height();
|
||||
|
||||
// Calculate scaled dimensions while maintaining aspect ratio
|
||||
var scale_factor = float.min(
|
||||
max_image_width / original_width,
|
||||
max_image_height / original_height
|
||||
);
|
||||
scale_factor = float.min(scale_factor, 1.0f); // Don't scale up
|
||||
|
||||
this.image_size = Graphene.Size() { width = original_width * scale_factor, height = original_height * scale_factor };
|
||||
this.image_size = Graphene.Size() { width = original_width, height = original_height };
|
||||
} catch (Error e) {
|
||||
// Fallback dimensions if image can't be loaded
|
||||
warning("Failed to load image %s: %s", image_path, e.message);
|
||||
@@ -65,12 +58,8 @@ private class ImageBubbleLayout : BubbleLayout
|
||||
}
|
||||
|
||||
public override float get_height() {
|
||||
float aspect_ratio = image_size.width / image_size.height;
|
||||
if (image_size.width > max_width) {
|
||||
return max_width / aspect_ratio;
|
||||
}
|
||||
|
||||
return image_size.height;
|
||||
var scale_factor = float.min(max_width / image_size.width, 1.0f);
|
||||
return image_size.height * scale_factor;
|
||||
}
|
||||
|
||||
public override float get_width() {
|
||||
|
||||
@@ -108,6 +108,30 @@ private class TranscriptDrawingArea : Widget
|
||||
text_bubble.vertical_padding = (last_sender == message.sender) ? 0.0f : 10.0f;
|
||||
items.add(text_bubble);
|
||||
|
||||
// Check for attachments. For each one, add an image layout bubble
|
||||
foreach (var attachment in message.attachments) {
|
||||
if (attachment.metadata != null) {
|
||||
var image_size = Graphene.Size() {
|
||||
width = attachment.metadata.attribution_info.width,
|
||||
height = attachment.metadata.attribution_info.height
|
||||
};
|
||||
|
||||
var image_layout = new ImageBubbleLayout(attachment.preview_path, message.from_me, this, max_width, image_size);
|
||||
image_layout.is_downloaded = attachment.preview_downloaded;
|
||||
items.add(image_layout);
|
||||
|
||||
// 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.
|
||||
if (!attachment.preview_downloaded) {
|
||||
try {
|
||||
Repository.get_instance().download_attachment(attachment.guid, true);
|
||||
} catch (GLib.Error e) {
|
||||
warning("Wasn't able to message daemon about queuing attachment download: %s", e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
last_sender = message.sender;
|
||||
last_date = date;
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ public class TranscriptView : Adw.Bin
|
||||
private TranscriptDrawingArea transcript_drawing_area = new TranscriptDrawingArea();
|
||||
private ScrolledWindow scrolled_window = new ScrolledWindow();
|
||||
private ulong messages_changed_handler_id = 0;
|
||||
private bool needs_reload = false;
|
||||
|
||||
public TranscriptView() {
|
||||
container = new Adw.ToolbarView();
|
||||
@@ -56,6 +57,36 @@ public class TranscriptView : Adw.Bin
|
||||
var header_bar = new Adw.HeaderBar();
|
||||
header_bar.set_title_widget(title_label);
|
||||
container.add_top_bar(header_bar);
|
||||
|
||||
Repository.get_instance().attachment_downloaded.connect((attachment_guid) => {
|
||||
debug("Attachment downloaded: %s", attachment_guid);
|
||||
|
||||
// See if this attachment is part of this transcript.
|
||||
bool contains_attachment = false;
|
||||
foreach (var message in _model.messages) {
|
||||
foreach (var attachment in message.attachments) {
|
||||
if (attachment.guid == attachment_guid) {
|
||||
contains_attachment = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (contains_attachment && !needs_reload) {
|
||||
debug("Queueing reload of messages for attachment download");
|
||||
|
||||
needs_reload = true;
|
||||
GLib.Idle.add(() => {
|
||||
if (needs_reload) {
|
||||
debug("Reloading messages for attachment download");
|
||||
model.load_messages();
|
||||
needs_reload = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}, GLib.Priority.HIGH);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void reload_messages() {
|
||||
|
||||
Reference in New Issue
Block a user