1
0
Fork 0

Compare commits

...

3 Commits

Author SHA1 Message Date
Benedikt Peetz 1c43626fad
Build(Cargo): Update `Cargo.lock` and upgrade `Cargo.toml` 2023-07-09 10:09:53 +02:00
Benedikt Peetz a9f72e34e6
Build(cargo): Remove wildcard version specification in `Cargo.toml`
Wildcard version is comparable to selecting a version depending on
the result of a dice roll. What I mean with this is, that the version
will be selected based on what the specific user already has in their
cargo registry. This means that the same codebase will compile
wonderfully on one machine but will fail with weird errors like:
`the trait 'From<crossterm::event::Event>' is not implemented for 'Input'`
on an other one.

Additionally crates.io does not accept crates with a bare wildcard
version requirement for aforementioned reasons.

Lastly using direct versions requirement allows to use `cargo upgrade`
to automatically update these requirements to their highest possible
value, as determined by SemVer. This works especially well, when adding
new dependencies with `cargo add`, as this also adds a direct version
requirement.
2023-07-09 10:09:52 +02:00
Benedikt Peetz 35225a14db
Style(treewide): Format all files with rustfmt 2023-07-09 10:09:50 +02:00
8 changed files with 686 additions and 534 deletions

306
Cargo.lock generated
View File

