fix(widgets)[status]: destruction (#54)

* Fix leaking Status widgets

* Workaround for spoiler stack binding
This commit is contained in:
Bleak Grey 2023-01-12 20:25:10 +03:00 committed by GitHub
parent 715a277736
commit 94688429bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 105 additions and 101 deletions

View File

@ -12,10 +12,11 @@ public class Tooth.Widgets.Status : ListBoxRow {
warning ("Trying to rebind a Status widget! This is not supposed to happen!");
_bound_status = value;
if (_bound_status != null)
if (_bound_status != null) {
bind ();
}
}
}
public API.Account? kind_instigator { get; set; default = null; }
@ -121,7 +122,23 @@ public class Tooth.Widgets.Status : ListBoxRow {
if (settings.larger_line_height)
add_css_class("ttl-status-line-height-large");
rebuild_actions ();
settings.notify["larger-font-size"].connect (() => {
if (settings.larger_font_size) {
add_css_class("ttl-status-font-large");
} else {
remove_css_class("ttl-status-font-large");
}
});
settings.notify["larger-line-height"].connect (() => {
if (settings.larger_line_height) {
add_css_class("ttl-status-line-height-large");
} else {
remove_css_class("ttl-status-line-height-large");
}
});
}
public Status (API.Status status) {
@ -207,23 +224,49 @@ public class Tooth.Widgets.Status : ListBoxRow {
}
protected virtual void bind () {
// Content
bind_property ("spoiler-text", spoiler_label, "label", BindingFlags.SYNC_CREATE);
bind_property ("spoiler-text-revealed", spoiler_label_rev, "label", BindingFlags.SYNC_CREATE);
status.formal.bind_property ("content", content, "content", BindingFlags.SYNC_CREATE);
var self_bindings = new BindingGroup ();
var formal_bindings = new BindingGroup ();
bind_property ("is_conversation_open", status_stats, "visible", BindingFlags.SYNC_CREATE);
status.formal.bind_property ("reblogs_count", reblog_count_label, "label", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
self_bindings.bind_property ("spoiler-text", spoiler_label, "label", BindingFlags.SYNC_CREATE);
self_bindings.bind_property ("spoiler-text-revealed", spoiler_label_rev, "label", BindingFlags.SYNC_CREATE);
notify["reveal-spoiler"].connect(() => {
spoiler_status_con.visible = reveal_spoiler && status.formal.has_spoiler;
spoiler_stack.visible_child_name = reveal_spoiler ? "content" : "spoiler";
});
self_bindings.bind_property ("is_conversation_open", status_stats, "visible", BindingFlags.SYNC_CREATE);
self_bindings.bind_property ("subtitle_text", handle_label, "label", BindingFlags.SYNC_CREATE);
self_bindings.bind_property ("date", date_label, "label", BindingFlags.SYNC_CREATE);
formal_bindings.bind_property ("pinned", pin_indicator, "visible", BindingFlags.SYNC_CREATE);
formal_bindings.bind_property ("is-edited", edited_indicator, "visible", BindingFlags.SYNC_CREATE);
formal_bindings.bind_property ("visibility", indicator, "icon_name", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
target.set_string (accounts.active.visibility[src.get_string ()].icon_name);
return true;
});
formal_bindings.bind_property ("visibility", indicator, "tooltip-text", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
target.set_string (accounts.active.visibility[src.get_string ()].name);
return true;
});
formal_bindings.bind_property ("account", avatar, "account", BindingFlags.SYNC_CREATE);
formal_bindings.bind_property ("status-reactions", this, "reactions", BindingFlags.SYNC_CREATE);
formal_bindings.bind_property ("has-spoiler", this, "reveal-spoiler", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
target.set_boolean (!src.get_boolean () || settings.show_spoilers);
return true;
});
formal_bindings.bind_property ("content", content, "content", BindingFlags.SYNC_CREATE);
formal_bindings.bind_property ("reblogs_count", reblog_count_label, "label", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
int64 srcval = (int64) src;
target.set_string (@"<b>$srcval</b> " + _("Reblogs"));
return true;
});
status.formal.bind_property ("favourites_count", fav_count_label, "label", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
formal_bindings.bind_property ("favourites_count", fav_count_label, "label", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
int64 srcval = (int64) src;
target.set_string (@"<b>$srcval</b> " + _("Favourites"));
return true;
});
status.formal.bind_property ("replies_count", reply_button_content, "label", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
formal_bindings.bind_property ("replies_count", reply_button_content, "label", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
int64 srcval = (int64) src;
if (srcval > 0) {
@ -242,56 +285,15 @@ public class Tooth.Widgets.Status : ListBoxRow {
target.set_string("");
return true;
});
self_bindings.set_source (this);
formal_bindings.set_source (status.formal);
// TODO: Ideally, this should be a binding too somehow
// bind_property ("title_text", name_label, "label", BindingFlags.SYNC_CREATE);
// title_text
name_label.set_label(title_text, status.formal.account.handle, status.formal.account.emojis_map, true);
bind_property ("subtitle_text", handle_label, "label", BindingFlags.SYNC_CREATE);
bind_property ("date", date_label, "label", BindingFlags.SYNC_CREATE);
status.formal.bind_property ("pinned", pin_indicator, "visible", BindingFlags.SYNC_CREATE);
status.formal.bind_property ("is-edited", edited_indicator, "visible", BindingFlags.SYNC_CREATE);
status.formal.bind_property ("visibility", indicator, "icon_name", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
target.set_string (accounts.active.visibility[src.get_string ()].icon_name);
return true;
});
status.formal.bind_property ("visibility", indicator, "tooltip-text", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
target.set_string (accounts.active.visibility[src.get_string ()].name);
return true;
});
status.formal.bind_property ("account", avatar, "account", BindingFlags.SYNC_CREATE);
// Spoiler //TODO: Spoilers
// reveal_spoiler = true;
// spoiler_stack.visible_child_name = "content";
// status.formal.bind_property ("has-spoiler", this, "reveal-spoiler", BindingFlags.INVERT_BOOLEAN);
settings.notify["larger-font-size"].connect (() => {
if (settings.larger_font_size) {
add_css_class("ttl-status-font-large");
} else {
remove_css_class("ttl-status-font-large");
}
});
settings.notify["larger-line-height"].connect (() => {
if (settings.larger_line_height) {
add_css_class("ttl-status-line-height-large");
} else {
remove_css_class("ttl-status-line-height-large");
}
});
status.formal.bind_property ("status-reactions", this, "reactions", BindingFlags.SYNC_CREATE);
status.formal.bind_property ("has-spoiler", this, "reveal-spoiler", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
target.set_boolean (!src.get_boolean () || settings.show_spoilers);
return true;
});
bind_property ("reveal-spoiler", spoiler_stack, "visible-child-name", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
var name = reveal_spoiler ? "content" : "spoiler";
spoiler_status_con.visible = src.get_boolean() && status.formal.has_spoiler;
target.set_string (name);
return true;
});
// Actions
reblog_button.bind (status.formal);
@ -322,6 +324,8 @@ public class Tooth.Widgets.Status : ListBoxRow {
date_label.destroy ();
}
// TODO: Votebox should be created dynamically if needed.
// Currently *all* status widgets contain one even if they don't have a poll.
if (status.poll==null){
poll.hide();
}