feat(nouser-explorer): integración al stack yahweh themed
Iter 10. nouser-explorer (paralela a nakui-explorer pero para ver Mónadas via daemon nouser) tenía colors hardcoded idénticos al patrón previo. Aplico el mismo refactor: theme global instalado, chrome a slots, widgets compartidos. - Nuevas deps: yahweh-theme + 3 widgets (banner, card, theme-switcher). - main() instala Theme::install_default. - render: 4 vars rgb() chrome → theme slots. - Header: flex_row + theme switcher a la derecha (mismo pattern que nakui-explorer). - error_banner: div hardcoded → banner_themed(Error). - 2 cards (Engine/Monad): div().flex_col().p().bg().rounded()... → card_themed(cx).border_l_4().border_color(accent). - Accents semánticos (engine cyan, data purple) quedan locales como señales de dominio. Las dos apps explorer del repo ahora comparten paleta themed + switcher común. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,10 @@ description = "Explorador GPUI de Mónadas: panel que descubre al daemon nouser
|
||||
brahman-card = { path = "../../core/brahman-card" }
|
||||
brahman-sidecar = { path = "../../shared/brahman-sidecar" }
|
||||
nouser-card = { path = "../../modules/nouser/card" }
|
||||
yahweh-theme = { path = "../../modules/ui_engine/libs/theme" }
|
||||
yahweh-widget-banner = { path = "../../modules/ui_engine/widgets/banner" }
|
||||
yahweh-widget-card = { path = "../../modules/ui_engine/widgets/card" }
|
||||
yahweh-widget-theme-switcher = { path = "../../modules/ui_engine/widgets/theme-switcher" }
|
||||
gpui = { workspace = true }
|
||||
|
||||
[[bin]]
|
||||
|
||||
@@ -29,6 +29,10 @@ use gpui::{
|
||||
use nouser_card::query::client as query_client;
|
||||
use nouser_card::query::{transport, ListMonadsResponse, FLOW_MONAD_LIST, FLOW_TYPE_NAME};
|
||||
use nouser_card::Lens;
|
||||
use yahweh_theme::Theme;
|
||||
use yahweh_widget_banner::{banner_themed, Banner};
|
||||
use yahweh_widget_card::card_themed;
|
||||
use yahweh_widget_theme_switcher::theme_switcher;
|
||||
|
||||
const REFRESH_INTERVAL: Duration = Duration::from_secs(2);
|
||||
const DISCOVERY_TIMEOUT: Duration = Duration::from_secs(3);
|
||||
@@ -36,6 +40,9 @@ const QUERY_TIMEOUT: Duration = Duration::from_secs(2);
|
||||
|
||||
fn main() {
|
||||
Application::new().run(|cx: &mut App| {
|
||||
// Theme global instalado al boot — los widgets themed lo
|
||||
// requieren y unifica el chrome del app.
|
||||
Theme::install_default(cx);
|
||||
let bounds = Bounds::centered(None, gpui::size(px(900.), px(640.)), cx);
|
||||
cx.open_window(
|
||||
WindowOptions {
|
||||
@@ -192,11 +199,14 @@ fn discover_via_broker() -> Result<PathBuf, ConsumerError> {
|
||||
}
|
||||
|
||||
impl Render for Explorer {
|
||||
fn render(&mut self, _w: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let bg = rgb(0x14171c);
|
||||
let card_bg = rgb(0x1d2128);
|
||||
let text_dim = rgb(0x9ba1ad);
|
||||
let text = rgb(0xe6e8ec);
|
||||
fn render(&mut self, _w: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
// Chrome viene del Theme global; los acentos por kind
|
||||
// (engine cyan, data purple) son señales semánticas del
|
||||
// dominio nouser y se mantienen locales.
|
||||
let theme = Theme::global(cx).clone();
|
||||
let bg = theme.bg_app.clone();
|
||||
let text = theme.fg_text;
|
||||
let text_dim = theme.fg_muted;
|
||||
let accent_engine = rgb(0x88c0d0);
|
||||
let accent_data = rgb(0xb48ead);
|
||||
|
||||
@@ -216,24 +226,27 @@ impl Render for Explorer {
|
||||
_ => "Buscando daemon nouser vía brahman-broker…".to_string(),
|
||||
};
|
||||
|
||||
// Header con título a la izquierda + theme switcher a la
|
||||
// derecha (mismo pattern que nakui-explorer).
|
||||
let header = div()
|
||||
.flex()
|
||||
.flex_row()
|
||||
.items_center()
|
||||
.px(px(16.))
|
||||
.py(px(12.))
|
||||
.bg(card_bg)
|
||||
.bg(theme.bg_panel.clone())
|
||||
.border_b_1()
|
||||
.border_color(rgb(0x2a2f38))
|
||||
.border_color(theme.border)
|
||||
.text_color(text)
|
||||
.text_size(px(14.))
|
||||
.child(header_text);
|
||||
.child(div().flex_grow().child(header_text))
|
||||
.child(theme_switcher(cx));
|
||||
|
||||
let error_banner = self.error.as_ref().map(|e| {
|
||||
div()
|
||||
banner_themed(cx, Banner::Error, e.clone())
|
||||
.px(px(16.))
|
||||
.py(px(8.))
|
||||
.bg(rgb(0x4a2020))
|
||||
.text_color(rgb(0xffd0d0))
|
||||
.text_size(px(12.))
|
||||
.child(e.clone())
|
||||
});
|
||||
|
||||
let cards: Vec<gpui::AnyElement> = match &self.snapshot {
|
||||
@@ -243,16 +256,9 @@ impl Render for Explorer {
|
||||
|
||||
// Engine card primero — el "ser" que owns las Mónadas.
|
||||
out.push(
|
||||
div()
|
||||
.flex()
|
||||
.flex_col()
|
||||
.p(px(12.))
|
||||
.mb(px(8.))
|
||||
.bg(card_bg)
|
||||
.rounded(px(6.))
|
||||
card_themed(cx)
|
||||
.border_l_4()
|
||||
.border_color(accent_engine)
|
||||
.gap(px(2.))
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
@@ -305,16 +311,9 @@ impl Render for Explorer {
|
||||
.map(|m| format!("model: {m}"));
|
||||
|
||||
out.push(
|
||||
div()
|
||||
.flex()
|
||||
.flex_col()
|
||||
.p(px(12.))
|
||||
.mb(px(8.))
|
||||
.bg(card_bg)
|
||||
.rounded(px(6.))
|
||||
card_themed(cx)
|
||||
.border_l_4()
|
||||
.border_color(accent_data)
|
||||
.gap(px(2.))
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
|
||||
Reference in New Issue
Block a user