fix: memory column aligned, closes #20
This commit is contained in:
+23
-20
@@ -55,7 +55,7 @@ fn generate_block<'a>(
|
|||||||
.lock()
|
.lock()
|
||||||
.update_heading_map(Region::Panel(panel), area);
|
.update_heading_map(Region::Panel(panel), area);
|
||||||
let current_selected_panel = gui_state.lock().selected_panel;
|
let current_selected_panel = gui_state.lock().selected_panel;
|
||||||
let title = match panel {
|
let mut title = match panel {
|
||||||
SelectablePanel::Containers => {
|
SelectablePanel::Containers => {
|
||||||
format!(
|
format!(
|
||||||
"{} {}",
|
"{} {}",
|
||||||
@@ -68,6 +68,9 @@ fn generate_block<'a>(
|
|||||||
}
|
}
|
||||||
SelectablePanel::Commands => String::new(),
|
SelectablePanel::Commands => String::new(),
|
||||||
};
|
};
|
||||||
|
if !title.is_empty() {
|
||||||
|
title = format!(" {title} ");
|
||||||
|
}
|
||||||
let mut block = Block::default()
|
let mut block = Block::default()
|
||||||
.borders(Borders::ALL)
|
.borders(Borders::ALL)
|
||||||
.border_type(BorderType::Rounded)
|
.border_type(BorderType::Rounded)
|
||||||
@@ -136,19 +139,21 @@ pub fn containers<B: Backend>(
|
|||||||
let state_style = Style::default().fg(i.state.get_color());
|
let state_style = Style::default().fg(i.state.get_color());
|
||||||
let blue = Style::default().fg(Color::Blue);
|
let blue = Style::default().fg(Color::Blue);
|
||||||
|
|
||||||
// let mems = format!(
|
|
||||||
// "{:>1} / {:>1}",
|
|
||||||
// i.mem_stats.back().unwrap_or(&ByteStats::default()),
|
|
||||||
// i.mem_limit
|
|
||||||
// );
|
|
||||||
|
|
||||||
let lines = Spans::from(vec![
|
let lines = Spans::from(vec![
|
||||||
Span::styled(
|
Span::styled(
|
||||||
format!("{:<width$}", i.state.to_string(), width = widths.state.1.into()),
|
format!(
|
||||||
|
"{:<width$}",
|
||||||
|
i.state.to_string(),
|
||||||
|
width = widths.state.1.into()
|
||||||
|
),
|
||||||
state_style,
|
state_style,
|
||||||
),
|
),
|
||||||
Span::styled(
|
Span::styled(
|
||||||
format!("{MARGIN}{:>width$}", i.status, width = &widths.status.1.into()),
|
format!(
|
||||||
|
"{MARGIN}{:>width$}",
|
||||||
|
i.status,
|
||||||
|
width = &widths.status.1.into()
|
||||||
|
),
|
||||||
state_style,
|
state_style,
|
||||||
),
|
),
|
||||||
Span::styled(
|
Span::styled(
|
||||||
@@ -161,7 +166,13 @@ pub fn containers<B: Backend>(
|
|||||||
state_style,
|
state_style,
|
||||||
),
|
),
|
||||||
Span::styled(
|
Span::styled(
|
||||||
format!("{MARGIN}{:>width_current$} / {:>width_limit$}", i.mem_stats.back().unwrap_or(&ByteStats::default()), i.mem_limit, width_current = &widths.mem.1.into(), width_limit = &widths.mem.2.into()),
|
format!(
|
||||||
|
"{MARGIN}{:>width_current$} / {:>width_limit$}",
|
||||||
|
i.mem_stats.back().unwrap_or(&ByteStats::default()),
|
||||||
|
i.mem_limit,
|
||||||
|
width_current = &widths.mem.1.into(),
|
||||||
|
width_limit = &widths.mem.2.into()
|
||||||
|
),
|
||||||
state_style,
|
state_style,
|
||||||
),
|
),
|
||||||
Span::styled(
|
Span::styled(
|
||||||
@@ -226,22 +237,14 @@ pub fn logs<B: Backend>(
|
|||||||
.alignment(Alignment::Center);
|
.alignment(Alignment::Center);
|
||||||
f.render_widget(paragraph, area);
|
f.render_widget(paragraph, area);
|
||||||
} else if let Some(index) = index {
|
} else if let Some(index) = index {
|
||||||
let items = app_data.lock().containers.items[index]
|
let items = List::new(app_data.lock().containers.items[index].logs.to_vec())
|
||||||
.logs
|
|
||||||
.items
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|i| i.1.clone())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let items = List::new(items)
|
|
||||||
.block(block)
|
.block(block)
|
||||||
.highlight_symbol(ARROW)
|
.highlight_symbol(ARROW)
|
||||||
.highlight_style(Style::default().add_modifier(Modifier::BOLD));
|
.highlight_style(Style::default().add_modifier(Modifier::BOLD));
|
||||||
f.render_stateful_widget(
|
f.render_stateful_widget(
|
||||||
items,
|
items,
|
||||||
area,
|
area,
|
||||||
&mut app_data.lock().containers.items[index].logs.state,
|
app_data.lock().containers.items[index].logs.state(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let paragraph = Paragraph::new("no logs found")
|
let paragraph = Paragraph::new("no logs found")
|
||||||
|
|||||||
+22
-28
@@ -6,7 +6,7 @@ use crossterm::{
|
|||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::{
|
use std::{
|
||||||
io,
|
io::{self, Write},
|
||||||
sync::{atomic::Ordering, Arc},
|
sync::{atomic::Ordering, Arc},
|
||||||
};
|
};
|
||||||
use std::{sync::atomic::AtomicBool, time::Instant};
|
use std::{sync::atomic::AtomicBool, time::Instant};
|
||||||
@@ -31,11 +31,10 @@ use crate::{
|
|||||||
/// Take control of the terminal in order to draw gui
|
/// Take control of the terminal in order to draw gui
|
||||||
pub async fn create_ui(
|
pub async fn create_ui(
|
||||||
app_data: Arc<Mutex<AppData>>,
|
app_data: Arc<Mutex<AppData>>,
|
||||||
sender: Sender<InputMessages>,
|
|
||||||
is_running: Arc<AtomicBool>,
|
|
||||||
gui_state: Arc<Mutex<GuiState>>,
|
|
||||||
docker_sx: Sender<DockerMessage>,
|
docker_sx: Sender<DockerMessage>,
|
||||||
// update_duration: Duration,
|
gui_state: Arc<Mutex<GuiState>>,
|
||||||
|
is_running: Arc<AtomicBool>,
|
||||||
|
sender: Sender<InputMessages>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
enable_raw_mode()?;
|
enable_raw_mode()?;
|
||||||
let mut stdout = io::stdout();
|
let mut stdout = io::stdout();
|
||||||
@@ -44,16 +43,14 @@ pub async fn create_ui(
|
|||||||
let mut terminal = Terminal::new(backend)?;
|
let mut terminal = Terminal::new(backend)?;
|
||||||
|
|
||||||
let res = run_app(
|
let res = run_app(
|
||||||
&mut terminal,
|
|
||||||
app_data,
|
app_data,
|
||||||
sender,
|
|
||||||
is_running,
|
|
||||||
gui_state,
|
|
||||||
docker_sx,
|
docker_sx,
|
||||||
|
gui_state,
|
||||||
|
is_running,
|
||||||
|
sender,
|
||||||
|
&mut terminal,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
terminal.clear()?;
|
|
||||||
|
|
||||||
disable_raw_mode()?;
|
disable_raw_mode()?;
|
||||||
execute!(
|
execute!(
|
||||||
terminal.backend_mut(),
|
terminal.backend_mut(),
|
||||||
@@ -65,46 +62,43 @@ pub async fn create_ui(
|
|||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
println!("{err}");
|
println!("{err}");
|
||||||
}
|
}
|
||||||
|
std::io::stdout().flush().unwrap_or(());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run a loop to draw the gui
|
/// Run a loop to draw the gui
|
||||||
async fn run_app<B: Backend + Send>(
|
async fn run_app<B: Backend + Send>(
|
||||||
terminal: &mut Terminal<B>,
|
|
||||||
app_data: Arc<Mutex<AppData>>,
|
app_data: Arc<Mutex<AppData>>,
|
||||||
sender: Sender<InputMessages>,
|
|
||||||
is_running: Arc<AtomicBool>,
|
|
||||||
gui_state: Arc<Mutex<GuiState>>,
|
|
||||||
docker_sx: Sender<DockerMessage>,
|
docker_sx: Sender<DockerMessage>,
|
||||||
|
gui_state: Arc<Mutex<GuiState>>,
|
||||||
|
is_running: Arc<AtomicBool>,
|
||||||
|
sender: Sender<InputMessages>,
|
||||||
|
terminal: &mut Terminal<B>,
|
||||||
) -> Result<(), AppError> {
|
) -> Result<(), AppError> {
|
||||||
let update_duration =
|
let update_duration =
|
||||||
std::time::Duration::from_millis(u64::from(app_data.lock().args.docker_interval));
|
std::time::Duration::from_millis(u64::from(app_data.lock().args.docker_interval));
|
||||||
let input_poll_rate = std::time::Duration::from_millis(75);
|
let input_poll_rate = std::time::Duration::from_millis(75);
|
||||||
let status_dockerconnect = gui_state.lock().status_contains(&[Status::DockerConnect]);
|
let status_dockerconnect = gui_state.lock().status_contains(&[Status::DockerConnect]);
|
||||||
|
let mut now = Instant::now();
|
||||||
if status_dockerconnect {
|
if status_dockerconnect {
|
||||||
let mut seconds = 5;
|
let mut seconds = 5;
|
||||||
loop {
|
loop {
|
||||||
if seconds < 1 {
|
if seconds < 1 {
|
||||||
is_running.store(false, Ordering::Relaxed);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if now.elapsed() >= std::time::Duration::from_secs(1) {
|
||||||
|
seconds -= 1;
|
||||||
|
now = Instant::now();
|
||||||
|
}
|
||||||
if terminal
|
if terminal
|
||||||
.draw(|f| draw_blocks::error(f, AppError::DockerConnect, Some(seconds)))
|
.draw(|f| draw_blocks::error(f, AppError::DockerConnect, Some(seconds)))
|
||||||
.is_err()
|
.is_err()
|
||||||
{
|
{
|
||||||
return Err(AppError::Terminal);
|
return Err(AppError::Terminal);
|
||||||
}
|
}
|
||||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
|
||||||
seconds -= 1;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut now = Instant::now();
|
while is_running.load(Ordering::Relaxed) {
|
||||||
loop {
|
|
||||||
if terminal.draw(|f| ui(f, &app_data, &gui_state)).is_err() {
|
|
||||||
return Err(AppError::Terminal);
|
|
||||||
}
|
|
||||||
// TODO could only draw if in gui mode, that way all inputs & docker commands will run, and can just trace!("{event"}) all over the place
|
|
||||||
// refactor this into own function, so can be called without drawing to the terminal
|
|
||||||
if crossterm::event::poll(input_poll_rate).unwrap_or(false) {
|
if crossterm::event::poll(input_poll_rate).unwrap_or(false) {
|
||||||
if let Ok(event) = event::read() {
|
if let Ok(event) = event::read() {
|
||||||
if let Event::Key(key) = event {
|
if let Event::Key(key) = event {
|
||||||
@@ -128,12 +122,12 @@ async fn run_app<B: Backend + Send>(
|
|||||||
docker_sx.send(DockerMessage::Update).await.unwrap_or(());
|
docker_sx.send(DockerMessage::Update).await.unwrap_or(());
|
||||||
now = Instant::now();
|
now = Instant::now();
|
||||||
}
|
}
|
||||||
|
if terminal.draw(|f| ui(f, &app_data, &gui_state)).is_err() {
|
||||||
if !is_running.load(Ordering::Relaxed) {
|
return Err(AppError::Terminal);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
terminal.clear().unwrap_or(());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user