Added some better theming to the UI, enabled clippy to warn on 2018 idioms, and added human_panic hook to report bugs
This commit is contained in:
+3
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "managarr"
|
name = "managarr"
|
||||||
version = "0.1.11"
|
version = "0.0.12"
|
||||||
authors = ["Alex Clarke <alex.j.tusa@gmail.com>"]
|
authors = ["Alex Clarke <alex.j.tusa@gmail.com>"]
|
||||||
description = "A TUI for managing *arr servers"
|
description = "A TUI for managing *arr servers"
|
||||||
keywords = ["managarr", "tui-rs", "dashboard", "servarr"]
|
keywords = ["managarr", "tui-rs", "dashboard", "servarr"]
|
||||||
@@ -12,11 +12,13 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.68"
|
anyhow = "1.0.68"
|
||||||
|
backtrace = "0.3.67"
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
clap = { version = "4.0.30", features = ["help", "usage", "error-context", "derive"] }
|
clap = { version = "4.0.30", features = ["help", "usage", "error-context", "derive"] }
|
||||||
confy = { version = "0.5.1", default_features = false, features = ["yaml_conf"] }
|
confy = { version = "0.5.1", default_features = false, features = ["yaml_conf"] }
|
||||||
crossterm = "0.26.1"
|
crossterm = "0.26.1"
|
||||||
derivative = "2.2.0"
|
derivative = "2.2.0"
|
||||||
|
human-panic = "1.1.3"
|
||||||
indoc = "2.0.0"
|
indoc = "2.0.0"
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
log4rs = { version = "1.2.0", features = ["file_appender"] }
|
log4rs = { version = "1.2.0", features = ["file_appender"] }
|
||||||
|
|||||||
+51
-2
@@ -1,7 +1,8 @@
|
|||||||
extern crate core;
|
#![warn(rust_2018_idioms)]
|
||||||
|
|
||||||
use std::io;
|
use std::panic::PanicInfo;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::{io, panic};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
@@ -36,6 +37,9 @@ struct Cli {}
|
|||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
log4rs::init_config(utils::init_logging_config())?;
|
log4rs::init_config(utils::init_logging_config())?;
|
||||||
|
panic::set_hook(Box::new(|info| {
|
||||||
|
panic_hook(info);
|
||||||
|
}));
|
||||||
Cli::parse();
|
Cli::parse();
|
||||||
|
|
||||||
let config = confy::load("managarr", "config")?;
|
let config = confy::load("managarr", "config")?;
|
||||||
@@ -105,3 +109,48 @@ async fn start_ui(app: &Arc<Mutex<App>>) -> Result<()> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
fn panic_hook(info: &PanicInfo<'_>) {
|
||||||
|
use backtrace::Backtrace;
|
||||||
|
use crossterm::style::Print;
|
||||||
|
|
||||||
|
let location = info.location().unwrap();
|
||||||
|
|
||||||
|
let msg = match info.payload().downcast_ref::<&'static str>() {
|
||||||
|
Some(s) => *s,
|
||||||
|
None => match info.payload().downcast_ref::<String>() {
|
||||||
|
Some(s) => &s[..],
|
||||||
|
None => "Box<Any>",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let stacktrace: String = format!("{:?}", Backtrace::new()).replace('\n', "\n\r");
|
||||||
|
|
||||||
|
disable_raw_mode().unwrap();
|
||||||
|
execute!(
|
||||||
|
io::stdout(),
|
||||||
|
LeaveAlternateScreen,
|
||||||
|
Print(format!(
|
||||||
|
"thread '<unnamed>' panicked at '{}', {}\n\r{}",
|
||||||
|
msg, location, stacktrace
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
fn panic_hook(info: &PanicInfo<'_>) {
|
||||||
|
use human_panic::{handle_dump, print_msg, Metadata};
|
||||||
|
|
||||||
|
let meta = Metadata {
|
||||||
|
version: env!("CARGO_PKG_VERSION").into(),
|
||||||
|
name: env!("CARGO_PKG_NAME").into(),
|
||||||
|
authors: env!("CARGO_PKG_AUTHORS").replace(":", ", ").into(),
|
||||||
|
homepage: env!("CARGO_PKG_HOMEPAGE").into(),
|
||||||
|
};
|
||||||
|
let file_path = handle_dump(&meta, info);
|
||||||
|
disable_raw_mode().unwrap();
|
||||||
|
execute!(io::stdout(), LeaveAlternateScreen).unwrap();
|
||||||
|
print_msg(file_path, &meta).expect("human-panic: printing error message to console failed");
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -43,7 +43,7 @@ impl<'a> Network<'a> {
|
|||||||
pub async fn handle_request<T, R>(
|
pub async fn handle_request<T, R>(
|
||||||
&self,
|
&self,
|
||||||
request_props: RequestProps<T>,
|
request_props: RequestProps<T>,
|
||||||
mut app_update_fn: impl FnMut(R, MutexGuard<App>),
|
mut app_update_fn: impl FnMut(R, MutexGuard<'_, App>),
|
||||||
) where
|
) where
|
||||||
T: Serialize + Default + Debug,
|
T: Serialize + Default + Debug,
|
||||||
R: DeserializeOwned,
|
R: DeserializeOwned,
|
||||||
|
|||||||
+36
-33
@@ -13,12 +13,12 @@ use tui::Frame;
|
|||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::models::{Route, StatefulList, StatefulTable, TabState};
|
use crate::models::{Route, StatefulList, StatefulTable, TabState};
|
||||||
use crate::ui::utils::{
|
use crate::ui::utils::{
|
||||||
borderless_block, centered_rect, horizontal_chunks, horizontal_chunks_with_margin, layout_block,
|
background_block, borderless_block, centered_rect, horizontal_chunks,
|
||||||
layout_block_top_border, layout_button_paragraph, layout_button_paragraph_borderless,
|
horizontal_chunks_with_margin, layout_block, layout_block_top_border, layout_button_paragraph,
|
||||||
layout_paragraph_borderless, logo_block, show_cursor, style_block_highlight, style_default,
|
layout_button_paragraph_borderless, layout_paragraph_borderless, logo_block, show_cursor,
|
||||||
style_default_bold, style_failure, style_help, style_highlight, style_primary, style_secondary,
|
style_block_highlight, style_default, style_default_bold, style_failure, style_help,
|
||||||
style_system_function, title_block, title_block_centered, vertical_chunks,
|
style_highlight, style_primary, style_secondary, style_system_function, title_block,
|
||||||
vertical_chunks_with_margin,
|
title_block_centered, vertical_chunks, vertical_chunks_with_margin,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod radarr_ui;
|
mod radarr_ui;
|
||||||
@@ -26,7 +26,8 @@ mod utils;
|
|||||||
|
|
||||||
static HIGHLIGHT_SYMBOL: &str = "=> ";
|
static HIGHLIGHT_SYMBOL: &str = "=> ";
|
||||||
|
|
||||||
pub fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
|
pub fn ui<B: Backend>(f: &mut Frame<'_, B>, app: &mut App) {
|
||||||
|
f.render_widget(background_block(), f.size());
|
||||||
let main_chunks = if !app.error.text.is_empty() {
|
let main_chunks = if !app.error.text.is_empty() {
|
||||||
let chunks = vertical_chunks_with_margin(
|
let chunks = vertical_chunks_with_margin(
|
||||||
vec![
|
vec![
|
||||||
@@ -115,6 +116,7 @@ pub fn draw_popup<B: Backend>(
|
|||||||
) {
|
) {
|
||||||
let popup_area = centered_rect(percent_x, percent_y, f.size());
|
let popup_area = centered_rect(percent_x, percent_y, f.size());
|
||||||
f.render_widget(Clear, popup_area);
|
f.render_widget(Clear, popup_area);
|
||||||
|
f.render_widget(background_block(), popup_area);
|
||||||
popup_fn(f, app, popup_area);
|
popup_fn(f, app, popup_area);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,6 +190,31 @@ fn draw_context_row<B: Backend>(f: &mut Frame<'_, B>, app: &App, area: Rect) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn draw_error_popup_over<B: Backend>(
|
||||||
|
f: &mut Frame<'_, B>,
|
||||||
|
app: &mut App,
|
||||||
|
area: Rect,
|
||||||
|
message: &str,
|
||||||
|
background_fn: fn(&mut Frame<'_, B>, &mut App, Rect),
|
||||||
|
) {
|
||||||
|
background_fn(f, app, area);
|
||||||
|
draw_error_popup(f, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_error_popup<B: Backend>(f: &mut Frame<'_, B>, message: &str) {
|
||||||
|
let prompt_area = centered_rect(25, 8, f.size());
|
||||||
|
f.render_widget(Clear, prompt_area);
|
||||||
|
f.render_widget(background_block(), prompt_area);
|
||||||
|
|
||||||
|
let error_message = Paragraph::new(Text::from(message))
|
||||||
|
.block(title_block_centered("Error").style(style_failure()))
|
||||||
|
.style(style_failure().add_modifier(Modifier::BOLD))
|
||||||
|
.wrap(Wrap { trim: false })
|
||||||
|
.alignment(Alignment::Center);
|
||||||
|
|
||||||
|
f.render_widget(error_message, prompt_area);
|
||||||
|
}
|
||||||
|
|
||||||
fn draw_tabs<'a, B: Backend>(
|
fn draw_tabs<'a, B: Backend>(
|
||||||
f: &mut Frame<'_, B>,
|
f: &mut Frame<'_, B>,
|
||||||
area: Rect,
|
area: Rect,
|
||||||
@@ -234,7 +261,7 @@ pub struct TableProps<'a, T> {
|
|||||||
fn draw_table<'a, B, T, F>(
|
fn draw_table<'a, B, T, F>(
|
||||||
f: &mut Frame<'_, B>,
|
f: &mut Frame<'_, B>,
|
||||||
content_area: Rect,
|
content_area: Rect,
|
||||||
block: Block,
|
block: Block<'_>,
|
||||||
table_props: TableProps<'a, T>,
|
table_props: TableProps<'a, T>,
|
||||||
row_mapper: F,
|
row_mapper: F,
|
||||||
is_loading: bool,
|
is_loading: bool,
|
||||||
@@ -302,30 +329,6 @@ pub fn loading<B: Backend>(f: &mut Frame<'_, B>, block: Block<'_>, area: Rect, i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_error_popup_over<B: Backend>(
|
|
||||||
f: &mut Frame<'_, B>,
|
|
||||||
app: &mut App,
|
|
||||||
area: Rect,
|
|
||||||
message: &str,
|
|
||||||
background_fn: fn(&mut Frame<'_, B>, &mut App, Rect),
|
|
||||||
) {
|
|
||||||
background_fn(f, app, area);
|
|
||||||
draw_error_popup(f, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn draw_error_popup<B: Backend>(f: &mut Frame<'_, B>, message: &str) {
|
|
||||||
let prompt_area = centered_rect(25, 8, f.size());
|
|
||||||
f.render_widget(Clear, prompt_area);
|
|
||||||
|
|
||||||
let error_message = Paragraph::new(Text::from(message))
|
|
||||||
.block(title_block_centered("Error").style(style_failure()))
|
|
||||||
.style(style_failure().add_modifier(Modifier::BOLD))
|
|
||||||
.wrap(Wrap { trim: false })
|
|
||||||
.alignment(Alignment::Center);
|
|
||||||
|
|
||||||
f.render_widget(error_message, prompt_area);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn draw_prompt_box<B: Backend>(
|
pub fn draw_prompt_box<B: Backend>(
|
||||||
f: &mut Frame<'_, B>,
|
f: &mut Frame<'_, B>,
|
||||||
prompt_area: Rect,
|
prompt_area: Rect,
|
||||||
@@ -341,7 +344,7 @@ pub fn draw_prompt_box_with_content<B: Backend>(
|
|||||||
prompt_area: Rect,
|
prompt_area: Rect,
|
||||||
title: &str,
|
title: &str,
|
||||||
prompt: &str,
|
prompt: &str,
|
||||||
content: Option<Paragraph>,
|
content: Option<Paragraph<'_>>,
|
||||||
yes_no_value: &bool,
|
yes_no_value: &bool,
|
||||||
) {
|
) {
|
||||||
f.render_widget(title_block_centered(title), prompt_area);
|
f.render_widget(title_block_centered(title), prompt_area);
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ fn draw_movie_details<B: Backend>(f: &mut Frame<'_, B>, app: &App, content_area:
|
|||||||
|
|
||||||
spans_info_default(title, split[1..].join(":"))
|
spans_info_default(title, split[1..].join(":"))
|
||||||
})
|
})
|
||||||
.collect::<Vec<Spans>>(),
|
.collect::<Vec<Spans<'_>>>(),
|
||||||
);
|
);
|
||||||
text.patch_style(determine_style_from_download_status(download_status));
|
text.patch_style(determine_style_from_download_status(download_status));
|
||||||
|
|
||||||
@@ -508,7 +508,7 @@ fn draw_manual_search_confirm_prompt<B: Backend>(
|
|||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|item| Spans::from(vec![Span::styled(format!("• {}", item), style_primary())]))
|
.map(|item| Spans::from(vec![Span::styled(format!("• {}", item), style_primary())]))
|
||||||
.collect::<Vec<Spans>>();
|
.collect::<Vec<Spans<'_>>>();
|
||||||
spans_vec.append(&mut rejections_spans);
|
spans_vec.append(&mut rejections_spans);
|
||||||
|
|
||||||
let content_paragraph = Paragraph::new(spans_vec)
|
let content_paragraph = Paragraph::new(spans_vec)
|
||||||
|
|||||||
+48
-18
@@ -5,6 +5,23 @@ use tui::text::{Span, Spans, Text};
|
|||||||
use tui::widgets::{Block, BorderType, Borders, LineGauge, Paragraph, Wrap};
|
use tui::widgets::{Block, BorderType, Borders, LineGauge, Paragraph, Wrap};
|
||||||
use tui::{symbols, Frame};
|
use tui::{symbols, Frame};
|
||||||
|
|
||||||
|
pub const COLOR_TEAL: Color = Color::Rgb(35, 50, 55);
|
||||||
|
// pub const COLOR_CYAN: Color = Color::Rgb(0, 230, 230);
|
||||||
|
pub const COLOR_CYAN: Color = Color::Cyan;
|
||||||
|
// pub const COLOR_LIGHT_BLUE: Color = Color::Rgb(138, 196, 255);
|
||||||
|
pub const COLOR_LIGHT_BLUE: Color = Color::LightBlue;
|
||||||
|
// pub const COLOR_YELLOW: Color = Color::Rgb(249, 229, 113);
|
||||||
|
pub const COLOR_YELLOW: Color = Color::Yellow;
|
||||||
|
// pub const COLOR_GREEN: Color = Color::Rgb(72, 213, 150);
|
||||||
|
pub const COLOR_GREEN: Color = Color::Green;
|
||||||
|
// pub const COLOR_RED: Color = Color::Rgb(249, 140, 164);
|
||||||
|
pub const COLOR_RED: Color = Color::Red;
|
||||||
|
// pub const COLOR_ORANGE: Color = Color::Rgb(255, 170, 66);
|
||||||
|
// pub const COLOR_WHITE: Color = Color::Rgb(255, 255, 255);
|
||||||
|
pub const COLOR_WHITE: Color = Color::White;
|
||||||
|
// pub const COLOR_MAGENTA: Color = Color::Rgb(139, 0, 139);
|
||||||
|
pub const COLOR_MAGENTA: Color = Color::Magenta;
|
||||||
|
|
||||||
pub fn horizontal_chunks(constraints: Vec<Constraint>, area: Rect) -> Vec<Rect> {
|
pub fn horizontal_chunks(constraints: Vec<Constraint>, area: Rect) -> Vec<Rect> {
|
||||||
layout_with_constraints(constraints)
|
layout_with_constraints(constraints)
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
@@ -45,6 +62,10 @@ fn layout_with_constraints(constraints: Vec<Constraint>) -> Layout {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn background_block<'a>() -> Block<'a> {
|
||||||
|
Block::default().style(Style::default().bg(COLOR_TEAL).fg(COLOR_WHITE))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn layout_block<'a>() -> Block<'a> {
|
pub fn layout_block<'a>() -> Block<'a> {
|
||||||
Block::default()
|
Block::default()
|
||||||
.borders(Borders::ALL)
|
.borders(Borders::ALL)
|
||||||
@@ -67,7 +88,11 @@ pub fn layout_block_bottom_border<'a>() -> Block<'a> {
|
|||||||
Block::default().borders(Borders::BOTTOM)
|
Block::default().borders(Borders::BOTTOM)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout_button_paragraph(is_selected: bool, label: &str, alignment: Alignment) -> Paragraph {
|
pub fn layout_button_paragraph(
|
||||||
|
is_selected: bool,
|
||||||
|
label: &str,
|
||||||
|
alignment: Alignment,
|
||||||
|
) -> Paragraph<'_> {
|
||||||
Paragraph::new(Text::from(label))
|
Paragraph::new(Text::from(label))
|
||||||
.block(layout_block())
|
.block(layout_block())
|
||||||
.alignment(alignment)
|
.alignment(alignment)
|
||||||
@@ -78,14 +103,14 @@ pub fn layout_button_paragraph_borderless(
|
|||||||
is_selected: bool,
|
is_selected: bool,
|
||||||
label: &str,
|
label: &str,
|
||||||
alignment: Alignment,
|
alignment: Alignment,
|
||||||
) -> Paragraph {
|
) -> Paragraph<'_> {
|
||||||
Paragraph::new(Text::from(label))
|
Paragraph::new(Text::from(label))
|
||||||
.block(borderless_block())
|
.block(borderless_block())
|
||||||
.alignment(alignment)
|
.alignment(alignment)
|
||||||
.style(style_block_highlight(is_selected))
|
.style(style_block_highlight(is_selected))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout_paragraph_borderless(string: &str) -> Paragraph {
|
pub fn layout_paragraph_borderless(string: &str) -> Paragraph<'_> {
|
||||||
Paragraph::new(Text::from(string))
|
Paragraph::new(Text::from(string))
|
||||||
.block(borderless_block())
|
.block(borderless_block())
|
||||||
.style(style_primary().add_modifier(Modifier::BOLD))
|
.style(style_primary().add_modifier(Modifier::BOLD))
|
||||||
@@ -131,7 +156,7 @@ pub fn style_highlight() -> Style {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn style_default() -> Style {
|
pub fn style_default() -> Style {
|
||||||
Style::default().fg(Color::White)
|
Style::default().fg(COLOR_WHITE)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn style_default_bold() -> Style {
|
pub fn style_default_bold() -> Style {
|
||||||
@@ -139,35 +164,35 @@ pub fn style_default_bold() -> Style {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn style_primary() -> Style {
|
pub fn style_primary() -> Style {
|
||||||
Style::default().fg(Color::Cyan)
|
Style::default().fg(COLOR_CYAN)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn style_secondary() -> Style {
|
pub fn style_secondary() -> Style {
|
||||||
Style::default().fg(Color::Yellow)
|
Style::default().fg(COLOR_YELLOW)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn style_system_function() -> Style {
|
pub fn style_system_function() -> Style {
|
||||||
Style::default().fg(Color::Yellow)
|
Style::default().fg(COLOR_YELLOW)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn style_unmonitored() -> Style {
|
pub fn style_unmonitored() -> Style {
|
||||||
Style::default().fg(Color::Rgb(91, 87, 87))
|
Style::default().fg(COLOR_WHITE)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn style_success() -> Style {
|
pub fn style_success() -> Style {
|
||||||
Style::default().fg(Color::Green)
|
Style::default().fg(COLOR_GREEN)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn style_warning() -> Style {
|
pub fn style_warning() -> Style {
|
||||||
Style::default().fg(Color::Magenta)
|
Style::default().fg(COLOR_MAGENTA)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn style_failure() -> Style {
|
pub fn style_failure() -> Style {
|
||||||
Style::default().fg(Color::Red)
|
Style::default().fg(COLOR_RED)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn style_help() -> Style {
|
pub fn style_help() -> Style {
|
||||||
Style::default().fg(Color::LightBlue)
|
Style::default().fg(COLOR_LIGHT_BLUE)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn style_block_highlight(is_selected: bool) -> Style {
|
pub fn style_block_highlight(is_selected: bool) -> Style {
|
||||||
@@ -223,19 +248,19 @@ pub fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
|
|||||||
.split(popup_layout[1])[1]
|
.split(popup_layout[1])[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn line_gauge_with_title(title: &str, ratio: f64) -> LineGauge {
|
pub fn line_gauge_with_title(title: &str, ratio: f64) -> LineGauge<'_> {
|
||||||
LineGauge::default()
|
LineGauge::default()
|
||||||
.block(Block::default().title(title))
|
.block(Block::default().title(title))
|
||||||
.gauge_style(Style::default().fg(Color::Cyan))
|
.gauge_style(Style::default().fg(COLOR_CYAN))
|
||||||
.line_set(symbols::line::THICK)
|
.line_set(symbols::line::THICK)
|
||||||
.ratio(ratio)
|
.ratio(ratio)
|
||||||
.label(Spans::from(format!("{:.0}%", ratio * 100.0)))
|
.label(Spans::from(format!("{:.0}%", ratio * 100.0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn line_gauge_with_label(title: &str, ratio: f64) -> LineGauge {
|
pub fn line_gauge_with_label(title: &str, ratio: f64) -> LineGauge<'_> {
|
||||||
LineGauge::default()
|
LineGauge::default()
|
||||||
.block(Block::default())
|
.block(Block::default())
|
||||||
.gauge_style(Style::default().fg(Color::Cyan))
|
.gauge_style(Style::default().fg(COLOR_CYAN))
|
||||||
.line_set(symbols::line::THICK)
|
.line_set(symbols::line::THICK)
|
||||||
.ratio(ratio)
|
.ratio(ratio)
|
||||||
.label(Spans::from(format!("{}: {:.0}%", title, ratio * 100.0)))
|
.label(Spans::from(format!("{}: {:.0}%", title, ratio * 100.0)))
|
||||||
@@ -264,8 +289,8 @@ mod test {
|
|||||||
layout_with_constraints, logo_block, spans_info_default, spans_info_primary,
|
layout_with_constraints, logo_block, spans_info_default, spans_info_primary,
|
||||||
spans_info_with_style, style_block_highlight, style_bold, style_default, style_default_bold,
|
spans_info_with_style, style_block_highlight, style_bold, style_default, style_default_bold,
|
||||||
style_failure, style_help, style_highlight, style_primary, style_secondary, style_success,
|
style_failure, style_help, style_highlight, style_primary, style_secondary, style_success,
|
||||||
style_system_function, style_warning, title_block, title_block_centered, title_style,
|
style_system_function, style_unmonitored, style_warning, title_block, title_block_centered,
|
||||||
vertical_chunks, vertical_chunks_with_margin,
|
title_style, vertical_chunks, vertical_chunks_with_margin,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -498,6 +523,11 @@ mod test {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_style_unmonitored() {
|
||||||
|
assert_eq!(style_unmonitored(), Style::default().fg(Color::White));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_style_default() {
|
fn test_style_default() {
|
||||||
assert_eq!(style_default(), Style::default().fg(Color::White));
|
assert_eq!(style_default(), Style::default().fg(Color::White));
|
||||||
|
|||||||
Reference in New Issue
Block a user