Small upd

This commit is contained in:
Michael Wain 2025-02-17 16:09:56 +03:00
parent d63296d7b4
commit 6b8b4ef355
3 changed files with 122 additions and 37 deletions

74
src/component.rs Normal file
View File

@ -0,0 +1,74 @@
pub mod table {
use ratatui::layout::{Constraint, Rect};
use ratatui::prelude::{Color, Style};
use ratatui::widgets::{Block, Borders, Row, Table};
use ratatui::Frame;
pub struct SmartTable {
header: Vec<String>,
data: Vec<Vec<String>>,
constraints: Vec<Constraint>,
selected_row: i32,
title: String,
}
impl SmartTable {
pub fn new(header: Vec<String>, constraints: Vec<Constraint>) -> Self {
Self {
header,
data: Vec::new(),
constraints,
selected_row: 0,
title: String::new(),
}
}
pub fn set_data(&mut self, data: Vec<Vec<String>>) {
self.data = data;
}
pub fn set_title(&mut self, title: String) {
self.title = title;
}
pub fn previous_row(&mut self) {
self.selected_row = (self.selected_row - 1).max(0);
}
pub fn next_row(&mut self) {
self.selected_row = (self.selected_row + 1).min(self.data.len() as i32 - 1);
}
pub fn selected_row(&self) -> usize {
self.selected_row as usize
}
pub fn render(&self, frame: &mut Frame, area: Rect) {
let mut v = vec![Row::new(self.header.clone()).style(Style::default().fg(Color::Gray))];
for (i, entry) in self.data.iter().enumerate() {
v.push(
Row::new(entry.clone()).style(if self.selected_row as usize == i {
Style::default().bg(Color::LightBlue).fg(Color::White)
} else {
Style::default()
}),
);
}
if self.selected_row as usize > area.rows().count() - 4 {
v = v[(self.selected_row as usize - (area.rows().count() - 4))..].to_vec();
}
let table = Table::new(v, self.constraints.clone())
.block(
Block::default()
.borders(Borders::ALL)
.title(self.title.as_ref()),
)
.style(Style::default().fg(Color::Black));
frame.render_widget(table, area);
}
}
}

View File

@ -1,8 +1,10 @@
use crate::component::table::SmartTable;
use crate::{screen::AppScreen, theme::Theme};
use chrono::{DateTime, Utc};
use crossterm::event::KeyCode;
use ratatui::layout::{Constraint, Direction, Layout, Rect};
use ratatui::prelude::{Color, Line, Style, Stylize};
use ratatui::widgets::{Block, Borders, Paragraph, Row, Table};
use ratatui::prelude::{Line, Stylize};
use ratatui::widgets::Paragraph;
use ratatui::Frame;
use std::cmp::Ordering;
use std::fs::DirEntry;
@ -10,19 +12,38 @@ use std::os::unix::fs::MetadataExt;
use std::path::PathBuf;
pub struct FileSystem {
dir: Vec<DirEntry>,
table: SmartTable,
}
impl Default for FileSystem {
fn default() -> Self {
let mut a = Self { dir: Vec::new() };
let table = SmartTable::new(
["Name", "Type", "Size", "Modified"]
.iter_mut()
.map(|s| s.to_string())
.collect(),
vec![
Constraint::Percentage(50),
Constraint::Length(5),
Constraint::Percentage(20),
Constraint::Percentage(30),
],
);
let mut a = Self { table };
a.get_path(dirs::document_dir().unwrap());
a
}
}
impl AppScreen for FileSystem {
fn handle_key_event(&mut self, key_event: crossterm::event::KeyEvent) {}
fn handle_key_event(&mut self, key_event: crossterm::event::KeyEvent) {
match key_event.code {
KeyCode::Up => self.table.previous_row(),
KeyCode::Down => self.table.next_row(),
_ => {}
}
}
fn render(&self, frame: &mut ratatui::Frame, theme: &Theme) {
let chunks = Layout::default()
@ -58,52 +79,41 @@ impl AppScreen for FileSystem {
impl FileSystem {
fn get_path(&mut self, p: PathBuf) {
let paths = std::fs::read_dir(p).unwrap();
self.dir = paths
let paths = std::fs::read_dir(&p).unwrap();
let mut dir = paths
.filter_map(|res| res.ok())
.filter(|p| p.path().extension().map_or(false, |ext| ext == "mp3") || p.path().is_dir())
.collect();
self.dir.sort_by(|a, b| {
.collect::<Vec<DirEntry>>();
dir.sort_by(|a, _b| {
if a.file_type().unwrap().is_dir() {
Ordering::Less
} else {
Ordering::Greater
}
});
}
fn render_main(&self, frame: &mut Frame, area: Rect) {
let mut v = vec![Row::new(vec!["Name", "Type", "Size", "Modified"])
.style(Style::default().fg(Color::Gray))];
for entry in self.dir.iter() {
let datetime: DateTime<Utc> = entry.metadata().unwrap().modified().unwrap().into();
let datetime = datetime.format("%d/%m/%Y %T").to_string();
let size = entry.metadata().unwrap().size().to_string();
let file_type = entry.file_type().unwrap().is_file().to_string();
v.push(
Row::new(vec![
let dir = dir
.iter()
.map(|entry| {
let datetime: DateTime<Utc> = entry.metadata().unwrap().modified().unwrap().into();
let datetime = datetime.format("%d/%m/%Y %T").to_string();
let size = entry.metadata().unwrap().size().to_string();
let file_type = entry.file_type().unwrap().is_file().to_string();
vec![
entry.file_name().to_str().unwrap().to_string(),
file_type,
size,
datetime,
])
.style(Style::default()),
);
}
]
})
.collect::<Vec<Vec<String>>>();
let table = Table::new(
v,
&[
Constraint::Percentage(50),
Constraint::Length(5),
Constraint::Percentage(20),
Constraint::Percentage(30),
],
)
.block(Block::default().borders(Borders::ALL).title(" Documents "))
.style(Style::default().fg(Color::Black));
self.table.set_data(dir);
self.table
.set_title(p.iter().last().unwrap().to_str().unwrap().to_string());
}
frame.render_widget(table, area);
fn render_main(&self, frame: &mut Frame, area: Rect) {
self.table.render(frame, area);
}
}

View File

@ -24,6 +24,7 @@ use tokio::sync::mpsc::{self, Receiver, UnboundedSender};
use tokio_util::sync::CancellationToken;
use wait_screen::WaitScreen;
mod component;
mod config;
mod dlp;
mod file_system;