Start styling notification panel
This commit is contained in:
parent
c20e781441
commit
23400a5a70
5 changed files with 81 additions and 39 deletions
|
@ -443,7 +443,8 @@ impl ChatPanel {
|
||||||
Flex::row()
|
Flex::row()
|
||||||
.with_child(render_avatar(
|
.with_child(render_avatar(
|
||||||
message.sender.avatar.clone(),
|
message.sender.avatar.clone(),
|
||||||
&theme,
|
&theme.chat_panel.avatar,
|
||||||
|
theme.chat_panel.avatar_container,
|
||||||
))
|
))
|
||||||
.with_child(
|
.with_child(
|
||||||
Label::new(
|
Label::new(
|
||||||
|
|
|
@ -11,7 +11,7 @@ use call::{report_call_event_for_room, ActiveCall, Room};
|
||||||
use feature_flags::{ChannelsAlpha, FeatureFlagAppExt};
|
use feature_flags::{ChannelsAlpha, FeatureFlagAppExt};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions,
|
actions,
|
||||||
elements::{Empty, Image},
|
elements::{ContainerStyle, Empty, Image},
|
||||||
geometry::{
|
geometry::{
|
||||||
rect::RectF,
|
rect::RectF,
|
||||||
vector::{vec2f, Vector2F},
|
vector::{vec2f, Vector2F},
|
||||||
|
@ -20,7 +20,7 @@ use gpui::{
|
||||||
AnyElement, AppContext, Element, ImageData, Task,
|
AnyElement, AppContext, Element, ImageData, Task,
|
||||||
};
|
};
|
||||||
use std::{rc::Rc, sync::Arc};
|
use std::{rc::Rc, sync::Arc};
|
||||||
use theme::Theme;
|
use theme::AvatarStyle;
|
||||||
use time::{OffsetDateTime, UtcOffset};
|
use time::{OffsetDateTime, UtcOffset};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
use workspace::AppState;
|
use workspace::AppState;
|
||||||
|
@ -133,8 +133,11 @@ fn notification_window_options(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_avatar<T: 'static>(avatar: Option<Arc<ImageData>>, theme: &Arc<Theme>) -> AnyElement<T> {
|
fn render_avatar<T: 'static>(
|
||||||
let avatar_style = theme.chat_panel.avatar;
|
avatar: Option<Arc<ImageData>>,
|
||||||
|
avatar_style: &AvatarStyle,
|
||||||
|
container: ContainerStyle,
|
||||||
|
) -> AnyElement<T> {
|
||||||
avatar
|
avatar
|
||||||
.map(|avatar| {
|
.map(|avatar| {
|
||||||
Image::from_data(avatar)
|
Image::from_data(avatar)
|
||||||
|
@ -154,7 +157,7 @@ fn render_avatar<T: 'static>(avatar: Option<Arc<ImageData>>, theme: &Arc<Theme>)
|
||||||
.into_any()
|
.into_any()
|
||||||
})
|
})
|
||||||
.contained()
|
.contained()
|
||||||
.with_style(theme.chat_panel.avatar_container)
|
.with_style(container)
|
||||||
.into_any()
|
.into_any()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ use rpc::proto;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use settings::SettingsStore;
|
use settings::SettingsStore;
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::{sync::Arc, time::Duration};
|
||||||
use theme::{IconButton, Theme};
|
use theme::{ui, Theme};
|
||||||
use time::{OffsetDateTime, UtcOffset};
|
use time::{OffsetDateTime, UtcOffset};
|
||||||
use util::{ResultExt, TryFutureExt};
|
use util::{ResultExt, TryFutureExt};
|
||||||
use workspace::{
|
use workspace::{
|
||||||
|
@ -197,9 +197,9 @@ impl NotificationPanel {
|
||||||
let NotificationPresenter {
|
let NotificationPresenter {
|
||||||
actor,
|
actor,
|
||||||
text,
|
text,
|
||||||
icon,
|
|
||||||
needs_response,
|
needs_response,
|
||||||
can_navigate,
|
can_navigate,
|
||||||
|
..
|
||||||
} = self.present_notification(entry, cx)?;
|
} = self.present_notification(entry, cx)?;
|
||||||
|
|
||||||
let theme = theme::current(cx);
|
let theme = theme::current(cx);
|
||||||
|
@ -227,17 +227,21 @@ impl NotificationPanel {
|
||||||
Flex::column()
|
Flex::column()
|
||||||
.with_child(
|
.with_child(
|
||||||
Flex::row()
|
Flex::row()
|
||||||
.with_children(
|
.with_children(actor.map(|actor| {
|
||||||
actor.map(|actor| render_avatar(actor.avatar.clone(), &theme)),
|
render_avatar(
|
||||||
|
actor.avatar.clone(),
|
||||||
|
&style.avatar,
|
||||||
|
style.avatar_container,
|
||||||
)
|
)
|
||||||
.with_child(render_icon_button(&theme.chat_panel.icon_button, icon))
|
}))
|
||||||
.with_child(
|
.with_child(
|
||||||
Label::new(
|
Label::new(
|
||||||
format_timestamp(timestamp, now, self.local_timezone),
|
format_timestamp(timestamp, now, self.local_timezone),
|
||||||
style.timestamp.text.clone(),
|
style.timestamp.text.clone(),
|
||||||
)
|
)
|
||||||
.contained()
|
.contained()
|
||||||
.with_style(style.timestamp.container),
|
.with_style(style.timestamp.container)
|
||||||
|
.flex_float(),
|
||||||
)
|
)
|
||||||
.align_children_center(),
|
.align_children_center(),
|
||||||
)
|
)
|
||||||
|
@ -245,8 +249,12 @@ impl NotificationPanel {
|
||||||
.with_children(if let Some(is_accepted) = response {
|
.with_children(if let Some(is_accepted) = response {
|
||||||
Some(
|
Some(
|
||||||
Label::new(
|
Label::new(
|
||||||
if is_accepted { "Accepted" } else { "Declined" },
|
if is_accepted {
|
||||||
style.button.text.clone(),
|
"You Accepted"
|
||||||
|
} else {
|
||||||
|
"You Declined"
|
||||||
|
},
|
||||||
|
style.read_text.text.clone(),
|
||||||
)
|
)
|
||||||
.into_any(),
|
.into_any(),
|
||||||
)
|
)
|
||||||
|
@ -573,19 +581,34 @@ impl View for NotificationPanel {
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
||||||
let theme = theme::current(cx);
|
let theme = theme::current(cx);
|
||||||
|
let style = &theme.notification_panel;
|
||||||
let element = if self.client.user_id().is_none() {
|
let element = if self.client.user_id().is_none() {
|
||||||
self.render_sign_in_prompt(&theme, cx)
|
self.render_sign_in_prompt(&theme, cx)
|
||||||
} else if self.notification_list.item_count() == 0 {
|
} else if self.notification_list.item_count() == 0 {
|
||||||
self.render_empty_state(&theme, cx)
|
self.render_empty_state(&theme, cx)
|
||||||
} else {
|
} else {
|
||||||
|
Flex::column()
|
||||||
|
.with_child(
|
||||||
|
Flex::row()
|
||||||
|
.with_child(Label::new("Notifications", style.title.text.clone()))
|
||||||
|
.with_child(ui::svg(&style.title_icon).flex_float())
|
||||||
|
.align_children_center()
|
||||||
|
.contained()
|
||||||
|
.with_style(style.title.container)
|
||||||
|
.constrained()
|
||||||
|
.with_height(style.title_height),
|
||||||
|
)
|
||||||
|
.with_child(
|
||||||
List::new(self.notification_list.clone())
|
List::new(self.notification_list.clone())
|
||||||
.contained()
|
.contained()
|
||||||
.with_style(theme.chat_panel.list)
|
.with_style(style.list)
|
||||||
|
.flex(1., true),
|
||||||
|
)
|
||||||
.into_any()
|
.into_any()
|
||||||
};
|
};
|
||||||
element
|
element
|
||||||
.contained()
|
.contained()
|
||||||
.with_style(theme.chat_panel.container)
|
.with_style(style.container)
|
||||||
.constrained()
|
.constrained()
|
||||||
.with_min_width(150.)
|
.with_min_width(150.)
|
||||||
.into_any()
|
.into_any()
|
||||||
|
@ -675,19 +698,6 @@ impl Panel for NotificationPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_icon_button<V: View>(style: &IconButton, svg_path: &'static str) -> impl Element<V> {
|
|
||||||
Svg::new(svg_path)
|
|
||||||
.with_color(style.color)
|
|
||||||
.constrained()
|
|
||||||
.with_width(style.icon_width)
|
|
||||||
.aligned()
|
|
||||||
.constrained()
|
|
||||||
.with_width(style.button_width)
|
|
||||||
.with_height(style.button_width)
|
|
||||||
.contained()
|
|
||||||
.with_style(style.container)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct NotificationToast {
|
pub struct NotificationToast {
|
||||||
notification_id: u64,
|
notification_id: u64,
|
||||||
actor: Option<Arc<User>>,
|
actor: Option<Arc<User>>,
|
||||||
|
|
|
@ -653,6 +653,9 @@ pub struct ChatPanel {
|
||||||
pub struct NotificationPanel {
|
pub struct NotificationPanel {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub container: ContainerStyle,
|
pub container: ContainerStyle,
|
||||||
|
pub title: ContainedText,
|
||||||
|
pub title_icon: SvgStyle,
|
||||||
|
pub title_height: f32,
|
||||||
pub list: ContainerStyle,
|
pub list: ContainerStyle,
|
||||||
pub avatar: AvatarStyle,
|
pub avatar: AvatarStyle,
|
||||||
pub avatar_container: ContainerStyle,
|
pub avatar_container: ContainerStyle,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { background, text } from "./components"
|
import { background, border, text } from "./components"
|
||||||
import { icon_button } from "../component/icon_button"
|
import { icon_button } from "../component/icon_button"
|
||||||
import { useTheme } from "../theme"
|
import { useTheme } from "../theme"
|
||||||
import { interactive } from "../element"
|
import { interactive } from "../element"
|
||||||
|
|
||||||
export default function chat_panel(): any {
|
export default function (): any {
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const layer = theme.middle
|
const layer = theme.middle
|
||||||
|
|
||||||
|
@ -12,12 +12,32 @@ export default function chat_panel(): any {
|
||||||
avatar: {
|
avatar: {
|
||||||
icon_width: 24,
|
icon_width: 24,
|
||||||
icon_height: 24,
|
icon_height: 24,
|
||||||
corner_radius: 4,
|
corner_radius: 12,
|
||||||
outer_width: 24,
|
outer_width: 24,
|
||||||
outer_corner_radius: 16,
|
outer_corner_radius: 24,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
...text(layer, "sans", "default"),
|
||||||
|
padding: { left: 8, right: 8 },
|
||||||
|
border: border(layer, { bottom: true }),
|
||||||
|
},
|
||||||
|
title_height: 32,
|
||||||
|
title_icon: {
|
||||||
|
asset: "icons/feedback.svg",
|
||||||
|
color: text(theme.lowest, "sans", "default").color,
|
||||||
|
dimensions: {
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
read_text: {
|
||||||
|
padding: { top: 4, bottom: 4 },
|
||||||
|
...text(layer, "sans", "disabled"),
|
||||||
|
},
|
||||||
|
unread_text: {
|
||||||
|
padding: { top: 4, bottom: 4 },
|
||||||
|
...text(layer, "sans", "base"),
|
||||||
},
|
},
|
||||||
read_text: text(layer, "sans", "disabled"),
|
|
||||||
unread_text: text(layer, "sans", "base"),
|
|
||||||
button: interactive({
|
button: interactive({
|
||||||
base: {
|
base: {
|
||||||
...text(theme.lowest, "sans", "on", { size: "xs" }),
|
...text(theme.lowest, "sans", "on", { size: "xs" }),
|
||||||
|
@ -42,7 +62,12 @@ export default function chat_panel(): any {
|
||||||
bottom: 2,
|
bottom: 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
list: {},
|
list: {
|
||||||
|
padding: {
|
||||||
|
left: 8,
|
||||||
|
right: 8,
|
||||||
|
},
|
||||||
|
},
|
||||||
icon_button: icon_button({
|
icon_button: icon_button({
|
||||||
variant: "ghost",
|
variant: "ghost",
|
||||||
color: "variant",
|
color: "variant",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue