.
This commit is contained in:
3
assets/icons/circle-check.svg
Normal file
3
assets/icons/circle-check.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
||||||
|
<circle cx="12" cy="12" r="9.25" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M7.75 12.9231L10.5625 15.75L15.25 8.75" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 341 B |
@@ -869,6 +869,7 @@ impl ChatPanel {
|
|||||||
Avatar::new()
|
Avatar::new()
|
||||||
.src(author.avatar())
|
.src(author.avatar())
|
||||||
.name(author.name())
|
.name(author.name())
|
||||||
|
.size(px(32.))
|
||||||
.flex_shrink_0()
|
.flex_shrink_0()
|
||||||
.relative(),
|
.relative(),
|
||||||
)
|
)
|
||||||
@@ -1380,7 +1381,6 @@ impl ChatPanel {
|
|||||||
.icon(CoopIcon::Settings2)
|
.icon(CoopIcon::Settings2)
|
||||||
.tooltip("Configuration")
|
.tooltip("Configuration")
|
||||||
.ghost()
|
.ghost()
|
||||||
.large()
|
|
||||||
.dropdown_menu(move |this, _window, _cx| {
|
.dropdown_menu(move |this, _window, _cx| {
|
||||||
let auto = matches!(signer_kind, SignerKind::Auto);
|
let auto = matches!(signer_kind, SignerKind::Auto);
|
||||||
let encryption = matches!(signer_kind, SignerKind::Encryption);
|
let encryption = matches!(signer_kind, SignerKind::Encryption);
|
||||||
@@ -1415,7 +1415,6 @@ impl ChatPanel {
|
|||||||
Button::new("emoji")
|
Button::new("emoji")
|
||||||
.icon(CoopIcon::Emoji)
|
.icon(CoopIcon::Emoji)
|
||||||
.ghost()
|
.ghost()
|
||||||
.large()
|
|
||||||
.dropdown_menu_with_anchor(gpui::Anchor::BottomLeft, move |this, _window, _cx| {
|
.dropdown_menu_with_anchor(gpui::Anchor::BottomLeft, move |this, _window, _cx| {
|
||||||
this.separator()
|
this.separator()
|
||||||
.menu("👍", Box::new(Command::Insert("👍")))
|
.menu("👍", Box::new(Command::Insert("👍")))
|
||||||
@@ -1543,7 +1542,6 @@ impl Render for ChatPanel {
|
|||||||
.loading(self.uploading)
|
.loading(self.uploading)
|
||||||
.disabled(self.uploading)
|
.disabled(self.uploading)
|
||||||
.ghost()
|
.ghost()
|
||||||
.large()
|
|
||||||
.on_click(cx.listener(move |this, _ev, window, cx| {
|
.on_click(cx.listener(move |this, _ev, window, cx| {
|
||||||
this.upload(window, cx);
|
this.upload(window, cx);
|
||||||
})),
|
})),
|
||||||
@@ -1560,7 +1558,6 @@ impl Render for ChatPanel {
|
|||||||
.icon(CoopIcon::PaperPlaneFill)
|
.icon(CoopIcon::PaperPlaneFill)
|
||||||
.disabled(self.uploading)
|
.disabled(self.uploading)
|
||||||
.ghost()
|
.ghost()
|
||||||
.large()
|
|
||||||
.on_click(cx.listener(move |this, _ev, window, cx| {
|
.on_click(cx.listener(move |this, _ev, window, cx| {
|
||||||
this.send_text_message(window, cx);
|
this.send_text_message(window, cx);
|
||||||
})),
|
})),
|
||||||
|
|||||||
@@ -4,13 +4,17 @@ use gpui::prelude::FluentBuilder;
|
|||||||
use gpui::{
|
use gpui::{
|
||||||
App, AppContext, Context, Entity, InteractiveElement, IntoElement, ParentElement, Render,
|
App, AppContext, Context, Entity, InteractiveElement, IntoElement, ParentElement, Render,
|
||||||
SharedString, StatefulInteractiveElement, Styled, Subscription, Task, Window, div, px,
|
SharedString, StatefulInteractiveElement, Styled, Subscription, Task, Window, div, px,
|
||||||
|
relative,
|
||||||
};
|
};
|
||||||
use gpui_component::avatar::Avatar;
|
use gpui_component::avatar::Avatar;
|
||||||
use gpui_component::button::{Button, ButtonVariants};
|
use gpui_component::button::{Button, ButtonVariants};
|
||||||
|
use gpui_component::separator::Separator;
|
||||||
use gpui_component::spinner::Spinner;
|
use gpui_component::spinner::Spinner;
|
||||||
use gpui_component::{ActiveTheme, Disableable, Icon, Sizable, WindowExt, h_flex, v_flex};
|
use gpui_component::{
|
||||||
|
ActiveTheme, Disableable, Icon, Sizable, StyledExt, WindowExt, h_flex, v_flex,
|
||||||
|
};
|
||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
use person::PersonRegistry;
|
use person::{PersonRegistry, shorten_pubkey};
|
||||||
use state::{NostrRegistry, StateEvent};
|
use state::{NostrRegistry, StateEvent};
|
||||||
|
|
||||||
use crate::dialogs::connect::ConnectSigner;
|
use crate::dialogs::connect::ConnectSigner;
|
||||||
@@ -178,17 +182,37 @@ impl Render for AccountSelector {
|
|||||||
.id(ix)
|
.id(ix)
|
||||||
.group("")
|
.group("")
|
||||||
.px_2()
|
.px_2()
|
||||||
.h_10()
|
.h_11()
|
||||||
.justify_between()
|
.justify_between()
|
||||||
.w_full()
|
.w_full()
|
||||||
.rounded(cx.theme().radius)
|
.rounded(cx.theme().radius)
|
||||||
.bg(cx.theme().secondary)
|
.bg(cx.theme().transparent)
|
||||||
.hover(|this| this.bg(cx.theme().secondary_hover))
|
.hover(|this| this.bg(cx.theme().secondary_hover))
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.child(Avatar::new().src(profile.avatar()).small())
|
.child(
|
||||||
.child(div().text_sm().child(profile.name())),
|
Avatar::new()
|
||||||
|
.src(profile.avatar())
|
||||||
|
.name(profile.name())
|
||||||
|
.size(px(32.)),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
v_flex()
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.text_sm()
|
||||||
|
.font_medium()
|
||||||
|
.line_height(relative(1.2))
|
||||||
|
.child(profile.name()),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.text_color(cx.theme().muted_foreground)
|
||||||
|
.text_xs()
|
||||||
|
.child(shorten_pubkey(profile.public_key(), 4)),
|
||||||
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.when(logging_in, |this| this.child(Spinner::new().small()))
|
.when(logging_in, |this| this.child(Spinner::new().small()))
|
||||||
.when(!logging_in, |this| {
|
.when(!logging_in, |this| {
|
||||||
@@ -224,7 +248,7 @@ impl Render for AccountSelector {
|
|||||||
|
|
||||||
items
|
items
|
||||||
})
|
})
|
||||||
.child(div().w_full().h_px().bg(cx.theme().border))
|
.child(Separator::horizontal())
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use gpui::{
|
|||||||
};
|
};
|
||||||
use gpui_component::button::{Button, ButtonVariants};
|
use gpui_component::button::{Button, ButtonVariants};
|
||||||
use gpui_component::dock::{DockPlacement, Panel, PanelEvent};
|
use gpui_component::dock::{DockPlacement, Panel, PanelEvent};
|
||||||
|
use gpui_component::separator::Separator;
|
||||||
use gpui_component::{ActiveTheme, Icon, Sizable, StyledExt, h_flex, v_flex};
|
use gpui_component::{ActiveTheme, Icon, Sizable, StyledExt, h_flex, v_flex};
|
||||||
use state::NostrRegistry;
|
use state::NostrRegistry;
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ impl Panel for GreeterPanel {
|
|||||||
"Greeter"
|
"Greeter"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn title(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn title(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
div().child(
|
div().child(
|
||||||
svg()
|
svg()
|
||||||
.path("brand/coop.svg")
|
.path("brand/coop.svg")
|
||||||
@@ -96,7 +97,7 @@ impl Render for GreeterPanel {
|
|||||||
svg()
|
svg()
|
||||||
.path("brand/coop.svg")
|
.path("brand/coop.svg")
|
||||||
.size_12()
|
.size_12()
|
||||||
.text_color(cx.theme().muted),
|
.text_color(cx.theme().secondary),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
@@ -111,41 +112,32 @@ impl Render for GreeterPanel {
|
|||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
.gap_2()
|
|
||||||
.w_full()
|
.w_full()
|
||||||
|
.gap_2()
|
||||||
|
.justify_start()
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
Separator::horizontal()
|
||||||
.gap_2()
|
.label("Get Started")
|
||||||
.w_full()
|
.flex_row_reverse(),
|
||||||
.text_xs()
|
|
||||||
.font_semibold()
|
|
||||||
.text_color(cx.theme().muted_foreground)
|
|
||||||
.child(SharedString::from("Get Started"))
|
|
||||||
.child(div().flex_1().h_px().bg(cx.theme().border)),
|
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
v_flex()
|
Button::new("profile")
|
||||||
.gap_2()
|
.icon(Icon::new(CoopIcon::Profile))
|
||||||
.w_full()
|
.label("Update profile")
|
||||||
.child(
|
.ghost()
|
||||||
Button::new("profile")
|
.small()
|
||||||
.icon(Icon::new(CoopIcon::Profile))
|
.justify_start()
|
||||||
.label("Update profile")
|
.on_click(cx.listener(move |this, _ev, window, cx| {
|
||||||
.ghost()
|
this.add_profile_panel(window, cx)
|
||||||
.small()
|
})),
|
||||||
.justify_start()
|
)
|
||||||
.on_click(cx.listener(move |this, _ev, window, cx| {
|
.child(
|
||||||
this.add_profile_panel(window, cx)
|
Button::new("invite")
|
||||||
})),
|
.icon(Icon::new(CoopIcon::Invite))
|
||||||
)
|
.label("Invite friends")
|
||||||
.child(
|
.ghost()
|
||||||
Button::new("invite")
|
.small()
|
||||||
.icon(Icon::new(CoopIcon::Invite))
|
.justify_start(),
|
||||||
.label("Invite friends")
|
|
||||||
.ghost()
|
|
||||||
.small()
|
|
||||||
.justify_start(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ enum SetMetadata {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct RelayListPanel {
|
pub struct RelayListPanel {
|
||||||
name: SharedString,
|
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
|
|
||||||
/// Relay URL input
|
/// Relay URL input
|
||||||
@@ -83,7 +82,6 @@ impl RelayListPanel {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
name: "Update Relay List".into(),
|
|
||||||
focus_handle: cx.focus_handle(),
|
focus_handle: cx.focus_handle(),
|
||||||
input,
|
input,
|
||||||
updating: false,
|
updating: false,
|
||||||
@@ -318,11 +316,7 @@ impl RelayListPanel {
|
|||||||
|
|
||||||
impl Panel for RelayListPanel {
|
impl Panel for RelayListPanel {
|
||||||
fn panel_name(&self) -> &'static str {
|
fn panel_name(&self) -> &'static str {
|
||||||
"Relay List"
|
"Update Relay List"
|
||||||
}
|
|
||||||
|
|
||||||
fn title(&mut self, window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
|
||||||
self.name.clone()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ impl Panel for TrashPanel {
|
|||||||
"Trash"
|
"Trash"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn title(&mut self, window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
fn title(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.text_sm()
|
.text_sm()
|
||||||
|
|||||||
@@ -124,12 +124,13 @@ impl RenderOnce for RoomEntry {
|
|||||||
.text_ellipsis()
|
.text_ellipsis()
|
||||||
.truncate()
|
.truncate()
|
||||||
.font_medium()
|
.font_medium()
|
||||||
|
.text_color(cx.theme().sidebar_foreground)
|
||||||
.child(name)
|
.child(name)
|
||||||
.when(is_selected, |this| {
|
.when(is_selected, |this| {
|
||||||
this.child(
|
this.child(
|
||||||
Icon::new(CoopIcon::CheckCircle)
|
Icon::new(CoopIcon::CheckCircle)
|
||||||
.small()
|
.small()
|
||||||
.text_color(cx.theme().primary_active),
|
.text_color(cx.theme().sidebar_accent_foreground),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use gpui::prelude::FluentBuilder;
|
|||||||
use gpui::{
|
use gpui::{
|
||||||
App, AppContext, Context, Entity, EventEmitter, FocusHandle, Focusable, IntoElement,
|
App, AppContext, Context, Entity, EventEmitter, FocusHandle, Focusable, IntoElement,
|
||||||
ParentElement, Render, SharedString, Styled, Subscription, Task, UniformListScrollHandle,
|
ParentElement, Render, SharedString, Styled, Subscription, Task, UniformListScrollHandle,
|
||||||
Window, div, px, uniform_list,
|
Window, div, px, relative, uniform_list,
|
||||||
};
|
};
|
||||||
use gpui_component::button::{Button, ButtonVariants};
|
use gpui_component::button::{Button, ButtonVariants};
|
||||||
use gpui_component::dock::{Panel, PanelEvent};
|
use gpui_component::dock::{Panel, PanelEvent};
|
||||||
@@ -492,6 +492,7 @@ impl Render for Sidebar {
|
|||||||
|
|
||||||
// Whether the find panel should be shown
|
// Whether the find panel should be shown
|
||||||
let show_find_panel = self.has_search || self.find_focused;
|
let show_find_panel = self.has_search || self.find_focused;
|
||||||
|
let show_create_button = !self.selected_pkeys.read(cx).is_empty() && show_find_panel;
|
||||||
|
|
||||||
// Set button label based on total selected users
|
// Set button label based on total selected users
|
||||||
let button_label = if self.selected_pkeys.read(cx).len() > 1 {
|
let button_label = if self.selected_pkeys.read(cx).len() > 1 {
|
||||||
@@ -504,9 +505,10 @@ impl Render for Sidebar {
|
|||||||
.image_cache(coop_cache("sidebar", IMAGE_CACHE_SIZE))
|
.image_cache(coop_cache("sidebar", IMAGE_CACHE_SIZE))
|
||||||
.size_full()
|
.size_full()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
|
.bg(cx.theme().sidebar)
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.h(px(28.0))
|
.h(px(32.0))
|
||||||
.border_b_1()
|
.border_b_1()
|
||||||
.border_color(cx.theme().border)
|
.border_color(cx.theme().border)
|
||||||
.bg(cx.theme().tab_bar)
|
.bg(cx.theme().tab_bar)
|
||||||
@@ -557,7 +559,7 @@ impl Render for Sidebar {
|
|||||||
.when(!show_find_panel, |this| this.label("Inbox"))
|
.when(!show_find_panel, |this| this.label("Inbox"))
|
||||||
.tooltip("All ongoing conversations")
|
.tooltip("All ongoing conversations")
|
||||||
.small()
|
.small()
|
||||||
.ghost()
|
.secondary()
|
||||||
.flex_1()
|
.flex_1()
|
||||||
.selected(
|
.selected(
|
||||||
!show_find_panel && self.current_filter(&RoomKind::Ongoing, cx),
|
!show_find_panel && self.current_filter(&RoomKind::Ongoing, cx),
|
||||||
@@ -605,19 +607,13 @@ impl Render for Sidebar {
|
|||||||
.items_center()
|
.items_center()
|
||||||
.justify_center()
|
.justify_center()
|
||||||
.text_center()
|
.text_center()
|
||||||
.child(
|
.child(div().text_sm().font_semibold().child("No conversations"))
|
||||||
div()
|
|
||||||
.text_sm()
|
|
||||||
.font_semibold()
|
|
||||||
.child(SharedString::from("No conversations")),
|
|
||||||
)
|
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.text_xs()
|
.text_xs()
|
||||||
.text_color(cx.theme().muted_foreground)
|
.text_color(cx.theme().muted_foreground)
|
||||||
.child(SharedString::from(
|
.line_height(relative(1.2))
|
||||||
"Start a conversation with someone to get started.",
|
.child("Start a conversation with someone to get started."),
|
||||||
)),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -665,12 +661,13 @@ impl Render for Sidebar {
|
|||||||
.flex_1()
|
.flex_1()
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
|
.px_1()
|
||||||
.gap_0p5()
|
.gap_0p5()
|
||||||
.text_xs()
|
.text_xs()
|
||||||
.font_semibold()
|
.font_semibold()
|
||||||
.text_color(cx.theme().muted_foreground)
|
.text_color(cx.theme().muted_foreground)
|
||||||
.child(Icon::new(CoopIcon::ChevronDown).small())
|
.child(Icon::new(CoopIcon::ChevronDown).small())
|
||||||
.child(SharedString::from("Suggestions")),
|
.child("Suggestions"),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
uniform_list(
|
uniform_list(
|
||||||
@@ -703,25 +700,18 @@ impl Render for Sidebar {
|
|||||||
.child(Scrollbar::vertical(&self.scroll_handle))
|
.child(Scrollbar::vertical(&self.scroll_handle))
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.when(!self.selected_pkeys.read(cx).is_empty(), |this| {
|
.when(show_create_button, |this| {
|
||||||
this.child(
|
this.child(
|
||||||
div()
|
div().absolute().bottom_2().left_0().w_full().px_2().child(
|
||||||
.absolute()
|
Button::new("create")
|
||||||
.bottom_0()
|
.label(button_label)
|
||||||
.left_0()
|
.primary()
|
||||||
.h_9()
|
.text_sm()
|
||||||
.w_full()
|
.shadow_md()
|
||||||
.px_2()
|
.on_click(cx.listener(move |this, _ev, window, cx| {
|
||||||
.child(
|
this.create_room(window, cx);
|
||||||
Button::new("create")
|
})),
|
||||||
.label(button_label)
|
),
|
||||||
.primary()
|
|
||||||
.small()
|
|
||||||
.shadow_lg()
|
|
||||||
.on_click(cx.listener(move |this, _ev, window, cx| {
|
|
||||||
this.create_room(window, cx);
|
|
||||||
})),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.when(loading, |this| {
|
.when(loading, |this| {
|
||||||
|
|||||||
@@ -575,7 +575,7 @@ impl Workspace {
|
|||||||
|
|
||||||
this.child(
|
this.child(
|
||||||
Button::new("current-user")
|
Button::new("current-user")
|
||||||
.child(Avatar::new().src(avatar.clone()).xsmall())
|
.child(Avatar::new().src(avatar.clone()).small())
|
||||||
.small()
|
.small()
|
||||||
.compact()
|
.compact()
|
||||||
.ghost()
|
.ghost()
|
||||||
@@ -590,7 +590,7 @@ impl Workspace {
|
|||||||
.gap_1p5()
|
.gap_1p5()
|
||||||
.text_xs()
|
.text_xs()
|
||||||
.text_color(cx.theme().muted_foreground)
|
.text_color(cx.theme().muted_foreground)
|
||||||
.child(Avatar::new().src(avatar.clone()).xsmall())
|
.child(Avatar::new().src(avatar.clone()).small())
|
||||||
.child(name.clone())
|
.child(name.clone())
|
||||||
}))
|
}))
|
||||||
.separator()
|
.separator()
|
||||||
|
|||||||
Reference in New Issue
Block a user