diff --git a/crates/chat/src/lib.rs b/crates/chat/src/lib.rs index 7b21f05..bdc4994 100644 --- a/crates/chat/src/lib.rs +++ b/crates/chat/src/lib.rs @@ -445,6 +445,11 @@ impl ChatRegistry { .count() } + /// Count the number of trash messages. + pub fn count_trash_messages(&self, cx: &App) -> usize { + self.trashes.read(cx).len() + } + /// Get the relays that have seen a given message. pub fn seen_on(&self, id: &EventId) -> HashSet { self.seens diff --git a/crates/coop/src/panels/mod.rs b/crates/coop/src/panels/mod.rs index bb47e07..e223f2f 100644 --- a/crates/coop/src/panels/mod.rs +++ b/crates/coop/src/panels/mod.rs @@ -4,3 +4,4 @@ pub mod greeter; pub mod messaging_relays; pub mod profile; pub mod relay_list; +pub mod trash; diff --git a/crates/coop/src/panels/trash.rs b/crates/coop/src/panels/trash.rs new file mode 100644 index 0000000..f3bbb79 --- /dev/null +++ b/crates/coop/src/panels/trash.rs @@ -0,0 +1,50 @@ +use gpui::{ + AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle, Focusable, + IntoElement, ParentElement, Render, SharedString, Styled, Window, div, svg, +}; +use state::NostrRegistry; +use theme::ActiveTheme; +use ui::button::{Button, ButtonVariants}; +use ui::dock::{DockPlacement, Panel, PanelEvent}; +use ui::{Icon, IconName, Sizable, StyledExt, h_flex, v_flex}; + +use crate::panels::profile; +use crate::workspace::Workspace; + +pub fn init(window: &mut Window, cx: &mut App) -> Entity { + cx.new(|cx| TrashPanel::new(window, cx)) +} + +pub struct TrashPanel { + name: SharedString, + focus_handle: FocusHandle, +} + +impl TrashPanel { + fn new(_window: &mut Window, cx: &mut App) -> Self { + Self { + name: "Trash".into(), + focus_handle: cx.focus_handle(), + } + } +} + +impl Panel for TrashPanel { + fn panel_id(&self) -> SharedString { + self.name.clone() + } +} + +impl EventEmitter for TrashPanel {} + +impl Focusable for TrashPanel { + fn focus_handle(&self, _: &App) -> gpui::FocusHandle { + self.focus_handle.clone() + } +} + +impl Render for TrashPanel { + fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { + div() + } +} diff --git a/crates/coop/src/workspace.rs b/crates/coop/src/workspace.rs index 472b01d..b88b981 100644 --- a/crates/coop/src/workspace.rs +++ b/crates/coop/src/workspace.rs @@ -9,7 +9,8 @@ use device::{DeviceEvent, DeviceRegistry}; use gpui::prelude::FluentBuilder; use gpui::{ Action, App, AppContext, Axis, Context, Entity, InteractiveElement, IntoElement, ParentElement, - Render, SharedString, Styled, Subscription, Window, div, px, + Render, SharedString, StatefulInteractiveElement, Styled, Subscription, Window, div, px, + relative, }; use nostr_sdk::prelude::*; use person::PersonRegistry; @@ -23,11 +24,11 @@ use ui::button::{Button, ButtonVariants}; use ui::dock::{ClosePanel, DockArea, DockItem, DockPlacement, PanelView}; use ui::menu::{DropdownMenu, PopupMenuItem}; use ui::notification::{Notification, NotificationKind}; -use ui::{Disableable, IconName, Root, Sizable, WindowExtension, h_flex, v_flex}; +use ui::{Disableable, Icon, IconName, Root, Sizable, WindowExtension, h_flex, v_flex}; use crate::dialogs::restore::RestoreEncryption; use crate::dialogs::{accounts, settings}; -use crate::panels::{backup, contact_list, greeter, messaging_relays, profile, relay_list}; +use crate::panels::{backup, contact_list, greeter, messaging_relays, profile, relay_list, trash}; use crate::sidebar; const PREPARE_MSG: &str = "Coop is preparing a new identity for you. This may take a moment..."; @@ -764,13 +765,48 @@ impl Workspace { let nostr = NostrRegistry::global(cx); let signer = nostr.read(cx).signer(); + let trashes = ChatRegistry::global(cx); + let trash_messages = trashes.read(cx).count_trash_messages(cx); + let Some(public_key) = signer.public_key() else { return div(); }; h_flex() .when(!cx.theme().platform.is_mac(), |this| this.pr_2()) - .gap_3() + .gap_2() + .when(trash_messages > 0, |this| { + this.child( + h_flex() + .id("trash-messages") + .h_6() + .px_1() + .gap_1() + .rounded(cx.theme().radius) + .hover(|this| this.bg(cx.theme().ghost_element_hover)) + .child( + Icon::new(IconName::Warning) + .small() + .text_color(cx.theme().text_danger), + ) + .child( + div() + .text_xs() + .line_height(relative(1.)) + .child(format!("{trash_messages}")), + ) + .on_click(move |_ev, window, cx| { + cx.stop_propagation(); + // Add the trash panel to the center workspace + Self::add_panel( + trash::init(window, cx), + DockPlacement::Center, + window, + cx, + ); + }), + ) + }) .child( Button::new("key") .icon(IconName::UserKey)