Redesign for the v1 stable release #3

Merged
reya merged 30 commits from v1-redesign into master 2026-02-04 01:43:24 +00:00
24 changed files with 138 additions and 162 deletions
Showing only changes of commit 2fa4436e2d - Show all commits

18
Cargo.lock generated
View File

@@ -1034,6 +1034,7 @@ dependencies = [
"anyhow", "anyhow",
"chat", "chat",
"common", "common",
"dock",
"emojis", "emojis",
"gpui", "gpui",
"gpui_tokio", "gpui_tokio",
@@ -1295,6 +1296,7 @@ dependencies = [
"chat_ui", "chat_ui",
"common", "common",
"device", "device",
"dock",
"futures", "futures",
"gpui", "gpui",
"gpui_tokio", "gpui_tokio",
@@ -1740,6 +1742,19 @@ dependencies = [
"rand 0.8.5", "rand 0.8.5",
] ]
[[package]]
name = "dock"
version = "0.3.0"
dependencies = [
"anyhow",
"common",
"gpui",
"log",
"smallvec",
"theme",
"ui",
]
[[package]] [[package]]
name = "downcast-rs" name = "downcast-rs"
version = "1.2.1" version = "1.2.1"
@@ -6584,10 +6599,7 @@ dependencies = [
"common", "common",
"gpui", "gpui",
"linicon", "linicon",
"log",
"nostr-sdk",
"smallvec", "smallvec",
"smol",
"theme", "theme",
"ui", "ui",
"windows 0.61.3", "windows 0.61.3",

View File

@@ -7,6 +7,7 @@ publish.workspace = true
[dependencies] [dependencies]
state = { path = "../state" } state = { path = "../state" }
ui = { path = "../ui" } ui = { path = "../ui" }
dock = { path = "../dock" }
theme = { path = "../theme" } theme = { path = "../theme" }
common = { path = "../common" } common = { path = "../common" }
person = { path = "../person" } person = { path = "../person" }

View File

@@ -4,6 +4,7 @@ use std::time::Duration;
pub use actions::*; pub use actions::*;
use chat::{Message, RenderedMessage, Room, RoomEvent, RoomKind, SendReport}; use chat::{Message, RenderedMessage, Room, RoomEvent, RoomKind, SendReport};
use common::{nip96_upload, RenderedTimestamp}; use common::{nip96_upload, RenderedTimestamp};
use dock::panel::{Panel, PanelEvent};
use gpui::prelude::FluentBuilder; use gpui::prelude::FluentBuilder;
use gpui::{ use gpui::{
div, img, list, px, red, relative, rems, svg, white, AnyElement, App, AppContext, div, img, list, px, red, relative, rems, svg, white, AnyElement, App, AppContext,
@@ -25,7 +26,6 @@ use theme::ActiveTheme;
use ui::avatar::Avatar; use ui::avatar::Avatar;
use ui::button::{Button, ButtonVariants}; use ui::button::{Button, ButtonVariants};
use ui::context_menu::ContextMenuExt; use ui::context_menu::ContextMenuExt;
use ui::dock_area::panel::{Panel, PanelEvent};
use ui::input::{InputEvent, InputState, TextInput}; use ui::input::{InputEvent, InputState, TextInput};
use ui::notification::Notification; use ui::notification::Notification;
use ui::popup_menu::PopupMenuExt; use ui::popup_menu::PopupMenuExt;

View File

@@ -29,6 +29,7 @@ icons = [
[dependencies] [dependencies]
assets = { path = "../assets" } assets = { path = "../assets" }
ui = { path = "../ui" } ui = { path = "../ui" }
dock = { path = "../dock" }
title_bar = { path = "../title_bar" } title_bar = { path = "../title_bar" }
theme = { path = "../theme" } theme = { path = "../theme" }
common = { path = "../common" } common = { path = "../common" }

View File

@@ -2,6 +2,7 @@ use std::time::Duration;
use anyhow::anyhow; use anyhow::anyhow;
use common::BUNKER_TIMEOUT; use common::BUNKER_TIMEOUT;
use dock::panel::{Panel, PanelEvent};
use gpui::prelude::FluentBuilder; use gpui::prelude::FluentBuilder;
use gpui::{ use gpui::{
div, relative, AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle, div, relative, AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle,
@@ -13,7 +14,6 @@ use smallvec::{smallvec, SmallVec};
use state::NostrRegistry; use state::NostrRegistry;
use theme::ActiveTheme; use theme::ActiveTheme;
use ui::button::{Button, ButtonVariants}; use ui::button::{Button, ButtonVariants};
use ui::dock_area::panel::{Panel, PanelEvent};
use ui::input::{InputEvent, InputState, TextInput}; use ui::input::{InputEvent, InputState, TextInput};
use ui::notification::Notification; use ui::notification::Notification;
use ui::{v_flex, Disableable, StyledExt, WindowExtension}; use ui::{v_flex, Disableable, StyledExt, WindowExtension};

View File

@@ -1,5 +1,6 @@
use anyhow::{anyhow, Error}; use anyhow::{anyhow, Error};
use common::{default_nip17_relays, default_nip65_relays, nip96_upload, BOOTSTRAP_RELAYS}; use common::{default_nip17_relays, default_nip65_relays, nip96_upload, BOOTSTRAP_RELAYS};
use dock::panel::{Panel, PanelEvent};
use gpui::{ use gpui::{
rems, AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle, Focusable, rems, AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle, Focusable,
IntoElement, ParentElement, PathPromptOptions, Render, SharedString, Styled, Task, Window, IntoElement, ParentElement, PathPromptOptions, Render, SharedString, Styled, Task, Window,
@@ -12,7 +13,6 @@ use smol::fs;
use state::NostrRegistry; use state::NostrRegistry;
use ui::avatar::Avatar; use ui::avatar::Avatar;
use ui::button::{Button, ButtonVariants}; use ui::button::{Button, ButtonVariants};
use ui::dock_area::panel::{Panel, PanelEvent};
use ui::input::{InputState, TextInput}; use ui::input::{InputState, TextInput};
use ui::modal::ModalButtonProps; use ui::modal::ModalButtonProps;
use ui::{divider, v_flex, Disableable, IconName, Sizable, WindowExtension}; use ui::{divider, v_flex, Disableable, IconName, Sizable, WindowExtension};

View File

@@ -4,6 +4,7 @@ use std::time::Duration;
use anyhow::{anyhow, Error}; use anyhow::{anyhow, Error};
use chat::{ChatEvent, ChatRegistry, Room, RoomKind}; use chat::{ChatEvent, ChatRegistry, Room, RoomKind};
use common::{DebouncedDelay, RenderedTimestamp, TextUtils, BOOTSTRAP_RELAYS, SEARCH_RELAYS}; use common::{DebouncedDelay, RenderedTimestamp, TextUtils, BOOTSTRAP_RELAYS, SEARCH_RELAYS};
use dock::panel::{Panel, PanelEvent};
use gpui::prelude::FluentBuilder; use gpui::prelude::FluentBuilder;
use gpui::{ use gpui::{
deferred, div, relative, uniform_list, App, AppContext, Context, Entity, EventEmitter, deferred, div, relative, uniform_list, App, AppContext, Context, Entity, EventEmitter,
@@ -17,7 +18,6 @@ use smallvec::{smallvec, SmallVec};
use state::{NostrRegistry, GIFTWRAP_SUBSCRIPTION}; use state::{NostrRegistry, GIFTWRAP_SUBSCRIPTION};
use theme::ActiveTheme; use theme::ActiveTheme;
use ui::button::{Button, ButtonVariants}; use ui::button::{Button, ButtonVariants};
use ui::dock_area::panel::{Panel, PanelEvent};
use ui::input::{InputEvent, InputState, TextInput}; use ui::input::{InputEvent, InputState, TextInput};
use ui::popup_menu::PopupMenuExt; use ui::popup_menu::PopupMenuExt;
use ui::{h_flex, v_flex, Icon, IconName, Selectable, Sizable, StyledExt, WindowExtension}; use ui::{h_flex, v_flex, Icon, IconName, Selectable, Sizable, StyledExt, WindowExtension};

View File

@@ -1,6 +1,7 @@
use std::time::Duration; use std::time::Duration;
use common::BUNKER_TIMEOUT; use common::BUNKER_TIMEOUT;
use dock::panel::{Panel, PanelEvent};
use gpui::prelude::FluentBuilder; use gpui::prelude::FluentBuilder;
use gpui::{ use gpui::{
div, relative, rems, svg, AnyElement, App, AppContext, Context, Entity, EventEmitter, div, relative, rems, svg, AnyElement, App, AppContext, Context, Entity, EventEmitter,
@@ -16,7 +17,6 @@ use state::NostrRegistry;
use theme::ActiveTheme; use theme::ActiveTheme;
use ui::avatar::Avatar; use ui::avatar::Avatar;
use ui::button::{Button, ButtonVariants}; use ui::button::{Button, ButtonVariants};
use ui::dock_area::panel::{Panel, PanelEvent};
use ui::indicator::Indicator; use ui::indicator::Indicator;
use ui::{h_flex, v_flex, Sizable, StyledExt, WindowExtension}; use ui::{h_flex, v_flex, Sizable, StyledExt, WindowExtension};

View File

@@ -1,10 +1,10 @@
use dock::panel::{Panel, PanelEvent};
use gpui::{ use gpui::{
div, svg, AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle, Focusable, div, svg, AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle, Focusable,
InteractiveElement, IntoElement, ParentElement, Render, SharedString, InteractiveElement, IntoElement, ParentElement, Render, SharedString,
StatefulInteractiveElement, Styled, Window, StatefulInteractiveElement, Styled, Window,
}; };
use theme::ActiveTheme; use theme::ActiveTheme;
use ui::dock_area::panel::{Panel, PanelEvent};
use ui::{h_flex, v_flex, StyledExt}; use ui::{h_flex, v_flex, StyledExt};
pub fn init(window: &mut Window, cx: &mut App) -> Entity<Welcome> { pub fn init(window: &mut Window, cx: &mut App) -> Entity<Welcome> {

View File

@@ -4,6 +4,8 @@ use auto_update::{AutoUpdateStatus, AutoUpdater};
use chat::{ChatEvent, ChatRegistry}; use chat::{ChatEvent, ChatRegistry};
use chat_ui::{CopyPublicKey, OpenPublicKey}; use chat_ui::{CopyPublicKey, OpenPublicKey};
use common::DEFAULT_SIDEBAR_WIDTH; use common::DEFAULT_SIDEBAR_WIDTH;
use dock::dock::DockPlacement;
use dock::{ClosePanel, DockArea, DockItem};
use gpui::prelude::FluentBuilder; use gpui::prelude::FluentBuilder;
use gpui::{ use gpui::{
deferred, div, px, relative, rems, App, AppContext, Axis, ClipboardItem, Context, Entity, deferred, div, px, relative, rems, App, AppContext, Axis, ClipboardItem, Context, Entity,
@@ -19,8 +21,6 @@ use theme::{ActiveTheme, Theme, ThemeMode, ThemeRegistry};
use title_bar::TitleBar; use title_bar::TitleBar;
use ui::avatar::Avatar; use ui::avatar::Avatar;
use ui::button::{Button, ButtonVariants}; use ui::button::{Button, ButtonVariants};
use ui::dock_area::dock::DockPlacement;
use ui::dock_area::{ClosePanel, DockArea, DockItem};
use ui::modal::ModalButtonProps; use ui::modal::ModalButtonProps;
use ui::popup_menu::PopupMenuExt; use ui::popup_menu::PopupMenuExt;
use ui::{h_flex, v_flex, IconName, Root, Sizable, WindowExtension}; use ui::{h_flex, v_flex, IconName, Root, Sizable, WindowExtension};
@@ -46,15 +46,12 @@ pub struct Workspace {
dock: Entity<DockArea>, dock: Entity<DockArea>,
/// Event subscriptions /// Event subscriptions
_subscriptions: SmallVec<[Subscription; 4]>, _subscriptions: SmallVec<[Subscription; 3]>,
} }
impl Workspace { impl Workspace {
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self { fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
let chat = ChatRegistry::global(cx); let chat = ChatRegistry::global(cx);
let nostr = NostrRegistry::global(cx);
let identity = nostr.read(cx).identity();
let title_bar = cx.new(|_| TitleBar::new()); let title_bar = cx.new(|_| TitleBar::new());
let dock = cx.new(|cx| DockArea::new(window, cx)); let dock = cx.new(|cx| DockArea::new(window, cx));
@@ -67,17 +64,6 @@ impl Workspace {
}), }),
); );
subscriptions.push(
// Observe the identity entity
cx.observe_in(&identity, window, move |this, state, window, cx| {
if state.read(cx).has_public_key() {
this.dock.update(cx, |this, cx| {
this.toggle_dock(DockPlacement::Left, window, cx);
});
};
}),
);
subscriptions.push( subscriptions.push(
// Observe all events emitted by the chat registry // Observe all events emitted by the chat registry
cx.subscribe_in(&chat, window, move |this, chat, ev, window, cx| { cx.subscribe_in(&chat, window, move |this, chat, ev, window, cx| {
@@ -158,7 +144,7 @@ impl Workspace {
// Update the dock layout // Update the dock layout
self.dock.update(cx, |this, cx| { self.dock.update(cx, |this, cx| {
this.set_left_dock(left, Some(px(DEFAULT_SIDEBAR_WIDTH)), false, window, cx); this.set_left_dock(left, Some(px(DEFAULT_SIDEBAR_WIDTH)), true, window, cx);
this.set_center(center, window, cx); this.set_center(center, window, cx);
}); });
} }
@@ -369,43 +355,50 @@ impl Workspace {
fn titlebar_left(&mut self, _window: &mut Window, cx: &Context<Self>) -> impl IntoElement { fn titlebar_left(&mut self, _window: &mut Window, cx: &Context<Self>) -> impl IntoElement {
let nostr = NostrRegistry::global(cx); let nostr = NostrRegistry::global(cx);
let chat = ChatRegistry::global(cx); let identity = nostr.read(cx).identity();
let status = chat.read(cx).loading();
if !nostr.read(cx).identity().read(cx).has_public_key() {
return div();
}
h_flex() h_flex()
.gap_2() .gap_2()
.h_6() .h_6()
.w_full() .w_full()
.child(compose_button()) .when_some(identity.read(cx).public_key, |this, public_key| {
.when(status, |this| { let persons = PersonRegistry::global(cx);
this.child(deferred( let profile = persons.read(cx).get(&public_key, cx);
h_flex()
.px_2() this.child(
.h_6() Button::new("user")
.gap_1() .small()
.text_xs() .reverse()
.rounded_full() .transparent()
.bg(cx.theme().surface_background) .icon(IconName::CaretDown)
.child(SharedString::from( .child(Avatar::new(profile.avatar()).size(rems(1.5)))
"Getting messages. This may take a while...", .popup_menu(move |this, _window, _cx| {
)), this.label(profile.name())
)) .menu_with_icon("Profile", IconName::Emoji, Box::new(ViewProfile))
.menu_with_icon(
"Messaging Relays",
IconName::Relay,
Box::new(ViewRelays),
)
.separator()
.menu_with_icon("Dark Mode", IconName::Sun, Box::new(DarkMode))
.menu_with_icon("Themes", IconName::Moon, Box::new(Themes))
.menu_with_icon("Settings", IconName::Settings, Box::new(Settings))
.menu_with_icon("Sign Out", IconName::Door, Box::new(Logout))
}),
)
}) })
.child(compose_button())
} }
fn titlebar_right(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement { fn titlebar_right(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let auto_update = AutoUpdater::global(cx); let chat = ChatRegistry::global(cx);
let status = chat.read(cx).loading();
let auto_update = AutoUpdater::global(cx);
let relay_auth = RelayAuth::global(cx); let relay_auth = RelayAuth::global(cx);
let pending_requests = relay_auth.read(cx).pending_requests(cx); let pending_requests = relay_auth.read(cx).pending_requests(cx);
let nostr = NostrRegistry::global(cx);
let identity = nostr.read(cx).identity();
h_flex() h_flex()
.gap_2() .gap_2()
.map(|this| match auto_update.read(cx).status.as_ref() { .map(|this| match auto_update.read(cx).status.as_ref() {
@@ -464,32 +457,19 @@ impl Workspace {
}), }),
) )
}) })
.when_some(identity.read(cx).public_key, |this, public_key| { .when(status, |this| {
let persons = PersonRegistry::global(cx); this.child(deferred(
let profile = persons.read(cx).get(&public_key, cx); h_flex()
.px_2()
this.child( .h_6()
Button::new("user") .gap_1()
.small() .text_xs()
.reverse() .rounded_full()
.transparent() .bg(cx.theme().surface_background)
.icon(IconName::CaretDown) .child(SharedString::from(
.child(Avatar::new(profile.avatar()).size(rems(1.45))) "Getting messages. This may take a while...",
.popup_menu(move |this, _window, _cx| { )),
this.label(profile.name()) ))
.menu_with_icon("Profile", IconName::Emoji, Box::new(ViewProfile))
.menu_with_icon(
"Messaging Relays",
IconName::Relay,
Box::new(ViewRelays),
)
.separator()
.menu_with_icon("Dark Mode", IconName::Sun, Box::new(DarkMode))
.menu_with_icon("Themes", IconName::Moon, Box::new(Themes))
.menu_with_icon("Settings", IconName::Settings, Box::new(Settings))
.menu_with_icon("Sign Out", IconName::Door, Box::new(Logout))
}),
)
}) })
} }
} }
@@ -498,13 +478,6 @@ impl Render for Workspace {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement { fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let modal_layer = Root::render_modal_layer(window, cx); let modal_layer = Root::render_modal_layer(window, cx);
let notification_layer = Root::render_notification_layer(window, cx); let notification_layer = Root::render_notification_layer(window, cx);
let left = self.titlebar_left(window, cx).into_any_element();
let right = self.titlebar_right(window, cx).into_any_element();
// Update title bar children
self.title_bar.update(cx, |this, _cx| {
this.set_children(vec![left, right]);
});
div() div()
.id(SharedString::from("workspace")) .id(SharedString::from("workspace"))
@@ -519,14 +492,8 @@ impl Render for Workspace {
.on_action(cx.listener(Self::on_keyring)) .on_action(cx.listener(Self::on_keyring))
.relative() .relative()
.size_full() .size_full()
.child( // Dock
v_flex() .child(self.dock.clone())
.size_full()
// Title Bar
.child(self.title_bar.clone())
// Dock
.child(self.dock.clone()),
)
// Notifications // Notifications
.children(notification_layer) .children(notification_layer)
// Modals // Modals

15
crates/dock/Cargo.toml Normal file
View File

@@ -0,0 +1,15 @@
[package]
name = "dock"
version.workspace = true
edition.workspace = true
publish.workspace = true
[dependencies]
common = { path = "../common" }
theme = { path = "../theme" }
ui = { path = "../ui" }
gpui.workspace = true
smallvec.workspace = true
anyhow.workspace = true
log.workspace = true

View File

@@ -6,27 +6,22 @@ use gpui::{
MouseMoveEvent, MouseUpEvent, ParentElement as _, Pixels, Point, Render, MouseMoveEvent, MouseUpEvent, ParentElement as _, Pixels, Point, Render,
StatefulInteractiveElement, Style, Styled as _, WeakEntity, Window, StatefulInteractiveElement, Style, Styled as _, WeakEntity, Window,
}; };
use serde::{Deserialize, Serialize};
use theme::ActiveTheme; use theme::ActiveTheme;
use ui::resizable::{HANDLE_PADDING, HANDLE_SIZE, PANEL_MIN_SIZE};
use ui::{AxisExt as _, StyledExt};
use super::{DockArea, DockItem}; use super::{DockArea, DockItem};
use crate::dock_area::panel::PanelView; use crate::panel::PanelView;
use crate::dock_area::tab_panel::TabPanel; use crate::tab_panel::TabPanel;
use crate::resizable::{HANDLE_PADDING, HANDLE_SIZE, PANEL_MIN_SIZE};
use crate::{AxisExt as _, StyledExt};
#[derive(Clone, Render)] #[derive(Clone, Render)]
struct ResizePanel; struct ResizePanel;
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DockPlacement { pub enum DockPlacement {
#[serde(rename = "center")]
Center, Center,
#[serde(rename = "left")]
Left, Left,
#[serde(rename = "bottom")]
Bottom, Bottom,
#[serde(rename = "right")]
Right, Right,
} }
@@ -58,14 +53,19 @@ impl DockPlacement {
pub struct Dock { pub struct Dock {
pub(super) placement: DockPlacement, pub(super) placement: DockPlacement,
dock_area: WeakEntity<DockArea>, dock_area: WeakEntity<DockArea>,
/// Dock layout
pub(crate) panel: DockItem, pub(crate) panel: DockItem,
/// The size is means the width or height of the Dock, if the placement is left or right, the size is width, otherwise the size is height. /// The size is means the width or height of the Dock, if the placement is left or right, the size is width, otherwise the size is height.
pub(super) size: Pixels, pub(super) size: Pixels,
/// Whether the Dock is open
pub(super) open: bool, pub(super) open: bool,
/// Whether the Dock is collapsible, default: true /// Whether the Dock is collapsible, default: true
pub(super) collapsible: bool, pub(super) collapsible: bool,
// Runtime state
/// Whether the Dock is resizing /// Whether the Dock is resizing
is_resizing: bool, is_resizing: bool,
} }

View File

@@ -7,25 +7,17 @@ use gpui::{
ParentElement as _, Pixels, Render, SharedString, Styled, Subscription, WeakEntity, Window, ParentElement as _, Pixels, Render, SharedString, Styled, Subscription, WeakEntity, Window,
}; };
use crate::dock_area::dock::{Dock, DockPlacement}; use crate::dock::{Dock, DockPlacement};
use crate::dock_area::panel::{Panel, PanelEvent, PanelStyle, PanelView}; use crate::panel::{Panel, PanelEvent, PanelStyle, PanelView};
use crate::dock_area::stack_panel::StackPanel; use crate::stack_panel::StackPanel;
use crate::dock_area::tab_panel::TabPanel; use crate::tab_panel::TabPanel;
pub mod dock; pub mod dock;
pub mod panel; pub mod panel;
pub mod stack_panel; pub mod stack_panel;
pub mod tab_panel; pub mod tab_panel;
actions!( actions!(dock, [ToggleZoom, ClosePanel]);
dock,
[
/// Zoom the current panel
ToggleZoom,
/// Close the current panel
ClosePanel
]
);
pub enum DockEvent { pub enum DockEvent {
/// The layout of the dock has changed, subscribers this to save the layout. /// The layout of the dock has changed, subscribers this to save the layout.

View File

@@ -2,9 +2,8 @@ use gpui::{
AnyElement, AnyView, App, Element, Entity, EventEmitter, FocusHandle, Focusable, Hsla, Render, AnyElement, AnyView, App, Element, Entity, EventEmitter, FocusHandle, Focusable, Hsla, Render,
SharedString, Window, SharedString, Window,
}; };
use ui::button::Button;
use crate::button::Button; use ui::popup_menu::PopupMenu;
use crate::popup_menu::PopupMenu;
pub enum PanelEvent { pub enum PanelEvent {
ZoomIn, ZoomIn,

View File

@@ -7,15 +7,15 @@ use gpui::{
Window, Window,
}; };
use smallvec::SmallVec; use smallvec::SmallVec;
use ui::resizable::{
use super::{DockArea, PanelEvent};
use crate::dock_area::panel::{Panel, PanelView};
use crate::dock_area::tab_panel::TabPanel;
use crate::resizable::{
h_resizable, resizable_panel, v_resizable, ResizablePanel, ResizablePanelEvent, h_resizable, resizable_panel, v_resizable, ResizablePanel, ResizablePanelEvent,
ResizablePanelGroup, ResizablePanelGroup,
}; };
use crate::{h_flex, AxisExt as _, Placement}; use ui::{h_flex, AxisExt as _, Placement};
use super::{DockArea, PanelEvent};
use crate::panel::{Panel, PanelView};
use crate::tab_panel::TabPanel;
pub struct StackPanel { pub struct StackPanel {
pub(super) parent: Option<WeakEntity<StackPanel>>, pub(super) parent: Option<WeakEntity<StackPanel>>,

View File

@@ -8,16 +8,15 @@ use gpui::{
StatefulInteractiveElement, Styled, WeakEntity, Window, StatefulInteractiveElement, Styled, WeakEntity, Window,
}; };
use theme::ActiveTheme; use theme::ActiveTheme;
use ui::button::{Button, ButtonVariants as _};
use ui::popup_menu::{PopupMenu, PopupMenuExt};
use ui::tab::tab_bar::TabBar;
use ui::tab::Tab;
use ui::{h_flex, v_flex, AxisExt, IconName, Placement, Selectable, Sizable, StyledExt};
use super::panel::PanelView; use crate::panel::{Panel, PanelView};
use super::stack_panel::StackPanel; use crate::stack_panel::StackPanel;
use super::{ClosePanel, DockArea, PanelEvent, PanelStyle, ToggleZoom}; use crate::{ClosePanel, DockArea, PanelEvent, PanelStyle, ToggleZoom};
use crate::button::{Button, ButtonVariants as _};
use crate::dock_area::panel::Panel;
use crate::popup_menu::{PopupMenu, PopupMenuExt};
use crate::tab::tab_bar::TabBar;
use crate::tab::Tab;
use crate::{h_flex, v_flex, AxisExt, IconName, Placement, Selectable, Sizable, StyledExt};
#[derive(Clone)] #[derive(Clone)]
struct TabState { struct TabState {
@@ -646,13 +645,9 @@ impl TabPanel {
.group("") .group("")
.overflow_hidden() .overflow_hidden()
.flex_1() .flex_1()
.p_1()
.child( .child(
div() div()
.size_full() .size_full()
.rounded(cx.theme().radius_lg)
.when(cx.theme().shadow, |this| this.shadow_sm())
.when(cx.theme().mode.is_dark(), |this| this.shadow_lg())
.bg(cx.theme().panel_background) .bg(cx.theme().panel_background)
.overflow_hidden() .overflow_hidden()
.child( .child(
@@ -667,7 +662,6 @@ impl TabPanel {
div() div()
.invisible() .invisible()
.absolute() .absolute()
.p_1()
.child( .child(
div() div()
.rounded(cx.theme().radius_lg) .rounded(cx.theme().radius_lg)

View File

@@ -653,6 +653,8 @@ impl NostrRegistry {
// Update the signer // Update the signer
self.set_signer(keys, false, cx); self.set_signer(keys, false, cx);
// TODO: set metadata
// Spawn a task to write the credentials // Spawn a task to write the credentials
cx.background_spawn(async move { cx.background_spawn(async move {
if let Err(e) = write_credential.await { if let Err(e) = write_credential.await {

View File

@@ -9,12 +9,9 @@ common = { path = "../common" }
theme = { path = "../theme" } theme = { path = "../theme" }
ui = { path = "../ui" } ui = { path = "../ui" }
nostr-sdk.workspace = true
gpui.workspace = true gpui.workspace = true
smol.workspace = true
smallvec.workspace = true smallvec.workspace = true
anyhow.workspace = true anyhow.workspace = true
log.workspace = true
[target.'cfg(target_os = "windows")'.dependencies] [target.'cfg(target_os = "windows")'.dependencies]
windows = { version = "0.61", features = ["Wdk_System_SystemServices"] } windows = { version = "0.61", features = ["Wdk_System_SystemServices"] }

View File

@@ -43,7 +43,7 @@ impl TitleBar {
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
pub fn height(window: &mut Window) -> Pixels { pub fn height(window: &mut Window) -> Pixels {
(1.75 * window.rem_size()).max(px(34.)) (1.75 * window.rem_size()).max(px(36.))
} }
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]

View File

@@ -5,7 +5,7 @@ use std::sync::OnceLock;
use gpui::prelude::FluentBuilder; use gpui::prelude::FluentBuilder;
use gpui::{ use gpui::{
svg, App, InteractiveElement, IntoElement, MouseButton, ParentElement, RenderOnce, svg, App, InteractiveElement, IntoElement, MouseButton, ParentElement, RenderOnce,
SharedString, StatefulInteractiveElement, Styled, Window, StatefulInteractiveElement, Styled, Window,
}; };
use linicon::{lookup_icon, IconType}; use linicon::{lookup_icon, IconType};
use theme::ActiveTheme; use theme::ActiveTheme;
@@ -70,15 +70,14 @@ impl RenderOnce for WindowControl {
.justify_center() .justify_center()
.items_center() .items_center()
.rounded_full() .rounded_full()
.size_6()
.map(|this| { .map(|this| {
if is_gnome { if is_gnome {
this.size_6() this.bg(cx.theme().tab_inactive_background)
.bg(cx.theme().tab_inactive_background)
.hover(|this| this.bg(cx.theme().tab_hover_background)) .hover(|this| this.bg(cx.theme().tab_hover_background))
.active(|this| this.bg(cx.theme().tab_active_background)) .active(|this| this.bg(cx.theme().tab_active_background))
} else { } else {
this.size_5() this.bg(cx.theme().ghost_element_background)
.bg(cx.theme().ghost_element_background)
.hover(|this| this.bg(cx.theme().ghost_element_hover)) .hover(|this| this.bg(cx.theme().ghost_element_hover))
.active(|this| this.bg(cx.theme().ghost_element_active)) .active(|this| this.bg(cx.theme().ghost_element_active))
} }
@@ -87,9 +86,7 @@ impl RenderOnce for WindowControl {
if let Some(Some(path)) = linux_controls().get(&self.kind).cloned() { if let Some(Some(path)) = linux_controls().get(&self.kind).cloned() {
this.child( this.child(
svg() svg()
.external_path(SharedString::from( .external_path(path.into_os_string().into_string().unwrap())
path.into_os_string().into_string().unwrap(),
))
.map(|this| { .map(|this| {
if cx.theme().is_dark() { if cx.theme().is_dark() {
this.text_color(gpui::white()) this.text_color(gpui::white())

View File

@@ -15,7 +15,6 @@ pub mod avatar;
pub mod button; pub mod button;
pub mod checkbox; pub mod checkbox;
pub mod divider; pub mod divider;
pub mod dock_area;
pub mod dropdown; pub mod dropdown;
pub mod history; pub mod history;
pub mod indicator; pub mod indicator;

View File

@@ -3,7 +3,7 @@ mod panel;
mod resize_handle; mod resize_handle;
pub use panel::*; pub use panel::*;
pub(crate) use resize_handle::*; pub use resize_handle::*;
pub fn h_resizable( pub fn h_resizable(
window: &mut Window, window: &mut Window,

View File

@@ -11,7 +11,7 @@ use gpui::{
use super::resize_handle; use super::resize_handle;
use crate::{h_flex, v_flex, AxisExt}; use crate::{h_flex, v_flex, AxisExt};
pub(crate) const PANEL_MIN_SIZE: Pixels = px(100.); pub const PANEL_MIN_SIZE: Pixels = px(100.);
pub enum ResizablePanelEvent { pub enum ResizablePanelEvent {
Resized, Resized,
@@ -53,7 +53,7 @@ impl ResizablePanelGroup {
self self
} }
pub(crate) fn set_axis(&mut self, axis: Axis, _window: &mut Window, cx: &mut Context<Self>) { pub fn set_axis(&mut self, axis: Axis, _window: &mut Window, cx: &mut Context<Self>) {
self.axis = axis; self.axis = axis;
cx.notify(); cx.notify();
} }
@@ -130,7 +130,7 @@ impl ResizablePanelGroup {
} }
/// Replace a child panel with a new panel at the given index. /// Replace a child panel with a new panel at the given index.
pub(crate) fn replace_child( pub fn replace_child(
&mut self, &mut self,
panel: ResizablePanel, panel: ResizablePanel,
ix: usize, ix: usize,
@@ -158,7 +158,7 @@ impl ResizablePanelGroup {
cx.notify() cx.notify()
} }
pub(crate) fn remove_all_children(&mut self, _window: &mut Window, cx: &mut Context<Self>) { pub fn remove_all_children(&mut self, _window: &mut Window, cx: &mut Context<Self>) {
self.sizes.clear(); self.sizes.clear();
self.panels.clear(); self.panels.clear();
cx.notify() cx.notify()
@@ -349,7 +349,7 @@ impl ResizablePanel {
self self
} }
pub(crate) fn content_visible<F>(mut self, content_visible: F) -> Self pub fn content_visible<F>(mut self, content_visible: F) -> Self
where where
F: Fn(&App) -> bool + 'static, F: Fn(&App) -> bool + 'static,
{ {

View File

@@ -7,11 +7,11 @@ use theme::ActiveTheme;
use crate::AxisExt as _; use crate::AxisExt as _;
pub(crate) const HANDLE_PADDING: Pixels = px(8.); pub const HANDLE_PADDING: Pixels = px(8.);
pub(crate) const HANDLE_SIZE: Pixels = px(2.); pub const HANDLE_SIZE: Pixels = px(2.);
#[derive(IntoElement)] #[derive(IntoElement)]
pub(crate) struct ResizeHandle { pub struct ResizeHandle {
base: Stateful<Div>, base: Stateful<Div>,
axis: Axis, axis: Axis,
} }
@@ -26,7 +26,7 @@ impl ResizeHandle {
} }
/// Create a resize handle for a resizable panel. /// Create a resize handle for a resizable panel.
pub(crate) fn resize_handle(id: impl Into<ElementId>, axis: Axis) -> ResizeHandle { pub fn resize_handle(id: impl Into<ElementId>, axis: Axis) -> ResizeHandle {
ResizeHandle::new(id, axis) ResizeHandle::new(id, axis)
} }