Fix some memory leaks
This commit is contained in:
parent
c526848098
commit
fb799e3ba8
|
@ -71,9 +71,7 @@ public class ConversationItemSkeleton : Plugins.ConversationItemWidgetInterface,
|
||||||
ContentMetaItem? content_meta_item = item as ContentMetaItem;
|
ContentMetaItem? content_meta_item = item as ContentMetaItem;
|
||||||
if (content_meta_item != null) {
|
if (content_meta_item != null) {
|
||||||
reactions_controller = new ReactionsController(conversation, content_meta_item.content_item, stream_interactor);
|
reactions_controller = new ReactionsController(conversation, content_meta_item.content_item, stream_interactor);
|
||||||
reactions_controller.box_activated.connect((widget) => {
|
reactions_controller.box_activated.connect(on_reaction_box_activated);
|
||||||
set_widget(widget, Plugins.WidgetType.GTK4, 3);
|
|
||||||
});
|
|
||||||
reactions_controller.init();
|
reactions_controller.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +168,10 @@ public class ConversationItemSkeleton : Plugins.ConversationItemWidgetInterface,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void on_reaction_box_activated(Widget widget) {
|
||||||
|
set_widget(widget, Plugins.WidgetType.GTK4, 3);
|
||||||
|
}
|
||||||
|
|
||||||
private void update_time() {
|
private void update_time() {
|
||||||
time_label.label = get_relative_time(item.time.to_local()).to_string();
|
time_label.label = get_relative_time(item.time.to_local()).to_string();
|
||||||
|
|
||||||
|
@ -271,6 +273,34 @@ public class ConversationItemSkeleton : Plugins.ConversationItemWidgetInterface,
|
||||||
stream_interactor.get_module(RosterManager.IDENTITY).disconnect(updated_roster_handler_id);
|
stream_interactor.get_module(RosterManager.IDENTITY).disconnect(updated_roster_handler_id);
|
||||||
updated_roster_handler_id = 0;
|
updated_roster_handler_id = 0;
|
||||||
}
|
}
|
||||||
|
reactions_controller = null;
|
||||||
|
|
||||||
|
// Children won't be disposed automatically
|
||||||
|
if (name_label != null) {
|
||||||
|
name_label.unparent();
|
||||||
|
name_label.dispose();
|
||||||
|
name_label = null;
|
||||||
|
}
|
||||||
|
if (time_label != null) {
|
||||||
|
time_label.unparent();
|
||||||
|
time_label.dispose();
|
||||||
|
time_label = null;
|
||||||
|
}
|
||||||
|
if (avatar_image != null) {
|
||||||
|
avatar_image.unparent();
|
||||||
|
avatar_image.dispose();
|
||||||
|
avatar_image = null;
|
||||||
|
}
|
||||||
|
if (encryption_image != null) {
|
||||||
|
encryption_image.unparent();
|
||||||
|
encryption_image.dispose();
|
||||||
|
encryption_image = null;
|
||||||
|
}
|
||||||
|
if (received_image != null) {
|
||||||
|
received_image.unparent();
|
||||||
|
received_image.dispose();
|
||||||
|
received_image = null;
|
||||||
|
}
|
||||||
base.dispose();
|
base.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -426,6 +426,7 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug
|
||||||
content_items.remove((ContentMetaItem)item);
|
content_items.remove((ContentMetaItem)item);
|
||||||
}
|
}
|
||||||
meta_items.remove(item);
|
meta_items.remove(item);
|
||||||
|
skeleton.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
removed_item(item);
|
removed_item(item);
|
||||||
|
@ -591,12 +592,19 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug
|
||||||
private void clear() {
|
private void clear() {
|
||||||
was_upper = null;
|
was_upper = null;
|
||||||
was_page_size = null;
|
was_page_size = null;
|
||||||
|
foreach (var item in content_items) {
|
||||||
|
item.dispose();
|
||||||
|
}
|
||||||
content_items.clear();
|
content_items.clear();
|
||||||
meta_items.clear();
|
meta_items.clear();
|
||||||
widget_order.clear();
|
widget_order.clear();
|
||||||
|
foreach (var skeleton in item_item_skeletons.values) {
|
||||||
|
skeleton.dispose();
|
||||||
|
}
|
||||||
item_item_skeletons.clear();
|
item_item_skeletons.clear();
|
||||||
foreach (Widget widget in widgets.values) {
|
foreach (Widget widget in widgets.values) {
|
||||||
main.remove(widget);
|
widget.unparent();
|
||||||
|
widget.dispose();
|
||||||
}
|
}
|
||||||
widgets.clear();
|
widgets.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,6 +135,17 @@ public class FileWidget : SizeRequestBox {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void dispose() {
|
||||||
|
if (default_widget_controller != null) default_widget_controller.dispose();
|
||||||
|
default_widget_controller = null;
|
||||||
|
if (content != null) {
|
||||||
|
content.unparent();
|
||||||
|
content.dispose();
|
||||||
|
content = null;
|
||||||
|
}
|
||||||
|
base.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FileWidgetController : Object {
|
public class FileWidgetController : Object {
|
||||||
|
|
|
@ -19,6 +19,7 @@ public class MessageMetaItem : ContentMetaItem {
|
||||||
private StreamInteractor stream_interactor;
|
private StreamInteractor stream_interactor;
|
||||||
private MessageItem message_item;
|
private MessageItem message_item;
|
||||||
public Message.Marked marked { get; set; }
|
public Message.Marked marked { get; set; }
|
||||||
|
public Plugins.ConversationItemWidgetInterface outer = null;
|
||||||
|
|
||||||
MessageItemEditMode? edit_mode = null;
|
MessageItemEditMode? edit_mode = null;
|
||||||
ChatTextViewController? controller = null;
|
ChatTextViewController? controller = null;
|
||||||
|
@ -35,6 +36,8 @@ public class MessageMetaItem : ContentMetaItem {
|
||||||
message_item = content_item as MessageItem;
|
message_item = content_item as MessageItem;
|
||||||
this.stream_interactor = stream_interactor;
|
this.stream_interactor = stream_interactor;
|
||||||
|
|
||||||
|
stream_interactor.get_module(MessageCorrection.IDENTITY).received_correction.connect(on_received_correction);
|
||||||
|
|
||||||
label.activate_link.connect(on_label_activate_link);
|
label.activate_link.connect(on_label_activate_link);
|
||||||
|
|
||||||
Message message = ((MessageItem) content_item).message;
|
Message message = ((MessageItem) content_item).message;
|
||||||
|
@ -146,10 +149,50 @@ public class MessageMetaItem : ContentMetaItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Object? get_widget(Plugins.ConversationItemWidgetInterface outer, Plugins.WidgetType type) {
|
public override Object? get_widget(Plugins.ConversationItemWidgetInterface outer, Plugins.WidgetType type) {
|
||||||
|
this.outer = outer;
|
||||||
|
|
||||||
stream_interactor.get_module(MessageCorrection.IDENTITY).received_correction.connect(on_received_correction);
|
this.notify["in-edit-mode"].connect(on_in_edit_mode_changed);
|
||||||
|
|
||||||
this.notify["in-edit-mode"].connect(() => {
|
outer.set_widget(label, Plugins.WidgetType.GTK4, 2);
|
||||||
|
|
||||||
|
if (message_item.message.quoted_item_id > 0) {
|
||||||
|
var quoted_content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_item_by_id(message_item.conversation, message_item.message.quoted_item_id);
|
||||||
|
if (quoted_content_item != null) {
|
||||||
|
var quote_model = new Quote.Model.from_content_item(quoted_content_item, message_item.conversation, stream_interactor);
|
||||||
|
quote_model.jump_to.connect(() => {
|
||||||
|
GLib.Application.get_default().activate_action("jump-to-conversation-message", new GLib.Variant.tuple(new GLib.Variant[] { new GLib.Variant.int32(message_item.conversation.id), new GLib.Variant.int32(quoted_content_item.id) }));
|
||||||
|
});
|
||||||
|
var quote_widget = Quote.get_widget(quote_model);
|
||||||
|
outer.set_widget(quote_widget, Plugins.WidgetType.GTK4, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Gee.List<Plugins.MessageAction>? get_item_actions(Plugins.WidgetType type) {
|
||||||
|
if (in_edit_mode) return null;
|
||||||
|
|
||||||
|
Gee.List<Plugins.MessageAction> actions = new ArrayList<Plugins.MessageAction>();
|
||||||
|
|
||||||
|
bool correction_allowed = stream_interactor.get_module(MessageCorrection.IDENTITY).is_own_correction_allowed(message_item.conversation, message_item.message);
|
||||||
|
if (correction_allowed) {
|
||||||
|
Plugins.MessageAction action1 = new Plugins.MessageAction();
|
||||||
|
action1.name = "correction";
|
||||||
|
action1.icon_name = "document-edit-symbolic";
|
||||||
|
action1.tooltip = _("Edit message");
|
||||||
|
action1.callback = () => {
|
||||||
|
this.in_edit_mode = true;
|
||||||
|
};
|
||||||
|
actions.add(action1);
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.add(get_reply_action(content_item, message_item.conversation, stream_interactor));
|
||||||
|
actions.add(get_reaction_action(content_item, message_item.conversation, stream_interactor));
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void on_in_edit_mode_changed() {
|
||||||
if (in_edit_mode == false) return;
|
if (in_edit_mode == false) return;
|
||||||
bool allowed = stream_interactor.get_module(MessageCorrection.IDENTITY).is_own_correction_allowed(message_item.conversation, message_item.message);
|
bool allowed = stream_interactor.get_module(MessageCorrection.IDENTITY).is_own_correction_allowed(message_item.conversation, message_item.message);
|
||||||
if (allowed) {
|
if (allowed) {
|
||||||
|
@ -182,46 +225,6 @@ public class MessageMetaItem : ContentMetaItem {
|
||||||
} else {
|
} else {
|
||||||
this.in_edit_mode = false;
|
this.in_edit_mode = false;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
outer.set_widget(label, Plugins.WidgetType.GTK4, 2);
|
|
||||||
|
|
||||||
if (message_item.message.quoted_item_id > 0) {
|
|
||||||
var quoted_content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_item_by_id(message_item.conversation, message_item.message.quoted_item_id);
|
|
||||||
if (quoted_content_item != null) {
|
|
||||||
var quote_model = new Quote.Model.from_content_item(quoted_content_item, message_item.conversation, stream_interactor);
|
|
||||||
quote_model.jump_to.connect(() => {
|
|
||||||
GLib.Application.get_default().activate_action("jump-to-conversation-message", new GLib.Variant.tuple(new GLib.Variant[] { new GLib.Variant.int32(message_item.conversation.id), new GLib.Variant.int32(quoted_content_item.id) }));
|
|
||||||
});
|
|
||||||
var quote_widget = Quote.get_widget(quote_model);
|
|
||||||
outer.set_widget(quote_widget, Plugins.WidgetType.GTK4, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Gee.List<Plugins.MessageAction>? get_item_actions(Plugins.WidgetType type) {
|
|
||||||
if (content_item as FileItem != null || this.in_edit_mode) return null;
|
|
||||||
if (in_edit_mode) return null;
|
|
||||||
|
|
||||||
Gee.List<Plugins.MessageAction> actions = new ArrayList<Plugins.MessageAction>();
|
|
||||||
|
|
||||||
bool correction_allowed = stream_interactor.get_module(MessageCorrection.IDENTITY).is_own_correction_allowed(message_item.conversation, message_item.message);
|
|
||||||
if (correction_allowed) {
|
|
||||||
Plugins.MessageAction action1 = new Plugins.MessageAction();
|
|
||||||
action1.name = "correction";
|
|
||||||
action1.icon_name = "document-edit-symbolic";
|
|
||||||
action1.tooltip = _("Edit message");
|
|
||||||
action1.callback = () => {
|
|
||||||
this.in_edit_mode = true;
|
|
||||||
};
|
|
||||||
actions.add(action1);
|
|
||||||
}
|
|
||||||
|
|
||||||
actions.add(get_reply_action(content_item, message_item.conversation, stream_interactor));
|
|
||||||
actions.add(get_reaction_action(content_item, message_item.conversation, stream_interactor));
|
|
||||||
|
|
||||||
return actions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_edit_send(string text) {
|
private void on_edit_send(string text) {
|
||||||
|
@ -244,6 +247,17 @@ public class MessageMetaItem : ContentMetaItem {
|
||||||
Dino.Application.get_default().open(new File[]{file}, "");
|
Dino.Application.get_default().open(new File[]{file}, "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void dispose() {
|
||||||
|
stream_interactor.get_module(MessageCorrection.IDENTITY).received_correction.disconnect(on_received_correction);
|
||||||
|
this.notify["in-edit-mode"].disconnect(on_in_edit_mode_changed);
|
||||||
|
if (label != null) {
|
||||||
|
label.unparent();
|
||||||
|
label.dispose();
|
||||||
|
label = null;
|
||||||
|
}
|
||||||
|
base.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[GtkTemplate (ui = "/im/dino/Dino/message_item_widget_edit_mode.ui")]
|
[GtkTemplate (ui = "/im/dino/Dino/message_item_widget_edit_mode.ui")]
|
||||||
|
|
|
@ -40,8 +40,14 @@ public class Dino.Ui.ViewModel.CompatDateSeparatorModel : DateSeparatorModel {
|
||||||
|
|
||||||
private void update_time_label() {
|
private void update_time_label() {
|
||||||
date_label = get_relative_time(date);
|
date_label = get_relative_time(date);
|
||||||
time_update_timeout = Timeout.add_seconds((int) get_next_time_change(), () => {
|
time_update_timeout = set_update_time_label_timeout((int) get_next_time_change(), this);
|
||||||
if (time_update_timeout != 0) update_time_label();
|
}
|
||||||
|
|
||||||
|
private static uint set_update_time_label_timeout(int interval, CompatDateSeparatorModel model_) {
|
||||||
|
WeakRef model_weak = WeakRef(model_);
|
||||||
|
return Timeout.add_seconds(interval, () => {
|
||||||
|
CompatDateSeparatorModel? model = (CompatDateSeparatorModel) model_weak.get();
|
||||||
|
if (model != null && model.time_update_timeout != 0) model.update_time_label();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,7 @@ public class BadMessagesPopulator : Plugins.ConversationItemPopulator, Plugins.C
|
||||||
foreach (BadMessageItem bad_item in bad_items) {
|
foreach (BadMessageItem bad_item in bad_items) {
|
||||||
item_collection.remove_item(bad_item);
|
item_collection.remove_item(bad_item);
|
||||||
}
|
}
|
||||||
|
bad_items.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(Conversation conversation, Plugins.ConversationItemCollection item_collection, Plugins.WidgetType type) {
|
public void init(Conversation conversation, Plugins.ConversationItemCollection item_collection, Plugins.WidgetType type) {
|
||||||
|
@ -103,7 +104,9 @@ public class BadMessagesPopulator : Plugins.ConversationItemPopulator, Plugins.C
|
||||||
init_state();
|
init_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close(Conversation conversation) { }
|
public void close(Conversation conversation) {
|
||||||
|
clear_state();
|
||||||
|
}
|
||||||
|
|
||||||
public void populate_timespan(Conversation conversation, DateTime after, DateTime before) { }
|
public void populate_timespan(Conversation conversation, DateTime after, DateTime before) { }
|
||||||
}
|
}
|
||||||
|
@ -131,9 +134,17 @@ public class BadMessageItem : Plugins.MetaConversationItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BadMessagesWidget : Box {
|
public class BadMessagesWidget : Box {
|
||||||
|
private Plugin plugin;
|
||||||
|
private Conversation conversation;
|
||||||
|
private Jid jid;
|
||||||
|
private Label label;
|
||||||
|
|
||||||
public BadMessagesWidget(Plugin plugin, Conversation conversation, Jid jid, BadnessType badness_type) {
|
public BadMessagesWidget(Plugin plugin, Conversation conversation, Jid jid, BadnessType badness_type) {
|
||||||
Object(orientation:Orientation.HORIZONTAL, spacing:5);
|
Object(orientation:Orientation.HORIZONTAL, spacing:5);
|
||||||
|
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.conversation = conversation;
|
||||||
|
this.jid = jid;
|
||||||
this.halign = Align.CENTER;
|
this.halign = Align.CENTER;
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
|
|
||||||
|
@ -159,19 +170,29 @@ public class BadMessagesWidget : Box {
|
||||||
} else {
|
} else {
|
||||||
warning_text += _("%s does not trust this device. That means, you might be missing messages.").printf(who);
|
warning_text += _("%s does not trust this device. That means, you might be missing messages.").printf(who);
|
||||||
}
|
}
|
||||||
Label label = new Label(warning_text) { margin_start=70, margin_end=70, justify=Justification.CENTER, use_markup=true, selectable=true, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, hexpand=true };
|
label = new Label(warning_text) { margin_start=70, margin_end=70, justify=Justification.CENTER, use_markup=true, selectable=true, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, hexpand=true };
|
||||||
label.add_css_class("dim-label");
|
label.add_css_class("dim-label");
|
||||||
this.append(label);
|
this.append(label);
|
||||||
|
|
||||||
label.activate_link.connect(() => {
|
|
||||||
if (badness_type == BadnessType.UNTRUSTED) {
|
if (badness_type == BadnessType.UNTRUSTED) {
|
||||||
|
label.activate_link.connect(on_label_activate_link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool on_label_activate_link() {
|
||||||
ContactDetailsDialog dialog = new ContactDetailsDialog(plugin, conversation.account, jid);
|
ContactDetailsDialog dialog = new ContactDetailsDialog(plugin, conversation.account, jid);
|
||||||
dialog.set_transient_for((Window) get_root());
|
dialog.set_transient_for((Window) get_root());
|
||||||
dialog.present();
|
dialog.present();
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
public override void dispose() {
|
||||||
|
if (label != null) {
|
||||||
|
label.unparent();
|
||||||
|
label.dispose();
|
||||||
|
label = null;
|
||||||
|
}
|
||||||
|
base.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue