feat: improve performance (#234)

* feat: use negentropy as much as possible

* update

* update
This commit is contained in:
雨宮蓮
2024-09-29 16:53:39 +07:00
committed by GitHub
parent afa9327bb7
commit f0fc89724d
26 changed files with 566 additions and 373 deletions

297
src-tauri/Cargo.lock generated
View File

@@ -318,7 +318,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -353,7 +353,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -427,9 +427,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "autocfg"
version = "1.3.0"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "backtrace"
@@ -499,9 +499,9 @@ checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]]
name = "bitcoin"
version = "0.32.2"
version = "0.32.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea507acc1cd80fc084ace38544bbcf7ced7c2aa65b653b102de0ce718df668f6"
checksum = "0032b0e8ead7074cda7fc4f034409607e3f03a6f71d66ade8a307f79b4d99e73"
dependencies = [
"base58ck",
"bech32",
@@ -621,7 +621,7 @@ dependencies = [
[[package]]
name = "border"
version = "0.1.0"
source = "git+https://github.com/ahkohd/tauri-toolkit?branch=v2#e2890ea09160354103406e1e2a908a3816a2a89c"
source = "git+https://github.com/ahkohd/tauri-toolkit?branch=v2#b74c963eee82d8f269c5c8848d12fd3b28fe329a"
dependencies = [
"cocoa 0.25.0",
"color",
@@ -763,9 +763,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.1.21"
version = "1.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0"
checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0"
dependencies = [
"shlex",
]
@@ -929,7 +929,7 @@ dependencies = [
[[package]]
name = "color"
version = "0.1.0"
source = "git+https://github.com/ahkohd/tauri-toolkit?branch=v2#e2890ea09160354103406e1e2a908a3816a2a89c"
source = "git+https://github.com/ahkohd/tauri-toolkit?branch=v2#b74c963eee82d8f269c5c8848d12fd3b28fe329a"
dependencies = [
"cocoa 0.25.0",
"objc",
@@ -1171,7 +1171,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
dependencies = [
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -1181,7 +1181,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
dependencies = [
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -1205,7 +1205,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -1216,7 +1216,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [
"darling_core",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -1260,7 +1260,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -1273,7 +1273,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustc_version",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -1343,7 +1343,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -1366,7 +1366,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -1431,9 +1431,9 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
[[package]]
name = "embed-resource"
version = "2.4.3"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4edcacde9351c33139a41e3c97eb2334351a81a2791bebb0b243df837128f602"
checksum = "f4e24052d7be71f0efb50c201557f6fe7d237cfd5a64fd5bcd7fd8fe32dbbffa"
dependencies = [
"cc",
"memchr",
@@ -1495,7 +1495,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -1575,9 +1575,9 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
[[package]]
name = "fdeflate"
version = "0.3.4"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645"
checksum = "d8090f921a24b04994d9929e204f50b498a33ea6ba559ffaa05e04f7ee7fb5ab"
dependencies = [
"simd-adler32",
]
@@ -1625,9 +1625,9 @@ dependencies = [
[[package]]
name = "flate2"
version = "1.0.33"
version = "1.0.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253"
checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0"
dependencies = [
"crc32fast",
"miniz_oxide 0.8.0",
@@ -1684,7 +1684,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -1797,7 +1797,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -1938,19 +1938,6 @@ dependencies = [
"x11",
]
[[package]]
name = "generator"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e"
dependencies = [
"cc",
"libc",
"log",
"rustversion",
"windows 0.48.0",
]
[[package]]
name = "generic-array"
version = "0.14.7"
@@ -2077,7 +2064,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -2168,7 +2155,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -2930,21 +2917,6 @@ version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "loom"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5"
dependencies = [
"cfg-if",
"generator",
"scoped-tls",
"serde",
"serde_json",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "lru"
version = "0.12.4"
@@ -2996,15 +2968,6 @@ dependencies = [
"tendril",
]
[[package]]
name = "matchers"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
dependencies = [
"regex-automata 0.1.10",
]
[[package]]
name = "matches"
version = "0.1.10"
@@ -3060,7 +3023,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
dependencies = [
"adler",
"simd-adler32",
]
[[package]]
@@ -3070,6 +3032,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
dependencies = [
"adler2",
"simd-adler32",
]
[[package]]
@@ -3087,7 +3050,7 @@ dependencies = [
[[package]]
name = "monitor"
version = "0.1.0"
source = "git+https://github.com/ahkohd/tauri-toolkit?branch=v2#e2890ea09160354103406e1e2a908a3816a2a89c"
source = "git+https://github.com/ahkohd/tauri-toolkit?branch=v2#b74c963eee82d8f269c5c8848d12fd3b28fe329a"
dependencies = [
"cocoa 0.25.0",
"core-foundation 0.9.4",
@@ -3100,16 +3063,17 @@ dependencies = [
[[package]]
name = "muda"
version = "0.14.1"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba8ac4080fb1e097c2c22acae467e46e4da72d941f02e82b67a87a2a89fa38b1"
checksum = "b8123dfd4996055ac9b15a60ad263b44b01e539007523ad7a4a533a3d93b0591"
dependencies = [
"cocoa 0.26.0",
"crossbeam-channel",
"dpi",
"gtk",
"keyboard-types",
"objc",
"objc2",
"objc2-app-kit",
"objc2-foundation",
"once_cell",
"png",
"serde",
@@ -3225,7 +3189,7 @@ dependencies = [
[[package]]
name = "nostr"
version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#e99e56e712ac4f3830390619e52ccd11a2b41f9e"
source = "git+https://github.com/rust-nostr/nostr#263833f295588bf7d9b35a8f9e93bf05ae8a5e76"
dependencies = [
"aes",
"base64 0.22.1",
@@ -3255,7 +3219,7 @@ dependencies = [
[[package]]
name = "nostr-database"
version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#e99e56e712ac4f3830390619e52ccd11a2b41f9e"
source = "git+https://github.com/rust-nostr/nostr#263833f295588bf7d9b35a8f9e93bf05ae8a5e76"
dependencies = [
"async-trait",
"flatbuffers",
@@ -3269,7 +3233,7 @@ dependencies = [
[[package]]
name = "nostr-lmdb"
version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#e99e56e712ac4f3830390619e52ccd11a2b41f9e"
source = "git+https://github.com/rust-nostr/nostr#263833f295588bf7d9b35a8f9e93bf05ae8a5e76"
dependencies = [
"heed",
"nostr",
@@ -3282,7 +3246,7 @@ dependencies = [
[[package]]
name = "nostr-relay-builder"
version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#e99e56e712ac4f3830390619e52ccd11a2b41f9e"
source = "git+https://github.com/rust-nostr/nostr#263833f295588bf7d9b35a8f9e93bf05ae8a5e76"
dependencies = [
"async-utility",
"async-wsocket",
@@ -3297,7 +3261,7 @@ dependencies = [
[[package]]
name = "nostr-relay-pool"
version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#e99e56e712ac4f3830390619e52ccd11a2b41f9e"
source = "git+https://github.com/rust-nostr/nostr#263833f295588bf7d9b35a8f9e93bf05ae8a5e76"
dependencies = [
"async-utility",
"async-wsocket",
@@ -3315,7 +3279,7 @@ dependencies = [
[[package]]
name = "nostr-sdk"
version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#e99e56e712ac4f3830390619e52ccd11a2b41f9e"
source = "git+https://github.com/rust-nostr/nostr#263833f295588bf7d9b35a8f9e93bf05ae8a5e76"
dependencies = [
"async-utility",
"atomic-destructor",
@@ -3335,7 +3299,7 @@ dependencies = [
[[package]]
name = "nostr-signer"
version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#e99e56e712ac4f3830390619e52ccd11a2b41f9e"
source = "git+https://github.com/rust-nostr/nostr#263833f295588bf7d9b35a8f9e93bf05ae8a5e76"
dependencies = [
"async-utility",
"nostr",
@@ -3348,7 +3312,7 @@ dependencies = [
[[package]]
name = "nostr-zapper"
version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#e99e56e712ac4f3830390619e52ccd11a2b41f9e"
source = "git+https://github.com/rust-nostr/nostr#263833f295588bf7d9b35a8f9e93bf05ae8a5e76"
dependencies = [
"async-trait",
"nostr",
@@ -3475,13 +3439,13 @@ dependencies = [
"proc-macro-crate 2.0.2",
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
name = "nwc"
version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#e99e56e712ac4f3830390619e52ccd11a2b41f9e"
source = "git+https://github.com/rust-nostr/nostr#263833f295588bf7d9b35a8f9e93bf05ae8a5e76"
dependencies = [
"async-utility",
"nostr",
@@ -3684,7 +3648,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -3965,7 +3929,7 @@ dependencies = [
"phf_shared 0.11.2",
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -4039,15 +4003,15 @@ dependencies = [
[[package]]
name = "png"
version = "0.17.13"
version = "0.17.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1"
checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0"
dependencies = [
"bitflags 1.3.2",
"crc32fast",
"fdeflate",
"flate2",
"miniz_oxide 0.7.4",
"miniz_oxide 0.8.0",
]
[[package]]
@@ -4376,9 +4340,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.5.5"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62871f2d65009c0256aed1b9cfeeb8ac272833c404e13d53d400cd0dad7a2ac0"
checksum = "355ae415ccd3a04315d3f8246e86d67689ea74d88d915576e1589a351062a13b"
dependencies = [
"bitflags 2.6.0",
]
@@ -4402,17 +4366,8 @@ checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata 0.4.7",
"regex-syntax 0.8.4",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
dependencies = [
"regex-syntax 0.6.29",
"regex-automata",
"regex-syntax",
]
[[package]]
@@ -4423,15 +4378,9 @@ checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax 0.8.4",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.8.4"
@@ -4600,9 +4549,9 @@ dependencies = [
[[package]]
name = "rustls-pki-types"
version = "1.8.0"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55"
[[package]]
name = "rustls-webpki"
@@ -4666,6 +4615,7 @@ dependencies = [
"serde",
"serde_json",
"url",
"uuid",
]
[[package]]
@@ -4677,15 +4627,9 @@ dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
name = "scoped-tls"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
name = "scopeguard"
version = "1.2.0"
@@ -4824,7 +4768,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -4835,7 +4779,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -4859,14 +4803,14 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
name = "serde_spanned"
version = "0.6.7"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d"
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
dependencies = [
"serde",
]
@@ -4910,7 +4854,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -5106,7 +5050,7 @@ dependencies = [
"Inflector",
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -5145,15 +5089,6 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "state"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8"
dependencies = [
"loom",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
@@ -5211,7 +5146,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -5244,9 +5179,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.77"
version = "2.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
dependencies = [
"proc-macro2",
"quote",
@@ -5361,7 +5296,7 @@ checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -5383,9 +5318,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
[[package]]
name = "tauri"
version = "2.0.0-rc.15"
version = "2.0.0-rc.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb3c3b1c7ac5b72d59da307b84af900a0098c74c9d7369f65018cd8ec0eb50fb"
checksum = "246bd333561c5601241b7a09f19957d5f659667f3c1191c869a066fb309e1841"
dependencies = [
"anyhow",
"bytes",
@@ -5416,7 +5351,6 @@ dependencies = [
"serde_repr",
"serialize-to-javascript",
"specta",
"state",
"swift-rs",
"tauri-build",
"tauri-macros",
@@ -5436,9 +5370,9 @@ dependencies = [
[[package]]
name = "tauri-build"
version = "2.0.0-rc.12"
version = "2.0.0-rc.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ff5713e81e02e0b99f5219b275abbd7d2c0cc0f30180e25b1b650e08feeac63"
checksum = "e5bc30f14b3c1548d75dfdf3e40bffe20a53bc4e3381e9bacc21dc765d701d0a"
dependencies = [
"anyhow",
"cargo_toml",
@@ -5458,9 +5392,9 @@ dependencies = [
[[package]]
name = "tauri-codegen"
version = "2.0.0-rc.12"
version = "2.0.0-rc.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5370f2591dcc93d4ff08d9dd168f5097f79b34e859883586a409c627544190e3"
checksum = "b1cfb6089cfc626b81bb8aa4692ede527732011dfd22486d8ac5bf299189841f"
dependencies = [
"base64 0.22.1",
"brotli",
@@ -5474,7 +5408,7 @@ dependencies = [
"serde",
"serde_json",
"sha2",
"syn 2.0.77",
"syn 2.0.79",
"tauri-utils",
"thiserror",
"time",
@@ -5485,14 +5419,14 @@ dependencies = [
[[package]]
name = "tauri-macros"
version = "2.0.0-rc.11"
version = "2.0.0-rc.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19442dc8ee002ab1926586f6aecb90114f3a1226766008b0c9ac2d9fec9eeb7e"
checksum = "1f04ed6fadd294ef8061137463fe31abccbb5fa61ff9946aab2896acd140cff1"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
"tauri-codegen",
"tauri-utils",
]
@@ -5515,9 +5449,9 @@ dependencies = [
[[package]]
name = "tauri-plugin"
version = "2.0.0-rc.12"
version = "2.0.0-rc.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e3368e91a98aa55ea4e3e8ccff516bc1ed2f85872c335ec35e9b345469032e0"
checksum = "6de7ffe64afa61c4cc13d450d64643b8db6cbb177a802beb88bf595594505ddf"
dependencies = [
"anyhow",
"glob",
@@ -5786,9 +5720,9 @@ dependencies = [
[[package]]
name = "tauri-runtime"
version = "2.0.0-rc.12"
version = "2.0.0-rc.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f38d8aaa1e81d20e8e208e3e317f81b59fb75c530fbae8a90e72d02001d687"
checksum = "8d9465366fd7f9e9c77385fa8b7cb583b060544e8800bd0309deb100008c312d"
dependencies = [
"dpi",
"gtk",
@@ -5805,9 +5739,9 @@ dependencies = [
[[package]]
name = "tauri-runtime-wry"
version = "2.0.0-rc.13"
version = "2.0.0-rc.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1ef5171e14c8fe3b5a63e75004c20d057747bc3e7fdc5f8ded625f0b29f5c7"
checksum = "a03a49d6bcc0e65d64ea4420e2097270a25a9e1ff0fb2ece75e54fbbd54e45f7"
dependencies = [
"gtk",
"http",
@@ -5854,14 +5788,14 @@ dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
name = "tauri-utils"
version = "2.0.0-rc.12"
version = "2.0.0-rc.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31fe4c9148e1b35225e1c00753f24b517ce00041d02eb4b4d6fd10613a47736c"
checksum = "a271545e4c25b36b922d98cf7e0c1755f64e92355705f656893e352aef0331e3"
dependencies = [
"brotli",
"cargo_metadata",
@@ -5889,6 +5823,7 @@ dependencies = [
"toml 0.8.2",
"url",
"urlpattern",
"uuid",
"walkdir",
]
@@ -5960,7 +5895,7 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -6057,7 +5992,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -6217,7 +6152,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -6247,23 +6182,19 @@ version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
"matchers",
"nu-ansi-term",
"once_cell",
"regex",
"sharded-slab",
"smallvec",
"thread_local",
"tracing",
"tracing-core",
"tracing-log",
]
[[package]]
name = "tray-icon"
version = "0.17.0"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "044d7738b3d50f288ddef035b793228740ad4d927f5466b0af55dc15e7e03cfe"
checksum = "533fc2d4105e0e3d96ce1c71f2d308c9fbbe2ef9c587cab63dd627ab5bde218f"
dependencies = [
"core-graphics 0.24.0",
"crossbeam-channel",
@@ -6450,6 +6381,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
dependencies = [
"getrandom 0.2.15",
"serde",
]
[[package]]
@@ -6549,7 +6481,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
"wasm-bindgen-shared",
]
@@ -6583,7 +6515,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -6596,9 +6528,9 @@ checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
[[package]]
name = "wasm-streams"
version = "0.4.0"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129"
checksum = "4e072d4e72f700fb3443d8fe94a39315df013eef1104903cdb0a2abd322bbecd"
dependencies = [
"futures-util",
"js-sys",
@@ -6692,7 +6624,7 @@ checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -6734,7 +6666,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys 0.48.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -6757,15 +6689,6 @@ dependencies = [
"windows-version",
]
[[package]]
name = "windows"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows"
version = "0.51.1"
@@ -6847,7 +6770,7 @@ checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -6858,7 +6781,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -6869,7 +6792,7 @@ checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -6880,7 +6803,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]
@@ -7166,9 +7089,9 @@ dependencies = [
[[package]]
name = "wry"
version = "0.43.1"
version = "0.44.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4d715cf5fe88e9647f3d17b207b6d060d4a88e7171d4ccb2d2c657dd1d44728"
checksum = "440600584cfbd8b0d28eace95c1f2c253db05dae43780b79380aa1e868f04c73"
dependencies = [
"base64 0.22.1",
"block",
@@ -7346,7 +7269,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
"syn 2.0.79",
]
[[package]]

File diff suppressed because one or more lines are too long

View File

@@ -2039,6 +2039,11 @@
"type": "string",
"const": "core:app:allow-name"
},
{
"description": "Enables the set_app_theme command without any pre-configured scope.",
"type": "string",
"const": "core:app:allow-set-app-theme"
},
{
"description": "Enables the tauri_version command without any pre-configured scope.",
"type": "string",
@@ -2069,6 +2074,11 @@
"type": "string",
"const": "core:app:deny-name"
},
{
"description": "Denies the set_app_theme command without any pre-configured scope.",
"type": "string",
"const": "core:app:deny-set-app-theme"
},
{
"description": "Denies the tauri_version command without any pre-configured scope.",
"type": "string",
@@ -2624,6 +2634,11 @@
"type": "string",
"const": "core:webview:default"
},
{
"description": "Enables the clear_all_browsing_data command without any pre-configured scope.",
"type": "string",
"const": "core:webview:allow-clear-all-browsing-data"
},
{
"description": "Enables the create_webview command without any pre-configured scope.",
"type": "string",
@@ -2679,16 +2694,31 @@
"type": "string",
"const": "core:webview:allow-webview-close"
},
{
"description": "Enables the webview_hide command without any pre-configured scope.",
"type": "string",
"const": "core:webview:allow-webview-hide"
},
{
"description": "Enables the webview_position command without any pre-configured scope.",
"type": "string",
"const": "core:webview:allow-webview-position"
},
{
"description": "Enables the webview_show command without any pre-configured scope.",
"type": "string",
"const": "core:webview:allow-webview-show"
},
{
"description": "Enables the webview_size command without any pre-configured scope.",
"type": "string",
"const": "core:webview:allow-webview-size"
},
{
"description": "Denies the clear_all_browsing_data command without any pre-configured scope.",
"type": "string",
"const": "core:webview:deny-clear-all-browsing-data"
},
{
"description": "Denies the create_webview command without any pre-configured scope.",
"type": "string",
@@ -2744,11 +2774,21 @@
"type": "string",
"const": "core:webview:deny-webview-close"
},
{
"description": "Denies the webview_hide command without any pre-configured scope.",
"type": "string",
"const": "core:webview:deny-webview-hide"
},
{
"description": "Denies the webview_position command without any pre-configured scope.",
"type": "string",
"const": "core:webview:deny-webview-position"
},
{
"description": "Denies the webview_show command without any pre-configured scope.",
"type": "string",
"const": "core:webview:deny-webview-show"
},
{
"description": "Denies the webview_size command without any pre-configured scope.",
"type": "string",
@@ -2829,6 +2869,11 @@
"type": "string",
"const": "core:window:allow-is-decorated"
},
{
"description": "Enables the is_enabled command without any pre-configured scope.",
"type": "string",
"const": "core:window:allow-is-enabled"
},
{
"description": "Enables the is_focused command without any pre-configured scope.",
"type": "string",
@@ -2959,6 +3004,11 @@
"type": "string",
"const": "core:window:allow-set-effects"
},
{
"description": "Enables the set_enabled command without any pre-configured scope.",
"type": "string",
"const": "core:window:allow-set-enabled"
},
{
"description": "Enables the set_focus command without any pre-configured scope.",
"type": "string",
@@ -3034,6 +3084,11 @@
"type": "string",
"const": "core:window:allow-set-skip-taskbar"
},
{
"description": "Enables the set_theme command without any pre-configured scope.",
"type": "string",
"const": "core:window:allow-set-theme"
},
{
"description": "Enables the set_title command without any pre-configured scope.",
"type": "string",
@@ -3159,6 +3214,11 @@
"type": "string",
"const": "core:window:deny-is-decorated"
},
{
"description": "Denies the is_enabled command without any pre-configured scope.",
"type": "string",
"const": "core:window:deny-is-enabled"
},
{
"description": "Denies the is_focused command without any pre-configured scope.",
"type": "string",
@@ -3289,6 +3349,11 @@
"type": "string",
"const": "core:window:deny-set-effects"
},
{
"description": "Denies the set_enabled command without any pre-configured scope.",
"type": "string",
"const": "core:window:deny-set-enabled"
},
{
"description": "Denies the set_focus command without any pre-configured scope.",
"type": "string",
@@ -3364,6 +3429,11 @@
"type": "string",
"const": "core:window:deny-set-skip-taskbar"
},
{
"description": "Denies the set_theme command without any pre-configured scope.",
"type": "string",
"const": "core:window:deny-set-theme"
},
{
"description": "Denies the set_title command without any pre-configured scope.",
"type": "string",

View File

@@ -2039,6 +2039,11 @@
"type": "string",
"const": "core:app:allow-name"
},
{
"description": "Enables the set_app_theme command without any pre-configured scope.",
"type": "string",
"const": "core:app:allow-set-app-theme"
},
{
"description": "Enables the tauri_version command without any pre-configured scope.",
"type": "string",
@@ -2069,6 +2074,11 @@
"type": "string",
"const": "core:app:deny-name"
},
{
"description": "Denies the set_app_theme command without any pre-configured scope.",
"type": "string",
"const": "core:app:deny-set-app-theme"
},
{
"description": "Denies the tauri_version command without any pre-configured scope.",
"type": "string",
@@ -2624,6 +2634,11 @@
"type": "string",
"const": "core:webview:default"
},
{
"description": "Enables the clear_all_browsing_data command without any pre-configured scope.",
"type": "string",
"const": "core:webview:allow-clear-all-browsing-data"
},
{
"description": "Enables the create_webview command without any pre-configured scope.",
"type": "string",
@@ -2679,16 +2694,31 @@
"type": "string",
"const": "core:webview:allow-webview-close"
},
{
"description": "Enables the webview_hide command without any pre-configured scope.",
"type": "string",
"const": "core:webview:allow-webview-hide"
},
{
"description": "Enables the webview_position command without any pre-configured scope.",
"type": "string",
"const": "core:webview:allow-webview-position"
},
{
"description": "Enables the webview_show command without any pre-configured scope.",
"type": "string",
"const": "core:webview:allow-webview-show"
},
{
"description": "Enables the webview_size command without any pre-configured scope.",
"type": "string",
"const": "core:webview:allow-webview-size"
},
{
"description": "Denies the clear_all_browsing_data command without any pre-configured scope.",
"type": "string",
"const": "core:webview:deny-clear-all-browsing-data"
},
{
"description": "Denies the create_webview command without any pre-configured scope.",
"type": "string",
@@ -2744,11 +2774,21 @@
"type": "string",
"const": "core:webview:deny-webview-close"
},
{
"description": "Denies the webview_hide command without any pre-configured scope.",
"type": "string",
"const": "core:webview:deny-webview-hide"
},
{
"description": "Denies the webview_position command without any pre-configured scope.",
"type": "string",
"const": "core:webview:deny-webview-position"
},
{
"description": "Denies the webview_show command without any pre-configured scope.",
"type": "string",
"const": "core:webview:deny-webview-show"
},
{
"description": "Denies the webview_size command without any pre-configured scope.",
"type": "string",
@@ -2829,6 +2869,11 @@
"type": "string",
"const": "core:window:allow-is-decorated"
},
{
"description": "Enables the is_enabled command without any pre-configured scope.",
"type": "string",
"const": "core:window:allow-is-enabled"
},
{
"description": "Enables the is_focused command without any pre-configured scope.",
"type": "string",
@@ -2959,6 +3004,11 @@
"type": "string",
"const": "core:window:allow-set-effects"
},
{
"description": "Enables the set_enabled command without any pre-configured scope.",
"type": "string",
"const": "core:window:allow-set-enabled"
},
{
"description": "Enables the set_focus command without any pre-configured scope.",
"type": "string",
@@ -3034,6 +3084,11 @@
"type": "string",
"const": "core:window:allow-set-skip-taskbar"
},
{
"description": "Enables the set_theme command without any pre-configured scope.",
"type": "string",
"const": "core:window:allow-set-theme"
},
{
"description": "Enables the set_title command without any pre-configured scope.",
"type": "string",
@@ -3159,6 +3214,11 @@
"type": "string",
"const": "core:window:deny-is-decorated"
},
{
"description": "Denies the is_enabled command without any pre-configured scope.",
"type": "string",
"const": "core:window:deny-is-enabled"
},
{
"description": "Denies the is_focused command without any pre-configured scope.",
"type": "string",
@@ -3289,6 +3349,11 @@
"type": "string",
"const": "core:window:deny-set-effects"
},
{
"description": "Denies the set_enabled command without any pre-configured scope.",
"type": "string",
"const": "core:window:deny-set-enabled"
},
{
"description": "Denies the set_focus command without any pre-configured scope.",
"type": "string",
@@ -3364,6 +3429,11 @@
"type": "string",
"const": "core:window:deny-set-skip-taskbar"
},
{
"description": "Denies the set_theme command without any pre-configured scope.",
"type": "string",
"const": "core:window:deny-set-theme"
},
{
"description": "Denies the set_title command without any pre-configured scope.",
"type": "string",

View File

@@ -3,7 +3,12 @@ use keyring_search::{Limit, List, Search};
use nostr_sdk::prelude::*;
use serde::{Deserialize, Serialize};
use specta::Type;
use std::{collections::HashSet, str::FromStr, time::Duration};
use std::{
collections::HashSet,
fs::{self, File},
str::FromStr,
time::Duration,
};
use tauri::{Emitter, Manager, State};
use crate::{
@@ -133,7 +138,7 @@ pub async fn connect_account(uri: String, state: State<'_, Nostr>) -> Result<Str
let remote_user = bunker_uri.signer_public_key().unwrap();
let remote_npub = remote_user.to_bech32().unwrap();
match Nip46Signer::new(bunker_uri, app_keys, Duration::from_secs(120), None).await {
match Nip46Signer::new(bunker_uri, app_keys, Duration::from_secs(120), None) {
Ok(signer) => {
let mut url = Url::parse(&uri).unwrap();
let query: Vec<(String, String)> = url
@@ -204,6 +209,17 @@ pub fn delete_account(id: String) -> Result<(), String> {
Ok(())
}
#[tauri::command]
#[specta::specta]
pub fn is_account_sync(id: String, handle: tauri::AppHandle) -> bool {
let config_dir = handle
.path()
.app_config_dir()
.expect("Error: app config directory not found.");
fs::metadata(config_dir.join(id)).is_ok()
}
#[tauri::command]
#[specta::specta]
pub async fn login(
@@ -244,7 +260,7 @@ pub async fn login(
let public_key = uri.signer_public_key().unwrap().to_bech32().unwrap();
let app_keys = Keys::from_str(&account.password).map_err(|e| e.to_string())?;
match Nip46Signer::new(uri, app_keys, Duration::from_secs(120), None).await {
match Nip46Signer::new(uri, app_keys, Duration::from_secs(120), None) {
Ok(signer) => {
// Update signer
client.set_signer(Some(signer.into())).await;
@@ -259,6 +275,11 @@ pub async fn login(
init_nip65(client, &public_key).await;
tauri::async_runtime::spawn(async move {
let config_dir = handle
.path()
.app_config_dir()
.expect("Error: app config directory not found.");
let state = handle.state::<Nostr>();
let client = &state.client;
@@ -298,64 +319,85 @@ pub async fn login(
state.settings.lock().await.clone_from(&settings);
};
let contact_list = client
.get_contact_list(Some(Duration::from_secs(5)))
.await
.unwrap();
// Get user's contact list
if let Ok(contacts) = client.get_contact_list(Some(Duration::from_secs(5))).await {
state.contact_list.lock().await.clone_from(&contacts);
if !contact_list.is_empty() {
let authors: Vec<PublicKey> = contact_list.iter().map(|f| f.public_key).collect();
if !contacts.is_empty() {
let pubkeys: Vec<PublicKey> = contacts.iter().map(|f| f.public_key).collect();
let metadata = Filter::new()
.authors(authors.clone())
.kind(Kind::Metadata)
.limit(authors.len());
let newsfeed = Filter::new()
.authors(pubkeys.clone())
.kinds(vec![Kind::TextNote, Kind::Repost])
.limit(NEWSFEED_NEG_LIMIT);
if let Ok(report) = client
.reconcile(metadata, NegentropyOptions::default())
.await
{
println!("received [metadata]: {}", report.received.len())
}
if client
.reconcile(newsfeed, NegentropyOptions::default())
.await
.is_ok()
{
handle.emit("synchronized", ()).unwrap();
}
let newsfeed = Filter::new()
.authors(authors.clone())
.kinds(vec![Kind::TextNote, Kind::Repost])
.limit(NEWSFEED_NEG_LIMIT);
if client
.reconcile(newsfeed, NegentropyOptions::default())
.await
.is_ok()
{
// Save state
let _ = File::create(config_dir.join(public_key.to_bech32().unwrap()));
// Update frontend
handle.emit("synchronized", ()).unwrap();
}
let contacts = Filter::new()
.authors(authors.clone())
.kind(Kind::ContactList)
.limit(authors.len() * 1000);
if let Ok(report) = client
.reconcile(contacts, NegentropyOptions::default())
.await
{
println!("received [contact list]: {}", report.received.len())
}
for author in authors.into_iter() {
let filter = Filter::new()
.authors(pubkeys.clone())
.author(author)
.kind(Kind::ContactList)
.limit(4000);
.limit(1);
if client
.reconcile(filter, NegentropyOptions::default())
.await
.is_ok()
{
for pubkey in pubkeys.into_iter() {
let mut list: Vec<PublicKey> = Vec::new();
let f = Filter::new()
.author(pubkey)
.kind(Kind::ContactList)
.limit(1);
let mut circles = state.circles.lock().await;
let mut list: Vec<PublicKey> = Vec::new();
if let Ok(events) = client.database().query(vec![f]).await {
if let Some(event) = events.into_iter().next() {
for tag in event.tags.into_iter() {
if let Some(TagStandard::PublicKey {
public_key,
uppercase: false,
..
}) = tag.to_standardized()
{
list.push(public_key)
}
}
if !list.is_empty() {
state.circles.lock().await.insert(pubkey, list);
};
if let Ok(events) = client.database().query(vec![filter]).await {
if let Some(event) = events.into_iter().next() {
for tag in event.tags.into_iter() {
if let Some(TagStandard::PublicKey {
public_key,
uppercase: false,
..
}) = tag.to_standardized()
{
list.push(public_key)
}
}
if !list.is_empty() {
circles.insert(author, list);
};
}
}
};
}
} else {
handle.emit("synchronized", ()).unwrap();
};
});

View File

@@ -28,13 +28,7 @@ pub async fn get_event(id: String, state: State<'_, Nostr>) -> Result<RichEvent,
let event_id = EventId::parse(&id).map_err(|err| err.to_string())?;
let filter = Filter::new().id(event_id);
match client
.get_events_of(
vec![filter],
EventSource::both(Some(Duration::from_secs(5))),
)
.await
{
match client.database().query(vec![filter.clone()]).await {
Ok(events) => {
if let Some(event) = events.first() {
let raw = event.as_json();
@@ -46,7 +40,29 @@ pub async fn get_event(id: String, state: State<'_, Nostr>) -> Result<RichEvent,
Ok(RichEvent { raw, parsed })
} else {
Err("Cannot found this event with current relay list".into())
match client
.get_events_of(
vec![filter],
EventSource::relays(Some(Duration::from_secs(5))),
)
.await
{
Ok(events) => {
if let Some(event) = events.first() {
let raw = event.as_json();
let parsed = if event.kind == Kind::TextNote {
Some(parse_event(&event.content).await)
} else {
None
};
Ok(RichEvent { raw, parsed })
} else {
Err("Cannot found this event with current relay list".into())
}
}
Err(err) => Err(err.to_string()),
}
}
}
Err(err) => Err(err.to_string()),
@@ -191,15 +207,12 @@ pub async fn get_events_by(
let author = PublicKey::parse(&public_key).map_err(|err| err.to_string())?;
let filter = Filter::new()
.kinds(vec![Kind::TextNote])
.kinds(vec![Kind::TextNote, Kind::Repost])
.author(author)
.limit(limit as usize);
match client
.get_events_of(
vec![filter],
EventSource::both(Some(Duration::from_secs(5))),
)
.get_events_of(vec![filter], EventSource::Database)
.await
{
Ok(events) => {
@@ -224,17 +237,11 @@ pub async fn get_events_by(
#[tauri::command]
#[specta::specta]
pub async fn get_events_from_contacts(
pub async fn get_local_events(
until: Option<&str>,
state: State<'_, Nostr>,
) -> Result<Vec<RichEvent>, String> {
let client = &state.client;
let contact_list = state.contact_list.lock().await;
let authors: Vec<PublicKey> = contact_list.iter().map(|f| f.public_key).collect();
if authors.is_empty() {
return Err("Contact List is empty.".into());
}
let as_of = match until {
Some(until) => Timestamp::from_str(until).map_err(|err| err.to_string())?,
@@ -244,8 +251,7 @@ pub async fn get_events_from_contacts(
let filter = Filter::new()
.kinds(vec![Kind::TextNote, Kind::Repost])
.limit(FETCH_LIMIT)
.until(as_of)
.authors(authors);
.until(as_of);
match client.database().query(vec![filter]).await {
Ok(events) => {
@@ -295,7 +301,7 @@ pub async fn get_group_events(
let filter = Filter::new()
.kinds(vec![Kind::TextNote, Kind::Repost])
.limit(FETCH_LIMIT)
.limit(20)
.until(as_of)
.authors(authors);
@@ -341,7 +347,7 @@ pub async fn get_global_events(
let filter = Filter::new()
.kinds(vec![Kind::TextNote, Kind::Repost])
.limit(FETCH_LIMIT)
.limit(20)
.until(as_of);
match client
@@ -385,7 +391,7 @@ pub async fn get_hashtag_events(
};
let filter = Filter::new()
.kinds(vec![Kind::TextNote, Kind::Repost])
.limit(FETCH_LIMIT)
.limit(20)
.until(as_of)
.hashtags(hashtags);

View File

@@ -46,10 +46,7 @@ pub async fn get_profile(id: Option<String>, state: State<'_, Nostr>) -> Result<
.kind(Kind::Metadata)
.limit(1);
match client
.get_events_of(vec![filter], EventSource::Database)
.await
{
match client.database().query(vec![filter.clone()]).await {
Ok(events) => {
if let Some(event) = events.first() {
if let Ok(metadata) = Metadata::from_json(&event.content) {
@@ -58,7 +55,26 @@ pub async fn get_profile(id: Option<String>, state: State<'_, Nostr>) -> Result<
Err("Parse metadata failed".into())
}
} else {
Ok(Metadata::new().as_json())
match client
.get_events_of(
vec![filter],
EventSource::relays(Some(Duration::from_secs(5))),
)
.await
{
Ok(events) => {
if let Some(event) = events.first() {
if let Ok(metadata) = Metadata::from_json(&event.content) {
Ok(metadata.as_json())
} else {
Err("Parse metadata failed".into())
}
} else {
Ok(Metadata::new().as_json())
}
}
Err(e) => Err(e.to_string()),
}
}
}
Err(e) => Err(e.to_string()),
@@ -80,9 +96,6 @@ pub async fn set_contact_list(
})
.collect();
// Update local state
state.contact_list.lock().await.clone_from(&contact_list);
match client.set_contact_list(contact_list).await {
Ok(_) => Ok(true),
Err(err) => Err(err.to_string()),
@@ -94,18 +107,13 @@ pub async fn set_contact_list(
pub async fn get_contact_list(state: State<'_, Nostr>) -> Result<Vec<String>, String> {
let client = &state.client;
match client.get_contact_list(Some(Duration::from_secs(10))).await {
match client.get_contact_list(Some(Duration::from_secs(5))).await {
Ok(contact_list) => {
if !contact_list.is_empty() {
let list = contact_list
.into_iter()
.map(|f| f.public_key.to_hex())
.collect();
Ok(list)
} else {
Err("Empty.".into())
}
let list = contact_list
.into_iter()
.map(|f| f.public_key.to_hex())
.collect();
Ok(list)
}
Err(err) => Err(err.to_string()),
}
@@ -144,16 +152,14 @@ pub async fn set_profile(profile: Profile, state: State<'_, Nostr>) -> Result<St
}
}
#[tauri::command]
#[specta::specta]
pub async fn is_contact_list_empty(state: State<'_, Nostr>) -> Result<bool, ()> {
Ok(state.contact_list.lock().await.is_empty())
}
#[tauri::command]
#[specta::specta]
pub async fn check_contact(hex: String, state: State<'_, Nostr>) -> Result<bool, String> {
let contact_list = state.contact_list.lock().await;
let client = &state.client;
let contact_list = client
.get_contact_list(Some(Duration::from_secs(5)))
.await
.map_err(|e| e.to_string())?;
match PublicKey::parse(&hex) {
Ok(public_key) => match contact_list.iter().position(|x| x.public_key == public_key) {
@@ -190,9 +196,6 @@ pub async fn toggle_contact(
}
}
// Update local state
state.contact_list.lock().await.clone_from(&contact_list);
// Publish
match client.set_contact_list(contact_list).await {
Ok(event_id) => Ok(event_id.to_string()),

View File

@@ -13,7 +13,6 @@ use crate::Settings;
pub struct Meta {
pub content: String,
pub images: Vec<String>,
pub videos: Vec<String>,
pub events: Vec<String>,
pub mentions: Vec<String>,
pub hashtags: Vec<String>,
@@ -44,7 +43,6 @@ const NOSTR_MENTIONS: [&str; 10] = [
"Nostr:naddr1",
];
const IMAGES: [&str; 7] = ["jpg", "jpeg", "gif", "png", "webp", "avif", "tiff"];
const VIDEOS: [&str; 5] = ["mp4", "mov", "avi", "webm", "mkv"];
pub fn get_latest_event(events: &[Event]) -> Option<&Event> {
events.iter().next()
@@ -115,7 +113,6 @@ pub async fn parse_event(content: &str) -> Meta {
.collect::<Vec<_>>();
let mut images = Vec::new();
let mut videos = Vec::new();
let mut text = content.to_string();
if !urls.is_empty() {
@@ -135,12 +132,6 @@ pub async fn parse_event(content: &str) -> Meta {
// Process the next item.
continue;
}
if VIDEOS.contains(&ext) {
text = text.replace(url_str, "");
videos.push(url_str.to_string());
// Process the next item.
continue;
}
}
// Check the content type of URL via HEAD request
@@ -167,7 +158,6 @@ pub async fn parse_event(content: &str) -> Meta {
mentions,
hashtags,
images,
videos,
}
}
@@ -262,7 +252,7 @@ pub async fn init_nip65(client: &Client, public_key: &str) {
if let Ok(events) = client
.get_events_of(
vec![filter],
EventSource::both(Some(Duration::from_secs(5))),
EventSource::relays(Some(Duration::from_secs(5))),
)
.await
{
@@ -284,8 +274,6 @@ pub async fn init_nip65(client: &Client, public_key: &str) {
}
}
}
} else {
eprintln!("Failed to get events for RelayList.");
}
}
@@ -344,7 +332,6 @@ mod tests {
assert_eq!(meta.content, "Check this image: #cool @npub1");
assert_eq!(meta.images, vec!["https://example.com/image.jpg"]);
assert_eq!(meta.videos, Vec::<String>::new());
assert_eq!(meta.hashtags, vec!["#cool"]);
assert_eq!(meta.mentions, vec!["@npub1"]);
}
@@ -356,7 +343,6 @@ mod tests {
assert_eq!(meta.content, "Check this video: #cool @npub1");
assert_eq!(meta.images, Vec::<String>::new());
assert_eq!(meta.videos, vec!["https://example.com/video.mp4"]);
assert_eq!(meta.hashtags, vec!["#cool"]);
assert_eq!(meta.mentions, vec!["@npub1"]);
}

View File

@@ -30,7 +30,6 @@ pub mod common;
pub struct Nostr {
client: Client,
contact_list: Mutex<Vec<Contact>>,
settings: Mutex<Settings>,
circles: Mutex<HashMap<PublicKey, Vec<PublicKey>>>,
}
@@ -56,7 +55,7 @@ impl Default for Settings {
image_resize_service: Some("https://wsrv.nl".to_string()),
use_relay_hint: true,
content_warning: true,
trusted_only: true,
trusted_only: false,
display_avatar: true,
display_zap_button: true,
display_repost_button: true,
@@ -83,8 +82,8 @@ struct Subscription {
struct NewSettings(Settings);
pub const DEFAULT_DIFFICULTY: u8 = 21;
pub const FETCH_LIMIT: usize = 20;
pub const NEWSFEED_NEG_LIMIT: usize = 256;
pub const FETCH_LIMIT: usize = 100;
pub const NEWSFEED_NEG_LIMIT: usize = 512;
pub const NOTIFICATION_NEG_LIMIT: usize = 64;
pub const NOTIFICATION_SUB_ID: &str = "lume_notification";
@@ -107,12 +106,12 @@ fn main() {
get_private_key,
delete_account,
reset_password,
is_account_sync,
login,
get_profile,
set_profile,
get_contact_list,
set_contact_list,
is_contact_list_empty,
check_contact,
toggle_contact,
get_mention_list,
@@ -135,7 +134,7 @@ fn main() {
get_replies,
subscribe_to,
get_events_by,
get_events_from_contacts,
get_local_events,
get_group_events,
get_global_events,
get_hashtag_events,
@@ -222,9 +221,9 @@ fn main() {
.gossip(true)
.max_avg_latency(Duration::from_millis(500))
.automatic_authentication(false)
.connection_timeout(Some(Duration::from_secs(5)))
.send_timeout(Some(Duration::from_secs(5)))
.timeout(Duration::from_secs(5));
.connection_timeout(Some(Duration::from_secs(20)))
.send_timeout(Some(Duration::from_secs(10)))
.timeout(Duration::from_secs(20));
// Setup nostr client
let client = ClientBuilder::default()
@@ -277,7 +276,6 @@ fn main() {
// Create global state
app.manage(Nostr {
client,
contact_list: Mutex::new(vec![]),
settings: Mutex::new(Settings::default()),
circles: Mutex::new(HashMap::new()),
});
@@ -308,7 +306,11 @@ fn main() {
}
}
None => {
let contact_list = state.contact_list.lock().await;
let contact_list = client
.get_contact_list(Some(Duration::from_secs(5)))
.await
.unwrap();
if !contact_list.is_empty() {
let authors: Vec<PublicKey> =
contact_list.iter().map(|f| f.public_key).collect();
@@ -459,6 +461,39 @@ fn main() {
Ok(())
})
.on_window_event(|window, event| {
if let tauri::WindowEvent::Focused(focused) = event {
if !focused {
let handle = window.app_handle().to_owned();
tauri::async_runtime::spawn(async move {
let state = handle.state::<Nostr>();
let client = &state.client;
if client.signer().await.is_ok() {
if let Ok(contact_list) =
client.get_contact_list(Some(Duration::from_secs(5))).await
{
let authors: Vec<PublicKey> =
contact_list.iter().map(|f| f.public_key).collect();
let newsfeed = Filter::new()
.authors(authors)
.kinds(vec![Kind::TextNote, Kind::Repost])
.limit(NEWSFEED_NEG_LIMIT);
if client
.reconcile(newsfeed, NegentropyOptions::default())
.await
.is_ok()
{
handle.emit("synchronized", ()).unwrap();
}
}
}
});
}
}
})
.plugin(prevent_default())
.plugin(tauri_plugin_decorum::init())
.plugin(tauri_plugin_store::Builder::default().build())

View File

@@ -1,27 +1,24 @@
import {
type PersistedQuery,
experimental_createPersister,
} from "@tanstack/query-persist-client-core";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { RouterProvider, createRouter } from "@tanstack/react-router";
import { type } from "@tauri-apps/plugin-os";
import { StrictMode } from "react";
import ReactDOM from "react-dom/client";
import { newQueryStorage } from "./commons";
import { routeTree } from "./routes.gen"; // auto generated file
import type { LumeEvent } from "./system";
import "./app.css";
import { experimental_createPersister } from "@tanstack/query-persist-client-core";
import { Store } from "@tauri-apps/plugin-store";
import { newQueryStorage } from "./commons";
const platform = type();
const tauriStore = new Store(".lume.dat");
const store = new Store(".cache");
const queryClient = new QueryClient({
defaultOptions: {
queries: {
gcTime: 1000 * 30,
persister: experimental_createPersister<PersistedQuery>({
storage: newQueryStorage(tauriStore),
maxAge: 1000 * 60 * 60 * 24, // 24 hours,
persister: experimental_createPersister({
storage: newQueryStorage(store),
maxAge: 1000 * 60 * 60 * 12, // 12 hours
}),
},
},

View File

@@ -96,6 +96,9 @@ async resetPassword(key: string, password: string) : Promise<Result<null, string
else return { status: "error", error: e as any };
}
},
async isAccountSync(id: string) : Promise<boolean> {
return await TAURI_INVOKE("is_account_sync", { id });
},
async login(account: string, password: string) : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("login", { account, password }) };
@@ -136,14 +139,6 @@ async setContactList(publicKeys: string[]) : Promise<Result<boolean, string>> {
else return { status: "error", error: e as any };
}
},
async isContactListEmpty() : Promise<Result<boolean, null>> {
try {
return { status: "ok", data: await TAURI_INVOKE("is_contact_list_empty") };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async checkContact(hex: string) : Promise<Result<boolean, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("check_contact", { hex }) };
@@ -320,9 +315,9 @@ async getEventsBy(publicKey: string, limit: number) : Promise<Result<RichEvent[]
else return { status: "error", error: e as any };
}
},
async getEventsFromContacts(until: string | null) : Promise<Result<RichEvent[], string>> {
async getLocalEvents(until: string | null) : Promise<Result<RichEvent[], string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_events_from_contacts", { until }) };
return { status: "ok", data: await TAURI_INVOKE("get_local_events", { until }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
@@ -475,7 +470,7 @@ subscription: "subscription"
export type Column = { label: string; url: string; x: number; y: number; width: number; height: number }
export type Mention = { pubkey: string; avatar: string; display_name: string; name: string }
export type Meta = { content: string; images: string[]; videos: string[]; events: string[]; mentions: string[]; hashtags: string[] }
export type Meta = { content: string; images: string[]; events: string[]; mentions: string[]; hashtags: string[] }
export type NewSettings = Settings
export type Profile = { name: string; display_name: string; about: string | null; picture: string; banner: string | null; nip05: string | null; lud16: string | null; website: string | null }
export type Relays = { connected: string[]; read: string[] | null; write: string[] | null; both: string[] | null }

View File

@@ -1,5 +1,5 @@
import { LumeWindow } from "@/system";
import { FrameCorners } from "@phosphor-icons/react";
import { ListPlus } from "@phosphor-icons/react";
import * as Tooltip from "@radix-ui/react-tooltip";
import { useNoteContext } from "../provider";
@@ -15,7 +15,7 @@ export function NoteOpenThread() {
onClick={() => LumeWindow.openEvent(event)}
className="group inline-flex h-7 w-14 bg-neutral-100 dark:bg-white/10 rounded-full items-center justify-center text-sm font-medium text-neutral-800 dark:text-neutral-200 hover:text-blue-500 hover:bg-neutral-200 dark:hover:bg-white/20"
>
<FrameCorners className="shrink-0 size-4" />
<ListPlus className="shrink-0 size-4" />
</button>
</Tooltip.Trigger>
<Tooltip.Portal>

View File

@@ -7,7 +7,6 @@ import { Hashtag } from "./mentions/hashtag";
import { MentionNote } from "./mentions/note";
import { MentionUser } from "./mentions/user";
import { Images } from "./preview/images";
import { Videos } from "./preview/videos";
import { useNoteContext } from "./provider";
export function NoteContent({
@@ -102,14 +101,9 @@ export function NoteContent({
{content}
</div>
{visible ? (
<>
{event.meta?.images.length ? (
<Images urls={event.meta.images} />
) : null}
{event.meta?.videos.length ? (
<Videos urls={event.meta.videos} />
) : null}
</>
event.meta?.images.length ? (
<Images urls={event.meta.images} />
) : null
) : null}
</div>
);

View File

@@ -6,7 +6,6 @@ import { Hashtag } from "./mentions/hashtag";
import { MentionNote } from "./mentions/note";
import { MentionUser } from "./mentions/user";
import { ImagePreview } from "./preview/image";
import { VideoPreview } from "./preview/video";
import { useNoteContext } from "./provider";
export function NoteContentLarge({
@@ -18,7 +17,7 @@ export function NoteContentLarge({
const content = useMemo(() => {
try {
// Get parsed meta
const { images, videos, hashtags, events, mentions } = event.meta;
const { images, hashtags, events, mentions } = event.meta;
// Define rich content
let richContent: ReactNode[] | string = event.content;
@@ -48,12 +47,6 @@ export function NoteContentLarge({
));
}
for (const video of videos) {
richContent = reactStringReplace(richContent, video, (match, i) => (
<VideoPreview key={match + i} url={match} />
));
}
richContent = reactStringReplace(
richContent,
/(https?:\/\/\S+)/gi,
@@ -75,8 +68,7 @@ export function NoteContentLarge({
));
return richContent;
} catch (e) {
console.log("[parser]: ", e);
} catch {
return event.content;
}
}, [event.content]);

View File

@@ -15,8 +15,7 @@ export function UserAvatar({ className }: { className?: string }) {
const picture = useMemo(() => {
if (service?.length && user.profile?.picture?.length) {
const url = `${service}?url=${user.profile?.picture}&w=100&h=100&default=1&n=-1`;
return url;
return `${service}?url=${user.profile?.picture}&w=100&h=100&n=-1&default=${user.profile?.picture}`;
} else {
return user.profile?.picture;
}

View File

@@ -59,10 +59,10 @@ export function UserFollowButton({ className }: { className?: string }) {
type="button"
disabled={isPending}
onClick={() => toggleFollow()}
className={cn("w-max", className)}
className={cn("w-max gap-1", className)}
>
{isError ? "Error" : null}
{isPending || isLoading ? <Spinner className="size-4" /> : null}
{isPending || isLoading ? <Spinner className="size-3" /> : null}
{isFollow ? "Unfollow" : "Follow"}
</button>
);

View File

@@ -13,6 +13,7 @@ import { createFileRoute } from '@tanstack/react-router'
// Import Routes
import { Route as rootRoute } from './routes/__root'
import { Route as LoadingImport } from './routes/loading'
import { Route as BootstrapRelaysImport } from './routes/bootstrap-relays'
import { Route as IndexImport } from './routes/index'
import { Route as EditorIndexImport } from './routes/editor/index'
@@ -95,6 +96,11 @@ const NewLazyRoute = NewLazyImport.update({
getParentRoute: () => rootRoute,
} as any).lazy(() => import('./routes/new.lazy').then((d) => d.Route))
const LoadingRoute = LoadingImport.update({
path: '/loading',
getParentRoute: () => rootRoute,
} as any)
const BootstrapRelaysRoute = BootstrapRelaysImport.update({
path: '/bootstrap-relays',
getParentRoute: () => rootRoute,
@@ -338,6 +344,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof BootstrapRelaysImport
parentRoute: typeof rootRoute
}
'/loading': {
id: '/loading'
path: '/loading'
fullPath: '/loading'
preLoaderRoute: typeof LoadingImport
parentRoute: typeof rootRoute
}
'/new': {
id: '/new'
path: '/new'
@@ -713,6 +726,7 @@ const ColumnsRouteWithChildren =
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/bootstrap-relays': typeof BootstrapRelaysRoute
'/loading': typeof LoadingRoute
'/new': typeof NewLazyRoute
'/reset': typeof ResetLazyRoute
'/$account': typeof AccountSettingsLazyRouteWithChildren
@@ -751,6 +765,7 @@ export interface FileRoutesByFullPath {
export interface FileRoutesByTo {
'/': typeof IndexRoute
'/bootstrap-relays': typeof BootstrapRelaysRoute
'/loading': typeof LoadingRoute
'/new': typeof NewLazyRoute
'/reset': typeof ResetLazyRoute
'/$account': typeof AccountSettingsLazyRouteWithChildren
@@ -790,6 +805,7 @@ export interface FileRoutesById {
__root__: typeof rootRoute
'/': typeof IndexRoute
'/bootstrap-relays': typeof BootstrapRelaysRoute
'/loading': typeof LoadingRoute
'/new': typeof NewLazyRoute
'/reset': typeof ResetLazyRoute
'/$account': typeof AccountRouteWithChildren
@@ -833,6 +849,7 @@ export interface FileRouteTypes {
fullPaths:
| '/'
| '/bootstrap-relays'
| '/loading'
| '/new'
| '/reset'
| '/$account'
@@ -870,6 +887,7 @@ export interface FileRouteTypes {
to:
| '/'
| '/bootstrap-relays'
| '/loading'
| '/new'
| '/reset'
| '/$account'
@@ -907,6 +925,7 @@ export interface FileRouteTypes {
| '__root__'
| '/'
| '/bootstrap-relays'
| '/loading'
| '/new'
| '/reset'
| '/$account'
@@ -949,6 +968,7 @@ export interface FileRouteTypes {
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
BootstrapRelaysRoute: typeof BootstrapRelaysRoute
LoadingRoute: typeof LoadingRoute
NewLazyRoute: typeof NewLazyRoute
ResetLazyRoute: typeof ResetLazyRoute
AccountRoute: typeof AccountRouteWithChildren
@@ -963,6 +983,7 @@ export interface RootRouteChildren {
const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
BootstrapRelaysRoute: BootstrapRelaysRoute,
LoadingRoute: LoadingRoute,
NewLazyRoute: NewLazyRoute,
ResetLazyRoute: ResetLazyRoute,
AccountRoute: AccountRouteWithChildren,
@@ -988,6 +1009,7 @@ export const routeTree = rootRoute
"children": [
"/",
"/bootstrap-relays",
"/loading",
"/new",
"/reset",
"/$account",
@@ -1005,6 +1027,9 @@ export const routeTree = rootRoute
"/bootstrap-relays": {
"filePath": "bootstrap-relays.tsx"
},
"/loading": {
"filePath": "loading.tsx"
},
"/new": {
"filePath": "new.lazy.tsx"
},

View File

@@ -224,7 +224,7 @@ function ReplyList() {
{isLoading ? (
<div className="flex items-center justify-center w-full mb-3 h-12 bg-black/5 dark:bg-white/5 rounded-xl">
<div className="flex items-center justify-center gap-2">
<Spinner className="size-5" />
<Spinner className="size-4" />
<span className="text-sm font-medium">Getting replies...</span>
</div>
</div>

View File

@@ -48,7 +48,7 @@ export function Screen() {
initialPageParam: 0,
queryFn: async ({ pageParam }: { pageParam: number }) => {
const until = pageParam > 0 ? pageParam.toString() : undefined;
const res = await commands.getEventsFromContacts(until);
const res = await commands.getLocalEvents(until);
if (res.status === "error") {
throw new Error(res.error);

View File

@@ -11,7 +11,7 @@ export const Route = createLazyFileRoute("/columns/_layout/trending")({
component: Screen,
});
export function Screen() {
function Screen() {
const { isLoading, isError, data } = useQuery({
queryKey: ["trending-notes"],
queryFn: async ({ signal }) => {

View File

@@ -64,11 +64,21 @@ function Screen() {
appSettings.setState(() => settings.data);
}
navigate({
to: "/$account/home",
params: { account: res.data },
replace: true,
});
const status = await commands.isAccountSync(res.data);
if (status) {
navigate({
to: "/$account/home",
params: { account: res.data },
replace: true,
});
} else {
navigate({
to: "/loading",
search: { account: res.data },
replace: true,
});
}
} else {
await message(res.error, { title: "Login", kind: "error" });
return;

47
src/routes/loading.tsx Normal file
View File

@@ -0,0 +1,47 @@
import { Spinner } from "@/components";
import { createFileRoute } from "@tanstack/react-router";
import { listen } from "@tauri-apps/api/event";
import { useEffect } from "react";
type RouteSearch = {
account: string;
};
export const Route = createFileRoute("/loading")({
validateSearch: (search: Record<string, string>): RouteSearch => {
return {
account: search.account,
};
},
component: Screen,
});
function Screen() {
const navigate = Route.useNavigate();
const search = Route.useSearch();
useEffect(() => {
const unlisten = listen("synchronized", () => {
navigate({
to: "/$account/home",
params: { account: search.account },
replace: true,
});
});
return () => {
unlisten.then((f) => f());
};
}, []);
return (
<div className="size-full flex items-center justify-center">
<div className="flex flex-col gap-2 items-center justify-center text-center">
<Spinner />
<p className="text-sm">
Fetching necessary data for the first time login...
</p>
</div>
</div>
);
}

View File

@@ -54,7 +54,7 @@ export function useEvent(id: string) {
refetchOnMount: false,
refetchOnReconnect: false,
staleTime: Number.POSITIVE_INFINITY,
retry: false,
retry: 2,
});
return { isLoading, isError, error, data };

View File

@@ -38,7 +38,7 @@ export function useProfile(pubkey: string, embed?: string) {
refetchOnWindowFocus: false,
refetchOnReconnect: false,
staleTime: Number.POSITIVE_INFINITY,
retry: false,
retry: 2,
});
return { isLoading, isError, profile };

View File

@@ -58,7 +58,7 @@ export const LumeWindow = {
eTags.find((el) => el[3] === "reply")?.[1] ?? eTags[1]?.[1];
const url = `/columns/events/${root ?? reply ?? event.id}`;
const label = `event-${root ?? reply ?? event.id}`;
const label = `event-${root?.substring(0, 6) ?? reply?.substring(0, 6) ?? event.id.substring(0, 6)}`;
LumeWindow.openColumn({ label, url, name: "Thread" });
},

View File

@@ -13,7 +13,6 @@ export enum Kind {
export interface Meta {
content: string;
images: string[];
videos: string[];
events: string[];
mentions: string[];
hashtags: string[];