parent
38829f4c00
commit
e34dcf1372
4 changed files with 125 additions and 64 deletions
118
src/tab.rs
118
src/tab.rs
|
|
@ -87,7 +87,9 @@ const DRAG_SCROLL_DISTANCE: f32 = 15.0;
|
|||
|
||||
//TODO: adjust for locales?
|
||||
const DATE_TIME_FORMAT: &str = "%b %-d, %-Y, %-I:%M %p";
|
||||
const DATE_TIME_FORMAT_MILITARY: &str = "%b %-d, %-Y, %-H:%M %p";
|
||||
const TIME_FORMAT: &str = "%-I:%M %p";
|
||||
const TIME_FORMAT_MILITARY: &str = "%-H:%M %p";
|
||||
static SPECIAL_DIRS: Lazy<HashMap<PathBuf, &'static str>> = Lazy::new(|| {
|
||||
let mut special_dirs = HashMap::new();
|
||||
if let Some(dir) = dirs::document_dir() {
|
||||
|
|
@ -380,10 +382,13 @@ fn format_permissions(metadata: &Metadata, owner: PermissionOwner) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
struct FormatTime(SystemTime);
|
||||
struct FormatTime {
|
||||
pub time: SystemTime,
|
||||
pub military_time: bool,
|
||||
}
|
||||
|
||||
impl FormatTime {
|
||||
fn from_secs(secs: i64) -> Option<Self> {
|
||||
fn from_secs(secs: i64, military_time: bool) -> 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();
|
||||
|
|
@ -393,31 +398,51 @@ impl FormatTime {
|
|||
.ok()
|
||||
.and_then(|now_secs| now_secs.checked_sub(secs))
|
||||
.map(Duration::from_secs)?;
|
||||
now.checked_add(filetime_diff).map(FormatTime)
|
||||
now.checked_add(filetime_diff).map(|time| Self {
|
||||
time,
|
||||
military_time,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for FormatTime {
|
||||
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.time);
|
||||
let now = chrono::Local::now();
|
||||
if date_time.date_naive() == now.date_naive() {
|
||||
write!(
|
||||
f,
|
||||
"{}, {}",
|
||||
fl!("today"),
|
||||
date_time.format_localized(TIME_FORMAT, *LANGUAGE_CHRONO)
|
||||
date_time.format_localized(
|
||||
if self.military_time {
|
||||
TIME_FORMAT_MILITARY
|
||||
} else {
|
||||
TIME_FORMAT
|
||||
},
|
||||
*LANGUAGE_CHRONO
|
||||
)
|
||||
)
|
||||
} else {
|
||||
date_time
|
||||
.format_localized(DATE_TIME_FORMAT, *LANGUAGE_CHRONO)
|
||||
.format_localized(
|
||||
if self.military_time {
|
||||
DATE_TIME_FORMAT_MILITARY
|
||||
} else {
|
||||
DATE_TIME_FORMAT
|
||||
},
|
||||
*LANGUAGE_CHRONO,
|
||||
)
|
||||
.fmt(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn format_time(time: SystemTime) -> FormatTime {
|
||||
FormatTime(time)
|
||||
const fn format_time(time: SystemTime, military_time: bool) -> FormatTime {
|
||||
FormatTime {
|
||||
time,
|
||||
military_time,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
|
|
@ -1497,6 +1522,7 @@ impl Item {
|
|||
&'a self,
|
||||
mime_app_cache_opt: Option<&'a mime_app::MimeAppCache>,
|
||||
sizes: IconSizes,
|
||||
military_time: bool,
|
||||
) -> Element<'a, Message> {
|
||||
let cosmic_theme::Spacing {
|
||||
space_xxxs,
|
||||
|
|
@ -1558,21 +1584,21 @@ impl Item {
|
|||
if let Ok(time) = metadata.created() {
|
||||
details = details.push(widget::text::body(fl!(
|
||||
"item-created",
|
||||
created = format_time(time).to_string()
|
||||
created = format_time(time, military_time).to_string()
|
||||
)));
|
||||
}
|
||||
|
||||
if let Ok(time) = metadata.modified() {
|
||||
details = details.push(widget::text::body(fl!(
|
||||
"item-modified",
|
||||
modified = format_time(time).to_string()
|
||||
modified = format_time(time, military_time).to_string()
|
||||
)));
|
||||
}
|
||||
|
||||
if let Ok(time) = metadata.accessed() {
|
||||
details = details.push(widget::text::body(fl!(
|
||||
"item-accessed",
|
||||
accessed = format_time(time).to_string()
|
||||
accessed = format_time(time, military_time).to_string()
|
||||
)));
|
||||
}
|
||||
|
||||
|
|
@ -1638,7 +1664,12 @@ impl Item {
|
|||
column.into()
|
||||
}
|
||||
|
||||
pub fn replace_view(&self, heading: String, sizes: IconSizes) -> Element<'_, Message> {
|
||||
pub fn replace_view(
|
||||
&self,
|
||||
heading: String,
|
||||
sizes: IconSizes,
|
||||
military_time: bool,
|
||||
) -> Element<'_, Message> {
|
||||
let cosmic_theme::Spacing { space_xxxs, .. } = theme::active().cosmic().spacing;
|
||||
|
||||
let mut row = widget::row().spacing(space_xxxs);
|
||||
|
|
@ -1662,7 +1693,7 @@ impl Item {
|
|||
if let Ok(time) = metadata.modified() {
|
||||
column = column.push(widget::text::body(format!(
|
||||
"Last modified: {}",
|
||||
format_time(time)
|
||||
format_time(time, military_time)
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
|
@ -1873,7 +1904,7 @@ impl Tab {
|
|||
viewport_rect: None,
|
||||
virtual_cursor_offset: None,
|
||||
last_scroll_position: None,
|
||||
last_scroll_offset: None
|
||||
last_scroll_offset: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2228,7 +2259,7 @@ impl Tab {
|
|||
// if our mouse is above the scrollable viewport, we want to scroll up
|
||||
let drag_start_point = Point {
|
||||
x: viewport.x,
|
||||
y: viewport.y
|
||||
y: viewport.y,
|
||||
};
|
||||
// diff_y should be NEGATIVE here when close to y=0 (above the MouseArea)
|
||||
// and positive when below the viewport
|
||||
|
|
@ -2241,39 +2272,30 @@ impl Tab {
|
|||
0.0
|
||||
};
|
||||
|
||||
|
||||
|
||||
commands.push(Command::AutoScroll(Some(scroll_y)));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if let Some(last_scroll_offset) = self.last_scroll_offset {
|
||||
if let Some(last_scroll_position) = self.last_scroll_position {
|
||||
self.virtual_cursor_offset = Some(Point {
|
||||
x: 0.0,
|
||||
y: (pos.y - last_scroll_position.y + last_scroll_offset.y)
|
||||
y: (pos.y - last_scroll_position.y
|
||||
+ last_scroll_offset.y),
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if let Some(last_scroll_position) = self.last_scroll_position {
|
||||
self.virtual_cursor_offset = Some(Point {
|
||||
x: 0.0,
|
||||
y: (pos.y - last_scroll_position.y)
|
||||
});
|
||||
}
|
||||
else {
|
||||
self.virtual_cursor_offset = Some(Point {
|
||||
x: 0.0,
|
||||
y: 0.0
|
||||
y: (pos.y - last_scroll_position.y),
|
||||
});
|
||||
} else {
|
||||
self.virtual_cursor_offset = Some(Point { x: 0.0, y: 0.0 });
|
||||
}
|
||||
}
|
||||
|
||||
commands.push(Command::AutoScroll(None));
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// reset our virtual cursor offset when we're back in bounds
|
||||
self.virtual_cursor_offset = None;
|
||||
self.last_scroll_position = Some(pos);
|
||||
|
|
@ -2292,13 +2314,11 @@ impl Tab {
|
|||
x: viewport.x - scroll_pos.x,
|
||||
y: viewport.y - scroll_pos.y,
|
||||
width: viewport.width,
|
||||
height: viewport.height
|
||||
height: viewport.height,
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
self.viewport_rect = Some(viewport);
|
||||
}
|
||||
|
||||
}
|
||||
Message::DragEnd(_) => {
|
||||
self.clicked = None;
|
||||
|
|
@ -2947,7 +2967,7 @@ impl Tab {
|
|||
Message::ScrollTab(scroll_speed) => {
|
||||
let mut new_offset = Point {
|
||||
x: 0.0,
|
||||
y: scroll_speed
|
||||
y: scroll_speed,
|
||||
};
|
||||
|
||||
if let Some(virtual_cursor_offset) = self.virtual_cursor_offset {
|
||||
|
|
@ -2961,17 +2981,20 @@ impl Tab {
|
|||
if let Some(global_cursor_position) = self.global_cursor_position {
|
||||
new_offset.x = global_cursor_position.x - last_scroll_position.x;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
self.virtual_cursor_offset = Some(new_offset);
|
||||
self.last_scroll_offset = Some(new_offset);
|
||||
|
||||
commands.push(Command::Iced(
|
||||
scrollable::scroll_by(self.scrollable_id.clone(), AbsoluteOffset {
|
||||
x: 0.0,
|
||||
y: scroll_speed
|
||||
}).into(),
|
||||
scrollable::scroll_by(
|
||||
self.scrollable_id.clone(),
|
||||
AbsoluteOffset {
|
||||
x: 0.0,
|
||||
y: scroll_speed,
|
||||
},
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
Message::ScrollToFocus => {
|
||||
|
|
@ -4311,14 +4334,17 @@ impl Tab {
|
|||
y += 1;
|
||||
}
|
||||
|
||||
let military_time = self.config.military_time;
|
||||
let modified_text = match &item.metadata {
|
||||
ItemMetadata::Path { metadata, .. } => match metadata.modified() {
|
||||
Ok(time) => format_time(time).to_string(),
|
||||
Ok(time) => format_time(time, military_time).to_string(),
|
||||
Err(_) => String::new(),
|
||||
},
|
||||
ItemMetadata::Trash { entry, .. } => FormatTime::from_secs(entry.time_deleted)
|
||||
.map(|t| t.to_string())
|
||||
.unwrap_or_default(),
|
||||
ItemMetadata::Trash { entry, .. } => {
|
||||
FormatTime::from_secs(entry.time_deleted, military_time)
|
||||
.map(|t| t.to_string())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
_ => String::new(),
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue