notifications.rs

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