fix: Enable quit on Docker connect error screen
This commit is contained in:
@@ -420,7 +420,7 @@ impl fmt::Display for State {
|
||||
}
|
||||
|
||||
/// Items for the container control list
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum DockerCommand {
|
||||
Pause,
|
||||
Restart,
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ use crate::app_data::DockerCommand;
|
||||
use std::fmt;
|
||||
|
||||
/// app errors to set in global state
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum AppError {
|
||||
DockerCommand(DockerCommand),
|
||||
DockerExec,
|
||||
|
||||
+15
-11
@@ -42,15 +42,17 @@ fn setup_tracing() {
|
||||
tracing_subscriber::fmt().with_max_level(Level::INFO).init();
|
||||
}
|
||||
|
||||
/// Read the optional docker_host path, the DOCKER_HOST env take priority over cli or config
|
||||
/// Read the optional docker_host path
|
||||
/// Bollard will use DOCKER_HOST env, so might be pointless here, although it will fix it's priority over any config setting
|
||||
fn read_docker_host(config: &Config) -> Option<String> {
|
||||
if let Ok(env) = std::env::var(DOCKER_HOST)
|
||||
if let Some(x) = &config.host {
|
||||
Some(x.to_string())
|
||||
} else if let Ok(env) = std::env::var(DOCKER_HOST)
|
||||
&& !env.trim().is_empty()
|
||||
{
|
||||
Some(env)
|
||||
} else {
|
||||
config.host.as_ref().cloned()
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,23 +176,24 @@ mod tests {
|
||||
/// Default test config, has timestamps turned off
|
||||
pub fn gen_config() -> Config {
|
||||
Config {
|
||||
app_colors: AppColors::new(),
|
||||
color_logs: false,
|
||||
dir_save: None,
|
||||
dir_config: None,
|
||||
docker_interval_ms: 1000,
|
||||
gui: true,
|
||||
host: None,
|
||||
show_std_err: false,
|
||||
in_container: false,
|
||||
save_dir: None,
|
||||
keymap: Keymap::new(),
|
||||
log_search_case_sensitive: true,
|
||||
raw_logs: false,
|
||||
show_self: false,
|
||||
app_colors: AppColors::new(),
|
||||
keymap: Keymap::new(),
|
||||
timestamp_format: "HH:MM:SS.NNNNN dd-mm-yyyy".to_owned(),
|
||||
show_timestamp: false,
|
||||
use_cli: false,
|
||||
show_logs: true,
|
||||
show_self: false,
|
||||
show_std_err: false,
|
||||
show_timestamp: false,
|
||||
timestamp_format: "HH:MM:SS.NNNNN dd-mm-yyyy".to_owned(),
|
||||
timezone: None,
|
||||
use_cli: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,6 +219,7 @@ mod tests {
|
||||
containers: StatefulList::new(containers.to_vec()),
|
||||
hidden_containers: vec![],
|
||||
current_sorted_id: vec![],
|
||||
inspect_data: None,
|
||||
error: None,
|
||||
sorted_by: None,
|
||||
rerender: Arc::new(Rerender::new()),
|
||||
|
||||
+20
-15
@@ -32,19 +32,21 @@ pub fn draw(
|
||||
.title_alignment(Alignment::Center)
|
||||
.borders(Borders::ALL);
|
||||
|
||||
let to_push = if matches!(error, AppError::DockerConnect) {
|
||||
let mut text = format!("\n{error}");
|
||||
|
||||
if error == &AppError::DockerConnect {
|
||||
let s = if let Some(host) = host {
|
||||
format!(" @ \"{host}\"")
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
format!(
|
||||
text.push_str(&format!(
|
||||
"{}\n\n {}::v{} closing in {:02} seconds",
|
||||
s,
|
||||
NAME,
|
||||
VERSION,
|
||||
seconds.unwrap_or(5),
|
||||
)
|
||||
))
|
||||
} else {
|
||||
let clear_text = if keymap.clear == Keymap::new().clear {
|
||||
format!("( {} ) {SUFFIX_CLEAR}", keymap.clear.0)
|
||||
@@ -53,6 +55,8 @@ pub fn draw(
|
||||
} else {
|
||||
format!(" ( {} ) {SUFFIX_CLEAR}", keymap.clear.0)
|
||||
};
|
||||
text.push_str(&format!("\n\n{clear_text}"));
|
||||
}
|
||||
|
||||
let quit_text = if keymap.quit == Keymap::new().quit {
|
||||
format!("( {} ) {SUFFIX_QUIT}", keymap.quit.0)
|
||||
@@ -61,12 +65,7 @@ pub fn draw(
|
||||
} else {
|
||||
format!(" ( {} ) {SUFFIX_QUIT}", keymap.quit.0)
|
||||
};
|
||||
format!("\n\n{clear_text}\n\n{quit_text}")
|
||||
};
|
||||
|
||||
let mut text = format!("\n{error}");
|
||||
|
||||
text.push_str(to_push.as_str());
|
||||
text.push_str(&format!("\n\n{quit_text}"));
|
||||
|
||||
// Find the maximum line width & height
|
||||
let padded_width = max_line_width(&text) + 8;
|
||||
@@ -113,7 +112,7 @@ mod tests {
|
||||
#[test]
|
||||
/// Test that the error popup is centered, red background, white border, white text, and displays the correct text
|
||||
fn test_draw_blocks_error_docker_connect_error() {
|
||||
let mut setup = test_setup(46, 9, true, true);
|
||||
let mut setup = test_setup(50, 11, true, true);
|
||||
setup
|
||||
.terminal
|
||||
.draw(|f| {
|
||||
@@ -130,21 +129,24 @@ mod tests {
|
||||
assert_snapshot!(setup.terminal.backend());
|
||||
for (row_index, result_row) in get_result(&setup) {
|
||||
for (result_cell_index, result_cell) in result_row.iter().enumerate() {
|
||||
if let (0 | 8, _) = (row_index, result_cell_index) {
|
||||
match (row_index, result_cell_index) {
|
||||
(0 | 10, _) | (_, 0 | 49) => {
|
||||
assert_eq!(result_cell.bg, Color::Reset);
|
||||
assert_eq!(result_cell.fg, Color::Reset);
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
assert_eq!(result_cell.bg, Color::Red);
|
||||
assert_eq!(result_cell.fg, Color::White);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// Test that the error popup is centered, red background, white border, white text, and displays the correct text with the custom docker host address
|
||||
fn test_draw_blocks_error_docker_connect_error_custom_host() {
|
||||
let mut setup = test_setup(46, 9, true, true);
|
||||
let mut setup = test_setup(60, 11, true, true);
|
||||
|
||||
setup
|
||||
.terminal
|
||||
@@ -162,16 +164,19 @@ mod tests {
|
||||
assert_snapshot!(setup.terminal.backend());
|
||||
for (row_index, result_row) in get_result(&setup) {
|
||||
for (result_cell_index, result_cell) in result_row.iter().enumerate() {
|
||||
if let (0 | 8, _) = (row_index, result_cell_index) {
|
||||
match (row_index, result_cell_index) {
|
||||
(0 | 10, _) | (_, 0 | 59) => {
|
||||
assert_eq!(result_cell.bg, Color::Reset);
|
||||
assert_eq!(result_cell.fg, Color::Reset);
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
assert_eq!(result_cell.bg, Color::Red);
|
||||
assert_eq!(result_cell.fg, Color::White);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// Test that the clearable error popup is centered, red background, white border, white text, and displays the correct text
|
||||
|
||||
+4
-2
@@ -3,11 +3,13 @@ source: src/ui/draw_blocks/error.rs
|
||||
expression: setup.terminal.backend()
|
||||
---
|
||||
" "
|
||||
"╭────────────────── Error ───────────────────╮"
|
||||
" ╭─────────────────── Error ────────────────────╮ "
|
||||
" │ │ "
|
||||
" │ Unable to access docker daemon │ "
|
||||
" │ │ "
|
||||
" │ oxker::v0.00.000 closing in 04 seconds │ "
|
||||
" │ │ "
|
||||
"╰────────────────────────────────────────────╯"
|
||||
" │ ( q ) quit oxker │ "
|
||||
" │ │ "
|
||||
" ╰──────────────────────────────────────────────╯ "
|
||||
" "
|
||||
|
||||
+5
-3
@@ -3,11 +3,13 @@ source: src/ui/draw_blocks/error.rs
|
||||
expression: setup.terminal.backend()
|
||||
---
|
||||
" "
|
||||
"╭────────────────── Error ───────────────────╮"
|
||||
" ╭──────────────────────── Error ─────────────────────────╮ "
|
||||
" │ │ "
|
||||
"│Unable to access docker daemon @ "/test/host│"
|
||||
" │ Unable to access docker daemon @ "/test/host.sock" │ "
|
||||
" │ │ "
|
||||
" │ oxker::v0.00.000 closing in 04 seconds │ "
|
||||
" │ │ "
|
||||
"╰────────────────────────────────────────────╯"
|
||||
" │ ( q ) quit oxker │ "
|
||||
" │ │ "
|
||||
" ╰────────────────────────────────────────────────────────╯ "
|
||||
" "
|
||||
|
||||
+14
-4
@@ -131,12 +131,12 @@ impl Ui {
|
||||
}
|
||||
|
||||
/// Draw the the error message ui, for 5 seconds, with a countdown
|
||||
fn err_loop(&mut self, host: Option<String>) -> Result<(), AppError> {
|
||||
async fn err_loop(&mut self, host: Option<String>) -> Result<(), AppError> {
|
||||
let mut seconds = 5;
|
||||
let colors = self.app_data.lock().config.app_colors;
|
||||
let keymap = self.app_data.lock().config.keymap.clone();
|
||||
let mut redraw = true;
|
||||
loop {
|
||||
while self.is_running.load(Ordering::SeqCst) {
|
||||
if self.now.elapsed() >= std::time::Duration::from_secs(1) {
|
||||
seconds -= 1;
|
||||
self.now = Instant::now();
|
||||
@@ -163,8 +163,18 @@ impl Ui {
|
||||
{
|
||||
return Err(AppError::Terminal);
|
||||
}
|
||||
if crossterm::event::poll(POLL_RATE).unwrap_or(false)
|
||||
&& let Ok(event) = event::read()
|
||||
&& let Event::Key(key) = event
|
||||
&& key.kind == event::KeyEventKind::Press
|
||||
{
|
||||
self.input_tx
|
||||
.send(InputMessages::ButtonPress((key.code, key.modifiers)))
|
||||
.await
|
||||
.ok();
|
||||
}
|
||||
redraw = false;
|
||||
std::thread::sleep(POLL_RATE);
|
||||
// std::thread::sleep(POLL_RATE);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -278,7 +288,7 @@ impl Ui {
|
||||
.iter()
|
||||
.find(|s| matches!(s, Status::DockerConnect(_)))
|
||||
{
|
||||
self.err_loop(msg.clone())?;
|
||||
self.err_loop(msg.clone()).await?;
|
||||
} else {
|
||||
self.gui_loop().await?;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user