diff --git a/podcasts-gtk/src/stacks/home.rs b/podcasts-gtk/src/stacks/home.rs index d9fe4df..4ab72cb 100644 --- a/podcasts-gtk/src/stacks/home.rs +++ b/podcasts-gtk/src/stacks/home.rs @@ -29,7 +29,7 @@ pub(crate) struct HomeStack { impl HomeStack { pub(crate) fn new(sender: Sender) -> Result { - let episodes = HomeView::new(sender.clone())?; + let episodes = HomeView::new(sender.clone(), None)?; let empty = EmptyView::new(); let stack = gtk::Stack::new(); let state = State::Empty; @@ -54,12 +54,6 @@ impl HomeStack { } pub(crate) fn update(&mut self) -> Result<(), Error> { - // Copy the vertical scrollbar adjustment from the old view. - self.episodes - .save_alignment() - .map_err(|err| error!("Failed to set episodes_view allignment: {}", err)) - .ok(); - self.replace_view()?; // Determine the actuall state. self.determine_state().map_err(From::from) @@ -68,7 +62,10 @@ impl HomeStack { fn replace_view(&mut self) -> Result<(), Error> { // Get the container of the view let old = &self.episodes.view.container().clone(); - let eps = HomeView::new(self.sender.clone())?; + + // Copy the vertical scrollbar adjustment from the old view. + let vadj = self.episodes.view.get_vadjustment(); + let eps = HomeView::new(self.sender.clone(), vadj)?; // Remove the old widget and add the new one // during this the previous view is removed, diff --git a/podcasts-gtk/src/widgets/home_view.rs b/podcasts-gtk/src/widgets/home_view.rs index b11bbea..af85708 100644 --- a/podcasts-gtk/src/widgets/home_view.rs +++ b/podcasts-gtk/src/widgets/home_view.rs @@ -1,11 +1,9 @@ use chrono::prelude::*; use failure::Error; -use gtk; -use gtk::prelude::*; +use gtk::{self, prelude::*, Adjustment}; use crossbeam_channel::Sender; -use fragile::Fragile; use libhandy::{Column, ColumnExt}; use podcasts_data::dbqueries; use podcasts_data::EpisodeWidgetModel; @@ -16,12 +14,6 @@ use widgets::{BaseView, EpisodeWidget}; use std::cell::Cell; use std::rc::Rc; -use std::sync::Mutex; - -lazy_static! { - pub(crate) static ref EPISODES_VIEW_VALIGNMENT: Mutex>> = - Mutex::new(None); -} #[derive(Debug, Clone)] enum ListSplit { @@ -94,74 +86,51 @@ impl Default for HomeView { // TODO: REFACTOR ME impl HomeView { - pub(crate) fn new(sender: Sender) -> Result, Error> { + pub(crate) fn new( + sender: Sender, + vadj: Option, + ) -> Result, Error> { use self::ListSplit::*; - let view = Rc::new(HomeView::default()); + let home = Rc::new(HomeView::default()); let ignore = utils::get_ignored_shows()?; let episodes = dbqueries::get_episodes_widgets_filter_limit(&ignore, 100)?; let now_utc = Utc::now(); - let view_ = view.clone(); + let home_weak = Rc::downgrade(&home); let func = move |ep: EpisodeWidgetModel| { + let home = match home_weak.upgrade() { + Some(h) => h, + None => return, + }; + let epoch = ep.epoch(); let widget = HomeEpisode::new(ep, &sender); match split(&now_utc, i64::from(epoch)) { - Today => add_to_box(&widget, &view_.today_list, &view_.today_box), - Yday => add_to_box(&widget, &view_.yday_list, &view_.yday_box), - Week => add_to_box(&widget, &view_.week_list, &view_.week_box), - Month => add_to_box(&widget, &view_.month_list, &view_.month_box), - Rest => add_to_box(&widget, &view_.rest_list, &view_.rest_box), + Today => add_to_box(&widget, &home.today_list, &home.today_box), + Yday => add_to_box(&widget, &home.yday_list, &home.yday_box), + Week => add_to_box(&widget, &home.week_list, &home.week_box), + Month => add_to_box(&widget, &home.month_list, &home.month_box), + Rest => add_to_box(&widget, &home.rest_list, &home.rest_box), } }; - let view_ = view.clone(); + let home_weak = Rc::downgrade(&home); let callback = move || { - view_ - .set_vadjustment() - .map_err(|err| format!("{}", err)) - .ok(); + let home = match home_weak.upgrade() { + Some(h) => h, + None => return, + }; + + if let Some(ref v) = vadj { + home.view.set_adjutments(None, Some(v)) + }; }; lazy_load_full(episodes, func, callback); - view.view.container().show_all(); - Ok(view) - } - - /// Set scrolled window vertical adjustment. - fn set_vadjustment(&self) -> Result<(), Error> { - let guard = EPISODES_VIEW_VALIGNMENT - .lock() - .map_err(|err| format_err!("Failed to lock widget align mutex: {}", err))?; - - if let Some(ref fragile) = *guard { - // Copy the vertical scrollbar adjustment from the old view into the new one. - let res = fragile - .try_get() - .map(|x| utils::smooth_scroll_to(self.view.scrolled_window(), &x)) - .map_err(From::from); - - debug_assert!(res.is_ok()); - return res; - } - - Ok(()) - } - - /// Save the vertical scrollbar position. - pub(crate) fn save_alignment(&self) -> Result<(), Error> { - if let Ok(mut guard) = EPISODES_VIEW_VALIGNMENT.lock() { - let adj = self - .view - .scrolled_window() - .get_vadjustment() - .ok_or_else(|| format_err!("Could not get the adjustment"))?; - *guard = Some(Fragile::new(adj)); - info!("Saved episodes_view alignment."); - } - - Ok(()) + home.view.container().show_all(); + Ok(home) } }