mirror of
https://github.com/SL-RU/mmtui.git
synced 2025-03-04 00:14:45 +01:00
Add size field, improve info, fix eject
This commit is contained in:
parent
7746a764f7
commit
69c1ba8dbc
5 changed files with 68 additions and 18 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -868,7 +868,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mmtui"
|
name = "mmtui"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "mmtui"
|
name = "mmtui"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["Lutsai Aleksandr <s.lyra@ya.ru>"]
|
authors = ["Lutsai Aleksandr <s.lyra@ya.ru>"]
|
||||||
description = "Terminal User Interface disk mount manager for TUI file managers"
|
description = "Terminal User Interface disk mount manager for TUI file managers"
|
||||||
|
|
|
@ -4,11 +4,13 @@ use std::collections::HashMap;
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
pub object_path: String,
|
pub object_path: String,
|
||||||
|
pub drive_path: String,
|
||||||
pub dev: String,
|
pub dev: String,
|
||||||
pub label: String,
|
pub label: String,
|
||||||
pub mount: Option<String>,
|
pub mount: Option<String>,
|
||||||
pub fstype: String,
|
pub fstype: String,
|
||||||
pub mounted: bool,
|
pub mounted: bool,
|
||||||
|
pub size: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[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 {
|
} else if let Ok(blk) = i.block().await {
|
||||||
let drv_path = blk.drive().await?.to_string();
|
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 {
|
let block = Block {
|
||||||
object_path: path,
|
object_path: path,
|
||||||
|
drive_path: drv_path.clone(),
|
||||||
dev: String::from_utf8_lossy(&blk.device().await?)
|
dev: String::from_utf8_lossy(&blk.device().await?)
|
||||||
.chars()
|
.chars()
|
||||||
.filter(|c| c != &'\0')
|
.filter(|c| c != &'\0')
|
||||||
|
@ -66,6 +74,7 @@ pub async fn collect_drives_from_udisk() -> udisks2::Result<Vec<Drive>> {
|
||||||
mount: None,
|
mount: None,
|
||||||
fstype: blk.id_type().await?,
|
fstype: blk.id_type().await?,
|
||||||
mounted: false,
|
mounted: false,
|
||||||
|
size,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(d) = drives.iter_mut().find(|i| i.object_path == drv_path) {
|
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 {
|
} else {
|
||||||
fstab.blocks.push(Block {
|
fstab.blocks.push(Block {
|
||||||
object_path: String::new(),
|
object_path: String::new(),
|
||||||
|
drive_path: fstab.object_path.clone(),
|
||||||
dev: i.dev,
|
dev: i.dev,
|
||||||
label: String::new(),
|
label: String::new(),
|
||||||
mount: i.path,
|
mount: i.path,
|
||||||
fstype: i.fs,
|
fstype: i.fs,
|
||||||
mounted: i.mounted,
|
mounted: i.mounted,
|
||||||
|
size: String::new(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,3 +162,16 @@ pub async fn unmount(block: &Block) -> udisks2::Result<()> {
|
||||||
|
|
||||||
Ok(())
|
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(())
|
||||||
|
}
|
||||||
|
|
|
@ -27,8 +27,9 @@ async fn main() -> udisks2::Result<()> {
|
||||||
let s = state.clone();
|
let s = state.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
let drv = drives::collect_all().await.unwrap();
|
if let Ok(drv) = drives::collect_all().await {
|
||||||
s.lock().await.clone_from(&drv);
|
s.lock().await.clone_from(&drv);
|
||||||
|
};
|
||||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
53
src/tui.rs
53
src/tui.rs
|
@ -24,7 +24,16 @@ pub struct Tui {
|
||||||
pub last_status: String,
|
pub last_status: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const HELP: &str = "j/▲⋮k/▼⋮l/o/▶ - CD⋮m - Mount⋮u - Unmount⋮e - Eject⋮q - Quit";
|
||||||
|
|
||||||
impl Tui {
|
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 {
|
pub async fn input(&mut self, key: KeyEvent) -> InputResult {
|
||||||
match key.code {
|
match key.code {
|
||||||
KeyCode::Up | KeyCode::Char('k') => {
|
KeyCode::Up | KeyCode::Char('k') => {
|
||||||
|
@ -37,21 +46,31 @@ impl Tui {
|
||||||
}
|
}
|
||||||
KeyCode::Char('m') => {
|
KeyCode::Char('m') => {
|
||||||
if let Some(b) = &self.selected {
|
if let Some(b) = &self.selected {
|
||||||
self.last_status = format!("{:?}", drives::mount(b).await);
|
self.set_status(drives::mount(b).await);
|
||||||
}
|
}
|
||||||
InputResult::None
|
InputResult::None
|
||||||
}
|
}
|
||||||
KeyCode::Char('u') => {
|
KeyCode::Char('u') => {
|
||||||
if let Some(b) = &self.selected {
|
if let Some(b) = &self.selected {
|
||||||
self.last_status = format!("{:?}", drives::unmount(b).await);
|
self.set_status(drives::unmount(b).await);
|
||||||
}
|
}
|
||||||
InputResult::None
|
InputResult::None
|
||||||
}
|
}
|
||||||
KeyCode::Esc | KeyCode::Char('q') => InputResult::Quit,
|
KeyCode::Char('e') => {
|
||||||
KeyCode::Enter => {
|
if let Some(b) = &self.selected {
|
||||||
let output = self.selected.clone().unwrap().mount.unwrap();
|
self.set_status(drives::eject(b).await);
|
||||||
InputResult::QuitChangeDirectory(output)
|
|
||||||
}
|
}
|
||||||
|
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,
|
_ => InputResult::None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,11 +100,20 @@ impl Tui {
|
||||||
.and_then(|n| rows.get(n).cloned())
|
.and_then(|n| rows.get(n).cloned())
|
||||||
.clone_into(&mut self.selected);
|
.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| {
|
let rows = rows.iter().map(|i| {
|
||||||
Row::new(vec![
|
Row::new(vec![
|
||||||
i.dev.clone(),
|
i.dev.clone(),
|
||||||
i.label.clone(),
|
i.label.clone(),
|
||||||
i.mount.clone().unwrap_or_default(),
|
i.mount.clone().unwrap_or_default(),
|
||||||
|
i.size.clone(),
|
||||||
if i.mounted {
|
if i.mounted {
|
||||||
"M".to_owned()
|
"M".to_owned()
|
||||||
} else {
|
} else {
|
||||||
|
@ -97,7 +125,8 @@ impl Tui {
|
||||||
Constraint::Ratio(1, 3),
|
Constraint::Ratio(1, 3),
|
||||||
Constraint::Ratio(1, 3),
|
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)
|
let table = Table::new(rows, widths)
|
||||||
.row_highlight_style(Color::Green)
|
.row_highlight_style(Color::Green)
|
||||||
|
@ -123,18 +152,14 @@ impl Tui {
|
||||||
};
|
};
|
||||||
|
|
||||||
format!(
|
format!(
|
||||||
"dev: {:?} label: {:?} type: {:?} {mounted} ",
|
"dev: {:?} label: {:?} type: {:?} size {} {mounted}",
|
||||||
s.dev, s.label, s.fstype
|
s.dev, s.label, s.fstype, s.size
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
None => String::new(),
|
None => String::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let info = format!(
|
let info = format!("{} | {HELP}\n{descr}", self.last_status);
|
||||||
"j - UP, k - DOWN, l - Goto mountpoint, m - Mount, u - Unmount, e - Eject\n{descr} {:?}",
|
|
||||||
self.last_status
|
|
||||||
);
|
|
||||||
|
|
||||||
let info = Paragraph::new(info).wrap(Wrap { trim: true });
|
let info = Paragraph::new(info).wrap(Wrap { trim: true });
|
||||||
frame.render_widget(info, layout[1]);
|
frame.render_widget(info, layout[1]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue