mirror of
https://gitlab.gnome.org/World/tootle
synced 2025-02-13 01:50:37 +01:00
Fix circular references
This commit is contained in:
parent
92dd1e044a
commit
3d0bd9e48e
@ -46,8 +46,10 @@ public class Tootle.API.Account : Entity, Widgetizable {
|
|||||||
return new Request.GET ("/api/v1/accounts/relationships")
|
return new Request.GET ("/api/v1/accounts/relationships")
|
||||||
.with_account (accounts.active)
|
.with_account (accounts.active)
|
||||||
.with_param ("id", id.to_string ())
|
.with_param ("id", id.to_string ())
|
||||||
.then_parse_array (node => {
|
.then ((sess, msg) => {
|
||||||
rs = API.Relationship.from (node);
|
Network.parse_array (msg, node => {
|
||||||
|
rs = API.Relationship.from (node);
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.on_error (network.on_error)
|
.on_error (network.on_error)
|
||||||
.exec ();
|
.exec ();
|
||||||
|
@ -4,11 +4,14 @@ using Gee;
|
|||||||
public class Tootle.Request : Soup.Message {
|
public class Tootle.Request : Soup.Message {
|
||||||
|
|
||||||
public string url { set; get; }
|
public string url { set; get; }
|
||||||
private Network.SuccessCallback? cb;
|
Network.SuccessCallback? cb;
|
||||||
private Network.ErrorCallback? error_cb;
|
Network.ErrorCallback? error_cb;
|
||||||
private HashMap<string, string>? pars;
|
HashMap<string, string>? pars;
|
||||||
private weak InstanceAccount? account;
|
weak InstanceAccount? account;
|
||||||
private bool needs_token = false;
|
bool needs_token = false;
|
||||||
|
|
||||||
|
weak Gtk.Widget? ctx;
|
||||||
|
bool has_ctx = false;
|
||||||
|
|
||||||
public Request.GET (string url) {
|
public Request.GET (string url) {
|
||||||
Object (method: "GET", url: url);
|
Object (method: "GET", url: url);
|
||||||
@ -20,23 +23,22 @@ public class Tootle.Request : Soup.Message {
|
|||||||
Object (method: "DELETE", url: url);
|
Object (method: "DELETE", url: url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Request with_ctx (Gtk.Widget ctx) {
|
||||||
|
this.has_ctx = true;
|
||||||
|
this.ctx = ctx;
|
||||||
|
this.ctx.destroy.connect (() => {
|
||||||
|
network.cancel (this);
|
||||||
|
this.ctx = null;
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Request then (owned Network.SuccessCallback cb) {
|
public Request then (owned Network.SuccessCallback cb) {
|
||||||
this.cb = (owned) cb;
|
this.cb = (s, m) => {
|
||||||
return this;
|
Idle.add (() => {
|
||||||
}
|
cb (s, m);
|
||||||
|
return false;
|
||||||
public Request then_parse_array (owned Network.NodeCallback _cb) {
|
});
|
||||||
this.cb = (sess, msg) => {
|
|
||||||
var parser = new Json.Parser ();
|
|
||||||
parser.load_from_data ((string) msg.response_body.flatten ().data, -1);
|
|
||||||
parser.get_root ().get_array ().foreach_element ((array, i, node) => _cb (node, msg));
|
|
||||||
};
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Request then_parse_obj (owned Network.ObjectCallback _cb) {
|
|
||||||
this.cb = (sess, msg) => {
|
|
||||||
_cb (network.parse (msg));
|
|
||||||
};
|
};
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -60,8 +62,7 @@ public class Tootle.Request : Soup.Message {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should be used for requests with default priority
|
public Request exec () {
|
||||||
public Request queue () {
|
|
||||||
var parameters = "";
|
var parameters = "";
|
||||||
if (pars != null) {
|
if (pars != null) {
|
||||||
parameters = "?";
|
parameters = "?";
|
||||||
@ -100,10 +101,4 @@ public class Tootle.Request : Soup.Message {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should be used for real-time user interactions (liking, removing and browsing posts)
|
|
||||||
public Request exec () {
|
|
||||||
this.priority = MessagePriority.HIGH;
|
|
||||||
return this.queue ();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,9 @@ public class Tootle.Cache : GLib.Object {
|
|||||||
|
|
||||||
protected class Item : GLib.Object {
|
protected class Item : GLib.Object {
|
||||||
public Pixbuf data { get; construct set; }
|
public Pixbuf data { get; construct set; }
|
||||||
public int64 references { get; construct set; }
|
public int references { get; construct set; }
|
||||||
|
|
||||||
public Item (Pixbuf d, int64 r) {
|
public Item (Pixbuf d, int r) {
|
||||||
Object (data: d, references: r);
|
Object (data: d, references: r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,12 +45,14 @@ public class Tootle.Cache : GLib.Object {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
item.references--;
|
item.references--;
|
||||||
//info (@"DEREF $(r.key) $(item.references)");
|
|
||||||
if (item.references <= 0) {
|
if (item.references <= 0) {
|
||||||
//info ("REMOVE %s", r.key);
|
// message (@"[X] $(r.key)");
|
||||||
items.remove (r.key);
|
items.remove (r.key);
|
||||||
items_in_progress.remove (r.key);
|
items_in_progress.remove (r.key);
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// message (@"[-] $(r.key) - $(item.references)");
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load (string? url, owned CachedResultCallback cb) {
|
public void load (string? url, owned CachedResultCallback cb) {
|
||||||
@ -59,9 +61,9 @@ public class Tootle.Cache : GLib.Object {
|
|||||||
|
|
||||||
var key = url;
|
var key = url;
|
||||||
if (items.contains (key)) {
|
if (items.contains (key)) {
|
||||||
//info (@"LOAD $key");
|
|
||||||
var item = items.@get (key);
|
var item = items.@get (key);
|
||||||
item.references++;
|
item.references++;
|
||||||
|
// message (@"[+] $key - $(item.references)");
|
||||||
cb (Reference () {
|
cb (Reference () {
|
||||||
data = item.data,
|
data = item.data,
|
||||||
key = key,
|
key = key,
|
||||||
@ -72,19 +74,19 @@ public class Tootle.Cache : GLib.Object {
|
|||||||
|
|
||||||
//var item = items.@get (key);
|
//var item = items.@get (key);
|
||||||
|
|
||||||
var message = items_in_progress.@get (key);
|
var msg = items_in_progress.@get (key);
|
||||||
if (message == null) {
|
if (msg == null) {
|
||||||
message = new Soup.Message ("GET", url);
|
msg = new Soup.Message ("GET", url);
|
||||||
ulong id = 0;
|
ulong id = 0;
|
||||||
id = message.finished.connect (() => {
|
id = msg.finished.connect (() => {
|
||||||
Pixbuf? pixbuf = null;
|
Pixbuf? pixbuf = null;
|
||||||
|
|
||||||
var data = message.response_body.flatten ().data;
|
var data = msg.response_body.flatten ().data;
|
||||||
var stream = new MemoryInputStream.from_data (data);
|
var stream = new MemoryInputStream.from_data (data);
|
||||||
pixbuf = new Pixbuf.from_stream (stream);
|
pixbuf = new Pixbuf.from_stream (stream);
|
||||||
stream.close ();
|
stream.close ();
|
||||||
|
|
||||||
//info (@"< STORE $key");
|
// message (@"[*] $key");
|
||||||
items[key] = new Item (pixbuf, 1);
|
items[key] = new Item (pixbuf, 1);
|
||||||
items_in_progress.remove (key);
|
items_in_progress.remove (key);
|
||||||
|
|
||||||
@ -94,10 +96,10 @@ public class Tootle.Cache : GLib.Object {
|
|||||||
loading = false
|
loading = false
|
||||||
});
|
});
|
||||||
|
|
||||||
message.disconnect (id);
|
msg.disconnect (id);
|
||||||
});
|
});
|
||||||
|
|
||||||
network.queue (message, (sess, msg) => {
|
network.queue (msg, (sess, mess) => {
|
||||||
// no one cares
|
// no one cares
|
||||||
},
|
},
|
||||||
(code, reason) => {
|
(code, reason) => {
|
||||||
@ -110,12 +112,12 @@ public class Tootle.Cache : GLib.Object {
|
|||||||
loading = true
|
loading = true
|
||||||
});
|
});
|
||||||
|
|
||||||
items_in_progress.insert (key, message);
|
items_in_progress.insert (key, msg);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//info ("AWAIT: %s", key);
|
//message ("[/]: %s", key);
|
||||||
ulong id = 0;
|
ulong id = 0;
|
||||||
id = message.finished.connect_after (() => {
|
id = msg.finished.connect_after (() => {
|
||||||
var it = items.@get (key);
|
var it = items.@get (key);
|
||||||
cb (Reference () {
|
cb (Reference () {
|
||||||
data = it.data,
|
data = it.data,
|
||||||
@ -123,13 +125,13 @@ public class Tootle.Cache : GLib.Object {
|
|||||||
loading = false
|
loading = false
|
||||||
});
|
});
|
||||||
it.references++;
|
it.references++;
|
||||||
message.disconnect (id);
|
msg.disconnect (id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear () {
|
public void clear () {
|
||||||
info ("PURGE");
|
// message ("[ CLEARED ALL ]");
|
||||||
items.remove_all ();
|
items.remove_all ();
|
||||||
items_in_progress.remove_all ();
|
items_in_progress.remove_all ();
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,24 @@
|
|||||||
public interface Tootle.IAccountListener : GLib.Object {
|
public interface Tootle.IAccountListener : GLib.Object {
|
||||||
|
|
||||||
protected void connect_account () {
|
//TODO: Refactor into AccountHolder
|
||||||
accounts.notify["active"].connect (() => on_account_changed (accounts.active));
|
|
||||||
accounts.saved.notify["size"].connect (() => on_accounts_changed (accounts.saved));
|
protected void account_listener_init () {
|
||||||
|
accounts.notify["active"].connect (_on_active_acc_update);
|
||||||
|
accounts.saved.notify["size"].connect (_on_saved_accs_update);
|
||||||
on_account_changed (accounts.active);
|
on_account_changed (accounts.active);
|
||||||
}
|
}
|
||||||
|
protected void account_listener_free () {
|
||||||
|
accounts.notify["active"].disconnect (_on_active_acc_update);
|
||||||
|
accounts.saved.notify["size"].disconnect (_on_saved_accs_update);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _on_active_acc_update (ParamSpec s) {
|
||||||
|
on_account_changed (accounts.active);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _on_saved_accs_update (ParamSpec s) {
|
||||||
|
on_accounts_changed (accounts.saved);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void on_account_changed (InstanceAccount? account) {}
|
public virtual void on_account_changed (InstanceAccount? account) {}
|
||||||
public virtual void on_accounts_changed (Gee.ArrayList<InstanceAccount> accounts) {}
|
public virtual void on_accounts_changed (Gee.ArrayList<InstanceAccount> accounts) {}
|
||||||
|
@ -29,17 +29,18 @@ public class Tootle.Network : GLib.Object {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void cancel_request (Soup.Message? msg) {
|
public void cancel (Soup.Message? msg) {
|
||||||
// if (msg == null)
|
if (msg == null)
|
||||||
// return;
|
return;
|
||||||
|
|
||||||
// switch (msg.status_code) {
|
switch (msg.status_code) {
|
||||||
// case Soup.Status.CANCELLED:
|
case Soup.Status.CANCELLED:
|
||||||
// case Soup.Status.OK:
|
case Soup.Status.OK:
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
// session.cancel_message (msg, Soup.Status.CANCELLED);
|
debug ("Cancelling message");
|
||||||
// }
|
session.cancel_message (msg, Soup.Status.CANCELLED);
|
||||||
|
}
|
||||||
|
|
||||||
public void queue (owned Soup.Message message, owned SuccessCallback? cb, owned ErrorCallback? errcb = null) {
|
public void queue (owned Soup.Message message, owned SuccessCallback? cb, owned ErrorCallback? errcb = null) {
|
||||||
requests_processing++;
|
requests_processing++;
|
||||||
@ -57,6 +58,9 @@ public class Tootle.Network : GLib.Object {
|
|||||||
errcb (Soup.Status.NONE, e.message);
|
errcb (Soup.Status.NONE, e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (status == Soup.Status.CANCELLED) {
|
||||||
|
debug ("Message is cancelled. Ignoring callback invocation.");
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (errcb != null)
|
if (errcb != null)
|
||||||
errcb ((int32)status, describe_error ((int32)status));
|
errcb ((int32)status, describe_error ((int32)status));
|
||||||
@ -89,4 +93,12 @@ public class Tootle.Network : GLib.Object {
|
|||||||
return parse_node (msg).get_object ();
|
return parse_node (msg).get_object ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void parse_array (Soup.Message msg, owned NodeCallback cb) throws Error {
|
||||||
|
var parser = new Json.Parser ();
|
||||||
|
parser.load_from_data ((string) msg.response_body.flatten ().data, -1);
|
||||||
|
parser.get_root ().get_array ().foreach_element ((array, i, node) => {
|
||||||
|
cb (node, msg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -71,8 +71,8 @@ public class Tootle.Views.Base : Box {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public virtual void clear (){
|
public virtual void clear (){
|
||||||
content_list.forall (widget => {
|
content_list.forall (w => {
|
||||||
widget.destroy ();
|
w.destroy ();
|
||||||
});
|
});
|
||||||
state = "status";
|
state = "status";
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ public class Tootle.Views.ExpandedStatus : Views.Base, IAccountListener {
|
|||||||
root_status: status,
|
root_status: status,
|
||||||
status_message: STATUS_LOADING
|
status_message: STATUS_LOADING
|
||||||
);
|
);
|
||||||
connect_account ();
|
account_listener_init ();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void on_account_changed (InstanceAccount? acc) {
|
public override void on_account_changed (InstanceAccount? acc) {
|
||||||
@ -38,8 +38,9 @@ public class Tootle.Views.ExpandedStatus : Views.Base, IAccountListener {
|
|||||||
public void request () {
|
public void request () {
|
||||||
new Request.GET (@"/api/v1/statuses/$(root_status.id)/context")
|
new Request.GET (@"/api/v1/statuses/$(root_status.id)/context")
|
||||||
.with_account (account)
|
.with_account (account)
|
||||||
.then_parse_obj (root => {
|
.with_ctx (this)
|
||||||
if (scrolled == null) return;
|
.then ((sess, msg) => {
|
||||||
|
var root = network.parse (msg);
|
||||||
|
|
||||||
var ancestors = root.get_array_member ("ancestors");
|
var ancestors = root.get_array_member ("ancestors");
|
||||||
ancestors.foreach_element ((array, i, node) => {
|
ancestors.foreach_element ((array, i, node) => {
|
||||||
|
@ -12,6 +12,8 @@ public class Tootle.Views.Profile : Views.Timeline {
|
|||||||
Button rs_button;
|
Button rs_button;
|
||||||
Label rs_button_label;
|
Label rs_button_label;
|
||||||
|
|
||||||
|
weak ListBoxRow note_row;
|
||||||
|
|
||||||
public bool exclude_replies { get; set; default = true; }
|
public bool exclude_replies { get; set; default = true; }
|
||||||
public bool only_media { get; set; default = false; }
|
public bool only_media { get; set; default = false; }
|
||||||
|
|
||||||
@ -39,7 +41,7 @@ public class Tootle.Views.Profile : Views.Timeline {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
var note_row = builder.get_object ("note_row") as ListBoxRow;
|
note_row = builder.get_object ("note_row") as ListBoxRow;
|
||||||
var note = builder.get_object ("note") as Widgets.RichLabel;
|
var note = builder.get_object ("note") as Widgets.RichLabel;
|
||||||
profile.bind_property ("note", note, "text", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
|
profile.bind_property ("note", note, "text", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
|
||||||
var text = Html.simplify ((string) src);
|
var text = Html.simplify ((string) src);
|
||||||
@ -83,6 +85,9 @@ public class Tootle.Views.Profile : Views.Timeline {
|
|||||||
);
|
);
|
||||||
profile.get_relationship ();
|
profile.get_relationship ();
|
||||||
}
|
}
|
||||||
|
~Profile () {
|
||||||
|
filter.destroy ();
|
||||||
|
}
|
||||||
|
|
||||||
public override void on_shown () {
|
public override void on_shown () {
|
||||||
window.header.custom_title = filter;
|
window.header.custom_title = filter;
|
||||||
|
@ -17,7 +17,7 @@ public class Tootle.Views.Timeline : IAccountListener, IStreamListener, Views.Ba
|
|||||||
construct {
|
construct {
|
||||||
app.refresh.connect (on_refresh);
|
app.refresh.connect (on_refresh);
|
||||||
status_button.clicked.connect (on_refresh);
|
status_button.clicked.connect (on_refresh);
|
||||||
connect_account ();
|
account_listener_init ();
|
||||||
|
|
||||||
on_status_added.connect (add_status);
|
on_status_added.connect (add_status);
|
||||||
on_status_removed.connect (remove_status);
|
on_status_removed.connect (remove_status);
|
||||||
@ -92,20 +92,22 @@ public class Tootle.Views.Timeline : IAccountListener, IStreamListener, Views.Ba
|
|||||||
public virtual bool request () {
|
public virtual bool request () {
|
||||||
var req = append_params (new Request.GET (get_req_url ()))
|
var req = append_params (new Request.GET (get_req_url ()))
|
||||||
.with_account (account)
|
.with_account (account)
|
||||||
.then_parse_array ((node, msg) => {
|
.with_ctx (this)
|
||||||
try {
|
.then ((sess, msg) => {
|
||||||
var e = Entity.from_json (accepts, node);
|
Network.parse_array (msg, node => {
|
||||||
var w = e as Widgetizable;
|
try {
|
||||||
append (w.to_widget ());
|
var e = Entity.from_json (accepts, node);
|
||||||
}
|
var w = e as Widgetizable;
|
||||||
catch (Error e) {
|
append (w.to_widget ());
|
||||||
warning (@"Timeline item parse error: $(e.message)");
|
}
|
||||||
}
|
catch (Error e) {
|
||||||
|
warning (@"Timeline item parse error: $(e.message)");
|
||||||
|
}
|
||||||
|
|
||||||
|
get_pages (msg.response_headers.get_one ("Link"));
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.on_error (on_error);
|
.on_error (on_error);
|
||||||
req.finished.connect (() => {
|
|
||||||
get_pages (req.response_headers.get_one ("Link"));
|
|
||||||
});
|
|
||||||
req.exec ();
|
req.exec ();
|
||||||
return GLib.Source.REMOVE;
|
return GLib.Source.REMOVE;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ public class Tootle.Widgets.AccountsButton : Gtk.MenuButton, IAccountListener {
|
|||||||
Button item_bookmarks;
|
Button item_bookmarks;
|
||||||
|
|
||||||
construct {
|
construct {
|
||||||
connect_account ();
|
account_listener_init ();
|
||||||
|
|
||||||
item_refresh.clicked.connect (() => {
|
item_refresh.clicked.connect (() => {
|
||||||
app.refresh ();
|
app.refresh ();
|
||||||
@ -101,6 +101,9 @@ public class Tootle.Widgets.AccountsButton : Gtk.MenuButton, IAccountListener {
|
|||||||
|
|
||||||
account_list.row_activated.connect (on_selection_changed);
|
account_list.row_activated.connect (on_selection_changed);
|
||||||
}
|
}
|
||||||
|
~AccountsButton () {
|
||||||
|
account_listener_free ();
|
||||||
|
}
|
||||||
|
|
||||||
protected void on_selection_changed (ListBoxRow r) {
|
protected void on_selection_changed (ListBoxRow r) {
|
||||||
var i = r.get_index ();
|
var i = r.get_index ();
|
||||||
|
@ -12,7 +12,7 @@ public class Tootle.Widgets.Avatar : EventBox {
|
|||||||
get_style_context ().add_class ("avatar");
|
get_style_context ().add_class ("avatar");
|
||||||
notify["url"].connect (on_url_updated);
|
notify["url"].connect (on_url_updated);
|
||||||
notify["size"].connect (on_redraw);
|
notify["size"].connect (on_redraw);
|
||||||
Screen.get_default ().monitors_changed.connect (on_redraw);
|
// Screen.get_default ().monitors_changed.connect (on_redraw);
|
||||||
on_url_updated ();
|
on_url_updated ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,11 +23,13 @@ public class Tootle.Widgets.Avatar : EventBox {
|
|||||||
|
|
||||||
~Avatar () {
|
~Avatar () {
|
||||||
notify["url"].disconnect (on_url_updated);
|
notify["url"].disconnect (on_url_updated);
|
||||||
Screen.get_default ().monitors_changed.disconnect (on_redraw);
|
// Screen.get_default ().monitors_changed.disconnect (on_redraw);
|
||||||
cache.unload (cached);
|
cache.unload (cached);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_url_updated () {
|
private void on_url_updated () {
|
||||||
|
if (cached != null)
|
||||||
|
cache.unload (cached);
|
||||||
cached = null;
|
cached = null;
|
||||||
on_redraw ();
|
on_redraw ();
|
||||||
cache.load (url, on_cache_result);
|
cache.load (url, on_cache_result);
|
||||||
@ -39,8 +41,7 @@ public class Tootle.Widgets.Avatar : EventBox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int get_scaled_size () {
|
public int get_scaled_size () {
|
||||||
return size;
|
return size; //return size * get_scale_factor ();
|
||||||
//return size * get_scale_factor ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_redraw () {
|
private void on_redraw () {
|
||||||
|
@ -112,7 +112,7 @@ public class Tootle.Widgets.Status : ListBoxRow {
|
|||||||
reblog_button.clicked.connect (() => {
|
reblog_button.clicked.connect (() => {
|
||||||
status.action (status.formal.reblogged ? "unreblog" : "reblog");
|
status.action (status.formal.reblogged ? "unreblog" : "reblog");
|
||||||
});
|
});
|
||||||
|
|
||||||
status.formal.bind_property ("bookmarked", bookmark_button, "active", BindingFlags.SYNC_CREATE);
|
status.formal.bind_property ("bookmarked", bookmark_button, "active", BindingFlags.SYNC_CREATE);
|
||||||
bookmark_button.clicked.connect (() => {
|
bookmark_button.clicked.connect (() => {
|
||||||
status.action (status.formal.bookmarked ? "unbookmark" : "bookmark");
|
status.action (status.formal.bookmarked ? "unbookmark" : "bookmark");
|
||||||
|
@ -3,6 +3,8 @@ using Gtk;
|
|||||||
[GtkTemplate (ui = "/com/github/bleakgrey/tootle/ui/widgets/timeline_filter.ui")]
|
[GtkTemplate (ui = "/com/github/bleakgrey/tootle/ui/widgets/timeline_filter.ui")]
|
||||||
public class Tootle.Widgets.TimelineFilter : MenuButton {
|
public class Tootle.Widgets.TimelineFilter : MenuButton {
|
||||||
|
|
||||||
|
weak Views.Profile view;
|
||||||
|
|
||||||
[GtkChild]
|
[GtkChild]
|
||||||
public Label title;
|
public Label title;
|
||||||
|
|
||||||
@ -22,7 +24,8 @@ public class Tootle.Widgets.TimelineFilter : MenuButton {
|
|||||||
radio_source.bind_property ("active", post_filter, "reveal-child", BindingFlags.SYNC_CREATE);
|
radio_source.bind_property ("active", post_filter, "reveal-child", BindingFlags.SYNC_CREATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TimelineFilter.with_profile (Views.Profile view) {
|
public TimelineFilter.with_profile (Views.Profile profile) {
|
||||||
|
this.view = profile;
|
||||||
radio_source.get_group ().@foreach (w => {
|
radio_source.get_group ().@foreach (w => {
|
||||||
w.toggled.connect (() => {
|
w.toggled.connect (() => {
|
||||||
if (w.active) {
|
if (w.active) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user