Redesign for the v1 stable release #3

Merged
reya merged 30 commits from v1-redesign into master 2026-02-04 01:43:24 +00:00
2 changed files with 88 additions and 111 deletions
Showing only changes of commit 2cc71e3278 - Show all commits

View File

@@ -1,7 +1,8 @@
use std::rc::Rc; use std::rc::Rc;
use chat::{ChatRegistry, RoomKind}; use chat::RoomKind;
use chat_ui::{CopyPublicKey, OpenPublicKey}; use chat_ui::{CopyPublicKey, OpenPublicKey};
use dock::ClosePanel;
use gpui::prelude::FluentBuilder; use gpui::prelude::FluentBuilder;
use gpui::{ use gpui::{
div, rems, App, ClickEvent, InteractiveElement, IntoElement, ParentElement as _, RenderOnce, div, rems, App, ClickEvent, InteractiveElement, IntoElement, ParentElement as _, RenderOnce,
@@ -13,7 +14,6 @@ use theme::ActiveTheme;
use ui::avatar::Avatar; use ui::avatar::Avatar;
use ui::context_menu::ContextMenuExt; use ui::context_menu::ContextMenuExt;
use ui::modal::ModalButtonProps; use ui::modal::ModalButtonProps;
use ui::skeleton::Skeleton;
use ui::{h_flex, StyledExt, WindowExtension}; use ui::{h_flex, StyledExt, WindowExtension};
use crate::views::screening; use crate::views::screening;
@@ -21,7 +21,6 @@ use crate::views::screening;
#[derive(IntoElement)] #[derive(IntoElement)]
pub struct RoomListItem { pub struct RoomListItem {
ix: usize, ix: usize,
room_id: Option<u64>,
public_key: Option<PublicKey>, public_key: Option<PublicKey>,
name: Option<SharedString>, name: Option<SharedString>,
avatar: Option<SharedString>, avatar: Option<SharedString>,
@@ -35,7 +34,6 @@ impl RoomListItem {
pub fn new(ix: usize) -> Self { pub fn new(ix: usize) -> Self {
Self { Self {
ix, ix,
room_id: None,
public_key: None, public_key: None,
name: None, name: None,
avatar: None, avatar: None,
@@ -45,11 +43,6 @@ impl RoomListItem {
} }
} }
pub fn room_id(mut self, room_id: u64) -> Self {
self.room_id = Some(room_id);
self
}
pub fn public_key(mut self, public_key: PublicKey) -> Self { pub fn public_key(mut self, public_key: PublicKey) -> Self {
self.public_key = Some(public_key); self.public_key = Some(public_key);
self self
@@ -89,41 +82,6 @@ impl RenderOnce for RoomListItem {
let hide_avatar = AppSettings::get_hide_avatar(cx); let hide_avatar = AppSettings::get_hide_avatar(cx);
let screening = AppSettings::get_screening(cx); let screening = AppSettings::get_screening(cx);
let (
Some(public_key),
Some(room_id),
Some(name),
Some(avatar),
Some(created_at),
Some(kind),
Some(handler),
) = (
self.public_key,
self.room_id,
self.name,
self.avatar,
self.created_at,
self.kind,
self.handler,
)
else {
return h_flex()
.id(self.ix)
.h_9()
.w_full()
.px_1p5()
.gap_2()
.child(Skeleton::new().flex_shrink_0().size_6().rounded_full())
.child(
div()
.flex_1()
.flex()
.justify_between()
.child(Skeleton::new().w_32().h_2p5().rounded(cx.theme().radius))
.child(Skeleton::new().w_6().h_2p5().rounded(cx.theme().radius)),
);
};
h_flex() h_flex()
.id(self.ix) .id(self.ix)
.h_9() .h_9()
@@ -133,6 +91,7 @@ impl RenderOnce for RoomListItem {
.text_sm() .text_sm()
.rounded(cx.theme().radius) .rounded(cx.theme().radius)
.when(!hide_avatar, |this| { .when(!hide_avatar, |this| {
this.when_some(self.avatar, |this, avatar| {
this.child( this.child(
div() div()
.flex_shrink_0() .flex_shrink_0()
@@ -142,13 +101,15 @@ impl RenderOnce for RoomListItem {
.child(Avatar::new(avatar).size(rems(1.5))), .child(Avatar::new(avatar).size(rems(1.5))),
) )
}) })
})
.child( .child(
div() div()
.flex_1() .flex_1()
.flex() .flex()
.items_center() .items_center()
.justify_between() .justify_between()
.child( .when_some(self.name, |this, name| {
this.child(
div() div()
.flex_1() .flex_1()
.line_clamp(1) .line_clamp(1)
@@ -157,13 +118,14 @@ impl RenderOnce for RoomListItem {
.font_medium() .font_medium()
.child(name), .child(name),
) )
})
.child( .child(
h_flex() h_flex()
.gap_1p5() .gap_1p5()
.flex_shrink_0() .flex_shrink_0()
.text_xs() .text_xs()
.text_color(cx.theme().text_placeholder) .text_color(cx.theme().text_placeholder)
.child(created_at) .when_some(self.created_at, |this, created_at| this.child(created_at))
.when_some(self.kind, |this, kind| { .when_some(self.kind, |this, kind| {
this.when(kind == RoomKind::Request, |this| { this.when(kind == RoomKind::Request, |this| {
this.child( this.child(
@@ -174,14 +136,16 @@ impl RenderOnce for RoomListItem {
), ),
) )
.hover(|this| this.bg(cx.theme().elevated_surface_background)) .hover(|this| this.bg(cx.theme().elevated_surface_background))
.context_menu(move |this, _window, _cx| { .when_some(self.public_key, |this, public_key| {
this.context_menu(move |this, _window, _cx| {
this.menu("View Profile", Box::new(OpenPublicKey(public_key))) this.menu("View Profile", Box::new(OpenPublicKey(public_key)))
.menu("Copy Public Key", Box::new(CopyPublicKey(public_key))) .menu("Copy Public Key", Box::new(CopyPublicKey(public_key)))
}) })
.on_click(move |event, window, cx| { .when_some(self.handler, |this, handler| {
this.on_click(move |event, window, cx| {
handler(event, window, cx); handler(event, window, cx);
if kind != RoomKind::Ongoing && screening { if self.kind != Some(RoomKind::Ongoing) && screening {
let screening = screening::init(public_key, window, cx); let screening = screening::init(public_key, window, cx);
window.open_modal(cx, move |this, _window, _cx| { window.open_modal(cx, move |this, _window, _cx| {
@@ -192,16 +156,16 @@ impl RenderOnce for RoomListItem {
.cancel_text("Ignore") .cancel_text("Ignore")
.ok_text("Response"), .ok_text("Response"),
) )
.on_cancel(move |_event, _window, cx| { .on_cancel(move |_event, window, cx| {
ChatRegistry::global(cx).update(cx, |this, cx| { window.dispatch_action(Box::new(ClosePanel), cx);
this.close_room(room_id, cx); // Prevent closing the modal on click
}); // Modal will be automatically closed after closing panel
// false to prevent closing the modal
// modal will be closed after closing panel
false false
}) })
}); });
} }
}) })
})
})
} }
} }

View File

@@ -20,6 +20,7 @@ use state::{NostrRegistry, GIFTWRAP_SUBSCRIPTION};
use theme::{ActiveTheme, CLIENT_SIDE_DECORATION_ROUNDING, TITLEBAR_HEIGHT}; use theme::{ActiveTheme, CLIENT_SIDE_DECORATION_ROUNDING, TITLEBAR_HEIGHT};
use ui::avatar::Avatar; use ui::avatar::Avatar;
use ui::button::{Button, ButtonVariants}; use ui::button::{Button, ButtonVariants};
use ui::indicator::Indicator;
use ui::input::{InputEvent, InputState, TextInput}; use ui::input::{InputEvent, InputState, TextInput};
use ui::{h_flex, v_flex, Icon, IconName, Sizable, StyledExt, WindowExtension}; use ui::{h_flex, v_flex, Icon, IconName, Sizable, StyledExt, WindowExtension};
@@ -539,23 +540,22 @@ impl Sidebar {
.flatten() .flatten()
.enumerate() .enumerate()
.map(|(ix, item)| { .map(|(ix, item)| {
let this = item.read(cx); let room = item.read(cx);
let room_id = this.id; let id = room.id;
let member = this.display_member(cx); let public_key = room.display_member(cx).public_key();
let handler = cx.listener({ let handler = cx.listener({
move |this, _ev, window, cx| { move |this, _ev, window, cx| {
this.open(room_id, window, cx); this.open(id, window, cx);
} }
}); });
RoomListItem::new(range.start + ix) RoomListItem::new(range.start + ix)
.room_id(room_id) .name(room.display_name(cx))
.name(this.display_name(cx)) .avatar(room.display_image(cx))
.avatar(this.display_image(cx)) .public_key(public_key)
.public_key(member.public_key()) .kind(room.kind)
.kind(this.kind) .created_at(room.created_at.to_ago())
.created_at(this.created_at.to_ago())
.on_click(handler) .on_click(handler)
.into_any_element() .into_any_element()
}) })
@@ -587,20 +587,12 @@ impl Render for Sidebar {
let chat = ChatRegistry::global(cx); let chat = ChatRegistry::global(cx);
let loading = chat.read(cx).loading(); let loading = chat.read(cx).loading();
// Get rooms from either search results or the chat registry // Get total rooms
let rooms = match self.search_results.read(cx).as_ref() { let total_rooms = match self.search_results.read(cx).as_ref() {
Some(results) => results, Some(results) => results.len(),
None => chat.read(cx).rooms(cx), None => chat.read(cx).rooms(cx).len(),
}; };
// Get total rooms count
let mut total_rooms = rooms.len();
// Add 3 dummy rooms to display as skeletons
if loading {
total_rooms += 3
}
v_flex() v_flex()
.on_action(cx.listener(Self::on_reload)) .on_action(cx.listener(Self::on_reload))
.on_action(cx.listener(Self::on_manage)) .on_action(cx.listener(Self::on_manage))
@@ -710,7 +702,28 @@ impl Render for Sidebar {
}), }),
) )
.h_full(), .h_full(),
)
.when(loading, |this| {
this.child(
div().absolute().top_2().left_0().w_full().px_8().child(
h_flex()
.gap_2()
.w_full()
.h_9()
.justify_center()
.bg(cx.theme().background.opacity(0.85))
.border_color(cx.theme().border_disabled)
.border_1()
.when(cx.theme().shadow, |this| this.shadow_sm())
.rounded_full()
.text_xs()
.font_semibold()
.text_color(cx.theme().text_muted)
.child(Indicator::new().small().color(cx.theme().icon_accent))
.child(SharedString::from("Getting messages...")),
), ),
) )
}),
)
} }
} }