migrate ui components to gpui-kit

This commit is contained in:
2026-10-21 13:40:29 +07:00
parent 0d4acf5b65
commit d0ad1a6f57
173 changed files with 2775 additions and 10885 deletions
+89 -72
View File
@@ -4,24 +4,25 @@ use chat::{Room, RoomKind};
use common::TimestampExt;
use gpui::prelude::FluentBuilder;
use gpui::{
AnyElement, App, Context, Entity, IntoElement, ParentElement, SharedString, Styled, WeakEntity,
Window, div, px,
AnyElement, App, Context, Entity, InteractiveElement as _, IntoElement, ParentElement,
SharedString, Styled, WeakEntity, Window, div, px,
};
use gpui_kit::assets::IconName;
use gpui_kit::component::avatar::Avatar;
use gpui_kit::component::dialog::DialogButtonProps;
use gpui_kit::component::dock::{ClosePanel, DockArea, DockPlacement, PanelHandle};
use gpui_kit::component::menu::{ContextMenuExt as _, PopupMenuItem};
use gpui_kit::component::{ActiveTheme, Icon, Selectable, Sizable, WindowExt, h_flex, v_flex};
use nip29::Group;
use nostr_sdk::prelude::*;
use settings::AppSettings;
use theme::{ActiveTheme, TextStyle, Typeset as _, button_radius};
use ui::avatar::Avatar;
use ui::dialog::DialogButtonProps;
use ui::dock::{ClosePanel, DockArea, DockPlacement, PanelHandle};
use ui::menu::{ContextMenu, PopupMenuItem};
use ui::nav::Nav;
use ui::{Icon, IconName, Selectable, Sizable, StyledExt, WindowExtension, h_flex, v_flex};
use ui::{TextStyle, Typeset as _, button_radius};
use super::Sidebar;
use super::list::ListSection;
use super::search::MessageHit;
use crate::dialogs::{profile, screening};
use crate::nav::Nav;
/// Open a room in the dock, screening new requests when enabled.
pub(crate) fn open_room(
@@ -30,7 +31,7 @@ pub(crate) fn open_room(
window: &mut Window,
cx: &mut App,
) {
ui::dock::add_panel_to(
crate::dock::add_panel_to(
dock,
PanelHandle::new(chat_ui::init(room.downgrade(), window, cx)),
DockPlacement::Center,
@@ -42,8 +43,9 @@ pub(crate) fn open_room(
let peer = room.read(cx).display_member(cx).public_key();
let view = screening::init(peer, window, cx);
window.open_dialog(cx, move |this, _window, _cx| {
this.confirm()
window.open_alert_dialog(cx, move |alert, _window, _cx| {
alert
.confirm()
.child(view.clone())
.button_props(
DialogButtonProps::default()
@@ -86,17 +88,21 @@ impl Sidebar {
};
let icon = if open {
IconName::CaretDown
IconName::ChevronDown
} else {
IconName::CaretRight
IconName::ChevronRight
};
Nav::new(label)
.label(label)
.suffix(Icon::new(icon).small().text_color(cx.theme().text_muted))
.suffix(
Icon::new(icon)
.small()
.text_color(cx.theme().muted_foreground),
)
.text_style(TextStyle::Caption)
.font_semibold()
.text_color(cx.theme().text_muted)
.font_weight(gpui::FontWeight::SEMIBOLD)
.text_color(cx.theme().muted_foreground)
.on_click(cx.listener(move |this, _event, _window, cx| {
match section {
ListSection::Pins => this.pins_open = !this.pins_open,
@@ -117,8 +123,8 @@ impl Sidebar {
Nav::new(label)
.label(label)
.text_style(TextStyle::Caption)
.font_semibold()
.text_color(cx.theme().text_muted)
.font_weight(gpui::FontWeight::SEMIBOLD)
.text_color(cx.theme().muted_foreground)
.into_any_element()
}
SidebarRow::Empty(text) => v_flex()
@@ -136,7 +142,7 @@ impl Sidebar {
.border_color(cx.theme().border)
.rounded(px(button_radius()))
.text_style(TextStyle::Caption)
.text_color(cx.theme().text_muted)
.text_color(cx.theme().muted_foreground)
.child(*text),
)
.into_any_element(),
@@ -144,6 +150,7 @@ impl Sidebar {
let id = room.read(cx).id;
let name = room.read(cx).display_name(cx);
let picture = room.read(cx).display_image(cx);
#[allow(unused_variables)]
let seed = room.read(cx).display_image_seed(cx);
let created_at = room.read(cx).created_at.to_ago();
let member = room.read(cx).members().first().copied();
@@ -158,12 +165,14 @@ impl Sidebar {
.label(name)
.text_style(TextStyle::Callout)
.when(!hide_avatar, |this| {
this.prefix(
Avatar::from_source(picture)
.seed(seed)
.small()
.flex_shrink_0(),
)
this.prefix(match picture {
Some(picture) => {
Avatar::new().src(picture).small().into_any_element()
}
None => {
Avatar::new().small().flex_shrink_0().into_any_element()
}
})
})
.suffix(
h_flex()
@@ -182,9 +191,9 @@ impl Sidebar {
.when(!spam, |this| {
this.child(
div()
.font_normal()
.font_weight(gpui::FontWeight::NORMAL)
.text_style(TextStyle::Caption)
.text_color(cx.theme().text_faint)
.text_color(cx.theme().muted_foreground)
.child(created_at),
)
}),
@@ -193,10 +202,11 @@ impl Sidebar {
open_room(&room, &dock, window, cx);
});
ContextMenu::new(
format!("room-menu-{index}"),
nav,
move |menu, _window, _cx| {
div()
.id(index)
.w_full()
.child(nav)
.context_menu(move |menu, _window, _cx| {
let menu = menu.item(
PopupMenuItem::new(if pinned { "Unpin" } else { "Pin" })
.on_click(move |_, _window, cx| {
@@ -215,9 +225,8 @@ impl Sidebar {
} else {
menu
}
},
)
.into_any_element()
})
.into_any_element()
}
SidebarRow::Contact { public_key } => {
let person = self.directory.read(cx).person(public_key, cx);
@@ -229,12 +238,14 @@ impl Sidebar {
.label(person.name())
.text_style(TextStyle::Callout)
.when(!hide_avatar, |this| {
this.prefix(
Avatar::from_source(person.avatar())
.seed(person.avatar_seed())
.small()
.flex_shrink_0(),
)
this.prefix(match person.avatar() {
Some(picture) => {
Avatar::new().src(picture).small().into_any_element()
}
None => {
Avatar::new().small().flex_shrink_0().into_any_element()
}
})
})
.selected(selected)
.on_click(move |_event, _window, cx| {
@@ -254,12 +265,14 @@ impl Sidebar {
.label(person.name())
.text_style(TextStyle::Callout)
.when(!hide_avatar, |this| {
this.prefix(
Avatar::from_source(person.avatar())
.seed(person.avatar_seed())
.small()
.flex_shrink_0(),
)
this.prefix(match person.avatar() {
Some(picture) => {
Avatar::new().src(picture).small().into_any_element()
}
None => {
Avatar::new().small().flex_shrink_0().into_any_element()
}
})
})
.on_click(move |_event, window, cx| {
profile::open(public_key, window, cx);
@@ -289,24 +302,26 @@ impl Sidebar {
.label(name)
.text_style(TextStyle::Callout)
.when(!hide_avatar, |this| {
this.prefix(
Avatar::from_source(picture)
.seed(seed)
.small()
.flex_shrink_0(),
)
this.prefix(match picture {
Some(picture) => {
Avatar::new().src(picture).small().into_any_element()
}
None => {
Avatar::new().small().flex_shrink_0().into_any_element()
}
})
})
.when_some(suffix, |this, suffix| {
this.suffix(
div()
.font_normal()
.font_weight(gpui::FontWeight::NORMAL)
.text_style(TextStyle::Caption)
.text_color(cx.theme().text_faint)
.text_color(cx.theme().muted_foreground)
.child(suffix),
)
})
.on_click(move |_event, window, cx| {
ui::dock::add_panel_to(
crate::dock::add_panel_to(
&dock,
PanelHandle::new(nip29_ui::init(group.clone(), window, cx)),
DockPlacement::Center,
@@ -321,10 +336,11 @@ impl Sidebar {
}
});
ContextMenu::new(
format!("group-menu-{index}"),
nav,
move |menu, _window, _cx| {
div()
.id(index)
.w_full()
.child(nav)
.context_menu(move |menu, _window, _cx| {
menu.item(
PopupMenuItem::new(if pinned { "Unpin" } else { "Pin" })
.on_click({
@@ -347,9 +363,8 @@ impl Sidebar {
}
}),
)
},
)
.into_any_element()
})
.into_any_element()
}
SidebarRow::Message { hit } => {
let person = self.directory.read(cx).person(&hit.author, cx);
@@ -362,20 +377,22 @@ impl Sidebar {
Nav::new(index)
.label(content)
.text_style(TextStyle::Callout)
.font_medium()
.font_weight(gpui::FontWeight::MEDIUM)
.when(!hide_avatar, |this| {
this.prefix(
Avatar::from_source(person.avatar())
.seed(person.avatar_seed())
.small()
.flex_shrink_0(),
)
this.prefix(match person.avatar() {
Some(picture) => {
Avatar::new().src(picture).small().into_any_element()
}
None => {
Avatar::new().small().flex_shrink_0().into_any_element()
}
})
})
.suffix(
div()
.font_normal()
.font_weight(gpui::FontWeight::NORMAL)
.text_style(TextStyle::Caption)
.text_color(cx.theme().text_faint)
.text_color(cx.theme().muted_foreground)
.child(detail),
)
.on_click(move |_event, window, cx| {