Updated dependencies; migrated tui-realm to 0.6.0
This commit is contained in:
parent
1558f4ffe4
commit
d15997cca0
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -22,7 +22,17 @@
|
|||
|
||||
## 0.6.1
|
||||
|
||||
Released on ??
|
||||
|
||||
- Enhancements:
|
||||
- Now that tui-rs supports title alignment, UI has been improved
|
||||
- Dependencies:
|
||||
- Updated `bitflags` to `1.3.2`
|
||||
- Updated `bytesize` to `1.1.0`
|
||||
- Updated `crossterm` to `0.20`
|
||||
- Updated `open` to `2.0.1`
|
||||
- Added `tui-realm-stdlib 0.6.0`
|
||||
- Updated `tui-realm` to `0.6.0`
|
||||
|
||||
## 0.6.0
|
||||
|
||||
|
|
176
Cargo.lock
generated
176
Cargo.lock
generated
|
@ -94,9 +94,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
|
@ -138,9 +138,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
|||
|
||||
[[package]]
|
||||
name = "bytesize"
|
||||
version = "1.0.1"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81a18687293a1546b67c246452202bbbf143d239cb43494cc163da14979082da"
|
||||
checksum = "6c58ec36aac5066d5ca17df51b3e70279f5670a72102f5752cb7e7c856adfc70"
|
||||
|
||||
[[package]]
|
||||
name = "cassowary"
|
||||
|
@ -150,9 +150,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.68"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
|
||||
checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
|
@ -264,34 +264,34 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.19.0"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c36c10130df424b2f3552fcc2ddcd9b28a27b1e54b358b45874f88d1ca6888c"
|
||||
checksum = "c0ebde6a9dd5e331cd6c6f48253254d117642c31653baa475e394657c59c1f7d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crossterm_winapi",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot 0.11.1",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm_winapi"
|
||||
version = "0.7.0"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0da8964ace4d3e4a044fd027919b2237000b24315a37c916f61809f1ff2140b9"
|
||||
checksum = "3a6966607622438301997d3dac0d2f6e9a90c68bb6bc1785ea98456ab93c0507"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-mac"
|
||||
version = "0.10.0"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6"
|
||||
checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"subtle",
|
||||
|
@ -506,9 +506,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.9"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
|
||||
checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
@ -521,9 +521,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
|||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.51"
|
||||
version = "0.3.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
|
||||
checksum = "ce791b7ca6638aae45be056e068fc756d871eb3b3b10b8efa62d1c9cec616752"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
@ -548,9 +548,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.98"
|
||||
version = "0.2.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
||||
checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765"
|
||||
|
||||
[[package]]
|
||||
name = "libssh2-sys"
|
||||
|
@ -630,9 +630,9 @@ checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
|
|||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.8"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
|
||||
[[package]]
|
||||
name = "md-5"
|
||||
|
@ -675,9 +675,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.7"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8d96b2e1c8da3957d58100b09f102c6d9cfdfced01b7ec5a8974044bb09dbd4"
|
||||
checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
|
@ -790,11 +790,11 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
|||
|
||||
[[package]]
|
||||
name = "open"
|
||||
version = "1.7.0"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1711eb4b31ce4ad35b0f316d8dfba4fe5c7ad601c448446d84aae7a896627b20"
|
||||
checksum = "b46b233de7d83bc167fe43ae2dda3b5b84e80e09cceba581e4decb958a4896bf"
|
||||
dependencies = [
|
||||
"which",
|
||||
"pathdiff",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
|
@ -884,7 +884,7 @@ dependencies = [
|
|||
"cfg-if 1.0.0",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall 0.2.9",
|
||||
"redox_syscall 0.2.10",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
@ -895,6 +895,12 @@ version = "0.1.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cacbb3c4ff353b534a67fb8d7524d00229da4cb1dc8c79f4db96e375ab5b619"
|
||||
|
||||
[[package]]
|
||||
name = "pathdiff"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877630b3de15c0b64cc52f659345724fbf6bdad9bd9566699fc53688f3c34a34"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
|
@ -927,9 +933,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.27"
|
||||
version = "1.0.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
||||
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
@ -1032,9 +1038,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
|||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee"
|
||||
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
@ -1046,7 +1052,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
|
||||
dependencies = [
|
||||
"getrandom 0.2.3",
|
||||
"redox_syscall 0.2.9",
|
||||
"redox_syscall 0.2.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1209,18 +1215,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.126"
|
||||
version = "1.0.127"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
|
||||
checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.126"
|
||||
version = "1.0.127"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
|
||||
checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1229,9 +1235,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.64"
|
||||
version = "1.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
||||
checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -1253,13 +1259,23 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.1.17"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e31d442c16f047a671b5a71e2161d6e68814012b7f5379d269ebd915fac2729"
|
||||
checksum = "470c5a6397076fae0094aaf06a08e6ba6f37acb77d3b1b91ea92b4d6c8650c39"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-mio"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29fd5867f1c4f2c5be079aee7a2adf1152ebb04a4bc4d341f504b7dece607ed4"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"signal-hook-registry",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1314,15 +1330,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.4.0"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2"
|
||||
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.73"
|
||||
version = "1.0.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
|
||||
checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1338,7 +1354,7 @@ dependencies = [
|
|||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"rand 0.8.4",
|
||||
"redox_syscall 0.2.9",
|
||||
"redox_syscall 0.2.10",
|
||||
"remove_dir_all",
|
||||
"winapi",
|
||||
]
|
||||
|
@ -1383,6 +1399,7 @@ dependencies = [
|
|||
"textwrap",
|
||||
"thiserror",
|
||||
"toml",
|
||||
"tui-realm-stdlib",
|
||||
"tuirealm",
|
||||
"ureq",
|
||||
"users",
|
||||
|
@ -1445,9 +1462,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.2.0"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342"
|
||||
checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
@ -1469,9 +1486,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tui"
|
||||
version = "0.15.0"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "861d8f3ad314ede6219bcb2ab844054b1de279ee37a9bc38e3d606f9d3fb2a71"
|
||||
checksum = "39c8ce4e27049eed97cfa363a5048b09d995e209994634a0efc26a14ab6c0c23"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cassowary",
|
||||
|
@ -1481,15 +1498,24 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "tuirealm"
|
||||
version = "0.4.3"
|
||||
name = "tui-realm-stdlib"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fcbd06f2aa6a2424aaa245c10e8767fe3f0fee234ac8c144cb15eaf2ee37ce9"
|
||||
checksum = "6bff91e1cdc741a7487d8cb20ac038e5ba926a0ec97b0f2ea918ac75640b9da5"
|
||||
dependencies = [
|
||||
"textwrap",
|
||||
"tuirealm",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tuirealm"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "634ad8e6a4b80ef032d31356b55964a995da5d05a9cf3a1bd134bae1ba7c197a"
|
||||
dependencies = [
|
||||
"crossterm",
|
||||
"textwrap",
|
||||
"tui",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1500,18 +1526,15 @@ checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
|
|||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.5"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0"
|
||||
dependencies = [
|
||||
"matches",
|
||||
]
|
||||
checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-linebreak"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05a31f45d18a3213b918019f78fe6a73a14ab896807f0aaf5622aa0684749455"
|
||||
checksum = "3a52dcaab0c48d931f7cc8ef826fa51690a08e1ea55117ef26f89864f532383f"
|
||||
dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
@ -1615,9 +1638,9 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.74"
|
||||
version = "0.2.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
|
||||
checksum = "b608ecc8f4198fe8680e2ed18eccab5f0cd4caaf3d83516fa5fb2e927fda2586"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
|
@ -1625,9 +1648,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.74"
|
||||
version = "0.2.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
|
||||
checksum = "580aa3a91a63d23aac5b6b267e2d13cb4f363e31dce6c352fca4752ae12e479f"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
|
@ -1640,9 +1663,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.74"
|
||||
version = "0.2.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
|
||||
checksum = "171ebf0ed9e1458810dfcb31f2e766ad6b3a89dbda42d8901f2b268277e5f09c"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
|
@ -1650,9 +1673,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.74"
|
||||
version = "0.2.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
|
||||
checksum = "6c2657dd393f03aa2a659c25c6ae18a13a4048cebd220e147933ea837efc589f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1663,15 +1686,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.74"
|
||||
version = "0.2.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
|
||||
checksum = "2e0c4a743a309662d45f4ede961d7afa4ba4131a59a639f29b0069c3798bbcc2"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.51"
|
||||
version = "0.3.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582"
|
||||
checksum = "01c70a82d842c9979078c772d4a1344685045f1a5628f677c2b2eab4dd7d2696"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
@ -1698,11 +1721,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.1.0"
|
||||
version = "4.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b55551e42cbdf2ce2bedd2203d0cc08dba002c27510f86dab6d0ce304cba3dfe"
|
||||
checksum = "ea187a8ef279bc014ec368c27a920da2024d2a711109bfbe3440585d5cf27ad9"
|
||||
dependencies = [
|
||||
"either",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
]
|
||||
|
||||
|
|
11
Cargo.toml
11
Cargo.toml
|
@ -28,11 +28,11 @@ path = "src/main.rs"
|
|||
|
||||
[dependencies]
|
||||
argh = "0.1.5"
|
||||
bitflags = "1.2.1"
|
||||
bytesize = "1.0.1"
|
||||
bitflags = "1.3.2"
|
||||
bytesize = "1.1.0"
|
||||
chrono = "0.4.19"
|
||||
content_inspector = "0.2.4"
|
||||
crossterm = "0.19.0"
|
||||
crossterm = "0.20"
|
||||
dirs = "3.0.1"
|
||||
edit = "0.1.3"
|
||||
ftp4 = { version = "4.0.2", features = [ "secure" ] }
|
||||
|
@ -41,7 +41,7 @@ keyring = { version = "0.10.1", optional = true }
|
|||
lazy_static = "1.4.0"
|
||||
log = "0.4.14"
|
||||
magic-crypt = "3.1.7"
|
||||
open = "1.7.0"
|
||||
open = "2.0.1"
|
||||
rand = "0.8.4"
|
||||
regex = "1.5.4"
|
||||
rpassword = "5.0.1"
|
||||
|
@ -52,7 +52,8 @@ tempfile = "3.1.0"
|
|||
textwrap = "0.14.2"
|
||||
thiserror = "^1.0.0"
|
||||
toml = "0.5.8"
|
||||
tuirealm = { version = "0.4.3", features = [ "with-components" ] }
|
||||
tui-realm-stdlib = "0.6.0"
|
||||
tuirealm = "0.6.0"
|
||||
ureq = { version = "2.1.0", features = [ "json" ] }
|
||||
whoami = "1.1.1"
|
||||
wildmatch = "2.0.0"
|
||||
|
|
|
@ -56,6 +56,7 @@ extern crate regex;
|
|||
extern crate ssh2;
|
||||
extern crate tempfile;
|
||||
extern crate textwrap;
|
||||
extern crate tui_realm_stdlib;
|
||||
extern crate tuirealm;
|
||||
extern crate ureq;
|
||||
#[cfg(target_family = "unix")]
|
||||
|
|
|
@ -32,7 +32,7 @@ use crate::system::environment;
|
|||
|
||||
// Ext
|
||||
use std::path::PathBuf;
|
||||
use tuirealm::components::{input::InputPropsBuilder, radio::RadioPropsBuilder};
|
||||
use tui_realm_stdlib::{input::InputPropsBuilder, radio::RadioPropsBuilder};
|
||||
use tuirealm::{Payload, PropsBuilder, Value};
|
||||
|
||||
impl AuthActivity {
|
||||
|
|
|
@ -35,7 +35,7 @@ use super::{
|
|||
COMPONENT_TEXT_HELP, COMPONENT_TEXT_NEW_VERSION_NOTES, COMPONENT_TEXT_SIZE_ERR,
|
||||
};
|
||||
use crate::ui::keymap::*;
|
||||
use tuirealm::components::InputPropsBuilder;
|
||||
use tui_realm_stdlib::InputPropsBuilder;
|
||||
use tuirealm::{Msg, Payload, PropsBuilder, Update, Value};
|
||||
|
||||
// -- update
|
||||
|
@ -52,53 +52,53 @@ impl Update for AuthActivity {
|
|||
None => None, // Exit after None
|
||||
Some(msg) => match msg {
|
||||
// Focus ( DOWN )
|
||||
(COMPONENT_RADIO_PROTOCOL, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_RADIO_PROTOCOL, key) if key == &MSG_KEY_DOWN => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_ADDR);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_ADDR, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_INPUT_ADDR, key) if key == &MSG_KEY_DOWN => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_PORT);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_PORT, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_INPUT_PORT, key) if key == &MSG_KEY_DOWN => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_USERNAME);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_USERNAME, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_INPUT_USERNAME, key) if key == &MSG_KEY_DOWN => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_PASSWORD);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_PASSWORD, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_INPUT_PASSWORD, key) if key == &MSG_KEY_DOWN => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_RADIO_PROTOCOL);
|
||||
None
|
||||
}
|
||||
// Focus ( UP )
|
||||
(COMPONENT_INPUT_PASSWORD, &MSG_KEY_UP) => {
|
||||
(COMPONENT_INPUT_PASSWORD, key) if key == &MSG_KEY_UP => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_USERNAME);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_USERNAME, &MSG_KEY_UP) => {
|
||||
(COMPONENT_INPUT_USERNAME, key) if key == &MSG_KEY_UP => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_PORT);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_PORT, &MSG_KEY_UP) => {
|
||||
(COMPONENT_INPUT_PORT, key) if key == &MSG_KEY_UP => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_ADDR);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_ADDR, &MSG_KEY_UP) => {
|
||||
(COMPONENT_INPUT_ADDR, key) if key == &MSG_KEY_UP => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_RADIO_PROTOCOL);
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_PROTOCOL, &MSG_KEY_UP) => {
|
||||
(COMPONENT_RADIO_PROTOCOL, key) if key == &MSG_KEY_UP => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_PASSWORD);
|
||||
None
|
||||
|
@ -118,25 +118,25 @@ impl Update for AuthActivity {
|
|||
}
|
||||
// Bookmarks commands
|
||||
// <RIGHT> / <LEFT>
|
||||
(COMPONENT_BOOKMARKS_LIST, &MSG_KEY_RIGHT) => {
|
||||
(COMPONENT_BOOKMARKS_LIST, key) if key == &MSG_KEY_RIGHT => {
|
||||
// Give focus to recents
|
||||
self.view.active(COMPONENT_RECENTS_LIST);
|
||||
None
|
||||
}
|
||||
(COMPONENT_RECENTS_LIST, &MSG_KEY_LEFT) => {
|
||||
(COMPONENT_RECENTS_LIST, key) if key == &MSG_KEY_LEFT => {
|
||||
// Give focus to bookmarks
|
||||
self.view.active(COMPONENT_BOOKMARKS_LIST);
|
||||
None
|
||||
}
|
||||
// <DEL | 'E'>
|
||||
(COMPONENT_BOOKMARKS_LIST, &MSG_KEY_DEL)
|
||||
| (COMPONENT_BOOKMARKS_LIST, &MSG_KEY_CHAR_E) => {
|
||||
(COMPONENT_BOOKMARKS_LIST, key)
|
||||
if key == &MSG_KEY_DEL || key == &MSG_KEY_CHAR_E =>
|
||||
{
|
||||
// Show delete popup
|
||||
self.mount_bookmark_del_dialog();
|
||||
None
|
||||
}
|
||||
(COMPONENT_RECENTS_LIST, &MSG_KEY_DEL)
|
||||
| (COMPONENT_RECENTS_LIST, &MSG_KEY_CHAR_E) => {
|
||||
(COMPONENT_RECENTS_LIST, key) if key == &MSG_KEY_DEL || key == &MSG_KEY_CHAR_E => {
|
||||
// Show delete popup
|
||||
self.mount_recent_del_dialog();
|
||||
None
|
||||
|
@ -203,67 +203,68 @@ impl Update for AuthActivity {
|
|||
}
|
||||
}
|
||||
// <ESC> hide tab
|
||||
(COMPONENT_RADIO_BOOKMARK_DEL_RECENT, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_RADIO_BOOKMARK_DEL_RECENT, key) if key == &MSG_KEY_ESC => {
|
||||
self.umount_recent_del_dialog();
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_BOOKMARK_DEL_RECENT, _) => None,
|
||||
(COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK, key) if key == &MSG_KEY_ESC => {
|
||||
self.umount_bookmark_del_dialog();
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK, _) => None,
|
||||
// Error message
|
||||
(COMPONENT_TEXT_ERROR, &MSG_KEY_ENTER) | (COMPONENT_TEXT_ERROR, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_TEXT_ERROR, key) if key == &MSG_KEY_ESC || key == &MSG_KEY_ENTER => {
|
||||
// Umount text error
|
||||
self.umount_error();
|
||||
None
|
||||
}
|
||||
(COMPONENT_TEXT_ERROR, _) => None,
|
||||
(COMPONENT_TEXT_NEW_VERSION_NOTES, &MSG_KEY_ESC)
|
||||
| (COMPONENT_TEXT_NEW_VERSION_NOTES, &MSG_KEY_ENTER) => {
|
||||
(COMPONENT_TEXT_NEW_VERSION_NOTES, key)
|
||||
if key == &MSG_KEY_ESC || key == &MSG_KEY_ENTER =>
|
||||
{
|
||||
// Umount release notes
|
||||
self.umount_release_notes();
|
||||
None
|
||||
}
|
||||
(COMPONENT_TEXT_NEW_VERSION_NOTES, _) => None,
|
||||
// Help
|
||||
(_, &MSG_KEY_CTRL_H) => {
|
||||
(_, key) if key == &MSG_KEY_CTRL_H => {
|
||||
// Show help
|
||||
self.mount_help();
|
||||
None
|
||||
}
|
||||
// Release notes
|
||||
(_, &MSG_KEY_CTRL_R) => {
|
||||
(_, key) if key == &MSG_KEY_CTRL_R => {
|
||||
// Show release notes
|
||||
self.mount_release_notes();
|
||||
None
|
||||
}
|
||||
(COMPONENT_TEXT_HELP, &MSG_KEY_ENTER) | (COMPONENT_TEXT_HELP, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_TEXT_HELP, key) if key == &MSG_KEY_ESC || key == &MSG_KEY_ENTER => {
|
||||
// Hide text help
|
||||
self.umount_help();
|
||||
None
|
||||
}
|
||||
(COMPONENT_TEXT_HELP, _) => None,
|
||||
// Enter setup
|
||||
(_, &MSG_KEY_CTRL_C) => {
|
||||
(_, key) if key == &MSG_KEY_CTRL_C => {
|
||||
self.exit_reason = Some(super::ExitReason::EnterSetup);
|
||||
None
|
||||
}
|
||||
// Save bookmark; show popup
|
||||
(_, &MSG_KEY_CTRL_S) => {
|
||||
(_, key) if key == &MSG_KEY_CTRL_S => {
|
||||
// Show popup
|
||||
self.mount_bookmark_save_dialog();
|
||||
// Give focus to bookmark name
|
||||
self.view.active(COMPONENT_INPUT_BOOKMARK_NAME);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_BOOKMARK_NAME, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_INPUT_BOOKMARK_NAME, key) if key == &MSG_KEY_DOWN => {
|
||||
// Give focus to pwd
|
||||
self.view.active(COMPONENT_RADIO_BOOKMARK_SAVE_PWD);
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_BOOKMARK_SAVE_PWD, &MSG_KEY_UP) => {
|
||||
(COMPONENT_RADIO_BOOKMARK_SAVE_PWD, key) if key == &MSG_KEY_UP => {
|
||||
// Give focus to pwd
|
||||
self.view.active(COMPONENT_INPUT_BOOKMARK_NAME);
|
||||
None
|
||||
|
@ -291,8 +292,9 @@ impl Update for AuthActivity {
|
|||
self.view_bookmarks()
|
||||
}
|
||||
// Hide save bookmark
|
||||
(COMPONENT_INPUT_BOOKMARK_NAME, &MSG_KEY_ESC)
|
||||
| (COMPONENT_RADIO_BOOKMARK_SAVE_PWD, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_INPUT_BOOKMARK_NAME, key) | (COMPONENT_RADIO_BOOKMARK_SAVE_PWD, key)
|
||||
if key == &MSG_KEY_ESC =>
|
||||
{
|
||||
// Umount popup
|
||||
self.umount_bookmark_save_dialog();
|
||||
None
|
||||
|
@ -307,45 +309,30 @@ impl Update for AuthActivity {
|
|||
self.umount_quit();
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_QUIT, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_RADIO_QUIT, key) if key == &MSG_KEY_ESC => {
|
||||
self.umount_quit();
|
||||
None
|
||||
}
|
||||
// -- text size error; block everything
|
||||
(COMPONENT_TEXT_SIZE_ERR, _) => None,
|
||||
// <TAB> bookmarks
|
||||
(COMPONENT_BOOKMARKS_LIST, &MSG_KEY_TAB)
|
||||
| (COMPONENT_RECENTS_LIST, &MSG_KEY_TAB) => {
|
||||
(COMPONENT_BOOKMARKS_LIST, key) | (COMPONENT_RECENTS_LIST, key)
|
||||
if key == &MSG_KEY_TAB =>
|
||||
{
|
||||
// Give focus to address
|
||||
self.view.active(COMPONENT_INPUT_ADDR);
|
||||
None
|
||||
}
|
||||
// Any <TAB>, go to bookmarks
|
||||
(_, &MSG_KEY_TAB) => {
|
||||
(_, key) if key == &MSG_KEY_TAB => {
|
||||
self.view.active(COMPONENT_BOOKMARKS_LIST);
|
||||
None
|
||||
}
|
||||
// On submit on any unhandled (connect)
|
||||
(_, Msg::OnSubmit(_)) | (_, &MSG_KEY_ENTER) => {
|
||||
// Validate fields
|
||||
match self.collect_host_params() {
|
||||
Err(err) => {
|
||||
// mount error
|
||||
self.mount_error(err);
|
||||
}
|
||||
Ok(params) => {
|
||||
self.save_recent();
|
||||
// Set file transfer params to context
|
||||
self.context_mut().set_ftparams(params);
|
||||
// Set exit reason
|
||||
self.exit_reason = Some(super::ExitReason::Connect);
|
||||
}
|
||||
}
|
||||
// Return None
|
||||
None
|
||||
}
|
||||
(_, Msg::OnSubmit(_)) => self.on_unhandled_submit(),
|
||||
(_, key) if key == &MSG_KEY_ENTER => self.on_unhandled_submit(),
|
||||
// <ESC> => Quit
|
||||
(_, &MSG_KEY_ESC) => {
|
||||
(_, key) if key == &MSG_KEY_ESC => {
|
||||
self.mount_quit();
|
||||
None
|
||||
}
|
||||
|
@ -367,4 +354,23 @@ impl AuthActivity {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_unhandled_submit(&mut self) -> Option<(String, Msg)> {
|
||||
// Validate fields
|
||||
match self.collect_host_params() {
|
||||
Err(err) => {
|
||||
// mount error
|
||||
self.mount_error(err);
|
||||
}
|
||||
Ok(params) => {
|
||||
self.save_recent();
|
||||
// Set file transfer params to context
|
||||
self.context_mut().set_ftparams(params);
|
||||
// Set exit reason
|
||||
self.exit_reason = Some(super::ExitReason::Connect);
|
||||
}
|
||||
}
|
||||
// Return None
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,17 +27,15 @@
|
|||
*/
|
||||
// Locals
|
||||
use super::{AuthActivity, Context, FileTransferProtocol};
|
||||
use crate::ui::components::{
|
||||
bookmark_list::{BookmarkList, BookmarkListPropsBuilder},
|
||||
msgbox::{MsgBox, MsgBoxPropsBuilder},
|
||||
};
|
||||
use crate::ui::components::bookmark_list::{BookmarkList, BookmarkListPropsBuilder};
|
||||
use crate::utils::ui::draw_area_in;
|
||||
// Ext
|
||||
use tuirealm::components::{
|
||||
use tui_realm_stdlib::{
|
||||
input::{Input, InputPropsBuilder},
|
||||
label::{Label, LabelPropsBuilder},
|
||||
list::{List, ListPropsBuilder},
|
||||
paragraph::{Paragraph, ParagraphPropsBuilder},
|
||||
radio::{Radio, RadioPropsBuilder},
|
||||
scrolltable::{ScrollTablePropsBuilder, Scrolltable},
|
||||
span::{Span, SpanPropsBuilder},
|
||||
textarea::{Textarea, TextareaPropsBuilder},
|
||||
};
|
||||
|
@ -47,7 +45,7 @@ use tuirealm::tui::{
|
|||
widgets::{BorderType, Borders, Clear},
|
||||
};
|
||||
use tuirealm::{
|
||||
props::{InputType, PropsBuilder, TableBuilder, TextSpan, TextSpanBuilder},
|
||||
props::{Alignment, InputType, PropsBuilder, TableBuilder, TextSpan},
|
||||
Msg, Payload, Value,
|
||||
};
|
||||
|
||||
|
@ -91,19 +89,11 @@ impl AuthActivity {
|
|||
Box::new(Span::new(
|
||||
SpanPropsBuilder::default()
|
||||
.with_spans(vec![
|
||||
TextSpanBuilder::new("Press ").bold().build(),
|
||||
TextSpanBuilder::new("<CTRL+H>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
TextSpanBuilder::new(" to show keybindings; ")
|
||||
.bold()
|
||||
.build(),
|
||||
TextSpanBuilder::new("<CTRL+C>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
TextSpanBuilder::new(" to enter setup").bold().build(),
|
||||
TextSpan::new("Press ").bold(),
|
||||
TextSpan::new("<CTRL+H>").bold().fg(key_color),
|
||||
TextSpan::new(" to show keybindings; ").bold(),
|
||||
TextSpan::new("<CTRL+C>").bold().fg(key_color),
|
||||
TextSpan::new(" to enter setup").bold(),
|
||||
])
|
||||
.build(),
|
||||
)),
|
||||
|
@ -118,15 +108,8 @@ impl AuthActivity {
|
|||
.with_color(protocol_color)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, protocol_color)
|
||||
.with_options(
|
||||
Some(String::from("Protocol")),
|
||||
vec![
|
||||
String::from("SFTP"),
|
||||
String::from("SCP"),
|
||||
String::from("FTP"),
|
||||
String::from("FTPS"),
|
||||
],
|
||||
)
|
||||
.with_title("Protocol", Alignment::Left)
|
||||
.with_options(&["SFTP", "SCP", "FTP", "FTPS"])
|
||||
.with_value(Self::protocol_enum_to_opt(default_protocol))
|
||||
.build(),
|
||||
)),
|
||||
|
@ -138,7 +121,7 @@ impl AuthActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_foreground(addr_color)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, addr_color)
|
||||
.with_label(String::from("Remote host"))
|
||||
.with_label("Remote host", Alignment::Left)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -149,7 +132,7 @@ impl AuthActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_foreground(port_color)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, port_color)
|
||||
.with_label(String::from("Port number"))
|
||||
.with_label("Port number", Alignment::Left)
|
||||
.with_input(InputType::Number)
|
||||
.with_input_len(5)
|
||||
.with_value(Self::get_default_port_for_protocol(default_protocol).to_string())
|
||||
|
@ -163,7 +146,7 @@ impl AuthActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_foreground(username_color)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, username_color)
|
||||
.with_label(String::from("Username"))
|
||||
.with_label("Username", Alignment::Left)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -174,7 +157,7 @@ impl AuthActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_foreground(password_color)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, password_color)
|
||||
.with_label(String::from("Password"))
|
||||
.with_label("Password", Alignment::Left)
|
||||
.with_input(InputType::Password)
|
||||
.build(),
|
||||
)),
|
||||
|
@ -193,7 +176,7 @@ impl AuthActivity {
|
|||
.with_foreground(Color::Yellow)
|
||||
.with_spans(vec![
|
||||
TextSpan::from("termscp "),
|
||||
TextSpanBuilder::new(version.as_str()).underlined().bold().build(),
|
||||
TextSpan::new(version.as_str()).underlined().bold(),
|
||||
TextSpan::from(" is NOW available! Get it from <https://veeso.github.io/termscp/>; view release notes with <CTRL+R>"),
|
||||
])
|
||||
.build(),
|
||||
|
@ -208,7 +191,7 @@ impl AuthActivity {
|
|||
.with_background(bookmarks_color)
|
||||
.with_foreground(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Plain, bookmarks_color)
|
||||
.with_bookmarks(Some(String::from("Bookmarks")), vec![])
|
||||
.with_title("Bookmarks", Alignment::Left)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -220,7 +203,7 @@ impl AuthActivity {
|
|||
.with_background(recents_color)
|
||||
.with_foreground(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Plain, recents_color)
|
||||
.with_bookmarks(Some(String::from("Recent connections")), vec![])
|
||||
.with_title("Recent connections", Alignment::Left)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -426,7 +409,7 @@ impl AuthActivity {
|
|||
let msg = self.view.update(
|
||||
super::COMPONENT_BOOKMARKS_LIST,
|
||||
BookmarkListPropsBuilder::from(props)
|
||||
.with_bookmarks(Some(String::from("Bookmarks")), bookmarks)
|
||||
.with_bookmarks(bookmarks)
|
||||
.build(),
|
||||
);
|
||||
msg
|
||||
|
@ -464,7 +447,7 @@ impl AuthActivity {
|
|||
let msg = self.view.update(
|
||||
super::COMPONENT_RECENTS_LIST,
|
||||
BookmarkListPropsBuilder::from(props)
|
||||
.with_bookmarks(Some(String::from("Recent connections")), bookmarks)
|
||||
.with_bookmarks(bookmarks)
|
||||
.build(),
|
||||
);
|
||||
msg
|
||||
|
@ -482,12 +465,13 @@ impl AuthActivity {
|
|||
let err_color = self.theme().misc_error_dialog;
|
||||
self.view.mount(
|
||||
super::COMPONENT_TEXT_ERROR,
|
||||
Box::new(MsgBox::new(
|
||||
MsgBoxPropsBuilder::default()
|
||||
Box::new(Paragraph::new(
|
||||
ParagraphPropsBuilder::default()
|
||||
.with_foreground(err_color)
|
||||
.with_borders(Borders::ALL, BorderType::Thick, err_color)
|
||||
.bold()
|
||||
.with_texts(None, vec![TextSpan::from(text)])
|
||||
.with_text_alignment(Alignment::Center)
|
||||
.with_texts(vec![TextSpan::from(text)])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -510,17 +494,15 @@ impl AuthActivity {
|
|||
let err_color = self.theme().misc_error_dialog;
|
||||
self.view.mount(
|
||||
super::COMPONENT_TEXT_SIZE_ERR,
|
||||
Box::new(MsgBox::new(
|
||||
MsgBoxPropsBuilder::default()
|
||||
Box::new(Paragraph::new(
|
||||
ParagraphPropsBuilder::default()
|
||||
.with_foreground(err_color)
|
||||
.with_borders(Borders::ALL, BorderType::Thick, err_color)
|
||||
.bold()
|
||||
.with_texts(
|
||||
None,
|
||||
vec![TextSpan::from(
|
||||
"termscp requires at least 24 lines of height to run",
|
||||
)],
|
||||
)
|
||||
.with_texts(vec![TextSpan::from(
|
||||
"termscp requires at least 24 lines of height to run",
|
||||
)])
|
||||
.with_text_alignment(Alignment::Center)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -548,10 +530,8 @@ impl AuthActivity {
|
|||
.with_color(quit_color)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, quit_color)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_options(
|
||||
Some(String::from("Quit termscp?")),
|
||||
vec![String::from("Yes"), String::from("No")],
|
||||
)
|
||||
.with_title("Quit termscp?", Alignment::Center)
|
||||
.with_options(&[String::from("Yes"), String::from("No")])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -577,10 +557,8 @@ impl AuthActivity {
|
|||
.with_color(warn_color)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, warn_color)
|
||||
.with_options(
|
||||
Some(String::from("Delete bookmark?")),
|
||||
vec![String::from("Yes"), String::from("No")],
|
||||
)
|
||||
.with_title("Delete bookmark?", Alignment::Center)
|
||||
.with_options(&[String::from("Yes"), String::from("No")])
|
||||
.with_value(1)
|
||||
.build(),
|
||||
)),
|
||||
|
@ -610,10 +588,8 @@ impl AuthActivity {
|
|||
.with_color(warn_color)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, warn_color)
|
||||
.with_options(
|
||||
Some(String::from("Delete bookmark?")),
|
||||
vec![String::from("Yes"), String::from("No")],
|
||||
)
|
||||
.with_title("Delete bookmark?", Alignment::Center)
|
||||
.with_options(&[String::from("Yes"), String::from("No")])
|
||||
.with_value(1)
|
||||
.build(),
|
||||
)),
|
||||
|
@ -640,7 +616,7 @@ impl AuthActivity {
|
|||
Box::new(Input::new(
|
||||
InputPropsBuilder::default()
|
||||
.with_foreground(save_color)
|
||||
.with_label(String::from("Save bookmark as…"))
|
||||
.with_label("Save bookmark as…", Alignment::Center)
|
||||
.with_borders(
|
||||
Borders::TOP | Borders::RIGHT | Borders::LEFT,
|
||||
BorderType::Rounded,
|
||||
|
@ -659,10 +635,8 @@ impl AuthActivity {
|
|||
BorderType::Rounded,
|
||||
Color::Reset,
|
||||
)
|
||||
.with_options(
|
||||
Some(String::from("Save password?")),
|
||||
vec![String::from("Yes"), String::from("No")],
|
||||
)
|
||||
.with_title("Save password?", Alignment::Center)
|
||||
.with_options(&[String::from("Yes"), String::from("No")])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -685,77 +659,38 @@ impl AuthActivity {
|
|||
let key_color = self.theme().misc_keys;
|
||||
self.view.mount(
|
||||
super::COMPONENT_TEXT_HELP,
|
||||
Box::new(Scrolltable::new(
|
||||
ScrollTablePropsBuilder::default()
|
||||
Box::new(List::new(
|
||||
ListPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::White)
|
||||
.with_highlighted_str(Some("?"))
|
||||
.with_max_scroll_step(8)
|
||||
.scrollable(true)
|
||||
.bold()
|
||||
.with_table(
|
||||
Some(String::from("Help")),
|
||||
.with_title("Help", Alignment::Center)
|
||||
.with_rows(
|
||||
TableBuilder::default()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<ESC>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<ESC>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Quit termscp"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<TAB>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<TAB>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Switch from form and bookmarks"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<RIGHT/LEFT>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<RIGHT/LEFT>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Switch bookmark tab"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<UP/DOWN>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<UP/DOWN>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Move up/down in current tab"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<ENTER>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<ENTER>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Connect/Load bookmark"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<DEL|E>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<DEL|E>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Delete selected bookmark"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<CTRL+C>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<CTRL+C>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Enter setup"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<CTRL+S>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<CTRL+S>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Save bookmark"))
|
||||
.build(),
|
||||
)
|
||||
|
@ -786,7 +721,8 @@ impl AuthActivity {
|
|||
Box::new(Textarea::new(
|
||||
TextareaPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightYellow)
|
||||
.with_texts(Some(String::from("Release notes")), spans)
|
||||
.with_title("Release notes", Alignment::Center)
|
||||
.with_texts(spans)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
|
|
@ -42,9 +42,9 @@ use crate::ui::components::{file_list::FileListPropsBuilder, logbox::LogboxProps
|
|||
use crate::ui::keymap::*;
|
||||
use crate::utils::fmt::fmt_path_elide_ex;
|
||||
// externals
|
||||
use tui_realm_stdlib::progress_bar::ProgressBarPropsBuilder;
|
||||
use tuirealm::{
|
||||
components::progress_bar::ProgressBarPropsBuilder,
|
||||
props::{PropsBuilder, TableBuilder, TextSpan, TextSpanBuilder},
|
||||
props::{Alignment, PropsBuilder, TableBuilder, TextSpan},
|
||||
tui::style::Color,
|
||||
Msg, Payload, Update, Value,
|
||||
};
|
||||
|
@ -63,13 +63,13 @@ impl Update for FileTransferActivity {
|
|||
None => None, // Exit after None
|
||||
Some(msg) => match msg {
|
||||
// -- local tab
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_RIGHT) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) if key == &MSG_KEY_RIGHT => {
|
||||
// Change tab
|
||||
self.view.active(COMPONENT_EXPLORER_REMOTE);
|
||||
self.browser.change_tab(FileExplorerTab::Remote);
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_BACKSPACE) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) if key == &MSG_KEY_BACKSPACE => {
|
||||
// Go to previous directory
|
||||
self.action_go_to_previous_local_dir(false);
|
||||
if self.browser.sync_browsing {
|
||||
|
@ -98,11 +98,11 @@ impl Update for FileTransferActivity {
|
|||
None
|
||||
}
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_SPACE) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) if key == &MSG_KEY_SPACE => {
|
||||
self.action_local_send();
|
||||
self.update_remote_filelist()
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_A) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) if key == &MSG_KEY_CHAR_A => {
|
||||
// Toggle hidden files
|
||||
self.local_mut().toggle_hidden_files();
|
||||
// Update status bar
|
||||
|
@ -110,24 +110,24 @@ impl Update for FileTransferActivity {
|
|||
// Reload file list component
|
||||
self.update_local_filelist()
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_I) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) if key == &MSG_KEY_CHAR_I => {
|
||||
if let SelectedEntry::One(file) = self.get_local_selected_entries() {
|
||||
self.mount_file_info(&file);
|
||||
}
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_L) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) if key == &MSG_KEY_CHAR_L => {
|
||||
// Reload directory
|
||||
self.reload_local_dir();
|
||||
// Reload file list component
|
||||
self.update_local_filelist()
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_O) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) if key == &MSG_KEY_CHAR_O => {
|
||||
self.action_edit_local_file();
|
||||
// Reload file list component
|
||||
self.update_local_filelist()
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_U) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) if key == &MSG_KEY_CHAR_U => {
|
||||
self.action_go_to_local_upper_dir(false);
|
||||
if self.browser.sync_browsing {
|
||||
let _ = self.update_remote_filelist();
|
||||
|
@ -136,7 +136,7 @@ impl Update for FileTransferActivity {
|
|||
self.update_local_filelist()
|
||||
}
|
||||
// -- remote tab
|
||||
(COMPONENT_EXPLORER_REMOTE, &MSG_KEY_LEFT) => {
|
||||
(COMPONENT_EXPLORER_REMOTE, key) if key == &MSG_KEY_LEFT => {
|
||||
// Change tab
|
||||
self.view.active(COMPONENT_EXPLORER_LOCAL);
|
||||
self.browser.change_tab(FileExplorerTab::Local);
|
||||
|
@ -162,11 +162,11 @@ impl Update for FileTransferActivity {
|
|||
None
|
||||
}
|
||||
}
|
||||
(COMPONENT_EXPLORER_REMOTE, &MSG_KEY_SPACE) => {
|
||||
(COMPONENT_EXPLORER_REMOTE, key) if key == &MSG_KEY_SPACE => {
|
||||
self.action_remote_recv();
|
||||
self.update_local_filelist()
|
||||
}
|
||||
(COMPONENT_EXPLORER_REMOTE, &MSG_KEY_BACKSPACE) => {
|
||||
(COMPONENT_EXPLORER_REMOTE, key) if key == &MSG_KEY_BACKSPACE => {
|
||||
// Go to previous directory
|
||||
self.action_go_to_previous_remote_dir(false);
|
||||
// If sync is enabled update local too
|
||||
|
@ -176,7 +176,7 @@ impl Update for FileTransferActivity {
|
|||
// Reload file list component
|
||||
self.update_remote_filelist()
|
||||
}
|
||||
(COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_A) => {
|
||||
(COMPONENT_EXPLORER_REMOTE, key) if key == &MSG_KEY_CHAR_A => {
|
||||
// Toggle hidden files
|
||||
self.remote_mut().toggle_hidden_files();
|
||||
// Update status bar
|
||||
|
@ -184,25 +184,25 @@ impl Update for FileTransferActivity {
|
|||
// Reload file list component
|
||||
self.update_remote_filelist()
|
||||
}
|
||||
(COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_I) => {
|
||||
(COMPONENT_EXPLORER_REMOTE, key) if key == &MSG_KEY_CHAR_I => {
|
||||
if let SelectedEntry::One(file) = self.get_remote_selected_entries() {
|
||||
self.mount_file_info(&file);
|
||||
}
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_L) => {
|
||||
(COMPONENT_EXPLORER_REMOTE, key) if key == &MSG_KEY_CHAR_L => {
|
||||
// Reload directory
|
||||
self.reload_remote_dir();
|
||||
// Reload file list component
|
||||
self.update_remote_filelist()
|
||||
}
|
||||
(COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_O) => {
|
||||
(COMPONENT_EXPLORER_REMOTE, key) if key == &MSG_KEY_CHAR_O => {
|
||||
// Edit file
|
||||
self.action_edit_remote_file();
|
||||
// Reload file list component
|
||||
self.update_remote_filelist()
|
||||
}
|
||||
(COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_U) => {
|
||||
(COMPONENT_EXPLORER_REMOTE, key) if key == &MSG_KEY_CHAR_U => {
|
||||
self.action_go_to_remote_upper_dir(false);
|
||||
if self.browser.sync_browsing {
|
||||
let _ = self.update_local_filelist();
|
||||
|
@ -211,64 +211,78 @@ impl Update for FileTransferActivity {
|
|||
self.update_remote_filelist()
|
||||
}
|
||||
// -- common explorer keys
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_B)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_B) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) | (COMPONENT_EXPLORER_REMOTE, key)
|
||||
if key == &MSG_KEY_CHAR_B =>
|
||||
{
|
||||
// Show sorting file
|
||||
self.mount_file_sorting();
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_C)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_C) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) | (COMPONENT_EXPLORER_REMOTE, key)
|
||||
if key == &MSG_KEY_CHAR_C =>
|
||||
{
|
||||
self.mount_copy();
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_D)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_D) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) | (COMPONENT_EXPLORER_REMOTE, key)
|
||||
if key == &MSG_KEY_CHAR_D =>
|
||||
{
|
||||
self.mount_mkdir();
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_F)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_F) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) | (COMPONENT_EXPLORER_REMOTE, key)
|
||||
if key == &MSG_KEY_CHAR_F =>
|
||||
{
|
||||
self.mount_find_input();
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_G)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_G) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) | (COMPONENT_EXPLORER_REMOTE, key)
|
||||
if key == &MSG_KEY_CHAR_G =>
|
||||
{
|
||||
self.mount_goto();
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_H)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_H) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) | (COMPONENT_EXPLORER_REMOTE, key)
|
||||
if key == &MSG_KEY_CHAR_H =>
|
||||
{
|
||||
self.mount_help();
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_N)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_N) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) | (COMPONENT_EXPLORER_REMOTE, key)
|
||||
if key == &MSG_KEY_CHAR_N =>
|
||||
{
|
||||
self.mount_newfile();
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_Q)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_Q)
|
||||
| (COMPONENT_LOG_BOX, &MSG_KEY_CHAR_Q) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key)
|
||||
| (COMPONENT_EXPLORER_REMOTE, key)
|
||||
| (COMPONENT_LOG_BOX, key)
|
||||
if key == &MSG_KEY_CHAR_Q =>
|
||||
{
|
||||
self.mount_quit();
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_R)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_R) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) | (COMPONENT_EXPLORER_REMOTE, key)
|
||||
if key == &MSG_KEY_CHAR_R =>
|
||||
{
|
||||
// Mount rename
|
||||
self.mount_rename();
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_S)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_S)
|
||||
| (COMPONENT_EXPLORER_FIND, &MSG_KEY_CHAR_S) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key)
|
||||
| (COMPONENT_EXPLORER_REMOTE, key)
|
||||
| (COMPONENT_EXPLORER_FIND, key)
|
||||
if key == &MSG_KEY_CHAR_S =>
|
||||
{
|
||||
// Mount save as
|
||||
self.mount_saveas();
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_V)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_V)
|
||||
| (COMPONENT_EXPLORER_FIND, &MSG_KEY_CHAR_V) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key)
|
||||
| (COMPONENT_EXPLORER_REMOTE, key)
|
||||
| (COMPONENT_EXPLORER_FIND, key)
|
||||
if key == &MSG_KEY_CHAR_V =>
|
||||
{
|
||||
// View
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_open_local(),
|
||||
|
@ -279,44 +293,49 @@ impl Update for FileTransferActivity {
|
|||
}
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_W)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_W)
|
||||
| (COMPONENT_EXPLORER_FIND, &MSG_KEY_CHAR_W) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key)
|
||||
| (COMPONENT_EXPLORER_REMOTE, key)
|
||||
| (COMPONENT_EXPLORER_FIND, key)
|
||||
if key == &MSG_KEY_CHAR_W =>
|
||||
{
|
||||
// Open with
|
||||
self.mount_openwith();
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_X)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_X) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) | (COMPONENT_EXPLORER_REMOTE, key)
|
||||
if key == &MSG_KEY_CHAR_X =>
|
||||
{
|
||||
// Mount exec
|
||||
self.mount_exec();
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_Y)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_Y) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) | (COMPONENT_EXPLORER_REMOTE, key)
|
||||
if key == &MSG_KEY_CHAR_Y =>
|
||||
{
|
||||
// Toggle browser sync
|
||||
self.browser.toggle_sync_browsing();
|
||||
// Update status bar
|
||||
self.refresh_remote_status_bar();
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_ESC)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_ESC)
|
||||
| (COMPONENT_LOG_BOX, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key)
|
||||
| (COMPONENT_EXPLORER_REMOTE, key)
|
||||
| (COMPONENT_LOG_BOX, key)
|
||||
if key == &MSG_KEY_ESC =>
|
||||
{
|
||||
self.mount_disconnect();
|
||||
None
|
||||
}
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_DEL)
|
||||
| (COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_E)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_DEL)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_E)
|
||||
| (COMPONENT_EXPLORER_FIND, &MSG_KEY_DEL)
|
||||
| (COMPONENT_EXPLORER_FIND, &MSG_KEY_CHAR_E) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key)
|
||||
| (COMPONENT_EXPLORER_REMOTE, key)
|
||||
| (COMPONENT_EXPLORER_FIND, key)
|
||||
if key == &MSG_KEY_CHAR_E || key == &MSG_KEY_DEL =>
|
||||
{
|
||||
self.mount_radio_delete();
|
||||
None
|
||||
}
|
||||
// -- find result explorer
|
||||
(COMPONENT_EXPLORER_FIND, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_EXPLORER_FIND, key) if key == &MSG_KEY_ESC => {
|
||||
// Umount find
|
||||
self.umount_find();
|
||||
// Finalize find
|
||||
|
@ -337,7 +356,7 @@ impl Update for FileTransferActivity {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
(COMPONENT_EXPLORER_FIND, &MSG_KEY_SPACE) => {
|
||||
(COMPONENT_EXPLORER_FIND, key) if key == &MSG_KEY_SPACE => {
|
||||
// Get entry
|
||||
self.action_find_transfer(None);
|
||||
// Reload files
|
||||
|
@ -349,18 +368,19 @@ impl Update for FileTransferActivity {
|
|||
}
|
||||
}
|
||||
// -- switch to log
|
||||
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_TAB)
|
||||
| (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_TAB) => {
|
||||
(COMPONENT_EXPLORER_LOCAL, key) | (COMPONENT_EXPLORER_REMOTE, key)
|
||||
if key == &MSG_KEY_TAB =>
|
||||
{
|
||||
self.view.active(COMPONENT_LOG_BOX); // Active log box
|
||||
None
|
||||
}
|
||||
// -- Log box
|
||||
(COMPONENT_LOG_BOX, &MSG_KEY_TAB) => {
|
||||
(COMPONENT_LOG_BOX, key) if key == &MSG_KEY_TAB => {
|
||||
self.view.blur(); // Blur log box
|
||||
None
|
||||
}
|
||||
// -- copy popup
|
||||
(COMPONENT_INPUT_COPY, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_INPUT_COPY, key) if key == &MSG_KEY_ESC => {
|
||||
self.umount_copy();
|
||||
None
|
||||
}
|
||||
|
@ -383,7 +403,7 @@ impl Update for FileTransferActivity {
|
|||
}
|
||||
(COMPONENT_INPUT_COPY, _) => None,
|
||||
// -- exec popup
|
||||
(COMPONENT_INPUT_EXEC, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_INPUT_EXEC, key) if key == &MSG_KEY_ESC => {
|
||||
self.umount_exec();
|
||||
None
|
||||
}
|
||||
|
@ -406,7 +426,7 @@ impl Update for FileTransferActivity {
|
|||
}
|
||||
(COMPONENT_INPUT_EXEC, _) => None,
|
||||
// -- find popup
|
||||
(COMPONENT_INPUT_FIND, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_INPUT_FIND, key) if key == &MSG_KEY_ESC => {
|
||||
self.umount_find_input();
|
||||
None
|
||||
}
|
||||
|
@ -441,7 +461,7 @@ impl Update for FileTransferActivity {
|
|||
None
|
||||
}
|
||||
// -- goto popup
|
||||
(COMPONENT_INPUT_GOTO, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_INPUT_GOTO, key) if key == &MSG_KEY_ESC => {
|
||||
self.umount_goto();
|
||||
None
|
||||
}
|
||||
|
@ -474,7 +494,7 @@ impl Update for FileTransferActivity {
|
|||
}
|
||||
(COMPONENT_INPUT_GOTO, _) => None,
|
||||
// -- make directory
|
||||
(COMPONENT_INPUT_MKDIR, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_INPUT_MKDIR, key) if key == &MSG_KEY_ESC => {
|
||||
self.umount_mkdir();
|
||||
None
|
||||
}
|
||||
|
@ -494,7 +514,7 @@ impl Update for FileTransferActivity {
|
|||
}
|
||||
(COMPONENT_INPUT_MKDIR, _) => None,
|
||||
// -- new file
|
||||
(COMPONENT_INPUT_NEWFILE, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_INPUT_NEWFILE, key) if key == &MSG_KEY_ESC => {
|
||||
self.umount_newfile();
|
||||
None
|
||||
}
|
||||
|
@ -514,7 +534,7 @@ impl Update for FileTransferActivity {
|
|||
}
|
||||
(COMPONENT_INPUT_NEWFILE, _) => None,
|
||||
// -- open with
|
||||
(COMPONENT_INPUT_OPEN_WITH, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_INPUT_OPEN_WITH, key) if key == &MSG_KEY_ESC => {
|
||||
self.umount_openwith();
|
||||
None
|
||||
}
|
||||
|
@ -531,7 +551,7 @@ impl Update for FileTransferActivity {
|
|||
}
|
||||
(COMPONENT_INPUT_OPEN_WITH, _) => None,
|
||||
// -- rename
|
||||
(COMPONENT_INPUT_RENAME, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_INPUT_RENAME, key) if key == &MSG_KEY_ESC => {
|
||||
self.umount_rename();
|
||||
None
|
||||
}
|
||||
|
@ -553,7 +573,7 @@ impl Update for FileTransferActivity {
|
|||
}
|
||||
(COMPONENT_INPUT_RENAME, _) => None,
|
||||
// -- save as
|
||||
(COMPONENT_INPUT_SAVEAS, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_INPUT_SAVEAS, key) if key == &MSG_KEY_ESC => {
|
||||
self.umount_saveas();
|
||||
None
|
||||
}
|
||||
|
@ -578,15 +598,18 @@ impl Update for FileTransferActivity {
|
|||
}
|
||||
(COMPONENT_INPUT_SAVEAS, _) => None,
|
||||
// -- fileinfo
|
||||
(COMPONENT_LIST_FILEINFO, &MSG_KEY_ENTER)
|
||||
| (COMPONENT_LIST_FILEINFO, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_LIST_FILEINFO, key) | (COMPONENT_LIST_FILEINFO, key)
|
||||
if key == &MSG_KEY_ENTER || key == &MSG_KEY_ESC =>
|
||||
{
|
||||
self.umount_file_info();
|
||||
None
|
||||
}
|
||||
(COMPONENT_LIST_FILEINFO, _) => None,
|
||||
// -- delete
|
||||
(COMPONENT_RADIO_DELETE, &MSG_KEY_ESC)
|
||||
| (COMPONENT_RADIO_DELETE, Msg::OnSubmit(Payload::One(Value::Usize(1)))) => {
|
||||
(COMPONENT_RADIO_DELETE, key)
|
||||
if key == &MSG_KEY_ESC
|
||||
|| key == &Msg::OnSubmit(Payload::One(Value::Usize(1))) =>
|
||||
{
|
||||
self.umount_radio_delete();
|
||||
None
|
||||
}
|
||||
|
@ -631,8 +654,10 @@ impl Update for FileTransferActivity {
|
|||
}
|
||||
(COMPONENT_RADIO_DELETE, _) => None,
|
||||
// -- disconnect
|
||||
(COMPONENT_RADIO_DISCONNECT, &MSG_KEY_ESC)
|
||||
| (COMPONENT_RADIO_DISCONNECT, Msg::OnSubmit(Payload::One(Value::Usize(1)))) => {
|
||||
(COMPONENT_RADIO_DISCONNECT, key)
|
||||
if key == &MSG_KEY_ESC
|
||||
|| key == &Msg::OnSubmit(Payload::One(Value::Usize(1))) =>
|
||||
{
|
||||
self.umount_disconnect();
|
||||
None
|
||||
}
|
||||
|
@ -643,8 +668,10 @@ impl Update for FileTransferActivity {
|
|||
}
|
||||
(COMPONENT_RADIO_DISCONNECT, _) => None,
|
||||
// -- quit
|
||||
(COMPONENT_RADIO_QUIT, &MSG_KEY_ESC)
|
||||
| (COMPONENT_RADIO_QUIT, Msg::OnSubmit(Payload::One(Value::Usize(1)))) => {
|
||||
(COMPONENT_RADIO_QUIT, key)
|
||||
if key == &MSG_KEY_ESC
|
||||
|| key == &Msg::OnSubmit(Payload::One(Value::Usize(1))) =>
|
||||
{
|
||||
self.umount_quit();
|
||||
None
|
||||
}
|
||||
|
@ -655,8 +682,11 @@ impl Update for FileTransferActivity {
|
|||
}
|
||||
(COMPONENT_RADIO_QUIT, _) => None,
|
||||
// -- sorting
|
||||
(COMPONENT_RADIO_SORTING, &MSG_KEY_ESC)
|
||||
| (COMPONENT_RADIO_SORTING, Msg::OnSubmit(_)) => {
|
||||
(COMPONENT_RADIO_SORTING, key) if key == &MSG_KEY_ESC => {
|
||||
self.umount_file_sorting();
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_SORTING, Msg::OnSubmit(_)) => {
|
||||
self.umount_file_sorting();
|
||||
None
|
||||
}
|
||||
|
@ -688,25 +718,31 @@ impl Update for FileTransferActivity {
|
|||
}
|
||||
(COMPONENT_RADIO_SORTING, _) => None,
|
||||
// -- error
|
||||
(COMPONENT_TEXT_ERROR, &MSG_KEY_ESC) | (COMPONENT_TEXT_ERROR, &MSG_KEY_ENTER) => {
|
||||
(COMPONENT_TEXT_ERROR, key) | (COMPONENT_TEXT_ERROR, key)
|
||||
if key == &MSG_KEY_ESC || key == &MSG_KEY_ENTER =>
|
||||
{
|
||||
self.umount_error();
|
||||
None
|
||||
}
|
||||
(COMPONENT_TEXT_ERROR, _) => None,
|
||||
// -- fatal
|
||||
(COMPONENT_TEXT_FATAL, &MSG_KEY_ESC) | (COMPONENT_TEXT_FATAL, &MSG_KEY_ENTER) => {
|
||||
(COMPONENT_TEXT_FATAL, key) | (COMPONENT_TEXT_FATAL, key)
|
||||
if key == &MSG_KEY_ESC || key == &MSG_KEY_ENTER =>
|
||||
{
|
||||
self.exit_reason = Some(super::ExitReason::Disconnect);
|
||||
None
|
||||
}
|
||||
(COMPONENT_TEXT_FATAL, _) => None,
|
||||
// -- help
|
||||
(COMPONENT_TEXT_HELP, &MSG_KEY_ESC) | (COMPONENT_TEXT_HELP, &MSG_KEY_ENTER) => {
|
||||
(COMPONENT_TEXT_HELP, key) | (COMPONENT_TEXT_HELP, key)
|
||||
if key == &MSG_KEY_ESC || key == &MSG_KEY_ENTER =>
|
||||
{
|
||||
self.umount_help();
|
||||
None
|
||||
}
|
||||
(COMPONENT_TEXT_HELP, _) => None,
|
||||
// -- progress bar
|
||||
(COMPONENT_PROGRESS_BAR_PARTIAL, &MSG_KEY_CTRL_C) => {
|
||||
(COMPONENT_PROGRESS_BAR_PARTIAL, key) if key == &MSG_KEY_CTRL_C => {
|
||||
// Set transfer aborted to True
|
||||
self.transfer.abort();
|
||||
None
|
||||
|
@ -752,7 +788,8 @@ impl FileTransferActivity {
|
|||
.collect();
|
||||
// Update
|
||||
let props = FileListPropsBuilder::from(props)
|
||||
.with_files(Some(hostname), files)
|
||||
.with_files(files)
|
||||
.with_title(hostname, Alignment::Left)
|
||||
.build();
|
||||
// Update
|
||||
self.view.update(super::COMPONENT_EXPLORER_LOCAL, props)
|
||||
|
@ -790,7 +827,8 @@ impl FileTransferActivity {
|
|||
.collect();
|
||||
// Update
|
||||
let props = FileListPropsBuilder::from(props)
|
||||
.with_files(Some(hostname), files)
|
||||
.with_files(files)
|
||||
.with_title(hostname, Alignment::Left)
|
||||
.build();
|
||||
self.view.update(super::COMPONENT_EXPLORER_REMOTE, props)
|
||||
}
|
||||
|
@ -823,7 +861,7 @@ impl FileTransferActivity {
|
|||
)))
|
||||
.add_col(TextSpan::from(" ["))
|
||||
.add_col(
|
||||
TextSpanBuilder::new(
|
||||
TextSpan::new(
|
||||
format!(
|
||||
"{:5}",
|
||||
match record.level {
|
||||
|
@ -834,16 +872,13 @@ impl FileTransferActivity {
|
|||
)
|
||||
.as_str(),
|
||||
)
|
||||
.with_foreground(fg)
|
||||
.build(),
|
||||
.fg(fg),
|
||||
)
|
||||
.add_col(TextSpan::from("]: "))
|
||||
.add_col(TextSpan::from(record.msg.as_ref()));
|
||||
}
|
||||
let table = table.build();
|
||||
let props = LogboxPropsBuilder::from(props)
|
||||
.with_log(Some(String::from("Log")), table)
|
||||
.build();
|
||||
let props = LogboxPropsBuilder::from(props).with_log(table).build();
|
||||
self.view.update(super::COMPONENT_LOG_BOX, props)
|
||||
}
|
||||
None => None,
|
||||
|
@ -852,9 +887,8 @@ impl FileTransferActivity {
|
|||
|
||||
pub(super) fn update_progress_bar(&mut self, filename: String) -> Option<(String, Msg)> {
|
||||
if let Some(props) = self.view.get_props(COMPONENT_PROGRESS_BAR_FULL) {
|
||||
let root_name: String = props.texts.title.as_deref().unwrap_or("").to_string();
|
||||
let props = ProgressBarPropsBuilder::from(props)
|
||||
.with_texts(Some(root_name), self.transfer.full.to_string())
|
||||
.with_label(self.transfer.full.to_string())
|
||||
.with_progress(self.transfer.full.calc_progress())
|
||||
.build();
|
||||
let _ = self.view.update(COMPONENT_PROGRESS_BAR_FULL, props);
|
||||
|
@ -862,7 +896,8 @@ impl FileTransferActivity {
|
|||
match self.view.get_props(COMPONENT_PROGRESS_BAR_PARTIAL) {
|
||||
Some(props) => {
|
||||
let props = ProgressBarPropsBuilder::from(props)
|
||||
.with_texts(Some(filename), self.transfer.partial.to_string())
|
||||
.with_title(filename, Alignment::Center)
|
||||
.with_label(self.transfer.partial.to_string())
|
||||
.with_progress(self.transfer.partial.calc_progress())
|
||||
.build();
|
||||
self.view.update(COMPONENT_PROGRESS_BAR_PARTIAL, props)
|
||||
|
@ -889,7 +924,6 @@ impl FileTransferActivity {
|
|||
match self.view.get_props(COMPONENT_EXPLORER_FIND) {
|
||||
None => None,
|
||||
Some(props) => {
|
||||
let title: String = props.texts.title.clone().unwrap_or_default();
|
||||
// Prepare files
|
||||
let files: Vec<String> = self
|
||||
.found()
|
||||
|
@ -897,9 +931,7 @@ impl FileTransferActivity {
|
|||
.iter_files()
|
||||
.map(|x: &FsEntry| self.found().unwrap().fmt_file(x))
|
||||
.collect();
|
||||
let props = FileListPropsBuilder::from(props)
|
||||
.with_files(Some(title), files)
|
||||
.build();
|
||||
let props = FileListPropsBuilder::from(props).with_files(files).build();
|
||||
self.view.update(COMPONENT_EXPLORER_FIND, props)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ use crate::fs::FsEntry;
|
|||
use crate::ui::components::{
|
||||
file_list::{FileList, FileListPropsBuilder},
|
||||
logbox::{LogBox, LogboxPropsBuilder},
|
||||
msgbox::{MsgBox, MsgBoxPropsBuilder},
|
||||
};
|
||||
use crate::ui::store::Store;
|
||||
use crate::utils::fmt::fmt_time;
|
||||
|
@ -40,15 +39,16 @@ use crate::utils::ui::draw_area_in;
|
|||
// Ext
|
||||
use bytesize::ByteSize;
|
||||
use std::path::PathBuf;
|
||||
use tuirealm::components::{
|
||||
use tui_realm_stdlib::{
|
||||
input::{Input, InputPropsBuilder},
|
||||
list::{List, ListPropsBuilder},
|
||||
paragraph::{Paragraph, ParagraphPropsBuilder},
|
||||
progress_bar::{ProgressBar, ProgressBarPropsBuilder},
|
||||
radio::{Radio, RadioPropsBuilder},
|
||||
scrolltable::{ScrollTablePropsBuilder, Scrolltable},
|
||||
span::{Span, SpanPropsBuilder},
|
||||
table::{Table, TablePropsBuilder},
|
||||
};
|
||||
use tuirealm::props::{PropsBuilder, TableBuilder, TextSpan, TextSpanBuilder};
|
||||
use tuirealm::props::{Alignment, PropsBuilder, TableBuilder, TextSpan};
|
||||
use tuirealm::tui::{
|
||||
layout::{Constraint, Direction, Layout},
|
||||
style::Color,
|
||||
|
@ -101,6 +101,7 @@ impl FileTransferActivity {
|
|||
super::COMPONENT_LOG_BOX,
|
||||
Box::new(LogBox::new(
|
||||
LogboxPropsBuilder::default()
|
||||
.with_title("Log", Alignment::Left)
|
||||
.with_background(log_background)
|
||||
.with_borders(Borders::ALL, BorderType::Plain, log_panel)
|
||||
.build(),
|
||||
|
@ -383,12 +384,13 @@ impl FileTransferActivity {
|
|||
let error_color = self.theme().misc_error_dialog;
|
||||
self.view.mount(
|
||||
super::COMPONENT_TEXT_ERROR,
|
||||
Box::new(MsgBox::new(
|
||||
MsgBoxPropsBuilder::default()
|
||||
Box::new(Paragraph::new(
|
||||
ParagraphPropsBuilder::default()
|
||||
.with_foreground(error_color)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, error_color)
|
||||
.bold()
|
||||
.with_texts(None, vec![TextSpan::from(text)])
|
||||
.with_text_alignment(Alignment::Center)
|
||||
.with_texts(vec![TextSpan::from(text)])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -408,12 +410,13 @@ impl FileTransferActivity {
|
|||
let error_color = self.theme().misc_error_dialog;
|
||||
self.view.mount(
|
||||
super::COMPONENT_TEXT_FATAL,
|
||||
Box::new(MsgBox::new(
|
||||
MsgBoxPropsBuilder::default()
|
||||
Box::new(Paragraph::new(
|
||||
ParagraphPropsBuilder::default()
|
||||
.with_foreground(error_color)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, error_color)
|
||||
.bold()
|
||||
.with_texts(None, vec![TextSpan::from(text)])
|
||||
.with_text_alignment(Alignment::Center)
|
||||
.with_texts(vec![TextSpan::from(text)])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -422,28 +425,26 @@ impl FileTransferActivity {
|
|||
}
|
||||
|
||||
pub(super) fn mount_wait(&mut self, text: &str) {
|
||||
self.mount_wait_ex(text, false, Color::Reset);
|
||||
self.mount_wait_ex(text, Color::Reset);
|
||||
}
|
||||
|
||||
pub(super) fn mount_blocking_wait(&mut self, text: &str) {
|
||||
self.mount_wait_ex(text, true, Color::Reset);
|
||||
self.mount_wait_ex(text, Color::Reset);
|
||||
self.view();
|
||||
}
|
||||
|
||||
fn mount_wait_ex(&mut self, text: &str, blink: bool, color: Color) {
|
||||
fn mount_wait_ex(&mut self, text: &str, color: Color) {
|
||||
// Mount
|
||||
let mut builder: MsgBoxPropsBuilder = MsgBoxPropsBuilder::default();
|
||||
let mut builder: ParagraphPropsBuilder = ParagraphPropsBuilder::default();
|
||||
builder
|
||||
.with_foreground(color)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::White)
|
||||
.bold()
|
||||
.with_texts(None, vec![TextSpan::from(text)]);
|
||||
if blink {
|
||||
builder.blink();
|
||||
}
|
||||
.with_text_alignment(Alignment::Center)
|
||||
.with_texts(vec![TextSpan::from(text)]);
|
||||
self.view.mount(
|
||||
super::COMPONENT_TEXT_WAIT,
|
||||
Box::new(MsgBox::new(builder.build())),
|
||||
Box::new(Paragraph::new(builder.build())),
|
||||
);
|
||||
// Give focus to info
|
||||
self.view.active(super::COMPONENT_TEXT_WAIT);
|
||||
|
@ -466,10 +467,8 @@ impl FileTransferActivity {
|
|||
.with_color(quit_color)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, quit_color)
|
||||
.with_options(
|
||||
Some(String::from("Are you sure you want to quit?")),
|
||||
vec![String::from("Yes"), String::from("No")],
|
||||
)
|
||||
.with_title("Are you sure you want to quit?", Alignment::Center)
|
||||
.with_options(&[String::from("Yes"), String::from("No")])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -496,10 +495,8 @@ impl FileTransferActivity {
|
|||
.with_color(quit_color)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, quit_color)
|
||||
.with_options(
|
||||
Some(String::from("Are you sure you want to disconnect?")),
|
||||
vec![String::from("Yes"), String::from("No")],
|
||||
)
|
||||
.with_title("Are you sure you want to disconnect?", Alignment::Center)
|
||||
.with_options(&[String::from("Yes"), String::from("No")])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -521,7 +518,7 @@ impl FileTransferActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, input_color)
|
||||
.with_foreground(input_color)
|
||||
.with_label(String::from("Copy file(s) to…"))
|
||||
.with_label("Copy file(s) to…", Alignment::Center)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -540,7 +537,7 @@ impl FileTransferActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, input_color)
|
||||
.with_foreground(input_color)
|
||||
.with_label(String::from("Execute command"))
|
||||
.with_label("Execute command", Alignment::Center)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -570,7 +567,10 @@ impl FileTransferActivity {
|
|||
super::COMPONENT_EXPLORER_FIND,
|
||||
Box::new(FileList::new(
|
||||
FileListPropsBuilder::default()
|
||||
.with_files(Some(format!("Search results for \"{}\"", search)), vec![])
|
||||
.with_title(
|
||||
format!("Search results for \"{}\"", search),
|
||||
Alignment::Left,
|
||||
)
|
||||
.with_borders(Borders::ALL, BorderType::Plain, hg)
|
||||
.with_highlight_color(hg)
|
||||
.with_background(bg)
|
||||
|
@ -594,7 +594,7 @@ impl FileTransferActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, input_color)
|
||||
.with_foreground(input_color)
|
||||
.with_label(String::from("Search files by name"))
|
||||
.with_label("Search files by name", Alignment::Center)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -615,7 +615,7 @@ impl FileTransferActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, input_color)
|
||||
.with_foreground(input_color)
|
||||
.with_label(String::from("Change working directory"))
|
||||
.with_label("Change working directory", Alignment::Center)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -634,7 +634,7 @@ impl FileTransferActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, input_color)
|
||||
.with_foreground(input_color)
|
||||
.with_label(String::from("Insert directory name"))
|
||||
.with_label("Insert directory name", Alignment::Center)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -653,7 +653,7 @@ impl FileTransferActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, input_color)
|
||||
.with_foreground(input_color)
|
||||
.with_label(String::from("New file name"))
|
||||
.with_label("New file name", Alignment::Center)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -672,7 +672,7 @@ impl FileTransferActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, input_color)
|
||||
.with_foreground(input_color)
|
||||
.with_label(String::from("Open file with…"))
|
||||
.with_label("Open file with…", Alignment::Center)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -691,7 +691,7 @@ impl FileTransferActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, input_color)
|
||||
.with_foreground(input_color)
|
||||
.with_label(String::from("Move file(s) to…"))
|
||||
.with_label("Move file(s) to…", Alignment::Center)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -710,7 +710,7 @@ impl FileTransferActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, input_color)
|
||||
.with_foreground(input_color)
|
||||
.with_label(String::from("Save as…"))
|
||||
.with_label("Save as…", Alignment::Center)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -735,7 +735,7 @@ impl FileTransferActivity {
|
|||
BorderType::Rounded,
|
||||
Color::Reset,
|
||||
)
|
||||
.with_texts(Some(root_name), String::new())
|
||||
.with_title(root_name, Alignment::Center)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -750,7 +750,7 @@ impl FileTransferActivity {
|
|||
BorderType::Rounded,
|
||||
Color::Reset,
|
||||
)
|
||||
.with_texts(Some(String::from("Please wait")), String::new())
|
||||
.with_title("Please wait", Alignment::Center)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -782,15 +782,13 @@ impl FileTransferActivity {
|
|||
.with_color(sorting_color)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, sorting_color)
|
||||
.with_options(
|
||||
Some(String::from("Sort files by")),
|
||||
vec![
|
||||
String::from("Name"),
|
||||
String::from("Modify time"),
|
||||
String::from("Creation time"),
|
||||
String::from("Size"),
|
||||
],
|
||||
)
|
||||
.with_title("Sort files by", Alignment::Center)
|
||||
.with_options(&[
|
||||
String::from("Name"),
|
||||
String::from("Modify time"),
|
||||
String::from("Creation time"),
|
||||
String::from("Size"),
|
||||
])
|
||||
.with_value(index)
|
||||
.build(),
|
||||
)),
|
||||
|
@ -811,10 +809,8 @@ impl FileTransferActivity {
|
|||
.with_color(warn_color)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Plain, warn_color)
|
||||
.with_options(
|
||||
Some(String::from("Delete file")),
|
||||
vec![String::from("Yes"), String::from("No")],
|
||||
)
|
||||
.with_title("Delete file", Alignment::Center)
|
||||
.with_options(&[String::from("Yes"), String::from("No")])
|
||||
.with_value(1)
|
||||
.build(),
|
||||
)),
|
||||
|
@ -841,54 +837,35 @@ impl FileTransferActivity {
|
|||
None => format!("{}", file.get_abs_path().display()),
|
||||
};
|
||||
// Make texts
|
||||
texts.add_col(TextSpan::from("Path: ")).add_col(
|
||||
TextSpanBuilder::new(path.as_str())
|
||||
.with_foreground(Color::Yellow)
|
||||
.build(),
|
||||
);
|
||||
texts
|
||||
.add_col(TextSpan::from("Path: "))
|
||||
.add_col(TextSpan::new(path.as_str()).fg(Color::Yellow));
|
||||
if let Some(filetype) = file.get_ftype() {
|
||||
texts
|
||||
.add_row()
|
||||
.add_col(TextSpan::from("File type: "))
|
||||
.add_col(
|
||||
TextSpanBuilder::new(filetype.as_str())
|
||||
.with_foreground(Color::LightGreen)
|
||||
.build(),
|
||||
);
|
||||
.add_col(TextSpan::new(filetype.as_str()).fg(Color::LightGreen));
|
||||
}
|
||||
let (bsize, size): (ByteSize, usize) = (ByteSize(file.get_size() as u64), file.get_size());
|
||||
texts.add_row().add_col(TextSpan::from("Size: ")).add_col(
|
||||
TextSpanBuilder::new(format!("{} ({})", bsize, size).as_str())
|
||||
.with_foreground(Color::Cyan)
|
||||
.build(),
|
||||
);
|
||||
texts
|
||||
.add_row()
|
||||
.add_col(TextSpan::from("Size: "))
|
||||
.add_col(TextSpan::new(format!("{} ({})", bsize, size).as_str()).fg(Color::Cyan));
|
||||
let ctime: String = fmt_time(file.get_creation_time(), "%b %d %Y %H:%M:%S");
|
||||
let atime: String = fmt_time(file.get_last_access_time(), "%b %d %Y %H:%M:%S");
|
||||
let mtime: String = fmt_time(file.get_creation_time(), "%b %d %Y %H:%M:%S");
|
||||
texts
|
||||
.add_row()
|
||||
.add_col(TextSpan::from("Creation time: "))
|
||||
.add_col(
|
||||
TextSpanBuilder::new(ctime.as_str())
|
||||
.with_foreground(Color::LightGreen)
|
||||
.build(),
|
||||
);
|
||||
.add_col(TextSpan::new(ctime.as_str()).fg(Color::LightGreen));
|
||||
texts
|
||||
.add_row()
|
||||
.add_col(TextSpan::from("Last modified time: "))
|
||||
.add_col(
|
||||
TextSpanBuilder::new(mtime.as_str())
|
||||
.with_foreground(Color::LightBlue)
|
||||
.build(),
|
||||
);
|
||||
.add_col(TextSpan::new(mtime.as_str()).fg(Color::LightBlue));
|
||||
texts
|
||||
.add_row()
|
||||
.add_col(TextSpan::from("Last access time: "))
|
||||
.add_col(
|
||||
TextSpanBuilder::new(atime.as_str())
|
||||
.with_foreground(Color::LightRed)
|
||||
.build(),
|
||||
);
|
||||
.add_col(TextSpan::new(atime.as_str()).fg(Color::LightRed));
|
||||
// User
|
||||
#[cfg(target_family = "unix")]
|
||||
let username: String = match file.get_user() {
|
||||
|
@ -911,22 +888,21 @@ impl FileTransferActivity {
|
|||
};
|
||||
#[cfg(target_os = "windows")]
|
||||
let group: String = format!("{}", file.get_group().unwrap_or(0));
|
||||
texts.add_row().add_col(TextSpan::from("User: ")).add_col(
|
||||
TextSpanBuilder::new(username.as_str())
|
||||
.with_foreground(Color::LightYellow)
|
||||
.build(),
|
||||
);
|
||||
texts.add_row().add_col(TextSpan::from("Group: ")).add_col(
|
||||
TextSpanBuilder::new(group.as_str())
|
||||
.with_foreground(Color::Blue)
|
||||
.build(),
|
||||
);
|
||||
texts
|
||||
.add_row()
|
||||
.add_col(TextSpan::from("User: "))
|
||||
.add_col(TextSpan::new(username.as_str()).fg(Color::LightYellow));
|
||||
texts
|
||||
.add_row()
|
||||
.add_col(TextSpan::from("Group: "))
|
||||
.add_col(TextSpan::new(group.as_str()).fg(Color::Blue));
|
||||
self.view.mount(
|
||||
super::COMPONENT_LIST_FILEINFO,
|
||||
Box::new(Table::new(
|
||||
TablePropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::White)
|
||||
.with_table(Some(file.get_name().to_string()), texts.build())
|
||||
.with_title(file.get_name(), Alignment::Left)
|
||||
.with_table(texts.build())
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -941,22 +917,16 @@ impl FileTransferActivity {
|
|||
let sorting_color = self.theme().transfer_status_sorting;
|
||||
let hidden_color = self.theme().transfer_status_hidden;
|
||||
let local_bar_spans: Vec<TextSpan> = vec![
|
||||
TextSpanBuilder::new("File sorting: ")
|
||||
.with_foreground(sorting_color)
|
||||
.build(),
|
||||
TextSpanBuilder::new(Self::get_file_sorting_str(self.local().get_file_sorting()))
|
||||
.with_foreground(sorting_color)
|
||||
.reversed()
|
||||
.build(),
|
||||
TextSpanBuilder::new(" Hidden files: ")
|
||||
.with_foreground(hidden_color)
|
||||
.build(),
|
||||
TextSpanBuilder::new(Self::get_hidden_files_str(
|
||||
TextSpan::new("File sorting: ").fg(sorting_color),
|
||||
TextSpan::new(Self::get_file_sorting_str(self.local().get_file_sorting()))
|
||||
.fg(sorting_color)
|
||||
.reversed(),
|
||||
TextSpan::new(" Hidden files: ").fg(hidden_color),
|
||||
TextSpan::new(Self::get_hidden_files_str(
|
||||
self.local().hidden_files_visible(),
|
||||
))
|
||||
.with_foreground(hidden_color)
|
||||
.reversed()
|
||||
.build(),
|
||||
.fg(hidden_color)
|
||||
.reversed(),
|
||||
];
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_SPAN_STATUS_BAR_LOCAL) {
|
||||
self.view.update(
|
||||
|
@ -973,32 +943,23 @@ impl FileTransferActivity {
|
|||
let hidden_color = self.theme().transfer_status_hidden;
|
||||
let sync_color = self.theme().transfer_status_sync_browsing;
|
||||
let remote_bar_spans: Vec<TextSpan> = vec![
|
||||
TextSpanBuilder::new("File sorting: ")
|
||||
.with_foreground(sorting_color)
|
||||
.build(),
|
||||
TextSpanBuilder::new(Self::get_file_sorting_str(self.remote().get_file_sorting()))
|
||||
.with_foreground(sorting_color)
|
||||
.reversed()
|
||||
.build(),
|
||||
TextSpanBuilder::new(" Hidden files: ")
|
||||
.with_foreground(hidden_color)
|
||||
.build(),
|
||||
TextSpanBuilder::new(Self::get_hidden_files_str(
|
||||
TextSpan::new("File sorting: ").fg(sorting_color),
|
||||
TextSpan::new(Self::get_file_sorting_str(self.remote().get_file_sorting()))
|
||||
.fg(sorting_color)
|
||||
.reversed(),
|
||||
TextSpan::new(" Hidden files: ").fg(hidden_color),
|
||||
TextSpan::new(Self::get_hidden_files_str(
|
||||
self.remote().hidden_files_visible(),
|
||||
))
|
||||
.with_foreground(hidden_color)
|
||||
.reversed()
|
||||
.build(),
|
||||
TextSpanBuilder::new(" Sync Browsing: ")
|
||||
.with_foreground(sync_color)
|
||||
.build(),
|
||||
TextSpanBuilder::new(match self.browser.sync_browsing {
|
||||
.fg(hidden_color)
|
||||
.reversed(),
|
||||
TextSpan::new(" Sync Browsing: ").fg(sync_color),
|
||||
TextSpan::new(match self.browser.sync_browsing {
|
||||
true => "ON ",
|
||||
false => "OFF",
|
||||
})
|
||||
.with_foreground(sync_color)
|
||||
.reversed()
|
||||
.build(),
|
||||
.fg(sync_color)
|
||||
.reversed(),
|
||||
];
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_SPAN_STATUS_BAR_REMOTE) {
|
||||
self.view.update(
|
||||
|
@ -1017,253 +978,109 @@ impl FileTransferActivity {
|
|||
let key_color = self.theme().misc_keys;
|
||||
self.view.mount(
|
||||
super::COMPONENT_TEXT_HELP,
|
||||
Box::new(Scrolltable::new(
|
||||
ScrollTablePropsBuilder::default()
|
||||
Box::new(List::new(
|
||||
ListPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::White)
|
||||
.with_highlighted_str(Some("?"))
|
||||
.with_max_scroll_step(8)
|
||||
.bold()
|
||||
.with_table(
|
||||
Some(String::from("Help")),
|
||||
.scrollable(true)
|
||||
.with_title("Help", Alignment::Center)
|
||||
.with_rows(
|
||||
TableBuilder::default()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<ESC>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<ESC>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Disconnect"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<TAB>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<TAB>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(
|
||||
" Switch between explorer and logs",
|
||||
))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<BACKSPACE>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<BACKSPACE>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Go to previous directory"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<RIGHT/LEFT>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<RIGHT/LEFT>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Change explorer tab"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<UP/DOWN>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<UP/DOWN>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Move up/down in list"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<ENTER>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<ENTER>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Enter directory"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<SPACE>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<SPACE>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Upload/Download file"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<A>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<A>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Toggle hidden files"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<B>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<B>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Change file sorting mode"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<C>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<C>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Copy"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<D>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<D>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Make directory"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<G>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<G>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Go to path"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<H>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<H>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Show help"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<I>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<I>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Show info about selected file"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<L>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<L>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Reload directory content"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<M>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<M>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Select file"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<N>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<N>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Create new file"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<O>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<O>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(
|
||||
" Open text file with preferred editor",
|
||||
))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<Q>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<Q>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Quit termscp"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<R>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<R>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Rename file"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<S>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<S>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Save file as"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<U>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<U>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Go to parent directory"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<V>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<V>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(
|
||||
" Open file with default application for file type",
|
||||
))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<W>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<W>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(
|
||||
" Open file with specified application",
|
||||
))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<X>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<X>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Execute shell command"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<Y>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<Y>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Toggle synchronized browsing"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<DEL|E>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<DEL|E>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Delete selected file"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<CTRL+A>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<CTRL+A>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Select all files"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<CTRL+C>")
|
||||
.bold()
|
||||
.with_foreground(key_color)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<CTRL+C>").bold().fg(key_color))
|
||||
.add_col(TextSpan::from(" Interrupt file transfer"))
|
||||
.build(),
|
||||
)
|
||||
|
|
|
@ -74,65 +74,67 @@ impl SetupActivity {
|
|||
None => None,
|
||||
Some(msg) => match msg {
|
||||
// Input field <DOWN>
|
||||
(COMPONENT_INPUT_TEXT_EDITOR, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_INPUT_TEXT_EDITOR, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_RADIO_DEFAULT_PROTOCOL);
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_DEFAULT_PROTOCOL, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_RADIO_DEFAULT_PROTOCOL, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_RADIO_HIDDEN_FILES);
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_HIDDEN_FILES, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_RADIO_HIDDEN_FILES, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_RADIO_UPDATES);
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_UPDATES, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_RADIO_UPDATES, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_RADIO_GROUP_DIRS);
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_GROUP_DIRS, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_RADIO_GROUP_DIRS, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_INPUT_LOCAL_FILE_FMT);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_LOCAL_FILE_FMT, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_INPUT_LOCAL_FILE_FMT, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_INPUT_REMOTE_FILE_FMT);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_REMOTE_FILE_FMT, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_INPUT_REMOTE_FILE_FMT, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_INPUT_TEXT_EDITOR);
|
||||
None
|
||||
}
|
||||
// Input field <UP>
|
||||
(COMPONENT_INPUT_REMOTE_FILE_FMT, &MSG_KEY_UP) => {
|
||||
(COMPONENT_INPUT_REMOTE_FILE_FMT, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_INPUT_LOCAL_FILE_FMT);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_LOCAL_FILE_FMT, &MSG_KEY_UP) => {
|
||||
(COMPONENT_INPUT_LOCAL_FILE_FMT, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_RADIO_GROUP_DIRS);
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_GROUP_DIRS, &MSG_KEY_UP) => {
|
||||
(COMPONENT_RADIO_GROUP_DIRS, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_RADIO_UPDATES);
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_UPDATES, &MSG_KEY_UP) => {
|
||||
(COMPONENT_RADIO_UPDATES, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_RADIO_HIDDEN_FILES);
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_HIDDEN_FILES, &MSG_KEY_UP) => {
|
||||
(COMPONENT_RADIO_HIDDEN_FILES, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_RADIO_DEFAULT_PROTOCOL);
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_DEFAULT_PROTOCOL, &MSG_KEY_UP) => {
|
||||
(COMPONENT_RADIO_DEFAULT_PROTOCOL, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_INPUT_TEXT_EDITOR);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_TEXT_EDITOR, &MSG_KEY_UP) => {
|
||||
(COMPONENT_INPUT_TEXT_EDITOR, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_INPUT_REMOTE_FILE_FMT);
|
||||
None
|
||||
}
|
||||
// Error <ENTER> or <ESC>
|
||||
(COMPONENT_TEXT_ERROR, &MSG_KEY_ENTER) | (COMPONENT_TEXT_ERROR, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_TEXT_ERROR, key) | (COMPONENT_TEXT_ERROR, key)
|
||||
if key == &MSG_KEY_ESC || key == &MSG_KEY_ENTER =>
|
||||
{
|
||||
// Umount text error
|
||||
self.umount_error();
|
||||
None
|
||||
|
@ -161,7 +163,9 @@ impl SetupActivity {
|
|||
}
|
||||
(COMPONENT_RADIO_QUIT, _) => None,
|
||||
// Close help
|
||||
(COMPONENT_TEXT_HELP, &MSG_KEY_ENTER) | (COMPONENT_TEXT_HELP, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_TEXT_HELP, key) | (COMPONENT_TEXT_HELP, key)
|
||||
if key == &MSG_KEY_ESC || key == &MSG_KEY_ENTER =>
|
||||
{
|
||||
// Umount help
|
||||
self.umount_help();
|
||||
None
|
||||
|
@ -189,12 +193,12 @@ impl SetupActivity {
|
|||
None
|
||||
}
|
||||
// <CTRL+H> Show help
|
||||
(_, &MSG_KEY_CTRL_H) => {
|
||||
(_, key) if key == &MSG_KEY_CTRL_H => {
|
||||
// Show help
|
||||
self.mount_help();
|
||||
None
|
||||
}
|
||||
(_, &MSG_KEY_TAB) => {
|
||||
(_, key) if key == &MSG_KEY_TAB => {
|
||||
// Change view
|
||||
if let Err(err) = self.action_change_tab(ViewLayout::SshKeys) {
|
||||
self.mount_error(err.as_str());
|
||||
|
@ -202,7 +206,7 @@ impl SetupActivity {
|
|||
None
|
||||
}
|
||||
// <CTRL+R> Revert changes
|
||||
(_, &MSG_KEY_CTRL_R) => {
|
||||
(_, key) if key == &MSG_KEY_CTRL_R => {
|
||||
// Revert changes
|
||||
if let Err(err) = self.action_reset_config() {
|
||||
self.mount_error(err.as_str());
|
||||
|
@ -210,13 +214,13 @@ impl SetupActivity {
|
|||
None
|
||||
}
|
||||
// <CTRL+S> Save
|
||||
(_, &MSG_KEY_CTRL_S) => {
|
||||
(_, key) if key == &MSG_KEY_CTRL_S => {
|
||||
// Show save
|
||||
self.mount_save_popup();
|
||||
None
|
||||
}
|
||||
// <ESC>
|
||||
(_, &MSG_KEY_ESC) => {
|
||||
(_, key) if key == &MSG_KEY_ESC => {
|
||||
self.action_on_esc();
|
||||
None
|
||||
}
|
||||
|
@ -232,7 +236,9 @@ impl SetupActivity {
|
|||
None => None,
|
||||
Some(msg) => match msg {
|
||||
// Error <ENTER> or <ESC>
|
||||
(COMPONENT_TEXT_ERROR, &MSG_KEY_ENTER) | (COMPONENT_TEXT_ERROR, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_TEXT_ERROR, key) | (COMPONENT_TEXT_ERROR, key)
|
||||
if key == &MSG_KEY_ESC || key == &MSG_KEY_ENTER =>
|
||||
{
|
||||
// Umount text error
|
||||
self.umount_error();
|
||||
None
|
||||
|
@ -261,7 +267,9 @@ impl SetupActivity {
|
|||
}
|
||||
(COMPONENT_RADIO_QUIT, _) => None,
|
||||
// Close help
|
||||
(COMPONENT_TEXT_HELP, &MSG_KEY_ENTER) | (COMPONENT_TEXT_HELP, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_TEXT_HELP, key) | (COMPONENT_TEXT_HELP, key)
|
||||
if key == &MSG_KEY_ESC || key == &MSG_KEY_ENTER =>
|
||||
{
|
||||
// Umount help
|
||||
self.umount_help();
|
||||
None
|
||||
|
@ -300,28 +308,30 @@ impl SetupActivity {
|
|||
(COMPONENT_RADIO_SAVE, _) => None,
|
||||
// Edit SSH Key
|
||||
// <CTRL+H> Show help
|
||||
(_, &MSG_KEY_CTRL_H) => {
|
||||
(_, key) if key == &MSG_KEY_CTRL_H => {
|
||||
// Show help
|
||||
self.mount_help();
|
||||
None
|
||||
}
|
||||
// New key <DOWN>
|
||||
(COMPONENT_INPUT_SSH_HOST, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_INPUT_SSH_HOST, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_INPUT_SSH_USERNAME);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_SSH_USERNAME, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_INPUT_SSH_USERNAME, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_INPUT_SSH_HOST);
|
||||
None
|
||||
}
|
||||
// New key <UP>
|
||||
(COMPONENT_INPUT_SSH_USERNAME, &MSG_KEY_UP)
|
||||
| (COMPONENT_INPUT_SSH_USERNAME, &MSG_KEY_TAB) => {
|
||||
(COMPONENT_INPUT_SSH_USERNAME, key) | (COMPONENT_INPUT_SSH_USERNAME, key)
|
||||
if key == &MSG_KEY_UP || key == &MSG_KEY_TAB =>
|
||||
{
|
||||
self.view.active(COMPONENT_INPUT_SSH_HOST);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_SSH_HOST, &MSG_KEY_UP)
|
||||
| (COMPONENT_INPUT_SSH_HOST, &MSG_KEY_TAB) => {
|
||||
(COMPONENT_INPUT_SSH_HOST, key) | (COMPONENT_INPUT_SSH_HOST, key)
|
||||
if key == &MSG_KEY_UP || key == &MSG_KEY_TAB =>
|
||||
{
|
||||
self.view.active(COMPONENT_INPUT_SSH_USERNAME);
|
||||
None
|
||||
}
|
||||
|
@ -335,14 +345,15 @@ impl SetupActivity {
|
|||
None
|
||||
}
|
||||
// New key <ESC>
|
||||
(COMPONENT_INPUT_SSH_HOST, &MSG_KEY_ESC)
|
||||
| (COMPONENT_INPUT_SSH_USERNAME, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_INPUT_SSH_HOST, key) | (COMPONENT_INPUT_SSH_USERNAME, key)
|
||||
if key == &MSG_KEY_ESC =>
|
||||
{
|
||||
// Umount new ssh key
|
||||
self.umount_new_ssh_key();
|
||||
None
|
||||
}
|
||||
// <CTRL+N> New key
|
||||
(COMPONENT_LIST_SSH_KEYS, &MSG_KEY_CTRL_N) => {
|
||||
(COMPONENT_LIST_SSH_KEYS, key) if key == &MSG_KEY_CTRL_N => {
|
||||
// Show new key popup
|
||||
self.mount_new_ssh_key();
|
||||
None
|
||||
|
@ -356,13 +367,14 @@ impl SetupActivity {
|
|||
None
|
||||
}
|
||||
// <DEL | CTRL+E> Show delete
|
||||
(COMPONENT_LIST_SSH_KEYS, &MSG_KEY_CTRL_E)
|
||||
| (COMPONENT_LIST_SSH_KEYS, &MSG_KEY_DEL) => {
|
||||
(COMPONENT_LIST_SSH_KEYS, key) | (COMPONENT_LIST_SSH_KEYS, key)
|
||||
if key == &MSG_KEY_CTRL_E || key == &MSG_KEY_DEL =>
|
||||
{
|
||||
// Show delete key
|
||||
self.mount_del_ssh_key();
|
||||
None
|
||||
}
|
||||
(_, &MSG_KEY_TAB) => {
|
||||
(_, key) if key == &MSG_KEY_TAB => {
|
||||
// Change view
|
||||
if let Err(err) = self.action_change_tab(ViewLayout::Theme) {
|
||||
self.mount_error(err.as_str());
|
||||
|
@ -370,7 +382,7 @@ impl SetupActivity {
|
|||
None
|
||||
}
|
||||
// <CTRL+R> Revert changes
|
||||
(_, &MSG_KEY_CTRL_R) => {
|
||||
(_, key) if key == &MSG_KEY_CTRL_R => {
|
||||
// Revert changes
|
||||
if let Err(err) = self.action_reset_config() {
|
||||
self.mount_error(err.as_str());
|
||||
|
@ -378,13 +390,13 @@ impl SetupActivity {
|
|||
None
|
||||
}
|
||||
// <CTRL+S> Save
|
||||
(_, &MSG_KEY_CTRL_S) => {
|
||||
(_, key) if key == &MSG_KEY_CTRL_S => {
|
||||
// Show save
|
||||
self.mount_save_popup();
|
||||
None
|
||||
}
|
||||
// <ESC>
|
||||
(_, &MSG_KEY_ESC) => {
|
||||
(_, key) if key == &MSG_KEY_ESC => {
|
||||
self.action_on_esc();
|
||||
None
|
||||
}
|
||||
|
@ -400,217 +412,217 @@ impl SetupActivity {
|
|||
None => None,
|
||||
Some(msg) => match msg {
|
||||
// Input fields
|
||||
(COMPONENT_COLOR_AUTH_PROTOCOL, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_AUTH_PROTOCOL, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_AUTH_ADDR);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_AUTH_ADDR, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_AUTH_ADDR, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_AUTH_PORT);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_AUTH_PORT, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_AUTH_PORT, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_AUTH_USERNAME);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_AUTH_USERNAME, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_AUTH_USERNAME, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_AUTH_PASSWORD);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_AUTH_PASSWORD, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_AUTH_PASSWORD, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_AUTH_BOOKMARKS);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_AUTH_BOOKMARKS, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_AUTH_BOOKMARKS, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_AUTH_RECENTS);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_AUTH_RECENTS, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_AUTH_RECENTS, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_MISC_ERROR);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_MISC_ERROR, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_MISC_ERROR, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_MISC_INPUT);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_MISC_INPUT, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_MISC_INPUT, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_MISC_KEYS);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_MISC_KEYS, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_MISC_KEYS, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_MISC_QUIT);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_MISC_QUIT, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_MISC_QUIT, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_MISC_SAVE);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_MISC_SAVE, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_MISC_SAVE, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_MISC_WARN);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_MISC_WARN, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_MISC_WARN, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_BG);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_BG, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_BG, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_FG);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_FG, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_FG, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_HG);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_HG, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_HG, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view
|
||||
.active(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_BG);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_BG, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_BG, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view
|
||||
.active(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_FG);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_FG, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_FG, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view
|
||||
.active(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_HG);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_HG, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_HG, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_PROG_BAR_FULL);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_PROG_BAR_FULL, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_TRANSFER_PROG_BAR_FULL, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_PROG_BAR_PARTIAL);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_PROG_BAR_PARTIAL, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_TRANSFER_PROG_BAR_PARTIAL, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_LOG_BG);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_LOG_BG, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_TRANSFER_LOG_BG, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_LOG_WIN);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_LOG_WIN, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_TRANSFER_LOG_WIN, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_STATUS_SORTING);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_STATUS_SORTING, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_TRANSFER_STATUS_SORTING, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_STATUS_HIDDEN);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_STATUS_HIDDEN, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_TRANSFER_STATUS_HIDDEN, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_STATUS_SYNC);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_STATUS_SYNC, &MSG_KEY_DOWN) => {
|
||||
(COMPONENT_COLOR_TRANSFER_STATUS_SYNC, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_COLOR_AUTH_PROTOCOL);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_AUTH_PROTOCOL, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_AUTH_PROTOCOL, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_STATUS_SYNC);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_AUTH_ADDR, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_AUTH_ADDR, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_AUTH_PROTOCOL);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_AUTH_PORT, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_AUTH_PORT, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_AUTH_ADDR);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_AUTH_USERNAME, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_AUTH_USERNAME, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_AUTH_PORT);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_AUTH_PASSWORD, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_AUTH_PASSWORD, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_AUTH_USERNAME);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_AUTH_BOOKMARKS, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_AUTH_BOOKMARKS, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_AUTH_PASSWORD);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_AUTH_RECENTS, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_AUTH_RECENTS, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_AUTH_BOOKMARKS);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_MISC_ERROR, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_MISC_ERROR, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_AUTH_RECENTS);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_MISC_INPUT, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_MISC_INPUT, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_MISC_ERROR);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_MISC_KEYS, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_MISC_KEYS, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_MISC_INPUT);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_MISC_QUIT, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_MISC_QUIT, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_MISC_KEYS);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_MISC_SAVE, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_MISC_SAVE, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_MISC_QUIT);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_MISC_WARN, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_MISC_WARN, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_MISC_SAVE);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_BG, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_BG, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_MISC_WARN);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_FG, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_FG, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_BG);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_HG, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_HG, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_FG);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_BG, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_BG, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_HG);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_FG, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_FG, key) if key == &MSG_KEY_UP => {
|
||||
self.view
|
||||
.active(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_BG);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_HG, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_HG, key) if key == &MSG_KEY_UP => {
|
||||
self.view
|
||||
.active(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_FG);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_PROG_BAR_FULL, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_TRANSFER_PROG_BAR_FULL, key) if key == &MSG_KEY_UP => {
|
||||
self.view
|
||||
.active(COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_HG);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_PROG_BAR_PARTIAL, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_TRANSFER_PROG_BAR_PARTIAL, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_PROG_BAR_FULL);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_LOG_BG, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_TRANSFER_LOG_BG, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_PROG_BAR_PARTIAL);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_LOG_WIN, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_TRANSFER_LOG_WIN, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_LOG_BG);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_STATUS_SORTING, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_TRANSFER_STATUS_SORTING, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_LOG_WIN);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_STATUS_HIDDEN, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_TRANSFER_STATUS_HIDDEN, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_STATUS_SORTING);
|
||||
None
|
||||
}
|
||||
(COMPONENT_COLOR_TRANSFER_STATUS_SYNC, &MSG_KEY_UP) => {
|
||||
(COMPONENT_COLOR_TRANSFER_STATUS_SYNC, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_COLOR_TRANSFER_STATUS_HIDDEN);
|
||||
None
|
||||
}
|
||||
|
@ -624,7 +636,9 @@ impl SetupActivity {
|
|||
None
|
||||
}
|
||||
// Error <ENTER> or <ESC>
|
||||
(COMPONENT_TEXT_ERROR, &MSG_KEY_ENTER) | (COMPONENT_TEXT_ERROR, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_TEXT_ERROR, key) | (COMPONENT_TEXT_ERROR, key)
|
||||
if key == &MSG_KEY_ESC || key == &MSG_KEY_ENTER =>
|
||||
{
|
||||
// Umount text error
|
||||
self.umount_error();
|
||||
None
|
||||
|
@ -653,7 +667,9 @@ impl SetupActivity {
|
|||
}
|
||||
(COMPONENT_RADIO_QUIT, _) => None,
|
||||
// Close help
|
||||
(COMPONENT_TEXT_HELP, &MSG_KEY_ENTER) | (COMPONENT_TEXT_HELP, &MSG_KEY_ESC) => {
|
||||
(COMPONENT_TEXT_HELP, key) | (COMPONENT_TEXT_HELP, key)
|
||||
if key == &MSG_KEY_ESC || key == &MSG_KEY_ENTER =>
|
||||
{
|
||||
// Umount help
|
||||
self.umount_help();
|
||||
None
|
||||
|
@ -676,12 +692,12 @@ impl SetupActivity {
|
|||
(COMPONENT_RADIO_SAVE, _) => None,
|
||||
// Edit SSH Key
|
||||
// <CTRL+H> Show help
|
||||
(_, &MSG_KEY_CTRL_H) => {
|
||||
(_, key) if key == &MSG_KEY_CTRL_H => {
|
||||
// Show help
|
||||
self.mount_help();
|
||||
None
|
||||
}
|
||||
(_, &MSG_KEY_TAB) => {
|
||||
(_, key) if key == &MSG_KEY_TAB => {
|
||||
// Change view
|
||||
if let Err(err) = self.action_change_tab(ViewLayout::SetupForm) {
|
||||
self.mount_error(err.as_str());
|
||||
|
@ -689,7 +705,7 @@ impl SetupActivity {
|
|||
None
|
||||
}
|
||||
// <CTRL+R> Revert changes
|
||||
(_, &MSG_KEY_CTRL_R) => {
|
||||
(_, key) if key == &MSG_KEY_CTRL_R => {
|
||||
// Revert changes
|
||||
if let Err(err) = self.action_reset_theme() {
|
||||
self.mount_error(err.as_str());
|
||||
|
@ -697,13 +713,13 @@ impl SetupActivity {
|
|||
None
|
||||
}
|
||||
// <CTRL+S> Save
|
||||
(_, &MSG_KEY_CTRL_S) => {
|
||||
(_, key) if key == &MSG_KEY_CTRL_S => {
|
||||
// Show save
|
||||
self.mount_save_popup();
|
||||
None
|
||||
}
|
||||
// <ESC>
|
||||
(_, &MSG_KEY_ESC) => {
|
||||
(_, key) if key == &MSG_KEY_ESC => {
|
||||
self.action_on_esc();
|
||||
None
|
||||
}
|
||||
|
|
|
@ -34,14 +34,14 @@ use super::*;
|
|||
pub use setup::*;
|
||||
pub use ssh_keys::*;
|
||||
pub use theme::*;
|
||||
// Locals
|
||||
use crate::ui::components::msgbox::{MsgBox, MsgBoxPropsBuilder};
|
||||
// Ext
|
||||
use tuirealm::components::{
|
||||
use tui_realm_stdlib::{
|
||||
list::{List, ListPropsBuilder},
|
||||
paragraph::{Paragraph, ParagraphPropsBuilder},
|
||||
radio::{Radio, RadioPropsBuilder},
|
||||
scrolltable::{ScrollTablePropsBuilder, Scrolltable},
|
||||
span::{Span, SpanPropsBuilder},
|
||||
};
|
||||
use tuirealm::props::{PropsBuilder, TableBuilder, TextSpan, TextSpanBuilder};
|
||||
use tuirealm::props::{Alignment, PropsBuilder, TableBuilder, TextSpan};
|
||||
use tuirealm::tui::{
|
||||
style::Color,
|
||||
widgets::{BorderType, Borders},
|
||||
|
@ -79,12 +79,13 @@ impl SetupActivity {
|
|||
// Mount
|
||||
self.view.mount(
|
||||
super::COMPONENT_TEXT_ERROR,
|
||||
Box::new(MsgBox::new(
|
||||
MsgBoxPropsBuilder::default()
|
||||
Box::new(Paragraph::new(
|
||||
ParagraphPropsBuilder::default()
|
||||
.with_foreground(Color::Red)
|
||||
.bold()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::Red)
|
||||
.with_texts(None, vec![TextSpan::from(text)])
|
||||
.with_texts(vec![TextSpan::from(text)])
|
||||
.with_text_alignment(Alignment::Center)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -110,16 +111,15 @@ impl SetupActivity {
|
|||
.with_color(Color::LightRed)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightRed)
|
||||
.with_options(
|
||||
Some(String::from(
|
||||
"There are unsaved changes! Save changes before leaving?",
|
||||
)),
|
||||
vec![
|
||||
String::from("Save"),
|
||||
String::from("Don't save"),
|
||||
String::from("Cancel"),
|
||||
],
|
||||
.with_title(
|
||||
"There are unsaved changes! Save changes before leaving?",
|
||||
Alignment::Center,
|
||||
)
|
||||
.with_options(&[
|
||||
String::from("Save"),
|
||||
String::from("Don't save"),
|
||||
String::from("Cancel"),
|
||||
])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -145,10 +145,8 @@ impl SetupActivity {
|
|||
.with_color(Color::LightYellow)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightYellow)
|
||||
.with_options(
|
||||
Some(String::from("Save changes?")),
|
||||
vec![String::from("Yes"), String::from("No")],
|
||||
)
|
||||
.with_title("Save changes?", Alignment::Center)
|
||||
.with_options(&[String::from("Yes"), String::from("No")])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -163,91 +161,81 @@ impl SetupActivity {
|
|||
self.view.umount(super::COMPONENT_RADIO_SAVE);
|
||||
}
|
||||
|
||||
pub(self) fn mount_header_tab(&mut self, idx: usize) {
|
||||
self.view.mount(
|
||||
super::COMPONENT_RADIO_TAB,
|
||||
Box::new(Radio::new(
|
||||
RadioPropsBuilder::default()
|
||||
.with_color(Color::LightYellow)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::BOTTOM, BorderType::Thick, Color::White)
|
||||
.with_options(&[
|
||||
String::from("User Interface"),
|
||||
String::from("SSH Keys"),
|
||||
String::from("Theme"),
|
||||
])
|
||||
.with_value(idx)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
pub(self) fn mount_footer(&mut self) {
|
||||
self.view.mount(
|
||||
super::COMPONENT_TEXT_FOOTER,
|
||||
Box::new(Span::new(
|
||||
SpanPropsBuilder::default()
|
||||
.with_spans(vec![
|
||||
TextSpan::new("Press ").bold(),
|
||||
TextSpan::new("<CTRL+H>").bold().fg(Color::Cyan),
|
||||
TextSpan::new(" to show keybindings").bold(),
|
||||
])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
/// ### mount_help
|
||||
///
|
||||
/// Mount help
|
||||
pub(super) fn mount_help(&mut self) {
|
||||
self.view.mount(
|
||||
super::COMPONENT_TEXT_HELP,
|
||||
Box::new(Scrolltable::new(
|
||||
ScrollTablePropsBuilder::default()
|
||||
Box::new(List::new(
|
||||
ListPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::White)
|
||||
.with_highlighted_str(Some("?"))
|
||||
.with_max_scroll_step(8)
|
||||
.bold()
|
||||
.with_table(
|
||||
Some(String::from("Help")),
|
||||
.with_title("Help", Alignment::Center)
|
||||
.scrollable(true)
|
||||
.with_rows(
|
||||
TableBuilder::default()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<ESC>")
|
||||
.bold()
|
||||
.with_foreground(Color::Cyan)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<ESC>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Exit setup"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<TAB>")
|
||||
.bold()
|
||||
.with_foreground(Color::Cyan)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<TAB>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Change setup page"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<RIGHT/LEFT>")
|
||||
.bold()
|
||||
.with_foreground(Color::Cyan)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<RIGHT/LEFT>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Change cursor"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<UP/DOWN>")
|
||||
.bold()
|
||||
.with_foreground(Color::Cyan)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<UP/DOWN>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Change input field"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<ENTER>")
|
||||
.bold()
|
||||
.with_foreground(Color::Cyan)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<ENTER>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Select / Dismiss popup"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<DEL|E>")
|
||||
.bold()
|
||||
.with_foreground(Color::Cyan)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<DEL|E>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Delete SSH key"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<CTRL+N>")
|
||||
.bold()
|
||||
.with_foreground(Color::Cyan)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<CTRL+N>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" New SSH key"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<CTRL+R>")
|
||||
.bold()
|
||||
.with_foreground(Color::Cyan)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<CTRL+R>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Revert changes"))
|
||||
.add_row()
|
||||
.add_col(
|
||||
TextSpanBuilder::new("<CTRL+S>")
|
||||
.bold()
|
||||
.with_foreground(Color::Cyan)
|
||||
.build(),
|
||||
)
|
||||
.add_col(TextSpan::new("<CTRL+S>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Save configuration"))
|
||||
.build(),
|
||||
)
|
||||
|
|
|
@ -33,10 +33,9 @@ use crate::fs::explorer::GroupDirs;
|
|||
use crate::utils::ui::draw_area_in;
|
||||
// Ext
|
||||
use std::path::PathBuf;
|
||||
use tuirealm::components::{
|
||||
use tui_realm_stdlib::{
|
||||
input::{Input, InputPropsBuilder},
|
||||
radio::{Radio, RadioPropsBuilder},
|
||||
span::{Span, SpanPropsBuilder},
|
||||
};
|
||||
use tuirealm::tui::{
|
||||
layout::{Constraint, Direction, Layout},
|
||||
|
@ -44,7 +43,7 @@ use tuirealm::tui::{
|
|||
widgets::{BorderType, Borders, Clear},
|
||||
};
|
||||
use tuirealm::{
|
||||
props::{PropsBuilder, TextSpanBuilder},
|
||||
props::{Alignment, PropsBuilder},
|
||||
Payload, Value, View,
|
||||
};
|
||||
|
||||
|
@ -59,41 +58,9 @@ impl SetupActivity {
|
|||
self.view = View::init();
|
||||
// Common stuff
|
||||
// Radio tab
|
||||
self.view.mount(
|
||||
super::COMPONENT_RADIO_TAB,
|
||||
Box::new(Radio::new(
|
||||
RadioPropsBuilder::default()
|
||||
.with_color(Color::LightYellow)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::BOTTOM, BorderType::Thick, Color::White)
|
||||
.with_options(
|
||||
None,
|
||||
vec![
|
||||
String::from("User Interface"),
|
||||
String::from("SSH Keys"),
|
||||
String::from("Theme"),
|
||||
],
|
||||
)
|
||||
.with_value(0)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
self.mount_header_tab(0);
|
||||
// Footer
|
||||
self.view.mount(
|
||||
super::COMPONENT_TEXT_FOOTER,
|
||||
Box::new(Span::new(
|
||||
SpanPropsBuilder::default()
|
||||
.with_spans(vec![
|
||||
TextSpanBuilder::new("Press ").bold().build(),
|
||||
TextSpanBuilder::new("<CTRL+H>")
|
||||
.bold()
|
||||
.with_foreground(Color::Cyan)
|
||||
.build(),
|
||||
TextSpanBuilder::new(" to show keybindings").bold().build(),
|
||||
])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
self.mount_footer();
|
||||
// Input fields
|
||||
self.view.mount(
|
||||
super::COMPONENT_INPUT_TEXT_EDITOR,
|
||||
|
@ -101,7 +68,7 @@ impl SetupActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_foreground(Color::LightGreen)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightGreen)
|
||||
.with_label(String::from("Text editor"))
|
||||
.with_label("Text editor", Alignment::Left)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -113,15 +80,13 @@ impl SetupActivity {
|
|||
.with_color(Color::LightCyan)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightCyan)
|
||||
.with_options(
|
||||
Some(String::from("Default file transfer protocol")),
|
||||
vec![
|
||||
String::from("SFTP"),
|
||||
String::from("SCP"),
|
||||
String::from("FTP"),
|
||||
String::from("FTPS"),
|
||||
],
|
||||
)
|
||||
.with_title("Default file transfer protocol", Alignment::Left)
|
||||
.with_options(&[
|
||||
String::from("SFTP"),
|
||||
String::from("SCP"),
|
||||
String::from("FTP"),
|
||||
String::from("FTPS"),
|
||||
])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -132,10 +97,8 @@ impl SetupActivity {
|
|||
.with_color(Color::LightRed)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightRed)
|
||||
.with_options(
|
||||
Some(String::from("Show hidden files (by default)")),
|
||||
vec![String::from("Yes"), String::from("No")],
|
||||
)
|
||||
.with_title("Show hidden files (by default)?", Alignment::Left)
|
||||
.with_options(&[String::from("Yes"), String::from("No")])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -146,10 +109,8 @@ impl SetupActivity {
|
|||
.with_color(Color::LightYellow)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightYellow)
|
||||
.with_options(
|
||||
Some(String::from("Check for updates?")),
|
||||
vec![String::from("Yes"), String::from("No")],
|
||||
)
|
||||
.with_title("Check for updates?", Alignment::Left)
|
||||
.with_options(&[String::from("Yes"), String::from("No")])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -160,14 +121,12 @@ impl SetupActivity {
|
|||
.with_color(Color::LightMagenta)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightMagenta)
|
||||
.with_options(
|
||||
Some(String::from("Group directories")),
|
||||
vec![
|
||||
String::from("Display first"),
|
||||
String::from("Display Last"),
|
||||
String::from("No"),
|
||||
],
|
||||
)
|
||||
.with_title("Group directories", Alignment::Left)
|
||||
.with_options(&[
|
||||
String::from("Display first"),
|
||||
String::from("Display Last"),
|
||||
String::from("No"),
|
||||
])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -177,7 +136,7 @@ impl SetupActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_foreground(Color::LightBlue)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightBlue)
|
||||
.with_label(String::from("File formatter syntax (local)"))
|
||||
.with_label("File formatter syntax (local)", Alignment::Left)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
@ -187,7 +146,7 @@ impl SetupActivity {
|
|||
InputPropsBuilder::default()
|
||||
.with_foreground(Color::LightGreen)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightGreen)
|
||||
.with_label(String::from("File formatter syntax (remote)"))
|
||||
.with_label("File formatter syntax (remote)", Alignment::Left)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
|
|
@ -31,10 +31,9 @@ use super::{Context, SetupActivity};
|
|||
use crate::ui::components::bookmark_list::{BookmarkList, BookmarkListPropsBuilder};
|
||||
use crate::utils::ui::draw_area_in;
|
||||
// Ext
|
||||
use tuirealm::components::{
|
||||
use tui_realm_stdlib::{
|
||||
input::{Input, InputPropsBuilder},
|
||||
radio::{Radio, RadioPropsBuilder},
|
||||
span::{Span, SpanPropsBuilder},
|
||||
};
|
||||
use tuirealm::tui::{
|
||||
layout::{Constraint, Direction, Layout},
|
||||
|
@ -42,7 +41,7 @@ use tuirealm::tui::{
|
|||
widgets::{BorderType, Borders, Clear},
|
||||
};
|
||||
use tuirealm::{
|
||||
props::{PropsBuilder, TextSpanBuilder},
|
||||
props::{Alignment, PropsBuilder},
|
||||
View,
|
||||
};
|
||||
|
||||
|
@ -57,46 +56,15 @@ impl SetupActivity {
|
|||
self.view = View::init();
|
||||
// Common stuff
|
||||
// Radio tab
|
||||
self.view.mount(
|
||||
super::COMPONENT_RADIO_TAB,
|
||||
Box::new(Radio::new(
|
||||
RadioPropsBuilder::default()
|
||||
.with_color(Color::LightYellow)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::BOTTOM, BorderType::Thick, Color::LightYellow)
|
||||
.with_options(
|
||||
None,
|
||||
vec![
|
||||
String::from("User Interface"),
|
||||
String::from("SSH Keys"),
|
||||
String::from("Theme"),
|
||||
],
|
||||
)
|
||||
.with_value(1)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
// Radio tab
|
||||
self.mount_header_tab(1);
|
||||
// Footer
|
||||
self.view.mount(
|
||||
super::COMPONENT_TEXT_FOOTER,
|
||||
Box::new(Span::new(
|
||||
SpanPropsBuilder::default()
|
||||
.with_spans(vec![
|
||||
TextSpanBuilder::new("Press ").bold().build(),
|
||||
TextSpanBuilder::new("<CTRL+H>")
|
||||
.bold()
|
||||
.with_foreground(Color::Cyan)
|
||||
.build(),
|
||||
TextSpanBuilder::new(" to show keybindings").bold().build(),
|
||||
])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
self.mount_footer();
|
||||
self.view.mount(
|
||||
super::COMPONENT_LIST_SSH_KEYS,
|
||||
Box::new(BookmarkList::new(
|
||||
BookmarkListPropsBuilder::default()
|
||||
.with_bookmarks(Some(String::from("SSH Keys")), vec![])
|
||||
.with_title("SSH keys", Alignment::Left)
|
||||
.with_borders(Borders::ALL, BorderType::Plain, Color::LightGreen)
|
||||
.with_background(Color::LightGreen)
|
||||
.with_foreground(Color::Black)
|
||||
|
@ -211,10 +179,8 @@ impl SetupActivity {
|
|||
.with_color(Color::LightRed)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightRed)
|
||||
.with_options(
|
||||
Some(String::from("Delete key?")),
|
||||
vec![String::from("Yes"), String::from("No")],
|
||||
)
|
||||
.with_title("Delete key?", Alignment::Center)
|
||||
.with_options(&[String::from("Yes"), String::from("No")])
|
||||
.with_value(1) // Default: No
|
||||
.build(),
|
||||
)),
|
||||
|
@ -238,7 +204,7 @@ impl SetupActivity {
|
|||
super::COMPONENT_INPUT_SSH_HOST,
|
||||
Box::new(Input::new(
|
||||
InputPropsBuilder::default()
|
||||
.with_label(String::from("Hostname or address"))
|
||||
.with_label("Hostname or address", Alignment::Center)
|
||||
.with_borders(
|
||||
Borders::TOP | Borders::RIGHT | Borders::LEFT,
|
||||
BorderType::Plain,
|
||||
|
@ -251,7 +217,7 @@ impl SetupActivity {
|
|||
super::COMPONENT_INPUT_SSH_USERNAME,
|
||||
Box::new(Input::new(
|
||||
InputPropsBuilder::default()
|
||||
.with_label(String::from("Username"))
|
||||
.with_label("Username", Alignment::Center)
|
||||
.with_borders(
|
||||
Borders::BOTTOM | Borders::RIGHT | Borders::LEFT,
|
||||
BorderType::Plain,
|
||||
|
@ -287,7 +253,7 @@ impl SetupActivity {
|
|||
})
|
||||
.collect();
|
||||
let props = BookmarkListPropsBuilder::from(props)
|
||||
.with_bookmarks(Some(String::from("SSH Keys")), keys)
|
||||
.with_bookmarks(keys)
|
||||
.build();
|
||||
self.view.update(super::COMPONENT_LIST_SSH_KEYS, props);
|
||||
}
|
||||
|
|
|
@ -33,18 +33,14 @@ use crate::ui::components::color_picker::{ColorPicker, ColorPickerPropsBuilder};
|
|||
use crate::utils::parser::parse_color;
|
||||
use crate::utils::ui::draw_area_in;
|
||||
// Ext
|
||||
use tuirealm::components::{
|
||||
label::{Label, LabelPropsBuilder},
|
||||
radio::{Radio, RadioPropsBuilder},
|
||||
span::{Span, SpanPropsBuilder},
|
||||
};
|
||||
use tui_realm_stdlib::label::{Label, LabelPropsBuilder};
|
||||
use tuirealm::tui::{
|
||||
layout::{Constraint, Direction, Layout},
|
||||
style::Color,
|
||||
widgets::{BorderType, Borders, Clear},
|
||||
};
|
||||
use tuirealm::{
|
||||
props::{PropsBuilder, TextSpanBuilder},
|
||||
props::{Alignment, PropsBuilder},
|
||||
Payload, Value, View,
|
||||
};
|
||||
|
||||
|
@ -59,41 +55,9 @@ impl SetupActivity {
|
|||
self.view = View::init();
|
||||
// Common stuff
|
||||
// Radio tab
|
||||
self.view.mount(
|
||||
super::COMPONENT_RADIO_TAB,
|
||||
Box::new(Radio::new(
|
||||
RadioPropsBuilder::default()
|
||||
.with_color(Color::LightYellow)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::BOTTOM, BorderType::Thick, Color::White)
|
||||
.with_options(
|
||||
None,
|
||||
vec![
|
||||
String::from("User Interface"),
|
||||
String::from("SSH Keys"),
|
||||
String::from("Theme"),
|
||||
],
|
||||
)
|
||||
.with_value(2)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
self.mount_header_tab(2);
|
||||
// Footer
|
||||
self.view.mount(
|
||||
super::COMPONENT_TEXT_FOOTER,
|
||||
Box::new(Span::new(
|
||||
SpanPropsBuilder::default()
|
||||
.with_spans(vec![
|
||||
TextSpanBuilder::new("Press ").bold().build(),
|
||||
TextSpanBuilder::new("<CTRL+H>")
|
||||
.bold()
|
||||
.with_foreground(Color::Cyan)
|
||||
.build(),
|
||||
TextSpanBuilder::new(" to show keybindings").bold().build(),
|
||||
])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
self.mount_footer();
|
||||
// auth colors
|
||||
self.mount_title(super::COMPONENT_COLOR_AUTH_TITLE, "Authentication styles");
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_AUTH_PROTOCOL, "Protocol");
|
||||
|
@ -653,7 +617,7 @@ impl SetupActivity {
|
|||
Box::new(ColorPicker::new(
|
||||
ColorPickerPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::Reset)
|
||||
.with_label(label.to_string())
|
||||
.with_label(label.to_string(), Alignment::Left)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
|
|
|
@ -26,18 +26,19 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
// ext
|
||||
use tuirealm::components::utils::get_block;
|
||||
use tui_realm_stdlib::utils::get_block;
|
||||
use tuirealm::event::{Event, KeyCode};
|
||||
use tuirealm::props::{BordersProps, Props, PropsBuilder, TextParts, TextSpan};
|
||||
use tuirealm::props::{Alignment, BlockTitle, BordersProps, Props, PropsBuilder};
|
||||
use tuirealm::tui::{
|
||||
layout::{Corner, Rect},
|
||||
style::{Color, Style},
|
||||
text::Span,
|
||||
widgets::{BorderType, Borders, List, ListItem, ListState},
|
||||
};
|
||||
use tuirealm::{Canvas, Component, Msg, Payload, Value};
|
||||
use tuirealm::{Component, Frame, Msg, Payload, PropPayload, PropValue, Value};
|
||||
|
||||
// -- props
|
||||
const PROP_BOOKMARKS: &str = "bookmarks";
|
||||
|
||||
pub struct BookmarkListPropsBuilder {
|
||||
props: Option<Props>,
|
||||
|
@ -117,10 +118,19 @@ impl BookmarkListPropsBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn with_bookmarks(&mut self, title: Option<String>, bookmarks: Vec<String>) -> &mut Self {
|
||||
pub fn with_title<S: AsRef<str>>(&mut self, text: S, alignment: Alignment) -> &mut Self {
|
||||
if let Some(props) = self.props.as_mut() {
|
||||
let bookmarks: Vec<TextSpan> = bookmarks.into_iter().map(TextSpan::from).collect();
|
||||
props.texts = TextParts::new(title, Some(bookmarks));
|
||||
props.title = Some(BlockTitle::new(text, alignment));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_bookmarks(&mut self, bookmarks: Vec<String>) -> &mut Self {
|
||||
if let Some(props) = self.props.as_mut() {
|
||||
let bookmarks: Vec<PropValue> = bookmarks.into_iter().map(PropValue::Str).collect();
|
||||
props
|
||||
.own
|
||||
.insert(PROP_BOOKMARKS, PropPayload::Vec(bookmarks));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -210,25 +220,30 @@ impl BookmarkList {
|
|||
// Initialize states
|
||||
let mut states: OwnStates = OwnStates::default();
|
||||
// Set list length
|
||||
states.set_list_len(match &props.texts.spans {
|
||||
Some(tokens) => tokens.len(),
|
||||
None => 0,
|
||||
});
|
||||
states.set_list_len(Self::bookmarks_len(&props));
|
||||
BookmarkList { props, states }
|
||||
}
|
||||
|
||||
fn bookmarks_len(props: &Props) -> usize {
|
||||
match props.own.get(PROP_BOOKMARKS) {
|
||||
None => 0,
|
||||
Some(bookmarks) => bookmarks.unwrap_vec().len(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for BookmarkList {
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
fn render(&self, render: &mut Canvas, area: Rect) {
|
||||
fn render(&self, render: &mut Frame, area: Rect) {
|
||||
if self.props.visible {
|
||||
// Make list
|
||||
let list_item: Vec<ListItem> = match self.props.texts.spans.as_ref() {
|
||||
None => vec![],
|
||||
Some(lines) => lines
|
||||
let list_item: Vec<ListItem> = match self.props.own.get(PROP_BOOKMARKS) {
|
||||
Some(PropPayload::Vec(lines)) => lines
|
||||
.iter()
|
||||
.map(|line| ListItem::new(Span::from(line.content.to_string())))
|
||||
.map(|x| x.unwrap_str())
|
||||
.map(|x| ListItem::new(Span::from(x.to_string())))
|
||||
.collect(),
|
||||
_ => vec![],
|
||||
};
|
||||
let (fg, bg): (Color, Color) = match self.states.focus {
|
||||
true => (self.props.foreground, self.props.background),
|
||||
|
@ -241,7 +256,7 @@ impl Component for BookmarkList {
|
|||
List::new(list_item)
|
||||
.block(get_block(
|
||||
&self.props.borders,
|
||||
&self.props.texts.title,
|
||||
self.props.title.as_ref(),
|
||||
self.states.focus,
|
||||
))
|
||||
.start_corner(Corner::TopLeft)
|
||||
|
@ -260,10 +275,7 @@ impl Component for BookmarkList {
|
|||
fn update(&mut self, props: Props) -> Msg {
|
||||
self.props = props;
|
||||
// re-Set list length
|
||||
self.states.set_list_len(match &self.props.texts.spans {
|
||||
Some(tokens) => tokens.len(),
|
||||
None => 0,
|
||||
});
|
||||
self.states.set_list_len(Self::bookmarks_len(&self.props));
|
||||
// Reset list index
|
||||
self.states.reset_list_index();
|
||||
Msg::None
|
||||
|
@ -347,20 +359,24 @@ mod tests {
|
|||
.with_foreground(Color::Red)
|
||||
.with_background(Color::Blue)
|
||||
.with_borders(Borders::ALL, BorderType::Double, Color::Red)
|
||||
.with_bookmarks(
|
||||
Some(String::from("filelist")),
|
||||
vec![String::from("file1"), String::from("file2")],
|
||||
)
|
||||
.with_title("filelist", Alignment::Left)
|
||||
.with_bookmarks(vec![String::from("file1"), String::from("file2")])
|
||||
.build(),
|
||||
);
|
||||
assert_eq!(component.props.foreground, Color::Red);
|
||||
assert_eq!(component.props.background, Color::Blue);
|
||||
assert_eq!(component.props.visible, true);
|
||||
assert_eq!(component.props.title.as_ref().unwrap().text(), "filelist");
|
||||
assert_eq!(
|
||||
component.props.texts.title.as_ref().unwrap().as_str(),
|
||||
"filelist"
|
||||
component
|
||||
.props
|
||||
.own
|
||||
.get(PROP_BOOKMARKS)
|
||||
.unwrap()
|
||||
.unwrap_vec()
|
||||
.len(),
|
||||
2
|
||||
);
|
||||
assert_eq!(component.props.texts.spans.as_ref().unwrap().len(), 2);
|
||||
// Verify states
|
||||
assert_eq!(component.states.list_index, 0);
|
||||
assert_eq!(component.states.list_len, 2);
|
||||
|
@ -384,14 +400,11 @@ mod tests {
|
|||
// Update
|
||||
component.update(
|
||||
BookmarkListPropsBuilder::from(component.get_props())
|
||||
.with_bookmarks(
|
||||
Some(String::from("filelist")),
|
||||
vec![
|
||||
String::from("file1"),
|
||||
String::from("file2"),
|
||||
String::from("file3"),
|
||||
],
|
||||
)
|
||||
.with_bookmarks(vec![
|
||||
String::from("file1"),
|
||||
String::from("file2"),
|
||||
String::from("file3"),
|
||||
])
|
||||
.build(),
|
||||
);
|
||||
// Verify states
|
||||
|
|
|
@ -30,15 +30,15 @@
|
|||
use crate::utils::fmt::fmt_color;
|
||||
use crate::utils::parser::parse_color;
|
||||
// ext
|
||||
use tuirealm::components::input::{Input, InputPropsBuilder};
|
||||
use tui_realm_stdlib::input::{Input, InputPropsBuilder};
|
||||
use tuirealm::event::Event;
|
||||
use tuirealm::props::{Props, PropsBuilder};
|
||||
use tuirealm::props::{Alignment, Props, PropsBuilder};
|
||||
use tuirealm::tui::{
|
||||
layout::Rect,
|
||||
style::Color,
|
||||
widgets::{BorderType, Borders},
|
||||
};
|
||||
use tuirealm::{Canvas, Component, Msg, Payload, Value};
|
||||
use tuirealm::{Component, Frame, Msg, Payload, Value};
|
||||
|
||||
// -- props
|
||||
|
||||
|
@ -98,8 +98,8 @@ impl ColorPickerPropsBuilder {
|
|||
/// ### with_label
|
||||
///
|
||||
/// Set input label
|
||||
pub fn with_label(&mut self, label: String) -> &mut Self {
|
||||
self.puppet.with_label(label);
|
||||
pub fn with_label<S: AsRef<str>>(&mut self, label: S, alignment: Alignment) -> &mut Self {
|
||||
self.puppet.with_label(label, alignment);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ impl Component for ColorPicker {
|
|||
/// Based on the current properties and states, renders a widget using the provided render engine in the provided Area
|
||||
/// If focused, cursor is also set (if supported by widget)
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
fn render(&self, render: &mut Canvas, area: Rect) {
|
||||
fn render(&self, render: &mut Frame, area: Rect) {
|
||||
self.input.render(render, area);
|
||||
}
|
||||
|
||||
|
@ -260,6 +260,7 @@ mod test {
|
|||
.visible()
|
||||
.with_color(&Color::Rgb(204, 170, 0))
|
||||
.with_borders(Borders::ALL, BorderType::Double, Color::Rgb(204, 170, 0))
|
||||
.with_label("omar", Alignment::Left)
|
||||
.build(),
|
||||
);
|
||||
// Focus
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
// ext
|
||||
use tuirealm::components::utils::get_block;
|
||||
use tui_realm_stdlib::utils::get_block;
|
||||
use tuirealm::event::{Event, KeyCode, KeyModifiers};
|
||||
use tuirealm::props::{
|
||||
BordersProps, PropPayload, PropValue, Props, PropsBuilder, TextParts, TextSpan,
|
||||
Alignment, BlockTitle, BordersProps, PropPayload, PropValue, Props, PropsBuilder,
|
||||
};
|
||||
use tuirealm::tui::{
|
||||
layout::{Corner, Rect},
|
||||
|
@ -37,11 +37,12 @@ use tuirealm::tui::{
|
|||
text::Span,
|
||||
widgets::{BorderType, Borders, List, ListItem, ListState},
|
||||
};
|
||||
use tuirealm::{Canvas, Component, Msg, Payload, Value};
|
||||
use tuirealm::{Component, Frame, Msg, Payload, Value};
|
||||
|
||||
// -- props
|
||||
|
||||
const PROP_HIGHLIGHT_COLOR: &str = "props-highlight-color";
|
||||
const PROP_FILES: &str = "files";
|
||||
const PALETTE_HIGHLIGHT_COLOR: &str = "props-highlight-color";
|
||||
|
||||
pub struct FileListPropsBuilder {
|
||||
props: Option<Props>,
|
||||
|
@ -107,10 +108,7 @@ impl FileListPropsBuilder {
|
|||
/// Set highlighted color
|
||||
pub fn with_highlight_color(&mut self, color: Color) -> &mut Self {
|
||||
if let Some(props) = self.props.as_mut() {
|
||||
props.own.insert(
|
||||
PROP_HIGHLIGHT_COLOR,
|
||||
PropPayload::One(PropValue::Color(color)),
|
||||
);
|
||||
props.palette.insert(PALETTE_HIGHLIGHT_COLOR, color);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -134,10 +132,17 @@ impl FileListPropsBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn with_files(&mut self, title: Option<String>, files: Vec<String>) -> &mut Self {
|
||||
pub fn with_title<S: AsRef<str>>(&mut self, text: S, alignment: Alignment) -> &mut Self {
|
||||
if let Some(props) = self.props.as_mut() {
|
||||
let files: Vec<TextSpan> = files.into_iter().map(TextSpan::from).collect();
|
||||
props.texts = TextParts::new(title, Some(files));
|
||||
props.title = Some(BlockTitle::new(text, alignment));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_files(&mut self, files: Vec<String>) -> &mut Self {
|
||||
if let Some(props) = self.props.as_mut() {
|
||||
let files: Vec<PropValue> = files.into_iter().map(PropValue::Str).collect();
|
||||
props.own.insert(PROP_FILES, PropPayload::Vec(files));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -299,32 +304,39 @@ impl FileList {
|
|||
// Initialize states
|
||||
let mut states: OwnStates = OwnStates::default();
|
||||
// Init list states
|
||||
states.init_list_states(props.texts.spans.as_ref().map(|x| x.len()).unwrap_or(0));
|
||||
states.init_list_states(Self::files_len(&props));
|
||||
FileList { props, states }
|
||||
}
|
||||
|
||||
fn files_len(props: &Props) -> usize {
|
||||
match props.own.get(PROP_FILES) {
|
||||
None => 0,
|
||||
Some(files) => files.unwrap_vec().len(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for FileList {
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
fn render(&self, render: &mut Canvas, area: Rect) {
|
||||
fn render(&self, render: &mut Frame, area: Rect) {
|
||||
if self.props.visible {
|
||||
// Make list
|
||||
let list_item: Vec<ListItem> = match self.props.texts.spans.as_ref() {
|
||||
None => vec![],
|
||||
Some(lines) => lines
|
||||
let list_item: Vec<ListItem> = match self.props.own.get(PROP_FILES) {
|
||||
Some(PropPayload::Vec(lines)) => lines
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(num, line)| {
|
||||
let to_display: String = match self.states.is_selected(num) {
|
||||
true => format!("*{}", line.content),
|
||||
false => line.content.to_string(),
|
||||
true => format!("*{}", line.unwrap_str()),
|
||||
false => line.unwrap_str().to_string(),
|
||||
};
|
||||
ListItem::new(Span::from(to_display))
|
||||
})
|
||||
.collect(),
|
||||
_ => vec![],
|
||||
};
|
||||
let highlighted_color: Color = match self.props.own.get(PROP_HIGHLIGHT_COLOR) {
|
||||
Some(PropPayload::One(PropValue::Color(c))) => *c,
|
||||
let highlighted_color: Color = match self.props.palette.get(PALETTE_HIGHLIGHT_COLOR) {
|
||||
Some(c) => *c,
|
||||
_ => Color::Reset,
|
||||
};
|
||||
let (h_fg, h_bg): (Color, Color) = match self.states.focus {
|
||||
|
@ -338,7 +350,7 @@ impl Component for FileList {
|
|||
List::new(list_item)
|
||||
.block(get_block(
|
||||
&self.props.borders,
|
||||
&self.props.texts.title,
|
||||
self.props.title.as_ref(),
|
||||
self.states.focus,
|
||||
))
|
||||
.start_corner(Corner::TopLeft)
|
||||
|
@ -362,14 +374,7 @@ impl Component for FileList {
|
|||
fn update(&mut self, props: Props) -> Msg {
|
||||
self.props = props;
|
||||
// re-Set list states
|
||||
self.states.init_list_states(
|
||||
self.props
|
||||
.texts
|
||||
.spans
|
||||
.as_ref()
|
||||
.map(|x| x.len())
|
||||
.unwrap_or(0),
|
||||
);
|
||||
self.states.init_list_states(Self::files_len(&self.props));
|
||||
Msg::None
|
||||
}
|
||||
|
||||
|
@ -551,24 +556,33 @@ mod tests {
|
|||
.with_background(Color::Blue)
|
||||
.with_highlight_color(Color::LightRed)
|
||||
.with_borders(Borders::ALL, BorderType::Double, Color::Red)
|
||||
.with_files(
|
||||
Some(String::from("files")),
|
||||
vec![String::from("file1"), String::from("file2")],
|
||||
)
|
||||
.with_title("files", Alignment::Left)
|
||||
.with_files(vec![String::from("file1"), String::from("file2")])
|
||||
.build(),
|
||||
);
|
||||
assert_eq!(
|
||||
*component.props.own.get(PROP_HIGHLIGHT_COLOR).unwrap(),
|
||||
PropPayload::One(PropValue::Color(Color::LightRed))
|
||||
*component
|
||||
.props
|
||||
.palette
|
||||
.get(PALETTE_HIGHLIGHT_COLOR)
|
||||
.unwrap(),
|
||||
Color::LightRed
|
||||
);
|
||||
assert_eq!(component.props.foreground, Color::Red);
|
||||
assert_eq!(component.props.background, Color::Blue);
|
||||
assert_eq!(component.props.visible, true);
|
||||
assert_eq!(component.props.title.as_ref().unwrap().text(), "files");
|
||||
assert_eq!(
|
||||
component.props.texts.title.as_ref().unwrap().as_str(),
|
||||
"files"
|
||||
component
|
||||
.props
|
||||
.own
|
||||
.get(PROP_FILES)
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.unwrap_vec()
|
||||
.len(),
|
||||
2
|
||||
);
|
||||
assert_eq!(component.props.texts.spans.as_ref().unwrap().len(), 2);
|
||||
// Verify states
|
||||
assert_eq!(component.states.list_index, 0);
|
||||
assert_eq!(component.states.selected.len(), 0);
|
||||
|
@ -594,14 +608,11 @@ mod tests {
|
|||
// Update
|
||||
component.update(
|
||||
FileListPropsBuilder::from(component.get_props())
|
||||
.with_files(
|
||||
Some(String::from("filelist")),
|
||||
vec![
|
||||
String::from("file1"),
|
||||
String::from("file2"),
|
||||
String::from("file3"),
|
||||
],
|
||||
)
|
||||
.with_files(vec![
|
||||
String::from("file1"),
|
||||
String::from("file2"),
|
||||
String::from("file3"),
|
||||
])
|
||||
.build(),
|
||||
);
|
||||
// Verify states
|
||||
|
@ -670,14 +681,11 @@ mod tests {
|
|||
// Make component
|
||||
let mut component: FileList = FileList::new(
|
||||
FileListPropsBuilder::default()
|
||||
.with_files(
|
||||
Some(String::from("files")),
|
||||
vec![
|
||||
String::from("file1"),
|
||||
String::from("file2"),
|
||||
String::from("file3"),
|
||||
],
|
||||
)
|
||||
.with_files(vec![
|
||||
String::from("file1"),
|
||||
String::from("file2"),
|
||||
String::from("file3"),
|
||||
])
|
||||
.build(),
|
||||
);
|
||||
// Get state
|
||||
|
@ -735,10 +743,7 @@ mod tests {
|
|||
// Update files
|
||||
component.update(
|
||||
FileListPropsBuilder::from(component.get_props())
|
||||
.with_files(
|
||||
Some(String::from("filelist")),
|
||||
vec![String::from("file1"), String::from("file2")],
|
||||
)
|
||||
.with_files(vec![String::from("file1"), String::from("file2")])
|
||||
.build(),
|
||||
);
|
||||
// Selection should now be empty
|
||||
|
|
|
@ -26,18 +26,22 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
// ext
|
||||
use tuirealm::components::utils::{get_block, wrap_spans};
|
||||
use tui_realm_stdlib::utils::{get_block, wrap_spans};
|
||||
use tuirealm::event::{Event, KeyCode};
|
||||
use tuirealm::props::{BordersProps, Props, PropsBuilder, Table as TextTable, TextParts};
|
||||
use tuirealm::props::{
|
||||
Alignment, BlockTitle, BordersProps, Props, PropsBuilder, Table as TextTable,
|
||||
};
|
||||
use tuirealm::tui::{
|
||||
layout::{Corner, Rect},
|
||||
style::{Color, Style},
|
||||
widgets::{BorderType, Borders, List, ListItem, ListState},
|
||||
};
|
||||
use tuirealm::{Canvas, Component, Msg, Payload, Value};
|
||||
use tuirealm::{Component, Frame, Msg, Payload, PropPayload, PropValue, Value};
|
||||
|
||||
// -- props
|
||||
|
||||
const PROP_TABLE: &str = "table";
|
||||
|
||||
pub struct LogboxPropsBuilder {
|
||||
props: Option<Props>,
|
||||
}
|
||||
|
@ -106,9 +110,18 @@ impl LogboxPropsBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn with_log(&mut self, title: Option<String>, table: TextTable) -> &mut Self {
|
||||
pub fn with_title<S: AsRef<str>>(&mut self, text: S, alignment: Alignment) -> &mut Self {
|
||||
if let Some(props) = self.props.as_mut() {
|
||||
props.texts = TextParts::table(title, table);
|
||||
props.title = Some(BlockTitle::new(text, alignment));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_log(&mut self, table: TextTable) -> &mut Self {
|
||||
if let Some(props) = self.props.as_mut() {
|
||||
props
|
||||
.own
|
||||
.insert(PROP_TABLE, PropPayload::One(PropValue::Table(table)));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -198,33 +211,37 @@ impl LogBox {
|
|||
// Initialize states
|
||||
let mut states: OwnStates = OwnStates::default();
|
||||
// Set list length
|
||||
states.set_list_len(match &props.texts.table {
|
||||
Some(rows) => rows.len(),
|
||||
None => 0,
|
||||
});
|
||||
states.set_list_len(Self::table_len(&props));
|
||||
// Reset list index
|
||||
states.reset_list_index();
|
||||
LogBox { props, states }
|
||||
}
|
||||
|
||||
fn table_len(props: &Props) -> usize {
|
||||
match props.own.get(PROP_TABLE) {
|
||||
Some(PropPayload::One(PropValue::Table(table))) => table.len(),
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for LogBox {
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
fn render(&self, render: &mut Canvas, area: Rect) {
|
||||
fn render(&self, render: &mut Frame, area: Rect) {
|
||||
if self.props.visible {
|
||||
let width: usize = area.width as usize - 4;
|
||||
// Make list
|
||||
let list_items: Vec<ListItem> = match self.props.texts.table.as_ref() {
|
||||
None => Vec::new(),
|
||||
Some(table) => table
|
||||
let list_items: Vec<ListItem> = match self.props.own.get(PROP_TABLE) {
|
||||
Some(PropPayload::One(PropValue::Table(table))) => table
|
||||
.iter()
|
||||
.map(|row| ListItem::new(wrap_spans(row, width, &self.props)))
|
||||
.collect(), // Make List item from TextSpan
|
||||
_ => Vec::new(),
|
||||
};
|
||||
let w = List::new(list_items)
|
||||
.block(get_block(
|
||||
&self.props.borders,
|
||||
&self.props.texts.title,
|
||||
self.props.title.as_ref(),
|
||||
self.states.focus,
|
||||
))
|
||||
.start_corner(Corner::BottomLeft)
|
||||
|
@ -240,10 +257,7 @@ impl Component for LogBox {
|
|||
fn update(&mut self, props: Props) -> Msg {
|
||||
self.props = props;
|
||||
// re-Set list length
|
||||
self.states.set_list_len(match &self.props.texts.table {
|
||||
Some(rows) => rows.len(),
|
||||
None => 0,
|
||||
});
|
||||
self.states.set_list_len(Self::table_len(&self.props));
|
||||
// Reset list index
|
||||
self.states.reset_list_index();
|
||||
Msg::None
|
||||
|
@ -323,8 +337,8 @@ mod tests {
|
|||
.visible()
|
||||
.with_borders(Borders::ALL, BorderType::Double, Color::Red)
|
||||
.with_background(Color::Blue)
|
||||
.with_title("log", Alignment::Left)
|
||||
.with_log(
|
||||
Some(String::from("Log")),
|
||||
TableBuilder::default()
|
||||
.add_col(TextSpan::from("12:29"))
|
||||
.add_col(TextSpan::from("system crashed"))
|
||||
|
@ -337,11 +351,7 @@ mod tests {
|
|||
);
|
||||
assert_eq!(component.props.visible, true);
|
||||
assert_eq!(component.props.background, Color::Blue);
|
||||
assert_eq!(
|
||||
component.props.texts.title.as_ref().unwrap().as_str(),
|
||||
"Log"
|
||||
);
|
||||
assert_eq!(component.props.texts.table.as_ref().unwrap().len(), 2);
|
||||
assert_eq!(component.props.title.as_ref().unwrap().text(), "Log");
|
||||
// Verify states
|
||||
assert_eq!(component.states.list_index, 0);
|
||||
assert_eq!(component.states.list_len, 2);
|
||||
|
@ -364,7 +374,6 @@ mod tests {
|
|||
component.update(
|
||||
LogboxPropsBuilder::from(component.get_props())
|
||||
.with_log(
|
||||
Some(String::from("Log")),
|
||||
TableBuilder::default()
|
||||
.add_col(TextSpan::from("12:29"))
|
||||
.add_col(TextSpan::from("system crashed"))
|
||||
|
|
|
@ -30,4 +30,3 @@ pub mod bookmark_list;
|
|||
pub mod color_picker;
|
||||
pub mod file_list;
|
||||
pub mod logbox;
|
||||
pub mod msgbox;
|
||||
|
|
|
@ -1,268 +0,0 @@
|
|||
//! ## MsgBox
|
||||
//!
|
||||
//! `MsgBox` component renders a simple readonly no event associated centered text
|
||||
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* termscp - Copyright (c) 2021 Christian Visintin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
// locals
|
||||
use crate::utils::fmt::align_text_center;
|
||||
// ext
|
||||
use tuirealm::components::utils::{get_block, use_or_default_styles};
|
||||
use tuirealm::event::Event;
|
||||
use tuirealm::props::{BordersProps, Props, PropsBuilder, TextParts, TextSpan};
|
||||
use tuirealm::tui::{
|
||||
layout::{Corner, Rect},
|
||||
style::{Color, Modifier, Style},
|
||||
text::{Span, Spans},
|
||||
widgets::{BorderType, Borders, List, ListItem},
|
||||
};
|
||||
use tuirealm::{Canvas, Component, Msg, Payload};
|
||||
|
||||
// -- Props
|
||||
|
||||
pub struct MsgBoxPropsBuilder {
|
||||
props: Option<Props>,
|
||||
}
|
||||
|
||||
impl Default for MsgBoxPropsBuilder {
|
||||
fn default() -> Self {
|
||||
MsgBoxPropsBuilder {
|
||||
props: Some(Props::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PropsBuilder for MsgBoxPropsBuilder {
|
||||
fn build(&mut self) -> Props {
|
||||
self.props.take().unwrap()
|
||||
}
|
||||
|
||||
fn hidden(&mut self) -> &mut Self {
|
||||
if let Some(props) = self.props.as_mut() {
|
||||
props.visible = false;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn visible(&mut self) -> &mut Self {
|
||||
if let Some(props) = self.props.as_mut() {
|
||||
props.visible = true;
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Props> for MsgBoxPropsBuilder {
|
||||
fn from(props: Props) -> Self {
|
||||
MsgBoxPropsBuilder { props: Some(props) }
|
||||
}
|
||||
}
|
||||
|
||||
impl MsgBoxPropsBuilder {
|
||||
pub fn with_foreground(&mut self, color: Color) -> &mut Self {
|
||||
if let Some(props) = self.props.as_mut() {
|
||||
props.foreground = color;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn bold(&mut self) -> &mut Self {
|
||||
if let Some(props) = self.props.as_mut() {
|
||||
props.modifiers |= Modifier::BOLD;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn blink(&mut self) -> &mut Self {
|
||||
if let Some(props) = self.props.as_mut() {
|
||||
props.modifiers |= Modifier::SLOW_BLINK;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_borders(
|
||||
&mut self,
|
||||
borders: Borders,
|
||||
variant: BorderType,
|
||||
color: Color,
|
||||
) -> &mut Self {
|
||||
if let Some(props) = self.props.as_mut() {
|
||||
props.borders = BordersProps {
|
||||
borders,
|
||||
variant,
|
||||
color,
|
||||
}
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_texts(&mut self, title: Option<String>, texts: Vec<TextSpan>) -> &mut Self {
|
||||
if let Some(props) = self.props.as_mut() {
|
||||
props.texts = TextParts::new(title, Some(texts));
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
// -- component
|
||||
|
||||
pub struct MsgBox {
|
||||
props: Props,
|
||||
}
|
||||
|
||||
impl MsgBox {
|
||||
/// ### new
|
||||
///
|
||||
/// Instantiate a new Text component
|
||||
pub fn new(props: Props) -> Self {
|
||||
MsgBox { props }
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for MsgBox {
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
fn render(&self, render: &mut Canvas, area: Rect) {
|
||||
// Make a Span
|
||||
if self.props.visible {
|
||||
let lines: Vec<ListItem> = match self.props.texts.spans.as_ref() {
|
||||
None => Vec::new(),
|
||||
Some(rows) => {
|
||||
let mut lines: Vec<ListItem> = Vec::new();
|
||||
for line in rows.iter() {
|
||||
// Keep line color, or use default
|
||||
let (fg, bg, modifiers) = use_or_default_styles(&self.props, line);
|
||||
let message_row =
|
||||
textwrap::wrap(line.content.as_str(), area.width as usize);
|
||||
for msg in message_row.iter() {
|
||||
lines.push(ListItem::new(Spans::from(vec![Span::styled(
|
||||
align_text_center(msg, area.width),
|
||||
Style::default().add_modifier(modifiers).fg(fg).bg(bg),
|
||||
)])));
|
||||
}
|
||||
}
|
||||
lines
|
||||
}
|
||||
};
|
||||
render.render_widget(
|
||||
List::new(lines)
|
||||
.block(get_block(
|
||||
&self.props.borders,
|
||||
&self.props.texts.title,
|
||||
true,
|
||||
))
|
||||
.start_corner(Corner::TopLeft)
|
||||
.style(
|
||||
Style::default()
|
||||
.fg(self.props.foreground)
|
||||
.bg(self.props.background),
|
||||
),
|
||||
area,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, props: Props) -> Msg {
|
||||
self.props = props;
|
||||
// Return None
|
||||
Msg::None
|
||||
}
|
||||
|
||||
fn get_props(&self) -> Props {
|
||||
self.props.clone()
|
||||
}
|
||||
|
||||
fn on(&mut self, ev: Event) -> Msg {
|
||||
// Return key
|
||||
if let Event::Key(key) = ev {
|
||||
Msg::OnKey(key)
|
||||
} else {
|
||||
Msg::None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_state(&self) -> Payload {
|
||||
Payload::None
|
||||
}
|
||||
|
||||
fn blur(&mut self) {}
|
||||
|
||||
fn active(&mut self) {}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
use pretty_assertions::assert_eq;
|
||||
use tuirealm::event::{KeyCode, KeyEvent};
|
||||
use tuirealm::props::{TextSpan, TextSpanBuilder};
|
||||
use tuirealm::tui::style::Color;
|
||||
|
||||
#[test]
|
||||
fn test_ui_components_msgbox() {
|
||||
let mut component: MsgBox = MsgBox::new(
|
||||
MsgBoxPropsBuilder::default()
|
||||
.hidden()
|
||||
.visible()
|
||||
.with_foreground(Color::Red)
|
||||
.bold()
|
||||
.blink()
|
||||
.with_borders(Borders::ALL, BorderType::Double, Color::Red)
|
||||
.with_texts(
|
||||
None,
|
||||
vec![
|
||||
TextSpan::from("Press "),
|
||||
TextSpanBuilder::new("<ESC>")
|
||||
.with_foreground(Color::Cyan)
|
||||
.bold()
|
||||
.build(),
|
||||
TextSpan::from(" to quit"),
|
||||
],
|
||||
)
|
||||
.build(),
|
||||
);
|
||||
assert_eq!(component.props.foreground, Color::Red);
|
||||
assert!(component.props.modifiers.intersects(Modifier::BOLD));
|
||||
assert_eq!(component.props.visible, true);
|
||||
assert_eq!(component.props.texts.spans.as_ref().unwrap().len(), 3);
|
||||
component.active();
|
||||
component.blur();
|
||||
// Update
|
||||
let props = MsgBoxPropsBuilder::from(component.get_props())
|
||||
.hidden()
|
||||
.with_foreground(Color::Yellow)
|
||||
.build();
|
||||
assert_eq!(component.update(props), Msg::None);
|
||||
assert_eq!(component.props.visible, false);
|
||||
assert_eq!(component.props.foreground, Color::Yellow);
|
||||
// Get value
|
||||
assert_eq!(component.get_state(), Payload::None);
|
||||
// Event
|
||||
assert_eq!(
|
||||
component.on(Event::Key(KeyEvent::from(KeyCode::Delete))),
|
||||
Msg::OnKey(KeyEvent::from(KeyCode::Delete))
|
||||
);
|
||||
}
|
||||
}
|
|
@ -100,23 +100,6 @@ pub fn fmt_millis(duration: Duration) -> String {
|
|||
format!("{}.{:0width$}", seconds, millis, width = 3)
|
||||
}
|
||||
|
||||
/// align_text_center
|
||||
///
|
||||
/// Align text to center for a given width
|
||||
pub fn align_text_center(text: &str, width: u16) -> String {
|
||||
let indent_size: usize = match (width as usize) >= text.len() {
|
||||
// NOTE: The check prevents underflow
|
||||
true => (width as usize - text.len()) / 2,
|
||||
false => 0,
|
||||
};
|
||||
textwrap::indent(
|
||||
text,
|
||||
(0..indent_size).map(|_| " ").collect::<String>().as_str(),
|
||||
)
|
||||
.trim_end()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
/// ### elide_path
|
||||
///
|
||||
/// Elide a path if longer than width
|
||||
|
@ -362,18 +345,6 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_utils_align_text_center() {
|
||||
assert_eq!(
|
||||
align_text_center("hello world!", 24),
|
||||
String::from(" hello world!")
|
||||
);
|
||||
// Bad case
|
||||
assert_eq!(
|
||||
align_text_center("hello world!", 8),
|
||||
String::from("hello world!")
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn test_utils_fmt_millis() {
|
||||
assert_eq!(
|
||||
|
|
Loading…
Reference in a new issue