diff --git a/Cargo.lock b/Cargo.lock
index 0509fa7..8777f3d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -94,6 +94,56 @@ dependencies = [
"libc",
]
+[[package]]
+name = "anstream"
+version = "0.6.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "is_terminal_polyfill",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
+dependencies = [
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
+dependencies = [
+ "anstyle",
+ "once_cell_polyfill",
+ "windows-sys 0.61.2",
+]
+
[[package]]
name = "anyhow"
version = "1.0.100"
@@ -1097,6 +1147,46 @@ dependencies = [
"libloading",
]
+[[package]]
+name = "clap"
+version = "4.5.57"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6899ea499e3fb9305a65d5ebf6e3d2248c5fab291f300ad0a704fbe142eae31a"
+dependencies = [
+ "clap_builder",
+ "clap_derive",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.5.57"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b12c8b680195a62a8364d16b8447b01b6c2c8f9aaf68bee653be34d4245e238"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "clap_lex",
+ "strsim",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.5.55"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5"
+dependencies = [
+ "heck 0.5.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.7.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32"
+
[[package]]
name = "cmake"
version = "0.1.57"
@@ -1192,6 +1282,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
+[[package]]
+name = "colorchoice"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
+
[[package]]
name = "combine"
version = "4.6.7"
@@ -3274,6 +3370,12 @@ dependencies = [
"once_cell",
]
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
+
[[package]]
name = "itertools"
version = "0.13.0"
@@ -4246,6 +4348,12 @@ version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+[[package]]
+name = "once_cell_polyfill"
+version = "1.70.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
+
[[package]]
name = "oneshot"
version = "0.1.13"
@@ -4508,6 +4616,20 @@ dependencies = [
"state",
]
+[[package]]
+name = "petname"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9cd31dcfdbbd7431a807ef4df6edd6473228e94d5c805e8cf671227a21bad068"
+dependencies = [
+ "anyhow",
+ "clap",
+ "itertools 0.14.0",
+ "proc-macro2",
+ "quote",
+ "rand 0.8.5",
+]
+
[[package]]
name = "phf"
version = "0.11.3"
@@ -6074,6 +6196,7 @@ dependencies = [
"nostr-connect",
"nostr-lmdb",
"nostr-sdk",
+ "petname",
"reqwest",
"rustls",
"serde",
@@ -6097,6 +6220,12 @@ dependencies = [
"float-cmp",
]
+[[package]]
+name = "strsim"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+
[[package]]
name = "strum"
version = "0.26.3"
@@ -7102,6 +7231,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
+[[package]]
+name = "utf8parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+
[[package]]
name = "util"
version = "0.1.0"
diff --git a/assets/icons/shield.svg b/assets/icons/shield.svg
new file mode 100644
index 0000000..dacf3b7
--- /dev/null
+++ b/assets/icons/shield.svg
@@ -0,0 +1,3 @@
+
diff --git a/crates/chat/src/lib.rs b/crates/chat/src/lib.rs
index 6a38bd6..ea02060 100644
--- a/crates/chat/src/lib.rs
+++ b/crates/chat/src/lib.rs
@@ -104,7 +104,7 @@ impl ChatRegistry {
let device_signer = device.read(cx).device_signer.clone();
// A flag to indicate if the registry is loading
- let tracking_flag = Arc::new(AtomicBool::new(true));
+ let tracking_flag = Arc::new(AtomicBool::new(false));
// Channel for communication between nostr and gpui
let (tx, rx) = flume::bounded::(2048);
@@ -166,7 +166,7 @@ impl ChatRegistry {
Self {
rooms: vec![],
- loading: true,
+ loading: false,
sender: tx.clone(),
tracking_flag,
tracking: None,
@@ -253,37 +253,18 @@ impl ChatRegistry {
/// Tracking the status of unwrapping gift wrap events.
fn tracking(&mut self, cx: &mut Context) {
- let nostr = NostrRegistry::global(cx);
- let client = nostr.read(cx).client();
-
let status = self.tracking_flag.clone();
let tx = self.sender.clone();
self.tracking = Some(cx.background_spawn(async move {
let loop_duration = Duration::from_secs(12);
- let mut total_loops = 0;
loop {
- if client.has_signer().await {
- total_loops += 1;
-
- if status.load(Ordering::Acquire) {
- // Reset gift wrap processing flag
- _ = status.compare_exchange(
- true,
- false,
- Ordering::Release,
- Ordering::Relaxed,
- );
- tx.send_async(NostrEvent::Unwrapping(true)).await.ok();
- } else {
- // Wait at least 2 loops to prevent exiting early while events are still being processed
- if total_loops >= 2 {
- tx.send_async(NostrEvent::Unwrapping(false)).await.ok();
- // Reset the counter
- total_loops = 0;
- }
- }
+ if status.load(Ordering::Acquire) {
+ _ = status.compare_exchange(true, false, Ordering::Release, Ordering::Relaxed);
+ tx.send_async(NostrEvent::Unwrapping(true)).await.ok();
+ } else {
+ tx.send_async(NostrEvent::Unwrapping(false)).await.ok();
}
smol::Timer::after(loop_duration).await;
}
diff --git a/crates/common/src/display.rs b/crates/common/src/display.rs
index 3f967ff..ab7c215 100644
--- a/crates/common/src/display.rs
+++ b/crates/common/src/display.rs
@@ -12,6 +12,7 @@ const SECONDS_IN_MINUTE: i64 = 60;
const MINUTES_IN_HOUR: i64 = 60;
const HOURS_IN_DAY: i64 = 24;
const DAYS_IN_MONTH: i64 = 30;
+const IMAGE_RESIZER: &str = "https://wsrv.nl";
pub trait RenderedProfile {
fn avatar(&self) -> SharedString;
@@ -24,7 +25,12 @@ impl RenderedProfile for Profile {
.picture
.as_ref()
.filter(|picture| !picture.is_empty())
- .map(|picture| picture.into())
+ .map(|picture| {
+ let url = format!(
+ "{IMAGE_RESIZER}/?url={picture}&w=100&h=100&fit=cover&mask=circle&n=-1"
+ );
+ url.into()
+ })
.unwrap_or_else(|| "brand/avatar.png".into())
}
diff --git a/crates/coop/src/dialogs/compose.rs b/crates/coop/src/dialogs/compose.rs
deleted file mode 100644
index f7af756..0000000
--- a/crates/coop/src/dialogs/compose.rs
+++ /dev/null
@@ -1,510 +0,0 @@
-use std::ops::Range;
-use std::time::Duration;
-
-use anyhow::{anyhow, Error};
-use chat::{ChatRegistry, Room};
-use common::{TextUtils, BOOTSTRAP_RELAYS};
-use gpui::prelude::FluentBuilder;
-use gpui::{
- div, px, relative, rems, uniform_list, App, AppContext, Context, Entity, InteractiveElement,
- IntoElement, ParentElement, Render, RetainAllImageCache, SharedString,
- StatefulInteractiveElement, Styled, Subscription, Task, Window,
-};
-use gpui_tokio::Tokio;
-use nostr_sdk::prelude::*;
-use person::PersonRegistry;
-use smallvec::{smallvec, SmallVec};
-use state::{NostrAddress, NostrRegistry};
-use theme::ActiveTheme;
-use ui::avatar::Avatar;
-use ui::button::{Button, ButtonVariants};
-use ui::input::{InputEvent, InputState, TextInput};
-use ui::modal::ModalButtonProps;
-use ui::notification::Notification;
-use ui::{h_flex, v_flex, Disableable, Icon, IconName, Sizable, StyledExt, WindowExtension};
-
-pub fn compose_button() -> impl IntoElement {
- div().child(
- Button::new("compose")
- .icon(IconName::Plus)
- .ghost_alt()
- .cta()
- .small()
- .rounded()
- .on_click(move |_, window, cx| {
- let compose = cx.new(|cx| Compose::new(window, cx));
- let weak_view = compose.downgrade();
-
- window.open_modal(cx, move |modal, _window, cx| {
- let weak_view = weak_view.clone();
- let label = if compose.read(cx).selected(cx).len() > 1 {
- SharedString::from("Create Group DM")
- } else {
- SharedString::from("Create DM")
- };
-
- modal
- .alert()
- .overlay_closable(true)
- .keyboard(true)
- .show_close(true)
- .button_props(ModalButtonProps::default().ok_text(label))
- .title(SharedString::from("Direct Messages"))
- .child(compose.clone())
- .on_ok(move |_, window, cx| {
- weak_view
- .update(cx, |this, cx| {
- this.submit(window, cx);
- })
- .ok();
-
- // false to prevent the modal from closing
- false
- })
- })
- }),
- )
-}
-
-#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
-struct Contact {
- public_key: PublicKey,
- selected: bool,
-}
-
-impl AsRef for Contact {
- fn as_ref(&self) -> &PublicKey {
- &self.public_key
- }
-}
-
-impl Contact {
- pub fn new(public_key: PublicKey) -> Self {
- Self {
- public_key,
- selected: false,
- }
- }
-
- pub fn selected(mut self) -> Self {
- self.selected = true;
- self
- }
-}
-
-pub struct Compose {
- /// Input for the room's subject
- title_input: Entity,
-
- /// Input for the room's members
- user_input: Entity,
-
- /// User's contacts
- contacts: Entity>,
-
- /// Error message
- error_message: Entity