update
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
use gpui::prelude::*;
|
use gpui::prelude::*;
|
||||||
use gpui::{AnyElement, Context, Entity, SharedString, WeakEntity, Window, div, px};
|
use gpui::{AnyElement, Context, Entity, SharedString, WeakEntity, Window, div, px};
|
||||||
use gpui_component::button::{Button, ButtonVariants};
|
use gpui_component::button::{Button, ButtonVariants};
|
||||||
use gpui_component::input::{Editor, EditorState};
|
use gpui_component::input::{Editor, EditorState, TabSize};
|
||||||
use gpui_component::list::ListItem;
|
use gpui_component::list::ListItem;
|
||||||
use gpui_component::spinner::Spinner;
|
use gpui_component::spinner::Spinner;
|
||||||
use gpui_component::text::{TextView, TextViewState};
|
use gpui_component::text::{TextView, TextViewState};
|
||||||
@@ -280,7 +280,16 @@ impl RepoDetailView {
|
|||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
let language = code_language(path.as_ref()).unwrap_or("text");
|
let language = code_language(path.as_ref()).unwrap_or("text");
|
||||||
let state = cx.new(|cx| EditorState::new(language, window, cx).default_value(text));
|
let state = cx.new(|cx| {
|
||||||
|
EditorState::new(language, window, cx)
|
||||||
|
.default_value(text)
|
||||||
|
.tab_size(TabSize {
|
||||||
|
tab_size: 4,
|
||||||
|
hard_tabs: false,
|
||||||
|
})
|
||||||
|
.line_number(true)
|
||||||
|
.folding(true)
|
||||||
|
});
|
||||||
self.code = Some(CodeView { path, state });
|
self.code = Some(CodeView { path, state });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,14 +303,12 @@ impl RepoDetailView {
|
|||||||
return preview_spinner();
|
return preview_spinner();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disabled: the preview is read-only. Selection, copy and the
|
|
||||||
// built-in search (Cmd/Ctrl+F) still work; editing is blocked by the
|
|
||||||
// component's disabled state.
|
|
||||||
Editor::new(&code.state)
|
Editor::new(&code.state)
|
||||||
.readonly(true)
|
.readonly(true)
|
||||||
.bordered(false)
|
.bordered(false)
|
||||||
.rounded_none()
|
.rounded_none()
|
||||||
.h_full()
|
.h_full()
|
||||||
|
.text_sm()
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use gpui::{
|
|||||||
AnyElement, App, ClipboardItem, Context, Entity, EventEmitter, FocusHandle, Focusable, Pixels,
|
AnyElement, App, ClipboardItem, Context, Entity, EventEmitter, FocusHandle, Focusable, Pixels,
|
||||||
Render, SharedString, Size, Subscription, Task, WeakEntity, Window, div, px, size,
|
Render, SharedString, Size, Subscription, Task, WeakEntity, Window, div, px, size,
|
||||||
};
|
};
|
||||||
|
use gpui_component::avatar::{Avatar, AvatarGroup};
|
||||||
use gpui_component::button::{Button, ButtonVariants, DropdownButton};
|
use gpui_component::button::{Button, ButtonVariants, DropdownButton};
|
||||||
use gpui_component::combobox::{
|
use gpui_component::combobox::{
|
||||||
Caret, Combobox, ComboboxEvent, ComboboxState, ComboboxTriggerContext,
|
Caret, Combobox, ComboboxEvent, ComboboxState, ComboboxTriggerContext,
|
||||||
@@ -26,7 +27,7 @@ use gpui_component::{
|
|||||||
};
|
};
|
||||||
use signed_core::Announcement;
|
use signed_core::Announcement;
|
||||||
use signed_git::{CommitList, FileCommit};
|
use signed_git::{CommitList, FileCommit};
|
||||||
use signed_state::{GitStore, RepoStore};
|
use signed_state::{GitStore, ProfileStore, RepoStore};
|
||||||
|
|
||||||
mod browser;
|
mod browser;
|
||||||
mod commits;
|
mod commits;
|
||||||
@@ -941,6 +942,54 @@ impl RepoDetailView {
|
|||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_else(|| SharedString::from(announcement.id.clone()))
|
.unwrap_or_else(|| SharedString::from(announcement.id.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Horizontal list of everyone who maintains the repository: the owner
|
||||||
|
/// shown in full, and any additional maintainers as a compact overlapping avatar group.
|
||||||
|
fn render_maintainers(&self, cx: &mut Context<Self>) -> AnyElement {
|
||||||
|
let announcement = self.announcement();
|
||||||
|
let profile_store = ProfileStore::global(cx);
|
||||||
|
|
||||||
|
let mut seen = HashSet::new();
|
||||||
|
let rest: Vec<_> = announcement
|
||||||
|
.maintainers
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.filter(|key| *key != announcement.owner && seen.insert(*key))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let owner = profile_store.read(cx).get(&announcement.owner);
|
||||||
|
let owner_name = owner.name();
|
||||||
|
let owner_picture = owner.picture();
|
||||||
|
|
||||||
|
h_flex()
|
||||||
|
.w_full()
|
||||||
|
.gap_3()
|
||||||
|
.items_center()
|
||||||
|
.flex_wrap()
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.gap_1()
|
||||||
|
.items_center()
|
||||||
|
.child(
|
||||||
|
Avatar::new()
|
||||||
|
.name(owner_name.clone())
|
||||||
|
.when_some(owner_picture, |this, url| this.src(url))
|
||||||
|
.small(),
|
||||||
|
)
|
||||||
|
.child(div().text_xs().whitespace_nowrap().child(owner_name)),
|
||||||
|
)
|
||||||
|
.when(!rest.is_empty(), |this| {
|
||||||
|
this.child(AvatarGroup::new().small().limit(5).ellipsis().children(
|
||||||
|
rest.into_iter().map(|key| {
|
||||||
|
let profile = profile_store.read(cx).get(&key);
|
||||||
|
Avatar::new()
|
||||||
|
.name(profile.name())
|
||||||
|
.when_some(profile.picture(), |this, url| this.src(url))
|
||||||
|
}),
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.into_any_element()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Panel for RepoDetailView {
|
impl Panel for RepoDetailView {
|
||||||
@@ -1064,11 +1113,25 @@ impl RepoDetailView {
|
|||||||
.child(div().font_semibold().child(name))
|
.child(div().font_semibold().child(name))
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
|
.min_w_0()
|
||||||
.text_xs()
|
.text_xs()
|
||||||
.text_color(cx.theme().muted_foreground)
|
.text_color(cx.theme().muted_foreground)
|
||||||
.line_clamp(3)
|
.line_clamp(2)
|
||||||
.text_ellipsis()
|
.text_ellipsis()
|
||||||
.child(description),
|
.child(description),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.mt_2()
|
||||||
|
.gap_2()
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.text_xs()
|
||||||
|
.text_color(cx.theme().muted_foreground)
|
||||||
|
.font_semibold()
|
||||||
|
.child("Maintainers:"),
|
||||||
|
)
|
||||||
|
.child(self.render_maintainers(cx)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
@@ -1081,6 +1144,7 @@ impl RepoDetailView {
|
|||||||
.button(
|
.button(
|
||||||
Button::new("relay-trigger")
|
Button::new("relay-trigger")
|
||||||
.label(format!("{} relays", relays.len()))
|
.label(format!("{} relays", relays.len()))
|
||||||
|
.small()
|
||||||
.ghost(),
|
.ghost(),
|
||||||
)
|
)
|
||||||
.dropdown_menu(move |menu, _window, _cx| {
|
.dropdown_menu(move |menu, _window, _cx| {
|
||||||
@@ -1107,7 +1171,12 @@ impl RepoDetailView {
|
|||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
DropdownButton::new("web")
|
DropdownButton::new("web")
|
||||||
.button(Button::new("web-trigger").label("Websites").ghost())
|
.button(
|
||||||
|
Button::new("web-trigger")
|
||||||
|
.label("Websites")
|
||||||
|
.small()
|
||||||
|
.ghost(),
|
||||||
|
)
|
||||||
.dropdown_menu(move |menu, _window, _cx| {
|
.dropdown_menu(move |menu, _window, _cx| {
|
||||||
let mut menu = menu;
|
let mut menu = menu;
|
||||||
if web.is_empty() {
|
if web.is_empty() {
|
||||||
@@ -1167,41 +1236,9 @@ impl RepoDetailView {
|
|||||||
.flex_1()
|
.flex_1()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.justify_end()
|
.justify_end()
|
||||||
.child(
|
|
||||||
div().w(px(120.)).child(
|
|
||||||
Combobox::new(&self.branch_select)
|
|
||||||
.placeholder("Branch")
|
|
||||||
.appearance(false)
|
|
||||||
.menu_width(px(200.))
|
|
||||||
.disabled(worktree_empty)
|
|
||||||
.bg(cx.theme().muted)
|
|
||||||
.rounded(cx.theme().radius)
|
|
||||||
.render_trigger(|ctx, _window, cx| {
|
|
||||||
Self::render_ref_trigger(
|
|
||||||
ctx,
|
|
||||||
CustomIconName::GitBranch,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.child(
|
|
||||||
div().w(px(120.)).child(
|
|
||||||
Combobox::new(&self.tag_select)
|
|
||||||
.placeholder("Tag")
|
|
||||||
.appearance(false)
|
|
||||||
.menu_width(px(200.))
|
|
||||||
.disabled(worktree_empty)
|
|
||||||
.bg(cx.theme().muted)
|
|
||||||
.rounded(cx.theme().radius)
|
|
||||||
.render_trigger(|ctx, _window, cx| {
|
|
||||||
Self::render_ref_trigger(ctx, CustomIconName::Tag, cx)
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.child(
|
.child(
|
||||||
Button::new("enc")
|
Button::new("enc")
|
||||||
.secondary()
|
.ghost()
|
||||||
.when_some(self.head_commit.as_ref(), |this, commit| {
|
.when_some(self.head_commit.as_ref(), |this, commit| {
|
||||||
this.child(
|
this.child(
|
||||||
div()
|
div()
|
||||||
@@ -1232,6 +1269,38 @@ impl RepoDetailView {
|
|||||||
this.open_commit_diff(&id, window, cx);
|
this.open_commit_diff(&id, window, cx);
|
||||||
}
|
}
|
||||||
})),
|
})),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
div().w(px(120.)).child(
|
||||||
|
Combobox::new(&self.branch_select)
|
||||||
|
.placeholder("Branch")
|
||||||
|
.appearance(false)
|
||||||
|
.menu_width(px(200.))
|
||||||
|
.disabled(worktree_empty)
|
||||||
|
.bg(cx.theme().muted)
|
||||||
|
.rounded(cx.theme().radius)
|
||||||
|
.render_trigger(|ctx, _window, cx| {
|
||||||
|
Self::render_ref_trigger(
|
||||||
|
ctx,
|
||||||
|
CustomIconName::GitBranch,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
div().w(px(120.)).child(
|
||||||
|
Combobox::new(&self.tag_select)
|
||||||
|
.placeholder("Tag")
|
||||||
|
.appearance(false)
|
||||||
|
.menu_width(px(200.))
|
||||||
|
.disabled(worktree_empty)
|
||||||
|
.bg(cx.theme().muted)
|
||||||
|
.rounded(cx.theme().radius)
|
||||||
|
.render_trigger(|ctx, _window, cx| {
|
||||||
|
Self::render_ref_trigger(ctx, CustomIconName::Tag, cx)
|
||||||
|
}),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ impl Render for SidebarPanel {
|
|||||||
.child(NavItem::new("explore", "Browse", IconName::Globe).on_click(
|
.child(NavItem::new("explore", "Browse", IconName::Globe).on_click(
|
||||||
cx.listener(|this, _ev, window, cx| this.open_explore(window, cx)),
|
cx.listener(|this, _ev, window, cx| this.open_explore(window, cx)),
|
||||||
))
|
))
|
||||||
.child(NavItem::new("search", "Saerch", IconName::Search).on_click(
|
.child(NavItem::new("search", "Search", IconName::Search).on_click(
|
||||||
cx.listener(|this, _ev, window, cx| this.open_explore(window, cx)),
|
cx.listener(|this, _ev, window, cx| this.open_explore(window, cx)),
|
||||||
))
|
))
|
||||||
.child(
|
.child(
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ fn main() {
|
|||||||
kind: WindowKind::Normal,
|
kind: WindowKind::Normal,
|
||||||
app_id: Some("Signed".to_owned()),
|
app_id: Some("Signed".to_owned()),
|
||||||
titlebar: Some(TitlebarOptions {
|
titlebar: Some(TitlebarOptions {
|
||||||
title: Some(SharedString::new_static("Signed Platform")),
|
title: Some(SharedString::new_static("Signed")),
|
||||||
traffic_light_position: Some(point(px(9.0), px(9.0))),
|
traffic_light_position: Some(point(px(9.0), px(9.0))),
|
||||||
appears_transparent: true,
|
appears_transparent: true,
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user