feat(radarr): make the collection movie overview popup scrollable
A collection movie's overview renders in a popup that does not scroll, so a long overview overflows with no way to read the rest. The popup now scrolls. The popup owns its own ScrollableText, built from the selected collection movie's overview when it opens and torn down on Esc so a reopened popup starts at the top. Scrolling mutates only that owned state. The background renders the Collection record's overview and the movies table, neither of which carries a scroll offset, so they cannot scroll along with the popup. The popup also gains the loading and absent fallbacks the rest of the tree already has. Give the collection movie fixture an overview distinct from its collection's, and a multi-paragraph one, so the snapshots can tell the two records apart and a scrolled popup is distinguishable from an unscrolled one.
This commit is contained in:
24 files changed
+913
-66
No files matched your search
@@ -1,7 +1,7 @@
|
||||
use ratatui::Frame;
|
||||
use ratatui::layout::{Constraint, Flex, Layout, Rect};
|
||||
use ratatui::style::Stylize;
|
||||
use ratatui::text::{Line, Text};
|
||||
use ratatui::text::{Line, Span, Text};
|
||||
use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
|
||||
|
||||
use crate::app::App;
|
||||
@@ -10,11 +10,12 @@ use crate::models::radarr_models::CollectionMovie;
|
||||
use crate::models::servarr_data::radarr::radarr_data::{
|
||||
ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS,
|
||||
};
|
||||
use crate::ui::styles::ManagarrStyle;
|
||||
use crate::ui::styles::{ManagarrStyle, default_style};
|
||||
use crate::ui::utils::{
|
||||
borderless_block, get_width_from_percentage, layout_block_top_border_with_title, title_block,
|
||||
title_style,
|
||||
};
|
||||
use crate::ui::widgets::loading_block::LoadingBlock;
|
||||
use crate::ui::widgets::managarr_table::ManagarrTable;
|
||||
use crate::ui::widgets::popup::Size;
|
||||
use crate::ui::{DrawUi, draw_popup};
|
||||
@@ -219,20 +220,35 @@ fn draw_movie_overview(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
||||
.flex(Flex::SpaceBetween)
|
||||
.margin(1)
|
||||
.areas(area);
|
||||
let overview = Text::from(
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.collection_movies
|
||||
.current_selection()
|
||||
.clone()
|
||||
.overview,
|
||||
)
|
||||
.default_color();
|
||||
|
||||
let paragraph = Paragraph::new(overview)
|
||||
.block(borderless_block())
|
||||
.wrap(Wrap { trim: false });
|
||||
match app.data.radarr_data.movie_overview_modal.as_ref() {
|
||||
Some(movie_overview_modal) if !app.is_loading => {
|
||||
let overview = &movie_overview_modal.overview;
|
||||
let text = Text::from(
|
||||
overview
|
||||
.items
|
||||
.iter()
|
||||
.map(|line| overview_line(line))
|
||||
.collect::<Vec<Line<'static>>>(),
|
||||
);
|
||||
|
||||
f.render_widget(paragraph, paragraph_area);
|
||||
let paragraph = Paragraph::new(text)
|
||||
.block(borderless_block())
|
||||
.wrap(Wrap { trim: false })
|
||||
.scroll((overview.offset, 0));
|
||||
|
||||
f.render_widget(paragraph, paragraph_area);
|
||||
}
|
||||
_ => f.render_widget(
|
||||
LoadingBlock::new(
|
||||
app.is_loading || app.data.radarr_data.movie_overview_modal.is_none(),
|
||||
borderless_block(),
|
||||
),
|
||||
paragraph_area,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn overview_line(line: &str) -> Line<'static> {
|
||||
Line::from(Span::styled(line.trim_end().to_owned(), default_style()))
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pretty_assertions::assert_str_eq;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::app::App;
|
||||
@@ -7,9 +8,39 @@ mod tests {
|
||||
ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS,
|
||||
};
|
||||
use crate::ui::DrawUi;
|
||||
use crate::ui::radarr_ui::collections::collection_details_ui::CollectionDetailsUi;
|
||||
use crate::ui::radarr_ui::collections::collection_details_ui::{
|
||||
CollectionDetailsUi, overview_line,
|
||||
};
|
||||
use crate::ui::ui_test_utils::test_utils::{TerminalSize, render_to_string_with_app};
|
||||
|
||||
#[test]
|
||||
fn test_overview_line_trims_a_trailing_carriage_return() {
|
||||
let line = overview_line("The sequel took seven years to finish.\r");
|
||||
|
||||
assert_str_eq!(
|
||||
line.spans[0].content,
|
||||
"The sequel took seven years to finish."
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_overview_line_renders_a_carriage_return_only_line_as_blank() {
|
||||
let line = overview_line("\r");
|
||||
|
||||
assert_str_eq!(line.spans[0].content, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_overview_line_does_not_split_a_label_from_a_colon_in_the_prose() {
|
||||
let line = overview_line("It was shot in Madison, Wisconsin: a city the cast never left.");
|
||||
|
||||
assert_eq!(line.spans.len(), 1);
|
||||
assert_str_eq!(
|
||||
line.spans[0].content,
|
||||
"It was shot in Madison, Wisconsin: a city the cast never left."
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collection_details_ui_accepts() {
|
||||
ActiveRadarrBlock::iter().for_each(|active_radarr_block| {
|
||||
@@ -36,6 +67,32 @@ mod tests {
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scrolling_the_movie_overview_does_not_scroll_the_collection_details_behind_it() {
|
||||
let mut app = App::test_default_fully_populated();
|
||||
app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into());
|
||||
|
||||
let before = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
|
||||
CollectionDetailsUi::draw(f, app, f.area());
|
||||
});
|
||||
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.movie_overview_modal
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.overview
|
||||
.offset = 3;
|
||||
|
||||
let after = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
|
||||
CollectionDetailsUi::draw(f, app, f.area());
|
||||
});
|
||||
|
||||
assert_contains!(before, "Overview: Collection blah blah blah");
|
||||
assert_str_eq!(before, after);
|
||||
}
|
||||
|
||||
mod snapshot_tests {
|
||||
use super::*;
|
||||
use crate::models::stateful_table::StatefulTable;
|
||||
@@ -59,6 +116,52 @@ mod tests {
|
||||
insta::assert_snapshot!(active_radarr_block.to_string(), output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collection_details_ui_renders_scrolled_movie_overview() {
|
||||
let mut app = App::test_default_fully_populated();
|
||||
app.push_navigation_stack(ActiveRadarrBlock::ViewMovieOverview.into());
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.movie_overview_modal
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.overview
|
||||
.offset = 2;
|
||||
|
||||
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
|
||||
CollectionDetailsUi::draw(f, app, f.area());
|
||||
});
|
||||
|
||||
insta::assert_snapshot!(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collection_details_ui_renders_movie_overview_loading() {
|
||||
let mut app = App::test_default_fully_populated();
|
||||
app.is_loading = true;
|
||||
app.push_navigation_stack(ActiveRadarrBlock::ViewMovieOverview.into());
|
||||
|
||||
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
|
||||
CollectionDetailsUi::draw(f, app, f.area());
|
||||
});
|
||||
|
||||
insta::assert_snapshot!(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collection_details_ui_renders_movie_overview_when_the_modal_is_absent() {
|
||||
let mut app = App::test_default_fully_populated();
|
||||
app.data.radarr_data.movie_overview_modal = None;
|
||||
app.push_navigation_stack(ActiveRadarrBlock::ViewMovieOverview.into());
|
||||
|
||||
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
|
||||
CollectionDetailsUi::draw(f, app, f.area());
|
||||
});
|
||||
|
||||
insta::assert_snapshot!(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collection_details_ui_renders_collection_details_empty() {
|
||||
let mut app = App::test_default_fully_populated();
|
||||
|
||||
+4
-4
@@ -18,12 +18,12 @@ expression: output
|
||||
│ │
|
||||
│ │
|
||||
│ ╭ Overview ────────────────────────────────────────────────────╮ │
|
||||
│ Movies ───────────────────│Collection blah blah blah │───────────────────────────│
|
||||
│ Movies ───────────────────│Collection movie blah blah blah │───────────────────────────│
|
||||
│ ✔ Title │ │ │
|
||||
│=> ✔ Test │ │family, fun │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│=> ✔ Test │It was shot in Madison, Wisconsin: a city the cast never really │family, fun │
|
||||
│ │left. │ │
|
||||
│ │ │ │
|
||||
│ │The sequel took seven years to finish. │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
---
|
||||
source: src/ui/radarr_ui/collections/collection_details_ui_tests.rs
|
||||
expression: output
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
╭ Test Collection ───────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│Overview: Collection blah blah blah │
|
||||
│Root Folder Path: /nfs/movies │
|
||||
│Quality Profile: HD - 1080p │
|
||||
│Minimum Availability: Released │
|
||||
│Monitored: Yes │
|
||||
│Search on Add: Yes │
|
||||
│ │
|
||||
│ │
|
||||
│ ╭ Overview ────────────────────────────────────────────────────╮ │
|
||||
│ Movies ───────────────────│ │───────────────────────────│
|
||||
│ │ │ │
|
||||
│ │ Loading ... │ │
|
||||
│ Loading ... │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ ╰────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
---
|
||||
source: src/ui/radarr_ui/collections/collection_details_ui_tests.rs
|
||||
expression: output
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
╭ Test Collection ───────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│Overview: Collection blah blah blah │
|
||||
│Root Folder Path: /nfs/movies │
|
||||
│Quality Profile: HD - 1080p │
|
||||
│Minimum Availability: Released │
|
||||
│Monitored: Yes │
|
||||
│Search on Add: Yes │
|
||||
│ │
|
||||
│ │
|
||||
│ ╭ Overview ────────────────────────────────────────────────────╮ │
|
||||
│ Movies ───────────────────│ │───────────────────────────│
|
||||
│ ✔ Title │ │ │
|
||||
│=> ✔ Test │ Loading ... │family, fun │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ ╰────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
---
|
||||
source: src/ui/radarr_ui/collections/collection_details_ui_tests.rs
|
||||
expression: output
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
╭ Test Collection ───────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│Overview: Collection blah blah blah │
|
||||
│Root Folder Path: /nfs/movies │
|
||||
│Quality Profile: HD - 1080p │
|
||||
│Minimum Availability: Released │
|
||||
│Monitored: Yes │
|
||||
│Search on Add: Yes │
|
||||
│ │
|
||||
│ │
|
||||
│ ╭ Overview ────────────────────────────────────────────────────╮ │
|
||||
│ Movies ───────────────────│It was shot in Madison, Wisconsin: a city the cast never really │───────────────────────────│
|
||||
│ ✔ Title │left. │ │
|
||||
│=> ✔ Test │ │family, fun │
|
||||
│ │The sequel took seven years to finish. │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ ╰────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||
+3
-3
@@ -13,11 +13,11 @@ expression: output
|
||||
│Root Folder Path: /nfs/movies │
|
||||
│Quality Profile: HD - 1080p │
|
||||
│Minimum Avai╭────────────────────────────────────── Add Movie - Test ───────────────────────────────────────╮ │
|
||||
│Monitored: Y│ Collection blah blah blah │ │
|
||||
│Monitored: Y│ Collection movie blah blah blah │ │
|
||||
│Search on Ad│ │ │
|
||||
│ │ It was shot in Madison, Wisconsin: a city the cast never really left. │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ The sequel took seven years to finish. │ │
|
||||
│ Movies ──│ │───────────│
|
||||
│ ✔ Title │ ╭────────────────────────────────────────────╮ │ │
|
||||
│=> ✔ Test │ Root Folder: │/nfs ▼ │ │ │
|
||||
|
||||
+3
-3
@@ -13,11 +13,11 @@ expression: output
|
||||
│Root Folder Path: /nfs/movies │
|
||||
│Quality Profile: HD - 1080p │
|
||||
│Minimum Avai╭────────────────────────────────────── Add Movie - Test ───────────────────────────────────────╮ │
|
||||
│Monitored: Y│ Collection blah blah blah │ │
|
||||
│Monitored: Y│ Collection movie blah blah blah │ │
|
||||
│Search on Ad│ │ │
|
||||
│ │ It was shot in Madison, Wisconsin: a city the cast never really left. │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ The sequel took seven years to finish. │ │
|
||||
│ Movies ──│ │───────────│
|
||||
│ ✔ Title │ ╭────────────────────────────────────────────╮ │ │
|
||||
│=> ✔ Test │ ╭───────────────────────────────╮ ▼ │ │ │
|
||||
|
||||
+3
-3
@@ -13,11 +13,11 @@ expression: output
|
||||
│Root Folder Path: /nfs/movies │
|
||||
│Quality Profile: HD - 1080p │
|
||||
│Minimum Avai╭────────────────────────────────────── Add Movie - Test ───────────────────────────────────────╮ │
|
||||
│Monitored: Y│ Collection blah blah blah │ │
|
||||
│Monitored: Y│ Collection movie blah blah blah │ │
|
||||
│Search on Ad│ │ │
|
||||
│ │ It was shot in Madison, Wisconsin: a city the cast never really left. │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ The sequel took seven years to finish. │ │
|
||||
│ Movies ──│ │───────────│
|
||||
│ ✔ Title │ ╭────────────────────────────────────────────╮ │ │
|
||||
│=> ✔ Test │ ╭───────────────────────────────╮ ▼ │ │ │
|
||||
|
||||
+3
-3
@@ -13,11 +13,11 @@ expression: output
|
||||
│Root Folder Path: /nfs/movies │
|
||||
│Quality Profile: HD - 1080p │
|
||||
│Minimum Avai╭────────────────────────────────────── Add Movie - Test ───────────────────────────────────────╮ │
|
||||
│Monitored: Y│ Collection blah blah blah │ │
|
||||
│Monitored: Y│ Collection movie blah blah blah │ │
|
||||
│Search on Ad│ │ │
|
||||
│ │ It was shot in Madison, Wisconsin: a city the cast never really left. │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ The sequel took seven years to finish. │ │
|
||||
│ Movies ──│ │───────────│
|
||||
│ ✔ Title │ ╭────────────────────────────────────────────╮ │ │
|
||||
│=> ✔ Test │ ╭───────────────────────────────╮ ▼ │ │ │
|
||||
|
||||
+3
-3
@@ -13,11 +13,11 @@ expression: output
|
||||
│Root Folder Path: /nfs/movies │
|
||||
│Quality Profile: HD - 1080p │
|
||||
│Minimum Avai╭────────────────────────────────────── Add Movie - Test ───────────────────────────────────────╮ │
|
||||
│Monitored: Y│ Collection blah blah blah │ │
|
||||
│Monitored: Y│ Collection movie blah blah blah │ │
|
||||
│Search on Ad│ │ │
|
||||
│ │ It was shot in Madison, Wisconsin: a city the cast never really left. │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ The sequel took seven years to finish. │ │
|
||||
│ Movies ──│ │───────────│
|
||||
│ ✔ Title │ ╭────────────────────────────────────────────╮ │ │
|
||||
│=> ✔ Test │ ╭───────────────────────────────╮ ▼ │ │ │
|
||||
|
||||
+3
-3
@@ -13,11 +13,11 @@ expression: output
|
||||
│Root Folder Path: /nfs/movies │
|
||||
│Quality Profile: HD - 1080p │
|
||||
│Minimum Avai╭────────────────────────────────────── Add Movie - Test ───────────────────────────────────────╮ │
|
||||
│Monitored: Y│ Collection blah blah blah │ │
|
||||
│Monitored: Y│ Collection movie blah blah blah │ │
|
||||
│Search on Ad│ │ │
|
||||
│ │ It was shot in Madison, Wisconsin: a city the cast never really left. │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ The sequel took seven years to finish. │ │
|
||||
│ Movies ──│ │───────────│
|
||||
│ ✔ Title │ ╭────────────────────────────────────────────╮ │ │
|
||||
│=> ✔ Test │ Root Folder: │/nfs ▼ │ │ │
|
||||
|
||||
Reference in new issue
Block a user