mirror of
https://github.com/bobwen-dev/hunter
synced 2025-04-12 00:55:41 +02:00
fix blocking when entering/leaving large directory
This commit is contained in:
parent
428879e184
commit
abc35e0e7d
@ -12,7 +12,7 @@ use std::collections::HashSet;
|
|||||||
|
|
||||||
use crate::files::{File, Files};
|
use crate::files::{File, Files};
|
||||||
use crate::fscache::FsCache;
|
use crate::fscache::FsCache;
|
||||||
use crate::listview::ListView;
|
use crate::listview::{ListView, FileSource};
|
||||||
use crate::hbox::HBox;
|
use crate::hbox::HBox;
|
||||||
use crate::widget::Widget;
|
use crate::widget::Widget;
|
||||||
use crate::tabview::{TabView, Tabbable};
|
use crate::tabview::{TabView, Tabbable};
|
||||||
@ -259,65 +259,44 @@ impl FileBrowser {
|
|||||||
|
|
||||||
let cache = fs_cache.clone();
|
let cache = fs_cache.clone();
|
||||||
let main_widget = AsyncWidget::new(&core, move |stale| {
|
let main_widget = AsyncWidget::new(&core, move |stale| {
|
||||||
let name = if main_path.parent().is_none() {
|
let dir = File::new_from_path(&main_path, None)?;
|
||||||
"root".to_string()
|
let source = FileSource::Path(dir);
|
||||||
} else {
|
ListView::builder(core_m, source)
|
||||||
main_path.file_name()?
|
.meta_all()
|
||||||
.to_string_lossy()
|
.prerender()
|
||||||
.to_string()
|
.with_cache(cache)
|
||||||
};
|
.with_stale(stale.clone())
|
||||||
let main_dir = File::new(&name,
|
.build()
|
||||||
main_path.clone(),
|
|
||||||
None);
|
|
||||||
let (selected_file, files) = cache.get_files(&main_dir,
|
|
||||||
stale.clone())?;
|
|
||||||
let mut files = files.run_sync()?;
|
|
||||||
|
|
||||||
files.meta_all();
|
|
||||||
|
|
||||||
let mut list = ListView::new(&core_m.clone(),
|
|
||||||
files);
|
|
||||||
|
|
||||||
selected_file.map(|f| list.select_file(&f));
|
|
||||||
|
|
||||||
|
|
||||||
list.refresh().log();
|
|
||||||
|
|
||||||
Ok(list)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let cache = fs_cache.clone();
|
let cache = fs_cache.clone();
|
||||||
if let Some(left_path) = left_path {
|
if let Some(left_path) = left_path {
|
||||||
let left_widget = AsyncWidget::new(&core, move |stale| {
|
let left_widget = AsyncWidget::new(&core_l.clone(), move |stale| {
|
||||||
let name = if left_path.parent().is_none() {
|
let dir = File::new_from_path(&left_path, None)?;
|
||||||
"root".to_string()
|
let source = FileSource::Path(dir);
|
||||||
} else {
|
ListView::builder(core_l, source)
|
||||||
left_path.file_name()?
|
.meta_all()
|
||||||
.to_string_lossy()
|
.prerender()
|
||||||
.to_string()
|
.with_cache(cache)
|
||||||
};
|
.with_stale(stale.clone())
|
||||||
let left_dir = File::new(&name,
|
.build()
|
||||||
left_path.clone(),
|
|
||||||
None);
|
|
||||||
let (selected_file, files) = cache.get_files(&left_dir,
|
|
||||||
stale.clone())?;
|
|
||||||
let files = files.run_sync()?;
|
|
||||||
let mut list = ListView::new(&core_l, files);
|
|
||||||
|
|
||||||
selected_file.map(|f| list.select_file(&f));
|
|
||||||
list.refresh().log();
|
|
||||||
|
|
||||||
Ok(list)
|
|
||||||
});
|
});
|
||||||
let left_widget = FileBrowserWidgets::FileList(left_widget);
|
let left_widget = FileBrowserWidgets::FileList(left_widget);
|
||||||
columns.push_widget(left_widget);
|
columns.push_widget(left_widget);
|
||||||
} else {
|
} else {
|
||||||
let left_widget = AsyncWidget::new(&core, move |_| {
|
let mut left_widget = AsyncWidget::new(&core_l.clone(), move |_| {
|
||||||
let blank = TextView::new_blank(&core_l);
|
let files = Files::default();
|
||||||
Ok(blank)
|
let source = FileSource::Files(files);
|
||||||
|
ListView::builder(core_l, source).build()
|
||||||
});
|
});
|
||||||
|
|
||||||
let left_widget = FileBrowserWidgets::Blank(left_widget);
|
left_widget.widget.on_ready(move |_, stale| {
|
||||||
|
// To stop from drawing empty placeholder
|
||||||
|
stale.set_stale()?;
|
||||||
|
Ok(())
|
||||||
|
}).log();
|
||||||
|
|
||||||
|
let left_widget = FileBrowserWidgets::FileList(left_widget);
|
||||||
columns.push_widget(left_widget);
|
columns.push_widget(left_widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,41 +344,44 @@ impl FileBrowser {
|
|||||||
}
|
}
|
||||||
err @ Err(_) => err.log()
|
err @ Err(_) => err.log()
|
||||||
}
|
}
|
||||||
|
self.preview_widget_mut()?.set_stale().log();
|
||||||
|
self.preview_widget_mut()?.cancel_animation().log();
|
||||||
let previewer_files = self.preview_widget_mut()?.take_files().ok();
|
let previewer_files = self.preview_widget_mut()?.take_files().ok();
|
||||||
|
|
||||||
self.columns.remove_widget(0);
|
|
||||||
|
|
||||||
self.prev_cwd = Some(self.cwd.clone());
|
self.prev_cwd = Some(self.cwd.clone());
|
||||||
self.cwd = dir.clone();
|
self.cwd = dir.clone();
|
||||||
|
|
||||||
let core = self.core.clone();
|
|
||||||
let cache = self.fs_cache.clone();
|
let cache = self.fs_cache.clone();
|
||||||
|
self.main_async_widget_mut()?.change_to(move |stale, core| {
|
||||||
let main_widget = AsyncWidget::new(&core.clone(), move |stale| {
|
let source = match previewer_files {
|
||||||
let (selected_file, files) = match previewer_files {
|
Some(files) => FileSource::Files(files),
|
||||||
Some(files) => (None, files),
|
None => FileSource::Path(dir)
|
||||||
None => {
|
|
||||||
let (selected_file, files) = cache.get_files(&dir,
|
|
||||||
stale.clone())?;
|
|
||||||
let files = files.run_sync()?;
|
|
||||||
(selected_file, files)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut list = ListView::new(&core, files);
|
ListView::builder(core, source)
|
||||||
|
.meta_all()
|
||||||
|
.prerender()
|
||||||
|
.with_cache(cache)
|
||||||
|
.with_stale(stale.clone())
|
||||||
|
.build()
|
||||||
|
}).log();
|
||||||
|
|
||||||
selected_file.map(|f| list.select_file(&f));
|
|
||||||
list.content.meta_all();
|
|
||||||
|
|
||||||
Ok(list)
|
let cache = self.fs_cache.clone();
|
||||||
});
|
let left_dir = self.cwd.parent_as_file()?;
|
||||||
|
self.left_async_widget_mut()?.change_to(move |stale, core| {
|
||||||
let main_widget = FileBrowserWidgets::FileList(main_widget);
|
let source = FileSource::Path(left_dir);
|
||||||
self.columns.insert_widget(1, main_widget);
|
|
||||||
|
|
||||||
|
ListView::builder(core, source)
|
||||||
|
.prerender()
|
||||||
|
.with_cache(cache)
|
||||||
|
.with_stale(stale.clone())
|
||||||
|
.build()
|
||||||
|
}).log();
|
||||||
} else {
|
} else {
|
||||||
self.preview_widget().map(|preview| preview.cancel_animation()).log();
|
self.preview_widget_mut().map(|preview| {
|
||||||
|
preview.cancel_animation().log();
|
||||||
|
}).log();
|
||||||
self.core.get_sender().send(Events::InputEnabled(false))?;
|
self.core.get_sender().send(Events::InputEnabled(false))?;
|
||||||
self.core.screen.suspend().log();
|
self.core.screen.suspend().log();
|
||||||
|
|
||||||
@ -421,6 +403,7 @@ impl FileBrowser {
|
|||||||
"xdg-open", err)).log()
|
"xdg-open", err)).log()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -548,40 +531,61 @@ impl FileBrowser {
|
|||||||
|
|
||||||
pub fn go_back(&mut self) -> HResult<()> {
|
pub fn go_back(&mut self) -> HResult<()> {
|
||||||
if let Ok(new_cwd) = self.cwd.parent_as_file() {
|
if let Ok(new_cwd) = self.cwd.parent_as_file() {
|
||||||
let core = self.core.clone();
|
let previewer_selection = self.selected_file().ok();
|
||||||
|
let main_selection = self.cwd.clone();
|
||||||
let preview_files = self.take_main_files();
|
let preview_files = self.take_main_files();
|
||||||
let old_left = self.columns.remove_widget(0);
|
|
||||||
self.prev_cwd = Some(self.cwd.clone());
|
self.prev_cwd = Some(self.cwd.clone());
|
||||||
self.cwd = new_cwd.clone();
|
self.cwd = new_cwd.clone();
|
||||||
|
|
||||||
if let Ok(left_dir) = new_cwd.parent_as_file() {
|
|
||||||
let cache = self.fs_cache.clone();
|
let cache = self.fs_cache.clone();
|
||||||
let left_widget = AsyncWidget::new(&core.clone(), move |stale| {
|
|
||||||
let (selected_file, files) = cache.get_files(&left_dir,
|
|
||||||
stale.clone())?;
|
|
||||||
let files = files.run_sync()?;
|
|
||||||
let mut list = ListView::new(&core, files);
|
|
||||||
selected_file.map(|f| list.select_file(&f));
|
|
||||||
Ok(list)
|
|
||||||
});
|
|
||||||
|
|
||||||
let left_widget = FileBrowserWidgets::FileList(left_widget);
|
let files = self.take_left_files();
|
||||||
self.columns.prepend_widget(left_widget);
|
let file_source = match files {
|
||||||
|
Ok(files) => FileSource::Files(files),
|
||||||
|
Err(_) => FileSource::Path(new_cwd.clone())
|
||||||
|
};
|
||||||
|
|
||||||
|
self.main_async_widget_mut()?.change_to(move |stale, core| {
|
||||||
|
ListView::builder(core, file_source)
|
||||||
|
.select(main_selection)
|
||||||
|
.meta_all()
|
||||||
|
.prerender()
|
||||||
|
.with_cache(cache)
|
||||||
|
.with_stale(stale.clone())
|
||||||
|
.build()
|
||||||
|
}).log();
|
||||||
|
|
||||||
|
if let Ok(left_dir) = new_cwd.parent_as_file() {
|
||||||
|
let file_source = FileSource::Path(left_dir);
|
||||||
|
let cache = self.fs_cache.clone();
|
||||||
|
self.left_async_widget_mut()?.change_to(move |stale, core| {
|
||||||
|
ListView::builder(core, file_source)
|
||||||
|
.prerender()
|
||||||
|
.with_cache(cache)
|
||||||
|
.with_stale(stale.clone())
|
||||||
|
.build()
|
||||||
|
}).log();
|
||||||
} else {
|
} else {
|
||||||
let left_widget = AsyncWidget::new(&core.clone(), move |_| {
|
// Just place a dummy in the left column
|
||||||
let blank = TextView::new_blank(&core);
|
self.left_async_widget_mut()?.change_to(move |_, core| {
|
||||||
Ok(blank)
|
let files = Files::default();
|
||||||
});
|
let source = FileSource::Files(files);
|
||||||
|
ListView::builder(core, source).build()
|
||||||
|
}).log();
|
||||||
|
|
||||||
let left_widget = FileBrowserWidgets::Blank(left_widget);
|
self.left_async_widget_mut()?.widget.on_ready(move |_, stale| {
|
||||||
self.columns.prepend_widget(left_widget);
|
// To stop from drawing empty placeholder
|
||||||
|
stale.set_stale()?;
|
||||||
|
Ok(())
|
||||||
|
}).log()
|
||||||
}
|
}
|
||||||
self.columns.replace_widget(1, old_left);
|
|
||||||
self.main_widget_mut()?.content.meta_all();
|
|
||||||
|
|
||||||
if let Ok(preview_files) = preview_files {
|
if let Ok(preview_files) = preview_files {
|
||||||
self.preview_widget_mut().map(|preview| {
|
self.preview_widget_mut().map(|preview| {
|
||||||
preview.put_preview_files(preview_files)
|
preview.put_preview_files(preview_files,
|
||||||
|
previewer_selection)
|
||||||
}).ok();
|
}).ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -686,6 +690,9 @@ impl FileBrowser {
|
|||||||
|
|
||||||
let selection = self.cwd()?.clone();
|
let selection = self.cwd()?.clone();
|
||||||
|
|
||||||
|
self.cwd.parent_as_file()
|
||||||
|
.map(|dir| self.fs_cache
|
||||||
|
.set_selection(dir.clone(), selection.clone())).log();
|
||||||
self.left_widget_mut()?.select_file(&selection);
|
self.left_widget_mut()?.select_file(&selection);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1294,7 +1301,12 @@ impl Acting for FileBrowser {
|
|||||||
Left => self.go_back(),
|
Left => self.go_back(),
|
||||||
Right => self.enter_dir(),
|
Right => self.enter_dir(),
|
||||||
_ => {
|
_ => {
|
||||||
|
let pos = self.main_widget()?.get_selection();
|
||||||
self.main_widget_mut()?.movement(movement)?;
|
self.main_widget_mut()?.movement(movement)?;
|
||||||
|
if self.main_widget()?.get_selection() != pos {
|
||||||
|
self.preview_widget_mut()?.set_stale().log();
|
||||||
|
self.preview_widget_mut()?.cancel_animation().log();
|
||||||
|
}
|
||||||
self.save_selected_file()?;
|
self.save_selected_file()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -631,6 +631,8 @@ impl Files {
|
|||||||
pub fn meta_all(&mut self) {
|
pub fn meta_all(&mut self) {
|
||||||
let len = self.len();
|
let len = self.len();
|
||||||
self.meta_upto(len, None);
|
self.meta_upto(len, None);
|
||||||
|
self.dirty_meta.set_dirty();
|
||||||
|
self.meta_set_fresh().log();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn meta_upto(&mut self, to: usize, sender: Option<Sender<Events>>) {
|
pub fn meta_upto(&mut self, to: usize, sender: Option<Sender<Events>>) {
|
||||||
|
@ -6,7 +6,7 @@ use std::path::PathBuf;
|
|||||||
|
|
||||||
use crate::files::{File, Files, Kind};
|
use crate::files::{File, Files, Kind};
|
||||||
use crate::fscache::FsCache;
|
use crate::fscache::FsCache;
|
||||||
use crate::listview::ListView;
|
use crate::listview::{ListView, FileSource};
|
||||||
use crate::textview::TextView;
|
use crate::textview::TextView;
|
||||||
use crate::widget::{Widget, WidgetCore};
|
use crate::widget::{Widget, WidgetCore};
|
||||||
use crate::coordinates::Coordinates;
|
use crate::coordinates::Coordinates;
|
||||||
@ -295,6 +295,7 @@ impl Previewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_stale(&mut self) -> HResult<()> {
|
pub fn set_stale(&mut self) -> HResult<()> {
|
||||||
|
self.cancel_animation()?;
|
||||||
self.widget.set_stale()
|
self.widget.set_stale()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,25 +317,31 @@ impl Previewer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn put_preview_files(&mut self, files: Files) {
|
pub fn put_preview_files(&mut self,
|
||||||
let core = self.core.clone();
|
files: Files,
|
||||||
|
selected_file: Option<File>) {
|
||||||
let dir = files.directory.clone();
|
let dir = files.directory.clone();
|
||||||
let cache = self.cache.clone();
|
let cache = self.cache.clone();
|
||||||
self.file = Some(dir);
|
self.file = Some(dir);
|
||||||
|
|
||||||
self.widget = AsyncWidget::new(&self.core, move |_| {
|
self.widget.change_to(move |stale, core| {
|
||||||
let selected_file = cache.get_selection(&files.directory);
|
let source = crate::listview::FileSource::Files(files);
|
||||||
let mut filelist = ListView::new(&core, files);
|
|
||||||
|
|
||||||
selected_file.map(|file| filelist.select_file(&file)).log();
|
let list = ListView::builder(core.clone(), source)
|
||||||
|
.prerender()
|
||||||
|
.with_cache(cache)
|
||||||
|
.with_stale(stale.clone())
|
||||||
|
.select(selected_file)
|
||||||
|
.build()?;
|
||||||
|
|
||||||
Ok(PreviewWidget::FileList(filelist))
|
Ok(PreviewWidget::FileList(list))
|
||||||
});
|
}).log();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_file(&mut self,
|
pub fn set_file(&mut self,
|
||||||
file: &File) -> HResult<()> {
|
file: &File) -> HResult<()> {
|
||||||
if Some(file) == self.file.as_ref() && !self.widget.is_stale()? { return Ok(()) }
|
if Some(file) == self.file.as_ref() && !self.widget.is_stale()? { return Ok(()) }
|
||||||
|
self.widget.set_stale().ok();
|
||||||
|
|
||||||
let same_dir = self.file
|
let same_dir = self.file
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@ -349,8 +356,6 @@ impl Previewer {
|
|||||||
let animator = self.animator.clone();
|
let animator = self.animator.clone();
|
||||||
let has_media = self.core.config().media_available();
|
let has_media = self.core.config().media_available();
|
||||||
|
|
||||||
self.widget.set_stale().ok();
|
|
||||||
|
|
||||||
if same_dir {
|
if same_dir {
|
||||||
self.animator.set_fresh().ok();
|
self.animator.set_fresh().ok();
|
||||||
} else {
|
} else {
|
||||||
@ -430,7 +435,7 @@ impl Previewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn reload(&mut self) {
|
pub fn reload(&mut self) {
|
||||||
if let Some(file) = self.file.clone() {
|
if let Some(file) = self.file.take() {
|
||||||
self.file = None;
|
self.file = None;
|
||||||
self.set_file(&file).log();
|
self.set_file(&file).log();
|
||||||
}
|
}
|
||||||
@ -448,19 +453,17 @@ impl Previewer {
|
|||||||
stale: &Stale,
|
stale: &Stale,
|
||||||
animator: &Stale)
|
animator: &Stale)
|
||||||
-> HResult<PreviewWidget> {
|
-> HResult<PreviewWidget> {
|
||||||
let (selection, cached_files) = cache.get_files(&file, stale.clone())?;
|
if stale.is_stale()? { return Previewer::preview_failed(&file) }
|
||||||
|
let source = FileSource::Path(file.clone());
|
||||||
|
|
||||||
let files = cached_files.run_sync()?;
|
let mut file_list = ListView::builder(core.clone(), source)
|
||||||
|
.prerender()
|
||||||
|
.with_cache(cache)
|
||||||
|
.with_stale(stale.clone())
|
||||||
|
.build()?;
|
||||||
|
|
||||||
if stale.is_stale()? { return Previewer::preview_failed(&file) }
|
if stale.is_stale()? { return Previewer::preview_failed(&file) }
|
||||||
|
|
||||||
let mut file_list = ListView::new(&core, files);
|
|
||||||
if let Some(selection) = selection {
|
|
||||||
file_list.select_file(&selection);
|
|
||||||
}
|
|
||||||
file_list.set_coordinates(&core.coordinates)?;
|
|
||||||
file_list.refresh()?;
|
|
||||||
if stale.is_stale()? { return Previewer::preview_failed(&file) }
|
|
||||||
file_list.animate_slide_up(Some(animator))?;
|
file_list.animate_slide_up(Some(animator))?;
|
||||||
Ok(PreviewWidget::FileList(file_list))
|
Ok(PreviewWidget::FileList(file_list))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user