2018-04-14 12:09:06 +00:00
|
|
|
using Gtk;
|
|
|
|
using Gdk;
|
|
|
|
|
2018-05-19 12:21:03 +00:00
|
|
|
public class Tootle.TimelineView : AbstractView {
|
2018-04-14 12:09:06 +00:00
|
|
|
|
2018-05-19 12:21:03 +00:00
|
|
|
protected string timeline;
|
|
|
|
protected string pars;
|
|
|
|
protected int limit = 25;
|
|
|
|
protected bool is_last_page = false;
|
|
|
|
protected string? page_next;
|
|
|
|
protected string? page_prev;
|
2018-06-13 13:13:41 +00:00
|
|
|
|
2018-06-20 15:50:42 +00:00
|
|
|
protected Notificator? notificator;
|
2018-04-14 12:09:06 +00:00
|
|
|
|
2018-05-19 12:21:03 +00:00
|
|
|
public TimelineView (string timeline, string pars = "") {
|
2018-05-05 15:38:01 +00:00
|
|
|
base ();
|
2018-04-14 12:09:06 +00:00
|
|
|
this.timeline = timeline;
|
2018-05-19 12:21:03 +00:00
|
|
|
this.pars = pars;
|
2018-04-14 17:53:09 +00:00
|
|
|
|
2018-06-13 13:13:41 +00:00
|
|
|
accounts.switched.connect (on_account_changed);
|
|
|
|
app.refresh.connect (on_refresh);
|
|
|
|
destroy.connect (() => {
|
|
|
|
if (notificator != null)
|
|
|
|
notificator.close ();
|
|
|
|
});
|
2018-04-14 12:09:06 +00:00
|
|
|
|
2018-06-20 15:50:42 +00:00
|
|
|
setup_notificator ();
|
2018-05-05 15:38:01 +00:00
|
|
|
request ();
|
2018-04-14 12:09:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public override string get_icon () {
|
|
|
|
return "user-home-symbolic";
|
|
|
|
}
|
|
|
|
|
|
|
|
public override string get_name () {
|
2018-05-09 21:46:24 +00:00
|
|
|
return _("Home");
|
2018-04-14 12:09:06 +00:00
|
|
|
}
|
|
|
|
|
2018-10-23 10:05:24 +00:00
|
|
|
public virtual void on_status_added (Status status) {
|
|
|
|
prepend (status);
|
2018-05-19 16:01:54 +00:00
|
|
|
}
|
|
|
|
|
2018-10-23 10:05:24 +00:00
|
|
|
public virtual bool is_status_owned (Status status) {
|
2018-05-31 12:13:21 +00:00
|
|
|
return false;
|
2018-05-21 15:23:31 +00:00
|
|
|
}
|
|
|
|
|
2018-10-23 10:05:24 +00:00
|
|
|
public void prepend (Status status) {
|
|
|
|
append (status, true);
|
2018-05-27 17:14:48 +00:00
|
|
|
}
|
|
|
|
|
2018-10-23 10:05:24 +00:00
|
|
|
public void append (Status status, bool first = false){
|
2018-05-19 13:55:41 +00:00
|
|
|
if (empty != null)
|
|
|
|
empty.destroy ();
|
|
|
|
|
2018-04-18 09:13:22 +00:00
|
|
|
var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
|
|
|
|
separator.show ();
|
2018-05-18 21:14:12 +00:00
|
|
|
|
2018-10-23 10:05:24 +00:00
|
|
|
var widget = new StatusWidget (status);
|
2018-04-18 09:13:22 +00:00
|
|
|
widget.separator = separator;
|
2018-04-26 14:05:03 +00:00
|
|
|
widget.button_press_event.connect(widget.open);
|
2018-10-23 10:05:24 +00:00
|
|
|
if (!is_status_owned (status))
|
2018-05-21 15:23:31 +00:00
|
|
|
widget.avatar.button_press_event.connect(widget.open_account);
|
2018-04-18 09:13:22 +00:00
|
|
|
view.pack_start(separator, false, false, 0);
|
2018-04-16 20:36:57 +00:00
|
|
|
view.pack_start(widget, false, false, 0);
|
2018-05-19 16:01:54 +00:00
|
|
|
|
2018-05-19 17:27:30 +00:00
|
|
|
if (first) {
|
2018-05-19 16:01:54 +00:00
|
|
|
view.reorder_child (widget, 0);
|
2018-05-19 17:27:30 +00:00
|
|
|
view.reorder_child (separator, 0);
|
|
|
|
}
|
2018-04-14 12:09:06 +00:00
|
|
|
}
|
|
|
|
|
2018-05-19 12:21:03 +00:00
|
|
|
public override void clear () {
|
|
|
|
this.page_prev = null;
|
|
|
|
this.page_next = null;
|
|
|
|
this.is_last_page = false;
|
|
|
|
base.clear ();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void get_pages (string? header) {
|
|
|
|
page_next = page_prev = null;
|
2018-05-19 13:55:41 +00:00
|
|
|
if (header == null)
|
2018-05-19 12:21:03 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
var pages = header.split (",");
|
|
|
|
foreach (var page in pages) {
|
|
|
|
var sanitized = page
|
|
|
|
.replace ("<","")
|
|
|
|
.replace (">", "")
|
|
|
|
.split (";")[0];
|
|
|
|
|
2018-05-19 13:55:41 +00:00
|
|
|
if ("rel=\"prev\"" in page)
|
2018-05-19 12:21:03 +00:00
|
|
|
page_prev = sanitized;
|
2018-05-19 13:55:41 +00:00
|
|
|
else
|
2018-05-19 12:21:03 +00:00
|
|
|
page_next = sanitized;
|
|
|
|
}
|
|
|
|
|
|
|
|
is_last_page = page_prev != null & page_next == null;
|
|
|
|
}
|
|
|
|
|
2018-05-05 15:38:01 +00:00
|
|
|
public virtual string get_url () {
|
2018-05-19 12:21:03 +00:00
|
|
|
if (page_next != null)
|
|
|
|
return page_next;
|
2018-04-26 14:05:03 +00:00
|
|
|
|
2018-10-23 10:05:24 +00:00
|
|
|
var url = "%s/api/v1/timelines/%s?limit=%i".printf (accounts.formal.instance, this.timeline, this.limit);
|
2018-05-19 12:21:03 +00:00
|
|
|
url += this.pars;
|
2018-04-26 14:05:03 +00:00
|
|
|
return url;
|
|
|
|
}
|
|
|
|
|
2018-05-05 15:38:01 +00:00
|
|
|
public virtual void request (){
|
2018-05-29 12:25:56 +00:00
|
|
|
if (accounts.current == null) {
|
|
|
|
empty_state ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-04-26 14:05:03 +00:00
|
|
|
var msg = new Soup.Message("GET", get_url ());
|
2018-05-19 13:55:41 +00:00
|
|
|
msg.finished.connect (() => empty_state ());
|
2018-06-20 15:50:42 +00:00
|
|
|
network.queue(msg, (sess, mess) => {
|
2018-10-23 10:05:24 +00:00
|
|
|
try {
|
|
|
|
network.parse_array (mess).foreach_element ((array, i, node) => {
|
2018-04-14 12:09:06 +00:00
|
|
|
var object = node.get_object ();
|
|
|
|
if (object != null){
|
|
|
|
var status = Status.parse(object);
|
2018-10-23 10:05:24 +00:00
|
|
|
append (status);
|
2018-04-14 12:09:06 +00:00
|
|
|
}
|
|
|
|
});
|
2018-05-19 12:21:03 +00:00
|
|
|
get_pages (mess.response_headers.get_one ("Link"));
|
2018-04-14 12:09:06 +00:00
|
|
|
}
|
|
|
|
catch (GLib.Error e) {
|
|
|
|
warning ("Can't update feed");
|
|
|
|
warning (e.message);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2018-04-26 14:05:03 +00:00
|
|
|
|
2018-05-03 08:11:31 +00:00
|
|
|
public virtual void on_refresh (){
|
|
|
|
clear ();
|
|
|
|
request ();
|
|
|
|
}
|
|
|
|
|
2018-06-20 15:50:42 +00:00
|
|
|
public virtual Soup.Message? get_stream (){
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2018-04-26 14:05:03 +00:00
|
|
|
public virtual void on_account_changed (Account? account){
|
|
|
|
if(account == null)
|
|
|
|
return;
|
2018-06-13 13:13:41 +00:00
|
|
|
|
2018-06-20 15:50:42 +00:00
|
|
|
var stream = get_stream ();
|
|
|
|
if (notificator != null && stream != null) {
|
|
|
|
var old_url = notificator.get_url ();
|
|
|
|
var new_url = stream.get_uri ().to_string (false);
|
|
|
|
if (old_url != new_url) {
|
|
|
|
info ("Updating notificator %s", notificator.get_name ());
|
|
|
|
setup_notificator ();
|
|
|
|
}
|
2018-06-13 13:13:41 +00:00
|
|
|
}
|
|
|
|
|
2018-05-05 15:38:01 +00:00
|
|
|
on_refresh ();
|
2018-04-26 14:05:03 +00:00
|
|
|
}
|
|
|
|
|
2018-06-20 15:50:42 +00:00
|
|
|
protected void setup_notificator () {
|
|
|
|
if (notificator != null)
|
|
|
|
notificator.close ();
|
|
|
|
|
|
|
|
var stream = get_stream ();
|
|
|
|
if (stream == null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
notificator = new Notificator (stream);
|
2018-10-23 10:05:24 +00:00
|
|
|
notificator.status_added.connect ((status) => {
|
2018-06-20 15:50:42 +00:00
|
|
|
if (can_stream ())
|
2018-10-23 10:05:24 +00:00
|
|
|
on_status_added (status);
|
2018-06-20 15:50:42 +00:00
|
|
|
});
|
|
|
|
notificator.start ();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected virtual bool is_public () {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected virtual bool can_stream () {
|
|
|
|
var allowed_public = true;
|
|
|
|
if (is_public ())
|
|
|
|
allowed_public = settings.live_updates_public;
|
|
|
|
|
|
|
|
return settings.live_updates && allowed_public;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override void bottom_reached (){
|
2018-05-19 12:21:03 +00:00
|
|
|
if (is_last_page) {
|
|
|
|
debug ("Last page reached");
|
|
|
|
return;
|
|
|
|
}
|
2018-04-26 14:05:03 +00:00
|
|
|
request ();
|
|
|
|
}
|
2018-04-14 12:09:06 +00:00
|
|
|
|
|
|
|
}
|