This commit is contained in:
Ren Amamiya
2026-04-04 08:53:20 +07:00
parent 707533c145
commit 0403d0e4ec
2 changed files with 50 additions and 76 deletions

View File

@@ -11,7 +11,7 @@ use gpui::{
relative, relative,
}; };
use nostr_sdk::prelude::*; use nostr_sdk::prelude::*;
use person::PersonRegistry; use person::{PersonRegistry, shorten_pubkey};
use serde::Deserialize; use serde::Deserialize;
use smallvec::{SmallVec, smallvec}; use smallvec::{SmallVec, smallvec};
use state::{NostrRegistry, StateEvent}; use state::{NostrRegistry, StateEvent};
@@ -141,10 +141,11 @@ impl Workspace {
match event { match event {
DeviceEvent::Requesting => { DeviceEvent::Requesting => {
const MSG: &str = const MSG: &str =
"Please open the other client and approve the encryption key request"; "Coop has sent a request for an encryption key. Please open the other client then approve the request.";
let note = Notification::new() let note = Notification::new()
.id::<DeviceNotifcation>() .id::<DeviceNotifcation>()
.autohide(false)
.title("Wait for approval") .title("Wait for approval")
.message(MSG) .message(MSG)
.with_kind(NotificationKind::Info); .with_kind(NotificationKind::Info);
@@ -154,6 +155,7 @@ impl Workspace {
DeviceEvent::Creating => { DeviceEvent::Creating => {
let note = Notification::new() let note = Notification::new()
.id::<DeviceNotifcation>() .id::<DeviceNotifcation>()
.autohide(false)
.message("Creating encryption key") .message("Creating encryption key")
.with_kind(NotificationKind::Info); .with_kind(NotificationKind::Info);
@@ -167,16 +169,6 @@ impl Workspace {
window.push_notification(note, cx); window.push_notification(note, cx);
} }
DeviceEvent::NotSet { reason } => {
let note = Notification::new()
.id::<DeviceNotifcation>()
.title("Cannot setup the encryption key")
.message(reason)
.autohide(false)
.with_kind(NotificationKind::Error);
window.push_notification(note, cx);
}
DeviceEvent::Error(error) => { DeviceEvent::Error(error) => {
window.push_notification(Notification::error(error).autohide(false), cx); window.push_notification(Notification::error(error).autohide(false), cx);
} }
@@ -643,6 +635,7 @@ impl Workspace {
fn titlebar_right(&mut self, cx: &mut Context<Self>) -> impl IntoElement { fn titlebar_right(&mut self, cx: &mut Context<Self>) -> impl IntoElement {
let chat = ChatRegistry::global(cx); let chat = ChatRegistry::global(cx);
let initializing = chat.read(cx).initializing; let initializing = chat.read(cx).initializing;
let trash_messages = chat.read(cx).count_trash_messages(cx);
let device = DeviceRegistry::global(cx); let device = DeviceRegistry::global(cx);
let device_initializing = device.read(cx).initializing; let device_initializing = device.read(cx).initializing;
@@ -650,13 +643,14 @@ impl Workspace {
let nostr = NostrRegistry::global(cx); let nostr = NostrRegistry::global(cx);
let signer = nostr.read(cx).signer(); 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 { let Some(public_key) = signer.public_key() else {
return div(); return div();
}; };
let persons = PersonRegistry::global(cx);
let profile = persons.read(cx).get(&public_key, cx);
let announcement = profile.announcement();
h_flex() h_flex()
.when(!cx.theme().platform.is_mac(), |this| this.pr_2()) .when(!cx.theme().platform.is_mac(), |this| this.pr_2())
.gap_2() .gap_2()
@@ -704,25 +698,34 @@ impl Workspace {
.xsmall() .xsmall()
.tooltip("Loading decoupled encryption key...") .tooltip("Loading decoupled encryption key...")
}) })
.dropdown_menu(move |this, _window, cx| { .dropdown_menu(move |this, _window, _cx| {
let requesting = device.read(cx).requesting;
this.min_w(px(260.)) this.min_w(px(260.))
.label("Encryption Key") .label("Encryption Key")
.when(requesting, |this| { .when_some(announcement.as_ref(), |this, announcement| {
let name = announcement.client_name();
let pkey = shorten_pubkey(announcement.public_key(), 8);
this.item(PopupMenuItem::element(move |_window, cx| { this.item(PopupMenuItem::element(move |_window, cx| {
h_flex() h_flex()
.px_1() .gap_1()
.w_full()
.gap_2()
.text_sm() .text_sm()
.child( .child(
div() Icon::new(IconName::Device)
.size_1p5() .small()
.rounded_full() .text_color(cx.theme().icon_muted),
.bg(cx.theme().icon_accent),
) )
.child(SharedString::from("Waiting for approval...")) .child(name.clone())
}))
.item(PopupMenuItem::element(move |_window, cx| {
h_flex()
.gap_1()
.text_sm()
.child(
Icon::new(IconName::UserKey)
.small()
.text_color(cx.theme().icon_muted),
)
.child(SharedString::from(pkey.clone()))
})) }))
}) })
.separator() .separator()
@@ -761,9 +764,6 @@ impl Workspace {
.tooltip("Getting inbox messages...") .tooltip("Getting inbox messages...")
}) })
.dropdown_menu(move |this, _window, cx| { .dropdown_menu(move |this, _window, cx| {
let persons = PersonRegistry::global(cx);
let profile = persons.read(cx).get(&public_key, cx);
let urls: Vec<(SharedString, SharedString)> = profile let urls: Vec<(SharedString, SharedString)> = profile
.messaging_relays() .messaging_relays()
.iter() .iter()

View File

@@ -39,8 +39,6 @@ pub enum DeviceEvent {
Requesting, Requesting,
/// The device is creating a new encryption key /// The device is creating a new encryption key
Creating, Creating,
/// Encryption key is not set
NotSet { reason: SharedString },
/// An error occurred /// An error occurred
Error(SharedString), Error(SharedString),
} }
@@ -52,15 +50,6 @@ impl DeviceEvent {
{ {
Self::Error(error.into()) Self::Error(error.into())
} }
pub fn not_set<T>(reason: T) -> Self
where
T: Into<SharedString>,
{
Self::NotSet {
reason: reason.into(),
}
}
} }
/// Device Registry /// Device Registry
@@ -71,9 +60,6 @@ pub struct DeviceRegistry {
/// Whether the registry is currently initializing /// Whether the registry is currently initializing
pub initializing: bool, pub initializing: bool,
/// Whether the registry is waiting for encryption key approval from other devices
pub requesting: bool,
/// Whether there is a pending request for encryption key approval /// Whether there is a pending request for encryption key approval
pub pending_request: bool, pub pending_request: bool,
@@ -105,7 +91,6 @@ impl DeviceRegistry {
let subscription = cx.subscribe_in(&nostr, window, |this, _e, event, _window, cx| { let subscription = cx.subscribe_in(&nostr, window, |this, _e, event, _window, cx| {
if event == &StateEvent::SignerSet { if event == &StateEvent::SignerSet {
this.set_initializing(true, cx); this.set_initializing(true, cx);
this.set_requesting(false, cx);
this.get_announcement(cx); this.get_announcement(cx);
}; };
}); });
@@ -116,7 +101,6 @@ impl DeviceRegistry {
Self { Self {
initializing: true, initializing: true,
requesting: false,
pending_request: false, pending_request: false,
tasks: vec![], tasks: vec![],
_subscription: Some(subscription), _subscription: Some(subscription),
@@ -188,12 +172,6 @@ impl DeviceRegistry {
cx.notify(); cx.notify();
} }
/// Set whether the registry is waiting for encryption key approval from other devices
fn set_requesting(&mut self, requesting: bool, cx: &mut Context<Self>) {
self.requesting = requesting;
cx.notify();
}
/// Set whether there is a pending request for encryption key approval /// Set whether there is a pending request for encryption key approval
fn set_pending_request(&mut self, pending: bool, cx: &mut Context<Self>) { fn set_pending_request(&mut self, pending: bool, cx: &mut Context<Self>) {
self.pending_request = pending; self.pending_request = pending;
@@ -353,30 +331,27 @@ impl DeviceRegistry {
// Get encryption key from the database and compare with the announcement // Get encryption key from the database and compare with the announcement
let task: Task<Result<Keys, Error>> = cx.background_spawn(async move { let task: Task<Result<Keys, Error>> = cx.background_spawn(async move {
if let Ok(keys) = get_keys(&client).await { let keys = get_keys(&client).await?;
// Compare the public key from the announcement with the one from the database
if keys.public_key() != device_pubkey { if keys.public_key() != device_pubkey {
return Err(anyhow!("Encryption Key doesn't match the announcement")); return Err(anyhow!("Encryption Key doesn't match the announcement"));
}; };
Ok(keys) Ok(keys)
} else {
Err(anyhow!("Encryption Key not found. Please create a new key"))
}
}); });
self.tasks.push(cx.spawn(async move |this, cx| { self.tasks.push(cx.spawn(async move |this, cx| {
match task.await { if let Ok(keys) = task.await {
Ok(keys) => {
this.update(cx, |this, cx| { this.update(cx, |this, cx| {
this.set_signer(keys, cx); this.set_signer(keys, cx);
this.wait_for_request(cx); this.wait_for_request(cx);
})?; })?;
} } else {
Err(e) => { this.update(cx, |this, cx| {
this.update(cx, |_this, cx| { this.request(cx);
cx.emit(DeviceEvent::not_set(e.to_string()));
})?; })?;
} }
};
Ok(()) Ok(())
})); }));
} }
@@ -454,7 +429,7 @@ impl DeviceRegistry {
} }
Ok(None) => { Ok(None) => {
this.update(cx, |this, cx| { this.update(cx, |this, cx| {
this.set_requesting(true, cx); this.set_initializing(false, cx);
this.wait_for_approval(cx); this.wait_for_approval(cx);
cx.emit(DeviceEvent::Requesting); cx.emit(DeviceEvent::Requesting);
@@ -519,12 +494,11 @@ impl DeviceRegistry {
Ok(keys) => { Ok(keys) => {
this.update(cx, |this, cx| { this.update(cx, |this, cx| {
this.set_signer(keys, cx); this.set_signer(keys, cx);
this.set_requesting(false, cx);
})?; })?;
} }
Err(e) => { Err(e) => {
this.update(cx, |_this, cx| { this.update(cx, |_this, cx| {
cx.emit(DeviceEvent::not_set(e.to_string())); cx.emit(DeviceEvent::error(e.to_string()));
})?; })?;
} }
} }