get basic tui working with Ratatui
This commit is contained in:
parent
a0a3139964
commit
a0582ead78
|
|
@ -2,6 +2,24 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.13"
|
||||
|
|
@ -37,7 +55,7 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -47,15 +65,54 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
|
||||
[[package]]
|
||||
name = "bufstream"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8"
|
||||
|
||||
[[package]]
|
||||
name = "cassowary"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
|
||||
|
||||
[[package]]
|
||||
name = "castaway"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc"
|
||||
dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.4"
|
||||
|
|
@ -84,7 +141,7 @@ version = "4.5.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
|
|
@ -102,12 +159,136 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||
|
||||
[[package]]
|
||||
name = "compact_str"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f"
|
||||
dependencies = [
|
||||
"castaway",
|
||||
"cfg-if",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm_winapi"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"allocator-api2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "indoc"
|
||||
version = "2.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "lru"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mpd"
|
||||
version = "0.1.0"
|
||||
|
|
@ -117,6 +298,41 @@ dependencies = [
|
|||
"bufstream",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.81"
|
||||
|
|
@ -135,12 +351,43 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ratatui"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a564a852040e82671dc50a37d88f3aa83bbc690dfc6844cfe7a2591620206a80"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"cassowary",
|
||||
"compact_str",
|
||||
"crossterm",
|
||||
"indoc",
|
||||
"itertools",
|
||||
"lru",
|
||||
"paste",
|
||||
"stability",
|
||||
"strum",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rmptui"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"crossterm",
|
||||
"mpd",
|
||||
"ratatui",
|
||||
"rust_fzf",
|
||||
"simple-dmenu",
|
||||
]
|
||||
|
|
@ -151,18 +398,110 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76a94b9c6a9880356cc6de038a52397509f8ac86a18c30d76da904b08fec2cb1"
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-mio"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simple-dmenu"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f392360283341235b298e79f0360bd924db6e6ad1e0964cbf4c43ea79c237eb"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "stability"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ff9eaf853dec4c8802325d8b6d3dffa86cc707fd7a1a4cdbf416e13b061787a"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29"
|
||||
dependencies = [
|
||||
"strum_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946"
|
||||
dependencies = [
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.60"
|
||||
|
|
@ -180,19 +519,89 @@ version = "1.0.12"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -201,28 +610,46 @@ version = "0.52.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_aarch64_gnullvm 0.52.5",
|
||||
"windows_aarch64_msvc 0.52.5",
|
||||
"windows_i686_gnu 0.52.5",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
"windows_i686_msvc 0.52.5",
|
||||
"windows_x86_64_gnu 0.52.5",
|
||||
"windows_x86_64_gnullvm 0.52.5",
|
||||
"windows_x86_64_msvc 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.5"
|
||||
|
|
@ -235,26 +662,70 @@ version = "0.52.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -10,3 +10,5 @@ mpd = "0.1.0"
|
|||
clap = { version = "4.0.29", features = ["derive"] }
|
||||
rust_fzf = "0.3.1"
|
||||
simple-dmenu = "0.1.0"
|
||||
ratatui = "0.26.2"
|
||||
crossterm = "0.27.0"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
use crate::connection::Connection;
|
||||
use crate::list::ContentList;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
// Application result type
|
||||
pub type AppResult<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||
|
||||
/// Application
|
||||
#[derive(Debug)]
|
||||
pub struct App {
|
||||
/// check if app is running
|
||||
pub running: bool,
|
||||
pub conn: Connection,
|
||||
pub play_deque: VecDeque<String>,
|
||||
pub list: ContentList,
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn new(addrs: &str) -> Self {
|
||||
let mut conn = Connection::new(addrs).unwrap();
|
||||
let mut vec: VecDeque<String> = VecDeque::new();
|
||||
Self::get_queue(&mut conn, &mut vec);
|
||||
Self {
|
||||
running: true,
|
||||
conn,
|
||||
play_deque: vec,
|
||||
list: ContentList::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tick(&self) {}
|
||||
|
||||
pub fn quit(&mut self) {
|
||||
self.running = false;
|
||||
}
|
||||
|
||||
pub fn get_queue(conn: &mut Connection, vec: &mut VecDeque<String>) {
|
||||
conn.conn.queue().unwrap().into_iter().for_each(|x| {
|
||||
if let Some(title) = x.title {
|
||||
if let Some(artist) = x.artist {
|
||||
vec.push_back(format!("{} - {}", artist, title));
|
||||
} else {
|
||||
vec.push_back(title)
|
||||
}
|
||||
} else {
|
||||
vec.push_back(x.file)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn update_queue(&mut self) {
|
||||
self.play_deque.clear();
|
||||
Self::get_queue(&mut self.conn, &mut self.play_deque);
|
||||
}
|
||||
}
|
||||
|
||||
fn to_vecdeque(filenames: &Vec<String>) -> VecDeque<String> {
|
||||
let mut v: VecDeque<String> = VecDeque::new();
|
||||
v = filenames.iter().map(|x| x.to_string()).collect();
|
||||
v
|
||||
}
|
||||
44
src/cli.rs
44
src/cli.rs
|
|
@ -1,28 +1,12 @@
|
|||
use clap::{Parser, Subcommand};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(version, about)]
|
||||
#[clap(author = "krolyxon")]
|
||||
#[clap(version, about, author = "krolyxon")]
|
||||
/// MPD client made with Rust
|
||||
pub struct Args {
|
||||
/// pause
|
||||
#[clap(short, long, default_value = "false")]
|
||||
pub pause: bool,
|
||||
|
||||
/// toggle pause
|
||||
#[arg(short, long, default_value = "false")]
|
||||
pub toggle_pause: bool,
|
||||
|
||||
/// show current status
|
||||
#[arg(short, long, default_value = "false")]
|
||||
pub show_status: bool,
|
||||
|
||||
/// use fzf selector for selecting songs
|
||||
#[arg(short, long, default_value = "false")]
|
||||
pub fzf_select: bool,
|
||||
|
||||
/// use dmenu selector for selecting songss
|
||||
#[arg(short, long, default_value = "false")]
|
||||
pub dmenu_select: bool,
|
||||
/// No TUI
|
||||
#[arg(short= 'n', default_value="false")]
|
||||
pub no_tui: bool,
|
||||
|
||||
#[command(subcommand)]
|
||||
pub command: Command,
|
||||
|
|
@ -30,14 +14,30 @@ pub struct Args {
|
|||
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum Command {
|
||||
#[command(arg_required_else_help = true)]
|
||||
#[command(arg_required_else_help = true, long_flag = "volume" , short_flag = 'v')]
|
||||
/// Set Volume
|
||||
Volume {
|
||||
vol: String,
|
||||
},
|
||||
|
||||
/// Use dmenu for selection
|
||||
#[command(long_flag = "dmenu" , short_flag = 'd')]
|
||||
Dmenu,
|
||||
|
||||
/// Use Fzf for selection
|
||||
#[command(long_flag = "fzf" , short_flag = 'f')]
|
||||
Fzf,
|
||||
|
||||
/// Check Status
|
||||
#[command(long_flag = "status" , short_flag = 's')]
|
||||
Status,
|
||||
|
||||
/// Pause playback
|
||||
#[command(long_flag = "pause" , short_flag = 'p')]
|
||||
Pause,
|
||||
|
||||
/// Toggle Playback
|
||||
#[command(long_flag = "toggle" , short_flag = 't')]
|
||||
Toggle,
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,20 @@
|
|||
use mpd::song::Song;
|
||||
use mpd::{Client, State};
|
||||
use simple_dmenu::dmenu;
|
||||
use std::process::Command;
|
||||
|
||||
pub type Result<T> = core::result::Result<T, Error>;
|
||||
pub type Error = Box<dyn std::error::Error>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Connection {
|
||||
pub conn: Client,
|
||||
pub songs_filenames: Vec<String>,
|
||||
}
|
||||
|
||||
impl Connection {
|
||||
pub fn new(addrs: &str) -> Result<Self, mpd::error::Error> {
|
||||
let mut conn = Client::connect(addrs)?;
|
||||
pub fn new(addrs: &str) -> Result<Self> {
|
||||
let mut conn = Client::connect(addrs).unwrap();
|
||||
let songs_filenames: Vec<String> = conn
|
||||
.listall()
|
||||
.unwrap()
|
||||
|
|
@ -23,23 +28,29 @@ impl Connection {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn play_fzf(&mut self) {
|
||||
pub fn play_fzf(&mut self) -> Result<()> {
|
||||
is_installed("fzf").map_err(|ex| ex)?;
|
||||
|
||||
let ss = &self.songs_filenames;
|
||||
let fzf_choice = rust_fzf::select(ss.clone(), Vec::new()).unwrap();
|
||||
let index = get_choice_index(&self.songs_filenames, fzf_choice.get(0).unwrap());
|
||||
let song = self.get_song_with_only_filename(ss.get(index).unwrap());
|
||||
self.push(&song);
|
||||
self.push(&song)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn play_dmenu(&mut self) {
|
||||
pub fn play_dmenu(&mut self) -> Result<()> {
|
||||
is_installed("dmenu").map_err(|ex| ex)?;
|
||||
let ss: Vec<&str> = self.songs_filenames.iter().map(|x| x.as_str()).collect();
|
||||
let op = dmenu!(iter &ss; args "-l", "30");
|
||||
let index = get_choice_index(&self.songs_filenames, &op);
|
||||
let song = self.get_song_with_only_filename(ss.get(index).unwrap());
|
||||
self.push(&song);
|
||||
self.push(&song)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn push(&mut self, song: &Song) {
|
||||
pub fn push(&mut self, song: &Song) -> Result<()> {
|
||||
if self.conn.queue().unwrap().is_empty() {
|
||||
self.conn.push(song).unwrap();
|
||||
self.conn.play().unwrap();
|
||||
|
|
@ -50,9 +61,11 @@ impl Connection {
|
|||
}
|
||||
self.conn.next().unwrap();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_song_with_only_filename(&self, filename: &str) -> Song {
|
||||
pub fn get_song_with_only_filename(&self, filename: &str) -> Song {
|
||||
Song {
|
||||
file: filename.to_string(),
|
||||
artist: None,
|
||||
|
|
@ -66,6 +79,10 @@ impl Connection {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_current_song(&mut self) -> Option<String> {
|
||||
self.conn.currentsong().unwrap().unwrap_or_default().title
|
||||
|
||||
}
|
||||
pub fn status(&mut self) {
|
||||
let current_song = self.conn.currentsong();
|
||||
let status = self.conn.status().unwrap();
|
||||
|
|
@ -112,3 +129,16 @@ fn get_choice_index(ss: &Vec<String>, selection: &str) -> usize {
|
|||
|
||||
choice
|
||||
}
|
||||
|
||||
fn is_installed(ss: &str) -> Result<()> {
|
||||
let output = Command::new("which")
|
||||
.arg(ss)
|
||||
.output()
|
||||
.expect("Failed to execute command");
|
||||
if output.status.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
let err = format!("{} not installed", ss);
|
||||
Err(err.into())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
DmenuNotInstalled,
|
||||
FzfNotInstalled,
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
use crate::app::AppResult;
|
||||
use crossterm::event::{self, Event as CrosstermEvent, KeyEvent, MouseEvent};
|
||||
use std::sync::mpsc;
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
/// Terminal events.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum Event {
|
||||
/// Terminal tick.
|
||||
Tick,
|
||||
/// Key press.
|
||||
Key(KeyEvent),
|
||||
/// Mouse click/scroll.
|
||||
Mouse(MouseEvent),
|
||||
/// Terminal resize.
|
||||
Resize(u16, u16),
|
||||
}
|
||||
|
||||
/// Terminal event handler.
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
pub struct EventHandler {
|
||||
/// Event sender channel.
|
||||
sender: mpsc::Sender<Event>,
|
||||
/// Event receiver channel.
|
||||
receiver: mpsc::Receiver<Event>,
|
||||
/// Event handler thread.
|
||||
handler: thread::JoinHandle<()>,
|
||||
}
|
||||
|
||||
impl EventHandler {
|
||||
/// Constructs a new instance of [`EventHandler`].
|
||||
pub fn new(tick_rate: u64) -> Self {
|
||||
let tick_rate = Duration::from_millis(tick_rate);
|
||||
let (sender, receiver) = mpsc::channel();
|
||||
let handler = {
|
||||
let sender = sender.clone();
|
||||
thread::spawn(move || {
|
||||
let mut last_tick = Instant::now();
|
||||
loop {
|
||||
let timeout = tick_rate
|
||||
.checked_sub(last_tick.elapsed())
|
||||
.unwrap_or(tick_rate);
|
||||
|
||||
if event::poll(timeout).expect("failed to poll new events") {
|
||||
match event::read().expect("unable to read event") {
|
||||
CrosstermEvent::Key(e) => sender.send(Event::Key(e)),
|
||||
CrosstermEvent::Mouse(e) => sender.send(Event::Mouse(e)),
|
||||
CrosstermEvent::Resize(w, h) => sender.send(Event::Resize(w, h)),
|
||||
CrosstermEvent::FocusGained => Ok(()),
|
||||
CrosstermEvent::FocusLost => Ok(()),
|
||||
CrosstermEvent::Paste(_) => unimplemented!(),
|
||||
}
|
||||
.expect("failed to send terminal event")
|
||||
}
|
||||
|
||||
if last_tick.elapsed() >= tick_rate {
|
||||
sender.send(Event::Tick).expect("failed to send tick event");
|
||||
last_tick = Instant::now();
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
Self {
|
||||
sender,
|
||||
receiver,
|
||||
handler,
|
||||
}
|
||||
}
|
||||
|
||||
/// Receive the next event from the handler thread.
|
||||
///
|
||||
/// This function will always block the current thread if
|
||||
/// there is no data available and it's possible for more data to be sent.
|
||||
pub fn next(&self) -> AppResult<Event> {
|
||||
Ok(self.receiver.recv()?)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
use crate::app::{App, AppResult};
|
||||
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
|
||||
|
||||
pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
|
||||
match key_event.code {
|
||||
KeyCode::Char('q') | KeyCode::Esc => app.quit(),
|
||||
KeyCode::Char('c') | KeyCode::Char('C') => {
|
||||
if key_event.modifiers == KeyModifiers::CONTROL {
|
||||
app.quit();
|
||||
}
|
||||
}
|
||||
|
||||
KeyCode::Char('j') => {
|
||||
app.list.next();
|
||||
}
|
||||
|
||||
KeyCode::Char('k') => {
|
||||
app.list.prev();
|
||||
}
|
||||
|
||||
KeyCode::Enter | KeyCode::Char('l') => {
|
||||
let song = app.conn.get_song_with_only_filename(app.conn.songs_filenames.get(app.list.index).unwrap());
|
||||
app.conn.push(&song).unwrap();
|
||||
app.update_queue();
|
||||
}
|
||||
|
||||
// Playback controls
|
||||
// Toggle Pause
|
||||
KeyCode::Char('p') => {
|
||||
app.conn.toggle_pause();
|
||||
}
|
||||
|
||||
// Pause
|
||||
KeyCode::Char('s') => {
|
||||
app.conn.pause();
|
||||
}
|
||||
|
||||
// Clearn Queue
|
||||
KeyCode::Char('x') => {
|
||||
app.conn.conn.clear()?;
|
||||
app.update_queue();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/// Command line interface (deprecated)
|
||||
pub mod cli;
|
||||
|
||||
/// Handle mpd connection
|
||||
pub mod connection;
|
||||
|
||||
/// Widget renderer
|
||||
pub mod ui;
|
||||
|
||||
/// Terminal user Interface
|
||||
pub mod tui;
|
||||
|
||||
/// Content list
|
||||
pub mod list;
|
||||
|
||||
/// Event Handler
|
||||
pub mod event;
|
||||
|
||||
/// KeyEvent Handler
|
||||
pub mod handler;
|
||||
|
||||
/// Application
|
||||
pub mod app;
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#[derive(Debug)]
|
||||
pub struct ContentList {
|
||||
pub index: usize
|
||||
}
|
||||
|
||||
impl ContentList {
|
||||
pub fn new() -> Self {
|
||||
ContentList {
|
||||
index: 0
|
||||
}
|
||||
}
|
||||
|
||||
// Go to next item in list
|
||||
pub fn next(&mut self) {
|
||||
self.index += 1;
|
||||
}
|
||||
|
||||
/// Go to previous item in list
|
||||
pub fn prev(&mut self) {
|
||||
if self.index != 0 {
|
||||
self.index -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
71
src/main.rs
71
src/main.rs
|
|
@ -1,24 +1,63 @@
|
|||
mod cli;
|
||||
mod connection;
|
||||
#![allow(unused_imports)]
|
||||
use clap::Parser;
|
||||
use cli::Args;
|
||||
use cli::Command;
|
||||
use connection::Connection;
|
||||
use rmptui::app;
|
||||
use rmptui::app::App;
|
||||
use rmptui::app::AppResult;
|
||||
use rmptui::cli::Args;
|
||||
use rmptui::cli::Command;
|
||||
use rmptui::connection::Connection;
|
||||
use rmptui::event::Event;
|
||||
use rmptui::event::EventHandler;
|
||||
use rmptui::handler;
|
||||
use rmptui::tui;
|
||||
use std::io;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args = Args::parse();
|
||||
let mut conn = Connection::new("127.0.0.1:6600")?;
|
||||
use crossterm::event::{self, KeyCode, KeyEvent, KeyEventKind};
|
||||
use ratatui::{
|
||||
prelude::*,
|
||||
symbols::border,
|
||||
widgets::{block::*, *},
|
||||
};
|
||||
|
||||
match args.command {
|
||||
Command::Volume { vol } => {
|
||||
conn.set_volume(vol);
|
||||
pub type Result<T> = core::result::Result<T, Error>;
|
||||
pub type Error = Box<dyn std::error::Error>;
|
||||
|
||||
fn main() -> AppResult<()> {
|
||||
// let args = Args::parse();
|
||||
|
||||
// if args.no_tui {
|
||||
// handle_tui()?;
|
||||
// } else {
|
||||
// match args.command {
|
||||
// Command::Volume { vol } => {
|
||||
// conn.set_volume(vol);
|
||||
// }
|
||||
// Command::Dmenu => conn.play_dmenu().unwrap(),
|
||||
// Command::Fzf => conn.play_fzf().unwrap(),
|
||||
// Command::Status => conn.status(),
|
||||
// Command::Pause => conn.pause(),
|
||||
// Command::Toggle => conn.toggle_pause(),
|
||||
// };
|
||||
// }
|
||||
|
||||
let backend = CrosstermBackend::new(io::stderr());
|
||||
let terminal = Terminal::new(backend)?;
|
||||
let mut app = App::new("127.0.0.1:6600");
|
||||
let events = EventHandler::new(250);
|
||||
|
||||
let mut tui = tui::Tui::new(terminal, events);
|
||||
tui.init()?;
|
||||
|
||||
while app.running {
|
||||
tui.draw(&mut app)?;
|
||||
match tui.events.next()? {
|
||||
Event::Tick => app.tick(),
|
||||
Event::Key(key_event) => handler::handle_key_events(key_event, &mut app)?,
|
||||
Event::Mouse(_) => {}
|
||||
Event::Resize(_, _) => {}
|
||||
}
|
||||
Command::Dmenu => conn.play_dmenu(),
|
||||
Command::Fzf => conn.play_fzf(),
|
||||
Command::Status => conn.status(),
|
||||
Command::Pause => conn.pause(),
|
||||
Command::Toggle => conn.toggle_pause(),
|
||||
}
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
use crate::connection::Connection;
|
||||
use crate::ui;
|
||||
use crossterm::event::{DisableMouseCapture, EnableMouseCapture};
|
||||
use crossterm::{
|
||||
terminal::{self, *},
|
||||
};
|
||||
use ratatui::prelude::*;
|
||||
use std::io::{self, stdout, Stdout};
|
||||
use std::panic;
|
||||
|
||||
use crate::app::{App, AppResult};
|
||||
use crate::event::EventHandler;
|
||||
|
||||
pub type CrosstermTerminal = ratatui::Terminal<ratatui::backend::CrosstermBackend<std::io::Stderr>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Tui {
|
||||
terminal: CrosstermTerminal,
|
||||
pub events: EventHandler,
|
||||
}
|
||||
|
||||
impl Tui {
|
||||
pub fn new(terminal: CrosstermTerminal, events: EventHandler) -> Self {
|
||||
Self { terminal, events }
|
||||
}
|
||||
|
||||
pub fn init(&mut self) -> AppResult<()> {
|
||||
terminal::enable_raw_mode()?;
|
||||
crossterm::execute!(io::stdout(), EnterAlternateScreen, EnableMouseCapture)?;
|
||||
|
||||
let panic_hook = panic::take_hook();
|
||||
panic::set_hook(Box::new(move |panic| {
|
||||
Self::reset().expect("failed to reset the terminal");
|
||||
panic_hook(panic);
|
||||
}));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// [`Draw`] the terminal interface by [`rendering`] the widgets.
|
||||
///
|
||||
/// [`Draw`]: ratatui::Terminal::draw
|
||||
/// [`rendering`]: crate::ui::render
|
||||
pub fn draw(&mut self, app: &mut App) -> AppResult<()> {
|
||||
self.terminal.draw(|frame| ui::render(app, frame))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Resets the terminal interface.
|
||||
///
|
||||
/// This function is also used for the panic hook to revert
|
||||
/// the terminal properties if unexpected errors occur.
|
||||
fn reset() -> AppResult<()> {
|
||||
terminal::disable_raw_mode()?;
|
||||
crossterm::execute!(io::stderr(), LeaveAlternateScreen, DisableMouseCapture)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Exits the terminal interface.
|
||||
///
|
||||
/// It disables the raw mode and reverts back the terminal properties.
|
||||
pub fn exit(&mut self) -> AppResult<()> {
|
||||
Self::reset()?;
|
||||
self.terminal.show_cursor()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
use crate::{app::App, connection::Connection};
|
||||
use ratatui::{prelude::*, widgets::*};
|
||||
|
||||
/// Renders the user interface widgets
|
||||
pub fn render(app: &mut App, frame: &mut Frame) {
|
||||
// This is where you add new widgets.
|
||||
// See the following resources:
|
||||
// - https://docs.rs/ratatui/latest/ratatui/widgets/index.html
|
||||
// - https://github.com/ratatui-org/ratatui/tree/master/examples
|
||||
|
||||
// List of songs
|
||||
let mut state = ListState::default();
|
||||
let size = Rect::new(100, 0, frame.size().width, frame.size().height - 3);
|
||||
let list = List::new(app.conn.songs_filenames.clone())
|
||||
.block(Block::default().title("Song List").borders(Borders::ALL))
|
||||
.highlight_style(Style::new().add_modifier(Modifier::REVERSED))
|
||||
.highlight_symbol(">>")
|
||||
.repeat_highlight_symbol(true);
|
||||
|
||||
state.select(Some(app.list.index));
|
||||
frame.render_stateful_widget(list, size, &mut state);
|
||||
|
||||
// Play Queue
|
||||
let size = Rect::new(0, 0, 100, frame.size().height - 25);
|
||||
let list = List::new(app.play_deque.clone())
|
||||
.block(Block::default().title("Play Queue").borders(Borders::ALL))
|
||||
.highlight_style(Style::new().add_modifier(Modifier::REVERSED))
|
||||
.highlight_symbol(">>")
|
||||
.repeat_highlight_symbol(true);
|
||||
frame.render_widget(list, size);
|
||||
|
||||
// Status
|
||||
let size = Rect::new(0, frame.size().height - 3, frame.size().width, 3);
|
||||
let status = Paragraph::new(app.conn.conn.status().unwrap().volume.to_string())
|
||||
.block(Block::default().title("Status").borders(Borders::ALL));
|
||||
frame.render_widget(status, size);
|
||||
}
|
||||
Reference in New Issue