chore: Refine the UI (#102)

* update deps

* update window options

* linux title bar

* fix build

* .

* fix build

* rounded corners on linux

* .

* .

* fix i18n key

* fix change subject modal

* .

* update new account

* .

* update relay modal

* .

* fix i18n keys

---------

Co-authored-by: reya <reya@macbook.local>
This commit is contained in:
reya
2025-08-02 11:37:15 +07:00
committed by GitHub
co-authored by reya
parent 3cf9dde882
commit c188f12993
43 changed files with 2552 additions and 1790 deletions
+29 -102
View File
@@ -4,15 +4,14 @@ use std::time::Duration;
use anyhow::{anyhow, Error};
use common::debounced_delay::DebouncedDelay;
use common::display::{DisplayProfile, TextUtils};
use global::constants::{BOOTSTRAP_RELAYS, DEFAULT_MODAL_WIDTH, SEARCH_RELAYS};
use common::display::TextUtils;
use global::constants::{BOOTSTRAP_RELAYS, SEARCH_RELAYS};
use global::nostr_client;
use gpui::prelude::FluentBuilder;
use gpui::{
div, px, relative, rems, uniform_list, AnyElement, App, AppContext, ClipboardItem, Context,
Entity, EventEmitter, FocusHandle, Focusable, InteractiveElement, IntoElement, ParentElement,
Render, RetainAllImageCache, SharedString, StatefulInteractiveElement, Styled, Subscription,
Task, Window,
div, relative, uniform_list, AnyElement, App, AppContext, Context, Entity, EventEmitter,
FocusHandle, Focusable, IntoElement, ParentElement, Render, RetainAllImageCache, SharedString,
Styled, Subscription, Task, Window,
};
use gpui_tokio::Tokio;
use i18n::t;
@@ -25,7 +24,6 @@ use registry::{Registry, RoomEmitter};
use settings::AppSettings;
use smallvec::{smallvec, SmallVec};
use theme::ActiveTheme;
use ui::avatar::Avatar;
use ui::button::{Button, ButtonRounded, ButtonVariants};
use ui::dock_area::panel::{Panel, PanelEvent};
use ui::indicator::Indicator;
@@ -34,8 +32,6 @@ use ui::popup_menu::PopupMenu;
use ui::skeleton::Skeleton;
use ui::{v_flex, ContextModal, IconName, Selectable, Sizable, StyledExt};
use crate::views::compose;
mod list_item;
const FIND_DELAY: u64 = 600;
@@ -551,18 +547,6 @@ impl Sidebar {
});
}
fn open_compose(&self, window: &mut Window, cx: &mut Context<Self>) {
let compose = compose::init(window, cx);
let title = SharedString::new(t!("sidebar.direct_messages"));
window.open_modal(cx, move |modal, _window, _cx| {
modal
.title(title.clone())
.width(px(DEFAULT_MODAL_WIDTH))
.child(compose.clone())
});
}
fn open_loading_modal(&self, window: &mut Window, cx: &mut Context<Self>) {
let title = SharedString::new(t!("sidebar.loading_modal_title"));
let text_1 = SharedString::new(t!("sidebar.loading_modal_body_1"));
@@ -596,49 +580,6 @@ impl Sidebar {
});
}
fn account(&self, profile: &Profile, cx: &Context<Self>) -> impl IntoElement {
let proxy = AppSettings::get_proxy_user_avatars(cx);
div()
.px_3()
.h_8()
.flex_none()
.flex()
.justify_between()
.items_center()
.child(
div()
.id("current-user")
.flex()
.items_center()
.gap_2()
.text_sm()
.font_semibold()
.child(Avatar::new(profile.avatar_url(proxy)).size(rems(1.75)))
.child(profile.display_name())
.on_click(cx.listener({
let Ok(public_key) = profile.public_key().to_bech32();
let item = ClipboardItem::new_string(public_key);
move |_, _, window, cx| {
cx.write_to_clipboard(item.clone());
window.push_notification(t!("common.copied"), cx);
}
})),
)
.child(
Button::new("compose")
.icon(IconName::PlusFill)
.tooltip(t!("sidebar.dm_tooltip"))
.small()
.primary()
.rounded(ButtonRounded::Full)
.on_click(cx.listener(|this, _, window, cx| {
this.open_compose(window, cx);
})),
)
}
fn skeletons(&self, total: i32) -> impl IntoIterator<Item = impl IntoElement> {
(0..total).map(|_| {
div()
@@ -727,9 +668,6 @@ impl Focusable for Sidebar {
impl Render for Sidebar {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let registry = Registry::read_global(cx);
let profile = Identity::read_global(cx)
.public_key()
.map(|pk| registry.get_person(&pk, cx));
// Get rooms from either search results or the chat registry
let rooms = if let Some(results) = self.local_result.read(cx).as_ref() {
@@ -745,22 +683,17 @@ impl Render for Sidebar {
}
};
div()
v_flex()
.image_cache(self.image_cache.clone())
.size_full()
.relative()
.flex()
.flex_col()
.gap_3()
// Account
.when_some(profile, |this, profile| {
this.child(self.account(&profile, cx))
})
// Search Input
.child(
div()
.relative()
.px_3()
.mt_3()
.px_2p5()
.w_full()
.h_7()
.flex_none()
@@ -781,14 +714,12 @@ impl Render for Sidebar {
)
// Chat Rooms
.child(
div()
.px_2()
.w_full()
.flex_1()
.overflow_y_hidden()
.flex()
.flex_col()
v_flex()
.gap_1()
.flex_1()
.px_1p5()
.w_full()
.overflow_y_hidden()
.child(
div()
.flex_none()
@@ -879,8 +810,11 @@ impl Render for Sidebar {
),
)
.when(registry.loading, |this| {
let title = SharedString::new(t!("sidebar.retrieving_messages"));
let desc = SharedString::new(t!("sidebar.retrieving_messages_description"));
this.child(
div().absolute().bottom_4().px_4().w_full().child(
div().absolute().bottom_3().px_3().w_full().child(
div()
.p_1()
.w_full()
@@ -890,35 +824,28 @@ impl Render for Sidebar {
.justify_between()
.bg(cx.theme().panel_background)
.shadow_sm()
// Empty div
.child(div().size_6().flex_shrink_0())
// Loading indicator
// Loading
.child(div().flex_shrink_0().pl_1().child(Indicator::new().small()))
// Title
.child(
div()
v_flex()
.flex_1()
.flex()
.flex_col()
.items_center()
.justify_center()
.text_xs()
.text_center()
.child(
div()
.text_sm()
.font_semibold()
.flex()
.items_center()
.gap_1()
.line_height(relative(1.2))
.child(Indicator::new().xsmall())
.child(SharedString::new(t!(
"sidebar.retrieving_messages"
))),
.child(title.clone()),
)
.child(div().text_color(cx.theme().text_muted).child(
SharedString::new(t!(
"sidebar.retrieving_messages_description"
)),
)),
.child(
div()
.text_xs()
.text_color(cx.theme().text_muted)
.child(desc.clone()),
),
)
// Info button
.child(