deja-vu/win_installer/src/components/wim_scan.rs

154 lines
4.9 KiB
Rust

// This file is part of Deja-Vu.
//
// Deja-Vu is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Deja-Vu is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
//
use core::{action::Action, components::Component, config::Config, state::Mode};
use std::{
iter::zip,
sync::{Arc, Mutex},
};
use color_eyre::Result;
use crossterm::event::KeyEvent;
use ratatui::{
prelude::*,
widgets::{Block, Borders, Clear, List, ListItem, Padding, Paragraph},
};
use tokio::sync::mpsc::UnboundedSender;
use crate::wim::WimSources;
#[derive(Default)]
pub struct WimScan {
command_tx: Option<UnboundedSender<Action>>,
config: Config,
mode: Mode,
scan_network: bool,
wim_sources: Arc<Mutex<WimSources>>,
}
impl WimScan {
#[must_use]
pub fn new(wim_sources: Arc<Mutex<WimSources>>) -> Self {
let wim_sources = wim_sources.clone();
Self {
wim_sources,
..Default::default()
}
}
}
impl Component for WimScan {
fn handle_key_event(&mut self, key: KeyEvent) -> Result<Option<Action>> {
let _ = key; // to appease clippy
Ok(None)
}
fn register_action_handler(&mut self, tx: UnboundedSender<Action>) -> Result<()> {
self.command_tx = Some(tx);
Ok(())
}
fn register_config_handler(&mut self, config: Config) -> Result<()> {
self.config = config;
Ok(())
}
fn update(&mut self, action: Action) -> Result<Option<Action>> {
match action {
Action::FindWimNetwork => self.scan_network = true,
Action::SetMode(new_mode) => {
self.mode = new_mode;
}
_ => {}
}
Ok(None)
}
fn draw(&mut self, frame: &mut Frame, area: Rect) -> Result<()> {
if self.mode != Mode::ScanWinSources {
return Ok(());
}
frame.render_widget(Clear, area);
// Prep
let [left, right] = Layout::default()
.direction(Direction::Horizontal)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
.areas(area);
let [left_title, left_body] = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Length(1), Constraint::Min(1)])
.areas(left);
let [right_title, right_body] = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Length(1), Constraint::Min(1)])
.areas(right);
// Titles
let titles = vec![
Paragraph::new(Line::from("Local").centered())
.block(Block::default().borders(Borders::NONE)),
Paragraph::new(Line::from("Network").centered())
.block(Block::default().borders(Borders::NONE)),
];
for (title, area) in zip(titles, [left_title, right_title]) {
frame.render_widget(title, area);
}
// WIM Info
if let Ok(wim_sources) = self.wim_sources.lock() {
// Local
let mut left_list = Vec::new();
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)
.padding(Padding::new(1, 1, 1, 1)),
);
frame.render_widget(left_list, left_body);
// Network
let mut right_list = Vec::new();
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)
.padding(Padding::new(1, 1, 1, 1)),
);
frame.render_widget(right_list, right_body);
}
// Done
Ok(())
}
}