diff --git a/assets/icons/ban.svg b/assets/icons/ban.svg new file mode 100644 index 00000000..0129765f --- /dev/null +++ b/assets/icons/ban.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/login.svg b/assets/icons/login.svg new file mode 100644 index 00000000..dc5ec458 --- /dev/null +++ b/assets/icons/login.svg @@ -0,0 +1 @@ + diff --git a/crates/nip29_ui/src/message.rs b/crates/nip29_ui/src/message.rs index 142a8eca..7bb3b0b2 100644 --- a/crates/nip29_ui/src/message.rs +++ b/crates/nip29_ui/src/message.rs @@ -13,6 +13,7 @@ use theme::ActiveTheme; use ui::avatar::Avatar; use ui::menu::{ContextMenu, PopupMenu, PopupMenuItem}; use ui::message::MessageRow; +use ui::{Icon, IconName, Sizable, StyledExt, h_flex}; use crate::GroupPanel; @@ -134,20 +135,63 @@ pub(crate) fn render_activity(ix: usize, activity: &Activity, cx: &App) -> AnyEl let subject = persons.read(cx).get(&activity.subject(), cx); let hide_avatar = AppSettings::get_hide_avatar(cx); - MessageRow::new(ix) - .show_author(true) - .hide_avatar(hide_avatar) - .avatar( - Avatar::new(subject.avatar()) - .seed(subject.avatar_seed()) - .flex_shrink_0(), + h_flex() + .id(ix) + .w_full() + .gap_2() + .py_1() + .px_3() + .hover(|this| this.bg(cx.theme().surface_background)) + .child(badge(activity, cx)) + .when(!hide_avatar, |this| { + this.child( + Avatar::new(subject.avatar()) + .seed(subject.avatar_seed()) + .small() + .flex_shrink_0(), + ) + }) + .child( + div() + .min_w_0() + .truncate() + .text_sm() + .font_semibold() + .child(subject.name()), ) - .author(SharedString::from(format!( - "{} {}", - subject.name(), - action(activity) - ))) - .timestamp(activity.created_at.to_human_time()) + .child( + div() + .min_w_0() + .truncate() + .text_sm() + .text_color(cx.theme().text_placeholder) + .child(SharedString::from(action(activity))), + ) + .child( + div() + .flex_shrink_0() + .ml_1() + .text_xs() + .text_color(cx.theme().text_placeholder) + .child(activity.created_at.to_ago()), + ) + .into_any_element() +} + +fn badge(activity: &Activity, cx: &App) -> AnyElement { + let (icon, color) = match activity.kind { + Kind::GroupJoinRequest => (IconName::Login, cx.theme().icon_accent), + Kind::GroupPutUser => (IconName::Login, cx.theme().icon_accent), + Kind::GroupLeaveRequest => (IconName::Logout, cx.theme().text_danger), + Kind::GroupRemoveUser => (IconName::Ban, cx.theme().text_danger), + _ => (IconName::Info, cx.theme().icon_muted), + }; + + h_flex() + .flex_shrink_0() + .justify_center() + .size_8() + .child(Icon::new(icon).small().text_color(color)) .into_any_element() } diff --git a/crates/ui/src/icon.rs b/crates/ui/src/icon.rs index 1e708c06..198f5977 100644 --- a/crates/ui/src/icon.rs +++ b/crates/ui/src/icon.rs @@ -25,6 +25,7 @@ pub enum IconName { ArrowDownCircle, Boom, Book, + Ban, ChevronDown, CaretDown, CaretRight, @@ -50,6 +51,7 @@ pub enum IconName { Link, Loader, Lock, + Login, Logout, Message, Moon, @@ -106,6 +108,7 @@ impl IconNamed for IconName { Self::ArrowDownCircle => "icons/arrow-down-circle.svg", Self::Boom => "icons/boom.svg", Self::Book => "icons/book.svg", + Self::Ban => "icons/ban.svg", Self::ChevronDown => "icons/chevron-down.svg", Self::CaretDown => "icons/caret-down.svg", Self::CaretRight => "icons/caret-right.svg", @@ -131,6 +134,7 @@ impl IconNamed for IconName { Self::Link => "icons/link.svg", Self::Loader => "icons/loader.svg", Self::Lock => "icons/lock.svg", + Self::Login => "icons/login.svg", Self::Logout => "icons/logout.svg", Self::Message => "icons/message.svg", Self::Moon => "icons/moon.svg",