tootle-linux-client/src/Views/Timeline.vala

171 lines
4.5 KiB
Vala
Raw Normal View History

2018-04-14 14:09:06 +02:00
using Gtk;
using Gdk;
public class Tootle.Views.Timeline : IAccountListener, IStreamListener, Views.Base {
2019-03-07 17:16:52 +01:00
2020-06-03 14:41:21 +02:00
public string url { get; construct set; }
2020-05-29 14:19:35 +02:00
public bool is_public { get; construct set; default = false; }
protected InstanceAccount? account = null;
2020-06-03 14:41:21 +02:00
protected bool is_last_page { get; set; default = false; }
protected string? page_next { get; set; }
protected string? page_prev { get; set; }
protected string? stream = null;
2019-03-07 17:16:52 +01:00
2020-05-29 14:19:35 +02:00
construct {
2018-06-13 15:13:41 +02:00
app.refresh.connect (on_refresh);
2020-05-29 14:19:35 +02:00
status_button.clicked.connect (on_refresh);
connect_account ();
on_status_added.connect (add_status);
on_status_removed.connect (remove_status);
2020-05-29 14:19:35 +02:00
}
~Timeline () {
streams.unsubscribe (stream, this);
2018-04-14 14:09:06 +02:00
}
2019-03-07 17:16:52 +01:00
2019-03-11 15:14:37 +01:00
public virtual bool is_status_owned (API.Status status) {
2020-05-29 14:19:35 +02:00
return status.is_owned ();
2018-05-21 17:23:31 +02:00
}
2019-03-07 17:16:52 +01:00
public virtual GLib.Object? to_entity (Json.Object? json) {
return new API.Status (json);
2018-05-27 19:14:48 +02:00
}
2019-03-07 17:16:52 +01:00
public virtual Widget? widgetize (GLib.Object? entity) {
var status = entity as API.Status;
if (status == null)
return null;
2018-05-18 23:14:12 +02:00
var w = new Widgets.Status (status);
w.button_press_event.connect (w.open);
if (!is_status_owned (status))
w.avatar.button_press_event.connect (w.on_avatar_clicked);
2019-03-07 17:16:52 +01:00
return w;
}
public void prepend (Widget? w) {
append (w, true);
}
public virtual void append (Widget? w, bool first = false) {
if (w == null)
return;
if (first)
2020-06-02 11:35:29 +02:00
content_list.prepend (w);
else
content_list.insert (w, -1);
on_content_changed ();
2018-04-14 14:09:06 +02:00
}
2019-03-07 17:16:52 +01:00
public override void clear () {
this.page_prev = null;
this.page_next = null;
this.is_last_page = false;
base.clear ();
}
2019-03-07 17:16:52 +01:00
public void get_pages (string? header) {
page_next = page_prev = null;
2018-05-19 15:55:41 +02:00
if (header == null)
return;
2019-03-07 17:16:52 +01:00
var pages = header.split (",");
foreach (var page in pages) {
var sanitized = page
.replace ("<","")
.replace (">", "")
.split (";")[0];
2018-05-19 15:55:41 +02:00
if ("rel=\"prev\"" in page)
page_prev = sanitized;
2018-05-19 15:55:41 +02:00
else
page_next = sanitized;
}
2019-03-07 17:16:52 +01:00
is_last_page = page_prev != null & page_next == null;
}
2019-03-07 17:16:52 +01:00
2020-06-03 14:41:21 +02:00
public virtual string get_req_url () {
if (page_next != null)
return page_next;
2019-03-07 17:16:52 +01:00
2020-06-03 14:41:21 +02:00
return url;
2018-04-26 16:05:03 +02:00
}
2019-03-07 17:16:52 +01:00
2020-05-29 14:19:35 +02:00
public virtual Request append_params (Request req) {
2020-06-01 03:27:11 +02:00
return req.with_param ("limit", @"$(settings.timeline_page_size)");
2018-05-03 10:11:31 +02:00
}
2019-03-07 17:16:52 +01:00
2020-05-29 14:19:35 +02:00
public virtual bool request () {
2020-06-03 14:41:21 +02:00
append_params (new Request.GET (get_req_url ()))
2020-05-29 14:19:35 +02:00
.with_account (account)
.then_parse_array ((node, msg) => {
var obj = node.get_object ();
if (obj == null)
warning ("Received invalid Json.Object");
else {
var entity = to_entity (obj);
if (entity == null)
warning ("Can't convert Json.Object to required entity");
else
append (widgetize (entity));
}
2020-05-29 14:19:35 +02:00
get_pages (msg.response_headers.get_one ("Link"));
})
.on_error (on_error)
.exec ();
return GLib.Source.REMOVE;
2018-04-26 16:05:03 +02:00
}
2019-03-07 17:16:52 +01:00
2020-05-29 14:19:35 +02:00
public virtual void on_refresh () {
status_button.sensitive = false;
clear ();
status_message = STATUS_LOADING;
GLib.Idle.add (request);
}
2019-03-07 17:16:52 +01:00
2020-05-29 14:19:35 +02:00
public virtual string? get_stream_url () {
return null;
2018-06-20 17:50:42 +02:00
}
2019-03-07 17:16:52 +01:00
public virtual void on_account_changed (InstanceAccount? acc) {
2020-05-29 14:19:35 +02:00
account = acc;
streams.unsubscribe (stream, this);
streams.subscribe (get_stream_url (), this, out stream);
on_refresh ();
2018-06-20 17:50:42 +02:00
}
2019-03-07 17:16:52 +01:00
2020-05-30 12:31:02 +02:00
protected override void on_bottom_reached () {
if (is_last_page) {
info ("Last page reached");
return;
}
request ();
}
protected virtual void add_status (API.Status status) {
2020-05-30 18:37:35 +02:00
var allow_update = true;
if (is_public)
2020-05-31 21:56:03 +02:00
allow_update = settings.public_live_updates;
2020-05-30 18:37:35 +02:00
if (settings.live_updates && allow_update)
prepend (widgetize (status));
2018-06-20 17:50:42 +02:00
}
2019-03-07 17:16:52 +01:00
protected virtual void remove_status (int64 id) {
2020-05-30 18:37:35 +02:00
if (settings.live_updates) {
content.get_children ().@foreach (w => {
var sw = w as Widgets.Status;
if (sw != null && sw.status.id == id)
sw.destroy ();
});
}
2018-04-26 16:05:03 +02:00
}
2018-04-14 14:09:06 +02:00
}