feat: refine the search bar (#207)
* update deps * refactor the search cancellation * . * .
This commit is contained in:
144
Cargo.lock
generated
144
Cargo.lock
generated
@@ -504,15 +504,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async_zip"
|
||||
version = "0.0.17"
|
||||
version = "0.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b9f7252833d5ed4b00aa9604b563529dd5e11de9c23615de2dcdf91eb87b52"
|
||||
checksum = "0d8c50d65ce1b0e0cb65a785ff615f78860d7754290647d3b983208daa4f85e6"
|
||||
dependencies = [
|
||||
"async-compression",
|
||||
"crc32fast",
|
||||
"futures-lite 2.6.1",
|
||||
"pin-project",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror 2.0.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -602,9 +602,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-rs"
|
||||
version = "1.15.0"
|
||||
version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5932a7d9d28b0d2ea34c6b3779d35e3dd6f6345317c34e73438c4f1f29144151"
|
||||
checksum = "6b5ce75405893cd713f9ab8e297d8e438f624dde7d706108285f7e17a25a180f"
|
||||
dependencies = [
|
||||
"aws-lc-sys",
|
||||
"zeroize",
|
||||
@@ -612,11 +612,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-sys"
|
||||
version = "0.33.0"
|
||||
version = "0.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1826f2e4cfc2cd19ee53c42fbf68e2f81ec21108e0b7ecf6a71cf062137360fc"
|
||||
checksum = "179c3777a8b5e70e90ea426114ffc565b2c1a9f82f6c4a0c5a34aa6ef5e781b6"
|
||||
dependencies = [
|
||||
"bindgen 0.72.1",
|
||||
"cc",
|
||||
"cmake",
|
||||
"dunce",
|
||||
@@ -667,26 +666,6 @@ dependencies = [
|
||||
"syn 2.0.110",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.72.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools 0.13.0",
|
||||
"log",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash 2.1.1",
|
||||
"shlex",
|
||||
"syn 2.0.110",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bip39"
|
||||
version = "2.2.0"
|
||||
@@ -890,6 +869,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "btreecap"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6160c957d8aa33d0a8ba1dbab98e3cb57023ad9374c501441e88559f99e6c4c9"
|
||||
|
||||
[[package]]
|
||||
name = "built"
|
||||
version = "0.8.0"
|
||||
@@ -942,26 +927,25 @@ checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
|
||||
|
||||
[[package]]
|
||||
name = "calloop"
|
||||
version = "0.13.0"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec"
|
||||
checksum = "cb9f6e1368bd4621d2c86baa7e37de77a938adf5221e5dd3d6133340101b309e"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"log",
|
||||
"polling",
|
||||
"rustix 0.38.44",
|
||||
"rustix 1.1.2",
|
||||
"slab",
|
||||
"thiserror 1.0.69",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "calloop-wayland-source"
|
||||
version = "0.3.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20"
|
||||
checksum = "138efcf0940a02ebf0cc8d1eff41a1682a46b431630f4c52450d6265876021fa"
|
||||
dependencies = [
|
||||
"calloop",
|
||||
"rustix 0.38.44",
|
||||
"rustix 1.1.2",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
]
|
||||
@@ -995,9 +979,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.46"
|
||||
version = "1.2.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b97463e1064cb1b1c1384ad0a0b9c8abd0988e2a91f52606c80ef14aadb63e36"
|
||||
checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"jobserver",
|
||||
@@ -1242,7 +1226,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collections"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"rustc-hash 2.1.1",
|
||||
@@ -1674,7 +1658,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "derive_refineable"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2614,13 +2598,13 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gpui"
|
||||
version = "0.2.2"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"as-raw-xcb-connection",
|
||||
"ashpd 0.11.0",
|
||||
"async-task",
|
||||
"bindgen 0.71.1",
|
||||
"bindgen",
|
||||
"bitflags 2.10.0",
|
||||
"blade-graphics",
|
||||
"blade-macros",
|
||||
@@ -2713,7 +2697,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gpui_macros"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
@@ -2724,7 +2708,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gpui_tokio"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"gpui",
|
||||
@@ -2795,9 +2779,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.16.0"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
|
||||
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
@@ -2953,7 +2937,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "http_client"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-compression",
|
||||
@@ -2979,7 +2963,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "http_client_tls"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"rustls-platform-verifier",
|
||||
@@ -3269,12 +3253,12 @@ checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.12.0"
|
||||
version = "2.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f"
|
||||
checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.16.0",
|
||||
"hashbrown 0.16.1",
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
@@ -3775,10 +3759,10 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "media"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bindgen 0.71.1",
|
||||
"bindgen",
|
||||
"core-foundation 0.10.0",
|
||||
"core-video",
|
||||
"ctor",
|
||||
@@ -4025,7 +4009,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "nostr"
|
||||
version = "0.44.1"
|
||||
source = "git+https://github.com/rust-nostr/nostr#aa01f9fb8cd1ddbcc66e2b4ef58eeedbc0d54f56"
|
||||
source = "git+https://github.com/rust-nostr/nostr#8ab324a972145713466145e5daaf1e8351e6d7e7"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"base64",
|
||||
@@ -4049,7 +4033,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "nostr-connect"
|
||||
version = "0.44.0"
|
||||
source = "git+https://github.com/rust-nostr/nostr#aa01f9fb8cd1ddbcc66e2b4ef58eeedbc0d54f56"
|
||||
source = "git+https://github.com/rust-nostr/nostr#8ab324a972145713466145e5daaf1e8351e6d7e7"
|
||||
dependencies = [
|
||||
"async-utility",
|
||||
"nostr",
|
||||
@@ -4061,8 +4045,9 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "nostr-database"
|
||||
version = "0.44.0"
|
||||
source = "git+https://github.com/rust-nostr/nostr#aa01f9fb8cd1ddbcc66e2b4ef58eeedbc0d54f56"
|
||||
source = "git+https://github.com/rust-nostr/nostr#8ab324a972145713466145e5daaf1e8351e6d7e7"
|
||||
dependencies = [
|
||||
"btreecap",
|
||||
"flatbuffers",
|
||||
"lru",
|
||||
"nostr",
|
||||
@@ -4072,7 +4057,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "nostr-gossip"
|
||||
version = "0.44.0"
|
||||
source = "git+https://github.com/rust-nostr/nostr#aa01f9fb8cd1ddbcc66e2b4ef58eeedbc0d54f56"
|
||||
source = "git+https://github.com/rust-nostr/nostr#8ab324a972145713466145e5daaf1e8351e6d7e7"
|
||||
dependencies = [
|
||||
"nostr",
|
||||
]
|
||||
@@ -4080,7 +4065,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "nostr-lmdb"
|
||||
version = "0.44.0"
|
||||
source = "git+https://github.com/rust-nostr/nostr#aa01f9fb8cd1ddbcc66e2b4ef58eeedbc0d54f56"
|
||||
source = "git+https://github.com/rust-nostr/nostr#8ab324a972145713466145e5daaf1e8351e6d7e7"
|
||||
dependencies = [
|
||||
"async-utility",
|
||||
"flume",
|
||||
@@ -4094,7 +4079,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "nostr-relay-pool"
|
||||
version = "0.44.0"
|
||||
source = "git+https://github.com/rust-nostr/nostr#aa01f9fb8cd1ddbcc66e2b4ef58eeedbc0d54f56"
|
||||
source = "git+https://github.com/rust-nostr/nostr#8ab324a972145713466145e5daaf1e8351e6d7e7"
|
||||
dependencies = [
|
||||
"async-utility",
|
||||
"async-wsocket",
|
||||
@@ -4111,7 +4096,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "nostr-sdk"
|
||||
version = "0.44.1"
|
||||
source = "git+https://github.com/rust-nostr/nostr#aa01f9fb8cd1ddbcc66e2b4ef58eeedbc0d54f56"
|
||||
source = "git+https://github.com/rust-nostr/nostr#8ab324a972145713466145e5daaf1e8351e6d7e7"
|
||||
dependencies = [
|
||||
"async-utility",
|
||||
"nostr",
|
||||
@@ -4628,7 +4613,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||
[[package]]
|
||||
name = "perf"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"collections",
|
||||
"serde",
|
||||
@@ -5254,7 +5239,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "refineable"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"derive_refineable",
|
||||
]
|
||||
@@ -5352,7 +5337,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "reqwest_client"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -5406,7 +5391,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rope"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"log",
|
||||
@@ -5872,7 +5857,7 @@ checksum = "16c2f82143577edb4921b71ede051dac62ca3c16084e918bf7b40c96ae10eb33"
|
||||
[[package]]
|
||||
name = "semantic_version"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde",
|
||||
@@ -6327,7 +6312,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
[[package]]
|
||||
name = "sum_tree"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"log",
|
||||
@@ -6978,6 +6963,7 @@ version = "0.1.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
@@ -7295,7 +7281,7 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||
[[package]]
|
||||
name = "util"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-fs",
|
||||
@@ -7331,7 +7317,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "util_macros"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zed-industries/zed#1e2f15a3d70258ab366e9ac9309605749d5b0a27"
|
||||
source = "git+https://github.com/zed-industries/zed#de58a496efd3379dd787326c678b931ffff4213f"
|
||||
dependencies = [
|
||||
"perf",
|
||||
"quote",
|
||||
@@ -7370,9 +7356,9 @@ checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
||||
|
||||
[[package]]
|
||||
name = "value-bag"
|
||||
version = "1.11.1"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "943ce29a8a743eb10d6082545d861b24f9d1b160b7d741e0f2cdf726bec909c5"
|
||||
checksum = "7ba6f5989077681266825251a52748b8c1d8a4ad098cc37e440103d0ea717fc0"
|
||||
dependencies = [
|
||||
"value-bag-serde1",
|
||||
"value-bag-sval2",
|
||||
@@ -7380,20 +7366,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "value-bag-serde1"
|
||||
version = "1.11.1"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35540706617d373b118d550d41f5dfe0b78a0c195dc13c6815e92e2638432306"
|
||||
checksum = "16530907bfe2999a1773ca5900a65101e092c70f642f25cc23ca0c43573262c5"
|
||||
dependencies = [
|
||||
"erased-serde",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"serde_fmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "value-bag-sval2"
|
||||
version = "1.11.1"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fe7e140a2658cc16f7ee7a86e413e803fc8f9b5127adc8755c19f9fefa63a52"
|
||||
checksum = "d00ae130edd690eaa877e4f40605d534790d1cf1d651e7685bd6a144521b251f"
|
||||
dependencies = [
|
||||
"sval",
|
||||
"sval_buffer",
|
||||
@@ -8723,18 +8709,18 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.27"
|
||||
version = "0.8.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c"
|
||||
checksum = "43fa6694ed34d6e57407afbccdeecfa268c470a7d2a5b0cf49ce9fcc345afb90"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.27"
|
||||
version = "0.8.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
|
||||
checksum = "c640b22cd9817fae95be82f0d2f90b11f7605f6c319d16705c459b27ac2cbc26"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
@@ -11,7 +11,11 @@ pub const BOOTSTRAP_RELAYS: [&str; 5] = [
|
||||
];
|
||||
|
||||
/// Search Relays.
|
||||
pub const SEARCH_RELAYS: [&str; 1] = ["wss://relay.nostr.band"];
|
||||
pub const SEARCH_RELAYS: [&str; 3] = [
|
||||
"wss://relay.nostr.band",
|
||||
"wss://search.nos.today",
|
||||
"wss://relay.noswhere.com",
|
||||
];
|
||||
|
||||
/// Default relay for Nostr Connect
|
||||
pub const NOSTR_CONNECT_RELAY: &str = "wss://relay.nsec.app";
|
||||
|
||||
@@ -35,8 +35,8 @@ use ui::{h_flex, v_flex, ContextModal, IconName, Root, Sizable, StyledExt};
|
||||
use crate::actions::{reset, DarkMode, KeyringPopup, Logout, Settings, ViewProfile, ViewRelays};
|
||||
use crate::user::viewer;
|
||||
use crate::views::compose::compose_button;
|
||||
use crate::views::{onboarding, preferences, setup_relay, sidebar, startup, welcome};
|
||||
use crate::{login, new_identity, user};
|
||||
use crate::views::{onboarding, preferences, setup_relay, startup, welcome};
|
||||
use crate::{login, new_identity, sidebar, user};
|
||||
|
||||
pub fn init(window: &mut Window, cx: &mut App) -> Entity<ChatSpace> {
|
||||
cx.new(|cx| ChatSpace::new(window, cx))
|
||||
|
||||
@@ -111,7 +111,7 @@ impl Login {
|
||||
}
|
||||
|
||||
fn login_with_bunker(&mut self, content: &str, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let Ok(uri) = NostrConnectURI::parse(content) else {
|
||||
let Ok(uri) = NostrConnectUri::parse(content) else {
|
||||
self.set_error(t!("login.bunker_invalid"), cx);
|
||||
return;
|
||||
};
|
||||
@@ -165,7 +165,7 @@ impl Login {
|
||||
fn save_connection(
|
||||
&mut self,
|
||||
keys: &Keys,
|
||||
uri: &NostrConnectURI,
|
||||
uri: &NostrConnectUri,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
|
||||
@@ -15,6 +15,7 @@ mod actions;
|
||||
mod chatspace;
|
||||
mod login;
|
||||
mod new_identity;
|
||||
mod sidebar;
|
||||
mod user;
|
||||
mod views;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::collections::BTreeSet;
|
||||
use std::ops::Range;
|
||||
use std::time::Duration;
|
||||
|
||||
use account::Account;
|
||||
use anyhow::{anyhow, Error};
|
||||
use chat::{ChatEvent, ChatRegistry, Room, RoomKind};
|
||||
use common::{DebouncedDelay, RenderedTimestamp, TextUtils, BOOTSTRAP_RELAYS, SEARCH_RELAYS};
|
||||
@@ -13,7 +13,6 @@ use gpui::{
|
||||
};
|
||||
use gpui_tokio::Tokio;
|
||||
use i18n::{shared_t, t};
|
||||
use itertools::Itertools;
|
||||
use list_item::RoomListItem;
|
||||
use nostr_sdk::prelude::*;
|
||||
use settings::AppSettings;
|
||||
@@ -31,42 +30,43 @@ use crate::actions::{RelayStatus, Reload};
|
||||
mod list_item;
|
||||
|
||||
const FIND_DELAY: u64 = 600;
|
||||
const FIND_LIMIT: usize = 10;
|
||||
const FIND_LIMIT: usize = 20;
|
||||
|
||||
pub fn init(window: &mut Window, cx: &mut App) -> Entity<Sidebar> {
|
||||
Sidebar::new(window, cx)
|
||||
cx.new(|cx| Sidebar::new(window, cx))
|
||||
}
|
||||
|
||||
pub struct Sidebar {
|
||||
name: SharedString,
|
||||
// Search
|
||||
|
||||
/// Focus handle for the sidebar
|
||||
focus_handle: FocusHandle,
|
||||
|
||||
/// Image cache
|
||||
image_cache: Entity<RetainAllImageCache>,
|
||||
|
||||
/// Search results
|
||||
search_results: Entity<Option<Vec<Entity<Room>>>>,
|
||||
|
||||
/// Async search operation
|
||||
search_task: Option<Task<()>>,
|
||||
|
||||
find_input: Entity<InputState>,
|
||||
find_debouncer: DebouncedDelay<Self>,
|
||||
finding: bool,
|
||||
cancel_handle: Entity<Option<smol::channel::Sender<()>>>,
|
||||
local_result: Entity<Option<Vec<Entity<Room>>>>,
|
||||
global_result: Entity<Option<Vec<Entity<Room>>>>,
|
||||
// Rooms
|
||||
|
||||
indicator: Entity<Option<RoomKind>>,
|
||||
active_filter: Entity<RoomKind>,
|
||||
// GPUI
|
||||
focus_handle: FocusHandle,
|
||||
image_cache: Entity<RetainAllImageCache>,
|
||||
#[allow(dead_code)]
|
||||
subscriptions: SmallVec<[Subscription; 3]>,
|
||||
|
||||
/// Event subscriptions
|
||||
_subscriptions: SmallVec<[Subscription; 3]>,
|
||||
}
|
||||
|
||||
impl Sidebar {
|
||||
pub fn new(window: &mut Window, cx: &mut App) -> Entity<Self> {
|
||||
cx.new(|cx| Self::view(window, cx))
|
||||
}
|
||||
|
||||
fn view(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let active_filter = cx.new(|_| RoomKind::Ongoing);
|
||||
let indicator = cx.new(|_| None);
|
||||
let local_result = cx.new(|_| None);
|
||||
let global_result = cx.new(|_| None);
|
||||
let cancel_handle = cx.new(|_| None);
|
||||
let search_results = cx.new(|_| None);
|
||||
|
||||
let find_input =
|
||||
cx.new(|cx| InputState::new(window, cx).placeholder(t!("sidebar.search_label")));
|
||||
@@ -99,11 +99,13 @@ impl Sidebar {
|
||||
// Subscribe for find input events
|
||||
cx.subscribe_in(&find_input, window, |this, state, event, window, cx| {
|
||||
match event {
|
||||
InputEvent::PressEnter { .. } => this.search(window, cx),
|
||||
InputEvent::PressEnter { .. } => {
|
||||
this.search(window, cx);
|
||||
}
|
||||
InputEvent::Change => {
|
||||
// Clear the result when input is empty
|
||||
if state.read(cx).value().is_empty() {
|
||||
this.clear_search_results(window, cx);
|
||||
this.clear(window, cx);
|
||||
} else {
|
||||
// Run debounced search
|
||||
this.find_debouncer.fire_new(
|
||||
@@ -125,62 +127,65 @@ impl Sidebar {
|
||||
image_cache: RetainAllImageCache::new(cx),
|
||||
find_debouncer: DebouncedDelay::new(),
|
||||
finding: false,
|
||||
cancel_handle,
|
||||
indicator,
|
||||
active_filter,
|
||||
find_input,
|
||||
local_result,
|
||||
global_result,
|
||||
subscriptions,
|
||||
search_results,
|
||||
search_task: None,
|
||||
_subscriptions: subscriptions,
|
||||
}
|
||||
}
|
||||
|
||||
async fn request_metadata(client: &Client, public_key: PublicKey) -> Result<(), Error> {
|
||||
let opts = SubscribeAutoCloseOptions::default().exit_policy(ReqExitPolicy::ExitOnEOSE);
|
||||
let kinds = vec![Kind::Metadata, Kind::ContactList];
|
||||
let filter = Filter::new().author(public_key).kinds(kinds).limit(10);
|
||||
|
||||
client
|
||||
.subscribe_to(BOOTSTRAP_RELAYS, filter, Some(opts))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn nip50(client: &Client, query: &str) -> Result<BTreeSet<Room>, Error> {
|
||||
async fn nip50(client: &Client, query: &str) -> Result<Vec<Event>, Error> {
|
||||
let signer = client.signer().await?;
|
||||
let public_key = signer.get_public_key().await?;
|
||||
|
||||
let timeout = Duration::from_secs(2);
|
||||
let mut rooms: BTreeSet<Room> = BTreeSet::new();
|
||||
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::Metadata)
|
||||
.search(query.to_lowercase())
|
||||
.limit(FIND_LIMIT);
|
||||
|
||||
if let Ok(events) = client
|
||||
.fetch_events_from(SEARCH_RELAYS, filter, timeout)
|
||||
.await
|
||||
{
|
||||
// Process to verify the search results
|
||||
for event in events.into_iter().unique_by(|event| event.pubkey) {
|
||||
let mut stream = client
|
||||
.stream_events_from(SEARCH_RELAYS, filter, Duration::from_secs(3))
|
||||
.await?;
|
||||
|
||||
let mut results: Vec<Event> = Vec::with_capacity(FIND_LIMIT);
|
||||
|
||||
while let Some(event) = stream.next().await {
|
||||
// Skip if author is match current user
|
||||
if event.pubkey == public_key {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Request metadata event's author
|
||||
Self::request_metadata(client, event.pubkey).await?;
|
||||
|
||||
// Construct room
|
||||
let room = Room::new(None, public_key, vec![event.pubkey]);
|
||||
|
||||
rooms.insert(room);
|
||||
}
|
||||
// Skip if the event has already been added
|
||||
if results.iter().any(|this| this.pubkey == event.pubkey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Ok(rooms)
|
||||
results.push(event);
|
||||
}
|
||||
|
||||
if results.is_empty() {
|
||||
return Err(anyhow!("No results for query {query}"));
|
||||
}
|
||||
|
||||
// Get all public keys
|
||||
let public_keys: Vec<PublicKey> = results.iter().map(|event| event.pubkey).collect();
|
||||
|
||||
// Fetch metadata and contact lists if public keys is not empty
|
||||
if !public_keys.is_empty() {
|
||||
let opts = SubscribeAutoCloseOptions::default().exit_policy(ReqExitPolicy::ExitOnEOSE);
|
||||
let filter = Filter::new()
|
||||
.kinds(vec![Kind::Metadata, Kind::ContactList])
|
||||
.limit(public_keys.len() * 2)
|
||||
.authors(public_keys);
|
||||
|
||||
client
|
||||
.subscribe_to(BOOTSTRAP_RELAYS, filter, Some(opts))
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
fn debounced_search(&self, window: &mut Window, cx: &mut Context<Self>) -> Task<()> {
|
||||
@@ -192,63 +197,38 @@ impl Sidebar {
|
||||
})
|
||||
}
|
||||
|
||||
fn search_by_nip50(
|
||||
&mut self,
|
||||
query: &str,
|
||||
rx: smol::channel::Receiver<()>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
fn search_by_nip50(&mut self, query: &str, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let account = Account::global(cx);
|
||||
let public_key = account.read(cx).public_key();
|
||||
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let client = nostr.read(cx).client();
|
||||
|
||||
let query = query.to_owned();
|
||||
let query_cloned = query.clone();
|
||||
|
||||
let task = smol::future::or(
|
||||
Tokio::spawn(cx, async move { Self::nip50(&client, &query).await.ok() }),
|
||||
Tokio::spawn(cx, async move {
|
||||
let _ = rx.recv().await.is_ok();
|
||||
None
|
||||
}),
|
||||
);
|
||||
self.search_task = Some(cx.spawn_in(window, async move |this, cx| {
|
||||
let result = Self::nip50(&client, &query).await;
|
||||
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
match task.await {
|
||||
Ok(Some(results)) => {
|
||||
this.update_in(cx, |this, window, cx| {
|
||||
let msg = t!("sidebar.empty", query = query_cloned);
|
||||
let rooms = results.into_iter().map(|r| cx.new(|_| r)).collect_vec();
|
||||
match result {
|
||||
Ok(results) => {
|
||||
let rooms = results
|
||||
.into_iter()
|
||||
.map(|event| {
|
||||
cx.new(|_| Room::new(None, public_key, vec![event.pubkey]))
|
||||
})
|
||||
.collect();
|
||||
|
||||
if rooms.is_empty() {
|
||||
window.push_notification(msg, cx);
|
||||
this.set_results(rooms, cx);
|
||||
}
|
||||
|
||||
this.results(rooms, true, window, cx);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
// User cancelled the search
|
||||
Ok(None) => {
|
||||
cx.update(|window, cx| {
|
||||
this.update(cx, |this, cx| {
|
||||
this.set_finding(false, window, cx);
|
||||
this.set_cancel_handle(None, cx);
|
||||
})
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
// Async task failed
|
||||
Err(e) => {
|
||||
this.update_in(cx, |this, window, cx| {
|
||||
window.push_notification(e.to_string(), cx);
|
||||
this.set_finding(false, window, cx);
|
||||
this.set_cancel_handle(None, cx);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
};
|
||||
this.set_finding(false, window, cx);
|
||||
})
|
||||
.detach();
|
||||
.ok();
|
||||
}));
|
||||
}
|
||||
|
||||
fn search_by_nip05(&mut self, query: &str, window: &mut Window, cx: &mut Context<Self>) {
|
||||
@@ -261,7 +241,8 @@ impl Sidebar {
|
||||
Ok(profile) => {
|
||||
let signer = client.signer().await?;
|
||||
let public_key = signer.get_public_key().await?;
|
||||
let room = Room::new(None, public_key, vec![profile.public_key]);
|
||||
let receivers = vec![profile.public_key];
|
||||
let room = Room::new(None, public_key, receivers);
|
||||
|
||||
Ok(room)
|
||||
}
|
||||
@@ -269,40 +250,25 @@ impl Sidebar {
|
||||
}
|
||||
});
|
||||
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
match task.await {
|
||||
self.search_task = Some(cx.spawn_in(window, async move |this, cx| {
|
||||
let result = task.await;
|
||||
|
||||
this.update_in(cx, |this, window, cx| {
|
||||
match result {
|
||||
Ok(Ok(room)) => {
|
||||
cx.update(|window, cx| {
|
||||
this.update(cx, |this, cx| {
|
||||
this.results(vec![cx.new(|_| room)], true, window, cx);
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
.ok();
|
||||
this.set_results(vec![cx.new(|_| room)], cx);
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
cx.update(|window, cx| {
|
||||
this.update(cx, |this, cx| {
|
||||
window.push_notification(e.to_string(), cx);
|
||||
this.set_cancel_handle(None, cx);
|
||||
this.set_finding(false, window, cx);
|
||||
})
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
Err(e) => {
|
||||
cx.update(|window, cx| {
|
||||
this.update(cx, |this, cx| {
|
||||
window.push_notification(e.to_string(), cx);
|
||||
this.set_cancel_handle(None, cx);
|
||||
}
|
||||
}
|
||||
this.set_finding(false, window, cx);
|
||||
})
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
};
|
||||
})
|
||||
.detach();
|
||||
}));
|
||||
}
|
||||
|
||||
fn search_by_pubkey(&mut self, query: &str, window: &mut Window, cx: &mut Context<Self>) {
|
||||
@@ -310,7 +276,7 @@ impl Sidebar {
|
||||
let client = nostr.read(cx).client();
|
||||
|
||||
let Ok(public_key) = query.to_public_key() else {
|
||||
window.push_notification(t!("common.pubkey_invalid"), cx);
|
||||
window.push_notification("Public Key is invalid", cx);
|
||||
self.set_finding(false, window, cx);
|
||||
return;
|
||||
};
|
||||
@@ -318,46 +284,49 @@ impl Sidebar {
|
||||
let task: Task<Result<Room, Error>> = cx.background_spawn(async move {
|
||||
let signer = client.signer().await?;
|
||||
let author = signer.get_public_key().await?;
|
||||
let room = Room::new(None, author, vec![public_key]);
|
||||
|
||||
Self::request_metadata(&client, public_key).await?;
|
||||
let opts = SubscribeAutoCloseOptions::default().exit_policy(ReqExitPolicy::ExitOnEOSE);
|
||||
let receivers = vec![public_key];
|
||||
let room = Room::new(None, author, receivers);
|
||||
|
||||
let filter = Filter::new()
|
||||
.kinds(vec![Kind::Metadata, Kind::ContactList])
|
||||
.author(public_key)
|
||||
.limit(2);
|
||||
|
||||
client
|
||||
.subscribe_to(BOOTSTRAP_RELAYS, filter, Some(opts))
|
||||
.await?;
|
||||
|
||||
Ok(room)
|
||||
});
|
||||
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
match task.await {
|
||||
Ok(room) => {
|
||||
cx.update(|window, cx| {
|
||||
this.update(cx, |this, cx| {
|
||||
let chat = ChatRegistry::global(cx);
|
||||
let result = chat.read(cx).search_by_public_key(public_key, cx);
|
||||
self.search_task = Some(cx.spawn_in(window, async move |this, cx| {
|
||||
let result = task.await;
|
||||
|
||||
if !result.is_empty() {
|
||||
this.results(result, false, window, cx);
|
||||
this.update_in(cx, |this, window, cx| {
|
||||
match result {
|
||||
Ok(room) => {
|
||||
let chat = ChatRegistry::global(cx);
|
||||
let local_results = chat.read(cx).search_by_public_key(public_key, cx);
|
||||
|
||||
if !local_results.is_empty() {
|
||||
this.set_results(local_results, cx);
|
||||
} else {
|
||||
this.results(vec![cx.new(|_| room)], true, window, cx);
|
||||
this.set_results(vec![cx.new(|_| room)], cx);
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
Err(e) => {
|
||||
cx.update(|window, cx| {
|
||||
window.push_notification(e.to_string(), cx);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
};
|
||||
this.set_finding(false, window, cx);
|
||||
})
|
||||
.detach();
|
||||
.ok();
|
||||
}));
|
||||
}
|
||||
|
||||
fn search(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let (tx, rx) = smol::channel::bounded::<()>(1);
|
||||
let tx_clone = tx.clone();
|
||||
|
||||
// Return if the query is empty
|
||||
if self.find_input.read(cx).value().is_empty() {
|
||||
return;
|
||||
@@ -365,15 +334,12 @@ impl Sidebar {
|
||||
|
||||
// Return if search is in progress
|
||||
if self.finding {
|
||||
if self.cancel_handle.read(cx).is_none() {
|
||||
window.push_notification(t!("sidebar.search_in_progress"), cx);
|
||||
if self.search_task.is_none() {
|
||||
window.push_notification("There is another search in progress", cx);
|
||||
return;
|
||||
} else {
|
||||
// This is a hack to cancel ongoing search request
|
||||
cx.background_spawn(async move {
|
||||
tx.send(()).await.ok();
|
||||
})
|
||||
.detach();
|
||||
// Cancel ongoing search request
|
||||
self.search_task = None;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,48 +364,25 @@ impl Sidebar {
|
||||
}
|
||||
}
|
||||
|
||||
let chat = ChatRegistry::global(cx);
|
||||
// Get all local results with current query
|
||||
let chat = ChatRegistry::global(cx);
|
||||
let local_results = chat.read(cx).search(&query, cx);
|
||||
|
||||
if !local_results.is_empty() {
|
||||
// Try to update with local results first
|
||||
self.results(local_results, false, window, cx);
|
||||
} else {
|
||||
if !local_results.is_empty() {
|
||||
self.set_results(local_results, cx);
|
||||
return;
|
||||
};
|
||||
|
||||
// If no local results, try global search via NIP-50
|
||||
self.set_cancel_handle(Some(tx_clone), cx);
|
||||
self.search_by_nip50(&query, rx, window, cx);
|
||||
}
|
||||
self.search_by_nip50(&query, window, cx);
|
||||
}
|
||||
|
||||
fn results(
|
||||
&mut self,
|
||||
rooms: Vec<Entity<Room>>,
|
||||
global: bool,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if self.finding {
|
||||
self.set_finding(false, window, cx);
|
||||
}
|
||||
|
||||
if self.cancel_handle.read(cx).is_some() {
|
||||
self.set_cancel_handle(None, cx);
|
||||
}
|
||||
|
||||
if !rooms.is_empty() {
|
||||
if global {
|
||||
self.global_result.update(cx, |this, cx| {
|
||||
fn set_results(&mut self, rooms: Vec<Entity<Room>>, cx: &mut Context<Self>) {
|
||||
self.search_results.update(cx, |this, cx| {
|
||||
*this = Some(rooms);
|
||||
cx.notify();
|
||||
});
|
||||
} else {
|
||||
self.local_result.update(cx, |this, cx| {
|
||||
*this = Some(rooms);
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_finding(&mut self, status: bool, _window: &mut Window, cx: &mut Context<Self>) {
|
||||
@@ -453,31 +396,14 @@ impl Sidebar {
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn set_cancel_handle(
|
||||
&mut self,
|
||||
handle: Option<smol::channel::Sender<()>>,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.cancel_handle.update(cx, |this, cx| {
|
||||
*this = handle;
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
|
||||
fn clear_search_results(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
fn clear(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
// Reset the input state
|
||||
if self.finding {
|
||||
self.set_finding(false, window, cx);
|
||||
}
|
||||
|
||||
// Clear all local results
|
||||
self.local_result.update(cx, |this, cx| {
|
||||
*this = None;
|
||||
cx.notify();
|
||||
});
|
||||
|
||||
// Clear all global results
|
||||
self.global_result.update(cx, |this, cx| {
|
||||
self.search_results.update(cx, |this, cx| {
|
||||
*this = None;
|
||||
cx.notify();
|
||||
});
|
||||
@@ -499,10 +425,11 @@ impl Sidebar {
|
||||
}
|
||||
|
||||
fn open_room(&mut self, id: u64, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let room = if let Some(room) = ChatRegistry::global(cx).read(cx).room(&id, cx) {
|
||||
let chat = ChatRegistry::global(cx);
|
||||
let room = if let Some(room) = chat.read(cx).room(&id, cx) {
|
||||
room
|
||||
} else {
|
||||
let Some(result) = self.global_result.read(cx).as_ref() else {
|
||||
let Some(result) = self.search_results.read(cx).as_ref() else {
|
||||
window.push_notification(t!("common.room_error"), cx);
|
||||
return;
|
||||
};
|
||||
@@ -513,12 +440,12 @@ impl Sidebar {
|
||||
};
|
||||
|
||||
// Clear all search results
|
||||
self.clear_search_results(window, cx);
|
||||
self.clear(window, cx);
|
||||
|
||||
room
|
||||
};
|
||||
|
||||
ChatRegistry::global(cx).update(cx, |this, cx| {
|
||||
chat.update(cx, |this, cx| {
|
||||
this.push_room(room, cx);
|
||||
});
|
||||
}
|
||||
@@ -673,12 +600,10 @@ impl Render for Sidebar {
|
||||
let loading = chat.read(cx).loading;
|
||||
|
||||
// Get rooms from either search results or the chat registry
|
||||
let rooms = if let Some(results) = self.local_result.read(cx).as_ref() {
|
||||
results.to_owned()
|
||||
} else if let Some(results) = self.global_result.read(cx).as_ref() {
|
||||
let rooms = if let Some(results) = self.search_results.read(cx).as_ref() {
|
||||
results.to_owned()
|
||||
} else {
|
||||
#[allow(clippy::collapsible_else_if)]
|
||||
// Filter rooms based on the active filter
|
||||
if self.active_filter.read(cx) == &RoomKind::Ongoing {
|
||||
chat.read(cx).ongoing_rooms(cx)
|
||||
} else {
|
||||
@@ -717,13 +642,19 @@ impl Render for Sidebar {
|
||||
.cleanable()
|
||||
.appearance(true)
|
||||
.text_xs()
|
||||
.suffix(
|
||||
.map(|this| {
|
||||
if !self.find_input.read(cx).loading {
|
||||
this.suffix(
|
||||
Button::new("find")
|
||||
.icon(IconName::Search)
|
||||
.tooltip(t!("sidebar.search_tooltip"))
|
||||
.transparent()
|
||||
.small(),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}),
|
||||
),
|
||||
)
|
||||
// Chat Rooms
|
||||
@@ -3,6 +3,5 @@ pub mod onboarding;
|
||||
pub mod preferences;
|
||||
pub mod screening;
|
||||
pub mod setup_relay;
|
||||
pub mod sidebar;
|
||||
pub mod startup;
|
||||
pub mod welcome;
|
||||
|
||||
@@ -78,7 +78,7 @@ impl Onboarding {
|
||||
let timeout = Duration::from_secs(NOSTR_CONNECT_TIMEOUT);
|
||||
|
||||
let relay = RelayUrl::parse(NOSTR_CONNECT_RELAY).unwrap();
|
||||
let uri = NostrConnectURI::client(app_keys.public_key(), vec![relay], CLIENT_NAME);
|
||||
let uri = NostrConnectUri::client(app_keys.public_key(), vec![relay], CLIENT_NAME);
|
||||
let qr_code = uri.to_string().to_qr();
|
||||
|
||||
// NIP46: https://github.com/nostr-protocol/nips/blob/master/46.md
|
||||
@@ -119,7 +119,7 @@ impl Onboarding {
|
||||
|
||||
fn save_connection(
|
||||
&mut self,
|
||||
uri: &NostrConnectURI,
|
||||
uri: &NostrConnectUri,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
|
||||
@@ -76,7 +76,7 @@ impl Startup {
|
||||
|
||||
// Try to login with bunker
|
||||
if secret.starts_with("bunker://") {
|
||||
match NostrConnectURI::parse(secret) {
|
||||
match NostrConnectUri::parse(secret) {
|
||||
Ok(uri) => {
|
||||
self.login_with_bunker(uri, window, cx);
|
||||
}
|
||||
@@ -102,7 +102,7 @@ impl Startup {
|
||||
|
||||
fn login_with_bunker(
|
||||
&mut self,
|
||||
uri: NostrConnectURI,
|
||||
uri: NostrConnectUri,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
|
||||
@@ -69,9 +69,15 @@ impl NostrRegistry {
|
||||
timeout: Duration::from_secs(600),
|
||||
});
|
||||
|
||||
// Construct the nostr client
|
||||
// Construct the lmdb
|
||||
let lmdb = cx.background_executor().block(async move {
|
||||
let path = config_dir().join("nostr");
|
||||
let lmdb = NostrLMDB::open(path).expect("Failed to initialize database");
|
||||
NostrLMDB::open(path)
|
||||
.await
|
||||
.expect("Failed to initialize database")
|
||||
});
|
||||
|
||||
// Construct the nostr client
|
||||
let client = ClientBuilder::default().database(lmdb).opts(opts).build();
|
||||
|
||||
let tracker = Arc::new(RwLock::new(EventTracker::default()));
|
||||
|
||||
Reference in New Issue
Block a user