diff --git a/crates/concord/src/state.rs b/crates/concord/src/state.rs index 7bb519b3..aa3f459d 100644 --- a/crates/concord/src/state.rs +++ b/crates/concord/src/state.rs @@ -235,6 +235,17 @@ impl CommunityState { None => BTreeMap::new(), }; + let relays = material + .relays + .iter() + .filter_map(|relay| RelayUrl::parse(relay).ok()) + .collect(); + + let control_root = match &material.control_root { + Some(root) => Some(decode_hex_32(root)?), + None => None, + }; + let mut channels = Vec::with_capacity(material.channels.len()); for grant in &material.channels { @@ -260,17 +271,10 @@ impl CommunityState { owner_salt: decode_hex_32(&material.owner_salt)?, community_root: decode_hex_32(&material.community_root)?, root_epoch: material.root_epoch, - control_root: match &material.control_root { - Some(root) => Some(decode_hex_32(root)?), - None => None, - }, + control_root, control_pks, channels, - relays: material - .relays - .iter() - .filter_map(|relay| RelayUrl::parse(relay).ok()) - .collect(), + relays, heads: Vec::new(), banned: BTreeSet::new(), cursors: BTreeMap::new(), diff --git a/crates/workspace/src/dialogs/new_chat.rs b/crates/workspace/src/dialogs/new_chat.rs index 8b039d98..1a7fca76 100644 --- a/crates/workspace/src/dialogs/new_chat.rs +++ b/crates/workspace/src/dialogs/new_chat.rs @@ -5,19 +5,21 @@ use anyhow::Error; use chat::{ChatRegistry, Room, RoomKind}; use gpui::prelude::FluentBuilder; use gpui::{ - AnyElement, App, AppContext, Context, Entity, IntoElement, ParentElement, Render, SharedString, - Styled, Subscription, Task, WeakEntity, Window, div, px, uniform_list, + AnyElement, App, AppContext, Context, Entity, InteractiveElement, IntoElement, ParentElement, + Render, SharedString, StatefulInteractiveElement as _, Styled, Subscription, Task, WeakEntity, + Window, div, px, uniform_list, }; use nostr_sdk::prelude::*; use person::PersonRegistry; use state::NostrRegistry; use theme::ActiveTheme; +use ui::avatar::Avatar; use ui::button::{Button, ButtonVariants}; use ui::dialog::DialogButtonProps; use ui::dock::{DockArea, DockPlacement, PanelHandle}; use ui::input::{Input, InputEvent, InputState}; use ui::nav::Nav; -use ui::{Disableable, IconName, Selectable, Sizable, WindowExtension, h_flex, v_flex}; +use ui::{Disableable, IconName, Sizable, WindowExtension, h_flex, v_flex}; use crate::sidebar::nav_avatar; @@ -341,7 +343,6 @@ impl NewChat { .flatten() .enumerate() .map(|(offset, public_key)| { - let selected = self.members.contains(public_key); let profile = persons.read(cx).get(public_key, cx); let public_key = *public_key; @@ -352,7 +353,6 @@ impl NewChat { nav_avatar(Some(profile.avatar_seed()), profile.avatar(), cx), |this, avatar| this.prefix(avatar), ) - .selected(selected) .on_click(cx.listener(move |this, _event, _window, cx| { this.toggle_member(&public_key, cx); })) @@ -360,6 +360,35 @@ impl NewChat { }) .collect() } + + fn render_members(&self, cx: &mut Context) -> impl IntoElement { + let persons = PersonRegistry::global(cx); + + h_flex() + .flex_wrap() + .gap_1() + .children(self.members.iter().map(|public_key| { + let profile = persons.read(cx).get(public_key, cx); + let public_key = *public_key; + let id = SharedString::from(format!("m-{}", public_key.to_hex())); + + h_flex() + .id(id) + .gap_1() + .p_0p5() + .rounded_full() + .bg(cx.theme().ghost_element_background_alt) + .text_size(px(10.)) + .hover(|this| this.bg(cx.theme().ghost_element_hover)) + .when_some(profile.avatar(), |this, avatar| { + this.child(Avatar::from_source(avatar).xsmall().flex_shrink_0()) + }) + .child(div().max_w_32().truncate().child(profile.name())) + .on_click(cx.listener(move |this, _event, _window, cx| { + this.toggle_member(&public_key, cx); + })) + })) + } } impl Render for NewChat { @@ -371,43 +400,42 @@ impl Render for NewChat { v_flex() .gap_3() .child( - v_flex() + h_flex() + .gap_1() + .w_full() + .child(Input::new(&self.input).flex_1().text_sm().cleanable(true)) .child( - h_flex() - .gap_1() - .w_full() - .child(Input::new(&self.input).flex_1().text_sm().cleanable(true)) - .child( - Button::new("add") - .icon(IconName::Plus) - .tooltip("Add person") - .ghost() - .large() - .disabled(self.resolving) - .on_click(cx.listener(|this, _event, window, cx| { - this.submit(window, cx); - })), - ), - ) - .map(|this| { - if let Some(error) = self.error.clone() { - this.child( - div() - .text_xs() - .text_center() - .text_color(cx.theme().text_danger) - .child(error), - ) - } else { - this.child( - div() - .text_xs() - .text_color(cx.theme().text_placeholder) - .child(notice), - ) - } - }), + Button::new("add") + .icon(IconName::Plus) + .tooltip("Add person") + .ghost() + .large() + .disabled(self.resolving) + .on_click(cx.listener(|this, _event, window, cx| { + this.submit(window, cx); + })), + ), ) + .when(!self.members.is_empty(), |this| { + this.child(self.render_members(cx)) + }) + .map(|this| { + if let Some(error) = self.error.clone() { + this.child( + div() + .text_xs() + .text_color(cx.theme().text_danger) + .child(error), + ) + } else { + this.child( + div() + .text_xs() + .text_color(cx.theme().text_placeholder) + .child(notice), + ) + } + }) .child( uniform_list( "contacts",