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 hammond_data::utils::checkup;
use hammond_data::Source;
use hammond_data::{Podcast, Source};
use headerbar::Header;
use content::Content;
use utils;
use std::sync::Arc;
use std::time::Duration;
use std::sync::mpsc::{channel, Receiver, Sender};
#[derive(Clone, Debug)]
@ -23,7 +24,10 @@ pub enum Action {
RefreshShowsView,
RefreshWidget,
RefreshWidgetIfVis,
ReplaceWidget(Podcast),
RefreshWidgetIfSame(i32),
ShowWidgetAnimated,
ShowShowsAnimated,
HeaderBarShowTile(String),
HeaderBarNormal,
HeaderBarHideUpdateIndicator,
@ -132,8 +136,8 @@ impl App {
let headerbar = self.header.clone();
let sender = self.sender.clone();
let receiver = self.receiver;
gtk::timeout_add(250, move || {
match receiver.try_recv() {
gtk::idle_add(move || {
match receiver.recv_timeout(Duration::from_millis(10)) {
Ok(Action::UpdateSources(source)) => {
if let Some(s) = source {
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::RefreshEpisodesView) => content.update_episode_view(),
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::HeaderBarNormal) => headerbar.switch_to_normal(),
Ok(Action::HeaderBarHideUpdateIndicator) => headerbar.hide_update_notification(),

View File

@ -26,8 +26,8 @@ pub struct Content {
impl Content {
pub fn new(sender: Sender<Action>) -> Arc<Content> {
let stack = gtk::Stack::new();
let episodes = EpisodeStack::new(sender.clone());
let shows = ShowStack::new(sender.clone());
let episodes = Arc::new(EpisodeStack::new(sender.clone()));
let shows = Arc::new(ShowStack::new(sender.clone()));
stack.add_titled(&episodes.stack, "episodes", "Episodes");
stack.add_titled(&shows.stack, "shows", "Shows");
@ -92,15 +92,15 @@ pub struct ShowStack {
}
impl ShowStack {
fn new(sender: Sender<Action>) -> Arc<ShowStack> {
fn new(sender: Sender<Action>) -> ShowStack {
let stack = gtk::Stack::new();
let show = Arc::new(ShowStack {
let show = ShowStack {
stack,
sender: sender.clone(),
});
};
let pop = ShowsPopulated::new(show.clone(), sender.clone());
let pop = ShowsPopulated::new(sender.clone());
let widget = ShowWidget::default();
let empty = EmptyView::new();
@ -144,7 +144,7 @@ impl ShowStack {
.unwrap();
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.
scrolled_window
.get_vadjustment()
@ -174,7 +174,7 @@ impl ShowStack {
.unwrap();
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
// name. It's a hack since we can't yet subclass GObject easily.
let oldid = WidgetExt::get_name(&old);
@ -253,7 +253,7 @@ pub struct EpisodeStack {
}
impl EpisodeStack {
fn new(sender: Sender<Action>) -> Arc<EpisodeStack> {
fn new(sender: Sender<Action>) -> EpisodeStack {
let episodes = EpisodesView::new(sender.clone());
let empty = EmptyView::new();
let stack = gtk::Stack::new();
@ -267,7 +267,7 @@ impl EpisodeStack {
stack.set_visible_child_name("episodes");
}
Arc::new(EpisodeStack { stack, sender })
EpisodeStack { stack, sender }
}
pub fn update(&self) {

View File

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

View File

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