Add manual input elements to the app an ui #216
130
Cargo.lock
generated
130
Cargo.lock
generated
@ -65,7 +65,7 @@ version = "0.2.14"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi 0.1.19",
|
||||||
"libc",
|
"libc",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
@ -129,9 +129,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "castaway"
|
name = "castaway"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc"
|
checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustversion",
|
"rustversion",
|
||||||
]
|
]
|
||||||
@ -168,13 +168,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "compact_str"
|
name = "compact_str"
|
||||||
version = "0.7.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f"
|
checksum = "6050c3a16ddab2e412160b31f2c871015704239bca62f72f6e5f0be631d3f644"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"castaway",
|
"castaway",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"itoa",
|
"itoa",
|
||||||
|
"rustversion",
|
||||||
"ryu",
|
"ryu",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
]
|
]
|
||||||
@ -197,15 +198,15 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossterm"
|
name = "crossterm"
|
||||||
version = "0.27.0"
|
version = "0.28.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
|
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.2",
|
"bitflags 2.4.2",
|
||||||
"crossterm_winapi",
|
"crossterm_winapi",
|
||||||
"libc",
|
"mio 1.0.2",
|
||||||
"mio",
|
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
|
"rustix",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"signal-hook-mio",
|
"signal-hook-mio",
|
||||||
"winapi",
|
"winapi",
|
||||||
@ -393,9 +394,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.4.1"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
@ -406,6 +407,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "0.2.12"
|
version = "0.2.12"
|
||||||
@ -498,10 +505,14 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indoc"
|
name = "instability"
|
||||||
version = "2.0.4"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8"
|
checksum = "b23a0c8dfe501baac4adf6ebbfa6eddf8f0c07f56b058cc1288017e32397846c"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.48",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipnet"
|
name = "ipnet"
|
||||||
@ -511,9 +522,9 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.12.1"
|
version = "0.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
@ -541,15 +552,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.153"
|
version = "0.2.158"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.4.13"
|
version = "0.4.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
|
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
@ -604,11 +615,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
|
checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
|
||||||
"wasi",
|
"wasi",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi 0.3.9",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"wasi",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mockall"
|
name = "mockall"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
@ -653,6 +676,7 @@ dependencies = [
|
|||||||
"structopt",
|
"structopt",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tui-input",
|
||||||
"url",
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
"version_check",
|
"version_check",
|
||||||
@ -911,21 +935,22 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ratatui"
|
name = "ratatui"
|
||||||
version = "0.26.0"
|
version = "0.28.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "154b85ef15a5d1719bcaa193c3c81fe645cd120c156874cd660fe49fd21d1373"
|
checksum = "fdef7f9be5c0122f890d58bdf4d964349ba6a6161f705907526d891efabba57d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.2",
|
"bitflags 2.4.2",
|
||||||
"cassowary",
|
"cassowary",
|
||||||
"compact_str",
|
"compact_str",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"indoc",
|
"instability",
|
||||||
"itertools",
|
"itertools",
|
||||||
"lru",
|
"lru",
|
||||||
"paste",
|
"paste",
|
||||||
"stability",
|
|
||||||
"strum",
|
"strum",
|
||||||
|
"strum_macros",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
|
"unicode-truncate",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -986,9 +1011,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.31"
|
version = "0.38.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
|
checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.2",
|
"bitflags 2.4.2",
|
||||||
"errno",
|
"errno",
|
||||||
@ -1127,12 +1152,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook-mio"
|
name = "signal-hook-mio"
|
||||||
version = "0.2.3"
|
version = "0.2.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio 1.0.2",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1189,16 +1214,6 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "stability"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ebd1b177894da2a2d9120208c3386066af06a488255caabc5de8ddca22dbc3ce"
|
|
||||||
dependencies = [
|
|
||||||
"quote",
|
|
||||||
"syn 1.0.109",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "static_assertions"
|
name = "static_assertions"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@ -1246,11 +1261,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum_macros"
|
name = "strum_macros"
|
||||||
version = "0.26.1"
|
version = "0.26.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18"
|
checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.4.1",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
@ -1377,7 +1392,7 @@ dependencies = [
|
|||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio 0.8.10",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
@ -1470,6 +1485,16 @@ version = "0.2.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tui-input"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd137780d743c103a391e06fe952487f914b299a4fe2c3626677f6a6339a7c6b"
|
||||||
|
dependencies = [
|
||||||
|
"ratatui",
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typed-builder"
|
name = "typed-builder"
|
||||||
version = "0.18.1"
|
version = "0.18.1"
|
||||||
@ -1518,10 +1543,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
|
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-truncate"
|
||||||
version = "0.1.11"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf"
|
||||||
|
dependencies = [
|
||||||
|
"itertools",
|
||||||
|
"unicode-segmentation",
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
|
@ -7,16 +7,18 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aho-corasick = { version = "1.1.2", optional = true }
|
aho-corasick = { version = "1.1.2", optional = true }
|
||||||
crossterm = { version = "0.27.0", optional = true}
|
crossterm = { version = "0.28.1", optional = true}
|
||||||
once_cell = { version = "1.19.0", optional = true}
|
once_cell = { version = "1.19.0", optional = true}
|
||||||
openssh = { version = "0.10.3", features = ["native-mux"], default-features = false, optional = true}
|
openssh = { version = "0.10.3", features = ["native-mux"], default-features = false, optional = true}
|
||||||
paste = { version = "1.0.15", optional = true }
|
paste = { version = "1.0.15", optional = true }
|
||||||
ratatui = { version = "0.26.0", optional = true}
|
ratatui = { version = "0.28.1", optional = true}
|
||||||
reqwest = { version = "0.11.25", features = ["blocking", "json"], optional = true }
|
reqwest = { version = "0.11.25", features = ["blocking", "json"], optional = true }
|
||||||
serde = { version = "1.0.196", features = ["derive"], optional = true }
|
serde = { version = "1.0.196", features = ["derive"], optional = true }
|
||||||
serde_json = { version = "1.0.113", optional = true}
|
serde_json = { version = "1.0.113", optional = true}
|
||||||
structopt = { version = "0.3.26", optional = true}
|
structopt = { version = "0.3.26", optional = true}
|
||||||
tokio = { version = "1.36.0", features = ["rt"], optional = true}
|
tokio = { version = "1.36.0", features = ["rt"], optional = true}
|
||||||
|
# ratatui/crossterm dependency version must match with musichhoard's ratatui/crossterm
|
||||||
|
tui-input = { version = "0.10.1", optional = true }
|
||||||
url = { version = "2.5.0" }
|
url = { version = "2.5.0" }
|
||||||
uuid = { version = "1.7.0" }
|
uuid = { version = "1.7.0" }
|
||||||
|
|
||||||
@ -35,7 +37,7 @@ database-json = ["serde", "serde_json"]
|
|||||||
library-beets = []
|
library-beets = []
|
||||||
library-beets-ssh = ["openssh", "tokio"]
|
library-beets-ssh = ["openssh", "tokio"]
|
||||||
musicbrainz = ["paste", "reqwest", "serde", "serde_json"]
|
musicbrainz = ["paste", "reqwest", "serde", "serde_json"]
|
||||||
tui = ["aho-corasick", "crossterm", "once_cell", "ratatui"]
|
tui = ["aho-corasick", "crossterm", "once_cell", "ratatui", "tui-input"]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "musichoard"
|
name = "musichoard"
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
|
use tui_input::{backend::crossterm::EventHandler, Input};
|
||||||
|
|
||||||
use crate::tui::app::{
|
use crate::tui::app::{
|
||||||
machine::{App, AppInner, AppMachine},
|
machine::{App, AppInner, AppMachine},
|
||||||
AppPublic, AppState, IAppInteractInput,
|
AppPublic, AppState, IAppInteractInput, InputEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::match_state::MatchState;
|
use super::match_state::MatchState;
|
||||||
|
|
||||||
pub struct InputState {
|
pub struct InputState {
|
||||||
string: String,
|
input: Input,
|
||||||
client: InputClient,
|
client: InputClient,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,7 +21,7 @@ impl AppMachine<InputState> {
|
|||||||
AppMachine {
|
AppMachine {
|
||||||
inner,
|
inner,
|
||||||
state: InputState {
|
state: InputState {
|
||||||
string: String::new(),
|
input: Input::default(),
|
||||||
client,
|
client,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -36,7 +38,7 @@ impl<'a> From<&'a mut AppMachine<InputState>> for AppPublic<'a> {
|
|||||||
fn from(machine: &'a mut AppMachine<InputState>) -> Self {
|
fn from(machine: &'a mut AppMachine<InputState>) -> Self {
|
||||||
AppPublic {
|
AppPublic {
|
||||||
inner: (&mut machine.inner).into(),
|
inner: (&mut machine.inner).into(),
|
||||||
state: AppState::Input(&machine.state.string),
|
state: AppState::Input(&machine.state.input),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,13 +46,8 @@ impl<'a> From<&'a mut AppMachine<InputState>> for AppPublic<'a> {
|
|||||||
impl IAppInteractInput for AppMachine<InputState> {
|
impl IAppInteractInput for AppMachine<InputState> {
|
||||||
type APP = App;
|
type APP = App;
|
||||||
|
|
||||||
fn append_character(mut self, ch: char) -> Self::APP {
|
fn input(mut self, input: InputEvent) -> Self::APP {
|
||||||
self.state.string.push(ch);
|
self.state.input.handle_event(&crossterm::event::Event::Key(input));
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn delete_character(mut self) -> Self::APP {
|
|
||||||
self.state.string.pop();
|
|
||||||
self.into()
|
self.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
mod machine;
|
mod machine;
|
||||||
mod selection;
|
mod selection;
|
||||||
|
|
||||||
|
use crossterm::event::KeyEvent;
|
||||||
pub use machine::App;
|
pub use machine::App;
|
||||||
pub use selection::{Category, Delta, Selection, WidgetState};
|
pub use selection::{Category, Delta, Selection, WidgetState};
|
||||||
|
|
||||||
use musichoard::collection::{album::AlbumMeta, artist::ArtistMeta, Collection};
|
use musichoard::collection::{album::AlbumMeta, artist::ArtistMeta, Collection};
|
||||||
|
use tui_input::Input;
|
||||||
|
|
||||||
use crate::tui::lib::interface::musicbrainz::Match;
|
use crate::tui::lib::interface::musicbrainz::Match;
|
||||||
|
|
||||||
@ -133,11 +135,11 @@ pub trait IAppInteractMatch {
|
|||||||
fn abort(self) -> Self::APP;
|
fn abort(self) -> Self::APP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type InputEvent = KeyEvent;
|
||||||
pub trait IAppInteractInput {
|
pub trait IAppInteractInput {
|
||||||
type APP: IApp;
|
type APP: IApp;
|
||||||
|
|
||||||
fn append_character(self, ch: char) -> Self::APP;
|
fn input(self, input: InputEvent) -> Self::APP;
|
||||||
fn delete_character(self) -> Self::APP;
|
|
||||||
fn confirm(self) -> Self::APP;
|
fn confirm(self) -> Self::APP;
|
||||||
fn cancel(self) -> Self::APP;
|
fn cancel(self) -> Self::APP;
|
||||||
}
|
}
|
||||||
@ -214,8 +216,19 @@ pub struct MatchStatePublic<'app> {
|
|||||||
pub state: &'app mut WidgetState,
|
pub state: &'app mut WidgetState,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type AppPublicState<'app> =
|
pub type InputStatePublic<'app> = &'app Input;
|
||||||
AppState<(), (), (), &'app str, (), MatchStatePublic<'app>, &'app str, &'app str, &'app str>;
|
|
||||||
|
pub type AppPublicState<'app> = AppState<
|
||||||
|
(),
|
||||||
|
(),
|
||||||
|
(),
|
||||||
|
&'app str,
|
||||||
|
(),
|
||||||
|
MatchStatePublic<'app>,
|
||||||
|
InputStatePublic<'app>,
|
||||||
|
&'app str,
|
||||||
|
&'app str,
|
||||||
|
>;
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
BrowseState,
|
BrowseState,
|
||||||
|
@ -201,20 +201,17 @@ impl<APP: IApp> IEventHandlerPrivate<APP> for EventHandler {
|
|||||||
|
|
||||||
fn handle_input_key_event(app: <APP as IApp>::InputState, key_event: KeyEvent) -> APP {
|
fn handle_input_key_event(app: <APP as IApp>::InputState, key_event: KeyEvent) -> APP {
|
||||||
if key_event.modifiers == KeyModifiers::CONTROL {
|
if key_event.modifiers == KeyModifiers::CONTROL {
|
||||||
return match key_event.code {
|
match key_event.code {
|
||||||
KeyCode::Char('g') | KeyCode::Char('G') => app.cancel(),
|
KeyCode::Char('g') | KeyCode::Char('G') => return app.cancel(),
|
||||||
_ => app.no_op(),
|
_ => {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
match key_event.code {
|
match key_event.code {
|
||||||
// Add/remove character.
|
|
||||||
KeyCode::Char(ch) => app.append_character(ch),
|
|
||||||
KeyCode::Backspace => app.delete_character(),
|
|
||||||
// Return.
|
// Return.
|
||||||
KeyCode::Esc | KeyCode::Enter => app.confirm(),
|
KeyCode::Esc | KeyCode::Enter => app.confirm(),
|
||||||
// Othey keys.
|
// Othey keys.
|
||||||
_ => app.no_op(),
|
_ => app.input(key_event),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,8 @@ use crate::tui::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::app::InputStatePublic;
|
||||||
|
|
||||||
pub trait IUi {
|
pub trait IUi {
|
||||||
fn render<APP: IAppAccess>(app: &mut APP, frame: &mut Frame);
|
fn render<APP: IAppAccess>(app: &mut APP, frame: &mut Frame);
|
||||||
}
|
}
|
||||||
@ -68,7 +70,7 @@ impl Ui {
|
|||||||
frame: &mut Frame,
|
frame: &mut Frame,
|
||||||
) {
|
) {
|
||||||
let active = selection.category();
|
let active = selection.category();
|
||||||
let areas = FrameArea::new(frame.size());
|
let areas = FrameArea::new(frame.area());
|
||||||
|
|
||||||
let artist_state = ArtistState::new(
|
let artist_state = ArtistState::new(
|
||||||
active == Category::Artist,
|
active == Category::Artist,
|
||||||
@ -106,7 +108,7 @@ impl Ui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render_info_overlay(artists: &Collection, selection: &mut Selection, frame: &mut Frame) {
|
fn render_info_overlay(artists: &Collection, selection: &mut Selection, frame: &mut Frame) {
|
||||||
let area = OverlayBuilder::default().build(frame.size());
|
let area = OverlayBuilder::default().build(frame.area());
|
||||||
|
|
||||||
if selection.category() == Category::Artist {
|
if selection.category() == Category::Artist {
|
||||||
let overlay = ArtistOverlay::new(artists, &selection.widget_state_artist().list);
|
let overlay = ArtistOverlay::new(artists, &selection.widget_state_artist().list);
|
||||||
@ -126,13 +128,13 @@ impl Ui {
|
|||||||
let area = OverlayBuilder::default()
|
let area = OverlayBuilder::default()
|
||||||
.with_width(OverlaySize::Value(39))
|
.with_width(OverlaySize::Value(39))
|
||||||
.with_height(OverlaySize::Value(4))
|
.with_height(OverlaySize::Value(4))
|
||||||
.build(frame.size());
|
.build(frame.area());
|
||||||
let reload_text = ReloadOverlay::paragraph();
|
let reload_text = ReloadOverlay::paragraph();
|
||||||
UiWidget::render_overlay_widget("Reload", reload_text, area, false, frame);
|
UiWidget::render_overlay_widget("Reload", reload_text, area, false, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_fetch_overlay(frame: &mut Frame) {
|
fn render_fetch_overlay(frame: &mut Frame) {
|
||||||
let area = OverlayBuilder::default().build(frame.size());
|
let area = OverlayBuilder::default().build(frame.area());
|
||||||
let fetch_text = FetchOverlay::paragraph();
|
let fetch_text = FetchOverlay::paragraph();
|
||||||
UiWidget::render_overlay_widget("Fetching", fetch_text, area, false, frame)
|
UiWidget::render_overlay_widget("Fetching", fetch_text, area, false, frame)
|
||||||
}
|
}
|
||||||
@ -142,15 +144,29 @@ impl Ui {
|
|||||||
state: &mut WidgetState,
|
state: &mut WidgetState,
|
||||||
frame: &mut Frame,
|
frame: &mut Frame,
|
||||||
) {
|
) {
|
||||||
let area = OverlayBuilder::default().build(frame.size());
|
let area = OverlayBuilder::default().build(frame.area());
|
||||||
let st = MatchOverlay::new(info, state);
|
let st = MatchOverlay::new(info, state);
|
||||||
UiWidget::render_overlay_list_widget(&st.matching, st.list, st.state, true, area, frame)
|
UiWidget::render_overlay_list_widget(&st.matching, st.list, st.state, true, area, frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_input_overlay(input: InputStatePublic, frame: &mut Frame) {
|
||||||
|
let area = OverlayBuilder::default()
|
||||||
|
.with_height(OverlaySize::Value(3))
|
||||||
|
.build(frame.area());
|
||||||
|
UiWidget::render_overlay_widget("Input", Paragraph::new(input.value()), area, false, frame);
|
||||||
|
|
||||||
|
let width = area.width.max(3) - 3; // keep 2 for borders and 1 for cursor
|
||||||
|
let scroll = input.visual_scroll(width as usize);
|
||||||
|
frame.set_cursor_position((
|
||||||
|
area.x + ((input.visual_cursor()).max(scroll) - scroll) as u16 + 1,
|
||||||
|
area.y + 1,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
fn render_error_overlay<S: AsRef<str>>(title: S, msg: S, frame: &mut Frame) {
|
fn render_error_overlay<S: AsRef<str>>(title: S, msg: S, frame: &mut Frame) {
|
||||||
let area = OverlayBuilder::default()
|
let area = OverlayBuilder::default()
|
||||||
.with_height(OverlaySize::Value(4))
|
.with_height(OverlaySize::Value(4))
|
||||||
.build(frame.size());
|
.build(frame.area());
|
||||||
let error_text = ErrorOverlay::paragraph(msg.as_ref());
|
let error_text = ErrorOverlay::paragraph(msg.as_ref());
|
||||||
UiWidget::render_overlay_widget(title.as_ref(), error_text, area, true, frame);
|
UiWidget::render_overlay_widget(title.as_ref(), error_text, area, true, frame);
|
||||||
}
|
}
|
||||||
@ -170,6 +186,7 @@ impl IUi for Ui {
|
|||||||
AppState::Reload(()) => Self::render_reload_overlay(frame),
|
AppState::Reload(()) => Self::render_reload_overlay(frame),
|
||||||
AppState::Fetch(()) => Self::render_fetch_overlay(frame),
|
AppState::Fetch(()) => Self::render_fetch_overlay(frame),
|
||||||
AppState::Match(public) => Self::render_match_overlay(public.info, public.state, frame),
|
AppState::Match(public) => Self::render_match_overlay(public.info, public.state, frame),
|
||||||
|
AppState::Input(input) => Self::render_input_overlay(input, frame),
|
||||||
AppState::Error(msg) => Self::render_error_overlay("Error", msg, frame),
|
AppState::Error(msg) => Self::render_error_overlay("Error", msg, frame),
|
||||||
AppState::Critical(msg) => Self::render_error_overlay("Critical Error", msg, frame),
|
AppState::Critical(msg) => Self::render_error_overlay("Critical Error", msg, frame),
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -211,7 +228,7 @@ mod tests {
|
|||||||
info: m.info,
|
info: m.info,
|
||||||
state: m.state,
|
state: m.state,
|
||||||
}),
|
}),
|
||||||
AppState::Input(s) => AppState::Input(s),
|
AppState::Input(ref i) => AppState::Input(i),
|
||||||
AppState::Error(s) => AppState::Error(s),
|
AppState::Error(s) => AppState::Error(s),
|
||||||
AppState::Critical(s) => AppState::Critical(s),
|
AppState::Critical(s) => AppState::Critical(s),
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user