diff --git a/crates/git_ui/src/file_history_view.rs b/crates/git_ui/src/file_history_view.rs index d2bac8cdeda4ce41c35906d25eec470e4de00bad..e34806aacae48122caf3a12246b04862898f2bed 100644 --- a/crates/git_ui/src/file_history_view.rs +++ b/crates/git_ui/src/file_history_view.rs @@ -4,8 +4,7 @@ use git::repository::{FileHistory, FileHistoryEntry, RepoPath}; use git::{GitHostingProviderRegistry, GitRemote, parse_git_remote_url}; use gpui::{ AnyElement, AnyEntity, App, Asset, Context, Entity, EventEmitter, FocusHandle, Focusable, - IntoElement, ListSizingBehavior, Render, Task, UniformListScrollHandle, WeakEntity, Window, - actions, rems, uniform_list, + IntoElement, Render, Task, UniformListScrollHandle, WeakEntity, Window, actions, uniform_list, }; use project::{ Project, ProjectPath, @@ -14,11 +13,8 @@ use project::{ use std::any::{Any, TypeId}; use time::OffsetDateTime; -use ui::{ - Avatar, Button, ButtonStyle, Color, Icon, IconName, IconSize, Label, LabelCommon as _, - LabelSize, SharedString, prelude::*, -}; -use util::{ResultExt, truncate_and_trailoff}; +use ui::{Avatar, Chip, Divider, ListItem, WithScrollbar, prelude::*}; +use util::ResultExt; use workspace::{ Item, Workspace, item::{ItemEvent, SaveOptions}, @@ -195,38 +191,24 @@ impl FileHistoryView { task.detach(); } - fn list_item_height(&self) -> Rems { - rems(2.0) - } - - fn fallback_commit_avatar() -> AnyElement { - Icon::new(IconName::Person) - .color(Color::Muted) - .size(IconSize::Small) - .into_element() - .into_any() - } - fn render_commit_avatar( &self, sha: &SharedString, window: &mut Window, cx: &mut App, - ) -> AnyElement { + ) -> impl IntoElement { let remote = self.remote.as_ref().filter(|r| r.host_supports_avatars()); + let size = rems_from_px(20.); if let Some(remote) = remote { let avatar_asset = CommitAvatarAsset::new(remote.clone(), sha.clone()); if let Some(Some(url)) = window.use_asset::(&avatar_asset, cx) { - Avatar::new(url.to_string()) - .size(rems(1.25)) - .into_element() - .into_any() + Avatar::new(url.to_string()).size(size) } else { - Self::fallback_commit_avatar() + Avatar::new("").size(size) } } else { - Self::fallback_commit_avatar() + Avatar::new("").size(size) } } @@ -263,34 +245,52 @@ impl FileHistoryView { time_format::TimestampFormat::Relative, ); - let selected = self.selected_entry == Some(ix); let sha = entry.sha.clone(); let repo = self.repository.clone(); let workspace = self.workspace.clone(); let file_path = self.history.path.clone(); - let base_bg = if selected { - cx.theme().status().info.alpha(0.1) - } else { - cx.theme().colors().editor_background - }; - - let hover_bg = if selected { - cx.theme().status().info.alpha(0.15) - } else { - cx.theme().colors().element_hover - }; - - h_flex() - .id(("commit", ix)) - .h(self.list_item_height()) - .w_full() - .items_center() - .px(rems(0.75)) - .gap_2() - .bg(base_bg) - .hover(|style| style.bg(hover_bg)) - .cursor_pointer() + ListItem::new(("commit", ix)) + .child( + h_flex() + .h_8() + .w_full() + .pl_0p5() + .pr_2p5() + .gap_2() + .child( + div() + .w(rems_from_px(52.)) + .flex_none() + .child(Chip::new(pr_number)), + ) + .child(self.render_commit_avatar(&entry.sha, window, cx)) + .child( + h_flex() + .w_full() + .justify_between() + .child( + h_flex() + .gap_1() + .child( + Label::new(entry.author_name.clone()) + .size(LabelSize::Small) + .color(Color::Default), + ) + .child( + Label::new(&entry.subject) + .size(LabelSize::Small) + .color(Color::Muted) + .truncate(), + ), + ) + .child( + Label::new(relative_timestamp) + .size(LabelSize::Small) + .color(Color::Muted), + ), + ), + ) .on_click(cx.listener(move |this, _, window, cx| { this.selected_entry = Some(ix); cx.notify(); @@ -308,56 +308,6 @@ impl FileHistoryView { ); } })) - .child( - div().flex_none().min_w(rems(4.0)).child( - div() - .px(rems(0.5)) - .py(rems(0.25)) - .rounded_md() - .bg(cx.theme().colors().element_background) - .border_1() - .border_color(cx.theme().colors().border) - .child( - Label::new(pr_number) - .size(LabelSize::Small) - .color(Color::Muted) - .single_line(), - ), - ), - ) - .child( - div() - .flex_none() - .w(rems(1.75)) - .child(self.render_commit_avatar(&entry.sha, window, cx)), - ) - .child( - div().flex_1().overflow_hidden().child( - h_flex() - .gap_3() - .items_center() - .child( - Label::new(entry.author_name.clone()) - .size(LabelSize::Small) - .color(Color::Default) - .single_line(), - ) - .child( - Label::new(truncate_and_trailoff(&entry.subject, 100)) - .size(LabelSize::Small) - .color(Color::Muted) - .single_line(), - ), - ), - ) - .child( - div().flex_none().child( - Label::new(relative_timestamp) - .size(LabelSize::Small) - .color(Color::Muted) - .single_line(), - ), - ) .into_any_element() } } @@ -419,31 +369,49 @@ impl Focusable for FileHistoryView { } impl Render for FileHistoryView { - fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { + fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { let _file_name = self.history.path.file_name().unwrap_or("File"); let entry_count = self.history.entries.len(); v_flex() .size_full() + .bg(cx.theme().colors().editor_background) .child( h_flex() - .px(rems(0.75)) - .py(rems(0.5)) - .border_b_1() - .border_color(cx.theme().colors().border) - .bg(cx.theme().colors().title_bar_background) - .items_center() + .h(rems_from_px(41.)) + .pl_3() + .pr_2() .justify_between() + .border_b_1() + .border_color(cx.theme().colors().border_variant) .child( - h_flex().gap_2().items_center().child( - Label::new(format!("History: {}", self.history.path.as_unix_str())) - .size(LabelSize::Default), - ), + Label::new(self.history.path.as_unix_str().to_string()) + .color(Color::Muted) + .buffer_font(cx), ) .child( - Label::new(format!("{} commits", entry_count)) - .size(LabelSize::Small) - .color(Color::Muted), + h_flex() + .gap_1p5() + .child( + Label::new(format!("{} commits", entry_count)) + .size(LabelSize::Small) + .color(Color::Muted) + .when(self.has_more, |this| this.mr_1()), + ) + .when(self.has_more, |this| { + this.child(Divider::vertical()).child( + Button::new("load-more", "Load More") + .disabled(self.loading_more) + .label_size(LabelSize::Small) + .icon(IconName::ArrowCircle) + .icon_size(IconSize::Small) + .icon_color(Color::Muted) + .icon_position(IconPosition::Start) + .on_click(cx.listener(|this, _, window, cx| { + this.load_more(window, cx); + })), + ) + }), ), ) .child( @@ -474,24 +442,9 @@ impl Render for FileHistoryView { ) .flex_1() .size_full() - .with_sizing_behavior(ListSizingBehavior::Auto) .track_scroll(&self.scroll_handle) }) - .when(self.has_more, |this| { - this.child( - div().p(rems(0.75)).flex().justify_start().child( - Button::new("load-more", "Load more") - .style(ButtonStyle::Subtle) - .disabled(self.loading_more) - .label_size(LabelSize::Small) - .icon(IconName::ArrowCircle) - .icon_position(IconPosition::Start) - .on_click(cx.listener(|this, _, window, cx| { - this.load_more(window, cx); - })), - ), - ) - }), + .vertical_scrollbar_for(&self.scroll_handle, window, cx), ) } } @@ -518,7 +471,7 @@ impl Item for FileHistoryView { } fn tab_icon(&self, _window: &Window, _cx: &App) -> Option { - Some(Icon::new(IconName::FileGit)) + Some(Icon::new(IconName::GitBranch)) } fn telemetry_event_text(&self) -> Option<&'static str> { diff --git a/crates/ui/src/components/avatar.rs b/crates/ui/src/components/avatar.rs index 551ab4e3edff90f3b987ddd5ef19cfdeae1fa214..7b2ba8ce5cbfee2589695c1a9d0dcd61a266b093 100644 --- a/crates/ui/src/components/avatar.rs +++ b/crates/ui/src/components/avatar.rs @@ -91,10 +91,16 @@ impl RenderOnce for Avatar { self.image .size(image_size) .rounded_full() - .bg(cx.theme().colors().ghost_element_background) + .bg(cx.theme().colors().element_disabled) .with_fallback(|| { - Icon::new(IconName::Person) - .color(Color::Muted) + h_flex() + .size_full() + .justify_center() + .child( + Icon::new(IconName::Person) + .color(Color::Muted) + .size(IconSize::Small), + ) .into_any_element() }), )