Add empty state
This commit is contained in:
parent
349a05bbd5
commit
ef21a53cf9
|
@ -2,6 +2,7 @@
|
|||
<gresources>
|
||||
<gresource prefix="/com/github/bleakgrey/tootle/">
|
||||
<file alias="Application.css">Application.css</file>
|
||||
<file alias="logo128.png">logo128.png</file>
|
||||
<file alias="logo128">logo128.png</file>
|
||||
<file alias="empty_state">empty_state.png</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
|
@ -2,8 +2,9 @@ using Gtk;
|
|||
|
||||
public abstract class Tootle.AbstractView : Gtk.ScrolledWindow {
|
||||
|
||||
public Gtk.Image image;
|
||||
public Gtk.Image? image;
|
||||
public Gtk.Box view;
|
||||
protected Gtk.Box? empty;
|
||||
|
||||
construct {
|
||||
view = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
|
||||
|
@ -40,4 +41,30 @@ public abstract class Tootle.AbstractView : Gtk.ScrolledWindow {
|
|||
|
||||
public virtual void bottom_reached (){}
|
||||
|
||||
public virtual bool is_empty () {
|
||||
return view.get_children ().length () <= 1;
|
||||
}
|
||||
|
||||
public virtual bool empty_state () {
|
||||
if (empty != null)
|
||||
empty.destroy ();
|
||||
if (!is_empty ())
|
||||
return false;
|
||||
|
||||
empty = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
|
||||
empty.margin = 64;
|
||||
var image = new Image.from_resource ("/com/github/bleakgrey/tootle/empty_state");
|
||||
var text = new Gtk.Label (_("Nothing to see here"));
|
||||
text.get_style_context ().add_class ("h2");
|
||||
text.opacity = 0.5;
|
||||
empty.vexpand = true;
|
||||
empty.valign = Gtk.Align.FILL;
|
||||
empty.pack_start (image, false, false, 0);
|
||||
empty.pack_start (text, false, false, 12);
|
||||
empty.show_all ();
|
||||
view.pack_start (empty, false, false, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -197,6 +197,10 @@ public class Tootle.AccountView : TimelineView {
|
|||
return btn;
|
||||
}
|
||||
|
||||
public override bool is_empty () {
|
||||
return view.get_children ().length () <= 2;
|
||||
}
|
||||
|
||||
public override bool is_status_owned (Status status){
|
||||
return status.get_formal ().account.id == account.id;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ public class Tootle.AddAccountView : Tootle.AbstractView {
|
|||
hexpand = true;
|
||||
halign = Gtk.Align.CENTER;
|
||||
|
||||
image = new Image.from_resource ("/com/github/bleakgrey/tootle/logo128.png");
|
||||
image = new Image.from_resource ("/com/github/bleakgrey/tootle/logo128");
|
||||
image.halign = Gtk.Align.CENTER;
|
||||
image.hexpand = true;
|
||||
image.margin_bottom = 24;
|
||||
|
|
|
@ -4,10 +4,12 @@ public class Tootle.FollowersView : TimelineView {
|
|||
|
||||
public FollowersView (ref Account account) {
|
||||
base (account.id.to_string ());
|
||||
|
||||
}
|
||||
|
||||
public new void prepend (ref Account account){
|
||||
if (empty != null)
|
||||
empty.destroy ();
|
||||
|
||||
var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
|
||||
separator.show ();
|
||||
|
||||
|
@ -27,7 +29,7 @@ public class Tootle.FollowersView : TimelineView {
|
|||
|
||||
public override void request (){
|
||||
var msg = new Soup.Message("GET", get_url ());
|
||||
debug (get_url ());
|
||||
msg.finished.connect (() => empty_state ());
|
||||
Tootle.network.queue(msg, (sess, mess) => {
|
||||
try{
|
||||
Tootle.network.parse_array (mess).foreach_element ((array, i, node) => {
|
||||
|
|
|
@ -22,7 +22,10 @@ public class Tootle.NotificationsView : AbstractView {
|
|||
return _("Notifications");
|
||||
}
|
||||
|
||||
public void prepend (Notification notification, bool invert_order = false) {
|
||||
public void prepend (Notification notification) {
|
||||
if (empty != null)
|
||||
empty.destroy ();
|
||||
|
||||
var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
|
||||
separator.show ();
|
||||
|
||||
|
@ -37,8 +40,15 @@ public class Tootle.NotificationsView : AbstractView {
|
|||
if (!(widget is NotificationWidget))
|
||||
return;
|
||||
|
||||
if (view.get_children ().length () <= 1)
|
||||
empty_state ();
|
||||
}
|
||||
|
||||
public override bool empty_state () {
|
||||
var is_empty = base.empty_state ();
|
||||
if (image != null && is_empty)
|
||||
image.icon_name = get_icon ();
|
||||
|
||||
return is_empty;
|
||||
}
|
||||
|
||||
public virtual void on_refresh () {
|
||||
|
@ -89,6 +99,8 @@ public class Tootle.NotificationsView : AbstractView {
|
|||
warning (e.message);
|
||||
}
|
||||
});
|
||||
|
||||
empty_state ();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,12 +44,6 @@ public class Tootle.SearchView : AbstractView {
|
|||
view.pack_start (widget, false, false, 0);
|
||||
}
|
||||
|
||||
private void append_empty_state (){
|
||||
var empty_state = new Gtk.Label (_("No Results"));
|
||||
empty_state.get_style_context ().add_class ("h2");
|
||||
view.pack_start (empty_state, false, false, 6);
|
||||
}
|
||||
|
||||
private void append_hashtag (string name) {
|
||||
var text = "<a href=\"%s/tags/%s\">#%s</a>".printf (Tootle.settings.instance_url, Soup.URI.encode (name, null), name);
|
||||
var widget = new RichLabel (text);
|
||||
|
@ -79,10 +73,6 @@ public class Tootle.SearchView : AbstractView {
|
|||
var hashtags = root.get_array_member ("hashtags");
|
||||
|
||||
clear ();
|
||||
if (accounts.get_length () == 0 && statuses.get_length () == 0 && hashtags.get_length () == 0) {
|
||||
append_empty_state ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (accounts.get_length () > 0) {
|
||||
append_header (_("Accounts"));
|
||||
|
@ -108,6 +98,8 @@ public class Tootle.SearchView : AbstractView {
|
|||
append_hashtag (node.get_string ());
|
||||
});
|
||||
}
|
||||
|
||||
empty_state ();
|
||||
|
||||
}
|
||||
catch (GLib.Error e) {
|
||||
|
|
|
@ -36,6 +36,9 @@ public class Tootle.TimelineView : AbstractView {
|
|||
}
|
||||
|
||||
public void prepend (ref Status status){
|
||||
if (empty != null)
|
||||
empty.destroy ();
|
||||
|
||||
var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
|
||||
separator.show ();
|
||||
|
||||
|
@ -58,16 +61,12 @@ public class Tootle.TimelineView : AbstractView {
|
|||
public virtual void on_remove (Widget widget){
|
||||
if (!(widget is StatusWidget))
|
||||
return;
|
||||
|
||||
//TODO: empty state
|
||||
}
|
||||
|
||||
public void get_pages (string? header) {
|
||||
page_next = page_prev = null;
|
||||
if (header == null) {
|
||||
debug ("No pagingation links");
|
||||
if (header == null)
|
||||
return;
|
||||
}
|
||||
|
||||
var pages = header.split (",");
|
||||
foreach (var page in pages) {
|
||||
|
@ -76,14 +75,10 @@ public class Tootle.TimelineView : AbstractView {
|
|||
.replace (">", "")
|
||||
.split (";")[0];
|
||||
|
||||
if ("rel=\"prev\"" in page) {
|
||||
debug ("found prev page %s", sanitized);
|
||||
if ("rel=\"prev\"" in page)
|
||||
page_prev = sanitized;
|
||||
}
|
||||
else {
|
||||
debug ("found next page %s", sanitized);
|
||||
else
|
||||
page_next = sanitized;
|
||||
}
|
||||
}
|
||||
|
||||
is_last_page = page_prev != null & page_next == null;
|
||||
|
@ -100,6 +95,7 @@ public class Tootle.TimelineView : AbstractView {
|
|||
|
||||
public virtual void request (){
|
||||
var msg = new Soup.Message("GET", get_url ());
|
||||
msg.finished.connect (() => empty_state ());
|
||||
Tootle.network.queue(msg, (sess, mess) => {
|
||||
try{
|
||||
Tootle.network.parse_array (mess).foreach_element ((array, i, node) => {
|
||||
|
@ -126,7 +122,6 @@ public class Tootle.TimelineView : AbstractView {
|
|||
public virtual void on_account_changed (Account? account){
|
||||
if(account == null)
|
||||
return;
|
||||
|
||||
on_refresh ();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue