notifications.rs

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