diff --git a/src/API/Status.vala b/src/API/Status.vala index 0321e93..3e9648b 100644 --- a/src/API/Status.vala +++ b/src/API/Status.vala @@ -1,4 +1,4 @@ -public class Tootle.Status{ +public class Tootle.Status { public abstract signal void updated (); diff --git a/src/AccountManager.vala b/src/AccountManager.vala index 848b06e..19168b4 100644 --- a/src/AccountManager.vala +++ b/src/AccountManager.vala @@ -6,7 +6,7 @@ public class Tootle.AccountManager : Object{ public abstract signal void added(Account account); public abstract signal void removed(Account account); - public Account current; + public Account? current; public AccountManager(){ Object(); diff --git a/src/Application.vala b/src/Application.vala index ba60720..ba01d84 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -13,8 +13,9 @@ namespace Tootle{ public class Application : Granite.Application { - public abstract signal void toast(string title); - public abstract signal void error(string title, string text); + public abstract signal void refresh (); + public abstract signal void toast (string title); + public abstract signal void error (string title, string text); construct { application_id = "com.github.bleakgrey.tootle"; diff --git a/src/CacheManager.vala b/src/CacheManager.vala index d1d15b0..e38603a 100644 --- a/src/CacheManager.vala +++ b/src/CacheManager.vala @@ -3,10 +3,10 @@ using GLib; public class Tootle.CacheManager : GLib.Object{ - private static string path_images; + private static string path_downloads; construct{ - path_images = GLib.Environment.get_user_special_dir (UserDirectory.DOWNLOAD); + path_downloads = GLib.Environment.get_user_special_dir (UserDirectory.DOWNLOAD); } //TODO: actually cache images @@ -23,7 +23,7 @@ public class Tootle.CacheManager : GLib.Object{ loader.close(); avatar.pixbuf = loader.get_pixbuf (); }); - Tootle.network.queue(msg, (sess, mess) => {}); + Tootle.network.queue(msg); } public void load_image (string url, Gtk.Image image){ @@ -34,7 +34,7 @@ public class Tootle.CacheManager : GLib.Object{ loader.close(); image.set_from_pixbuf (loader.get_pixbuf ()); }); - Tootle.network.queue(msg, (sess, mess) => {}); + Tootle.network.queue(msg); } } diff --git a/src/Dialogs/PostDialog.vala b/src/Dialogs/PostDialog.vala index 74bc7eb..60b9719 100644 --- a/src/Dialogs/PostDialog.vala +++ b/src/Dialogs/PostDialog.vala @@ -137,7 +137,7 @@ public class Tootle.PostDialog : Gtk.Dialog { try{ var root = Tootle.network.parse (mess); var status = Status.parse (root); - Tootle.window.home.prepend (status); + debug (status.id.to_string ()); //TODO: Live updates this.destroy (); } catch (GLib.Error e) { diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 8cbd7ac..b8d1970 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -7,11 +7,6 @@ public class Tootle.MainWindow: Gtk.Window { public Tootle.HeaderBar header; public Stack primary_stack; public Stack secondary_stack; - - public HomeView home = new HomeView (); - public LocalView feed_local = new LocalView (); - public FederatedView feed_federated = new FederatedView (); - public NotificationsView notifications = new NotificationsView (); construct { var provider = new Gtk.CssProvider (); @@ -57,45 +52,45 @@ public class Tootle.MainWindow: Gtk.Window { Tootle.accounts.init (); } - private void on_account_switched(Account? account){ - secondary_stack.forall (widget => secondary_stack.remove (widget)); - - if(account == null) - show_setup_views (); - else - show_main_views (); + private void reset () { + header.button_mode.clear_children (); + secondary_stack.forall (widget => widget.destroy ()); } - private void show_setup_views (){ + private void on_account_switched(Account? account = Tootle.accounts.current){ + reset (); + if(account == null) + build_setup_view (); + else + build_main_view (); + } + + private void build_setup_view (){ var add_account = new AddAccountView (); secondary_stack.add_named (add_account, add_account.get_name ()); header.update (false, true); } - private void show_main_views (){ - header.button_mode.clear_children (); - add_view (home); - add_view (notifications); - add_view (feed_local); - add_view (feed_federated); - header.button_mode.set_active (0); + private void build_main_view (){ + add_header_view (new HomeView ()); + add_header_view (new NotificationsView ()); + add_header_view (new LocalView ()); + add_header_view (new FederatedView ()); header.update (true); } - private void add_view (AbstractView view) { - if (view.show_in_header){ - var img = new Gtk.Image.from_icon_name(view.get_icon (), Gtk.IconSize.LARGE_TOOLBAR); - img.tooltip_text = view.get_name (); - header.button_mode.append (img); - view.image = img; - secondary_stack.add_named(view, view.get_name ()); - - if (view is NotificationsView) - img.pixel_size = 20; // For some reason Notifications icon is too small without this - } + private void add_header_view (AbstractView view) { + var img = new Gtk.Image.from_icon_name(view.get_icon (), Gtk.IconSize.LARGE_TOOLBAR); + img.tooltip_text = view.get_name (); + header.button_mode.append (img); + view.image = img; + secondary_stack.add_named(view, view.get_name ()); + + if (view is NotificationsView) + img.pixel_size = 20; // For some reason Notifications icon is too small without this } - public void open_secondary_view (Widget widget) { + public void open_view (Widget widget) { widget.show (); var i = int.parse (primary_stack.get_visible_child_name ()); i++; diff --git a/src/NetManager.vala b/src/NetManager.vala index f813efd..cbc6d0c 100644 --- a/src/NetManager.vala +++ b/src/NetManager.vala @@ -6,7 +6,6 @@ public class Tootle.NetManager : GLib.Object { public abstract signal void started(); public abstract signal void finished(); - public abstract signal void refresh(); private int requests_processing = 0; private Soup.Session session; @@ -16,11 +15,15 @@ public class Tootle.NetManager : GLib.Object { session.ssl_strict = true; session.ssl_use_system_ca_file = true; session.timeout = 20; + session.max_conns = 15; session.request_unqueued.connect (() => { requests_processing--; if(requests_processing <= 0) finished (); }); + + // Soup.Logger logger = new Soup.Logger (Soup.LoggerLogLevel.MINIMAL, -1); + // session.add_feature (logger); } public NetManager() { diff --git a/src/Views/AbstractView.vala b/src/Views/AbstractView.vala index d62d3e9..5822d32 100644 --- a/src/Views/AbstractView.vala +++ b/src/Views/AbstractView.vala @@ -3,7 +3,6 @@ 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; @@ -21,8 +20,7 @@ public abstract class Tootle.AbstractView : Gtk.ScrolledWindow { pre_construct (); } - public AbstractView (bool show) { - show_in_header = show; + public AbstractView () { show_all (); } diff --git a/src/Views/AccountView.vala b/src/Views/AccountView.vala index e261c12..00c51d1 100644 --- a/src/Views/AccountView.vala +++ b/src/Views/AccountView.vala @@ -99,7 +99,6 @@ public class Tootle.AccountView : Tootle.HomeView { } public AccountView (Account acc) { - base ("account_"+acc.id.to_string ()); account = acc; account.updated.connect(rebind); @@ -177,16 +176,20 @@ public class Tootle.AccountView : Tootle.HomeView { return status.get_formal ().account.id == account.id; } - public override string get_url (){ + public override string get_url () { var url = "%s/api/v1/accounts/%lld/statuses".printf (Tootle.settings.instance_url, account.id); url += "?limit=25"; if (max_id > 0) - url += "&max_id=" + max_id.to_string (); - + url += "&max_id=" + max_id.to_string (); return url; } + public override void request (){ + if(account != null) + base.request (); + } + public static void open_from_id (int64 id){ var url = "%s/api/v1/accounts/%lld".printf (Tootle.settings.instance_url, id); var msg = new Soup.Message("GET", url); @@ -195,7 +198,7 @@ public class Tootle.AccountView : Tootle.HomeView { try{ var root = Tootle.network.parse (mess); var acc = Account.parse (root); - Tootle.window.open_secondary_view (new AccountView (acc)); + Tootle.window.open_view (new AccountView (acc)); } catch (GLib.Error e) { warning ("Can't update feed"); @@ -214,7 +217,7 @@ public class Tootle.AccountView : Tootle.HomeView { var object = node.get_object (); if (object != null){ var acc = Account.parse(object); - Tootle.window.open_secondary_view (new AccountView (acc)); + Tootle.window.open_view (new AccountView (acc)); } else warning ("No results found for account: "+name); //TODO: toast notifications diff --git a/src/Views/AddAccountView.vala b/src/Views/AddAccountView.vala index d3494bf..9cf6fb3 100644 --- a/src/Views/AddAccountView.vala +++ b/src/Views/AddAccountView.vala @@ -110,7 +110,7 @@ public class Tootle.AddAccountView : Tootle.AbstractView { } public AddAccountView () { - base (false); + base (); } public override string get_name () { diff --git a/src/Views/HomeView.vala b/src/Views/HomeView.vala index ff57fde..312e8d2 100644 --- a/src/Views/HomeView.vala +++ b/src/Views/HomeView.vala @@ -6,16 +6,17 @@ public class Tootle.HomeView : Tootle.AbstractView { private string timeline; public HomeView (string timeline = "home") { - base (true); + base (); this.timeline = timeline; view.remove.connect (on_remove); Tootle.accounts.switched.connect(on_account_changed); - Tootle.network.refresh.connect(on_refresh); + Tootle.app.refresh.connect(on_refresh); // var s = new Status(1); // s.content = "Test content, wow!"; // prepend (s); + request (); } public override string get_icon () { @@ -50,7 +51,7 @@ public class Tootle.HomeView : Tootle.AbstractView { //TODO: empty state } - public virtual string get_url (){ + public virtual string get_url () { var url = Tootle.settings.instance_url; url += "api/v1/timelines/"; url += this.timeline; @@ -62,7 +63,7 @@ public class Tootle.HomeView : Tootle.AbstractView { return url; } - public void request (){ + public virtual void request (){ var msg = new Soup.Message("GET", get_url ()); Tootle.network.queue(msg, (sess, mess) => { try{ @@ -90,8 +91,8 @@ public class Tootle.HomeView : Tootle.AbstractView { public virtual void on_account_changed (Account? account){ if(account == null) return; - clear (); - request (); + + on_refresh (); } public override void bottom_reached (){ diff --git a/src/Views/NotificationsView.vala b/src/Views/NotificationsView.vala index 5f25340..4ab546f 100644 --- a/src/Views/NotificationsView.vala +++ b/src/Views/NotificationsView.vala @@ -4,11 +4,13 @@ using Gdk; public class Tootle.NotificationsView : Tootle.AbstractView { public NotificationsView () { - base (true); + base (); view.remove.connect (on_remove); Tootle.accounts.switched.connect(on_account_changed); - Tootle.network.refresh.connect(on_refresh); + Tootle.app.refresh.connect(on_refresh); + + request (); } public override string get_icon () { @@ -46,9 +48,8 @@ public class Tootle.NotificationsView : Tootle.AbstractView { public virtual void on_account_changed (Account? account){ if(account == null) return; - - clear (); - request (); + + on_refresh (); } public void request (){ diff --git a/src/Views/StatusView.vala b/src/Views/StatusView.vala index f22473e..c24636c 100644 --- a/src/Views/StatusView.vala +++ b/src/Views/StatusView.vala @@ -6,7 +6,7 @@ public class Tootle.StatusView : Tootle.AbstractView { bool last_was_a_root = false; public StatusView (Status status) { - base (false); + base (); root_status = status; request_context (); } diff --git a/src/Widgets/AccountsButton.vala b/src/Widgets/AccountsButton.vala index 3bc24af..9d57eb1 100644 --- a/src/Widgets/AccountsButton.vala +++ b/src/Widgets/AccountsButton.vala @@ -54,11 +54,11 @@ public class Tootle.AccountsButton : Gtk.MenuButton{ item_refresh = new Gtk.ModelButton (); item_refresh.text = _("Refresh"); - item_refresh.clicked.connect (() => Tootle.network.refresh ()); + item_refresh.clicked.connect (() => Tootle.app.refresh ()); item_favs = new Gtk.ModelButton (); item_favs.text = _("Favorites"); - item_favs.clicked.connect (() => Tootle.window.open_secondary_view (new FavoritesView ())); + item_favs.clicked.connect (() => Tootle.window.open_view (new FavoritesView ())); item_settings = new Gtk.ModelButton (); item_settings.text = _("Settings"); diff --git a/src/Widgets/HeaderBar.vala b/src/Widgets/HeaderBar.vala index e39bf02..0635d45 100644 --- a/src/Widgets/HeaderBar.vala +++ b/src/Widgets/HeaderBar.vala @@ -8,6 +8,8 @@ public class Tootle.HeaderBar : Gtk.HeaderBar{ Button button_toot; Button button_back; + private int last_tab = 0; + construct { spinner = new Spinner (); spinner.active = true; @@ -39,6 +41,7 @@ public class Tootle.HeaderBar : Gtk.HeaderBar{ button_mode = new Granite.Widgets.ModeButton (); button_mode.get_style_context ().add_class ("mode"); button_mode.mode_changed.connect(widget => { + last_tab = button_mode.selected; Tootle.window.secondary_stack.set_visible_child_name(widget.tooltip_text); }); button_mode.show (); @@ -60,6 +63,7 @@ public class Tootle.HeaderBar : Gtk.HeaderBar{ } public void update (bool primary_mode, bool hide_all = false){ + button_mode.set_active (last_tab); if (hide_all){ button_mode.opacity = 0; button_mode.sensitive = false; diff --git a/src/Widgets/StatusWidget.vala b/src/Widgets/StatusWidget.vala index ea28f65..88ed7cc 100644 --- a/src/Widgets/StatusWidget.vala +++ b/src/Widgets/StatusWidget.vala @@ -120,7 +120,7 @@ public class Tootle.StatusWidget : Gtk.EventBox { status.updated.connect (rebind); get_style_context ().add_class ("status"); - if (status.reblog != null){ + if (status.reblog != null) { var image = new Gtk.Image.from_icon_name("go-up-symbolic", Gtk.IconSize.SMALL_TOOLBAR); image.halign = Gtk.Align.END; image.margin_end = 6; @@ -137,7 +137,7 @@ public class Tootle.StatusWidget : Gtk.EventBox { grid.attach (label, 2, 0, 2, 1); } - if (is_spoiler ()){ + if (is_spoiler ()) { revealer.reveal_child = false; var spoiler_box = new Box (Gtk.Orientation.HORIZONTAL, 6); spoiler_box.margin_end = 12; @@ -184,12 +184,12 @@ public class Tootle.StatusWidget : Gtk.EventBox { rebind (); } - public void highlight (){ + public void highlight () { grid.get_style_context ().add_class ("card"); grid.margin_bottom = 6; } - public void rebind (){ + public void rebind () { title_user.label = "%s".printf (status.get_formal ().account.display_name); title_acct.label = "@" + status.account.acct; content_label.label = status.content; @@ -209,13 +209,13 @@ public class Tootle.StatusWidget : Gtk.EventBox { Tootle.cache.load_avatar (status.get_formal ().account.avatar, this.avatar, this.avatar_size); } - public bool is_spoiler (){ + public bool is_spoiler () { return status.spoiler_text != null || status.sensitive; } // elementary OS has old GLib, so I have to improvise // Version >=2.56 provides DateTime.from_iso8601 - public void parse_date_iso8601 (string date){ + public void parse_date_iso8601 (string date) { var cmd = "date -d " + date + " +%s"; var runner = new CmdRunner ("/bin/", cmd); //Workaround for Granite SimpleCommand pipes bug runner.done.connect (exit => { @@ -226,19 +226,19 @@ public class Tootle.StatusWidget : Gtk.EventBox { runner.run (); } - public bool on_avatar_clicked (){ + public bool on_avatar_clicked () { var view = new AccountView (status.get_formal ().account); - Tootle.window.open_secondary_view (view); + Tootle.window.open_view (view); return true; } - public bool open (){ + public bool open () { var view = new StatusView (status.get_formal ()); - Tootle.window.open_secondary_view (view); + Tootle.window.open_view (view); return false; } - private Gtk.ToggleButton get_action_button (string icon_path){ + 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 (); button.can_default = false;