Added typo checks and upgraded to the latest version of Ratatui
This commit is contained in:
+4
-3
@@ -9,6 +9,7 @@ repository = "https://github.com/Dark-Alex-17/managarr"
|
|||||||
homepage = "https://github.com/Dark-Alex-17/managarr"
|
homepage = "https://github.com/Dark-Alex-17/managarr"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
rust-version = "1.65.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.68"
|
anyhow = "1.0.68"
|
||||||
@@ -28,10 +29,10 @@ reqwest = { version = "0.11.14", features = ["json"] }
|
|||||||
serde_yaml = "0.9.16"
|
serde_yaml = "0.9.16"
|
||||||
serde_json = "1.0.91"
|
serde_json = "1.0.91"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
strum = {version = "0.24", features = ["derive"] }
|
strum = {version = "0.25.0", features = ["derive"] }
|
||||||
strum_macros = "0.24"
|
strum_macros = "0.25.0"
|
||||||
tokio = { version = "1.24.1", features = ["full"] }
|
tokio = { version = "1.24.1", features = ["full"] }
|
||||||
tui = { version = "0.20.1", package = "ratatui" }
|
tui = { version = "0.21.0", package = "ratatui", features = ["all-widgets"] }
|
||||||
urlencoding = "2.1.2"
|
urlencoding = "2.1.2"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ Managarr assumes reasonable defaults to connect to each service (i.e. Radarr is
|
|||||||
but all servers will require you to input the API token.
|
but all servers will require you to input the API token.
|
||||||
|
|
||||||
The configuration file is located somewhere different for each OS
|
The configuration file is located somewhere different for each OS
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
```
|
```
|
||||||
$HOME/.config/managarr/config.yml
|
$HOME/.config/managarr/config.yml
|
||||||
|
|||||||
+3
-3
@@ -4,7 +4,7 @@ use std::rc::Rc;
|
|||||||
use tui::backend::Backend;
|
use tui::backend::Backend;
|
||||||
use tui::layout::{Alignment, Constraint, Rect};
|
use tui::layout::{Alignment, Constraint, Rect};
|
||||||
use tui::style::Modifier;
|
use tui::style::Modifier;
|
||||||
use tui::text::{Span, Spans, Text};
|
use tui::text::{Line, Span, Text};
|
||||||
use tui::widgets::Paragraph;
|
use tui::widgets::Paragraph;
|
||||||
use tui::widgets::Row;
|
use tui::widgets::Row;
|
||||||
use tui::widgets::Table;
|
use tui::widgets::Table;
|
||||||
@@ -81,7 +81,7 @@ fn draw_header_row<B: Backend>(f: &mut Frame<'_, B>, app: &mut App<'_>, area: Re
|
|||||||
.server_tabs
|
.server_tabs
|
||||||
.tabs
|
.tabs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|tab| Spans::from(Span::styled(tab.title, style_default_bold())))
|
.map(|tab| Line::from(Span::styled(tab.title, style_default_bold())))
|
||||||
.collect();
|
.collect();
|
||||||
let tabs = Tabs::new(titles)
|
let tabs = Tabs::new(titles)
|
||||||
.block(logo_block())
|
.block(logo_block())
|
||||||
@@ -273,7 +273,7 @@ fn draw_tabs<'a, B: Backend>(
|
|||||||
let titles = tab_state
|
let titles = tab_state
|
||||||
.tabs
|
.tabs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|tab_route| Spans::from(Span::styled(tab_route.title, style_default_bold())))
|
.map(|tab_route| Line::from(Span::styled(tab_route.title, style_default_bold())))
|
||||||
.collect();
|
.collect();
|
||||||
let tabs = Tabs::new(titles)
|
let tabs = Tabs::new(titles)
|
||||||
.block(block)
|
.block(block)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use crate::models::Route;
|
|||||||
use crate::ui::radarr_ui::collections_ui::draw_collections;
|
use crate::ui::radarr_ui::collections_ui::draw_collections;
|
||||||
use crate::ui::utils::{
|
use crate::ui::utils::{
|
||||||
borderless_block, get_width_from_percentage, layout_block_top_border_with_title,
|
borderless_block, get_width_from_percentage, layout_block_top_border_with_title,
|
||||||
spans_info_primary, style_default, style_help, style_primary, title_block, title_style,
|
line_info_primary, style_default, style_help, style_primary, title_block, title_style,
|
||||||
vertical_chunks_with_margin,
|
vertical_chunks_with_margin,
|
||||||
};
|
};
|
||||||
use crate::ui::{draw_large_popup_over, draw_small_popup_over, draw_table, DrawUi, TableProps};
|
use crate::ui::{draw_large_popup_over, draw_small_popup_over, draw_table, DrawUi, TableProps};
|
||||||
@@ -106,24 +106,24 @@ pub(super) fn draw_collection_details<B: Backend>(
|
|||||||
let minimum_availability = collection_selection.minimum_availability.to_display_str();
|
let minimum_availability = collection_selection.minimum_availability.to_display_str();
|
||||||
|
|
||||||
let collection_description = Text::from(vec![
|
let collection_description = Text::from(vec![
|
||||||
spans_info_primary(
|
line_info_primary(
|
||||||
"Overview: ".to_owned(),
|
"Overview: ".to_owned(),
|
||||||
collection_selection.overview.clone().unwrap_or_default(),
|
collection_selection.overview.clone().unwrap_or_default(),
|
||||||
),
|
),
|
||||||
spans_info_primary(
|
line_info_primary(
|
||||||
"Root Folder Path: ".to_owned(),
|
"Root Folder Path: ".to_owned(),
|
||||||
collection_selection
|
collection_selection
|
||||||
.root_folder_path
|
.root_folder_path
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
),
|
),
|
||||||
spans_info_primary("Quality Profile: ".to_owned(), quality_profile),
|
line_info_primary("Quality Profile: ".to_owned(), quality_profile),
|
||||||
spans_info_primary(
|
line_info_primary(
|
||||||
"Minimum Availability: ".to_owned(),
|
"Minimum Availability: ".to_owned(),
|
||||||
minimum_availability.to_owned(),
|
minimum_availability.to_owned(),
|
||||||
),
|
),
|
||||||
spans_info_primary("Monitored: ".to_owned(), monitored.to_owned()),
|
line_info_primary("Monitored: ".to_owned(), monitored.to_owned()),
|
||||||
spans_info_primary("Search on Add: ".to_owned(), search_on_add.to_owned()),
|
line_info_primary("Search on Add: ".to_owned(), search_on_add.to_owned()),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let description_paragraph = Paragraph::new(collection_description)
|
let description_paragraph = Paragraph::new(collection_description)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::iter;
|
|||||||
use tui::backend::Backend;
|
use tui::backend::Backend;
|
||||||
use tui::layout::{Alignment, Constraint, Rect};
|
use tui::layout::{Alignment, Constraint, Rect};
|
||||||
use tui::style::{Modifier, Style};
|
use tui::style::{Modifier, Style};
|
||||||
use tui::text::{Span, Spans, Text};
|
use tui::text::{Line, Span, Text};
|
||||||
use tui::widgets::{Cell, ListItem, Paragraph, Row, Wrap};
|
use tui::widgets::{Cell, ListItem, Paragraph, Row, Wrap};
|
||||||
use tui::Frame;
|
use tui::Frame;
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ use crate::models::Route;
|
|||||||
use crate::ui::radarr_ui::library_ui::draw_library;
|
use crate::ui::radarr_ui::library_ui::draw_library;
|
||||||
use crate::ui::utils::{
|
use crate::ui::utils::{
|
||||||
borderless_block, get_width_from_percentage, layout_block_bottom_border, layout_block_top_border,
|
borderless_block, get_width_from_percentage, layout_block_bottom_border, layout_block_top_border,
|
||||||
spans_info_default, style_awaiting_import, style_bold, style_default, style_failure,
|
line_info_default, style_awaiting_import, style_bold, style_default, style_failure,
|
||||||
style_primary, style_success, style_warning, vertical_chunks,
|
style_primary, style_success, style_warning, vertical_chunks,
|
||||||
};
|
};
|
||||||
use crate::ui::{
|
use crate::ui::{
|
||||||
@@ -216,9 +216,9 @@ fn draw_movie_details<B: Backend>(f: &mut Frame<'_, B>, app: &App<'_>, content_a
|
|||||||
let split = line.split(':').collect::<Vec<&str>>();
|
let split = line.split(':').collect::<Vec<&str>>();
|
||||||
let title = format!("{}:", split[0]);
|
let title = format!("{}:", split[0]);
|
||||||
|
|
||||||
spans_info_default(title, split[1..].join(":"))
|
line_info_default(title, split[1..].join(":"))
|
||||||
})
|
})
|
||||||
.collect::<Vec<Spans<'_>>>(),
|
.collect::<Vec<Line<'_>>>(),
|
||||||
);
|
);
|
||||||
text.patch_style(determine_style_from_download_status(download_status));
|
text.patch_style(determine_style_from_download_status(download_status));
|
||||||
|
|
||||||
@@ -524,7 +524,7 @@ fn draw_manual_search_confirm_prompt<B: Backend>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
if current_selection.rejected {
|
if current_selection.rejected {
|
||||||
let mut spans_vec = vec![Spans::from(vec![Span::styled(
|
let mut lines_vec = vec![Line::from(vec![Span::styled(
|
||||||
"Rejection reasons: ",
|
"Rejection reasons: ",
|
||||||
style_primary().add_modifier(Modifier::BOLD),
|
style_primary().add_modifier(Modifier::BOLD),
|
||||||
)])];
|
)])];
|
||||||
@@ -533,11 +533,11 @@ fn draw_manual_search_confirm_prompt<B: Backend>(
|
|||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|item| Spans::from(vec![Span::styled(format!("• {}", item), style_primary())]))
|
.map(|item| Line::from(vec![Span::styled(format!("• {}", item), style_primary())]))
|
||||||
.collect::<Vec<Spans<'_>>>();
|
.collect::<Vec<Line<'_>>>();
|
||||||
spans_vec.append(&mut rejections_spans);
|
lines_vec.append(&mut rejections_spans);
|
||||||
|
|
||||||
let content_paragraph = Paragraph::new(spans_vec)
|
let content_paragraph = Paragraph::new(lines_vec)
|
||||||
.block(borderless_block())
|
.block(borderless_block())
|
||||||
.wrap(Wrap { trim: false })
|
.wrap(Wrap { trim: false })
|
||||||
.alignment(Alignment::Left);
|
.alignment(Alignment::Left);
|
||||||
|
|||||||
+10
-10
@@ -2,7 +2,7 @@ use std::rc::Rc;
|
|||||||
use tui::backend::Backend;
|
use tui::backend::Backend;
|
||||||
use tui::layout::{Alignment, Constraint, Direction, Layout, Rect};
|
use tui::layout::{Alignment, Constraint, Direction, Layout, Rect};
|
||||||
use tui::style::{Color, Modifier, Style};
|
use tui::style::{Color, Modifier, Style};
|
||||||
use tui::text::{Span, Spans, Text};
|
use tui::text::{Line, Span, 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};
|
||||||
|
|
||||||
@@ -120,24 +120,24 @@ pub fn borderless_block<'a>() -> Block<'a> {
|
|||||||
Block::default()
|
Block::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spans_info_with_style<'a>(
|
pub fn line_info_with_style<'a>(
|
||||||
title: String,
|
title: String,
|
||||||
content: String,
|
content: String,
|
||||||
title_style: Style,
|
title_style: Style,
|
||||||
content_style: Style,
|
content_style: Style,
|
||||||
) -> Spans<'a> {
|
) -> Line<'a> {
|
||||||
Spans::from(vec![
|
Line::from(vec![
|
||||||
Span::styled(title, title_style),
|
Span::styled(title, title_style),
|
||||||
Span::styled(content, content_style),
|
Span::styled(content, content_style),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spans_info_default<'a>(title: String, content: String) -> Spans<'a> {
|
pub fn line_info_default<'a>(title: String, content: String) -> Line<'a> {
|
||||||
spans_info_with_style(title, content, style_bold(), style_default())
|
line_info_with_style(title, content, style_bold(), style_default())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spans_info_primary<'a>(title: String, content: String) -> Spans<'a> {
|
pub fn line_info_primary<'a>(title: String, content: String) -> Line<'a> {
|
||||||
spans_info_with_style(
|
line_info_with_style(
|
||||||
title,
|
title,
|
||||||
content,
|
content,
|
||||||
style_primary().add_modifier(Modifier::BOLD),
|
style_primary().add_modifier(Modifier::BOLD),
|
||||||
@@ -256,7 +256,7 @@ pub fn line_gauge_with_title(title: &str, ratio: f64) -> LineGauge<'_> {
|
|||||||
.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(Line::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<'_> {
|
||||||
@@ -265,7 +265,7 @@ pub fn line_gauge_with_label(title: &str, ratio: f64) -> LineGauge<'_> {
|
|||||||
.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(Line::from(format!("{}: {:.0}%", title, ratio * 100.0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show_cursor<B: Backend>(f: &mut Frame<'_, B>, area: Rect, offset: usize, string: &str) {
|
pub fn show_cursor<B: Backend>(f: &mut Frame<'_, B>, area: Rect, offset: usize, string: &str) {
|
||||||
|
|||||||
+15
-15
@@ -3,15 +3,15 @@ mod test {
|
|||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use tui::layout::{Alignment, Constraint, Direction, Layout, Rect};
|
use tui::layout::{Alignment, Constraint, Direction, Layout, Rect};
|
||||||
use tui::style::{Color, Modifier, Style};
|
use tui::style::{Color, Modifier, Style};
|
||||||
use tui::text::{Span, Spans};
|
use tui::text::{Line, Span};
|
||||||
use tui::widgets::{Block, BorderType, Borders};
|
use tui::widgets::{Block, BorderType, Borders};
|
||||||
|
|
||||||
use crate::ui::utils::{
|
use crate::ui::utils::{
|
||||||
borderless_block, centered_rect, get_width_from_percentage, horizontal_chunks,
|
borderless_block, centered_rect, get_width_from_percentage, horizontal_chunks,
|
||||||
horizontal_chunks_with_margin, layout_block, layout_block_bottom_border,
|
horizontal_chunks_with_margin, layout_block, layout_block_bottom_border,
|
||||||
layout_block_top_border, layout_block_top_border_with_title, layout_block_with_title,
|
layout_block_top_border, layout_block_top_border_with_title, layout_block_with_title,
|
||||||
layout_with_constraints, logo_block, spans_info_default, spans_info_primary,
|
layout_with_constraints, line_info_default, line_info_primary, line_info_with_style,
|
||||||
spans_info_with_style, style_block_highlight, style_bold, style_default, style_default_bold,
|
logo_block, 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_unmonitored, style_warning, title_block, title_block_centered,
|
style_system_function, style_unmonitored, style_warning, title_block, title_block_centered,
|
||||||
title_style, vertical_chunks, vertical_chunks_with_margin,
|
title_style, vertical_chunks, vertical_chunks_with_margin,
|
||||||
@@ -177,32 +177,32 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_spans_info_with_style() {
|
fn test_line_info_with_style() {
|
||||||
let first_style = Style::default()
|
let first_style = Style::default()
|
||||||
.fg(Color::DarkGray)
|
.fg(Color::DarkGray)
|
||||||
.add_modifier(Modifier::BOLD);
|
.add_modifier(Modifier::BOLD);
|
||||||
let second_style = Style::default()
|
let second_style = Style::default()
|
||||||
.fg(Color::LightYellow)
|
.fg(Color::LightYellow)
|
||||||
.add_modifier(Modifier::ITALIC);
|
.add_modifier(Modifier::ITALIC);
|
||||||
let expected_spans = Spans::from(vec![
|
let expected_lines = Line::from(vec![
|
||||||
Span::styled("title".to_owned(), first_style),
|
Span::styled("title".to_owned(), first_style),
|
||||||
Span::styled("content".to_owned(), second_style),
|
Span::styled("content".to_owned(), second_style),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
spans_info_with_style(
|
line_info_with_style(
|
||||||
"title".to_owned(),
|
"title".to_owned(),
|
||||||
"content".to_owned(),
|
"content".to_owned(),
|
||||||
first_style,
|
first_style,
|
||||||
second_style
|
second_style
|
||||||
),
|
),
|
||||||
expected_spans
|
expected_lines
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_spans_info_default() {
|
fn test_line_info_default() {
|
||||||
let expected_spans = Spans::from(vec![
|
let expected_line = Line::from(vec![
|
||||||
Span::styled(
|
Span::styled(
|
||||||
"title".to_owned(),
|
"title".to_owned(),
|
||||||
Style::default().add_modifier(Modifier::BOLD),
|
Style::default().add_modifier(Modifier::BOLD),
|
||||||
@@ -211,14 +211,14 @@ mod test {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
spans_info_default("title".to_owned(), "content".to_owned()),
|
line_info_default("title".to_owned(), "content".to_owned()),
|
||||||
expected_spans
|
expected_line
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_spans_info_primary() {
|
fn test_line_info_primary() {
|
||||||
let expected_spans = Spans::from(vec![
|
let expected_line = Line::from(vec![
|
||||||
Span::styled(
|
Span::styled(
|
||||||
"title".to_owned(),
|
"title".to_owned(),
|
||||||
Style::default()
|
Style::default()
|
||||||
@@ -229,8 +229,8 @@ mod test {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
spans_info_primary("title".to_owned(), "content".to_owned()),
|
line_info_primary("title".to_owned(), "content".to_owned()),
|
||||||
expected_spans
|
expected_line
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
# configuration for https://github.com/crate-ci/typos
|
||||||
|
|
||||||
|
[default.extend-words]
|
||||||
|
ratatui = "ratatui"
|
||||||
|
managarr = "managarr"
|
||||||
|
radarr = "radarr"
|
||||||
|
sonarr = "sonarr"
|
||||||
|
servarr = "servarr"
|
||||||
|
readarr = "readarr"
|
||||||
|
lidarr = "lidarr"
|
||||||
|
whisparr = "whisparr"
|
||||||
|
bazarr = "bazarr"
|
||||||
|
prowlarr = "prowlarr"
|
||||||
|
tautulli = "tautulli"
|
||||||
Reference in New Issue
Block a user