Add size field, improve info, fix eject

This commit is contained in:
Lutsai Aleksandr 2025-01-02 02:31:43 +03:00
parent 7746a764f7
commit 69c1ba8dbc
5 changed files with 68 additions and 18 deletions

2
Cargo.lock generated
View file

@ -868,7 +868,7 @@ dependencies = [
[[package]]
name = "mmtui"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"crossterm",
"ratatui",

View file

@ -1,6 +1,6 @@
[package]
name = "mmtui"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
authors = ["Lutsai Aleksandr <s.lyra@ya.ru>"]
description = "Terminal User Interface disk mount manager for TUI file managers"

View file

@ -4,11 +4,13 @@ use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct Block {
pub object_path: String,
pub drive_path: String,
pub dev: String,
pub label: String,
pub mount: Option<String>,
pub fstype: String,
pub mounted: bool,
pub size: String,
}
#[derive(Debug, Clone)]
@ -56,8 +58,14 @@ pub async fn collect_drives_from_udisk() -> udisks2::Result<Vec<Drive>> {
}
} else if let Ok(blk) = i.block().await {
let drv_path = blk.drive().await?.to_string();
let size = if let Ok(size) = blk.size().await {
client.size_for_display(size, true, false)
} else {
String::new()
};
let block = Block {
object_path: path,
drive_path: drv_path.clone(),
dev: String::from_utf8_lossy(&blk.device().await?)
.chars()
.filter(|c| c != &'\0')
@ -66,6 +74,7 @@ pub async fn collect_drives_from_udisk() -> udisks2::Result<Vec<Drive>> {
mount: None,
fstype: blk.id_type().await?,
mounted: false,
size,
};
if let Some(d) = drives.iter_mut().find(|i| i.object_path == drv_path) {
@ -108,11 +117,13 @@ pub async fn collect_all() -> udisks2::Result<Vec<Drive>> {
} else {
fstab.blocks.push(Block {
object_path: String::new(),
drive_path: fstab.object_path.clone(),
dev: i.dev,
label: String::new(),
mount: i.path,
fstype: i.fs,
mounted: i.mounted,
size: String::new(),
});
}
}
@ -151,3 +162,16 @@ pub async fn unmount(block: &Block) -> udisks2::Result<()> {
Ok(())
}
pub async fn eject(block: &Block) -> udisks2::Result<()> {
let client = udisks2::Client::new().await?;
client
.object(block.drive_path.clone())?
.drive()
.await?
.eject(HashMap::new())
.await?;
Ok(())
}

View file

@ -27,8 +27,9 @@ async fn main() -> udisks2::Result<()> {
let s = state.clone();
tokio::spawn(async move {
loop {
let drv = drives::collect_all().await.unwrap();
s.lock().await.clone_from(&drv);
if let Ok(drv) = drives::collect_all().await {
s.lock().await.clone_from(&drv);
};
tokio::time::sleep(Duration::from_millis(500)).await;
}
});

View file

@ -24,7 +24,16 @@ pub struct Tui {
pub last_status: String,
}
const HELP: &str = "j/▲⋮k/▼⋮l/o/▶ - CD⋮m - Mount⋮u - Unmount⋮e - Eject⋮q - Quit";
impl Tui {
fn set_status(&mut self, res: udisks2::Result<()>) {
self.last_status = match res {
Ok(()) => String::from("Ok"),
Err(e) => format!("Error: {e:?}"),
}
}
pub async fn input(&mut self, key: KeyEvent) -> InputResult {
match key.code {
KeyCode::Up | KeyCode::Char('k') => {
@ -37,21 +46,31 @@ impl Tui {
}
KeyCode::Char('m') => {
if let Some(b) = &self.selected {
self.last_status = format!("{:?}", drives::mount(b).await);
self.set_status(drives::mount(b).await);
}
InputResult::None
}
KeyCode::Char('u') => {
if let Some(b) = &self.selected {
self.last_status = format!("{:?}", drives::unmount(b).await);
self.set_status(drives::unmount(b).await);
}
InputResult::None
}
KeyCode::Esc | KeyCode::Char('q') => InputResult::Quit,
KeyCode::Enter => {
let output = self.selected.clone().unwrap().mount.unwrap();
InputResult::QuitChangeDirectory(output)
KeyCode::Char('e') => {
if let Some(b) = &self.selected {
self.set_status(drives::eject(b).await);
}
InputResult::None
}
KeyCode::Enter | KeyCode::Char('l' | 'o') => {
if let Some(s) = &self.selected {
let output = s.clone().mount.unwrap_or_default();
InputResult::QuitChangeDirectory(output)
} else {
InputResult::Quit
}
}
KeyCode::Esc | KeyCode::Char('q') => InputResult::Quit,
_ => InputResult::None,
}
}
@ -81,11 +100,20 @@ impl Tui {
.and_then(|n| rows.get(n).cloned())
.clone_into(&mut self.selected);
let max_size_field_length: u16 = rows
.iter()
.map(|r| r.size.len())
.max()
.unwrap_or(0)
.try_into()
.unwrap_or(0);
let rows = rows.iter().map(|i| {
Row::new(vec![
i.dev.clone(),
i.label.clone(),
i.mount.clone().unwrap_or_default(),
i.size.clone(),
if i.mounted {
"M".to_owned()
} else {
@ -97,7 +125,8 @@ impl Tui {
Constraint::Ratio(1, 3),
Constraint::Ratio(1, 3),
Constraint::Ratio(1, 3),
Constraint::Length(3),
Constraint::Length(max_size_field_length),
Constraint::Length(1),
];
let table = Table::new(rows, widths)
.row_highlight_style(Color::Green)
@ -123,18 +152,14 @@ impl Tui {
};
format!(
"dev: {:?} label: {:?} type: {:?} {mounted} ",
s.dev, s.label, s.fstype
"dev: {:?} label: {:?} type: {:?} size {} {mounted}",
s.dev, s.label, s.fstype, s.size
)
}
None => String::new(),
};
let info = format!(
"j - UP, k - DOWN, l - Goto mountpoint, m - Mount, u - Unmount, e - Eject\n{descr} {:?}",
self.last_status
);
let info = format!("{} | {HELP}\n{descr}", self.last_status);
let info = Paragraph::new(info).wrap(Wrap { trim: true });
frame.render_widget(info, layout[1]);
}