From 5ad52fa4b268cbb1707b9dc69e57ff7242db25f5 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 19 Nov 2017 23:32:37 +0200 Subject: [PATCH] Refactored to remove from Database refferences. --- hammond-data/src/lib.rs | 6 +-- hammond-data/src/utils.rs | 4 +- hammond-gtk/src/headerbar.rs | 21 +++++----- hammond-gtk/src/main.rs | 18 ++++----- hammond-gtk/src/utils.rs | 22 +++++------ hammond-gtk/src/views/podcasts_view.rs | 50 ++++++++++------------- hammond-gtk/src/widgets/episode.rs | 55 +++++++++++--------------- hammond-gtk/src/widgets/podcast.rs | 40 ++++++++----------- 8 files changed, 91 insertions(+), 125 deletions(-) diff --git a/hammond-data/src/lib.rs b/hammond-data/src/lib.rs index 04e1ed0..06481c1 100644 --- a/hammond-data/src/lib.rs +++ b/hammond-data/src/lib.rs @@ -90,11 +90,11 @@ fn get_temp_db() -> TempDB { let tmp_dir = tempdir::TempDir::new("hammond_unit_test").unwrap(); let db_path = tmp_dir .path() - .join(format!("hammonddb_{}.db", rng.gen::())); + .join("test.db"); let pool = utils::init_pool(db_path.to_str().unwrap()); - let db = pool.get().unwrap(); - utils::run_migration_on(&db).unwrap(); + let db = pool.clone().get().unwrap(); + utils::run_migration_on(&*db).unwrap(); TempDB(tmp_dir, db_path, pool) } diff --git a/hammond-data/src/utils.rs b/hammond-data/src/utils.rs index 324fee4..cb0acc3 100644 --- a/hammond-data/src/utils.rs +++ b/hammond-data/src/utils.rs @@ -27,7 +27,9 @@ pub fn init() -> Result<()> { pub fn init_pool(db_path: &str) -> Pool { let config = r2d2::Config::default(); let manager = ConnectionManager::::new(db_path); - r2d2::Pool::new(config, manager).expect("Failed to create pool.") + let pool = r2d2::Pool::new(config, manager).expect("Failed to create pool."); + info!("Database pool initialized."); + pool } pub fn run_migration_on(connection: &SqliteConnection) -> Result<()> { diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 9686d66..438d814 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -2,12 +2,11 @@ use gtk; use gtk::prelude::*; use hammond_data::models::NewSource; -use hammond_data::Database; use podcasts_view::update_podcasts_view; use utils; -pub fn get_headerbar(db: &Database, stack: >k::Stack) -> gtk::HeaderBar { +pub fn get_headerbar(stack: >k::Stack) -> gtk::HeaderBar { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); let header: gtk::HeaderBar = builder.get_object("headerbar1").unwrap(); @@ -23,9 +22,9 @@ pub fn get_headerbar(db: &Database, stack: >k::Stack) -> gtk::HeaderBar { println!("{:?}", url.get_text()); }); - add_button.connect_clicked(clone!(db, stack, add_popover => move |_| { + add_button.connect_clicked(clone!(stack, add_popover => move |_| { let url = new_url.get_text().unwrap_or_default(); - on_add_bttn_clicked(&db, &stack, &url); + on_add_bttn_clicked(&stack, &url); // TODO: lock the button instead of hiding and add notification of feed added. // TODO: map the spinner @@ -36,29 +35,29 @@ pub fn get_headerbar(db: &Database, stack: >k::Stack) -> gtk::HeaderBar { // TODO: make it a back arrow button, that will hide when appropriate, // and add a StackSwitcher when more views are added. - home_button.connect_clicked(clone!(db, stack => move |_| { + home_button.connect_clicked(clone!(stack => move |_| { let vis = stack.get_visible_child_name().unwrap(); stack.set_visible_child_name("fb_parent"); if vis != "pdw" { - update_podcasts_view(&db, &stack); + update_podcasts_view(&stack); } })); // FIXME: There appears to be a memmory leak here. - refresh_button.connect_clicked(clone!(stack, db => move |_| { - utils::refresh_feed(&db, &stack, None, None); + refresh_button.connect_clicked(clone!(stack => move |_| { + utils::refresh_feed(&stack, None, None); })); header } -fn on_add_bttn_clicked(db: &Database, stack: >k::Stack, url: &str) { - let source = NewSource::new_with_uri(url).into_source(db); +fn on_add_bttn_clicked(stack: >k::Stack, url: &str) { + let source = NewSource::new_with_uri(url).into_source(); info!("{:?} feed added", url); if let Ok(s) = source { // update the db - utils::refresh_feed(db, stack, Some(vec![s]), None); + utils::refresh_feed(stack, Some(vec![s]), None); } else { error!("Feed probably already exists."); error!("Error: {:?}", source.unwrap_err()); diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 869c31f..ba4a7d2 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -18,8 +18,6 @@ extern crate open; use log::LogLevel; use hammond_data::utils::checkup; -use std::sync::{Arc, Mutex}; - use gtk::prelude::*; use gio::{ActionMapExt, ApplicationExt, MenuExt, SimpleActionExt}; @@ -56,8 +54,6 @@ THIS IS STILL A PROTOTYPE. */ fn build_ui(app: >k::Application) { - let db = Arc::new(Mutex::new(hammond_data::utils::establish_connection())); - let menu = gio::Menu::new(); menu.append("Quit", "app.quit"); menu.append("Checkup", "app.check"); @@ -67,7 +63,7 @@ fn build_ui(app: >k::Application) { let window = gtk::ApplicationWindow::new(app); window.set_default_size(1150, 650); // Setup the Stack that will manage the switch between podcasts_view and podcast_widget. - let stack = podcasts_view::setup_stack(&db); + let stack = podcasts_view::setup_stack(); window.add(&stack); window.connect_delete_event(|w, _| { @@ -85,19 +81,19 @@ fn build_ui(app: >k::Application) { // Setup the checkup in the app menu. let check = gio::SimpleAction::new("check", None); - check.connect_activate(clone!(db => move |_, _| { - let _ = checkup(&db); - })); + check.connect_activate(move |_, _| { + let _ = checkup(); + }); app.add_action(&check); // queue a db update 1 minute after the startup. - gtk::idle_add(clone!(db, stack => move || { - utils::refresh_feed(&db, &stack, None, Some(60)); + gtk::idle_add(clone!(stack => move || { + utils::refresh_feed(&stack, None, Some(60)); glib::Continue(false) })); // Get the headerbar - let header = headerbar::get_headerbar(&db, &stack); + let header = headerbar::get_headerbar(&stack); window.set_titlebar(&header); window.show_all(); diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 3952141..54d99af 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -3,7 +3,6 @@ use gtk; use hammond_data::feed; use hammond_data::models::Source; -use hammond_data::Database; use std::{thread, time}; use std::cell::RefCell; @@ -11,7 +10,7 @@ use std::sync::mpsc::{channel, Receiver}; use views::podcasts_view; -type Foo = RefCell)>>; +type Foo = RefCell)>>; // Create a thread local storage that will store the arguments to be transfered. thread_local!(static GLOBAL: Foo = RefCell::new(None)); @@ -21,7 +20,6 @@ thread_local!(static GLOBAL: Foo = RefCell::new(None)); /// `delay` represents the desired time in seconds for the thread to sleep before executing. /// When It's done,it queues up a `podcast_view` refresh. pub fn refresh_feed( - db: &Database, stack: >k::Stack, source: Option>, delay: Option, @@ -30,11 +28,11 @@ pub fn refresh_feed( let (sender, receiver) = channel(); // Pass the desired arguments into the Local Thread Storage. - GLOBAL.with(clone!(db, stack => move |global| { - *global.borrow_mut() = Some((db, stack, receiver)); + GLOBAL.with(clone!(stack => move |global| { + *global.borrow_mut() = Some((stack, receiver)); })); - thread::spawn(clone!(db => move || { + thread::spawn(move || { if let Some(s) = delay{ let t = time::Duration::from_secs(s); thread::sleep(t); @@ -42,27 +40,27 @@ pub fn refresh_feed( let feeds = { if let Some(mut vec) = source { - Ok(feed::fetch(&db, vec)) + Ok(feed::fetch(vec)) } else { - feed::fetch_all(&db) + feed::fetch_all() } }; if let Ok(mut x) = feeds { - feed::index(&db, &mut x); + feed::index(&mut x); info!("Indexing done."); sender.send(true).expect("Couldn't send data to channel");; glib::idle_add(refresh_podcasts_view); }; - })); + }); } fn refresh_podcasts_view() -> glib::Continue { GLOBAL.with(|global| { - if let Some((ref db, ref stack, ref reciever)) = *global.borrow() { + if let Some((ref stack, ref reciever)) = *global.borrow() { if reciever.try_recv().is_ok() { - podcasts_view::update_podcasts_view(db, stack); + podcasts_view::update_podcasts_view(stack); } } }); diff --git a/hammond-gtk/src/views/podcasts_view.rs b/hammond-gtk/src/views/podcasts_view.rs index 9bfcaca..eaf3d1c 100644 --- a/hammond-gtk/src/views/podcasts_view.rs +++ b/hammond-gtk/src/views/podcasts_view.rs @@ -5,7 +5,6 @@ use diesel::associations::Identifiable; use hammond_data::dbqueries; use hammond_data::models::Podcast; -use hammond_data::Database; use widgets::podcast::*; @@ -21,22 +20,19 @@ fn show_empty_view(stack: >k::Stack) { info!("Empty view."); } -fn populate_flowbox(db: &Database, flowbox: >k::FlowBox) { - let podcasts = { - let db = db.lock().unwrap(); - dbqueries::get_podcasts(&db) - }; +fn populate_flowbox(flowbox: >k::FlowBox) { + let podcasts = dbqueries::get_podcasts(); if let Ok(pds) = podcasts { pds.iter().for_each(|parent| { - let f = create_flowbox_child(db, parent); + let f = create_flowbox_child(parent); flowbox.add(&f); }); flowbox.show_all(); } } -fn create_flowbox_child(db: &Database, pd: &Podcast) -> gtk::FlowBoxChild { +fn create_flowbox_child(pd: &Podcast) -> gtk::FlowBoxChild { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/podcasts_child.ui"); // Copy of gnome-music AlbumWidget @@ -53,7 +49,7 @@ fn create_flowbox_child(db: &Database, pd: &Podcast) -> gtk::FlowBoxChild { pd_cover.set_from_pixbuf(&img); }; - configure_banner(db, pd, &banner, &banner_title); + configure_banner(pd, &banner, &banner_title); let fbc = gtk::FlowBoxChild::new(); // There's probably a better way to store the id somewhere. @@ -62,15 +58,12 @@ fn create_flowbox_child(db: &Database, pd: &Podcast) -> gtk::FlowBoxChild { fbc } -fn configure_banner(db: &Database, pd: &Podcast, banner: >k::Image, banner_title: >k::Label) { +fn configure_banner(pd: &Podcast, banner: >k::Image, banner_title: >k::Label) { let bann = Pixbuf::new_from_resource_at_scale("/org/gnome/hammond/banner.png", 256, 256, true); if let Ok(b) = bann { banner.set_from_pixbuf(&b); - let new_episodes = { - let tempdb = db.lock().unwrap(); - dbqueries::get_pd_unplayed_episodes(&tempdb, pd) - }; + let new_episodes = dbqueries::get_pd_unplayed_episodes(pd); if let Ok(n) = new_episodes { if !n.is_empty() { @@ -82,9 +75,9 @@ fn configure_banner(db: &Database, pd: &Podcast, banner: >k::Image, banner_tit } } -fn on_flowbox_child_activate(db: &Database, stack: >k::Stack, parent: &Podcast) { +fn on_flowbox_child_activate(stack: >k::Stack, parent: &Podcast) { let old = stack.get_child_by_name("pdw").unwrap(); - let pdw = podcast_widget(db, stack, parent); + let pdw = podcast_widget(stack, parent); stack.remove(&old); stack.add_named(&pdw, "pdw"); @@ -95,11 +88,11 @@ fn on_flowbox_child_activate(db: &Database, stack: >k::Stack, parent: &Podcast old.destroy(); } -fn setup_podcasts_flowbox(db: &Database, stack: >k::Stack) -> gtk::FlowBox { +fn setup_podcasts_flowbox(stack: >k::Stack) -> gtk::FlowBox { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/podcasts_view.ui"); let fb_parent: gtk::Box = builder.get_object("fb_parent").unwrap(); let flowbox: gtk::FlowBox = builder.get_object("flowbox").unwrap(); - init_flowbox(db, stack, &flowbox); + init_flowbox(stack, &flowbox); stack.add_named(&fb_parent, "fb_parent"); @@ -112,21 +105,21 @@ fn setup_podcasts_flowbox(db: &Database, stack: >k::Stack) -> gtk::FlowBox { flowbox } -pub fn setup_stack(db: &Database) -> gtk::Stack { +pub fn setup_stack() -> gtk::Stack { let stack = gtk::Stack::new(); stack.set_transition_type(gtk::StackTransitionType::SlideLeftRight); setup_empty_view(&stack); setup_podcast_widget(&stack); - setup_podcasts_flowbox(db, &stack); + setup_podcasts_flowbox(&stack); stack } -pub fn update_podcasts_view(db: &Database, stack: >k::Stack) { +pub fn update_podcasts_view(stack: >k::Stack) { let vis = stack.get_visible_child_name().unwrap(); let old = stack.get_child_by_name("fb_parent").unwrap(); stack.remove(&old); - let flowbox = setup_podcasts_flowbox(db, stack); + let flowbox = setup_podcasts_flowbox(stack); if vis == "empty" && !flowbox.get_children().is_empty() { stack.set_visible_child_name("fb_parent"); @@ -142,17 +135,14 @@ pub fn update_podcasts_view(db: &Database, stack: >k::Stack) { old.destroy(); } -fn init_flowbox(db: &Database, stack: >k::Stack, flowbox: >k::FlowBox) { +fn init_flowbox(stack: >k::Stack, flowbox: >k::FlowBox) { // TODO: handle unwraps. - flowbox.connect_child_activated(clone!(db, stack => move |_, child| { + flowbox.connect_child_activated(clone!(stack => move |_, child| { // This is such an ugly hack... let id = child.get_name().unwrap().parse::().unwrap(); - let parent = { - let tempdb = db.lock().unwrap(); - dbqueries::get_podcast_from_id(&tempdb, id).unwrap() - }; - on_flowbox_child_activate(&db, &stack, &parent); + let parent = dbqueries::get_podcast_from_id(id).unwrap(); + on_flowbox_child_activate(&stack, &parent); })); // Populate the flowbox with the Podcasts. - populate_flowbox(db, flowbox); + populate_flowbox(flowbox); } diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 385a470..75baaca 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -2,7 +2,6 @@ use open; use hammond_data::dbqueries; use hammond_data::models::{Episode, Podcast}; use hammond_downloader::downloader; -use hammond_data::Database; use hammond_data::utils::*; use hammond_data::errors::*; @@ -23,7 +22,7 @@ type Foo = RefCell thread_local!(static GLOBAL: Foo = RefCell::new(None)); -fn epidose_widget(db: &Database, episode: &mut Episode, pd_title: &str) -> gtk::Box { +fn epidose_widget(episode: &mut Episode, pd_title: &str) -> gtk::Box { // This is just a prototype and will be reworked probably. let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episode_widget.ui"); @@ -70,42 +69,41 @@ fn epidose_widget(db: &Database, episode: &mut Episode, pd_title: &str) -> gtk:: } play_button.connect_clicked( - clone!(db, episode, played_button, unplayed_button => move |_| { - on_play_bttn_clicked(&db, *episode.id()); - let _ = set_played_now(&db, &mut episode.clone()); + clone!(episode, played_button, unplayed_button => move |_| { + on_play_bttn_clicked(*episode.id()); + let _ = set_played_now(&mut episode.clone()); played_button.hide(); unplayed_button.show(); }), ); delete_button.connect_clicked( - clone!(episode, db, play_button, download_button => move |del| { - on_delete_bttn_clicked(&db, *episode.id()); + clone!(episode, play_button, download_button => move |del| { + on_delete_bttn_clicked(*episode.id()); del.hide(); play_button.hide(); download_button.show(); }), ); - played_button.connect_clicked(clone!(db, episode, unplayed_button => move |played| { - let _ = set_played_now(&db, &mut episode.clone()); + played_button.connect_clicked(clone!(episode, unplayed_button => move |played| { + let _ = set_played_now(&mut episode.clone()); played.hide(); unplayed_button.show(); })); - unplayed_button.connect_clicked(clone!(db, episode, played_button => move |un| { + unplayed_button.connect_clicked(clone!(episode, played_button => move |un| { let mut episode = episode.clone(); episode.set_played(None); - let _ = episode.save(&db); + let _ = episode.save(); un.hide(); played_button.show(); })); let pd_title = pd_title.to_owned(); download_button.connect_clicked( - clone!(db, play_button, delete_button, episode => move |dl| { + clone!(play_button, delete_button, episode => move |dl| { on_download_clicked( - &db, &pd_title, &mut episode.clone(), dl, @@ -120,7 +118,6 @@ fn epidose_widget(db: &Database, episode: &mut Episode, pd_title: &str) -> gtk:: // TODO: show notification when dl is finished. fn on_download_clicked( - db: &Database, pd_title: &str, ep: &mut Episode, download_bttn: >k::Button, @@ -137,23 +134,20 @@ fn on_download_clicked( let pd_title = pd_title.to_owned(); let mut ep = ep.clone(); - thread::spawn(clone!(db => move || { + thread::spawn(move || { let download_fold = downloader::get_download_folder(&pd_title).unwrap(); - let e = downloader::get_episode(&db, &mut ep, download_fold.as_str()); + let e = downloader::get_episode(&mut ep, download_fold.as_str()); if let Err(err) = e { error!("Error while trying to download: {}", ep.uri()); error!("Error: {}", err); }; sender.send(true).expect("Couldn't send data to channel");; glib::idle_add(receive); - })); + }); } -fn on_play_bttn_clicked(db: &Database, episode_id: i32) { - let local_uri = { - let tempdb = db.lock().unwrap(); - dbqueries::get_episode_local_uri_from_id(&tempdb, episode_id).unwrap() - }; +fn on_play_bttn_clicked(episode_id: i32) { + let local_uri = dbqueries::get_episode_local_uri_from_id(episode_id).unwrap(); if let Some(uri) = local_uri { if Path::new(&uri).exists() { @@ -172,13 +166,10 @@ fn on_play_bttn_clicked(db: &Database, episode_id: i32) { } } -fn on_delete_bttn_clicked(db: &Database, episode_id: i32) { - let mut ep = { - let tempdb = db.lock().unwrap(); - dbqueries::get_episode_from_id(&tempdb, episode_id).unwrap() - }; +fn on_delete_bttn_clicked(episode_id: i32) { + let mut ep = dbqueries::get_episode_from_id(episode_id).unwrap(); - let e = delete_local_content(db, &mut ep); + let e = delete_local_content(&mut ep); if let Err(err) = e { error!("Error while trying to delete file: {:?}", ep.local_uri()); error!("Error: {}", err); @@ -200,14 +191,12 @@ fn receive() -> glib::Continue { glib::Continue(false) } -pub fn episodes_listbox(db: &Database, pd: &Podcast) -> Result { - let conn = db.lock().unwrap(); - let episodes = dbqueries::get_pd_episodes(&conn, pd)?; - drop(conn); +pub fn episodes_listbox(pd: &Podcast) -> Result { + let episodes = dbqueries::get_pd_episodes(pd)?; let list = gtk::ListBox::new(); episodes.into_iter().for_each(|mut ep| { - let w = epidose_widget(db, &mut ep, pd.title()); + let w = epidose_widget(&mut ep, pd.title()); list.add(&w) }); diff --git a/hammond-gtk/src/widgets/podcast.rs b/hammond-gtk/src/widgets/podcast.rs index f7a4047..7801b25 100644 --- a/hammond-gtk/src/widgets/podcast.rs +++ b/hammond-gtk/src/widgets/podcast.rs @@ -6,13 +6,12 @@ use std::fs; use hammond_data::dbqueries; use hammond_data::models::Podcast; -use hammond_data::Database; use hammond_downloader::downloader; use widgets::episode::episodes_listbox; use podcasts_view::update_podcasts_view; -pub fn podcast_widget(db: &Database, stack: >k::Stack, pd: &Podcast) -> gtk::Box { +pub fn podcast_widget(stack: >k::Stack, pd: &Podcast) -> gtk::Box { // Adapted from gnome-music AlbumWidget let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/podcast_widget.ui"); let pd_widget: gtk::Box = builder.get_object("podcast_widget").unwrap(); @@ -25,12 +24,12 @@ pub fn podcast_widget(db: &Database, stack: >k::Stack, pd: &Podcast) -> gtk::B let played_button: gtk::Button = builder.get_object("mark_all_played_button").unwrap(); // TODO: should spawn a thread to avoid locking the UI probably. - unsub_button.connect_clicked(clone!(db, stack, pd => move |bttn| { - on_unsub_button_clicked(&db, &stack, &pd, bttn); + unsub_button.connect_clicked(clone!(stack, pd => move |bttn| { + on_unsub_button_clicked(&stack, &pd, bttn); })); title_label.set_text(pd.title()); - let listbox = episodes_listbox(db, pd); + let listbox = episodes_listbox(pd); if let Ok(l) = listbox { view.add(&l); } @@ -45,22 +44,21 @@ pub fn podcast_widget(db: &Database, stack: >k::Stack, pd: &Podcast) -> gtk::B cover.set_from_pixbuf(&i); } - played_button.connect_clicked(clone!(db, stack, pd => move |_| { - on_played_button_clicked(&db, &stack, &pd); + played_button.connect_clicked(clone!(stack, pd => move |_| { + on_played_button_clicked(&stack, &pd); })); - show_played_button(db, pd, &played_button); + show_played_button(pd, &played_button); pd_widget } fn on_unsub_button_clicked( - db: &Database, stack: >k::Stack, pd: &Podcast, unsub_button: >k::Button, ) { - let res = dbqueries::remove_feed(db, pd); + let res = dbqueries::remove_feed(pd); if res.is_ok() { info!("{} was removed succesfully.", pd.title()); // hack to get away without properly checking for none. @@ -76,23 +74,17 @@ fn on_unsub_button_clicked( }; } stack.set_visible_child_name("fb_parent"); - update_podcasts_view(db, stack); + update_podcasts_view(stack); } -fn on_played_button_clicked(db: &Database, stack: >k::Stack, pd: &Podcast) { - { - let tempdb = db.lock().unwrap(); - let _ = dbqueries::update_none_to_played_now(&tempdb, pd); - } +fn on_played_button_clicked(stack: >k::Stack, pd: &Podcast) { + let _ = dbqueries::update_none_to_played_now(pd); - update_podcast_widget(db, stack, pd); + update_podcast_widget(stack, pd); } -fn show_played_button(db: &Database, pd: &Podcast, played_button: >k::Button) { - let new_episodes = { - let tempdb = db.lock().unwrap(); - dbqueries::get_pd_unplayed_episodes(&tempdb, pd) - }; +fn show_played_button(pd: &Podcast, played_button: >k::Button) { + let new_episodes = dbqueries::get_pd_unplayed_episodes(pd); if let Ok(n) = new_episodes { if !n.is_empty() { @@ -117,9 +109,9 @@ pub fn setup_podcast_widget(stack: >k::Stack) { stack.add_named(&pd_widget, "pdw"); } -pub fn update_podcast_widget(db: &Database, stack: >k::Stack, pd: &Podcast) { +pub fn update_podcast_widget(stack: >k::Stack, pd: &Podcast) { let old = stack.get_child_by_name("pdw").unwrap(); - let pdw = podcast_widget(db, stack, pd); + let pdw = podcast_widget(stack, pd); let vis = stack.get_visible_child_name().unwrap(); stack.remove(&old);