From a294dab70cff3506f8b847d09f78c40a2553d513 Mon Sep 17 00:00:00 2001 From: Schmiddiii Date: Sun, 13 Nov 2022 11:05:47 +0100 Subject: [PATCH] :lipstick: Add status pages (#107) * :lipstick: Add status pages * Fix spelling Co-authored-by: Hari Rana Co-authored-by: Hari Rana --- data/resources/ui/feed_page.ui | 20 +++++++++++++ data/resources/ui/filter_page.ui | 20 +++++++++++++ data/resources/ui/subscription_page.ui | 20 +++++++++++++ data/resources/ui/watch_later.ui | 20 +++++++++++++ src/gui/feed/feed_list.rs | 27 +++++++++++++----- src/gui/filter/filter_list.rs | 33 ++++++++++++++++++++++ src/gui/filter/filter_page.rs | 2 ++ src/gui/subscription/subscription_list.rs | 34 ++++++++++++++++++++++- src/gui/subscription/subscription_page.rs | 2 ++ src/gui/watch_later.rs | 2 ++ 10 files changed, 172 insertions(+), 8 deletions(-) diff --git a/data/resources/ui/feed_page.ui b/data/resources/ui/feed_page.ui index ecc30a5..0b0ef98 100644 --- a/data/resources/ui/feed_page.ui +++ b/data/resources/ui/feed_page.ui @@ -54,6 +54,26 @@ + + + + feed_list + + + + + + + + No Videos Found + Are you subscribed to channels? + go-home-symbolic + True + + + feed_list + + diff --git a/data/resources/ui/filter_page.ui b/data/resources/ui/filter_page.ui index 4573d16..2d85ed6 100644 --- a/data/resources/ui/filter_page.ui +++ b/data/resources/ui/filter_page.ui @@ -57,6 +57,26 @@ + + + + filter_list + + + + + + + + No Filters + How about adding some filters? + funnel-symbolic + True + + + filter_list + + diff --git a/data/resources/ui/subscription_page.ui b/data/resources/ui/subscription_page.ui index 47dd372..1d2fb91 100644 --- a/data/resources/ui/subscription_page.ui +++ b/data/resources/ui/subscription_page.ui @@ -81,6 +81,26 @@ + + + + subscription_list + + + + + + + + No Subscriptions + How about subscribing to some channels? + library-artists-symbolic + True + + + subscription_list + + diff --git a/data/resources/ui/watch_later.ui b/data/resources/ui/watch_later.ui index 6a4e73d..945d559 100644 --- a/data/resources/ui/watch_later.ui +++ b/data/resources/ui/watch_later.ui @@ -18,6 +18,26 @@ + + + + feed_page + + + + + + + + Everything Watched + How about going outside? + alarm-symbolic + True + + + feed_page + + diff --git a/src/gui/feed/feed_list.rs b/src/gui/feed/feed_list.rs index e639f43..e29fde8 100644 --- a/src/gui/feed/feed_list.rs +++ b/src/gui/feed/feed_list.rs @@ -77,6 +77,7 @@ impl FeedList { let _ = self.activate_action("feed.more", None); self.set_more_available(); + self.notify("is-empty"); } pub fn prepend(&self, new_item: VideoObject) { @@ -90,6 +91,7 @@ impl FeedList { loaded_count.set(loaded_count.get() + 1); self.set_more_available(); + self.notify("is-empty"); } pub fn remove(&self, new_item: VideoObject) { @@ -111,6 +113,7 @@ impl FeedList { } self.set_more_available(); + self.notify("is-empty"); } pub fn set_playlist_manager(&self, playlist_manager: PlaylistManager) { @@ -228,13 +231,22 @@ pub mod imp { fn properties() -> &'static [ParamSpec] { static PROPERTIES: Lazy> = Lazy::new(|| { - vec![ParamSpecBoolean::new( - "more-available", - "more-available", - "more-available", - false, - ParamFlags::READWRITE, - )] + vec![ + ParamSpecBoolean::new( + "more-available", + "more-available", + "more-available", + false, + ParamFlags::READWRITE, + ), + ParamSpecBoolean::new( + "is-empty", + "is-empty", + "is-empty", + false, + ParamFlags::READABLE, + ), + ] }); PROPERTIES.as_ref() } @@ -254,6 +266,7 @@ pub mod imp { fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value { match pspec.name() { "more-available" => self.more_available.get().to_value(), + "is-empty" => (self.model.borrow().n_items() == 0).to_value(), _ => unimplemented!(), } } diff --git a/src/gui/filter/filter_list.rs b/src/gui/filter/filter_list.rs index 41e4afa..30b2be2 100644 --- a/src/gui/filter/filter_list.rs +++ b/src/gui/filter/filter_list.rs @@ -24,6 +24,7 @@ use gdk::{ prelude::{Cast, ListModelExtManual}, subclass::prelude::ObjectSubclassIsExt, }; +use gdk_pixbuf::prelude::ObjectExt; use tf_filter::FilterGroup; use tf_join::AnyVideoFilter; @@ -43,6 +44,7 @@ impl FilterList { model.remove_all(); model.splice(0, 0, &items); + self.notify("is-empty"); } pub fn add(&self, new_item: FilterObject) { @@ -50,6 +52,7 @@ impl FilterList { let model = &imp.model; model.borrow_mut().insert(0, &new_item); + self.notify("is-empty"); } pub fn remove(&self, new_item: FilterObject) { @@ -64,6 +67,7 @@ impl FilterList { }) { model.remove(idx as u32); } + self.notify("is-empty"); } pub fn set_filter_group(&self, filter_group: Arc>>) { @@ -82,6 +86,10 @@ pub mod imp { use gdk::glib::MainContext; use gdk::glib::Sender; use gdk::glib::PRIORITY_DEFAULT; + use gdk_pixbuf::glib::ParamFlags; + use gdk_pixbuf::glib::ParamSpec; + use gdk_pixbuf::glib::ParamSpecBoolean; + use gdk_pixbuf::glib::Value; use glib::subclass::InitializingObject; use gtk::glib; use gtk::prelude::*; @@ -90,6 +98,7 @@ pub mod imp { use gtk::Widget; use gtk::CompositeTemplate; + use once_cell::sync::Lazy; use tf_filter::FilterEvent; use tf_filter::FilterGroup; use tf_join::AnyVideoFilter; @@ -200,6 +209,30 @@ pub mod imp { fn constructed(&self, obj: &Self::Type) { self.parent_constructed(obj); } + + fn properties() -> &'static [ParamSpec] { + static PROPERTIES: Lazy> = Lazy::new(|| { + vec![ParamSpecBoolean::new( + "is-empty", + "is-empty", + "is-empty", + false, + ParamFlags::READABLE, + )] + }); + PROPERTIES.as_ref() + } + + fn set_property(&self, _obj: &Self::Type, _id: usize, _value: &Value, _pspec: &ParamSpec) { + unimplemented!() + } + + fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value { + match pspec.name() { + "is-empty" => (self.model.borrow().n_items() == 0).to_value(), + _ => unimplemented!(), + } + } } impl WidgetImpl for FilterList {} diff --git a/src/gui/filter/filter_page.rs b/src/gui/filter/filter_page.rs index 73b12f4..98bd600 100644 --- a/src/gui/filter/filter_page.rs +++ b/src/gui/filter/filter_page.rs @@ -61,6 +61,7 @@ pub mod imp { use tf_join::AnyVideoFilter; use crate::gui::filter::filter_list::FilterList; + use crate::gui::utility::Utility; #[derive(CompositeTemplate, Default)] #[template(resource = "/ui/filter_page.ui")] @@ -140,6 +141,7 @@ pub mod imp { fn class_init(klass: &mut Self::Class) { Self::bind_template(klass); + Utility::bind_template_callbacks(klass); } fn instance_init(obj: &InitializingObject) { diff --git a/src/gui/subscription/subscription_list.rs b/src/gui/subscription/subscription_list.rs index 5a1d213..00799c8 100644 --- a/src/gui/subscription/subscription_list.rs +++ b/src/gui/subscription/subscription_list.rs @@ -22,6 +22,7 @@ use gdk::{ prelude::{Cast, ListModelExtManual}, subclass::prelude::ObjectSubclassIsExt, }; +use gdk_pixbuf::prelude::ObjectExt; use gtk::{traits::SorterExt, SorterChange}; use tf_join::{AnySubscription, AnySubscriptionList}; @@ -41,6 +42,7 @@ impl SubscriptionList { model.remove_all(); model.splice(0, 0, &items); + self.notify("is-empty"); } pub fn add(&self, new_item: SubscriptionObject) { @@ -53,7 +55,8 @@ impl SubscriptionList { .borrow() .as_ref() .expect("`Sorter` to be set up") - .changed(SorterChange::Different) + .changed(SorterChange::Different); + self.notify("is-empty"); } pub fn remove(&self, new_item: SubscriptionObject) { @@ -68,6 +71,7 @@ impl SubscriptionList { }) { model.remove(idx as u32); } + self.notify("is-empty"); } pub fn update(&self, sub: AnySubscription) { @@ -104,6 +108,10 @@ pub mod imp { use gdk::glib::Sender; use gdk::glib::PRIORITY_DEFAULT; use gdk_pixbuf::glib::subclass::Signal; + use gdk_pixbuf::glib::ParamFlags; + use gdk_pixbuf::glib::ParamSpec; + use gdk_pixbuf::glib::ParamSpecBoolean; + use gdk_pixbuf::glib::Value; use glib::subclass::InitializingObject; use gtk::glib; use gtk::prelude::*; @@ -275,6 +283,30 @@ pub mod imp { self.parent_constructed(obj); } + fn properties() -> &'static [ParamSpec] { + static PROPERTIES: Lazy> = Lazy::new(|| { + vec![ParamSpecBoolean::new( + "is-empty", + "is-empty", + "is-empty", + false, + ParamFlags::READABLE, + )] + }); + PROPERTIES.as_ref() + } + + fn set_property(&self, _obj: &Self::Type, _id: usize, _value: &Value, _pspec: &ParamSpec) { + unimplemented!() + } + + fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value { + match pspec.name() { + "is-empty" => (self.model.borrow().n_items() == 0).to_value(), + _ => unimplemented!(), + } + } + fn signals() -> &'static [Signal] { static SIGNALS: Lazy> = Lazy::new(|| { vec![Signal::builder( diff --git a/src/gui/subscription/subscription_page.rs b/src/gui/subscription/subscription_page.rs index 7dad7f9..50a20b8 100644 --- a/src/gui/subscription/subscription_page.rs +++ b/src/gui/subscription/subscription_page.rs @@ -83,6 +83,7 @@ pub mod imp { use crate::gui::subscription::platform::PlatformObject; use crate::gui::subscription::subscription_item_object::SubscriptionObject; use crate::gui::subscription::subscription_list::SubscriptionList; + use crate::gui::utility::Utility; #[derive(CompositeTemplate, Default)] #[template(resource = "/ui/subscription_page.ui")] @@ -257,6 +258,7 @@ pub mod imp { fn class_init(klass: &mut Self::Class) { Self::bind_template(klass); Self::bind_template_callbacks(klass); + Utility::bind_template_callbacks(klass); } fn instance_init(obj: &InitializingObject) { diff --git a/src/gui/watch_later.rs b/src/gui/watch_later.rs index 86a8723..7709569 100644 --- a/src/gui/watch_later.rs +++ b/src/gui/watch_later.rs @@ -58,6 +58,7 @@ pub mod imp { use crate::gui::feed::feed_item_object::VideoObject; use crate::gui::feed::feed_list::FeedList; + use crate::gui::utility::Utility; #[derive(CompositeTemplate, Default)] #[template(resource = "/ui/watch_later.ui")] @@ -127,6 +128,7 @@ pub mod imp { fn class_init(klass: &mut Self::Class) { Self::bind_template(klass); + Utility::bind_template_callbacks(klass); } fn instance_init(obj: &InitializingObject) {