This commit is contained in:
2026-10-21 16:20:51 +07:00
parent d0ad1a6f57
commit d7160e196e
46 changed files with 2307 additions and 1534 deletions
+48 -61
View File
@@ -16,7 +16,6 @@ use gpui::{
retain_all, svg, white,
};
use gpui_kit::assets::IconName;
use gpui_kit::component::avatar::Avatar;
use gpui_kit::component::button::{Button, ButtonVariants};
use gpui_kit::component::dock::{Panel, PanelEvent};
use gpui_kit::component::input::{Input, InputEvent, InputState, Textarea, TextareaState};
@@ -34,11 +33,11 @@ use smallvec::{SmallVec, smallvec};
use state::{
FileAttachment, NostrRegistry, download_and_decrypt_to_file, upload, upload_encrypted,
};
use ui::{TextStyle, Typeset as _};
use crate::file::*;
use crate::message::{
MessageMedia, MessageRow, ReactionBar, ReplyPreview, WelcomeMessage, group_reactions, opens_run,
Avatar, MessageMedia, MessageRow, ReactionBar, ReplyPreview, WelcomeMessage, group_reactions,
opens_run,
};
use crate::text::RenderedText;
@@ -931,9 +930,9 @@ impl ChatPanel {
h_flex()
.h_10()
.justify_center()
.text_style(TextStyle::Callout)
.text_xs()
.bg(cx.theme().secondary)
.rounded(px(ui::panel_radius()))
.rounded(cx.theme().radius_lg)
.child("Message isn't traced yet"),
)
})
@@ -946,10 +945,10 @@ impl ChatPanel {
h_flex()
.h_7()
.px_2()
.gap(px(ui::SPACE))
.gap_2()
.bg(cx.theme().secondary)
.rounded(px(ui::control_radius()))
.text_style(TextStyle::Callout)
.rounded(cx.theme().radius)
.text_xs()
.child(div().size_1p5().rounded_full().bg(gpui::green()))
.child(SharedString::from(url.to_string())),
);
@@ -978,10 +977,10 @@ impl ChatPanel {
h_flex()
.h_7()
.px_2()
.gap(px(ui::SPACE))
.gap_2()
.bg(cx.theme().secondary)
.rounded(px(ui::control_radius()))
.text_style(TextStyle::Callout)
.rounded(cx.theme().radius)
.text_xs()
.child(div().size_1p5().rounded_full().bg(gpui::green()))
.child(SharedString::from(url.to_string())),
);
@@ -1018,7 +1017,7 @@ impl ChatPanel {
.items_center()
.justify_center()
.text_center()
.text_style(TextStyle::Caption)
.text_xs()
.text_color(cx.theme().muted_foreground)
.line_height(relative(1.3))
.child(
@@ -1041,7 +1040,7 @@ impl ChatPanel {
h_flex()
.w_full()
.gap_3()
.text_style(TextStyle::Callout)
.text_xs()
.child(
h_flex()
.flex_shrink_0()
@@ -1157,10 +1156,11 @@ impl ChatPanel {
.ghost()
.relative()
.flex_shrink_0()
.child(match author.avatar() {
Some(picture) => Avatar::new().src(picture).into_any_element(),
None => Avatar::new().into_any_element(),
})
.child(
Avatar::new(author.avatar())
.seed(author.avatar_seed())
.into_any_element(),
)
.dropdown_menu(move |this, _window, _cx| {
this.menu("Public Key", Box::new(Command::Copy(pk)))
.menu("View Relays", Box::new(Command::Relays(pk)))
@@ -1290,23 +1290,18 @@ impl ChatPanel {
let avatar = profile.avatar();
v_flex()
.gap(px(ui::SPACE))
.gap_2()
.w_full()
.child(
h_flex()
.gap(px(ui::SPACE))
.text_style(TextStyle::Callout)
.gap_2()
.text_xs()
.child(SharedString::from("Sent to:"))
.child(
h_flex()
.gap_1()
.font_weight(gpui::FontWeight::SEMIBOLD)
.child(match avatar {
Some(picture) => {
Avatar::new().src(picture).small().into_any_element()
}
None => Avatar::new().small().into_any_element(),
})
.child(Avatar::new(avatar).seed(profile.avatar_seed()).small())
.child(name.clone()),
),
)
@@ -1318,8 +1313,8 @@ impl ChatPanel {
.p_1()
.h_16()
.w_full()
.text_style(TextStyle::Callout)
.rounded(px(ui::surface_radius()))
.text_xs()
.rounded(cx.theme().radius_lg)
.bg(cx.theme().warning.opacity(0.15))
.text_color(cx.theme().warning)
.child(div().flex_1().w_full().text_center().child(error)),
@@ -1328,7 +1323,7 @@ impl ChatPanel {
.when_some(report.output().cloned(), |this, output| {
this.child(
v_flex()
.gap(px(ui::SPACE))
.gap_2()
.w_full()
.children({
let mut items = Vec::with_capacity(output.failed.len());
@@ -1339,18 +1334,18 @@ impl ChatPanel {
.gap_0p5()
.p_1()
.w_full()
.rounded(px(ui::surface_radius()))
.rounded(cx.theme().radius_lg)
.bg(cx.theme().danger.opacity(0.06))
.child(
div()
.text_style(TextStyle::Caption)
.text_xs()
.font_weight(gpui::FontWeight::SEMIBOLD)
.line_height(relative(1.25))
.child(SharedString::from(url.to_string())),
)
.child(
div()
.text_style(TextStyle::Caption)
.text_xs()
.text_color(cx.theme().danger.opacity(0.9))
.line_height(relative(1.25))
.child(SharedString::from(msg.to_string())),
@@ -1369,18 +1364,18 @@ impl ChatPanel {
.gap_0p5()
.p_1()
.w_full()
.rounded(px(ui::surface_radius()))
.rounded(cx.theme().radius_lg)
.bg(cx.theme().muted)
.child(
div()
.text_style(TextStyle::Caption)
.text_xs()
.font_weight(gpui::FontWeight::SEMIBOLD)
.line_height(relative(1.25))
.child(SharedString::from(url.0.to_string())),
)
.child(
div()
.text_style(TextStyle::Caption)
.text_xs()
.line_height(relative(1.25))
.child(SharedString::from("Successfully")),
),
@@ -1408,7 +1403,7 @@ impl ChatPanel {
.right_4()
.top_neg_2()
.when(cx.theme().shadow, |this| this.shadow_sm())
.rounded(px(ui::surface_radius()))
.rounded(cx.theme().radius_lg)
.border_1()
.border_color(cx.theme().border)
.bg(cx.theme().background)
@@ -1488,7 +1483,7 @@ impl ChatPanel {
img(url.as_str())
.size_16()
.when(cx.theme().shadow, |this| this.shadow_lg())
.rounded(px(ui::control_radius()))
.rounded(cx.theme().radius)
.object_fit(ObjectFit::Cover),
)
.child(
@@ -1549,7 +1544,7 @@ impl ChatPanel {
.border_color(cx.theme().border)
.h(px(250.))
.object_fit(ObjectFit::Cover)
.rounded(px(ui::bubble_radius())),
.rounded(cx.theme().radius_lg),
)
.into_any_element();
}
@@ -1577,21 +1572,21 @@ impl ChatPanel {
.self_start()
.items_start()
.min_w_0()
.gap(px(ui::SPACE))
.gap_2()
.p_2()
.border_1()
.border_color(cx.theme().border)
.rounded(px(ui::control_radius()))
.rounded(cx.theme().radius)
.child(Icon::new(IconName::Lock).text_color(cx.theme().primary))
.child(
v_flex()
.min_w_0()
.overflow_hidden()
.text_style(TextStyle::Callout)
.text_xs()
.child(div().line_height(relative(1.2)).child(file.display_name()))
.child(
div()
.text_style(TextStyle::Caption)
.text_xs()
.text_color(cx.theme().muted_foreground)
.child(label),
),
@@ -1623,7 +1618,7 @@ impl ChatPanel {
img(pending.path.clone())
.size_16()
.when(cx.theme().shadow, |this| this.shadow_sm())
.rounded(px(ui::control_radius()))
.rounded(cx.theme().radius)
.object_fit(ObjectFit::Cover),
)
} else {
@@ -1633,11 +1628,11 @@ impl ChatPanel {
.flex()
.items_center()
.justify_center()
.rounded(px(ui::control_radius()))
.rounded(cx.theme().radius)
.border_1()
.border_color(cx.theme().border)
.bg(cx.theme().sidebar)
.text_style(TextStyle::Caption)
.text_xs()
.text_center()
.child("Preview not available"),
)
@@ -1696,7 +1691,7 @@ impl ChatPanel {
.flex()
.items_baseline()
.gap_1()
.text_style(TextStyle::Caption)
.text_xs()
.text_color(cx.theme().muted_foreground)
.child("Replying to:")
.child(div().text_color(cx.theme().primary).child(profile.name())),
@@ -1717,7 +1712,7 @@ impl ChatPanel {
.child(
div()
.w_full()
.text_style(TextStyle::Callout)
.text_xs()
.text_ellipsis()
.line_clamp(1)
.child(text.preview()),
@@ -1827,24 +1822,16 @@ impl Panel for ChatPanel {
self.room
.read_with(cx, |this, cx| {
let label = this.display_name(cx);
let picture = this.display_image(cx);
let seed = this.display_image_seed(cx);
h_flex()
.gap_1()
.text_style(TextStyle::Caption)
.child(match picture {
Some(picture) => Avatar::new().src(picture).xsmall().into_any_element(),
None => Avatar::new().xsmall().into_any_element(),
})
.text_xs()
.child(Avatar::new(this.display_image(cx)).seed(seed).xsmall())
.child(label)
.into_any_element()
})
.unwrap_or(
div()
.text_style(TextStyle::Caption)
.child("Unknown")
.into_any_element(),
)
.unwrap_or(div().text_xs().child("Unknown").into_any_element())
}
fn toolbar_buttons(
@@ -1895,7 +1882,7 @@ impl Render for ChatPanel {
.h_12()
.w_full()
.px_2()
.gap(px(ui::SPACE))
.gap_2()
.border_b_1()
.border_color(cx.theme().border)
.child(Input::new(&self.subject_input).small())
@@ -1951,7 +1938,7 @@ impl Render for ChatPanel {
this.child(
div()
.px_1()
.text_style(TextStyle::Caption)
.text_xs()
.text_color(cx.theme().warning)
.child(WARNING),
)
+15 -13
View File
@@ -10,7 +10,8 @@ use gpui_kit::component::{
ActiveTheme, InteractiveElementExt as _, StyledExt as _, h_flex, v_flex,
};
use smallvec::SmallVec;
use ui::{TextStyle, Typeset as _, bubble_radius, control_radius};
pub use ui::Avatar;
type MouseDownListener = Box<dyn Fn(&MouseDownEvent, &mut Window, &mut App) + 'static>;
type ClickListener = Box<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>;
@@ -206,8 +207,8 @@ impl RenderOnce for MessageRow {
.when(show_author, |this| {
this.child(
h_flex()
.gap(px(ui::SPACE))
.text_style(TextStyle::Callout)
.gap_2()
.text_xs()
.text_color(cx.theme().muted_foreground)
.when_some(author, |this, author| {
this.child(
@@ -296,7 +297,7 @@ impl RenderOnce for ReplyPreview {
.px_2()
.border_l_2()
.border_color(cx.theme().list_active)
.text_style(TextStyle::Callout)
.text_xs()
.refine_style(&style)
.child(div().font_weight(gpui::FontWeight::SEMIBOLD).child(author))
.child(div().w_full().text_ellipsis().line_clamp(1).child(preview))
@@ -346,7 +347,7 @@ impl RenderOnce for MessageMedia {
.border_color(cx.theme().border)
.h(px(250.))
.object_fit(ObjectFit::Cover)
.rounded(px(bubble_radius())),
.rounded(cx.theme().radius_lg),
)
.into_any_element();
}
@@ -357,7 +358,7 @@ impl RenderOnce for MessageMedia {
.flex()
.flex_row()
.flex_wrap()
.gap(px(ui::SPACE))
.gap_2()
.refine_style(&style)
.children(media.into_iter().enumerate().map(|(ix, item)| {
div().id(format!("media-{ix}")).flex_shrink_0().child(
@@ -365,7 +366,7 @@ impl RenderOnce for MessageMedia {
.h_32()
.border_1()
.border_color(cx.theme().border)
.rounded(px(bubble_radius())),
.rounded(cx.theme().radius_lg),
)
}))
.into_any_element()
@@ -441,11 +442,11 @@ impl RenderOnce for ReactionBar {
.refine_style(&style)
.children(groups.into_iter().map(|group| {
h_flex()
.gap(px(ui::SPACE))
.gap_2()
.py_0p5()
.px_1()
.rounded(px(control_radius()))
.text_style(TextStyle::Caption)
.rounded(cx.theme().radius)
.text_xs()
.border_1()
.when(group.mine, |this| {
this.text_color(cx.theme().foreground)
@@ -525,7 +526,7 @@ impl RenderOnce for WelcomeMessage {
v_flex()
.id(id)
.w_full()
.gap(px(ui::SPACE))
.gap_2()
.p_3()
.items_center()
.justify_center()
@@ -540,7 +541,8 @@ impl RenderOnce for WelcomeMessage {
.when_some(title, |this, title| {
this.child(
div()
.text_style(TextStyle::Headline)
.text_sm()
.font_semibold()
.text_color(cx.theme().foreground)
.child(title),
)
@@ -548,7 +550,7 @@ impl RenderOnce for WelcomeMessage {
.when_some(message, |this, message| {
this.child(
div()
.text_style(TextStyle::Caption)
.text_xs()
.text_color(cx.theme().muted_foreground)
.child(message),
)