@ -4,9 +4,9 @@ version = 3
[[package]] [[package]]
name = "addr2line" name = "addr2line"
version = "0.19.0" version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3"
dependencies = [ dependencies = [
"gimli", "gimli",
] ]
@ -138,20 +138,20 @@ version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [ dependencies = [
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"syn 2.0.22", "syn 2.0.24",
] ]
[[package]] [[package]]
name = "async-trait" name = "async-trait"
version = "0.1.68" version = "0.1.71"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf"
dependencies = [ dependencies = [
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"syn 2.0.22", "syn 2.0.24",
] ]
[[package]] [[package]]
@ -191,9 +191,9 @@ dependencies = [
[[package]] [[package]]
name = "backtrace" name = "backtrace"
version = "0.3.67" version = "0.3.68"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12"
dependencies = [ dependencies = [
"addr2line", "addr2line",
"cc", "cc",
@ -230,9 +230,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "blake3" name = "blake3"
version = "1.4.0" version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "729b71f35bd3fa1a4c86b85d32c8b9069ea7fe14f7a53cfabb65f62d4265b888" checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5"
dependencies = [ dependencies = [
"arrayref", "arrayref",
"arrayvec", "arrayvec",
@ -402,9 +402,9 @@ checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3"
[[package]] [[package]]
name = "constant_time_eq" name = "constant_time_eq"
version = "0.2.6" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6" checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2"
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
@ -424,9 +424,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.8" version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -538,7 +538,7 @@ checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
dependencies = [ dependencies = [
"fnv", "fnv",
"ident_case", "ident_case",
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"strsim", "strsim",
"syn 1.0.109", "syn 1.0.109",
@ -593,7 +593,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f91d4cfa921f1c05904dc3c57b4a32c38aed3340cce209f3a6fd1478babafc4" checksum = "1f91d4cfa921f1c05904dc3c57b4a32c38aed3340cce209f3a6fd1478babafc4"
dependencies = [ dependencies = [
"darling", "darling",
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"syn 1.0.109", "syn 1.0.109",
] ]
@ -640,9 +640,9 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
dependencies = [ dependencies = [
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"syn 2.0.22", "syn 2.0.24",
] ]
[[package]] [[package]]
@ -699,7 +699,7 @@ checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
dependencies = [ dependencies = [
"errno-dragonfly", "errno-dragonfly",
"libc", "libc",
"windows-sys 0.48.0", "windows-sys",
] ]
[[package]] [[package]]
@ -839,9 +839,9 @@ version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [ dependencies = [
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"syn 2.0.22", "syn 2.0.24",
] ]
[[package]] [[package]]
@ -987,18 +987,9 @@ checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.2.6" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
[[package]] [[package]]
name = "hkdf" name = "hkdf"
@ -1191,9 +1182,9 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [ dependencies = [
"hermit-abi 0.3.1", "hermit-abi",
"libc", "libc",
"windows-sys 0.48.0", "windows-sys",
] ]
[[package]] [[package]]
@ -1213,9 +1204,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.6" version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a"
[[package]] [[package]]
name = "js-sys" name = "js-sys"
@ -1495,9 +1486,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.6.2" version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
dependencies = [ dependencies = [
"adler", "adler",
] ]
@ -1511,7 +1502,7 @@ dependencies = [
"libc", "libc",
"log", "log",
"wasi 0.11.0+wasi-snapshot-preview1", "wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.48.0", "windows-sys",
] ]
[[package]] [[package]]
@ -1543,19 +1534,19 @@ dependencies = [
[[package]] [[package]]
name = "num_cpus" name = "num_cpus"
version = "1.15.0" version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [ dependencies = [
"hermit-abi 0.2.6", "hermit-abi",
"libc", "libc",
] ]
[[package]] [[package]]
name = "object" name = "object"
version = "0.30.4" version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -1593,9 +1584,9 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [ dependencies = [
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"syn 2.0.22", "syn 2.0.24",
] ]
[[package]] [[package]]
@ -1695,29 +1686,29 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
[[package]] [[package]]
name = "pin-project" name = "pin-project"
version = "1.1.0" version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842"
dependencies = [ dependencies = [
"pin-project-internal", "pin-project-internal",
] ]
[[package]] [[package]]
name = "pin-project-internal" name = "pin-project-internal"
version = "1.1.0" version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c"
dependencies = [ dependencies = [
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"syn 2.0.22", "syn 2.0.24",
] ]
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.9" version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57"
[[package]] [[package]]
name = "pin-utils" name = "pin-utils"
@ -1779,9 +1770,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.63" version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -1813,7 +1804,7 @@ checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"itertools", "itertools",
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"syn 1.0.109", "syn 1.0.109",
] ]
@ -1833,7 +1824,7 @@ version = "1.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
dependencies = [ dependencies = [
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
] ]
[[package]] [[package]]
@ -2042,9 +2033,21 @@ dependencies = [
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.8.4" version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@ -2053,9 +2056,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846"
[[package]] [[package]]
name = "reqwest" name = "reqwest"
@ -2185,7 +2188,7 @@ checksum = "0f82e91eb61cd86d9287303133ee55b54618eccb75a522cc22a42c15f5bda340"
dependencies = [ dependencies = [
"once_cell", "once_cell",
"proc-macro-crate", "proc-macro-crate",
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"ruma-identifiers-validation", "ruma-identifiers-validation",
"serde", "serde",
@ -2201,31 +2204,31 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.37.20" version = "0.37.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"errno", "errno",
"io-lifetimes", "io-lifetimes",
"libc", "libc",
"linux-raw-sys", "linux-raw-sys",
"windows-sys 0.48.0", "windows-sys",
] ]
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.13" version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9"
[[package]] [[package]]
name = "schannel" name = "schannel"
version = "0.1.21" version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88"
dependencies = [ dependencies = [
"windows-sys 0.42.0", "windows-sys",
] ]
[[package]] [[package]]
@ -2259,38 +2262,38 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.164" version = "1.0.169"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" checksum = "bd51c3db8f9500d531e6c12dd0fd4ad13d133e9117f5aebac3cdbb8b6d9824b0"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_bytes" name = "serde_bytes"
version = "0.11.9" version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" checksum = "5a16be4fe5320ade08736447e3198294a5ea9a6d44dde6f35f0a5e06859c427a"
dependencies = [ dependencies = [
"serde", "serde",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.164" version = "1.0.169"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" checksum = "27738cfea0d944ab72c3ed01f3d5f23ec4322af8a1431e40ce630e4c01ea74fd"
dependencies = [ dependencies = [
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"syn 2.0.22", "syn 2.0.24",
] ]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.99" version = "1.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@ -2396,9 +2399,9 @@ dependencies = [
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.10.0" version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
[[package]] [[package]]
name = "socket2" name = "socket2"
@ -2448,18 +2451,18 @@ version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [ dependencies = [
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"unicode-ident", "unicode-ident",
] ]
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.22" version = "2.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616" checksum = "36ccaf716a23c35ff908f91c971a86a9a71af5998c1d8f10e828d9f55f68ac00"
dependencies = [ dependencies = [
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"unicode-ident", "unicode-ident",
] ]
@ -2475,27 +2478,27 @@ dependencies = [
"fastrand", "fastrand",
"redox_syscall 0.3.5", "redox_syscall 0.3.5",
"rustix", "rustix",
"windows-sys 0.48.0", "windows-sys",
] ]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.40" version = "1.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.40" version = "1.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f"
dependencies = [ dependencies = [
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"syn 2.0.22", "syn 2.0.24",
] ]
[[package]] [[package]]
@ -2526,9 +2529,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.29.0" version = "1.29.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "374442f06ee49c3a28a8fc9f01a2596fed7559c6b99b31279c3261778e77d84f" checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da"
dependencies = [ dependencies = [
"autocfg 1.1.0", "autocfg 1.1.0",
"backtrace", "backtrace",
@ -2539,7 +2542,7 @@ dependencies = [
"pin-project-lite", "pin-project-lite",
"socket2", "socket2",
"tokio-macros", "tokio-macros",
"windows-sys 0.48.0", "windows-sys",
] ]
[[package]] [[package]]
@ -2548,9 +2551,9 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
dependencies = [ dependencies = [
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"syn 2.0.22", "syn 2.0.24",
] ]
[[package]] [[package]]
@ -2594,9 +2597,9 @@ checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.19.11" version = "0.19.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7" checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78"
dependencies = [ dependencies = [
"indexmap 2.0.0", "indexmap 2.0.0",
"toml_datetime", "toml_datetime",
@ -2627,9 +2630,9 @@ version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
dependencies = [ dependencies = [
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"syn 2.0.22", "syn 2.0.24",
] ]
[[package]] [[package]]
@ -2648,7 +2651,7 @@ dependencies = [
"anyhow", "anyhow",
"cli-log", "cli-log",
"crossterm", "crossterm",
"indexmap 1.9.3", "indexmap 2.0.0",
"matrix-sdk", "matrix-sdk",
"serde", "serde",
"tokio", "tokio",
@ -2700,9 +2703,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.9" version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73"
[[package]] [[package]]
name = "unicode-normalization" name = "unicode-normalization"
@ -2865,9 +2868,9 @@ dependencies = [
"bumpalo", "bumpalo",
"log", "log",
"once_cell", "once_cell",
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"syn 2.0.22", "syn 2.0.24",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -2899,9 +2902,9 @@ version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [ dependencies = [
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"syn 2.0.22", "syn 2.0.24",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -2974,21 +2977,6 @@ dependencies = [
"windows-targets", "windows-targets",
] ]
[[package]]
name = "windows-sys"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
"windows_aarch64_gnullvm 0.42.2",
"windows_aarch64_msvc 0.42.2",
"windows_i686_gnu 0.42.2",
"windows_i686_msvc 0.42.2",
"windows_x86_64_gnu 0.42.2",
"windows_x86_64_gnullvm 0.42.2",
"windows_x86_64_msvc 0.42.2",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.48.0" version = "0.48.0"
@ -3004,93 +2992,51 @@ version = "0.48.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm 0.48.0", "windows_aarch64_gnullvm",
"windows_aarch64_msvc 0.48.0", "windows_aarch64_msvc",
"windows_i686_gnu 0.48.0", "windows_i686_gnu",
"windows_i686_msvc 0.48.0", "windows_i686_msvc",
"windows_x86_64_gnu 0.48.0", "windows_x86_64_gnu",
"windows_x86_64_gnullvm 0.48.0", "windows_x86_64_gnullvm",
"windows_x86_64_msvc 0.48.0", "windows_x86_64_msvc",
] ]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.48.0" version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.48.0" version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.48.0" version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.48.0" version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.48.0" version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.48.0" version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.48.0" version = "0.48.0"
@ -3099,9 +3045,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.4.7" version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -3142,7 +3088,7 @@ version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [ dependencies = [
"proc-macro2 1.0.63", "proc-macro2 1.0.64",
"quote 1.0.29", "quote 1.0.29",
"syn 2.0.22", "syn 2.0.24",
] ]

View File

@ -8,12 +8,12 @@ license = "MIT"
[dependencies] [dependencies]
tui = "0.19" tui = "0.19"
tui-textarea = { version = "*" } tui-textarea = { version = "0.2", features = ["crossterm"] }
crossterm = "*" crossterm = "0.25"
matrix-sdk = "0.6" matrix-sdk = "0.6"
anyhow = "1.0" anyhow = "1.0"
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } tokio = { version = "1.29", features = ["macros", "rt-multi-thread"] }
tokio-util = "0.7" tokio-util = "0.7"
serde = "1.0" serde = "1.0"
cli-log = "2.0" cli-log = "2.0"
indexmap = "*" indexmap = "2.0.0"

View File

@ -1,13 +1,13 @@
use std::fs; use std::fs;
use matrix_sdk::{Client,
config::SyncSettings,
ruma::{user_id,
events::room::message::SyncRoomMessageEvent,
exports::serde_json},
Session};
use anyhow::{Error, Result}; use anyhow::{Error, Result};
use cli_log::{error, info, warn};
use matrix_sdk::{
config::SyncSettings,
ruma::{events::room::message::SyncRoomMessageEvent, exports::serde_json, user_id},
Client, Session,
};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use cli_log::{error, warn, info};
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Account { pub struct Account {
@ -47,7 +47,8 @@ impl AccountsManager {
return match config { return match config {
Some(s) => { Some(s) => {
info!("Loading serialized AccountsManager"); info!("Loading serialized AccountsManager");
let accounts_data:AccountsData = serde_json::from_str(&s).expect("failed to deserialize json"); let accounts_data: AccountsData =
serde_json::from_str(&s).expect("failed to deserialize json");
let mut clients = Vec::new(); let mut clients = Vec::new();
clients.resize(accounts_data.accounts.len(), None); clients.resize(accounts_data.accounts.len(), None);
Self { Self {
@ -56,7 +57,7 @@ impl AccountsManager {
accounts: accounts_data.accounts, accounts: accounts_data.accounts,
clients, clients,
} }
}, }
None => { None => {
info!("Creating empty AccountsManager"); info!("Creating empty AccountsManager");
Self { Self {
@ -66,7 +67,7 @@ impl AccountsManager {
clients: Vec::new(), clients: Vec::new(),
} }
} }
} };
} }
pub async fn restore(&mut self) -> Result<()> { pub async fn restore(&mut self) -> Result<()> {
@ -74,7 +75,12 @@ impl AccountsManager {
Ok(()) Ok(())
} }
pub async fn add(&mut self, homeserver: &String, username: &String, password: &String) -> Result<u32> { pub async fn add(
&mut self,
homeserver: &String,
username: &String,
password: &String,
) -> Result<u32> {
let id = self.num_accounts; let id = self.num_accounts;
self.num_accounts += 1; self.num_accounts += 1;
@ -84,7 +90,8 @@ impl AccountsManager {
.build() .build()
.await?; .await?;
client.login_username(username, password) client
.login_username(username, password)
.initial_device_display_name("Trinitrix") .initial_device_display_name("Trinitrix")
.send() .send()
.await?; .await?;
@ -94,9 +101,13 @@ impl AccountsManager {
let account = Account { let account = Account {
homeserver: homeserver.to_string(), homeserver: homeserver.to_string(),
id, id,
name: client.account().get_display_name().await?.expect("failed to fetch display name"), name: client
.account()
.get_display_name()
.await?
.expect("failed to fetch display name"),
session: session.clone(), session: session.clone(),
sync_token: None sync_token: None,
}; };
self.logout().await?; self.logout().await?;
@ -105,7 +116,11 @@ impl AccountsManager {
self.clients.push(Some(client)); self.clients.push(Some(client));
self.save()?; self.save()?;
info!("Logged in as '{}' device ID: {}", session.user_id.to_string(), session.device_id.to_string()); info!(
"Logged in as '{}' device ID: {}",
session.user_id.to_string(),
session.device_id.to_string()
);
Ok(id) Ok(id)
} }
@ -120,8 +135,16 @@ impl AccountsManager {
self.get(account_id).expect("Account lookup failed") self.get(account_id).expect("Account lookup failed")
}; };
if self.clients.get(account_id as usize).expect("client lookup failed").is_none() { if self
info!("No client cached for account: '{}' -> requesting a new one", &account.session.user_id); .clients
.get(account_id as usize)
.expect("client lookup failed")
.is_none()
{
info!(
"No client cached for account: '{}' -> requesting a new one",
&account.session.user_id
);
let client = Client::builder() let client = Client::builder()
.homeserver_url(&account.homeserver) .homeserver_url(&account.homeserver)
.sled_store(format!("userdata/{account_id}"), Some("supersecure"))? .sled_store(format!("userdata/{account_id}"), Some("supersecure"))?
@ -130,7 +153,10 @@ impl AccountsManager {
client.restore_login(account.session.clone()).await?; client.restore_login(account.session.clone()).await?;
self.clients.insert(account_id as usize, Some(client)); self.clients.insert(account_id as usize, Some(client));
} else { } else {
info!("Using cached client for account: '{}'", &account.session.user_id); info!(
"Using cached client for account: '{}'",
&account.session.user_id
);
}; };
info!("Restored account"); info!("Restored account");
@ -188,5 +214,7 @@ impl AccountsManager {
} }
} }
pub fn num_accounts(&self) -> u32 { self.num_accounts } pub fn num_accounts(&self) -> u32 {
self.num_accounts
}
} }

View File

@ -1,14 +1,27 @@
use crate::app::{App, status::{Status, State}}; use anyhow::{Error, Result};
use crate::ui; use cli_log::{error, info, warn};
use tokio::time::Duration; use matrix_sdk::{
use tokio::sync::{mpsc, broadcast}; config::SyncSettings,
use tokio_util::sync::CancellationToken; room::Room,
use anyhow::{Result, Error}; ruma::events::room::{
use matrix_sdk::{Client, room::{Room}, config::SyncSettings, ruma::events::room::{
member::StrippedRoomMemberEvent, member::StrippedRoomMemberEvent,
message::{MessageType, OriginalSyncRoomMessageEvent, RoomMessageEventContent}, message::{MessageType, OriginalSyncRoomMessageEvent, RoomMessageEventContent},
}, LoopCtrl}; },
use cli_log::{error, warn, info}; Client, LoopCtrl,
};
use tokio::{
sync::{broadcast, mpsc},
time::Duration,
};
use tokio_util::sync::CancellationToken;
use crate::{
app::{
status::{State, Status},
App,
},
ui,
};
#[derive(Debug)] #[derive(Debug)]
pub enum EventStatus { pub enum EventStatus {
@ -20,7 +33,7 @@ pub enum EventStatus {
#[derive(Debug)] #[derive(Debug)]
pub struct Event { pub struct Event {
input_event: Option<crossterm::event::Event>, input_event: Option<crossterm::event::Event>,
matrix_event: Option<matrix_sdk::deserialized_responses::SyncResponse> matrix_event: Option<matrix_sdk::deserialized_responses::SyncResponse>,
} }
pub struct EventBuilder { pub struct EventBuilder {
@ -42,7 +55,6 @@ impl Default for EventBuilder {
event: Event::default(), event: Event::default(),
} }
} }
} }
impl EventBuilder { impl EventBuilder {
@ -51,7 +63,10 @@ impl EventBuilder {
self self
} }
fn matrix_event(&mut self, matrix_event: matrix_sdk::deserialized_responses::SyncResponse) -> &Self { fn matrix_event(
&mut self,
matrix_event: matrix_sdk::deserialized_responses::SyncResponse,
) -> &Self {
self.event.matrix_event = Some(matrix_event); self.event.matrix_event = Some(matrix_event);
self self
} }
@ -66,7 +81,6 @@ impl EventBuilder {
impl Event { impl Event {
pub async fn handle(&self, app: &mut App<'_>) -> Result<EventStatus> { pub async fn handle(&self, app: &mut App<'_>) -> Result<EventStatus> {
if self.matrix_event.is_some() { if self.matrix_event.is_some() {
return self.handle_matrix(app).await; return self.handle_matrix(app).await;
} }
@ -88,7 +102,11 @@ impl Event {
None => continue, None => continue,
}; };
for m_event in m_room.timeline.events.clone() { for m_event in m_room.timeline.events.clone() {
let event = m_event.event.deserialize().unwrap().into_full_event(m_room_id.clone()); let event = m_event
.event
.deserialize()
.unwrap()
.into_full_event(m_room_id.clone());
room.timeline_add(event); room.timeline_add(event);
} }
} }
@ -99,59 +117,83 @@ impl Event {
async fn handle_main(&self, app: &mut App<'_>) -> Result<EventStatus> { async fn handle_main(&self, app: &mut App<'_>) -> Result<EventStatus> {
if self.input_event.is_some() { if self.input_event.is_some() {
match tui_textarea::Input::from(self.input_event.clone().unwrap()) { match tui_textarea::Input::from(self.input_event.clone().unwrap()) {
tui_textarea::Input { key: tui_textarea::Key::Esc, .. } => return Ok(EventStatus::Terminate), tui_textarea::Input {
key: tui_textarea::Key::Esc,
..
} => return Ok(EventStatus::Terminate),
tui_textarea::Input { tui_textarea::Input {
key: tui_textarea::Key::Tab, key: tui_textarea::Key::Tab,
.. ..
} => { } => {
app.ui.cycle_main_input_position(); app.ui.cycle_main_input_position();
} }
input => { input => match app.ui.input_position() {
match app.ui.input_position() {
ui::MainInputPosition::MessageCompose => { ui::MainInputPosition::MessageCompose => {
match input { match input {
tui_textarea::Input {key: tui_textarea::Key::Enter, alt: true, ..} => { tui_textarea::Input {
key: tui_textarea::Key::Enter,
alt: true,
..
} => {
match app.status.room_mut() { match app.status.room_mut() {
Some(room) => { Some(room) => {
room.send(app.ui.message_compose.lines().join("\n")).await?; room.send(app.ui.message_compose.lines().join("\n"))
.await?;
app.ui.message_compose_clear(); app.ui.message_compose_clear();
}, }
None => () None => (),
}; };
} }
_ => { app.ui.message_compose.input(input); } _ => {
app.ui.message_compose.input(input);
}
}; };
}, }
ui::MainInputPosition::Rooms => { ui::MainInputPosition::Rooms => {
match input { match input {
tui_textarea::Input {key: tui_textarea::Key::Up, ..} => { tui_textarea::Input {
key: tui_textarea::Key::Up,
..
} => {
let i = match app.ui.rooms_state.selected() { let i = match app.ui.rooms_state.selected() {
Some(i) => { Some(i) => {
if i > 0 { i - 1 } if i > 0 {
else { i } i - 1
}, } else {
i
}
}
None => 0, None => 0,
}; };
app.ui.rooms_state.select(Some(i)); app.ui.rooms_state.select(Some(i));
app.status.set_room_by_index(i)?; app.status.set_room_by_index(i)?;
}, }
tui_textarea::Input {key: tui_textarea::Key::Down, ..} => { tui_textarea::Input {
key: tui_textarea::Key::Down,
..
} => {
let i = match app.ui.rooms_state.selected() { let i = match app.ui.rooms_state.selected() {
Some(i) => { Some(i) => {
if i < app.status.rooms().len() { i + 1 } if i < app.status.rooms().len() {
else { i } i + 1
}, } else {
i
}
}
None => 0, None => 0,
}; };
app.ui.rooms_state.select(Some(i)); app.ui.rooms_state.select(Some(i));
app.status.set_room_by_index(i)?; app.status.set_room_by_index(i)?;
}, }
_ => () _ => (),
}; };
}, }
ui::MainInputPosition::Messages => { ui::MainInputPosition::Messages => {
match input { match input {
tui_textarea::Input {key: tui_textarea::Key::Up, ..} => { tui_textarea::Input {
key: tui_textarea::Key::Up,
..
} => {
match app.status.room_mut() { match app.status.room_mut() {
Some(room) => { Some(room) => {
let len = room.timeline().len(); let len = room.timeline().len();
@ -165,11 +207,14 @@ impl Event {
if i <= len - 5 { if i <= len - 5 {
room.poll_old_timeline().await?; room.poll_old_timeline().await?;
} }
}, }
None => (), None => (),
}; };
}, }
tui_textarea::Input {key: tui_textarea::Key::Down, ..} => { tui_textarea::Input {
key: tui_textarea::Key::Down,
..
} => {
match app.status.room_mut() { match app.status.room_mut() {
Some(room) => { Some(room) => {
match room.view_scroll() { match room.view_scroll() {
@ -182,16 +227,15 @@ impl Event {
} }
None => (), None => (),
}; };
}, }
None => (), None => (),
}; };
}, }
_ => ()
};
},
_ => (), _ => (),
};
} }
} _ => (),
},
}; };
} }
Ok(EventStatus::Ok) Ok(EventStatus::Ok)
@ -200,18 +244,21 @@ impl Event {
async fn handle_setup(&self, app: &mut App<'_>) -> Result<EventStatus> { async fn handle_setup(&self, app: &mut App<'_>) -> Result<EventStatus> {
let ui = match &mut app.ui.setup_ui { let ui = match &mut app.ui.setup_ui {
Some(ui) => ui, Some(ui) => ui,
None => return Err(Error::msg("SetupUI instance not found")) None => return Err(Error::msg("SetupUI instance not found")),
}; };
if self.input_event.is_some() { if self.input_event.is_some() {
match tui_textarea::Input::from(self.input_event.clone().unwrap()) { match tui_textarea::Input::from(self.input_event.clone().unwrap()) {
tui_textarea::Input { key: tui_textarea::Key::Esc, .. } => return Ok(EventStatus::Terminate), tui_textarea::Input {
key: tui_textarea::Key::Esc,
..
} => return Ok(EventStatus::Terminate),
tui_textarea::Input { tui_textarea::Input {
key: tui_textarea::Key::Tab, key: tui_textarea::Key::Tab,
.. ..
} => { } => {
ui.cycle_input_position(); ui.cycle_input_position();
}, }
tui_textarea::Input { tui_textarea::Input {
key: tui_textarea::Key::Enter, key: tui_textarea::Key::Enter,
.. ..
@ -225,33 +272,40 @@ impl Event {
if login.is_ok() { if login.is_ok() {
return Ok(EventStatus::Finished); return Ok(EventStatus::Finished);
} }
}, }
_ => ui.cycle_input_position(), _ => ui.cycle_input_position(),
}; };
}, }
input => { input => match ui.input_position() {
match ui.input_position() { ui::SetupInputPosition::Homeserver => {
ui::SetupInputPosition::Homeserver => { ui.homeserver.input(input); }, ui.homeserver.input(input);
ui::SetupInputPosition::Username => { ui.username.input(input); }, }
ui::SetupInputPosition::Username => {
ui.username.input(input);
}
ui::SetupInputPosition::Password => { ui::SetupInputPosition::Password => {
ui.password_data.input(input.clone()); ui.password_data.input(input.clone());
match input.key { match input.key {
tui_textarea::Key::Char(_) => { tui_textarea::Key::Char(_) => {
ui.password.input(tui_textarea::Input { key: tui_textarea::Key::Char('*'), ctrl: false, alt: false }); ui.password.input(tui_textarea::Input {
}, key: tui_textarea::Key::Char('*'),
_ => { ui.password.input(input); }, ctrl: false,
alt: false,
});
}
_ => {
ui.password.input(input);
}
}
} }
},
_ => (), _ => (),
} },
}
}; };
} }
Ok(EventStatus::Ok) Ok(EventStatus::Ok)
} }
} }
async fn poll_input_events_stage_2(channel: mpsc::Sender<Event>) -> Result<()> { async fn poll_input_events_stage_2(channel: mpsc::Sender<Event>) -> Result<()> {
loop { loop {
if crossterm::event::poll(Duration::from_millis(100))? { if crossterm::event::poll(Duration::from_millis(100))? {
@ -266,7 +320,10 @@ async fn poll_input_events_stage_2(channel: mpsc::Sender<Event>) -> Result<()> {
} }
} }
pub async fn poll_input_events(channel: mpsc::Sender<Event>, kill: CancellationToken) -> Result<()> { pub async fn poll_input_events(
channel: mpsc::Sender<Event>,
kill: CancellationToken,
) -> Result<()> {
tokio::select! { tokio::select! {
output = poll_input_events_stage_2(channel) => output, output = poll_input_events_stage_2(channel) => output,
_ = kill.cancelled() => Err(Error::msg("received kill signal")) _ = kill.cancelled() => Err(Error::msg("received kill signal"))
@ -280,21 +337,25 @@ async fn poll_matrix_events_stage_2(channel: mpsc::Sender<Event>, client: Client
let tx = &channel; let tx = &channel;
client.sync_with_callback(sync_settings, |response| async move { client
let event = EventBuilder::default() .sync_with_callback(sync_settings, |response| async move {
.matrix_event(response) let event = EventBuilder::default().matrix_event(response).build();
.build();
match tx.send(event).await { match tx.send(event).await {
Ok(_) => LoopCtrl::Continue, Ok(_) => LoopCtrl::Continue,
Err(_) => LoopCtrl::Break, Err(_) => LoopCtrl::Break,
} }
}).await?; })
.await?;
Ok(()) Ok(())
} }
pub async fn poll_matrix_events(channel: mpsc::Sender<Event>, kill: CancellationToken, client: Client) -> Result<()> { pub async fn poll_matrix_events(
channel: mpsc::Sender<Event>,
kill: CancellationToken,
client: Client,
) -> Result<()> {
tokio::select! { tokio::select! {
output = poll_matrix_events_stage_2(channel, client) => output, output = poll_matrix_events_stage_2(channel, client) => output,
_ = kill.cancelled() => Err(Error::msg("received kill signal")), _ = kill.cancelled() => Err(Error::msg("received kill signal")),

View File

@ -1,27 +1,29 @@
pub mod event; pub mod event;
pub mod status; pub mod status;
use crate::accounts;
use crate::ui;
use std::path::Path; use std::path::Path;
use matrix_sdk::{Client,
room::{Room}, use accounts::{Account, AccountsManager};
use anyhow::{Error, Result};
use cli_log::{error, info, warn};
use matrix_sdk::{
config::SyncSettings, config::SyncSettings,
event_handler::Ctx,
room::Room,
ruma::events::room::{ ruma::events::room::{
member::StrippedRoomMemberEvent, member::StrippedRoomMemberEvent,
message::{MessageType, OriginalSyncRoomMessageEvent, RoomMessageEventContent}, message::{MessageType, OriginalSyncRoomMessageEvent, RoomMessageEventContent},
}, },
event_handler::Ctx Client,
};
use status::{State, Status};
use tokio::{
sync::{broadcast, mpsc},
time::{sleep, Duration},
}; };
use accounts::Account;
use accounts::AccountsManager;
use anyhow::{Result, Error};
use cli_log::{error, warn, info};
use tokio::{time::{sleep, Duration}, sync::{mpsc, broadcast}};
use tokio_util::sync::CancellationToken; use tokio_util::sync::CancellationToken;
use status::{Status, State};
use crate::{accounts, ui};
pub struct App<'a> { pub struct App<'a> {
ui: ui::UI<'a>, ui: ui::UI<'a>,
@ -35,9 +37,7 @@ pub struct App<'a> {
} }
impl Drop for App<'_> { impl Drop for App<'_> {
fn drop(&mut self) { fn drop(&mut self) {}
}
} }
impl App<'_> { impl App<'_> {
@ -65,9 +65,11 @@ impl App<'_> {
} }
pub async fn run(&mut self) -> Result<()> { pub async fn run(&mut self) -> Result<()> {
// Spawn input event listener // Spawn input event listener
tokio::task::spawn(event::poll_input_events(self.channel_tx.clone(), self.input_listener_killer.clone())); tokio::task::spawn(event::poll_input_events(
self.channel_tx.clone(),
self.input_listener_killer.clone(),
));
if self.account().is_err() { if self.account().is_err() {
info!("No saved sessions found -> jumping into setup"); info!("No saved sessions found -> jumping into setup");
@ -77,14 +79,13 @@ impl App<'_> {
self.init_account().await?; self.init_account().await?;
} }
loop { loop {
self.status.set_state(State::Main); self.status.set_state(State::Main);
self.ui.update(&self.status).await?; self.ui.update(&self.status).await?;
let event: event::Event = match self.channel_rx.recv().await { let event: event::Event = match self.channel_rx.recv().await {
Some(e) => e, Some(e) => e,
None => return Err(Error::msg("Event channel has no senders")) None => return Err(Error::msg("Event channel has no senders")),
}; };
match event.handle(self).await? { match event.handle(self).await? {
@ -107,7 +108,7 @@ impl App<'_> {
let event: event::Event = match self.channel_rx.recv().await { let event: event::Event = match self.channel_rx.recv().await {
Some(e) => e, Some(e) => e,
None => return Err(Error::msg("Event channel has no senders")) None => return Err(Error::msg("Event channel has no senders")),
}; };
match event.handle(self).await? { match event.handle(self).await? {
@ -121,14 +122,19 @@ impl App<'_> {
pub async fn init_account(&mut self) -> Result<()> { pub async fn init_account(&mut self) -> Result<()> {
let client = match self.client() { let client = match self.client() {
Some(c) => c, Some(c) => c,
None => return Err(Error::msg("failed to get current client")) None => return Err(Error::msg("failed to get current client")),
}.clone(); }
.clone();
self.matrix_listener_killer.cancel(); self.matrix_listener_killer.cancel();
self.matrix_listener_killer = CancellationToken::new(); self.matrix_listener_killer = CancellationToken::new();
// Spawn Matrix Event Listener // Spawn Matrix Event Listener
tokio::task::spawn(event::poll_matrix_events(self.channel_tx.clone(), self.matrix_listener_killer.clone(), client.clone())); tokio::task::spawn(event::poll_matrix_events(
self.channel_tx.clone(),
self.matrix_listener_killer.clone(),
client.clone(),
));
// Reset Status // Reset Status
self.status = Status::new(Some(client)); self.status = Status::new(Some(client));
@ -139,10 +145,11 @@ impl App<'_> {
self.status.set_account_name(name); self.status.set_account_name(name);
self.status.set_account_user_id(user_id); self.status.set_account_user_id(user_id);
for (_, room) in self.status.rooms_mut() { for (_, room) in self.status.rooms_mut() {
room.update_name().await?; room.update_name().await?;
for _ in 0..3 { room.poll_old_timeline().await?; } for _ in 0..3 {
room.poll_old_timeline().await?;
}
} }
info!("Initializing client for the current account"); info!("Initializing client for the current account");
@ -151,12 +158,18 @@ impl App<'_> {
} }
pub async fn switch_account(&mut self, account_id: u32) -> Result<()> { pub async fn switch_account(&mut self, account_id: u32) -> Result<()> {
Ok(()) Ok(())
} }
pub async fn login(&mut self, homeserver: &String, username: &String, password: &String) -> Result<()> { pub async fn login(
self.accounts_manager.add(homeserver, username, password).await?; &mut self,
homeserver: &String,
username: &String,
password: &String,
) -> Result<()> {
self.accounts_manager
.add(homeserver, username, password)
.await?;
self.init_account().await?; self.init_account().await?;
Ok(()) Ok(())
} }
@ -165,7 +178,7 @@ impl App<'_> {
let account = self.accounts_manager.current(); let account = self.accounts_manager.current();
match account { match account {
None => Err(Error::msg("failed to resolve current account")), None => Err(Error::msg("failed to resolve current account")),
Some(a) => Ok(a) Some(a) => Ok(a),
} }
} }

View File

@ -1,14 +1,16 @@
use std::any::Any; use std::any::Any;
use anyhow::{Error, Result};
use cli_log::{error, info, warn};
use indexmap::IndexMap; use indexmap::IndexMap;
use matrix_sdk::{Client, use matrix_sdk::{
ruma::{events::{AnyTimelineEvent, room::MessagesOptions,
room::message::RoomMessageEventContent, ruma::{
StateEventType}, events::{room::message::RoomMessageEventContent, AnyTimelineEvent, StateEventType},
RoomId, RoomId, TransactionId,
TransactionId}, },
room::MessagesOptions}; Client,
use anyhow::{Result, Error}; };
use cli_log::{error, warn, info};
pub enum State { pub enum State {
None, None,
@ -50,26 +52,29 @@ impl Room {
pub async fn poll_old_timeline(&mut self) -> Result<()> { pub async fn poll_old_timeline(&mut self) -> Result<()> {
if let Some(AnyTimelineEvent::State(event)) = &self.timeline.get(0) { if let Some(AnyTimelineEvent::State(event)) = &self.timeline.get(0) {
if event.event_type() == StateEventType::RoomCreate { if event.event_type() == StateEventType::RoomCreate {
return Ok(()) return Ok(());
} }
} }
let mut messages_options = MessagesOptions::backward(); let mut messages_options = MessagesOptions::backward();
messages_options = match &self.timeline_end { messages_options = match &self.timeline_end {
Some(end) => messages_options.from(end.as_str()), Some(end) => messages_options.from(end.as_str()),
None => messages_options None => messages_options,
}; };
let events = self.matrix_room.messages(messages_options).await?; let events = self.matrix_room.messages(messages_options).await?;
self.timeline_end = events.end; self.timeline_end = events.end;
for event in events.chunk.iter() { for event in events.chunk.iter() {
self.timeline.insert(0, match event.event.deserialize() { self.timeline.insert(
0,
match event.event.deserialize() {
Ok(ev) => ev, Ok(ev) => ev,
Err(err) => { Err(err) => {
warn!("Failed to deserialize timeline event - {err}"); warn!("Failed to deserialize timeline event - {err}");
continue; continue;
} }
}); },
);
} }
Ok(()) Ok(())
} }
@ -87,7 +92,9 @@ impl Room {
self.timeline.push(event); self.timeline.push(event);
} }
pub fn timeline(&self) -> &Vec<AnyTimelineEvent> { &self.timeline } pub fn timeline(&self) -> &Vec<AnyTimelineEvent> {
&self.timeline
}
pub async fn send(&mut self, message: String) -> Result<()> { pub async fn send(&mut self, message: String) -> Result<()> {
let content = RoomMessageEventContent::text_plain(message); let content = RoomMessageEventContent::text_plain(message);
@ -114,9 +121,7 @@ impl Status {
let mut rooms = IndexMap::new(); let mut rooms = IndexMap::new();
if let Some(c) = &client { if let Some(c) = &client {
for r in c.joined_rooms() { for r in c.joined_rooms() {
rooms.insert( rooms.insert(r.room_id().to_string(), Room::new(r.clone()));
r.room_id().to_string(),
Room::new(r.clone()));
} }
}; };
@ -167,7 +172,10 @@ impl Status {
self.current_room_id = room_id.to_string(); self.current_room_id = room_id.to_string();
Ok(()) Ok(())
} else { } else {
Err(Error::msg(format!("failed to set room -> invalid room id {}", room_id.to_string()))) Err(Error::msg(format!(
"failed to set room -> invalid room id {}",
room_id.to_string()
)))
} }
} }
@ -176,7 +184,10 @@ impl Status {
self.current_room_id = room_id.clone(); self.current_room_id = room_id.clone();
Ok(()) Ok(())
} else { } else {
Err(Error::msg(format!("failed to set room -> invalid room index {}", room_index))) Err(Error::msg(format!(
"failed to set room -> invalid room index {}",
room_index
)))
} }
} }

View File

@ -1,8 +1,8 @@
mod ui;
mod accounts; mod accounts;
mod app; mod app;
mod ui;
use cli_log::{error, warn, info}; use cli_log::{error, info, warn};
#[tokio::main] #[tokio::main]
async fn main() -> anyhow::Result<()> { async fn main() -> anyhow::Result<()> {

View File

@ -1,30 +1,35 @@
use crate::app::status::Status; use std::{cmp, io, io::Stdout};
use std::cmp;
use crossterm::{
event::{self, DisableMouseCapture, EnableMouseCapture, Event, read},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
style::{style},
};
use anyhow::{Error, Result}; use anyhow::{Error, Result};
use std::io::Stdout; use cli_log::{error, info, warn};
use std::io; use crossterm::{
use tui::{backend::CrosstermBackend, layout::{Constraint, Direction, Layout}, widgets::{Block, Borders, Widget}, Terminal, Frame}; event::{self, read, DisableMouseCapture, EnableMouseCapture, Event},
use tui::layout::{Alignment, Corner}; execute,
use tui::style::{Color, Modifier, Style}; style::style,
use tui::text::{Spans, Span, Text}; terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
use tui::widgets::{List, ListItem, ListState, Paragraph, Wrap}; };
use matrix_sdk::{
room::MessagesOptions,
ruma::events::{AnyMessageLikeEvent, AnyTimelineEvent},
};
use tui::{
backend::CrosstermBackend,
layout::{Alignment, Constraint, Corner, Direction, Layout},
style::{Color, Modifier, Style},
text::{Span, Spans, Text},
widgets::{Block, Borders, List, ListItem, ListState, Paragraph, Widget, Wrap},
Frame, Terminal,
};
use tui_textarea::{Input, Key, TextArea}; use tui_textarea::{Input, Key, TextArea};
use cli_log::{error, warn, info};
use matrix_sdk::{room::MessagesOptions, ruma::events::{AnyTimelineEvent, AnyMessageLikeEvent}}; use crate::app::status::Status;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum SetupInputPosition { pub enum SetupInputPosition {
Homeserver, Homeserver,
Username, Username,
Password, Password,
Ok Ok,
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@ -33,7 +38,7 @@ pub enum MainInputPosition {
Rooms, Rooms,
Messages, Messages,
MessageCompose, MessageCompose,
RoomInfo RoomInfo,
} }
pub struct SetupUI<'a> { pub struct SetupUI<'a> {
@ -54,7 +59,6 @@ pub struct UI<'a> {
pub setup_ui: Option<SetupUI<'a>>, pub setup_ui: Option<SetupUI<'a>>,
} }
fn terminal_prepare() -> Result<Stdout> { fn terminal_prepare() -> Result<Stdout> {
enable_raw_mode()?; enable_raw_mode()?;
let mut stdout = io::stdout(); let mut stdout = io::stdout();
@ -80,9 +84,7 @@ pub fn textarea_inactivate(textarea: &mut TextArea) {
.block() .block()
.cloned() .cloned()
.unwrap_or_else(|| Block::default().borders(Borders::ALL)); .unwrap_or_else(|| Block::default().borders(Borders::ALL));
textarea.set_block( textarea.set_block(b.style(Style::default().fg(Color::DarkGray)));
b.style(Style::default().fg(Color::DarkGray))
);
} }
impl Drop for UI<'_> { impl Drop for UI<'_> {
@ -94,7 +96,9 @@ impl Drop for UI<'_> {
LeaveAlternateScreen, LeaveAlternateScreen,
DisableMouseCapture DisableMouseCapture
).expect("While destructing UI -> Failed execute backend commands (LeaveAlternateScreen and DisableMouseCapture)"); ).expect("While destructing UI -> Failed execute backend commands (LeaveAlternateScreen and DisableMouseCapture)");
self.terminal.show_cursor().expect("While destructing UI -> Failed to re-enable cursor"); self.terminal
.show_cursor()
.expect("While destructing UI -> Failed to re-enable cursor");
} }
} }
@ -105,18 +109,9 @@ impl SetupUI<'_> {
let mut password = TextArea::default(); let mut password = TextArea::default();
let mut password_data = TextArea::default(); let mut password_data = TextArea::default();
homeserver.set_block( homeserver.set_block(Block::default().title("Homeserver").borders(Borders::ALL));
Block::default() username.set_block(Block::default().title("Username").borders(Borders::ALL));
.title("Homeserver") password.set_block(Block::default().title("Password").borders(Borders::ALL));
.borders(Borders::ALL));
username.set_block(
Block::default()
.title("Username")
.borders(Borders::ALL));
password.set_block(
Block::default()
.title("Password")
.borders(Borders::ALL));
textarea_activate(&mut homeserver); textarea_activate(&mut homeserver);
textarea_inactivate(&mut username); textarea_inactivate(&mut username);
@ -138,46 +133,49 @@ impl SetupUI<'_> {
textarea_activate(&mut self.username); textarea_activate(&mut self.username);
textarea_inactivate(&mut self.password); textarea_inactivate(&mut self.password);
SetupInputPosition::Username SetupInputPosition::Username
}, }
SetupInputPosition::Username => { SetupInputPosition::Username => {
textarea_inactivate(&mut self.homeserver); textarea_inactivate(&mut self.homeserver);
textarea_inactivate(&mut self.username); textarea_inactivate(&mut self.username);
textarea_activate(&mut self.password); textarea_activate(&mut self.password);
SetupInputPosition::Password SetupInputPosition::Password
}, }
SetupInputPosition::Password => { SetupInputPosition::Password => {
textarea_inactivate(&mut self.homeserver); textarea_inactivate(&mut self.homeserver);
textarea_inactivate(&mut self.username); textarea_inactivate(&mut self.username);
textarea_inactivate(&mut self.password); textarea_inactivate(&mut self.password);
SetupInputPosition::Ok SetupInputPosition::Ok
}, }
SetupInputPosition::Ok => { SetupInputPosition::Ok => {
textarea_activate(&mut self.homeserver); textarea_activate(&mut self.homeserver);
textarea_inactivate(&mut self.username); textarea_inactivate(&mut self.username);
textarea_inactivate(&mut self.password); textarea_inactivate(&mut self.password);
SetupInputPosition::Homeserver SetupInputPosition::Homeserver
}, }
}; };
} }
pub fn input_position(&self) -> &SetupInputPosition { &self.input_position } pub fn input_position(&self) -> &SetupInputPosition {
&self.input_position
}
pub async fn update(&'_ mut self, terminal: &mut Terminal<CrosstermBackend<Stdout>>) -> Result<()> { pub async fn update(
&'_ mut self,
terminal: &mut Terminal<CrosstermBackend<Stdout>>,
) -> Result<()> {
let mut strings: Vec<String> = Vec::new(); let mut strings: Vec<String> = Vec::new();
strings.resize(3, "".to_string()); strings.resize(3, "".to_string());
let content_ok = match self.input_position { let content_ok = match self.input_position {
SetupInputPosition:: Ok => Span::styled("OK", Style::default().add_modifier(Modifier::UNDERLINED)), SetupInputPosition::Ok => {
Span::styled("OK", Style::default().add_modifier(Modifier::UNDERLINED))
}
_ => Span::styled("OK", Style::default().fg(Color::DarkGray)), _ => Span::styled("OK", Style::default().fg(Color::DarkGray)),
}; };
let block = Block::default() let block = Block::default().title("Login").borders(Borders::ALL);
.title("Login")
.borders(Borders::ALL);
let mut ok = Paragraph::new(content_ok)
.alignment(Alignment::Center);
let mut ok = Paragraph::new(content_ok).alignment(Alignment::Center);
// define a 32 * 6 chunk in the middle of the screen // define a 32 * 6 chunk in the middle of the screen
let mut chunk = terminal.size()?; let mut chunk = terminal.size()?;
@ -194,12 +192,15 @@ impl SetupUI<'_> {
let chunks = Layout::default() let chunks = Layout::default()
.direction(Direction::Vertical) .direction(Direction::Vertical)
.constraints([ .constraints(
[
Constraint::Length(3), // 0. Homserver: Constraint::Length(3), // 0. Homserver:
Constraint::Length(3), // 1. Username: Constraint::Length(3), // 1. Username:
Constraint::Length(3), // 2. Password: Constraint::Length(3), // 2. Password:
Constraint::Length(1) // 3. OK Constraint::Length(1), // 3. OK
].as_ref()) ]
.as_ref(),
)
.split(split_chunk); .split(split_chunk);
terminal.draw(|frame| { terminal.draw(|frame| {
@ -226,7 +227,8 @@ impl UI<'_> {
message_compose.set_block( message_compose.set_block(
Block::default() Block::default()
.title("Message Compose (send: <Alt>+<Enter>)") .title("Message Compose (send: <Alt>+<Enter>)")
.borders(Borders::ALL)); .borders(Borders::ALL),
);
info!("Initialized UI"); info!("Initialized UI");
@ -235,7 +237,7 @@ impl UI<'_> {
input_position: MainInputPosition::Rooms, input_position: MainInputPosition::Rooms,
rooms_state: ListState::default(), rooms_state: ListState::default(),
message_compose, message_compose,
setup_ui: None setup_ui: None,
} }
} }
@ -249,14 +251,17 @@ impl UI<'_> {
}; };
} }
pub fn input_position(&self) -> &MainInputPosition { &self.input_position } pub fn input_position(&self) -> &MainInputPosition {
&self.input_position
}
pub fn message_compose_clear(&mut self) { pub fn message_compose_clear(&mut self) {
self.message_compose = TextArea::default(); self.message_compose = TextArea::default();
self.message_compose.set_block( self.message_compose.set_block(
Block::default() Block::default()
.title("Message Compose (send: <Alt>+<Enter>)") .title("Message Compose (send: <Alt>+<Enter>)")
.borders(Borders::ALL)); .borders(Borders::ALL),
);
} }
pub async fn update(&mut self, status: &Status) -> Result<()> { pub async fn update(&mut self, status: &Status) -> Result<()> {
@ -264,7 +269,14 @@ impl UI<'_> {
let main_chunks = Layout::default() let main_chunks = Layout::default()
.direction(Direction::Horizontal) .direction(Direction::Horizontal)
.constraints([Constraint::Length(32), Constraint::Min(16), Constraint::Length(32)].as_ref()) .constraints(
[
Constraint::Length(32),
Constraint::Min(16),
Constraint::Length(32),
]
.as_ref(),
)
.split(chunk); .split(chunk);
let left_chunks = Layout::default() let left_chunks = Layout::default()
@ -274,7 +286,13 @@ impl UI<'_> {
let middle_chunks = Layout::default() let middle_chunks = Layout::default()
.direction(Direction::Vertical) .direction(Direction::Vertical)
.constraints([Constraint::Min(4), Constraint::Length(cmp::min(2 + self.message_compose.lines().len() as u16, 8))].as_ref()) .constraints(
[
Constraint::Min(4),
Constraint::Length(cmp::min(2 + self.message_compose.lines().len() as u16, 8)),
]
.as_ref(),
)
.split(main_chunks[1]); .split(main_chunks[1]);
let right_chunks = Layout::default() let right_chunks = Layout::default()
@ -282,15 +300,22 @@ impl UI<'_> {
.constraints([Constraint::Min(4)].as_ref()) .constraints([Constraint::Min(4)].as_ref())
.split(main_chunks[2]); .split(main_chunks[2]);
let mut status_content = Text::styled(status.account_name(), Style::default().add_modifier(Modifier::BOLD)); let mut status_content = Text::styled(
status.account_name(),
Style::default().add_modifier(Modifier::BOLD),
);
status_content.extend(Text::styled(status.account_user_id(), Style::default())); status_content.extend(Text::styled(status.account_user_id(), Style::default()));
status_content.extend(Text::styled("settings", Style::default().fg(Color::LightMagenta).add_modifier(Modifier::ITALIC | Modifier::UNDERLINED))); status_content.extend(Text::styled(
"settings",
Style::default()
.fg(Color::LightMagenta)
.add_modifier(Modifier::ITALIC | Modifier::UNDERLINED),
));
let rooms_content = status.rooms() let rooms_content = status
.rooms()
.iter() .iter()
.map(|(_, room)| { .map(|(_, room)| ListItem::new(Span::styled(room.name(), Style::default())))
ListItem::new(Span::styled(room.name(), Style::default()))
})
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let messages_content = match status.room() { let messages_content = match status.room() {
@ -300,7 +325,6 @@ impl UI<'_> {
.rev() .rev()
.map(|event| { .map(|event| {
match event { match event {
// Message Like Events // Message Like Events
AnyTimelineEvent::MessageLike(message_like_event) => { AnyTimelineEvent::MessageLike(message_like_event) => {
let (content, color) = match &message_like_event { let (content, color) = match &message_like_event {
@ -312,30 +336,48 @@ impl UI<'_> {
.body(); .body();
(message_content.to_string(), Color::White) (message_content.to_string(), Color::White)
}, }
_ => ("~~~ not supported message like event ~~~".to_string(), Color::Red) _ => (
"~~~ not supported message like event ~~~".to_string(),
Color::Red,
),
}; };
let mut text = Text::styled(message_like_event.sender().to_string(), let mut text = Text::styled(
Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD)); message_like_event.sender().to_string(),
text.extend(Text::styled(content.to_string(), Style::default()
Style::default().fg(color))); .fg(Color::Cyan)
.add_modifier(Modifier::BOLD),
);
text.extend(Text::styled(
content.to_string(),
Style::default().fg(color),
));
ListItem::new(text) ListItem::new(text)
}, }
// State Events // State Events
AnyTimelineEvent::State(state) => { AnyTimelineEvent::State(state) => {
ListItem::new(vec![Spans::from(vec![ ListItem::new(vec![Spans::from(vec![
Span::styled(state.sender().to_string(), Style::default().fg(Color::DarkGray)), Span::styled(
state.sender().to_string(),
Style::default().fg(Color::DarkGray),
),
Span::styled(": ", Style::default().fg(Color::DarkGray)), Span::styled(": ", Style::default().fg(Color::DarkGray)),
Span::styled(state.event_type().to_string(), Style::default().fg(Color::DarkGray)) Span::styled(
state.event_type().to_string(),
Style::default().fg(Color::DarkGray),
),
])]) ])])
} }
} }
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
}, }
None => { None => {
vec![ListItem::new(Text::styled("No room selected!", Style::default().fg(Color::Red)))] vec![ListItem::new(Text::styled(
"No room selected!",
Style::default().fg(Color::Red),
))]
} }
}; };
@ -347,73 +389,124 @@ impl UI<'_> {
room_info_content.extend(Text::styled(room.name(), Style::default().fg(Color::Cyan))); room_info_content.extend(Text::styled(room.name(), Style::default().fg(Color::Cyan)));
if room.encrypted() { if room.encrypted() {
room_info_content.extend(Text::styled("Encrypted", Style::default().fg(Color::Green))); room_info_content
.extend(Text::styled("Encrypted", Style::default().fg(Color::Green)));
} else { } else {
room_info_content.extend(Text::styled("Not Encrypted!", Style::default().fg(Color::Red))); room_info_content.extend(Text::styled(
"Not Encrypted!",
Style::default().fg(Color::Red),
));
} }
} else { } else {
room_info_content.extend(Text::styled("No room selected!", Style::default().fg(Color::Red))); room_info_content.extend(Text::styled(
"No room selected!",
Style::default().fg(Color::Red),
));
} }
// calculate to widgets colors, based of which widget is currently selected // calculate to widgets colors, based of which widget is currently selected
let colors = match self.input_position { let colors = match self.input_position {
MainInputPosition::Status => { MainInputPosition::Status => {
textarea_inactivate(&mut self.message_compose); textarea_inactivate(&mut self.message_compose);
vec![Color::White, Color::DarkGray, Color::DarkGray, Color::DarkGray, Color::DarkGray] vec![
}, Color::White,
Color::DarkGray,
Color::DarkGray,
Color::DarkGray,
Color::DarkGray,
]
}
MainInputPosition::Rooms => { MainInputPosition::Rooms => {
textarea_inactivate(&mut self.message_compose); textarea_inactivate(&mut self.message_compose);
vec![Color::DarkGray, Color::White, Color::DarkGray, Color::DarkGray, Color::DarkGray] vec![
}, Color::DarkGray,
Color::White,
Color::DarkGray,
Color::DarkGray,
Color::DarkGray,
]
}
MainInputPosition::Messages => { MainInputPosition::Messages => {
textarea_inactivate(&mut self.message_compose); textarea_inactivate(&mut self.message_compose);
vec![Color::DarkGray, Color::DarkGray, Color::White, Color::DarkGray, Color::DarkGray] vec![
}, Color::DarkGray,
Color::DarkGray,
Color::White,
Color::DarkGray,
Color::DarkGray,
]
}
MainInputPosition::MessageCompose => { MainInputPosition::MessageCompose => {
textarea_activate(&mut self.message_compose); textarea_activate(&mut self.message_compose);
vec![Color::DarkGray, Color::DarkGray, Color::DarkGray, Color::DarkGray, Color::DarkGray] vec![
}, Color::DarkGray,
Color::DarkGray,
Color::DarkGray,
Color::DarkGray,
Color::DarkGray,
]
}
MainInputPosition::RoomInfo => { MainInputPosition::RoomInfo => {
textarea_inactivate(&mut self.message_compose); textarea_inactivate(&mut self.message_compose);
vec![Color::DarkGray, Color::DarkGray, Color::DarkGray, Color::DarkGray, Color::White] vec![
}, Color::DarkGray,
Color::DarkGray,
Color::DarkGray,
Color::DarkGray,
Color::White,
]
}
}; };
// initiate the widgets // initiate the widgets
let status_panel = Paragraph::new(status_content) let status_panel = Paragraph::new(status_content)
.block(Block::default() .block(
Block::default()
.title("Status") .title("Status")
.borders(Borders::ALL) .borders(Borders::ALL)
.style(Style::default().fg(colors[MainInputPosition::Status as usize]))) .style(Style::default().fg(colors[MainInputPosition::Status as usize])),
)
.alignment(Alignment::Left); .alignment(Alignment::Left);
let rooms_panel = List::new(rooms_content) let rooms_panel = List::new(rooms_content)
.block(Block::default() .block(
Block::default()
.title("Rooms (navigate: arrow keys)") .title("Rooms (navigate: arrow keys)")
.borders(Borders::ALL) .borders(Borders::ALL)
.style(Style::default().fg(colors[MainInputPosition::Rooms as usize]))) .style(Style::default().fg(colors[MainInputPosition::Rooms as usize])),
)
.style(Style::default().fg(Color::DarkGray)) .style(Style::default().fg(Color::DarkGray))
.highlight_style(Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD)) .highlight_style(
Style::default()
.fg(Color::Cyan)
.add_modifier(Modifier::BOLD),
)
.highlight_symbol(">"); .highlight_symbol(">");
let messages_panel = List::new(messages_content) let messages_panel = List::new(messages_content)
.block(Block::default() .block(
Block::default()
.title("Messages") .title("Messages")
.borders(Borders::ALL) .borders(Borders::ALL)
.style(Style::default().fg(colors[MainInputPosition::Messages as usize]))) .style(Style::default().fg(colors[MainInputPosition::Messages as usize])),
)
.start_corner(Corner::BottomLeft) .start_corner(Corner::BottomLeft)
.highlight_symbol(">") .highlight_symbol(">")
.highlight_style(Style::default().fg(Color::LightMagenta).add_modifier(Modifier::BOLD)); .highlight_style(
Style::default()
.fg(Color::LightMagenta)
.add_modifier(Modifier::BOLD),
);
let room_info_panel = Paragraph::new(room_info_content) let room_info_panel = Paragraph::new(room_info_content)
.block(Block::default() .block(
Block::default()
.title("Room Info") .title("Room Info")
.borders(Borders::ALL) .borders(Borders::ALL)
.style(Style::default().fg(colors[MainInputPosition::RoomInfo as usize]))) .style(Style::default().fg(colors[MainInputPosition::RoomInfo as usize])),
)
.alignment(Alignment::Center); .alignment(Alignment::Center);
// render the widgets // render the widgets
self.terminal.draw(|frame| { self.terminal.draw(|frame| {
frame.render_widget(status_panel, left_chunks[0]); frame.render_widget(status_panel, left_chunks[0]);