.
This commit is contained in:
@@ -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()
|
||||||
|
|||||||
@@ -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?;
|
||||||
if keys.public_key() != device_pubkey {
|
|
||||||
return Err(anyhow!("Encryption Key doesn't match the announcement"));
|
// Compare the public key from the announcement with the one from the database
|
||||||
};
|
if keys.public_key() != device_pubkey {
|
||||||
Ok(keys)
|
return Err(anyhow!("Encryption Key doesn't match the announcement"));
|
||||||
} else {
|
};
|
||||||
Err(anyhow!("Encryption Key not found. Please create a new key"))
|
|
||||||
}
|
Ok(keys)
|
||||||
});
|
});
|
||||||
|
|
||||||
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 {
|
||||||
}
|
this.update(cx, |this, cx| {
|
||||||
Err(e) => {
|
this.request(cx);
|
||||||
this.update(cx, |_this, 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()));
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user