refactor(ui): 拆分 app/connection_view/widgets 为子组件,对话框归拢 dialogs/
- ui/app/ 拆为门面、events(引擎事件泵)、actions(用户动作)、io(导入导出)、 theme(主题)、titlebar/sidebar/main_area(渲染分区) - ui/connection_view/ 拆为门面、subscribe、messages、publish、vars、util(纯函数) - ui/widgets/ 拆为 select(可搜索下拉)、kv_editor、common(字段行/状态/时间) - 五个对话框归拢 ui/dialogs/,linear-theme.json 随 theme.rs 迁入 ui/app/ - clippy 0 警告,全部路径经门面保持稳定
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
//! 基础部件:字段行布局、连接状态指示、时间格式化。
|
||||
|
||||
use gpui_kit::component::{h_flex, v_flex, ActiveTheme as _};
|
||||
use gpui_kit::{div, px, App, Hsla, IntoElement, ParentElement as _, SharedString, Styled as _};
|
||||
|
||||
use crate::model::ConnectionStatus;
|
||||
|
||||
/// 小号标签 + 控件的垂直字段容器(可选字段,无校验态)。
|
||||
pub fn field(label: impl Into<SharedString>, control: impl IntoElement) -> impl IntoElement {
|
||||
field_ex(label, control, false, None, Hsla::default())
|
||||
}
|
||||
|
||||
/// 字段行变体:`required` 时标签后追加红色 `*`;
|
||||
/// `error` 为 Some 时在控件下方渲染红字提示(`danger` 为主题错误色)。
|
||||
pub fn field_ex(
|
||||
label: impl Into<SharedString>,
|
||||
control: impl IntoElement,
|
||||
required: bool,
|
||||
error: Option<SharedString>,
|
||||
danger: Hsla,
|
||||
) -> impl IntoElement {
|
||||
v_flex()
|
||||
.gap_1()
|
||||
.min_w(px(0.))
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_0p5()
|
||||
.items_baseline()
|
||||
.child(div().text_xs().child(label.into()))
|
||||
.children(required.then(|| div().text_xs().text_color(danger).child("*"))),
|
||||
)
|
||||
.child(control)
|
||||
.children(error.map(|e| div().text_xs().text_color(danger).child(e)))
|
||||
}
|
||||
|
||||
// ─── 状态颜色 ────────────────────────────────────────────────────────────────
|
||||
|
||||
pub fn status_color(status: ConnectionStatus, cx: &App) -> Hsla {
|
||||
let t = cx.theme();
|
||||
match status {
|
||||
ConnectionStatus::Connected => t.success,
|
||||
ConnectionStatus::Connecting => t.warning,
|
||||
ConnectionStatus::Error => t.danger,
|
||||
ConnectionStatus::Disconnected => t.muted_foreground,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn status_dot(status: ConnectionStatus, cx: &App) -> impl IntoElement {
|
||||
div()
|
||||
.size(px(8.))
|
||||
.rounded_full()
|
||||
.bg(status_color(status, cx))
|
||||
}
|
||||
|
||||
// ─── 键值对编辑器 ────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
pub fn format_time(ts_ms: i64, show_millis: bool) -> String {
|
||||
use chrono::TimeZone as _;
|
||||
let Some(dt) = chrono::Local.timestamp_millis_opt(ts_ms).single() else {
|
||||
return String::new();
|
||||
};
|
||||
if show_millis {
|
||||
dt.format("%H:%M:%S%.3f").to_string()
|
||||
} else {
|
||||
dt.format("%H:%M:%S").to_string()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user