Continuous scrolling
This commit is contained in:
parent
67a5ac06f0
commit
e138d83150
|
@ -2,6 +2,7 @@ using Gtk;
|
|||
|
||||
public abstract class Tootle.AbstractView : Gtk.ScrolledWindow {
|
||||
|
||||
public int64 max_id = -1;
|
||||
public bool show_in_header;
|
||||
public Gtk.Image image;
|
||||
public Gtk.Box view;
|
||||
|
@ -10,6 +11,13 @@ public abstract class Tootle.AbstractView : Gtk.ScrolledWindow {
|
|||
view = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
|
||||
hscrollbar_policy = Gtk.PolicyType.NEVER;
|
||||
add (view);
|
||||
|
||||
edge_reached.connect(pos => {
|
||||
if (pos == Gtk.PositionType.BOTTOM)
|
||||
bottom_reached ();
|
||||
});
|
||||
|
||||
pre_construct ();
|
||||
}
|
||||
|
||||
public AbstractView (bool show) {
|
||||
|
@ -25,4 +33,15 @@ public abstract class Tootle.AbstractView : Gtk.ScrolledWindow {
|
|||
return "unnamed";
|
||||
}
|
||||
|
||||
public void clear (){
|
||||
max_id = -1;
|
||||
view.forall (widget => view.remove (widget));
|
||||
|
||||
pre_construct ();
|
||||
}
|
||||
|
||||
public virtual void pre_construct () {}
|
||||
|
||||
public virtual void bottom_reached (){}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using Gtk;
|
||||
using Granite;
|
||||
|
||||
public class Tootle.AccountView : Tootle.AbstractView {
|
||||
public class Tootle.AccountView : Tootle.HomeView {
|
||||
|
||||
Account account;
|
||||
|
||||
|
@ -13,7 +13,7 @@ public class Tootle.AccountView : Tootle.AbstractView {
|
|||
Gtk.Label note;
|
||||
Gtk.Grid counters;
|
||||
|
||||
construct {
|
||||
public override void pre_construct () {
|
||||
header = new Gtk.Grid ();
|
||||
|
||||
avatar = new Granite.Widgets.Avatar.with_default_icon (128);
|
||||
|
@ -51,8 +51,8 @@ public class Tootle.AccountView : Tootle.AbstractView {
|
|||
view.pack_start (header, false, false, 0);
|
||||
}
|
||||
|
||||
public AccountView (Account acc){
|
||||
base (false);
|
||||
public AccountView (Account acc) {
|
||||
base ("account_"+acc.id.to_string ());
|
||||
account = acc;
|
||||
|
||||
display_name.label = account.display_name;
|
||||
|
@ -68,13 +68,29 @@ public class Tootle.AccountView : Tootle.AbstractView {
|
|||
var stylesheet = ".header{background-image: url(\"%s\")}".printf (account.header);
|
||||
var css_provider = Granite.Widgets.Utils.get_css_provider (stylesheet);
|
||||
header_image.get_style_context ().add_provider (css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
request ();
|
||||
}
|
||||
|
||||
private void add_counter (string name, int i, int64 val){
|
||||
private void add_counter (string name, int i, int64 val) {
|
||||
var label_name = new Gtk.Label (name);
|
||||
var label_val = new Gtk.Label (val.to_string ());
|
||||
counters.attach (label_name, i, 1, 1, 1);
|
||||
counters.attach (label_val, i, 2, 1, 1);
|
||||
}
|
||||
|
||||
public override bool is_status_owned (Status status){
|
||||
return status.account.id == account.id;
|
||||
}
|
||||
|
||||
public override string get_url (){
|
||||
var url = "%s/api/v1/accounts/%lld/statuses".printf (Settings.instance.instance_url, account.id);
|
||||
url += "?limit=25";
|
||||
|
||||
if (max_id > 0)
|
||||
url += "&max_id=" + max_id.to_string ();
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,12 +4,10 @@ using Gdk;
|
|||
public class Tootle.HomeView : Tootle.AbstractView {
|
||||
|
||||
private string timeline;
|
||||
private string pars;
|
||||
|
||||
public HomeView (string timeline = "home", string pars = "") {
|
||||
public HomeView (string timeline = "home") {
|
||||
base (true);
|
||||
this.timeline = timeline;
|
||||
this.pars = pars;
|
||||
|
||||
view.remove.connect (on_remove);
|
||||
AccountManager.instance.switched.connect(on_account_changed);
|
||||
|
@ -24,22 +22,23 @@ public class Tootle.HomeView : Tootle.AbstractView {
|
|||
}
|
||||
|
||||
public override string get_name () {
|
||||
return "Home Timeline";
|
||||
return "Home";
|
||||
}
|
||||
|
||||
public void prepend(Status status){ //TODO: clear all on account switch
|
||||
public virtual bool is_status_owned (Status status){
|
||||
return false;
|
||||
}
|
||||
|
||||
public void prepend(Status status){
|
||||
var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
|
||||
separator.show ();
|
||||
|
||||
var widget = new StatusWidget(status);
|
||||
widget.separator = separator;
|
||||
widget.rebind (status);
|
||||
widget.button_press_event.connect(() => {
|
||||
var open_status = status.reblog != null ? status.reblog : status;
|
||||
var view = new StatusView (open_status);
|
||||
Tootle.window.open_secondary_view (view);
|
||||
return false;
|
||||
});
|
||||
widget.button_press_event.connect(widget.open);
|
||||
if (!is_status_owned (status))
|
||||
widget.avatar.button_press_event.connect(widget.on_avatar_clicked);
|
||||
view.pack_start(separator, false, false, 0);
|
||||
view.pack_start(widget, false, false, 0);
|
||||
}
|
||||
|
@ -48,25 +47,30 @@ public class Tootle.HomeView : Tootle.AbstractView {
|
|||
if (!(widget is StatusWidget))
|
||||
return;
|
||||
|
||||
//debug ("removed");
|
||||
//TODO: empty state
|
||||
}
|
||||
|
||||
public virtual void on_account_changed (Account? account){
|
||||
if(account == null)
|
||||
return;
|
||||
|
||||
public virtual string get_url (){
|
||||
var url = Settings.instance.instance_url;
|
||||
url += "api/v1/timelines/";
|
||||
url += this.timeline;
|
||||
url += this.pars;
|
||||
url += "?limit=25";
|
||||
|
||||
var msg = new Soup.Message("GET", url);
|
||||
if (max_id > 0)
|
||||
url += "&max_id=" + max_id.to_string ();
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
public void request (){
|
||||
var msg = new Soup.Message("GET", get_url ());
|
||||
NetManager.instance.queue(msg, (sess, mess) => {
|
||||
try{
|
||||
NetManager.parse_array (mess).foreach_element ((array, i, node) => {
|
||||
var object = node.get_object ();
|
||||
if (object != null){
|
||||
var status = Status.parse(object);
|
||||
max_id = status.id;
|
||||
prepend (status);
|
||||
}
|
||||
});
|
||||
|
@ -77,5 +81,17 @@ public class Tootle.HomeView : Tootle.AbstractView {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
public virtual void on_account_changed (Account? account){
|
||||
if(account == null)
|
||||
return;
|
||||
|
||||
clear ();
|
||||
request ();
|
||||
}
|
||||
|
||||
public override void bottom_reached (){
|
||||
request ();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ using Gtk;
|
|||
public class Tootle.LocalView : Tootle.HomeView {
|
||||
|
||||
public LocalView () {
|
||||
base ("public", "?local=true");
|
||||
base ("public");
|
||||
}
|
||||
|
||||
public override string get_icon () {
|
||||
|
@ -13,5 +13,11 @@ public class Tootle.LocalView : Tootle.HomeView {
|
|||
public override string get_name () {
|
||||
return "Local Timeline";
|
||||
}
|
||||
|
||||
public override string get_url (){
|
||||
string url = base.get_url ();
|
||||
url += "&local=true";
|
||||
return url;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ public class Tootle.StatusView : Tootle.AbstractView {
|
|||
widget.content.selectable = true;
|
||||
if (widget.spoiler_content != null)
|
||||
widget.spoiler_content.selectable = true;
|
||||
widget.avatar.button_press_event.connect(widget.on_avatar_clicked);
|
||||
view.pack_start (widget, false, false, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ public class Tootle.NotificationWidget : Gtk.Grid {
|
|||
if (notification.status != null){
|
||||
status_widget = new StatusWidget (this.notification.status);
|
||||
status_widget.rebind (this.notification.status);
|
||||
status_widget.button_press_event.connect(status_widget.open);
|
||||
status_widget.avatar.button_press_event.connect(status_widget.on_avatar_clicked);
|
||||
attach(status_widget, 1, 3, 3, 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,12 +29,12 @@ public class Tootle.StatusWidget : Gtk.EventBox {
|
|||
avatar = new Granite.Widgets.Avatar.with_default_icon (avatar_size);
|
||||
avatar.valign = Gtk.Align.START;
|
||||
avatar.margin_end = 6;
|
||||
user = new Gtk.Label (_("Anonymous"));
|
||||
user = new Gtk.Label ("");
|
||||
user.hexpand = true;
|
||||
user.halign = Gtk.Align.START;
|
||||
user.use_markup = true;
|
||||
|
||||
content = new Gtk.Label (_("Error parsing text :c"));
|
||||
content = new Gtk.Label ("");
|
||||
content.halign = Gtk.Align.START;
|
||||
content.use_markup = true;
|
||||
content.single_line_mode = false;
|
||||
|
@ -146,17 +146,22 @@ public class Tootle.StatusWidget : Gtk.EventBox {
|
|||
|
||||
var avatar_url = status.reblog != null ? status.reblog.account.avatar : status.account.avatar;
|
||||
CacheManager.instance.load_avatar (avatar_url, this.avatar, this.avatar_size);
|
||||
|
||||
avatar.button_press_event.connect(on_avatar_clicked);
|
||||
}
|
||||
|
||||
private bool on_avatar_clicked (){
|
||||
public bool on_avatar_clicked (){
|
||||
var account = status.reblog != null ? status.reblog.account : status.account;
|
||||
var view = new AccountView (account);
|
||||
Tootle.window.open_secondary_view (view);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool open (){
|
||||
var open_status = status.reblog != null ? status.reblog : status;
|
||||
var view = new StatusView (open_status);
|
||||
Tootle.window.open_secondary_view (view);
|
||||
return false;
|
||||
}
|
||||
|
||||
private Gtk.ToggleButton get_action_button (string icon_path){
|
||||
var icon = new Gtk.Image.from_icon_name (icon_path, Gtk.IconSize.SMALL_TOOLBAR);
|
||||
var button = new Gtk.ToggleButton ();
|
||||
|
|
Loading…
Reference in New Issue