notifications.rs

  1use client::User;
  2use gpui::{
  3    elements::*,
  4    platform::{CursorStyle, MouseButton},
  5    Action, AnyElement, Element, View, ViewContext,
  6};
  7use settings::Settings;
  8use std::sync::Arc;
  9
 10enum Dismiss {}
 11enum Button {}
 12
 13pub fn render_user_notification<V: View, A: Action + Clone>(
 14    user: Arc<User>,
 15    title: &'static str,
 16    body: Option<&'static str>,
 17    dismiss_action: A,
 18    buttons: Vec<(&'static str, Box<dyn Action>)>,
 19    cx: &mut ViewContext<V>,
 20) -> AnyElement<V> {
 21    let theme = cx.global::<Settings>().theme.clone();
 22    let theme = &theme.contact_notification;
 23
 24    Flex::column()
 25        .with_child(
 26            Flex::row()
 27                .with_children(user.avatar.clone().map(|avatar| {
 28                    Image::from_data(avatar)
 29                        .with_style(theme.header_avatar)
 30                        .aligned()
 31                        .constrained()
 32                        .with_height(
 33                            cx.font_cache()
 34                                .line_height(theme.header_message.text.font_size),
 35                        )
 36                        .aligned()
 37                        .top()
 38                }))
 39                .with_child(
 40                    Text::new(
 41                        format!("{} {}", user.github_login, title),
 42                        theme.header_message.text.clone(),
 43                    )
 44                    .contained()
 45                    .with_style(theme.header_message.container)
 46                    .aligned()
 47                    .top()
 48                    .left()
 49                    .flex(1., true),
 50                )
 51                .with_child(
 52                    MouseEventHandler::<Dismiss, V>::new(user.id as usize, cx, |state, _| {
 53                        let style = theme.dismiss_button.style_for(state, false);
 54                        Svg::new("icons/x_mark_8.svg")
 55                            .with_color(style.color)
 56                            .constrained()
 57                            .with_width(style.icon_width)
 58                            .aligned()
 59                            .contained()
 60                            .with_style(style.container)
 61                            .constrained()
 62                            .with_width(style.button_width)
 63                            .with_height(style.button_width)
 64                    })
 65                    .with_cursor_style(CursorStyle::PointingHand)
 66                    .with_padding(Padding::uniform(5.))
 67                    .on_click(MouseButton::Left, move |_, _, cx| {
 68                        cx.dispatch_any_action(dismiss_action.boxed_clone())
 69                    })
 70                    .aligned()
 71                    .constrained()
 72                    .with_height(
 73                        cx.font_cache()
 74                            .line_height(theme.header_message.text.font_size),
 75                    )
 76                    .aligned()
 77                    .top()
 78                    .flex_float(),
 79                )
 80                .into_any_named("contact notification header"),
 81        )
 82        .with_children(body.map(|body| {
 83            Label::new(body, theme.body_message.text.clone())
 84                .contained()
 85                .with_style(theme.body_message.container)
 86        }))
 87        .with_children(if buttons.is_empty() {
 88            None
 89        } else {
 90            Some(
 91                Flex::row()
 92                    .with_children(buttons.into_iter().enumerate().map(
 93                        |(ix, (message, action))| {
 94                            MouseEventHandler::<Button, V>::new(ix, cx, |state, _| {
 95                                let button = theme.button.style_for(state, false);
 96                                Label::new(message, button.text.clone())
 97                                    .contained()
 98                                    .with_style(button.container)
 99                            })
100                            .with_cursor_style(CursorStyle::PointingHand)
101                            .on_click(MouseButton::Left, move |_, _, cx| {
102                                cx.dispatch_any_action(action.boxed_clone())
103                            })
104                        },
105                    ))
106                    .aligned()
107                    .right(),
108            )
109        })
110        .contained()
111        .into_any()
112}