Refactor content state with Application actions

Instead of each view/widget determening if its populated on its own,
make add Application Actions and apply the state globally.
This commit is contained in:
Jordan Petridis 2018-08-19 13:44:11 +03:00
parent 79ac3b9700
commit 9f42e91088
No known key found for this signature in database
GPG Key ID: E8523968931763BE
5 changed files with 41 additions and 44 deletions

View File

@ -64,6 +64,8 @@ pub(crate) enum Action {
ErrorNotification(String), ErrorNotification(String),
InitEpisode(i32), InitEpisode(i32),
InitShowMenu(Fragile<ShowMenu>), InitShowMenu(Fragile<ShowMenu>),
EmptyState,
PopulatedState,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -347,6 +349,8 @@ impl App {
let menu = &s.get().container; let menu = &s.get().container;
self.headerbar.set_secondary_menu(menu); self.headerbar.set_secondary_menu(menu);
} }
Action::EmptyState => self.content.switch_to_empty_views(),
Action::PopulatedState => self.content.switch_to_populated(),
} }
} }

View File

@ -12,6 +12,12 @@ use std::rc::Rc;
use i18n::i18n; use i18n::i18n;
#[derive(Debug, Clone, Copy)]
pub(crate) enum State {
Populated,
Empty,
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct Content { pub(crate) struct Content {
stack: gtk::Stack, stack: gtk::Stack,
@ -88,4 +94,22 @@ impl Content {
pub(crate) fn get_shows(&self) -> Rc<RefCell<ShowStack>> { pub(crate) fn get_shows(&self) -> Rc<RefCell<ShowStack>> {
self.shows.clone() self.shows.clone()
} }
pub(crate) fn switch_to_empty_views(&self) {
use gtk::StackTransitionType::*;
self.home
.borrow_mut()
.switch_visible(State::Empty, Crossfade);
self.shows.borrow_mut().switch_visible(State::Empty);
}
pub(crate) fn switch_to_populated(&self) {
use gtk::StackTransitionType::*;
self.home
.borrow_mut()
.switch_visible(State::Populated, Crossfade);
self.shows.borrow_mut().switch_visible(State::Populated);
}
} }

View File

@ -4,21 +4,14 @@ use gtk::StackTransitionType;
use crossbeam_channel::Sender; use crossbeam_channel::Sender;
use failure::Error; use failure::Error;
use podcasts_data::dbqueries::is_episodes_populated;
use podcasts_data::errors::DataError;
use app::Action; use app::Action;
use stacks::State;
use widgets::{EmptyView, HomeView}; use widgets::{EmptyView, HomeView};
use std::ops::Deref; use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
#[derive(Debug, Clone, Copy)]
enum State {
Home,
Empty,
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct HomeStack { pub(crate) struct HomeStack {
empty: EmptyView, empty: EmptyView,
@ -38,7 +31,7 @@ impl HomeStack {
stack.add_named(episodes.view.container(), "home"); stack.add_named(episodes.view.container(), "home");
stack.add_named(empty.deref(), "empty"); stack.add_named(empty.deref(), "empty");
let mut home = HomeStack { let home = HomeStack {
empty, empty,
episodes, episodes,
stack, stack,
@ -46,7 +39,6 @@ impl HomeStack {
sender, sender,
}; };
home.determine_state()?;
Ok(home) Ok(home)
} }
@ -55,12 +47,6 @@ impl HomeStack {
} }
pub(crate) fn update(&mut self) -> Result<(), Error> { pub(crate) fn update(&mut self) -> Result<(), Error> {
self.replace_view()?;
// Determine the actual state.
self.determine_state().map_err(From::from)
}
fn replace_view(&mut self) -> Result<(), Error> {
// Get the container of the view // Get the container of the view
let old = &self.episodes.view.container().clone(); let old = &self.episodes.view.container().clone();
@ -88,13 +74,13 @@ impl HomeStack {
Ok(()) Ok(())
} }
fn switch_visible(&mut self, s: State, animation: StackTransitionType) { pub(crate) fn switch_visible(&mut self, s: State, animation: StackTransitionType) {
use self::State::*; use self::State::*;
match s { match s {
Home => { Populated => {
self.stack.set_visible_child_full("home", animation); self.stack.set_visible_child_full("home", animation);
self.state = Home; self.state = Populated;
} }
Empty => { Empty => {
self.stack.set_visible_child_full("empty", animation); self.stack.set_visible_child_full("empty", animation);
@ -102,14 +88,4 @@ impl HomeStack {
} }
} }
} }
fn determine_state(&mut self) -> Result<(), DataError> {
if is_episodes_populated()? {
self.switch_visible(State::Home, StackTransitionType::Crossfade);
} else {
self.switch_visible(State::Empty, StackTransitionType::Crossfade);
};
Ok(())
}
} }

View File

@ -3,7 +3,7 @@ mod home;
mod populated; mod populated;
mod show; mod show;
pub(crate) use self::content::Content; pub(crate) use self::content::{Content, State};
pub(crate) use self::home::HomeStack; pub(crate) use self::home::HomeStack;
pub(crate) use self::populated::{PopulatedStack, PopulatedState}; pub(crate) use self::populated::{PopulatedStack, PopulatedState};
pub(crate) use self::show::ShowStack; pub(crate) use self::show::ShowStack;

View File

@ -6,6 +6,7 @@ use failure::Error;
use podcasts_data::dbqueries::is_podcasts_populated; use podcasts_data::dbqueries::is_podcasts_populated;
use app::Action; use app::Action;
use stacks::content::State;
use stacks::PopulatedStack; use stacks::PopulatedStack;
use utils::get_ignored_shows; use utils::get_ignored_shows;
use widgets::EmptyView; use widgets::EmptyView;
@ -14,18 +15,12 @@ use std::cell::RefCell;
use std::ops::Deref; use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
#[derive(Debug, Clone, Copy)]
pub(crate) enum ShowState {
Populated,
Empty,
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct ShowStack { pub(crate) struct ShowStack {
empty: EmptyView, empty: EmptyView,
populated: Rc<RefCell<PopulatedStack>>, populated: Rc<RefCell<PopulatedStack>>,
stack: gtk::Stack, stack: gtk::Stack,
state: ShowState, state: State,
sender: Sender<Action>, sender: Sender<Action>,
} }
@ -34,7 +29,7 @@ impl ShowStack {
let populated = Rc::new(RefCell::new(PopulatedStack::new(sender.clone()))); let populated = Rc::new(RefCell::new(PopulatedStack::new(sender.clone())));
let empty = EmptyView::default(); let empty = EmptyView::default();
let stack = gtk::Stack::new(); let stack = gtk::Stack::new();
let state = ShowState::Empty; let state = State::Empty;
stack.add_named(&populated.borrow().container(), "populated"); stack.add_named(&populated.borrow().container(), "populated");
stack.add_named(empty.deref(), "empty"); stack.add_named(empty.deref(), "empty");
@ -65,8 +60,8 @@ impl ShowStack {
self.determine_state() self.determine_state()
} }
fn switch_visible(&mut self, s: ShowState) { pub(crate) fn switch_visible(&mut self, s: State) {
use self::ShowState::*; use self::State::*;
match s { match s {
Populated => { Populated => {
@ -81,14 +76,12 @@ impl ShowStack {
} }
fn determine_state(&mut self) -> Result<(), Error> { fn determine_state(&mut self) -> Result<(), Error> {
use self::ShowState::*;
let ign = get_ignored_shows()?; let ign = get_ignored_shows()?;
debug!("IGNORED SHOWS {:?}", ign); debug!("IGNORED SHOWS {:?}", ign);
if is_podcasts_populated(&ign)? { if is_podcasts_populated(&ign)? {
self.switch_visible(Populated); self.sender.send(Action::PopulatedState);
} else { } else {
self.switch_visible(Empty); self.sender.send(Action::EmptyState);
}; };
Ok(()) Ok(())