@@ -111,55 +111,9 @@ impl ChatSpace {
|
|||||||
subscriptions.push(cx.observe_in(
|
subscriptions.push(cx.observe_in(
|
||||||
&client_keys,
|
&client_keys,
|
||||||
window,
|
window,
|
||||||
|_this: &mut Self, state, window, cx| {
|
|this: &mut Self, state, window, cx| {
|
||||||
if !state.read(cx).has_keys() {
|
if !state.read(cx).has_keys() {
|
||||||
let title = SharedString::new(t!("startup.client_keys_warning"));
|
this.render_client_keys_modal(window, cx);
|
||||||
let desc = SharedString::new(t!("startup.client_keys_desc"));
|
|
||||||
|
|
||||||
window.open_modal(cx, move |this, _window, cx| {
|
|
||||||
this.overlay_closable(false)
|
|
||||||
.show_close(false)
|
|
||||||
.keyboard(false)
|
|
||||||
.confirm()
|
|
||||||
.button_props(
|
|
||||||
ModalButtonProps::default()
|
|
||||||
.cancel_text(t!("startup.create_new_keys"))
|
|
||||||
.ok_text(t!("common.allow")),
|
|
||||||
)
|
|
||||||
.child(
|
|
||||||
div()
|
|
||||||
.w_full()
|
|
||||||
.h_40()
|
|
||||||
.flex()
|
|
||||||
.flex_col()
|
|
||||||
.gap_1()
|
|
||||||
.items_center()
|
|
||||||
.justify_center()
|
|
||||||
.text_center()
|
|
||||||
.text_sm()
|
|
||||||
.child(
|
|
||||||
div()
|
|
||||||
.font_semibold()
|
|
||||||
.text_color(cx.theme().text_muted)
|
|
||||||
.child(title.clone()),
|
|
||||||
)
|
|
||||||
.child(desc.clone()),
|
|
||||||
)
|
|
||||||
.on_cancel(|_, _window, cx| {
|
|
||||||
ClientKeys::global(cx).update(cx, |this, cx| {
|
|
||||||
this.new_keys(cx);
|
|
||||||
});
|
|
||||||
// true: Close modal
|
|
||||||
true
|
|
||||||
})
|
|
||||||
.on_ok(|_, window, cx| {
|
|
||||||
ClientKeys::global(cx).update(cx, |this, cx| {
|
|
||||||
this.load(window, cx);
|
|
||||||
});
|
|
||||||
// true: Close modal
|
|
||||||
true
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
@@ -301,8 +255,13 @@ impl ChatSpace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn on_sign_out(&mut self, _ev: &Logout, window: &mut Window, cx: &mut Context<Self>) {
|
fn on_sign_out(&mut self, _ev: &Logout, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
|
let registry = Registry::global(cx);
|
||||||
let identity = Identity::global(cx);
|
let identity = Identity::global(cx);
|
||||||
// TODO: save current session?
|
|
||||||
|
registry.update(cx, |this, cx| {
|
||||||
|
this.reset(cx);
|
||||||
|
});
|
||||||
|
|
||||||
identity.update(cx, |this, cx| {
|
identity.update(cx, |this, cx| {
|
||||||
this.unload(window, cx);
|
this.unload(window, cx);
|
||||||
});
|
});
|
||||||
@@ -326,6 +285,56 @@ impl ChatSpace {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_client_keys_modal(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
|
let title = SharedString::new(t!("startup.client_keys_warning"));
|
||||||
|
let desc = SharedString::new(t!("startup.client_keys_desc"));
|
||||||
|
|
||||||
|
window.open_modal(cx, move |this, _window, cx| {
|
||||||
|
this.overlay_closable(false)
|
||||||
|
.show_close(false)
|
||||||
|
.keyboard(false)
|
||||||
|
.confirm()
|
||||||
|
.button_props(
|
||||||
|
ModalButtonProps::default()
|
||||||
|
.cancel_text(t!("startup.create_new_keys"))
|
||||||
|
.ok_text(t!("common.allow")),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.w_full()
|
||||||
|
.h_40()
|
||||||
|
.flex()
|
||||||
|
.flex_col()
|
||||||
|
.gap_1()
|
||||||
|
.items_center()
|
||||||
|
.justify_center()
|
||||||
|
.text_center()
|
||||||
|
.text_sm()
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.font_semibold()
|
||||||
|
.text_color(cx.theme().text_muted)
|
||||||
|
.child(title.clone()),
|
||||||
|
)
|
||||||
|
.child(desc.clone()),
|
||||||
|
)
|
||||||
|
.on_cancel(|_, _window, cx| {
|
||||||
|
ClientKeys::global(cx).update(cx, |this, cx| {
|
||||||
|
this.new_keys(cx);
|
||||||
|
});
|
||||||
|
// true: Close modal
|
||||||
|
true
|
||||||
|
})
|
||||||
|
.on_ok(|_, window, cx| {
|
||||||
|
ClientKeys::global(cx).update(cx, |this, cx| {
|
||||||
|
this.load(window, cx);
|
||||||
|
});
|
||||||
|
// true: Close modal
|
||||||
|
true
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn render_titlebar_left_side(
|
fn render_titlebar_left_side(
|
||||||
&mut self,
|
&mut self,
|
||||||
_window: &mut Window,
|
_window: &mut Window,
|
||||||
|
|||||||
@@ -358,8 +358,6 @@ async fn handle_nostr_notifications(
|
|||||||
let client = nostr_client();
|
let client = nostr_client();
|
||||||
let auto_close = SubscribeAutoCloseOptions::default().exit_policy(ReqExitPolicy::ExitOnEOSE);
|
let auto_close = SubscribeAutoCloseOptions::default().exit_policy(ReqExitPolicy::ExitOnEOSE);
|
||||||
let mut notifications = client.notifications();
|
let mut notifications = client.notifications();
|
||||||
let mut processed_relay_list = false;
|
|
||||||
let mut processed_inbox_relay = false;
|
|
||||||
|
|
||||||
while let Ok(notification) = notifications.recv().await {
|
while let Ok(notification) = notifications.recv().await {
|
||||||
let RelayPoolNotification::Message { message, .. } = notification else {
|
let RelayPoolNotification::Message { message, .. } = notification else {
|
||||||
@@ -379,11 +377,6 @@ async fn handle_nostr_notifications(
|
|||||||
Kind::RelayList => {
|
Kind::RelayList => {
|
||||||
// Get metadata for event's pubkey that matches the current user's pubkey
|
// Get metadata for event's pubkey that matches the current user's pubkey
|
||||||
if let Ok(true) = is_from_current_user(&event).await {
|
if let Ok(true) = is_from_current_user(&event).await {
|
||||||
match processed_relay_list {
|
|
||||||
true => continue,
|
|
||||||
false => processed_relay_list = true,
|
|
||||||
}
|
|
||||||
|
|
||||||
let sub_id = SubscriptionId::new("metadata");
|
let sub_id = SubscriptionId::new("metadata");
|
||||||
let filter = Filter::new()
|
let filter = Filter::new()
|
||||||
.kinds(vec![Kind::Metadata, Kind::ContactList, Kind::InboxRelays])
|
.kinds(vec![Kind::Metadata, Kind::ContactList, Kind::InboxRelays])
|
||||||
@@ -398,11 +391,6 @@ async fn handle_nostr_notifications(
|
|||||||
}
|
}
|
||||||
Kind::InboxRelays => {
|
Kind::InboxRelays => {
|
||||||
if let Ok(true) = is_from_current_user(&event).await {
|
if let Ok(true) = is_from_current_user(&event).await {
|
||||||
match processed_inbox_relay {
|
|
||||||
true => continue,
|
|
||||||
false => processed_inbox_relay = true,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get all inbox relays
|
// Get all inbox relays
|
||||||
let relays = event
|
let relays = event
|
||||||
.tags
|
.tags
|
||||||
@@ -423,8 +411,6 @@ async fn handle_nostr_notifications(
|
|||||||
_ = client.connect_relay(relay).await;
|
_ = client.connect_relay(relay).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
log::info!("Connected to messaging relays");
|
|
||||||
|
|
||||||
let filter = Filter::new().kind(Kind::GiftWrap).pubkey(event.pubkey);
|
let filter = Filter::new().kind(Kind::GiftWrap).pubkey(event.pubkey);
|
||||||
let sub_id = SubscriptionId::new("gift-wrap");
|
let sub_id = SubscriptionId::new("gift-wrap");
|
||||||
|
|
||||||
@@ -436,7 +422,7 @@ async fn handle_nostr_notifications(
|
|||||||
.await
|
.await
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
log::info!("Subscribing to gift wrap events in: {relays:?}");
|
log::info!("Subscribing to messages in: {relays:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ pub fn nostr_client() -> &'static Client {
|
|||||||
.gossip(true)
|
.gossip(true)
|
||||||
.automatic_authentication(true)
|
.automatic_authentication(true)
|
||||||
.verify_subscriptions(false)
|
.verify_subscriptions(false)
|
||||||
// Sleep after idle for 20 seconds
|
// Sleep after idle for 30 seconds
|
||||||
.sleep_when_idle(SleepWhenIdle::Enabled {
|
.sleep_when_idle(SleepWhenIdle::Enabled {
|
||||||
timeout: Duration::from_secs(20),
|
timeout: Duration::from_secs(30),
|
||||||
});
|
});
|
||||||
|
|
||||||
ClientBuilder::default().database(lmdb).opts(opts).build()
|
ClientBuilder::default().database(lmdb).opts(opts).build()
|
||||||
|
|||||||
@@ -127,8 +127,9 @@ impl Identity {
|
|||||||
.kind(Kind::ApplicationSpecificData)
|
.kind(Kind::ApplicationSpecificData)
|
||||||
.identifier(ACCOUNT_D);
|
.identifier(ACCOUNT_D);
|
||||||
|
|
||||||
// Unset signer
|
// Reset the nostr client
|
||||||
client.unset_signer().await;
|
client.unset_signer().await;
|
||||||
|
client.unsubscribe_all().await;
|
||||||
|
|
||||||
// Delete account
|
// Delete account
|
||||||
client.database().delete(filter).await?;
|
client.database().delete(filter).await?;
|
||||||
@@ -257,7 +258,7 @@ impl Identity {
|
|||||||
this.set_public_key(None, window, cx);
|
this.set_public_key(None, window, cx);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
// Close modal
|
// true to close the modal
|
||||||
true
|
true
|
||||||
})
|
})
|
||||||
.on_ok(move |_, window, cx| {
|
.on_ok(move |_, window, cx| {
|
||||||
@@ -271,7 +272,7 @@ impl Identity {
|
|||||||
this.verify_keys(enc, password, weak_error, window, cx);
|
this.verify_keys(enc, password, weak_error, window, cx);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
// false to keep the modal open
|
||||||
false
|
false
|
||||||
})
|
})
|
||||||
.child(
|
.child(
|
||||||
@@ -321,25 +322,33 @@ impl Identity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt the password in the background to prevent blocking the main thread
|
// Decrypt the password in the background to prevent blocking the main thread
|
||||||
let task: Task<Option<SecretKey>> =
|
let task: Task<Result<SecretKey, Error>> = cx.background_spawn(async move {
|
||||||
cx.background_spawn(async move { enc.decrypt(&password).ok() });
|
let secret = enc.decrypt(&password)?;
|
||||||
|
Ok(secret)
|
||||||
|
});
|
||||||
|
|
||||||
cx.spawn_in(window, async move |this, cx| {
|
cx.spawn_in(window, async move |this, cx| {
|
||||||
if let Some(secret) = task.await {
|
match task.await {
|
||||||
cx.update(|window, cx| {
|
Ok(secret) => {
|
||||||
window.close_modal(cx);
|
cx.update(|window, cx| {
|
||||||
// Update user's signer with decrypted secret key
|
this.update(cx, |this, cx| {
|
||||||
this.update(cx, |this, cx| {
|
// Update user's signer with decrypted secret key
|
||||||
this.set_signer(Keys::new(secret), window, cx);
|
this.set_signer(Keys::new(secret), window, cx);
|
||||||
|
// Close the current modal
|
||||||
|
window.close_modal(cx);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
})
|
}
|
||||||
.ok();
|
Err(e) => {
|
||||||
} else {
|
error
|
||||||
_ = error.update(cx, |this, cx| {
|
.update(cx, |this, cx| {
|
||||||
*this = Some("Invalid password".into());
|
*this = Some(e.to_string().into());
|
||||||
cx.notify();
|
cx.notify();
|
||||||
});
|
})
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
@@ -597,15 +606,12 @@ async fn get_nip65_relays(public_key: PublicKey) -> Result<(), Error> {
|
|||||||
let client = nostr_client();
|
let client = nostr_client();
|
||||||
let opts = SubscribeAutoCloseOptions::default().exit_policy(ReqExitPolicy::ExitOnEOSE);
|
let opts = SubscribeAutoCloseOptions::default().exit_policy(ReqExitPolicy::ExitOnEOSE);
|
||||||
let sub_id = SubscriptionId::new("nip65-relays");
|
let sub_id = SubscriptionId::new("nip65-relays");
|
||||||
|
|
||||||
let filter = Filter::new()
|
let filter = Filter::new()
|
||||||
.kind(Kind::RelayList)
|
.kind(Kind::RelayList)
|
||||||
.author(public_key)
|
.author(public_key)
|
||||||
.limit(1);
|
.limit(1);
|
||||||
|
|
||||||
if client.subscription(&sub_id).await.is_empty() {
|
client.subscribe_with_id(sub_id, filter, Some(opts)).await?;
|
||||||
client.subscribe_with_id(sub_id, filter, Some(opts)).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,12 @@ impl Registry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn reset(&mut self, cx: &mut Context<Self>) {
|
||||||
|
self.rooms = vec![];
|
||||||
|
self.loading = true;
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn set_persons_from_task(
|
pub(crate) fn set_persons_from_task(
|
||||||
&mut self,
|
&mut self,
|
||||||
task: Task<Result<Vec<Profile>, Error>>,
|
task: Task<Result<Vec<Profile>, Error>>,
|
||||||
|
|||||||
Reference in New Issue
Block a user