facepile.rs

 1use crate::prelude::*;
 2use crate::{Avatar, Player};
 3
 4#[derive(RenderOnce)]
 5pub struct Facepile {
 6    players: Vec<Player>,
 7}
 8
 9impl<V: 'static> Component<V> for Facepile {
10    type Rendered = Div<V>;
11
12    fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> Self::Rendered {
13        let player_count = self.players.len();
14        let player_list = self.players.iter().enumerate().map(|(ix, player)| {
15            let isnt_last = ix < player_count - 1;
16
17            div()
18                .when(isnt_last, |div| div.neg_mr_1())
19                .child(Avatar::new(player.avatar_src().to_string()))
20        });
21        div().p_1().flex().items_center().children(player_list)
22    }
23}
24
25impl Facepile {
26    pub fn new<P: Iterator<Item = Player>>(players: P) -> Self {
27        Self {
28            players: players.collect(),
29        }
30    }
31}
32
33use gpui::{Div, RenderOnce};
34#[cfg(feature = "stories")]
35pub use stories::*;
36
37#[cfg(feature = "stories")]
38mod stories {
39    use super::*;
40    use crate::{static_players, Story};
41    use gpui::{Div, Render};
42
43    pub struct FacepileStory;
44
45    impl Render<Self> for FacepileStory {
46        type Element = Div<Self>;
47
48        fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
49            let players = static_players();
50
51            Story::container(cx)
52                .child(Story::title_for::<_, Facepile>(cx))
53                .child(Story::label(cx, "Default"))
54                .child(
55                    div()
56                        .flex()
57                        .gap_3()
58                        .child(Facepile::new(players.clone().into_iter().take(1)))
59                        .child(Facepile::new(players.clone().into_iter().take(2)))
60                        .child(Facepile::new(players.clone().into_iter().take(3))),
61                )
62        }
63    }
64}