feat: add relay tracking for gift wrap events #21
@@ -27,9 +27,9 @@ 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};
|
||||||
use crate::sidebar;
|
use crate::sidebar;
|
||||||
|
|
||||||
|
const PREPARE_MSG: &str = "Coop is preparing a new identity for you. This may take a moment...";
|
||||||
const ENC_MSG: &str = "Encryption Key is a special key that used to encrypt and decrypt your messages. \
|
const ENC_MSG: &str = "Encryption Key is a special key that used to encrypt and decrypt your messages. \
|
||||||
Your identity is completely decoupled from all encryption processes to protect your privacy.";
|
Your identity is completely decoupled from all encryption processes to protect your privacy.";
|
||||||
|
|
||||||
const ENC_WARN: &str = "By resetting your encryption key, you will lose access to \
|
const ENC_WARN: &str = "By resetting your encryption key, you will lose access to \
|
||||||
all your encrypted messages before. This action cannot be undone.";
|
all your encrypted messages before. This action cannot be undone.";
|
||||||
|
|
||||||
@@ -37,6 +37,7 @@ pub fn init(window: &mut Window, cx: &mut App) -> Entity<Workspace> {
|
|||||||
cx.new(|cx| Workspace::new(window, cx))
|
cx.new(|cx| Workspace::new(window, cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SignerNotifcation;
|
||||||
struct RelayNotifcation;
|
struct RelayNotifcation;
|
||||||
|
|
||||||
#[derive(Action, Clone, PartialEq, Eq, Deserialize)]
|
#[derive(Action, Clone, PartialEq, Eq, Deserialize)]
|
||||||
@@ -107,21 +108,29 @@ impl Workspace {
|
|||||||
// Subscribe to the signer events
|
// Subscribe to the signer events
|
||||||
cx.subscribe_in(&nostr, window, move |this, _state, event, window, cx| {
|
cx.subscribe_in(&nostr, window, move |this, _state, event, window, cx| {
|
||||||
match event {
|
match event {
|
||||||
|
StateEvent::Creating => {
|
||||||
|
let note = Notification::new()
|
||||||
|
.id::<SignerNotifcation>()
|
||||||
|
.title("Preparing a new identity")
|
||||||
|
.message(PREPARE_MSG)
|
||||||
|
.autohide(false)
|
||||||
|
.with_kind(NotificationKind::Info);
|
||||||
|
|
||||||
|
window.push_notification(note, cx);
|
||||||
|
}
|
||||||
StateEvent::Connecting => {
|
StateEvent::Connecting => {
|
||||||
let note = Notification::new()
|
let note = Notification::new()
|
||||||
.id::<RelayNotifcation>()
|
.id::<RelayNotifcation>()
|
||||||
.message("Connecting to the bootstrap relay...")
|
.message("Connecting to the bootstrap relays...")
|
||||||
.with_kind(NotificationKind::Info)
|
.with_kind(NotificationKind::Info);
|
||||||
.icon(IconName::Relay);
|
|
||||||
|
|
||||||
window.push_notification(note, cx);
|
window.push_notification(note, cx);
|
||||||
}
|
}
|
||||||
StateEvent::Connected => {
|
StateEvent::Connected => {
|
||||||
let note = Notification::new()
|
let note = Notification::new()
|
||||||
.id::<RelayNotifcation>()
|
.id::<RelayNotifcation>()
|
||||||
.message("Connected to the bootstrap relay")
|
.message("Connected to the bootstrap relays")
|
||||||
.with_kind(NotificationKind::Success)
|
.with_kind(NotificationKind::Success);
|
||||||
.icon(IconName::Relay);
|
|
||||||
|
|
||||||
window.push_notification(note, cx);
|
window.push_notification(note, cx);
|
||||||
}
|
}
|
||||||
@@ -136,6 +145,8 @@ impl Workspace {
|
|||||||
this.set_center_layout(window, cx);
|
this.set_center_layout(window, cx);
|
||||||
this.set_relay_connected(false, cx);
|
this.set_relay_connected(false, cx);
|
||||||
this.set_inbox_connected(false, cx);
|
this.set_inbox_connected(false, cx);
|
||||||
|
// Clear the signer notification
|
||||||
|
window.clear_notification::<SignerNotifcation>(cx);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ use std::time::Duration;
|
|||||||
use anyhow::{Context as AnyhowContext, Error, anyhow};
|
use anyhow::{Context as AnyhowContext, Error, anyhow};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
App, AppContext, Context, Entity, EventEmitter, Global, IntoElement, ParentElement,
|
App, AppContext, Context, Entity, EventEmitter, Global, IntoElement, ParentElement,
|
||||||
SharedString, Styled, Task, Window, div, relative,
|
SharedString, Styled, Subscription, Task, Window, div, relative,
|
||||||
};
|
};
|
||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
use person::PersonRegistry;
|
use person::PersonRegistry;
|
||||||
use state::{Announcement, DEVICE_GIFTWRAP, DeviceState, NostrRegistry, TIMEOUT, app_name};
|
use state::{
|
||||||
|
Announcement, DEVICE_GIFTWRAP, DeviceState, NostrRegistry, StateEvent, TIMEOUT, app_name,
|
||||||
|
};
|
||||||
use theme::ActiveTheme;
|
use theme::ActiveTheme;
|
||||||
use ui::avatar::Avatar;
|
use ui::avatar::Avatar;
|
||||||
use ui::button::{Button, ButtonVariants};
|
use ui::button::{Button, ButtonVariants};
|
||||||
@@ -48,6 +50,9 @@ pub struct DeviceRegistry {
|
|||||||
|
|
||||||
/// Async tasks
|
/// Async tasks
|
||||||
tasks: Vec<Task<Result<(), Error>>>,
|
tasks: Vec<Task<Result<(), Error>>>,
|
||||||
|
|
||||||
|
/// Event subscription
|
||||||
|
_subscription: Option<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter<DeviceEvent> for DeviceRegistry {}
|
impl EventEmitter<DeviceEvent> for DeviceRegistry {}
|
||||||
@@ -65,16 +70,26 @@ impl DeviceRegistry {
|
|||||||
|
|
||||||
/// Create a new device registry instance
|
/// Create a new device registry instance
|
||||||
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||||
|
let nostr = NostrRegistry::global(cx);
|
||||||
let state = DeviceState::default();
|
let state = DeviceState::default();
|
||||||
|
|
||||||
|
let subscription =
|
||||||
|
Some(
|
||||||
|
cx.subscribe_in(&nostr, window, |this, _state, ev, _window, cx| {
|
||||||
|
if let StateEvent::SignerSet = ev {
|
||||||
|
this.get_announcement(cx);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
cx.defer_in(window, |this, window, cx| {
|
cx.defer_in(window, |this, window, cx| {
|
||||||
this.handle_notifications(window, cx);
|
this.handle_notifications(window, cx);
|
||||||
this.get_announcement(cx);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
state,
|
state,
|
||||||
tasks: vec![],
|
tasks: vec![],
|
||||||
|
_subscription: subscription,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use state::NostrRegistry;
|
|||||||
use theme::ActiveTheme;
|
use theme::ActiveTheme;
|
||||||
use ui::button::{Button, ButtonVariants};
|
use ui::button::{Button, ButtonVariants};
|
||||||
use ui::notification::Notification;
|
use ui::notification::Notification;
|
||||||
use ui::{Disableable, IconName, Sizable, WindowExtension, v_flex};
|
use ui::{Disableable, IconName, Sizable, StyledExt, WindowExtension, v_flex};
|
||||||
|
|
||||||
const AUTH_MESSAGE: &str =
|
const AUTH_MESSAGE: &str =
|
||||||
"Approve the authentication request to allow Coop to continue sending or receiving events.";
|
"Approve the authentication request to allow Coop to continue sending or receiving events.";
|
||||||
@@ -344,8 +344,9 @@ impl RelayAuth {
|
|||||||
.px_1p5()
|
.px_1p5()
|
||||||
.rounded_sm()
|
.rounded_sm()
|
||||||
.text_xs()
|
.text_xs()
|
||||||
|
.font_semibold()
|
||||||
.bg(cx.theme().elevated_surface_background)
|
.bg(cx.theme().elevated_surface_background)
|
||||||
.text_color(cx.theme().text_accent)
|
.text_color(cx.theme().text)
|
||||||
.child(url.clone()),
|
.child(url.clone()),
|
||||||
)
|
)
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ impl Global for GlobalNostrRegistry {}
|
|||||||
/// Signer event.
|
/// Signer event.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub enum StateEvent {
|
pub enum StateEvent {
|
||||||
|
/// Creating the signer
|
||||||
|
Creating,
|
||||||
/// Connecting to the bootstrapping relay
|
/// Connecting to the bootstrapping relay
|
||||||
Connecting,
|
Connecting,
|
||||||
/// Connected to the bootstrapping relay
|
/// Connected to the bootstrapping relay
|
||||||
@@ -289,6 +291,9 @@ impl NostrRegistry {
|
|||||||
// Create a write credential task
|
// Create a write credential task
|
||||||
let write_credential = cx.write_credentials(&username, &username, &secret);
|
let write_credential = cx.write_credentials(&username, &username, &secret);
|
||||||
|
|
||||||
|
// Emit creating event
|
||||||
|
cx.emit(StateEvent::Creating);
|
||||||
|
|
||||||
// Run async tasks in background
|
// Run async tasks in background
|
||||||
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
|
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
|
||||||
let signer = async_keys.into_nostr_signer();
|
let signer = async_keys.into_nostr_signer();
|
||||||
@@ -301,7 +306,7 @@ impl NostrRegistry {
|
|||||||
client
|
client
|
||||||
.send_event(&event)
|
.send_event(&event)
|
||||||
.to(BOOTSTRAP_RELAYS)
|
.to(BOOTSTRAP_RELAYS)
|
||||||
.ok_timeout(Duration::from_secs(TIMEOUT))
|
.ack_policy(AckPolicy::none())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Construct the default metadata
|
// Construct the default metadata
|
||||||
|
|||||||
@@ -330,7 +330,12 @@ impl Render for Notification {
|
|||||||
.items_start()
|
.items_start()
|
||||||
.refine_style(&self.style)
|
.refine_style(&self.style)
|
||||||
.when_some(icon, |this, icon| {
|
.when_some(icon, |this, icon| {
|
||||||
this.child(div().flex_shrink_0().child(icon))
|
this.child(
|
||||||
|
div()
|
||||||
|
.flex_shrink_0()
|
||||||
|
.when(self.message.is_some(), |this| this.pt_0p5())
|
||||||
|
.child(icon),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.child(
|
.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
@@ -340,7 +345,13 @@ impl Render for Notification {
|
|||||||
this.child(div().text_sm().font_semibold().child(title))
|
this.child(div().text_sm().font_semibold().child(title))
|
||||||
})
|
})
|
||||||
.when_some(self.message.clone(), |this, message| {
|
.when_some(self.message.clone(), |this, message| {
|
||||||
this.child(div().text_sm().line_height(relative(1.25)).child(message))
|
this.child(
|
||||||
|
div()
|
||||||
|
.text_sm()
|
||||||
|
.text_color(cx.theme().text_muted)
|
||||||
|
.line_height(relative(1.3))
|
||||||
|
.child(message),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.when_some(content, |this, content| this.child(content))
|
.when_some(content, |this, content| this.child(content))
|
||||||
.when_some(action, |this, action| {
|
.when_some(action, |this, action| {
|
||||||
|
|||||||
Reference in New Issue
Block a user