chore: update gpui-components
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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(¬ification, move |view, _, _: &DismissEvent, cx| {
|
||||
view.notifications.retain(|note| id != note.read(cx).id);
|
||||
})
|
||||
.detach();
|
||||
self.subscriptions.insert(
|
||||
id.clone(),
|
||||
cx.subscribe(¬ification, 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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
Reference in New Issue
Block a user