chore: improve performance (#42)

* use uniform list for rooms list

* move profile cache to outside gpui context

* update comment

* refactor

* refactor

* .

* .

* add avatar component

* .

* refactor

* .
This commit is contained in:
reya
2025-05-27 07:34:22 +07:00
committed by GitHub
parent 45564c7722
commit 0f884f8142
25 changed files with 1087 additions and 1373 deletions

View File

@@ -30,19 +30,19 @@ pub trait ButtonVariants: Sized {
self.with_variant(ButtonVariant::Primary)
}
/// With the secondary style for the Button.
fn secondary(self) -> Self {
self.with_variant(ButtonVariant::Secondary)
}
/// With the ghost style for the Button.
fn ghost(self) -> Self {
self.with_variant(ButtonVariant::Ghost)
}
/// With the link style for the Button.
fn link(self) -> Self {
self.with_variant(ButtonVariant::Link)
}
/// With the text style for the Button, it will no padding look like a normal text.
fn text(self) -> Self {
self.with_variant(ButtonVariant::Text)
/// With the transparent style for the Button.
fn transparent(self) -> Self {
self.with_variant(ButtonVariant::Transparent)
}
/// With the custom style for the Button.
@@ -86,9 +86,9 @@ impl ButtonCustomVariant {
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum ButtonVariant {
Primary,
Secondary,
Ghost,
Link,
Text,
Transparent,
Custom(ButtonCustomVariant),
}
@@ -98,20 +98,6 @@ impl Default for ButtonVariant {
}
}
impl ButtonVariant {
fn is_link(&self) -> bool {
matches!(self, Self::Link)
}
fn is_text(&self) -> bool {
matches!(self, Self::Text)
}
fn no_padding(&self) -> bool {
self.is_link() || self.is_text()
}
}
type OnClick = Option<Box<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>>;
/// A Button element.
@@ -295,7 +281,7 @@ impl RenderOnce for Button {
ButtonRounded::Normal => this.rounded(cx.theme().radius),
ButtonRounded::Full => this.rounded_full(),
})
.when(!style.no_padding(), |this| {
.map(|this| {
if self.label.is_none() && self.children.is_empty() {
// Icon Button
match self.size {
@@ -321,13 +307,13 @@ impl RenderOnce for Button {
}
}
})
.text_color(normal_style.fg)
.when(self.selected, |this| {
let selected_style = style.selected(window, cx);
this.bg(selected_style.bg).text_color(selected_style.fg)
})
.when(!self.disabled && !self.selected, |this| {
this.bg(normal_style.bg)
.when(normal_style.underline, |this| this.text_decoration_1())
.hover(|this| {
let hover_style = style.hovered(window, cx);
this.bg(hover_style.bg)
@@ -359,7 +345,6 @@ impl RenderOnce for Button {
.text_color(disabled_style.fg)
.shadow_none()
})
.text_color(normal_style.fg)
.child({
div()
.flex()
@@ -405,13 +390,14 @@ impl RenderOnce for Button {
struct ButtonVariantStyle {
bg: Hsla,
fg: Hsla,
underline: bool,
}
impl ButtonVariant {
fn bg_color(&self, _window: &Window, cx: &App) -> Hsla {
match self {
ButtonVariant::Primary => cx.theme().element_background,
ButtonVariant::Secondary => cx.theme().elevated_surface_background,
ButtonVariant::Transparent => gpui::transparent_black(),
ButtonVariant::Custom(colors) => colors.color,
_ => cx.theme().ghost_element_background,
}
@@ -420,90 +406,87 @@ impl ButtonVariant {
fn text_color(&self, _window: &Window, cx: &App) -> Hsla {
match self {
ButtonVariant::Primary => cx.theme().element_foreground,
ButtonVariant::Link => cx.theme().text_accent,
ButtonVariant::Secondary => cx.theme().text_muted,
ButtonVariant::Transparent => cx.theme().text_placeholder,
ButtonVariant::Ghost => cx.theme().text_muted,
ButtonVariant::Custom(colors) => colors.foreground,
_ => cx.theme().text,
}
}
fn underline(&self, _window: &Window, _cx: &App) -> bool {
matches!(self, ButtonVariant::Link)
}
fn normal(&self, window: &Window, cx: &App) -> ButtonVariantStyle {
let bg = self.bg_color(window, cx);
let fg = self.text_color(window, cx);
let underline = self.underline(window, cx);
ButtonVariantStyle { bg, fg, underline }
ButtonVariantStyle { bg, fg }
}
fn hovered(&self, window: &Window, cx: &App) -> ButtonVariantStyle {
let bg = match self {
ButtonVariant::Primary => cx.theme().element_hover,
ButtonVariant::Secondary => cx.theme().secondary_hover,
ButtonVariant::Ghost => cx.theme().ghost_element_hover,
ButtonVariant::Link => cx.theme().ghost_element_background,
ButtonVariant::Text => cx.theme().ghost_element_background,
ButtonVariant::Transparent => gpui::transparent_black(),
ButtonVariant::Custom(colors) => colors.hover,
};
let fg = match self {
ButtonVariant::Secondary => cx.theme().secondary_foreground,
ButtonVariant::Ghost => cx.theme().text,
ButtonVariant::Link => cx.theme().text_accent,
ButtonVariant::Transparent => cx.theme().text_placeholder,
_ => self.text_color(window, cx),
};
let underline = self.underline(window, cx);
ButtonVariantStyle { bg, fg, underline }
ButtonVariantStyle { bg, fg }
}
fn active(&self, window: &Window, cx: &App) -> ButtonVariantStyle {
let bg = match self {
ButtonVariant::Primary => cx.theme().element_active,
ButtonVariant::Secondary => cx.theme().secondary_active,
ButtonVariant::Ghost => cx.theme().ghost_element_active,
ButtonVariant::Transparent => gpui::transparent_black(),
ButtonVariant::Custom(colors) => colors.active,
_ => cx.theme().ghost_element_background,
};
let fg = match self {
ButtonVariant::Link => cx.theme().text_accent,
ButtonVariant::Text => cx.theme().text,
ButtonVariant::Secondary => cx.theme().secondary_foreground,
ButtonVariant::Transparent => cx.theme().text_placeholder,
_ => self.text_color(window, cx),
};
let underline = self.underline(window, cx);
ButtonVariantStyle { bg, fg, underline }
ButtonVariantStyle { bg, fg }
}
fn selected(&self, window: &Window, cx: &App) -> ButtonVariantStyle {
let bg = match self {
ButtonVariant::Primary => cx.theme().element_selected,
ButtonVariant::Secondary => cx.theme().secondary_selected,
ButtonVariant::Ghost => cx.theme().ghost_element_selected,
ButtonVariant::Transparent => gpui::transparent_black(),
ButtonVariant::Custom(colors) => colors.active,
_ => cx.theme().ghost_element_background,
};
let fg = match self {
ButtonVariant::Link => cx.theme().text_accent,
ButtonVariant::Text => cx.theme().text,
ButtonVariant::Secondary => cx.theme().secondary_foreground,
ButtonVariant::Transparent => cx.theme().text_placeholder,
_ => self.text_color(window, cx),
};
let underline = self.underline(window, cx);
ButtonVariantStyle { bg, fg, underline }
ButtonVariantStyle { bg, fg }
}
fn disabled(&self, window: &Window, cx: &App) -> ButtonVariantStyle {
fn disabled(&self, _window: &Window, cx: &App) -> ButtonVariantStyle {
let bg = match self {
ButtonVariant::Link | ButtonVariant::Ghost | ButtonVariant::Text => {
cx.theme().ghost_element_disabled
}
ButtonVariant::Ghost => cx.theme().ghost_element_disabled,
ButtonVariant::Secondary => cx.theme().secondary_disabled,
_ => cx.theme().element_disabled,
};
let fg = match self {
ButtonVariant::Primary => cx.theme().text_muted, // TODO: use a different color?
_ => cx.theme().text_muted,
};
let underline = self.underline(window, cx);
ButtonVariantStyle { bg, fg, underline }
ButtonVariantStyle { bg, fg }
}
}