Migrate StackSwitch actions to use the AppAction channel.

This commit is contained in:
Jordan Petridis 2018-01-11 01:14:54 +02:00
parent 8a90de3c0e
commit 95ff3715a3
No known key found for this signature in database
GPG Key ID: CEABAD9F5683B9A6
4 changed files with 39 additions and 40 deletions

View File

@ -5,13 +5,14 @@ use gtk::prelude::*;
use gio::{ActionMapExt, ApplicationExt, ApplicationExtManual, SimpleActionExt}; use gio::{ActionMapExt, ApplicationExt, ApplicationExtManual, SimpleActionExt};
use hammond_data::utils::checkup; use hammond_data::utils::checkup;
use hammond_data::Source; use hammond_data::{Podcast, Source};
use headerbar::Header; use headerbar::Header;
use content::Content; use content::Content;
use utils; use utils;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration;
use std::sync::mpsc::{channel, Receiver, Sender}; use std::sync::mpsc::{channel, Receiver, Sender};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -23,7 +24,10 @@ pub enum Action {
RefreshShowsView, RefreshShowsView,
RefreshWidget, RefreshWidget,
RefreshWidgetIfVis, RefreshWidgetIfVis,
ReplaceWidget(Podcast),
RefreshWidgetIfSame(i32), RefreshWidgetIfSame(i32),
ShowWidgetAnimated,
ShowShowsAnimated,
HeaderBarShowTile(String), HeaderBarShowTile(String),
HeaderBarNormal, HeaderBarNormal,
HeaderBarHideUpdateIndicator, HeaderBarHideUpdateIndicator,
@ -132,8 +136,8 @@ impl App {
let headerbar = self.header.clone(); let headerbar = self.header.clone();
let sender = self.sender.clone(); let sender = self.sender.clone();
let receiver = self.receiver; let receiver = self.receiver;
gtk::timeout_add(250, move || { gtk::idle_add(move || {
match receiver.try_recv() { match receiver.recv_timeout(Duration::from_millis(10)) {
Ok(Action::UpdateSources(source)) => { Ok(Action::UpdateSources(source)) => {
if let Some(s) = source { if let Some(s) = source {
utils::refresh_feed(headerbar.clone(), Some(vec![s]), sender.clone()) utils::refresh_feed(headerbar.clone(), Some(vec![s]), sender.clone())
@ -146,6 +150,9 @@ impl App {
Ok(Action::RefreshWidgetIfSame(id)) => content.update_widget_if_same(id), Ok(Action::RefreshWidgetIfSame(id)) => content.update_widget_if_same(id),
Ok(Action::RefreshEpisodesView) => content.update_episode_view(), Ok(Action::RefreshEpisodesView) => content.update_episode_view(),
Ok(Action::RefreshEpisodesViewBGR) => content.update_episode_view_if_baground(), Ok(Action::RefreshEpisodesViewBGR) => content.update_episode_view_if_baground(),
Ok(Action::ReplaceWidget(ref pd)) => content.get_shows().replace_widget(pd),
Ok(Action::ShowWidgetAnimated) => content.get_shows().switch_widget_animated(),
Ok(Action::ShowShowsAnimated) => content.get_shows().switch_podcasts_animated(),
Ok(Action::HeaderBarShowTile(title)) => headerbar.switch_to_back(&title), Ok(Action::HeaderBarShowTile(title)) => headerbar.switch_to_back(&title),
Ok(Action::HeaderBarNormal) => headerbar.switch_to_normal(), Ok(Action::HeaderBarNormal) => headerbar.switch_to_normal(),
Ok(Action::HeaderBarHideUpdateIndicator) => headerbar.hide_update_notification(), Ok(Action::HeaderBarHideUpdateIndicator) => headerbar.hide_update_notification(),

View File

@ -26,8 +26,8 @@ pub struct Content {
impl Content { impl Content {
pub fn new(sender: Sender<Action>) -> Arc<Content> { pub fn new(sender: Sender<Action>) -> Arc<Content> {
let stack = gtk::Stack::new(); let stack = gtk::Stack::new();
let episodes = EpisodeStack::new(sender.clone()); let episodes = Arc::new(EpisodeStack::new(sender.clone()));
let shows = ShowStack::new(sender.clone()); let shows = Arc::new(ShowStack::new(sender.clone()));
stack.add_titled(&episodes.stack, "episodes", "Episodes"); stack.add_titled(&episodes.stack, "episodes", "Episodes");
stack.add_titled(&shows.stack, "shows", "Shows"); stack.add_titled(&shows.stack, "shows", "Shows");
@ -92,15 +92,15 @@ pub struct ShowStack {
} }
impl ShowStack { impl ShowStack {
fn new(sender: Sender<Action>) -> Arc<ShowStack> { fn new(sender: Sender<Action>) -> ShowStack {
let stack = gtk::Stack::new(); let stack = gtk::Stack::new();
let show = Arc::new(ShowStack { let show = ShowStack {
stack, stack,
sender: sender.clone(), sender: sender.clone(),
}); };
let pop = ShowsPopulated::new(show.clone(), sender.clone()); let pop = ShowsPopulated::new(sender.clone());
let widget = ShowWidget::default(); let widget = ShowWidget::default();
let empty = EmptyView::new(); let empty = EmptyView::new();
@ -144,7 +144,7 @@ impl ShowStack {
.unwrap(); .unwrap();
debug!("Name: {:?}", WidgetExt::get_name(&scrolled_window)); debug!("Name: {:?}", WidgetExt::get_name(&scrolled_window));
let pop = ShowsPopulated::new(Arc::new(self.clone()), self.sender.clone()); let pop = ShowsPopulated::new(self.sender.clone());
// Copy the vertical scrollbar adjustment from the old view into the new one. // Copy the vertical scrollbar adjustment from the old view into the new one.
scrolled_window scrolled_window
.get_vadjustment() .get_vadjustment()
@ -174,7 +174,7 @@ impl ShowStack {
.unwrap(); .unwrap();
debug!("Name: {:?}", WidgetExt::get_name(&old)); debug!("Name: {:?}", WidgetExt::get_name(&old));
let new = ShowWidget::new(Arc::new(self.clone()), pd, self.sender.clone()); let new = ShowWidget::new(pd, self.sender.clone());
// Each composite ShowWidget is a gtkBox with the Podcast.id encoded in the gtk::Widget // Each composite ShowWidget is a gtkBox with the Podcast.id encoded in the gtk::Widget
// name. It's a hack since we can't yet subclass GObject easily. // name. It's a hack since we can't yet subclass GObject easily.
let oldid = WidgetExt::get_name(&old); let oldid = WidgetExt::get_name(&old);
@ -253,7 +253,7 @@ pub struct EpisodeStack {
} }
impl EpisodeStack { impl EpisodeStack {
fn new(sender: Sender<Action>) -> Arc<EpisodeStack> { fn new(sender: Sender<Action>) -> EpisodeStack {
let episodes = EpisodesView::new(sender.clone()); let episodes = EpisodesView::new(sender.clone());
let empty = EmptyView::new(); let empty = EmptyView::new();
let stack = gtk::Stack::new(); let stack = gtk::Stack::new();
@ -267,7 +267,7 @@ impl EpisodeStack {
stack.set_visible_child_name("episodes"); stack.set_visible_child_name("episodes");
} }
Arc::new(EpisodeStack { stack, sender }) EpisodeStack { stack, sender }
} }
pub fn update(&self) { pub fn update(&self) {

View File

@ -6,11 +6,9 @@ use hammond_data::dbqueries;
use hammond_data::Podcast; use hammond_data::Podcast;
use utils::get_pixbuf_from_path; use utils::get_pixbuf_from_path;
use content::ShowStack;
use app::Action; use app::Action;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use std::sync::Arc;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ShowsPopulated { pub struct ShowsPopulated {
@ -35,26 +33,27 @@ impl Default for ShowsPopulated {
} }
impl ShowsPopulated { impl ShowsPopulated {
pub fn new(show: Arc<ShowStack>, sender: Sender<Action>) -> ShowsPopulated { pub fn new(sender: Sender<Action>) -> ShowsPopulated {
let pop = ShowsPopulated::default(); let pop = ShowsPopulated::default();
pop.init(show, sender); pop.init(sender);
pop pop
} }
pub fn init(&self, show: Arc<ShowStack>, sender: Sender<Action>) { pub fn init(&self, sender: Sender<Action>) {
use gtk::WidgetExt; use gtk::WidgetExt;
// TODO: handle unwraps. // TODO: handle unwraps.
self.flowbox self.flowbox.connect_child_activated(move |_, child| {
.connect_child_activated(clone!(show, sender => move |_, child| {
// This is such an ugly hack... // This is such an ugly hack...
let id = WidgetExt::get_name(child).unwrap().parse::<i32>().unwrap(); let id = WidgetExt::get_name(child).unwrap().parse::<i32>().unwrap();
let pd = dbqueries::get_podcast_from_id(id).unwrap(); let pd = dbqueries::get_podcast_from_id(id).unwrap();
show.replace_widget(&pd); sender
sender.send(Action::HeaderBarShowTile(pd.title().into())).unwrap(); .send(Action::HeaderBarShowTile(pd.title().into()))
show.switch_widget_animated(); .unwrap();
})); sender.send(Action::ReplaceWidget(pd)).unwrap();
sender.send(Action::ShowWidgetAnimated).unwrap();
});
// Populate the flowbox with the Podcasts. // Populate the flowbox with the Podcasts.
self.populate_flowbox(); self.populate_flowbox();
} }

View File

@ -10,11 +10,9 @@ use hammond_data::utils::{delete_show, replace_extra_spaces};
use widgets::episode::episodes_listbox; use widgets::episode::episodes_listbox;
use utils::get_pixbuf_from_path; use utils::get_pixbuf_from_path;
use content::ShowStack;
use app::Action; use app::Action;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use std::sync::Arc;
use std::thread; use std::thread;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -56,19 +54,19 @@ impl Default for ShowWidget {
} }
impl ShowWidget { impl ShowWidget {
pub fn new(shows: Arc<ShowStack>, pd: &Podcast, sender: Sender<Action>) -> ShowWidget { pub fn new(pd: &Podcast, sender: Sender<Action>) -> ShowWidget {
let pdw = ShowWidget::default(); let pdw = ShowWidget::default();
pdw.init(shows, pd, sender); pdw.init(pd, sender);
pdw pdw
} }
pub fn init(&self, shows: Arc<ShowStack>, pd: &Podcast, sender: Sender<Action>) { pub fn init(&self, pd: &Podcast, sender: Sender<Action>) {
// Hacky workaround so the pd.id() can be retrieved from the `ShowStack`. // Hacky workaround so the pd.id() can be retrieved from the `ShowStack`.
WidgetExt::set_name(&self.container, &pd.id().to_string()); WidgetExt::set_name(&self.container, &pd.id().to_string());
self.unsub self.unsub
.connect_clicked(clone!(shows, pd, sender => move |bttn| { .connect_clicked(clone!(pd, sender => move |bttn| {
on_unsub_button_clicked(shows.clone(), &pd, bttn, sender.clone()); on_unsub_button_clicked(&pd, bttn, sender.clone());
})); }));
self.setup_listbox(pd, sender.clone()); self.setup_listbox(pd, sender.clone());
@ -110,12 +108,7 @@ impl ShowWidget {
} }
} }
fn on_unsub_button_clicked( fn on_unsub_button_clicked(pd: &Podcast, unsub_button: &gtk::Button, sender: Sender<Action>) {
shows: Arc<ShowStack>,
pd: &Podcast,
unsub_button: &gtk::Button,
sender: Sender<Action>,
) {
// hack to get away without properly checking for none. // hack to get away without properly checking for none.
// if pressed twice would panic. // if pressed twice would panic.
unsub_button.hide(); unsub_button.hide();
@ -126,16 +119,16 @@ fn on_unsub_button_clicked(
error!("Error: {}", err); error!("Error: {}", err);
} }
})); }));
shows.switch_podcasts_animated();
sender.send(Action::HeaderBarNormal).unwrap(); sender.send(Action::HeaderBarNormal).unwrap();
sender.send(Action::ShowShowsAnimated).unwrap();
// Queue a refresh after the switch to avoid blocking the db. // Queue a refresh after the switch to avoid blocking the db.
sender.send(Action::RefreshShowsView).unwrap(); sender.send(Action::RefreshShowsView).unwrap();
sender.send(Action::RefreshEpisodesView).unwrap(); sender.send(Action::RefreshEpisodesView).unwrap();
} }
#[allow(dead_code)] #[allow(dead_code)]
fn on_played_button_clicked(shows: Arc<ShowStack>, pd: &Podcast) { fn on_played_button_clicked(pd: &Podcast, sender: Sender<Action>) {
let _ = dbqueries::update_none_to_played_now(pd); let _ = dbqueries::update_none_to_played_now(pd);
shows.update_widget(); sender.send(Action::RefreshWidget).unwrap();
} }