From 0e4430bae40ef996727512cac8296fb3724f538c Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 19 Apr 2018 02:52:58 +0300 Subject: [PATCH] EpisodeView: Initial refactor to make loading non-blocking. --- hammond-data/src/dbqueries.rs | 14 +++++ hammond-gtk/src/stacks/episode.rs | 49 ++++++++--------- hammond-gtk/src/views/episodes.rs | 88 ++++++++++++------------------- 3 files changed, 74 insertions(+), 77 deletions(-) diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index 6e8bb74..372dad5 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -349,6 +349,20 @@ pub(crate) fn episode_exists(title_: &str, podcast_id_: i32) -> Result Result { + use schema::episode::dsl::*; + + let db = connection(); + let con = db.get()?; + + select(exists(episode.count())) + .get_result(&con) + .map_err(From::from) +} + pub(crate) fn index_new_episodes(eps: &[NewEpisode]) -> Result<(), DataError> { use schema::episode::dsl::*; let db = connection(); diff --git a/hammond-gtk/src/stacks/episode.rs b/hammond-gtk/src/stacks/episode.rs index b1bd89a..9080032 100644 --- a/hammond-gtk/src/stacks/episode.rs +++ b/hammond-gtk/src/stacks/episode.rs @@ -3,10 +3,11 @@ use gtk::prelude::*; use gtk::Cast; use failure::Error; - -use views::{EmptyView, EpisodesView}; +use hammond_data::dbqueries::is_episodes_populated; +use hammond_data::errors::DataError; use app::Action; +use views::{EmptyView, EpisodesView}; use std::sync::mpsc::Sender; @@ -24,12 +25,7 @@ impl EpisodeStack { stack.add_named(&episodes.container, "episodes"); stack.add_named(&empty.container, "empty"); - - if episodes.is_empty() { - stack.set_visible_child_name("empty"); - } else { - stack.set_visible_child_name("episodes"); - } + set_stack_visible(&stack)?; Ok(EpisodeStack { stack, sender }) } @@ -43,28 +39,23 @@ impl EpisodeStack { .map_err(|_| format_err!("Failed to downcast stack child to a Box."))?; debug!("Name: {:?}", WidgetExt::get_name(&old)); - let scrolled_window = old.get_children() - .first() - .ok_or_else(|| format_err!("Box container has no childs."))? - .clone() - .downcast::() - .map_err(|_| format_err!("Failed to downcast stack child to a ScrolledWindow."))?; - debug!("Name: {:?}", WidgetExt::get_name(&scrolled_window)); + // let scrolled_window = old.get_children() + // .first() + // .ok_or_else(|| format_err!("Box container has no childs."))? + // .clone() + // .downcast::() + // .map_err(|_| format_err!("Failed to downcast stack child to a ScrolledWindow."))?; + // debug!("Name: {:?}", WidgetExt::get_name(&scrolled_window)); let eps = EpisodesView::new(self.sender.clone())?; // Copy the vertical scrollbar adjustment from the old view into the new one. - scrolled_window - .get_vadjustment() - .map(|x| eps.set_vadjustment(&x)); + // scrolled_window + // .get_vadjustment() + // .map(|x| eps.set_vadjustment(&x)); self.stack.remove(&old); self.stack.add_named(&eps.container, "episodes"); - - if eps.is_empty() { - self.stack.set_visible_child_name("empty"); - } else { - self.stack.set_visible_child_name("episodes"); - } + set_stack_visible(&self.stack)?; old.destroy(); @@ -75,3 +66,13 @@ impl EpisodeStack { self.stack.clone() } } + +fn set_stack_visible(stack: >k::Stack) -> Result<(), DataError> { + if is_episodes_populated()? { + stack.set_visible_child_name("episodes"); + } else { + stack.set_visible_child_name("empty"); + }; + + Ok(()) +} diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index 1b44f76..6d0fcc2 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -7,9 +7,11 @@ use hammond_data::dbqueries; use hammond_data::EpisodeWidgetQuery; use app::Action; +use utils::lazy_load_full; use utils::{get_ignored_shows, set_image_from_path}; use widgets::EpisodeWidget; +use std::rc::Rc; use std::sync::mpsc::Sender; use std::sync::Arc; @@ -78,85 +80,65 @@ impl Default for EpisodesView { // TODO: REFACTOR ME impl EpisodesView { #[inline] - pub fn new(sender: Sender) -> Result { - let view = EpisodesView::default(); + pub fn new(sender: Sender) -> Result, Error> { + let view = Rc::new(EpisodesView::default()); let ignore = get_ignored_shows()?; - let episodes = dbqueries::get_episodes_widgets_filter_limit(&ignore, 50)?; + let episodes = dbqueries::get_episodes_widgets_filter_limit(&ignore, 200)?; let now_utc = Utc::now(); - episodes.into_iter().for_each(|ep| { + let view_ = view.clone(); + let func = move |ep: EpisodeWidgetQuery| { let epoch = ep.epoch(); let viewep = EpisodesViewWidget::new(ep, sender.clone()); let t = split(&now_utc, i64::from(epoch)); match t { ListSplit::Today => { - view.today_list.add(&viewep.container); + view_.today_list.add(&viewep.container); } ListSplit::Yday => { - view.yday_list.add(&viewep.container); + view_.yday_list.add(&viewep.container); } ListSplit::Week => { - view.week_list.add(&viewep.container); + view_.week_list.add(&viewep.container); } ListSplit::Month => { - view.month_list.add(&viewep.container); + view_.month_list.add(&viewep.container); } ListSplit::Rest => { - view.rest_list.add(&viewep.container); + view_.rest_list.add(&viewep.container); } } + }; + + let callback = clone!(view => move || { + if view.today_list.get_children().is_empty() { + view.today_box.hide(); + } + + if view.yday_list.get_children().is_empty() { + view.yday_box.hide(); + } + + if view.week_list.get_children().is_empty() { + view.week_box.hide(); + } + + if view.month_list.get_children().is_empty() { + view.month_box.hide(); + } + + if view.rest_list.get_children().is_empty() { + view.rest_box.hide(); + } }); - if view.today_list.get_children().is_empty() { - view.today_box.hide(); - } - - if view.yday_list.get_children().is_empty() { - view.yday_box.hide(); - } - - if view.week_list.get_children().is_empty() { - view.week_box.hide(); - } - - if view.month_list.get_children().is_empty() { - view.month_box.hide(); - } - - if view.rest_list.get_children().is_empty() { - view.rest_box.hide(); - } + lazy_load_full(episodes, func, callback); view.container.show_all(); Ok(view) } - #[inline] - pub fn is_empty(&self) -> bool { - if !self.today_list.get_children().is_empty() { - return false; - } - - if !self.yday_list.get_children().is_empty() { - return false; - } - - if !self.week_list.get_children().is_empty() { - return false; - } - - if !self.month_list.get_children().is_empty() { - return false; - } - - if !self.rest_list.get_children().is_empty() { - return false; - } - - true - } - #[inline] /// Set scrolled window vertical adjustment. pub fn set_vadjustment(&self, vadjustment: >k::Adjustment) {