Optimization for reloading metadata

This commit is contained in:
Jeremy Soller 2024-03-20 16:27:00 -06:00
parent 64612b7230
commit d0a2a9262e
No known key found for this signature in database
GPG key ID: D02FD439211AF56F
3 changed files with 83 additions and 8 deletions

View file

@ -916,16 +916,55 @@ impl Application for App {
log::debug!("{:?}", events);
let mut needs_reload = Vec::new();
for entity in self.tab_model.iter() {
if let Some(tab) = self.tab_model.data::<Tab>(entity) {
let entities: Vec<_> = self.tab_model.iter().collect();
for entity in entities {
if let Some(tab) = self.tab_model.data_mut::<Tab>(entity) {
//TODO: support reloading trash, somehow
if let Location::Path(path) = &tab.location {
let mut contains_change = false;
for event in events.iter() {
for event_path in event.paths.iter() {
if event_path.starts_with(&path) {
contains_change = true;
break;
match event.kind {
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;
}
}
}
}
}

View file

@ -33,7 +33,7 @@ use std::{
use crate::{
config::TabConfig,
fl, home_dir,
tab::{self, Location, Tab},
tab::{self, ItemMetadata, Location, Tab},
};
#[derive(Clone, Debug)]
@ -460,8 +460,44 @@ impl Application for App {
for event in events.iter() {
for event_path in event.paths.iter() {
if event_path.starts_with(&path) {
contains_change = true;
break;
match event.kind {
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;
}
}
}
}
}

View file

@ -673,7 +673,7 @@ pub struct Tab {
pub history_i: usize,
pub history: Vec<Location>,
pub config: TabConfig,
items_opt: Option<Vec<Item>>,
pub(crate) items_opt: Option<Vec<Item>>,
scrollable_id: widget::Id,
select_focus: Option<usize>,
select_shift: Option<usize>,