move dock to seperated crate
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m24s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m16s
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m24s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m16s
This commit is contained in:
18
Cargo.lock
generated
18
Cargo.lock
generated
@@ -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",
|
||||||
|
|||||||
@@ -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" }
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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" }
|
||||||
|
|||||||
@@ -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};
|
||||||
|
|||||||
@@ -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};
|
||||||
|
|||||||
@@ -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};
|
||||||
|
|||||||
@@ -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};
|
||||||
|
|
||||||
|
|||||||
@@ -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> {
|
||||||
|
|||||||
@@ -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
15
crates/dock/Cargo.toml
Normal 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
|
||||||
@@ -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,
|
||||||
}
|
}
|
||||||
@@ -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.
|
||||||
@@ -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,
|
||||||
@@ -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>>,
|
||||||
@@ -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)
|
||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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"] }
|
||||||
|
|||||||
@@ -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")]
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user