fix: page navigation works with multiple page-axis categories
[/] previously broke after the first page category due to a hard-coded `break`. Replaced with odometer-style navigation: ] advances the last page category, carrying into the previous when it wraps (like digit incrementing). [ decrements the same way. Single-category behaviour is unchanged except it now wraps around instead of clamping at the end. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@ -1052,47 +1052,63 @@ impl App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn page_next(&mut self) {
|
/// Gather (cat_name, items, current_idx) for all non-empty page categories.
|
||||||
|
fn page_cat_data(&self) -> Vec<(String, Vec<String>, usize)> {
|
||||||
let page_cats: Vec<String> = self.model.active_view()
|
let page_cats: Vec<String> = self.model.active_view()
|
||||||
.map(|v| v.categories_on(Axis::Page).into_iter().map(String::from).collect())
|
.map(|v| v.categories_on(Axis::Page).into_iter().map(String::from).collect())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
for cat_name in &page_cats {
|
page_cats.into_iter().filter_map(|cat| {
|
||||||
let items: Vec<String> = self.model.category(cat_name)
|
let items: Vec<String> = self.model.category(&cat)
|
||||||
.map(|c| c.ordered_item_names().into_iter().map(String::from).collect())
|
.map(|c| c.ordered_item_names().into_iter().map(String::from).collect())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
if items.is_empty() { continue; }
|
if items.is_empty() { return None; }
|
||||||
let current = self.model.active_view()
|
let current = self.model.active_view()
|
||||||
.and_then(|v| v.page_selection(cat_name))
|
.and_then(|v| v.page_selection(&cat))
|
||||||
.map(String::from)
|
.map(String::from)
|
||||||
.unwrap_or_else(|| items[0].clone());
|
.or_else(|| items.first().cloned())
|
||||||
let idx = items.iter().position(|i| i == ¤t).unwrap_or(0);
|
.unwrap_or_default();
|
||||||
let next_idx = (idx + 1).min(items.len() - 1);
|
let idx = items.iter().position(|i| *i == current).unwrap_or(0);
|
||||||
if let Some(view) = self.model.active_view_mut() {
|
Some((cat, items, idx))
|
||||||
view.set_page_selection(cat_name, &items[next_idx]);
|
}).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn page_next(&mut self) {
|
||||||
|
let data = self.page_cat_data();
|
||||||
|
if data.is_empty() { return; }
|
||||||
|
// Odometer: advance from last category, carry propagates backward.
|
||||||
|
let mut indices: Vec<usize> = data.iter().map(|(_, _, i)| *i).collect();
|
||||||
|
let mut carry = true;
|
||||||
|
for i in (0..data.len()).rev() {
|
||||||
|
if !carry { break; }
|
||||||
|
indices[i] += 1;
|
||||||
|
if indices[i] >= data[i].1.len() { indices[i] = 0; } else { carry = false; }
|
||||||
|
}
|
||||||
|
if let Some(view) = self.model.active_view_mut() {
|
||||||
|
for (i, (cat, items, _)) in data.iter().enumerate() {
|
||||||
|
view.set_page_selection(cat, &items[indices[i]]);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn page_prev(&mut self) {
|
fn page_prev(&mut self) {
|
||||||
let page_cats: Vec<String> = self.model.active_view()
|
let data = self.page_cat_data();
|
||||||
.map(|v| v.categories_on(Axis::Page).into_iter().map(String::from).collect())
|
if data.is_empty() { return; }
|
||||||
.unwrap_or_default();
|
// Odometer: decrement from last category, borrow propagates backward.
|
||||||
for cat_name in &page_cats {
|
let mut indices: Vec<usize> = data.iter().map(|(_, _, i)| *i).collect();
|
||||||
let items: Vec<String> = self.model.category(cat_name)
|
let mut borrow = true;
|
||||||
.map(|c| c.ordered_item_names().into_iter().map(String::from).collect())
|
for i in (0..data.len()).rev() {
|
||||||
.unwrap_or_default();
|
if !borrow { break; }
|
||||||
if items.is_empty() { continue; }
|
if indices[i] == 0 {
|
||||||
let current = self.model.active_view()
|
indices[i] = data[i].1.len().saturating_sub(1);
|
||||||
.and_then(|v| v.page_selection(cat_name))
|
} else {
|
||||||
.map(String::from)
|
indices[i] -= 1;
|
||||||
.unwrap_or_else(|| items[0].clone());
|
borrow = false;
|
||||||
let idx = items.iter().position(|i| i == ¤t).unwrap_or(0);
|
}
|
||||||
let prev_idx = idx.saturating_sub(1);
|
}
|
||||||
if let Some(view) = self.model.active_view_mut() {
|
if let Some(view) = self.model.active_view_mut() {
|
||||||
view.set_page_selection(cat_name, &items[prev_idx]);
|
for (i, (cat, items, _)) in data.iter().enumerate() {
|
||||||
|
view.set_page_selection(cat, &items[indices[i]]);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user