diff --git a/Cargo.lock b/Cargo.lock index 87313b4..492c3d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,13 +220,10 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.2.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -262,19 +259,6 @@ dependencies = [ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crossbeam-epoch" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "crossbeam-epoch" version = "0.7.1" @@ -304,11 +288,6 @@ dependencies = [ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crossbeam-utils" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "crossbeam-utils" version = "0.6.5" @@ -1417,15 +1396,6 @@ dependencies = [ "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "parking_lot" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "parking_lot" version = "0.7.1" @@ -1435,18 +1405,6 @@ dependencies = [ "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "parking_lot_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "parking_lot_core" version = "0.4.0" @@ -1557,7 +1515,7 @@ name = "podcasts-gtk" version = "0.1.0" dependencies = [ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "fragile 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1673,18 +1631,6 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rand" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rand" version = "0.6.5" @@ -2576,15 +2522,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "286e0b41c3a20da26536c6000a280585d519fd07b3956b43aed8a79e9edce980" "checksum core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "716c271e8613ace48344f723b60b900a93150271e5be206212d052bbc0883efa" "checksum crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192" -"checksum crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b85741761b7f160bc5e7e0c14986ef685b7f8bf9b7ad081c60c604bb4649827" +"checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" -"checksum crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2449aaa4ec7ef96e5fb24db16024b935df718e9ae1cec0a1e68feeca2efca7b8" "checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4" "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" -"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" "checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" "checksum ctor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9a43db2bba5cafdc6aa068c892a518e477ee0df3705e53ec70247a9ff93546d5" "checksum darling 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "52f20e669de9a5689aa54f3ca9ddc9e14ae5eef15028192bd2f7caf9376a0040" @@ -2698,9 +2642,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum pango 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4e36b55d7cd522bd183efeb3dfabc547bda1f26eadf8a1241dac09ab3fd3242c" "checksum pango-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "747ab9cd4d537e6dc5ef0e4308c10dde8b706673b0237fed4e056b8d2c0b23c8" -"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" -"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" @@ -2718,7 +2660,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" "checksum r2d2 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5d746fc8a0dab19ccea7ff73ad535854e90ddb3b4b8cdce953dd5cd0b2e7bd22" "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" diff --git a/podcasts-gtk/Cargo.toml b/podcasts-gtk/Cargo.toml index 09bcaca..787930b 100644 --- a/podcasts-gtk/Cargo.toml +++ b/podcasts-gtk/Cargo.toml @@ -6,7 +6,7 @@ version = "0.1.0" [dependencies] chrono = "0.4.6" -crossbeam-channel = "0.2.6" +crossbeam-channel = "0.3.8" gdk = "0.10.0" gdk-pixbuf = "0.6.0" glib = "0.7.1" diff --git a/podcasts-gtk/src/app.rs b/podcasts-gtk/src/app.rs index f539276..369fe6a 100644 --- a/podcasts-gtk/src/app.rs +++ b/podcasts-gtk/src/app.rs @@ -304,115 +304,125 @@ impl App { } fn setup_action_channel(&self) -> glib::Continue { - if let Some(action) = self.receiver.try_recv() { - trace!("Incoming channel action: {:?}", action); - match action { - Action::RefreshAllViews => self.content.update(), - Action::RefreshShowsView => self.content.update_shows_view(), - Action::RefreshWidgetIfSame(id) => self.content.update_widget_if_same(id), - Action::RefreshEpisodesView => self.content.update_home(), - Action::RefreshEpisodesViewBGR => self.content.update_home_if_background(), - Action::ReplaceWidget(pd) => { - let shows = self.content.get_shows(); - let mut pop = shows.borrow().populated(); - pop.borrow_mut() - .replace_widget(pd.clone()) - .map_err(|err| error!("Failed to update ShowWidget: {}", err)) - .map_err(|_| error!("Failed to update ShowWidget {}", pd.title())) - .ok(); - } - Action::ShowWidgetAnimated => { - let shows = self.content.get_shows(); - let mut pop = shows.borrow().populated(); - pop.borrow_mut().switch_visible( - PopulatedState::Widget, - gtk::StackTransitionType::SlideLeft, - ); - } - Action::ShowShowsAnimated => { - let shows = self.content.get_shows(); - let mut pop = shows.borrow().populated(); - pop.borrow_mut() - .switch_visible(PopulatedState::View, gtk::StackTransitionType::SlideRight); - } - Action::HeaderBarShowTile(title) => self.headerbar.switch_to_back(&title), - Action::HeaderBarNormal => self.headerbar.switch_to_normal(), - Action::MarkAllPlayerNotification(pd) => { - let notif = mark_all_notif(pd, &self.sender); - notif.show(&self.overlay); - } - Action::RemoveShow(pd) => { - let notif = remove_show_notif(pd, self.sender.clone()); - notif.show(&self.overlay); - } - Action::ErrorNotification(err) => { - error!("An error notification was triggered: {}", err); - let callback = |revealer: gtk::Revealer| { - revealer.set_reveal_child(false); - glib::Continue(false) - }; - let undo_cb: Option = None; - let notif = InAppNotification::new(&err, 6000, callback, undo_cb); - notif.show(&self.overlay); - } - Action::ShowUpdateNotif(receiver) => { - let sender = self.sender.clone(); - let callback = move |revealer: gtk::Revealer| { - if let Some(_) = receiver.try_recv() { - revealer.set_reveal_child(false); - sender.send(Action::RefreshAllViews); - return glib::Continue(false); - } + use crossbeam_channel::TryRecvError; - glib::Continue(true) - }; - let txt = i18n("Fetching new episodes"); - let undo_cb: Option = None; - let updater = InAppNotification::new(&txt, 250, callback, undo_cb); - updater.set_close_state(State::Hidden); - updater.set_spinner_state(SpinnerState::Active); - - let old = self.updater.replace(Some(updater)); - old.map(|i| i.destroy()); - self.updater - .borrow() - .as_ref() - .map(|i| i.show(&self.overlay)); - } - Action::InitEpisode(rowid) => { - let res = self.player.initialize_episode(rowid); - debug_assert!(res.is_ok()); - } - Action::InitShowMenu(s) => { - let menu = &s.get().container; - self.headerbar.set_secondary_menu(menu); - } - Action::EmptyState => { - self.window - .lookup_action("refresh") - .and_then(|action| action.downcast::().ok()) - // Disable refresh action - .map(|action| action.set_enabled(false)); - - self.headerbar.switch.set_sensitive(false); - self.content.switch_to_empty_views(); - } - Action::PopulatedState => { - self.window - .lookup_action("refresh") - .and_then(|action| action.downcast::().ok()) - // Enable refresh action - .map(|action| action.set_enabled(true)); - - self.headerbar.switch.set_sensitive(true); - self.content.switch_to_populated(); - } - // https://gitlab.gnome.org/GNOME/gtk/issues/624#note_109968 - Action::RaiseWindow => self - .window - .present_with_time((glib::get_monotonic_time() / 1000) as u32), + let action = match self.receiver.try_recv() { + Ok(a) => a, + Err(TryRecvError::Empty) => return glib::Continue(true), + Err(TryRecvError::Disconnected) => { + unreachable!("How the hell was the action channel dropped.") } - } + }; + + trace!("Incoming channel action: {:?}", action); + match action { + Action::RefreshAllViews => self.content.update(), + Action::RefreshShowsView => self.content.update_shows_view(), + Action::RefreshWidgetIfSame(id) => self.content.update_widget_if_same(id), + Action::RefreshEpisodesView => self.content.update_home(), + Action::RefreshEpisodesViewBGR => self.content.update_home_if_background(), + Action::ReplaceWidget(pd) => { + let shows = self.content.get_shows(); + let mut pop = shows.borrow().populated(); + pop.borrow_mut() + .replace_widget(pd.clone()) + .map_err(|err| error!("Failed to update ShowWidget: {}", err)) + .map_err(|_| error!("Failed to update ShowWidget {}", pd.title())) + .ok(); + } + Action::ShowWidgetAnimated => { + let shows = self.content.get_shows(); + let mut pop = shows.borrow().populated(); + pop.borrow_mut().switch_visible( + PopulatedState::Widget, + gtk::StackTransitionType::SlideLeft, + ); + } + Action::ShowShowsAnimated => { + let shows = self.content.get_shows(); + let mut pop = shows.borrow().populated(); + pop.borrow_mut() + .switch_visible(PopulatedState::View, gtk::StackTransitionType::SlideRight); + } + Action::HeaderBarShowTile(title) => self.headerbar.switch_to_back(&title), + Action::HeaderBarNormal => self.headerbar.switch_to_normal(), + Action::MarkAllPlayerNotification(pd) => { + let notif = mark_all_notif(pd, &self.sender); + notif.show(&self.overlay); + } + Action::RemoveShow(pd) => { + let notif = remove_show_notif(pd, self.sender.clone()); + notif.show(&self.overlay); + } + Action::ErrorNotification(err) => { + error!("An error notification was triggered: {}", err); + let callback = |revealer: gtk::Revealer| { + revealer.set_reveal_child(false); + glib::Continue(false) + }; + let undo_cb: Option = None; + let notif = InAppNotification::new(&err, 6000, callback, undo_cb); + notif.show(&self.overlay); + } + Action::ShowUpdateNotif(receiver) => { + let sender = self.sender.clone(); + let callback = move |revealer: gtk::Revealer| match receiver.try_recv() { + Err(TryRecvError::Empty) => glib::Continue(true), + Err(TryRecvError::Disconnected) => glib::Continue(false), + Ok(_) => { + revealer.set_reveal_child(false); + sender + .send(Action::RefreshAllViews) + .expect("Action channel blew up somehow"); + glib::Continue(false) + } + }; + let txt = i18n("Fetching new episodes"); + let undo_cb: Option = None; + let updater = InAppNotification::new(&txt, 250, callback, undo_cb); + updater.set_close_state(State::Hidden); + updater.set_spinner_state(SpinnerState::Active); + + let old = self.updater.replace(Some(updater)); + old.map(|i| i.destroy()); + self.updater + .borrow() + .as_ref() + .map(|i| i.show(&self.overlay)); + } + Action::InitEpisode(rowid) => { + let res = self.player.initialize_episode(rowid); + debug_assert!(res.is_ok()); + } + Action::InitShowMenu(s) => { + let menu = &s.get().container; + self.headerbar.set_secondary_menu(menu); + } + Action::EmptyState => { + self.window + .lookup_action("refresh") + .and_then(|action| action.downcast::().ok()) + // Disable refresh action + .map(|action| action.set_enabled(false)); + + self.headerbar.switch.set_sensitive(false); + self.content.switch_to_empty_views(); + } + Action::PopulatedState => { + self.window + .lookup_action("refresh") + .and_then(|action| action.downcast::().ok()) + // Enable refresh action + .map(|action| action.set_enabled(true)); + + self.headerbar.switch.set_sensitive(true); + self.content.switch_to_populated(); + } + // https://gitlab.gnome.org/GNOME/gtk/issues/624#note_109968 + Action::RaiseWindow => self + .window + .present_with_time((glib::get_monotonic_time() / 1000) as u32), + }; glib::Continue(true) } diff --git a/podcasts-gtk/src/headerbar.rs b/podcasts-gtk/src/headerbar.rs index 12ce300..f83999d 100644 --- a/podcasts-gtk/src/headerbar.rs +++ b/podcasts-gtk/src/headerbar.rs @@ -204,7 +204,7 @@ impl Header { s.back.connect_clicked(clone!(weak, sender => move |_| { weak.upgrade().map(|h| h.switch_to_normal()); - sender.send(Action::ShowShowsAnimated); + sender.send(Action::ShowShowsAnimated).expect("Action channel blew up somehow"); })); } diff --git a/podcasts-gtk/src/stacks/show.rs b/podcasts-gtk/src/stacks/show.rs index 0cca89f..17fac5f 100644 --- a/podcasts-gtk/src/stacks/show.rs +++ b/podcasts-gtk/src/stacks/show.rs @@ -98,9 +98,13 @@ impl ShowStack { let ign = get_ignored_shows()?; debug!("IGNORED SHOWS {:?}", ign); if is_episodes_populated(&ign)? { - self.sender.send(Action::PopulatedState); + self.sender + .send(Action::PopulatedState) + .expect("Action channel blew up somehow");; } else { - self.sender.send(Action::EmptyState); + self.sender + .send(Action::EmptyState) + .expect("Action channel blew up somehow");; }; Ok(()) diff --git a/podcasts-gtk/src/utils.rs b/podcasts-gtk/src/utils.rs index 5998000..4fd0b0e 100644 --- a/podcasts-gtk/src/utils.rs +++ b/podcasts-gtk/src/utils.rs @@ -231,7 +231,9 @@ where { rayon::spawn(move || { let (up_sender, up_receiver) = bounded(1); - sender.send(Action::ShowUpdateNotif(up_receiver)); + sender + .send(Action::ShowUpdateNotif(up_receiver)) + .expect("Action channel blew up somehow"); if let Some(s) = source { // Refresh only specified feeds @@ -248,7 +250,9 @@ where .ok(); }; - up_sender.send(true); + up_sender + .send(true) + .expect("Channel was dropped unexpectedly");; }); } @@ -313,7 +317,9 @@ pub(crate) fn set_image_from_path( THREADPOOL.spawn(move || { // This operation is polling and will block the thread till the download is finished if let Ok(pd) = dbqueries::get_podcast_cover_from_id(show_id) { - sender.send(downloader::cache_image(&pd)); + sender + .send(downloader::cache_image(&pd)) + .expect("channel was dropped unexpectedly"); } if let Ok(mut guard) = COVER_DL_REGISTRY.write() { @@ -325,18 +331,22 @@ pub(crate) fn set_image_from_path( let image = image.clone(); let s = size as i32; gtk::timeout_add(25, move || { - if let Some(path) = receiver.try_recv() { - if let Ok(path) = path { - if let Ok(px) = Pixbuf::new_from_file_at_scale(&path, s, s, true) { - if let Ok(mut hashmap) = CACHED_PIXBUFS.write() { - hashmap.insert((show_id, size), Mutex::new(Fragile::new(px.clone()))); - image.set_from_pixbuf(&px); + use crossbeam_channel::TryRecvError; + + match receiver.try_recv() { + Err(TryRecvError::Empty) => glib::Continue(true), + Err(TryRecvError::Disconnected) => glib::Continue(false), + Ok(path) => { + if let Ok(path) = path { + if let Ok(px) = Pixbuf::new_from_file_at_scale(&path, s, s, true) { + if let Ok(mut hashmap) = CACHED_PIXBUFS.write() { + hashmap.insert((show_id, size), Mutex::new(Fragile::new(px.clone()))); + image.set_from_pixbuf(&px); + } } } + glib::Continue(false) } - glib::Continue(false) - } else { - glib::Continue(true) } }); Ok(()) @@ -404,12 +414,14 @@ pub(crate) fn on_import_clicked(window: >k::ApplicationWindow, sender: &Sender refresh(Some(sources), sender) } else { let text = i18n("Failed to parse the imported file"); - sender.send(Action::ErrorNotification(text)); + sender.send(Action::ErrorNotification(text)).expect("Action channel blew up somehow");; } })) } else { let text = i18n("Selected file could not be accessed."); - sender.send(Action::ErrorNotification(text)); + sender + .send(Action::ErrorNotification(text)) + .expect("Action channel blew up somehow");; } } } @@ -446,12 +458,14 @@ pub(crate) fn on_export_clicked(window: >k::ApplicationWindow, sender: &Sender rayon::spawn(clone!(sender => move || { if opml::export_from_db(filename, i18n("GNOME Podcasts Subscriptions").as_str()).is_err() { let text = i18n("Failed to export podcasts"); - sender.send(Action::ErrorNotification(text)); + sender.send(Action::ErrorNotification(text)).expect("Action channel blew up somehow"); } })) } else { let text = i18n("Selected file could not be accessed."); - sender.send(Action::ErrorNotification(text)); + sender + .send(Action::ErrorNotification(text)) + .expect("Action channel blew up somehow");; } } } diff --git a/podcasts-gtk/src/widgets/episode.rs b/podcasts-gtk/src/widgets/episode.rs index 296e9d0..60d9fab 100644 --- a/podcasts-gtk/src/widgets/episode.rs +++ b/podcasts-gtk/src/widgets/episode.rs @@ -488,7 +488,9 @@ fn on_download_clicked(ep: &EpisodeWidgetModel, sender: &Sender) -> Resu manager::add(ep.rowid(), download_fold)?; // Update Views - sender.send(Action::RefreshEpisodesViewBGR); + sender + .send(Action::RefreshEpisodesViewBGR) + .expect("Action channel blew up somehow");; Ok(()) } @@ -507,9 +509,13 @@ fn on_play_bttn_clicked( widget.info.set_title(&episode); // Play the episode - sender.send(Action::InitEpisode(episode.rowid())); + sender + .send(Action::InitEpisode(episode.rowid())) + .expect("Action channel blew up somehow");; // Refresh background views to match the normal/greyout title state - sender.send(Action::RefreshEpisodesViewBGR); + sender + .send(Action::RefreshEpisodesViewBGR) + .expect("Action channel blew up somehow");; Ok(()) } diff --git a/podcasts-gtk/src/widgets/player.rs b/podcasts-gtk/src/widgets/player.rs index a4d0e6e..6ab5cd7 100644 --- a/podcasts-gtk/src/widgets/player.rs +++ b/podcasts-gtk/src/widgets/player.rs @@ -534,7 +534,7 @@ impl PlayerWrapper { self.player.connect_error(clone!(sender => move |_, _error| { // sender.send(Action::ErrorNotification(format!("Player Error: {}", error))); let s = i18n("The media player was unable to execute an action."); - sender.send(Action::ErrorNotification(s)); + sender.send(Action::ErrorNotification(s)).expect("Action channel blew up somehow"); })); // The following callbacks require `Send` but are handled by the gtk main loop @@ -631,8 +631,8 @@ impl PlayerWrapper { weak.upgrade().map(|p| p.rewind()); })); - self.info - .mpris - .connect_raise(clone!(sender => move || sender.send(Action::RaiseWindow))); + self.info.mpris.connect_raise(clone!(sender => move || { + sender.send(Action::RaiseWindow).expect("Action channel blew up somehow"); + })); } } diff --git a/podcasts-gtk/src/widgets/show.rs b/podcasts-gtk/src/widgets/show.rs index a27c5d0..0c67bfc 100644 --- a/podcasts-gtk/src/widgets/show.rs +++ b/podcasts-gtk/src/widgets/show.rs @@ -87,7 +87,9 @@ impl ShowWidget { pdw.init(&pd); let menu = ShowMenu::new(&pd, &pdw.episodes, &sender); - sender.send(Action::InitShowMenu(Fragile::new(menu))); + sender + .send(Action::InitShowMenu(Fragile::new(menu))) + .expect("Action channel blew up somehow"); let pdw = Rc::new(pdw); let res = populate_listbox(&pdw, pd.clone(), sender, vadj); @@ -127,6 +129,8 @@ fn populate_listbox( sender: Sender, vadj: Option, ) -> Result<(), Error> { + use crossbeam_channel::TryRecvError; + let count = dbqueries::get_pd_episodes_count(&pd)?; let (sender_, receiver) = bounded(1); @@ -134,7 +138,7 @@ fn populate_listbox( if let Ok(episodes) = dbqueries::get_pd_episodeswidgets(&pd) { // The receiver can be dropped if there's an early return // like on show without episodes for example. - sender_.send(episodes); + let _ = sender_.send(episodes); } })); @@ -148,9 +152,11 @@ fn populate_listbox( let list_weak = show.episodes.downgrade(); gtk::idle_add(move || { let episodes = match receiver.try_recv() { - Some(e) => e, - None => return glib::Continue(true), + Ok(e) => e, + Err(TryRecvError::Empty) => return glib::Continue(true), + Err(TryRecvError::Disconnected) => return glib::Continue(false), }; + debug_assert!(episodes.len() as i64 == count); let constructor = clone!(sender => move |ep| { diff --git a/podcasts-gtk/src/widgets/show_menu.rs b/podcasts-gtk/src/widgets/show_menu.rs index a4ae2f3..3e5f27b 100644 --- a/podcasts-gtk/src/widgets/show_menu.rs +++ b/podcasts-gtk/src/widgets/show_menu.rs @@ -97,7 +97,7 @@ impl ShowMenu { let res = dim_titles(&episodes); debug_assert!(res.is_some()); - sender.send(Action::MarkAllPlayerNotification(pd.clone())) + sender.send(Action::MarkAllPlayerNotification(pd.clone())).expect("Action channel blew up somehow") })); } @@ -108,13 +108,13 @@ impl ShowMenu { // if pressed twice would panic. unsub.set_sensitive(false); - sender.send(Action::RemoveShow(pd.clone())); + sender.send(Action::RemoveShow(pd.clone())).expect("Action channel blew up somehow"); - sender.send(Action::HeaderBarNormal); - sender.send(Action::ShowShowsAnimated); + sender.send(Action::HeaderBarNormal).expect("Action channel blew up somehow"); + sender.send(Action::ShowShowsAnimated).expect("Action channel blew up somehow"); // Queue a refresh after the switch to avoid blocking the db. - sender.send(Action::RefreshShowsView); - sender.send(Action::RefreshEpisodesView); + sender.send(Action::RefreshShowsView).expect("Action channel blew up somehow"); + sender.send(Action::RefreshEpisodesView).expect("Action channel blew up somehow"); unsub.set_sensitive(true); })); @@ -149,8 +149,12 @@ fn mark_all_watched(pd: &Show, sender: &Sender) -> Result<(), Error> { dbqueries::update_none_to_played_now(pd)?; // Not all widgets might have been loaded when the mark_all is hit // So we will need to refresh again after it's done. - sender.send(Action::RefreshWidgetIfSame(pd.id())); - sender.send(Action::RefreshEpisodesView); + sender + .send(Action::RefreshWidgetIfSame(pd.id())) + .expect("Action channel blew up somehow"); + sender + .send(Action::RefreshEpisodesView) + .expect("Action channel blew up somehow"); Ok(()) } @@ -165,7 +169,9 @@ pub(crate) fn mark_all_notif(pd: Arc, sender: &Sender) -> InAppNot glib::Continue(false) }; - let undo_callback = clone!(sender => move || sender.send(Action::RefreshWidgetIfSame(id))); + let undo_callback = clone!(sender => move || { + sender.send(Action::RefreshWidgetIfSame(id)).expect("Action channel blew up somehow") + }); let text = i18n("Marked all episodes as listened"); InAppNotification::new(&text, 6000, callback, Some(undo_callback)) } @@ -189,7 +195,7 @@ pub(crate) fn remove_show_notif(pd: Arc, sender: Sender) -> InAppN .map_err(|_| error!("Failed to delete {}", pd_.title())) .ok(); - sender_.send(Action::RefreshEpisodesView); + sender_.send(Action::RefreshEpisodesView).expect("Action channel blew up somehow"); })); revealer.set_reveal_child(false); @@ -199,8 +205,12 @@ pub(crate) fn remove_show_notif(pd: Arc, sender: Sender) -> InAppN let undo_callback = move || { let res = utils::uningore_show(pd.id()); debug_assert!(res.is_ok()); - sender.send(Action::RefreshShowsView); - sender.send(Action::RefreshEpisodesView); + sender + .send(Action::RefreshShowsView) + .expect("Action channel blew up somehow"); + sender + .send(Action::RefreshEpisodesView) + .expect("Action channel blew up somehow"); }; InAppNotification::new(&text, 6000, callback, Some(undo_callback)) diff --git a/podcasts-gtk/src/widgets/shows_view.rs b/podcasts-gtk/src/widgets/shows_view.rs index 0e11dbd..3a2f395 100644 --- a/podcasts-gtk/src/widgets/shows_view.rs +++ b/podcasts-gtk/src/widgets/shows_view.rs @@ -107,9 +107,15 @@ fn on_child_activate(child: >k::FlowBoxChild, sender: &Sender) -> Resu .parse::()?; let pd = Arc::new(dbqueries::get_podcast_from_id(id)?); - sender.send(Action::HeaderBarShowTile(pd.title().into())); - sender.send(Action::ReplaceWidget(pd)); - sender.send(Action::ShowWidgetAnimated); + sender + .send(Action::HeaderBarShowTile(pd.title().into())) + .expect("Action channel blew up somehow"); + sender + .send(Action::ReplaceWidget(pd)) + .expect("Action channel blew up somehow"); + sender + .send(Action::ShowWidgetAnimated) + .expect("Action channel blew up somehow"); Ok(()) }