1use crate::prelude::*;
2use gpui::{img, Img, RenderOnce};
3
4#[derive(RenderOnce)]
5pub struct Avatar {
6 src: SharedString,
7 shape: Shape,
8}
9
10impl<V: 'static> Component<V> for Avatar {
11 type Rendered = Img<V>;
12
13 fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> Self::Rendered {
14 let mut img = img();
15
16 if self.shape == Shape::Circle {
17 img = img.rounded_full();
18 } else {
19 img = img.rounded_md();
20 }
21
22 img.uri(self.src.clone())
23 .size_4()
24 // todo!(Pull the avatar fallback background from the theme.)
25 .bg(gpui::red())
26 }
27}
28
29impl Avatar {
30 pub fn new(src: impl Into<SharedString>) -> Self {
31 Self {
32 src: src.into(),
33 shape: Shape::Circle,
34 }
35 }
36
37 pub fn shape(mut self, shape: Shape) -> Self {
38 self.shape = shape;
39 self
40 }
41}
42
43#[cfg(feature = "stories")]
44pub use stories::*;
45
46#[cfg(feature = "stories")]
47mod stories {
48 use super::*;
49 use crate::Story;
50 use gpui::{Div, Render};
51
52 pub struct AvatarStory;
53
54 impl Render<Self> for AvatarStory {
55 type Element = Div<Self>;
56
57 fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
58 Story::container(cx)
59 .child(Story::title_for::<_, Avatar>(cx))
60 .child(Story::label(cx, "Default"))
61 .child(Avatar::new(
62 "https://avatars.githubusercontent.com/u/1714999?v=4",
63 ))
64 .child(Avatar::new(
65 "https://avatars.githubusercontent.com/u/326587?v=4",
66 ))
67 }
68 }
69}