Optimization for reloading metadata
This commit is contained in:
parent
64612b7230
commit
d0a2a9262e
3 changed files with 83 additions and 8 deletions
47
src/app.rs
47
src/app.rs
|
|
@ -916,16 +916,55 @@ impl Application for App {
|
||||||
log::debug!("{:?}", events);
|
log::debug!("{:?}", events);
|
||||||
|
|
||||||
let mut needs_reload = Vec::new();
|
let mut needs_reload = Vec::new();
|
||||||
for entity in self.tab_model.iter() {
|
let entities: Vec<_> = self.tab_model.iter().collect();
|
||||||
if let Some(tab) = self.tab_model.data::<Tab>(entity) {
|
for entity in entities {
|
||||||
|
if let Some(tab) = self.tab_model.data_mut::<Tab>(entity) {
|
||||||
//TODO: support reloading trash, somehow
|
//TODO: support reloading trash, somehow
|
||||||
if let Location::Path(path) = &tab.location {
|
if let Location::Path(path) = &tab.location {
|
||||||
let mut contains_change = false;
|
let mut contains_change = false;
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
for event_path in event.paths.iter() {
|
for event_path in event.paths.iter() {
|
||||||
if event_path.starts_with(&path) {
|
if event_path.starts_with(&path) {
|
||||||
contains_change = true;
|
match event.kind {
|
||||||
break;
|
notify::EventKind::Modify(
|
||||||
|
notify::event::ModifyKind::Metadata(_),
|
||||||
|
)
|
||||||
|
| notify::EventKind::Modify(
|
||||||
|
notify::event::ModifyKind::Data(_),
|
||||||
|
) => {
|
||||||
|
// If metadata or data changed, find the matching item and reload it
|
||||||
|
//TODO: this could be further optimized by looking at what exactly changed
|
||||||
|
if let Some(items) = &mut tab.items_opt {
|
||||||
|
for item in items.iter_mut() {
|
||||||
|
if item.path_opt.as_ref()
|
||||||
|
== Some(event_path)
|
||||||
|
{
|
||||||
|
//TODO: reload more, like mime types?
|
||||||
|
match fs::metadata(&event_path) {
|
||||||
|
Ok(new_metadata) => match &mut item
|
||||||
|
.metadata
|
||||||
|
{
|
||||||
|
ItemMetadata::Path {
|
||||||
|
metadata,
|
||||||
|
..
|
||||||
|
} => *metadata = new_metadata,
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
log::warn!("failed to reload metadata for {:?}: {}", path, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TODO item.thumbnail_opt =
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// Any other events reload the whole tab
|
||||||
|
contains_change = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ use std::{
|
||||||
use crate::{
|
use crate::{
|
||||||
config::TabConfig,
|
config::TabConfig,
|
||||||
fl, home_dir,
|
fl, home_dir,
|
||||||
tab::{self, Location, Tab},
|
tab::{self, ItemMetadata, Location, Tab},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
@ -460,8 +460,44 @@ impl Application for App {
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
for event_path in event.paths.iter() {
|
for event_path in event.paths.iter() {
|
||||||
if event_path.starts_with(&path) {
|
if event_path.starts_with(&path) {
|
||||||
contains_change = true;
|
match event.kind {
|
||||||
break;
|
notify::EventKind::Modify(
|
||||||
|
notify::event::ModifyKind::Metadata(_),
|
||||||
|
)
|
||||||
|
| notify::EventKind::Modify(notify::event::ModifyKind::Data(
|
||||||
|
_,
|
||||||
|
)) => {
|
||||||
|
// If metadata or data changed, find the matching item and reload it
|
||||||
|
//TODO: this could be further optimized by looking at what exactly changed
|
||||||
|
if let Some(items) = &mut self.tab.items_opt {
|
||||||
|
for item in items.iter_mut() {
|
||||||
|
if item.path_opt.as_ref() == Some(event_path) {
|
||||||
|
//TODO: reload more, like mime types?
|
||||||
|
match fs::metadata(&event_path) {
|
||||||
|
Ok(new_metadata) => {
|
||||||
|
match &mut item.metadata {
|
||||||
|
ItemMetadata::Path {
|
||||||
|
metadata,
|
||||||
|
..
|
||||||
|
} => *metadata = new_metadata,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
log::warn!("failed to reload metadata for {:?}: {}", path, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TODO item.thumbnail_opt =
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// Any other events reload the whole tab
|
||||||
|
contains_change = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -673,7 +673,7 @@ pub struct Tab {
|
||||||
pub history_i: usize,
|
pub history_i: usize,
|
||||||
pub history: Vec<Location>,
|
pub history: Vec<Location>,
|
||||||
pub config: TabConfig,
|
pub config: TabConfig,
|
||||||
items_opt: Option<Vec<Item>>,
|
pub(crate) items_opt: Option<Vec<Item>>,
|
||||||
scrollable_id: widget::Id,
|
scrollable_id: widget::Id,
|
||||||
select_focus: Option<usize>,
|
select_focus: Option<usize>,
|
||||||
select_shift: Option<usize>,
|
select_shift: Option<usize>,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue