diff --git a/crates/assets/assets/icons/markdown.svg b/crates/assets/assets/icons/markdown.svg new file mode 100644 index 0000000..f11c48f --- /dev/null +++ b/crates/assets/assets/icons/markdown.svg @@ -0,0 +1,3 @@ + + + diff --git a/crates/assets/src/lib.rs b/crates/assets/src/lib.rs index 33c97db..3a16192 100644 --- a/crates/assets/src/lib.rs +++ b/crates/assets/src/lib.rs @@ -87,6 +87,7 @@ pub enum CustomIconName { GitClone, GitBranch, Tag, + Markdown, } impl IconNamed for CustomIconName { @@ -108,6 +109,7 @@ impl IconNamed for CustomIconName { CustomIconName::GitClone => "icons/git-clone.svg", CustomIconName::GitBranch => "icons/git-branch.svg", CustomIconName::Tag => "icons/tag.svg", + CustomIconName::Markdown => "icons/markdown.svg", } .into() } diff --git a/crates/workspace/src/views/repo_detail/issue_detail.rs b/crates/workspace/src/views/repo_detail/issue_detail.rs index 91f4505..ecd9213 100644 --- a/crates/workspace/src/views/repo_detail/issue_detail.rs +++ b/crates/workspace/src/views/repo_detail/issue_detail.rs @@ -1,3 +1,4 @@ +use assets::CustomIconName; use dock::{BasePanel, Panel, PanelEvent}; use gpui::prelude::*; use gpui::{ @@ -9,7 +10,7 @@ use gpui_component::button::{Button, ButtonVariants}; use gpui_component::input::{Textarea, TextareaState}; use gpui_component::scroll::ScrollableElement; use gpui_component::tag::Tag; -use gpui_component::{ActiveTheme, Sizable, StyledExt, h_flex, v_flex}; +use gpui_component::{ActiveTheme, Icon, Sizable, StyledExt, h_flex, v_flex}; use nostr::prelude::{Event, EventId, PublicKey}; use signed_core::activity_subject; use signed_state::{ProfileStore, RepoStore}; @@ -84,7 +85,7 @@ impl IssueDetailView { let picture = profile.picture(); h_flex() - .gap_2() + .gap_1() .items_center() .child( Avatar::new() @@ -107,7 +108,7 @@ impl IssueDetailView { div() .text_sm() .text_color(cx.theme().muted_foreground) - .child("No labels"), + .child("None yet."), ) } else { this.child(h_flex().gap_1().children({ @@ -133,9 +134,11 @@ impl IssueDetailView { fn render_comments(&mut self, id: &EventId, cx: &mut Context) -> impl IntoElement { let store = self.store.read(cx); let comments: Vec<&Event> = store.comments_of(id).collect(); + let title = SharedString::from(format!("Discussions {}", comments.len())); v_flex() - .gap_3() + .gap_4() + .child(div().text_xs().font_semibold().child(title)) .children(comments.iter().map(|comment| { let profile = ProfileStore::global(cx).read(cx).get(&comment.pubkey); let author = profile.name(); @@ -144,6 +147,10 @@ impl IssueDetailView { v_flex() .gap_1() + .p_3() + .border_1() + .border_color(cx.theme().border) + .rounded(cx.theme().radius) .child( h_flex() .gap_2() @@ -156,10 +163,15 @@ impl IssueDetailView { .name(author.clone()) .when_some(picture, |this, url| this.src(url)) .rounded(cx.theme().radius) - .xsmall(), + .small(), ) .child(author), ) + .child( + div() + .text_color(cx.theme().muted_foreground) + .child("commented"), + ) .child( div() .text_color(cx.theme().muted_foreground) @@ -175,42 +187,57 @@ impl IssueDetailView { .into_any_element() } - fn render_form(&mut self, id: &EventId, _cx: &mut Context) -> impl IntoElement { + fn render_form(&mut self, id: &EventId, cx: &mut Context) -> impl IntoElement { let comment_input = self.comment_input.clone(); let store = self.store.clone(); let id = id.to_owned(); v_flex() .gap_2() - .child(Textarea::new(&self.comment_input).h(px(96.))) .child( - h_flex().justify_end().child( - Button::new("comment") - .primary() - .label("Comment") - .tooltip("Post comment") - .on_click(move |_event, window, cx| { - let content = comment_input.read(cx).value().trim().to_string(); - if content.is_empty() { - return; - } - let Some(root) = store - .read(cx) - .issues - .iter() - .find(|issue| issue.id == id) - .cloned() - else { - return; - }; - store.update(cx, |store, cx| { - store.comment(&root, content, cx); - }); - comment_input.update(cx, |input, cx| { - input.set_value("", window, cx); - }); - }), - ), + Textarea::new(&self.comment_input) + .h_24() + .text_color(cx.theme().muted_foreground) + .bg(cx.theme().muted), + ) + .child( + h_flex() + .justify_between() + .child( + h_flex() + .gap_1() + .text_xs() + .text_color(cx.theme().muted_foreground) + .child(Icon::new(CustomIconName::Markdown).small()) + .child("Markdown is supported"), + ) + .child( + Button::new("comment") + .primary() + .label("Comment") + .tooltip("Post comment") + .on_click(move |_event, window, cx| { + let content = comment_input.read(cx).value().trim().to_string(); + if content.is_empty() { + return; + } + let Some(root) = store + .read(cx) + .issues + .iter() + .find(|issue| issue.id == id) + .cloned() + else { + return; + }; + store.update(cx, |store, cx| { + store.comment(&root, content, cx); + }); + comment_input.update(cx, |input, cx| { + input.set_value("", window, cx); + }); + }), + ), ) .into_any_element() }