From 912876d09846a8aa40fee0c95d6839b13a80e25c Mon Sep 17 00:00:00 2001 From: Evan Paterakis Date: Tue, 10 Dec 2024 11:00:51 +0200 Subject: [PATCH] feat(Timelines): bubble --- data/gresource.xml | 1 + .../icons/scalable/actions/tuba-fish-symbolic.svg | 2 ++ src/API/Instance.vala | 10 ++++++++++ src/Services/Accounts/InstanceAccount.vala | 4 ++++ src/Services/Accounts/Mastodon/Account.vala | 15 +++++++++++++++ src/Views/Bubble.vala | 8 ++++++++ src/Views/Sidebar.vala | 10 ++++++++-- src/Views/meson.build | 1 + 8 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 data/icons/scalable/actions/tuba-fish-symbolic.svg create mode 100644 src/Views/Bubble.vala diff --git a/data/gresource.xml b/data/gresource.xml index d44e6766b..6e73a106d 100644 --- a/data/gresource.xml +++ b/data/gresource.xml @@ -76,6 +76,7 @@ icons/scalable/actions/tuba-police-badge2-symbolic.svg icons/scalable/actions/tuba-clock-alt-symbolic.svg icons/scalable/actions/tuba-quotation-symbolic.svg + icons/scalable/actions/tuba-fish-symbolic.svg gtk/help-overlay.ui diff --git a/data/icons/scalable/actions/tuba-fish-symbolic.svg b/data/icons/scalable/actions/tuba-fish-symbolic.svg new file mode 100644 index 000000000..dea2b4542 --- /dev/null +++ b/data/icons/scalable/actions/tuba-fish-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/src/API/Instance.vala b/src/API/Instance.vala index 05ccd02b2..c7e90c64f 100644 --- a/src/API/Instance.vala +++ b/src/API/Instance.vala @@ -40,6 +40,16 @@ public class Tuba.API.Instance : Entity { } } + public bool supports_bubble { + get { + if (pleroma != null && pleroma.metadata != null && pleroma.metadata.features != null) { + return "bubble_timeline" in pleroma.metadata.features; + } + + return false; + } + } + public string[]? compat_supported_mime_types { get { if (pleroma != null && pleroma.metadata != null) { diff --git a/src/Services/Accounts/InstanceAccount.vala b/src/Services/Accounts/InstanceAccount.vala index 7c3d3a8b1..071def0c4 100644 --- a/src/Services/Accounts/InstanceAccount.vala +++ b/src/Services/Accounts/InstanceAccount.vala @@ -60,6 +60,7 @@ public class Tuba.InstanceAccount : API.Account, Streamable { } public virtual signal void activated () { + bump_sidebar_items (); gather_instance_info (); gather_instance_custom_emojis (); GLib.Idle.add (gather_fav_lists); @@ -508,10 +509,13 @@ public class Tuba.InstanceAccount : API.Account, Streamable { } app.handle_share (); + bump_sidebar_items (); }) .exec (); } + protected virtual void bump_sidebar_items () {} + private void gather_v2_instance_info () { new Request.GET ("/api/v2/instance") .with_account (this) diff --git a/src/Services/Accounts/Mastodon/Account.vala b/src/Services/Accounts/Mastodon/Account.vala index 5d94a4c68..c31f0b73c 100644 --- a/src/Services/Accounts/Mastodon/Account.vala +++ b/src/Services/Accounts/Mastodon/Account.vala @@ -121,6 +121,16 @@ public class Tuba.Mastodon.Account : InstanceAccount { } }; + public static Place PLACE_BUBBLE = new Place () { // vala-lint=naming-convention + + icon = "tuba-fish-symbolic", + title = "Bubble", // NOTE: Leave untranslated for now + open_func = (win) => { + win.open_view (set_as_sidebar_item (new Views.Bubble ())); + }, + visible = false + }; + public static Place PLACE_FEDERATED = new Place () { // vala-lint=naming-convention icon = "tuba-globe-symbolic", @@ -150,10 +160,15 @@ public class Tuba.Mastodon.Account : InstanceAccount { PLACE_EXPLORE, PLACE_LOCAL, + PLACE_BUBBLE, PLACE_FEDERATED, PLACE_LISTS }; + protected override void bump_sidebar_items () { + PLACE_BUBBLE.visible = this.instance_info != null && this.instance_info.supports_bubble; + } + public override void register_known_places (GLib.ListStore places) { app.bind_property ("is-mobile", PLACE_NOTIFICATIONS, "visible", GLib.BindingFlags.SYNC_CREATE | GLib.BindingFlags.INVERT_BOOLEAN); app.bind_property ("is-mobile", PLACE_CONVERSATIONS, "visible", GLib.BindingFlags.SYNC_CREATE | GLib.BindingFlags.INVERT_BOOLEAN); diff --git a/src/Views/Bubble.vala b/src/Views/Bubble.vala new file mode 100644 index 000000000..fbb6b2517 --- /dev/null +++ b/src/Views/Bubble.vala @@ -0,0 +1,8 @@ +public class Tuba.Views.Bubble : Views.Timeline { + construct { + url = "/api/v1/timelines/bubble"; + label = "Bubble"; // NOTE: Leave untranslated for now + icon = "tuba-fish-symbolic"; + is_public = true; + } +} diff --git a/src/Views/Sidebar.vala b/src/Views/Sidebar.vala index 7f093a057..c9f7ad866 100644 --- a/src/Views/Sidebar.vala +++ b/src/Views/Sidebar.vala @@ -198,13 +198,14 @@ public class Tuba.Views.Sidebar : Gtk.Widget, AccountHolder { // Item [GtkTemplate (ui = "/dev/geopjr/Tuba/ui/views/sidebar/item.ui")] protected class ItemRow : Gtk.ListBoxRow { - public Place place; + public Place place {get; set;} [GtkChild] unowned Gtk.Image icon; [GtkChild] unowned Gtk.Label label; [GtkChild] unowned Gtk.Label badge; public ItemRow (Place place) { + this.notify["visible"].connect (on_visibility_changed); this.place = place; place.bind_property ("title", label, "label", BindingFlags.SYNC_CREATE); place.bind_property ("icon", icon, "icon-name", BindingFlags.SYNC_CREATE); @@ -220,6 +221,12 @@ public class Tuba.Views.Sidebar : Gtk.Widget, AccountHolder { on_attention_change (); } + // ListBox's bind_model sets visibility of every row to true + // when the model changes. Let's do some hacking around it. + void on_visibility_changed () { + if (this.visible != this.place.visible) this.visible = this.place.visible; + } + void on_attention_change () { if (this.place.needs_attention) { badge.remove_css_class ("no-attention"); @@ -256,7 +263,6 @@ public class Tuba.Views.Sidebar : Gtk.Widget, AccountHolder { } } - void view_announcements_cb () { app.open_announcements (); } diff --git a/src/Views/meson.build b/src/Views/meson.build index c580cd307..4872191f5 100644 --- a/src/Views/meson.build +++ b/src/Views/meson.build @@ -3,6 +3,7 @@ sources += files( 'Announcements.vala', 'Base.vala', 'Bookmarks.vala', + 'Bubble.vala', 'ContentBase.vala', 'Conversations.vala', 'DraftStatuses.vala',