diff --git a/win_installer/src/app.rs b/win_installer/src/app.rs index 401ccd2..c98d219 100644 --- a/win_installer/src/app.rs +++ b/win_installer/src/app.rs @@ -262,6 +262,9 @@ impl App { self.last_tick_key_events.drain(..); // Check background task(s) self.tasks.poll()?; + if let Ok(mut wim_sources) = self.state.wim_sources.lock() { + wim_sources.poll(); + } } Action::Quit => self.should_quit = true, Action::Suspend => self.should_suspend = true, diff --git a/win_installer/src/components/wim_scan.rs b/win_installer/src/components/wim_scan.rs index d2c6caf..cb5abc1 100644 --- a/win_installer/src/components/wim_scan.rs +++ b/win_installer/src/components/wim_scan.rs @@ -23,7 +23,7 @@ use color_eyre::Result; use crossterm::event::KeyEvent; use ratatui::{ prelude::*, - widgets::{Block, Borders, Clear, HighlightSpacing, List, ListItem, Padding, Paragraph}, + widgets::{Block, Borders, Clear, List, ListItem, Padding, Paragraph}, }; use tokio::sync::mpsc::UnboundedSender; @@ -111,12 +111,16 @@ impl Component for WimScan { if let Ok(wim_sources) = self.wim_sources.lock() { // Local let mut left_list = Vec::new(); - left_list.extend( - wim_sources - .local - .iter() - .map(|wimfile| ListItem::new(format!("{}\n\n", wimfile.path))), - ); + if wim_sources.thread_local.is_some() { + left_list.push(ListItem::new("Scanning...")); + } else { + left_list.extend( + wim_sources + .local + .iter() + .map(|wimfile| ListItem::new(format!("{}\n\n", wimfile.path))), + ); + } let left_list = List::new(left_list).block( Block::default() .borders(Borders::ALL) @@ -126,12 +130,16 @@ impl Component for WimScan { // Network let mut right_list = Vec::new(); - right_list.extend(wim_sources.network.iter().map(|wimfile| { - ListItem::new(format!( - "{}\n\n", - wimfile.path.split("\\").last().unwrap_or(&wimfile.path) - )) - })); + if wim_sources.thread_network.is_some() { + right_list.push(ListItem::new("Scanning...")); + } else { + right_list.extend(wim_sources.network.iter().map(|wimfile| { + ListItem::new(format!( + "{}\n\n", + wimfile.path.split("\\").last().unwrap_or(&wimfile.path) + )) + })); + } let right_list = List::new(right_list).block( Block::default() .borders(Borders::ALL) diff --git a/win_installer/src/state.rs b/win_installer/src/state.rs index 4c948a8..15536f6 100644 --- a/win_installer/src/state.rs +++ b/win_installer/src/state.rs @@ -90,17 +90,27 @@ impl State { pub fn scan_wim_local(&mut self, scan_type: ScanType) { let disk_list_arc = self.disk_list.clone(); let wim_sources_arc = self.wim_sources.clone(); - tokio::task::spawn(async move { - scan_local_drives(disk_list_arc, wim_sources_arc, scan_type); - }); + let wim_sources_arc_inner = self.wim_sources.clone(); + if let Ok(mut wim_sources) = wim_sources_arc.lock() + && wim_sources.thread_local.is_none() + { + wim_sources.thread_local = Some(tokio::task::spawn(async move { + scan_local_drives(disk_list_arc, wim_sources_arc_inner, scan_type); + })); + } } pub fn scan_wim_network(&mut self) { - let config = self.config.clone(); let wim_sources_arc = self.wim_sources.clone(); - tokio::task::spawn(async move { - scan_network_share(config, wim_sources_arc); - }); + let wim_sources_arc_inner = self.wim_sources.clone(); + if let Ok(mut wim_sources) = wim_sources_arc.lock() + && wim_sources.thread_network.is_none() + { + let config = self.config.clone(); + wim_sources.thread_network = Some(tokio::task::spawn(async move { + scan_network_share(config, wim_sources_arc_inner); + })); + } } } diff --git a/win_installer/src/wim.rs b/win_installer/src/wim.rs index cb44c22..97117ef 100644 --- a/win_installer/src/wim.rs +++ b/win_installer/src/wim.rs @@ -1,4 +1,3 @@ -use core::system::disk::bytes_to_string; // This file is part of Deja-Vu. // // Deja-Vu is free software: you can redistribute it and/or modify it @@ -26,8 +25,11 @@ use std::{ }; use tempfile::NamedTempFile; +use tokio::task::JoinHandle; use xml::reader::{EventReader, XmlEvent}; +use core::system::disk::bytes_to_string; + static WIMINFO_EXE: LazyLock = LazyLock::new(|| { let program_files = PathBuf::from(env::var("PROGRAMFILES").expect("Failed to resolve %PROGRAMFILES%")); @@ -156,6 +158,8 @@ impl fmt::Display for WimImage { pub struct WimSources { pub local: Vec, pub network: Vec, + pub thread_local: Option>, + pub thread_network: Option>, } impl WimSources { @@ -187,6 +191,23 @@ impl WimSources { list } + pub fn poll(&mut self) { + let thread = self.thread_local.take(); + if let Some(local) = thread + && !local.is_finished() + { + // Task still going, keep tracking + self.thread_local = Some(local); + } + let thread = self.thread_network.take(); + if let Some(network) = thread + && !network.is_finished() + { + // Task still going, keep tracking + self.thread_network = Some(network); + } + } + pub fn reset_all(&mut self) { self.local.clear(); self.network.clear();