wip: refactor
This commit is contained in:
143
crates/app/src/views/app.rs
Normal file
143
crates/app/src/views/app.rs
Normal file
@@ -0,0 +1,143 @@
|
||||
use components::{
|
||||
dock::{DockArea, DockItem, DockPlacement, PanelStyle},
|
||||
theme::{ActiveTheme, Theme},
|
||||
Root, TitleBar,
|
||||
};
|
||||
use coop_ui::block::BlockContainer;
|
||||
use gpui::*;
|
||||
use nostr_sdk::prelude::*;
|
||||
use serde::Deserialize;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::{
|
||||
dock::{left_dock::LeftDock, welcome::WelcomeBlock},
|
||||
onboarding::Onboarding,
|
||||
};
|
||||
use crate::states::account::AccountState;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Deserialize)]
|
||||
pub struct AddPanel {
|
||||
pub title: Option<String>,
|
||||
pub receiver: PublicKey,
|
||||
}
|
||||
|
||||
impl_actions!(dock, [AddPanel]);
|
||||
|
||||
pub struct DockAreaTab {
|
||||
id: &'static str,
|
||||
version: usize,
|
||||
}
|
||||
|
||||
pub const DOCK_AREA: DockAreaTab = DockAreaTab {
|
||||
id: "dock",
|
||||
version: 1,
|
||||
};
|
||||
|
||||
pub struct AppView {
|
||||
onboarding: View<Onboarding>,
|
||||
dock: View<DockArea>,
|
||||
}
|
||||
|
||||
impl AppView {
|
||||
pub fn new(cx: &mut ViewContext<'_, Self>) -> AppView {
|
||||
// Sync theme with system
|
||||
cx.observe_window_appearance(|_, cx| {
|
||||
Theme::sync_system_appearance(cx);
|
||||
})
|
||||
.detach();
|
||||
|
||||
// Onboarding
|
||||
let onboarding = cx.new_view(Onboarding::new);
|
||||
|
||||
// Dock
|
||||
let dock = cx.new_view(|cx| {
|
||||
DockArea::new(DOCK_AREA.id, Some(DOCK_AREA.version), cx).panel_style(PanelStyle::TabBar)
|
||||
});
|
||||
|
||||
cx.observe_global::<AccountState>(|view, cx| {
|
||||
// TODO: save dock state and load previous state on startup
|
||||
if cx.global::<AccountState>().in_use.is_some() {
|
||||
Self::init_layout(view.dock.downgrade(), cx);
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
|
||||
AppView { onboarding, dock }
|
||||
}
|
||||
|
||||
fn init_layout(dock_area: WeakView<DockArea>, cx: &mut WindowContext) {
|
||||
let left = DockItem::panel(Arc::new(BlockContainer::panel::<LeftDock>(cx)));
|
||||
let center = Self::init_dock_items(&dock_area, cx);
|
||||
|
||||
_ = dock_area.update(cx, |view, cx| {
|
||||
view.set_version(DOCK_AREA.version, cx);
|
||||
view.set_left_dock(left, Some(px(260.)), true, cx);
|
||||
view.set_center(center, cx);
|
||||
view.set_dock_collapsible(
|
||||
Edges {
|
||||
left: false,
|
||||
..Default::default()
|
||||
},
|
||||
cx,
|
||||
);
|
||||
// TODO: support right dock?
|
||||
// TODO: support bottom dock?
|
||||
});
|
||||
}
|
||||
|
||||
fn init_dock_items(dock_area: &WeakView<DockArea>, cx: &mut WindowContext) -> DockItem {
|
||||
DockItem::split_with_sizes(
|
||||
Axis::Vertical,
|
||||
vec![DockItem::tabs(
|
||||
vec![
|
||||
Arc::new(BlockContainer::panel::<WelcomeBlock>(cx)),
|
||||
// TODO: add chat block
|
||||
],
|
||||
None,
|
||||
dock_area,
|
||||
cx,
|
||||
)],
|
||||
vec![None],
|
||||
dock_area,
|
||||
cx,
|
||||
)
|
||||
}
|
||||
|
||||
fn on_action_add_panel(&mut self, _action: &AddPanel, cx: &mut ViewContext<Self>) {
|
||||
// TODO: add chat panel
|
||||
let panel = Arc::new(BlockContainer::panel::<WelcomeBlock>(cx));
|
||||
|
||||
self.dock.update(cx, |dock_area, cx| {
|
||||
dock_area.add_panel(panel, DockPlacement::Center, cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for AppView {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
let modal_layer = Root::render_modal_layer(cx);
|
||||
let notification_layer = Root::render_notification_layer(cx);
|
||||
|
||||
let mut content = div();
|
||||
|
||||
if cx.global::<AccountState>().in_use.is_none() {
|
||||
content = content.size_full().child(self.onboarding.clone())
|
||||
} else {
|
||||
content = content
|
||||
.on_action(cx.listener(Self::on_action_add_panel))
|
||||
.size_full()
|
||||
.flex()
|
||||
.flex_col()
|
||||
.child(TitleBar::new())
|
||||
.child(self.dock.clone())
|
||||
}
|
||||
|
||||
div()
|
||||
.bg(cx.theme().background)
|
||||
.text_color(cx.theme().foreground)
|
||||
.size_full()
|
||||
.child(content)
|
||||
.child(div().absolute().top_8().children(notification_layer))
|
||||
.children(modal_layer)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user