EpisodeView: Initial refactor to make loading non-blocking.

This commit is contained in:
Jordan Petridis 2018-04-19 02:52:58 +03:00
parent f811a9c8f4
commit 0e4430bae4
No known key found for this signature in database
GPG Key ID: CEABAD9F5683B9A6
3 changed files with 74 additions and 77 deletions

View File

@ -349,6 +349,20 @@ pub(crate) fn episode_exists(title_: &str, podcast_id_: i32) -> Result<bool, Dat
.map_err(From::from)
}
/// Check `episode` table empty
///
/// Return true if `episode` table is populated.
pub fn is_episodes_populated() -> Result<bool, DataError> {
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();

View File

@ -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::<gtk::ScrolledWindow>()
.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::<gtk::ScrolledWindow>()
// .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: &gtk::Stack) -> Result<(), DataError> {
if is_episodes_populated()? {
stack.set_visible_child_name("episodes");
} else {
stack.set_visible_child_name("empty");
};
Ok(())
}

View File

@ -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<Action>) -> Result<EpisodesView, Error> {
let view = EpisodesView::default();
pub fn new(sender: Sender<Action>) -> Result<Rc<EpisodesView>, 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: &gtk::Adjustment) {