Merge pull request #478 from joshuamegnauth54/issue-458-show-trashed-on-time

Show file deletion date in Trash
This commit is contained in:
Jeremy Soller 2024-09-25 08:42:00 -06:00 committed by GitHub
commit 181bed29a4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 80 additions and 12 deletions

View file

@ -14,6 +14,7 @@ today = Today
# List view # List view
name = Name name = Name
modified = Modified modified = Modified
trashed-on = Trashed
size = Size size = Size
# Dialogs # Dialogs
@ -198,6 +199,7 @@ remove-from-sidebar = Remove from sidebar
sort-by-name = Sort by name sort-by-name = Sort by name
sort-by-modified = Sort by modified sort-by-modified = Sort by modified
sort-by-size = Sort by size sort-by-size = Sort by size
sort-by-trashed = Sort by delete time
# Menu # Menu

View file

@ -238,7 +238,7 @@ pub fn context_menu<'a>(
} else { } else {
// TODO: Nested menu // TODO: Nested menu
children.push(sort_item(fl!("sort-by-name"), HeadingOptions::Name)); children.push(sort_item(fl!("sort-by-name"), HeadingOptions::Name));
children.push(sort_item(fl!("sort-by-modified"), HeadingOptions::Modified)); children.push(sort_item(fl!("sort-by-trashed"), HeadingOptions::TrashedOn));
children.push(sort_item(fl!("sort-by-size"), HeadingOptions::Size)); children.push(sort_item(fl!("sort-by-size"), HeadingOptions::Size));
} }
} }
@ -277,6 +277,7 @@ pub fn dialog_menu<'a>(
Action::SetSort(sort, dir), Action::SetSort(sort, dir),
) )
}; };
let in_trash = tab.location == Location::Trash;
MenuBar::new(vec![ MenuBar::new(vec![
menu::Tree::with_children( menu::Tree::with_children(
@ -315,12 +316,20 @@ pub fn dialog_menu<'a>(
sort_item(fl!("sort-z-a"), tab::HeadingOptions::Name, false), sort_item(fl!("sort-z-a"), tab::HeadingOptions::Name, false),
sort_item( sort_item(
fl!("sort-newest-first"), fl!("sort-newest-first"),
tab::HeadingOptions::Modified, if in_trash {
tab::HeadingOptions::TrashedOn
} else {
tab::HeadingOptions::Modified
},
false, false,
), ),
sort_item( sort_item(
fl!("sort-oldest-first"), fl!("sort-oldest-first"),
tab::HeadingOptions::Modified, if in_trash {
tab::HeadingOptions::TrashedOn
} else {
tab::HeadingOptions::Modified
},
true, true,
), ),
sort_item( sort_item(
@ -357,6 +366,7 @@ pub fn menu_bar<'a>(
Action::SetSort(sort, dir), Action::SetSort(sort, dir),
) )
}; };
let in_trash = tab_opt.map_or(false, |tab| tab.location == Location::Trash);
MenuBar::new(vec![ MenuBar::new(vec![
menu::Tree::with_children( menu::Tree::with_children(
@ -444,12 +454,20 @@ pub fn menu_bar<'a>(
sort_item(fl!("sort-z-a"), tab::HeadingOptions::Name, false), sort_item(fl!("sort-z-a"), tab::HeadingOptions::Name, false),
sort_item( sort_item(
fl!("sort-newest-first"), fl!("sort-newest-first"),
tab::HeadingOptions::Modified, if in_trash {
tab::HeadingOptions::TrashedOn
} else {
tab::HeadingOptions::Modified
},
false, false,
), ),
sort_item( sort_item(
fl!("sort-oldest-first"), fl!("sort-oldest-first"),
tab::HeadingOptions::Modified, if in_trash {
tab::HeadingOptions::TrashedOn
} else {
tab::HeadingOptions::Modified
},
true, true,
), ),
sort_item( sort_item(

View file

@ -51,7 +51,7 @@ use std::{
os::unix::fs::MetadataExt, os::unix::fs::MetadataExt,
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::{Arc, Mutex}, sync::{Arc, Mutex},
time::{Duration, Instant}, time::{Duration, Instant, SystemTime},
}; };
use crate::{ use crate::{
@ -265,6 +265,21 @@ fn format_permissions(metadata: &Metadata, owner: PermissionOwner) -> String {
struct FormatTime(std::time::SystemTime); struct FormatTime(std::time::SystemTime);
impl FormatTime {
fn from_secs(secs: i64) -> Option<Self> {
// This looks convoluted because we need to ensure the units match up
let secs: u64 = secs.try_into().ok()?;
let now = SystemTime::now();
let filetime_diff = now
.duration_since(SystemTime::UNIX_EPOCH)
.map(|from_epoch| from_epoch.as_secs())
.ok()
.and_then(|now_secs| now_secs.checked_sub(secs))
.map(Duration::from_secs)?;
now.checked_add(filetime_diff).map(FormatTime)
}
}
impl Display for FormatTime { impl Display for FormatTime {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let date_time = chrono::DateTime::<chrono::Local>::from(self.0); let date_time = chrono::DateTime::<chrono::Local>::from(self.0);
@ -1219,6 +1234,7 @@ pub enum HeadingOptions {
Name = 0, Name = 0,
Modified, Modified,
Size, Size,
TrashedOn,
} }
impl fmt::Display for HeadingOptions { impl fmt::Display for HeadingOptions {
@ -1227,6 +1243,7 @@ impl fmt::Display for HeadingOptions {
HeadingOptions::Name => write!(f, "{}", fl!("name")), HeadingOptions::Name => write!(f, "{}", fl!("name")),
HeadingOptions::Modified => write!(f, "{}", fl!("modified")), HeadingOptions::Modified => write!(f, "{}", fl!("modified")),
HeadingOptions::Size => write!(f, "{}", fl!("size")), HeadingOptions::Size => write!(f, "{}", fl!("size")),
HeadingOptions::TrashedOn => write!(f, "{}", fl!("trashed-on")),
} }
} }
} }
@ -1237,6 +1254,7 @@ impl HeadingOptions {
HeadingOptions::Name.to_string(), HeadingOptions::Name.to_string(),
HeadingOptions::Modified.to_string(), HeadingOptions::Modified.to_string(),
HeadingOptions::Size.to_string(), HeadingOptions::Size.to_string(),
HeadingOptions::TrashedOn.to_string(),
] ]
} }
} }
@ -2495,6 +2513,26 @@ impl Tab {
} }
}); });
} }
HeadingOptions::TrashedOn => {
let time_deleted = |x: &Item| match &x.metadata {
ItemMetadata::Trash { entry, .. } => Some(entry.time_deleted),
_ => None,
};
items.sort_by(|a, b| {
let a_time_deleted = time_deleted(a.1);
let b_time_deleted = time_deleted(b.1);
if self.config.folders_first {
match (a.1.metadata.is_dir(), b.1.metadata.is_dir()) {
(true, false) => Ordering::Less,
(false, true) => Ordering::Greater,
_ => check_reverse(a_time_deleted.cmp(&b_time_deleted), heading_sort),
}
} else {
check_reverse(b_time_deleted.cmp(&a_time_deleted), heading_sort)
}
});
}
} }
Some(items) Some(items)
} }
@ -2765,12 +2803,19 @@ impl Tab {
let heading_row = widget::row::with_children(vec![ let heading_row = widget::row::with_children(vec![
heading_item(fl!("name"), Length::Fill, HeadingOptions::Name), heading_item(fl!("name"), Length::Fill, HeadingOptions::Name),
//TODO: do not show modified column when in the trash if self.location == Location::Trash {
heading_item( heading_item(
fl!("modified"), fl!("trashed-on"),
Length::Fixed(modified_width), Length::Fixed(modified_width),
HeadingOptions::Modified, HeadingOptions::TrashedOn,
), )
} else {
heading_item(
fl!("modified"),
Length::Fixed(modified_width),
HeadingOptions::Modified,
)
},
heading_item(fl!("size"), Length::Fixed(size_width), HeadingOptions::Size), heading_item(fl!("size"), Length::Fixed(size_width), HeadingOptions::Size),
]) ])
.align_items(Alignment::Center) .align_items(Alignment::Center)
@ -3384,6 +3429,9 @@ impl Tab {
Ok(time) => format_time(time).to_string(), Ok(time) => format_time(time).to_string(),
Err(_) => String::new(), Err(_) => String::new(),
}, },
ItemMetadata::Trash { entry, .. } => FormatTime::from_secs(entry.time_deleted)
.map(|t| t.to_string())
.unwrap_or_default(),
_ => String::new(), _ => String::new(),
}; };