Track WIM scans to avoid stacking scans

This commit is contained in:
2Shirt 2025-12-04 22:36:38 -08:00
parent c4c174b546
commit 87ccc80602
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
4 changed files with 63 additions and 21 deletions

View file

@ -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,

View file

@ -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)

View file

@ -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);
}));
}
}
}

View file

@ -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<String> = 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<WimFile>,
pub network: Vec<WimFile>,
pub thread_local: Option<JoinHandle<()>>,
pub thread_network: Option<JoinHandle<()>>,
}
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();