Redesign for the v1 stable release #3
@@ -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
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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...")),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user