use super::*;
#[derive(Clone, Debug, PartialEq)]
pub struct Flat {
pub dir: PathBuf,
pub feed: Option<Arc<Vec<(PathBuf, bool)>>>,
}
impl AppState {
pub fn feed_follow(&mut self, moves: &[(PathBuf, PathBuf)]) {
for flat in [&mut self.flat_left, &mut self.flat_right].into_iter().flatten() {
let Some(feed) = &flat.feed else { continue };
let dir = &flat.dir;
let followed: Vec<(PathBuf, bool)> = feed
.iter()
.map(|(relative, is_dir)| {
let at = dir.join(relative);
let moved = moves.iter().find_map(|(from, to)| at.strip_prefix(from).ok().map(|below| if below.as_os_str().is_empty() { to.clone() } else { to.join(below) }));
let relative = moved.and_then(|moved| moved.strip_prefix(dir).ok().map(Path::to_path_buf)).unwrap_or_else(|| relative.clone());
(relative, *is_dir)
})
.collect();
flat.feed = Some(Arc::new(followed));
}
}
pub fn flat(&self, is_left: bool) -> Option<&Flat> {
if is_left { self.flat_left.as_ref() } else { self.flat_right.as_ref() }
}
pub(super) fn flat_mut(&mut self, is_left: bool) -> &mut Option<Flat> {
if is_left { &mut self.flat_left } else { &mut self.flat_right }
}
pub fn toggle_flat(&mut self) {
let is_left = self.is_left_active;
let (children, state) = if is_left { (&self.children_left, &self.state_left) } else { (&self.children_right, &self.state_right) };
let cursor = state.selected().and_then(|index| children.get(index)).map(|item| item.name_os.clone());
let before = self.flat(is_left).cloned();
let landing = match self.flat_mut(is_left).take() {
Some(_) => cursor.and_then(|name| Path::new(&name).components().next().map(|first| first.as_os_str().to_os_string())),
None => {
*self.flat_mut(is_left) = Some(Flat { dir: self.panel_dir(is_left), feed: None });
cursor
}
};
self.reload_panel(is_left, landing.as_deref());
if let Some(pending) = self.listing_mut(is_left) {
pending.restore_flat = Some(before);
}
}
}