add workspace

This commit is contained in:
2026-08-05 11:07:12 +07:00
parent 8de6018e28
commit 6b13d8a8f7
5 changed files with 162 additions and 44 deletions
+59 -41
View File
@@ -1,13 +1,14 @@
use gpui::prelude::*;
use gpui::{AnyView, Context, Render, SharedString, Subscription, Window, div, px};
use gpui_component::{ActiveTheme, StyledExt};
use gpui::{Context, Entity, Render, SharedString, Subscription, Window, div, px};
use gpui_component::dock::{DockArea, DockItem};
use gpui_component::{ActiveTheme, Root, StyledExt, TitleBar, v_flex};
use signed_state::{Backend, BackendEvent};
use crate::views::RepoListView;
use crate::views::SidebarPanel;
/// Root view of the app: header, active screen, status bar.
/// Root view of the app: title bar, dock area, status bar.
pub struct Workspace {
active_screen: AnyView,
dock: Entity<DockArea>,
status: SharedString,
_subscription: Subscription,
}
@@ -15,11 +16,34 @@ pub struct Workspace {
impl Workspace {
pub fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
let backend = Backend::global(cx);
let repo_list = cx.new(|cx| RepoListView::new(window, cx));
let dock = cx.new(|cx| DockArea::new("dock", Some(1), window, cx));
let weak_dock = dock.downgrade();
let sidebar = cx.new(|cx| SidebarPanel::new(weak_dock.clone(), cx));
dock.update(cx, |dock_area, cx| {
dock_area.set_left_dock(
DockItem::tab(sidebar.clone(), &weak_dock, window, cx),
Some(px(240.)),
true,
window,
cx,
);
});
sidebar.update(cx, |sidebar, cx| sidebar.open_explore(window, cx));
let connected = backend.read(cx).is_connected();
let sync_progress = backend.read(cx).sync_progress();
let status = if let Some((total, current)) = sync_progress {
format!("Syncing repositories... {current}/{total}").into()
} else if connected {
"Connected".into()
} else {
"Connecting...".into()
};
let subscription = cx.subscribe(&backend, |this, _backend, event, cx| {
match event {
BackendEvent::Connected => this.status = "Connected".into(),
@@ -34,54 +58,48 @@ impl Workspace {
});
Self {
active_screen: repo_list.into(),
status: if let Some((total, current)) = sync_progress {
format!("Syncing repositories... {current}/{total}").into()
} else if connected {
"Connected".into()
} else {
"Connecting...".into()
},
dock,
status,
_subscription: subscription,
}
}
}
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 dialog_layer = Root::render_dialog_layer(window, cx);
let notification_layer = Root::render_notification_layer(window, cx);
div()
.id("workspace")
.v_flex()
.size_full()
.bg(cx.theme().background)
.text_color(cx.theme().foreground)
.child(
div()
.h_flex()
.px_4()
.py_2()
.border_b(px(1.))
.border_color(cx.theme().border)
.child(div().text_lg().font_semibold().child("Signed")),
)
.child(
div()
.flex_1()
.overflow_hidden()
.child(self.active_screen.clone()),
)
.child(
div()
.h_flex()
.px_4()
.py_1()
.border_t(px(1.))
.border_color(cx.theme().border)
v_flex()
.size_full()
// Title Bar
.child(TitleBar::new())
// Dock Area
.child(self.dock.clone())
// Status Bar
.child(
div()
.text_xs()
.text_color(cx.theme().muted_foreground)
.child(self.status.clone()),
.h_flex()
.px_4()
.py_1()
.border_t(px(1.))
.border_color(cx.theme().border)
.child(
div()
.text_xs()
.text_color(cx.theme().muted_foreground)
.child(self.status.clone()),
),
),
)
// Notifications
.children(notification_layer)
// Modals
.children(dialog_layer)
}
}