From 85c485a4e49cf1afeca99142f3e6f1309fb225d5 Mon Sep 17 00:00:00 2001 From: reya Date: Tue, 18 Feb 2025 16:43:30 +0700 Subject: [PATCH] feat: refactor async task and remove tokio as dep --- Cargo.lock | 315 ++++++-------- Cargo.toml | 9 +- crates/app/Cargo.toml | 5 +- crates/app/src/main.rs | 543 +++++++++++------------- crates/app/src/views/app.rs | 1 - crates/app/src/views/chat.rs | 1 - crates/app/src/views/contacts.rs | 1 - crates/app/src/views/onboarding.rs | 1 - crates/app/src/views/profile.rs | 1 - crates/app/src/views/relays.rs | 1 - crates/app/src/views/sidebar/compose.rs | 1 - crates/chats/Cargo.toml | 3 +- crates/chats/src/registry.rs | 3 +- crates/common/src/constants.rs | 2 - crates/common/src/utils.rs | 3 +- crates/state/Cargo.toml | 1 - crates/state/src/lib.rs | 14 +- 17 files changed, 421 insertions(+), 484 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 29aa5a6..8268aee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,7 +49,7 @@ dependencies = [ "const-random", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -195,20 +195,20 @@ dependencies = [ [[package]] name = "ashpd" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9c39d707614dbcc6bed00015539f488d8e3fe3e66ed60961efc0c90f4b380b3" +checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df" dependencies = [ "async-fs", "async-net", "enumflags2", "futures-channel", "futures-util", - "rand", + "rand 0.9.0", "serde", "serde_repr", "url", - "zbus 5.5.0", + "zbus", ] [[package]] @@ -741,9 +741,9 @@ dependencies = [ [[package]] name = "built" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73848a43c5d63a1251d17adf6c2bf78aa94830e60a335a95eeea45d6ba9e1e4d" +checksum = "56ed6191a7e78c36abdb16ab65341eefd73d64d303fffccdbb00d51e4205967b" [[package]] name = "bumpalo" @@ -930,6 +930,7 @@ dependencies = [ "gpui", "itertools 0.13.0", "nostr-sdk", + "oneshot", "smol", "state", ] @@ -972,9 +973,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.29" +version = "4.5.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acebd8ad879283633b343856142139f2da2317c96b05b4dd6181c61e2480184" +checksum = "92b7b18d71fad5313a1e320fa9897994228ce274b60faa4d694fe0ea89cd9e6d" dependencies = [ "clap_builder", "clap_derive", @@ -982,9 +983,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.29" +version = "4.5.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ba32cbda51c7e1dfd49acc1457ba1a7dec5b64fe360e828acb13ca8dc9c2f9" +checksum = "a35db2071778a7344791a4fb4f95308b5673d219dee3ae348b86642574ecc90c" dependencies = [ "anstream", "anstyle", @@ -1092,7 +1093,7 @@ dependencies = [ [[package]] name = "collections" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e60123bbdc58c37ad5ec60429fc730d5f9b8fd90" +source = "git+https://github.com/zed-industries/zed#b4fc127e492924427b6f0afcad03b144b632152b" dependencies = [ "indexmap", "rustc-hash 2.1.1", @@ -1177,11 +1178,13 @@ dependencies = [ "chats", "common", "dirs 5.0.1", + "futures", "gpui", "itertools 0.13.0", "log", "nostr-connect", "nostr-sdk", + "oneshot", "reqwest_client", "rust-embed", "rustls", @@ -1189,7 +1192,6 @@ dependencies = [ "serde_json", "smol", "state", - "tokio", "tracing-subscriber", "ui", ] @@ -1367,15 +1369,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "typenum", ] [[package]] name = "ctor" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "952d7c24b2615675db90c2201742b49c314dea9fa56c6688cbf8c4dee2b2553f" +checksum = "035a5c3c87da8be7a0e5ebd6fbabcccd8651a59c27197096d1dfd74f312aaee5" +dependencies = [ + "ctor-proc-macro", +] + +[[package]] +name = "ctor-proc-macro" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "107adb396b2d8e7766e79151083ce1cc624b51dfd1c23e0429c50226bba693eb" [[package]] name = "data-encoding" @@ -1405,7 +1416,7 @@ dependencies = [ [[package]] name = "derive_refineable" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e60123bbdc58c37ad5ec60429fc730d5f9b8fd90" +source = "git+https://github.com/zed-industries/zed#b4fc127e492924427b6f0afcad03b144b632152b" dependencies = [ "proc-macro2", "quote", @@ -2124,7 +2135,7 @@ dependencies = [ [[package]] name = "gpui" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e60123bbdc58c37ad5ec60429fc730d5f9b8fd90" +source = "git+https://github.com/zed-industries/zed#b4fc127e492924427b6f0afcad03b144b632152b" dependencies = [ "anyhow", "as-raw-xcb-connection", @@ -2174,7 +2185,7 @@ dependencies = [ "pathfinder_geometry", "postage", "profiling", - "rand", + "rand 0.8.5", "raw-window-handle", "refineable", "resvg", @@ -2211,7 +2222,7 @@ dependencies = [ [[package]] name = "gpui_macros" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e60123bbdc58c37ad5ec60429fc730d5f9b8fd90" +source = "git+https://github.com/zed-industries/zed#b4fc127e492924427b6f0afcad03b144b632152b" dependencies = [ "proc-macro2", "quote", @@ -2434,7 +2445,7 @@ dependencies = [ [[package]] name = "http_client" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e60123bbdc58c37ad5ec60429fc730d5f9b8fd90" +source = "git+https://github.com/zed-industries/zed#b4fc127e492924427b6f0afcad03b144b632152b" dependencies = [ "anyhow", "bytes", @@ -3121,7 +3132,7 @@ dependencies = [ [[package]] name = "media" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e60123bbdc58c37ad5ec60429fc730d5f9b8fd90" +source = "git+https://github.com/zed-industries/zed#b4fc127e492924427b6f0afcad03b144b632152b" dependencies = [ "anyhow", "bindgen 0.70.1", @@ -3300,7 +3311,7 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" [[package]] name = "nostr" version = "0.39.0" -source = "git+https://github.com/rust-nostr/nostr#43b9080a5b9f24466bd892f80c22ae4845d1fab1" +source = "git+https://github.com/rust-nostr/nostr#a269f7c937cb6c220023795b07686a5d7e337fb0" dependencies = [ "aes", "base64", @@ -3312,7 +3323,6 @@ dependencies = [ "chacha20poly1305", "getrandom 0.2.15", "instant", - "js-sys", "reqwest 0.12.12", "scrypt", "secp256k1", @@ -3320,15 +3330,12 @@ dependencies = [ "serde_json", "unicode-normalization", "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", ] [[package]] name = "nostr-connect" version = "0.39.0" -source = "git+https://github.com/rust-nostr/nostr#43b9080a5b9f24466bd892f80c22ae4845d1fab1" +source = "git+https://github.com/rust-nostr/nostr#a269f7c937cb6c220023795b07686a5d7e337fb0" dependencies = [ "async-utility", "nostr", @@ -3340,7 +3347,7 @@ dependencies = [ [[package]] name = "nostr-database" version = "0.39.0" -source = "git+https://github.com/rust-nostr/nostr#43b9080a5b9f24466bd892f80c22ae4845d1fab1" +source = "git+https://github.com/rust-nostr/nostr#a269f7c937cb6c220023795b07686a5d7e337fb0" dependencies = [ "flatbuffers", "lru", @@ -3351,7 +3358,7 @@ dependencies = [ [[package]] name = "nostr-lmdb" version = "0.39.0" -source = "git+https://github.com/rust-nostr/nostr#43b9080a5b9f24466bd892f80c22ae4845d1fab1" +source = "git+https://github.com/rust-nostr/nostr#a269f7c937cb6c220023795b07686a5d7e337fb0" dependencies = [ "async-utility", "heed", @@ -3364,7 +3371,7 @@ dependencies = [ [[package]] name = "nostr-relay-pool" version = "0.39.0" -source = "git+https://github.com/rust-nostr/nostr#43b9080a5b9f24466bd892f80c22ae4845d1fab1" +source = "git+https://github.com/rust-nostr/nostr#a269f7c937cb6c220023795b07686a5d7e337fb0" dependencies = [ "async-utility", "async-wsocket", @@ -3381,7 +3388,7 @@ dependencies = [ [[package]] name = "nostr-sdk" version = "0.39.0" -source = "git+https://github.com/rust-nostr/nostr#43b9080a5b9f24466bd892f80c22ae4845d1fab1" +source = "git+https://github.com/rust-nostr/nostr#a269f7c937cb6c220023795b07686a5d7e337fb0" dependencies = [ "async-utility", "nostr", @@ -3438,7 +3445,7 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand", + "rand 0.8.5", "serde", "smallvec", "zeroize", @@ -3741,16 +3748,22 @@ version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +[[package]] +name = "oneshot" +version = "0.1.10" +source = "git+https://github.com/faern/oneshot#d36ef86c3cbcc54764391ae89805c160696cf57c" + [[package]] name = "oo7" -version = "0.3.3" -source = "git+https://github.com/zed-industries/oo7?branch=avoid-crypto-panic#9d5d5fcd7e4e0add9b420ffb58f67661b0b37568" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d939e731a8ef5d7809bedad43a7b4220d05093d5c76f7ee9c5289092bcb7bba4" dependencies = [ "aes", + "ashpd", "async-fs", "async-io", "async-lock", - "async-net", "blocking", "cbc", "cipher", @@ -3758,19 +3771,21 @@ dependencies = [ "endi", "futures-lite 2.6.0", "futures-util", + "getrandom 0.3.1", "hkdf", "hmac", "md-5", "num", "num-bigint-dig", "pbkdf2", - "rand", + "rand 0.9.0", "serde", "sha2", "subtle", - "zbus 4.4.0", + "zbus", + "zbus_macros", "zeroize", - "zvariant 4.2.0", + "zvariant", ] [[package]] @@ -3864,7 +3879,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -3932,7 +3947,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", - "rand", + "rand 0.8.5", ] [[package]] @@ -4080,7 +4095,7 @@ version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -4197,7 +4212,7 @@ checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" dependencies = [ "bytes", "getrandom 0.2.15", - "rand", + "rand 0.8.5", "ring", "rustc-hash 2.1.1", "rustls", @@ -4239,8 +4254,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.1", + "zerocopy 0.8.18", ] [[package]] @@ -4250,7 +4276,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.1", ] [[package]] @@ -4262,6 +4298,16 @@ dependencies = [ "getrandom 0.2.15", ] +[[package]] +name = "rand_core" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a88e0da7a2c97baa202165137c158d0a2e824ac465d13d81046727b34cb247d3" +dependencies = [ + "getrandom 0.3.1", + "zerocopy 0.8.18", +] + [[package]] name = "random_name_generator" version = "0.3.6" @@ -4273,7 +4319,7 @@ dependencies = [ "clap", "lazy_static", "log", - "rand", + "rand 0.8.5", "regex", "rust-embed", "titlecase", @@ -4311,8 +4357,8 @@ dependencies = [ "once_cell", "paste", "profiling", - "rand", - "rand_chacha", + "rand 0.8.5", + "rand_chacha 0.3.1", "simd_helpers", "system-deps", "thiserror 1.0.69", @@ -4406,7 +4452,7 @@ dependencies = [ [[package]] name = "refineable" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e60123bbdc58c37ad5ec60429fc730d5f9b8fd90" +source = "git+https://github.com/zed-industries/zed#b4fc127e492924427b6f0afcad03b144b632152b" dependencies = [ "derive_refineable", ] @@ -4535,13 +4581,14 @@ dependencies = [ [[package]] name = "reqwest_client" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e60123bbdc58c37ad5ec60429fc730d5f9b8fd90" +source = "git+https://github.com/zed-industries/zed#b4fc127e492924427b6f0afcad03b144b632152b" dependencies = [ "anyhow", "bytes", "futures", "http_client", "log", + "regex", "reqwest 0.12.8", "serde", "smol", @@ -4868,7 +4915,7 @@ version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" dependencies = [ - "rand", + "rand 0.8.5", "secp256k1-sys", "serde", ] @@ -4914,7 +4961,7 @@ checksum = "c2fdfc24bc566f839a2da4c4295b82db7d25a24253867d5c64355abb5799bdbe" [[package]] name = "semantic_version" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e60123bbdc58c37ad5ec60429fc730d5f9b8fd90" +source = "git+https://github.com/zed-industries/zed#b4fc127e492924427b6f0afcad03b144b632152b" dependencies = [ "anyhow", "serde", @@ -5123,9 +5170,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "smol" @@ -5184,7 +5231,6 @@ version = "0.0.0" dependencies = [ "dirs 5.0.1", "nostr-sdk", - "tokio", ] [[package]] @@ -5239,7 +5285,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sum_tree" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e60123bbdc58c37ad5ec60429fc730d5f9b8fd90" +source = "git+https://github.com/zed-industries/zed#b4fc127e492924427b6f0afcad03b144b632152b" dependencies = [ "arrayvec", "log", @@ -5472,9 +5518,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.16.0" +version = "3.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91" +checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" dependencies = [ "cfg-if", "fastrand 2.3.0", @@ -5646,9 +5692,7 @@ dependencies = [ "bytes", "libc", "mio", - "parking_lot", "pin-project-lite", - "signal-hook-registry", "socket2", "tokio-macros", "windows-sys 0.52.0", @@ -5858,7 +5902,7 @@ dependencies = [ "http", "httparse", "log", - "rand", + "rand 0.8.5", "rustls", "rustls-pki-types", "sha1", @@ -6067,7 +6111,7 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "util" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e60123bbdc58c37ad5ec60429fc730d5f9b8fd90" +source = "git+https://github.com/zed-industries/zed#b4fc127e492924427b6f0afcad03b144b632152b" dependencies = [ "anyhow", "async-fs", @@ -6092,9 +6136,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced87ca4be083373936a67f8de945faa23b6b42384bd5b64434850802c6dccd0" +checksum = "8c1f41ffb7cf259f1ecc2876861a17e7142e63ead296f671f81f6ae85903e0d6" dependencies = [ "getrandom 0.3.1", "serde", @@ -6967,44 +7011,6 @@ dependencies = [ "synstructure", ] -[[package]] -name = "zbus" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" -dependencies = [ - "async-broadcast", - "async-executor", - "async-fs", - "async-io", - "async-lock", - "async-process", - "async-recursion", - "async-task", - "async-trait", - "blocking", - "enumflags2", - "event-listener", - "futures-core", - "futures-sink", - "futures-util", - "hex", - "nix", - "ordered-stream", - "rand", - "serde", - "serde_repr", - "sha1", - "static_assertions", - "tracing", - "uds_windows", - "windows-sys 0.52.0", - "xdg-home", - "zbus_macros 4.4.0", - "zbus_names 3.0.0", - "zvariant 4.2.0", -] - [[package]] name = "zbus" version = "5.5.0" @@ -7036,22 +7042,9 @@ dependencies = [ "windows-sys 0.59.0", "winnow", "xdg-home", - "zbus_macros 5.5.0", - "zbus_names 4.2.0", - "zvariant 5.4.0", -] - -[[package]] -name = "zbus_macros" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.98", - "zvariant_utils 2.1.0", + "zbus_macros", + "zbus_names", + "zvariant", ] [[package]] @@ -7064,20 +7057,9 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.98", - "zbus_names 4.2.0", - "zvariant 5.4.0", - "zvariant_utils 3.2.0", -] - -[[package]] -name = "zbus_names" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" -dependencies = [ - "serde", - "static_assertions", - "zvariant 4.2.0", + "zbus_names", + "zvariant", + "zvariant_utils", ] [[package]] @@ -7089,7 +7071,7 @@ dependencies = [ "serde", "static_assertions", "winnow", - "zvariant 5.4.0", + "zvariant", ] [[package]] @@ -7105,7 +7087,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "byteorder", - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79386d31a42a4996e3336b0919ddb90f81112af416270cff95b5f5af22b839c2" +dependencies = [ + "zerocopy-derive 0.8.18", ] [[package]] @@ -7119,6 +7110,17 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "zerocopy-derive" +version = "0.8.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76331675d372f91bf8d17e13afbd5fe639200b73d01f0fc748bb059f9cca2db7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + [[package]] name = "zerofrom" version = "0.1.5" @@ -7206,19 +7208,6 @@ dependencies = [ "zune-core", ] -[[package]] -name = "zvariant" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe" -dependencies = [ - "endi", - "enumflags2", - "serde", - "static_assertions", - "zvariant_derive 4.2.0", -] - [[package]] name = "zvariant" version = "5.4.0" @@ -7231,21 +7220,8 @@ dependencies = [ "static_assertions", "url", "winnow", - "zvariant_derive 5.4.0", - "zvariant_utils 3.2.0", -] - -[[package]] -name = "zvariant_derive" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.98", - "zvariant_utils 2.1.0", + "zvariant_derive", + "zvariant_utils", ] [[package]] @@ -7258,18 +7234,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.98", - "zvariant_utils 3.2.0", -] - -[[package]] -name = "zvariant_utils" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.98", + "zvariant_utils", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 62e399c..d73ae56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,11 +15,15 @@ nostr-relay-builder = { git = "https://github.com/rust-nostr/nostr" } nostr-connect = { git = "https://github.com/rust-nostr/nostr" } nostr-sdk = { git = "https://github.com/rust-nostr/nostr", features = [ "lmdb", - "all-nips", + "nip96", + "nip59", + "nip49", + "nip44", + "nip05", ] } smol = "2" -tokio = { version = "1", features = ["full"] } +oneshot = { git = "https://github.com/faern/oneshot" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" dirs = "5.0" @@ -30,6 +34,7 @@ tracing = "0.1.40" anyhow = "1.0.44" smallvec = "1.13.2" rust-embed = "8.5.0" +log = "0.4" [profile.release] strip = true diff --git a/crates/app/Cargo.toml b/crates/app/Cargo.toml index 3aad385..ba110c7 100644 --- a/crates/app/Cargo.toml +++ b/crates/app/Cargo.toml @@ -17,7 +17,6 @@ chats = { path = "../chats" } gpui.workspace = true reqwest_client.workspace = true -tokio.workspace = true nostr-connect.workspace = true nostr-sdk.workspace = true anyhow.workspace = true @@ -26,8 +25,10 @@ serde_json.workspace = true itertools.workspace = true dirs.workspace = true rust-embed.workspace = true +log.workspace = true smol.workspace = true +oneshot.workspace = true rustls = "0.23.23" +futures= "0.3" tracing-subscriber = { version = "0.3.18", features = ["fmt"] } -log = "0.4" diff --git a/crates/app/src/main.rs b/crates/app/src/main.rs index 3d35af1..862d6c6 100644 --- a/crates/app/src/main.rs +++ b/crates/app/src/main.rs @@ -1,12 +1,10 @@ use asset::Assets; -use async_utility::task::spawn; use chats::registry::ChatRegistry; use common::{ - constants::{ - ALL_MESSAGES_SUB_ID, APP_ID, APP_NAME, FAKE_SIG, KEYRING_SERVICE, NEW_MESSAGE_SUB_ID, - }, + constants::{ALL_MESSAGES_SUB_ID, APP_ID, APP_NAME, KEYRING_SERVICE, NEW_MESSAGE_SUB_ID}, profile::NostrProfile, }; +use futures::{select, FutureExt}; use gpui::{ actions, px, size, App, AppContext, Application, AsyncApp, Bounds, KeyBinding, Menu, MenuItem, WindowBounds, WindowKind, WindowOptions, @@ -16,20 +14,24 @@ use gpui::{point, SharedString, TitlebarOptions}; #[cfg(target_os = "linux")] use gpui::{WindowBackgroundAppearance, WindowDecorations}; use log::{error, info}; -use nostr_sdk::prelude::*; +use nostr_sdk::{ + pool::prelude::ReqExitPolicy, Client, Event, Filter, Keys, Kind, Metadata, PublicKey, + RelayMessage, RelayPoolNotification, SubscribeAutoCloseOptions, +}; +use nostr_sdk::{prelude::NostrEventsDatabaseExt, FromBech32, SubscriptionId}; +use smol::Timer; use state::{get_client, initialize_client}; -use std::{borrow::Cow, collections::HashSet, str::FromStr, sync::Arc, time::Duration}; -use tokio::sync::{mpsc, oneshot}; +use std::{collections::HashSet, mem, sync::Arc, time::Duration}; use ui::{theme::Theme, Root}; use views::{app, onboarding, startup}; mod asset; mod views; -actions!(main_menu, [Quit]); +actions!(coop, [Quit]); #[derive(Clone)] -pub enum Signal { +enum Signal { /// Receive event Event(Event), /// Receive EOSE @@ -37,214 +39,166 @@ pub enum Signal { } fn main() { - // Issue: https://github.com/snapview/tokio-tungstenite/issues/353 - rustls::crypto::ring::default_provider() - .install_default() - .expect("Failed to install rustls crypto provider"); + // Fix crash on startup + // TODO: why this is needed? + _ = rustls::crypto::ring::default_provider().install_default(); + // Enable logging + tracing_subscriber::fmt::init(); - // Initialize Nostr client - initialize_client(); + let (event_tx, event_rx) = smol::channel::bounded::(2048); + let (batch_tx, batch_rx) = smol::channel::bounded::>(100); - // Get client - let client = get_client(); - let (signal_tx, mut signal_rx) = tokio::sync::mpsc::channel::(2048); - - spawn(async move { - // Add some bootstrap relays - _ = client.add_relay("wss://relay.damus.io/").await; - _ = client.add_relay("wss://relay.primal.net/").await; - _ = client.add_relay("wss://user.kindpag.es/").await; - _ = client.add_relay("wss://directory.yabu.me/").await; - _ = client.add_discovery_relay("wss://relaydiscovery.com").await; - - // Connect to all relays - _ = client.connect().await - }); - - spawn(async move { - let (batch_tx, mut batch_rx) = mpsc::channel::>(20); - - async fn sync_metadata(client: &Client, buffer: &HashSet) { - let filter = Filter::new() - .authors(buffer.iter().copied()) - .kind(Kind::Metadata) - .limit(buffer.len()); - - if let Err(e) = client.sync(filter, &SyncOptions::default()).await { - error!("NEG error: {e}"); - } - } - - async fn process_batch(client: &Client, events: &[Cow<'_, Event>]) { - let sig = Signature::from_str(FAKE_SIG).unwrap(); - let mut buffer: HashSet = HashSet::with_capacity(20); - - for event in events.iter() { - if let Ok(UnwrappedGift { mut rumor, sender }) = - client.unwrap_gift_wrap(event).await - { - let pubkeys: HashSet = event.tags.public_keys().copied().collect(); - buffer.extend(pubkeys); - buffer.insert(sender); - - // Create event's ID is not exist - rumor.ensure_id(); - - // Save event to database - if let Some(id) = rumor.id { - let ev = Event::new( - id, - rumor.pubkey, - rumor.created_at, - rumor.kind, - rumor.tags, - rumor.content, - sig, - ); - - if let Err(e) = client.database().save_event(&ev).await { - error!("Save error: {}", e); - } - } - } - } - - sync_metadata(client, &buffer).await; - } - - // Spawn a thread to handle batch process - spawn(async move { - const BATCH_SIZE: usize = 20; - const BATCH_TIMEOUT: Duration = Duration::from_millis(200); - - let mut batch = Vec::with_capacity(20); - let mut timeout = Box::pin(tokio::time::sleep(BATCH_TIMEOUT)); - - loop { - tokio::select! { - event = batch_rx.recv() => { - if let Some(event) = event { - batch.push(event); - - if batch.len() == BATCH_SIZE { - process_batch(client, &batch).await; - batch.clear(); - timeout = Box::pin(tokio::time::sleep(BATCH_TIMEOUT)); - } - } else { - break; - } - } - _ = &mut timeout => { - if !batch.is_empty() { - process_batch(client, &batch).await; - batch.clear(); - } - timeout = Box::pin(tokio::time::sleep(BATCH_TIMEOUT)); - } - } - } - }); - - let all_id = SubscriptionId::new(ALL_MESSAGES_SUB_ID); - let new_id = SubscriptionId::new(NEW_MESSAGE_SUB_ID); - let sig = Signature::from_str(FAKE_SIG).unwrap(); - let mut notifications = client.notifications(); - - while let Ok(notification) = notifications.recv().await { - if let RelayPoolNotification::Message { message, .. } = notification { - match message { - RelayMessage::Event { - event, - subscription_id, - } => match event.kind { - Kind::GiftWrap => { - if new_id == *subscription_id { - if let Ok(UnwrappedGift { mut rumor, .. }) = - client.unwrap_gift_wrap(&event).await - { - // Compute event id if not exist - rumor.ensure_id(); - - if let Some(id) = rumor.id { - let ev = Event::new( - id, - rumor.pubkey, - rumor.created_at, - rumor.kind, - rumor.tags, - rumor.content, - sig, - ); - - // Save rumor to database to further query - if let Err(e) = client.database().save_event(&ev).await { - error!("Save error: {}", e); - } - - // Send new event to GPUI - if let Err(e) = signal_tx.send(Signal::Event(ev)).await { - error!("Send error: {}", e) - } - } - } - } - - if let Err(e) = batch_tx.send(event).await { - error!("Failed to add to batch: {}", e); - } - } - Kind::ContactList => { - let public_keys: HashSet<_> = - event.tags.public_keys().copied().collect(); - - sync_metadata(client, &public_keys).await; - } - _ => {} - }, - RelayMessage::EndOfStoredEvents(subscription_id) => { - if all_id == *subscription_id { - if let Err(e) = signal_tx.send(Signal::Eose).await { - error!("Failed to send eose: {}", e) - }; - } - } - _ => {} - } - } - } - }); + // Initialize nostr client + let client = initialize_client(); + // Initialize application let app = Application::new() .with_assets(Assets) .with_http_client(Arc::new(reqwest_client::ReqwestClient::new())); + // Connect to default relays + app.background_executor() + .spawn(async { + _ = client.add_relay("wss://relay.damus.io/").await; + _ = client.add_relay("wss://relay.primal.net/").await; + _ = client.add_relay("wss://user.kindpag.es/").await; + _ = client.add_relay("wss://purplepag.es/").await; + _ = client.add_discovery_relay("wss://relaydiscovery.com").await; + _ = client.connect().await + }) + .detach(); + + // Handle batch metadata + app.background_executor() + .spawn(async move { + const BATCH_SIZE: usize = 20; + const BATCH_TIMEOUT: Duration = Duration::from_millis(200); + + let mut batch: HashSet = HashSet::new(); + + loop { + let mut timeout = Box::pin(Timer::after(BATCH_TIMEOUT).fuse()); + + select! { + pubkeys = batch_rx.recv().fuse() => { + match pubkeys { + Ok(keys) => { + batch.extend(keys); + if batch.len() >= BATCH_SIZE { + sync_metadata(client, mem::take(&mut batch)).await; + } + } + Err(_) => break, + } + } + _ = timeout => { + if !batch.is_empty() { + sync_metadata(client, mem::take(&mut batch)).await; + } + } + } + } + }) + .detach(); + + // Handle notifications + app.background_executor() + .spawn(async move { + let rng_keys = Keys::generate(); + let all_id = SubscriptionId::new(ALL_MESSAGES_SUB_ID); + let new_id = SubscriptionId::new(NEW_MESSAGE_SUB_ID); + let mut notifications = client.notifications(); + + while let Ok(notification) = notifications.recv().await { + if let RelayPoolNotification::Message { message, .. } = notification { + match message { + RelayMessage::Event { + event, + subscription_id, + } => { + match event.kind { + Kind::GiftWrap => { + if let Ok(gift) = client.unwrap_gift_wrap(&event).await { + let mut pubkeys = vec![]; + + // Sign the rumor with the generated keys, + // this event will be used for internal only, + // and NEVER send to relays. + if let Ok(event) = gift.rumor.sign_with_keys(&rng_keys) { + pubkeys.extend(event.tags.public_keys()); + pubkeys.push(event.pubkey); + + // Save the event to the database, use for query directly. + if let Err(e) = + client.database().save_event(&event).await + { + error!("Failed to save event: {}", e); + } + + // Send all pubkeys to the batch + if let Err(e) = batch_tx.send(pubkeys).await { + error!("Failed to send pubkeys to batch: {}", e) + } + + // Send this event to the GPUI + if new_id == *subscription_id { + if let Err(e) = + event_tx.send(Signal::Event(event)).await + { + error!("Failed to send event to GPUI: {}", e) + } + } + } + } + } + Kind::ContactList => { + let pubkeys = + event.tags.public_keys().copied().collect::>(); + sync_metadata(client, pubkeys).await; + } + _ => {} + } + } + RelayMessage::EndOfStoredEvents(subscription_id) => { + if all_id == *subscription_id { + if let Err(e) = event_tx.send(Signal::Eose).await { + error!("Failed to send eose: {}", e) + }; + } + } + _ => {} + } + } + } + }) + .detach(); + + // Handle re-open window app.on_reopen(move |cx| { let client = get_client(); let (tx, rx) = oneshot::channel::>(); - cx.spawn(|mut cx| async move { - cx.background_spawn(async move { - if let Ok(signer) = client.signer().await { - if let Ok(public_key) = signer.get_public_key().await { - let metadata = if let Ok(Some(metadata)) = - client.database().metadata(public_key).await - { + cx.background_spawn(async move { + if let Ok(signer) = client.signer().await { + if let Ok(public_key) = signer.get_public_key().await { + let metadata = + if let Ok(Some(metadata)) = client.database().metadata(public_key).await { metadata } else { Metadata::new() }; - _ = tx.send(Some(NostrProfile::new(public_key, metadata))); - } else { - _ = tx.send(None); - } + _ = tx.send(Some(NostrProfile::new(public_key, metadata))); } else { _ = tx.send(None); } - }) - .detach(); + } else { + _ = tx.send(None); + } + }) + .detach(); + cx.spawn(|mut cx| async move { if let Ok(result) = rx.await { _ = restore_window(result, &mut cx).await; } @@ -269,118 +223,131 @@ fn main() { items: vec![MenuItem::action("Quit", Quit)], }]); - let opts = WindowOptions { - #[cfg(not(target_os = "linux"))] - titlebar: Some(TitlebarOptions { - title: Some(SharedString::new_static(APP_NAME)), - traffic_light_position: Some(point(px(9.0), px(9.0))), - appears_transparent: true, - }), - window_bounds: Some(WindowBounds::Windowed(Bounds::centered( - None, - size(px(900.0), px(680.0)), - cx, - ))), - #[cfg(target_os = "linux")] - window_background: WindowBackgroundAppearance::Transparent, - #[cfg(target_os = "linux")] - window_decorations: Some(WindowDecorations::Client), - kind: WindowKind::Normal, - ..Default::default() - }; + // Open window with default options + cx.open_window( + WindowOptions { + #[cfg(not(target_os = "linux"))] + titlebar: Some(TitlebarOptions { + title: Some(SharedString::new_static(APP_NAME)), + traffic_light_position: Some(point(px(9.0), px(9.0))), + appears_transparent: true, + }), + window_bounds: Some(WindowBounds::Windowed(Bounds::centered( + None, + size(px(900.0), px(680.0)), + cx, + ))), + #[cfg(target_os = "linux")] + window_background: WindowBackgroundAppearance::Transparent, + #[cfg(target_os = "linux")] + window_decorations: Some(WindowDecorations::Client), + kind: WindowKind::Normal, + ..Default::default() + }, + |window, cx| { + window.set_window_title(APP_NAME); + window.set_app_id(APP_ID); - cx.open_window(opts, |window, cx| { - window.set_window_title(APP_NAME); - window.set_app_id(APP_ID); + #[cfg(not(target_os = "linux"))] + window + .observe_window_appearance(|window, cx| { + Theme::sync_system_appearance(Some(window), cx); + }) + .detach(); - #[cfg(not(target_os = "linux"))] - window - .observe_window_appearance(|window, cx| { - Theme::sync_system_appearance(Some(window), cx); - }) - .detach(); + let handle = window.window_handle(); + let root = cx.new(|cx| Root::new(startup::init(window, cx).into(), window, cx)); - let handle = window.window_handle(); - let root = cx.new(|cx| Root::new(startup::init(window, cx).into(), window, cx)); + let task = cx.read_credentials(KEYRING_SERVICE); + let (tx, rx) = oneshot::channel::>(); - let task = cx.read_credentials(KEYRING_SERVICE); - let (tx, rx) = oneshot::channel::>(); + // Read credential in OS Keyring + cx.background_spawn(async { + let profile = if let Ok(Some((npub, secret))) = task.await { + let public_key = PublicKey::from_bech32(&npub).unwrap(); + let secret_hex = String::from_utf8(secret).unwrap(); + let keys = Keys::parse(&secret_hex).unwrap(); - // Read credential in OS Keyring - cx.background_spawn(async { - let profile = if let Ok(Some((npub, secret))) = task.await { - let public_key = PublicKey::from_bech32(&npub).unwrap(); - let secret_hex = String::from_utf8(secret).unwrap(); - let keys = Keys::parse(&secret_hex).unwrap(); + // Update nostr signer + _ = client.set_signer(keys).await; - // Update nostr signer - _ = client.set_signer(keys).await; - - // Get user's metadata - let metadata = - if let Ok(Some(metadata)) = client.database().metadata(public_key).await { + // Get user's metadata + let metadata = if let Ok(Some(metadata)) = + client.database().metadata(public_key).await + { metadata } else { Metadata::new() }; - Some(NostrProfile::new(public_key, metadata)) - } else { - None - }; + Some(NostrProfile::new(public_key, metadata)) + } else { + None + }; - _ = tx.send(profile) - }) - .detach(); + _ = tx.send(profile) + }) + .detach(); - // Set root view based on credential status - cx.spawn(|mut cx| async move { - if let Ok(Some(profile)) = rx.await { - _ = cx.update_window(handle, |_, window, cx| { - window.replace_root(cx, |window, cx| { - Root::new(app::init(profile, window, cx).into(), window, cx) - }); - }); - } else { - _ = cx.update_window(handle, |_, window, cx| { - window.replace_root(cx, |window, cx| { - Root::new(onboarding::init(window, cx).into(), window, cx) - }); - }); - } - }) - .detach(); - - // Listen for messages from the Nostr thread - cx.spawn(|cx| async move { - while let Some(signal) = signal_rx.recv().await { - match signal { - Signal::Eose => { - _ = cx.update(|cx| { - if let Some(chats) = ChatRegistry::global(cx) { - chats.update(cx, |this, cx| this.load_chat_rooms(cx)) - } + // Set root view based on credential status + cx.spawn(|mut cx| async move { + if let Ok(Some(profile)) = rx.await { + _ = cx.update_window(handle, |_, window, cx| { + window.replace_root(cx, |window, cx| { + Root::new(app::init(profile, window, cx).into(), window, cx) }); - } - Signal::Event(event) => { - _ = cx.update(|cx| { - if let Some(chats) = ChatRegistry::global(cx) { - chats.update(cx, |this, cx| this.push_message(event, cx)) - } + }); + } else { + _ = cx.update_window(handle, |_, window, cx| { + window.replace_root(cx, |window, cx| { + Root::new(onboarding::init(window, cx).into(), window, cx) }); - } + }); } - } - }) - .detach(); + }) + .detach(); - root - }) + cx.spawn(|cx| async move { + while let Ok(signal) = event_rx.recv().await { + cx.update(|cx| { + match signal { + Signal::Eose => { + if let Some(chats) = ChatRegistry::global(cx) { + chats.update(cx, |this, cx| this.load_chat_rooms(cx)) + } + } + Signal::Event(event) => { + if let Some(chats) = ChatRegistry::global(cx) { + chats.update(cx, |this, cx| this.push_message(event, cx)) + } + } + }; + }) + .ok(); + } + }) + .detach(); + + root + }, + ) .expect("System error. Please re-open the app."); }); } -async fn restore_window(profile: Option, cx: &mut AsyncApp) -> Result<()> { +async fn sync_metadata(client: &Client, buffer: HashSet) { + let opts = SubscribeAutoCloseOptions::default().exit_policy(ReqExitPolicy::ExitOnEOSE); + let filter = Filter::new() + .authors(buffer.iter().cloned()) + .kind(Kind::Metadata) + .limit(buffer.len()); + + if let Err(e) = client.subscribe(filter, Some(opts)).await { + error!("Subscribe error: {e}"); + } +} + +async fn restore_window(profile: Option, cx: &mut AsyncApp) -> anyhow::Result<()> { let opts = cx .update(|cx| WindowOptions { #[cfg(not(target_os = "linux"))] diff --git a/crates/app/src/views/app.rs b/crates/app/src/views/app.rs index 8df435e..cc14833 100644 --- a/crates/app/src/views/app.rs +++ b/crates/app/src/views/app.rs @@ -8,7 +8,6 @@ use nostr_sdk::prelude::*; use serde::Deserialize; use state::get_client; use std::sync::Arc; -use tokio::sync::oneshot; use ui::{ button::{Button, ButtonRounded, ButtonVariants}, dock_area::{dock::DockPlacement, DockArea, DockItem}, diff --git a/crates/app/src/views/chat.rs b/crates/app/src/views/chat.rs index 571b2d3..5988f27 100644 --- a/crates/app/src/views/chat.rs +++ b/crates/app/src/views/chat.rs @@ -19,7 +19,6 @@ use nostr_sdk::prelude::*; use smol::fs; use state::get_client; use std::sync::Arc; -use tokio::sync::oneshot; use ui::{ button::{Button, ButtonRounded, ButtonVariants}, dock_area::panel::{Panel, PanelEvent}, diff --git a/crates/app/src/views/contacts.rs b/crates/app/src/views/contacts.rs index 39e4a66..c40f7ec 100644 --- a/crates/app/src/views/contacts.rs +++ b/crates/app/src/views/contacts.rs @@ -6,7 +6,6 @@ use gpui::{ }; use nostr_sdk::prelude::*; use state::get_client; -use tokio::sync::oneshot; use ui::{ button::Button, dock_area::panel::{Panel, PanelEvent}, diff --git a/crates/app/src/views/onboarding.rs b/crates/app/src/views/onboarding.rs index 51e0253..b2fb1da 100644 --- a/crates/app/src/views/onboarding.rs +++ b/crates/app/src/views/onboarding.rs @@ -6,7 +6,6 @@ use gpui::{ use nostr_connect::prelude::*; use state::get_client; use std::{path::PathBuf, time::Duration}; -use tokio::sync::oneshot; use ui::{ button::{Button, ButtonCustomVariant, ButtonVariants}, input::{InputEvent, TextInput}, diff --git a/crates/app/src/views/profile.rs b/crates/app/src/views/profile.rs index 5aedef7..3c47b37 100644 --- a/crates/app/src/views/profile.rs +++ b/crates/app/src/views/profile.rs @@ -9,7 +9,6 @@ use nostr_sdk::prelude::*; use smol::fs; use state::get_client; use std::str::FromStr; -use tokio::sync::oneshot; use ui::{ button::{Button, ButtonVariants}, dock_area::panel::{Panel, PanelEvent}, diff --git a/crates/app/src/views/relays.rs b/crates/app/src/views/relays.rs index 9eaa6ec..7ec9f26 100644 --- a/crates/app/src/views/relays.rs +++ b/crates/app/src/views/relays.rs @@ -4,7 +4,6 @@ use gpui::{ }; use nostr_sdk::prelude::*; use state::get_client; -use tokio::sync::oneshot; use ui::{ button::{Button, ButtonVariants}, input::{InputEvent, TextInput}, diff --git a/crates/app/src/views/sidebar/compose.rs b/crates/app/src/views/sidebar/compose.rs index cdb213a..4a36f2e 100644 --- a/crates/app/src/views/sidebar/compose.rs +++ b/crates/app/src/views/sidebar/compose.rs @@ -14,7 +14,6 @@ use serde::Deserialize; use smol::Timer; use state::get_client; use std::{collections::HashSet, time::Duration}; -use tokio::sync::oneshot; use ui::{ button::{Button, ButtonRounded}, input::{InputEvent, TextInput}, diff --git a/crates/chats/Cargo.toml b/crates/chats/Cargo.toml index 8e4ad21..3701505 100644 --- a/crates/chats/Cargo.toml +++ b/crates/chats/Cargo.toml @@ -12,5 +12,6 @@ gpui.workspace = true nostr-sdk.workspace = true anyhow.workspace = true itertools.workspace = true -smol.workspace = true chrono.workspace = true +smol.workspace = true +oneshot.workspace = true diff --git a/crates/chats/src/registry.rs b/crates/chats/src/registry.rs index 96bcae8..2d693fb 100644 --- a/crates/chats/src/registry.rs +++ b/crates/chats/src/registry.rs @@ -1,5 +1,4 @@ use anyhow::anyhow; -use async_utility::tokio::sync::oneshot; use common::utils::{compare, room_hash, signer_public_key}; use gpui::{App, AppContext, Context, Entity, Global}; use itertools::Itertools; @@ -31,8 +30,10 @@ impl ChatRegistry { pub fn register(cx: &mut App) -> Entity { Self::global(cx).unwrap_or_else(|| { let entity = cx.new(Self::new); + // Set global state cx.set_global(GlobalChatRegistry(entity.clone())); + // Observe and load metadata for any new rooms cx.observe_new::(|this, _window, cx| { let client = get_client(); diff --git a/crates/common/src/constants.rs b/crates/common/src/constants.rs index c0d85b2..6135411 100644 --- a/crates/common/src/constants.rs +++ b/crates/common/src/constants.rs @@ -2,8 +2,6 @@ pub const KEYRING_SERVICE: &str = "Coop Safe Storage"; pub const APP_NAME: &str = "Coop"; pub const APP_ID: &str = "su.reya.coop"; -pub const FAKE_SIG: &str = "f9e79d141c004977192d05a86f81ec7c585179c371f7350a5412d33575a2a356433f58e405c2296ed273e2fe0aafa25b641e39cc4e1f3f261ebf55bce0cbac83"; - /// Subscriptions pub const NEW_MESSAGE_SUB_ID: &str = "listen_new_giftwraps"; pub const ALL_MESSAGES_SUB_ID: &str = "listen_all_giftwraps"; diff --git a/crates/common/src/utils.rs b/crates/common/src/utils.rs index 81018ea..005e08e 100644 --- a/crates/common/src/utils.rs +++ b/crates/common/src/utils.rs @@ -16,13 +16,14 @@ pub async fn signer_public_key(client: &Client) -> anyhow::Result anyhow::Result<(), anyhow::Error> { + let sync_opts = SyncOptions::default(); let subscription = Filter::new() .kind(Kind::ContactList) .author(public_key) .limit(1); // Get contact list - _ = client.sync(subscription, &SyncOptions::default()).await; + _ = client.sync(subscription, &sync_opts).await; let all_messages_sub_id = SubscriptionId::new(ALL_MESSAGES_SUB_ID); let new_message_sub_id = SubscriptionId::new(NEW_MESSAGE_SUB_ID); diff --git a/crates/state/Cargo.toml b/crates/state/Cargo.toml index a31843a..ac6da2e 100644 --- a/crates/state/Cargo.toml +++ b/crates/state/Cargo.toml @@ -6,5 +6,4 @@ publish = false [dependencies] nostr-sdk.workspace = true -tokio.workspace = true dirs.workspace = true diff --git a/crates/state/src/lib.rs b/crates/state/src/lib.rs index a83c50a..a1250cd 100644 --- a/crates/state/src/lib.rs +++ b/crates/state/src/lib.rs @@ -4,23 +4,29 @@ use std::{fs, sync::OnceLock, time::Duration}; static CLIENT: OnceLock = OnceLock::new(); -pub fn initialize_client() { +pub fn initialize_client() -> &'static Client { // Setup app data folder let config_dir = config_dir().expect("Config directory not found"); - let _ = fs::create_dir_all(config_dir.join("Coop/")); + let app_dir = config_dir.join("Coop/"); + + // Create app directory if it doesn't exist + _ = fs::create_dir_all(&app_dir); // Setup database - let lmdb = NostrLMDB::open(config_dir.join("Coop/nostr")).expect("Database is NOT initialized"); + let lmdb = NostrLMDB::open(app_dir.join("nostr")).expect("Database is NOT initialized"); // Client options let opts = Options::new() + // NIP-65 .gossip(true) - .max_avg_latency(Duration::from_secs(2)); + // Skip all very slow relays + .max_avg_latency(Duration::from_millis(800)); // Setup Nostr Client let client = ClientBuilder::default().database(lmdb).opts(opts).build(); CLIENT.set(client).expect("Client is already initialized!"); + CLIENT.get().expect("Client is NOT initialized!") } pub fn get_client() -> &'static Client {