.
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m30s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m15s
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m30s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m15s
This commit is contained in:
565
Cargo.lock
generated
565
Cargo.lock
generated
@@ -85,12 +85,6 @@ dependencies = [
|
||||
"equator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
@@ -152,9 +146,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.100"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
||||
checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea"
|
||||
|
||||
[[package]]
|
||||
name = "ar_archive_writer"
|
||||
@@ -536,15 +530,6 @@ dependencies = [
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atoi"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic"
|
||||
version = "0.5.3"
|
||||
@@ -1279,7 +1264,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collections"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"rustc-hash 2.1.1",
|
||||
@@ -1364,12 +1349,6 @@ dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-oid"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
|
||||
|
||||
[[package]]
|
||||
name = "const-random"
|
||||
version = "0.1.18"
|
||||
@@ -1590,21 +1569,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cosmic-text"
|
||||
version = "0.14.2"
|
||||
version = "0.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da46a9d5a8905cc538a4a5bceb6a4510de7a51049c5588c0114efce102bcbbe8"
|
||||
checksum = "8c5c9868e64aa6c5410629a83450e142c80e721c727a5bc0fb18107af6c2d66b"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"fontdb 0.16.2",
|
||||
"fontdb",
|
||||
"harfrust",
|
||||
"linebender_resource_handle",
|
||||
"log",
|
||||
"rangemap",
|
||||
"rustc-hash 1.1.0",
|
||||
"rustybuzz 0.14.1",
|
||||
"rustc-hash 2.1.1",
|
||||
"self_cell",
|
||||
"skrifa 0.40.0",
|
||||
"smol_str",
|
||||
"swash",
|
||||
"sys-locale",
|
||||
"ttf-parser 0.21.1",
|
||||
"unicode-bidi",
|
||||
"unicode-linebreak",
|
||||
"unicode-script",
|
||||
@@ -1620,21 +1600,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d"
|
||||
dependencies = [
|
||||
"crc-catalog",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc-catalog"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.5.0"
|
||||
@@ -1729,17 +1694,6 @@ version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26bf8fc351c5ed29b5c2f0cbbac1b209b74f60ecd62e675a998df72c49af5204"
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.7.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"pem-rfc7468",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.20"
|
||||
@@ -1756,7 +1710,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "derive_refineable"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1788,7 +1742,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"const-oid",
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
@@ -1893,12 +1846,6 @@ dependencies = [
|
||||
"ui",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dotenvy"
|
||||
version = "0.15.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
|
||||
|
||||
[[package]]
|
||||
name = "downcast-rs"
|
||||
version = "1.2.1"
|
||||
@@ -1958,9 +1905,6 @@ name = "either"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embed-resource"
|
||||
@@ -2078,17 +2022,6 @@ dependencies = [
|
||||
"svg_fmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "etcetera"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"home",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "euclid"
|
||||
version = "0.22.13"
|
||||
@@ -2301,6 +2234,15 @@ dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "font-types"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1e4d2d0cf79d38430cc9dc9aadec84774bff2e1ba30ae2bf6c16cfce9385a23"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fontconfig-parser"
|
||||
version = "0.5.8"
|
||||
@@ -2310,20 +2252,6 @@ dependencies = [
|
||||
"roxmltree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fontdb"
|
||||
version = "0.16.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3"
|
||||
dependencies = [
|
||||
"fontconfig-parser",
|
||||
"log",
|
||||
"memmap2 0.9.9",
|
||||
"slotmap",
|
||||
"tinyvec",
|
||||
"ttf-parser 0.20.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fontdb"
|
||||
version = "0.23.0"
|
||||
@@ -2335,7 +2263,7 @@ dependencies = [
|
||||
"memmap2 0.9.9",
|
||||
"slotmap",
|
||||
"tinyvec",
|
||||
"ttf-parser 0.25.1",
|
||||
"ttf-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2477,17 +2405,6 @@ dependencies = [
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-intrusive"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"lock_api",
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.31"
|
||||
@@ -2711,7 +2628,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gpui"
|
||||
version = "0.2.2"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"as-raw-xcb-connection",
|
||||
@@ -2813,7 +2730,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gpui_macros"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
@@ -2824,7 +2741,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gpui_tokio"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"gpui",
|
||||
@@ -2869,6 +2786,19 @@ dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "harfrust"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f9f40651a03bc0f7316bd75267ff5767e93017ef3cfffe76c6aa7252cc5a31c"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"bytemuck",
|
||||
"core_maths",
|
||||
"read-fonts 0.37.0",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.9.1"
|
||||
@@ -2890,8 +2820,6 @@ version = "0.15.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"equivalent",
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
@@ -2901,15 +2829,6 @@ version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||
|
||||
[[package]]
|
||||
name = "hashlink"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
|
||||
dependencies = [
|
||||
"hashbrown 0.15.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
@@ -3057,7 +2976,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "http_client"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-compression",
|
||||
@@ -3082,7 +3001,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "http_client_tls"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"rustls-platform-verifier",
|
||||
@@ -3629,15 +3548,10 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.30.1"
|
||||
name = "linebender_resource_handle"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
checksum = "d4a5ff6bcca6c4867b1c4fd4ef63e4db7436ef363e0ad7531d1558856bae64f4"
|
||||
|
||||
[[package]]
|
||||
name = "linicon"
|
||||
@@ -3843,7 +3757,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "media"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bindgen",
|
||||
@@ -4139,13 +4053,14 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nostr-gossip-sqlite"
|
||||
name = "nostr-gossip-memory"
|
||||
version = "0.44.0"
|
||||
source = "git+https://github.com/rust-nostr/nostr#9031e3684c661690a4c61865ac11d311456371e7"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"lru",
|
||||
"nostr",
|
||||
"nostr-gossip",
|
||||
"sqlx",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
@@ -4691,15 +4606,6 @@ dependencies = [
|
||||
"hmac",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pem-rfc7468"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.2"
|
||||
@@ -4709,7 +4615,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||
[[package]]
|
||||
name = "perf"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"collections",
|
||||
"serde",
|
||||
@@ -4836,27 +4742,6 @@ dependencies = [
|
||||
"futures-io",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs1"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
|
||||
dependencies = [
|
||||
"der",
|
||||
"pkcs8",
|
||||
"spki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs8"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
|
||||
dependencies = [
|
||||
"der",
|
||||
"spki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.32"
|
||||
@@ -5315,7 +5200,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6717cf23b488adf64b9d711329542ba34de147df262370221940dfabc2c91358"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"font-types",
|
||||
"font-types 0.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "read-fonts"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b634fabf032fab15307ffd272149b622260f55974d9fad689292a5d33df02e5"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"core_maths",
|
||||
"font-types 0.11.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5379,7 +5275,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "refineable"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"derive_refineable",
|
||||
]
|
||||
@@ -5478,7 +5374,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "reqwest_client"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -5533,7 +5429,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rope"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"log",
|
||||
@@ -5551,26 +5447,6 @@ version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
|
||||
|
||||
[[package]]
|
||||
name = "rsa"
|
||||
version = "0.9.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"digest",
|
||||
"num-bigint-dig",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"pkcs1",
|
||||
"pkcs8",
|
||||
"rand_core 0.6.4",
|
||||
"signature",
|
||||
"spki",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed"
|
||||
version = "8.11.0"
|
||||
@@ -5761,23 +5637,6 @@ version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
|
||||
[[package]]
|
||||
name = "rustybuzz"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"bytemuck",
|
||||
"libm",
|
||||
"smallvec",
|
||||
"ttf-parser 0.21.1",
|
||||
"unicode-bidi-mirroring 0.2.0",
|
||||
"unicode-ccc 0.2.0",
|
||||
"unicode-properties",
|
||||
"unicode-script",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustybuzz"
|
||||
version = "0.20.1"
|
||||
@@ -5789,9 +5648,9 @@ dependencies = [
|
||||
"core_maths",
|
||||
"log",
|
||||
"smallvec",
|
||||
"ttf-parser 0.25.1",
|
||||
"unicode-bidi-mirroring 0.4.0",
|
||||
"unicode-ccc 0.4.0",
|
||||
"ttf-parser",
|
||||
"unicode-bidi-mirroring",
|
||||
"unicode-ccc",
|
||||
"unicode-properties",
|
||||
"unicode-script",
|
||||
]
|
||||
@@ -5832,7 +5691,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "scheduler"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"async-task",
|
||||
"backtrace",
|
||||
@@ -6179,16 +6038,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.8"
|
||||
@@ -6226,7 +6075,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c31071dedf532758ecf3fed987cdb4bd9509f900e026ab684b4ecb81ea49841"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"read-fonts",
|
||||
"read-fonts 0.35.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "skrifa"
|
||||
version = "0.40.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fbdfe3d2475fbd7ddd1f3e5cf8288a30eb3e5f95832829570cd88115a7434ac"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"read-fonts 0.37.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6249,9 +6108,6 @@ name = "smallvec"
|
||||
version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smol"
|
||||
@@ -6272,9 +6128,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "smol_str"
|
||||
version = "0.2.2"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead"
|
||||
checksum = "0f7a918bd2a9951d18ee6e48f076843e8e73a9a5d22cf05bcd4b7a81bdd04e17"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
@@ -6313,204 +6169,6 @@ dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spki"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"der",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc"
|
||||
dependencies = [
|
||||
"sqlx-core",
|
||||
"sqlx-macros",
|
||||
"sqlx-mysql",
|
||||
"sqlx-postgres",
|
||||
"sqlx-sqlite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-core"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
"crc",
|
||||
"crossbeam-queue",
|
||||
"either",
|
||||
"event-listener 5.4.1",
|
||||
"futures-core",
|
||||
"futures-intrusive",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"hashbrown 0.15.5",
|
||||
"hashlink",
|
||||
"indexmap",
|
||||
"log",
|
||||
"memchr",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"smallvec",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tracing",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-macros"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"sqlx-core",
|
||||
"sqlx-macros-core",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-macros-core"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b"
|
||||
dependencies = [
|
||||
"dotenvy",
|
||||
"either",
|
||||
"heck 0.5.0",
|
||||
"hex",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"sqlx-core",
|
||||
"sqlx-mysql",
|
||||
"sqlx-postgres",
|
||||
"sqlx-sqlite",
|
||||
"syn 2.0.114",
|
||||
"tokio",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-mysql"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526"
|
||||
dependencies = [
|
||||
"atoi",
|
||||
"base64",
|
||||
"bitflags 2.10.0",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"crc",
|
||||
"digest",
|
||||
"dotenvy",
|
||||
"either",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"generic-array",
|
||||
"hex",
|
||||
"hkdf",
|
||||
"hmac",
|
||||
"itoa",
|
||||
"log",
|
||||
"md-5",
|
||||
"memchr",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"rand 0.8.5",
|
||||
"rsa",
|
||||
"serde",
|
||||
"sha1",
|
||||
"sha2",
|
||||
"smallvec",
|
||||
"sqlx-core",
|
||||
"stringprep",
|
||||
"thiserror 2.0.18",
|
||||
"tracing",
|
||||
"whoami",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-postgres"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46"
|
||||
dependencies = [
|
||||
"atoi",
|
||||
"base64",
|
||||
"bitflags 2.10.0",
|
||||
"byteorder",
|
||||
"crc",
|
||||
"dotenvy",
|
||||
"etcetera",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"hex",
|
||||
"hkdf",
|
||||
"hmac",
|
||||
"home",
|
||||
"itoa",
|
||||
"log",
|
||||
"md-5",
|
||||
"memchr",
|
||||
"once_cell",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"smallvec",
|
||||
"sqlx-core",
|
||||
"stringprep",
|
||||
"thiserror 2.0.18",
|
||||
"tracing",
|
||||
"whoami",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-sqlite"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea"
|
||||
dependencies = [
|
||||
"atoi",
|
||||
"flume",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-intrusive",
|
||||
"futures-util",
|
||||
"libsqlite3-sys",
|
||||
"log",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"serde_urlencoded",
|
||||
"sqlx-core",
|
||||
"thiserror 2.0.18",
|
||||
"tracing",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.1"
|
||||
@@ -6562,7 +6220,7 @@ dependencies = [
|
||||
"gpui_tokio",
|
||||
"log",
|
||||
"nostr-connect",
|
||||
"nostr-gossip-sqlite",
|
||||
"nostr-gossip-memory",
|
||||
"nostr-lmdb",
|
||||
"nostr-sdk",
|
||||
"petname",
|
||||
@@ -6589,17 +6247,6 @@ dependencies = [
|
||||
"float-cmp",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stringprep"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
"unicode-properties",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
@@ -6658,7 +6305,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
[[package]]
|
||||
name = "sum_tree"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"log",
|
||||
@@ -6767,7 +6414,7 @@ version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47846491253e976bdd07d0f9cc24b7daf24720d11309302ccbbc6e6b6e53550a"
|
||||
dependencies = [
|
||||
"skrifa",
|
||||
"skrifa 0.37.0",
|
||||
"yazi",
|
||||
"zeno",
|
||||
]
|
||||
@@ -7393,18 +7040,6 @@ version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4"
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8"
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.25.1"
|
||||
@@ -7491,24 +7126,12 @@ version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi-mirroring"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi-mirroring"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dfa6e8c60bb66d49db113e0125ee8711b7647b5579dc7f5f19c42357ed039fe"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ccc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ccc"
|
||||
version = "0.4.0"
|
||||
@@ -7604,13 +7227,13 @@ dependencies = [
|
||||
"base64",
|
||||
"data-url",
|
||||
"flate2",
|
||||
"fontdb 0.23.0",
|
||||
"fontdb",
|
||||
"imagesize",
|
||||
"kurbo",
|
||||
"log",
|
||||
"pico-args",
|
||||
"roxmltree",
|
||||
"rustybuzz 0.20.1",
|
||||
"rustybuzz",
|
||||
"simplecss",
|
||||
"siphasher",
|
||||
"strict-num",
|
||||
@@ -7643,7 +7266,7 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
[[package]]
|
||||
name = "util"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-fs",
|
||||
@@ -7681,7 +7304,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "util_macros"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"perf",
|
||||
"quote",
|
||||
@@ -8125,7 +7748,7 @@ version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -9062,18 +8685,18 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.38"
|
||||
version = "0.8.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57cf3aa6855b23711ee9852dfc97dfaa51c45feaba5b645d0c777414d494a961"
|
||||
checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.38"
|
||||
version = "0.8.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a616990af1a287837c4fe6596ad77ef57948f787e46ce28e166facc0cc1cb75"
|
||||
checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -9157,7 +8780,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "zlog"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@@ -9174,7 +8797,7 @@ checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445"
|
||||
[[package]]
|
||||
name = "ztracing"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
@@ -9185,7 +8808,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ztracing_macro"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#49c777779a63a0f44abec3ba7bd490c8b1552667"
|
||||
source = "git+https://github.com/zed-industries/zed#7cb4d75139b39efb0d1d1e90faf7480d0f1dc734"
|
||||
|
||||
[[package]]
|
||||
name = "zune-core"
|
||||
|
||||
@@ -19,7 +19,7 @@ reqwest_client = { git = "https://github.com/zed-industries/zed" }
|
||||
nostr-lmdb = { 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 = [ "nip96", "nip59", "nip49", "nip44" ] }
|
||||
nostr-gossip-sqlite = { git = "https://github.com/rust-nostr/nostr" }
|
||||
nostr-gossip-memory = { git = "https://github.com/rust-nostr/nostr" }
|
||||
|
||||
# Others
|
||||
anyhow = "1.0.44"
|
||||
|
||||
@@ -146,15 +146,15 @@ impl ChatRegistry {
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
NostrEvent::Eose => {
|
||||
NostrEvent::Unwrapping(status) => {
|
||||
this.update(cx, |this, cx| {
|
||||
this.set_loading(status, cx);
|
||||
this.get_rooms(cx);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
NostrEvent::Unwrapping(status) => {
|
||||
NostrEvent::Eose => {
|
||||
this.update(cx, |this, cx| {
|
||||
this.set_loading(status, cx);
|
||||
this.get_rooms(cx);
|
||||
})
|
||||
.ok();
|
||||
@@ -310,10 +310,24 @@ impl ChatRegistry {
|
||||
/// Add a new room to the start of list.
|
||||
pub fn add_room<I>(&mut self, room: I, cx: &mut Context<Self>)
|
||||
where
|
||||
I: Into<Room>,
|
||||
I: Into<Room> + 'static,
|
||||
{
|
||||
self.rooms.insert(0, cx.new(|_| room.into()));
|
||||
cx.notify();
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let client = nostr.read(cx).client();
|
||||
|
||||
self.tasks.push(cx.spawn(async move |this, cx| {
|
||||
if let Some(signer) = client.signer() {
|
||||
if let Ok(public_key) = signer.get_public_key().await {
|
||||
this.update(cx, |this, cx| {
|
||||
this.rooms
|
||||
.insert(0, cx.new(|_| room.into().organize(&public_key)));
|
||||
cx.emit(ChatEvent::Ping);
|
||||
cx.notify();
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/// Emit an open room event.
|
||||
@@ -407,23 +421,20 @@ impl ChatRegistry {
|
||||
pub fn get_rooms(&mut self, cx: &mut Context<Self>) {
|
||||
let task = self.get_rooms_from_database(cx);
|
||||
|
||||
self.tasks.push(
|
||||
// Run and finished in the background
|
||||
cx.spawn(async move |this, cx| {
|
||||
match task.await {
|
||||
Ok(rooms) => {
|
||||
this.update(cx, move |this, cx| {
|
||||
this.extend_rooms(rooms, cx);
|
||||
this.sort(cx);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to load rooms: {e}")
|
||||
}
|
||||
};
|
||||
}),
|
||||
);
|
||||
self.tasks.push(cx.spawn(async move |this, cx| {
|
||||
match task.await {
|
||||
Ok(rooms) => {
|
||||
this.update(cx, move |this, cx| {
|
||||
this.extend_rooms(rooms, cx);
|
||||
this.sort(cx);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to load rooms: {e}")
|
||||
}
|
||||
};
|
||||
}));
|
||||
}
|
||||
|
||||
/// Create a task to load rooms from the database
|
||||
@@ -434,8 +445,11 @@ impl ChatRegistry {
|
||||
cx.background_spawn(async move {
|
||||
let signer = client.signer().context("Signer not found")?;
|
||||
let public_key = signer.get_public_key().await?;
|
||||
|
||||
// Get contacts
|
||||
let contacts = client.database().contacts_public_keys(public_key).await?;
|
||||
|
||||
// Construct authored filter
|
||||
let authored_filter = Filter::new()
|
||||
.kind(Kind::ApplicationSpecificData)
|
||||
.custom_tag(SingleLetterTag::lowercase(Alphabet::A), public_key);
|
||||
@@ -443,6 +457,7 @@ impl ChatRegistry {
|
||||
// Get all authored events
|
||||
let authored = client.database().query(authored_filter).await?;
|
||||
|
||||
// Construct addressed filter
|
||||
let addressed_filter = Filter::new()
|
||||
.kind(Kind::ApplicationSpecificData)
|
||||
.custom_tag(SingleLetterTag::lowercase(Alphabet::P), public_key);
|
||||
@@ -453,6 +468,7 @@ impl ChatRegistry {
|
||||
// Merge authored and addressed events
|
||||
let events = authored.merge(addressed);
|
||||
|
||||
// Collect results
|
||||
let mut rooms: HashSet<Room> = HashSet::new();
|
||||
let mut grouped: HashMap<u64, Vec<UnsignedEvent>> = HashMap::new();
|
||||
|
||||
@@ -468,24 +484,21 @@ impl ChatRegistry {
|
||||
for (_id, mut messages) in grouped.into_iter() {
|
||||
messages.sort_by_key(|m| Reverse(m.created_at));
|
||||
|
||||
// Always use the latest message
|
||||
let Some(latest) = messages.first() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let mut room = Room::from(latest);
|
||||
|
||||
if rooms.iter().any(|r| r.id == room.id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut public_keys = room.members();
|
||||
public_keys.retain(|pk| pk != &public_key);
|
||||
// Construct the room from the latest message.
|
||||
//
|
||||
// Call `.organize` to ensure the current user is at the end of the list.
|
||||
let mut room = Room::from(latest).organize(&public_key);
|
||||
|
||||
// Check if the user has responded to the room
|
||||
let user_sent = messages.iter().any(|m| m.pubkey == public_key);
|
||||
|
||||
// Check if public keys are from the user's contacts
|
||||
let is_contact = public_keys.iter().any(|k| contacts.contains(k));
|
||||
let is_contact = room.members.iter().any(|k| contacts.contains(k));
|
||||
|
||||
// Set the room's kind based on status
|
||||
if user_sent || is_contact {
|
||||
@@ -499,6 +512,24 @@ impl ChatRegistry {
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse a nostr event into a message and push it to the belonging room
|
||||
///
|
||||
/// If the room doesn't exist, it will be created.
|
||||
/// Updates room ordering based on the most recent messages.
|
||||
pub fn new_message(&mut self, message: NewMessage, cx: &mut Context<Self>) {
|
||||
match self.rooms.iter().find(|e| e.read(cx).id == message.room) {
|
||||
Some(room) => {
|
||||
room.update(cx, |this, cx| {
|
||||
this.push_message(message, cx);
|
||||
});
|
||||
}
|
||||
None => {
|
||||
// Push the new room to the front of the list
|
||||
self.add_room(message.rumor, cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Trigger a refresh of the opened chat rooms by their IDs
|
||||
pub fn refresh_rooms(&mut self, ids: Option<Vec<u64>>, cx: &mut Context<Self>) {
|
||||
if let Some(ids) = ids {
|
||||
@@ -512,53 +543,6 @@ impl ChatRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a nostr event into a message and push it to the belonging room
|
||||
///
|
||||
/// If the room doesn't exist, it will be created.
|
||||
/// Updates room ordering based on the most recent messages.
|
||||
pub fn new_message(&mut self, message: NewMessage, cx: &mut Context<Self>) {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
// Get the unique id
|
||||
let id = message.rumor.uniq_id();
|
||||
// Get the author
|
||||
let author = message.rumor.pubkey;
|
||||
|
||||
match self.rooms.iter().find(|room| room.read(cx).id == id) {
|
||||
Some(room) => {
|
||||
let new_message = message.rumor.created_at > room.read(cx).created_at;
|
||||
let created_at = message.rumor.created_at;
|
||||
|
||||
// Update room
|
||||
room.update(cx, |this, cx| {
|
||||
// Update the last timestamp if the new message is newer
|
||||
if new_message {
|
||||
this.set_created_at(created_at, cx);
|
||||
}
|
||||
|
||||
// Set this room is ongoing if the new message is from current user
|
||||
// if author == nostr.read(cx).identity().read(cx).public_key() {
|
||||
// this.set_ongoing(cx);
|
||||
// }
|
||||
|
||||
// Emit the new message to the room
|
||||
this.emit_message(message, cx);
|
||||
});
|
||||
|
||||
// Resort all rooms in the registry by their created at (after updated)
|
||||
if new_message {
|
||||
self.sort(cx);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// Push the new room to the front of the list
|
||||
self.add_room(&message.rumor, cx);
|
||||
|
||||
// Notify the UI about the new room
|
||||
cx.emit(ChatEvent::Ping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Unwraps a gift-wrapped event and processes its contents.
|
||||
async fn extract_rumor(
|
||||
client: &Client,
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
use std::hash::Hash;
|
||||
|
||||
use common::EventUtils;
|
||||
use nostr_sdk::prelude::*;
|
||||
|
||||
/// New message.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct NewMessage {
|
||||
pub gift_wrap: EventId,
|
||||
pub room: u64,
|
||||
pub rumor: UnsignedEvent,
|
||||
}
|
||||
|
||||
impl NewMessage {
|
||||
pub fn new(gift_wrap: EventId, rumor: UnsignedEvent) -> Self {
|
||||
Self { gift_wrap, rumor }
|
||||
let room = rumor.uniq_id();
|
||||
|
||||
Self {
|
||||
gift_wrap,
|
||||
room,
|
||||
rumor,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ use nostr_sdk::prelude::*;
|
||||
use person::{Person, PersonRegistry};
|
||||
use state::{tracker, NostrRegistry};
|
||||
|
||||
use crate::NewMessage;
|
||||
use crate::{ChatRegistry, NewMessage};
|
||||
|
||||
const SEND_RETRY: usize = 10;
|
||||
|
||||
@@ -99,16 +99,20 @@ pub enum RoomKind {
|
||||
Ongoing,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Room {
|
||||
/// Conversation ID
|
||||
pub id: u64,
|
||||
|
||||
/// The timestamp of the last message in the room
|
||||
pub created_at: Timestamp,
|
||||
|
||||
/// Subject of the room
|
||||
pub subject: Option<SharedString>,
|
||||
|
||||
/// All members of the room
|
||||
pub members: Vec<PublicKey>,
|
||||
pub(super) members: Vec<PublicKey>,
|
||||
|
||||
/// Kind
|
||||
pub kind: RoomKind,
|
||||
}
|
||||
@@ -145,11 +149,7 @@ impl From<&UnsignedEvent> for Room {
|
||||
fn from(val: &UnsignedEvent) -> Self {
|
||||
let id = val.uniq_id();
|
||||
let created_at = val.created_at;
|
||||
|
||||
// Get the members from the event's tags and event's pubkey
|
||||
let members = val.extract_public_keys();
|
||||
|
||||
// Get subject from tags
|
||||
let subject = val
|
||||
.tags
|
||||
.find(TagKind::Subject)
|
||||
@@ -165,6 +165,12 @@ impl From<&UnsignedEvent> for Room {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UnsignedEvent> for Room {
|
||||
fn from(val: UnsignedEvent) -> Self {
|
||||
Room::from(&val)
|
||||
}
|
||||
}
|
||||
|
||||
impl Room {
|
||||
/// Constructs a new room with the given receiver and tags.
|
||||
pub fn new<T>(author: PublicKey, receivers: T) -> Self
|
||||
@@ -172,16 +178,30 @@ impl Room {
|
||||
T: IntoIterator<Item = PublicKey>,
|
||||
{
|
||||
let tags = Tags::from_list(receivers.into_iter().map(Tag::public_key).collect());
|
||||
// Construct an unsigned event for a direct message
|
||||
//
|
||||
// WARNING: never sign this event
|
||||
let mut event = EventBuilder::new(Kind::PrivateDirectMessage, "")
|
||||
.tags(tags)
|
||||
.build(author);
|
||||
|
||||
// Generate event ID
|
||||
// Ensure that the ID is set
|
||||
event.ensure_id();
|
||||
|
||||
Room::from(&event)
|
||||
}
|
||||
|
||||
/// Organizes the members of the room by moving the target member to the end.
|
||||
///
|
||||
/// Always call this function to ensure the current user is at the end of the list.
|
||||
pub fn organize(mut self, target: &PublicKey) -> Self {
|
||||
if let Some(index) = self.members.iter().position(|member| member == target) {
|
||||
let member = self.members.remove(index);
|
||||
self.members.push(member);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the kind of the room and returns the modified room
|
||||
pub fn kind(mut self, kind: RoomKind) -> Self {
|
||||
self.kind = kind;
|
||||
@@ -275,9 +295,21 @@ impl Room {
|
||||
}
|
||||
}
|
||||
|
||||
/// Emits a new message signal to the current room
|
||||
pub fn emit_message(&self, message: NewMessage, cx: &mut Context<Self>) {
|
||||
/// Push a new message to the current room
|
||||
pub fn push_message(&mut self, message: NewMessage, cx: &mut Context<Self>) {
|
||||
let created_at = message.rumor.created_at;
|
||||
let new_message = created_at > self.created_at;
|
||||
|
||||
// Emit the incoming message event
|
||||
cx.emit(RoomEvent::Incoming(message));
|
||||
|
||||
if new_message {
|
||||
self.set_created_at(created_at, cx);
|
||||
// Sort chats after emitting a new message
|
||||
ChatRegistry::global(cx).update(cx, |this, cx| {
|
||||
this.sort(cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Emits a signal to reload the current room's messages.
|
||||
|
||||
@@ -12,44 +12,6 @@ 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;
|
||||
fn display_name(&self) -> SharedString;
|
||||
}
|
||||
|
||||
impl RenderedProfile for Profile {
|
||||
fn avatar(&self) -> SharedString {
|
||||
self.metadata()
|
||||
.picture
|
||||
.as_ref()
|
||||
.filter(|picture| !picture.is_empty())
|
||||
.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())
|
||||
}
|
||||
|
||||
fn display_name(&self) -> SharedString {
|
||||
if let Some(display_name) = self.metadata().display_name.as_ref() {
|
||||
if !display_name.is_empty() {
|
||||
return SharedString::from(display_name);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(name) = self.metadata().name.as_ref() {
|
||||
if !name.is_empty() {
|
||||
return SharedString::from(name);
|
||||
}
|
||||
}
|
||||
|
||||
SharedString::from(shorten_pubkey(self.public_key(), 4))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait RenderedTimestamp {
|
||||
fn to_human_time(&self) -> SharedString;
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{Context as AnyhowContext, Error};
|
||||
use common::{shorten_pubkey, RenderedProfile, RenderedTimestamp, BOOTSTRAP_RELAYS};
|
||||
use common::{shorten_pubkey, RenderedTimestamp, BOOTSTRAP_RELAYS};
|
||||
use gpui::prelude::FluentBuilder;
|
||||
use gpui::{
|
||||
div, px, relative, rems, uniform_list, App, AppContext, Context, Div, Entity,
|
||||
@@ -11,7 +11,7 @@ use gpui::{
|
||||
use nostr_sdk::prelude::*;
|
||||
use person::{Person, PersonRegistry};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use state::{NostrAddress, NostrRegistry};
|
||||
use state::{NostrAddress, NostrRegistry, TIMEOUT};
|
||||
use theme::ActiveTheme;
|
||||
use ui::avatar::Avatar;
|
||||
use ui::button::{Button, ButtonVariants};
|
||||
@@ -22,56 +22,117 @@ pub fn init(public_key: PublicKey, window: &mut Window, cx: &mut App) -> Entity<
|
||||
cx.new(|cx| Screening::new(public_key, window, cx))
|
||||
}
|
||||
|
||||
/// Screening
|
||||
pub struct Screening {
|
||||
profile: Person,
|
||||
/// Public Key of the person being screened.
|
||||
public_key: PublicKey,
|
||||
|
||||
/// Whether the person's address is verified.
|
||||
verified: bool,
|
||||
|
||||
/// Whether the person is followed by current user.
|
||||
followed: bool,
|
||||
|
||||
/// Last time the person was active.
|
||||
last_active: Option<Timestamp>,
|
||||
mutual_contacts: Vec<Profile>,
|
||||
_tasks: SmallVec<[Task<()>; 3]>,
|
||||
|
||||
/// All mutual contacts of the person being screened.
|
||||
mutual_contacts: Vec<PublicKey>,
|
||||
|
||||
/// Async tasks
|
||||
tasks: SmallVec<[Task<()>; 3]>,
|
||||
}
|
||||
|
||||
impl Screening {
|
||||
pub fn new(public_key: PublicKey, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let http_client = cx.http_client();
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let client = nostr.read(cx).client();
|
||||
|
||||
let persons = PersonRegistry::global(cx);
|
||||
let profile = persons.read(cx).get(&public_key, cx);
|
||||
|
||||
let mut tasks = smallvec![];
|
||||
|
||||
// Check WOT
|
||||
let contact_check: Task<Result<(bool, Vec<Profile>), Error>> = cx.background_spawn({
|
||||
let client = nostr.read(cx).client();
|
||||
async move {
|
||||
let signer = client.signer().context("Signer not found")?;
|
||||
let signer_pubkey = signer.get_public_key().await?;
|
||||
|
||||
// Check if user is in contact list
|
||||
let contacts = client.database().contacts_public_keys(signer_pubkey).await;
|
||||
let followed = contacts.unwrap_or_default().contains(&public_key);
|
||||
|
||||
// Check mutual contacts
|
||||
let contact_list = Filter::new().kind(Kind::ContactList).pubkey(public_key);
|
||||
let mut mutual_contacts = vec![];
|
||||
|
||||
if let Ok(events) = client.database().query(contact_list).await {
|
||||
for event in events.into_iter().filter(|ev| ev.pubkey != signer_pubkey) {
|
||||
if let Ok(metadata) = client.database().metadata(event.pubkey).await {
|
||||
let profile = Profile::new(event.pubkey, metadata.unwrap_or_default());
|
||||
mutual_contacts.push(profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok((followed, mutual_contacts))
|
||||
}
|
||||
cx.defer_in(window, move |this, _window, cx| {
|
||||
this.check_contact(cx);
|
||||
this.check_wot(cx);
|
||||
this.check_last_activity(cx);
|
||||
this.verify_identifier(cx);
|
||||
});
|
||||
|
||||
// Check the last activity
|
||||
let activity_check = cx.background_spawn(async move {
|
||||
Self {
|
||||
public_key,
|
||||
verified: false,
|
||||
followed: false,
|
||||
last_active: None,
|
||||
mutual_contacts: vec![],
|
||||
tasks: smallvec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn check_contact(&mut self, cx: &mut Context<Self>) {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let client = nostr.read(cx).client();
|
||||
let public_key = self.public_key;
|
||||
|
||||
let task: Task<Result<bool, Error>> = cx.background_spawn(async move {
|
||||
let signer = client.signer().context("Signer not found")?;
|
||||
let signer_pubkey = signer.get_public_key().await?;
|
||||
|
||||
// Check if user is in contact list
|
||||
let contacts = client.database().contacts_public_keys(signer_pubkey).await;
|
||||
let followed = contacts.unwrap_or_default().contains(&public_key);
|
||||
|
||||
Ok(followed)
|
||||
});
|
||||
|
||||
self.tasks.push(cx.spawn(async move |this, cx| {
|
||||
let result = task.await.unwrap_or(false);
|
||||
|
||||
this.update(cx, |this, cx| {
|
||||
this.followed = result;
|
||||
cx.notify();
|
||||
})
|
||||
.ok();
|
||||
}));
|
||||
}
|
||||
|
||||
fn check_wot(&mut self, cx: &mut Context<Self>) {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let client = nostr.read(cx).client();
|
||||
let public_key = self.public_key;
|
||||
|
||||
let task: Task<Result<Vec<PublicKey>, Error>> = cx.background_spawn(async move {
|
||||
let signer = client.signer().context("Signer not found")?;
|
||||
let signer_pubkey = signer.get_public_key().await?;
|
||||
|
||||
// Check mutual contacts
|
||||
let filter = Filter::new().kind(Kind::ContactList).pubkey(public_key);
|
||||
let mut mutual_contacts = vec![];
|
||||
|
||||
if let Ok(events) = client.database().query(filter).await {
|
||||
for event in events.into_iter().filter(|ev| ev.pubkey != signer_pubkey) {
|
||||
mutual_contacts.push(event.pubkey);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(mutual_contacts)
|
||||
});
|
||||
|
||||
self.tasks.push(cx.spawn(async move |this, cx| {
|
||||
match task.await {
|
||||
Ok(contacts) => {
|
||||
this.update(cx, |this, cx| {
|
||||
this.mutual_contacts = contacts;
|
||||
cx.notify();
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to fetch mutual contacts: {}", e);
|
||||
}
|
||||
};
|
||||
}));
|
||||
}
|
||||
|
||||
fn check_last_activity(&mut self, cx: &mut Context<Self>) {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let client = nostr.read(cx).client();
|
||||
let public_key = self.public_key;
|
||||
|
||||
let task: Task<Option<Timestamp>> = cx.background_spawn(async move {
|
||||
let filter = Filter::new().author(public_key).limit(1);
|
||||
let mut activity: Option<Timestamp> = None;
|
||||
|
||||
@@ -83,7 +144,7 @@ impl Screening {
|
||||
|
||||
if let Ok(mut stream) = client
|
||||
.stream_events(target)
|
||||
.timeout(Duration::from_secs(2))
|
||||
.timeout(Duration::from_secs(TIMEOUT))
|
||||
.await
|
||||
{
|
||||
while let Some((_url, event)) = stream.next().await {
|
||||
@@ -96,78 +157,61 @@ impl Screening {
|
||||
activity
|
||||
});
|
||||
|
||||
// Verify the NIP05 address if available
|
||||
let addr_check = profile.metadata().nip05.and_then(|address| {
|
||||
Nip05Address::parse(&address).ok().map(|addr| {
|
||||
cx.background_spawn(async move { addr.verify(&http_client, &public_key).await })
|
||||
self.tasks.push(cx.spawn(async move |this, cx| {
|
||||
let result = task.await;
|
||||
|
||||
this.update(cx, |this, cx| {
|
||||
this.last_active = result;
|
||||
cx.notify();
|
||||
})
|
||||
});
|
||||
|
||||
tasks.push(
|
||||
// Run the contact check in the background
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
if let Ok((followed, mutual_contacts)) = contact_check.await {
|
||||
this.update(cx, |this, cx| {
|
||||
this.followed = followed;
|
||||
this.mutual_contacts = mutual_contacts;
|
||||
cx.notify();
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
tasks.push(
|
||||
// Run the activity check in the background
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
let active = activity_check.await;
|
||||
|
||||
this.update(cx, |this, cx| {
|
||||
this.last_active = active;
|
||||
cx.notify();
|
||||
})
|
||||
.ok();
|
||||
}),
|
||||
);
|
||||
|
||||
tasks.push(
|
||||
// Run the NIP-05 verification in the background
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
if let Some(task) = addr_check {
|
||||
if let Ok(verified) = task.await {
|
||||
this.update(cx, |this, cx| {
|
||||
this.verified = verified;
|
||||
cx.notify();
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
Self {
|
||||
profile,
|
||||
verified: false,
|
||||
followed: false,
|
||||
last_active: None,
|
||||
mutual_contacts: vec![],
|
||||
_tasks: tasks,
|
||||
}
|
||||
.ok();
|
||||
}));
|
||||
}
|
||||
|
||||
fn address(&self, _cx: &Context<Self>) -> Option<String> {
|
||||
self.profile.metadata().nip05
|
||||
fn verify_identifier(&mut self, cx: &mut Context<Self>) {
|
||||
let http_client = cx.http_client();
|
||||
let public_key = self.public_key;
|
||||
|
||||
// Skip if the user doesn't have a NIP-05 identifier
|
||||
let Some(address) = self.address(cx) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let task: Task<Result<bool, Error>> =
|
||||
cx.background_spawn(async move { address.verify(&http_client, &public_key).await });
|
||||
|
||||
self.tasks.push(cx.spawn(async move |this, cx| {
|
||||
let result = task.await.unwrap_or(false);
|
||||
|
||||
this.update(cx, |this, cx| {
|
||||
this.verified = result;
|
||||
cx.notify();
|
||||
})
|
||||
.ok();
|
||||
}));
|
||||
}
|
||||
|
||||
fn open_njump(&mut self, _window: &mut Window, cx: &mut App) {
|
||||
let Ok(bech32) = self.profile.public_key().to_bech32();
|
||||
fn profile(&self, cx: &Context<Self>) -> Person {
|
||||
let persons = PersonRegistry::global(cx);
|
||||
persons.read(cx).get(&self.public_key, cx)
|
||||
}
|
||||
|
||||
fn address(&self, cx: &Context<Self>) -> Option<Nip05Address> {
|
||||
self.profile(cx)
|
||||
.metadata()
|
||||
.nip05
|
||||
.and_then(|addr| Nip05Address::parse(&addr).ok())
|
||||
}
|
||||
|
||||
fn open_njump(&mut self, _window: &mut Window, cx: &mut Context<Self>) {
|
||||
let Ok(bech32) = self.profile(cx).public_key().to_bech32();
|
||||
cx.open_url(&format!("https://njump.me/{bech32}"));
|
||||
}
|
||||
|
||||
fn report(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let client = nostr.read(cx).client();
|
||||
let public_key = self.profile.public_key();
|
||||
let public_key = self.public_key;
|
||||
|
||||
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
|
||||
let tag = Tag::public_key_report(public_key, Report::Impersonation);
|
||||
@@ -180,7 +224,7 @@ impl Screening {
|
||||
Ok(())
|
||||
});
|
||||
|
||||
cx.spawn_in(window, async move |_, cx| {
|
||||
self.tasks.push(cx.spawn_in(window, async move |_, cx| {
|
||||
if task.await.is_ok() {
|
||||
cx.update(|window, cx| {
|
||||
window.close_modal(cx);
|
||||
@@ -188,8 +232,7 @@ impl Screening {
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}));
|
||||
}
|
||||
|
||||
fn mutual_contacts(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
@@ -202,25 +245,27 @@ impl Screening {
|
||||
this.title(SharedString::from("Mutual contacts")).child(
|
||||
v_flex().gap_1().pb_4().child(
|
||||
uniform_list("contacts", total, move |range, _window, cx| {
|
||||
let persons = PersonRegistry::global(cx);
|
||||
let mut items = Vec::with_capacity(total);
|
||||
|
||||
for ix in range {
|
||||
if let Some(contact) = contacts.get(ix) {
|
||||
items.push(
|
||||
h_flex()
|
||||
.h_11()
|
||||
.w_full()
|
||||
.px_2()
|
||||
.gap_1p5()
|
||||
.rounded(cx.theme().radius)
|
||||
.text_sm()
|
||||
.hover(|this| {
|
||||
this.bg(cx.theme().elevated_surface_background)
|
||||
})
|
||||
.child(Avatar::new(contact.avatar()).size(rems(1.75)))
|
||||
.child(contact.display_name()),
|
||||
);
|
||||
}
|
||||
let Some(contact) = contacts.get(ix) else {
|
||||
continue;
|
||||
};
|
||||
let profile = persons.read(cx).get(contact, cx);
|
||||
|
||||
items.push(
|
||||
h_flex()
|
||||
.h_11()
|
||||
.w_full()
|
||||
.px_2()
|
||||
.gap_1p5()
|
||||
.rounded(cx.theme().radius)
|
||||
.text_sm()
|
||||
.hover(|this| this.bg(cx.theme().elevated_surface_background))
|
||||
.child(Avatar::new(profile.avatar()).size(rems(1.75)))
|
||||
.child(profile.name()),
|
||||
);
|
||||
}
|
||||
|
||||
items
|
||||
@@ -234,7 +279,9 @@ impl Screening {
|
||||
|
||||
impl Render for Screening {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let shorten_pubkey = shorten_pubkey(self.profile.public_key(), 8);
|
||||
let profile = self.profile(cx);
|
||||
let shorten_pubkey = shorten_pubkey(self.public_key, 8);
|
||||
|
||||
let total_mutuals = self.mutual_contacts.len();
|
||||
let last_active = self.last_active.map(|_| true);
|
||||
|
||||
@@ -246,12 +293,12 @@ impl Render for Screening {
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.text_center()
|
||||
.child(Avatar::new(self.profile.avatar()).size(rems(4.)))
|
||||
.child(Avatar::new(profile.avatar()).size(rems(4.)))
|
||||
.child(
|
||||
div()
|
||||
.font_semibold()
|
||||
.line_height(relative(1.25))
|
||||
.child(self.profile.name()),
|
||||
.child(profile.name()),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
|
||||
@@ -5,6 +5,8 @@ use gpui::SharedString;
|
||||
use nostr_sdk::prelude::*;
|
||||
use state::Announcement;
|
||||
|
||||
const IMAGE_RESIZER: &str = "https://wsrv.nl";
|
||||
|
||||
/// Person
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Person {
|
||||
@@ -86,7 +88,12 @@ impl Person {
|
||||
.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())
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ common = { path = "../common" }
|
||||
nostr-sdk.workspace = true
|
||||
nostr-lmdb.workspace = true
|
||||
nostr-connect.workspace = true
|
||||
nostr-gossip-sqlite.workspace = true
|
||||
nostr-gossip-memory.workspace = true
|
||||
|
||||
gpui.workspace = true
|
||||
gpui_tokio.workspace = true
|
||||
|
||||
@@ -6,9 +6,8 @@ use std::time::Duration;
|
||||
use anyhow::{anyhow, Context as AnyhowContext, Error};
|
||||
use common::{config_dir, CLIENT_NAME};
|
||||
use gpui::{App, AppContext, Context, Entity, Global, Subscription, Task};
|
||||
use gpui_tokio::Tokio;
|
||||
use nostr_connect::prelude::*;
|
||||
use nostr_gossip_sqlite::prelude::*;
|
||||
use nostr_gossip_memory::prelude::*;
|
||||
use nostr_lmdb::NostrLmdb;
|
||||
use nostr_sdk::prelude::*;
|
||||
|
||||
@@ -125,20 +124,6 @@ impl NostrRegistry {
|
||||
.expect("Failed to initialize database")
|
||||
});
|
||||
|
||||
// Use tokio to spawn a task to build the gossip instance
|
||||
let build_gossip_sqlite = Tokio::spawn(cx, async move {
|
||||
NostrGossipSqlite::open(config_dir().join("gossip"))
|
||||
.await
|
||||
.expect("Failed to initialize gossip")
|
||||
});
|
||||
|
||||
// Initialize the nostr gossip instance
|
||||
let gossip = cx.foreground_executor().block_on(async move {
|
||||
build_gossip_sqlite
|
||||
.await
|
||||
.expect("Failed to initialize gossip")
|
||||
});
|
||||
|
||||
// Construct the nostr signer
|
||||
let app_keys = Self::create_or_init_app_keys().unwrap_or(Keys::generate());
|
||||
let signer = Arc::new(CoopSigner::new(app_keys.clone()));
|
||||
@@ -150,7 +135,7 @@ impl NostrRegistry {
|
||||
// Construct the nostr client
|
||||
let client = ClientBuilder::default()
|
||||
.signer(signer.clone())
|
||||
.gossip(gossip)
|
||||
.gossip(NostrGossipMemory::unbounded())
|
||||
.database(lmdb)
|
||||
.automatic_authentication(false)
|
||||
.verify_subscriptions(false)
|
||||
|
||||
Reference in New Issue
Block a user