update avatar

This commit is contained in:
2026-11-03 10:42:21 +07:00
parent 1340dcf3e9
commit 659e22e9fc
6 changed files with 912 additions and 150 deletions
+88 -78
View File
@@ -1253,7 +1253,7 @@ impl Render for AvatarDemo {
.size_full()
.p_4()
.child(demo_section(
"pictures fall back to initials",
"pictures, with a seeded pixel-art fallback",
colors,
h_flex()
.flex_wrap()
@@ -1263,13 +1263,18 @@ impl Render for AvatarDemo {
.name("Reya Adele")
.picture(Some("https://github.com/reya.png")),
)
.child(Avatar::new("ada@reya.info").name("Ada Lovelace"))
.child(
Avatar::new("ada@reya.info")
.name("Ada Lovelace")
.picture(Some("https://example.com/missing.png")),
Avatar::new("grace@reya.info")
.name("Grace Hopper")
.fully_rounded(true),
)
.child(Avatar::new("grace@reya.info").name("Grace Hopper").small())
.child(Avatar::new("desk@reya.info").name("Help Desk").large()),
.child(
Avatar::new("desk@reya.info")
.name("Help Desk")
.fully_rounded(true)
.large(),
),
))
}
}
@@ -2410,79 +2415,84 @@ where
}
fn main() {
application().with_assets(IconAssets).run(|cx: &mut App| {
gpui_native_core::init(cx);
let layout_state = LayoutState::new(cx);
let dock_state = DockState::new(cx);
// A panel that declares a right sidebar view asks for it to open on
// activation; visibility itself stays on the shell's LayoutState.
let layout_for_dock = layout_state.clone();
dock_state.update(cx, |dock, _| {
dock.on_open_right_sidebar(move |cx| {
layout_for_dock.update(cx, |state, cx| {
state.set_right_sidebar_visible(true, cx);
// Without a client gpui installs a NullHttpClient and remote images —
// the avatar pictures — silently never load.
application()
.with_assets(IconAssets)
.with_http_client(std::sync::Arc::new(reqwest_client::ReqwestClient::new()))
.run(|cx: &mut App| {
gpui_native_core::init(cx);
let layout_state = LayoutState::new(cx);
let dock_state = DockState::new(cx);
// A panel that declares a right sidebar view asks for it to open on
// activation; visibility itself stays on the shell's LayoutState.
let layout_for_dock = layout_state.clone();
dock_state.update(cx, |dock, _| {
dock.on_open_right_sidebar(move |cx| {
layout_for_dock.update(cx, |state, cx| {
state.set_right_sidebar_visible(true, cx);
});
});
});
});
let bounds = Bounds::centered(None, size(px(960.0), px(640.0)), cx);
if let Err(err) = cx.open_window(
WindowOptions {
window_bounds: Some(WindowBounds::Windowed(bounds)),
titlebar: Some(gpui::TitlebarOptions {
title: Some("gpui-native-kit gallery".into()),
// The shell's strips are the titlebar; the native one only
// hosts the traffic lights on macOS.
appears_transparent: true,
let bounds = Bounds::centered(None, size(px(960.0), px(640.0)), cx);
if let Err(err) = cx.open_window(
WindowOptions {
window_bounds: Some(WindowBounds::Windowed(bounds)),
titlebar: Some(gpui::TitlebarOptions {
title: Some("gpui-native-kit gallery".into()),
// The shell's strips are the titlebar; the native one only
// hosts the traffic lights on macOS.
appears_transparent: true,
..Default::default()
}),
// The strips move the window themselves, so a tab dragged inside
// the titlebar band never drags the window with it.
app_owns_titlebar_drag: true,
..Default::default()
}),
// The strips move the window themselves, so a tab dragged inside
// the titlebar band never drags the window with it.
app_owns_titlebar_drag: true,
..Default::default()
},
|window, cx| {
Theme::sync_from_window(window, cx);
Theme::sync_window_rem_size(window, cx);
// Detached on purpose: the subscription lives as long as the window.
window
.observe_window_appearance(|window, cx| {
Theme::sync_from_window(window, cx);
Theme::sync_window_rem_size(window, cx);
cx.refresh_windows();
})
.detach();
let toasts = cx.new(|_| Toasts::default());
let alerts = cx.new(|_| Alerts::default());
let gallery = cx.new(|cx| {
// Toast pushes and dismissals repaint the stack.
cx.observe(&toasts, |_, _, cx| cx.notify()).detach();
// Alert pushes and dismissals repaint it.
cx.observe(&alerts, |_, _, cx| cx.notify()).detach();
Gallery {
layout_state: layout_state.clone(),
dock_state: dock_state.clone(),
alerts: alerts.clone(),
toasts: toasts.clone(),
dialog_open: false,
alert_open: false,
}
});
dock_state.update(cx, |dock, cx| {
Gallery::register_panels(
dock,
layout_state.clone(),
alerts.clone(),
toasts.clone(),
gallery.downgrade(),
cx,
);
dock.open_panel("welcome", window, cx);
});
gallery
},
) {
eprintln!("failed to open gallery window: {err}");
}
cx.activate(true);
});
},
|window, cx| {
Theme::sync_from_window(window, cx);
Theme::sync_window_rem_size(window, cx);
// Detached on purpose: the subscription lives as long as the window.
window
.observe_window_appearance(|window, cx| {
Theme::sync_from_window(window, cx);
Theme::sync_window_rem_size(window, cx);
cx.refresh_windows();
})
.detach();
let toasts = cx.new(|_| Toasts::default());
let alerts = cx.new(|_| Alerts::default());
let gallery = cx.new(|cx| {
// Toast pushes and dismissals repaint the stack.
cx.observe(&toasts, |_, _, cx| cx.notify()).detach();
// Alert pushes and dismissals repaint it.
cx.observe(&alerts, |_, _, cx| cx.notify()).detach();
Gallery {
layout_state: layout_state.clone(),
dock_state: dock_state.clone(),
alerts: alerts.clone(),
toasts: toasts.clone(),
dialog_open: false,
alert_open: false,
}
});
dock_state.update(cx, |dock, cx| {
Gallery::register_panels(
dock,
layout_state.clone(),
alerts.clone(),
toasts.clone(),
gallery.downgrade(),
cx,
);
dock.open_panel("welcome", window, cx);
});
gallery
},
) {
eprintln!("failed to open gallery window: {err}");
}
cx.activate(true);
});
}