notifications.rs

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