Hammond-gtk: Stack, Content constructors return Results now.
Constructors now proxy underlying errors that migth occur during initialazation. I think that's about the last unwraps in the main thread.
This commit is contained in:
parent
89564996df
commit
2d33606251
@ -65,7 +65,8 @@ impl App {
|
||||
let (sender, receiver) = channel();
|
||||
|
||||
// Create a content instance
|
||||
let content = Arc::new(Content::new(sender.clone()));
|
||||
let content =
|
||||
Arc::new(Content::new(sender.clone()).expect("Content Initialization failed."));
|
||||
|
||||
// Create the headerbar
|
||||
let header = Arc::new(Header::new(content.clone(), &window, sender.clone()));
|
||||
@ -87,7 +88,7 @@ impl App {
|
||||
let sender = self.sender.clone();
|
||||
// Update the feeds right after the Application is initialized.
|
||||
gtk::timeout_add_seconds(2, move || {
|
||||
utils::refresh_feed(None, sender.clone());
|
||||
utils::refresh_feed_wrapper(None, sender.clone());
|
||||
glib::Continue(false)
|
||||
});
|
||||
|
||||
@ -95,7 +96,7 @@ impl App {
|
||||
// Auto-updater, runs every hour.
|
||||
// TODO: expose the interval in which it run to a user setting.
|
||||
gtk::timeout_add_seconds(3600, move || {
|
||||
utils::refresh_feed(None, sender.clone());
|
||||
utils::refresh_feed_wrapper(None, sender.clone());
|
||||
glib::Continue(true)
|
||||
});
|
||||
|
||||
@ -122,9 +123,9 @@ impl App {
|
||||
match receiver.recv_timeout(Duration::from_millis(10)) {
|
||||
Ok(Action::UpdateSources(source)) => {
|
||||
if let Some(s) = source {
|
||||
utils::refresh_feed(Some(vec![s]), sender.clone());
|
||||
utils::refresh_feed_wrapper(Some(vec![s]), sender.clone());
|
||||
} else {
|
||||
utils::refresh_feed(None, sender.clone());
|
||||
utils::refresh_feed_wrapper(None, sender.clone());
|
||||
}
|
||||
}
|
||||
Ok(Action::RefreshAllViews) => content.update(),
|
||||
|
||||
@ -26,20 +26,20 @@ pub struct Content {
|
||||
}
|
||||
|
||||
impl Content {
|
||||
pub fn new(sender: Sender<Action>) -> Content {
|
||||
pub fn new(sender: Sender<Action>) -> Result<Content, Error> {
|
||||
let stack = gtk::Stack::new();
|
||||
let episodes = Arc::new(EpisodeStack::new(sender.clone()));
|
||||
let shows = Arc::new(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");
|
||||
|
||||
Content {
|
||||
Ok(Content {
|
||||
stack,
|
||||
shows,
|
||||
episodes,
|
||||
sender,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn update(&self) {
|
||||
@ -107,7 +107,7 @@ pub struct ShowStack {
|
||||
}
|
||||
|
||||
impl ShowStack {
|
||||
fn new(sender: Sender<Action>) -> ShowStack {
|
||||
fn new(sender: Sender<Action>) -> Result<ShowStack, Error> {
|
||||
let stack = gtk::Stack::new();
|
||||
|
||||
let show = ShowStack {
|
||||
@ -115,7 +115,7 @@ impl ShowStack {
|
||||
sender: sender.clone(),
|
||||
};
|
||||
|
||||
let pop = ShowsPopulated::new(sender.clone());
|
||||
let pop = ShowsPopulated::new(sender.clone())?;
|
||||
let widget = ShowWidget::default();
|
||||
let empty = EmptyView::new();
|
||||
|
||||
@ -129,7 +129,7 @@ impl ShowStack {
|
||||
show.stack.set_visible_child_name("podcasts")
|
||||
}
|
||||
|
||||
show
|
||||
Ok(show)
|
||||
}
|
||||
|
||||
// pub fn update(&self) {
|
||||
@ -138,7 +138,9 @@ impl ShowStack {
|
||||
// }
|
||||
|
||||
pub fn update_podcasts(&self) -> Result<(), Error> {
|
||||
let vis = self.stack.get_visible_child_name().unwrap();
|
||||
let vis = self.stack
|
||||
.get_visible_child_name()
|
||||
.ok_or_else(|| format_err!("Failed to get visible child name."))?;
|
||||
|
||||
let old = self.stack
|
||||
.get_child_by_name("podcasts")
|
||||
@ -155,7 +157,7 @@ impl ShowStack {
|
||||
.map_err(|_| format_err!("Failed to downcast stack child to a ScrolledWindow."))?;
|
||||
debug!("Name: {:?}", WidgetExt::get_name(&scrolled_window));
|
||||
|
||||
let pop = ShowsPopulated::new(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()
|
||||
@ -269,8 +271,8 @@ pub struct EpisodeStack {
|
||||
}
|
||||
|
||||
impl EpisodeStack {
|
||||
fn new(sender: Sender<Action>) -> EpisodeStack {
|
||||
let episodes = EpisodesView::new(sender.clone());
|
||||
fn new(sender: Sender<Action>) -> Result<EpisodeStack, Error> {
|
||||
let episodes = EpisodesView::new(sender.clone())?;
|
||||
let empty = EmptyView::new();
|
||||
let stack = gtk::Stack::new();
|
||||
|
||||
@ -283,7 +285,7 @@ impl EpisodeStack {
|
||||
stack.set_visible_child_name("episodes");
|
||||
}
|
||||
|
||||
EpisodeStack { stack, sender }
|
||||
Ok(EpisodeStack { stack, sender })
|
||||
}
|
||||
|
||||
// Look into refactoring to a state-machine.
|
||||
@ -303,7 +305,7 @@ impl EpisodeStack {
|
||||
.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());
|
||||
let eps = EpisodesView::new(self.sender.clone())?;
|
||||
// Copy the vertical scrollbar adjustment from the old view into the new one.
|
||||
scrolled_window
|
||||
.get_vadjustment()
|
||||
|
||||
@ -90,7 +90,9 @@ impl Header {
|
||||
self.add_toggle.set_popover(&add_popover);
|
||||
|
||||
self.update_button.connect_clicked(move |_| {
|
||||
sender.send(Action::UpdateSources(None)).unwrap();
|
||||
sender
|
||||
.send(Action::UpdateSources(None))
|
||||
.expect("Action channel blew up.");
|
||||
});
|
||||
|
||||
self.about_button
|
||||
|
||||
@ -112,8 +112,12 @@ pub fn add(id: i32, directory: &str, sender: Sender<Action>) -> Result<(), Error
|
||||
// }
|
||||
// }
|
||||
|
||||
sender.send(Action::RefreshEpisodesView).unwrap();
|
||||
sender.send(Action::RefreshWidgetIfSame(pid)).unwrap();
|
||||
sender
|
||||
.send(Action::RefreshEpisodesView)
|
||||
.expect("Action channel blew up.");
|
||||
sender
|
||||
.send(Action::RefreshWidgetIfSame(pid))
|
||||
.expect("Action channel blew up.");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -17,14 +17,23 @@ use std::thread;
|
||||
|
||||
use app::Action;
|
||||
|
||||
pub fn refresh_feed_wrapper(source: Option<Vec<Source>>, sender: Sender<Action>) {
|
||||
if let Err(err) = refresh_feed(source, sender) {
|
||||
error!("An error occured while trying to update the feeds.");
|
||||
error!("Error: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the rss feed(s) originating from `source`.
|
||||
/// If `source` is None, Fetches all the `Source` entries in the database and updates them.
|
||||
/// When It's done,it queues up a `RefreshViews` action.
|
||||
pub fn refresh_feed(source: Option<Vec<Source>>, sender: Sender<Action>) {
|
||||
sender.send(Action::HeaderBarShowUpdateIndicator).unwrap();
|
||||
fn refresh_feed(source: Option<Vec<Source>>, sender: Sender<Action>) -> Result<(), Error> {
|
||||
sender.send(Action::HeaderBarShowUpdateIndicator)?;
|
||||
|
||||
thread::spawn(move || {
|
||||
let mut sources = source.unwrap_or_else(|| dbqueries::get_sources().unwrap());
|
||||
let mut sources = source.unwrap_or_else(|| {
|
||||
dbqueries::get_sources().expect("Failed to retrieve Sources from the database.")
|
||||
});
|
||||
|
||||
// Work around to improve the feed addition experience.
|
||||
// Many times links to rss feeds are just redirects(usually to an https version).
|
||||
@ -40,11 +49,11 @@ pub fn refresh_feed(source: Option<Vec<Source>>, sender: Sender<Action>) {
|
||||
if let Err(err) = pipeline::index_single_source(source, false) {
|
||||
error!("Error While trying to update the database.");
|
||||
error!("Error msg: {}", err);
|
||||
let source = dbqueries::get_source_from_id(id).unwrap();
|
||||
|
||||
if let Err(err) = pipeline::index_single_source(source, false) {
|
||||
error!("Error While trying to update the database.");
|
||||
error!("Error msg: {}", err);
|
||||
if let Ok(source) = dbqueries::get_source_from_id(id) {
|
||||
if let Err(err) = pipeline::index_single_source(source, false) {
|
||||
error!("Error While trying to update the database.");
|
||||
error!("Error msg: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -55,9 +64,14 @@ pub fn refresh_feed(source: Option<Vec<Source>>, sender: Sender<Action>) {
|
||||
}
|
||||
}
|
||||
|
||||
sender.send(Action::HeaderBarHideUpdateIndicator).unwrap();
|
||||
sender.send(Action::RefreshAllViews).unwrap();
|
||||
sender
|
||||
.send(Action::HeaderBarHideUpdateIndicator)
|
||||
.expect("Action channel blew up.");
|
||||
sender
|
||||
.send(Action::RefreshAllViews)
|
||||
.expect("Action channel blew up.");
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
|
||||
@ -75,9 +75,9 @@ impl Default for EpisodesView {
|
||||
|
||||
// TODO: REFACTOR ME
|
||||
impl EpisodesView {
|
||||
pub fn new(sender: Sender<Action>) -> EpisodesView {
|
||||
pub fn new(sender: Sender<Action>) -> Result<EpisodesView, Error> {
|
||||
let view = EpisodesView::default();
|
||||
let episodes = dbqueries::get_episodes_widgets_with_limit(50).unwrap();
|
||||
let episodes = dbqueries::get_episodes_widgets_with_limit(50)?;
|
||||
let now_utc = Utc::now();
|
||||
|
||||
episodes.into_iter().for_each(|mut ep| {
|
||||
@ -124,7 +124,7 @@ impl EpisodesView {
|
||||
}
|
||||
|
||||
view.container.show_all();
|
||||
view
|
||||
Ok(view)
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
|
||||
@ -33,41 +33,34 @@ impl Default for ShowsPopulated {
|
||||
}
|
||||
|
||||
impl ShowsPopulated {
|
||||
pub fn new(sender: Sender<Action>) -> ShowsPopulated {
|
||||
pub fn new(sender: Sender<Action>) -> Result<ShowsPopulated, Error> {
|
||||
let pop = ShowsPopulated::default();
|
||||
pop.init(sender);
|
||||
pop
|
||||
pop.init(sender)?;
|
||||
Ok(pop)
|
||||
}
|
||||
|
||||
pub fn init(&self, sender: Sender<Action>) {
|
||||
use gtk::WidgetExt;
|
||||
|
||||
// TODO: handle unwraps.
|
||||
pub fn init(&self, sender: Sender<Action>) -> Result<(), Error> {
|
||||
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();
|
||||
|
||||
sender
|
||||
.send(Action::HeaderBarShowTile(pd.title().into()))
|
||||
.unwrap();
|
||||
sender.send(Action::ReplaceWidget(pd)).unwrap();
|
||||
sender.send(Action::ShowWidgetAnimated).unwrap();
|
||||
if let Err(err) = on_child_activate(child, sender.clone()) {
|
||||
error!(
|
||||
"Something went wrong during flowbox child activation: {}.",
|
||||
err
|
||||
)
|
||||
};
|
||||
});
|
||||
// Populate the flowbox with the Podcasts.
|
||||
self.populate_flowbox();
|
||||
self.populate_flowbox()
|
||||
}
|
||||
|
||||
fn populate_flowbox(&self) {
|
||||
let podcasts = dbqueries::get_podcasts();
|
||||
fn populate_flowbox(&self) -> Result<(), Error> {
|
||||
let podcasts = dbqueries::get_podcasts()?;
|
||||
|
||||
if let Ok(pds) = podcasts {
|
||||
pds.iter().for_each(|parent| {
|
||||
let flowbox_child = ShowsChild::new(parent);
|
||||
self.flowbox.add(&flowbox_child.child);
|
||||
});
|
||||
self.flowbox.show_all();
|
||||
}
|
||||
podcasts.iter().for_each(|parent| {
|
||||
let flowbox_child = ShowsChild::new(parent);
|
||||
self.flowbox.add(&flowbox_child.child);
|
||||
});
|
||||
self.flowbox.show_all();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
@ -80,6 +73,21 @@ impl ShowsPopulated {
|
||||
}
|
||||
}
|
||||
|
||||
fn on_child_activate(child: >k::FlowBoxChild, sender: Sender<Action>) -> Result<(), Error> {
|
||||
use gtk::WidgetExt;
|
||||
|
||||
// This is such an ugly hack...
|
||||
let id = WidgetExt::get_name(child)
|
||||
.ok_or_else(|| format_err!("Faild to get \"episodes\" child from the stack."))?
|
||||
.parse::<i32>()?;
|
||||
let pd = dbqueries::get_podcast_from_id(id)?;
|
||||
|
||||
sender.send(Action::HeaderBarShowTile(pd.title().into()))?;
|
||||
sender.send(Action::ReplaceWidget(pd))?;
|
||||
sender.send(Action::ShowWidgetAnimated)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ShowsChild {
|
||||
container: gtk::Box,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user