chore: update gpui-components

This commit is contained in:
2025-02-05 07:33:21 +07:00
parent c7d17ef90d
commit 72e42bf22a
16 changed files with 99 additions and 82 deletions

View File

@@ -16,9 +16,7 @@ use ui::{
Icon, IconName, Root, Sizable, TitleBar,
};
use super::{
chat, contacts, onboarding, profile, settings, sidebar::Sidebar, welcome::WelcomePanel,
};
use super::{chat, contacts, onboarding, profile, settings, sidebar, welcome};
#[derive(Clone, PartialEq, Eq, Deserialize)]
pub enum PanelKind {
@@ -65,11 +63,11 @@ impl AppView {
pub fn new(account: NostrProfile, window: &mut Window, cx: &mut Context<'_, Self>) -> AppView {
let dock = cx.new(|cx| DockArea::new(DOCK_AREA.id, Some(DOCK_AREA.version), window, cx));
let weak_dock = dock.downgrade();
let left_panel = DockItem::panel(Arc::new(Sidebar::new(window, cx)));
let left_panel = DockItem::panel(Arc::new(sidebar::init(window, cx)));
let center_panel = DockItem::split_with_sizes(
Axis::Vertical,
vec![DockItem::tabs(
vec![Arc::new(WelcomePanel::new(window, cx))],
vec![Arc::new(welcome::init(window, cx))],
None,
&weak_dock,
window,

View File

@@ -5,10 +5,10 @@ use common::{
utils::{compare, message_time, nip96_upload},
};
use gpui::{
div, img, list, px, white, AnyElement, App, AppContext, Context, Entity, EventEmitter, Flatten,
FocusHandle, Focusable, InteractiveElement, IntoElement, ListAlignment, ListState, ObjectFit,
ParentElement, PathPromptOptions, Pixels, Render, SharedString, StatefulInteractiveElement,
Styled, StyledImage, WeakEntity, Window,
div, img, list, prelude::FluentBuilder, px, white, AnyElement, App, AppContext, Context,
Entity, EventEmitter, Flatten, FocusHandle, Focusable, InteractiveElement, IntoElement,
ListAlignment, ListState, ObjectFit, ParentElement, PathPromptOptions, Pixels, Render,
SharedString, StatefulInteractiveElement, Styled, StyledImage, WeakEntity, Window,
};
use itertools::Itertools;
use message::Message;
@@ -21,7 +21,6 @@ use ui::{
dock_area::panel::{Panel, PanelEvent},
input::{InputEvent, TextInput},
popup_menu::PopupMenu,
prelude::FluentBuilder,
theme::{scale::ColorScaleStep, ActiveTheme},
v_flex, ContextModal, Icon, IconName, Sizable,
};

View File

@@ -1,8 +1,8 @@
use common::profile::NostrProfile;
use gpui::{
div, img, px, uniform_list, AnyElement, App, AppContext, Context, Entity, EventEmitter,
FocusHandle, Focusable, InteractiveElement, IntoElement, ParentElement, Render, SharedString,
Styled, Window,
div, img, prelude::FluentBuilder, px, uniform_list, AnyElement, App, AppContext, Context,
Entity, EventEmitter, FocusHandle, Focusable, InteractiveElement, IntoElement, ParentElement,
Render, SharedString, Styled, Window,
};
use nostr_sdk::prelude::*;
use state::get_client;
@@ -12,7 +12,6 @@ use ui::{
dock_area::panel::{Panel, PanelEvent},
indicator::Indicator,
popup_menu::PopupMenu,
prelude::FluentBuilder,
theme::{scale::ColorScaleStep, ActiveTheme},
Sizable,
};

View File

@@ -1,8 +1,8 @@
use app_state::registry::AppRegistry;
use common::profile::NostrProfile;
use gpui::{
div, relative, svg, App, AppContext, BorrowAppContext, Context, Entity, IntoElement,
ParentElement, Render, Styled, Window,
div, prelude::FluentBuilder, relative, svg, App, AppContext, BorrowAppContext, Context, Entity,
IntoElement, ParentElement, Render, Styled, Window,
};
use nostr_connect::prelude::*;
use state::get_client;
@@ -12,7 +12,6 @@ use ui::{
button::{Button, ButtonVariants},
input::{InputEvent, TextInput},
notification::NotificationType,
prelude::FluentBuilder,
theme::{scale::ColorScaleStep, ActiveTheme},
ContextModal, Root, Size, StyledExt,
};

View File

@@ -5,9 +5,9 @@ use common::{
utils::{random_name, room_hash},
};
use gpui::{
div, img, impl_internal_actions, px, uniform_list, App, AppContext, Context, Entity,
FocusHandle, InteractiveElement, IntoElement, ParentElement, Render, SharedString,
StatefulInteractiveElement, Styled, Window,
div, img, impl_internal_actions, prelude::FluentBuilder, px, uniform_list, App, AppContext,
Context, Entity, FocusHandle, InteractiveElement, IntoElement, ParentElement, Render,
SharedString, StatefulInteractiveElement, Styled, Window,
};
use nostr_sdk::prelude::*;
use serde::Deserialize;
@@ -18,7 +18,6 @@ use ui::{
button::{Button, ButtonRounded},
indicator::Indicator,
input::{InputEvent, TextInput},
prelude::FluentBuilder,
theme::{scale::ColorScaleStep, ActiveTheme},
Icon, IconName, Sizable, Size, StyledExt,
};

View File

@@ -18,6 +18,10 @@ use ui::{
mod compose;
mod inbox;
pub fn init(window: &mut Window, cx: &mut App) -> Entity<Sidebar> {
Sidebar::new(window, cx)
}
pub struct Sidebar {
// Panel
name: SharedString,

View File

@@ -10,14 +10,18 @@ use ui::{
StyledExt,
};
pub struct WelcomePanel {
pub fn init(window: &mut Window, cx: &mut App) -> Entity<Welcome> {
Welcome::new(window, cx)
}
pub struct Welcome {
name: SharedString,
closable: bool,
zoomable: bool,
focus_handle: FocusHandle,
}
impl WelcomePanel {
impl Welcome {
pub fn new(window: &mut Window, cx: &mut App) -> Entity<Self> {
cx.new(|cx| Self::view(window, cx))
}
@@ -32,7 +36,7 @@ impl WelcomePanel {
}
}
impl Panel for WelcomePanel {
impl Panel for Welcome {
fn panel_id(&self) -> SharedString {
"WelcomePanel".into()
}
@@ -58,15 +62,15 @@ impl Panel for WelcomePanel {
}
}
impl EventEmitter<PanelEvent> for WelcomePanel {}
impl EventEmitter<PanelEvent> for Welcome {}
impl Focusable for WelcomePanel {
impl Focusable for Welcome {
fn focus_handle(&self, _: &App) -> gpui::FocusHandle {
self.focus_handle.clone()
}
}
impl Render for WelcomePanel {
impl Render for Welcome {
fn render(&mut self, _window: &mut gpui::Window, cx: &mut Context<Self>) -> impl IntoElement {
div()
.size_full()

View File

@@ -2,7 +2,8 @@ use gpui::{
actions, anchored, canvas, deferred, div, prelude::FluentBuilder, px, rems, AnyElement, App,
AppContext, Bounds, ClickEvent, Context, DismissEvent, ElementId, Entity, EventEmitter,
FocusHandle, Focusable, InteractiveElement, IntoElement, KeyBinding, Length, ParentElement,
Pixels, Render, SharedString, StatefulInteractiveElement, Styled, Task, WeakEntity, Window,
Pixels, Render, SharedString, StatefulInteractiveElement, Styled, Subscription, Task,
WeakEntity, Window,
};
use crate::{
@@ -245,6 +246,8 @@ pub struct Dropdown<D: DropdownDelegate + 'static> {
/// Store the bounds of the input
bounds: Bounds<Pixels>,
disabled: bool,
#[allow(dead_code)]
subscriptions: Vec<Subscription>,
}
pub struct SearchableVec<T> {
@@ -255,6 +258,7 @@ pub struct SearchableVec<T> {
impl<T: DropdownItem + Clone> SearchableVec<T> {
pub fn new(items: impl Into<Vec<T>>) -> Self {
let items = items.into();
Self {
items: items.clone(),
matched_items: items,
@@ -345,10 +349,10 @@ where
list
});
cx.on_blur(&list.focus_handle(cx), window, Self::on_blur)
.detach();
cx.on_blur(&focus_handle, window, Self::on_blur).detach();
let subscriptions = vec![
cx.on_blur(&list.focus_handle(cx), window, Self::on_blur),
cx.on_blur(&focus_handle, window, Self::on_blur),
];
let mut this = Self {
id: id.into(),
@@ -365,6 +369,7 @@ where
menu_width: Length::Auto,
bounds: Bounds::default(),
disabled: false,
subscriptions,
};
this.set_selected_index(selected_index, window, cx);
this

View File

@@ -3,7 +3,7 @@ use gpui::{
ClipboardItem, Context, Entity, EntityInputHandler, EventEmitter, FocusHandle, Focusable,
InteractiveElement as _, IntoElement, KeyBinding, KeyDownEvent, MouseButton, MouseDownEvent,
MouseMoveEvent, MouseUpEvent, ParentElement as _, Pixels, Point, Rems, Render, ScrollHandle,
ScrollWheelEvent, SharedString, Styled as _, UTF16Selection, Window, WrappedLine,
ScrollWheelEvent, SharedString, Styled as _, Subscription, UTF16Selection, Window, WrappedLine,
};
use smallvec::SmallVec;
use std::{cell::Cell, ops::Range, rc::Rc};
@@ -213,6 +213,8 @@ pub struct TextInput {
pub(crate) scroll_size: gpui::Size<Pixels>,
/// To remember the horizontal column (x-coordinate) of the cursor position.
preferred_x_offset: Option<Pixels>,
#[allow(dead_code)]
subscriptions: Vec<Subscription>,
}
impl EventEmitter<InputEvent> for TextInput {}
@@ -222,7 +224,25 @@ impl TextInput {
let focus_handle = cx.focus_handle();
let blink_cursor = cx.new(|_| BlinkCursor::new());
let history = History::new().group_interval(std::time::Duration::from_secs(1));
let input = Self {
let subscriptions = vec![
// Observe the blink cursor to repaint the view when it changes.
cx.observe(&blink_cursor, |_, _, cx| cx.notify()),
// Blink the cursor when the window is active, pause when it's not.
cx.observe_window_activation(window, |input, window, cx| {
if window.is_window_active() {
let focus_handle = input.focus_handle.clone();
if focus_handle.is_focused(window) {
input.blink_cursor.update(cx, |blink_cursor, cx| {
blink_cursor.start(cx);
});
}
}
}),
cx.on_focus(&focus_handle, window, Self::on_focus),
cx.on_blur(&focus_handle, window, Self::on_blur),
];
Self {
focus_handle: focus_handle.clone(),
text: "".into(),
multi_line: false,
@@ -256,29 +276,8 @@ impl TextInput {
scrollbar_state: Rc::new(Cell::new(ScrollbarState::default())),
scroll_size: gpui::size(px(0.), px(0.)),
preferred_x_offset: None,
};
// Observe the blink cursor to repaint the view when it changes.
cx.observe(&input.blink_cursor, |_, _, cx| cx.notify())
.detach();
// Blink the cursor when the window is active, pause when it's not.
cx.observe_window_activation(window, |input, window, cx| {
if window.is_window_active() {
let focus_handle = input.focus_handle.clone();
if focus_handle.is_focused(window) {
input.blink_cursor.update(cx, |blink_cursor, cx| {
blink_cursor.start(cx);
});
}
}
})
.detach();
cx.on_focus(&focus_handle, window, Self::on_focus).detach();
cx.on_blur(&focus_handle, window, Self::on_blur).detach();
input
subscriptions,
}
}
/// Use the text input field as a multi-line Textarea.

View File

@@ -15,7 +15,6 @@ pub mod modal;
pub mod notification;
pub mod popover;
pub mod popup_menu;
pub mod prelude;
pub mod progress;
pub mod radio;
pub mod resizable;

View File

@@ -8,7 +8,7 @@ use gpui::{
actions, div, prelude::FluentBuilder, px, uniform_list, AnyElement, App, AppContext, Context,
Entity, FocusHandle, Focusable, InteractiveElement, IntoElement, KeyBinding, Length,
ListSizingBehavior, MouseButton, ParentElement, Render, ScrollStrategy, SharedString, Styled,
Task, UniformListScrollHandle, Window,
Subscription, Task, UniformListScrollHandle, Window,
};
use smol::Timer;
use std::{cell::Cell, rc::Rc, time::Duration};
@@ -111,6 +111,7 @@ pub struct List<D: ListDelegate> {
selected_index: Option<usize>,
right_clicked_index: Option<usize>,
_search_task: Task<()>,
query_input_subscription: Subscription,
}
impl<D> List<D>
@@ -129,8 +130,8 @@ where
.cleanable()
});
cx.subscribe_in(&query_input, window, Self::on_query_input_event)
.detach();
let query_input_subscription =
cx.subscribe_in(&query_input, window, Self::on_query_input_event);
Self {
focus_handle: cx.focus_handle(),
@@ -146,6 +147,7 @@ where
loading: false,
size: Size::default(),
_search_task: Task::ready(()),
query_input_subscription,
}
}
@@ -180,8 +182,8 @@ where
window: &mut Window,
cx: &mut Context<Self>,
) {
cx.subscribe_in(&query_input, window, Self::on_query_input_event)
.detach();
self.query_input_subscription =
cx.subscribe_in(&query_input, window, Self::on_query_input_event);
self.query_input = Some(query_input);
}

View File

@@ -12,10 +12,16 @@ use crate::{
use gpui::{
div, prelude::FluentBuilder, px, Animation, AnimationExt, App, AppContext, ClickEvent, Context,
DismissEvent, ElementId, Entity, EventEmitter, InteractiveElement as _, IntoElement,
ParentElement as _, Render, SharedString, StatefulInteractiveElement, Styled, Window,
ParentElement as _, Render, SharedString, StatefulInteractiveElement, Styled, Subscription,
Window,
};
use smol::Timer;
use std::{any::TypeId, collections::VecDeque, sync::Arc, time::Duration};
use std::{
any::TypeId,
collections::{HashMap, VecDeque},
sync::Arc,
time::Duration,
};
pub enum NotificationType {
Info,
@@ -24,7 +30,7 @@ pub enum NotificationType {
Error,
}
#[derive(Debug, PartialEq, Clone)]
#[derive(Debug, PartialEq, Clone, Hash, Eq)]
pub(crate) enum NotificationId {
Id(TypeId),
IdAndElementId(TypeId, ElementId),
@@ -294,6 +300,7 @@ pub struct NotificationList {
/// Notifications that will be auto hidden.
pub(crate) notifications: VecDeque<Entity<Notification>>,
expanded: bool,
subscriptions: HashMap<NotificationId, Subscription>,
}
impl NotificationList {
@@ -301,6 +308,7 @@ impl NotificationList {
Self {
notifications: VecDeque::new(),
expanded: false,
subscriptions: HashMap::new(),
}
}
@@ -319,10 +327,13 @@ impl NotificationList {
let notification = cx.new(|_| notification);
cx.subscribe(&notification, move |view, _, _: &DismissEvent, cx| {
view.notifications.retain(|note| id != note.read(cx).id);
})
.detach();
self.subscriptions.insert(
id.clone(),
cx.subscribe(&notification, move |view, _, _: &DismissEvent, cx| {
view.notifications.retain(|note| id != note.read(cx).id);
view.subscriptions.remove(&id);
}),
);
self.notifications.push_back(notification.clone());
if autohide {

View File

@@ -11,7 +11,8 @@ use gpui::{
actions, anchored, canvas, div, prelude::FluentBuilder, px, rems, Action, AnyElement, App,
AppContext, Bounds, Context, Corner, DismissEvent, Edges, Entity, EventEmitter, FocusHandle,
Focusable, InteractiveElement, IntoElement, KeyBinding, Keystroke, ParentElement, Pixels,
Render, ScrollHandle, SharedString, StatefulInteractiveElement, Styled, WeakEntity, Window,
Render, ScrollHandle, SharedString, StatefulInteractiveElement, Styled, Subscription,
WeakEntity, Window,
};
use std::{cell::Cell, ops::Deref, rc::Rc};
@@ -114,7 +115,8 @@ pub struct PopupMenu {
scroll_state: Rc<Cell<ScrollbarState>>,
action_focus_handle: Option<FocusHandle>,
_subscriptions: [gpui::Subscription; 1],
#[allow(dead_code)]
subscriptions: Vec<Subscription>,
}
impl PopupMenu {
@@ -125,10 +127,12 @@ impl PopupMenu {
) -> Entity<Self> {
cx.new(|cx| {
let focus_handle = cx.focus_handle();
let _on_blur_subscription =
cx.on_blur(&focus_handle, window, |this: &mut PopupMenu, window, cx| {
this.dismiss(&Dismiss, window, cx)
});
let subscriptions =
vec![
cx.on_blur(&focus_handle, window, |this: &mut PopupMenu, window, cx| {
this.dismiss(&Dismiss, window, cx)
}),
];
let menu = Self {
focus_handle,
@@ -144,7 +148,7 @@ impl PopupMenu {
scrollable: false,
scroll_handle: ScrollHandle::default(),
scroll_state: Rc::new(Cell::new(ScrollbarState::default())),
_subscriptions: [_on_blur_subscription],
subscriptions,
};
window.refresh();
f(menu, window, cx)

View File

@@ -1,5 +0,0 @@
pub use gpui::prelude::*;
pub use gpui::{
div, px, relative, rems, AbsoluteLength, DefiniteLength, Div, Element, ElementId,
InteractiveElement, ParentElement, Pixels, Rems, RenderOnce, SharedString, Styled, Window,
};