@@ -864,7 +864,7 @@ impl PickerDelegate for BranchListDelegate {
) -> Option<Self::ListItem> {
let entry = &self.matches.get(ix)?;
- let (commit_time, author_name, subject) = entry
+ let (commit_time, absolute_time, author_name, subject) = entry
.as_branch()
.and_then(|branch| {
branch.most_recent_commit.as_ref().map(|commit| {
@@ -879,11 +879,22 @@ impl PickerDelegate for BranchListDelegate {
local_offset,
time_format::TimestampFormat::Relative,
);
+ let absolute_time = time_format::format_localized_timestamp(
+ commit_time,
+ OffsetDateTime::now_utc(),
+ local_offset,
+ time_format::TimestampFormat::EnhancedAbsolute,
+ );
let author = commit.author_name.clone();
- (Some(formatted_time), Some(author), Some(subject))
+ (
+ Some(formatted_time),
+ Some(absolute_time),
+ Some(author),
+ Some(subject),
+ )
})
})
- .unwrap_or_else(|| (None, None, None));
+ .unwrap_or_else(|| (None, None, None, None));
let is_head_branch = entry.as_branch().is_some_and(|branch| branch.is_head);
@@ -1076,19 +1087,31 @@ impl PickerDelegate for BranchListDelegate {
.when_some(
entry.as_branch().map(|b| b.name().to_string()),
|this, branch_name| {
- this.map(|this| {
- if is_head_branch {
- this.tooltip(move |_, cx| {
- Tooltip::with_meta(
- branch_name.clone(),
- None,
- "Current Branch",
- cx,
+ let absolute_time = absolute_time.clone();
+ this.tooltip({
+ let is_head = is_head_branch;
+ Tooltip::element(move |_, _| {
+ v_flex()
+ .child(Label::new(branch_name.clone()))
+ .when(is_head, |this| {
+ this.child(
+ Label::new("Current Branch")
+ .size(LabelSize::Small)
+ .color(Color::Muted),
+ )
+ })
+ .when_some(
+ absolute_time.clone(),
+ |this, time| {
+ this.child(
+ Label::new(time)
+ .size(LabelSize::Small)
+ .color(Color::Muted),
+ )
+ },
)
- })
- } else {
- this.tooltip(Tooltip::text(branch_name))
- }
+ .into_any_element()
+ })
})
},
),
@@ -223,6 +223,7 @@ struct StashEntryMatch {
entry: StashEntry,
positions: Vec<usize>,
formatted_timestamp: String,
+ formatted_absolute_timestamp: String,
}
pub struct StashListDelegate {
@@ -264,6 +265,17 @@ impl StashListDelegate {
}
fn format_timestamp(timestamp: i64, timezone: UtcOffset) -> String {
+ let timestamp =
+ OffsetDateTime::from_unix_timestamp(timestamp).unwrap_or(OffsetDateTime::now_utc());
+ time_format::format_localized_timestamp(
+ timestamp,
+ OffsetDateTime::now_utc(),
+ timezone,
+ time_format::TimestampFormat::Relative,
+ )
+ }
+
+ fn format_absolute_timestamp(timestamp: i64, timezone: UtcOffset) -> String {
let timestamp =
OffsetDateTime::from_unix_timestamp(timestamp).unwrap_or(OffsetDateTime::now_utc());
time_format::format_localized_timestamp(
@@ -388,11 +400,14 @@ impl PickerDelegate for StashListDelegate {
.into_iter()
.map(|entry| {
let formatted_timestamp = Self::format_timestamp(entry.timestamp, timezone);
+ let formatted_absolute_timestamp =
+ Self::format_absolute_timestamp(entry.timestamp, timezone);
StashEntryMatch {
entry,
positions: Vec::new(),
formatted_timestamp,
+ formatted_absolute_timestamp,
}
})
.collect()
@@ -421,11 +436,14 @@ impl PickerDelegate for StashListDelegate {
.map(|candidate| {
let entry = all_stash_entries[candidate.candidate_id].clone();
let formatted_timestamp = Self::format_timestamp(entry.timestamp, timezone);
+ let formatted_absolute_timestamp =
+ Self::format_absolute_timestamp(entry.timestamp, timezone);
StashEntryMatch {
entry,
positions: candidate.positions,
formatted_timestamp,
+ formatted_absolute_timestamp,
}
})
.collect()
@@ -544,6 +562,7 @@ impl PickerDelegate for StashListDelegate {
.toggle_state(selected)
.child(
h_flex()
+ .min_w_0()
.w_full()
.gap_2p5()
.child(
@@ -551,7 +570,33 @@ impl PickerDelegate for StashListDelegate {
.size(IconSize::Small)
.color(Color::Muted),
)
- .child(div().w_full().child(stash_label).child(branch_info)),
+ .child(
+ v_flex()
+ .id(format!("stash-tooltip-{ix}"))
+ .min_w_0()
+ .w_full()
+ .child(stash_label)
+ .child(branch_info)
+ .tooltip({
+ let stash_message = Self::format_message(
+ entry_match.entry.index,
+ &entry_match.entry.message,
+ );
+ let absolute_timestamp =
+ entry_match.formatted_absolute_timestamp.clone();
+
+ Tooltip::element(move |_, _| {
+ v_flex()
+ .child(Label::new(stash_message.clone()))
+ .child(
+ Label::new(absolute_timestamp.clone())
+ .size(LabelSize::Small)
+ .color(Color::Muted),
+ )
+ .into_any_element()
+ })
+ }),
+ ),
)
.end_slot(
h_flex()
@@ -889,7 +889,7 @@ impl PickerDelegate for WorktreeListDelegate {
})
.size(IconSize::Small),
)
- .child(v_flex().w_full().child(branch_name).map(|this| {
+ .child(v_flex().w_full().min_w_0().child(branch_name).map(|this| {
if entry.is_new {
this.child(
Label::new(sublabel)