feat: dashboard skeleton
This commit is contained in:
43
src/screen/dashboard/mod.rs
Normal file
43
src/screen/dashboard/mod.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
mod screen;
|
||||
mod titlebar;
|
||||
|
||||
use gpui::{AppContext, BorrowAppContext, point, px, size};
|
||||
pub(crate) use screen::new;
|
||||
|
||||
use crate::{app, screen::dashboard::screen::Screen};
|
||||
|
||||
pub fn open_window(screen: Screen, cx: &mut gpui::App) -> anyhow::Result<()> {
|
||||
let (top_left, window_bounds) = cx.read_global::<app::Global, _>(|global, cx| {
|
||||
(
|
||||
global.safe_area.origin,
|
||||
gpui::Bounds::centered(None, size(px(800.), px(600.0)), cx),
|
||||
)
|
||||
});
|
||||
|
||||
cx.open_window(
|
||||
gpui::WindowOptions {
|
||||
window_bounds: Some(gpui::WindowBounds::Windowed(window_bounds)),
|
||||
titlebar: Some(gpui::TitlebarOptions {
|
||||
appears_transparent: true,
|
||||
traffic_light_position: Some(top_left + point(px(12.), px(12.))),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
|window, cx| {
|
||||
cx.new(|cx| {
|
||||
cx.observe_window_appearance(window, |_, window, cx| {
|
||||
cx.update_global::<app::Global, ()>(|global, cx| {
|
||||
global.current_theme = global
|
||||
.theme_family
|
||||
.theme_for_appearance(window.appearance());
|
||||
cx.notify();
|
||||
});
|
||||
})
|
||||
.detach();
|
||||
screen
|
||||
})
|
||||
},
|
||||
)
|
||||
.map(|_| ())
|
||||
}
|
||||
41
src/screen/dashboard/screen.rs
Normal file
41
src/screen/dashboard/screen.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
use gpui::{AppContext, ParentElement, Styled, div};
|
||||
|
||||
use crate::{app, screen::dashboard::titlebar};
|
||||
|
||||
pub(crate) struct Screen {
|
||||
titlebar: gpui::Entity<titlebar::TitleBar>,
|
||||
}
|
||||
|
||||
pub(crate) fn new(cx: &mut gpui::App) -> Screen {
|
||||
Screen {
|
||||
titlebar: cx.new(|cx| titlebar::new(cx)),
|
||||
}
|
||||
}
|
||||
|
||||
impl gpui::Render for Screen {
|
||||
fn render(
|
||||
&mut self,
|
||||
_window: &mut gpui::Window,
|
||||
cx: &mut gpui::Context<Self>,
|
||||
) -> impl gpui::IntoElement {
|
||||
let theme = app::current_theme(cx);
|
||||
div()
|
||||
.flex()
|
||||
.flex_col()
|
||||
.bg(theme.colors.background)
|
||||
.size_full()
|
||||
.child(self.titlebar.clone())
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
.flex_row()
|
||||
.flex_1()
|
||||
.w_full()
|
||||
.gap_2()
|
||||
.px_3()
|
||||
.pb_3()
|
||||
.child(div().w_1_4().h_full().rounded_lg().bg(theme.colors.surface))
|
||||
.child(div().w_3_4().h_full().rounded_lg().bg(theme.colors.surface)),
|
||||
)
|
||||
}
|
||||
}
|
||||
80
src/screen/dashboard/titlebar.rs
Normal file
80
src/screen/dashboard/titlebar.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
use gpui::{ParentElement, Styled, TitlebarOptions, div};
|
||||
|
||||
use crate::component::button::button;
|
||||
use crate::query::{self, QueryStatus, read_query, use_query};
|
||||
use crate::{
|
||||
api, app,
|
||||
component::{
|
||||
font_icon::{FontIcon, font_icon},
|
||||
text::text,
|
||||
},
|
||||
};
|
||||
|
||||
pub struct TitleBar {
|
||||
fetch_user_query: query::Entity<api::user::Fetch>,
|
||||
}
|
||||
|
||||
pub struct RepoSelector {}
|
||||
|
||||
pub fn new(cx: &mut gpui::Context<TitleBar>) -> TitleBar {
|
||||
TitleBar {
|
||||
fetch_user_query: use_query(api::user::Fetch, cx),
|
||||
}
|
||||
}
|
||||
|
||||
impl gpui::Render for TitleBar {
|
||||
fn render(
|
||||
&mut self,
|
||||
_window: &mut gpui::Window,
|
||||
cx: &mut gpui::Context<Self>,
|
||||
) -> impl gpui::IntoElement {
|
||||
let g = cx.global::<app::Global>();
|
||||
let user = read_query(&self.fetch_user_query, cx);
|
||||
|
||||
let user_avatar = match user {
|
||||
QueryStatus::Err(api::Error::Unauthenticated) => div().absolute().right_2p5().child(
|
||||
button("login-btn")
|
||||
.leading(font_icon(FontIcon::Github))
|
||||
.label("Login"),
|
||||
),
|
||||
|
||||
_ => div(),
|
||||
};
|
||||
|
||||
div()
|
||||
.flex_row()
|
||||
.justify_center()
|
||||
.items_center()
|
||||
.w_full()
|
||||
.h_10()
|
||||
.flex()
|
||||
.px(g.safe_area.size.width)
|
||||
.py_2()
|
||||
.bg(g.current_theme.colors.background)
|
||||
.text_color(g.current_theme.colors.text)
|
||||
.relative()
|
||||
.child(repo_selector(cx))
|
||||
.child(user_avatar)
|
||||
}
|
||||
}
|
||||
|
||||
impl RepoSelector {
|
||||
pub fn new(cx: &mut gpui::Context<Self>) -> Self {
|
||||
use_query(api::repo::List, cx);
|
||||
use_query(api::user::Fetch, cx);
|
||||
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
fn repo_selector<T: 'static>(_cx: &gpui::Context<T>) -> gpui::Div {
|
||||
div()
|
||||
.flex()
|
||||
.flex_row()
|
||||
.items_center()
|
||||
.gap_1()
|
||||
.text_xs()
|
||||
.child(font_icon(FontIcon::FolderGit).size_3())
|
||||
.child(text("test/repo"))
|
||||
.child(font_icon(FontIcon::ChevronDown).size_3())
|
||||
}
|
||||
Reference in New Issue
Block a user