chore: migrate to gpui-base (#51)

Reviewed-on: #51
This commit was merged in pull request #51.
This commit is contained in:
2026-09-17 11:50:14 +00:00
parent 874f103752
commit 0c1c23fe9c
69 changed files with 2458 additions and 15637 deletions
+63 -68
View File
@@ -8,7 +8,7 @@ use common::download_dir;
use device::{DeviceEvent, DeviceRegistry};
use gpui::prelude::FluentBuilder;
use gpui::{
Action, App, AppContext, Axis, Context, Entity, InteractiveElement, IntoElement, ParentElement,
Action, App, AppContext, Context, Entity, InteractiveElement, IntoElement, ParentElement,
Render, SharedString, Styled, Subscription, Task, Window, div, px,
};
use nostr_sdk::prelude::*;
@@ -19,7 +19,7 @@ use state::{NostrRegistry, StateEvent};
use theme::{ActiveTheme, SIDEBAR_WIDTH, Theme, ThemeRegistry};
use ui::avatar::Avatar;
use ui::button::{Button, ButtonVariants};
use ui::dock::{ClosePanel, DockArea, DockItem, DockPlacement, PanelView};
use ui::dock::{self, ClosePanel, DockArea, DockLayout, DockPlacement, Panel, PanelHandle};
use ui::menu::{DropdownMenu, PopupMenuItem};
use ui::notification::{Notification, NotificationKind};
use ui::{Icon, IconName, Root, Sizable, TitleBar, WindowExtension, h_flex, v_flex};
@@ -78,7 +78,7 @@ impl Workspace {
let nostr = NostrRegistry::global(cx);
let sidebar = cx.new(|cx| Sidebar::new(window, cx));
let dock = cx.new(|cx| DockArea::new(window, cx));
let dock = dock::dock_area("coop", window, cx);
let mut subscriptions = smallvec![];
@@ -185,20 +185,18 @@ impl Workspace {
}
ChatEvent::OpenRoom(id) => {
if let Some(room) = chat.read(cx).room(id, cx) {
this.dock.update(cx, |this, cx| {
this.add_panel(
Arc::new(chat_ui::init(room, window, cx)),
DockPlacement::Center,
window,
cx,
);
});
this.add_panel_to_dock(
chat_ui::init(room, window, cx),
DockPlacement::Center,
window,
cx,
);
}
}
ChatEvent::CloseRoom(..) => {
this.dock.update(cx, |this, cx| {
this.dock.update(cx, |area, cx| {
// Force focus to the tab panel
this.focus_tab_panel(window, cx);
ui::dock::focus_tab_panel(area, window, cx);
// Dispatch the close panel action
cx.defer_in(window, |_, window, cx| {
@@ -216,14 +214,12 @@ impl Workspace {
);
cx.defer_in(window, |this, window, cx| {
let dock = this.dock.downgrade();
let greeter = Arc::new(greeter::init(window, cx));
let tabs = DockItem::tabs(vec![greeter], None, &dock, window, cx);
let center = DockItem::split(Axis::Vertical, vec![tabs], &dock, window, cx);
let greeter = PanelHandle::new(greeter::init(window, cx));
let center = DockLayout::v_split()
.child(DockLayout::tabs().panel_view(Arc::new(greeter), cx), None);
this.dock.update(cx, |this, cx| {
this.set_center(center, window, cx);
});
this.dock
.update(cx, |area, cx| area.set_center(center, window, cx));
});
Self {
@@ -234,22 +230,36 @@ impl Workspace {
}
}
/// Add panel to the dock
pub fn add_panel<P>(panel: P, placement: DockPlacement, window: &mut Window, cx: &mut App)
where
P: PanelView,
{
/// Add a panel to the dock, from anywhere that has the window but not the
/// workspace.
pub fn add_panel<P: Panel>(
panel: Entity<P>,
placement: DockPlacement,
window: &mut Window,
cx: &mut App,
) {
if let Some(root) = window.root::<Root>().flatten()
&& let Ok(workspace) = root.read(cx).view().clone().downcast::<Self>()
{
workspace.update(cx, |this, cx| {
this.dock.update(cx, |this, cx| {
this.add_panel(Arc::new(panel), placement, window, cx);
});
this.add_panel_to_dock(panel, placement, window, cx)
});
}
}
/// Add a panel to the dock, or focus it if it is already docked.
fn add_panel_to_dock<P: Panel>(
&mut self,
panel: Entity<P>,
placement: DockPlacement,
window: &mut Window,
cx: &mut Context<Self>,
) {
self.dock.update(cx, |area, cx| {
ui::dock::add_panel(area, PanelHandle::new(panel), placement, window, cx)
});
}
/// Handle command events
fn on_command(&mut self, command: &Command, window: &mut Window, cx: &mut Context<Self>) {
match command {
@@ -268,45 +278,32 @@ impl Workspace {
let nostr = NostrRegistry::global(cx);
if let Some(public_key) = nostr.read(cx).current_user() {
self.dock.update(cx, |this, cx| {
this.add_panel(
Arc::new(profile::init(public_key, window, cx)),
DockPlacement::Left,
window,
cx,
);
});
self.add_panel_to_dock(
profile::init(public_key, window, cx),
DockPlacement::Left,
window,
cx,
);
}
}
Command::ShowContactList => {
self.dock.update(cx, |this, cx| {
this.add_panel(
Arc::new(contact_list::init(window, cx)),
DockPlacement::Left,
window,
cx,
);
});
self.add_panel_to_dock(
contact_list::init(window, cx),
DockPlacement::Left,
window,
cx,
);
}
Command::ShowBackup => {
self.dock.update(cx, |this, cx| {
this.add_panel(
Arc::new(backup::init(window, cx)),
DockPlacement::Left,
window,
cx,
);
});
self.add_panel_to_dock(backup::init(window, cx), DockPlacement::Left, window, cx);
}
Command::ShowMessaging => {
self.dock.update(cx, |this, cx| {
this.add_panel(
Arc::new(messaging_relays::init(window, cx)),
DockPlacement::Left,
window,
cx,
);
});
self.add_panel_to_dock(
messaging_relays::init(window, cx),
DockPlacement::Left,
window,
cx,
);
}
Command::RefreshMessagingRelays => {
let chat = ChatRegistry::global(cx);
@@ -316,14 +313,12 @@ impl Workspace {
});
}
Command::ShowRelayList => {
self.dock.update(cx, |this, cx| {
this.add_panel(
Arc::new(relay_list::init(window, cx)),
DockPlacement::Right,
window,
cx,
);
});
self.add_panel_to_dock(
relay_list::init(window, cx),
DockPlacement::Right,
window,
cx,
);
}
Command::RefreshEncryption => {
let device = DeviceRegistry::global(cx);
+4 -5
View File
@@ -15,7 +15,7 @@ use theme::ActiveTheme;
use ui::avatar::Avatar;
use ui::button::{Button, ButtonVariants};
use ui::dock::{Panel, PanelEvent};
use ui::input::{Input, InputState};
use ui::input::{Input, InputState, Textarea, TextareaState};
use ui::notification::Notification;
use ui::{Disableable, IconName, Sizable, StyledExt, WindowExtension, h_flex, v_flex};
@@ -38,7 +38,7 @@ pub struct ProfilePanel {
avatar_input: Entity<InputState>,
/// User's bio multi line input
bio_input: Entity<InputState>,
bio_input: Entity<TextareaState>,
/// User's website url text input
website_input: Entity<InputState>,
@@ -64,8 +64,7 @@ impl ProfilePanel {
// Use multi-line input for bio
let bio_input = cx.new(|cx| {
InputState::new(window, cx)
.multi_line(true)
TextareaState::new(window, cx)
.auto_grow(3, 8)
.placeholder("A short introduce about you.")
});
@@ -367,7 +366,7 @@ impl Render for ProfilePanel {
.text_color(cx.theme().text_muted)
.child(SharedString::from("A short introduction about you:")),
)
.child(Input::new(&self.bio_input).small()),
.child(Textarea::new(&self.bio_input).small()),
)
.child(
v_flex()
+14 -11
View File
@@ -257,10 +257,10 @@ impl Sidebar {
}
/// Set the finding status
fn set_finding(&mut self, status: bool, _window: &mut Window, cx: &mut Context<Self>) {
fn set_finding(&mut self, status: bool, window: &mut Window, cx: &mut Context<Self>) {
// Disable the input to prevent duplicate requests
self.find_input.update(cx, |this, cx| {
this.set_loading(status, cx);
this.set_loading(status, window, cx);
});
// Set the search status
self.finding = status;
@@ -530,15 +530,18 @@ impl Render for Sidebar {
.small()
.text_xs()
.disabled(loading)
.when(!self.find_input.read(cx).loading, |this| {
this.suffix(
Button::new("find-icon")
.icon(IconName::Search)
.tooltip("Press Enter to search")
.transparent()
.small(),
)
}),
.when(
!self.find_input.read(cx).presentation().is_loading(),
|this| {
this.suffix(
Button::new("find-icon")
.icon(IconName::Search)
.tooltip("Press Enter to search")
.transparent()
.small(),
)
},
),
),
)
.child(