mirror of
https://github.com/Xithrius/twitch-tui.git
synced 2024-09-11 13:45:30 +03:00
Preparing for v2.0 (#74)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
5893ae8c60
commit
9ac53ca891
3
.gitignore
vendored
3
.gitignore
vendored
@ -14,9 +14,6 @@
|
|||||||
# JetBrains project config folder.
|
# JetBrains project config folder.
|
||||||
.idea
|
.idea
|
||||||
|
|
||||||
# Visual Studio Code config folder.
|
|
||||||
.vscode
|
|
||||||
|
|
||||||
# Ignore Vim temporary and swap files.
|
# Ignore Vim temporary and swap files.
|
||||||
*.sw?
|
*.sw?
|
||||||
*~
|
*~
|
||||||
|
42
.vscode/launch.json
vendored
Normal file
42
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug executable 'twt'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"--bin=twt",
|
||||||
|
"--package=twitch-tui"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "twt",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug unit tests in executable 'twt'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--no-run",
|
||||||
|
"--bin=twt",
|
||||||
|
"--package=twitch-tui"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "twt",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"editor.defaultFormatter": "matklad.rust-analyzer"
|
||||||
|
}
|
332
Cargo.lock
generated
332
Cargo.lock
generated
@ -39,9 +39,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.0.1"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
@ -63,9 +63,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.72"
|
version = "1.0.73"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
|
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@ -103,9 +103,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clipboard-win"
|
name = "clipboard-win"
|
||||||
version = "4.2.2"
|
version = "4.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3db8340083d28acb43451166543b98c838299b7e0863621be53a338adceea0ed"
|
checksum = "2f3e1238132dc01f081e1cbb9dace14e5ef4c3a51ee244bd982275fb514605db"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"error-code",
|
"error-code",
|
||||||
"str-buf",
|
"str-buf",
|
||||||
@ -114,9 +114,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.9.2"
|
version = "0.9.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3"
|
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
"libc",
|
"libc",
|
||||||
@ -290,20 +290,50 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "error-code"
|
name = "errno"
|
||||||
version = "2.3.0"
|
version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b5115567ac25674e0043e472be13d14e537f37ea8aa4bdc4aef0c89add1db1ff"
|
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
|
||||||
|
dependencies = [
|
||||||
|
"errno-dragonfly",
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno-dragonfly"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "error-code"
|
||||||
|
version = "2.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"str-buf",
|
"str-buf",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fd-lock"
|
name = "fastrand"
|
||||||
version = "3.0.1"
|
version = "1.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cfc110fe50727d46a428eed832df40affe9bf74d077cac1bf3f2718e823f14c5"
|
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
|
||||||
|
dependencies = [
|
||||||
|
"instant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fd-lock"
|
||||||
|
version = "3.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fcef756dea9cf3db5ce73759cf0467330427a786b47711b8d6c97620d718ceb9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
@ -415,10 +445,19 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "fuzzy-matcher"
|
||||||
version = "0.2.3"
|
version = "0.3.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94"
|
||||||
|
dependencies = [
|
||||||
|
"thread_local",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
@ -452,6 +491,15 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "io-lifetimes"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f6ef6787e7f0faedc040f95716bdd0e62bcfcf4ba93da053b62dea2691c13864"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "irc"
|
name = "irc"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
@ -527,9 +575,9 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memoffset"
|
name = "memoffset"
|
||||||
version = "0.6.4"
|
version = "0.6.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
|
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
@ -598,9 +646,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "nix"
|
||||||
version = "0.23.0"
|
version = "0.23.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f305c2c2e4c39a82f7bf0bf65fb557f9070ce06781d4f2454295cc34b1c43188"
|
checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cc",
|
"cc",
|
||||||
@ -611,9 +659,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ntapi"
|
name = "ntapi"
|
||||||
version = "0.3.6"
|
version = "0.3.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
|
checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
@ -639,9 +687,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.13.0"
|
version = "1.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
|
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
@ -649,9 +697,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.8.0"
|
version = "1.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl"
|
name = "openssl"
|
||||||
@ -669,15 +717,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-probe"
|
name = "openssl-probe"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
|
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.71"
|
version = "0.9.72"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7df13d165e607909b363a4757a6f133f8a818a74e9d3a98d09c6128e15fa4c73"
|
checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"cc",
|
"cc",
|
||||||
@ -736,18 +784,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.0.8"
|
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 = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08"
|
checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pin-project-internal",
|
"pin-project-internal",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-internal"
|
name = "pin-project-internal"
|
||||||
version = "1.0.8"
|
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 = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389"
|
checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -756,9 +804,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.7"
|
version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
|
checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-utils"
|
name = "pin-utils"
|
||||||
@ -768,15 +816,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.22"
|
version = "0.3.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
|
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ppv-lite86"
|
|
||||||
version = "0.2.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-error"
|
name = "proc-macro-error"
|
||||||
@ -804,18 +846,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.32"
|
version = "1.0.36"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
|
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.10"
|
version = "1.0.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
|
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@ -830,46 +872,6 @@ dependencies = [
|
|||||||
"nibble_vec",
|
"nibble_vec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand"
|
|
||||||
version = "0.8.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"rand_chacha",
|
|
||||||
"rand_core",
|
|
||||||
"rand_hc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_chacha"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
|
||||||
dependencies = [
|
|
||||||
"ppv-lite86",
|
|
||||||
"rand_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.6.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
|
||||||
dependencies = [
|
|
||||||
"getrandom",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_hc"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.2.10"
|
version = "0.2.10"
|
||||||
@ -915,6 +917,20 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustix"
|
||||||
|
version = "0.32.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7cee647393af53c750e15dcbf7781cdd2e550b246bde76e46c326e7ea3c73773"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"errno",
|
||||||
|
"io-lifetimes",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustyline"
|
name = "rustyline"
|
||||||
version = "9.1.2"
|
version = "9.1.2"
|
||||||
@ -957,9 +973,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework"
|
name = "security-framework"
|
||||||
version = "2.3.1"
|
version = "2.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "23a2ac85147a3a11d77ecf1bc7166ec0b92febfa4461c37944e180f319ece467"
|
checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
@ -970,9 +986,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework-sys"
|
name = "security-framework-sys"
|
||||||
version = "2.4.2"
|
version = "2.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e"
|
checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
"libc",
|
"libc",
|
||||||
@ -1000,9 +1016,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook"
|
name = "signal-hook"
|
||||||
version = "0.3.10"
|
version = "0.3.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c98891d737e271a2954825ef19e46bd16bdb98e2746f2eec4f7a4ef7946efd1"
|
checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
@ -1036,9 +1052,9 @@ checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smawk"
|
name = "smawk"
|
||||||
@ -1094,9 +1110,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.82"
|
version = "1.0.86"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
|
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1105,13 +1121,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.2.0"
|
version = "3.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
|
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"fastrand",
|
||||||
"libc",
|
"libc",
|
||||||
"rand",
|
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"remove_dir_all",
|
"remove_dir_all",
|
||||||
"winapi",
|
"winapi",
|
||||||
@ -1157,6 +1173,15 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "1.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.1.43"
|
version = "0.1.43"
|
||||||
@ -1264,6 +1289,7 @@ dependencies = [
|
|||||||
"crossterm 0.20.0",
|
"crossterm 0.20.0",
|
||||||
"enum-iterator",
|
"enum-iterator",
|
||||||
"futures",
|
"futures",
|
||||||
|
"fuzzy-matcher",
|
||||||
"irc",
|
"irc",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"rustyline",
|
"rustyline",
|
||||||
@ -1358,9 +1384,35 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.28.0"
|
version = "0.30.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "82ca39602d5cbfa692c4b67e3bcbb2751477355141c1ed434c94da4186836ff6"
|
checksum = "030b7ff91626e57a05ca64a07c481973cbb2db774e4852c9c7ca342408c6a99a"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_msvc 0.28.0",
|
||||||
|
"windows_i686_gnu 0.28.0",
|
||||||
|
"windows_i686_msvc 0.28.0",
|
||||||
|
"windows_x86_64_gnu 0.28.0",
|
||||||
|
"windows_x86_64_msvc 0.28.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_msvc 0.32.0",
|
||||||
|
"windows_i686_gnu 0.32.0",
|
||||||
|
"windows_i686_msvc 0.32.0",
|
||||||
|
"windows_x86_64_gnu 0.32.0",
|
||||||
|
"windows_x86_64_msvc 0.32.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_msvc 0.28.0",
|
"windows_aarch64_msvc 0.28.0",
|
||||||
"windows_i686_gnu 0.28.0",
|
"windows_i686_gnu 0.28.0",
|
||||||
@ -1384,9 +1436,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.28.0"
|
version = "0.30.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52695a41e536859d5308cc613b4a022261a274390b25bd29dfff4bf08505f3c2"
|
checksum = "29277a4435d642f775f63c7d1faeb927adba532886ce0287bd985bffb16b6bca"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
@ -1396,9 +1448,27 @@ checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.28.0"
|
version = "0.30.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f54725ac23affef038fecb177de6c9bf065787c2f432f79e3c373da92f3e1d8a"
|
checksum = "1145e1989da93956c68d1864f32fb97c8f561a8f89a5125f6a2b7ea75524e4b8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
@ -1408,9 +1478,15 @@ checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.28.0"
|
version = "0.30.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "51d5158a43cc43623c0729d1ad6647e62fa384a3d135fd15108d37c683461f64"
|
checksum = "d4a09e3a0d4753b73019db171c1339cd4362c8c44baf1bcea336235e955954a6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
@ -1420,9 +1496,15 @@ checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.28.0"
|
version = "0.30.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bc31f409f565611535130cfe7ee8e6655d3fa99c1c61013981e491921b5ce954"
|
checksum = "8ca64fcb0220d58db4c119e050e7af03c69e6f4f415ef69ec1773d9aab422d5a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
@ -1432,7 +1514,31 @@ checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.28.0"
|
version = "0.30.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08cabc9f0066848fef4bc6a1c1668e6efce38b661d2aeec75d18d8617eebb5f1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.32.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.32.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f"
|
checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f"
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ rustyline = "9.1.2"
|
|||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
structopt = "0.3.26"
|
structopt = "0.3.26"
|
||||||
enum-iterator = "0.7.0"
|
enum-iterator = "0.7.0"
|
||||||
|
fuzzy-matcher = "0.3.7"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
bench = false
|
bench = false
|
||||||
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2021 Xithrius
|
Copyright (c) 2022 Xithrius
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -11,12 +11,14 @@ pub enum State {
|
|||||||
Input,
|
Input,
|
||||||
Help,
|
Help,
|
||||||
ChannelSwitch,
|
ChannelSwitch,
|
||||||
|
Search,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, std::cmp::Eq, std::hash::Hash, IntoEnumIterator)]
|
#[derive(PartialEq, std::cmp::Eq, std::hash::Hash, IntoEnumIterator)]
|
||||||
pub enum BufferName {
|
pub enum BufferName {
|
||||||
Chat,
|
Chat,
|
||||||
Channel,
|
Channel,
|
||||||
|
MessageSearch,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
@ -32,6 +34,10 @@ pub struct App {
|
|||||||
pub table_constraints: Option<Vec<Constraint>>,
|
pub table_constraints: Option<Vec<Constraint>>,
|
||||||
/// The titles of the columns within the table of the terminal
|
/// The titles of the columns within the table of the terminal
|
||||||
pub column_titles: Option<Vec<String>>,
|
pub column_titles: Option<Vec<String>>,
|
||||||
|
/// Scrolling offset for windows
|
||||||
|
pub scroll_offset: usize,
|
||||||
|
/// A temporary snapshot of current messages
|
||||||
|
pub messages_snapshot: VecDeque<Data>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
@ -49,10 +55,16 @@ impl App {
|
|||||||
input_buffers: input_buffers_map,
|
input_buffers: input_buffers_map,
|
||||||
table_constraints: None,
|
table_constraints: None,
|
||||||
column_titles: None,
|
column_titles: None,
|
||||||
|
scroll_offset: 0,
|
||||||
|
messages_snapshot: VecDeque::with_capacity(config.terminal.maximum_messages),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_buffer(&mut self) -> &mut LineBuffer {
|
pub fn current_buffer(&self) -> &LineBuffer {
|
||||||
|
return self.input_buffers.get(&self.selected_buffer).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn current_buffer_mut(&mut self) -> &mut LineBuffer {
|
||||||
return self.input_buffers.get_mut(&self.selected_buffer).unwrap();
|
return self.input_buffers.get_mut(&self.selected_buffer).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,13 @@ use crate::{
|
|||||||
utils::{colors::hsl_to_rgb, styles, text::align_text},
|
utils::{colors::hsl_to_rgb, styles, text::align_text},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum PayLoad {
|
||||||
|
Message(String),
|
||||||
|
Err(String),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct DataBuilder<'conf> {
|
pub struct DataBuilder<'conf> {
|
||||||
pub date_format: &'conf str,
|
pub date_format: &'conf str,
|
||||||
@ -24,7 +31,7 @@ impl<'conf> DataBuilder<'conf> {
|
|||||||
time_sent: Local::now().format(self.date_format).to_string(),
|
time_sent: Local::now().format(self.date_format).to_string(),
|
||||||
author: user,
|
author: user,
|
||||||
system: false,
|
system: false,
|
||||||
message,
|
payload: PayLoad::Message(message),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +40,7 @@ impl<'conf> DataBuilder<'conf> {
|
|||||||
time_sent: Local::now().format(self.date_format).to_string(),
|
time_sent: Local::now().format(self.date_format).to_string(),
|
||||||
author: "System".to_string(),
|
author: "System".to_string(),
|
||||||
system: true,
|
system: true,
|
||||||
message,
|
payload: PayLoad::Message(message),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +49,7 @@ impl<'conf> DataBuilder<'conf> {
|
|||||||
time_sent: Local::now().format(self.date_format).to_string(),
|
time_sent: Local::now().format(self.date_format).to_string(),
|
||||||
author: "Twitch".to_string(),
|
author: "Twitch".to_string(),
|
||||||
system: true,
|
system: true,
|
||||||
message,
|
payload: PayLoad::Message(message),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,8 +58,8 @@ impl<'conf> DataBuilder<'conf> {
|
|||||||
pub struct Data {
|
pub struct Data {
|
||||||
pub time_sent: String,
|
pub time_sent: String,
|
||||||
pub author: String,
|
pub author: String,
|
||||||
pub message: String,
|
|
||||||
pub system: bool,
|
pub system: bool,
|
||||||
|
pub payload: PayLoad,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Data {
|
impl Data {
|
||||||
@ -77,14 +84,14 @@ impl Data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_row(&self, frontend_config: &FrontendConfig, limit: &usize) -> (u16, Row) {
|
pub fn to_row(&self, frontend_config: &FrontendConfig, limit: &usize) -> (u16, Row) {
|
||||||
let message = textwrap::fill(self.message.as_str(), *limit);
|
if let PayLoad::Message(m) = &self.payload {
|
||||||
|
let message = textwrap::fill(m.as_str(), *limit);
|
||||||
|
|
||||||
let style;
|
let style = if self.system {
|
||||||
if self.system {
|
styles::SYSTEM_CHAT
|
||||||
style = styles::SYSTEM_CHAT;
|
|
||||||
} else {
|
} else {
|
||||||
style = Style::default().fg(self.hash_username(&frontend_config.palette));
|
Style::default().fg(self.hash_username(&frontend_config.palette))
|
||||||
}
|
};
|
||||||
|
|
||||||
let mut row_vector = vec![
|
let mut row_vector = vec![
|
||||||
Cell::from(align_text(
|
Cell::from(align_text(
|
||||||
@ -109,6 +116,9 @@ impl Data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(msg_height, row)
|
(msg_height, row)
|
||||||
|
} else {
|
||||||
|
panic!("Data.to_row() can only take message payloads.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,8 +133,8 @@ mod tests {
|
|||||||
Data {
|
Data {
|
||||||
time_sent: Local::now().format("%c").to_string(),
|
time_sent: Local::now().format("%c").to_string(),
|
||||||
author: "human".to_string(),
|
author: "human".to_string(),
|
||||||
message: "beep boop".to_string(),
|
|
||||||
system: false,
|
system: false,
|
||||||
|
payload: PayLoad::Message("beep boop".to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
src/main.rs
12
src/main.rs
@ -1,3 +1,9 @@
|
|||||||
|
mod handlers;
|
||||||
|
mod terminal;
|
||||||
|
mod twitch;
|
||||||
|
mod ui;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
@ -9,12 +15,6 @@ use handlers::{
|
|||||||
|
|
||||||
use crate::handlers::app::App;
|
use crate::handlers::app::App;
|
||||||
|
|
||||||
mod handlers;
|
|
||||||
mod terminal;
|
|
||||||
mod twitch;
|
|
||||||
mod ui;
|
|
||||||
mod utils;
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
match CompleteConfig::new() {
|
match CompleteConfig::new() {
|
||||||
|
@ -18,7 +18,7 @@ use crate::{
|
|||||||
handlers::{
|
handlers::{
|
||||||
app::{App, BufferName, State},
|
app::{App, BufferName, State},
|
||||||
config::CompleteConfig,
|
config::CompleteConfig,
|
||||||
data::{Data, DataBuilder},
|
data::{Data, DataBuilder, PayLoad},
|
||||||
event::{Config, Event, Events, Key},
|
event::{Config, Event, Events, Key},
|
||||||
},
|
},
|
||||||
twitch::Action,
|
twitch::Action,
|
||||||
@ -96,24 +96,47 @@ pub async fn ui_driver(
|
|||||||
};
|
};
|
||||||
|
|
||||||
'outer: loop {
|
'outer: loop {
|
||||||
|
if let Ok(info) = rx.try_recv() {
|
||||||
|
match info.payload {
|
||||||
|
PayLoad::Message(_) => app.messages.push_front(info),
|
||||||
|
|
||||||
|
// If something such as a keypress failed, fallback to the normal state of the application.
|
||||||
|
PayLoad::Err(err) => {
|
||||||
|
app.state = State::Normal;
|
||||||
|
app.selected_buffer = BufferName::Chat;
|
||||||
|
|
||||||
|
app.messages.push_front(data_builder.system(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
terminal
|
terminal
|
||||||
.draw(|frame| draw_ui(frame, &mut app, &config))
|
.draw(|frame| draw_ui(frame, &mut app, &config))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
if let Ok(info) = rx.try_recv() {
|
|
||||||
app.messages.push_front(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(Event::Input(key)) = events.next().await {
|
if let Some(Event::Input(key)) = events.next().await {
|
||||||
match app.state {
|
match app.state {
|
||||||
State::Input | State::ChannelSwitch => {
|
State::Input | State::ChannelSwitch | State::Search => {
|
||||||
let input_buffer = app.get_buffer();
|
let input_buffer = app.current_buffer_mut();
|
||||||
|
|
||||||
match key {
|
match key {
|
||||||
Key::Up => {
|
Key::Up => match app.state {
|
||||||
if let State::Input = app.state {
|
State::Input => {
|
||||||
app.state = State::Normal;
|
app.state = State::Normal;
|
||||||
}
|
}
|
||||||
|
State::Search => {
|
||||||
|
if app.scroll_offset > 1 {
|
||||||
|
app.scroll_offset -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
Key::Down => {
|
||||||
|
if let State::Search = app.state {
|
||||||
|
if app.scroll_offset < app.messages_snapshot.len() {
|
||||||
|
app.scroll_offset += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Key::Ctrl('f') | Key::Right => {
|
Key::Ctrl('f') | Key::Right => {
|
||||||
input_buffer.move_forward(1);
|
input_buffer.move_forward(1);
|
||||||
@ -169,6 +192,7 @@ pub async fn ui_driver(
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
input_message.update("", 0);
|
input_message.update("", 0);
|
||||||
}
|
}
|
||||||
BufferName::Channel => {
|
BufferName::Channel => {
|
||||||
@ -184,11 +208,13 @@ pub async fn ui_driver(
|
|||||||
|
|
||||||
config.twitch.channel = input_message.to_string();
|
config.twitch.channel = input_message.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
input_message.update("", 0);
|
input_message.update("", 0);
|
||||||
|
|
||||||
app.selected_buffer = BufferName::Chat;
|
app.selected_buffer = BufferName::Chat;
|
||||||
app.state = State::Normal;
|
app.state = State::Normal;
|
||||||
}
|
}
|
||||||
|
BufferName::MessageSearch => {}
|
||||||
},
|
},
|
||||||
Key::Char(c) => {
|
Key::Char(c) => {
|
||||||
input_buffer.insert(c, 1);
|
input_buffer.insert(c, 1);
|
||||||
@ -205,12 +231,20 @@ pub async fn ui_driver(
|
|||||||
app.state = State::Normal;
|
app.state = State::Normal;
|
||||||
app.selected_buffer = BufferName::Chat;
|
app.selected_buffer = BufferName::Chat;
|
||||||
}
|
}
|
||||||
Key::Char('?') => app.state = State::Help,
|
|
||||||
Key::Char('i') => app.state = State::Input,
|
|
||||||
Key::Char('C') => {
|
Key::Char('C') => {
|
||||||
app.state = State::ChannelSwitch;
|
app.state = State::ChannelSwitch;
|
||||||
app.selected_buffer = BufferName::Channel;
|
app.selected_buffer = BufferName::Channel;
|
||||||
}
|
}
|
||||||
|
Key::Char('?') => app.state = State::Help,
|
||||||
|
Key::Char('i') => {
|
||||||
|
app.state = State::Input;
|
||||||
|
app.selected_buffer = BufferName::Chat;
|
||||||
|
}
|
||||||
|
Key::Char('s') => {
|
||||||
|
app.state = State::Search;
|
||||||
|
app.selected_buffer = BufferName::MessageSearch;
|
||||||
|
app.messages_snapshot = app.messages.clone();
|
||||||
|
}
|
||||||
Key::Char('q') => {
|
Key::Char('q') => {
|
||||||
quitting(terminal);
|
quitting(terminal);
|
||||||
break 'outer;
|
break 'outer;
|
||||||
@ -220,11 +254,10 @@ pub async fn ui_driver(
|
|||||||
quitting(terminal);
|
quitting(terminal);
|
||||||
break 'outer;
|
break 'outer;
|
||||||
}
|
}
|
||||||
State::ChannelSwitch => {
|
_ => {
|
||||||
app.selected_buffer = BufferName::Chat;
|
|
||||||
app.state = State::Normal;
|
app.state = State::Normal;
|
||||||
|
app.selected_buffer = BufferName::Chat;
|
||||||
}
|
}
|
||||||
_ => app.state = State::Normal,
|
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
|
@ -29,7 +29,9 @@ pub async fn twitch_irc(mut config: CompleteConfig, tx: Sender<Data>, mut rx: Re
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut client = Client::from_config(irc_config.clone()).await.unwrap();
|
let mut client = Client::from_config(irc_config.clone()).await.unwrap();
|
||||||
|
|
||||||
client.identify().unwrap();
|
client.identify().unwrap();
|
||||||
|
|
||||||
let mut stream = client.stream().unwrap();
|
let mut stream = client.stream().unwrap();
|
||||||
let data_builder = DataBuilder::new(&config.frontend.date_format);
|
let data_builder = DataBuilder::new(&config.frontend.date_format);
|
||||||
let mut room_state_startup = false;
|
let mut room_state_startup = false;
|
||||||
@ -57,17 +59,19 @@ pub async fn twitch_irc(mut config: CompleteConfig, tx: Sender<Data>, mut rx: Re
|
|||||||
biased;
|
biased;
|
||||||
|
|
||||||
Some(action) = rx.recv() => {
|
Some(action) = rx.recv() => {
|
||||||
|
let current_channel = format!("#{}", config.twitch.channel);
|
||||||
|
|
||||||
match action {
|
match action {
|
||||||
Action::Privmsg(message) => {
|
Action::Privmsg(message) => {
|
||||||
client
|
client
|
||||||
.send_privmsg(format!("#{}", config.twitch.channel), message)
|
.send_privmsg(current_channel, message)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
Action::Join(channel) => {
|
Action::Join(channel) => {
|
||||||
let channel_list = format!("#{}", channel);
|
let channel_list = format!("#{}", channel);
|
||||||
|
|
||||||
// Leave previous channel
|
// Leave previous channel
|
||||||
if let Err(err) = client.send_part(format!("#{}", config.twitch.channel)) {
|
if let Err(err) = client.send_part(current_channel) {
|
||||||
tx.send(data_builder.twitch(err.to_string())).await.unwrap()
|
tx.send(data_builder.twitch(err.to_string())).await.unwrap()
|
||||||
} else {
|
} else {
|
||||||
tx.send(data_builder.twitch(format!("Joined {}", channel_list))).await.unwrap();
|
tx.send(data_builder.twitch(format!("Joined {}", channel_list))).await.unwrap();
|
||||||
@ -85,7 +89,7 @@ pub async fn twitch_irc(mut config: CompleteConfig, tx: Sender<Data>, mut rx: Re
|
|||||||
}
|
}
|
||||||
Some(_message) = stream.next() => {
|
Some(_message) = stream.next() => {
|
||||||
if let Ok(message) = _message {
|
if let Ok(message) = _message {
|
||||||
let mut tags: HashMap<&str, &str> = std::collections::HashMap::new();
|
let mut tags: HashMap<&str, &str> = HashMap::new();
|
||||||
if let Some(ref _tags) = message.tags {
|
if let Some(ref _tags) = message.tags {
|
||||||
for tag in _tags {
|
for tag in _tags {
|
||||||
if let Some(ref tag_value) = tag.1 {
|
if let Some(ref tag_value) = tag.1 {
|
||||||
|
@ -8,7 +8,7 @@ use tui::{
|
|||||||
style::{Color, Modifier, Style},
|
style::{Color, Modifier, Style},
|
||||||
terminal::Frame,
|
terminal::Frame,
|
||||||
text::{Span, Spans},
|
text::{Span, Spans},
|
||||||
widgets::{Block, Borders, Clear, Paragraph, Row, Table},
|
widgets::{Block, Borders, Paragraph, Row, Table},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -16,10 +16,7 @@ use crate::{
|
|||||||
app::{App, State},
|
app::{App, State},
|
||||||
config::CompleteConfig,
|
config::CompleteConfig,
|
||||||
},
|
},
|
||||||
ui::{
|
ui::statics::COMMANDS,
|
||||||
popups::{centered_popup, Centering},
|
|
||||||
statics::COMMANDS,
|
|
||||||
},
|
|
||||||
utils::{styles, text::get_cursor_position},
|
utils::{styles, text::get_cursor_position},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -122,7 +119,7 @@ pub fn draw_ui<T: Backend>(frame: &mut Frame<T>, app: &mut App, config: &Complet
|
|||||||
|
|
||||||
match app.state {
|
match app.state {
|
||||||
State::Input => {
|
State::Input => {
|
||||||
let input_buffer = app.get_buffer();
|
let input_buffer = app.current_buffer();
|
||||||
|
|
||||||
if input_buffer.starts_with('/') {
|
if input_buffer.starts_with('/') {
|
||||||
let suggested_commands = COMMANDS
|
let suggested_commands = COMMANDS
|
||||||
@ -165,31 +162,9 @@ pub fn draw_ui<T: Backend>(frame: &mut Frame<T>, app: &mut App, config: &Complet
|
|||||||
vertical_chunks[vertical_chunk_constraints.len() - 1],
|
vertical_chunks[vertical_chunk_constraints.len() - 1],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
State::Help => popups::help::keybinds(frame),
|
State::Help => popups::help::show_keybinds(frame),
|
||||||
State::ChannelSwitch => {
|
State::ChannelSwitch => popups::channels::switch_channels(frame, app),
|
||||||
let input_rect = centered_popup(Centering::Input(30, 10), frame.size());
|
State::Search => popups::messages::search_messages(frame, app),
|
||||||
|
_ => {}
|
||||||
let input_buffer = app.get_buffer();
|
|
||||||
|
|
||||||
let cursor_pos = get_cursor_position(input_buffer);
|
|
||||||
|
|
||||||
frame.set_cursor(
|
|
||||||
(input_rect.x + cursor_pos as u16 + 1)
|
|
||||||
.min(input_rect.x + input_rect.width.saturating_sub(2)),
|
|
||||||
input_rect.y + 1,
|
|
||||||
);
|
|
||||||
|
|
||||||
let paragraph = Paragraph::new(input_buffer.as_str())
|
|
||||||
.style(Style::default().fg(Color::Yellow))
|
|
||||||
.block(Block::default().borders(Borders::ALL).title("[ Channel ]"))
|
|
||||||
.scroll((
|
|
||||||
0,
|
|
||||||
((cursor_pos + 3) as u16).saturating_sub(input_rect.width),
|
|
||||||
));
|
|
||||||
|
|
||||||
frame.render_widget(Clear, input_rect);
|
|
||||||
frame.render_widget(paragraph, input_rect);
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
37
src/ui/popups/channels.rs
Normal file
37
src/ui/popups/channels.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
use tui::{
|
||||||
|
backend::Backend,
|
||||||
|
style::{Color, Style},
|
||||||
|
terminal::Frame,
|
||||||
|
widgets::{Block, Borders, Clear, Paragraph},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
handlers::app::App,
|
||||||
|
ui::popups::{centered_popup, WindowType},
|
||||||
|
utils::text::get_cursor_position,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn switch_channels<T: Backend>(frame: &mut Frame<T>, app: &mut App) {
|
||||||
|
let input_rect = centered_popup(WindowType::Input(frame.size().height), frame.size());
|
||||||
|
|
||||||
|
let input_buffer = app.current_buffer();
|
||||||
|
|
||||||
|
let cursor_pos = get_cursor_position(input_buffer);
|
||||||
|
|
||||||
|
frame.set_cursor(
|
||||||
|
(input_rect.x + cursor_pos as u16 + 1)
|
||||||
|
.min(input_rect.x + input_rect.width.saturating_sub(2)),
|
||||||
|
input_rect.y + 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
let paragraph = Paragraph::new(input_buffer.as_str())
|
||||||
|
.style(Style::default().fg(Color::Yellow))
|
||||||
|
.block(Block::default().borders(Borders::ALL).title("[ Channel ]"))
|
||||||
|
.scroll((
|
||||||
|
0,
|
||||||
|
((cursor_pos + 3) as u16).saturating_sub(input_rect.width),
|
||||||
|
));
|
||||||
|
|
||||||
|
frame.render_widget(Clear, input_rect);
|
||||||
|
frame.render_widget(paragraph, input_rect);
|
||||||
|
}
|
@ -7,13 +7,13 @@ use tui::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ui::{
|
ui::{
|
||||||
popups::{centered_popup, Centering},
|
popups::{centered_popup, Centering, WindowType},
|
||||||
statics::{HELP_COLUMN_TITLES, HELP_KEYBINDS},
|
statics::{HELP_COLUMN_TITLES, HELP_KEYBINDS},
|
||||||
},
|
},
|
||||||
utils::{styles, text::vector_column_max},
|
utils::{styles, text::vector_column_max},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn keybinds<T: Backend>(frame: &mut Frame<T>) {
|
pub fn show_keybinds<T: Backend>(frame: &mut Frame<T>) {
|
||||||
let table_widths = vector_column_max(&HELP_KEYBINDS, None)
|
let table_widths = vector_column_max(&HELP_KEYBINDS, None)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Constraint::Min)
|
.map(Constraint::Min)
|
||||||
@ -26,7 +26,13 @@ pub fn keybinds<T: Backend>(frame: &mut Frame<T>) {
|
|||||||
.column_spacing(2)
|
.column_spacing(2)
|
||||||
.style(styles::BORDER_NAME);
|
.style(styles::BORDER_NAME);
|
||||||
|
|
||||||
let area = centered_popup(Centering::Window(60, 50), frame.size());
|
let area = centered_popup(
|
||||||
|
WindowType::Window(
|
||||||
|
Centering::Middle(frame.size().height),
|
||||||
|
HELP_KEYBINDS.len() as u16,
|
||||||
|
),
|
||||||
|
frame.size(),
|
||||||
|
);
|
||||||
|
|
||||||
frame.render_widget(Clear, area);
|
frame.render_widget(Clear, area);
|
||||||
frame.render_widget(help_table, area);
|
frame.render_widget(help_table, area);
|
||||||
|
142
src/ui/popups/messages.rs
Normal file
142
src/ui/popups/messages.rs
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
|
use tui::{
|
||||||
|
backend::Backend,
|
||||||
|
layout::Constraint,
|
||||||
|
style::{Color, Modifier, Style},
|
||||||
|
terminal::Frame,
|
||||||
|
text::{Span, Spans},
|
||||||
|
widgets::{Block, Borders, Clear, Paragraph, Row, Table},
|
||||||
|
};
|
||||||
|
|
||||||
|
use fuzzy_matcher::skim::SkimMatcherV2;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
handlers::{app::App, data::PayLoad},
|
||||||
|
ui::popups::{centered_popup, scroll_view, Centering, WindowType},
|
||||||
|
utils::{styles, text::get_cursor_position},
|
||||||
|
};
|
||||||
|
use fuzzy_matcher::FuzzyMatcher;
|
||||||
|
|
||||||
|
const MAX_MESSAGE_SEARCH: u16 = 10;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref FUZZY_FINDER: SkimMatcherV2 = SkimMatcherV2::default();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn search_messages<T: Backend>(frame: &mut Frame<T>, app: &mut App) {
|
||||||
|
let input_rect = centered_popup(WindowType::Input(frame.size().height), frame.size());
|
||||||
|
let window_rect = centered_popup(
|
||||||
|
WindowType::Window(Centering::Height(frame.size().height), MAX_MESSAGE_SEARCH),
|
||||||
|
frame.size(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let input_buffer = app.current_buffer();
|
||||||
|
|
||||||
|
let cursor_pos = get_cursor_position(input_buffer);
|
||||||
|
|
||||||
|
frame.set_cursor(
|
||||||
|
(input_rect.x + cursor_pos as u16 + 1)
|
||||||
|
.min(input_rect.x + input_rect.width.saturating_sub(2)),
|
||||||
|
input_rect.y + 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
let input_text = &input_buffer.as_str();
|
||||||
|
|
||||||
|
let input_paragraph = Paragraph::new(*input_text)
|
||||||
|
.style(Style::default().fg(Color::Yellow))
|
||||||
|
.block(
|
||||||
|
Block::default()
|
||||||
|
.borders(Borders::ALL)
|
||||||
|
.title("[ Message Search ]"),
|
||||||
|
)
|
||||||
|
.scroll((
|
||||||
|
0,
|
||||||
|
((cursor_pos + 3) as u16).saturating_sub(input_rect.width),
|
||||||
|
));
|
||||||
|
|
||||||
|
frame.render_widget(Clear, input_rect);
|
||||||
|
frame.render_widget(input_paragraph, input_rect);
|
||||||
|
|
||||||
|
let all_messages = app
|
||||||
|
.messages_snapshot
|
||||||
|
.iter()
|
||||||
|
.flat_map(|f| match &f.payload {
|
||||||
|
PayLoad::Message(m) => Some(m.as_str()),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<VecDeque<&str>>();
|
||||||
|
|
||||||
|
if all_messages.is_empty() {
|
||||||
|
let window_paragraph = Table::new(vec![])
|
||||||
|
.block(Block::default().borders(Borders::ALL).title("[ Results ]"))
|
||||||
|
.column_spacing(2)
|
||||||
|
.style(styles::BORDER_NAME);
|
||||||
|
|
||||||
|
frame.render_widget(Clear, window_rect);
|
||||||
|
frame.render_widget(window_paragraph, window_rect);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let maximum_message_length = *all_messages
|
||||||
|
.iter()
|
||||||
|
.map(|v| v.len())
|
||||||
|
.collect::<Vec<usize>>()
|
||||||
|
.iter()
|
||||||
|
.max()
|
||||||
|
.unwrap() as u16;
|
||||||
|
|
||||||
|
let table_widths = all_messages
|
||||||
|
.iter()
|
||||||
|
.map(|_| Constraint::Min(maximum_message_length))
|
||||||
|
.collect::<Vec<Constraint>>();
|
||||||
|
|
||||||
|
let render_messages = scroll_view(all_messages, app.scroll_offset, MAX_MESSAGE_SEARCH as usize);
|
||||||
|
|
||||||
|
let rows = if input_text.is_empty() {
|
||||||
|
render_messages
|
||||||
|
.iter()
|
||||||
|
.map(|&v| Row::new(vec![v]))
|
||||||
|
.collect::<Vec<Row>>()
|
||||||
|
} else {
|
||||||
|
render_messages
|
||||||
|
.iter()
|
||||||
|
.flat_map(|&f| {
|
||||||
|
let chars = f.chars();
|
||||||
|
|
||||||
|
if let Some((_, indices)) = FUZZY_FINDER.fuzzy_indices(f, input_text) {
|
||||||
|
Some(Row::new(vec![Spans::from(
|
||||||
|
chars
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, s)| {
|
||||||
|
if indices.contains(&i) {
|
||||||
|
Span::styled(
|
||||||
|
s.to_string(),
|
||||||
|
Style::default()
|
||||||
|
.fg(Color::Red)
|
||||||
|
.add_modifier(Modifier::BOLD),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Span::raw(s.to_string())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<Span>>(),
|
||||||
|
)]))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<Row>>()
|
||||||
|
};
|
||||||
|
|
||||||
|
let window_paragraph = Table::new(rows)
|
||||||
|
.block(Block::default().borders(Borders::ALL).title("[ Results ]"))
|
||||||
|
.column_spacing(2)
|
||||||
|
.widths(&table_widths)
|
||||||
|
.style(styles::BORDER_NAME);
|
||||||
|
|
||||||
|
frame.render_widget(Clear, window_rect);
|
||||||
|
frame.render_widget(window_paragraph, window_rect);
|
||||||
|
}
|
@ -1,47 +1,40 @@
|
|||||||
|
pub mod channels;
|
||||||
pub mod help;
|
pub mod help;
|
||||||
|
pub mod messages;
|
||||||
|
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use tui::layout::{Constraint, Direction, Layout, Rect};
|
use tui::layout::{Constraint, Direction, Layout, Rect};
|
||||||
|
|
||||||
|
const HORIZONTAL_CONSTRAINTS: [Constraint; 3] = [
|
||||||
|
Constraint::Percentage(15),
|
||||||
|
Constraint::Percentage(70),
|
||||||
|
Constraint::Percentage(15),
|
||||||
|
];
|
||||||
|
|
||||||
pub enum Centering {
|
pub enum Centering {
|
||||||
Input(u16, u16),
|
Height(u16),
|
||||||
Window(u16, u16),
|
Middle(u16),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn centered_popup(c: Centering, size: Rect) -> Rect {
|
pub enum WindowType {
|
||||||
|
/// An input window, with the integer representing the height of the terminal
|
||||||
|
Input(u16),
|
||||||
|
/// A window containing either some specified terminal height, or in the middle,
|
||||||
|
/// with an integer describing the amount of vertically stored items
|
||||||
|
Window(Centering, u16),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn centered_popup(c: WindowType, size: Rect) -> Rect {
|
||||||
match c {
|
match c {
|
||||||
Centering::Window(percent_x, percent_y) => {
|
WindowType::Input(v) => {
|
||||||
let popup_layout = Layout::default()
|
let popup_layout = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.constraints(
|
.constraints(
|
||||||
[
|
[
|
||||||
Constraint::Percentage((100 - percent_y) / 2),
|
Constraint::Length((v / 2) as u16 - 6),
|
||||||
Constraint::Percentage(percent_y),
|
|
||||||
Constraint::Percentage((100 - percent_y) / 2),
|
|
||||||
]
|
|
||||||
.as_ref(),
|
|
||||||
)
|
|
||||||
.split(size);
|
|
||||||
|
|
||||||
Layout::default()
|
|
||||||
.direction(Direction::Horizontal)
|
|
||||||
.constraints(
|
|
||||||
[
|
|
||||||
Constraint::Percentage((100 - percent_x) / 2),
|
|
||||||
Constraint::Percentage(percent_x),
|
|
||||||
Constraint::Percentage((100 - percent_x) / 2),
|
|
||||||
]
|
|
||||||
.as_ref(),
|
|
||||||
)
|
|
||||||
.split(popup_layout[1])[1]
|
|
||||||
}
|
|
||||||
Centering::Input(percent_x, percent_y) => {
|
|
||||||
let popup_layout = Layout::default()
|
|
||||||
.direction(Direction::Vertical)
|
|
||||||
.constraints(
|
|
||||||
[
|
|
||||||
Constraint::Percentage((100 - percent_y) / 2),
|
|
||||||
Constraint::Length(3),
|
Constraint::Length(3),
|
||||||
Constraint::Percentage((100 - percent_y) / 2),
|
Constraint::Min(0),
|
||||||
]
|
]
|
||||||
.as_ref(),
|
.as_ref(),
|
||||||
)
|
)
|
||||||
@ -49,15 +42,113 @@ pub fn centered_popup(c: Centering, size: Rect) -> Rect {
|
|||||||
|
|
||||||
Layout::default()
|
Layout::default()
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
.constraints(
|
.constraints(HORIZONTAL_CONSTRAINTS.as_ref())
|
||||||
[
|
.split(popup_layout[1])[1]
|
||||||
Constraint::Percentage((100 - percent_x) / 2),
|
}
|
||||||
Constraint::Percentage(percent_x),
|
WindowType::Window(v, i) => {
|
||||||
Constraint::Percentage((100 - percent_x) / 2),
|
let popup_layout = Layout::default()
|
||||||
]
|
.direction(Direction::Vertical)
|
||||||
.as_ref(),
|
.constraints([
|
||||||
)
|
Constraint::Length(match v {
|
||||||
|
Centering::Height(terminal_height) => (terminal_height / 2) as u16 - 3,
|
||||||
|
Centering::Middle(terminal_height) => ((terminal_height - i) / 2) as u16,
|
||||||
|
}),
|
||||||
|
Constraint::Length(i),
|
||||||
|
match v {
|
||||||
|
Centering::Height(_) => Constraint::Min(0),
|
||||||
|
Centering::Middle(terminal_height) => {
|
||||||
|
Constraint::Length(((terminal_height - i) / 2) as u16 - 3)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.split(size);
|
||||||
|
|
||||||
|
Layout::default()
|
||||||
|
.direction(Direction::Horizontal)
|
||||||
|
.constraints(HORIZONTAL_CONSTRAINTS.as_ref())
|
||||||
.split(popup_layout[1])[1]
|
.split(popup_layout[1])[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn scroll_view<T: std::marker::Copy>(
|
||||||
|
v: VecDeque<T>,
|
||||||
|
offset: usize,
|
||||||
|
amount: usize,
|
||||||
|
) -> VecDeque<T> {
|
||||||
|
if offset > v.len() {
|
||||||
|
panic!(
|
||||||
|
"Scroll offset is {}, but length of VecDeque is {}.",
|
||||||
|
offset,
|
||||||
|
v.len()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// If the offset is at 0 or at the bottom of the input, then there's no need to move.
|
||||||
|
else if (offset == 0 && amount == v.len()) || v.is_empty() {
|
||||||
|
v
|
||||||
|
}
|
||||||
|
// If there's no amount specified, return everything behind and including the offset index values,
|
||||||
|
// or when the offset and the amount wanted goes over the length of the VecDeque.
|
||||||
|
else if amount == 0 || offset + amount > v.len() {
|
||||||
|
v.range(offset..).copied().collect::<VecDeque<T>>()
|
||||||
|
} else {
|
||||||
|
v.range(offset..offset + amount)
|
||||||
|
.copied()
|
||||||
|
.collect::<VecDeque<T>>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
fn setup() -> VecDeque<i32> {
|
||||||
|
VecDeque::from([1, 2, 3, 4, 5])
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "Scroll offset is 10, but length of VecDeque is 5.")]
|
||||||
|
fn test_offset_plus_amount_over_length() {
|
||||||
|
scroll_view(setup(), 10, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "Scroll offset is 3, but length of VecDeque is 0.")]
|
||||||
|
fn test_zero_length_input_some_offset() {
|
||||||
|
scroll_view(vec![].iter().copied().collect::<VecDeque<i32>>(), 3, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_zero_length_input_no_offset() {
|
||||||
|
let empty_deq: VecDeque<i32> = scroll_view(VecDeque::from([]), 0, 3);
|
||||||
|
|
||||||
|
assert_eq!(empty_deq, VecDeque::from([]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_no_offset_no_amount() {
|
||||||
|
let empty_deq: VecDeque<i32> = scroll_view(VecDeque::from([]), 0, 0);
|
||||||
|
|
||||||
|
assert_eq!(empty_deq, VecDeque::from([]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_offset_1_all_elements() {
|
||||||
|
assert_eq!(scroll_view(setup(), 1, 0), VecDeque::from([2, 3, 4, 5]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_no_offset_some_amount() {
|
||||||
|
assert_eq!(scroll_view(setup(), 0, 3), VecDeque::from([1, 2, 3]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_some_offset_some_amount() {
|
||||||
|
assert_eq!(scroll_view(setup(), 2, 2), VecDeque::from([3, 4]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_offset_and_amount_centered() {
|
||||||
|
assert_eq!(scroll_view(setup(), 1, 3), VecDeque::from([2, 3, 4]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user