fix: page up and down stop at the table edges instead of wrapping
A page is 20 rows and the index wrapped modulo one less than the row count, so the last row was unreachable by paging, 21-row and 5-row tables did nothing on page down from the first row, and 4-row tables cycled 0, 2, 1 and never reached row 3. Page down now clamps to the last row and page up clamps to the first. With no division left, a single-row table is safe, so the early return only guards the empty table again, matching scroll_to_top and scroll_to_bottom.
This commit is contained in:
4 files changed
+166
-47
No files matched your search
@@ -171,10 +171,19 @@ mod property_tests {
|
|||||||
table.set_items(movies);
|
table.set_items(movies);
|
||||||
|
|
||||||
for i in 0..page_ops {
|
for i in 0..page_ops {
|
||||||
|
let previous_index = table.state.selected().unwrap();
|
||||||
|
|
||||||
if i % 2 == 0 {
|
if i % 2 == 0 {
|
||||||
table.page_down();
|
table.page_down();
|
||||||
|
|
||||||
|
prop_assert_eq!(
|
||||||
|
table.state.selected(),
|
||||||
|
Some((previous_index + 20).min(list_size - 1))
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
table.page_up();
|
table.page_up();
|
||||||
|
|
||||||
|
prop_assert_eq!(table.state.selected(), Some(previous_index.saturating_sub(20)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let current = table.current_selection();
|
let current = table.current_selection();
|
||||||
|
|||||||
@@ -606,17 +606,18 @@ mod tests {
|
|||||||
.take(100)
|
.take(100)
|
||||||
.collect();
|
.collect();
|
||||||
app.data.radarr_data.movies.set_items(movies_vec);
|
app.data.radarr_data.movies.set_items(movies_vec);
|
||||||
|
app.data.radarr_data.movies.state.select(Some(50));
|
||||||
TableHandlerUnit::new(key, &mut app, ActiveRadarrBlock::Movies, None).handle();
|
TableHandlerUnit::new(key, &mut app, ActiveRadarrBlock::Movies, None).handle();
|
||||||
|
|
||||||
if key == Key::PgUp {
|
if key == Key::PgUp {
|
||||||
assert_str_eq!(
|
assert_str_eq!(
|
||||||
app.data.radarr_data.movies.current_selection().title.text,
|
app.data.radarr_data.movies.current_selection().title.text,
|
||||||
"Test 79"
|
"Test 30"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
assert_str_eq!(
|
assert_str_eq!(
|
||||||
app.data.radarr_data.movies.current_selection().title.text,
|
app.data.radarr_data.movies.current_selection().title.text,
|
||||||
"Test 20"
|
"Test 70"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,29 +100,26 @@ where
|
|||||||
{
|
{
|
||||||
fn page_down(&mut self) {
|
fn page_down(&mut self) {
|
||||||
let items_len = self.active_items().len();
|
let items_len = self.active_items().len();
|
||||||
if items_len <= 1 {
|
if items_len == 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let state = self.active_state_mut();
|
let state = self.active_state_mut();
|
||||||
match state.selected() {
|
match state.selected() {
|
||||||
Some(i) => state.select(Some(i.saturating_add(20) % (items_len - 1))),
|
Some(i) => state.select(Some(i.saturating_add(20).min(items_len - 1))),
|
||||||
None => state.select_first(),
|
None => state.select_first(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn page_up(&mut self) {
|
fn page_up(&mut self) {
|
||||||
let items_len = self.active_items().len();
|
let items_len = self.active_items().len();
|
||||||
if items_len <= 1 {
|
if items_len == 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let state = self.active_state_mut();
|
let state = self.active_state_mut();
|
||||||
match state.selected() {
|
match state.selected() {
|
||||||
Some(i) => {
|
Some(i) => state.select(Some(i.saturating_sub(20))),
|
||||||
let len = items_len - 1;
|
|
||||||
state.select(Some((i + len - (20 % len)) % len));
|
|
||||||
}
|
|
||||||
None => state.select_last(),
|
None => state.select_last(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -318,6 +318,69 @@ mod tests {
|
|||||||
20
|
20
|
||||||
);
|
);
|
||||||
|
|
||||||
|
stateful_table.page_down();
|
||||||
|
|
||||||
|
assert_some_eq_x!(
|
||||||
|
stateful_table.filtered_state.as_ref().unwrap().selected(),
|
||||||
|
40
|
||||||
|
);
|
||||||
|
|
||||||
|
stateful_table.page_down();
|
||||||
|
|
||||||
|
assert_some_eq_x!(
|
||||||
|
stateful_table.filtered_state.as_ref().unwrap().selected(),
|
||||||
|
60
|
||||||
|
);
|
||||||
|
|
||||||
|
stateful_table.page_down();
|
||||||
|
|
||||||
|
assert_some_eq_x!(
|
||||||
|
stateful_table.filtered_state.as_ref().unwrap().selected(),
|
||||||
|
80
|
||||||
|
);
|
||||||
|
|
||||||
|
stateful_table.page_down();
|
||||||
|
|
||||||
|
assert_some_eq_x!(
|
||||||
|
stateful_table.filtered_state.as_ref().unwrap().selected(),
|
||||||
|
99
|
||||||
|
);
|
||||||
|
|
||||||
|
stateful_table.page_down();
|
||||||
|
|
||||||
|
assert_some_eq_x!(
|
||||||
|
stateful_table.filtered_state.as_ref().unwrap().selected(),
|
||||||
|
99
|
||||||
|
);
|
||||||
|
|
||||||
|
stateful_table.page_up();
|
||||||
|
|
||||||
|
assert_some_eq_x!(
|
||||||
|
stateful_table.filtered_state.as_ref().unwrap().selected(),
|
||||||
|
79
|
||||||
|
);
|
||||||
|
|
||||||
|
stateful_table.page_up();
|
||||||
|
|
||||||
|
assert_some_eq_x!(
|
||||||
|
stateful_table.filtered_state.as_ref().unwrap().selected(),
|
||||||
|
59
|
||||||
|
);
|
||||||
|
|
||||||
|
stateful_table.page_up();
|
||||||
|
|
||||||
|
assert_some_eq_x!(
|
||||||
|
stateful_table.filtered_state.as_ref().unwrap().selected(),
|
||||||
|
39
|
||||||
|
);
|
||||||
|
|
||||||
|
stateful_table.page_up();
|
||||||
|
|
||||||
|
assert_some_eq_x!(
|
||||||
|
stateful_table.filtered_state.as_ref().unwrap().selected(),
|
||||||
|
19
|
||||||
|
);
|
||||||
|
|
||||||
stateful_table.page_up();
|
stateful_table.page_up();
|
||||||
|
|
||||||
assert_some_eq_x!(
|
assert_some_eq_x!(
|
||||||
@@ -327,33 +390,10 @@ mod tests {
|
|||||||
|
|
||||||
stateful_table.page_up();
|
stateful_table.page_up();
|
||||||
|
|
||||||
assert_some_eq_x!(
|
|
||||||
stateful_table.filtered_state.as_ref().unwrap().selected(),
|
|
||||||
stateful_table.filtered_items.as_ref().unwrap().len() - 21
|
|
||||||
);
|
|
||||||
|
|
||||||
stateful_table.page_down();
|
|
||||||
|
|
||||||
assert_some_eq_x!(
|
assert_some_eq_x!(
|
||||||
stateful_table.filtered_state.as_ref().unwrap().selected(),
|
stateful_table.filtered_state.as_ref().unwrap().selected(),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
stateful_table.scroll_down();
|
|
||||||
stateful_table.page_up();
|
|
||||||
|
|
||||||
assert_some_eq_x!(
|
|
||||||
stateful_table.filtered_state.as_ref().unwrap().selected(),
|
|
||||||
stateful_table.filtered_items.as_ref().unwrap().len() - 20
|
|
||||||
);
|
|
||||||
|
|
||||||
stateful_table.scroll_down();
|
|
||||||
stateful_table.page_down();
|
|
||||||
|
|
||||||
assert_some_eq_x!(
|
|
||||||
stateful_table.filtered_state.as_ref().unwrap().selected(),
|
|
||||||
2
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -376,33 +416,105 @@ mod tests {
|
|||||||
|
|
||||||
assert_some_eq_x!(stateful_table.state.selected(), 20);
|
assert_some_eq_x!(stateful_table.state.selected(), 20);
|
||||||
|
|
||||||
|
stateful_table.page_down();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 40);
|
||||||
|
|
||||||
|
stateful_table.page_down();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 60);
|
||||||
|
|
||||||
|
stateful_table.page_down();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 80);
|
||||||
|
|
||||||
|
stateful_table.page_down();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 99);
|
||||||
|
|
||||||
|
stateful_table.page_down();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 99);
|
||||||
|
|
||||||
|
stateful_table.page_up();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 79);
|
||||||
|
|
||||||
|
stateful_table.page_up();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 59);
|
||||||
|
|
||||||
|
stateful_table.page_up();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 39);
|
||||||
|
|
||||||
|
stateful_table.page_up();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 19);
|
||||||
|
|
||||||
stateful_table.page_up();
|
stateful_table.page_up();
|
||||||
|
|
||||||
assert_some_eq_x!(stateful_table.state.selected(), 0);
|
assert_some_eq_x!(stateful_table.state.selected(), 0);
|
||||||
|
|
||||||
stateful_table.page_up();
|
stateful_table.page_up();
|
||||||
|
|
||||||
assert_some_eq_x!(
|
assert_some_eq_x!(stateful_table.state.selected(), 0);
|
||||||
stateful_table.state.selected(),
|
}
|
||||||
stateful_table.items.len() - 21
|
|
||||||
);
|
|
||||||
|
|
||||||
stateful_table.page_down();
|
#[test]
|
||||||
|
fn test_stateful_table_pagination_on_twenty_one_item_table_stops_at_last_item() {
|
||||||
|
let mut stateful_table = StatefulTable::default();
|
||||||
|
stateful_table.set_items((0..21).collect());
|
||||||
|
|
||||||
assert_some_eq_x!(stateful_table.state.selected(), 0);
|
assert_some_eq_x!(stateful_table.state.selected(), 0);
|
||||||
|
|
||||||
stateful_table.scroll_down();
|
|
||||||
stateful_table.page_up();
|
|
||||||
|
|
||||||
assert_some_eq_x!(
|
|
||||||
stateful_table.state.selected(),
|
|
||||||
stateful_table.items.len() - 20
|
|
||||||
);
|
|
||||||
|
|
||||||
stateful_table.scroll_down();
|
|
||||||
stateful_table.page_down();
|
stateful_table.page_down();
|
||||||
|
|
||||||
assert_some_eq_x!(stateful_table.state.selected(), 2);
|
assert_some_eq_x!(stateful_table.state.selected(), 20);
|
||||||
|
|
||||||
|
stateful_table.page_down();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 20);
|
||||||
|
|
||||||
|
stateful_table.page_up();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_stateful_table_pagination_on_five_item_table_stops_at_last_item() {
|
||||||
|
let mut stateful_table = StatefulTable::default();
|
||||||
|
stateful_table.set_items((0..5).collect());
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 0);
|
||||||
|
|
||||||
|
stateful_table.page_down();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 4);
|
||||||
|
|
||||||
|
stateful_table.page_down();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 4);
|
||||||
|
|
||||||
|
stateful_table.page_up();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_stateful_table_pagination_on_four_item_table_reaches_last_item() {
|
||||||
|
let mut stateful_table = StatefulTable::default();
|
||||||
|
stateful_table.set_items((0..4).collect());
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 0);
|
||||||
|
|
||||||
|
stateful_table.page_down();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 3);
|
||||||
|
|
||||||
|
stateful_table.page_up();
|
||||||
|
|
||||||
|
assert_some_eq_x!(stateful_table.state.selected(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in new issue
Block a user