refactor: redesign theme tokens and split catppuccin themes
This commit is contained in:
@@ -9,7 +9,7 @@ use crate::{
|
||||
api::{self},
|
||||
app,
|
||||
component::{
|
||||
font_icon::{FontIcon, font_icon},
|
||||
font_icon::{FontIcon, FontIconSvg, font_icon},
|
||||
text::text,
|
||||
},
|
||||
query::{self, QueryStatus, read_query, use_query},
|
||||
@@ -134,6 +134,19 @@ impl gpui::RenderOnce for IssueListItem {
|
||||
fn render(self, _window: &mut gpui::Window, cx: &mut gpui::App) -> impl IntoElement {
|
||||
let theme = app::current_theme(cx);
|
||||
|
||||
fn pill(label: impl gpui::IntoElement + gpui::Styled, icon: FontIconSvg) -> gpui::Div {
|
||||
div()
|
||||
.flex()
|
||||
.flex_row()
|
||||
.items_center()
|
||||
.justify_start()
|
||||
.rounded_full()
|
||||
.px_2()
|
||||
.gap_1()
|
||||
.child(icon.size_3())
|
||||
.child(label.text_xs())
|
||||
}
|
||||
|
||||
let repo_name_text = match self.repo_name {
|
||||
| Some(name) => text(name),
|
||||
| None => text("Unknown repo"),
|
||||
@@ -141,39 +154,43 @@ impl gpui::RenderOnce for IssueListItem {
|
||||
.text_xs()
|
||||
.opacity(0.5);
|
||||
|
||||
let icon = if self.is_draft {
|
||||
font_icon(FontIcon::PullRequestDraft)
|
||||
.text_color(theme.colors.text)
|
||||
.opacity(0.5)
|
||||
let status_pill = if self.is_draft {
|
||||
pill(
|
||||
text("Draft").text_color(theme.colors.text),
|
||||
font_icon(FontIcon::PullRequestDraft).text_color(theme.colors.text),
|
||||
)
|
||||
.bg(theme.colors.surface)
|
||||
} else {
|
||||
match self.status {
|
||||
| api::issues::PullRequestState::Closed => {
|
||||
font_icon(FontIcon::PullRequestClosed).text_color(theme.colors.danger)
|
||||
| api::issues::PullRequestState::Closed => pill(
|
||||
text("Closed").text_color(theme.colors.danger_on_solid),
|
||||
font_icon(FontIcon::PullRequestClosed).text_color(theme.colors.danger_on_solid),
|
||||
)
|
||||
.bg(theme.colors.danger_solid),
|
||||
| api::issues::PullRequestState::Merged => pill(
|
||||
text("Merged").text_color(theme.colors.accent_on_solid),
|
||||
font_icon(FontIcon::PullRequestClosed).text_color(theme.colors.accent_on_solid),
|
||||
)
|
||||
.bg(theme.colors.accent_solid),
|
||||
| _ => pill(
|
||||
text("Open").text_color(theme.colors.success_on_solid),
|
||||
font_icon(FontIcon::PullRequestArrow).text_color(theme.colors.success_on_solid),
|
||||
)
|
||||
.bg(theme.colors.success_solid),
|
||||
}
|
||||
| api::issues::PullRequestState::Merged => {
|
||||
font_icon(FontIcon::PullRequestClosed).text_color(theme.colors.success)
|
||||
}
|
||||
| _ => font_icon(FontIcon::PullRequestArrow).text_color(theme.colors.success),
|
||||
}
|
||||
}
|
||||
.flex_shrink_0()
|
||||
.size_4();
|
||||
|
||||
let description_text = match self.description {
|
||||
| Some(description) => text(description).text_xs(),
|
||||
| None => text("No description provided").opacity(0.5).text_xs(),
|
||||
};
|
||||
|
||||
let pills_row = div().flex().flex_row().gap_1().my_1().child(status_pill);
|
||||
|
||||
div()
|
||||
.relative()
|
||||
.w_full()
|
||||
.px_1p5()
|
||||
.px_3()
|
||||
.py_1()
|
||||
.gap_2()
|
||||
.flex()
|
||||
.flex_row()
|
||||
.items_center()
|
||||
.child(icon)
|
||||
.child(
|
||||
div()
|
||||
.flex_1()
|
||||
@@ -191,33 +208,30 @@ impl gpui::RenderOnce for IssueListItem {
|
||||
.min_w_0()
|
||||
.line_clamp(2),
|
||||
)
|
||||
.child(description_text),
|
||||
.child(pills_row),
|
||||
)
|
||||
.when(!self.is_last, |it| {
|
||||
it.border_b_1().border_color(theme.colors.border)
|
||||
})
|
||||
.when(self.is_selected, |it| {
|
||||
it.bg(gpui::Rgba {
|
||||
a: 0.05,
|
||||
..theme.colors.accent
|
||||
})
|
||||
.overflow_hidden()
|
||||
.border_r_1()
|
||||
.child(
|
||||
div()
|
||||
.absolute()
|
||||
.right_0()
|
||||
.top_0()
|
||||
.bottom_0()
|
||||
.w_px()
|
||||
.bg(theme.colors.accent)
|
||||
.shadow(vec![gpui::BoxShadow {
|
||||
blur_radius: px(16.),
|
||||
spread_radius: px(2.),
|
||||
color: gpui::Hsla::from(theme.colors.accent).alpha(0.8),
|
||||
offset: point(px(-2.), px(0.)),
|
||||
}]),
|
||||
)
|
||||
it.bg(theme.colors.selection_bg)
|
||||
.overflow_hidden()
|
||||
.border_r_1()
|
||||
.child(
|
||||
div()
|
||||
.absolute()
|
||||
.right_0()
|
||||
.top_0()
|
||||
.bottom_0()
|
||||
.w_px()
|
||||
.bg(theme.colors.selection_border)
|
||||
.shadow(vec![gpui::BoxShadow {
|
||||
blur_radius: px(16.),
|
||||
spread_radius: px(2.),
|
||||
color: gpui::Hsla::from(theme.colors.selection_border).alpha(0.8),
|
||||
offset: point(px(-2.), px(0.)),
|
||||
}]),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use gpui::{
|
||||
AppContext, InteractiveElement, IntoElement, ParentElement, StatefulInteractiveElement, Styled,
|
||||
div, img, point, prelude::FluentBuilder, px,
|
||||
div, img, prelude::FluentBuilder,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -24,7 +24,7 @@ pub(crate) struct PullRequestView {
|
||||
#[derive(gpui::IntoElement)]
|
||||
struct Toolbar {}
|
||||
|
||||
pub fn new(cx: &mut gpui::Context<PullRequestView>) -> PullRequestView {
|
||||
pub fn new(_cx: &mut gpui::Context<PullRequestView>) -> PullRequestView {
|
||||
PullRequestView {
|
||||
markdown_viewer: None,
|
||||
pull_request_query: None,
|
||||
@@ -89,37 +89,41 @@ impl PullRequestView {
|
||||
.rounded_full();
|
||||
|
||||
match pr.state {
|
||||
| api::issues::PullRequestState::Open => {
|
||||
status_pill = status_pill
|
||||
.bg(theme.colors.success)
|
||||
.child(
|
||||
font_icon(FontIcon::PullRequestArrow)
|
||||
.size_3()
|
||||
.text_color(theme.colors.accent_text),
|
||||
)
|
||||
.child(text("Open").text_color(theme.colors.accent_text).text_xs());
|
||||
}
|
||||
| api::issues::PullRequestState::Closed => {
|
||||
status_pill = status_pill
|
||||
.bg(theme.colors.danger)
|
||||
.child(
|
||||
font_icon(FontIcon::PullRequestClosed)
|
||||
.size_3()
|
||||
.text_color(theme.colors.accent_text),
|
||||
)
|
||||
.child(
|
||||
text("Closed")
|
||||
.text_color(theme.colors.accent_text)
|
||||
| api::issues::PullRequestState::Open => {
|
||||
status_pill = status_pill
|
||||
.bg(theme.colors.success_solid)
|
||||
.child(
|
||||
font_icon(FontIcon::PullRequestArrow)
|
||||
.size_3()
|
||||
.text_color(theme.colors.success_on_solid),
|
||||
)
|
||||
.child(
|
||||
text("Open")
|
||||
.text_color(theme.colors.success_on_solid)
|
||||
.text_xs(),
|
||||
);
|
||||
}
|
||||
| api::issues::PullRequestState::Closed => {
|
||||
status_pill = status_pill
|
||||
.bg(theme.colors.danger_solid)
|
||||
.child(
|
||||
font_icon(FontIcon::PullRequestClosed)
|
||||
.size_3()
|
||||
.text_color(theme.colors.danger_on_solid),
|
||||
)
|
||||
.child(
|
||||
text("Closed")
|
||||
.text_color(theme.colors.danger_on_solid)
|
||||
.text_xs(),
|
||||
);
|
||||
}
|
||||
| api::issues::PullRequestState::Merged => {
|
||||
status_pill = status_pill.bg(theme.colors.accent_solid).child(
|
||||
text("Merged")
|
||||
.text_color(theme.colors.accent_on_solid)
|
||||
.text_xs(),
|
||||
);
|
||||
}
|
||||
| api::issues::PullRequestState::Merged => {
|
||||
status_pill = status_pill.bg(theme.colors.accent).child(
|
||||
text("Merged")
|
||||
.text_color(theme.colors.accent_text)
|
||||
.text_xs(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let merge_text = match (
|
||||
@@ -127,48 +131,48 @@ impl PullRequestView {
|
||||
pr.base_branch_name.as_ref(),
|
||||
pr.head_branch_name.as_ref(),
|
||||
) {
|
||||
| (Some(author), Some(base_branch), Some(head_branch)) => {
|
||||
let str = format!(
|
||||
"{} requested to merge {} into {}",
|
||||
author.login, head_branch, base_branch
|
||||
);
|
||||
| (Some(author), Some(base_branch), Some(head_branch)) => {
|
||||
let str = format!(
|
||||
"{} requested to merge {} into {}",
|
||||
author.login, head_branch, base_branch
|
||||
);
|
||||
|
||||
let head_branch_text_offset = author.login.len() + 20;
|
||||
let base_branch_text_offset = head_branch_text_offset + head_branch.len() + 6;
|
||||
let head_branch_text_offset = author.login.len() + 20;
|
||||
let base_branch_text_offset = head_branch_text_offset + head_branch.len() + 6;
|
||||
|
||||
let highlights = [
|
||||
(
|
||||
0..author.login.len(),
|
||||
gpui::HighlightStyle {
|
||||
font_weight: Some(gpui::FontWeight::BOLD),
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
(
|
||||
head_branch_text_offset..head_branch_text_offset + head_branch.len(),
|
||||
gpui::HighlightStyle {
|
||||
font_weight: Some(gpui::FontWeight::BOLD),
|
||||
color: Some(theme.colors.accent.into()),
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
(
|
||||
base_branch_text_offset..base_branch_text_offset + base_branch.len(),
|
||||
gpui::HighlightStyle {
|
||||
font_weight: Some(gpui::FontWeight::BOLD),
|
||||
color: Some(theme.colors.accent.into()),
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
];
|
||||
let highlights = [
|
||||
(
|
||||
0..author.login.len(),
|
||||
gpui::HighlightStyle {
|
||||
font_weight: Some(gpui::FontWeight::BOLD),
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
(
|
||||
head_branch_text_offset..head_branch_text_offset + head_branch.len(),
|
||||
gpui::HighlightStyle {
|
||||
font_weight: Some(gpui::FontWeight::BOLD),
|
||||
color: Some(theme.colors.accent_fg.into()),
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
(
|
||||
base_branch_text_offset..base_branch_text_offset + base_branch.len(),
|
||||
gpui::HighlightStyle {
|
||||
font_weight: Some(gpui::FontWeight::BOLD),
|
||||
color: Some(theme.colors.accent_fg.into()),
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
];
|
||||
|
||||
Some((
|
||||
author,
|
||||
gpui::StyledText::new(str).with_highlights(highlights),
|
||||
))
|
||||
}
|
||||
Some((
|
||||
author,
|
||||
gpui::StyledText::new(str).with_highlights(highlights),
|
||||
))
|
||||
}
|
||||
|
||||
| _ => None,
|
||||
| _ => None,
|
||||
};
|
||||
|
||||
let metadata_line =
|
||||
@@ -257,24 +261,24 @@ impl gpui::Render for PullRequestView {
|
||||
cx: &mut gpui::Context<Self>,
|
||||
) -> impl gpui::IntoElement {
|
||||
div().size_full().child(match &self.pull_request_query {
|
||||
| Some(q) => match read_query(q, cx) {
|
||||
| QueryStatus::Loaded(pr) => self.pr_content(pr, cx),
|
||||
| QueryStatus::Err(e) => div()
|
||||
.size_full()
|
||||
.child(format!("{:?}", e))
|
||||
.into_any_element(),
|
||||
| QueryStatus::Loading => div()
|
||||
.size_full()
|
||||
.child("loading pr content")
|
||||
.into_any_element(),
|
||||
},
|
||||
| None => div().size_full().child("no pr selected").into_any_element(),
|
||||
| Some(q) => match read_query(q, cx) {
|
||||
| QueryStatus::Loaded(pr) => self.pr_content(pr, cx),
|
||||
| QueryStatus::Err(e) => div()
|
||||
.size_full()
|
||||
.child(format!("{:?}", e))
|
||||
.into_any_element(),
|
||||
| QueryStatus::Loading => div()
|
||||
.size_full()
|
||||
.child("loading pr content")
|
||||
.into_any_element(),
|
||||
},
|
||||
| None => div().size_full().child("no pr selected").into_any_element(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl gpui::RenderOnce for Toolbar {
|
||||
fn render(self, window: &mut gpui::Window, cx: &mut gpui::App) -> impl IntoElement {
|
||||
fn render(self, _window: &mut gpui::Window, cx: &mut gpui::App) -> impl IntoElement {
|
||||
fn toolbar_button(id: impl Into<gpui::ElementId>) -> Button {
|
||||
button(id)
|
||||
.px_2p5()
|
||||
|
||||
@@ -5,7 +5,6 @@ use crate::{
|
||||
screen::dashboard::{
|
||||
issue_list::{self, IssueList},
|
||||
pull_request_view::{self, PullRequestView},
|
||||
sidebar::{self, Sidebar, SidebarItemValue},
|
||||
titlebar::{self, TitleBar},
|
||||
},
|
||||
};
|
||||
@@ -13,7 +12,6 @@ use crate::{
|
||||
pub(crate) struct Screen {
|
||||
titlebar: gpui::Entity<TitleBar>,
|
||||
issue_list: gpui::Entity<IssueList>,
|
||||
sidebar: gpui::Entity<Sidebar>,
|
||||
pull_request_view: gpui::Entity<PullRequestView>,
|
||||
|
||||
issue_filter: Option<&'static str>,
|
||||
@@ -23,7 +21,6 @@ pub(crate) fn new(cx: &mut gpui::Context<Screen>) -> Screen {
|
||||
let mut screen = Screen {
|
||||
titlebar: cx.new(titlebar::new),
|
||||
issue_list: cx.new(issue_list::new),
|
||||
sidebar: cx.new(|_| sidebar::new()),
|
||||
pull_request_view: cx.new(pull_request_view::new),
|
||||
|
||||
issue_filter: None,
|
||||
@@ -34,35 +31,15 @@ pub(crate) fn new(cx: &mut gpui::Context<Screen>) -> Screen {
|
||||
|
||||
impl Screen {
|
||||
fn on_create(&mut self, cx: &mut gpui::Context<Self>) {
|
||||
let on_item_change = cx.listener(|this, value, _, cx| {
|
||||
this.handle_sidebar_item_change(value, cx);
|
||||
});
|
||||
self.sidebar.update(cx, |sidebar, _| {
|
||||
sidebar.on_item_change(on_item_change);
|
||||
});
|
||||
|
||||
_ = cx
|
||||
.subscribe(&self.issue_list, |this, _, event, cx| match event {
|
||||
| issue_list::Event::ItemSelected(pr_id) => {
|
||||
this.handle_issue_list_item_selected(pr_id, cx);
|
||||
}
|
||||
| issue_list::Event::ItemSelected(pr_id) => {
|
||||
this.handle_issue_list_item_selected(pr_id, cx);
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
fn handle_sidebar_item_change(
|
||||
&mut self,
|
||||
value: &SidebarItemValue,
|
||||
cx: &mut gpui::Context<Self>,
|
||||
) {
|
||||
match value {
|
||||
| SidebarItemValue::PullRequest { filter } => {
|
||||
self.issue_filter = Some(*filter);
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_issue_list_item_selected(
|
||||
&mut self,
|
||||
id: &api::issues::Id,
|
||||
@@ -97,21 +74,12 @@ impl gpui::Render for Screen {
|
||||
.flex_1()
|
||||
.min_h_0()
|
||||
.w_full()
|
||||
.child(
|
||||
div()
|
||||
.w_40()
|
||||
.flex_shrink_0()
|
||||
.h_full()
|
||||
.child(self.sidebar.clone()),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.w_64()
|
||||
.flex_shrink_0()
|
||||
.h_full()
|
||||
.bg(theme.colors.surface)
|
||||
.border_x_1()
|
||||
.border_color(theme.colors.border)
|
||||
.bg(theme.colors.surface_chrome)
|
||||
.overflow_hidden()
|
||||
.child(self.issue_list.clone()),
|
||||
)
|
||||
|
||||
@@ -160,19 +160,19 @@ impl gpui::RenderOnce for SidebarItem {
|
||||
.px_2()
|
||||
.py_1()
|
||||
.gap_2()
|
||||
.child(font_icon(self.icon).size_3().when(self.is_selected, |it| {
|
||||
it.text_color(theme.colors.accent_text)
|
||||
}))
|
||||
.child(
|
||||
font_icon(self.icon)
|
||||
.size_3()
|
||||
.when(self.is_selected, |it| it.text_color(theme.colors.accent_fg)),
|
||||
)
|
||||
.child(
|
||||
text(self.title)
|
||||
.text_sm()
|
||||
.leading_tight()
|
||||
.when(self.is_selected, |it| {
|
||||
it.text_color(theme.colors.accent_text)
|
||||
}),
|
||||
.when(self.is_selected, |it| it.text_color(theme.colors.accent_fg)),
|
||||
),
|
||||
)
|
||||
.when_some(self.on_click, |it, f| it.on_click(f))
|
||||
.when(self.is_selected, |it| it.bg(theme.colors.accent))
|
||||
.when(self.is_selected, |it| it.bg(theme.colors.selection_bg))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use gpui::{ParentElement, Styled, TitlebarOptions, div};
|
||||
use gpui::{ParentElement, Styled, div};
|
||||
|
||||
use crate::component::button::button;
|
||||
use crate::query::{self, QueryStatus, read_query, use_lazy_query, use_query};
|
||||
use crate::query::{self, QueryStatus, read_query, use_lazy_query};
|
||||
use crate::{
|
||||
api, app,
|
||||
component::{
|
||||
@@ -32,13 +32,13 @@ impl gpui::Render for TitleBar {
|
||||
let user = read_query(&self.fetch_user_query, cx);
|
||||
|
||||
let user_avatar = match user {
|
||||
QueryStatus::Err(api::Error::Unauthenticated) => div().absolute().right_2p5().child(
|
||||
| QueryStatus::Err(api::Error::Unauthenticated) => div().absolute().right_2p5().child(
|
||||
button("login-btn")
|
||||
.leading(font_icon(FontIcon::Github))
|
||||
.label("Login"),
|
||||
),
|
||||
|
||||
_ => div(),
|
||||
| _ => div(),
|
||||
};
|
||||
|
||||
div()
|
||||
@@ -50,7 +50,7 @@ impl gpui::Render for TitleBar {
|
||||
.flex()
|
||||
.px(g.safe_area.size.width)
|
||||
.py_2()
|
||||
.bg(g.current_theme.colors.background)
|
||||
.bg(g.current_theme.colors.surface_chrome)
|
||||
.text_color(g.current_theme.colors.text)
|
||||
.relative()
|
||||
.border_b_1()
|
||||
@@ -61,7 +61,7 @@ impl gpui::Render for TitleBar {
|
||||
}
|
||||
|
||||
impl RepoSelector {
|
||||
pub fn new(cx: &mut gpui::Context<Self>) -> Self {
|
||||
pub fn new(_cx: &mut gpui::Context<Self>) -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user