From c7cf5e44c4af54445d633c9c36ff2d69dae1aaff Mon Sep 17 00:00:00 2001 From: Artem Polishchuk Date: Mon, 30 Mar 2020 14:25:23 +0300 Subject: [PATCH 001/311] Add Fedora installation info --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 77327c38..df53abbb 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ The terminal in the demo above is using the [Rigel theme](https://rigel.netlify. - [Snap](#snap) - [AUR](#aur) - [Void Linux](#void-linux) + - [Fedora/CentOS](#fedora-centos) - [Cargo](#cargo) - [Note on Linux](#note-on-linux) - [Windows](#windows-10) @@ -89,6 +90,14 @@ Available on the official repositories. To install, run sudo xbps-install -Su spotify-tui ``` +### Fedora/CentOS + +Available on the [Copr](https://copr.fedorainfracloud.org/coprs/atim/spotify-tui/) repositories. To install, run + +```bash +sudo dnf copr enable atim/spotify-tui -y && sudo dnf install spotify-tui +``` + ### Cargo Use this option if your architecture is not supported by the pre-built binaries found on the [releases page](https://github.com/Rigellute/spotify-tui/releases). From b7a5ecb4e4bccd73ba1ad3ae21ec0f0382caac91 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2020 06:52:43 +0000 Subject: [PATCH 002/311] Bump anyhow from 1.0.27 to 1.0.28 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.27 to 1.0.28. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.27...1.0.28) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88c7ee1a..8123e458 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,9 +20,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "013a6e0a2cbe3d20f9c60b65458f7a7f7a5e636c5d0f45a5a6aee5d4b1f01785" +checksum = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff" [[package]] name = "arc-swap" diff --git a/Cargo.toml b/Cargo.toml index cf882d80..9056cfcb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ crossterm = "0.17" tokio = { version = "0.2", features = ["full"] } proc-macro2 = "1.0.9" rand="0.7.3" -anyhow = "1.0.26" +anyhow = "1.0.28" [[bin]] bench = false From 376efcbabf2aa582ca61f6a5eda65a5f68ff1595 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2020 10:38:57 +0000 Subject: [PATCH 003/311] Bump proc-macro2 from 1.0.9 to 1.0.10 Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.9 to 1.0.10. - [Release notes](https://github.com/alexcrichton/proc-macro2/releases) - [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.9...1.0.10) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 28 ++++++++++++++-------------- Cargo.toml | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8123e458..3643dfb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -456,7 +456,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", "synstructure", @@ -560,7 +560,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -1096,7 +1096,7 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -1148,9 +1148,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" +checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" dependencies = [ "unicode-xid 0.2.0", ] @@ -1176,7 +1176,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", ] [[package]] @@ -1531,7 +1531,7 @@ version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -1626,7 +1626,7 @@ dependencies = [ "clipboard", "crossterm 0.17.1", "dirs", - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "rand 0.7.3", "rspotify", "serde", @@ -1666,7 +1666,7 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "unicode-xid 0.2.0", ] @@ -1677,7 +1677,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", "unicode-xid 0.2.0", @@ -1730,7 +1730,7 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "227362df41d566be41a28f64401e07a043157c21c14b9785a0d8e256f940a8fd" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -1785,7 +1785,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", ] @@ -1983,7 +1983,7 @@ dependencies = [ "bumpalo", "lazy_static", "log", - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", "wasm-bindgen-shared", @@ -2017,7 +2017,7 @@ version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931" dependencies = [ - "proc-macro2 1.0.9", + "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.17", "wasm-bindgen-backend", diff --git a/Cargo.toml b/Cargo.toml index 9056cfcb..0a5af7c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ backtrace = "0.3.46" clipboard = "0.5.0" crossterm = "0.17" tokio = { version = "0.2", features = ["full"] } -proc-macro2 = "1.0.9" +proc-macro2 = "1.0.10" rand="0.7.3" anyhow = "1.0.28" From 87d7ab8e0c4acafd07ba5cc5ab95605cf2df783a Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2020 10:45:41 +0000 Subject: [PATCH 004/311] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index df53abbb..0e326e49 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-44-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-45-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -338,6 +338,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Jeremy Stucki

πŸ’»
(´⌣`ΚƒΖͺ)

πŸ’» +
Artem Polishchuk

πŸ“¦ From 9deada3dc1dc301dc4ab9f06467da8eecf543d17 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2020 10:45:42 +0000 Subject: [PATCH 005/311] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 1366794c..757b65e9 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -411,6 +411,15 @@ "contributions": [ "code" ] + }, + { + "login": "tim77", + "name": "Artem Polishchuk", + "avatar_url": "https://avatars0.githubusercontent.com/u/5614476?v=4", + "profile": "https://github.com/tim77", + "contributions": [ + "platform" + ] } ], "contributorsPerLine": 7, From 4dc7d48f2ff44c880af71cde9fac49f205bf72d0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2020 06:48:29 +0000 Subject: [PATCH 006/311] Bump tokio from 0.2.13 to 0.2.14 Bumps [tokio](https://github.com/tokio-rs/tokio) from 0.2.13 to 0.2.14. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-0.2.13...tokio-0.2.14) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3643dfb1..3bca4957 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1757,9 +1757,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa5e81d6bc4e67fe889d5783bd2a128ab2e0cfa487e0be16b6a8d177b101616" +checksum = "2751672f9da075d045c67fdb0068be9850ab7b231fa77bb51d6fd35da9c0bb0d" dependencies = [ "bytes 0.5.4", "fnv", From 411a2246451ba1e97ccc88c12e00d3b9a1593062 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Fri, 3 Apr 2020 11:38:02 +0100 Subject: [PATCH 007/311] Regenerate lock file --- Cargo.lock | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3bca4957..13ffeb8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -609,9 +609,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7938e6aa2a31df4e21f224dc84704bd31c089a6d1355c535b03667371cccc843" +checksum = "377038bf3c89d18d6ca1431e7a5027194fbd724ca10592b9487ede5e8e144f42" dependencies = [ "bytes 0.5.4", "fnv", @@ -1127,9 +1127,9 @@ checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" [[package]] name = "proc-macro-hack" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcfdefadc3d57ca21cf17990a28ef4c0f7c61383a28cb7604cf4a18e6ede1420" +checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" [[package]] name = "proc-macro-nested" @@ -1496,21 +1496,22 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "security-framework" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97bbedbe81904398b6ebb054b3e912f99d55807125790f3198ac990d98def5b0" +checksum = "572dfa3a0785509e7a44b5b4bebcf94d41ba34e9ed9eb9df722545c3b3c4144a" dependencies = [ "bitflags", "core-foundation", "core-foundation-sys", + "libc", "security-framework-sys", ] [[package]] name = "security-framework-sys" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06fd2f23e31ef68dd2328cc383bd493142e46107a3a0e24f7d734e3f3b80fe4c" +checksum = "8ddb15a5fec93b7021b8a9e96009c5d8d51c15673569f7c0f6b7204e5b7b404f" dependencies = [ "core-foundation-sys", "libc", @@ -1606,9 +1607,9 @@ checksum = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" [[package]] name = "socket2" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" +checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" dependencies = [ "cfg-if", "libc", @@ -1757,9 +1758,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2751672f9da075d045c67fdb0068be9850ab7b231fa77bb51d6fd35da9c0bb0d" +checksum = "619cdb2245c40c42d563089b72e80c5df659513d667a017598439ef7a7b1ffe1" dependencies = [ "bytes 0.5.4", "fnv", @@ -1815,9 +1816,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" +checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" dependencies = [ "bytes 0.5.4", "futures-core", @@ -2086,9 +2087,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" +checksum = "fa515c5163a99cc82bab70fd3bfdd36d827be85de63737b40fcef2ce084a436e" dependencies = [ "winapi 0.3.8", ] From 5cd08634903d9f6d4b31c684da3b120ab602c3d8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2020 07:12:03 +0000 Subject: [PATCH 008/311] Bump tokio from 0.2.15 to 0.2.16 Bumps [tokio](https://github.com/tokio-rs/tokio) from 0.2.15 to 0.2.16. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-0.2.15...tokio-0.2.16) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13ffeb8c..f7a47645 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1758,9 +1758,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "619cdb2245c40c42d563089b72e80c5df659513d667a017598439ef7a7b1ffe1" +checksum = "ee5a0dd887e37d37390c13ff8ac830f992307fe30a1fff0ab8427af67211ba28" dependencies = [ "bytes 0.5.4", "fnv", From e2459affaf0f5c87baf69591bf4facf58f3fa73a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2020 07:12:22 +0000 Subject: [PATCH 009/311] Bump serde from 1.0.105 to 1.0.106 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.105 to 1.0.106. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.105...v1.0.106) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13ffeb8c..37f46e11 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1519,18 +1519,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e707fbbf255b8fc8c3b99abb91e7257a622caeb20a9818cbadbeeede4e0932ff" +checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8" +checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" dependencies = [ "proc-macro2 1.0.10", "quote 1.0.3", From b8d1230a6c677141246c43aa84af7ef926fcfa5a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2020 07:12:45 +0000 Subject: [PATCH 010/311] Bump serde_json from 1.0.50 to 1.0.51 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.50 to 1.0.51. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.50...v1.0.51) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13ffeb8c..0c2ce7e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1539,9 +1539,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.50" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78a7a12c167809363ec3bd7329fc0a3369056996de43c4b37ef3cd54a6ce4867" +checksum = "da07b57ee2623368351e9a0488bb0b261322a15a6e0ae53e243cbdc0f4208da9" dependencies = [ "itoa", "ryu", From af142ab32a74fae17878ec4feb3ae635439bf4e0 Mon Sep 17 00:00:00 2001 From: Chris Sosnin Date: Thu, 9 Apr 2020 19:42:51 +0300 Subject: [PATCH 011/311] Fix crash when there're no artists avaliable Simple check for an out of bounds panic. --- src/handlers/artists.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/handlers/artists.rs b/src/handlers/artists.rs index 7d85f53d..4e28c8b9 100644 --- a/src/handlers/artists.rs +++ b/src/handlers/artists.rs @@ -42,9 +42,11 @@ pub fn handler(key: Key, app: &mut App) { } Key::Enter => { let artists = app.artists.to_owned(); - let artist = &artists[app.artists_list_index]; - app.get_artist(artist.id.clone(), artist.name.clone()); - app.push_navigation_stack(RouteId::Artist, ActiveBlock::ArtistBlock); + if !artists.is_empty() { + let artist = &artists[app.artists_list_index]; + app.get_artist(artist.id.clone(), artist.name.clone()); + app.push_navigation_stack(RouteId::Artist, ActiveBlock::ArtistBlock); + } } Key::Char('D') => app.user_unfollow_artists(ActiveBlock::AlbumList), Key::Char('e') => { From b520730ef19375427222673f7569c616d2575c93 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2020 06:51:17 +0000 Subject: [PATCH 012/311] Bump tokio from 0.2.16 to 0.2.17 Bumps [tokio](https://github.com/tokio-rs/tokio) from 0.2.16 to 0.2.17. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-0.2.16...tokio-0.2.17) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5a560da3..c14fe7b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1758,9 +1758,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee5a0dd887e37d37390c13ff8ac830f992307fe30a1fff0ab8427af67211ba28" +checksum = "39fb9142eb6e9cc37f4f29144e62618440b149a138eee01a7bbe9b9226aaf17c" dependencies = [ "bytes 0.5.4", "fnv", From 40de4b30db56d5bc65ed1102596fe2c105ef76ae Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2020 06:51:37 +0000 Subject: [PATCH 013/311] Bump crossterm from 0.17.1 to 0.17.3 Bumps [crossterm](https://github.com/crossterm-rs/crossterm) from 0.17.1 to 0.17.3. - [Release notes](https://github.com/crossterm-rs/crossterm/releases) - [Changelog](https://github.com/crossterm-rs/crossterm/blob/master/CHANGELOG.md) - [Commits](https://github.com/crossterm-rs/crossterm/commits) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5a560da3..e03cc229 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -281,9 +281,9 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.17.1" +version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aa8fc03593d557fb7897c88b0bae3cbae1e52c1ab7fbaa9033ef1af3a354eef" +checksum = "ccdd8ef63a44e821956c6a276eca0faaa889d6a067dfcdbd5bfe85dce3a1d250" dependencies = [ "bitflags", "crossterm_winapi 0.6.1", @@ -1625,7 +1625,7 @@ dependencies = [ "backtrace", "clap", "clipboard", - "crossterm 0.17.1", + "crossterm 0.17.3", "dirs", "proc-macro2 1.0.10", "rand 0.7.3", From 3ad2995e6a93c779e2b60e74b68f438153fc9fbc Mon Sep 17 00:00:00 2001 From: Chris Sosnin Date: Fri, 10 Apr 2020 12:23:15 +0300 Subject: [PATCH 014/311] Allow specifying alternative config file path Closes Rigellute/spotify-tui#355 --- src/main.rs | 13 ++++++++++++- src/user_config.rs | 17 +++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index 20cd9a8e..37a7836b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,6 +34,7 @@ use std::{ cmp::{max, min}, io::{self, stdout, Write}, panic::{self, PanicInfo}, + path::PathBuf, sync::Arc, time::Instant, }; @@ -42,7 +43,7 @@ use tui::{ backend::{Backend, CrosstermBackend}, Terminal, }; -use user_config::UserConfig; +use user_config::{UserConfig, UserConfigPaths}; const SCOPES: [&str; 13] = [ "playlist-read-collaborative", @@ -133,9 +134,19 @@ async fn main() -> Result<()> { .long("tick-rate") .help("Set the tick rate (milliseconds): the lower the number the higher the FPS. It can be nicer to have a lower value when you want to use the audio analysis view of the app. Beware that this comes at a CPU cost!") .takes_value(true)) + .arg(Arg::with_name("config") + .short("c") + .long("config") + .help("Specify configuration file path.") + .takes_value(true)) .get_matches(); let mut user_config = UserConfig::new(); + if let Some(config_file_path) = matches.value_of("config") { + let config_file_path = PathBuf::from(config_file_path); + let path = UserConfigPaths { config_file_path }; + user_config.path_to_config.replace(path); + } user_config.load_config()?; if let Some(tick_rate) = matches diff --git a/src/user_config.rs b/src/user_config.rs index 3c4d2d38..4581f00a 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -135,6 +135,7 @@ fn check_reserved_keys(key: Key) -> Result<()> { Ok(()) } +#[derive(Clone)] pub struct UserConfigPaths { pub config_file_path: PathBuf, } @@ -213,6 +214,7 @@ pub struct UserConfig { pub keys: KeyBindings, pub theme: Theme, pub behavior: BehaviorConfig, + pub path_to_config: Option, } impl UserConfig { @@ -246,10 +248,11 @@ impl UserConfig { volume_increment: 10, tick_rate_milliseconds: 250, }, + path_to_config: None, } } - pub fn get_or_build_paths(&self) -> Result { + pub fn get_or_build_paths(&mut self) -> Result<()> { match dirs::home_dir() { Some(home) => { let path = Path::new(&home); @@ -269,8 +272,8 @@ impl UserConfig { let paths = UserConfigPaths { config_file_path: config_file_path.to_path_buf(), }; - - Ok(paths) + self.path_to_config = Some(paths); + Ok(()) } None => Err(anyhow!("No $HOME directory found for client config")), } @@ -361,7 +364,13 @@ impl UserConfig { } pub fn load_config(&mut self) -> Result<()> { - let paths = self.get_or_build_paths()?; + let paths = match &self.path_to_config { + Some(path) => path, + None => { + self.get_or_build_paths()?; + self.path_to_config.as_ref().unwrap() + } + }; if paths.config_file_path.exists() { let config_string = fs::read_to_string(&paths.config_file_path)?; // serde fails if file is empty From 51af67d4db9d1cbaa3a25c079eaf43c1ff7bbf5e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2020 21:08:06 +0000 Subject: [PATCH 015/311] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e326e49..c42de1e1 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-45-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-46-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -339,6 +339,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Jeremy Stucki

πŸ’»
(´⌣`ΚƒΖͺ)

πŸ’»
Artem Polishchuk

πŸ“¦ +
Chris Sosnin

πŸ’» From aad9d26a1fb7837c303a6b8871d20a07a165a4bc Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2020 21:08:07 +0000 Subject: [PATCH 016/311] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 757b65e9..bfe66f70 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -420,6 +420,15 @@ "contributions": [ "platform" ] + }, + { + "login": "slumber", + "name": "Chris Sosnin", + "avatar_url": "https://avatars2.githubusercontent.com/u/48099298?v=4", + "profile": "https://github.com/slumber", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, From e567acb20601b607c3fb51aa3ec62a32f68ab2ef Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Fri, 10 Apr 2020 22:15:46 +0100 Subject: [PATCH 017/311] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57e7df6c..870251c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## [Unreleased] +- Fix crash when there're no artists avaliable [#388](https://github.com/Rigellute/spotify-tui/pull/388) +- Allow specifying alternative config file path [#391](https://github.com/Rigellute/spotify-tui/pull/391) + ## [0.17.1] - 2020-03-30 ### Fixed From 2ab4d24fd4b5c8a4ecc0b6bfb2e5a66a1cec2ec5 Mon Sep 17 00:00:00 2001 From: Chris Sosnin Date: Sat, 11 Apr 2020 19:13:23 +0300 Subject: [PATCH 018/311] List artists names in the album view --- src/ui/mod.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 93186fd9..91583fad 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -500,11 +500,16 @@ where TableHeaderItem { id: ColumnId::SongTitle, text: "Title", - width: get_percentage_width(layout_chunk.width, 0.80), + width: get_percentage_width(layout_chunk.width, 2.0 / 5.0) - 5, + }, + TableHeaderItem { + text: "Artist", + width: get_percentage_width(layout_chunk.width, 2.0 / 5.0), + ..Default::default() }, TableHeaderItem { text: "Length", - width: get_percentage_width(layout_chunk.width, 0.15), + width: get_percentage_width(layout_chunk.width, 1.0 / 5.0), ..Default::default() }, ], @@ -529,6 +534,7 @@ where "".to_string(), item.track_number.to_string(), item.name.to_owned(), + create_artist_string(&item.artists), millis_to_minutes(u128::from(item.duration_ms)), ], }) From e0bda08079a8399f0e378b124ec043dda2f66764 Mon Sep 17 00:00:00 2001 From: Ben Buhse Date: Sun, 12 Apr 2020 10:36:01 -0500 Subject: [PATCH 019/311] Update README.md Fix a typo on line 150 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c42de1e1..8444808c 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ After that program is available as: `spt` or `spt.exe` 1. Download the latest [binary](https://github.com/Rigellute/spotify-tui/releases) for your OS. 1. `cd` to the file you just downloaded and unzip -1. `cd` to `spotify-ui` and run with `./spt` +1. `cd` to `spotify-tui` and run with `./spt` ## Connecting to Spotify’s API From d84a8dd356671a7b3fa5e651c4455898435a88a8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2020 07:00:15 +0000 Subject: [PATCH 020/311] Bump tokio from 0.2.17 to 0.2.18 Bumps [tokio](https://github.com/tokio-rs/tokio) from 0.2.17 to 0.2.18. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-0.2.17...tokio-0.2.18) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c411ac26..76512a50 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1758,9 +1758,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39fb9142eb6e9cc37f4f29144e62618440b149a138eee01a7bbe9b9226aaf17c" +checksum = "34ef16d072d2b6dc8b4a56c70f5c5ced1a37752116f8e7c1e80c659aa7cb6713" dependencies = [ "bytes 0.5.4", "fnv", From 2e18881d061e95f23a6384783722ae556c471198 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2020 10:05:50 +0000 Subject: [PATCH 021/311] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8444808c..6d28b271 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-46-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-47-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -340,6 +340,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
(´⌣`ΚƒΖͺ)

πŸ’»
Artem Polishchuk

πŸ“¦
Chris Sosnin

πŸ’» +
Ben Buhse

πŸ“– From be4fc39068a35b7619a3f61c762cb11a846133c7 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2020 10:05:51 +0000 Subject: [PATCH 022/311] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index bfe66f70..16f9a8f0 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -429,6 +429,15 @@ "contributions": [ "code" ] + }, + { + "login": "bwbuhse", + "name": "Ben Buhse", + "avatar_url": "https://avatars1.githubusercontent.com/u/21225303?v=4", + "profile": "http://www.benbuhse.com", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, From f96a33e696e2241ac7ee01081628f313cccabeaf Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 13 Apr 2020 11:35:51 +0100 Subject: [PATCH 023/311] Fix unwrap crash when opening playlist Closes #394 --- src/network.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network.rs b/src/network.rs index b555fbf7..82cc0093 100644 --- a/src/network.rs +++ b/src/network.rs @@ -358,7 +358,7 @@ impl<'a> Network<'a> { .items .clone() .into_iter() - .map(|item| item.track.unwrap()) + .filter_map(|item| item.track) .collect::>(), ) .await; From 633ff729b5588f432b1fa3cf1f800c5893854467 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 13 Apr 2020 12:19:01 +0100 Subject: [PATCH 024/311] Update CHANGELOG --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 870251c8..1a6e4e23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,15 @@ ## [Unreleased] +### Fixed + +- Fix crash when opening playlist [#398](https://github.com/Rigellute/spotify-tui/pull/398) - Fix crash when there're no artists avaliable [#388](https://github.com/Rigellute/spotify-tui/pull/388) + +### Added + - Allow specifying alternative config file path [#391](https://github.com/Rigellute/spotify-tui/pull/391) +- List artists names in the album view [#393](https://github.com/Rigellute/spotify-tui/pull/393) ## [0.17.1] - 2020-03-30 From e8ed863b4946bbe88f5c95959d6b394c38a35de3 Mon Sep 17 00:00:00 2001 From: Chris Sosnin Date: Mon, 13 Apr 2020 23:52:47 +0300 Subject: [PATCH 025/311] Correctly handle playlist unfollowing --- src/app.rs | 13 +++++++++++++ src/handlers/search_results.rs | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/app.rs b/src/app.rs index ce8d77cf..d33533fb 100644 --- a/src/app.rs +++ b/src/app.rs @@ -777,6 +777,19 @@ impl App { } } + pub fn user_unfollow_playlist_search_result(&mut self) { + if let (Some(playlists), Some(selected_index), Some(user)) = ( + &self.search_results.playlists, + self.search_results.selected_playlists_index, + &self.user, + ) { + let selected_playlist = &playlists.playlists.items[selected_index]; + let selected_id = selected_playlist.id.clone(); + let user_id = user.id.clone(); + self.dispatch(IoEvent::UserUnfollowPlaylist(user_id, selected_id)) + } + } + pub fn get_made_for_you(&mut self) { // TODO: replace searches when relevant endpoint is added const DISCOVER_WEEKLY: &str = "Discover Weekly"; diff --git a/src/handlers/search_results.rs b/src/handlers/search_results.rs index 7350f862..61ee148d 100644 --- a/src/handlers/search_results.rs +++ b/src/handlers/search_results.rs @@ -444,7 +444,7 @@ pub fn handler(key: Key, app: &mut App) { SearchResultBlock::SongSearch => {} SearchResultBlock::ArtistSearch => app.user_unfollow_artists(ActiveBlock::SearchResultBlock), SearchResultBlock::PlaylistSearch => { - app.user_unfollow_playlist(); + app.user_unfollow_playlist_search_result(); } SearchResultBlock::Empty => {} }, From ff6fb4d1f158ac5e542370e2f78341f594ab13f2 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Wed, 15 Apr 2020 22:32:30 -0400 Subject: [PATCH 026/311] setting up control/model logic --- .gitignore | 3 +++ src/app.rs | 5 +++++ src/handlers/dialog.rs | 23 +++++++++++++++++++++++ src/handlers/mod.rs | 4 ++++ src/handlers/playlist.rs | 12 +++++++++++- src/ui/mod.rs | 9 +++++++++ 6 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/handlers/dialog.rs diff --git a/.gitignore b/.gitignore index af23db13..dcdf4a12 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ spt*.txt .ci/lp-creds snapcraft-login secrets.tar + +*.swp +tags diff --git a/src/app.rs b/src/app.rs index ce8d77cf..c90f42af 100644 --- a/src/app.rs +++ b/src/app.rs @@ -126,6 +126,7 @@ pub enum ActiveBlock { MadeForYou, Artists, BasicView, + Dialog, } #[derive(Clone, PartialEq, Debug)] @@ -281,6 +282,8 @@ pub struct App { io_tx: Option>, pub is_fetching_current_playback: bool, pub spotify_token_expiry: Instant, + pub dialog: Option, + pub confirm: bool, } impl Default for App { @@ -354,6 +357,8 @@ impl Default for App { io_tx: None, is_fetching_current_playback: false, spotify_token_expiry: Instant::now(), + dialog: None, + confirm: false, } } } diff --git a/src/handlers/dialog.rs b/src/handlers/dialog.rs new file mode 100644 index 00000000..3a354fce --- /dev/null +++ b/src/handlers/dialog.rs @@ -0,0 +1,23 @@ +use super::super::app::App; +use crate::event::Key; + +pub fn handler(key: Key, app: &mut App) { + match key { + Key::Enter => { + app.pop_navigation_stack(); + + if app.confirm { + app.user_unfollow_playlist() + } + } + Key::Esc => { + app.pop_navigation_stack(); + } + Key::Char('q') => { + app.pop_navigation_stack(); + } + Key::Right => app.confirm = !app.confirm, + Key::Left => app.confirm = !app.confirm, + _ => {} + } +} diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index d1ccb9c8..374ee72a 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -5,6 +5,7 @@ mod artist; mod artists; mod basic_view; mod common_key_events; +mod dialog; mod empty; mod error_screen; mod help_menu; @@ -156,6 +157,9 @@ fn handle_block_events(key: Key, app: &mut App) { ActiveBlock::BasicView => { basic_view::handler(key, app); } + ActiveBlock::Dialog => { + dialog::handler(key, app); + } } } diff --git a/src/handlers/playlist.rs b/src/handlers/playlist.rs index 9c9230e9..e567be12 100644 --- a/src/handlers/playlist.rs +++ b/src/handlers/playlist.rs @@ -2,6 +2,7 @@ use super::{ super::app::{App, TrackTableContext}, common_key_events, }; +use crate::app::ActiveBlock; use crate::event::Key; use crate::network::IoEvent; @@ -70,7 +71,16 @@ pub fn handler(key: Key, app: &mut App) { }; } Key::Char('D') => { - app.user_unfollow_playlist(); + if let (Some(playlists), Some(selected_index)) = (&app.playlists, app.selected_playlist_index) + { + let selected_playlist = &playlists.items[selected_index].name; + app.dialog = Some(selected_playlist.clone()); + app.confirm = false; + + let route = app.get_current_route().id.clone(); + app.push_navigation_stack(route, ActiveBlock::Dialog); + } + // app.user_unfollow_playlist(); } _ => {} } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 91583fad..c0c66b57 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -178,6 +178,9 @@ where // Currently playing draw_playbar(f, app, parent_layout[2]); + + // Possibly draw confirm dialog + draw_dialog(f, app); } pub fn draw_routes(f: &mut Frame, app: &App, layout_chunk: Rect) @@ -1328,6 +1331,12 @@ fn draw_selectable_list( .render(f, layout_chunk); } +fn draw_dialog(f: &mut Frame, app: &App) +where + B: Backend, +{ +} + fn draw_table( f: &mut Frame, app: &App, From 768fa5e8180fa30ddf39004d560d291a8a021553 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Thu, 16 Apr 2020 08:29:46 -0400 Subject: [PATCH 027/311] popup dialog seems to work --- src/ui/clear.rs | 16 ++++++++++++ src/ui/mod.rs | 67 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/ui/clear.rs diff --git a/src/ui/clear.rs b/src/ui/clear.rs new file mode 100644 index 00000000..5b801d1a --- /dev/null +++ b/src/ui/clear.rs @@ -0,0 +1,16 @@ +use tui::buffer::Buffer; +use tui::layout::Rect; +use tui::widgets::Widget; + +#[derive(Debug, Clone)] +pub struct Clear; + +impl Widget for Clear { + fn draw(&mut self, area: Rect, buf: &mut Buffer) { + for x in area.left()..area.right() { + for y in area.top()..area.bottom() { + buf.get_mut(x, y).reset(); + } + } + } +} diff --git a/src/ui/mod.rs b/src/ui/mod.rs index c0c66b57..37256e81 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1,4 +1,5 @@ pub mod audio_analysis; +pub mod clear; pub mod help; pub mod util; use super::{ @@ -12,7 +13,7 @@ use help::get_help_docs; use rspotify::senum::RepeatState; use tui::{ backend::Backend, - layout::{Constraint, Direction, Layout, Rect}, + layout::{Alignment, Constraint, Direction, Layout, Rect}, style::{Modifier, Style}, widgets::{Block, Borders, Gauge, Paragraph, Row, SelectableList, Table, Text, Widget}, Frame, @@ -1335,6 +1336,70 @@ fn draw_dialog(f: &mut Frame, app: &App) where B: Backend, { + if app.get_current_route().active_block == ActiveBlock::Dialog { + if let Some(playlist) = app.dialog.as_ref() { + let bounds = f.size(); + let w = std::cmp::min(bounds.width - 2, 45); + let h = 8; + + let x = (bounds.width - w) / 2; + let y = bounds.height / 4; + + let rect = Rect::new(x, y, w, h); + + // when upgrading to tui-rs 0.9.0 + // can replace this with the provided + // Clear widget + let mut cl = clear::Clear {}; + cl.render(f, rect); + Block::default() + .borders(Borders::ALL) + .border_style(Style::default().fg(app.user_config.theme.inactive)) + .render(f, rect); + + let vchunks = Layout::default() + .direction(Direction::Vertical) + .margin(2) + .constraints([Constraint::Min(3), Constraint::Length(3)].as_ref()) + .split(rect); + + // suggestion: possibly put this as part of + // app.dialog, but would have to introduce lifetime + let text = [ + Text::raw("Are you sure you want to delete\nthe playlist: "), + Text::styled(playlist.as_str(), Style::default().modifier(Modifier::BOLD)), + Text::raw("?"), + ]; + + Paragraph::new(text.iter()) + .alignment(Alignment::Center) + .render(f, vchunks[0]); + + let hchunks = Layout::default() + .direction(Direction::Horizontal) + .horizontal_margin(3) + .constraints([Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)].as_ref()) + .split(vchunks[1]); + + Paragraph::new([Text::raw("Ok")].iter()) + .style(Style::default().fg(if app.confirm { + app.user_config.theme.hovered + } else { + app.user_config.theme.inactive + })) + .alignment(Alignment::Center) + .render(f, hchunks[0]); + + Paragraph::new([Text::raw("Cancel")].iter()) + .style(Style::default().fg(if app.confirm { + app.user_config.theme.inactive + } else { + app.user_config.theme.hovered + })) + .alignment(Alignment::Center) + .render(f, hchunks[1]); + } + } } fn draw_table( From 67182413e1333782a22502bc652007000aa84ec3 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Thu, 16 Apr 2020 08:40:27 -0400 Subject: [PATCH 028/311] added some support for future dialogs --- src/app.rs | 7 ++++++- src/handlers/dialog.rs | 12 ++++++++++-- src/handlers/mod.rs | 2 +- src/handlers/playlist.rs | 5 ++--- src/ui/mod.rs | 4 ++-- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/app.rs b/src/app.rs index c90f42af..638e3d1c 100644 --- a/src/app.rs +++ b/src/app.rs @@ -104,6 +104,11 @@ pub enum ArtistBlock { Empty, } +#[derive(Clone, Copy, PartialEq, Debug)] +pub enum DialogContext { + Playlist, +} + #[derive(Clone, Copy, PartialEq, Debug)] pub enum ActiveBlock { Analysis, @@ -126,7 +131,7 @@ pub enum ActiveBlock { MadeForYou, Artists, BasicView, - Dialog, + Dialog(DialogContext), } #[derive(Clone, PartialEq, Debug)] diff --git a/src/handlers/dialog.rs b/src/handlers/dialog.rs index 3a354fce..c605c8e9 100644 --- a/src/handlers/dialog.rs +++ b/src/handlers/dialog.rs @@ -1,4 +1,4 @@ -use super::super::app::App; +use super::super::app::{ActiveBlock, App, DialogContext}; use crate::event::Key; pub fn handler(key: Key, app: &mut App) { @@ -7,7 +7,11 @@ pub fn handler(key: Key, app: &mut App) { app.pop_navigation_stack(); if app.confirm { - app.user_unfollow_playlist() + if let ActiveBlock::Dialog(d) = app.get_current_route().active_block { + match d { + DialogContext::Playlist => handle_playlist_dialog(app), + } + } } } Key::Esc => { @@ -21,3 +25,7 @@ pub fn handler(key: Key, app: &mut App) { _ => {} } } + +fn handle_playlist_dialog(app: &mut App) { + app.user_unfollow_playlist() +} diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 374ee72a..75c95473 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -157,7 +157,7 @@ fn handle_block_events(key: Key, app: &mut App) { ActiveBlock::BasicView => { basic_view::handler(key, app); } - ActiveBlock::Dialog => { + ActiveBlock::Dialog(_) => { dialog::handler(key, app); } } diff --git a/src/handlers/playlist.rs b/src/handlers/playlist.rs index e567be12..9b791d70 100644 --- a/src/handlers/playlist.rs +++ b/src/handlers/playlist.rs @@ -1,5 +1,5 @@ use super::{ - super::app::{App, TrackTableContext}, + super::app::{App, DialogContext, TrackTableContext}, common_key_events, }; use crate::app::ActiveBlock; @@ -78,9 +78,8 @@ pub fn handler(key: Key, app: &mut App) { app.confirm = false; let route = app.get_current_route().id.clone(); - app.push_navigation_stack(route, ActiveBlock::Dialog); + app.push_navigation_stack(route, ActiveBlock::Dialog(DialogContext::Playlist)); } - // app.user_unfollow_playlist(); } _ => {} } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 37256e81..01c9e086 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1336,12 +1336,12 @@ fn draw_dialog(f: &mut Frame, app: &App) where B: Backend, { - if app.get_current_route().active_block == ActiveBlock::Dialog { + if let ActiveBlock::Dialog(_) = app.get_current_route().active_block { if let Some(playlist) = app.dialog.as_ref() { let bounds = f.size(); + // maybe do this better let w = std::cmp::min(bounds.width - 2, 45); let h = 8; - let x = (bounds.width - w) / 2; let y = bounds.height / 4; From 6c96be736c6c6fe9390e078230cf1e600e6e0441 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Thu, 16 Apr 2020 10:16:19 -0400 Subject: [PATCH 029/311] fixed not working bug and esc --- src/handlers/dialog.rs | 15 ++++++--------- src/handlers/mod.rs | 3 +++ src/handlers/search_results.rs | 15 +++++++++++++-- src/ui/mod.rs | 10 +++++----- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/handlers/dialog.rs b/src/handlers/dialog.rs index c605c8e9..39977d90 100644 --- a/src/handlers/dialog.rs +++ b/src/handlers/dialog.rs @@ -4,19 +4,16 @@ use crate::event::Key; pub fn handler(key: Key, app: &mut App) { match key { Key::Enter => { - app.pop_navigation_stack(); - - if app.confirm { - if let ActiveBlock::Dialog(d) = app.get_current_route().active_block { - match d { - DialogContext::Playlist => handle_playlist_dialog(app), + if let Some(route) = app.pop_navigation_stack() { + if app.confirm { + if let ActiveBlock::Dialog(d) = route.active_block { + match d { + DialogContext::Playlist => handle_playlist_dialog(app), + } } } } } - Key::Esc => { - app.pop_navigation_stack(); - } Key::Char('q') => { app.pop_navigation_stack(); } diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 75c95473..69116923 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -176,6 +176,9 @@ fn handle_escape(app: &mut App) { ActiveBlock::Error => { app.pop_navigation_stack(); } + ActiveBlock::Dialog(_) => { + app.pop_navigation_stack(); + } // These are global views that have no active/inactive distinction so do nothing ActiveBlock::SelectDevice | ActiveBlock::Analysis => {} _ => { diff --git a/src/handlers/search_results.rs b/src/handlers/search_results.rs index 7350f862..843484ed 100644 --- a/src/handlers/search_results.rs +++ b/src/handlers/search_results.rs @@ -1,6 +1,7 @@ use super::{ super::app::{ - ActiveBlock, App, RecommendationsContext, RouteId, SearchResultBlock, TrackTableContext, + ActiveBlock, App, DialogContext, RecommendationsContext, RouteId, SearchResultBlock, + TrackTableContext, }, common_key_events, }; @@ -444,7 +445,17 @@ pub fn handler(key: Key, app: &mut App) { SearchResultBlock::SongSearch => {} SearchResultBlock::ArtistSearch => app.user_unfollow_artists(ActiveBlock::SearchResultBlock), SearchResultBlock::PlaylistSearch => { - app.user_unfollow_playlist(); + if let (Some(playlists), Some(selected_index)) = + (&app.playlists, app.selected_playlist_index) + { + let selected_playlist = &playlists.items[selected_index].name; + app.dialog = Some(selected_playlist.clone()); + app.confirm = false; + + let route = app.get_current_route().id.clone(); + app.push_navigation_stack(route, ActiveBlock::Dialog(DialogContext::Playlist)); + } + // app.user_unfollow_playlist(); } SearchResultBlock::Empty => {} }, diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 01c9e086..66f88470 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1340,12 +1340,12 @@ where if let Some(playlist) = app.dialog.as_ref() { let bounds = f.size(); // maybe do this better - let w = std::cmp::min(bounds.width - 2, 45); - let h = 8; - let x = (bounds.width - w) / 2; - let y = bounds.height / 4; + let width = std::cmp::min(bounds.width - 2, 45); + let height = 8; + let left = (bounds.width - width) / 2; + let top = bounds.height / 4; - let rect = Rect::new(x, y, w, h); + let rect = Rect::new(left, top, width, height); // when upgrading to tui-rs 0.9.0 // can replace this with the provided From fb0112895bff9895113d1e037b0c54baf2fe2ff4 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Thu, 16 Apr 2020 10:49:44 -0400 Subject: [PATCH 030/311] restated unfollowing playlist search results --- src/app.rs | 3 ++- src/handlers/dialog.rs | 7 ++++++- src/handlers/playlist.rs | 2 +- src/handlers/search_results.rs | 11 ++++++----- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/app.rs b/src/app.rs index 07bade23..2e4cf2a5 100644 --- a/src/app.rs +++ b/src/app.rs @@ -106,7 +106,8 @@ pub enum ArtistBlock { #[derive(Clone, Copy, PartialEq, Debug)] pub enum DialogContext { - Playlist, + PlaylistWindow, + PlaylistSearch, } #[derive(Clone, Copy, PartialEq, Debug)] diff --git a/src/handlers/dialog.rs b/src/handlers/dialog.rs index 39977d90..6d35ff82 100644 --- a/src/handlers/dialog.rs +++ b/src/handlers/dialog.rs @@ -8,7 +8,8 @@ pub fn handler(key: Key, app: &mut App) { if app.confirm { if let ActiveBlock::Dialog(d) = route.active_block { match d { - DialogContext::Playlist => handle_playlist_dialog(app), + DialogContext::PlaylistWindow => handle_playlist_dialog(app), + DialogContext::PlaylistSearch => handle_playlist_search_dialog(app), } } } @@ -26,3 +27,7 @@ pub fn handler(key: Key, app: &mut App) { fn handle_playlist_dialog(app: &mut App) { app.user_unfollow_playlist() } + +fn handle_playlist_search_dialog(app: &mut App) { + app.user_unfollow_playlist_search_result() +} diff --git a/src/handlers/playlist.rs b/src/handlers/playlist.rs index 9b791d70..8eb50b2a 100644 --- a/src/handlers/playlist.rs +++ b/src/handlers/playlist.rs @@ -78,7 +78,7 @@ pub fn handler(key: Key, app: &mut App) { app.confirm = false; let route = app.get_current_route().id.clone(); - app.push_navigation_stack(route, ActiveBlock::Dialog(DialogContext::Playlist)); + app.push_navigation_stack(route, ActiveBlock::Dialog(DialogContext::PlaylistWindow)); } } _ => {} diff --git a/src/handlers/search_results.rs b/src/handlers/search_results.rs index 25107ae9..2e651403 100644 --- a/src/handlers/search_results.rs +++ b/src/handlers/search_results.rs @@ -445,15 +445,16 @@ pub fn handler(key: Key, app: &mut App) { SearchResultBlock::SongSearch => {} SearchResultBlock::ArtistSearch => app.user_unfollow_artists(ActiveBlock::SearchResultBlock), SearchResultBlock::PlaylistSearch => { - if let (Some(playlists), Some(selected_index)) = - (&app.playlists, app.selected_playlist_index) - { - let selected_playlist = &playlists.items[selected_index].name; + if let (Some(playlists), Some(selected_index)) = ( + &app.search_results.playlists, + app.search_results.selected_playlists_index, + ) { + let selected_playlist = &playlists.playlists.items[selected_index].name; app.dialog = Some(selected_playlist.clone()); app.confirm = false; let route = app.get_current_route().id.clone(); - app.push_navigation_stack(route, ActiveBlock::Dialog(DialogContext::Playlist)); + app.push_navigation_stack(route, ActiveBlock::Dialog(DialogContext::PlaylistSearch)); } } SearchResultBlock::Empty => {} From dd0c4c84f84c02d45b5ee8dda4b49236580a8f04 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2020 13:51:50 +0000 Subject: [PATCH 031/311] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d28b271..159c946b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-47-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-48-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -341,6 +341,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Artem Polishchuk

πŸ“¦
Chris Sosnin

πŸ’»
Ben Buhse

πŸ“– +
Sean Li

πŸ’» From 0a50f8fd5abbe6d897ca3fd19e39633606493205 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2020 13:51:51 +0000 Subject: [PATCH 032/311] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 16f9a8f0..3a03c307 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -438,6 +438,15 @@ "contributions": [ "doc" ] + }, + { + "login": "ilnaes", + "name": "Sean Li", + "avatar_url": "https://avatars1.githubusercontent.com/u/20805499?v=4", + "profile": "https://github.com/ilnaes", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, From feed2a035ab460a66b00802fb927c035173dc0ce Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Fri, 17 Apr 2020 14:58:20 +0100 Subject: [PATCH 033/311] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a6e4e23..22561ccb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,13 @@ - Fix crash when opening playlist [#398](https://github.com/Rigellute/spotify-tui/pull/398) - Fix crash when there're no artists avaliable [#388](https://github.com/Rigellute/spotify-tui/pull/388) +- Correctly handle playlist unfollowing [#399](https://github.com/Rigellute/spotify-tui/pull/399) ### Added - Allow specifying alternative config file path [#391](https://github.com/Rigellute/spotify-tui/pull/391) - List artists names in the album view [#393](https://github.com/Rigellute/spotify-tui/pull/393) +- Add confirmation modal for delete playlist action [#402](https://github.com/Rigellute/spotify-tui/pull/402) ## [0.17.1] - 2020-03-30 From 650e35ea213f17ce455a976dacfbdadd07059940 Mon Sep 17 00:00:00 2001 From: Florian Dehau Date: Thu, 16 Apr 2020 21:18:05 +0200 Subject: [PATCH 034/311] Bump tui from 0.8.0 to 0.9.1 Replace all `Widget.render` calls by `Frame::render_widget` and refactor to remove newly introduced lifetimes issues. --- Cargo.lock | 49 ++++-------- Cargo.toml | 6 +- src/ui/audio_analysis.rs | 60 +++++++------- src/ui/mod.rs | 167 +++++++++++++++++++-------------------- 4 files changed, 129 insertions(+), 153 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76512a50..2b080f4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -263,22 +263,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "crossterm" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5750773d74a7dc612eac2ded3f55e9cdeeaa072210cd17c0192aedb48adb3618" -dependencies = [ - "bitflags", - "crossterm_winapi 0.5.1", - "lazy_static", - "libc", - "mio", - "parking_lot", - "signal-hook", - "winapi 0.3.8", -] - [[package]] name = "crossterm" version = "0.17.3" @@ -286,7 +270,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccdd8ef63a44e821956c6a276eca0faaa889d6a067dfcdbd5bfe85dce3a1d250" dependencies = [ "bitflags", - "crossterm_winapi 0.6.1", + "crossterm_winapi", "lazy_static", "libc", "mio", @@ -295,15 +279,6 @@ dependencies = [ "winapi 0.3.8", ] -[[package]] -name = "crossterm_winapi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8777c700901e2d5b50c406f736ed6b8f9e43645c7e104ddb74f8bc42b8ae62f6" -dependencies = [ - "winapi 0.3.8", -] - [[package]] name = "crossterm_winapi" version = "0.6.1" @@ -763,6 +738,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.5" @@ -1434,7 +1418,7 @@ dependencies = [ "dotenv", "env_logger", "failure", - "itertools", + "itertools 0.8.2", "lazy_static", "log", "percent-encoding 1.0.1", @@ -1625,7 +1609,7 @@ dependencies = [ "backtrace", "clap", "clipboard", - "crossterm 0.17.3", + "crossterm", "dirs", "proc-macro2 1.0.10", "rand 0.7.3", @@ -1842,16 +1826,15 @@ checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" [[package]] name = "tui" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b871b61f4c4b81e630215cd12e0ec29953d4545898e21a9e023b7520a74a9f9" +checksum = "b7de74b91c6cb83119a2140e7c215d95d9e54db27b58a500a2cbdeec4987b0a2" dependencies = [ "bitflags", "cassowary", - "crossterm 0.14.2", + "crossterm", "either", - "itertools", - "log", + "itertools 0.9.0", "unicode-segmentation", "unicode-width", ] diff --git a/Cargo.toml b/Cargo.toml index 0a5af7c1..ead660cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ license = "MIT OR Apache-2.0" [dependencies] rspotify = "0.9.0" -tui = { version = "0.8.0", features = ["crossterm"], default-features = false } +tui = { version = "0.9.0", features = ["crossterm"], default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" @@ -24,10 +24,10 @@ clap = "2.33.0" unicode-width = "0.1.7" backtrace = "0.3.46" clipboard = "0.5.0" -crossterm = "0.17" +crossterm = "0.17" tokio = { version = "0.2", features = ["full"] } proc-macro2 = "1.0.10" -rand="0.7.3" +rand = "0.7.3" anyhow = "1.0.28" [[bin]] diff --git a/src/ui/audio_analysis.rs b/src/ui/audio_analysis.rs index f6e9d10c..2e5b0356 100644 --- a/src/ui/audio_analysis.rs +++ b/src/ui/audio_analysis.rs @@ -4,7 +4,7 @@ use tui::{ backend::Backend, layout::{Constraint, Direction, Layout}, style::Style, - widgets::{BarChart, Block, Borders, Paragraph, Text, Widget}, + widgets::{BarChart, Block, Borders, Paragraph, Text}, Frame, }; const PITCHES: [&str; 12] = [ @@ -76,29 +76,27 @@ where .find(|section| section.start >= progress_seconds); if let (Some(segment), Some(section)) = (segment, section) { - Paragraph::new( - [ - Text::raw(format!( - "Tempo: {} (confidence {:.0}%)\n", - section.tempo, - section.tempo_confidence * 100.0 - )), - Text::raw(format!( - "Key: {} (confidence {:.0}%)\n", - PITCHES.get(section.key as usize).unwrap_or(&PITCHES[0]), - section.key_confidence * 100.0 - )), - Text::raw(format!( - "Time Signature: {}/4 (confidence {:.0}%)\n", - section.time_signature, - section.time_signature_confidence * 100.0 - )), - ] - .iter(), - ) - .block(analysis_block) - .style(Style::default().fg(app.user_config.theme.text)) - .render(f, chunks[0]); + let texts = [ + Text::raw(format!( + "Tempo: {} (confidence {:.0}%)\n", + section.tempo, + section.tempo_confidence * 100.0 + )), + Text::raw(format!( + "Key: {} (confidence {:.0}%)\n", + PITCHES.get(section.key as usize).unwrap_or(&PITCHES[0]), + section.key_confidence * 100.0 + )), + Text::raw(format!( + "Time Signature: {}/4 (confidence {:.0}%)\n", + section.time_signature, + section.time_signature_confidence * 100.0 + )), + ]; + let p = Paragraph::new(texts.iter()) + .block(analysis_block) + .style(Style::default().fg(app.user_config.theme.text)); + f.render_widget(p, chunks[0]); let data: Vec<(&str, u64)> = segment .pitches @@ -115,7 +113,7 @@ where }) .collect(); - BarChart::default() + let analysis_bar = BarChart::default() .block(bar_chart_block) .data(&data) .bar_width(width as u16) @@ -124,14 +122,14 @@ where Style::default() .fg(app.user_config.theme.analysis_bar_text) .bg(app.user_config.theme.analysis_bar), - ) - .render(f, chunks[1]); + ); + f.render_widget(analysis_bar, chunks[1]); } else { - empty_analysis_block().render(f, chunks[0]); - empty_pitches_block().render(f, chunks[1]); + f.render_widget(empty_analysis_block(), chunks[0]); + f.render_widget(empty_pitches_block(), chunks[1]); }; } else { - empty_analysis_block().render(f, chunks[0]); - empty_pitches_block().render(f, chunks[1]); + f.render_widget(empty_analysis_block(), chunks[0]); + f.render_widget(empty_pitches_block(), chunks[1]); } } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 66f88470..b982d0d9 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -15,7 +15,7 @@ use tui::{ backend::Backend, layout::{Alignment, Constraint, Direction, Layout, Rect}, style::{Modifier, Style}, - widgets::{Block, Borders, Gauge, Paragraph, Row, SelectableList, Table, Text, Widget}, + widgets::{Block, Borders, Gauge, List, ListState, Paragraph, Row, Table, Text}, Frame, }; use util::{ @@ -90,7 +90,7 @@ where .iter() .map(|item| Row::StyledData(item.iter(), gray)); - Table::new(header.iter(), rows) + let help_menu = Table::new(header.iter(), rows) .block( Block::default() .borders(Borders::ALL) @@ -104,8 +104,8 @@ where Constraint::Length(50), Constraint::Length(40), Constraint::Length(20), - ]) - .render(f, chunks[0]); + ]); + f.render_widget(help_menu, chunks[0]); } pub fn draw_input_and_help_box(f: &mut Frame, app: &App, layout_chunk: Rect) @@ -125,15 +125,15 @@ where ); let input_string: String = app.input.iter().collect(); - Paragraph::new([Text::raw(&input_string)].iter()) - .block( - Block::default() - .borders(Borders::ALL) - .title("Search") - .title_style(get_color(highlight_state, app.user_config.theme)) - .border_style(get_color(highlight_state, app.user_config.theme)), - ) - .render(f, chunks[0]); + let lines = [Text::raw(&input_string)]; + let input = Paragraph::new(lines.iter()).block( + Block::default() + .borders(Borders::ALL) + .title("Search") + .title_style(get_color(highlight_state, app.user_config.theme)) + .border_style(get_color(highlight_state, app.user_config.theme)), + ); + f.render_widget(input, chunks[0]); let help_block_text = if app.is_loading { (app.user_config.theme.hint, "Loading...") @@ -147,10 +147,11 @@ where .border_style(Style::default().fg(help_block_text.0)) .title_style(Style::default().fg(help_block_text.0)); - Paragraph::new([Text::raw(help_block_text.1)].iter()) + let lines = [Text::raw(help_block_text.1)]; + let help = Paragraph::new(lines.iter()) .block(block) - .style(Style::default().fg(help_block_text.0)) - .render(f, chunks[1]); + .style(Style::default().fg(help_block_text.0)); + f.render_widget(help, chunks[1]); } pub fn draw_main_layout(f: &mut Frame, app: &App) @@ -807,12 +808,12 @@ where current_route.hovered_block == ActiveBlock::PlayBar, ); - Block::default() + let title_block = Block::default() .borders(Borders::ALL) .title(&title) .title_style(get_color(highlight_state, app.user_config.theme)) - .border_style(get_color(highlight_state, app.user_config.theme)) - .render(f, layout_chunk); + .border_style(get_color(highlight_state, app.user_config.theme)); + f.render_widget(title_block, layout_chunk); let track_name = if app .liked_song_ids_set @@ -823,25 +824,25 @@ where track_item.name.clone() }; - Paragraph::new( - [Text::styled( - create_artist_string(&track_item.artists), - Style::default().fg(app.user_config.theme.text), - )] - .iter(), - ) - .style(Style::default().fg(app.user_config.theme.text)) - .block( - Block::default().title(&track_name).title_style( - Style::default() - .fg(app.user_config.theme.selected) - .modifier(Modifier::BOLD), - ), - ) - .render(f, chunks[0]); + let lines = [Text::styled( + create_artist_string(&track_item.artists), + Style::default().fg(app.user_config.theme.text), + )]; + let artist = Paragraph::new(lines.iter()) + .style(Style::default().fg(app.user_config.theme.text)) + .block( + Block::default().title(&track_name).title_style( + Style::default() + .fg(app.user_config.theme.selected) + .modifier(Modifier::BOLD), + ), + ); + f.render_widget(artist, chunks[0]); let perc = get_track_progress_percentage(app.song_progress_ms, track_item.duration_ms); - Gauge::default() + let song_progress_label = + display_track_progress(app.song_progress_ms, track_item.duration_ms); + let song_progress = Gauge::default() .block(Block::default().title("")) .style( Style::default() @@ -850,11 +851,8 @@ where .modifier(Modifier::ITALIC | Modifier::BOLD), ) .percent(perc) - .label(&display_track_progress( - app.song_progress_ms, - track_item.duration_ms, - )) - .render(f, chunks[1]); + .label(&song_progress_label); + f.render_widget(song_progress, chunks[1]); } } } @@ -892,7 +890,7 @@ Hint: a playback device must be either an official spotify client or a light wei ), ]; - Paragraph::new(playing_text.iter()) + let playing_paragraph = Paragraph::new(playing_text.iter()) .wrap(true) .style(Style::default().fg(app.user_config.theme.text)) .block( @@ -901,8 +899,8 @@ Hint: a playback device must be either an official spotify client or a light wei .title("Error") .title_style(Style::default().fg(app.user_config.theme.error_border)) .border_style(Style::default().fg(app.user_config.theme.error_border)), - ) - .render(f, chunks[0]); + ); + f.render_widget(playing_paragraph, chunks[0]); } fn draw_home(f: &mut Frame, app: &App, layout_chunk: Rect) @@ -921,12 +919,12 @@ where current_route.hovered_block == ActiveBlock::Home, ); - Block::default() + let welcome = Block::default() .title("Welcome!") .borders(Borders::ALL) .title_style(get_color(highlight_state, app.user_config.theme)) - .border_style(get_color(highlight_state, app.user_config.theme)) - .render(f, layout_chunk); + .border_style(get_color(highlight_state, app.user_config.theme)); + f.render_widget(welcome, layout_chunk); let changelog = include_str!("../../CHANGELOG.md").to_string(); @@ -949,18 +947,18 @@ where ]; // Contains the banner - Paragraph::new(top_text.iter()) + let top_text = Paragraph::new(top_text.iter()) .style(Style::default().fg(app.user_config.theme.text)) - .block(Block::default()) - .render(f, chunks[0]); + .block(Block::default()); + f.render_widget(top_text, chunks[0]); // CHANGELOG - Paragraph::new(bottom_text.iter()) + let bottom_text = Paragraph::new(bottom_text.iter()) .style(Style::default().fg(app.user_config.theme.text)) .block(Block::default()) .wrap(true) - .scroll(app.home_scroll) - .render(f, chunks[1]); + .scroll(app.home_scroll); + f.render_widget(bottom_text, chunks[1]); } fn draw_not_implemented_yet( @@ -985,11 +983,11 @@ fn draw_not_implemented_yet( let text = vec![Text::raw("Not implemented yet!")]; - Paragraph::new(text.iter()) + let not_implemented = Paragraph::new(text.iter()) .style(Style::default().fg(app.user_config.theme.text)) .block(display_block) - .wrap(true) - .render(f, layout_chunk); + .wrap(true); + f.render_widget(not_implemented, layout_chunk); } fn draw_artist_albums(f: &mut Frame, app: &App, layout_chunk: Rect) @@ -1079,14 +1077,14 @@ where .margin(5) .split(f.size()); - let device_instructions = vec![ - "To play tracks, please select a device.", - "Use `j/k` or up/down arrow keys to move up and down and to select", - "Your choice here will be cached so you can jump straight back in when you next open `spotify-tui`.", - "You can change the playback device at any time by pressing `d`.", + let device_instructions = [ + Text::raw("To play tracks, please select a device."), + Text::raw("Use `j/k` or up/down arrow keys to move up and down and to select"), + Text::raw("Your choice here will be cached so you can jump straight back in when you next open `spotify-tui`."), + Text::raw("You can change the playback device at any time by pressing `d`."), ]; - Paragraph::new([Text::raw(device_instructions.join("\n"))].iter()) + let instructions = Paragraph::new(device_instructions.iter()) .style(Style::default().fg(app.user_config.theme.text)) .wrap(true) .block( @@ -1098,27 +1096,25 @@ where .fg(app.user_config.theme.active) .modifier(Modifier::BOLD), ), - ) - .render(f, chunks[0]); + ); + f.render_widget(instructions, chunks[0]); - let no_device_message = vec!["No devices found: Make sure a device is active".to_string()]; + let no_device_message = vec![Text::raw("No devices found: Make sure a device is active")]; - let items = match &app.devices { + let items: Box> = match &app.devices { Some(items) => { if items.devices.is_empty() { - no_device_message + Box::new(no_device_message.into_iter()) } else { - items - .devices - .iter() - .map(|device| device.name.to_owned()) - .collect() + Box::new(items.devices.iter().map(|device| Text::raw(&device.name))) } } - None => no_device_message, + None => Box::new(no_device_message.into_iter()), }; - SelectableList::default() + let mut state = ListState::default(); + state.select(app.selected_device_index); + let list = List::new(items) .block( Block::default() .title("Devices") @@ -1126,15 +1122,13 @@ where .title_style(Style::default().fg(app.user_config.theme.active)) .border_style(Style::default().fg(app.user_config.theme.inactive)), ) - .items(&items) .style(Style::default().fg(app.user_config.theme.text)) - .select(app.selected_device_index) .highlight_style( Style::default() .fg(app.user_config.theme.active) .modifier(Modifier::BOLD), - ) - .render(f, chunks[1]); + ); + f.render_stateful_widget(list, chunks[1], &mut state); } pub fn draw_album_list(f: &mut Frame, app: &App, layout_chunk: Rect) @@ -1317,7 +1311,10 @@ fn draw_selectable_list( B: Backend, S: std::convert::AsRef, { - SelectableList::default() + let mut state = ListState::default(); + state.select(selected_index); + + let list = List::new(items.iter().map(|i| Text::raw(i.as_ref()))) .block( Block::default() .title(title) @@ -1325,11 +1322,9 @@ fn draw_selectable_list( .title_style(get_color(highlight_state, app.user_config.theme)) .border_style(get_color(highlight_state, app.user_config.theme)), ) - .items(items) .style(Style::default().fg(app.user_config.theme.text)) - .select(selected_index) - .highlight_style(get_color(highlight_state, app.user_config.theme).modifier(Modifier::BOLD)) - .render(f, layout_chunk); + .highlight_style(get_color(highlight_state, app.user_config.theme).modifier(Modifier::BOLD)); + f.render_stateful_widget(list, layout_chunk, &mut state); } fn draw_dialog(f: &mut Frame, app: &App) @@ -1480,7 +1475,7 @@ fn draw_table( .map(|h| Constraint::Length(h.width)) .collect::>(); - Table::new(header.items.iter().map(|h| h.text), rows) + let table = Table::new(header.items.iter().map(|h| h.text), rows) .block( Block::default() .borders(Borders::ALL) @@ -1490,6 +1485,6 @@ fn draw_table( .border_style(get_color(highlight_state, app.user_config.theme)), ) .style(Style::default().fg(app.user_config.theme.text)) - .widths(&widths) - .render(f, layout_chunk); + .widths(&widths); + f.render_widget(table, layout_chunk); } From f7b6a319c4d2b3c18aa58932ed369a1bf0b088d8 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Fri, 17 Apr 2020 15:16:31 +0100 Subject: [PATCH 035/311] Update modal implementation --- Cargo.toml | 2 +- src/ui/clear.rs | 16 ---------------- src/ui/mod.rs | 39 ++++++++++++++++++++------------------- 3 files changed, 21 insertions(+), 36 deletions(-) delete mode 100644 src/ui/clear.rs diff --git a/Cargo.toml b/Cargo.toml index ead660cb..00a8f050 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ license = "MIT OR Apache-2.0" [dependencies] rspotify = "0.9.0" -tui = { version = "0.9.0", features = ["crossterm"], default-features = false } +tui = { version = "0.9.1", features = ["crossterm"], default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" diff --git a/src/ui/clear.rs b/src/ui/clear.rs deleted file mode 100644 index 5b801d1a..00000000 --- a/src/ui/clear.rs +++ /dev/null @@ -1,16 +0,0 @@ -use tui::buffer::Buffer; -use tui::layout::Rect; -use tui::widgets::Widget; - -#[derive(Debug, Clone)] -pub struct Clear; - -impl Widget for Clear { - fn draw(&mut self, area: Rect, buf: &mut Buffer) { - for x in area.left()..area.right() { - for y in area.top()..area.bottom() { - buf.get_mut(x, y).reset(); - } - } - } -} diff --git a/src/ui/mod.rs b/src/ui/mod.rs index b982d0d9..687c88da 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1,5 +1,4 @@ pub mod audio_analysis; -pub mod clear; pub mod help; pub mod util; use super::{ @@ -15,7 +14,7 @@ use tui::{ backend::Backend, layout::{Alignment, Constraint, Direction, Layout, Rect}, style::{Modifier, Style}, - widgets::{Block, Borders, Gauge, List, ListState, Paragraph, Row, Table, Text}, + widgets::{Block, Borders, Clear, Gauge, List, ListState, Paragraph, Row, Table, Text}, Frame, }; use util::{ @@ -1342,15 +1341,13 @@ where let rect = Rect::new(left, top, width, height); - // when upgrading to tui-rs 0.9.0 - // can replace this with the provided - // Clear widget - let mut cl = clear::Clear {}; - cl.render(f, rect); - Block::default() + f.render_widget(Clear, rect); + + let block = Block::default() .borders(Borders::ALL) - .border_style(Style::default().fg(app.user_config.theme.inactive)) - .render(f, rect); + .border_style(Style::default().fg(app.user_config.theme.inactive)); + + f.render_widget(block, rect); let vchunks = Layout::default() .direction(Direction::Vertical) @@ -1366,9 +1363,9 @@ where Text::raw("?"), ]; - Paragraph::new(text.iter()) - .alignment(Alignment::Center) - .render(f, vchunks[0]); + let text = Paragraph::new(text.iter()).alignment(Alignment::Center); + + f.render_widget(text, vchunks[0]); let hchunks = Layout::default() .direction(Direction::Horizontal) @@ -1376,23 +1373,27 @@ where .constraints([Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)].as_ref()) .split(vchunks[1]); - Paragraph::new([Text::raw("Ok")].iter()) + let ok_text = [Text::raw("Ok")]; + let ok = Paragraph::new(ok_text.iter()) .style(Style::default().fg(if app.confirm { app.user_config.theme.hovered } else { app.user_config.theme.inactive })) - .alignment(Alignment::Center) - .render(f, hchunks[0]); + .alignment(Alignment::Center); + + f.render_widget(ok, hchunks[0]); - Paragraph::new([Text::raw("Cancel")].iter()) + let cancel_text = [Text::raw("Cancel")]; + let cancel = Paragraph::new(cancel_text.iter()) .style(Style::default().fg(if app.confirm { app.user_config.theme.inactive } else { app.user_config.theme.hovered })) - .alignment(Alignment::Center) - .render(f, hchunks[1]); + .alignment(Alignment::Center); + + f.render_widget(cancel, hchunks[1]); } } } From 6993d61a78d755574554fb1ae9787e5b9f5ada0d Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Tue, 21 Apr 2020 14:01:09 +0100 Subject: [PATCH 036/311] Prepare release 0.18.0 --- CHANGELOG.md | 4 +++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22561ccb..36806ee1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,12 @@ ## [Unreleased] +## [0.18.0] - 2020-04-21 + ### Fixed - Fix crash when opening playlist [#398](https://github.com/Rigellute/spotify-tui/pull/398) -- Fix crash when there're no artists avaliable [#388](https://github.com/Rigellute/spotify-tui/pull/388) +- Fix crash when there are no artists avaliable [#388](https://github.com/Rigellute/spotify-tui/pull/388) - Correctly handle playlist unfollowing [#399](https://github.com/Rigellute/spotify-tui/pull/399) ### Added diff --git a/Cargo.lock b/Cargo.lock index 2b080f4a..b549f317 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1603,7 +1603,7 @@ dependencies = [ [[package]] name = "spotify-tui" -version = "0.17.1" +version = "0.18.0" dependencies = [ "anyhow", "backtrace", diff --git a/Cargo.toml b/Cargo.toml index 00a8f050..26215992 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ documentation = "https://github.com/Rigellute/spotify-tui" repository = "https://github.com/Rigellute/spotify-tui" keywords = ["spotify", "tui", "cli", "terminal"] categories = ["command-line-utilities"] -version = "0.17.1" +version = "0.18.0" authors = ["Alexander Keliris "] edition = "2018" license = "MIT OR Apache-2.0" From b94d74f94d88679d91f0d6c2918d62b1e8c64e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Gerber?= Date: Wed, 22 Apr 2020 11:39:10 +0200 Subject: [PATCH 037/311] Fix text display on device list --- src/ui/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 687c88da..ed482fbf 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1077,9 +1077,9 @@ where .split(f.size()); let device_instructions = [ - Text::raw("To play tracks, please select a device."), - Text::raw("Use `j/k` or up/down arrow keys to move up and down and to select"), - Text::raw("Your choice here will be cached so you can jump straight back in when you next open `spotify-tui`."), + Text::raw("To play tracks, please select a device. "), + Text::raw("Use `j/k` or up/down arrow keys to move up and down and to select. "), + Text::raw("Your choice here will be cached so you can jump straight back in when you next open `spotify-tui`. "), Text::raw("You can change the playback device at any time by pressing `d`."), ]; From 4de7d47893fe20b13c2a177648e5d22c8d8aef36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Gerber?= Date: Wed, 22 Apr 2020 12:18:16 +0200 Subject: [PATCH 038/311] Fix some rows in the API table --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 159c946b..01a2e4c2 100644 --- a/README.md +++ b/README.md @@ -367,9 +367,9 @@ This table shows all that is possible with the Spotify API, what is implemented | track | No | returns a single track given the track's ID, URI or URL | No | | tracks | No | returns a list of tracks given a list of track IDs, URIs, or URLs | No | | artist | No | returns a single artist given the artist's ID, URI or URL | Yes | -| artists | No | returns a list of artists given the artist IDs, URIs, or URLs | No | Get Spotify catalog information about an artist's albums | Yes | -| artist_albums | Yes | Get Spotify catalog information about an artist's top 10 tracks by country. | Yes | -| artist_top_tracks | No | Get Spotify catalog information about artists similar to an | Yes | +| artists | No | returns a list of artists given the artist IDs, URIs, or URLs | No | +| artist_albums | Yes | Get Spotify catalog information about an artist's albums | Yes | +| artist_top_tracks | No | Get Spotify catalog information about an artist's top 10 tracks by country. | Yes | | artist_related_artists | No | Get Spotify catalog information about artists similar to an identified artist. Similarity is based on analysis of the Spotify community's listening history. | Yes | | album | Yes | returns a single album given the album's ID, URIs or URL | Yes | | albums | No | returns a list of albums given the album IDs, URIs, or URLs | No | @@ -379,11 +379,11 @@ This table shows all that is possible with the Spotify API, what is implemented | search_playlist | Yes | Search playlist based on query | Yes | | album_track | Yes | Get Spotify catalog information about an album's tracks | Yes | | user | No | Gets basic profile information about a Spotify User | No | -| playlist | Yes | playlist | Yes | +| playlist | Yes | Get full details about Spotify playlist | Yes | | current_user_playlists | Yes | Get current user playlists without required getting his profile | Yes | | user_playlists | No | Gets playlists of a user | No | | user_playlist | No | Gets playlist of a user | No | -| user_playlist_tracks | Yes | Get full details of the tracks of a playlist owned by a user Yes | +| user_playlist_tracks | Yes | Get full details of the tracks of a playlist owned by a user | Yes | | user_playlist_create | No | Creates a playlist for a user | Yes | | user_playlist_change_detail | No | Changes a playlist's name and/or public/private state | Yes | | user_playlist_unfollow | No | Unfollows (deletes) a playlist for a user | Yes | @@ -414,10 +414,10 @@ This table shows all that is possible with the Spotify API, what is implemented | user_unfollow_users | No | Unfollow one or more users | No | | featured_playlists | No | Get a list of Spotify featured playlists | Yes | | new_releases | No | Get a list of new album releases featured in Spotify | Yes | -| categories | No | Get a list of new album releases featured in Spotify | Yes | +| categories | No | Get a list of categories used to tag items in Spotify | Yes | | recommendations | No | Get Recommendations Based on Seeds | Yes | | audio_features | No | Get audio features for a track | No | -| audios_feature | No | Get Audio Features for Several Tracks | No | +| audios_features | No | Get Audio Features for Several Tracks | No | | audio_analysis | No | Get Audio Analysis for a Track | No | | device | Yes | Get a User’s Available Devices | Yes | | current_playback | Yes | Get Information About The User’s Current Playback | Yes | From 4ff5b0b9cc173c235306ea32b4da86a6be37f384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Gerber?= Date: Wed, 22 Apr 2020 13:15:07 +0200 Subject: [PATCH 039/311] Update the API table --- README.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 01a2e4c2..4f168aa7 100644 --- a/README.md +++ b/README.md @@ -369,8 +369,8 @@ This table shows all that is possible with the Spotify API, what is implemented | artist | No | returns a single artist given the artist's ID, URI or URL | Yes | | artists | No | returns a list of artists given the artist IDs, URIs, or URLs | No | | artist_albums | Yes | Get Spotify catalog information about an artist's albums | Yes | -| artist_top_tracks | No | Get Spotify catalog information about an artist's top 10 tracks by country. | Yes | -| artist_related_artists | No | Get Spotify catalog information about artists similar to an identified artist. Similarity is based on analysis of the Spotify community's listening history. | Yes | +| artist_top_tracks | Yes | Get Spotify catalog information about an artist's top 10 tracks by country. | Yes | +| artist_related_artists | Yes | Get Spotify catalog information about artists similar to an identified artist. Similarity is based on analysis of the Spotify community's listening history. | Yes | | album | Yes | returns a single album given the album's ID, URIs or URL | Yes | | albums | No | returns a list of albums given the album IDs, URIs, or URLs | No | | search_album | Yes | Search album based on query | Yes | @@ -386,39 +386,39 @@ This table shows all that is possible with the Spotify API, what is implemented | user_playlist_tracks | Yes | Get full details of the tracks of a playlist owned by a user | Yes | | user_playlist_create | No | Creates a playlist for a user | Yes | | user_playlist_change_detail | No | Changes a playlist's name and/or public/private state | Yes | -| user_playlist_unfollow | No | Unfollows (deletes) a playlist for a user | Yes | +| user_playlist_unfollow | Yes | Unfollows (deletes) a playlist for a user | Yes | | user_playlist_add_track | No | Adds tracks to a playlist | Yes | | user_playlist_replace_track | No | Replace all tracks in a playlist | No | | user_playlist_recorder_tracks | No | Reorder tracks in a playlist | No | | user_playlist_remove_all_occurrences_of_track | No | Removes all occurrences of the given tracks from the given playlist | No | | user_playlist_remove_specific_occurrenes_of_track | No | Removes all occurrences of the given tracks from the given playlist | No | -| user_playlist_follow_playlist | No | Add the current authenticated user as a follower of a playlist. | Yes | +| user_playlist_follow_playlist | Yes | Add the current authenticated user as a follower of a playlist. | Yes | | user_playlist_check_follow | No | Check to see if the given users are following the given playlist | Yes | | me | No | Get detailed profile information about the current user. | Yes | | current_user | No | Alias for `me` | Yes | | current_user_playing_track | Yes | Get information about the current users currently playing track. | Yes | -| current_user_saved_albums | No | Gets a list of the albums saved in the current authorized user's "Your Music" library | Yes | +| current_user_saved_albums | Yes | Gets a list of the albums saved in the current authorized user's "Your Music" library | Yes | | current_user_saved_tracks | Yes | Gets the user's saved tracks or "Liked Songs" | Yes | -| current_user_followed_artists | No | Gets a list of the artists followed by the current authorized user | Yes | -| current_user_saved_tracks_delete | No | Remove one or more tracks from the current user's "Your Music" library. | Yes | +| current_user_followed_artists | Yes | Gets a list of the artists followed by the current authorized user | Yes | +| current_user_saved_tracks_delete | Yes | Remove one or more tracks from the current user's "Your Music" library. | Yes | | current_user_saved_tracks_contain | No | Check if one or more tracks is already saved in the current Spotify user’s β€œYour Music” library. | Yes | | current_user_saved_tracks_add | Yes | Save one or more tracks to the current user's "Your Music" library. | Yes | | current_user_top_artists | No | Get the current user's top artists | Yes | | current_user_top_tracks | No | Get the current user's top tracks | Yes | -| current_user_recently_played | No | Get the current user's recently played tracks | Yes | -| current_user_saved_albums_add | No | Add one or more albums to the current user's "Your Music" library. | Yes | -| current_user_saved_albums_delete | No | Remove one or more albums from the current user's "Your Music" library. | Yes | -| user_follow_artists | No | Follow one or more artists | Yes | -| user_unfollow_artists | No | Unfollow one or more artists | Yes | +| current_user_recently_played | Yes | Get the current user's recently played tracks | Yes | +| current_user_saved_albums_add | Yes | Add one or more albums to the current user's "Your Music" library. | Yes | +| current_user_saved_albums_delete | Yes | Remove one or more albums from the current user's "Your Music" library. | Yes | +| user_follow_artists | Yes | Follow one or more artists | Yes | +| user_unfollow_artists | Yes | Unfollow one or more artists | Yes | | user_follow_users | No | Follow one or more users | No | | user_unfollow_users | No | Unfollow one or more users | No | | featured_playlists | No | Get a list of Spotify featured playlists | Yes | | new_releases | No | Get a list of new album releases featured in Spotify | Yes | | categories | No | Get a list of categories used to tag items in Spotify | Yes | -| recommendations | No | Get Recommendations Based on Seeds | Yes | +| recommendations | Yes | Get Recommendations Based on Seeds | Yes | | audio_features | No | Get audio features for a track | No | | audios_features | No | Get Audio Features for Several Tracks | No | -| audio_analysis | No | Get Audio Analysis for a Track | No | +| audio_analysis | Yes | Get Audio Analysis for a Track | Yes | | device | Yes | Get a User’s Available Devices | Yes | | current_playback | Yes | Get Information About The User’s Current Playback | Yes | | current_playing | No | Get the User’s Currently Playing Track | No | @@ -427,7 +427,7 @@ This table shows all that is possible with the Spotify API, what is implemented | pause_playback | Yes | Pause a User’s Playback | Yes | | next_track | Yes | Skip User’s Playback To Next Track | Yes | | previous_track | Yes | Skip User’s Playback To Previous Track | Yes | -| seek_track | No | Seek To Position In Currently Playing Track | Yes | +| seek_track | Yes | Seek To Position In Currently Playing Track | Yes | | repeat | Yes | Set Repeat Mode On User’s Playback | Yes | -| volume | No | Set Volume For User’s Playback | No | +| volume | Yes | Set Volume For User’s Playback | Yes | | shuffle | Yes | Toggle Shuffle For User’s Playback | Yes | From f41913b6ba62175436fde1fce16dfcf13d2be16d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Gerber?= Date: Wed, 22 Apr 2020 13:18:28 +0200 Subject: [PATCH 040/311] Change parameter name to a more relevant one --- src/network.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network.rs b/src/network.rs index 82cc0093..f22b0fb8 100644 --- a/src/network.rs +++ b/src/network.rs @@ -949,15 +949,15 @@ impl<'a> Network<'a> { }; } - async fn current_user_saved_album_add(&mut self, artist_id: String) { + async fn current_user_saved_album_add(&mut self, album_id: String) { match self .spotify - .current_user_saved_albums_add(&[artist_id.to_owned()]) + .current_user_saved_albums_add(&[album_id.to_owned()]) .await { Ok(_) => { let mut app = self.app.lock().await; - app.saved_album_ids_set.insert(artist_id.to_owned()); + app.saved_album_ids_set.insert(album_id.to_owned()); } Err(e) => self.handle_error(anyhow!(e)).await, } From f8c9da1dc1484911e9d887429acd264de9c779ae Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2020 20:58:49 +0000 Subject: [PATCH 041/311] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 159c946b..d1114a5f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-48-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-49-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -342,6 +342,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Chris Sosnin

πŸ’»
Ben Buhse

πŸ“–
Sean Li

πŸ’» +
TimotheeGerber

πŸ’» πŸ“– From 4b5b6280424db2dbabf8983c9ef79c88c0cf2b65 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2020 20:58:50 +0000 Subject: [PATCH 042/311] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3a03c307..a077273e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -447,6 +447,16 @@ "contributions": [ "code" ] + }, + { + "login": "TimotheeGerber", + "name": "TimotheeGerber", + "avatar_url": "https://avatars3.githubusercontent.com/u/37541513?v=4", + "profile": "https://github.com/TimotheeGerber", + "contributions": [ + "code", + "doc" + ] } ], "contributorsPerLine": 7, From 2302cf789c4b0889c14caac1c96e79e5e5b65961 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Fri, 24 Apr 2020 22:47:03 +0100 Subject: [PATCH 043/311] Fix new clippy warnings --- how_to_release.md | 2 +- src/config.rs | 1 - src/handlers/analysis.rs | 6 +----- src/handlers/basic_view.rs | 6 +----- src/handlers/error_screen.rs | 6 +----- src/user_config.rs | 1 - 6 files changed, 4 insertions(+), 18 deletions(-) diff --git a/how_to_release.md b/how_to_release.md index a4fd32f1..a6fdf614 100644 --- a/how_to_release.md +++ b/how_to_release.md @@ -7,7 +7,7 @@ The release is triggered by pushing a tag. 1. Bump the version in `Cargo.toml` and run the app to update the `lock` file 1. Update the "Unreleased" header for the new version in the `CHANGELOG`. Use `### Added/Fixed/Changed` headers as appropriate 1. Commit the changes and push them. -1. Create a new tag e.g. `git tag -a v0.7.0` +1. Create a new tag e.g. `git tag -a v0.7.0` and add the CHANGELOG to the commit body 1. Push the tag `git push --tags` 1. Wait for the build to finish on the [Actions page](https://github.com/Rigellute/spotify-tui/actions) 1. This should publish to cargo as well diff --git a/src/config.rs b/src/config.rs index 6946e84d..849d9160 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,5 @@ use super::banner::BANNER; use anyhow::{anyhow, Result}; -use dirs; use serde::{Deserialize, Serialize}; use std::{ fs, diff --git a/src/handlers/analysis.rs b/src/handlers/analysis.rs index 0c659ff0..d9480082 100644 --- a/src/handlers/analysis.rs +++ b/src/handlers/analysis.rs @@ -1,7 +1,3 @@ use crate::{app::App, event::Key}; -pub fn handler(key: Key, _app: &mut App) { - match key { - _ => {} - }; -} +pub fn handler(_key: Key, _app: &mut App) {} diff --git a/src/handlers/basic_view.rs b/src/handlers/basic_view.rs index 0c659ff0..d9480082 100644 --- a/src/handlers/basic_view.rs +++ b/src/handlers/basic_view.rs @@ -1,7 +1,3 @@ use crate::{app::App, event::Key}; -pub fn handler(key: Key, _app: &mut App) { - match key { - _ => {} - }; -} +pub fn handler(_key: Key, _app: &mut App) {} diff --git a/src/handlers/error_screen.rs b/src/handlers/error_screen.rs index 0c659ff0..d9480082 100644 --- a/src/handlers/error_screen.rs +++ b/src/handlers/error_screen.rs @@ -1,7 +1,3 @@ use crate::{app::App, event::Key}; -pub fn handler(key: Key, _app: &mut App) { - match key { - _ => {} - }; -} +pub fn handler(_key: Key, _app: &mut App) {} diff --git a/src/user_config.rs b/src/user_config.rs index 4581f00a..7a981fc1 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -1,6 +1,5 @@ use crate::event::Key; use anyhow::{anyhow, Result}; -use dirs; use serde::{Deserialize, Serialize}; use std::{ fs, From 9baab61c8f386806e3d335a28d25499bbc18acaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Gerber?= Date: Sat, 25 Apr 2020 19:25:47 +0200 Subject: [PATCH 044/311] Fix token expiration datetime --- src/app.rs | 8 ++++---- src/main.rs | 4 ++-- src/network.rs | 16 +++++++++++----- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/app.rs b/src/app.rs index 2e4cf2a5..2cf21319 100644 --- a/src/app.rs +++ b/src/app.rs @@ -22,7 +22,7 @@ use std::sync::mpsc::Sender; use std::{ cmp::{max, min}, collections::HashSet, - time::Instant, + time::{Instant, SystemTime}, }; use tui::layout::Rect; @@ -287,7 +287,7 @@ pub struct App { pub is_loading: bool, io_tx: Option>, pub is_fetching_current_playback: bool, - pub spotify_token_expiry: Instant, + pub spotify_token_expiry: SystemTime, pub dialog: Option, pub confirm: bool, } @@ -362,7 +362,7 @@ impl Default for App { is_loading: false, io_tx: None, is_fetching_current_playback: false, - spotify_token_expiry: Instant::now(), + spotify_token_expiry: SystemTime::now(), dialog: None, confirm: false, } @@ -373,7 +373,7 @@ impl App { pub fn new( io_tx: Sender, user_config: UserConfig, - spotify_token_expiry: Instant, + spotify_token_expiry: SystemTime, ) -> App { App { io_tx: Some(io_tx), diff --git a/src/main.rs b/src/main.rs index 37a7836b..0d0cd5e4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,7 +36,7 @@ use std::{ panic::{self, PanicInfo}, path::PathBuf, sync::Arc, - time::Instant, + time::SystemTime, }; use tokio::sync::Mutex; use tui::{ @@ -300,7 +300,7 @@ async fn start_ui(user_config: UserConfig, app: &Arc>) -> Result<()> ))?; // Handle authentication refresh - if Instant::now() > app.spotify_token_expiry { + if SystemTime::now() > app.spotify_token_expiry { app.dispatch(IoEvent::RefreshAuthentication); } diff --git a/src/network.rs b/src/network.rs index f22b0fb8..32a61395 100644 --- a/src/network.rs +++ b/src/network.rs @@ -21,7 +21,7 @@ use rspotify::{ use serde_json::{map::Map, Value}; use std::{ sync::Arc, - time::{Duration, Instant}, + time::{Duration, Instant, SystemTime}, }; use tokio::sync::Mutex; use tokio::try_join; @@ -75,11 +75,17 @@ pub enum IoEvent { CurrentUserSavedTracksContains(Vec), } -pub fn get_spotify(token_info: TokenInfo) -> (Spotify, Instant) { - let token_expiry = Instant::now() - + Duration::from_secs(token_info.expires_in.into()) +pub fn get_spotify(token_info: TokenInfo) -> (Spotify, SystemTime) { + let token_expiry = { + if let Some(expires_at) = token_info.expires_at { + SystemTime::UNIX_EPOCH + + Duration::from_secs(expires_at as u64) // Set 10 seconds early - - Duration::from_secs(10); + - Duration::from_secs(10) + } else { + SystemTime::now() + } + }; let client_credential = SpotifyClientCredentials::default() .token_info(token_info) From 868a79c3da30e86b9a5edc9abb98f0bd79e540f2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2020 07:05:23 +0000 Subject: [PATCH 045/311] Bump tokio from 0.2.18 to 0.2.19 Bumps [tokio](https://github.com/tokio-rs/tokio) from 0.2.18 to 0.2.19. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-0.2.18...tokio-0.2.19) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b549f317..faf4dc3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1742,9 +1742,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ef16d072d2b6dc8b4a56c70f5c5ced1a37752116f8e7c1e80c659aa7cb6713" +checksum = "7d9c43f1bb96970e153bcbae39a65e249ccb942bd9d36dbdf086024920417c9c" dependencies = [ "bytes 0.5.4", "fnv", From 76bc8d76439f1e7ad795a16ba4cf30d5966eb339 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Tue, 28 Apr 2020 11:17:57 +0100 Subject: [PATCH 046/311] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36806ee1..6cbda215 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +- Fix re-authentication [#415](https://github.com/Rigellute/spotify-tui/pull/415) + ## [0.18.0] - 2020-04-21 ### Fixed From 3a76a82031a4d2eb173cc0a7756a28b7012d9280 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2020 06:56:13 +0000 Subject: [PATCH 047/311] Bump tokio from 0.2.19 to 0.2.20 Bumps [tokio](https://github.com/tokio-rs/tokio) from 0.2.19 to 0.2.20. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-0.2.19...tokio-0.2.20) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index faf4dc3b..6cbc915d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1742,9 +1742,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.19" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d9c43f1bb96970e153bcbae39a65e249ccb942bd9d36dbdf086024920417c9c" +checksum = "05c1d570eb1a36f0345a5ce9c6c6e665b70b73d11236912c0b477616aeec47b1" dependencies = [ "bytes 0.5.4", "fnv", From 33603880d9ac21ab64e990c379077da3abe1c515 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2020 06:56:34 +0000 Subject: [PATCH 048/311] Bump serde_json from 1.0.51 to 1.0.52 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.51 to 1.0.52. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.51...v1.0.52) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index faf4dc3b..acac8221 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1523,9 +1523,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.51" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da07b57ee2623368351e9a0488bb0b261322a15a6e0ae53e243cbdc0f4208da9" +checksum = "a7894c8ed05b7a3a279aeb79025fdec1d3158080b75b98a08faf2806bb799edd" dependencies = [ "itoa", "ryu", From cb5118e5fa218b0cea54d54bc5b1eeb10fc1b21e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 4 May 2020 07:03:09 +0000 Subject: [PATCH 049/311] Bump proc-macro2 from 1.0.10 to 1.0.12 Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.10 to 1.0.12. - [Release notes](https://github.com/alexcrichton/proc-macro2/releases) - [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.10...1.0.12) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 28 ++++++++++++++-------------- Cargo.toml | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae8333ad..d9cb553e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -431,7 +431,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.12", "quote 1.0.3", "syn 1.0.17", "synstructure", @@ -535,7 +535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.10", + "proc-macro2 1.0.12", "quote 1.0.3", "syn 1.0.17", ] @@ -1080,7 +1080,7 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.12", "quote 1.0.3", "syn 1.0.17", ] @@ -1132,9 +1132,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" +checksum = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319" dependencies = [ "unicode-xid 0.2.0", ] @@ -1160,7 +1160,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.12", ] [[package]] @@ -1516,7 +1516,7 @@ version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.12", "quote 1.0.3", "syn 1.0.17", ] @@ -1611,7 +1611,7 @@ dependencies = [ "clipboard", "crossterm", "dirs", - "proc-macro2 1.0.10", + "proc-macro2 1.0.12", "rand 0.7.3", "rspotify", "serde", @@ -1651,7 +1651,7 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.12", "quote 1.0.3", "unicode-xid 0.2.0", ] @@ -1662,7 +1662,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.12", "quote 1.0.3", "syn 1.0.17", "unicode-xid 0.2.0", @@ -1715,7 +1715,7 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "227362df41d566be41a28f64401e07a043157c21c14b9785a0d8e256f940a8fd" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.12", "quote 1.0.3", "syn 1.0.17", ] @@ -1770,7 +1770,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.12", "quote 1.0.3", "syn 1.0.17", ] @@ -1967,7 +1967,7 @@ dependencies = [ "bumpalo", "lazy_static", "log", - "proc-macro2 1.0.10", + "proc-macro2 1.0.12", "quote 1.0.3", "syn 1.0.17", "wasm-bindgen-shared", @@ -2001,7 +2001,7 @@ version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.12", "quote 1.0.3", "syn 1.0.17", "wasm-bindgen-backend", diff --git a/Cargo.toml b/Cargo.toml index 26215992..953086d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ backtrace = "0.3.46" clipboard = "0.5.0" crossterm = "0.17" tokio = { version = "0.2", features = ["full"] } -proc-macro2 = "1.0.10" +proc-macro2 = "1.0.12" rand = "0.7.3" anyhow = "1.0.28" From f49119b08a8e438895d9ba9f14200f0b3660a5cd Mon Sep 17 00:00:00 2001 From: Ferdinand Ratajczak Date: Thu, 30 Apr 2020 20:56:13 +0200 Subject: [PATCH 050/311] Update Ctrl-U shortcut to work like readline, add Ctrl-L Previously, it would delete the whole line. Now it deletes only the part of the line before the cursor and Ctrl-L deletes the whole line. --- src/handlers/input.rs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/handlers/input.rs b/src/handlers/input.rs index 752ddcb2..ba6a3ec8 100644 --- a/src/handlers/input.rs +++ b/src/handlers/input.rs @@ -10,6 +10,11 @@ use unicode_width::{UnicodeWidthChar, UnicodeWidthStr}; pub fn handler(key: Key, app: &mut App) { match key { Key::Ctrl('u') => { + app.input.drain(..app.input_idx); + app.input_idx = 0; + app.input_cursor_position = 0; + } + Key::Ctrl('l') => { app.input = vec![]; app.input_idx = 0; app.input_cursor_position = 0; @@ -118,16 +123,31 @@ mod tests { } #[test] - fn test_input_handler_clear_input_on_ctrl_u() { + fn test_input_handler_clear_input_on_ctrl_l() { let mut app = App::default(); app.input = str_to_vec_char("My text"); - handler(Key::Ctrl('u'), &mut app); + handler(Key::Ctrl('l'), &mut app); assert_eq!(app.input, str_to_vec_char("")); } + #[test] + fn test_input_handler_ctrl_u() { + let mut app = App::default(); + + app.input = str_to_vec_char("My text"); + + handler(Key::Ctrl('u'), &mut app); + assert_eq!(app.input, str_to_vec_char("My text")); + + app.input_cursor_position = 3; + app.input_idx = 3; + handler(Key::Ctrl('u'), &mut app); + assert_eq!(app.input, str_to_vec_char("text")); + } + #[test] fn test_input_handler_esc_back_to_playlist() { let mut app = App::default(); From 86db53711b0924c81ff1de187bb3451804c0843c Mon Sep 17 00:00:00 2001 From: Ferdinand Ratajczak Date: Thu, 30 Apr 2020 20:57:41 +0200 Subject: [PATCH 051/311] Add Ctrl-K readline shortcut (delete end of line) --- src/handlers/input.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/handlers/input.rs b/src/handlers/input.rs index ba6a3ec8..b3a65faf 100644 --- a/src/handlers/input.rs +++ b/src/handlers/input.rs @@ -9,6 +9,9 @@ use unicode_width::{UnicodeWidthChar, UnicodeWidthStr}; // Handle event when the search input block is active pub fn handler(key: Key, app: &mut App) { match key { + Key::Ctrl('k') => { + app.input.drain(app.input_idx..app.input.len()); + } Key::Ctrl('u') => { app.input.drain(..app.input_idx); app.input_idx = 0; @@ -148,6 +151,25 @@ mod tests { assert_eq!(app.input, str_to_vec_char("text")); } + #[test] + fn test_input_handler_ctrl_k() { + let mut app = App::default(); + + app.input = str_to_vec_char("My text"); + + handler(Key::Ctrl('k'), &mut app); + assert_eq!(app.input, str_to_vec_char("")); + + app.input = str_to_vec_char("My text"); + app.input_cursor_position = 2; + app.input_idx = 2; + handler(Key::Ctrl('k'), &mut app); + assert_eq!(app.input, str_to_vec_char("My")); + + handler(Key::Ctrl('k'), &mut app); + assert_eq!(app.input, str_to_vec_char("My")); + } + #[test] fn test_input_handler_esc_back_to_playlist() { let mut app = App::default(); From 02bb660dffb8bc869664b9b249fdff4dde6b8661 Mon Sep 17 00:00:00 2001 From: Ferdinand Ratajczak Date: Thu, 30 Apr 2020 20:58:41 +0200 Subject: [PATCH 052/311] Add Ctrl-W readline shortcut (delete previous word) --- src/handlers/input.rs | 57 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/handlers/input.rs b/src/handlers/input.rs index b3a65faf..b5880614 100644 --- a/src/handlers/input.rs +++ b/src/handlers/input.rs @@ -22,6 +22,24 @@ pub fn handler(key: Key, app: &mut App) { app.input_idx = 0; app.input_cursor_position = 0; } + Key::Ctrl('w') => { + if app.input_cursor_position == 0 { + return; + } + let word_end = match app.input[..app.input_idx].iter().rposition(|&x| x != ' ') { + Some(index) => index + 1, + None => 0, + }; + let word_start = match app.input[..word_end].iter().rposition(|&x| x == ' ') { + Some(index) => index + 1, + None => 0, + }; + let deleted: String = app.input[word_start..app.input_idx].iter().collect(); + let deleted_len: u16 = UnicodeWidthStr::width(deleted.as_str()).try_into().unwrap(); + app.input.drain(word_start..app.input_idx); + app.input_idx = word_start; + app.input_cursor_position -= deleted_len; + } Key::Ctrl('e') => { app.input_idx = app.input.len(); let input_string: String = app.input.iter().collect(); @@ -170,6 +188,45 @@ mod tests { assert_eq!(app.input, str_to_vec_char("My")); } + #[test] + fn test_input_handler_ctrl_w() { + let mut app = App::default(); + + app.input = str_to_vec_char("My text"); + + handler(Key::Ctrl('w'), &mut app); + assert_eq!(app.input, str_to_vec_char("My text")); + + app.input_cursor_position = 3; + app.input_idx = 3; + handler(Key::Ctrl('w'), &mut app); + assert_eq!(app.input, str_to_vec_char("text")); + assert_eq!(app.input_cursor_position, 0); + assert_eq!(app.input_idx, 0); + + app.input = str_to_vec_char(" "); + app.input_cursor_position = 3; + app.input_idx = 3; + handler(Key::Ctrl('w'), &mut app); + assert_eq!(app.input, str_to_vec_char(" ")); + assert_eq!(app.input_cursor_position, 0); + assert_eq!(app.input_idx, 0); + app.input_cursor_position = 1; + app.input_idx = 1; + handler(Key::Ctrl('w'), &mut app); + assert_eq!(app.input, str_to_vec_char("")); + assert_eq!(app.input_cursor_position, 0); + assert_eq!(app.input_idx, 0); + + app.input = str_to_vec_char("Hello there "); + app.input_cursor_position = 13; + app.input_idx = 13; + handler(Key::Ctrl('w'), &mut app); + assert_eq!(app.input, str_to_vec_char("Hello ")); + assert_eq!(app.input_cursor_position, 6); + assert_eq!(app.input_idx, 6); + } + #[test] fn test_input_handler_esc_back_to_playlist() { let mut app = App::default(); From e60dfbed15b7110e0346ec45fed9ed8f608eac1b Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 4 May 2020 11:57:06 +0100 Subject: [PATCH 053/311] Temp fix audio_analysis feature The Spotify endpoint for audio analysis has recently changed - some fields are now undefined. There is no official documentation of this, which is why I've had to use the heavy handed approach of making all audio analysis properties optional (fix made in [rspotify](https://github.com/ramsayleung/rspotify/pull/94)). This fix won't be accepted upstream (see link above), so I've had to use my fork of rspotify to fix this in the meantime. Hopefully a more permanent fix will follow. Closes #416 --- Cargo.lock | 3 +-- Cargo.toml | 2 +- src/ui/audio_analysis.rs | 20 ++++++++++++-------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b549f317..cda8759b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1409,8 +1409,7 @@ dependencies = [ [[package]] name = "rspotify" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29b79da3557219b1ea44609ae2bdddbe8f0cc71188ab863cc47d98e8a1d6eb5" +source = "git+https://github.com/Rigellute/rspotify#8d15009ea8e457ef5827334f22fef7e55b34c6b3" dependencies = [ "base64 0.10.1", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 26215992..d3b2e718 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ license = "MIT OR Apache-2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rspotify = "0.9.0" +rspotify = { git = "https://github.com/Rigellute/rspotify" } tui = { version = "0.9.1", features = ["crossterm"], default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/src/ui/audio_analysis.rs b/src/ui/audio_analysis.rs index 2e5b0356..ff4a8225 100644 --- a/src/ui/audio_analysis.rs +++ b/src/ui/audio_analysis.rs @@ -69,28 +69,30 @@ where let segment = analysis .segments .iter() - .find(|segment| segment.start >= progress_seconds); + .find(|segment| segment.start.unwrap_or(0.0) >= progress_seconds); let section = analysis .sections .iter() - .find(|section| section.start >= progress_seconds); + .find(|section| section.start.unwrap_or(0.0) >= progress_seconds); if let (Some(segment), Some(section)) = (segment, section) { let texts = [ Text::raw(format!( "Tempo: {} (confidence {:.0}%)\n", - section.tempo, - section.tempo_confidence * 100.0 + section.tempo.unwrap_or(0.0), + section.tempo_confidence.unwrap_or(0.0) * 100.0 )), Text::raw(format!( "Key: {} (confidence {:.0}%)\n", - PITCHES.get(section.key as usize).unwrap_or(&PITCHES[0]), - section.key_confidence * 100.0 + PITCHES + .get(section.key.unwrap_or(0) as usize) + .unwrap_or(&PITCHES[0]), + section.key_confidence.unwrap_or(0.0) * 100.0 )), Text::raw(format!( "Time Signature: {}/4 (confidence {:.0}%)\n", - section.time_signature, - section.time_signature_confidence * 100.0 + section.time_signature.unwrap_or(0), + section.time_signature_confidence.unwrap_or(0.0) * 100.0 )), ]; let p = Paragraph::new(texts.iter()) @@ -99,7 +101,9 @@ where f.render_widget(p, chunks[0]); let data: Vec<(&str, u64)> = segment + .clone() .pitches + .unwrap_or_default() .iter() .enumerate() .map(|(index, pitch)| { From 9bf6a280def5ac33283404d6e9a45f3902b0c5b2 Mon Sep 17 00:00:00 2001 From: Ferdinand Ratajczak Date: Mon, 4 May 2020 13:35:41 +0200 Subject: [PATCH 054/311] Add new readline shortcuts to help menu --- src/ui/help.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ui/help.rs b/src/ui/help.rs index d5c533d3..eb6bf159 100644 --- a/src/ui/help.rs +++ b/src/ui/help.rs @@ -63,7 +63,6 @@ pub fn get_help_docs() -> Vec> { "Selected block", ], vec!["Play all tracks for artist", "e", "Library -> Artists"], - vec!["Delete entire input", "", "Search input"], vec!["Search with input text", "", "Search input"], vec![ "Move cursor one space left", @@ -75,6 +74,18 @@ pub fn get_help_docs() -> Vec> { "", "Search input", ], + vec!["Delete entire input", "", "Search input"], + vec![ + "Delete text from cursor to start of input", + "", + "Search input", + ], + vec![ + "Delete text from cursor to end of input", + "", + "Search input", + ], + vec!["Delete previous word", "", "Search input"], vec!["Jump to start of input", "", "Search input"], vec!["Jump to end of input", "", "Search input"], vec![ From 30f11ea841309ae9744a4ccc7878fa7c4518e879 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 4 May 2020 12:29:39 +0000 Subject: [PATCH 055/311] docs: update README.md [skip ci] --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e66853c8..4e8722d7 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-49-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-50-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -344,6 +344,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Sean Li

πŸ’»
TimotheeGerber

πŸ’» πŸ“– + +
Ferdinand Ratajczak

πŸ’» + From c59867c032d1aa565b744e61791168eb04d875fd Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 4 May 2020 12:29:40 +0000 Subject: [PATCH 056/311] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index a077273e..80eac4ed 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -457,6 +457,15 @@ "code", "doc" ] + }, + { + "login": "fratajczak", + "name": "Ferdinand Ratajczak", + "avatar_url": "https://avatars2.githubusercontent.com/u/33835579?v=4", + "profile": "https://github.com/fratajczak", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, From acc4cadc45b24e379367f200dac51bcca747bbba Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 4 May 2020 12:33:11 +0000 Subject: [PATCH 057/311] Bump crossterm from 0.17.3 to 0.17.4 Bumps [crossterm](https://github.com/crossterm-rs/crossterm) from 0.17.3 to 0.17.4. - [Release notes](https://github.com/crossterm-rs/crossterm/releases) - [Changelog](https://github.com/crossterm-rs/crossterm/blob/master/CHANGELOG.md) - [Commits](https://github.com/crossterm-rs/crossterm/commits) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 055610ac..17c7fcb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -265,9 +265,9 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.17.3" +version = "0.17.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccdd8ef63a44e821956c6a276eca0faaa889d6a067dfcdbd5bfe85dce3a1d250" +checksum = "2a880035bfe4707e344da9acf50cc94d003fe337f50afd94c8722c1bb4e0a933" dependencies = [ "bitflags", "crossterm_winapi", From 4335894c110d6c86d7ff5661084e650ad3d060b9 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 4 May 2020 13:38:49 +0100 Subject: [PATCH 058/311] Prepare release v0.19.0 --- CHANGELOG.md | 9 ++++++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cbda215..e1f68ce1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,15 @@ # Changelog -## [Unreleased] +## [0.19.0] - 2020-05-04 + +### Fixed - Fix re-authentication [#415](https://github.com/Rigellute/spotify-tui/pull/415) +- Fix audio analysis feature [#435](https://github.com/Rigellute/spotify-tui/pull/435) + +### Added + +- Add more readline shortcuts to the search input [#425](https://github.com/Rigellute/spotify-tui/pull/425) ## [0.18.0] - 2020-04-21 diff --git a/Cargo.lock b/Cargo.lock index 055610ac..9b9e328d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1602,7 +1602,7 @@ dependencies = [ [[package]] name = "spotify-tui" -version = "0.18.0" +version = "0.19.0" dependencies = [ "anyhow", "backtrace", diff --git a/Cargo.toml b/Cargo.toml index ef756019..2586ea24 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ documentation = "https://github.com/Rigellute/spotify-tui" repository = "https://github.com/Rigellute/spotify-tui" keywords = ["spotify", "tui", "cli", "terminal"] categories = ["command-line-utilities"] -version = "0.18.0" +version = "0.19.0" authors = ["Alexander Keliris "] edition = "2018" license = "MIT OR Apache-2.0" From fe2fe3c8874a9bbbfdab50feb98d6c5c056cf423 Mon Sep 17 00:00:00 2001 From: Michael Hellwig Date: Wed, 6 May 2020 18:01:19 +0200 Subject: [PATCH 059/311] moved pagination to start of help-file --- src/ui/help.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ui/help.rs b/src/ui/help.rs index eb6bf159..3458caa1 100644 --- a/src/ui/help.rs +++ b/src/ui/help.rs @@ -1,5 +1,13 @@ pub fn get_help_docs() -> Vec> { vec![ + vec!["Scroll down to next result page", "", "Pagination"], + vec![ + "Scroll up to previous result page", + "", + "Pagination", + ], + vec!["Jump to start of playlist", "", "Pagination"], + vec!["Jump to end of playlist", "", "Pagination"], vec!["Jump to currently playing album", "a", "General"], vec![ "Jump to currently playing artist's album list", @@ -93,14 +101,6 @@ pub fn get_help_docs() -> Vec> { "", "Search input", ], - vec!["Scroll down to next result page", "", "Pagination"], - vec![ - "Scroll up to previous result page", - "", - "Pagination", - ], - vec!["Jump to start of playlist", "", "Pagination"], - vec!["Jump to end of playlist", "", "Pagination"], vec!["Delete saved album", "D", "Library -> Albums"], vec!["Delete saved playist", "D", "Playlist"], vec!["Follow an artists/playlist", "w", "Search result"], From 67dc397cf203abe954960d6bda1840f003ae58d5 Mon Sep 17 00:00:00 2001 From: GrudgeDuck Date: Sat, 9 May 2020 01:02:18 +0900 Subject: [PATCH 060/311] Add support for saving an album and following an artist in artist view --- src/app.rs | 76 +++++++++++++++++++++++++--------- src/handlers/artist.rs | 12 +++++- src/handlers/search_results.rs | 6 ++- src/ui/mod.rs | 24 ++++++++++- 4 files changed, 93 insertions(+), 25 deletions(-) diff --git a/src/app.rs b/src/app.rs index 2cf21319..c71672e7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -704,21 +704,41 @@ impl App { } } } + ActiveBlock::ArtistBlock => { + if let Some(artist) = &self.artist { + if let Some(selected_album) = artist.albums.items.get(artist.selected_album_index) { + if let Some(album_id) = selected_album.id.clone() { + self.dispatch(IoEvent::CurrentUserSavedAlbumDelete(album_id)); + } + } + } + } _ => (), } } - pub fn current_user_saved_album_add(&mut self) { - if let SearchResult { - albums: Some(ref albums), - selected_album_index: Some(selected_index), - .. - } = self.search_results - { - let selected_album = &albums.albums.items[selected_index]; - if let Some(album_id) = selected_album.id.clone() { - self.dispatch(IoEvent::CurrentUserSavedAlbumAdd(album_id)); + pub fn current_user_saved_album_add(&mut self, block: ActiveBlock) { + match block { + ActiveBlock::SearchResultBlock => { + if let Some(albums) = &self.search_results.albums { + if let Some(selected_index) = self.search_results.selected_album_index { + let selected_album = &albums.albums.items[selected_index]; + if let Some(album_id) = selected_album.id.clone() { + self.dispatch(IoEvent::CurrentUserSavedAlbumAdd(album_id)); + } + } + } + } + ActiveBlock::ArtistBlock => { + if let Some(artist) = &self.artist { + if let Some(selected_album) = artist.albums.items.get(artist.selected_album_index) { + if let Some(album_id) = selected_album.id.clone() { + self.dispatch(IoEvent::CurrentUserSavedAlbumAdd(album_id)); + } + } + } } + _ => (), } } @@ -741,20 +761,36 @@ impl App { } } } + ActiveBlock::ArtistBlock => { + if let Some(artist) = &self.artist { + let selected_artis = &artist.related_artists[artist.selected_related_artist_index]; + let artist_id = selected_artis.id.clone(); + self.dispatch(IoEvent::UserUnfollowArtists(vec![artist_id])); + } + } _ => (), }; } - pub fn user_follow_artists(&mut self) { - if let SearchResult { - artists: Some(ref artists), - selected_artists_index: Some(selected_index), - .. - } = self.search_results - { - let selected_artist: &FullArtist = &artists.artists.items[selected_index]; - let artist_id = selected_artist.id.clone(); - self.dispatch(IoEvent::UserFollowArtists(vec![artist_id])); + pub fn user_follow_artists(&mut self, block: ActiveBlock) { + match block { + ActiveBlock::SearchResultBlock => { + if let Some(artists) = &self.search_results.artists { + if let Some(selected_index) = self.search_results.selected_artists_index { + let selected_artist: &FullArtist = &artists.artists.items[selected_index]; + let artist_id = selected_artist.id.clone(); + self.dispatch(IoEvent::UserUnfollowArtists(vec![artist_id])); + } + } + } + ActiveBlock::ArtistBlock => { + if let Some(artist) = &self.artist { + let selected_artis = &artist.related_artists[artist.selected_related_artist_index]; + let artist_id = selected_artis.id.clone(); + self.dispatch(IoEvent::UserFollowArtists(vec![artist_id])); + } + } + _ => (), } } diff --git a/src/handlers/artist.rs b/src/handlers/artist.rs index a22f07f5..bd278d7c 100644 --- a/src/handlers/artist.rs +++ b/src/handlers/artist.rs @@ -1,5 +1,5 @@ use super::common_key_events; -use crate::app::{App, ArtistBlock, RecommendationsContext, TrackTableContext}; +use crate::app::{ActiveBlock, App, ArtistBlock, RecommendationsContext, TrackTableContext}; use crate::event::Key; use crate::network::IoEvent; @@ -296,6 +296,16 @@ pub fn handler(key: Key, app: &mut App) { handle_recommend_event_on_selected_block(app); } } + Key::Char('w') => match artist.artist_selected_block { + ArtistBlock::Albums => app.current_user_saved_album_add(ActiveBlock::ArtistBlock), + ArtistBlock::RelatedArtists => app.user_follow_artists(ActiveBlock::ArtistBlock), + _ => (), + }, + Key::Char('D') => match artist.artist_selected_block { + ArtistBlock::Albums => app.current_user_saved_album_delete(ActiveBlock::ArtistBlock), + ArtistBlock::RelatedArtists => app.user_unfollow_artists(ActiveBlock::ArtistBlock), + _ => (), + }, _ => {} }; } diff --git a/src/handlers/search_results.rs b/src/handlers/search_results.rs index 2e651403..d8eb884c 100644 --- a/src/handlers/search_results.rs +++ b/src/handlers/search_results.rs @@ -430,9 +430,11 @@ pub fn handler(key: Key, app: &mut App) { _ => handle_enter_event_on_selected_block(app), }, Key::Char('w') => match app.search_results.selected_block { - SearchResultBlock::AlbumSearch => app.current_user_saved_album_add(), + SearchResultBlock::AlbumSearch => { + app.current_user_saved_album_add(ActiveBlock::SearchResultBlock) + } SearchResultBlock::SongSearch => {} - SearchResultBlock::ArtistSearch => app.user_follow_artists(), + SearchResultBlock::ArtistSearch => app.user_follow_artists(ActiveBlock::SearchResultBlock), SearchResultBlock::PlaylistSearch => { app.user_follow_playlist(); } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index ed482fbf..8aa63076 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1035,7 +1035,20 @@ where .albums .items .iter() - .map(|item| item.name.to_owned()) + .map(|item| { + let mut album_artist = String::new(); + if let Some(album_id) = &item.id { + if app.saved_album_ids_set.contains(&album_id.to_owned()) { + album_artist.push_str("β™₯ "); + } + } + album_artist.push_str(&format!( + "{} - {}", + item.name.to_owned(), + create_artist_string(&item.artists) + )); + album_artist + }) .collect::>(); draw_selectable_list( @@ -1051,7 +1064,14 @@ where let related_artists = artist .related_artists .iter() - .map(|artist| artist.name.to_owned()) + .map(|item| { + let mut artist = String::new(); + if app.followed_artist_ids_set.contains(&item.id.to_owned()) { + artist.push_str("β™₯ "); + } + artist.push_str(&item.name.to_owned()); + artist + }) .collect::>(); draw_selectable_list( From 5be3c60dbde4eaa4a6072f2a12077675bc8606ee Mon Sep 17 00:00:00 2001 From: Sheel Choksi Date: Sat, 9 May 2020 20:49:31 -0700 Subject: [PATCH 061/311] Add user configuration toggle for the loading indicator This new setting, `show_loading_indicator`, can be added to the behavior section of the user configuration. Defaults to `true` to maintain existing behavior of showing the loading indicator. Set to `false` to disable the loading indicator. [Resolves #420] --- README.md | 2 ++ src/ui/mod.rs | 3 ++- src/user_config.rs | 7 +++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4e8722d7..1ef33159 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,8 @@ behavior: volume_increment: 10 # The lower the number the higher the "frames per second". You can decrease this number so that the audio visualisation is smoother but this can be expensive! tick_rate_milliseconds: 250 + # controls whether to show a loading indicator in the top right of the UI whenever communicating with Spotify API + show_loading_indicator: true keybindings: # Key stroke can be used if it only uses two keys: diff --git a/src/ui/mod.rs b/src/ui/mod.rs index ed482fbf..26f14a44 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -134,7 +134,8 @@ where ); f.render_widget(input, chunks[0]); - let help_block_text = if app.is_loading { + let show_loading = app.is_loading && app.user_config.behavior.show_loading_indicator; + let help_block_text = if show_loading { (app.user_config.theme.hint, "Loading...") } else { (app.user_config.theme.inactive, "Type ?") diff --git a/src/user_config.rs b/src/user_config.rs index 7a981fc1..a60b809a 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -192,6 +192,7 @@ pub struct BehaviorConfigString { pub seek_milliseconds: Option, pub volume_increment: Option, pub tick_rate_milliseconds: Option, + pub show_loading_indicator: Option, } #[derive(Clone)] @@ -199,6 +200,7 @@ pub struct BehaviorConfig { pub seek_milliseconds: u32, pub volume_increment: u8, pub tick_rate_milliseconds: u64, + pub show_loading_indicator: bool, } #[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -246,6 +248,7 @@ impl UserConfig { seek_milliseconds: 5 * 1000, volume_increment: 10, tick_rate_milliseconds: 250, + show_loading_indicator: true, }, path_to_config: None, } @@ -359,6 +362,10 @@ impl UserConfig { } } + if let Some(loading_indicator) = behavior_config.show_loading_indicator { + self.behavior.show_loading_indicator = loading_indicator; + } + Ok(()) } From 45460f0cf45192e6f68bab021f7eb163c8ec8cc4 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 11 May 2020 09:14:35 +0000 Subject: [PATCH 062/311] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4e8722d7..cf9d8c6a 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-50-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-51-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -346,6 +346,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Ferdinand Ratajczak

πŸ’» +
Michael Hellwig

πŸ“– From 1db6e2e6bab4b8080ab57ca1f866d1612e2b8128 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 11 May 2020 09:14:36 +0000 Subject: [PATCH 063/311] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 80eac4ed..6b13bf54 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -466,6 +466,15 @@ "contributions": [ "code" ] + }, + { + "login": "mhellwig", + "name": "Michael Hellwig", + "avatar_url": "https://avatars1.githubusercontent.com/u/414112?v=4", + "profile": "http://fnanp.in-ulm.de/microblog/", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, From 322ecbe59ac53e18d2ccffca6ccd356efcaaef64 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 11 May 2020 09:17:27 +0000 Subject: [PATCH 064/311] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ef33159..231daff6 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-50-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-51-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -348,6 +348,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Ferdinand Ratajczak

πŸ’» +
Sheel Choksi

πŸ’» From d3f8dcd1d520e81292f231b555cd20f696912180 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 11 May 2020 09:17:28 +0000 Subject: [PATCH 065/311] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 80eac4ed..d2bb1914 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -466,6 +466,15 @@ "contributions": [ "code" ] + }, + { + "login": "sheelc", + "name": "Sheel Choksi", + "avatar_url": "https://avatars0.githubusercontent.com/u/1355710?v=4", + "profile": "https://github.com/sheelc", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, From 4f813ed0bace2219e232e0513b8214815e8100a6 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 11 May 2020 09:18:35 +0000 Subject: [PATCH 066/311] docs: update README.md [skip ci] From 9e377408aedd6a8afd0175121d9e9da5983755a6 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 11 May 2020 09:18:36 +0000 Subject: [PATCH 067/311] docs: update .all-contributorsrc [skip ci] From 5d6862947f598fdd206cde451fe7b868870c303b Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 11 May 2020 10:22:59 +0100 Subject: [PATCH 068/311] Update CHANGELOG --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1f68ce1..7888f4df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## [Unreleased] + +- Move pagination instructions to top of help menu [#442](https://github.com/Rigellute/spotify-tui/pull/442) +- Add user configuration toggle for the loading indicator [#447](https://github.com/Rigellute/spotify-tui/pull/447) + ## [0.19.0] - 2020-05-04 ### Fixed From f36e6987c8d76f9fe85a79fc94743a52698de850 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 11 May 2020 10:39:07 +0100 Subject: [PATCH 069/311] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7888f4df..12326034 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Move pagination instructions to top of help menu [#442](https://github.com/Rigellute/spotify-tui/pull/442) - Add user configuration toggle for the loading indicator [#447](https://github.com/Rigellute/spotify-tui/pull/447) +- Add support for saving an album and following an artist in artist view [#445](https://github.com/Rigellute/spotify-tui/pull/445) ## [0.19.0] - 2020-05-04 From 743ccba9c71c2a75cfbdb5627466606ac71bcf94 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 11 May 2020 10:41:35 +0100 Subject: [PATCH 070/311] Update cargo.lock --- Cargo.lock | 291 +++++++++++++++++++++++++++-------------------------- 1 file changed, 150 insertions(+), 141 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06353866..a8b785c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,9 +26,9 @@ checksum = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff" [[package]] name = "arc-swap" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d663a8e9a99154b5fb793032533f6328da35e23aac63d5c152279aa8ba356825" +checksum = "b585a98a234c46fc563103e9278c9391fde1f4e6850334da895d27edb9580f62" [[package]] name = "arrayref" @@ -79,9 +79,9 @@ dependencies = [ [[package]] name = "backtrace-sys" -version = "0.1.35" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de8aba10a69c8e8d7622c5710229485ec32e9d55fdad160ea559c086fdcd118" +checksum = "18fbebbe1c9d1f383a9cc7e8ccdb471b91c8d024ee9c2ca5b5346121fe8b4399" dependencies = [ "cc", "libc", @@ -161,9 +161,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" [[package]] name = "cc" -version = "1.0.50" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" +checksum = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d" [[package]] name = "cfg-if" @@ -417,9 +417,9 @@ dependencies = [ [[package]] name = "failure" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8529c2421efa3066a5cbd8063d2244603824daccb6936b079010bb2aa89464b" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" dependencies = [ "backtrace", "failure_derive", @@ -427,13 +427,13 @@ dependencies = [ [[package]] name = "failure_derive" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ "proc-macro2 1.0.12", - "quote 1.0.3", - "syn 1.0.17", + "quote 1.0.4", + "syn 1.0.19", "synstructure", ] @@ -482,9 +482,9 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] name = "futures" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c329ae8753502fb44ae4fc2b622fa2a94652c41e795143765ba0927f92ab780" +checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613" dependencies = [ "futures-channel", "futures-core", @@ -497,9 +497,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c77d04ce8edd9cb903932b608268b3fffec4163dc053b3b402bf47eac1f1a8" +checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5" dependencies = [ "futures-core", "futures-sink", @@ -507,15 +507,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f25592f769825e89b92358db00d26f965761e094951ac44d3663ef25b7ac464a" +checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" [[package]] name = "futures-executor" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f674f3e1bcb15b37284a90cedf55afdba482ab061c407a9c0ebbd0f3109741ba" +checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314" dependencies = [ "futures-core", "futures-task", @@ -524,39 +524,42 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a638959aa96152c7a4cddf50fcb1e3fede0583b27157c26e67d6f99904090dc6" +checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" [[package]] name = "futures-macro" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" +checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" dependencies = [ "proc-macro-hack", "proc-macro2 1.0.12", - "quote 1.0.3", - "syn 1.0.17", + "quote 1.0.4", + "syn 1.0.19", ] [[package]] name = "futures-sink" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3466821b4bc114d95b087b850a724c6f83115e929bc88f1fa98a3304a944c8a6" +checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc" [[package]] name = "futures-task" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0a34e53cf6cdcd0178aa573aed466b646eb3db769570841fda0c7ede375a27" +checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626" +dependencies = [ + "once_cell", +] [[package]] name = "futures-util" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22766cf25d64306bedf0384da004d05c9974ab104fcc4528f1236181c18004c5" +checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6" dependencies = [ "futures-channel", "futures-core", @@ -565,6 +568,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", + "pin-project", "pin-utils", "proc-macro-hack", "proc-macro-nested", @@ -584,9 +588,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "377038bf3c89d18d6ca1431e7a5027194fbd724ca10592b9487ede5e8e144f42" +checksum = "79b7246d7e4b979c03fa093da39cfb3617a96bbeee6310af63991668d7e843ff" dependencies = [ "bytes 0.5.4", "fnv", @@ -603,9 +607,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e" +checksum = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4" dependencies = [ "libc", ] @@ -648,9 +652,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.13.4" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6081100e960d9d74734659ffc9cc91daf1c0fc7aceb8eaa94ee1a3f5046f2e" +checksum = "96816e1d921eca64d208a85aab4f7798455a8e34229ee5a88c935bdee1b78b14" dependencies = [ "bytes 0.5.4", "futures-channel", @@ -755,9 +759,9 @@ checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" [[package]] name = "js-sys" -version = "0.3.37" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055" +checksum = "fa5a448de267e7358beaf4a5d849518fe9a0c13fce7afd44b06e68550e5562a7" dependencies = [ "wasm-bindgen", ] @@ -780,21 +784,21 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.68" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" +checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" [[package]] name = "linked-hash-map" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" +checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" [[package]] name = "lock_api" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b" +checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" dependencies = [ "scopeguard", ] @@ -847,9 +851,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.21" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" +checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" dependencies = [ "cfg-if", "fuchsia-zircon", @@ -878,9 +882,9 @@ dependencies = [ [[package]] name = "mio-uds" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" +checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" dependencies = [ "iovec", "libc", @@ -929,9 +933,9 @@ dependencies = [ [[package]] name = "net2" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" dependencies = [ "cfg-if", "libc", @@ -959,9 +963,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" dependencies = [ "hermit-abi", "libc", @@ -996,11 +1000,17 @@ dependencies = [ "objc", ] +[[package]] +name = "once_cell" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" + [[package]] name = "openssl" -version = "0.10.28" +version = "0.10.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "973293749822d7dd6370d6da1e523b0d1db19f06c459134c658b2a4261378b52" +checksum = "cee6d85f4cb4c4f59a6a85d5b68a233d280c82e29e822913b9c8b129fbf20bdd" dependencies = [ "bitflags", "cfg-if", @@ -1018,9 +1028,9 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" [[package]] name = "openssl-sys" -version = "0.9.54" +version = "0.9.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1024c0a59774200a555087a6da3f253a9095a5f344e353b212ac4c8b8e450986" +checksum = "f02309a7f127000ed50594f0b50ecc69e7c654e16d41b4e8156d1b3df8e0b52e" dependencies = [ "autocfg 1.0.0", "cc", @@ -1031,9 +1041,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" +checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" dependencies = [ "lock_api", "parking_lot_core", @@ -1041,9 +1051,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" +checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" dependencies = [ "cfg-if", "cloudabi", @@ -1067,35 +1077,35 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pin-project" -version = "0.4.8" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c" +checksum = "81d480cb4e89522ccda96d0eed9af94180b7a5f93fb28f66e1fd7d68431663d1" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "0.4.8" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" +checksum = "a82996f11efccb19b685b14b5df818de31c1edcee3daa256ab5775dd98e72feb" dependencies = [ "proc-macro2 1.0.12", - "quote 1.0.3", - "syn 1.0.17", + "quote 1.0.4", + "syn 1.0.19", ] [[package]] name = "pin-project-lite" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" +checksum = "f7505eeebd78492e0f6108f7171c4948dbb120ee8119d9d77d0afa5469bef67f" [[package]] name = "pin-utils" -version = "0.1.0-alpha.4" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" @@ -1156,9 +1166,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" +checksum = "4c1f4b0efa5fc5e8ceb705136bfee52cfdb6a4e3509f770b478cd6ed434232a7" dependencies = [ "proc-macro2 1.0.12", ] @@ -1344,9 +1354,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.3.6" +version = "1.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6946991529684867e47d86474e3a6d0c0ab9b82d5821e314b1ede31fa3a4b3" +checksum = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692" dependencies = [ "aho-corasick", "memchr", @@ -1457,15 +1467,15 @@ checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" [[package]] name = "ryu" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76" +checksum = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1" [[package]] name = "schannel" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "039c25b130bd8c1321ee2d7de7fde2659fa9c2744e4bb29711cfc852ea53cd19" +checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" dependencies = [ "lazy_static", "winapi 0.3.8", @@ -1479,9 +1489,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "security-framework" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572dfa3a0785509e7a44b5b4bebcf94d41ba34e9ed9eb9df722545c3b3c4144a" +checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535" dependencies = [ "bitflags", "core-foundation", @@ -1492,9 +1502,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb15a5fec93b7021b8a9e96009c5d8d51c15673569f7c0f6b7204e5b7b404f" +checksum = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405" dependencies = [ "core-foundation-sys", "libc", @@ -1502,29 +1512,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.106" +version = "1.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" +checksum = "99e7b308464d16b56eba9964e4972a3eee817760ab60d88c3f86e1fecb08204c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.106" +version = "1.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" +checksum = "818fbf6bfa9a42d3bfcaca148547aa00c7b915bec71d1757aa2d44ca68771984" dependencies = [ "proc-macro2 1.0.12", - "quote 1.0.3", - "syn 1.0.17", + "quote 1.0.4", + "syn 1.0.19", ] [[package]] name = "serde_json" -version = "1.0.52" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7894c8ed05b7a3a279aeb79025fdec1d3158080b75b98a08faf2806bb799edd" +checksum = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2" dependencies = [ "itoa", "ryu", @@ -1545,9 +1555,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" +checksum = "16c7a592a1ec97c9c1c68d75b6e537dcbf60c7618e038e7841e00af1d9ccf0c4" dependencies = [ "dtoa", "linked-hash-map", @@ -1557,9 +1567,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b9f3a1686a29f53cfd91ee5e3db3c12313ec02d33765f02c1a9645a1811e2c" +checksum = "7c0893246f276ba1aac4983fb8711dad108e2886fd76bf618a382ab4e30e5bec" dependencies = [ "libc", "mio", @@ -1584,9 +1594,9 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" [[package]] name = "smallvec" -version = "1.2.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" +checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4" [[package]] name = "socket2" @@ -1646,12 +1656,12 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.17" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" +checksum = "e8e5aa70697bb26ee62214ae3288465ecec0000f05182f039b477001f08f5ae7" dependencies = [ "proc-macro2 1.0.12", - "quote 1.0.3", + "quote 1.0.4", "unicode-xid 0.2.0", ] @@ -1662,8 +1672,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ "proc-macro2 1.0.12", - "quote 1.0.3", - "syn 1.0.17", + "quote 1.0.4", + "syn 1.0.19", "unicode-xid 0.2.0", ] @@ -1701,22 +1711,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0570dc61221295909abdb95c739f2e74325e14293b2026b0a7e195091ec54ae" +checksum = "d12a1dae4add0f0d568eebc7bf142f145ba1aa2544cafb195c76f0f409091b60" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "227362df41d566be41a28f64401e07a043157c21c14b9785a0d8e256f940a8fd" +checksum = "3f34e0c1caaa462fd840ec6b768946ea1e7842620d94fe29d5b847138f521269" dependencies = [ "proc-macro2 1.0.12", - "quote 1.0.3", - "syn 1.0.17", + "quote 1.0.4", + "syn 1.0.19", ] [[package]] @@ -1730,12 +1740,11 @@ dependencies = [ [[package]] name = "time" -version = "0.1.42" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", - "redox_syscall", "winapi 0.3.8", ] @@ -1770,8 +1779,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" dependencies = [ "proc-macro2 1.0.12", - "quote 1.0.3", - "syn 1.0.17", + "quote 1.0.4", + "syn 1.0.19", ] [[package]] @@ -1789,9 +1798,9 @@ dependencies = [ [[package]] name = "tokio-tls" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bde02a3a5291395f59b06ec6945a3077602fac2b07eeeaf0dee2122f3619828" +checksum = "9a70f4fcd7b3b24fb194f837560168208f669ca8cb70d0c4b862944452396343" dependencies = [ "native-tls", "tokio", @@ -1825,9 +1834,9 @@ checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" [[package]] name = "tui" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7de74b91c6cb83119a2140e7c215d95d9e54db27b58a500a2cbdeec4987b0a2" +checksum = "89e8ecff008935939a4cf834c6e96e6cfb60f65f7d2e009027125f4df492a8d6" dependencies = [ "bitflags", "cassowary", @@ -1919,9 +1928,9 @@ checksum = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" [[package]] name = "vec_map" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" @@ -1947,9 +1956,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasm-bindgen" -version = "0.2.60" +version = "0.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f" +checksum = "e3c7d40d09cdbf0f4895ae58cf57d92e1e57a9dd8ed2e8390514b54a47cc5551" dependencies = [ "cfg-if", "serde", @@ -1959,24 +1968,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.60" +version = "0.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd" +checksum = "c3972e137ebf830900db522d6c8fd74d1900dcfc733462e9a12e942b00b4ac94" dependencies = [ "bumpalo", "lazy_static", "log", "proc-macro2 1.0.12", - "quote 1.0.3", - "syn 1.0.17", + "quote 1.0.4", + "syn 1.0.19", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7add542ea1ac7fdaa9dc25e031a6af33b7d63376292bd24140c637d00d1c312a" +checksum = "8a369c5e1dfb7569e14d62af4da642a3cbc2f9a3652fe586e26ac22222aa4b04" dependencies = [ "cfg-if", "js-sys", @@ -1986,38 +1995,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.60" +version = "0.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4" +checksum = "2cd85aa2c579e8892442954685f0d801f9129de24fa2136b2c6a539c76b65776" dependencies = [ - "quote 1.0.3", + "quote 1.0.4", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.60" +version = "0.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931" +checksum = "8eb197bd3a47553334907ffd2f16507b4f4f01bbec3ac921a7719e0decdfe72a" dependencies = [ "proc-macro2 1.0.12", - "quote 1.0.3", - "syn 1.0.17", + "quote 1.0.4", + "syn 1.0.19", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.60" +version = "0.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639" +checksum = "a91c2916119c17a8e316507afaaa2dd94b47646048014bbdf6bef098c1bb58ad" [[package]] name = "web-sys" -version = "0.3.37" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d6f51648d8c56c366144378a33290049eafdd784071077f6fe37dae64c1c4cb" +checksum = "8bc359e5dd3b46cb9687a051d50a2fdd228e4ba7cf6fcf861a5365c3d671a642" dependencies = [ "js-sys", "wasm-bindgen", @@ -2069,9 +2078,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa515c5163a99cc82bab70fd3bfdd36d827be85de63737b40fcef2ce084a436e" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ "winapi 0.3.8", ] From 19029cf4d5379c8b157e567090082bf32d061038 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 12 May 2020 06:45:20 +0000 Subject: [PATCH 071/311] Bump clap from 2.33.0 to 2.33.1 Bumps [clap](https://github.com/clap-rs/clap) from 2.33.0 to 2.33.1. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/v2.33.1/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v2.33.0...v2.33.1) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a8b785c3..4fe60db4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -186,9 +186,9 @@ dependencies = [ [[package]] name = "clap" -version = "2.33.0" +version = "2.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" +checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" dependencies = [ "ansi_term", "atty", diff --git a/Cargo.toml b/Cargo.toml index 2586ea24..a0fed34a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" dirs = "2.0.2" -clap = "2.33.0" +clap = "2.33.1" unicode-width = "0.1.7" backtrace = "0.3.46" clipboard = "0.5.0" From 6ae6a1c75171fdb086cbac74466d350edce5989c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 13 May 2020 06:51:47 +0000 Subject: [PATCH 072/311] Bump anyhow from 1.0.28 to 1.0.29 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.28 to 1.0.29. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.28...1.0.29) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4fe60db4..cac9b658 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,9 +20,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff" +checksum = "dc98824304f5513bb8f862f9e5985219003de4d730689e59d8f28818283a6fe4" [[package]] name = "arc-swap" diff --git a/Cargo.toml b/Cargo.toml index a0fed34a..5e094fba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ crossterm = "0.17" tokio = { version = "0.2", features = ["full"] } proc-macro2 = "1.0.12" rand = "0.7.3" -anyhow = "1.0.28" +anyhow = "1.0.29" [[bin]] bench = false From c3ad31159624289b75d29fc0cf5930923dac2aae Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 13 May 2020 06:52:07 +0000 Subject: [PATCH 073/311] Bump backtrace from 0.3.46 to 0.3.47 Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.46 to 0.3.47. - [Release notes](https://github.com/rust-lang/backtrace-rs/releases) - [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.46...0.3.47) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 38 +++++++++++++++++++++++++------------- Cargo.toml | 2 +- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4fe60db4..1b3e78e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,14 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "addr2line" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456d75cbb82da1ad150c8a9d97285ffcd21c9931dcb11e995903e7d75141b38b" +dependencies = [ + "gimli", +] + [[package]] name = "aho-corasick" version = "0.7.10" @@ -67,26 +76,17 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.46" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e692897359247cc6bb902933361652380af0f1b7651ae5c5013407f30e109e" +checksum = "a5393cb2f40a6fae0014c9af00018e95846f3b241b331a6b7733c326d3e58108" dependencies = [ - "backtrace-sys", + "addr2line", "cfg-if", "libc", + "object", "rustc-demangle", ] -[[package]] -name = "backtrace-sys" -version = "0.1.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fbebbe1c9d1f383a9cc7e8ccdb471b91c8d024ee9c2ca5b5346121fe8b4399" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "base64" version = "0.10.1" @@ -586,6 +586,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "gimli" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c" + [[package]] name = "h2" version = "0.2.5" @@ -1000,6 +1006,12 @@ dependencies = [ "objc", ] +[[package]] +name = "object" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cbca9424c482ee628fa549d9c812e2cd22f1180b9222c9200fdfa6eb31aecb2" + [[package]] name = "once_cell" version = "1.3.1" diff --git a/Cargo.toml b/Cargo.toml index a0fed34a..2226c8a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ serde_yaml = "0.8" dirs = "2.0.2" clap = "2.33.1" unicode-width = "0.1.7" -backtrace = "0.3.46" +backtrace = "0.3.47" clipboard = "0.5.0" crossterm = "0.17" tokio = { version = "0.2", features = ["full"] } From f50fe2b9741b4ff49b3aa9101267ad35e641f70f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 13 May 2020 06:52:31 +0000 Subject: [PATCH 074/311] Bump tui from 0.9.3 to 0.9.4 Bumps [tui](https://github.com/fdehau/tui-rs) from 0.9.3 to 0.9.4. - [Release notes](https://github.com/fdehau/tui-rs/releases) - [Changelog](https://github.com/fdehau/tui-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/fdehau/tui-rs/compare/v0.9.3...v0.9.4) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4fe60db4..bd1f007c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1834,9 +1834,9 @@ checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" [[package]] name = "tui" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e8ecff008935939a4cf834c6e96e6cfb60f65f7d2e009027125f4df492a8d6" +checksum = "c25eac88406f384894aa6db56ac0378c767254ee5829824ce5b0fc8fd24d5778" dependencies = [ "bitflags", "cassowary", diff --git a/Cargo.toml b/Cargo.toml index a0fed34a..2993f1c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ license = "MIT OR Apache-2.0" [dependencies] rspotify = { git = "https://github.com/Rigellute/rspotify" } -tui = { version = "0.9.1", features = ["crossterm"], default-features = false } +tui = { version = "0.9.4", features = ["crossterm"], default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" From b600bbf514fbf094bef224504b922fef18074a37 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 14 May 2020 06:41:33 +0000 Subject: [PATCH 075/311] Bump backtrace from 0.3.47 to 0.3.48 Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.47 to 0.3.48. - [Release notes](https://github.com/rust-lang/backtrace-rs/releases) - [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.47...0.3.48) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b159d1d2..366ad1e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,9 +76,9 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.47" +version = "0.3.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5393cb2f40a6fae0014c9af00018e95846f3b241b331a6b7733c326d3e58108" +checksum = "0df2f85c8a2abbe3b7d7e748052fdd9b76a0458fdeb16ad4223f5eca78c7c130" dependencies = [ "addr2line", "cfg-if", diff --git a/Cargo.toml b/Cargo.toml index 67edd789..ae01c84f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ serde_yaml = "0.8" dirs = "2.0.2" clap = "2.33.1" unicode-width = "0.1.7" -backtrace = "0.3.47" +backtrace = "0.3.48" clipboard = "0.5.0" crossterm = "0.17" tokio = { version = "0.2", features = ["full"] } From 70fdb6a460cdf8805fb886a5b72f1d014d9adb01 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 15 May 2020 06:45:57 +0000 Subject: [PATCH 076/311] Bump anyhow from 1.0.29 to 1.0.31 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.29 to 1.0.31. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.29...1.0.31) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b159d1d2..2ae86de6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,9 +29,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.29" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc98824304f5513bb8f862f9e5985219003de4d730689e59d8f28818283a6fe4" +checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f" [[package]] name = "arc-swap" diff --git a/Cargo.toml b/Cargo.toml index 67edd789..deb9b0f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ crossterm = "0.17" tokio = { version = "0.2", features = ["full"] } proc-macro2 = "1.0.12" rand = "0.7.3" -anyhow = "1.0.29" +anyhow = "1.0.31" [[bin]] bench = false From 10478c9ea97de3318428142afcacaeaac5114fe5 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 15 May 2020 09:27:47 +0000 Subject: [PATCH 077/311] Bump tokio from 0.2.20 to 0.2.21 Bumps [tokio](https://github.com/tokio-rs/tokio) from 0.2.20 to 0.2.21. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-0.2.20...tokio-0.2.21) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c54420e..6bafe908 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1762,9 +1762,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05c1d570eb1a36f0345a5ce9c6c6e665b70b73d11236912c0b477616aeec47b1" +checksum = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58" dependencies = [ "bytes 0.5.4", "fnv", From f3fcaaf5812705578311799f65c88c0e2ade6a13 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 18 May 2020 10:25:36 +0100 Subject: [PATCH 078/311] Remove proc-macro2 --- Cargo.lock | 1 - Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4fe60db4..b32659ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1620,7 +1620,6 @@ dependencies = [ "clipboard", "crossterm", "dirs", - "proc-macro2 1.0.12", "rand 0.7.3", "rspotify", "serde", diff --git a/Cargo.toml b/Cargo.toml index a0fed34a..e7ff289c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,6 @@ backtrace = "0.3.46" clipboard = "0.5.0" crossterm = "0.17" tokio = { version = "0.2", features = ["full"] } -proc-macro2 = "1.0.12" rand = "0.7.3" anyhow = "1.0.28" From 8abbeb7381f103e1037670a8b51a45513ba46d57 Mon Sep 17 00:00:00 2001 From: Oliver Daniel Date: Thu, 21 May 2020 15:44:19 -0400 Subject: [PATCH 079/311] Change currently_playing indicator Since we're already using the Geometric block for the heart, it just made sense to use something a little more elegant than the current indicator. :) Let me know if this causes any issues. --- src/ui/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 8489a41c..ea59abd3 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -329,7 +329,7 @@ where let mut song_name = "".to_string(); let id = item.clone().id.unwrap_or_else(|| "".to_string()); if currently_playing_id == id { - song_name += "|> " + song_name += "β–Ά " } if app.liked_song_ids_set.contains(&id) { song_name += "β™₯ "; @@ -1014,7 +1014,7 @@ where let mut name = String::new(); if let Some(context) = &app.current_playback_context { if context.item.as_ref().and_then(|item| item.id.as_ref()) == top_track.id.as_ref() { - name.push_str("|> "); + name.push_str("β–Ά "); } }; name.push_str(&top_track.name); @@ -1464,7 +1464,7 @@ fn draw_table( track_playing_index.and_then(|idx| idx.checked_sub(offset)) { if i == track_playing_offset_index { - formatted_row[title_idx] = format!("|> {}", &formatted_row[title_idx]); + formatted_row[title_idx] = format!("β–Ά {}", &formatted_row[title_idx]); style = Style::default() .fg(app.user_config.theme.active) .modifier(Modifier::BOLD); From eec1d403d6f573a9acf90715071016855fa9cb08 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 22 May 2020 06:49:17 +0000 Subject: [PATCH 080/311] Bump tui from 0.9.4 to 0.9.5 Bumps [tui](https://github.com/fdehau/tui-rs) from 0.9.4 to 0.9.5. - [Release notes](https://github.com/fdehau/tui-rs/releases) - [Changelog](https://github.com/fdehau/tui-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/fdehau/tui-rs/compare/v0.9.4...v0.9.5) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8074f5b9..c5af7dfb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1845,9 +1845,9 @@ checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" [[package]] name = "tui" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c25eac88406f384894aa6db56ac0378c767254ee5829824ce5b0fc8fd24d5778" +checksum = "9533d39bef0ae8f510e8a99d78702e68d1bbf0b98a78ec9740509d287010ae1e" dependencies = [ "bitflags", "cassowary", diff --git a/Cargo.toml b/Cargo.toml index c2dc16a6..f5131753 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ license = "MIT OR Apache-2.0" [dependencies] rspotify = { git = "https://github.com/Rigellute/rspotify" } -tui = { version = "0.9.4", features = ["crossterm"], default-features = false } +tui = { version = "0.9.5", features = ["crossterm"], default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" From c3c2d987cbc5dc14d67205cc901e23a9577d5a03 Mon Sep 17 00:00:00 2001 From: Drew Fisher Date: Sat, 23 May 2020 23:03:52 -0400 Subject: [PATCH 081/311] Add key to jump to context if available --- src/handlers/mod.rs | 18 ++++++++++++++++++ src/ui/help.rs | 1 + src/user_config.rs | 2 ++ 3 files changed, 21 insertions(+) diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 69116923..159bd1a1 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -39,6 +39,9 @@ pub fn handle_app(key: Key, app: &mut App) { _ if key == app.user_config.keys.jump_to_artist_album => { handle_jump_to_artist_album(app); } + _ if key == app.user_config.keys.jump_to_context => { + handle_jump_to_context(app); + } _ if key == app.user_config.keys.manage_devices => { app.dispatch(IoEvent::GetDevices); } @@ -187,6 +190,21 @@ fn handle_escape(app: &mut App) { } } +fn handle_jump_to_context(app: &mut App) { + if let Some(current_playback_context) = &app.current_playback_context { + if let Some(play_context) = current_playback_context.context.clone() { + match play_context._type { + rspotify::senum::Type::Album => handle_jump_to_album(app), + rspotify::senum::Type::Artist => handle_jump_to_artist_album(app), + rspotify::senum::Type::Playlist => { + app.dispatch(IoEvent::GetPlaylistTracks(play_context.uri, 0)) + } + _ => {} + } + } + } +} + fn handle_jump_to_album(app: &mut App) { if let Some(current_playback_context) = &app.current_playback_context { if let Some(full_track) = current_playback_context.item.clone() { diff --git a/src/ui/help.rs b/src/ui/help.rs index eb6bf159..d9fd938a 100644 --- a/src/ui/help.rs +++ b/src/ui/help.rs @@ -6,6 +6,7 @@ pub fn get_help_docs() -> Vec> { "A", "General", ], + vec!["Jump to current play context", "o", "General"], vec!["Increase volume by 10%", "+", "General"], vec!["Decrease volume by 10%", "-", "General"], vec!["Skip to next track", "n", "General"], diff --git a/src/user_config.rs b/src/user_config.rs index 7a981fc1..2ff32925 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -168,6 +168,7 @@ pub struct KeyBindings { pub back: Key, pub jump_to_album: Key, pub jump_to_artist_album: Key, + pub jump_to_context: Key, pub manage_devices: Key, pub decrease_volume: Key, pub increase_volume: Key, @@ -224,6 +225,7 @@ impl UserConfig { back: Key::Char('q'), jump_to_album: Key::Char('a'), jump_to_artist_album: Key::Char('A'), + jump_to_context: Key::Char('o'), manage_devices: Key::Char('d'), decrease_volume: Key::Char('-'), increase_volume: Key::Char('+'), From e450482491f7a60ff3af4825d95f3e1474a9005a Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Wed, 27 May 2020 09:58:26 +0100 Subject: [PATCH 082/311] Use upstream rspotify The Spotify API has fixed the audio analysis endpoint on their end, so my fork of rspotify is no longer needed. Closes #437 --- Cargo.lock | 3 ++- Cargo.toml | 2 +- src/ui/audio_analysis.rs | 19 ++++++++----------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c5af7dfb..779fe2dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1431,7 +1431,8 @@ dependencies = [ [[package]] name = "rspotify" version = "0.9.0" -source = "git+https://github.com/Rigellute/rspotify#8d15009ea8e457ef5827334f22fef7e55b34c6b3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29b79da3557219b1ea44609ae2bdddbe8f0cc71188ab863cc47d98e8a1d6eb5" dependencies = [ "base64 0.10.1", "chrono", diff --git a/Cargo.toml b/Cargo.toml index f5131753..3cc89964 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ license = "MIT OR Apache-2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rspotify = { git = "https://github.com/Rigellute/rspotify" } +rspotify = "0.9.0" tui = { version = "0.9.5", features = ["crossterm"], default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/src/ui/audio_analysis.rs b/src/ui/audio_analysis.rs index ff4a8225..609986f1 100644 --- a/src/ui/audio_analysis.rs +++ b/src/ui/audio_analysis.rs @@ -69,30 +69,28 @@ where let segment = analysis .segments .iter() - .find(|segment| segment.start.unwrap_or(0.0) >= progress_seconds); + .find(|segment| segment.start >= progress_seconds); let section = analysis .sections .iter() - .find(|section| section.start.unwrap_or(0.0) >= progress_seconds); + .find(|section| section.start >= progress_seconds); if let (Some(segment), Some(section)) = (segment, section) { let texts = [ Text::raw(format!( "Tempo: {} (confidence {:.0}%)\n", - section.tempo.unwrap_or(0.0), - section.tempo_confidence.unwrap_or(0.0) * 100.0 + section.tempo, + section.tempo_confidence * 100.0 )), Text::raw(format!( "Key: {} (confidence {:.0}%)\n", - PITCHES - .get(section.key.unwrap_or(0) as usize) - .unwrap_or(&PITCHES[0]), - section.key_confidence.unwrap_or(0.0) * 100.0 + PITCHES.get(section.key as usize).unwrap_or(&PITCHES[0]), + section.key_confidence * 100.0 )), Text::raw(format!( "Time Signature: {}/4 (confidence {:.0}%)\n", - section.time_signature.unwrap_or(0), - section.time_signature_confidence.unwrap_or(0.0) * 100.0 + section.time_signature, + section.time_signature_confidence * 100.0 )), ]; let p = Paragraph::new(texts.iter()) @@ -103,7 +101,6 @@ where let data: Vec<(&str, u64)> = segment .clone() .pitches - .unwrap_or_default() .iter() .enumerate() .map(|(index, pitch)| { From f723761efc8e1ad37caaa07e679706cc9bcfa727 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Wed, 27 May 2020 10:34:31 +0100 Subject: [PATCH 083/311] Fix .all-contributorsr --- .all-contributorsrc | 212 +++++++++++--------------------------------- 1 file changed, 52 insertions(+), 160 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index c4c350fd..054f79c1 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1,7 +1,5 @@ { - "files": [ - "README.md" - ], + "files": ["README.md"], "imageSize": 100, "commit": false, "contributors": [ @@ -27,463 +25,357 @@ "name": "Mickael Marques", "avatar_url": "https://avatars3.githubusercontent.com/u/6864231?v=4", "profile": "https://github.com/mikepombal", - "contributions": [ - "financial" - ] + "contributions": ["financial"] }, { "login": "HakierGrzonzo", "name": "Grzegorz Koperwas", "avatar_url": "https://avatars0.githubusercontent.com/u/36668331?v=4", "profile": "https://github.com/HakierGrzonzo", - "contributions": [ - "doc" - ] + "contributions": ["doc"] }, { "login": "amgassert", "name": "Austin Gassert", "avatar_url": "https://avatars2.githubusercontent.com/u/22896005?v=4", "profile": "https://github.com/amgassert", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "calenrobinette", "name": "Calen Robinette", "avatar_url": "https://avatars2.githubusercontent.com/u/30757528?v=4", "profile": "https://robinette.dev", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "MCOfficer", "name": "M*C*O", "avatar_url": "https://avatars0.githubusercontent.com/u/22377202?v=4", "profile": "https://mcofficer.me", - "contributions": [ - "infra" - ] + "contributions": ["infra"] }, { "login": "eminence", "name": "Andrew Chin", "avatar_url": "https://avatars0.githubusercontent.com/u/402454?v=4", "profile": "https://github.com/eminence", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "Monkeyanator", "name": "Sam Naser", "avatar_url": "https://avatars0.githubusercontent.com/u/4377348?v=4", "profile": "https://www.samnaser.com/", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "radogost", "name": "Micha", "avatar_url": "https://avatars0.githubusercontent.com/u/15713820?v=4", "profile": "https://github.com/radogost", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "neriglissar", "name": "neriglissar", "avatar_url": "https://avatars2.githubusercontent.com/u/53038761?v=4", "profile": "https://github.com/neriglissar", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "TimonPost", "name": "Timon", "avatar_url": "https://avatars3.githubusercontent.com/u/19969910?v=4", "profile": "https://github.com/TimonPost", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "echoSayonara", "name": "echoSayonara", "avatar_url": "https://avatars2.githubusercontent.com/u/54503126?v=4", "profile": "https://github.com/echoSayonara", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "D-Nice", "name": "D-Nice", "avatar_url": "https://avatars1.githubusercontent.com/u/2888248?v=4", "profile": "https://github.com/D-Nice", - "contributions": [ - "doc", - "infra" - ] + "contributions": ["doc", "infra"] }, { "login": "gpawlik", "name": "Grzegorz Pawlik", "avatar_url": "https://avatars3.githubusercontent.com/u/6296883?v=4", "profile": "http://gpawlik.com", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "LennyPenny", "name": "Lennart Bernhardt", "avatar_url": "https://avatars1.githubusercontent.com/u/4027243?v=4", "profile": "http://lenny.ninja", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "BlackYoup", "name": "Arnaud Lefebvre", "avatar_url": "https://avatars3.githubusercontent.com/u/6098160?v=4", "profile": "https://github.com/BlackYoup", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "tem1029", "name": "tem1029", "avatar_url": "https://avatars3.githubusercontent.com/u/57712713?v=4", "profile": "https://github.com/tem1029", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "Peterkmoss", "name": "Peter K. Moss", "avatar_url": "https://avatars2.githubusercontent.com/u/12544579?v=4", "profile": "http://peter.moss.dk", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "RadicalZephyr", "name": "Geoff Shannon", "avatar_url": "https://avatars1.githubusercontent.com/u/113102?v=4", "profile": "http://www.zephyrizing.net/", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "zacklukem", "name": "Zachary Mayhew", "avatar_url": "https://avatars0.githubusercontent.com/u/8787486?v=4", "profile": "http://zacklukem.info", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "jfaltis", "name": "jfaltis", "avatar_url": "https://avatars2.githubusercontent.com/u/45465572?v=4", "profile": "http://jfaltis.de", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "Bios-Marcel", "name": "Marcel Schramm", "avatar_url": "https://avatars3.githubusercontent.com/u/19377618?v=4", "profile": "https://marcelschr.me", - "contributions": [ - "doc" - ] + "contributions": ["doc"] }, { "login": "fangyi-zhou", "name": "Fangyi Zhou", "avatar_url": "https://avatars3.githubusercontent.com/u/7815439?v=4", "profile": "https://github.com/fangyi-zhou", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "synth-ruiner", "name": "Max", "avatar_url": "https://avatars1.githubusercontent.com/u/8642013?v=4", "profile": "https://github.com/synth-ruiner", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "svenvNL", "name": "Sven van der Vlist", "avatar_url": "https://avatars1.githubusercontent.com/u/13982006?v=4", "profile": "https://github.com/svenvNL", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "jacobchrismarsh", "name": "jacobchrismarsh", "avatar_url": "https://avatars2.githubusercontent.com/u/15932179?v=4", "profile": "https://github.com/jacobchrismarsh", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "TheWalkingLeek", "name": "Nils Rauch", "avatar_url": "https://avatars2.githubusercontent.com/u/36076343?v=4", "profile": "https://github.com/TheWalkingLeek", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "sputnick1124", "name": "Nick Stockton", "avatar_url": "https://avatars1.githubusercontent.com/u/8843309?v=4", "profile": "https://github.com/sputnick1124", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "stuarth", "name": "Stuart Hinson", "avatar_url": "https://avatars3.githubusercontent.com/u/7055?v=4", "profile": "http://stuarth.github.io", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "samcal", "name": "Sam Calvert", "avatar_url": "https://avatars3.githubusercontent.com/u/2117940?v=4", "profile": "https://github.com/samcal", - "contributions": [ - "code", - "doc" - ] + "contributions": ["code", "doc"] }, { "login": "jwijenbergh", "name": "Jeroen Wijenbergh", "avatar_url": "https://avatars0.githubusercontent.com/u/46386452?v=4", "profile": "https://github.com/jwijenbergh", - "contributions": [ - "doc" - ] + "contributions": ["doc"] }, { "login": "KimberleyCook", "name": "Kimberley Cook", "avatar_url": "https://avatars3.githubusercontent.com/u/2683270?v=4", "profile": "https://twitter.com/KimberleyCook91", - "contributions": [ - "doc" - ] + "contributions": ["doc"] }, { "login": "baxtea", "name": "Audrey Baxter", "avatar_url": "https://avatars0.githubusercontent.com/u/22502477?v=4", "profile": "https://github.com/baxtea", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "nkoehring", "name": "Norman", "avatar_url": "https://avatars2.githubusercontent.com/u/246402?v=4", "profile": "https://koehr.in", - "contributions": [ - "doc" - ] + "contributions": ["doc"] }, { "login": "blackwolf12333", "name": "Peter Maatman", "avatar_url": "https://avatars0.githubusercontent.com/u/1572975?v=4", "profile": "https://github.com/blackwolf12333", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "AlexandreSi", "name": "AlexandreS", "avatar_url": "https://avatars1.githubusercontent.com/u/32449369?v=4", "profile": "https://github.com/AlexandreSi", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "fiinnnn", "name": "Finn Vos", "avatar_url": "https://avatars2.githubusercontent.com/u/5011796?v=4", "profile": "https://github.com/fiinnnn", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "hurricanehrndz", "name": "Carlos Hernandez", "avatar_url": "https://avatars0.githubusercontent.com/u/5804237?v=4", "profile": "https://github.com/hurricanehrndz", - "contributions": [ - "platform" - ] + "contributions": ["platform"] }, { "login": "pedrohva", "name": "Pedro Alves", "avatar_url": "https://avatars3.githubusercontent.com/u/33297928?v=4", "profile": "https://github.com/pedrohva", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "jtagcat", "name": "jtagcat", "avatar_url": "https://avatars1.githubusercontent.com/u/38327267?v=4", "profile": "https://gitlab.com/jtagcat/", - "contributions": [ - "doc" - ] + "contributions": ["doc"] }, { "login": "BKitor", "name": "Benjamin Kitor", "avatar_url": "https://avatars0.githubusercontent.com/u/16880850?v=4", "profile": "https://github.com/BKitor", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "littleli", "name": "AleΕ‘ Najmann", "avatar_url": "https://avatars0.githubusercontent.com/u/544082?v=4", "profile": "https://ales.rocks", - "contributions": [ - "doc", - "platform" - ] + "contributions": ["doc", "platform"] }, { "login": "jeremystucki", "name": "Jeremy Stucki", "avatar_url": "https://avatars3.githubusercontent.com/u/7629727?v=4", "profile": "https://github.com/jeremystucki", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "pt2121", "name": "(´⌣`ΚƒΖͺ)", "avatar_url": "https://avatars0.githubusercontent.com/u/616399?v=4", "profile": "http://pt2121.github.io", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "tim77", "name": "Artem Polishchuk", "avatar_url": "https://avatars0.githubusercontent.com/u/5614476?v=4", "profile": "https://github.com/tim77", - "contributions": [ - "platform" - ] + "contributions": ["platform"] }, { "login": "slumber", "name": "Chris Sosnin", "avatar_url": "https://avatars2.githubusercontent.com/u/48099298?v=4", "profile": "https://github.com/slumber", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "bwbuhse", "name": "Ben Buhse", "avatar_url": "https://avatars1.githubusercontent.com/u/21225303?v=4", "profile": "http://www.benbuhse.com", - "contributions": [ - "doc" - ] + "contributions": ["doc"] }, { "login": "ilnaes", "name": "Sean Li", "avatar_url": "https://avatars1.githubusercontent.com/u/20805499?v=4", "profile": "https://github.com/ilnaes", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "TimotheeGerber", "name": "TimotheeGerber", "avatar_url": "https://avatars3.githubusercontent.com/u/37541513?v=4", "profile": "https://github.com/TimotheeGerber", - "contributions": [ - "code", - "doc" - ] + "contributions": ["code", "doc"] }, { "login": "fratajczak", "name": "Ferdinand Ratajczak", "avatar_url": "https://avatars2.githubusercontent.com/u/33835579?v=4", "profile": "https://github.com/fratajczak", - "contributions": [ - "code" - ] + "contributions": ["code"] }, { "login": "sheelc", "name": "Sheel Choksi", "avatar_url": "https://avatars0.githubusercontent.com/u/1355710?v=4", "profile": "https://github.com/sheelc", - "contributions": [ - "code" - ], + "contributions": ["code"] }, { "login": "mhellwig", "name": "Michael Hellwig", "avatar_url": "https://avatars1.githubusercontent.com/u/414112?v=4", "profile": "http://fnanp.in-ulm.de/microblog/", - "contributions": [ - "doc" - ] + "contributions": ["doc"] } ], "contributorsPerLine": 7, From 772680a0b4c8445b7a5d541c83e612cab51e6d36 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 27 May 2020 09:34:58 +0000 Subject: [PATCH 084/311] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e969e123..b8c99a38 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-51-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-53-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -350,6 +350,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Ferdinand Ratajczak

πŸ’»
Sheel Choksi

πŸ’»
Michael Hellwig

πŸ“– +
Oliver Daniel

πŸ’» From 5f783c239abc02a02fa2639709a13295177bb325 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 27 May 2020 09:34:59 +0000 Subject: [PATCH 085/311] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 221 +++++++++++++++++++++++++++++++++----------- 1 file changed, 169 insertions(+), 52 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 054f79c1..2c54e86d 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1,5 +1,7 @@ { - "files": ["README.md"], + "files": [ + "README.md" + ], "imageSize": 100, "commit": false, "contributors": [ @@ -25,357 +27,472 @@ "name": "Mickael Marques", "avatar_url": "https://avatars3.githubusercontent.com/u/6864231?v=4", "profile": "https://github.com/mikepombal", - "contributions": ["financial"] + "contributions": [ + "financial" + ] }, { "login": "HakierGrzonzo", "name": "Grzegorz Koperwas", "avatar_url": "https://avatars0.githubusercontent.com/u/36668331?v=4", "profile": "https://github.com/HakierGrzonzo", - "contributions": ["doc"] + "contributions": [ + "doc" + ] }, { "login": "amgassert", "name": "Austin Gassert", "avatar_url": "https://avatars2.githubusercontent.com/u/22896005?v=4", "profile": "https://github.com/amgassert", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "calenrobinette", "name": "Calen Robinette", "avatar_url": "https://avatars2.githubusercontent.com/u/30757528?v=4", "profile": "https://robinette.dev", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "MCOfficer", "name": "M*C*O", "avatar_url": "https://avatars0.githubusercontent.com/u/22377202?v=4", "profile": "https://mcofficer.me", - "contributions": ["infra"] + "contributions": [ + "infra" + ] }, { "login": "eminence", "name": "Andrew Chin", "avatar_url": "https://avatars0.githubusercontent.com/u/402454?v=4", "profile": "https://github.com/eminence", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "Monkeyanator", "name": "Sam Naser", "avatar_url": "https://avatars0.githubusercontent.com/u/4377348?v=4", "profile": "https://www.samnaser.com/", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "radogost", "name": "Micha", "avatar_url": "https://avatars0.githubusercontent.com/u/15713820?v=4", "profile": "https://github.com/radogost", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "neriglissar", "name": "neriglissar", "avatar_url": "https://avatars2.githubusercontent.com/u/53038761?v=4", "profile": "https://github.com/neriglissar", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "TimonPost", "name": "Timon", "avatar_url": "https://avatars3.githubusercontent.com/u/19969910?v=4", "profile": "https://github.com/TimonPost", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "echoSayonara", "name": "echoSayonara", "avatar_url": "https://avatars2.githubusercontent.com/u/54503126?v=4", "profile": "https://github.com/echoSayonara", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "D-Nice", "name": "D-Nice", "avatar_url": "https://avatars1.githubusercontent.com/u/2888248?v=4", "profile": "https://github.com/D-Nice", - "contributions": ["doc", "infra"] + "contributions": [ + "doc", + "infra" + ] }, { "login": "gpawlik", "name": "Grzegorz Pawlik", "avatar_url": "https://avatars3.githubusercontent.com/u/6296883?v=4", "profile": "http://gpawlik.com", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "LennyPenny", "name": "Lennart Bernhardt", "avatar_url": "https://avatars1.githubusercontent.com/u/4027243?v=4", "profile": "http://lenny.ninja", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "BlackYoup", "name": "Arnaud Lefebvre", "avatar_url": "https://avatars3.githubusercontent.com/u/6098160?v=4", "profile": "https://github.com/BlackYoup", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "tem1029", "name": "tem1029", "avatar_url": "https://avatars3.githubusercontent.com/u/57712713?v=4", "profile": "https://github.com/tem1029", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "Peterkmoss", "name": "Peter K. Moss", "avatar_url": "https://avatars2.githubusercontent.com/u/12544579?v=4", "profile": "http://peter.moss.dk", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "RadicalZephyr", "name": "Geoff Shannon", "avatar_url": "https://avatars1.githubusercontent.com/u/113102?v=4", "profile": "http://www.zephyrizing.net/", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "zacklukem", "name": "Zachary Mayhew", "avatar_url": "https://avatars0.githubusercontent.com/u/8787486?v=4", "profile": "http://zacklukem.info", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "jfaltis", "name": "jfaltis", "avatar_url": "https://avatars2.githubusercontent.com/u/45465572?v=4", "profile": "http://jfaltis.de", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "Bios-Marcel", "name": "Marcel Schramm", "avatar_url": "https://avatars3.githubusercontent.com/u/19377618?v=4", "profile": "https://marcelschr.me", - "contributions": ["doc"] + "contributions": [ + "doc" + ] }, { "login": "fangyi-zhou", "name": "Fangyi Zhou", "avatar_url": "https://avatars3.githubusercontent.com/u/7815439?v=4", "profile": "https://github.com/fangyi-zhou", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "synth-ruiner", "name": "Max", "avatar_url": "https://avatars1.githubusercontent.com/u/8642013?v=4", "profile": "https://github.com/synth-ruiner", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "svenvNL", "name": "Sven van der Vlist", "avatar_url": "https://avatars1.githubusercontent.com/u/13982006?v=4", "profile": "https://github.com/svenvNL", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "jacobchrismarsh", "name": "jacobchrismarsh", "avatar_url": "https://avatars2.githubusercontent.com/u/15932179?v=4", "profile": "https://github.com/jacobchrismarsh", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "TheWalkingLeek", "name": "Nils Rauch", "avatar_url": "https://avatars2.githubusercontent.com/u/36076343?v=4", "profile": "https://github.com/TheWalkingLeek", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "sputnick1124", "name": "Nick Stockton", "avatar_url": "https://avatars1.githubusercontent.com/u/8843309?v=4", "profile": "https://github.com/sputnick1124", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "stuarth", "name": "Stuart Hinson", "avatar_url": "https://avatars3.githubusercontent.com/u/7055?v=4", "profile": "http://stuarth.github.io", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "samcal", "name": "Sam Calvert", "avatar_url": "https://avatars3.githubusercontent.com/u/2117940?v=4", "profile": "https://github.com/samcal", - "contributions": ["code", "doc"] + "contributions": [ + "code", + "doc" + ] }, { "login": "jwijenbergh", "name": "Jeroen Wijenbergh", "avatar_url": "https://avatars0.githubusercontent.com/u/46386452?v=4", "profile": "https://github.com/jwijenbergh", - "contributions": ["doc"] + "contributions": [ + "doc" + ] }, { "login": "KimberleyCook", "name": "Kimberley Cook", "avatar_url": "https://avatars3.githubusercontent.com/u/2683270?v=4", "profile": "https://twitter.com/KimberleyCook91", - "contributions": ["doc"] + "contributions": [ + "doc" + ] }, { "login": "baxtea", "name": "Audrey Baxter", "avatar_url": "https://avatars0.githubusercontent.com/u/22502477?v=4", "profile": "https://github.com/baxtea", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "nkoehring", "name": "Norman", "avatar_url": "https://avatars2.githubusercontent.com/u/246402?v=4", "profile": "https://koehr.in", - "contributions": ["doc"] + "contributions": [ + "doc" + ] }, { "login": "blackwolf12333", "name": "Peter Maatman", "avatar_url": "https://avatars0.githubusercontent.com/u/1572975?v=4", "profile": "https://github.com/blackwolf12333", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "AlexandreSi", "name": "AlexandreS", "avatar_url": "https://avatars1.githubusercontent.com/u/32449369?v=4", "profile": "https://github.com/AlexandreSi", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "fiinnnn", "name": "Finn Vos", "avatar_url": "https://avatars2.githubusercontent.com/u/5011796?v=4", "profile": "https://github.com/fiinnnn", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "hurricanehrndz", "name": "Carlos Hernandez", "avatar_url": "https://avatars0.githubusercontent.com/u/5804237?v=4", "profile": "https://github.com/hurricanehrndz", - "contributions": ["platform"] + "contributions": [ + "platform" + ] }, { "login": "pedrohva", "name": "Pedro Alves", "avatar_url": "https://avatars3.githubusercontent.com/u/33297928?v=4", "profile": "https://github.com/pedrohva", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "jtagcat", "name": "jtagcat", "avatar_url": "https://avatars1.githubusercontent.com/u/38327267?v=4", "profile": "https://gitlab.com/jtagcat/", - "contributions": ["doc"] + "contributions": [ + "doc" + ] }, { "login": "BKitor", "name": "Benjamin Kitor", "avatar_url": "https://avatars0.githubusercontent.com/u/16880850?v=4", "profile": "https://github.com/BKitor", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "littleli", "name": "AleΕ‘ Najmann", "avatar_url": "https://avatars0.githubusercontent.com/u/544082?v=4", "profile": "https://ales.rocks", - "contributions": ["doc", "platform"] + "contributions": [ + "doc", + "platform" + ] }, { "login": "jeremystucki", "name": "Jeremy Stucki", "avatar_url": "https://avatars3.githubusercontent.com/u/7629727?v=4", "profile": "https://github.com/jeremystucki", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "pt2121", "name": "(´⌣`ΚƒΖͺ)", "avatar_url": "https://avatars0.githubusercontent.com/u/616399?v=4", "profile": "http://pt2121.github.io", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "tim77", "name": "Artem Polishchuk", "avatar_url": "https://avatars0.githubusercontent.com/u/5614476?v=4", "profile": "https://github.com/tim77", - "contributions": ["platform"] + "contributions": [ + "platform" + ] }, { "login": "slumber", "name": "Chris Sosnin", "avatar_url": "https://avatars2.githubusercontent.com/u/48099298?v=4", "profile": "https://github.com/slumber", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "bwbuhse", "name": "Ben Buhse", "avatar_url": "https://avatars1.githubusercontent.com/u/21225303?v=4", "profile": "http://www.benbuhse.com", - "contributions": ["doc"] + "contributions": [ + "doc" + ] }, { "login": "ilnaes", "name": "Sean Li", "avatar_url": "https://avatars1.githubusercontent.com/u/20805499?v=4", "profile": "https://github.com/ilnaes", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "TimotheeGerber", "name": "TimotheeGerber", "avatar_url": "https://avatars3.githubusercontent.com/u/37541513?v=4", "profile": "https://github.com/TimotheeGerber", - "contributions": ["code", "doc"] + "contributions": [ + "code", + "doc" + ] }, { "login": "fratajczak", "name": "Ferdinand Ratajczak", "avatar_url": "https://avatars2.githubusercontent.com/u/33835579?v=4", "profile": "https://github.com/fratajczak", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "sheelc", "name": "Sheel Choksi", "avatar_url": "https://avatars0.githubusercontent.com/u/1355710?v=4", "profile": "https://github.com/sheelc", - "contributions": ["code"] + "contributions": [ + "code" + ] }, { "login": "mhellwig", "name": "Michael Hellwig", "avatar_url": "https://avatars1.githubusercontent.com/u/414112?v=4", "profile": "http://fnanp.in-ulm.de/microblog/", - "contributions": ["doc"] + "contributions": [ + "doc" + ] + }, + { + "login": "oliver-daniel", + "name": "Oliver Daniel", + "avatar_url": "https://avatars2.githubusercontent.com/u/17235417?v=4", + "profile": "https://github.com/oliver-daniel", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, From 05900c81165a2e8607b842ad9a2c504e8e8c9358 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 27 May 2020 09:49:24 +0000 Subject: [PATCH 086/311] Bump crossterm from 0.17.4 to 0.17.5 Bumps [crossterm](https://github.com/crossterm-rs/crossterm) from 0.17.4 to 0.17.5. - [Release notes](https://github.com/crossterm-rs/crossterm/releases) - [Changelog](https://github.com/crossterm-rs/crossterm/blob/master/CHANGELOG.md) - [Commits](https://github.com/crossterm-rs/crossterm/compare/0.17.4...0.17.5) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 779fe2dc..a68aec7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -265,9 +265,9 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.17.4" +version = "0.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a880035bfe4707e344da9acf50cc94d003fe337f50afd94c8722c1bb4e0a933" +checksum = "9851d20b9809e561297ec3ca85d7cba3a57507fe8d01d07ba7b52469e1c89a11" dependencies = [ "bitflags", "crossterm_winapi", @@ -1580,9 +1580,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c0893246f276ba1aac4983fb8711dad108e2886fd76bf618a382ab4e30e5bec" +checksum = "8ff2db2112d6c761e12522c65f7768548bd6e8cd23d2a9dae162520626629bd6" dependencies = [ "libc", "mio", From ed41ad3c69691a696b2e3da64931a4a7d7d861e0 Mon Sep 17 00:00:00 2001 From: Drew Fisher Date: Wed, 27 May 2020 14:14:03 -0400 Subject: [PATCH 087/311] Add user keybind for context jump Signed-off-by: Drew Fisher --- src/user_config.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/user_config.rs b/src/user_config.rs index 2ff32925..439f61c5 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -144,6 +144,7 @@ pub struct KeyBindingsString { back: Option, jump_to_album: Option, jump_to_artist_album: Option, + jump_to_context: Option, manage_devices: Option, decrease_volume: Option, increase_volume: Option, @@ -293,6 +294,7 @@ impl UserConfig { to_keys!(back); to_keys!(jump_to_album); to_keys!(jump_to_artist_album); + to_keys!(jump_to_context); to_keys!(manage_devices); to_keys!(decrease_volume); to_keys!(increase_volume); From ee7bc6e3ba22107ee158e88b8acf9644b9e9d509 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 27 May 2020 21:04:18 +0000 Subject: [PATCH 088/311] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b8c99a38..a257f6c7 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-53-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-54-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -351,6 +351,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Sheel Choksi

πŸ’»
Michael Hellwig

πŸ“–
Oliver Daniel

πŸ’» +
Drew Fisher

πŸ’» From 7f9154bdf65b93238c6cfab2b46008b202de9751 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 27 May 2020 21:04:19 +0000 Subject: [PATCH 089/311] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 2c54e86d..700306df 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -493,6 +493,15 @@ "contributions": [ "code" ] + }, + { + "login": "Drewsapple", + "name": "Drew Fisher", + "avatar_url": "https://avatars2.githubusercontent.com/u/4532572?v=4", + "profile": "https://github.com/Drewsapple", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, From 0aed18d47d8518550060222d24038bed5d3064d1 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Wed, 27 May 2020 22:05:42 +0100 Subject: [PATCH 090/311] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12326034..40c414f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ - Move pagination instructions to top of help menu [#442](https://github.com/Rigellute/spotify-tui/pull/442) - Add user configuration toggle for the loading indicator [#447](https://github.com/Rigellute/spotify-tui/pull/447) - Add support for saving an album and following an artist in artist view [#445](https://github.com/Rigellute/spotify-tui/pull/445) +- Use the `β–Ά` glyph to indicate the currently playing song [#472](https://github.com/Rigellute/spotify-tui/pull/472) +- Jump to play context (if available) [#474](https://github.com/Rigellute/spotify-tui/pull/474) ## [0.19.0] - 2020-05-04 From 7a5a04c91a2aac49ee77a1b622a33b680d852ceb Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Thu, 28 May 2020 11:15:52 +0100 Subject: [PATCH 091/311] Prepare release v0.20.0 --- CHANGELOG.md | 9 ++++++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40c414f3..8fbc8771 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,18 @@ ## [Unreleased] +## [0.20.0] - 2020-05-28 + +### Fixed + - Move pagination instructions to top of help menu [#442](https://github.com/Rigellute/spotify-tui/pull/442) + +### Added + - Add user configuration toggle for the loading indicator [#447](https://github.com/Rigellute/spotify-tui/pull/447) - Add support for saving an album and following an artist in artist view [#445](https://github.com/Rigellute/spotify-tui/pull/445) - Use the `β–Ά` glyph to indicate the currently playing song [#472](https://github.com/Rigellute/spotify-tui/pull/472) -- Jump to play context (if available) [#474](https://github.com/Rigellute/spotify-tui/pull/474) +- Jump to play context (if available) - default binding is `o` [#474](https://github.com/Rigellute/spotify-tui/pull/474) ## [0.19.0] - 2020-05-04 diff --git a/Cargo.lock b/Cargo.lock index a68aec7a..f8671719 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1625,7 +1625,7 @@ dependencies = [ [[package]] name = "spotify-tui" -version = "0.19.0" +version = "0.20.0" dependencies = [ "anyhow", "backtrace", diff --git a/Cargo.toml b/Cargo.toml index 3cc89964..f17f2b97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ documentation = "https://github.com/Rigellute/spotify-tui" repository = "https://github.com/Rigellute/spotify-tui" keywords = ["spotify", "tui", "cli", "terminal"] categories = ["command-line-utilities"] -version = "0.19.0" +version = "0.20.0" authors = ["Alexander Keliris "] edition = "2018" license = "MIT OR Apache-2.0" From a7592709f576cf4480b4188e0046a8e251cfdf9e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 1 Jun 2020 07:08:08 +0000 Subject: [PATCH 092/311] Bump serde from 1.0.110 to 1.0.111 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.110 to 1.0.111. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.110...v1.0.111) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8671719..695abdf9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1525,18 +1525,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.110" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e7b308464d16b56eba9964e4972a3eee817760ab60d88c3f86e1fecb08204c" +checksum = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.110" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "818fbf6bfa9a42d3bfcaca148547aa00c7b915bec71d1757aa2d44ca68771984" +checksum = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250" dependencies = [ "proc-macro2 1.0.12", "quote 1.0.4", From 8275ce4adedd6c4f62596c69fa23c9ecfc8145b0 Mon Sep 17 00:00:00 2001 From: Macguire Rintoul <18323154+macguirerintoul@users.noreply.github.com> Date: Wed, 3 Jun 2020 18:52:41 -0700 Subject: [PATCH 093/311] add comments explaining user-configurable colours --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index a257f6c7..547635a6 100644 --- a/README.md +++ b/README.md @@ -188,18 +188,18 @@ The following is a sample config.yml file: # The theme colours can be an rgb string of the form "255, 255, 255" or a string that references the colours from your terminal theme: Reset, Black, Red, Green, Yellow, Blue, Magenta, Cyan, Gray, DarkGray, LightRed, LightGreen, LightYellow, LightBlue, LightMagenta, LightCyan, White. theme: - active: Cyan - banner: LightCyan - error_border: Red - error_text: LightRed - hint: Yellow - hovered: Magenta - inactive: Gray - playbar_background: Black - playbar_progress: LightCyan + active: Cyan # current playing song in list + banner: LightCyan # the "spotify-tui" banner on launch + error_border: Red # error dialog border + error_text: LightRed # error message text (e.g. "Spotify API reported error 404") + hint: Yellow # hint text in errors + hovered: Magenta # hovered pane border + inactive: Gray # borders of inactive panes + playbar_background: Black # background of progress bar + playbar_progress: LightCyan # filled-in part of the progress bar playbar_text: White - selected: LightCyan - text: "255, 255, 255" + selected: LightCyan # a) selected pane border, b) hovered item in list, & c) track title in player + text: "255, 255, 255" # text in panes behavior: seek_milliseconds: 5000 From a61d3eafbf30cf82e41fe710d44a46507be9b553 Mon Sep 17 00:00:00 2001 From: ncoder-1 <7622286+ncoder-1@users.noreply.github.com> Date: Wed, 3 Jun 2020 22:03:49 -0400 Subject: [PATCH 094/311] Update help.rs Fixed typo (Delete saved playlist) in help --- src/ui/help.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/help.rs b/src/ui/help.rs index f15622a7..6bdf0f53 100644 --- a/src/ui/help.rs +++ b/src/ui/help.rs @@ -103,7 +103,7 @@ pub fn get_help_docs() -> Vec> { "Search input", ], vec!["Delete saved album", "D", "Library -> Albums"], - vec!["Delete saved playist", "D", "Playlist"], + vec!["Delete saved playlist", "D", "Playlist"], vec!["Follow an artists/playlist", "w", "Search result"], vec!["Play random song in playlist", "S", "Selected Playlist"], ] From 15ef0a18070526c650539b6b9883bb748f305bd4 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Fri, 5 Jun 2020 08:45:39 +0100 Subject: [PATCH 095/311] Use playbar_text from theme in playbar This bug was reported here #484 --- src/ui/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ui/mod.rs b/src/ui/mod.rs index ea59abd3..bf8c3729 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -826,10 +826,11 @@ where let lines = [Text::styled( create_artist_string(&track_item.artists), - Style::default().fg(app.user_config.theme.text), + Style::default().fg(app.user_config.theme.playbar_text), )]; + let artist = Paragraph::new(lines.iter()) - .style(Style::default().fg(app.user_config.theme.text)) + .style(Style::default().fg(app.user_config.theme.playbar_text)) .block( Block::default().title(&track_name).title_style( Style::default() From f12a28ce3298b8ebd97661315391d563d0c2b788 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 5 Jun 2020 07:48:06 +0000 Subject: [PATCH 096/311] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a257f6c7..0015203a 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-54-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-55-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -352,6 +352,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Michael Hellwig

πŸ“–
Oliver Daniel

πŸ’»
Drew Fisher

πŸ’» +
ncoder-1

πŸ“– From c13cef9a7a8d46dc1208fa7212aaeda8ae15e67e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 5 Jun 2020 07:48:07 +0000 Subject: [PATCH 097/311] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 700306df..65331363 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -502,6 +502,15 @@ "contributions": [ "code" ] + }, + { + "login": "ncoder-1", + "name": "ncoder-1", + "avatar_url": "https://avatars0.githubusercontent.com/u/7622286?v=4", + "profile": "https://github.com/ncoder-1", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, From 5620aef6113cd9f80a941d01b900228001c9ed9c Mon Sep 17 00:00:00 2001 From: Macguire Rintoul <18323154+macguirerintoul@users.noreply.github.com> Date: Sat, 6 Jun 2020 15:57:30 -0700 Subject: [PATCH 098/311] add comment for playbar_text --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 547635a6..9db72ecf 100644 --- a/README.md +++ b/README.md @@ -197,7 +197,7 @@ theme: inactive: Gray # borders of inactive panes playbar_background: Black # background of progress bar playbar_progress: LightCyan # filled-in part of the progress bar - playbar_text: White + playbar_text: White # artist name in player pane selected: LightCyan # a) selected pane border, b) hovered item in list, & c) track title in player text: "255, 255, 255" # text in panes From 970c620f04374c7fa4c6a1c4dc3ef346411613ff Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Wed, 10 Jun 2020 12:09:23 +0100 Subject: [PATCH 099/311] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fbc8771..0c8f30a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +- Fix typo in help menu [#485](https://github.com/Rigellute/spotify-tui/pull/485) + ## [0.20.0] - 2020-05-28 ### Fixed From bbcfc4d74a6ffc30876b0c2208caa502ab986faa Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 11 Jun 2020 06:44:25 +0000 Subject: [PATCH 100/311] Bump serde_json from 1.0.53 to 1.0.55 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.53 to 1.0.55. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.53...v1.0.55) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 695abdf9..ead52daf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1545,9 +1545,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.53" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2" +checksum = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226" dependencies = [ "itoa", "ryu", From 1dd0921be43ceb101c0675e160aa65361430de57 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 11 Jun 2020 06:44:42 +0000 Subject: [PATCH 101/311] Bump serde_yaml from 0.8.12 to 0.8.13 Bumps [serde_yaml](https://github.com/dtolnay/serde-yaml) from 0.8.12 to 0.8.13. - [Release notes](https://github.com/dtolnay/serde-yaml/releases) - [Commits](https://github.com/dtolnay/serde-yaml/compare/0.8.12...0.8.13) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 695abdf9..f95997ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1568,9 +1568,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.12" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16c7a592a1ec97c9c1c68d75b6e537dcbf60c7618e038e7841e00af1d9ccf0c4" +checksum = "ae3e2dd40a7cdc18ca80db804b7f461a39bb721160a85c9a1fa30134bf3c02a5" dependencies = [ "dtoa", "linked-hash-map", From 6113ad3520357663124fa4aaaf590e2859a2e7d6 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sun, 14 Jun 2020 10:02:37 +0000 Subject: [PATCH 102/311] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d67d816e..00595561 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-55-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-56-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -353,6 +353,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Oliver Daniel

πŸ’»
Drew Fisher

πŸ’»
ncoder-1

πŸ“– +
Macguire Rintoul

πŸ“– From ad9eb82922ef893fa46f4e0297ce788753238e27 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sun, 14 Jun 2020 10:02:38 +0000 Subject: [PATCH 103/311] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 65331363..1aa84719 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -511,6 +511,15 @@ "contributions": [ "doc" ] + }, + { + "login": "macguirerintoul", + "name": "Macguire Rintoul", + "avatar_url": "https://avatars3.githubusercontent.com/u/18323154?v=4", + "profile": "http://macguire.me", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, From 34a61e319a31fb66f8d9d54bd00d95ae4e10c02e Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Sun, 14 Jun 2020 11:10:51 +0100 Subject: [PATCH 104/311] Run CI on pull requests and pushes to master --- .github/workflows/ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9faa0f0..546746a2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,7 @@ -on: [push, pull_request] +on: + pull_request: + push: + branches: master name: Continuous Integration From 7c26fd44aaa9732be5e6f256b4b841ca5bb50ed4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 16 Jun 2020 06:39:48 +0000 Subject: [PATCH 105/311] Bump backtrace from 0.3.48 to 0.3.49 Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.48 to 0.3.49. - [Release notes](https://github.com/rust-lang/backtrace-rs/releases) - [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.48...0.3.49) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 24 ++++++++++++++++++++---- Cargo.toml | 2 +- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 51c044b6..7288242e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,6 +9,12 @@ dependencies = [ "gimli", ] +[[package]] +name = "adler32" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d" + [[package]] name = "aho-corasick" version = "0.7.10" @@ -76,13 +82,14 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.48" +version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0df2f85c8a2abbe3b7d7e748052fdd9b76a0458fdeb16ad4223f5eca78c7c130" +checksum = "05100821de9e028f12ae3d189176b41ee198341eb8f369956407fea2f5cc666c" dependencies = [ "addr2line", "cfg-if", "libc", + "miniz_oxide", "object", "rustc-demangle", ] @@ -855,6 +862,15 @@ dependencies = [ "unicase", ] +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + [[package]] name = "mio" version = "0.6.22" @@ -1008,9 +1024,9 @@ dependencies = [ [[package]] name = "object" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cbca9424c482ee628fa549d9c812e2cd22f1180b9222c9200fdfa6eb31aecb2" +checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" [[package]] name = "once_cell" diff --git a/Cargo.toml b/Cargo.toml index f17f2b97..4bce9161 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ serde_yaml = "0.8" dirs = "2.0.2" clap = "2.33.1" unicode-width = "0.1.7" -backtrace = "0.3.48" +backtrace = "0.3.49" clipboard = "0.5.0" crossterm = "0.17" tokio = { version = "0.2", features = ["full"] } From 74993e319ca9fcf679127ed0cac1de81a258b4c6 Mon Sep 17 00:00:00 2001 From: RicardoHE97 Date: Sun, 21 Jun 2020 18:01:14 -0700 Subject: [PATCH 106/311] Feature: Add save album on album view Adds a new feature to add to saved albums when pressing 'w' key on album --- src/handlers/album_tracks.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/handlers/album_tracks.rs b/src/handlers/album_tracks.rs index e66774af..3703a27f 100644 --- a/src/handlers/album_tracks.rs +++ b/src/handlers/album_tracks.rs @@ -52,6 +52,7 @@ pub fn handler(key: Key, app: &mut App) { k if common_key_events::middle_event(k) => handle_middle_event(app), k if common_key_events::low_event(k) => handle_low_event(app), Key::Char('s') => handle_save_event(app), + Key::Char('w') => handle_save_album_event(app), Key::Enter => match app.album_table_context { AlbumTableContext::Full => { if let Some(selected_album) = app.selected_album_full.clone() { @@ -203,6 +204,24 @@ fn handle_save_event(app: &mut App) { } } +fn handle_save_album_event(app: &mut App) { + match app.album_table_context { + AlbumTableContext::Full => { + if let Some(selected_album) = app.selected_album_full.clone() { + let album_id = &selected_album.album.id; + app.dispatch(IoEvent::CurrentUserSavedAlbumAdd(album_id.to_string())); + }; + } + AlbumTableContext::Simplified => { + if let Some(selected_album_simplified) = app.selected_album_simplified.clone() { + if let Some(album_id) = selected_album_simplified.album.id { + app.dispatch(IoEvent::CurrentUserSavedAlbumAdd(album_id)); + }; + }; + } + } +} + #[cfg(test)] mod tests { use super::*; From b806deb694b19b03eb132a13dd7229aeddfb8e61 Mon Sep 17 00:00:00 2001 From: RicardoHE97 Date: Mon, 22 Jun 2020 11:09:56 -0700 Subject: [PATCH 107/311] Reformat album_tracks.rs --- src/handlers/album_tracks.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handlers/album_tracks.rs b/src/handlers/album_tracks.rs index 3703a27f..b600cbed 100644 --- a/src/handlers/album_tracks.rs +++ b/src/handlers/album_tracks.rs @@ -215,7 +215,7 @@ fn handle_save_album_event(app: &mut App) { AlbumTableContext::Simplified => { if let Some(selected_album_simplified) = app.selected_album_simplified.clone() { if let Some(album_id) = selected_album_simplified.album.id { - app.dispatch(IoEvent::CurrentUserSavedAlbumAdd(album_id)); + app.dispatch(IoEvent::CurrentUserSavedAlbumAdd(album_id)); }; }; } From 1072df58e801e11095608cf48061c2e9d8319915 Mon Sep 17 00:00:00 2001 From: RicardoHE97 Date: Mon, 22 Jun 2020 15:04:49 -0700 Subject: [PATCH 108/311] Add feature to like a song from basic view Add the feature to like a song with the 's' key when you are in the basic view. --- src/handlers/basic_view.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/handlers/basic_view.rs b/src/handlers/basic_view.rs index d9480082..697316b4 100644 --- a/src/handlers/basic_view.rs +++ b/src/handlers/basic_view.rs @@ -1,3 +1,16 @@ -use crate::{app::App, event::Key}; +use crate::{app::App, event::Key, network::IoEvent}; -pub fn handler(_key: Key, _app: &mut App) {} +pub fn handler(key: Key, app: &mut App) { + match key { + Key::Char('s') => { + if let Some(playing_context) = &app.current_playback_context { + if let Some(track) = &playing_context.clone().item { + if let Some(id) = &track.id { + app.dispatch(IoEvent::ToggleSaveTrack(id.to_string())); + } + } + } + } + _ => {} + }; +} From ee9c79e998dbfc301ef4fc8cbd2152471223c942 Mon Sep 17 00:00:00 2001 From: RicardoHE97 Date: Mon, 22 Jun 2020 22:01:25 -0700 Subject: [PATCH 109/311] Reformat code for basic_view.rs that fix a common mistake --- src/handlers/basic_view.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/handlers/basic_view.rs b/src/handlers/basic_view.rs index 697316b4..a2f10d1e 100644 --- a/src/handlers/basic_view.rs +++ b/src/handlers/basic_view.rs @@ -1,16 +1,13 @@ use crate::{app::App, event::Key, network::IoEvent}; pub fn handler(key: Key, app: &mut App) { - match key { - Key::Char('s') => { - if let Some(playing_context) = &app.current_playback_context { - if let Some(track) = &playing_context.clone().item { - if let Some(id) = &track.id { - app.dispatch(IoEvent::ToggleSaveTrack(id.to_string())); - } + if let Key::Char('s') = key { + if let Some(playing_context) = &app.current_playback_context { + if let Some(track) = &playing_context.clone().item { + if let Some(id) = &track.id { + app.dispatch(IoEvent::ToggleSaveTrack(id.to_string())); } } } - _ => {} - }; + } } From 3e15fdb31a3e2d0d1293eea1dd8ac37360030fc0 Mon Sep 17 00:00:00 2001 From: ksk001100 Date: Mon, 29 Jun 2020 12:51:20 +0900 Subject: [PATCH 110/311] enable unix shortcut key --- src/handlers/input.rs | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/handlers/input.rs b/src/handlers/input.rs index b5880614..702141c4 100644 --- a/src/handlers/input.rs +++ b/src/handlers/input.rs @@ -51,14 +51,14 @@ pub fn handler(key: Key, app: &mut App) { app.input_idx = 0; app.input_cursor_position = 0; } - Key::Left => { + Key::Left | Key::Ctrl('b') => { if !app.input.is_empty() && app.input_idx > 0 { let last_c = app.input[app.input_idx - 1]; app.input_idx -= 1; app.input_cursor_position -= compute_character_width(last_c); } } - Key::Right => { + Key::Right | Key::Ctrl('f') => { if app.input_idx < app.input.len() { let next_c = app.input[app.input_idx]; app.input_idx += 1; @@ -105,14 +105,14 @@ pub fn handler(key: Key, app: &mut App) { app.input_idx += 1; app.input_cursor_position += compute_character_width(c); } - Key::Backspace => { + Key::Backspace | Key::Ctrl('h') => { if !app.input.is_empty() && app.input_idx > 0 { let last_c = app.input.remove(app.input_idx - 1); app.input_idx -= 1; app.input_cursor_position -= compute_character_width(last_c); } } - Key::Delete => { + Key::Delete | Key::Ctrl('d') => { if !app.input.is_empty() && app.input_idx < app.input.len() { app.input.remove(app.input_idx); } @@ -268,6 +268,12 @@ mod tests { handler(Key::Backspace, &mut app); assert_eq!(app.input, str_to_vec_char("M tex")); + + app.input_idx = 1; + app.input_cursor_position = 1; + + handler(Key::Ctrl('h'), &mut app); + assert_eq!(app.input, str_to_vec_char(" tex")); } #[test] @@ -287,6 +293,13 @@ mod tests { handler(Key::Delete, &mut app); assert_eq!(app.input, str_to_vec_char("γƒ©γƒˆ")); + + app.input = str_to_vec_char("Rust"); + app.input_idx = 2; + app.input_cursor_position = 2; + + handler(Key::Ctrl('d'), &mut app); + assert_eq!(app.input, str_to_vec_char("Rut")); } #[test] @@ -304,6 +317,10 @@ mod tests { assert_eq!(app.input_cursor_position, input_len - 2); handler(Key::Left, &mut app); assert_eq!(app.input_cursor_position, input_len - 3); + handler(Key::Ctrl('b'), &mut app); + assert_eq!(app.input_cursor_position, input_len - 4); + handler(Key::Ctrl('b'), &mut app); + assert_eq!(app.input_cursor_position, input_len - 5); // Pretend to smash the left event to test the we have no out-of-bounds crash for _ in 0..20 { From dfa2770499d5c2e7f9a6ada91f6f0005a7139414 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2020 17:55:46 +0000 Subject: [PATCH 111/311] docs: update README.md [skip ci] --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 00595561..70266284 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-56-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-57-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -355,6 +355,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
ncoder-1

πŸ“–
Macguire Rintoul

πŸ“– + +
Ricardo Holguin

πŸ’» + From 84ae8d35edad163459aa0883e680c60f391e6dc6 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2020 17:55:47 +0000 Subject: [PATCH 112/311] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 1aa84719..53e97e3e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -520,6 +520,15 @@ "contributions": [ "doc" ] + }, + { + "login": "RicardoHE97", + "name": "Ricardo Holguin", + "avatar_url": "https://avatars3.githubusercontent.com/u/28399979?v=4", + "profile": "http://ricardohe97.github.io", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, From 5c4135b16a56031b3bb30e4fa037ad4baf20ec63 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2020 18:05:22 +0000 Subject: [PATCH 113/311] Bump serde from 1.0.111 to 1.0.114 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.111 to 1.0.114. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.111...v1.0.114) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 56 +++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7288242e..ccaadcf8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -438,9 +438,9 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ - "proc-macro2 1.0.12", + "proc-macro2 1.0.18", "quote 1.0.4", - "syn 1.0.19", + "syn 1.0.33", "synstructure", ] @@ -542,9 +542,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.12", + "proc-macro2 1.0.18", "quote 1.0.4", - "syn 1.0.19", + "syn 1.0.33", ] [[package]] @@ -1118,9 +1118,9 @@ version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a82996f11efccb19b685b14b5df818de31c1edcee3daa256ab5775dd98e72feb" dependencies = [ - "proc-macro2 1.0.12", + "proc-macro2 1.0.18", "quote 1.0.4", - "syn 1.0.19", + "syn 1.0.33", ] [[package]] @@ -1170,9 +1170,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.12" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319" +checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" dependencies = [ "unicode-xid 0.2.0", ] @@ -1198,7 +1198,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c1f4b0efa5fc5e8ceb705136bfee52cfdb6a4e3509f770b478cd6ed434232a7" dependencies = [ - "proc-macro2 1.0.12", + "proc-macro2 1.0.18", ] [[package]] @@ -1541,22 +1541,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.111" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d" +checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.111" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250" +checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" dependencies = [ - "proc-macro2 1.0.12", + "proc-macro2 1.0.18", "quote 1.0.4", - "syn 1.0.19", + "syn 1.0.33", ] [[package]] @@ -1684,11 +1684,11 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.19" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8e5aa70697bb26ee62214ae3288465ecec0000f05182f039b477001f08f5ae7" +checksum = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd" dependencies = [ - "proc-macro2 1.0.12", + "proc-macro2 1.0.18", "quote 1.0.4", "unicode-xid 0.2.0", ] @@ -1699,9 +1699,9 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ - "proc-macro2 1.0.12", + "proc-macro2 1.0.18", "quote 1.0.4", - "syn 1.0.19", + "syn 1.0.33", "unicode-xid 0.2.0", ] @@ -1752,9 +1752,9 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f34e0c1caaa462fd840ec6b768946ea1e7842620d94fe29d5b847138f521269" dependencies = [ - "proc-macro2 1.0.12", + "proc-macro2 1.0.18", "quote 1.0.4", - "syn 1.0.19", + "syn 1.0.33", ] [[package]] @@ -1806,9 +1806,9 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" dependencies = [ - "proc-macro2 1.0.12", + "proc-macro2 1.0.18", "quote 1.0.4", - "syn 1.0.19", + "syn 1.0.33", ] [[package]] @@ -2003,9 +2003,9 @@ dependencies = [ "bumpalo", "lazy_static", "log", - "proc-macro2 1.0.12", + "proc-macro2 1.0.18", "quote 1.0.4", - "syn 1.0.19", + "syn 1.0.33", "wasm-bindgen-shared", ] @@ -2037,9 +2037,9 @@ version = "0.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eb197bd3a47553334907ffd2f16507b4f4f01bbec3ac921a7719e0decdfe72a" dependencies = [ - "proc-macro2 1.0.12", + "proc-macro2 1.0.18", "quote 1.0.4", - "syn 1.0.19", + "syn 1.0.33", "wasm-bindgen-backend", "wasm-bindgen-shared", ] From df159f58a744a6065141dcc53908b30f520a7e46 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2020 18:06:48 +0000 Subject: [PATCH 114/311] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 70266284..0e57a104 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-57-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-58-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -357,6 +357,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Ricardo Holguin

πŸ’» +
Keisuke Toyota

πŸ’» From f5782140d2d8d63d588941c26f12bdd40468a72f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2020 18:06:49 +0000 Subject: [PATCH 115/311] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 53e97e3e..c7b3c858 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -529,6 +529,15 @@ "contributions": [ "code" ] + }, + { + "login": "ksk001100", + "name": "Keisuke Toyota", + "avatar_url": "https://avatars3.githubusercontent.com/u/13160198?v=4", + "profile": "https://ksk.netlify.com", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, From 9648083bdb37237b70020a7044d4490a06af9067 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 29 Jun 2020 19:11:16 +0100 Subject: [PATCH 116/311] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c8f30a6..4ea3180d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ ## [Unreleased] - Fix typo in help menu [#485](https://github.com/Rigellute/spotify-tui/pull/485) +- Add save album on album view [#506](https://github.com/Rigellute/spotify-tui/pull/506) +- Add feature to like a song from basic view [#507](https://github.com/Rigellute/spotify-tui/pull/507) +- Enable Unix and Linux shortcut keys in the input [#511](https://github.com/Rigellute/spotify-tui/pull/511) ## [0.20.0] - 2020-05-28 From c4e166f220b7b84c0dddc0671f5fd3191522106f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2020 06:35:22 +0000 Subject: [PATCH 117/311] Bump serde_json from 1.0.55 to 1.0.56 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.55 to 1.0.56. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.55...v1.0.56) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ccaadcf8..be706a0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1561,9 +1561,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.55" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226" +checksum = "3433e879a558dde8b5e8feb2a04899cf34fdde1fafb894687e52105fc1162ac3" dependencies = [ "itoa", "ryu", From 2a3042b41778565d97dfe84c7730e7fd7447c4af Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2020 06:35:43 +0000 Subject: [PATCH 118/311] Bump unicode-width from 0.1.7 to 0.1.8 Bumps [unicode-width](https://github.com/unicode-rs/unicode-width) from 0.1.7 to 0.1.8. - [Release notes](https://github.com/unicode-rs/unicode-width/releases) - [Commits](https://github.com/unicode-rs/unicode-width/commits/v0.1.8) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ccaadcf8..14f3c75b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1910,9 +1910,9 @@ checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" [[package]] name = "unicode-width" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" diff --git a/Cargo.toml b/Cargo.toml index 4bce9161..b9cd7a52 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ serde_json = "1.0" serde_yaml = "0.8" dirs = "2.0.2" clap = "2.33.1" -unicode-width = "0.1.7" +unicode-width = "0.1.8" backtrace = "0.3.49" clipboard = "0.5.0" crossterm = "0.17" From cf3f245173669b6c558327562b2e61f2e52498ed Mon Sep 17 00:00:00 2001 From: Nick Stockton Date: Sun, 5 Jul 2020 14:59:44 -0400 Subject: [PATCH 119/311] Add album artist field to full album view This is shown in the Simplified context, but wasn't in the FUll context. This causes the undesired behavior that getting to an album from the library context has a missing field (see #488). Fixes #488 --- src/ui/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ui/mod.rs b/src/ui/mod.rs index bf8c3729..0572958a 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -566,6 +566,7 @@ where "".to_string(), item.track_number.to_string(), item.name.to_owned(), + create_artist_string(&item.artists), millis_to_minutes(u128::from(item.duration_ms)), ], }) From 49eb05a77c5522ceecb6534ae9d58a03ae5b4498 Mon Sep 17 00:00:00 2001 From: Craig Astill Date: Fri, 10 Jul 2020 17:46:17 +0100 Subject: [PATCH 120/311] Handle track saving in non-album contexts (playlist/Made for you). Saving of tracks used to only work in album view (handled by: `src.handlers.album_tracks.handle_save_album_event`). Add some rough code to get track saving working in other cases. Manually tested `Playlist` and `Made for you` views. Fixes Rigellute/spotify-tui#495 --- src/handlers/track_table.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/handlers/track_table.rs b/src/handlers/track_table.rs index 29c03ce0..5199cfd1 100644 --- a/src/handlers/track_table.rs +++ b/src/handlers/track_table.rs @@ -141,6 +141,7 @@ pub fn handler(key: Key, app: &mut App) { None => {} }; } + Key::Char('s') => handle_save_track_event(app), Key::Char('S') => play_random_song(app), Key::Ctrl('e') => jump_to_end(app), Key::Ctrl('a') => jump_to_start(app), @@ -252,6 +253,15 @@ fn play_random_song(app: &mut App) { }; } +fn handle_save_track_event(app: &mut App) { + let (selected_index, tracks) = (&app.track_table.selected_index, &app.track_table.tracks); + if let Some(track) = tracks.get(*selected_index) { + if let Some(id) = &track.id { + app.dispatch(IoEvent::ToggleSaveTrack(id.to_string())); + }; + }; +} + fn handle_recommended_tracks(app: &mut App) { let (selected_index, tracks) = (&app.track_table.selected_index, &app.track_table.tracks); if let Some(track) = tracks.get(*selected_index) { From 4064722261d3044a101f27403593ab471eab63a3 Mon Sep 17 00:00:00 2001 From: Craig Astill Date: Fri, 10 Jul 2020 18:29:27 +0100 Subject: [PATCH 121/311] Fixed im/mutable borrow issue in track saving function. Fixes Rigellute/spotify-tui#495 --- src/handlers/track_table.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/handlers/track_table.rs b/src/handlers/track_table.rs index 5199cfd1..392444de 100644 --- a/src/handlers/track_table.rs +++ b/src/handlers/track_table.rs @@ -257,7 +257,8 @@ fn handle_save_track_event(app: &mut App) { let (selected_index, tracks) = (&app.track_table.selected_index, &app.track_table.tracks); if let Some(track) = tracks.get(*selected_index) { if let Some(id) = &track.id { - app.dispatch(IoEvent::ToggleSaveTrack(id.to_string())); + let _id = id.to_string(); + app.dispatch(IoEvent::ToggleSaveTrack(_id)); }; }; } From c139bc35bc3fa8984ae6cff85266e786b93e4dd5 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 22 Jul 2020 06:39:31 +0000 Subject: [PATCH 122/311] Bump tokio from 0.2.21 to 0.2.22 Bumps [tokio](https://github.com/tokio-rs/tokio) from 0.2.21 to 0.2.22. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-0.2.21...tokio-0.2.22) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ccaadcf8..e91bfa0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1778,9 +1778,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.21" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58" +checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd" dependencies = [ "bytes 0.5.4", "fnv", From 058b291435f0dc8d9086b1d21fd448a43d735b9a Mon Sep 17 00:00:00 2001 From: Craig Astill Date: Thu, 23 Jul 2020 17:52:50 +0100 Subject: [PATCH 123/311] Removed underscore from used variable name. Fallout from review of #525 with @Rigellute. Underscore prefix in Rust is shorthand for an unused variable. --- src/handlers/track_table.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/handlers/track_table.rs b/src/handlers/track_table.rs index 392444de..b9280df2 100644 --- a/src/handlers/track_table.rs +++ b/src/handlers/track_table.rs @@ -257,8 +257,8 @@ fn handle_save_track_event(app: &mut App) { let (selected_index, tracks) = (&app.track_table.selected_index, &app.track_table.tracks); if let Some(track) = tracks.get(*selected_index) { if let Some(id) = &track.id { - let _id = id.to_string(); - app.dispatch(IoEvent::ToggleSaveTrack(_id)); + let id = id.to_string(); + app.dispatch(IoEvent::ToggleSaveTrack(id)); }; }; } From 1948221ca76887f863d29f8ddfccf58c3b2799bd Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 24 Jul 2020 08:20:24 +0000 Subject: [PATCH 124/311] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e57a104..f8e3a868 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-58-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-59-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -358,6 +358,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Ricardo Holguin

πŸ’»
Keisuke Toyota

πŸ’» +
Craig Astill

πŸ’» From 5461c5bea434f6bf66a25b51dea309f1119ebad9 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 24 Jul 2020 08:20:25 +0000 Subject: [PATCH 125/311] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index c7b3c858..f482d83a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -538,6 +538,15 @@ "contributions": [ "code" ] + }, + { + "login": "jackson15j", + "name": "Craig Astill", + "avatar_url": "https://avatars1.githubusercontent.com/u/3226988?v=4", + "profile": "https://jackson15j.github.io", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, From d699b9f897f5bf3c94ff916997180b29871ab1f6 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Fri, 24 Jul 2020 09:32:15 +0100 Subject: [PATCH 126/311] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ea3180d..58f68829 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ - Add save album on album view [#506](https://github.com/Rigellute/spotify-tui/pull/506) - Add feature to like a song from basic view [#507](https://github.com/Rigellute/spotify-tui/pull/507) - Enable Unix and Linux shortcut keys in the input [#511](https://github.com/Rigellute/spotify-tui/pull/511) +- Add album artist field to full album view [#519](https://github.com/Rigellute/spotify-tui/pull/519) +- Handle track saving in non-album contexts (eg. playlist/Made for you). [#525](https://github.com/Rigellute/spotify-tui/pull/525) ## [0.20.0] - 2020-05-28 From 971581d8611d63880adcaefcc8b8ccd014d121a3 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Fri, 24 Jul 2020 10:25:30 +0100 Subject: [PATCH 127/311] Prepare release v0.21.0 --- CHANGELOG.md | 7 +++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58f68829..64392a17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,14 @@ ## [Unreleased] +## [0.21.0] - 2020-07-24 + +### Fixed + - Fix typo in help menu [#485](https://github.com/Rigellute/spotify-tui/pull/485) + +### Added + - Add save album on album view [#506](https://github.com/Rigellute/spotify-tui/pull/506) - Add feature to like a song from basic view [#507](https://github.com/Rigellute/spotify-tui/pull/507) - Enable Unix and Linux shortcut keys in the input [#511](https://github.com/Rigellute/spotify-tui/pull/511) diff --git a/Cargo.lock b/Cargo.lock index 4eb2aef3..7c778f7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1641,7 +1641,7 @@ dependencies = [ [[package]] name = "spotify-tui" -version = "0.20.0" +version = "0.21.0" dependencies = [ "anyhow", "backtrace", diff --git a/Cargo.toml b/Cargo.toml index b9cd7a52..4a702bfb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ documentation = "https://github.com/Rigellute/spotify-tui" repository = "https://github.com/Rigellute/spotify-tui" keywords = ["spotify", "tui", "cli", "terminal"] categories = ["command-line-utilities"] -version = "0.20.0" +version = "0.21.0" authors = ["Alexander Keliris "] edition = "2018" license = "MIT OR Apache-2.0" From 10e8d9e5f9887820f7cff6531357088d44816f86 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Fri, 24 Jul 2020 12:20:59 +0100 Subject: [PATCH 128/311] Run `cargo update` (#539) In our Cargo.lock there were some dependencies that have been yanked from the cargo registry. I've upgraded them (and others) --- Cargo.lock | 502 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 283 insertions(+), 219 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c778f7c..ed546a6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,24 +2,24 @@ # It is not intended for manual editing. [[package]] name = "addr2line" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456d75cbb82da1ad150c8a9d97285ffcd21c9931dcb11e995903e7d75141b38b" +checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072" dependencies = [ "gimli", ] [[package]] -name = "adler32" -version = "1.1.0" +name = "adler" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d" +checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" [[package]] name = "aho-corasick" -version = "0.7.10" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" +checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" dependencies = [ "memchr", ] @@ -30,7 +30,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -41,9 +41,9 @@ checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f" [[package]] name = "arc-swap" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b585a98a234c46fc563103e9278c9391fde1f4e6850334da895d27edb9580f62" +checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" [[package]] name = "arrayref" @@ -65,7 +65,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -82,9 +82,9 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.49" +version = "0.3.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05100821de9e028f12ae3d189176b41ee198341eb8f369956407fea2f5cc666c" +checksum = "46254cf2fdcdf1badb5934448c1bcbe046a56537b3987d96c51a7afc5d03f293" dependencies = [ "addr2line", "cfg-if", @@ -109,6 +109,12 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + [[package]] name = "bitflags" version = "1.2.1" @@ -134,9 +140,9 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] name = "bumpalo" -version = "3.2.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187" +checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" [[package]] name = "byteorder" @@ -156,9 +162,9 @@ dependencies = [ [[package]] name = "bytes" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] name = "cassowary" @@ -168,9 +174,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" [[package]] name = "cc" -version = "1.0.52" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d" +checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518" [[package]] name = "cfg-if" @@ -180,9 +186,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "chrono" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" +checksum = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6" dependencies = [ "num-integer", "num-traits", @@ -225,7 +231,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a093d6fed558e5fe24c3dfc85a68bb68f1c824f440d3ba5aca189e2998786b" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -272,18 +278,18 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.17.5" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9851d20b9809e561297ec3ca85d7cba3a57507fe8d01d07ba7b52469e1c89a11" +checksum = "6f4919d60f26ae233e14233cc39746c8c8bb8cd7b05840ace83604917b51b6c7" dependencies = [ "bitflags", "crossterm_winapi", "lazy_static", "libc", - "mio", + "mio 0.7.0", "parking_lot", "signal-hook", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -292,7 +298,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "057b7146d02fb50175fd7dbe5158f6097f33d02831f43b4ee8ae4ddf67b68f5c" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -367,14 +373,13 @@ dependencies = [ [[package]] name = "dirs-sys" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" +checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" dependencies = [ - "cfg-if", "libc", "redox_users", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -390,9 +395,9 @@ dependencies = [ [[package]] name = "dtoa" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3" +checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b" [[package]] name = "either" @@ -402,9 +407,9 @@ checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" [[package]] name = "encoding_rs" -version = "0.8.22" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d03faa7fe0c1431609dfad7bbe827af30f82e1e2ae6f7ee4fca6bd764bc28" +checksum = "e8ac63f94732332f44fe654443c46f6375d1939684c17b0afb6cb56b0456e171" dependencies = [ "cfg-if", ] @@ -438,17 +443,17 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ - "proc-macro2 1.0.18", - "quote 1.0.4", - "syn 1.0.33", + "proc-macro2 1.0.19", + "quote 1.0.7", + "syn 1.0.35", "synstructure", ] [[package]] name = "fnv" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foreign-types" @@ -542,9 +547,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.18", - "quote 1.0.4", - "syn 1.0.33", + "proc-macro2 1.0.19", + "quote 1.0.7", + "syn 1.0.35", ] [[package]] @@ -595,34 +600,43 @@ dependencies = [ [[package]] name = "gimli" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c" +checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" [[package]] name = "h2" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b7246d7e4b979c03fa093da39cfb3617a96bbeee6310af63991668d7e843ff" +checksum = "993f9e0baeed60001cf565546b0d3dbe6a6ad23f2bd31644a133c641eccf6d53" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "fnv", "futures-core", "futures-sink", "futures-util", "http", "indexmap", - "log", "slab", "tokio", "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb" +dependencies = [ + "autocfg 1.0.0", ] [[package]] name = "hermit-abi" -version = "0.1.12" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4" +checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9" dependencies = [ "libc", ] @@ -633,7 +647,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "fnv", "itoa", ] @@ -644,7 +658,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "http", ] @@ -665,11 +679,11 @@ dependencies = [ [[package]] name = "hyper" -version = "0.13.5" +version = "0.13.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96816e1d921eca64d208a85aab4f7798455a8e34229ee5a88c935bdee1b78b14" +checksum = "3e68a8dd9716185d9e64ea473ea6ef63529252e3e27623295a0378a19665d5eb" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "futures-channel", "futures-core", "futures-util", @@ -678,22 +692,22 @@ dependencies = [ "http-body", "httparse", "itoa", - "log", - "net2", "pin-project", + "socket2", "time", "tokio", "tower-service", + "tracing", "want", ] [[package]] name = "hyper-tls" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3adcd308402b9553630734e9c36b77a7e48b3821251ca2493e8cd596763aafaa" +checksum = "d979acc56dcb5b8dddba3917601745e877576475aa046df3226eabdecef78eed" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "hyper", "native-tls", "tokio", @@ -730,11 +744,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.3.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292" +checksum = "5b88cd59ee5f71fea89a62248fc8f387d44400cefe05ef548466d61ced9029a7" dependencies = [ "autocfg 1.0.0", + "hashbrown", ] [[package]] @@ -766,15 +781,15 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" [[package]] name = "js-sys" -version = "0.3.39" +version = "0.3.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa5a448de267e7358beaf4a5d849518fe9a0c13fce7afd44b06e68550e5562a7" +checksum = "52732a3d3ad72c58ad2dc70624f9c17b46ecd0943b9a4f1ee37c4c18c5d983e2" dependencies = [ "wasm-bindgen", ] @@ -797,9 +812,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.69" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" +checksum = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9" [[package]] name = "linked-hash-map" @@ -818,9 +833,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.8" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" dependencies = [ "cfg-if", ] @@ -864,11 +879,11 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.3.7" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f" dependencies = [ - "adler32", + "adler", ] [[package]] @@ -890,16 +905,30 @@ dependencies = [ "winapi 0.2.8", ] +[[package]] +name = "mio" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e9971bc8349a361217a8f2a41f5d011274686bd4436465ba51730921039d7fb" +dependencies = [ + "lazy_static", + "libc", + "log", + "miow 0.3.5", + "ntapi", + "winapi 0.3.9", +] + [[package]] name = "mio-named-pipes" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" +checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" dependencies = [ "log", - "mio", - "miow 0.3.3", - "winapi 0.3.8", + "mio 0.6.22", + "miow 0.3.5", + "winapi 0.3.9", ] [[package]] @@ -910,7 +939,7 @@ checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" dependencies = [ "iovec", "libc", - "mio", + "mio 0.6.22", ] [[package]] @@ -927,12 +956,12 @@ dependencies = [ [[package]] name = "miow" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" +checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e" dependencies = [ "socket2", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -961,14 +990,23 @@ checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" dependencies = [ "cfg-if", "libc", - "winapi 0.3.8", + "winapi 0.3.9", +] + +[[package]] +name = "ntapi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a31937dea023539c72ddae0e3571deadc1414b300483fa7aaec176168cfa9d2" +dependencies = [ + "winapi 0.3.9", ] [[package]] name = "num-integer" -version = "0.1.42" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" +checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" dependencies = [ "autocfg 1.0.0", "num-traits", @@ -976,9 +1014,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" dependencies = [ "autocfg 1.0.0", ] @@ -1030,15 +1068,15 @@ checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" [[package]] name = "once_cell" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" +checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" [[package]] name = "openssl" -version = "0.10.29" +version = "0.10.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee6d85f4cb4c4f59a6a85d5b68a233d280c82e29e822913b9c8b129fbf20bdd" +checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4" dependencies = [ "bitflags", "cfg-if", @@ -1056,9 +1094,9 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" [[package]] name = "openssl-sys" -version = "0.9.56" +version = "0.9.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f02309a7f127000ed50594f0b50ecc69e7c654e16d41b4e8156d1b3df8e0b52e" +checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de" dependencies = [ "autocfg 1.0.0", "cc", @@ -1088,7 +1126,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1105,29 +1143,29 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pin-project" -version = "0.4.16" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81d480cb4e89522ccda96d0eed9af94180b7a5f93fb28f66e1fd7d68431663d1" +checksum = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "0.4.16" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82996f11efccb19b685b14b5df818de31c1edcee3daa256ab5775dd98e72feb" +checksum = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7" dependencies = [ - "proc-macro2 1.0.18", - "quote 1.0.4", - "syn 1.0.33", + "proc-macro2 1.0.19", + "quote 1.0.7", + "syn 1.0.35", ] [[package]] name = "pin-project-lite" -version = "0.1.5" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7505eeebd78492e0f6108f7171c4948dbb120ee8119d9d77d0afa5469bef67f" +checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715" [[package]] name = "pin-utils" @@ -1137,27 +1175,27 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" +checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" [[package]] name = "ppv-lite86" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" +checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" [[package]] name = "proc-macro-hack" -version = "0.5.15" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" +checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4" [[package]] name = "proc-macro-nested" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694" +checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" [[package]] name = "proc-macro2" @@ -1170,11 +1208,11 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" +checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" dependencies = [ - "unicode-xid 0.2.0", + "unicode-xid 0.2.1", ] [[package]] @@ -1194,11 +1232,11 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.4" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c1f4b0efa5fc5e8ceb705136bfee52cfdb6a4e3509f770b478cd6ed434232a7" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" dependencies = [ - "proc-macro2 1.0.18", + "proc-macro2 1.0.19", ] [[package]] @@ -1217,7 +1255,7 @@ dependencies = [ "rand_os", "rand_pcg", "rand_xorshift", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1312,7 +1350,7 @@ checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" dependencies = [ "libc", "rand_core 0.4.2", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1326,7 +1364,7 @@ dependencies = [ "libc", "rand_core 0.4.2", "rdrand", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1365,9 +1403,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_users" @@ -1382,9 +1420,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.3.7" +version = "1.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692" +checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" dependencies = [ "aho-corasick", "memchr", @@ -1394,27 +1432,27 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae" +checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" [[package]] name = "remove_dir_all" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "reqwest" -version = "0.10.4" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b81e49ddec5109a9dcfc5f2a317ff53377c915e9ae9d4f2fb50914b85614e2" +checksum = "3b82c9238b305f26f53443e3a4bc8528d64b8d0bee408ec949eb7bf5635ec680" dependencies = [ - "base64 0.11.0", - "bytes 0.5.4", + "base64 0.12.3", + "bytes 0.5.6", "encoding_rs", "futures-core", "futures-util", @@ -1433,7 +1471,6 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "time", "tokio", "tokio-socks", "tokio-tls", @@ -1496,9 +1533,9 @@ checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" [[package]] name = "ryu" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "schannel" @@ -1507,7 +1544,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" dependencies = [ "lazy_static", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1554,9 +1591,9 @@ version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" dependencies = [ - "proc-macro2 1.0.18", - "quote 1.0.4", - "syn 1.0.33", + "proc-macro2 1.0.19", + "quote 1.0.7", + "syn 1.0.35", ] [[package]] @@ -1596,12 +1633,12 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff2db2112d6c761e12522c65f7768548bd6e8cd23d2a9dae162520626629bd6" +checksum = "604508c1418b99dfe1925ca9224829bb2a8a9a04dda655cc01fcad46f4ab05ed" dependencies = [ "libc", - "mio", + "mio 0.7.0", "signal-hook-registry", ] @@ -1623,9 +1660,9 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" [[package]] name = "smallvec" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4" +checksum = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f" [[package]] name = "socket2" @@ -1636,7 +1673,7 @@ dependencies = [ "cfg-if", "libc", "redox_syscall", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1684,25 +1721,25 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd" +checksum = "fb7f4c519df8c117855e19dd8cc851e89eb746fe7a73f0157e0d95fdec5369b0" dependencies = [ - "proc-macro2 1.0.18", - "quote 1.0.4", - "unicode-xid 0.2.0", + "proc-macro2 1.0.19", + "quote 1.0.7", + "unicode-xid 0.2.1", ] [[package]] name = "synstructure" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" +checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" dependencies = [ - "proc-macro2 1.0.18", - "quote 1.0.4", - "syn 1.0.33", - "unicode-xid 0.2.0", + "proc-macro2 1.0.19", + "quote 1.0.7", + "syn 1.0.35", + "unicode-xid 0.2.1", ] [[package]] @@ -1716,7 +1753,7 @@ dependencies = [ "rand 0.7.3", "redox_syscall", "remove_dir_all", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1739,22 +1776,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.16" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d12a1dae4add0f0d568eebc7bf142f145ba1aa2544cafb195c76f0f409091b60" +checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.16" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f34e0c1caaa462fd840ec6b768946ea1e7842620d94fe29d5b847138f521269" +checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" dependencies = [ - "proc-macro2 1.0.18", - "quote 1.0.4", - "syn 1.0.33", + "proc-macro2 1.0.19", + "quote 1.0.7", + "syn 1.0.35", ] [[package]] @@ -1773,23 +1810,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] +[[package]] +name = "tinyvec" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" + [[package]] name = "tokio" version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "fnv", "futures-core", "iovec", "lazy_static", "libc", "memchr", - "mio", + "mio 0.6.22", "mio-named-pipes", "mio-uds", "num_cpus", @@ -1797,7 +1840,7 @@ dependencies = [ "signal-hook-registry", "slab", "tokio-macros", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1806,9 +1849,9 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" dependencies = [ - "proc-macro2 1.0.18", - "quote 1.0.4", - "syn 1.0.33", + "proc-macro2 1.0.19", + "quote 1.0.7", + "syn 1.0.35", ] [[package]] @@ -1840,7 +1883,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "futures-core", "futures-sink", "log", @@ -1854,11 +1897,31 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" +[[package]] +name = "tracing" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbdf4ccd1652592b01286a5dbe1e2a77d78afaa34beadd9872a5f7396f92aaa9" +dependencies = [ + "cfg-if", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94ae75f0d28ae10786f3b1895c55fe72e79928fd5ccdebb5438c75e93fec178f" +dependencies = [ + "lazy_static", +] + [[package]] name = "try-lock" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "tui" @@ -1895,11 +1958,11 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" +checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" dependencies = [ - "smallvec", + "tinyvec", ] [[package]] @@ -1922,9 +1985,9 @@ checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" [[package]] name = "unicode-xid" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "url" @@ -1950,9 +2013,9 @@ dependencies = [ [[package]] name = "vcpkg" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" +checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" [[package]] name = "vec_map" @@ -1962,9 +2025,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" [[package]] name = "want" @@ -1984,9 +2047,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasm-bindgen" -version = "0.2.62" +version = "0.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c7d40d09cdbf0f4895ae58cf57d92e1e57a9dd8ed2e8390514b54a47cc5551" +checksum = "f3edbcc9536ab7eababcc6d2374a0b7bfe13a2b6d562c5e07f370456b1a8f33d" dependencies = [ "cfg-if", "serde", @@ -1996,24 +2059,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.62" +version = "0.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3972e137ebf830900db522d6c8fd74d1900dcfc733462e9a12e942b00b4ac94" +checksum = "89ed2fb8c84bfad20ea66b26a3743f3e7ba8735a69fe7d95118c33ec8fc1244d" dependencies = [ "bumpalo", "lazy_static", "log", - "proc-macro2 1.0.18", - "quote 1.0.4", - "syn 1.0.33", + "proc-macro2 1.0.19", + "quote 1.0.7", + "syn 1.0.35", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.12" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a369c5e1dfb7569e14d62af4da642a3cbc2f9a3652fe586e26ac22222aa4b04" +checksum = "41ad6e4e8b2b7f8c90b6e09a9b590ea15cb0d1dbe28502b5a405cd95d1981671" dependencies = [ "cfg-if", "js-sys", @@ -2023,38 +2086,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.62" +version = "0.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cd85aa2c579e8892442954685f0d801f9129de24fa2136b2c6a539c76b65776" +checksum = "eb071268b031a64d92fc6cf691715ca5a40950694d8f683c5bb43db7c730929e" dependencies = [ - "quote 1.0.4", + "quote 1.0.7", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.62" +version = "0.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb197bd3a47553334907ffd2f16507b4f4f01bbec3ac921a7719e0decdfe72a" +checksum = "cf592c807080719d1ff2f245a687cbadb3ed28b2077ed7084b47aba8b691f2c6" dependencies = [ - "proc-macro2 1.0.18", - "quote 1.0.4", - "syn 1.0.33", + "proc-macro2 1.0.19", + "quote 1.0.7", + "syn 1.0.35", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.62" +version = "0.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91c2916119c17a8e316507afaaa2dd94b47646048014bbdf6bef098c1bb58ad" +checksum = "72b6c0220ded549d63860c78c38f3bcc558d1ca3f4efa74942c536ddbbb55e87" [[package]] name = "web-sys" -version = "0.3.39" +version = "0.3.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bc359e5dd3b46cb9687a051d50a2fdd228e4ba7cf6fcf861a5365c3d671a642" +checksum = "8be2398f326b7ba09815d0b403095f34dd708579220d099caae89be0b32137b2" dependencies = [ "js-sys", "wasm-bindgen", @@ -2062,19 +2125,20 @@ dependencies = [ [[package]] name = "webbrowser" -version = "0.5.2" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d468a911faaaeb783693b004e1c62e0063e646b0afae5c146cd144e566e66d" +checksum = "ecad156490d6b620308ed411cfee90d280b3cbd13e189ea0d3fada8acc89158a" dependencies = [ + "web-sys", "widestring", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "widestring" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effc0e4ff8085673ea7b9b2e3c73f6bd4d118810c9009ed8f1e16bd96c331db6" +checksum = "a763e303c0e0f23b0da40888724762e802a8ffefbc22de4127ef42493c2ea68c" [[package]] name = "winapi" @@ -2084,9 +2148,9 @@ checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", @@ -2110,7 +2174,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -2121,11 +2185,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "winreg" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" +checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -2159,9 +2223,9 @@ dependencies = [ [[package]] name = "yaml-rust" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d" +checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d" dependencies = [ "linked-hash-map", ] From d9535ba5cdbaf2c83c02dd7387bb906f216e12cf Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Fri, 7 Aug 2020 09:56:42 +0100 Subject: [PATCH 129/311] Upgrade rspotify to 0.10.0 (#537) --- Cargo.lock | 4 +- Cargo.toml | 2 +- src/app.rs | 134 ++++++++++++++++++++------------- src/handlers/basic_view.rs | 21 ++++-- src/handlers/mod.rs | 39 +++++++--- src/handlers/playbar.rs | 21 ++++-- src/handlers/search_results.rs | 45 ++++++----- src/handlers/track_table.rs | 2 - src/network.rs | 108 +++++++++++++++++--------- src/ui/mod.rs | 78 ++++++++++++------- 10 files changed, 286 insertions(+), 168 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ed546a6b..223b4453 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1483,9 +1483,9 @@ dependencies = [ [[package]] name = "rspotify" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29b79da3557219b1ea44609ae2bdddbe8f0cc71188ab863cc47d98e8a1d6eb5" +checksum = "eefd7bb58b714606b30a490f751d7926942e2874eef5e82934d60d7a4a68dca4" dependencies = [ "base64 0.10.1", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 4a702bfb..9933d556 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ license = "MIT OR Apache-2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rspotify = "0.9.0" +rspotify = "0.10.0" tui = { version = "0.9.5", features = ["crossterm"], default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/src/app.rs b/src/app.rs index c71672e7..d1b427ba 100644 --- a/src/app.rs +++ b/src/app.rs @@ -6,14 +6,14 @@ use rspotify::{ album::{FullAlbum, SavedAlbum, SimplifiedAlbum}, artist::FullArtist, audio::AudioAnalysis, - context::FullPlayingContext, + context::CurrentlyPlaybackContext, device::DevicePayload, page::{CursorBasedPage, Page}, playing::PlayHistory, playlist::{PlaylistTrack, SimplifiedPlaylist}, - search::{SearchAlbums, SearchArtists, SearchPlaylists, SearchTracks}, track::{FullTrack, SavedTrack, SimplifiedTrack}, user::PrivateUser, + PlayingItem, }, senum::Country, }; @@ -185,14 +185,14 @@ pub enum RecommendationsContext { } pub struct SearchResult { - pub albums: Option, - pub artists: Option, - pub playlists: Option, + pub albums: Option>, + pub artists: Option>, + pub playlists: Option>, + pub tracks: Option>, pub selected_album_index: Option, pub selected_artists_index: Option, pub selected_playlists_index: Option, pub selected_tracks_index: Option, - pub tracks: Option, pub hovered_block: SearchResultBlock, pub selected_block: SearchResultBlock, } @@ -241,7 +241,7 @@ pub struct App { pub album_table_context: AlbumTableContext, pub saved_album_tracks_index: usize, pub api_error: String, - pub current_playback_context: Option, + pub current_playback_context: Option, pub devices: Option, // Inputs: // input is the string for input; @@ -413,41 +413,53 @@ impl App { pub fn update_on_tick(&mut self) { self.poll_current_playback(); - if let Some(FullPlayingContext { - item: Some(ref track), + if let Some(CurrentlyPlaybackContext { + item: Some(item), progress_ms: Some(progress_ms), is_playing: true, .. - }) = self.current_playback_context + }) = &self.current_playback_context { let elapsed = self .instant_since_last_current_playback_poll .elapsed() .as_millis() - + u128::from(progress_ms); - - if elapsed < u128::from(track.duration_ms) { - self.song_progress_ms = elapsed; - } else { - self.song_progress_ms = track.duration_ms.into(); + + u128::from(*progress_ms); + + match item { + PlayingItem::Track(track) => { + if elapsed < u128::from(track.duration_ms) { + self.song_progress_ms = elapsed; + } else { + self.song_progress_ms = track.duration_ms.into(); + } + } + PlayingItem::Episode(_episode) => {} } } } pub fn seek_forwards(&mut self) { - if let Some(FullPlayingContext { - item: Some(track), .. + if let Some(CurrentlyPlaybackContext { + item: Some(item), .. }) = &self.current_playback_context { - let event = if track.duration_ms - self.song_progress_ms as u32 - > self.user_config.behavior.seek_milliseconds - { - IoEvent::Seek(self.song_progress_ms as u32 + self.user_config.behavior.seek_milliseconds) - } else { - IoEvent::NextTrack + match item { + PlayingItem::Track(track) => { + let event = if track.duration_ms - self.song_progress_ms as u32 + > self.user_config.behavior.seek_milliseconds + { + IoEvent::Seek( + self.song_progress_ms as u32 + self.user_config.behavior.seek_milliseconds, + ) + } else { + IoEvent::NextTrack + }; + + self.dispatch(event); + } + PlayingItem::Episode(_episode) => {} }; - - self.dispatch(event) } } @@ -515,7 +527,7 @@ impl App { } pub fn toggle_playback(&mut self) { - if let Some(FullPlayingContext { + if let Some(CurrentlyPlaybackContext { is_playing: true, .. }) = &self.current_playback_context { @@ -581,13 +593,20 @@ impl App { None => return, }; - if let Some(FullPlayingContext { - item: Some(FullTrack { id: Some(id), .. }), - .. + if let Some(CurrentlyPlaybackContext { + item: Some(item), .. }) = &self.current_playback_context { - if let Err(e) = clipboard.set_contents(format!("https://open.spotify.com/track/{}", id)) { - self.handle_error(anyhow!("failed to set clipboard content: {}", e)); + match item { + PlayingItem::Track(track) => { + if let Err(e) = clipboard.set_contents(format!( + "https://open.spotify.com/track/{}", + track.id.to_owned().unwrap_or_default() + )) { + self.handle_error(anyhow!("failed to set clipboard content: {}", e)); + } + } + PlayingItem::Episode(_episode) => {} } } } @@ -598,17 +617,20 @@ impl App { None => return, }; - if let Some(FullPlayingContext { - item: - Some(FullTrack { - album: SimplifiedAlbum { id: Some(id), .. }, - .. - }), - .. + if let Some(CurrentlyPlaybackContext { + item: Some(item), .. }) = &self.current_playback_context { - if let Err(e) = clipboard.set_contents(format!("https://open.spotify.com/album/{}", id)) { - self.handle_error(anyhow!("failed to set clipboard content: {}", e)); + match item { + PlayingItem::Track(track) => { + if let Err(e) = clipboard.set_contents(format!( + "https://open.spotify.com/album/{}", + track.id.to_owned().unwrap_or_default() + )) { + self.handle_error(anyhow!("failed to set clipboard content: {}", e)); + } + } + PlayingItem::Episode(_episode) => {} } } } @@ -689,7 +711,7 @@ impl App { ActiveBlock::SearchResultBlock => { if let Some(albums) = &self.search_results.albums { if let Some(selected_index) = self.search_results.selected_album_index { - let selected_album = &albums.albums.items[selected_index]; + let selected_album = &albums.items[selected_index]; if let Some(album_id) = selected_album.id.clone() { self.dispatch(IoEvent::CurrentUserSavedAlbumDelete(album_id)); } @@ -722,7 +744,7 @@ impl App { ActiveBlock::SearchResultBlock => { if let Some(albums) = &self.search_results.albums { if let Some(selected_index) = self.search_results.selected_album_index { - let selected_album = &albums.albums.items[selected_index]; + let selected_album = &albums.items[selected_index]; if let Some(album_id) = selected_album.id.clone() { self.dispatch(IoEvent::CurrentUserSavedAlbumAdd(album_id)); } @@ -747,7 +769,7 @@ impl App { ActiveBlock::SearchResultBlock => { if let Some(artists) = &self.search_results.artists { if let Some(selected_index) = self.search_results.selected_artists_index { - let selected_artist: &FullArtist = &artists.artists.items[selected_index]; + let selected_artist: &FullArtist = &artists.items[selected_index]; let artist_id = selected_artist.id.clone(); self.dispatch(IoEvent::UserUnfollowArtists(vec![artist_id])); } @@ -777,7 +799,7 @@ impl App { ActiveBlock::SearchResultBlock => { if let Some(artists) = &self.search_results.artists { if let Some(selected_index) = self.search_results.selected_artists_index { - let selected_artist: &FullArtist = &artists.artists.items[selected_index]; + let selected_artist: &FullArtist = &artists.items[selected_index]; let artist_id = selected_artist.id.clone(); self.dispatch(IoEvent::UserUnfollowArtists(vec![artist_id])); } @@ -801,7 +823,7 @@ impl App { .. } = self.search_results { - let selected_playlist: &SimplifiedPlaylist = &playlists.playlists.items[selected_index]; + let selected_playlist: &SimplifiedPlaylist = &playlists.items[selected_index]; let selected_id = selected_playlist.id.clone(); let selected_public = selected_playlist.public; let selected_owner_id = selected_playlist.owner.id.clone(); @@ -830,7 +852,7 @@ impl App { self.search_results.selected_playlists_index, &self.user, ) { - let selected_playlist = &playlists.playlists.items[selected_index]; + let selected_playlist = &playlists.items[selected_index]; let selected_id = selected_playlist.id.clone(); let user_id = user.id.clone(); self.dispatch(IoEvent::UserUnfollowPlaylist(user_id, selected_id)) @@ -863,14 +885,18 @@ impl App { } pub fn get_audio_analysis(&mut self) { - if let Some(FullPlayingContext { - item: Some(ref track), - .. - }) = self.current_playback_context + if let Some(CurrentlyPlaybackContext { + item: Some(item), .. + }) = &self.current_playback_context { - let uri = track.uri.clone(); - self.dispatch(IoEvent::GetAudioAnalysis(uri)); - self.push_navigation_stack(RouteId::Analysis, ActiveBlock::Analysis); + match item { + PlayingItem::Track(track) => { + let uri = track.uri.clone(); + self.dispatch(IoEvent::GetAudioAnalysis(uri)); + self.push_navigation_stack(RouteId::Analysis, ActiveBlock::Analysis); + } + PlayingItem::Episode(_epidose) => {} + } } } diff --git a/src/handlers/basic_view.rs b/src/handlers/basic_view.rs index a2f10d1e..00a8a266 100644 --- a/src/handlers/basic_view.rs +++ b/src/handlers/basic_view.rs @@ -1,13 +1,22 @@ use crate::{app::App, event::Key, network::IoEvent}; +use rspotify::model::{context::CurrentlyPlaybackContext, PlayingItem}; pub fn handler(key: Key, app: &mut App) { if let Key::Char('s') = key { - if let Some(playing_context) = &app.current_playback_context { - if let Some(track) = &playing_context.clone().item { - if let Some(id) = &track.id { - app.dispatch(IoEvent::ToggleSaveTrack(id.to_string())); + if let Some(CurrentlyPlaybackContext { + item: Some(item), .. + }) = app.current_playback_context.to_owned() + { + match item { + PlayingItem::Track(track) => { + if let Some(track_id) = track.id { + app.dispatch(IoEvent::ToggleSaveTrack(track_id)); + } } - } - } + PlayingItem::Episode(episode) => { + app.dispatch(IoEvent::ToggleSaveTrack(episode.id)); + } + }; + }; } } diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 159bd1a1..6f761ddf 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -24,6 +24,7 @@ mod track_table; use super::app::{ActiveBlock, App, ArtistBlock, RouteId, SearchResultBlock}; use crate::event::Key; use crate::network::IoEvent; +use rspotify::model::{context::CurrentlyPlaybackContext, PlayingItem}; pub use input::handler as input_handler; @@ -206,23 +207,39 @@ fn handle_jump_to_context(app: &mut App) { } fn handle_jump_to_album(app: &mut App) { - if let Some(current_playback_context) = &app.current_playback_context { - if let Some(full_track) = current_playback_context.item.clone() { - app.dispatch(IoEvent::GetAlbumTracks(Box::new(full_track.album))); - } - }; + if let Some(CurrentlyPlaybackContext { + item: Some(item), .. + }) = app.current_playback_context.to_owned() + { + match item { + PlayingItem::Track(track) => { + app.dispatch(IoEvent::GetAlbumTracks(Box::new(track.album))); + } + PlayingItem::Episode(_episode) => { + // Do nothing for episode (yet!) + } + }; + } } // NOTE: this only finds the first artist of the song and jumps to their albums fn handle_jump_to_artist_album(app: &mut App) { - if let Some(current_playback_context) = &app.current_playback_context { - if let Some(playing_item) = ¤t_playback_context.item.clone() { - if let Some(artist) = playing_item.artists.first() { - if let Some(artist_id) = artist.id.clone() { - app.get_artist(artist_id, artist.name.clone()); - app.push_navigation_stack(RouteId::Artist, ActiveBlock::ArtistBlock); + if let Some(CurrentlyPlaybackContext { + item: Some(item), .. + }) = app.current_playback_context.to_owned() + { + match item { + PlayingItem::Track(track) => { + if let Some(artist) = track.artists.first() { + if let Some(artist_id) = artist.id.clone() { + app.get_artist(artist_id, artist.name.clone()); + app.push_navigation_stack(RouteId::Artist, ActiveBlock::ArtistBlock); + } } } + PlayingItem::Episode(_episode) => { + // Do nothing for episode (yet!) + } } }; } diff --git a/src/handlers/playbar.rs b/src/handlers/playbar.rs index 4d2f6c09..4746eba4 100644 --- a/src/handlers/playbar.rs +++ b/src/handlers/playbar.rs @@ -4,6 +4,7 @@ use super::{ }; use crate::event::Key; use crate::network::IoEvent; +use rspotify::model::{context::CurrentlyPlaybackContext, PlayingItem}; pub fn handler(key: Key, app: &mut App) { match key { @@ -11,13 +12,21 @@ pub fn handler(key: Key, app: &mut App) { app.set_current_route_state(Some(ActiveBlock::Empty), Some(ActiveBlock::MyPlaylists)); } Key::Char('s') => { - if let Some(playing_context) = &app.current_playback_context { - if let Some(track) = &playing_context.clone().item { - if let Some(id) = &track.id { - app.dispatch(IoEvent::ToggleSaveTrack(id.to_string())); + if let Some(CurrentlyPlaybackContext { + item: Some(item), .. + }) = app.current_playback_context.to_owned() + { + match item { + PlayingItem::Track(track) => { + if let Some(track_id) = track.id { + app.dispatch(IoEvent::ToggleSaveTrack(track_id)); + } } - } - } + PlayingItem::Episode(episode) => { + app.dispatch(IoEvent::ToggleSaveTrack(episode.id)); + } + }; + }; } _ => {} }; diff --git a/src/handlers/search_results.rs b/src/handlers/search_results.rs index d8eb884c..f4029e8e 100644 --- a/src/handlers/search_results.rs +++ b/src/handlers/search_results.rs @@ -14,7 +14,7 @@ fn handle_down_press_on_selected_block(app: &mut App) { SearchResultBlock::AlbumSearch => { if let Some(result) = &app.search_results.albums { let next_index = common_key_events::on_down_press_handler( - &result.albums.items, + &result.items, app.search_results.selected_album_index, ); app.search_results.selected_album_index = Some(next_index); @@ -23,7 +23,7 @@ fn handle_down_press_on_selected_block(app: &mut App) { SearchResultBlock::SongSearch => { if let Some(result) = &app.search_results.tracks { let next_index = common_key_events::on_down_press_handler( - &result.tracks.items, + &result.items, app.search_results.selected_tracks_index, ); app.search_results.selected_tracks_index = Some(next_index); @@ -32,7 +32,7 @@ fn handle_down_press_on_selected_block(app: &mut App) { SearchResultBlock::ArtistSearch => { if let Some(result) = &app.search_results.artists { let next_index = common_key_events::on_down_press_handler( - &result.artists.items, + &result.items, app.search_results.selected_artists_index, ); app.search_results.selected_artists_index = Some(next_index); @@ -41,7 +41,7 @@ fn handle_down_press_on_selected_block(app: &mut App) { SearchResultBlock::PlaylistSearch => { if let Some(result) = &app.search_results.playlists { let next_index = common_key_events::on_down_press_handler( - &result.playlists.items, + &result.items, app.search_results.selected_playlists_index, ); app.search_results.selected_playlists_index = Some(next_index); @@ -75,7 +75,7 @@ fn handle_up_press_on_selected_block(app: &mut App) { SearchResultBlock::AlbumSearch => { if let Some(result) = &app.search_results.albums { let next_index = common_key_events::on_up_press_handler( - &result.albums.items, + &result.items, app.search_results.selected_album_index, ); app.search_results.selected_album_index = Some(next_index); @@ -84,7 +84,7 @@ fn handle_up_press_on_selected_block(app: &mut App) { SearchResultBlock::SongSearch => { if let Some(result) = &app.search_results.tracks { let next_index = common_key_events::on_up_press_handler( - &result.tracks.items, + &result.items, app.search_results.selected_tracks_index, ); app.search_results.selected_tracks_index = Some(next_index); @@ -93,7 +93,7 @@ fn handle_up_press_on_selected_block(app: &mut App) { SearchResultBlock::ArtistSearch => { if let Some(result) = &app.search_results.artists { let next_index = common_key_events::on_up_press_handler( - &result.artists.items, + &result.items, app.search_results.selected_artists_index, ); app.search_results.selected_artists_index = Some(next_index); @@ -102,7 +102,7 @@ fn handle_up_press_on_selected_block(app: &mut App) { SearchResultBlock::PlaylistSearch => { if let Some(result) = &app.search_results.playlists { let next_index = common_key_events::on_up_press_handler( - &result.playlists.items, + &result.items, app.search_results.selected_playlists_index, ); app.search_results.selected_playlists_index = Some(next_index); @@ -164,25 +164,25 @@ fn handle_middle_press_on_selected_block(app: &mut App) { match app.search_results.selected_block { SearchResultBlock::AlbumSearch => { if let Some(result) = &app.search_results.albums { - let next_index = common_key_events::on_middle_press_handler(&result.albums.items); + let next_index = common_key_events::on_middle_press_handler(&result.items); app.search_results.selected_album_index = Some(next_index); } } SearchResultBlock::SongSearch => { if let Some(result) = &app.search_results.tracks { - let next_index = common_key_events::on_middle_press_handler(&result.tracks.items); + let next_index = common_key_events::on_middle_press_handler(&result.items); app.search_results.selected_tracks_index = Some(next_index); } } SearchResultBlock::ArtistSearch => { if let Some(result) = &app.search_results.artists { - let next_index = common_key_events::on_middle_press_handler(&result.artists.items); + let next_index = common_key_events::on_middle_press_handler(&result.items); app.search_results.selected_artists_index = Some(next_index); } } SearchResultBlock::PlaylistSearch => { if let Some(result) = &app.search_results.playlists { - let next_index = common_key_events::on_middle_press_handler(&result.playlists.items); + let next_index = common_key_events::on_middle_press_handler(&result.items); app.search_results.selected_playlists_index = Some(next_index); } } @@ -194,25 +194,25 @@ fn handle_low_press_on_selected_block(app: &mut App) { match app.search_results.selected_block { SearchResultBlock::AlbumSearch => { if let Some(result) = &app.search_results.albums { - let next_index = common_key_events::on_low_press_handler(&result.albums.items); + let next_index = common_key_events::on_low_press_handler(&result.items); app.search_results.selected_album_index = Some(next_index); } } SearchResultBlock::SongSearch => { if let Some(result) = &app.search_results.tracks { - let next_index = common_key_events::on_low_press_handler(&result.tracks.items); + let next_index = common_key_events::on_low_press_handler(&result.items); app.search_results.selected_tracks_index = Some(next_index); } } SearchResultBlock::ArtistSearch => { if let Some(result) = &app.search_results.artists { - let next_index = common_key_events::on_low_press_handler(&result.artists.items); + let next_index = common_key_events::on_low_press_handler(&result.items); app.search_results.selected_artists_index = Some(next_index); } } SearchResultBlock::PlaylistSearch => { if let Some(result) = &app.search_results.playlists { - let next_index = common_key_events::on_low_press_handler(&result.playlists.items); + let next_index = common_key_events::on_low_press_handler(&result.items); app.search_results.selected_playlists_index = Some(next_index); } } @@ -227,7 +227,7 @@ fn handle_enter_event_on_selected_block(app: &mut App) { &app.search_results.selected_album_index, &app.search_results.albums, ) { - if let Some(album) = albums_result.albums.items.get(index.to_owned()).cloned() { + if let Some(album) = albums_result.items.get(index.to_owned()).cloned() { app.track_table.context = Some(TrackTableContext::AlbumSearch); app.dispatch(IoEvent::GetAlbumTracks(Box::new(album))); }; @@ -238,7 +238,6 @@ fn handle_enter_event_on_selected_block(app: &mut App) { let tracks = app.search_results.tracks.clone(); let track_uris = tracks.map(|tracks| { tracks - .tracks .items .into_iter() .map(|track| track.uri) @@ -249,7 +248,7 @@ fn handle_enter_event_on_selected_block(app: &mut App) { SearchResultBlock::ArtistSearch => { if let Some(index) = &app.search_results.selected_artists_index { if let Some(result) = app.search_results.artists.clone() { - if let Some(artist) = result.artists.items.get(index.to_owned()) { + if let Some(artist) = result.items.get(index.to_owned()) { app.get_artist(artist.id.clone(), artist.name.clone()); app.push_navigation_stack(RouteId::Artist, ActiveBlock::ArtistBlock); }; @@ -261,7 +260,7 @@ fn handle_enter_event_on_selected_block(app: &mut App) { app.search_results.selected_playlists_index, &app.search_results.playlists, ) { - if let Some(playlist) = playlists_result.playlists.items.get(index) { + if let Some(playlist) = playlists_result.items.get(index) { // Go to playlist tracks table app.track_table.context = Some(TrackTableContext::PlaylistSearch); let playlist_id = playlist.id.to_owned(); @@ -321,7 +320,7 @@ fn handle_recommended_tracks(app: &mut App) { SearchResultBlock::SongSearch => { if let Some(index) = &app.search_results.selected_tracks_index { if let Some(result) = app.search_results.tracks.clone() { - if let Some(track) = result.tracks.items.get(index.to_owned()) { + if let Some(track) = result.items.get(index.to_owned()) { let track_id_list: Option> = match &track.id { Some(id) => Some(vec![id.to_string()]), None => None, @@ -336,7 +335,7 @@ fn handle_recommended_tracks(app: &mut App) { SearchResultBlock::ArtistSearch => { if let Some(index) = &app.search_results.selected_artists_index { if let Some(result) = app.search_results.artists.clone() { - if let Some(artist) = result.artists.items.get(index.to_owned()) { + if let Some(artist) = result.items.get(index.to_owned()) { let artist_id_list: Option> = Some(vec![artist.id.clone()]); app.recommendations_context = Some(RecommendationsContext::Artist); app.recommendations_seed = artist.name.clone(); @@ -451,7 +450,7 @@ pub fn handler(key: Key, app: &mut App) { &app.search_results.playlists, app.search_results.selected_playlists_index, ) { - let selected_playlist = &playlists.playlists.items[selected_index].name; + let selected_playlist = &playlists.items[selected_index].name; app.dialog = Some(selected_playlist.clone()); app.confirm = false; diff --git a/src/handlers/track_table.rs b/src/handlers/track_table.rs index b9280df2..e86f4ca7 100644 --- a/src/handlers/track_table.rs +++ b/src/handlers/track_table.rs @@ -205,7 +205,6 @@ fn play_random_song(app: &mut App) { ) { (Some(selected_playlist_index), Some(playlist_result)) => { if let Some(selected_playlist) = playlist_result - .playlists .items .get(selected_playlist_index.to_owned()) { @@ -382,7 +381,6 @@ fn on_enter(app: &mut App) { ) { (Some(selected_playlist_index), Some(playlist_result)) => { if let Some(selected_playlist) = playlist_result - .playlists .items .get(selected_playlist_index.to_owned()) { diff --git a/src/network.rs b/src/network.rs index 32a61395..6625f1bd 100644 --- a/src/network.rs +++ b/src/network.rs @@ -12,10 +12,12 @@ use rspotify::{ page::Page, playlist::{PlaylistTrack, SimplifiedPlaylist}, recommend::Recommendations, + search::SearchResult, track::FullTrack, + PlayingItem, }, oauth2::{SpotifyClientCredentials, SpotifyOAuth, TokenInfo}, - senum::{Country, RepeatState}, + senum::{Country, RepeatState, SearchType}, util::get_token, }; use serde_json::{map::Map, Value}; @@ -293,18 +295,23 @@ impl<'a> Network<'a> { } async fn get_current_playback(&mut self) { - let context = self.spotify.current_playback(None).await; + let context = self.spotify.current_playback(None, None).await; if let Ok(Some(c)) = context { let mut app = self.app.lock().await; app.current_playback_context = Some(c.clone()); app.instant_since_last_current_playback_poll = Instant::now(); - if let Some(track_id) = &c.item.and_then(|track| track.id) { - app.dispatch(IoEvent::CurrentUserSavedTracksContains(vec![ - track_id.to_owned() - ])); - } + if let Some(item) = c.item { + match item { + PlayingItem::Track(track) => { + if let Some(track_id) = track.id { + app.dispatch(IoEvent::CurrentUserSavedTracksContains(vec![track_id])); + }; + } + PlayingItem::Episode(_episode) => {} + } + }; } let mut app = self.app.lock().await; @@ -413,45 +420,66 @@ impl<'a> Network<'a> { } async fn get_search_results(&mut self, search_term: String, country: Option) { - let search_track = self - .spotify - .search_track(&search_term, self.small_search_limit, 0, country); + let search_track = self.spotify.search( + &search_term, + SearchType::Track, + self.small_search_limit, + 0, + country, + None, + ); - let search_artist = - self - .spotify - .search_artist(&search_term, self.small_search_limit, 0, country); + let search_artist = self.spotify.search( + &search_term, + SearchType::Artist, + self.small_search_limit, + 0, + country, + None, + ); - let search_album = self - .spotify - .search_album(&search_term, self.small_search_limit, 0, country); + let search_album = self.spotify.search( + &search_term, + SearchType::Album, + self.small_search_limit, + 0, + country, + None, + ); - let search_playlist = - self - .spotify - .search_playlist(&search_term, self.small_search_limit, 0, country); + let search_playlist = self.spotify.search( + &search_term, + SearchType::Playlist, + self.small_search_limit, + 0, + country, + None, + ); // Run the futures concurrently match try_join!(search_track, search_artist, search_album, search_playlist) { - Ok((track_results, artist_results, album_results, playlist_results)) => { + Ok(( + SearchResult::Tracks(track_results), + SearchResult::Artists(artist_results), + SearchResult::Albums(album_results), + SearchResult::Playlists(playlist_results), + )) => { let mut app = self.app.lock().await; - let artist_ids = artist_results - .artists + let artist_ids = album_results .items .iter() - .map(|item| item.id.to_owned()) + .filter_map(|item| item.id.to_owned()) .collect(); // Check if these artists are followed app.dispatch(IoEvent::UserArtistFollowCheck(artist_ids)); - let mut album_ids: Vec = Vec::new(); - album_results.albums.items.iter().for_each(|item| { - if let Some(id) = &item.id { - album_ids.push(id.to_owned()); - } - }); + let album_ids = album_results + .items + .iter() + .filter_map(|album| album.id.to_owned()) + .collect(); // Check if these albums are saved app.dispatch(IoEvent::CurrentUserSavedAlbumsContains(album_ids)); @@ -464,6 +492,7 @@ impl<'a> Network<'a> { Err(e) => { self.handle_error(anyhow!(e)).await; } + _ => {} }; } @@ -1039,12 +1068,18 @@ impl<'a> Network<'a> { match self .spotify - .search_playlist(&search_string, self.large_search_limit, 0, country) + .search( + &search_string, + SearchType::Playlist, + self.large_search_limit, + 0, + country, + None, + ) .await { - Ok(mut search_playlists) => { + Ok(SearchResult::Playlists(mut search_playlists)) => { let mut filtered_playlists = search_playlists - .playlists .items .iter() .filter(|playlist| playlist.owner.id == SPOTIFY_ID && playlist.name == search_string) @@ -1061,16 +1096,17 @@ impl<'a> Network<'a> { .items .append(&mut filtered_playlists); } else { - search_playlists.playlists.items = filtered_playlists; + search_playlists.items = filtered_playlists; app .library .made_for_you_playlists - .add_pages(search_playlists.playlists); + .add_pages(search_playlists); } } Err(e) => { self.handle_error(anyhow!(e)).await; } + _ => {} } } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 0572958a..f8a99915 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -9,6 +9,7 @@ use super::{ banner::BANNER, }; use help::get_help_docs; +use rspotify::model::PlayingItem; use rspotify::senum::RepeatState; use tui::{ backend::Backend, @@ -317,12 +318,16 @@ where let currently_playing_id = app .current_playback_context .clone() - .and_then(|context| context.item.and_then(|item| item.id)) + .and_then(|context| { + context.item.and_then(|item| match item { + PlayingItem::Track(track) => track.id, + PlayingItem::Episode(episode) => Some(episode.id), + }) + }) .unwrap_or_else(|| "".to_string()); let songs = match &app.search_results.tracks { - Some(r) => r - .tracks + Some(tracks) => tracks .items .iter() .map(|item| { @@ -354,8 +359,7 @@ where ); let artists = match &app.search_results.artists { - Some(r) => r - .artists + Some(artists) => artists .items .iter() .map(|item| { @@ -388,8 +392,7 @@ where .split(chunks[1]); let albums = match &app.search_results.albums { - Some(r) => r - .albums + Some(albums) => albums .items .iter() .map(|item| { @@ -421,8 +424,7 @@ where ); let playlists = match &app.search_results.playlists { - Some(r) => r - .playlists + Some(playlists) => playlists .items .iter() .map(|item| item.name.to_owned()) @@ -814,19 +816,35 @@ where .title(&title) .title_style(get_color(highlight_state, app.user_config.theme)) .border_style(get_color(highlight_state, app.user_config.theme)); + f.render_widget(title_block, layout_chunk); - let track_name = if app - .liked_song_ids_set - .contains(&track_item.id.clone().unwrap_or_else(|| "".to_string())) - { - format!("β™₯ {}", &track_item.name) + let (item_id, name, duration_ms) = match track_item { + PlayingItem::Track(track) => ( + track.id.to_owned().unwrap_or_else(|| "".to_string()), + track.name.to_owned(), + track.duration_ms, + ), + PlayingItem::Episode(episode) => ( + episode.id.to_owned(), + episode.name.to_owned(), + episode.duration_ms, + ), + }; + + let track_name = if app.liked_song_ids_set.contains(&item_id) { + format!("β™₯ {}", name) } else { - track_item.name.clone() + name + }; + + let play_bar_text = match track_item { + PlayingItem::Track(track) => create_artist_string(&track.artists), + PlayingItem::Episode(episode) => format!("{} - {}", episode.name, episode.show.name), }; let lines = [Text::styled( - create_artist_string(&track_item.artists), + play_bar_text, Style::default().fg(app.user_config.theme.playbar_text), )]; @@ -840,10 +858,9 @@ where ), ); f.render_widget(artist, chunks[0]); - let perc = get_track_progress_percentage(app.song_progress_ms, track_item.duration_ms); + let perc = get_track_progress_percentage(app.song_progress_ms, duration_ms); - let song_progress_label = - display_track_progress(app.song_progress_ms, track_item.duration_ms); + let song_progress_label = display_track_progress(app.song_progress_ms, duration_ms); let song_progress = Gauge::default() .block(Block::default().title("")) .style( @@ -1015,7 +1032,13 @@ where .map(|top_track| { let mut name = String::new(); if let Some(context) = &app.current_playback_context { - if context.item.as_ref().and_then(|item| item.id.as_ref()) == top_track.id.as_ref() { + let track_id = match &context.item { + Some(PlayingItem::Track(track)) => track.id.to_owned(), + Some(PlayingItem::Episode(episode)) => Some(episode.id.to_owned()), + _ => None, + }; + + if track_id == top_track.id { name.push_str("β–Ά "); } }; @@ -1434,13 +1457,14 @@ fn draw_table( { let selected_style = get_color(highlight_state, app.user_config.theme).modifier(Modifier::BOLD); - let track_playing_index = match &app.current_playback_context { - Some(ctx) => items.iter().position(|t| match &ctx.item { - Some(item) => Some(t.id.to_owned()) == item.id, - None => false, - }), - None => None, - }; + let track_playing_index = app.current_playback_context.to_owned().and_then(|ctx| { + ctx.item.and_then(|item| match item { + PlayingItem::Track(track) => items + .iter() + .position(|item| track.id.to_owned().map(|id| id == item.id).unwrap_or(false)), + PlayingItem::Episode(_episode) => None, + }) + }); let (title, header) = table_layout; From d4bb2a9c490f2aabe5f1353d9a75e379be50e0ce Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 09:07:31 +0100 Subject: [PATCH 130/311] Bump dirs from 2.0.2 to 3.0.1 (#520) Bumps [dirs](https://github.com/soc/dirs-rs) from 2.0.2 to 3.0.1. - [Release notes](https://github.com/soc/dirs-rs/releases) - [Commits](https://github.com/soc/dirs-rs/commits) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 5 ++--- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 223b4453..20654881 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -363,11 +363,10 @@ dependencies = [ [[package]] name = "dirs" -version = "2.0.2" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" +checksum = "142995ed02755914747cc6ca76fc7e4583cd18578746716d0508ea6ed558b9ff" dependencies = [ - "cfg-if", "dirs-sys", ] diff --git a/Cargo.toml b/Cargo.toml index 9933d556..a3ee47a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ tui = { version = "0.9.5", features = ["crossterm"], default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" -dirs = "2.0.2" +dirs = "3.0.1" clap = "2.33.1" unicode-width = "0.1.8" backtrace = "0.3.49" From 5cf5599b22a3b3bb29d15f0d36e8e6cfcaa8ca46 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 09:07:55 +0100 Subject: [PATCH 131/311] Bump serde_json from 1.0.56 to 1.0.57 (#543) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.56 to 1.0.57. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.56...v1.0.57) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 20654881..e3105f46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1597,9 +1597,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3433e879a558dde8b5e8feb2a04899cf34fdde1fafb894687e52105fc1162ac3" +checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" dependencies = [ "itoa", "ryu", From f593886991e14c226598ede86517919f78a37533 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 09:08:18 +0100 Subject: [PATCH 132/311] Bump anyhow from 1.0.31 to 1.0.32 (#544) Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.31 to 1.0.32. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.31...1.0.32) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e3105f46..15ab6611 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,9 +35,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f" +checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" [[package]] name = "arc-swap" diff --git a/Cargo.toml b/Cargo.toml index a3ee47a6..bb00aca4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ clipboard = "0.5.0" crossterm = "0.17" tokio = { version = "0.2", features = ["full"] } rand = "0.7.3" -anyhow = "1.0.31" +anyhow = "1.0.32" [[bin]] bench = false From 56a1f2c86536d703902d3d2d9f3f77a6b553bda4 Mon Sep 17 00:00:00 2001 From: Onielfa Date: Mon, 17 Aug 2020 10:11:25 +0200 Subject: [PATCH 133/311] =?UTF-8?q?Show=20=E2=99=A5=20next=20to=20album=20?= =?UTF-8?q?name=20in=20saved=20list=20(#540)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ui/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/mod.rs b/src/ui/mod.rs index f8a99915..547ae52c 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1217,7 +1217,7 @@ where .map(|album_page| TableItem { id: album_page.album.id.to_owned(), format: vec![ - album_page.album.name.to_owned(), + format!("β™₯ {}", &album_page.album.name), create_artist_string(&album_page.album.artists), album_page.album.release_date.to_owned(), ], From 0ba268764e54a03c92fdcff6c68f2ad1b2e63d4d Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh <46386452+jwijenbergh@users.noreply.github.com> Date: Mon, 17 Aug 2020 10:14:31 +0200 Subject: [PATCH 134/311] Document Nix support (#545) --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index f8e3a868..286bb006 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ The terminal in the demo above is using the [Rigel theme](https://rigel.netlify. - [Homebrew](#homebrew) - [Snap](#snap) - [AUR](#aur) + - [Nix](#nix) - [Void Linux](#void-linux) - [Fedora/CentOS](#fedora-centos) - [Cargo](#cargo) @@ -82,6 +83,14 @@ For those on Arch Linux you can find the package on AUR [here](https://aur.archl yay -S spotify-tui ``` +### Nix +Available as the package `spotify-tui`. To install run: +```bash +nix-env -iA nixpkgs.spotify-tui +``` +Where `nixpkgs` is the channel name in your configuration. For a more up-to-date installation, use the unstable channel. +It is also possible to add the package to `environment.systemPackages` (for NixOS), or `home.packages` when using [home-manager](https://github.com/rycee/home-manager). + ### Void Linux Available on the official repositories. To install, run From 4167bb28f734d16c774aff1d55970a839f347305 Mon Sep 17 00:00:00 2001 From: usrme Date: Mon, 17 Aug 2020 11:16:04 +0300 Subject: [PATCH 135/311] Add additional line of help to show that 'w' can be used to save/like an album (#548) * Fix typo from plural to singular * Add additional line of help to show that 'w' can be used to save/like an album --- src/ui/help.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ui/help.rs b/src/ui/help.rs index 6bdf0f53..416fbcf4 100644 --- a/src/ui/help.rs +++ b/src/ui/help.rs @@ -104,7 +104,8 @@ pub fn get_help_docs() -> Vec> { ], vec!["Delete saved album", "D", "Library -> Albums"], vec!["Delete saved playlist", "D", "Playlist"], - vec!["Follow an artists/playlist", "w", "Search result"], + vec!["Follow an artist/playlist", "w", "Search result"], + vec!["Save (like) album to library", "w", "Search result"], vec!["Play random song in playlist", "S", "Selected Playlist"], ] } From d55f9b34514dc6039167acffb12bd6b96e2a6213 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 09:16:32 +0100 Subject: [PATCH 136/311] docs: add onielfa as a contributor (#556) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index f482d83a..f47de575 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -547,6 +547,15 @@ "contributions": [ "code" ] + }, + { + "login": "onielfa", + "name": "Onielfa", + "avatar_url": "https://avatars0.githubusercontent.com/u/4358172?v=4", + "profile": "https://github.com/onielfa", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 286bb006..311c7913 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-59-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-60-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -368,6 +368,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Ricardo Holguin

πŸ’»
Keisuke Toyota

πŸ’»
Craig Astill

πŸ’» +
Onielfa

πŸ’» From 11328785c5d881717d9e23a4ca11c04bcfaeec32 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 09:17:48 +0100 Subject: [PATCH 137/311] docs: add jwijenbergh as a contributor (#557) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> From 52270a3c57dc6452548bf4456e3b40d98b5ebf63 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 17 Aug 2020 09:23:09 +0100 Subject: [PATCH 138/311] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64392a17..f22fefd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## [Unreleased] +- Show β™₯ next to album name in saved list [#540](https://github.com/Rigellute/spotify-tui/pull/540) +- Add additional line of help to show that 'w' can be used to save/like an album [#548](https://github.com/Rigellute/spotify-tui/pull/548) + ## [0.21.0] - 2020-07-24 ### Fixed From a0cef1678ebe82658511d95d96ac4234026c5da9 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 17 Aug 2020 09:23:19 +0100 Subject: [PATCH 139/311] Add config to skip CI based on commit message The all-contributors bot creates commits with `[skip ci]` messages. And I want GitHub actions to respect the skip! --- .github/workflows/ci.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 546746a2..75058c5a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,14 +6,19 @@ on: name: Continuous Integration jobs: - # Workaround for making Github Actions skip commits found here - # https://github.com/srz-zumix/ci-skip/blob/master/docs/github/WORKAROUND.md - # NOTE: this this only skips CI on `push` events, not from pull_request + # Workaround for making Github Actions skip based on commit message `[skip ci]` + # Source https://gist.github.com/ybiquitous/c80f15c18319c63cae8447a3be341267 prepare: runs-on: ubuntu-latest - if: "! contains(github.event.head_commit.message, '[skip ci]')" + if: | + !contains(format('{0} {1} {2}', github.event.head_commit.message, github.event.pull_request.title, github.event.pull_request.body), '[skip ci]') steps: - - run: echo "${{ github.event.head_commit.message }}" + - run: | + cat <<'MESSAGE' + github.event_name: ${{ toJson(github.event_name) }} + github.event: + ${{ toJson(github.event) }} + MESSAGE check: name: Check From c8e6eb63fb844f8b622a9cb6c572fa4a9c37c9a3 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 09:24:39 +0100 Subject: [PATCH 140/311] docs: add usrme as a contributor (#558) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index f47de575..33748d19 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -556,6 +556,15 @@ "contributions": [ "code" ] + }, + { + "login": "usrme", + "name": "usrme", + "avatar_url": "https://avatars3.githubusercontent.com/u/5902545?v=4", + "profile": "https://usrme.xyz", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 311c7913..0f202f0a 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-60-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-61-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -369,6 +369,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Keisuke Toyota

πŸ’»
Craig Astill

πŸ’»
Onielfa

πŸ’» +
usrme

πŸ“– From 08e7decdf29b9542d846424da1f85d69e8374d50 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 09:25:03 +0100 Subject: [PATCH 141/311] Bump serde from 1.0.114 to 1.0.115 (#552) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.114 to 1.0.115. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.114...v1.0.115) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 15ab6611..15e4ea14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1577,18 +1577,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.114" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" +checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.114" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" +checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48" dependencies = [ "proc-macro2 1.0.19", "quote 1.0.7", From 2e926a85200fa82ba338842642c854376d26af5b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 09:25:25 +0100 Subject: [PATCH 142/311] Bump clap from 2.33.1 to 2.33.3 (#555) Bumps [clap](https://github.com/clap-rs/clap) from 2.33.1 to 2.33.3. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/commits) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 15e4ea14..b8948a44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -199,9 +199,9 @@ dependencies = [ [[package]] name = "clap" -version = "2.33.1" +version = "2.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ "ansi_term", "atty", diff --git a/Cargo.toml b/Cargo.toml index bb00aca4..10f725d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" dirs = "3.0.1" -clap = "2.33.1" +clap = "2.33.3" unicode-width = "0.1.8" backtrace = "0.3.49" clipboard = "0.5.0" From a3e871b41f68726ef04a9d461382ff83a8b60e3c Mon Sep 17 00:00:00 2001 From: Sergey A <7361274+murlakatamenka@users.noreply.github.com> Date: Mon, 17 Aug 2020 11:26:09 +0300 Subject: [PATCH 143/311] Add Home and End buttons (#550) --- src/handlers/input.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/handlers/input.rs b/src/handlers/input.rs index 702141c4..81589e08 100644 --- a/src/handlers/input.rs +++ b/src/handlers/input.rs @@ -40,14 +40,14 @@ pub fn handler(key: Key, app: &mut App) { app.input_idx = word_start; app.input_cursor_position -= deleted_len; } - Key::Ctrl('e') => { + Key::End | Key::Ctrl('e') => { app.input_idx = app.input.len(); let input_string: String = app.input.iter().collect(); app.input_cursor_position = UnicodeWidthStr::width(input_string.as_str()) .try_into() .unwrap(); } - Key::Ctrl('a') => { + Key::Home | Key::Ctrl('a') => { app.input_idx = 0; app.input_cursor_position = 0; } From e9b3077087cb7521183e3621694eef40fcef7cd7 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 17 Aug 2020 09:27:21 +0100 Subject: [PATCH 144/311] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f22fefd6..d2b44d55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Show β™₯ next to album name in saved list [#540](https://github.com/Rigellute/spotify-tui/pull/540) - Add additional line of help to show that 'w' can be used to save/like an album [#548](https://github.com/Rigellute/spotify-tui/pull/548) +- Add handling Home and End buttons in user input [#550](https://github.com/Rigellute/spotify-tui/pull/550) ## [0.21.0] - 2020-07-24 From 17ae37095f0a82d597c04596e4cc75775f11b028 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 09:31:10 +0100 Subject: [PATCH 145/311] docs: add murlakatamenka as a contributor (#559) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 33748d19..f87a3d67 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -565,6 +565,15 @@ "contributions": [ "doc" ] + }, + { + "login": "murlakatamenka", + "name": "Sergey A.", + "avatar_url": "https://avatars2.githubusercontent.com/u/7361274?v=4", + "profile": "https://github.com/murlakatamenka", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 0f202f0a..a6be65a0 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-61-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-62-orange.svg?style=flat-square)](#contributors-) A Spotify client for the terminal written in Rust. @@ -370,6 +370,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Craig Astill

πŸ’»
Onielfa

πŸ’»
usrme

πŸ“– +
Sergey A.

πŸ’» From f20a9ed69de0f2c1c80fbed6600a450788766e18 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 24 Aug 2020 10:11:22 +0100 Subject: [PATCH 146/311] Add twitter badge to README --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a6be65a0..c6b037ff 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,13 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) + [![All Contributors](https://img.shields.io/badge/all_contributors-62-orange.svg?style=flat-square)](#contributors-) + +[![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) + A Spotify client for the terminal written in Rust. ![Demo](https://user-images.githubusercontent.com/12150276/75177190-91d4ab00-572d-11ea-80bd-c5e28c7b17ad.gif) @@ -84,10 +88,13 @@ yay -S spotify-tui ``` ### Nix + Available as the package `spotify-tui`. To install run: + ```bash nix-env -iA nixpkgs.spotify-tui ``` + Where `nixpkgs` is the channel name in your configuration. For a more up-to-date installation, use the unstable channel. It is also possible to add the package to `environment.systemPackages` (for NixOS), or `home.packages` when using [home-manager](https://github.com/rycee/home-manager). @@ -135,7 +142,7 @@ If you are using the Windows Subsystem for Linux, you'll need to [install additi ### Windows 10 -#### Scoop installer +#### Scoop installer First, make sure scoop installer is on your windows box, for instruction please visit [scoop.sh](https://scoop.sh) @@ -376,6 +383,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d + This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! From 81e357e21826e2b61278175ccd68077febbdc6df Mon Sep 17 00:00:00 2001 From: "Peter K. Moss" Date: Tue, 1 Sep 2020 14:16:53 +0200 Subject: [PATCH 147/311] Issue #490 updated tui to 0.10.0 and added playbar_progress_text option (#564) * Bump to tui v. 0.10.0, one line needs fixing * Compiles with tui 0.10.0, ui needs work * home layout fixed, playbar needs work * playbar layout now back to normal and label is using playbar_progress_text * Formatting * Fix audio analysis after tui upgrade Co-authored-by: Alexander Keliris --- Cargo.lock | 17 +-- Cargo.toml | 2 +- src/ui/audio_analysis.rs | 42 +++---- src/ui/mod.rs | 236 +++++++++++++++++++++++---------------- src/user_config.rs | 4 + 5 files changed, 167 insertions(+), 134 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8948a44..91edf028 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -769,15 +769,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "0.4.6" @@ -1492,7 +1483,7 @@ dependencies = [ "dotenv", "env_logger", "failure", - "itertools 0.8.2", + "itertools", "lazy_static", "log", "percent-encoding 1.0.1", @@ -1924,15 +1915,13 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "tui" -version = "0.9.5" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9533d39bef0ae8f510e8a99d78702e68d1bbf0b98a78ec9740509d287010ae1e" +checksum = "a977b0bb2e2033a6fef950f218f13622c3c34e59754b704ce3492dedab1dfe95" dependencies = [ "bitflags", "cassowary", "crossterm", - "either", - "itertools 0.9.0", "unicode-segmentation", "unicode-width", ] diff --git a/Cargo.toml b/Cargo.toml index 10f725d2..9e30dfa9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ license = "MIT OR Apache-2.0" [dependencies] rspotify = "0.10.0" -tui = { version = "0.9.5", features = ["crossterm"], default-features = false } +tui = { version = "0.10.0", features = ["crossterm"], default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" diff --git a/src/ui/audio_analysis.rs b/src/ui/audio_analysis.rs index 609986f1..307c3ee4 100644 --- a/src/ui/audio_analysis.rs +++ b/src/ui/audio_analysis.rs @@ -4,7 +4,8 @@ use tui::{ backend::Backend, layout::{Constraint, Direction, Layout}, style::Style, - widgets::{BarChart, Block, Borders, Paragraph, Text}, + text::{Span, Spans}, + widgets::{BarChart, Block, Borders, Paragraph}, Frame, }; const PITCHES: [&str; 12] = [ @@ -24,10 +25,12 @@ where .split(f.size()); let analysis_block = Block::default() - .title("Analysis") + .title(Span::styled( + "Analysis", + Style::default().fg(app.user_config.theme.inactive), + )) .borders(Borders::ALL) - .border_style(Style::default().fg(app.user_config.theme.inactive)) - .title_style(Style::default().fg(app.user_config.theme.inactive)); + .border_style(Style::default().fg(app.user_config.theme.inactive)); let white = Style::default().fg(app.user_config.theme.text); let gray = Style::default().fg(app.user_config.theme.inactive); @@ -38,20 +41,17 @@ where let bar_chart_block = Block::default() .borders(Borders::ALL) .style(white) - .title(bar_chart_title) - .title_style(gray) + .title(Span::styled(bar_chart_title, gray)) .border_style(gray); - let analysis_text = [Text::raw("No analysis available")]; let empty_analysis_block = || { - Paragraph::new(analysis_text.iter()) - .block(analysis_block) + Paragraph::new("No analysis available") + .block(analysis_block.clone()) .style(Style::default().fg(app.user_config.theme.text)) }; - let pitch_text = [Text::raw("No pitch information available")]; let empty_pitches_block = || { - Paragraph::new(pitch_text.iter()) - .block(bar_chart_block) + Paragraph::new("No pitch information available") + .block(bar_chart_block.clone()) .style(Style::default().fg(app.user_config.theme.text)) }; @@ -76,24 +76,24 @@ where .find(|section| section.start >= progress_seconds); if let (Some(segment), Some(section)) = (segment, section) { - let texts = [ - Text::raw(format!( - "Tempo: {} (confidence {:.0}%)\n", + let texts = vec![ + Spans::from(format!( + "Tempo: {} (confidence {:.0}%)", section.tempo, section.tempo_confidence * 100.0 )), - Text::raw(format!( - "Key: {} (confidence {:.0}%)\n", + Spans::from(format!( + "Key: {} (confidence {:.0}%)", PITCHES.get(section.key as usize).unwrap_or(&PITCHES[0]), section.key_confidence * 100.0 )), - Text::raw(format!( - "Time Signature: {}/4 (confidence {:.0}%)\n", + Spans::from(format!( + "Time Signature: {}/4 (confidence {:.0}%)", section.time_signature, section.time_signature_confidence * 100.0 )), ]; - let p = Paragraph::new(texts.iter()) + let p = Paragraph::new(texts) .block(analysis_block) .style(Style::default().fg(app.user_config.theme.text)); f.render_widget(p, chunks[0]); @@ -118,7 +118,7 @@ where .block(bar_chart_block) .data(&data) .bar_width(width as u16) - .style(Style::default().fg(app.user_config.theme.analysis_bar)) + .bar_style(Style::default().fg(app.user_config.theme.analysis_bar)) .value_style( Style::default() .fg(app.user_config.theme.analysis_bar_text) diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 547ae52c..2d76b1e8 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -15,7 +15,8 @@ use tui::{ backend::Backend, layout::{Alignment, Constraint, Direction, Layout, Rect}, style::{Modifier, Style}, - widgets::{Block, Borders, Clear, Gauge, List, ListState, Paragraph, Row, Table, Text}, + text::{Span, Spans, Text}, + widgets::{Block, Borders, Clear, Gauge, List, ListItem, ListState, Paragraph, Row, Table, Wrap}, Frame, }; use util::{ @@ -95,8 +96,7 @@ where Block::default() .borders(Borders::ALL) .style(white) - .title("Help (press to go back)") - .title_style(gray) + .title(Span::styled("Help (press to go back)", gray)) .border_style(gray), ) .style(Style::default().fg(app.user_config.theme.text)) @@ -125,12 +125,14 @@ where ); let input_string: String = app.input.iter().collect(); - let lines = [Text::raw(&input_string)]; - let input = Paragraph::new(lines.iter()).block( + let lines = Text::from((&input_string).as_str()); + let input = Paragraph::new(lines).block( Block::default() .borders(Borders::ALL) - .title("Search") - .title_style(get_color(highlight_state, app.user_config.theme)) + .title(Span::styled( + "Search", + get_color(highlight_state, app.user_config.theme), + )) .border_style(get_color(highlight_state, app.user_config.theme)), ); f.render_widget(input, chunks[0]); @@ -143,13 +145,12 @@ where }; let block = Block::default() - .title("Help") + .title(Span::styled("Help", Style::default().fg(help_block_text.0))) .borders(Borders::ALL) - .border_style(Style::default().fg(help_block_text.0)) - .title_style(Style::default().fg(help_block_text.0)); + .border_style(Style::default().fg(help_block_text.0)); - let lines = [Text::raw(help_block_text.1)]; - let help = Paragraph::new(lines.iter()) + let lines = Text::from(help_block_text.1); + let help = Paragraph::new(lines) .block(block) .style(Style::default().fg(help_block_text.0)); f.render_widget(help, chunks[1]); @@ -770,7 +771,14 @@ where { let chunks = Layout::default() .direction(Direction::Vertical) - .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref()) + .constraints( + [ + Constraint::Percentage(50), + Constraint::Percentage(25), + Constraint::Percentage(25), + ] + .as_ref(), + ) .margin(1) .split(layout_chunk); @@ -813,8 +821,10 @@ where let title_block = Block::default() .borders(Borders::ALL) - .title(&title) - .title_style(get_color(highlight_state, app.user_config.theme)) + .title(Span::styled( + &title, + get_color(highlight_state, app.user_config.theme), + )) .border_style(get_color(highlight_state, app.user_config.theme)); f.render_widget(title_block, layout_chunk); @@ -843,35 +853,38 @@ where PlayingItem::Episode(episode) => format!("{} - {}", episode.name, episode.show.name), }; - let lines = [Text::styled( + let lines = Text::from(Span::styled( play_bar_text, Style::default().fg(app.user_config.theme.playbar_text), - )]; + )); - let artist = Paragraph::new(lines.iter()) + let artist = Paragraph::new(lines) .style(Style::default().fg(app.user_config.theme.playbar_text)) .block( - Block::default().title(&track_name).title_style( + Block::default().title(Span::styled( + &track_name, Style::default() .fg(app.user_config.theme.selected) - .modifier(Modifier::BOLD), - ), + .add_modifier(Modifier::BOLD), + )), ); f.render_widget(artist, chunks[0]); let perc = get_track_progress_percentage(app.song_progress_ms, duration_ms); let song_progress_label = display_track_progress(app.song_progress_ms, duration_ms); let song_progress = Gauge::default() - .block(Block::default().title("")) - .style( + .gauge_style( Style::default() .fg(app.user_config.theme.playbar_progress) .bg(app.user_config.theme.playbar_background) - .modifier(Modifier::ITALIC | Modifier::BOLD), + .add_modifier(Modifier::ITALIC | Modifier::BOLD), ) .percent(perc) - .label(&song_progress_label); - f.render_widget(song_progress, chunks[1]); + .label(Span::styled( + &song_progress_label, + Style::default().fg(app.user_config.theme.playbar_progress_text), + )); + f.render_widget(song_progress, chunks[2]); } } } @@ -886,10 +899,10 @@ where .margin(5) .split(f.size()); - let playing_text = vec![ - Text::raw("Api response: "), - Text::styled(&app.api_error, Style::default().fg(app.user_config.theme.error_text)), - Text::styled( + let playing_text = Spans::from(vec![ + Span::raw("Api response: "), + Span::styled(&app.api_error, Style::default().fg(app.user_config.theme.error_text)), + Span::styled( " If you are trying to play a track, please check that @@ -899,24 +912,26 @@ If you are trying to play a track, please check that ", Style::default().fg(app.user_config.theme.text), ), - Text::styled(" + Span::styled(" Hint: a playback device must be either an official spotify client or a light weight alternative such as spotifyd ", Style::default().fg(app.user_config.theme.hint)), - Text::styled( + Span::styled( "\nPress to return", Style::default().fg(app.user_config.theme.inactive), ), - ]; + ]); - let playing_paragraph = Paragraph::new(playing_text.iter()) - .wrap(true) + let playing_paragraph = Paragraph::new(playing_text) + .wrap(Wrap { trim: true }) .style(Style::default().fg(app.user_config.theme.text)) .block( Block::default() .borders(Borders::ALL) - .title("Error") - .title_style(Style::default().fg(app.user_config.theme.error_border)) + .title(Span::styled( + "Error", + Style::default().fg(app.user_config.theme.error_border), + )) .border_style(Style::default().fg(app.user_config.theme.error_border)), ); f.render_widget(playing_paragraph, chunks[0]); @@ -939,9 +954,11 @@ where ); let welcome = Block::default() - .title("Welcome!") + .title(Span::styled( + "Welcome!", + get_color(highlight_state, app.user_config.theme), + )) .borders(Borders::ALL) - .title_style(get_color(highlight_state, app.user_config.theme)) .border_style(get_color(highlight_state, app.user_config.theme)); f.render_widget(welcome, layout_chunk); @@ -955,28 +972,29 @@ where changelog.replace("\n## [Unreleased]\n", "") }; - let top_text = vec![Text::styled( - BANNER, - Style::default().fg(app.user_config.theme.banner), - )]; + // Banner text with correct styling + let mut top_text = Text::from(BANNER); + top_text.patch_style(Style::default().fg(app.user_config.theme.banner)); - let bottom_text = vec![ - Text::raw("\nPlease report any bugs or missing features to https://github.com/Rigellute/spotify-tui\n\n"), - Text::raw(clean_changelog) - ]; + let bottom_text_raw = format!( + "{}{}", + "\nPlease report any bugs or missing features to https://github.com/Rigellute/spotify-tui\n\n", + clean_changelog + ); + let bottom_text = Text::from(bottom_text_raw.as_str()); // Contains the banner - let top_text = Paragraph::new(top_text.iter()) + let top_text = Paragraph::new(top_text) .style(Style::default().fg(app.user_config.theme.text)) .block(Block::default()); f.render_widget(top_text, chunks[0]); // CHANGELOG - let bottom_text = Paragraph::new(bottom_text.iter()) + let bottom_text = Paragraph::new(bottom_text) .style(Style::default().fg(app.user_config.theme.text)) .block(Block::default()) - .wrap(true) - .scroll(app.home_scroll); + .wrap(Wrap { trim: false }) + .scroll((app.home_scroll, 0)); f.render_widget(bottom_text, chunks[1]); } @@ -995,17 +1013,19 @@ fn draw_not_implemented_yet( current_route.hovered_block == block, ); let display_block = Block::default() - .title(title) + .title(Span::styled( + title, + get_color(highlight_state, app.user_config.theme), + )) .borders(Borders::ALL) - .title_style(get_color(highlight_state, app.user_config.theme)) .border_style(get_color(highlight_state, app.user_config.theme)); - let text = vec![Text::raw("Not implemented yet!")]; + let text = Text::from("Not implemented yet!"); - let not_implemented = Paragraph::new(text.iter()) + let not_implemented = Paragraph::new(text) .style(Style::default().fg(app.user_config.theme.text)) .block(display_block) - .wrap(true); + .wrap(Wrap { trim: true }); f.render_widget(not_implemented, layout_chunk); } @@ -1122,39 +1142,41 @@ where .margin(5) .split(f.size()); - let device_instructions = [ - Text::raw("To play tracks, please select a device. "), - Text::raw("Use `j/k` or up/down arrow keys to move up and down and to select. "), - Text::raw("Your choice here will be cached so you can jump straight back in when you next open `spotify-tui`. "), - Text::raw("You can change the playback device at any time by pressing `d`."), - ]; + let device_instructions = Spans::from(vec![ + Span::raw("To play tracks, please select a device. "), + Span::raw("Use `j/k` or up/down arrow keys to move up and down and to select. "), + Span::raw("Your choice here will be cached so you can jump straight back in when you next open `spotify-tui`. "), + Span::raw("You can change the playback device at any time by pressing `d`."), + ]); - let instructions = Paragraph::new(device_instructions.iter()) + let instructions = Paragraph::new(device_instructions) .style(Style::default().fg(app.user_config.theme.text)) - .wrap(true) + .wrap(Wrap { trim: true }) .block( - Block::default() - .borders(Borders::NONE) - .title("Welcome to spotify-tui!") - .title_style( - Style::default() - .fg(app.user_config.theme.active) - .modifier(Modifier::BOLD), - ), + Block::default().borders(Borders::NONE).title(Span::styled( + "Welcome to spotify-tui!", + Style::default() + .fg(app.user_config.theme.active) + .add_modifier(Modifier::BOLD), + )), ); f.render_widget(instructions, chunks[0]); - let no_device_message = vec![Text::raw("No devices found: Make sure a device is active")]; + let no_device_message = Span::raw("No devices found: Make sure a device is active"); - let items: Box> = match &app.devices { + let items = match &app.devices { Some(items) => { if items.devices.is_empty() { - Box::new(no_device_message.into_iter()) + vec![ListItem::new(no_device_message)] } else { - Box::new(items.devices.iter().map(|device| Text::raw(&device.name))) + items + .devices + .iter() + .map(|device| ListItem::new(Span::raw(&device.name))) + .collect() } } - None => Box::new(no_device_message.into_iter()), + None => vec![ListItem::new(no_device_message)], }; let mut state = ListState::default(); @@ -1162,16 +1184,18 @@ where let list = List::new(items) .block( Block::default() - .title("Devices") + .title(Span::styled( + "Devices", + Style::default().fg(app.user_config.theme.active), + )) .borders(Borders::ALL) - .title_style(Style::default().fg(app.user_config.theme.active)) .border_style(Style::default().fg(app.user_config.theme.inactive)), ) .style(Style::default().fg(app.user_config.theme.text)) .highlight_style( Style::default() .fg(app.user_config.theme.active) - .modifier(Modifier::BOLD), + .add_modifier(Modifier::BOLD), ); f.render_stateful_widget(list, chunks[1], &mut state); } @@ -1359,16 +1383,26 @@ fn draw_selectable_list( let mut state = ListState::default(); state.select(selected_index); - let list = List::new(items.iter().map(|i| Text::raw(i.as_ref()))) + let lst_items: Vec = items + .iter() + .map(|i| ListItem::new(Span::raw(i.as_ref()))) + .collect(); + + //TODO + let list = List::new(lst_items) .block( Block::default() - .title(title) + .title(Span::styled( + title, + get_color(highlight_state, app.user_config.theme), + )) .borders(Borders::ALL) - .title_style(get_color(highlight_state, app.user_config.theme)) .border_style(get_color(highlight_state, app.user_config.theme)), ) .style(Style::default().fg(app.user_config.theme.text)) - .highlight_style(get_color(highlight_state, app.user_config.theme).modifier(Modifier::BOLD)); + .highlight_style( + get_color(highlight_state, app.user_config.theme).add_modifier(Modifier::BOLD), + ); f.render_stateful_widget(list, layout_chunk, &mut state); } @@ -1403,13 +1437,16 @@ where // suggestion: possibly put this as part of // app.dialog, but would have to introduce lifetime - let text = [ - Text::raw("Are you sure you want to delete\nthe playlist: "), - Text::styled(playlist.as_str(), Style::default().modifier(Modifier::BOLD)), - Text::raw("?"), - ]; + let text = Spans::from(vec![ + Span::raw("Are you sure you want to delete\nthe playlist: "), + Span::styled( + playlist.as_str(), + Style::default().add_modifier(Modifier::BOLD), + ), + Span::raw("?"), + ]); - let text = Paragraph::new(text.iter()).alignment(Alignment::Center); + let text = Paragraph::new(text).alignment(Alignment::Center); f.render_widget(text, vchunks[0]); @@ -1419,8 +1456,8 @@ where .constraints([Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)].as_ref()) .split(vchunks[1]); - let ok_text = [Text::raw("Ok")]; - let ok = Paragraph::new(ok_text.iter()) + let ok_text = Span::raw("Ok"); + let ok = Paragraph::new(ok_text) .style(Style::default().fg(if app.confirm { app.user_config.theme.hovered } else { @@ -1430,8 +1467,8 @@ where f.render_widget(ok, hchunks[0]); - let cancel_text = [Text::raw("Cancel")]; - let cancel = Paragraph::new(cancel_text.iter()) + let cancel_text = Span::raw("Cancel"); + let cancel = Paragraph::new(cancel_text) .style(Style::default().fg(if app.confirm { app.user_config.theme.inactive } else { @@ -1455,7 +1492,8 @@ fn draw_table( ) where B: Backend, { - let selected_style = get_color(highlight_state, app.user_config.theme).modifier(Modifier::BOLD); + let selected_style = + get_color(highlight_state, app.user_config.theme).add_modifier(Modifier::BOLD); let track_playing_index = app.current_playback_context.to_owned().and_then(|ctx| { ctx.item.and_then(|item| match item { @@ -1493,7 +1531,7 @@ fn draw_table( formatted_row[title_idx] = format!("β–Ά {}", &formatted_row[title_idx]); style = Style::default() .fg(app.user_config.theme.active) - .modifier(Modifier::BOLD); + .add_modifier(Modifier::BOLD); } } } @@ -1528,8 +1566,10 @@ fn draw_table( Block::default() .borders(Borders::ALL) .style(Style::default().fg(app.user_config.theme.text)) - .title(title) - .title_style(get_color(highlight_state, app.user_config.theme)) + .title(Span::styled( + title, + get_color(highlight_state, app.user_config.theme), + )) .border_style(get_color(highlight_state, app.user_config.theme)), ) .style(Style::default().fg(app.user_config.theme.text)) diff --git a/src/user_config.rs b/src/user_config.rs index 36b58484..f76c6ea4 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -22,6 +22,7 @@ pub struct UserTheme { pub inactive: Option, pub playbar_background: Option, pub playbar_progress: Option, + pub playbar_progress_text: Option, pub playbar_text: Option, pub selected: Option, pub text: Option, @@ -40,6 +41,7 @@ pub struct Theme { pub inactive: Color, pub playbar_background: Color, pub playbar_progress: Color, + pub playbar_progress_text: Color, pub playbar_text: Color, pub selected: Color, pub text: Color, @@ -59,6 +61,7 @@ impl Default for Theme { inactive: Color::Gray, playbar_background: Color::Black, playbar_progress: Color::LightCyan, + playbar_progress_text: Color::LightCyan, playbar_text: Color::White, selected: Color::LightCyan, text: Color::White, @@ -337,6 +340,7 @@ impl UserConfig { to_theme_item!(inactive); to_theme_item!(playbar_background); to_theme_item!(playbar_progress); + to_theme_item!(playbar_progress_text); to_theme_item!(playbar_text); to_theme_item!(selected); to_theme_item!(text); From 1998c78100f59a6826e8f1ca27fa863fb20d0f0e Mon Sep 17 00:00:00 2001 From: Nick Stockton Date: Sun, 20 Sep 2020 12:01:14 -0400 Subject: [PATCH 148/311] Add basic playbar support for podcasts (#563) --- rustfmt.toml | 1 + src/app.rs | 70 +++++++++++++++++++++++++++++++------------------- src/network.rs | 12 ++++++--- src/ui/help.rs | 4 +-- 4 files changed, 55 insertions(+), 32 deletions(-) diff --git a/rustfmt.toml b/rustfmt.toml index 28781c75..c8283ea6 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1 +1,2 @@ tab_spaces=2 +edition = "2018" diff --git a/src/app.rs b/src/app.rs index d1b427ba..339c2765 100644 --- a/src/app.rs +++ b/src/app.rs @@ -426,15 +426,15 @@ impl App { .as_millis() + u128::from(*progress_ms); - match item { - PlayingItem::Track(track) => { - if elapsed < u128::from(track.duration_ms) { - self.song_progress_ms = elapsed; - } else { - self.song_progress_ms = track.duration_ms.into(); - } - } - PlayingItem::Episode(_episode) => {} + let duration_ms = match item { + PlayingItem::Track(track) => track.duration_ms, + PlayingItem::Episode(episode) => episode.duration_ms, + }; + + if elapsed < u128::from(duration_ms) { + self.song_progress_ms = elapsed; + } else { + self.song_progress_ms = duration_ms.into(); } } } @@ -444,22 +444,20 @@ impl App { item: Some(item), .. }) = &self.current_playback_context { - match item { - PlayingItem::Track(track) => { - let event = if track.duration_ms - self.song_progress_ms as u32 - > self.user_config.behavior.seek_milliseconds - { - IoEvent::Seek( - self.song_progress_ms as u32 + self.user_config.behavior.seek_milliseconds, - ) - } else { - IoEvent::NextTrack - }; - - self.dispatch(event); - } - PlayingItem::Episode(_episode) => {} + let duration_ms = match item { + PlayingItem::Track(track) => track.duration_ms, + PlayingItem::Episode(episode) => episode.duration_ms, }; + + let event = if duration_ms - self.song_progress_ms as u32 + > self.user_config.behavior.seek_milliseconds + { + IoEvent::Seek(self.song_progress_ms as u32 + self.user_config.behavior.seek_milliseconds) + } else { + IoEvent::NextTrack + }; + + self.dispatch(event); } } @@ -606,7 +604,14 @@ impl App { self.handle_error(anyhow!("failed to set clipboard content: {}", e)); } } - PlayingItem::Episode(_episode) => {} + PlayingItem::Episode(episode) => { + if let Err(e) = clipboard.set_contents(format!( + "https://open.spotify.com/episode/{}", + episode.id.to_owned() + )) { + self.handle_error(anyhow!("failed to set clipboard content: {}", e)); + } + } } } } @@ -630,7 +635,14 @@ impl App { self.handle_error(anyhow!("failed to set clipboard content: {}", e)); } } - PlayingItem::Episode(_episode) => {} + PlayingItem::Episode(episode) => { + if let Err(e) = clipboard.set_contents(format!( + "https://open.spotify.com/show/{}", + episode.show.id.to_owned() + )) { + self.handle_error(anyhow!("failed to set clipboard content: {}", e)); + } + } } } } @@ -895,7 +907,11 @@ impl App { self.dispatch(IoEvent::GetAudioAnalysis(uri)); self.push_navigation_stack(RouteId::Analysis, ActiveBlock::Analysis); } - PlayingItem::Episode(_epidose) => {} + PlayingItem::Episode(_episode) => { + // No audio analysis available for podcast uris, so just default to the empty analysis + // view to avoid a 400 error code + self.push_navigation_stack(RouteId::Analysis, ActiveBlock::Analysis); + } } } } diff --git a/src/network.rs b/src/network.rs index 6625f1bd..2a5722bb 100644 --- a/src/network.rs +++ b/src/network.rs @@ -17,7 +17,7 @@ use rspotify::{ PlayingItem, }, oauth2::{SpotifyClientCredentials, SpotifyOAuth, TokenInfo}, - senum::{Country, RepeatState, SearchType}, + senum::{AdditionalType, Country, RepeatState, SearchType}, util::get_token, }; use serde_json::{map::Map, Value}; @@ -295,7 +295,13 @@ impl<'a> Network<'a> { } async fn get_current_playback(&mut self) { - let context = self.spotify.current_playback(None, None).await; + let context = self + .spotify + .current_playback( + None, + Some(vec![AdditionalType::Episode, AdditionalType::Track]), + ) + .await; if let Ok(Some(c)) = context { let mut app = self.app.lock().await; @@ -309,7 +315,7 @@ impl<'a> Network<'a> { app.dispatch(IoEvent::CurrentUserSavedTracksContains(vec![track_id])); }; } - PlayingItem::Episode(_episode) => {} + PlayingItem::Episode(_episode) => { /*should map this to following the podcast show*/ } } }; } diff --git a/src/ui/help.rs b/src/ui/help.rs index 416fbcf4..69ffda60 100644 --- a/src/ui/help.rs +++ b/src/ui/help.rs @@ -22,8 +22,8 @@ pub fn get_help_docs() -> Vec> { vec!["Seek backwards 5 seconds", "<", "General"], vec!["Seek forwards 5 seconds", ">", "General"], vec!["Toggle shuffle", "", "General"], - vec!["Copy url to currently playing song", "c", "General"], - vec!["Copy url to currently playing album", "C", "General"], + vec!["Copy url to currently playing song/episode", "c", "General"], + vec!["Copy url to currently playing album/show", "C", "General"], vec!["Cycle repeat mode", "", "General"], vec![ "Move selection left", From 9fb51191dfa249374ea9c8d39b28dc6d3ed6d790 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Sun, 20 Sep 2020 17:12:25 +0100 Subject: [PATCH 149/311] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2b44d55..84699b66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Show β™₯ next to album name in saved list [#540](https://github.com/Rigellute/spotify-tui/pull/540) - Add additional line of help to show that 'w' can be used to save/like an album [#548](https://github.com/Rigellute/spotify-tui/pull/548) - Add handling Home and End buttons in user input [#550](https://github.com/Rigellute/spotify-tui/pull/550) +- Add basic playbar support for podcasts [#563](https://github.com/Rigellute/spotify-tui/pull/563) ## [0.21.0] - 2020-07-24 From 0ace8889c4fc598ee6e36a5dc2f70c59f6d4c971 Mon Sep 17 00:00:00 2001 From: Hideyuki Okada Date: Mon, 21 Sep 2020 01:29:24 +0900 Subject: [PATCH 150/311] Fix to be able to follow an artist in search result view (#565) --- src/app.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.rs b/src/app.rs index 339c2765..e230b37a 100644 --- a/src/app.rs +++ b/src/app.rs @@ -813,7 +813,7 @@ impl App { if let Some(selected_index) = self.search_results.selected_artists_index { let selected_artist: &FullArtist = &artists.items[selected_index]; let artist_id = selected_artist.id.clone(); - self.dispatch(IoEvent::UserUnfollowArtists(vec![artist_id])); + self.dispatch(IoEvent::UserFollowArtists(vec![artist_id])); } } } From 07bae2943558fda3e2b0ca9c1531bc9764f53abd Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Sun, 20 Sep 2020 17:34:32 +0100 Subject: [PATCH 151/311] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84699b66..4dfc44bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Add additional line of help to show that 'w' can be used to save/like an album [#548](https://github.com/Rigellute/spotify-tui/pull/548) - Add handling Home and End buttons in user input [#550](https://github.com/Rigellute/spotify-tui/pull/550) - Add basic playbar support for podcasts [#563](https://github.com/Rigellute/spotify-tui/pull/563) +- Fix to be able to follow an artist in search result view [#565](https://github.com/Rigellute/spotify-tui/pull/565) ## [0.21.0] - 2020-07-24 From e1ab8e9a72e5d5aea793587c59617e13a2dc7c83 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sun, 20 Sep 2020 17:35:05 +0100 Subject: [PATCH 152/311] docs: add elcih17 as a contributor (#582) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 6 ++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index f87a3d67..857b4004 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -574,6 +574,15 @@ "contributions": [ "code" ] + }, + { + "login": "elcih17", + "name": "Hideyuki Okada", + "avatar_url": "https://avatars3.githubusercontent.com/u/17084445?v=4", + "profile": "https://github.com/elcih17", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index c6b037ff..9f384e79 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) - -[![All Contributors](https://img.shields.io/badge/all_contributors-62-orange.svg?style=flat-square)](#contributors-) - +[![All Contributors](https://img.shields.io/badge/all_contributors-63-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -378,12 +376,12 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Onielfa

πŸ’»
usrme

πŸ“–
Sergey A.

πŸ’» +
Hideyuki Okada

πŸ’» - This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! From c631077042b524f4fe686d94425c2cd8e21fe665 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 22 Sep 2020 09:41:03 +0100 Subject: [PATCH 153/311] Bump crossterm from 0.17.7 to 0.17.8 (#571) Bumps [crossterm](https://github.com/crossterm-rs/crossterm) from 0.17.7 to 0.17.8. - [Release notes](https://github.com/crossterm-rs/crossterm/releases) - [Changelog](https://github.com/crossterm-rs/crossterm/blob/master/CHANGELOG.md) - [Commits](https://github.com/crossterm-rs/crossterm/commits) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 91edf028..233c7854 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -278,9 +278,9 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f4919d60f26ae233e14233cc39746c8c8bb8cd7b05840ace83604917b51b6c7" +checksum = "858085e389f71d31a6909f2b55a56b87d1cb8b168c0f513dcbed5e66a3e1039c" dependencies = [ "bitflags", "crossterm_winapi", From c849d4e8f2062f3d4fa42a77c375a2f45018707c Mon Sep 17 00:00:00 2001 From: kepae Date: Tue, 22 Sep 2020 04:43:56 -0400 Subject: [PATCH 154/311] add 'enable_text_emphasis' behavior config option (#573) --- README.md | 2 ++ src/ui/mod.rs | 7 ++++++- src/user_config.rs | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f384e79..fc669652 100644 --- a/README.md +++ b/README.md @@ -220,6 +220,8 @@ behavior: volume_increment: 10 # The lower the number the higher the "frames per second". You can decrease this number so that the audio visualisation is smoother but this can be expensive! tick_rate_milliseconds: 250 + # Enable text emphasis (typically italic/bold text styling). Disabling this might be important if the terminal config is otherwise restricted and rendering text escapes interferes with the UI. + enable_text_emphasis: true # controls whether to show a loading indicator in the top right of the UI whenever communicating with Spotify API show_loading_indicator: true diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 2d76b1e8..4fb8bad0 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -872,12 +872,17 @@ where let perc = get_track_progress_percentage(app.song_progress_ms, duration_ms); let song_progress_label = display_track_progress(app.song_progress_ms, duration_ms); + let modifier = if app.user_config.behavior.enable_text_emphasis { + Modifier::ITALIC | Modifier::BOLD + } else { + Modifier::empty() + }; let song_progress = Gauge::default() .gauge_style( Style::default() .fg(app.user_config.theme.playbar_progress) .bg(app.user_config.theme.playbar_background) - .add_modifier(Modifier::ITALIC | Modifier::BOLD), + .add_modifier(modifier), ) .percent(perc) .label(Span::styled( diff --git a/src/user_config.rs b/src/user_config.rs index f76c6ea4..99e945df 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -197,6 +197,7 @@ pub struct BehaviorConfigString { pub seek_milliseconds: Option, pub volume_increment: Option, pub tick_rate_milliseconds: Option, + pub enable_text_emphasis: Option, pub show_loading_indicator: Option, } @@ -205,6 +206,7 @@ pub struct BehaviorConfig { pub seek_milliseconds: u32, pub volume_increment: u8, pub tick_rate_milliseconds: u64, + pub enable_text_emphasis: bool, pub show_loading_indicator: bool, } @@ -254,6 +256,7 @@ impl UserConfig { seek_milliseconds: 5 * 1000, volume_increment: 10, tick_rate_milliseconds: 250, + enable_text_emphasis: true, show_loading_indicator: true, }, path_to_config: None, @@ -370,6 +373,10 @@ impl UserConfig { } } + if let Some(text_emphasis) = behavior_config.enable_text_emphasis { + self.behavior.enable_text_emphasis = text_emphasis; + } + if let Some(loading_indicator) = behavior_config.show_loading_indicator { self.behavior.show_loading_indicator = loading_indicator; } From 03a672944a784b88c6964d169c90200125e566c6 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 22 Sep 2020 09:45:58 +0100 Subject: [PATCH 155/311] docs: add kepae as a contributor (#586) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 10 ++++++++++ README.md | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 857b4004..74151e26 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -583,6 +583,16 @@ "contributions": [ "code" ] + }, + { + "login": "kepae", + "name": "kepae", + "avatar_url": "https://avatars2.githubusercontent.com/u/4238598?v=4", + "profile": "https://github.com/kepae", + "contributions": [ + "code", + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index fc669652..61d9b1c5 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-63-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-64-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -380,6 +380,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Sergey A.

πŸ’»
Hideyuki Okada

πŸ’» + +
kepae

πŸ’» πŸ“– + From 26583cdf43bf4d126137c62e63d7891dfe7a8a71 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 22 Sep 2020 09:46:14 +0100 Subject: [PATCH 156/311] Bump serde from 1.0.115 to 1.0.116 (#578) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.115 to 1.0.116. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.115...v1.0.116) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 233c7854..f3baa97e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1568,18 +1568,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.115" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5" +checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.115" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48" +checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" dependencies = [ "proc-macro2 1.0.19", "quote 1.0.7", From 6f8246bd179dd9282dba307abfcf1485ea8c6aa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89rico=20Nogueira=20Rolim?= <34201958+ericonr@users.noreply.github.com> Date: Tue, 22 Sep 2020 05:48:53 -0300 Subject: [PATCH 157/311] Don't add analysis view to stack if already in it. (#580) Before this commit, if a user pressed `v` multiple times, they would have to press `q` the same number of times to get to the previous view. This commit makes it so that an analysis view entry is only pushed into the navigation stack if the current view isn't an analysis one. --- src/app.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/app.rs b/src/app.rs index e230b37a..d06908f9 100644 --- a/src/app.rs +++ b/src/app.rs @@ -903,9 +903,11 @@ impl App { { match item { PlayingItem::Track(track) => { - let uri = track.uri.clone(); - self.dispatch(IoEvent::GetAudioAnalysis(uri)); - self.push_navigation_stack(RouteId::Analysis, ActiveBlock::Analysis); + if self.get_current_route().id != RouteId::Analysis { + let uri = track.uri.clone(); + self.dispatch(IoEvent::GetAudioAnalysis(uri)); + self.push_navigation_stack(RouteId::Analysis, ActiveBlock::Analysis); + } } PlayingItem::Episode(_episode) => { // No audio analysis available for podcast uris, so just default to the empty analysis From c4b355d95a98c370e6f5ffe706b2e7b23a5db43d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 22 Sep 2020 09:49:50 +0100 Subject: [PATCH 158/311] docs: add ericonr as a contributor (#587) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 74151e26..68187a46 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -593,6 +593,15 @@ "code", "doc" ] + }, + { + "login": "ericonr", + "name": "Γ‰rico Nogueira Rolim", + "avatar_url": "https://avatars0.githubusercontent.com/u/34201958?v=4", + "profile": "https://github.com/ericonr", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 61d9b1c5..4404b54e 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-64-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-65-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -382,6 +382,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
kepae

πŸ’» πŸ“– +
Γ‰rico Nogueira Rolim

πŸ’» From f418a9309aedc9c7692c1c88cfbf0c26b08ffa7c Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Tue, 22 Sep 2020 09:52:52 +0100 Subject: [PATCH 159/311] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dfc44bd..6aa6acba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ - Add handling Home and End buttons in user input [#550](https://github.com/Rigellute/spotify-tui/pull/550) - Add basic playbar support for podcasts [#563](https://github.com/Rigellute/spotify-tui/pull/563) - Fix to be able to follow an artist in search result view [#565](https://github.com/Rigellute/spotify-tui/pull/565) +- Add 'enable_text_emphasis' behavior config option [#573](https://github.com/Rigellute/spotify-tui/pull/573) +- Don't add analysis view to stack if already in it [#580](https://github.com/Rigellute/spotify-tui/pull/580) ## [0.21.0] - 2020-07-24 From 19d67707e36c667076a4cdbc033f22cf08cde287 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Tue, 22 Sep 2020 13:42:49 +0100 Subject: [PATCH 160/311] Update CHANGELOG (#588) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6aa6acba..07435bf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Show β™₯ next to album name in saved list [#540](https://github.com/Rigellute/spotify-tui/pull/540) - Add additional line of help to show that 'w' can be used to save/like an album [#548](https://github.com/Rigellute/spotify-tui/pull/548) - Add handling Home and End buttons in user input [#550](https://github.com/Rigellute/spotify-tui/pull/550) +- Add `playbar_progress_text` to user config and upgrade tui lib [#564](https://github.com/Rigellute/spotify-tui/pull/564) - Add basic playbar support for podcasts [#563](https://github.com/Rigellute/spotify-tui/pull/563) - Fix to be able to follow an artist in search result view [#565](https://github.com/Rigellute/spotify-tui/pull/565) - Add 'enable_text_emphasis' behavior config option [#573](https://github.com/Rigellute/spotify-tui/pull/573) From cc0c74a74029fbd53ce988f2de190e3610c7aec0 Mon Sep 17 00:00:00 2001 From: Alexander Meinhardt Scheurer Date: Tue, 22 Sep 2020 14:57:19 +0200 Subject: [PATCH 161/311] Add possibility to queue a song (#567) * Add possibility to queue a song Using the new method in rspotify, we can now queue a song. I have set the deafult to 'z', but it should probably be changed before the code is merged. * Fix Clippy errors and run fmt * Add `add_item_to_queue` in the entire user config * Add help text for queue track functionality --- src/handlers/album_tracks.rs | 25 ++++++++++++++++ src/handlers/artist.rs | 8 +++++ src/handlers/recently_played.rs | 7 +++++ src/handlers/search_results.rs | 21 +++++++++++++ src/handlers/track_table.rs | 52 +++++++++++++++++++++++++++++++++ src/network.rs | 17 +++++++++++ src/ui/help.rs | 1 + src/user_config.rs | 4 +++ 8 files changed, 135 insertions(+) diff --git a/src/handlers/album_tracks.rs b/src/handlers/album_tracks.rs index b600cbed..2ec6b032 100644 --- a/src/handlers/album_tracks.rs +++ b/src/handlers/album_tracks.rs @@ -77,6 +77,31 @@ pub fn handler(key: Key, app: &mut App) { Key::Char('r') => { handle_recommended_tracks(app); } + _ if key == app.user_config.keys.add_item_to_queue => match app.album_table_context { + AlbumTableContext::Full => { + if let Some(selected_album) = app.selected_album_full.clone() { + if let Some(track) = selected_album + .album + .tracks + .items + .get(app.saved_album_tracks_index) + { + app.dispatch(IoEvent::AddItemToQueue(track.uri.clone())); + } + }; + } + AlbumTableContext::Simplified => { + if let Some(selected_album_simplified) = &app.selected_album_simplified.clone() { + if let Some(track) = selected_album_simplified + .tracks + .items + .get(selected_album_simplified.selected_index) + { + app.dispatch(IoEvent::AddItemToQueue(track.uri.clone())); + } + }; + } + }, _ => {} }; } diff --git a/src/handlers/artist.rs b/src/handlers/artist.rs index bd278d7c..64cf3cc7 100644 --- a/src/handlers/artist.rs +++ b/src/handlers/artist.rs @@ -306,6 +306,14 @@ pub fn handler(key: Key, app: &mut App) { ArtistBlock::RelatedArtists => app.user_unfollow_artists(ActiveBlock::ArtistBlock), _ => (), }, + _ if key == app.user_config.keys.add_item_to_queue => { + if let ArtistBlock::TopTracks = artist.artist_selected_block { + if let Some(track) = artist.top_tracks.get(artist.selected_top_track_index) { + let uri = track.uri.clone(); + app.dispatch(IoEvent::AddItemToQueue(uri)); + }; + } + } _ => {} }; } diff --git a/src/handlers/recently_played.rs b/src/handlers/recently_played.rs index 0907d15d..e3358f8c 100644 --- a/src/handlers/recently_played.rs +++ b/src/handlers/recently_played.rs @@ -78,6 +78,13 @@ pub fn handler(key: Key, app: &mut App) { } } } + _ if key == app.user_config.keys.add_item_to_queue => { + if let Some(recently_played_result) = &app.recently_played.result.clone() { + if let Some(history) = recently_played_result.items.get(app.recently_played.index) { + app.dispatch(IoEvent::AddItemToQueue(history.track.uri.clone())) + } + }; + } _ => {} }; } diff --git a/src/handlers/search_results.rs b/src/handlers/search_results.rs index f4029e8e..1f16877e 100644 --- a/src/handlers/search_results.rs +++ b/src/handlers/search_results.rs @@ -220,6 +220,26 @@ fn handle_low_press_on_selected_block(app: &mut App) { } } +fn handle_add_item_to_queue(app: &mut App) { + match &app.search_results.selected_block { + SearchResultBlock::SongSearch => { + if let (Some(index), Some(tracks)) = ( + app.search_results.selected_tracks_index, + &app.search_results.tracks, + ) { + if let Some(track) = tracks.items.get(index) { + let uri = track.uri.clone(); + app.dispatch(IoEvent::AddItemToQueue(uri)); + } + } + } + SearchResultBlock::ArtistSearch => {} + SearchResultBlock::PlaylistSearch => {} + SearchResultBlock::AlbumSearch => {} + SearchResultBlock::Empty => {} + }; +} + fn handle_enter_event_on_selected_block(app: &mut App) { match &app.search_results.selected_block { SearchResultBlock::AlbumSearch => { @@ -461,6 +481,7 @@ pub fn handler(key: Key, app: &mut App) { SearchResultBlock::Empty => {} }, Key::Char('r') => handle_recommended_tracks(app), + _ if key == app.user_config.keys.add_item_to_queue => handle_add_item_to_queue(app), // Add `s` to "see more" on each option _ => {} } diff --git a/src/handlers/track_table.rs b/src/handlers/track_table.rs index e86f4ca7..76e369bd 100644 --- a/src/handlers/track_table.rs +++ b/src/handlers/track_table.rs @@ -149,6 +149,7 @@ pub fn handler(key: Key, app: &mut App) { Key::Char('r') => { handle_recommended_tracks(app); } + _ if key == app.user_config.keys.add_item_to_queue => on_queue(app), _ => {} } } @@ -426,6 +427,57 @@ fn on_enter(app: &mut App) { }; } +fn on_queue(app: &mut App) { + let TrackTable { + context, + selected_index, + tracks, + } = &app.track_table; + match &context { + Some(context) => match context { + TrackTableContext::MyPlaylists => { + if let Some(track) = tracks.get(*selected_index) { + let uri = track.uri.clone(); + app.dispatch(IoEvent::AddItemToQueue(uri)); + }; + } + TrackTableContext::RecommendedTracks => { + if let Some(full_track) = app.recommended_tracks.get(app.track_table.selected_index) { + let uri = full_track.uri.clone(); + app.dispatch(IoEvent::AddItemToQueue(uri)); + } + } + TrackTableContext::SavedTracks => { + if let Some(page) = app.library.saved_tracks.get_results(None) { + if let Some(saved_track) = page.items.get(app.track_table.selected_index) { + let uri = saved_track.track.uri.clone(); + app.dispatch(IoEvent::AddItemToQueue(uri)); + } + } + } + TrackTableContext::AlbumSearch => {} + TrackTableContext::PlaylistSearch => { + let TrackTable { + selected_index, + tracks, + .. + } = &app.track_table; + if let Some(track) = tracks.get(*selected_index) { + let uri = track.uri.clone(); + app.dispatch(IoEvent::AddItemToQueue(uri)); + }; + } + TrackTableContext::MadeForYou => { + if let Some(track) = tracks.get(*selected_index) { + let uri = track.uri.clone(); + app.dispatch(IoEvent::AddItemToQueue(uri)); + } + } + }, + None => {} + }; +} + fn jump_to_start(app: &mut App) { match &app.track_table.context { Some(context) => match context { diff --git a/src/network.rs b/src/network.rs index 2a5722bb..5959319e 100644 --- a/src/network.rs +++ b/src/network.rs @@ -75,6 +75,7 @@ pub enum IoEvent { GetAlbum(String), SetDeviceIdInConfig(String), CurrentUserSavedTracksContains(Vec), + AddItemToQueue(String), } pub fn get_spotify(token_info: TokenInfo) -> (Spotify, SystemTime) { @@ -259,6 +260,9 @@ impl<'a> Network<'a> { IoEvent::CurrentUserSavedTracksContains(track_ids) => { self.current_user_saved_tracks_contains(track_ids).await; } + IoEvent::AddItemToQueue(item) => { + self.add_item_to_queue(item).await; + } }; let mut app = self.app.lock().await; @@ -1215,4 +1219,17 @@ impl<'a> Network<'a> { // TODO panic! } } + + async fn add_item_to_queue(&mut self, item: String) { + match self + .spotify + .add_item_to_queue(item, self.client_config.device_id.clone()) + .await + { + Ok(()) => (), + Err(e) => { + self.handle_error(anyhow!(e)).await; + } + } + } } diff --git a/src/ui/help.rs b/src/ui/help.rs index 69ffda60..917c0b7c 100644 --- a/src/ui/help.rs +++ b/src/ui/help.rs @@ -107,5 +107,6 @@ pub fn get_help_docs() -> Vec> { vec!["Follow an artist/playlist", "w", "Search result"], vec!["Save (like) album to library", "w", "Search result"], vec!["Play random song in playlist", "S", "Selected Playlist"], + vec!["Add track to queue", "z", "Hovered over track"], ] } diff --git a/src/user_config.rs b/src/user_config.rs index 99e945df..d10830a7 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -165,6 +165,7 @@ pub struct KeyBindingsString { copy_album_url: Option, audio_analysis: Option, basic_view: Option, + add_item_to_queue: Option, } #[derive(Clone)] @@ -190,6 +191,7 @@ pub struct KeyBindings { pub copy_album_url: Key, pub audio_analysis: Key, pub basic_view: Key, + pub add_item_to_queue: Key, } #[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -251,6 +253,7 @@ impl UserConfig { copy_album_url: Key::Char('C'), audio_analysis: Key::Char('v'), basic_view: Key::Char('B'), + add_item_to_queue: Key::Char('z'), }, behavior: BehaviorConfig { seek_milliseconds: 5 * 1000, @@ -321,6 +324,7 @@ impl UserConfig { to_keys!(copy_album_url); to_keys!(audio_analysis); to_keys!(basic_view); + to_keys!(add_item_to_queue); Ok(()) } From bff69fb777a896abcfab33208e69891ddb4a3e45 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Tue, 22 Sep 2020 14:28:33 +0100 Subject: [PATCH 162/311] Add missing keybind config to README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 4404b54e..7c8aadb3 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,9 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) + [![All Contributors](https://img.shields.io/badge/all_contributors-65-orange.svg?style=flat-square)](#contributors-) + [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -252,6 +254,9 @@ keybindings: repeat: "r" search: "/" audio_analysis: "v" + jump_to_context: "o" + basic_view: "B" + add_item_to_queue: "z" ``` ## Limitations @@ -388,6 +393,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d + This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! From 0e8f3723ad3b91725d04b460ae6b511ac6ffac1c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 23 Sep 2020 21:34:43 +0100 Subject: [PATCH 163/311] docs: add BeneCollyridam as a contributor (#589) * Add missing keybind config to README * docs: update .all-contributorsrc [skip ci] Co-authored-by: Alexander Keliris Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 68187a46..8ca3e33b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -602,6 +602,15 @@ "contributions": [ "code" ] + }, + { + "login": "BeneCollyridam", + "name": "Alexander Meinhardt Scheurer", + "avatar_url": "https://avatars2.githubusercontent.com/u/15802915?v=4", + "profile": "https://github.com/BeneCollyridam", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 7c8aadb3..57837f8e 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ -[![All Contributors](https://img.shields.io/badge/all_contributors-65-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-66-orange.svg?style=flat-square)](#contributors-) @@ -388,6 +388,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
kepae

πŸ’» πŸ“–
Γ‰rico Nogueira Rolim

πŸ’» +
Alexander Meinhardt Scheurer

πŸ’» From 06208032f559b4d2a93785d9e701d566767f2285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kin=C5=A1t?= Date: Wed, 30 Sep 2020 18:11:25 +0200 Subject: [PATCH 164/311] Add next/prev page, jump to start/end to user config (#566) --- src/handlers/album_list.rs | 4 ++-- src/handlers/home.rs | 4 ++-- src/handlers/track_table.rs | 8 ++++---- src/user_config.rs | 16 ++++++++++++++++ 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/handlers/album_list.rs b/src/handlers/album_list.rs index 5a00244d..f4923f18 100644 --- a/src/handlers/album_list.rs +++ b/src/handlers/album_list.rs @@ -51,8 +51,8 @@ pub fn handler(key: Key, app: &mut App) { }; } } - Key::Ctrl('d') => app.get_current_user_saved_albums_next(), - Key::Ctrl('u') => app.get_current_user_saved_albums_previous(), + k if k == app.user_config.keys.next_page => app.get_current_user_saved_albums_next(), + k if k == app.user_config.keys.previous_page => app.get_current_user_saved_albums_previous(), Key::Char('D') => app.current_user_saved_album_delete(ActiveBlock::AlbumList), _ => {} }; diff --git a/src/handlers/home.rs b/src/handlers/home.rs index 470b9c24..15546fac 100644 --- a/src/handlers/home.rs +++ b/src/handlers/home.rs @@ -15,10 +15,10 @@ pub fn handler(key: Key, app: &mut App) { app.home_scroll -= SMALL_SCROLL; } } - Key::Ctrl('d') => { + k if k == app.user_config.keys.next_page => { app.home_scroll += LARGE_SCROLL; } - Key::Ctrl('u') => { + k if k == app.user_config.keys.previous_page => { if app.home_scroll > LARGE_SCROLL { app.home_scroll -= LARGE_SCROLL; } else { diff --git a/src/handlers/track_table.rs b/src/handlers/track_table.rs index 76e369bd..9dd81876 100644 --- a/src/handlers/track_table.rs +++ b/src/handlers/track_table.rs @@ -40,7 +40,7 @@ pub fn handler(key: Key, app: &mut App) { on_enter(app); } // Scroll down - Key::Ctrl('d') => { + k if k == app.user_config.keys.next_page => { match &app.track_table.context { Some(context) => match context { TrackTableContext::MyPlaylists => { @@ -93,7 +93,7 @@ pub fn handler(key: Key, app: &mut App) { }; } // Scroll up - Key::Ctrl('u') => { + k if k == app.user_config.keys.previous_page => { match &app.track_table.context { Some(context) => match context { TrackTableContext::MyPlaylists => { @@ -143,8 +143,8 @@ pub fn handler(key: Key, app: &mut App) { } Key::Char('s') => handle_save_track_event(app), Key::Char('S') => play_random_song(app), - Key::Ctrl('e') => jump_to_end(app), - Key::Ctrl('a') => jump_to_start(app), + k if k == app.user_config.keys.jump_to_end => jump_to_end(app), + k if k == app.user_config.keys.jump_to_start => jump_to_start(app), //recommended song radio Key::Char('r') => { handle_recommended_tracks(app); diff --git a/src/user_config.rs b/src/user_config.rs index d10830a7..a345df53 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -145,6 +145,10 @@ pub struct UserConfigPaths { #[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct KeyBindingsString { back: Option, + next_page: Option, + previous_page: Option, + jump_to_start: Option, + jump_to_end: Option, jump_to_album: Option, jump_to_artist_album: Option, jump_to_context: Option, @@ -171,6 +175,10 @@ pub struct KeyBindingsString { #[derive(Clone)] pub struct KeyBindings { pub back: Key, + pub next_page: Key, + pub previous_page: Key, + pub jump_to_start: Key, + pub jump_to_end: Key, pub jump_to_album: Key, pub jump_to_artist_album: Key, pub jump_to_context: Key, @@ -233,6 +241,10 @@ impl UserConfig { theme: Default::default(), keys: KeyBindings { back: Key::Char('q'), + next_page: Key::Ctrl('d'), + previous_page: Key::Ctrl('u'), + jump_to_start: Key::Ctrl('a'), + jump_to_end: Key::Ctrl('e'), jump_to_album: Key::Char('a'), jump_to_artist_album: Key::Char('A'), jump_to_context: Key::Char('o'), @@ -304,6 +316,10 @@ impl UserConfig { }; to_keys!(back); + to_keys!(next_page); + to_keys!(previous_page); + to_keys!(jump_to_start); + to_keys!(jump_to_end); to_keys!(jump_to_album); to_keys!(jump_to_artist_album); to_keys!(jump_to_context); From f880142ad70d1752c5058fec9238bbb96fb02c99 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2020 17:12:56 +0100 Subject: [PATCH 165/311] docs: add Toaster192 as a contributor (#597) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 6 ++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8ca3e33b..f8dd0b4e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -611,6 +611,15 @@ "contributions": [ "code" ] + }, + { + "login": "Toaster192", + "name": "OndΕ™ej KinΕ‘t", + "avatar_url": "https://avatars0.githubusercontent.com/u/14369229?v=4", + "profile": "https://github.com/Toaster192", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 57837f8e..ddf51240 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) - -[![All Contributors](https://img.shields.io/badge/all_contributors-66-orange.svg?style=flat-square)](#contributors-) - +[![All Contributors](https://img.shields.io/badge/all_contributors-67-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -389,12 +387,12 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
kepae

πŸ’» πŸ“–
Γ‰rico Nogueira Rolim

πŸ’»
Alexander Meinhardt Scheurer

πŸ’» +
OndΕ™ej KinΕ‘t

πŸ’» - This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! From 796f82b360a0bbe630402979b1428f6615d03111 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Wed, 30 Sep 2020 17:14:22 +0100 Subject: [PATCH 166/311] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07435bf8..81587604 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Fix to be able to follow an artist in search result view [#565](https://github.com/Rigellute/spotify-tui/pull/565) - Add 'enable_text_emphasis' behavior config option [#573](https://github.com/Rigellute/spotify-tui/pull/573) - Don't add analysis view to stack if already in it [#580](https://github.com/Rigellute/spotify-tui/pull/580) +- Add next/prev page, jump to start/end to user config [#566](https://github.com/Rigellute/spotify-tui/pull/566) ## [0.21.0] - 2020-07-24 From d9a817293ff9f3bfcc36bad084c4807896fe526d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2020 17:17:05 +0100 Subject: [PATCH 167/311] Bump tui from 0.10.0 to 0.12.0 (#592) Bumps [tui](https://github.com/fdehau/tui-rs) from 0.10.0 to 0.12.0. - [Release notes](https://github.com/fdehau/tui-rs/releases) - [Changelog](https://github.com/fdehau/tui-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/fdehau/tui-rs/compare/v0.10.0...v0.12.0) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f3baa97e..a53e51d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1915,9 +1915,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "tui" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a977b0bb2e2033a6fef950f218f13622c3c34e59754b704ce3492dedab1dfe95" +checksum = "c2eaeee894a1e9b90f80aa466fe59154fdb471980b5e104d8836fcea309ae17e" dependencies = [ "bitflags", "cassowary", diff --git a/Cargo.toml b/Cargo.toml index 9e30dfa9..307154f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ license = "MIT OR Apache-2.0" [dependencies] rspotify = "0.10.0" -tui = { version = "0.10.0", features = ["crossterm"], default-features = false } +tui = { version = "0.12.0", features = ["crossterm"], default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" From 1eff97a994fc33411f91de8215abf46b7bf0279b Mon Sep 17 00:00:00 2001 From: Kryan90 Date: Wed, 30 Sep 2020 10:24:06 -0600 Subject: [PATCH 168/311] Updated README with correct brew command (#594) spotify-tui is available as an official tap Trying to install with the current instructions gives and error "Error: No available formula or cask with the name "Rigellute/tap/spotify-tui"" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ddf51240..7ecf7276 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ The binary executable is `spt`. For both macOS and Linux ```bash -brew install Rigellute/tap/spotify-tui +brew install spotify-tui ``` To update, run From 726bebfac6072ef1a142f068a06e8fd31772eff1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2020 17:25:00 +0100 Subject: [PATCH 169/311] Bump crossterm from 0.17.8 to 0.18.0 (#595) Bumps [crossterm](https://github.com/crossterm-rs/crossterm) from 0.17.8 to 0.18.0. - [Release notes](https://github.com/crossterm-rs/crossterm/releases) - [Changelog](https://github.com/crossterm-rs/crossterm/blob/master/CHANGELOG.md) - [Commits](https://github.com/crossterm-rs/crossterm/commits/0.18) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 87 ++++++++++++++++++++++++++++++++++++++++++++++++------ Cargo.toml | 2 +- 2 files changed, 79 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a53e51d2..a66afda4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -243,6 +243,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "cloudabi" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" +dependencies = [ + "bitflags", +] + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -278,16 +287,32 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.17.8" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "858085e389f71d31a6909f2b55a56b87d1cb8b168c0f513dcbed5e66a3e1039c" +checksum = "6f4919d60f26ae233e14233cc39746c8c8bb8cd7b05840ace83604917b51b6c7" dependencies = [ "bitflags", "crossterm_winapi", "lazy_static", "libc", "mio 0.7.0", - "parking_lot", + "parking_lot 0.10.2", + "signal-hook", + "winapi 0.3.9", +] + +[[package]] +name = "crossterm" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2fcdc3c9cf8ee446222e8ee8691a6d21b563b8fe1a64b1873080db7b5b23cf0" +dependencies = [ + "bitflags", + "crossterm_winapi", + "lazy_static", + "libc", + "mio 0.7.0", + "parking_lot 0.11.0", "signal-hook", "winapi 0.3.9", ] @@ -751,6 +776,15 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "instant" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63312a18f7ea8760cdd0a7c5aac1a619752a246b833545e3e36d1f81f7cd9e66" +dependencies = [ + "cfg-if", +] + [[package]] name = "iovec" version = "0.1.4" @@ -821,6 +855,15 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "lock_api" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.11" @@ -1101,8 +1144,19 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" dependencies = [ - "lock_api", - "parking_lot_core", + "lock_api 0.3.4", + "parking_lot_core 0.7.2", +] + +[[package]] +name = "parking_lot" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733" +dependencies = [ + "instant", + "lock_api 0.4.1", + "parking_lot_core 0.8.0", ] [[package]] @@ -1112,7 +1166,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" dependencies = [ "cfg-if", - "cloudabi", + "cloudabi 0.0.3", + "libc", + "redox_syscall", + "smallvec", + "winapi 0.3.9", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" +dependencies = [ + "cfg-if", + "cloudabi 0.1.0", + "instant", "libc", "redox_syscall", "smallvec", @@ -1349,7 +1418,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" dependencies = [ - "cloudabi", + "cloudabi 0.0.3", "fuchsia-cprng", "libc", "rand_core 0.4.2", @@ -1674,7 +1743,7 @@ dependencies = [ "backtrace", "clap", "clipboard", - "crossterm", + "crossterm 0.18.0", "dirs", "rand 0.7.3", "rspotify", @@ -1921,7 +1990,7 @@ checksum = "c2eaeee894a1e9b90f80aa466fe59154fdb471980b5e104d8836fcea309ae17e" dependencies = [ "bitflags", "cassowary", - "crossterm", + "crossterm 0.17.7", "unicode-segmentation", "unicode-width", ] diff --git a/Cargo.toml b/Cargo.toml index 307154f8..204efe32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ clap = "2.33.3" unicode-width = "0.1.8" backtrace = "0.3.49" clipboard = "0.5.0" -crossterm = "0.17" +crossterm = "0.18" tokio = { version = "0.2", features = ["full"] } rand = "0.7.3" anyhow = "1.0.32" From b08a726c4ef7dd87f3dde22dd80e8f9b30b0fffc Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2020 18:05:03 +0100 Subject: [PATCH 170/311] docs: add Kryan90 as a contributor (#598) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index f8dd0b4e..7b60de77 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -620,6 +620,15 @@ "contributions": [ "code" ] + }, + { + "login": "Kryan90", + "name": "Kryan90", + "avatar_url": "https://avatars3.githubusercontent.com/u/18740821?v=4", + "profile": "https://github.com/Kryan90", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 7ecf7276..5e1deef7 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-67-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-68-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -388,6 +388,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Γ‰rico Nogueira Rolim

πŸ’»
Alexander Meinhardt Scheurer

πŸ’»
OndΕ™ej KinΕ‘t

πŸ’» +
Kryan90

πŸ“– From 128995ccabb067f1054c02a5f1d012fcbcf5e6de Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2020 18:13:23 +0100 Subject: [PATCH 171/311] Bump backtrace from 0.3.50 to 0.3.51 (#596) Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.50 to 0.3.51. - [Release notes](https://github.com/rust-lang/backtrace-rs/releases) - [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.50...0.3.51) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a66afda4..5e79c678 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,9 +82,9 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.50" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46254cf2fdcdf1badb5934448c1bcbe046a56537b3987d96c51a7afc5d03f293" +checksum = "ec1931848a574faa8f7c71a12ea00453ff5effbb5f51afe7f77d7a48cace6ac1" dependencies = [ "addr2line", "cfg-if", diff --git a/Cargo.toml b/Cargo.toml index 204efe32..471fc048 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ serde_yaml = "0.8" dirs = "3.0.1" clap = "2.33.3" unicode-width = "0.1.8" -backtrace = "0.3.49" +backtrace = "0.3.51" clipboard = "0.5.0" crossterm = "0.18" tokio = { version = "0.2", features = ["full"] } From 79c280f10f56835b539b47ee71047d13e243005d Mon Sep 17 00:00:00 2001 From: Nick Stockton Date: Thu, 1 Oct 2020 04:24:32 -0400 Subject: [PATCH 172/311] Full Podcast support (#581) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Handle ctrl-h like backspace * Stub out podcast search results * Draw podcast search results * Draw rough podcast episode table Still populating each item with some dummy values and don't currently update the selected show index, but navigation seems to work mostly correctly. * Stub out EpisodeTable handlers * Get episode playback working. Still need to clean a number of things up in the display * Rename MyShows -> SavedShows * Make borrow checker happy * RustFmt fixes * Better Date/Title/Duration layout Changed: * Display "Date - Title - Duration" for episodes instead of full description (it was too wordy/messy for most podcasts) * Properly mark the currently playing episode * Show episode resume point/played status This commit will force a re-auth of the app since it requires the `user-read-playback-position` scope. Changes: * Display / in the Duration column for episodes * Display βœ” next to episodes that have been fully played * rustfmt appeasement * Get rid of EpisodeTableContext There is currently no such thing as a context for playing episodes, and the only collection of episodes that is possible is the episodes from a show, so there's not currently a need to handle the playing or navigation context of the episode table. If there is some time in the future when it makes sense, it can be implemented then. * Add jump_to[start|end] for show episodes * Remove debug print * Update to match new tui API * Make rustfmt happy * Toggle order of podcast episodes * Handle ShowSearch for new key option * Use user config'd keys for paging Co-authored-by: Nicklas Stockton --- src/app.rs | 26 +++++ src/handlers/common_key_events.rs | 6 ++ src/handlers/episode_table.rs | 96 +++++++++++++++++++ src/handlers/mod.rs | 4 + src/handlers/search_results.rs | 81 +++++++++++++++- src/main.rs | 3 +- src/network.rs | 42 +++++++- src/ui/help.rs | 5 + src/ui/mod.rs | 154 ++++++++++++++++++++++++++++-- 9 files changed, 403 insertions(+), 14 deletions(-) create mode 100644 src/handlers/episode_table.rs diff --git a/src/app.rs b/src/app.rs index d06908f9..ad1b19a1 100644 --- a/src/app.rs +++ b/src/app.rs @@ -11,6 +11,7 @@ use rspotify::{ page::{CursorBasedPage, Page}, playing::PlayHistory, playlist::{PlaylistTrack, SimplifiedPlaylist}, + show::{SimplifiedEpisode, SimplifiedShow}, track::{FullTrack, SavedTrack, SimplifiedTrack}, user::PrivateUser, PlayingItem, @@ -93,6 +94,7 @@ pub enum SearchResultBlock { SongSearch, ArtistSearch, PlaylistSearch, + ShowSearch, Empty, } @@ -125,6 +127,7 @@ pub enum ActiveBlock { Library, MyPlaylists, Podcasts, + EpisodeTable, RecentlyPlayed, SearchResultBlock, SelectDevice, @@ -151,6 +154,7 @@ pub enum RouteId { MadeForYou, Artists, Podcasts, + PodcastEpisodes, Recommendations, } @@ -172,6 +176,7 @@ pub enum TrackTableContext { MadeForYou, } +// Is it possible to compose enums? #[derive(Clone, PartialEq, Debug, Copy)] pub enum AlbumTableContext { Simplified, @@ -189,10 +194,12 @@ pub struct SearchResult { pub artists: Option>, pub playlists: Option>, pub tracks: Option>, + pub shows: Option>, pub selected_album_index: Option, pub selected_artists_index: Option, pub selected_playlists_index: Option, pub selected_tracks_index: Option, + pub selected_shows_index: Option, pub hovered_block: SearchResultBlock, pub selected_block: SearchResultBlock, } @@ -204,6 +211,13 @@ pub struct TrackTable { pub context: Option, } +#[derive(Default)] +pub struct EpisodeTable { + pub episodes: Vec, + pub selected_index: usize, + pub reversed: bool, +} + #[derive(Clone)] pub struct SelectedAlbum { pub album: SimplifiedAlbum, @@ -275,6 +289,7 @@ pub struct App { pub small_search_limit: u32, pub song_progress_ms: u128, pub track_table: TrackTable, + pub episode_table: EpisodeTable, pub user: Option, pub album_list_index: usize, pub made_for_you_index: usize, @@ -342,16 +357,19 @@ impl Default for App { albums: None, artists: None, playlists: None, + shows: None, selected_album_index: None, selected_artists_index: None, selected_playlists_index: None, selected_tracks_index: None, + selected_shows_index: None, tracks: None, }, song_progress_ms: 0, selected_device_index: None, selected_playlist_index: None, track_table: Default::default(), + episode_table: Default::default(), user: None, instant_since_last_current_playback_poll: Instant::now(), clipboard_context: clipboard::ClipboardProvider::new().ok(), @@ -871,6 +889,14 @@ impl App { } } + pub fn user_follow_show(&mut self) { + unimplemented!(); + } + + pub fn user_unfollow_show(&mut self) { + unimplemented!(); + } + pub fn get_made_for_you(&mut self) { // TODO: replace searches when relevant endpoint is added const DISCOVER_WEEKLY: &str = "Discover Weekly"; diff --git a/src/handlers/common_key_events.rs b/src/handlers/common_key_events.rs index b38810e1..befa9b51 100644 --- a/src/handlers/common_key_events.rs +++ b/src/handlers/common_key_events.rs @@ -119,6 +119,12 @@ pub fn handle_right_event(app: &mut App) { RouteId::AlbumList => { app.set_current_route_state(Some(ActiveBlock::AlbumList), Some(ActiveBlock::AlbumList)); } + RouteId::PodcastEpisodes => { + app.set_current_route_state( + Some(ActiveBlock::EpisodeTable), + Some(ActiveBlock::EpisodeTable), + ); + } RouteId::MadeForYou => { app.set_current_route_state(Some(ActiveBlock::MadeForYou), Some(ActiveBlock::MadeForYou)); } diff --git a/src/handlers/episode_table.rs b/src/handlers/episode_table.rs new file mode 100644 index 00000000..3b760571 --- /dev/null +++ b/src/handlers/episode_table.rs @@ -0,0 +1,96 @@ +use super::{ + super::app::{App, EpisodeTable}, + common_key_events, +}; +use crate::event::Key; +use crate::network::IoEvent; + +pub fn handler(key: Key, app: &mut App) { + match key { + k if common_key_events::left_event(k) => common_key_events::handle_left_event(app), + k if common_key_events::down_event(k) => { + let next_index = common_key_events::on_down_press_handler( + &app.episode_table.episodes, + Some(app.episode_table.selected_index), + ); + app.episode_table.selected_index = next_index; + } + k if common_key_events::up_event(k) => { + let next_index = common_key_events::on_up_press_handler( + &app.episode_table.episodes, + Some(app.episode_table.selected_index), + ); + app.episode_table.selected_index = next_index; + } + k if common_key_events::high_event(k) => { + let next_index = common_key_events::on_high_press_handler(); + app.episode_table.selected_index = next_index; + } + k if common_key_events::middle_event(k) => { + let next_index = common_key_events::on_middle_press_handler(&app.episode_table.episodes); + app.episode_table.selected_index = next_index; + } + k if common_key_events::low_event(k) => { + let next_index = common_key_events::on_low_press_handler(&app.episode_table.episodes); + app.episode_table.selected_index = next_index; + } + Key::Enter => { + on_enter(app); + } + // Scroll down + k if k == app.user_config.keys.next_page => {} + // Scroll up + k if k == app.user_config.keys.previous_page => {} + Key::Char('S') => toggle_sort_by_date(app), + Key::Char('s') => {} // TODO: handle saving the show + Key::Ctrl('e') => jump_to_end(app), + Key::Ctrl('a') => jump_to_start(app), + _ => {} + } +} + +fn jump_to_end(app: &mut App) { + let last_idx = &app.episode_table.episodes.len() - 1; + app.episode_table.selected_index = last_idx; +} + +fn on_enter(app: &mut App) { + let EpisodeTable { + selected_index: _, + episodes, + reversed: _, + } = &app.episode_table; + let episode_uris = episodes + .iter() + .map(|episode| episode.uri.to_owned()) + .collect::>(); + app.dispatch(IoEvent::StartPlayback( + None, + Some(episode_uris), + Some(app.episode_table.selected_index), + )); +} + +fn jump_to_start(app: &mut App) { + app.episode_table.selected_index = 0; +} + +fn toggle_sort_by_date(app: &mut App) { + let selected_id = app + .episode_table + .episodes + .get(app.episode_table.selected_index) + .map(|e| e.id.clone()); + app.episode_table.episodes.reverse(); + app.episode_table.reversed ^= true; + if let Some(id) = selected_id { + app.episode_table.selected_index = app + .episode_table + .episodes + .iter() + .position(|e| e.id == id) + .unwrap_or(0); + } else { + app.episode_table.selected_index = 0; + } +} diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 6f761ddf..de595673 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -7,6 +7,7 @@ mod basic_view; mod common_key_events; mod dialog; mod empty; +mod episode_table; mod error_screen; mod help_menu; mod home; @@ -116,6 +117,9 @@ fn handle_block_events(key: Key, app: &mut App) { ActiveBlock::TrackTable => { track_table::handler(key, app); } + ActiveBlock::EpisodeTable => { + episode_table::handler(key, app); + } ActiveBlock::HelpMenu => { help_menu::handler(key, app); } diff --git a/src/handlers/search_results.rs b/src/handlers/search_results.rs index 1f16877e..aafbe917 100644 --- a/src/handlers/search_results.rs +++ b/src/handlers/search_results.rs @@ -47,6 +47,15 @@ fn handle_down_press_on_selected_block(app: &mut App) { app.search_results.selected_playlists_index = Some(next_index); } } + SearchResultBlock::ShowSearch => { + if let Some(result) = &app.search_results.shows { + let next_index = common_key_events::on_down_press_handler( + &result.items, + app.search_results.selected_shows_index, + ); + app.search_results.selected_shows_index = Some(next_index); + } + } SearchResultBlock::Empty => {} } } @@ -54,7 +63,7 @@ fn handle_down_press_on_selected_block(app: &mut App) { fn handle_down_press_on_hovered_block(app: &mut App) { match app.search_results.hovered_block { SearchResultBlock::AlbumSearch => { - app.search_results.hovered_block = SearchResultBlock::SongSearch; + app.search_results.hovered_block = SearchResultBlock::ShowSearch; } SearchResultBlock::SongSearch => { app.search_results.hovered_block = SearchResultBlock::AlbumSearch; @@ -63,7 +72,10 @@ fn handle_down_press_on_hovered_block(app: &mut App) { app.search_results.hovered_block = SearchResultBlock::PlaylistSearch; } SearchResultBlock::PlaylistSearch => { - app.search_results.hovered_block = SearchResultBlock::ArtistSearch; + app.search_results.hovered_block = SearchResultBlock::ShowSearch; + } + SearchResultBlock::ShowSearch => { + app.search_results.hovered_block = SearchResultBlock::SongSearch; } SearchResultBlock::Empty => {} } @@ -108,6 +120,15 @@ fn handle_up_press_on_selected_block(app: &mut App) { app.search_results.selected_playlists_index = Some(next_index); } } + SearchResultBlock::ShowSearch => { + if let Some(result) = &app.search_results.shows { + let next_index = common_key_events::on_up_press_handler( + &result.items, + app.search_results.selected_shows_index, + ); + app.search_results.selected_shows_index = Some(next_index); + } + } SearchResultBlock::Empty => {} } } @@ -118,14 +139,17 @@ fn handle_up_press_on_hovered_block(app: &mut App) { app.search_results.hovered_block = SearchResultBlock::SongSearch; } SearchResultBlock::SongSearch => { - app.search_results.hovered_block = SearchResultBlock::AlbumSearch; + app.search_results.hovered_block = SearchResultBlock::ShowSearch; } SearchResultBlock::ArtistSearch => { - app.search_results.hovered_block = SearchResultBlock::PlaylistSearch; + app.search_results.hovered_block = SearchResultBlock::ShowSearch; } SearchResultBlock::PlaylistSearch => { app.search_results.hovered_block = SearchResultBlock::ArtistSearch; } + SearchResultBlock::ShowSearch => { + app.search_results.hovered_block = SearchResultBlock::AlbumSearch; + } SearchResultBlock::Empty => {} } } @@ -156,6 +180,12 @@ fn handle_high_press_on_selected_block(app: &mut App) { app.search_results.selected_playlists_index = Some(next_index); } } + SearchResultBlock::ShowSearch => { + if let Some(_result) = &app.search_results.shows { + let next_index = common_key_events::on_high_press_handler(); + app.search_results.selected_shows_index = Some(next_index); + } + } SearchResultBlock::Empty => {} } } @@ -186,6 +216,12 @@ fn handle_middle_press_on_selected_block(app: &mut App) { app.search_results.selected_playlists_index = Some(next_index); } } + SearchResultBlock::ShowSearch => { + if let Some(result) = &app.search_results.shows { + let next_index = common_key_events::on_middle_press_handler(&result.items); + app.search_results.selected_shows_index = Some(next_index); + } + } SearchResultBlock::Empty => {} } } @@ -216,6 +252,12 @@ fn handle_low_press_on_selected_block(app: &mut App) { app.search_results.selected_playlists_index = Some(next_index); } } + SearchResultBlock::ShowSearch => { + if let Some(result) = &app.search_results.shows { + let next_index = common_key_events::on_low_press_handler(&result.items); + app.search_results.selected_shows_index = Some(next_index); + } + } SearchResultBlock::Empty => {} } } @@ -236,6 +278,7 @@ fn handle_add_item_to_queue(app: &mut App) { SearchResultBlock::ArtistSearch => {} SearchResultBlock::PlaylistSearch => {} SearchResultBlock::AlbumSearch => {} + SearchResultBlock::ShowSearch => {} SearchResultBlock::Empty => {} }; } @@ -288,6 +331,18 @@ fn handle_enter_event_on_selected_block(app: &mut App) { }; } } + SearchResultBlock::ShowSearch => { + if let (Some(index), Some(shows_result)) = ( + app.search_results.selected_shows_index, + &app.search_results.shows, + ) { + if let Some(show) = shows_result.items.get(index) { + // Go to show tracks table + let show_id = show.id.to_owned(); + app.dispatch(IoEvent::GetShowEpisodes(show_id)); + }; + } + } SearchResultBlock::Empty => {} }; } @@ -330,6 +385,15 @@ fn handle_enter_event_on_hovered_block(app: &mut App) { app.search_results.selected_playlists_index = Some(next_index); app.search_results.selected_block = SearchResultBlock::PlaylistSearch; } + SearchResultBlock::ShowSearch => { + let next_index = match app.search_results.selected_shows_index { + Some(index) => index, + None => 0, + }; + + app.search_results.selected_shows_index = Some(next_index); + app.search_results.selected_block = SearchResultBlock::ShowSearch; + } SearchResultBlock::Empty => {} }; } @@ -365,6 +429,7 @@ fn handle_recommended_tracks(app: &mut App) { }; } SearchResultBlock::PlaylistSearch => {} + SearchResultBlock::ShowSearch => {} SearchResultBlock::Empty => {} } } @@ -403,6 +468,9 @@ pub fn handler(key: Key, app: &mut App) { SearchResultBlock::PlaylistSearch => { app.search_results.hovered_block = SearchResultBlock::AlbumSearch; } + SearchResultBlock::ShowSearch => { + common_key_events::handle_left_event(app); + } SearchResultBlock::Empty => {} } } @@ -421,6 +489,7 @@ pub fn handler(key: Key, app: &mut App) { SearchResultBlock::PlaylistSearch => { app.search_results.hovered_block = SearchResultBlock::AlbumSearch; } + SearchResultBlock::ShowSearch => {} SearchResultBlock::Empty => {} } } @@ -457,6 +526,9 @@ pub fn handler(key: Key, app: &mut App) { SearchResultBlock::PlaylistSearch => { app.user_follow_playlist(); } + SearchResultBlock::ShowSearch => { + app.user_follow_show(); + } SearchResultBlock::Empty => {} }, Key::Char('D') => match app.search_results.selected_block { @@ -478,6 +550,7 @@ pub fn handler(key: Key, app: &mut App) { app.push_navigation_stack(route, ActiveBlock::Dialog(DialogContext::PlaylistSearch)); } } + SearchResultBlock::ShowSearch => app.user_unfollow_show(), SearchResultBlock::Empty => {} }, Key::Char('r') => handle_recommended_tracks(app), diff --git a/src/main.rs b/src/main.rs index 0d0cd5e4..8904dbc7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -45,7 +45,7 @@ use tui::{ }; use user_config::{UserConfig, UserConfigPaths}; -const SCOPES: [&str; 13] = [ +const SCOPES: [&str; 14] = [ "playlist-read-collaborative", "playlist-read-private", "playlist-modify-private", @@ -57,6 +57,7 @@ const SCOPES: [&str; 13] = [ "user-modify-playback-state", "user-read-currently-playing", "user-read-playback-state", + "user-read-playback-position", "user-read-private", "user-read-recently-played", ]; diff --git a/src/network.rs b/src/network.rs index 5959319e..fe0092bf 100644 --- a/src/network.rs +++ b/src/network.rs @@ -75,6 +75,7 @@ pub enum IoEvent { GetAlbum(String), SetDeviceIdInConfig(String), CurrentUserSavedTracksContains(Vec), + GetShowEpisodes(String), AddItemToQueue(String), } @@ -260,6 +261,9 @@ impl<'a> Network<'a> { IoEvent::CurrentUserSavedTracksContains(track_ids) => { self.current_user_saved_tracks_contains(track_ids).await; } + IoEvent::GetShowEpisodes(show_id) => { + self.get_show_episodes(show_id).await; + } IoEvent::AddItemToQueue(item) => { self.add_item_to_queue(item).await; } @@ -429,6 +433,25 @@ impl<'a> Network<'a> { } } + async fn get_show_episodes(&mut self, show_id: String) { + match self + .spotify + .get_shows_episodes(show_id, self.large_search_limit, 0, None) + .await + { + Ok(episodes) => { + let mut app = self.app.lock().await; + app.episode_table.episodes = episodes.items; + app.episode_table.reversed = false; + + app.push_navigation_stack(RouteId::PodcastEpisodes, ActiveBlock::EpisodeTable); + } + Err(e) => { + self.handle_error(anyhow!(e)).await; + } + } + } + async fn get_search_results(&mut self, search_term: String, country: Option) { let search_track = self.spotify.search( &search_term, @@ -466,13 +489,29 @@ impl<'a> Network<'a> { None, ); + let search_show = self.spotify.search( + &search_term, + SearchType::Show, + self.small_search_limit, + 0, + country, + None, + ); + // Run the futures concurrently - match try_join!(search_track, search_artist, search_album, search_playlist) { + match try_join!( + search_track, + search_artist, + search_album, + search_playlist, + search_show + ) { Ok(( SearchResult::Tracks(track_results), SearchResult::Artists(artist_results), SearchResult::Albums(album_results), SearchResult::Playlists(playlist_results), + SearchResult::Shows(show_results), )) => { let mut app = self.app.lock().await; @@ -498,6 +537,7 @@ impl<'a> Network<'a> { app.search_results.artists = Some(artist_results); app.search_results.albums = Some(album_results); app.search_results.playlists = Some(playlist_results); + app.search_results.shows = Some(show_results); } Err(e) => { self.handle_error(anyhow!(e)).await; diff --git a/src/ui/help.rs b/src/ui/help.rs index 917c0b7c..44cd9e96 100644 --- a/src/ui/help.rs +++ b/src/ui/help.rs @@ -107,6 +107,11 @@ pub fn get_help_docs() -> Vec> { vec!["Follow an artist/playlist", "w", "Search result"], vec!["Save (like) album to library", "w", "Search result"], vec!["Play random song in playlist", "S", "Selected Playlist"], + vec![ + "Toggle sort order of podcast episodes", + "S", + "Selected Show", + ], vec!["Add track to queue", "z", "Hovered over track"], ] } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 4fb8bad0..49485b0e 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -9,6 +9,7 @@ use super::{ banner::BANNER, }; use help::get_help_docs; +use rspotify::model::show::ResumePoint; use rspotify::model::PlayingItem; use rspotify::senum::RepeatState; use tui::{ @@ -32,12 +33,13 @@ pub enum TableId { Song, RecentlyPlayed, MadeForYou, + PodcastEpisodes, } #[derive(PartialEq)] pub enum ColumnId { None, - SongTitle, + Title, Liked, } @@ -219,6 +221,9 @@ where RouteId::AlbumList => { draw_album_list(f, app, chunks[1]); } + RouteId::PodcastEpisodes => { + draw_show_episodes(f, app, chunks[1]); + } RouteId::Home => { draw_home(f, app, chunks[1]); } @@ -307,7 +312,14 @@ where { let chunks = Layout::default() .direction(Direction::Vertical) - .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref()) + .constraints( + [ + Constraint::Percentage(35), + Constraint::Percentage(35), + Constraint::Percentage(25), + ] + .as_ref(), + ) .split(layout_chunk); { @@ -442,6 +454,31 @@ where app.search_results.selected_playlists_index, ); } + + { + let podcasts_block = Layout::default() + .direction(Direction::Horizontal) + .constraints([Constraint::Percentage(100)].as_ref()) + .split(chunks[2]); + + let podcasts = match &app.search_results.shows { + Some(podcasts) => podcasts + .items + .iter() + .map(|item| format!("{:} - {}", item.name, item.publisher)) + .collect(), + None => vec![], + }; + draw_selectable_list( + f, + app, + podcasts_block[0], + "Podcasts", + &podcasts, + get_search_results_highlight_state(app, SearchResultBlock::ShowSearch), + app.search_results.selected_shows_index, + ); + } } struct AlbumUI { @@ -506,7 +543,7 @@ where ..Default::default() }, TableHeaderItem { - id: ColumnId::SongTitle, + id: ColumnId::Title, text: "Title", width: get_percentage_width(layout_chunk.width, 2.0 / 5.0) - 5, }, @@ -611,7 +648,7 @@ where width: 2, }, TableHeaderItem { - id: ColumnId::SongTitle, + id: ColumnId::Title, text: "Title", width: get_percentage_width(layout_chunk.width, 0.3), }, @@ -690,7 +727,7 @@ where width: 2, }, TableHeaderItem { - id: ColumnId::SongTitle, + id: ColumnId::Title, text: "Title", width: get_percentage_width(layout_chunk.width, 0.3), }, @@ -1265,6 +1302,93 @@ where }; } +pub fn draw_show_episodes(f: &mut Frame, app: &App, layout_chunk: Rect) +where + B: Backend, +{ + let header = TableHeader { + id: TableId::PodcastEpisodes, + items: vec![ + TableHeaderItem { + // Column to mark an episode as fully played + text: "", + width: 2, + ..Default::default() + }, + TableHeaderItem { + text: "Date", + width: get_percentage_width(layout_chunk.width, 0.5 / 5.0) - 2, + ..Default::default() + }, + TableHeaderItem { + text: "Name", + width: get_percentage_width(layout_chunk.width, 3.5 / 5.0), + id: ColumnId::Title, + }, + TableHeaderItem { + text: "Duration", + width: get_percentage_width(layout_chunk.width, 1.0 / 5.0), + ..Default::default() + }, + ], + }; + + let current_route = app.get_current_route(); + + let highlight_state = ( + current_route.active_block == ActiveBlock::EpisodeTable, + current_route.hovered_block == ActiveBlock::EpisodeTable, + ); + + let items = app + .episode_table + .episodes + .iter() + .map(|episode| { + let (played_str, time_str) = match episode.resume_point { + Some(ResumePoint { + fully_played, + resume_position_ms, + }) => ( + if fully_played { + " βœ”".to_owned() + } else { + "".to_owned() + }, + format!( + "{} / {}", + millis_to_minutes(u128::from(resume_position_ms)), + millis_to_minutes(u128::from(episode.duration_ms)) + ), + ), + None => ( + "".to_owned(), + millis_to_minutes(u128::from(episode.duration_ms)), + ), + }; + TableItem { + id: episode.id.to_owned(), + format: vec![ + played_str, + episode.release_date.to_owned(), + episode.name.to_owned(), + time_str, + ], + } + }) + .collect::>(); + + draw_table( + f, + app, + layout_chunk, + ("Episodes", &header), + &items, + app.episode_table.selected_index, + highlight_state, + ); +} + pub fn draw_made_for_you(f: &mut Frame, app: &App, layout_chunk: Rect) where B: Backend, @@ -1319,7 +1443,7 @@ where width: 2, }, TableHeaderItem { - id: ColumnId::SongTitle, + id: ColumnId::Title, text: "Title", // We need to subtract the fixed value of the previous column width: get_percentage_width(layout_chunk.width, 2.0 / 5.0) - 2, @@ -1505,7 +1629,7 @@ fn draw_table( PlayingItem::Track(track) => items .iter() .position(|item| track.id.to_owned().map(|id| id == item.id).unwrap_or(false)), - PlayingItem::Episode(_episode) => None, + PlayingItem::Episode(episode) => items.iter().position(|item| episode.id == item.id), }) }); @@ -1528,7 +1652,7 @@ fn draw_table( match header.id { TableId::Song | TableId::RecentlyPlayed | TableId::Album => { // First check if the song should be highlighted because it is currently playing - if let Some(title_idx) = header.get_index(ColumnId::SongTitle) { + if let Some(title_idx) = header.get_index(ColumnId::Title) { if let Some(track_playing_offset_index) = track_playing_index.and_then(|idx| idx.checked_sub(offset)) { @@ -1548,6 +1672,20 @@ fn draw_table( } } } + TableId::PodcastEpisodes => { + if let Some(name_idx) = header.get_index(ColumnId::Title) { + if let Some(track_playing_offset_index) = + track_playing_index.and_then(|idx| idx.checked_sub(offset)) + { + if i == track_playing_offset_index { + formatted_row[name_idx] = format!("β–Ά {}", &formatted_row[name_idx]); + style = Style::default() + .fg(app.user_config.theme.active) + .add_modifier(Modifier::BOLD); + } + } + } + } _ => {} } From 4a4006abc4d79ed824d8fc258e7d6cce354ef25f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Thu, 1 Oct 2020 09:29:00 +0100 Subject: [PATCH 173/311] docs: add sputnick1124 as a contributor (#601) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 6 +++++- README.md | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7b60de77..b365647a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -263,7 +263,11 @@ "avatar_url": "https://avatars1.githubusercontent.com/u/8843309?v=4", "profile": "https://github.com/sputnick1124", "contributions": [ - "code" + "code", + "bug", + "maintenance", + "question", + "doc" ] }, { diff --git a/README.md b/README.md index 5e1deef7..a2f170cd 100644 --- a/README.md +++ b/README.md @@ -336,7 +336,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Sven van der Vlist

πŸ’»
jacobchrismarsh

πŸ’»
Nils Rauch

πŸ’» -
Nick Stockton

πŸ’» +
Nick Stockton

πŸ’» πŸ› 🚧 πŸ’¬ πŸ“–
Stuart Hinson

πŸ’» From db8bb26373337ea3e6b3989ed8c33a8a8e50a2f2 Mon Sep 17 00:00:00 2001 From: n-ivanov Date: Mon, 5 Oct 2020 01:53:35 -0700 Subject: [PATCH 174/311] Add user-configurable header styling (#583) --- README.md | 1 + src/ui/mod.rs | 1 + src/user_config.rs | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/README.md b/README.md index a2f170cd..6149a6cc 100644 --- a/README.md +++ b/README.md @@ -214,6 +214,7 @@ theme: playbar_text: White # artist name in player pane selected: LightCyan # a) selected pane border, b) hovered item in list, & c) track title in player text: "255, 255, 255" # text in panes + header: White # header text in panes (e.g. 'Title', 'Artist', etc.) behavior: seek_milliseconds: 5000 diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 49485b0e..460226a5 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1716,6 +1716,7 @@ fn draw_table( .border_style(get_color(highlight_state, app.user_config.theme)), ) .style(Style::default().fg(app.user_config.theme.text)) + .header_style(Style::default().fg(app.user_config.theme.header)) .widths(&widths); f.render_widget(table, layout_chunk); } diff --git a/src/user_config.rs b/src/user_config.rs index a345df53..7125f343 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -26,6 +26,7 @@ pub struct UserTheme { pub playbar_text: Option, pub selected: Option, pub text: Option, + pub header: Option, } #[derive(Copy, Clone, Debug)] @@ -45,6 +46,7 @@ pub struct Theme { pub playbar_text: Color, pub selected: Color, pub text: Color, + pub header: Color, } impl Default for Theme { @@ -65,6 +67,7 @@ impl Default for Theme { playbar_text: Color::White, selected: Color::LightCyan, text: Color::White, + header: Color::White, } } } @@ -367,6 +370,7 @@ impl UserConfig { to_theme_item!(playbar_text); to_theme_item!(selected); to_theme_item!(text); + to_theme_item!(header); Ok(()) } From 7955ef923693754798455d98f7858e74720fb9f7 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 5 Oct 2020 09:57:18 +0100 Subject: [PATCH 175/311] docs: add n-ivanov as a contributor (#605) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index b365647a..de6d97ae 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -633,6 +633,15 @@ "contributions": [ "doc" ] + }, + { + "login": "n-ivanov", + "name": "n-ivanov", + "avatar_url": "https://avatars3.githubusercontent.com/u/11470871?v=4", + "profile": "https://github.com/n-ivanov", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 6149a6cc..ead14499 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-68-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-69-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -390,6 +390,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Alexander Meinhardt Scheurer

πŸ’»
OndΕ™ej KinΕ‘t

πŸ’»
Kryan90

πŸ“– +
n-ivanov

πŸ’» From 4ac01ea379f470b33ab6dc1918e55377ddc35948 Mon Sep 17 00:00:00 2001 From: bi1yeu Date: Mon, 5 Oct 2020 01:58:08 -0700 Subject: [PATCH 176/311] Show active keybindings in Help (#585) * show active keybindings in help menu * properly format bare keys as `` * fix formatting * add new keybindings to help menu * fix formatting again --- src/event/key.rs | 26 ++++ src/main.rs | 2 +- src/ui/help.rs | 322 ++++++++++++++++++++++++++++++++++------------- src/ui/mod.rs | 2 +- 4 files changed, 266 insertions(+), 86 deletions(-) diff --git a/src/event/key.rs b/src/event/key.rs index 93336dfd..d8336b16 100644 --- a/src/event/key.rs +++ b/src/event/key.rs @@ -1,4 +1,5 @@ use crossterm::event; +use std::fmt; /// Represents an key. #[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)] @@ -94,6 +95,31 @@ impl Key { } } +impl fmt::Display for Key { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Key::Alt(' ') => write!(f, ""), + Key::Ctrl(' ') => write!(f, ""), + Key::Char(' ') => write!(f, ""), + Key::Alt(c) => write!(f, "", c), + Key::Ctrl(c) => write!(f, "", c), + Key::Char(c) => write!(f, "{}", c), + Key::Left | Key::Right | Key::Up | Key::Down => write!(f, "<{:?} Arrow Key>", self), + Key::Enter + | Key::Tab + | Key::Backspace + | Key::Esc + | Key::Ins + | Key::Delete + | Key::Home + | Key::End + | Key::PageUp + | Key::PageDown => write!(f, "<{:?}>", self), + _ => write!(f, "{:?}", self), + } + } +} + impl From for Key { fn from(key_event: event::KeyEvent) -> Self { match key_event { diff --git a/src/main.rs b/src/main.rs index 8904dbc7..8b4e941f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -345,7 +345,7 @@ async fn start_ui(user_config: UserConfig, app: &Arc>) -> Result<()> app.dispatch(IoEvent::GetPlaylists); app.dispatch(IoEvent::GetUser); app.dispatch(IoEvent::GetCurrentPlayback); - app.help_docs_size = ui::help::get_help_docs().len() as u32; + app.help_docs_size = ui::help::get_help_docs(&app.user_config.keys).len() as u32; is_first_render = false; } diff --git a/src/ui/help.rs b/src/ui/help.rs index 44cd9e96..baadeda4 100644 --- a/src/ui/help.rs +++ b/src/ui/help.rs @@ -1,117 +1,271 @@ -pub fn get_help_docs() -> Vec> { +use crate::user_config::KeyBindings; + +pub fn get_help_docs(key_bindings: &KeyBindings) -> Vec> { vec![ - vec!["Scroll down to next result page", "", "Pagination"], vec![ - "Scroll up to previous result page", - "", - "Pagination", + String::from("Scroll down to next result page"), + key_bindings.next_page.to_string(), + String::from("Pagination"), ], - vec!["Jump to start of playlist", "", "Pagination"], - vec!["Jump to end of playlist", "", "Pagination"], - vec!["Jump to currently playing album", "a", "General"], vec![ - "Jump to currently playing artist's album list", - "A", - "General", + String::from("Scroll up to previous result page"), + key_bindings.previous_page.to_string(), + String::from("Pagination"), ], - vec!["Jump to current play context", "o", "General"], - vec!["Increase volume by 10%", "+", "General"], - vec!["Decrease volume by 10%", "-", "General"], - vec!["Skip to next track", "n", "General"], - vec!["Skip to previous track", "p", "General"], - vec!["Seek backwards 5 seconds", "<", "General"], - vec!["Seek forwards 5 seconds", ">", "General"], - vec!["Toggle shuffle", "", "General"], - vec!["Copy url to currently playing song/episode", "c", "General"], - vec!["Copy url to currently playing album/show", "C", "General"], - vec!["Cycle repeat mode", "", "General"], vec![ - "Move selection left", - "h | | ", - "General", + String::from("Jump to start of playlist"), + key_bindings.jump_to_start.to_string(), + String::from("Pagination"), ], vec![ - "Move selection down", - "j | | ", - "General", + String::from("Jump to end of playlist"), + key_bindings.jump_to_end.to_string(), + String::from("Pagination"), ], vec![ - "Move selection up", - "k | | ", - "General", + String::from("Jump to currently playing album"), + key_bindings.jump_to_album.to_string(), + String::from("General"), ], vec![ - "Move selection right", - "l | | ", - "General", + String::from("Jump to currently playing artist's album list"), + key_bindings.jump_to_artist_album.to_string(), + String::from("General"), ], - vec!["Move selection to top of list", "H", "General"], - vec!["Move selection to middle of list", "M", "General"], - vec!["Move selection to bottom of list", "L", "General"], - vec!["Enter input for search", "/", "General"], - vec!["Pause/Resume playback", "", "General"], - vec!["Enter active mode", "", "General"], - vec!["Go to audio analysis screen", "v", "General"], - vec!["Go to playbar only screen (basic view)", "B", "General"], vec![ - "Go back or exit when nowhere left to back to", - "q", - "General", + String::from("Jump to current play context"), + key_bindings.jump_to_context.to_string(), + String::from("General"), ], - vec!["Select device to play music on", "d", "General"], - vec!["Enter hover mode", "", "Selected block"], - vec!["Save track in list or table", "s", "Selected block"], vec![ - "Start playback or enter album/artist/playlist", - "", - "Selected block", + String::from("Increase volume by 10%"), + key_bindings.increase_volume.to_string(), + String::from("General"), ], vec![ - "Play recommendations for song/artist", - "r", - "Selected block", + String::from("Decrease volume by 10%"), + key_bindings.decrease_volume.to_string(), + String::from("General"), ], - vec!["Play all tracks for artist", "e", "Library -> Artists"], - vec!["Search with input text", "", "Search input"], vec![ - "Move cursor one space left", - "", - "Search input", + String::from("Skip to next track"), + key_bindings.next_track.to_string(), + String::from("General"), ], vec![ - "Move cursor one space right", - "", - "Search input", + String::from("Skip to previous track"), + key_bindings.previous_track.to_string(), + String::from("General"), ], - vec!["Delete entire input", "", "Search input"], vec![ - "Delete text from cursor to start of input", - "", - "Search input", + String::from("Seek backwards 5 seconds"), + key_bindings.seek_backwards.to_string(), + String::from("General"), ], vec![ - "Delete text from cursor to end of input", - "", - "Search input", + String::from("Seek forwards 5 seconds"), + key_bindings.seek_forwards.to_string(), + String::from("General"), ], - vec!["Delete previous word", "", "Search input"], - vec!["Jump to start of input", "", "Search input"], - vec!["Jump to end of input", "", "Search input"], vec![ - "Escape from the input back to hovered block", - "", - "Search input", + String::from("Toggle shuffle"), + key_bindings.shuffle.to_string(), + String::from("General"), ], - vec!["Delete saved album", "D", "Library -> Albums"], - vec!["Delete saved playlist", "D", "Playlist"], - vec!["Follow an artist/playlist", "w", "Search result"], - vec!["Save (like) album to library", "w", "Search result"], - vec!["Play random song in playlist", "S", "Selected Playlist"], vec![ - "Toggle sort order of podcast episodes", - "S", - "Selected Show", + String::from("Copy url to currently playing song/episode"), + key_bindings.copy_song_url.to_string(), + String::from("General"), + ], + vec![ + String::from("Copy url to currently playing album/show"), + key_bindings.copy_album_url.to_string(), + String::from("General"), + ], + vec![ + String::from("Cycle repeat mode"), + key_bindings.repeat.to_string(), + String::from("General"), + ], + vec![ + String::from("Move selection left"), + String::from("h | | "), + String::from("General"), + ], + vec![ + String::from("Move selection down"), + String::from("j | | "), + String::from("General"), + ], + vec![ + String::from("Move selection up"), + String::from("k | | "), + String::from("General"), + ], + vec![ + String::from("Move selection right"), + String::from("l | | "), + String::from("General"), + ], + vec![ + String::from("Move selection to top of list"), + String::from("H"), + String::from("General"), + ], + vec![ + String::from("Move selection to middle of list"), + String::from("M"), + String::from("General"), + ], + vec![ + String::from("Move selection to bottom of list"), + String::from("L"), + String::from("General"), + ], + vec![ + String::from("Enter input for search"), + key_bindings.search.to_string(), + String::from("General"), + ], + vec![ + String::from("Pause/Resume playback"), + key_bindings.toggle_playback.to_string(), + String::from("General"), + ], + vec![ + String::from("Enter active mode"), + String::from(""), + String::from("General"), + ], + vec![ + String::from("Go to audio analysis screen"), + key_bindings.audio_analysis.to_string(), + String::from("General"), + ], + vec![ + String::from("Go to playbar only screen (basic view)"), + key_bindings.basic_view.to_string(), + String::from("General"), + ], + vec![ + String::from("Go back or exit when nowhere left to back to"), + key_bindings.back.to_string(), + String::from("General"), + ], + vec![ + String::from("Select device to play music on"), + key_bindings.manage_devices.to_string(), + String::from("General"), + ], + vec![ + String::from("Enter hover mode"), + String::from(""), + String::from("Selected block"), + ], + vec![ + String::from("Save track in list or table"), + String::from("s"), + String::from("Selected block"), + ], + vec![ + String::from("Start playback or enter album/artist/playlist"), + key_bindings.submit.to_string(), + String::from("Selected block"), + ], + vec![ + String::from("Play recommendations for song/artist"), + String::from("r"), + String::from("Selected block"), + ], + vec![ + String::from("Play all tracks for artist"), + String::from("e"), + String::from("Library -> Artists"), + ], + vec![ + String::from("Search with input text"), + String::from(""), + String::from("Search input"), + ], + vec![ + String::from("Move cursor one space left"), + String::from(""), + String::from("Search input"), + ], + vec![ + String::from("Move cursor one space right"), + String::from(""), + String::from("Search input"), + ], + vec![ + String::from("Delete entire input"), + String::from(""), + String::from("Search input"), + ], + vec![ + String::from("Delete text from cursor to start of input"), + String::from(""), + String::from("Search input"), + ], + vec![ + String::from("Delete text from cursor to end of input"), + String::from(""), + String::from("Search input"), + ], + vec![ + String::from("Delete previous word"), + String::from(""), + String::from("Search input"), + ], + vec![ + String::from("Jump to start of input"), + String::from(""), + String::from("Search input"), + ], + vec![ + String::from("Jump to end of input"), + String::from(""), + String::from("Search input"), + ], + vec![ + String::from("Escape from the input back to hovered block"), + String::from(""), + String::from("Search input"), + ], + vec![ + String::from("Delete saved album"), + String::from("D"), + String::from("Library -> Albums"), + ], + vec![ + String::from("Delete saved playlist"), + String::from("D"), + String::from("Playlist"), + ], + vec![ + String::from("Follow an artist/playlist"), + String::from("w"), + String::from("Search result"), + ], + vec![ + String::from("Save (like) album to library"), + String::from("w"), + String::from("Search result"), + ], + vec![ + String::from("Play random song in playlist"), + String::from("S"), + String::from("Selected Playlist"), + ], + vec![ + String::from("Toggle sort order of podcast episodes"), + String::from("S"), + String::from("Selected Show"), + ], + vec![ + String::from("Add track to queue"), + key_bindings.add_item_to_queue.to_string(), + String::from("Hovered over track"), ], - vec!["Add track to queue", "z", "Hovered over track"], ] } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 460226a5..8637de6d 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -86,7 +86,7 @@ where let gray = Style::default().fg(app.user_config.theme.text); let header = ["Description", "Event", "Context"]; - let help_docs = get_help_docs(); + let help_docs = get_help_docs(&app.user_config.keys); let help_docs = &help_docs[app.help_menu_offset as usize..]; let rows = help_docs From 05a3e830cf2387abfaddbd53ccfef7feb6a8bbc9 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 5 Oct 2020 09:59:29 +0100 Subject: [PATCH 177/311] docs: add bi1yeu as a contributor (#606) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 10 ++++++++++ README.md | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index de6d97ae..c2a08424 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -642,6 +642,16 @@ "contributions": [ "code" ] + }, + { + "login": "bi1yeu", + "name": "bi1yeu", + "avatar_url": "https://avatars3.githubusercontent.com/u/1185129?v=4", + "profile": "http://matthewbilyeu.com/resume/", + "contributions": [ + "code", + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index ead14499..076ce2e0 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-69-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-70-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -391,6 +391,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
OndΕ™ej KinΕ‘t

πŸ’»
Kryan90

πŸ“–
n-ivanov

πŸ’» +
bi1yeu

πŸ’» πŸ“– From 76ac1cdaa090ea2364ad26369a851cc2b905b510 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 5 Oct 2020 10:37:57 +0100 Subject: [PATCH 178/311] Fix new lines after tui upgrade (#607) --- src/ui/mod.rs | 83 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 34 deletions(-) diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 8637de6d..71f03bb1 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -941,28 +941,41 @@ where .margin(5) .split(f.size()); - let playing_text = Spans::from(vec![ - Span::raw("Api response: "), - Span::styled(&app.api_error, Style::default().fg(app.user_config.theme.error_text)), - Span::styled( - " - -If you are trying to play a track, please check that - 1. You have a Spotify Premium Account - 2. Your playback device is active and selected - press `d` to go to device selection menu - 3. If you're using spotifyd as a playback device, your device name must not contain spaces - ", - Style::default().fg(app.user_config.theme.text), + let playing_text = vec![ + Spans::from(vec![ + Span::raw("Api response: "), + Span::styled( + &app.api_error, + Style::default().fg(app.user_config.theme.error_text), + ), + ]), + Spans::from(Span::styled( + "If you are trying to play a track, please check that", + Style::default().fg(app.user_config.theme.text), + )), + Spans::from(Span::styled( + " 1. You have a Spotify Premium Account", + Style::default().fg(app.user_config.theme.text), + )), + Spans::from(Span::styled( + " 2. Your playback device is active and selected - press `d` to go to device selection menu", + Style::default().fg(app.user_config.theme.text), + )), + Spans::from(Span::styled( + " 3. If you're using spotifyd as a playback device, your device name must not contain spaces", + Style::default().fg(app.user_config.theme.text), + )), + Spans::from(Span::styled("Hint: a playback device must be either an official spotify client or a light weight alternative such as spotifyd", + Style::default().fg(app.user_config.theme.hint) ), - Span::styled(" -Hint: a playback device must be either an official spotify client or a light weight alternative such as spotifyd - ", - Style::default().fg(app.user_config.theme.hint)), - Span::styled( - "\nPress to return", - Style::default().fg(app.user_config.theme.inactive), - ), - ]); + ), + Spans::from( + Span::styled( + "\nPress to return", + Style::default().fg(app.user_config.theme.inactive), + ), + ) + ]; let playing_paragraph = Paragraph::new(playing_text) .wrap(Wrap { trim: true }) @@ -1184,12 +1197,12 @@ where .margin(5) .split(f.size()); - let device_instructions = Spans::from(vec![ - Span::raw("To play tracks, please select a device. "), - Span::raw("Use `j/k` or up/down arrow keys to move up and down and to select. "), - Span::raw("Your choice here will be cached so you can jump straight back in when you next open `spotify-tui`. "), - Span::raw("You can change the playback device at any time by pressing `d`."), - ]); + let device_instructions: Vec = vec![ + "To play tracks, please select a device. ", + "Use `j/k` or up/down arrow keys to move up and down and to select. ", + "Your choice here will be cached so you can jump straight back in when you next open `spotify-tui`. ", + "You can change the playback device at any time by pressing `d`.", + ].into_iter().map(|instruction| Spans::from(Span::raw(instruction))).collect(); let instructions = Paragraph::new(device_instructions) .style(Style::default().fg(app.user_config.theme.text)) @@ -1566,16 +1579,18 @@ where // suggestion: possibly put this as part of // app.dialog, but would have to introduce lifetime - let text = Spans::from(vec![ - Span::raw("Are you sure you want to delete\nthe playlist: "), - Span::styled( + let text = vec![ + Spans::from(Span::raw("Are you sure you want to delete the playlist: ")), + Spans::from(Span::styled( playlist.as_str(), Style::default().add_modifier(Modifier::BOLD), - ), - Span::raw("?"), - ]); + )), + Spans::from(Span::raw("?")), + ]; - let text = Paragraph::new(text).alignment(Alignment::Center); + let text = Paragraph::new(text) + .wrap(Wrap { trim: true }) + .alignment(Alignment::Center); f.render_widget(text, vchunks[0]); From 97b70c0cf239dadd70d6d748f192c3ca6520194f Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 5 Oct 2020 10:43:20 +0100 Subject: [PATCH 179/311] Prepare release v0.22.0 --- CHANGELOG.md | 15 +++++++++++++-- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81587604..8f2fefb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,15 +2,26 @@ ## [Unreleased] +## [0.22.0] - 2020-10-05 + +### Fixed + - Show β™₯ next to album name in saved list [#540](https://github.com/Rigellute/spotify-tui/pull/540) +- Fix to be able to follow an artist in search result view [#565](https://github.com/Rigellute/spotify-tui/pull/565) +- Don't add analysis view to stack if already in it [#580](https://github.com/Rigellute/spotify-tui/pull/580) + +### Added + - Add additional line of help to show that 'w' can be used to save/like an album [#548](https://github.com/Rigellute/spotify-tui/pull/548) - Add handling Home and End buttons in user input [#550](https://github.com/Rigellute/spotify-tui/pull/550) - Add `playbar_progress_text` to user config and upgrade tui lib [#564](https://github.com/Rigellute/spotify-tui/pull/564) - Add basic playbar support for podcasts [#563](https://github.com/Rigellute/spotify-tui/pull/563) -- Fix to be able to follow an artist in search result view [#565](https://github.com/Rigellute/spotify-tui/pull/565) - Add 'enable_text_emphasis' behavior config option [#573](https://github.com/Rigellute/spotify-tui/pull/573) -- Don't add analysis view to stack if already in it [#580](https://github.com/Rigellute/spotify-tui/pull/580) - Add next/prev page, jump to start/end to user config [#566](https://github.com/Rigellute/spotify-tui/pull/566) +- Add possibility to queue a song [#567](https://github.com/Rigellute/spotify-tui/pull/567) +- Add user-configurable header styling [#583](https://github.com/Rigellute/spotify-tui/pull/583) +- Show active keybindings in Help [#585](https://github.com/Rigellute/spotify-tui/pull/585) +- Full Podcast support [#581](https://github.com/Rigellute/spotify-tui/pull/581) ## [0.21.0] - 2020-07-24 diff --git a/Cargo.lock b/Cargo.lock index 5e79c678..15679696 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1737,7 +1737,7 @@ dependencies = [ [[package]] name = "spotify-tui" -version = "0.21.0" +version = "0.22.0" dependencies = [ "anyhow", "backtrace", diff --git a/Cargo.toml b/Cargo.toml index 471fc048..cdcb78a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ documentation = "https://github.com/Rigellute/spotify-tui" repository = "https://github.com/Rigellute/spotify-tui" keywords = ["spotify", "tui", "cli", "terminal"] categories = ["command-line-utilities"] -version = "0.21.0" +version = "0.22.0" authors = ["Alexander Keliris "] edition = "2018" license = "MIT OR Apache-2.0" From e4555b8ae2a04120b8ec6548e5adf99110cbc2bd Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Sun, 11 Oct 2020 08:35:18 +0100 Subject: [PATCH 180/311] Fix new clippy warnings (#614) * Fix new clippy warnings * Temp downgrade clippy toolchain Clippy is failing on CI with ``` panicked at 'index out of bounds: the len is 1 but the index is 1', src/tools/clippy/clippy_lints/src/repeat_once.rs:44:93 ``` This has been fixed in clippy itself, but was missed in the 1.47.0 release (https://github.com/rust-lang/rust-clippy/issues/6147). --- .github/workflows/ci.yml | 3 ++- src/handlers/common_key_events.rs | 36 +++++++------------------------ 2 files changed, 10 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75058c5a..3475e1f6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,9 +72,10 @@ jobs: needs: prepare steps: - uses: actions/checkout@master + # Temporarily downgrade Clippy until a new stable release includes a fix for CI breaking on 1.47 https://github.com/rust-lang/rust-clippy/issues/6147 - uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: 1.46.0 override: true - run: rustup component add clippy - uses: actions-rs/cargo@v1 diff --git a/src/handlers/common_key_events.rs b/src/handlers/common_key_events.rs index befa9b51..f1c2b3fc 100644 --- a/src/handlers/common_key_events.rs +++ b/src/handlers/common_key_events.rs @@ -1,52 +1,32 @@ use super::super::app::{ActiveBlock, App, RouteId}; use crate::event::Key; + pub fn down_event(key: Key) -> bool { - match key { - Key::Down | Key::Char('j') | Key::Ctrl('n') => true, - _ => false, - } + matches!(key, Key::Down | Key::Char('j') | Key::Ctrl('n')) } pub fn up_event(key: Key) -> bool { - match key { - Key::Up | Key::Char('k') | Key::Ctrl('p') => true, - _ => false, - } + matches!(key, Key::Up | Key::Char('k') | Key::Ctrl('p')) } pub fn left_event(key: Key) -> bool { - match key { - Key::Left | Key::Char('h') | Key::Ctrl('b') => true, - _ => false, - } + matches!(key, Key::Left | Key::Char('h') | Key::Ctrl('b')) } pub fn right_event(key: Key) -> bool { - match key { - Key::Right | Key::Char('l') | Key::Ctrl('f') => true, - _ => false, - } + matches!(key, Key::Right | Key::Char('l') | Key::Ctrl('f')) } pub fn high_event(key: Key) -> bool { - match key { - Key::Char('H') => true, - _ => false, - } + matches!(key, Key::Char('H')) } pub fn middle_event(key: Key) -> bool { - match key { - Key::Char('M') => true, - _ => false, - } + matches!(key, Key::Char('M')) } pub fn low_event(key: Key) -> bool { - match key { - Key::Char('L') => true, - _ => false, - } + matches!(key, Key::Char('L')) } pub fn on_down_press_handler(selection_data: &[T], selection_index: Option) -> usize { From bfe23d084de7221f6726c5710b22f15522101226 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 11 Oct 2020 08:41:14 +0100 Subject: [PATCH 181/311] Bump anyhow from 1.0.32 to 1.0.33 (#609) Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.32 to 1.0.33. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.32...1.0.33) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 15679696..b1c905b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,9 +35,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" +checksum = "a1fd36ffbb1fb7c834eac128ea8d0e310c5aeb635548f9d58861e1308d46e71c" [[package]] name = "arc-swap" diff --git a/Cargo.toml b/Cargo.toml index cdcb78a3..bdc7ba79 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ clipboard = "0.5.0" crossterm = "0.18" tokio = { version = "0.2", features = ["full"] } rand = "0.7.3" -anyhow = "1.0.32" +anyhow = "1.0.33" [[bin]] bench = false From 954864f8c1772d31e2930fb88ed8b32cc3b3ebbe Mon Sep 17 00:00:00 2001 From: May Date: Sun, 11 Oct 2020 03:50:07 -0400 Subject: [PATCH 182/311] Implement next/previous pagination behavior for the artists view (#604) --- src/app.rs | 46 +++++++++++++++++++++++++++++++++++++++++ src/handlers/artists.rs | 2 ++ src/network.rs | 10 +++++++++ 3 files changed, 58 insertions(+) diff --git a/src/app.rs b/src/app.rs index ad1b19a1..00010c41 100644 --- a/src/app.rs +++ b/src/app.rs @@ -676,6 +676,52 @@ impl App { )); } + pub fn set_saved_artists_to_table(&mut self, saved_artists_page: &CursorBasedPage) { + self.dispatch(IoEvent::SetArtistsToTable( + saved_artists_page + .items + .clone() + .into_iter() + .collect::>(), + )) + } + + pub fn get_current_user_saved_artists_next(&mut self) { + match self + .library + .saved_artists + .get_results(Some(self.library.saved_artists.index + 1)) + .cloned() + { + Some(saved_artists) => { + self.set_saved_artists_to_table(&saved_artists); + self.library.saved_artists.index += 1 + } + None => { + if let Some(saved_artists) = &self.library.saved_artists.clone().get_results(None) { + match saved_artists.items.last() { + Some(last_artist) => { + self.dispatch(IoEvent::GetFollowedArtists(Some(last_artist.id.clone()))); + } + None => { + return; + } + } + } + } + } + } + + pub fn get_current_user_saved_artists_previous(&mut self) { + if self.library.saved_artists.index > 0 { + self.library.saved_artists.index -= 1; + } + + if let Some(saved_artists) = &self.library.saved_artists.get_results(None).cloned() { + self.set_saved_artists_to_table(&saved_artists); + } + } + pub fn get_current_user_saved_tracks_next(&mut self) { // Before fetching the next tracks, check if we have already fetched them match self diff --git a/src/handlers/artists.rs b/src/handlers/artists.rs index 4e28c8b9..207eb164 100644 --- a/src/handlers/artists.rs +++ b/src/handlers/artists.rs @@ -72,6 +72,8 @@ pub fn handler(key: Key, app: &mut App) { app.get_recommendations_for_seed(artist_id_list, None, None); } } + k if k == app.user_config.keys.next_page => app.get_current_user_saved_artists_next(), + k if k == app.user_config.keys.previous_page => app.get_current_user_saved_artists_previous(), _ => {} } } diff --git a/src/network.rs b/src/network.rs index fe0092bf..6541fe5c 100644 --- a/src/network.rs +++ b/src/network.rs @@ -8,6 +8,7 @@ use rspotify::{ client::Spotify, model::{ album::SimplifiedAlbum, + artist::FullArtist, offset::for_position, page::Page, playlist::{PlaylistTrack, SimplifiedPlaylist}, @@ -71,6 +72,7 @@ pub enum IoEvent { GetRecommendationsForTrackId(String, Option), GetRecentlyPlayed, GetFollowedArtists(Option), + SetArtistsToTable(Vec), UserArtistFollowCheck(Vec), GetAlbum(String), SetDeviceIdInConfig(String), @@ -246,6 +248,9 @@ impl<'a> Network<'a> { IoEvent::GetFollowedArtists(after) => { self.get_followed_artists(after).await; } + IoEvent::SetArtistsToTable(full_artists) => { + self.set_artists_to_table(full_artists).await; + } IoEvent::UserArtistFollowCheck(artist_ids) => { self.user_artist_check_follow(artist_ids).await; } @@ -404,6 +409,11 @@ impl<'a> Network<'a> { )); } + async fn set_artists_to_table(&mut self, artists: Vec) { + let mut app = self.app.lock().await; + app.artists = artists; + } + async fn get_made_for_you_playlist_tracks( &mut self, playlist_id: String, From 9e03d064173d284577f7016160d625cbde93768a Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sun, 11 Oct 2020 08:51:10 +0100 Subject: [PATCH 183/311] docs: add Utagai as a contributor (#615) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index c2a08424..dfe5e530 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -652,6 +652,15 @@ "code", "doc" ] + }, + { + "login": "Utagai", + "name": "May", + "avatar_url": "https://avatars2.githubusercontent.com/u/10730394?v=4", + "profile": "https://github.com/Utagai", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 076ce2e0..c1b63bae 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-70-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-71-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -393,6 +393,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
n-ivanov

πŸ’»
bi1yeu

πŸ’» πŸ“– + +
May

πŸ’» + From c01b92c0d0b8eb3b7e415ba31323f525a41b6467 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Sun, 11 Oct 2020 08:52:03 +0100 Subject: [PATCH 184/311] Fix app crash due to unwrap (#599) Closes #590 --- src/handlers/made_for_you.rs | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/handlers/made_for_you.rs b/src/handlers/made_for_you.rs index ede6e354..1645ae26 100644 --- a/src/handlers/made_for_you.rs +++ b/src/handlers/made_for_you.rs @@ -41,24 +41,21 @@ pub fn handler(key: Key, app: &mut App) { } } Key::Enter => { - let (playlists, selected_playlist_index) = ( - &app - .library - .made_for_you_playlists - .get_results(Some(0)) - .unwrap(), + if let (Some(playlists), selected_playlist_index) = ( + &app.library.made_for_you_playlists.get_results(Some(0)), &app.made_for_you_index, - ); - app.track_table.context = Some(TrackTableContext::MadeForYou); - app.playlist_offset = 0; - if let Some(selected_playlist) = playlists.items.get(selected_playlist_index.to_owned()) { - app.made_for_you_offset = 0; - let playlist_id = selected_playlist.id.to_owned(); - app.dispatch(IoEvent::GetMadeForYouPlaylistTracks( - playlist_id, - app.made_for_you_offset, - )); - } + ) { + app.track_table.context = Some(TrackTableContext::MadeForYou); + app.playlist_offset = 0; + if let Some(selected_playlist) = playlists.items.get(selected_playlist_index.to_owned()) { + app.made_for_you_offset = 0; + let playlist_id = selected_playlist.id.to_owned(); + app.dispatch(IoEvent::GetMadeForYouPlaylistTracks( + playlist_id, + app.made_for_you_offset, + )); + } + }; } _ => {} } From f8e0872fc39f8ab0f5674c2466c68d61c37f9945 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 11 Oct 2020 08:53:06 +0100 Subject: [PATCH 185/311] Bump backtrace from 0.3.51 to 0.3.52 (#610) Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.51 to 0.3.52. - [Release notes](https://github.com/rust-lang/backtrace-rs/releases) - [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.51...0.3.52) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b1c905b3..a0723ac3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,9 +82,9 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.51" +version = "0.3.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec1931848a574faa8f7c71a12ea00453ff5effbb5f51afe7f77d7a48cace6ac1" +checksum = "f813291114c186a042350e787af10c26534601062603d888be110f59f85ef8fa" dependencies = [ "addr2line", "cfg-if", diff --git a/Cargo.toml b/Cargo.toml index bdc7ba79..254dc35b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ serde_yaml = "0.8" dirs = "3.0.1" clap = "2.33.3" unicode-width = "0.1.8" -backtrace = "0.3.51" +backtrace = "0.3.52" clipboard = "0.5.0" crossterm = "0.18" tokio = { version = "0.2", features = ["full"] } From 60b9d28d0da775542f96b00aa47a53cae68c2e83 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 11 Oct 2020 08:53:14 +0100 Subject: [PATCH 186/311] Bump serde_json from 1.0.57 to 1.0.58 (#600) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.57 to 1.0.58. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.57...v1.0.58) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a0723ac3..0309f574 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1657,9 +1657,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" +checksum = "a230ea9107ca2220eea9d46de97eddcb04cd00e92d13dda78e478dd33fa82bd4" dependencies = [ "itoa", "ryu", From 880c41589c068d496917a10a07165d2b85a134be Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Sun, 11 Oct 2020 08:55:15 +0100 Subject: [PATCH 187/311] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f2fefb4..993f3b7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## [Unreleased] +- Implement next/previous page behavior for the Artists table [#604](https://github.com/Rigellute/spotify-tui/pull/604) +- Fix app crash when pressing Enter before a screen has loaded [#599](https://github.com/Rigellute/spotify-tui/pull/599) + ## [0.22.0] - 2020-10-05 ### Fixed From 15204b3dae509abb22c91dd54fe9393e60644844 Mon Sep 17 00:00:00 2001 From: May Date: Tue, 13 Oct 2020 04:20:37 -0400 Subject: [PATCH 188/311] Update the saved albums cache set when getting an artist (#612) * Update the saved albums cache set when getting an artist * Prefer dispatching an IO event for updating the album cache set This should be more robust, less-awkward and consistent with the rest of the codebase. --- src/network.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/network.rs b/src/network.rs index 6541fe5c..360b6e64 100644 --- a/src/network.rs +++ b/src/network.rs @@ -786,6 +786,15 @@ impl<'a> Network<'a> { if let Ok((albums, top_tracks, related_artist)) = try_join!(albums, top_tracks, related_artist) { let mut app = self.app.lock().await; + + app.dispatch(IoEvent::CurrentUserSavedAlbumsContains( + albums + .items + .iter() + .filter_map(|item| item.id.to_owned()) + .collect(), + )); + app.artist = Some(Artist { artist_name, albums, @@ -979,10 +988,10 @@ impl<'a> Network<'a> { } async fn user_artist_check_follow(&mut self, artist_ids: Vec) { - if let Ok(are_follwed) = self.spotify.user_artist_check_follow(&artist_ids).await { + if let Ok(are_followed) = self.spotify.user_artist_check_follow(&artist_ids).await { let mut app = self.app.lock().await; artist_ids.iter().enumerate().for_each(|(i, id)| { - if are_follwed[i] { + if are_followed[i] { app.followed_artist_ids_set.insert(id.to_owned()); } else { app.followed_artist_ids_set.remove(id); @@ -1011,14 +1020,14 @@ impl<'a> Network<'a> { } async fn current_user_saved_albums_contains(&mut self, album_ids: Vec) { - if let Ok(are_follwed) = self + if let Ok(are_followed) = self .spotify .current_user_saved_albums_contains(&album_ids) .await { let mut app = self.app.lock().await; album_ids.iter().enumerate().for_each(|(i, id)| { - if are_follwed[i] { + if are_followed[i] { app.saved_album_ids_set.insert(id.to_owned()); } else { app.saved_album_ids_set.remove(id); From f498dc2ffdd2f93548a8de22ac4cfee626d8e0a1 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Tue, 13 Oct 2020 09:23:13 +0100 Subject: [PATCH 189/311] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 993f3b7c..5a4f24a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Implement next/previous page behavior for the Artists table [#604](https://github.com/Rigellute/spotify-tui/pull/604) - Fix app crash when pressing Enter before a screen has loaded [#599](https://github.com/Rigellute/spotify-tui/pull/599) +- Show saved albums when getting an artist [#612](https://github.com/Rigellute/spotify-tui/pull/612) ## [0.22.0] - 2020-10-05 From ed3f3dfab65676a11d56aa7373414af0f759f659 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 13 Oct 2020 09:24:15 +0100 Subject: [PATCH 190/311] docs: add Utagai as a contributor (#620) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> From 00b1acd846983b3ddee82d029ada91457765203d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Gerber?= <37541513+TimotheeGerber@users.noreply.github.com> Date: Wed, 21 Oct 2020 11:11:56 +0200 Subject: [PATCH 191/311] Transfer playback when changing device (#408) Closes #366 --- README.md | 2 +- src/handlers/select_device.rs | 2 +- src/network.rs | 18 ++++++++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c1b63bae..0eacd8ea 100644 --- a/README.md +++ b/README.md @@ -475,7 +475,7 @@ This table shows all that is possible with the Spotify API, what is implemented | device | Yes | Get a User’s Available Devices | Yes | | current_playback | Yes | Get Information About The User’s Current Playback | Yes | | current_playing | No | Get the User’s Currently Playing Track | No | -| transfer_playback | No | Transfer a User’s Playback | No | +| transfer_playback | Yes | Transfer a User’s Playback | Yes | | start_playback | Yes | Start/Resume a User’s Playback | Yes | | pause_playback | Yes | Pause a User’s Playback | Yes | | next_track | Yes | Skip User’s Playback To Next Track | Yes | diff --git a/src/handlers/select_device.rs b/src/handlers/select_device.rs index c8c4e3d7..f0514a70 100644 --- a/src/handlers/select_device.rs +++ b/src/handlers/select_device.rs @@ -70,7 +70,7 @@ pub fn handler(key: Key, app: &mut App) { Key::Enter => { if let (Some(devices), Some(index)) = (app.devices.clone(), app.selected_device_index) { if let Some(device) = &devices.devices.get(index) { - app.dispatch(IoEvent::SetDeviceIdInConfig(device.id.clone())); + app.dispatch(IoEvent::TransferPlaybackToDevice(device.id.clone())); } }; } diff --git a/src/network.rs b/src/network.rs index 360b6e64..4d31a5c1 100644 --- a/src/network.rs +++ b/src/network.rs @@ -75,7 +75,7 @@ pub enum IoEvent { SetArtistsToTable(Vec), UserArtistFollowCheck(Vec), GetAlbum(String), - SetDeviceIdInConfig(String), + TransferPlaybackToDevice(String), CurrentUserSavedTracksContains(Vec), GetShowEpisodes(String), AddItemToQueue(String), @@ -257,8 +257,8 @@ impl<'a> Network<'a> { IoEvent::GetAlbum(album_id) => { self.get_album(album_id).await; } - IoEvent::SetDeviceIdInConfig(device_id) => { - self.set_device_id_in_config(device_id).await; + IoEvent::TransferPlaybackToDevice(device_id) => { + self.transfert_playback_to_device(device_id).await; } IoEvent::Shuffle(shuffle_state) => { self.shuffle(shuffle_state).await; @@ -1255,7 +1255,17 @@ impl<'a> Network<'a> { } } - async fn set_device_id_in_config(&mut self, device_id: String) { + async fn transfert_playback_to_device(&mut self, device_id: String) { + match self.spotify.transfer_playback(&device_id, true).await { + Ok(()) => { + self.get_current_playback().await; + } + Err(e) => { + self.handle_error(anyhow!(e)).await; + return; + } + }; + match self.client_config.set_device_id(device_id) { Ok(()) => { let mut app = self.app.lock().await; From 54827dedfabfe1cd1481f8a8c7cae74e54d86458 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Wed, 21 Oct 2020 10:32:24 +0100 Subject: [PATCH 192/311] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a4f24a6..596b1e66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Implement next/previous page behavior for the Artists table [#604](https://github.com/Rigellute/spotify-tui/pull/604) - Fix app crash when pressing Enter before a screen has loaded [#599](https://github.com/Rigellute/spotify-tui/pull/599) - Show saved albums when getting an artist [#612](https://github.com/Rigellute/spotify-tui/pull/612) +- Transfer playback when changing device [#408](https://github.com/Rigellute/spotify-tui/pull/408) ## [0.22.0] - 2020-10-05 From 35950f1968bac8f7e9404bd772f1995e08ab0174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20A=2E=20Muci=C3=B1o?= Date: Wed, 21 Oct 2020 04:39:44 -0500 Subject: [PATCH 193/311] Simple change of layout (#502) * Change of layout. Constraints of size in fn draw_input_and_help_box changed from ".constraints([Constraint::Percentage(90), Constraint::Percentage(10)].as_ref())" to ".constraints([Constraint::Percentage(65), Constraint::Percentage(35)].as_ref())" to better suit the smaller space. fn draw_input_and_help_box moved to fn_draw_user_block * Add responsiveness to new layout change The new layout kicks in is the width is bigger than 150 (defined as SMALL_TERMINAL_WIDTH * Fix formatting. Co-authored-by: Finn Hediger --- src/ui/mod.rs | 101 ++++++++++++++++++++++++++++++++++--------------- src/ui/util.rs | 1 + 2 files changed, 72 insertions(+), 30 deletions(-) diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 71f03bb1..a458eb23 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -23,7 +23,7 @@ use tui::{ use util::{ create_artist_string, display_track_progress, get_artist_highlight_state, get_color, get_percentage_width, get_search_results_highlight_state, get_track_progress_percentage, - millis_to_minutes, + millis_to_minutes, SMALL_TERMINAL_WIDTH, }; pub enum TableId { @@ -114,9 +114,14 @@ pub fn draw_input_and_help_box(f: &mut Frame, app: &App, layout_chunk: Rec where B: Backend, { + // Check for the width and change the contraints accordingly let chunks = Layout::default() .direction(Direction::Horizontal) - .constraints([Constraint::Percentage(90), Constraint::Percentage(10)].as_ref()) + .constraints(if app.size.width >= SMALL_TERMINAL_WIDTH { + [Constraint::Percentage(65), Constraint::Percentage(35)].as_ref() + } else { + [Constraint::Percentage(90), Constraint::Percentage(10)].as_ref() + }) .split(layout_chunk); let current_route = app.get_current_route(); @@ -163,27 +168,42 @@ where B: Backend, { let margin = util::get_main_layout_margin(app); - let parent_layout = Layout::default() - .direction(Direction::Vertical) - .constraints( - [ - Constraint::Length(3), - Constraint::Min(1), - Constraint::Length(6), - ] - .as_ref(), - ) - .margin(margin) - .split(f.size()); - - // Search input and help - draw_input_and_help_box(f, app, parent_layout[0]); - - // Nested main block with potential routes - draw_routes(f, app, parent_layout[1]); - - // Currently playing - draw_playbar(f, app, parent_layout[2]); + // Responsive layout: new one kicks in at width 150 or higher + if app.size.width >= SMALL_TERMINAL_WIDTH { + let parent_layout = Layout::default() + .direction(Direction::Vertical) + .constraints([Constraint::Min(1), Constraint::Length(6)].as_ref()) + .margin(margin) + .split(f.size()); + + // Nested main block with potential routes + draw_routes(f, app, parent_layout[0]); + + // Currently playing + draw_playbar(f, app, parent_layout[1]); + } else { + let parent_layout = Layout::default() + .direction(Direction::Vertical) + .constraints( + [ + Constraint::Length(3), + Constraint::Min(1), + Constraint::Length(6), + ] + .as_ref(), + ) + .margin(margin) + .split(f.size()); + + // Search input and help + draw_input_and_help_box(f, app, parent_layout[0]); + + // Nested main block with potential routes + draw_routes(f, app, parent_layout[1]); + + // Currently playing + draw_playbar(f, app, parent_layout[2]); + } // Possibly draw confirm dialog draw_dialog(f, app); @@ -297,13 +317,34 @@ pub fn draw_user_block(f: &mut Frame, app: &App, layout_chunk: Rect) where B: Backend, { - let chunks = Layout::default() - .direction(Direction::Vertical) - .constraints([Constraint::Percentage(30), Constraint::Percentage(70)].as_ref()) - .split(layout_chunk); - - draw_library_block(f, app, chunks[0]); - draw_playlist_block(f, app, chunks[1]); + // Check for width to make a responsive layout + if app.size.width >= SMALL_TERMINAL_WIDTH { + let chunks = Layout::default() + .direction(Direction::Vertical) + .constraints( + [ + Constraint::Length(3), + Constraint::Percentage(30), + Constraint::Percentage(70), + ] + .as_ref(), + ) + .split(layout_chunk); + + // Search input and help + draw_input_and_help_box(f, app, chunks[0]); + draw_library_block(f, app, chunks[1]); + draw_playlist_block(f, app, chunks[2]); + } else { + let chunks = Layout::default() + .direction(Direction::Vertical) + .constraints([Constraint::Percentage(30), Constraint::Percentage(70)].as_ref()) + .split(layout_chunk); + + // Search input and help + draw_library_block(f, app, chunks[0]); + draw_playlist_block(f, app, chunks[1]); + } } pub fn draw_search_results(f: &mut Frame, app: &App, layout_chunk: Rect) diff --git a/src/ui/util.rs b/src/ui/util.rs index 6d03ded5..0b4b506c 100644 --- a/src/ui/util.rs +++ b/src/ui/util.rs @@ -3,6 +3,7 @@ use crate::user_config::Theme; use rspotify::model::artist::SimplifiedArtist; use tui::style::Style; +pub const SMALL_TERMINAL_WIDTH: u16 = 150; pub const SMALL_TERMINAL_HEIGHT: u16 = 45; pub fn get_search_results_highlight_state( From 08325baa7f1ba14efaa8cbe4e6a76c85068dd752 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Wed, 21 Oct 2020 10:40:47 +0100 Subject: [PATCH 194/311] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 596b1e66..6fb546c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Fix app crash when pressing Enter before a screen has loaded [#599](https://github.com/Rigellute/spotify-tui/pull/599) - Show saved albums when getting an artist [#612](https://github.com/Rigellute/spotify-tui/pull/612) - Transfer playback when changing device [#408](https://github.com/Rigellute/spotify-tui/pull/408) +- Make layout more responsive to large/small screens [#502](https://github.com/Rigellute/spotify-tui/pull/502) ## [0.22.0] - 2020-10-05 From 95a51dca03e1b734eabec6809cff51878bda2b89 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2020 10:41:15 +0100 Subject: [PATCH 195/311] docs: add mucinoab as a contributor (#629) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index dfe5e530..8f2c912e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -661,6 +661,15 @@ "contributions": [ "code" ] + }, + { + "login": "mucinoab", + "name": "Bruno A. MuciΓ±o", + "avatar_url": "https://avatars1.githubusercontent.com/u/28630268?v=4", + "profile": "https://mucinoab.github.io/", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 0eacd8ea..ac4624b6 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-71-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-72-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -395,6 +395,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
May

πŸ’» +
Bruno A. MuciΓ±o

πŸ’» From 4debdd6c416e8ff14b7039930a9bfde9a2f8bac0 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2020 10:46:22 +0100 Subject: [PATCH 196/311] docs: add OrangeFran as a contributor (#631) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8f2c912e..89b44f7b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -670,6 +670,15 @@ "contributions": [ "code" ] + }, + { + "login": "OrangeFran", + "name": "Finn Hediger", + "avatar_url": "https://avatars2.githubusercontent.com/u/55061632?v=4", + "profile": "https://github.com/OrangeFran", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index ac4624b6..d2e605f6 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,9 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) + [![All Contributors](https://img.shields.io/badge/all_contributors-72-orange.svg?style=flat-square)](#contributors-) + [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -214,7 +216,7 @@ theme: playbar_text: White # artist name in player pane selected: LightCyan # a) selected pane border, b) hovered item in list, & c) track title in player text: "255, 255, 255" # text in panes - header: White # header text in panes (e.g. 'Title', 'Artist', etc.) + header: White # header text in panes (e.g. 'Title', 'Artist', etc.) behavior: seek_milliseconds: 5000 @@ -396,11 +398,13 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
May

πŸ’»
Bruno A. MuciΓ±o

πŸ’» +
Finn Hediger

πŸ’» + This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! From ed0bf031f81ee348cab0da03939cb3a6848a669b Mon Sep 17 00:00:00 2001 From: May Date: Thu, 22 Oct 2020 06:47:42 -0400 Subject: [PATCH 197/311] Support searching by Spotify share URLs and URIs analogously to the desktop client (#623) * Generalize input processing to both URLs and URIs Unfortunately, I would have preferred the small refactor of adding process_input() to be in a separate commit, but I quite genuinely just forgot to commit my work, so these guys are mushed together here. * Add the boilerplate code for supporting tracks, playlists and podcasts * Introduce a spotify_resource_id() closure to reduce some duplication * Support searching playlists by URL/Spotify-URI * Support searching shows by URL/Spotify-URI * Support searching individual tracks by URL/Spotify-URI * Add initial parsing tests and required refactors * Add full suite of happy path test cases * Verify that we fail to match on invalid strings * Remove debug prints * Correct seek to track index on track search Albeit, not very cleanly. Want to try getting it nicer before I put this up... * Handle query parameters in URIs * Always push a GetPlaylist to the navigation stack to avoid UI inconsistency * Clear the playlist selection no matter what kind of search we do * Remove debug prints * Remove redundant clone * Prefer unwrap_or_else() --- src/handlers/input.rs | 202 ++++++++++++++++++++++++++++++++++++------ src/network.rs | 41 ++++++++- 2 files changed, 212 insertions(+), 31 deletions(-) diff --git a/src/handlers/input.rs b/src/handlers/input.rs index 81589e08..f7d79fa0 100644 --- a/src/handlers/input.rs +++ b/src/handlers/input.rs @@ -69,36 +69,9 @@ pub fn handler(key: Key, app: &mut App) { app.set_current_route_state(Some(ActiveBlock::Empty), Some(ActiveBlock::Library)); } Key::Enter => { - let user_country = app.get_user_country(); let input_str: String = app.input.iter().collect(); - // Don't do anything if there is no input - if input_str.is_empty() { - return; - } - - let album_url_prefix = "https://open.spotify.com/album/"; - - if input_str.starts_with(album_url_prefix) { - let album_id = input_str.trim_start_matches(album_url_prefix); - app.dispatch(IoEvent::GetAlbum(album_id.to_string())); - return; - } - - let artist_url_prefix = "https://open.spotify.com/artist/"; - - if input_str.starts_with(artist_url_prefix) { - let artist_id = input_str.trim_start_matches(artist_url_prefix); - app.get_artist(artist_id.to_string(), "".to_string()); - app.push_navigation_stack(RouteId::Artist, ActiveBlock::ArtistBlock); - return; - } - - app.dispatch(IoEvent::GetSearchResults(input_str, user_country)); - - // On searching for a track, clear the playlist selection - app.selected_playlist_index = Some(0); - app.push_navigation_stack(RouteId::Search, ActiveBlock::SearchResultBlock); + process_input(app, input_str); } Key::Char(c) => { app.input.insert(app.input_idx, c); @@ -121,6 +94,74 @@ pub fn handler(key: Key, app: &mut App) { } } +fn process_input(app: &mut App, input: String) { + // Don't do anything if there is no input + if input.is_empty() { + return; + } + + // On searching for a track, clear the playlist selection + app.selected_playlist_index = Some(0); + + if attempt_process_uri(app, &input, "https://open.spotify.com/", "/") + || attempt_process_uri(app, &input, "spotify:", ":") + { + return; + } + + // Default fallback behavior: treat the input as a raw search phrase. + app.dispatch(IoEvent::GetSearchResults(input, app.get_user_country())); + app.push_navigation_stack(RouteId::Search, ActiveBlock::SearchResultBlock); +} + +fn spotify_resource_id(base: &str, uri: &str, sep: &str, resource_type: &str) -> (String, bool) { + let uri_prefix = format!("{}{}{}", base, resource_type, sep); + let id_string_with_query_params = uri.trim_start_matches(&uri_prefix); + let query_idx = id_string_with_query_params + .find('?') + .unwrap_or_else(|| id_string_with_query_params.len()); + let id_string = id_string_with_query_params[0..query_idx].to_string(); + // If the lengths aren't equal, we must have found a match. + let matched = id_string_with_query_params.len() != uri.len() && id_string.len() != uri.len(); + (id_string, matched) +} + +// Returns true if the input was successfully processed as a Spotify URI. +fn attempt_process_uri(app: &mut App, input: &str, base: &str, sep: &str) -> bool { + let (album_id, matched) = spotify_resource_id(base, input, sep, "album"); + if matched { + app.dispatch(IoEvent::GetAlbum(album_id)); + return true; + } + + let (artist_id, matched) = spotify_resource_id(base, input, sep, "artist"); + if matched { + app.get_artist(artist_id, "".to_string()); + app.push_navigation_stack(RouteId::Artist, ActiveBlock::ArtistBlock); + return true; + } + + let (track_id, matched) = spotify_resource_id(base, input, sep, "track"); + if matched { + app.dispatch(IoEvent::GetAlbumForTrack(track_id)); + return true; + } + + let (playlist_id, matched) = spotify_resource_id(base, input, sep, "playlist"); + if matched { + app.dispatch(IoEvent::GetPlaylistTracks(playlist_id, 0)); + return true; + } + + let (show_id, matched) = spotify_resource_id(base, input, sep, "show"); + if matched { + app.dispatch(IoEvent::GetShowEpisodes(show_id)); + return true; + } + + false +} + fn compute_character_width(character: char) -> u16 { UnicodeWidthChar::width(character) .unwrap() @@ -357,4 +398,109 @@ mod tests { assert_eq!(app.input_idx, 2); assert_eq!(app.input_cursor_position, 4); } + + mod test_uri_parsing { + use super::*; + + const URI_BASE: &str = "spotify:"; + const URL_BASE: &str = "https://open.spotify.com/"; + + fn check_uri_parse(expected_id: &str, parsed: (String, bool)) { + assert_eq!(parsed.1, true); + assert_eq!(parsed.0, expected_id); + } + + fn run_test_for_id_and_resource_type(id: &str, resource_type: &str) { + check_uri_parse( + id, + spotify_resource_id( + URI_BASE, + &format!("spotify:{}:{}", resource_type, id), + ":", + resource_type, + ), + ); + check_uri_parse( + id, + spotify_resource_id( + URL_BASE, + &format!("https://open.spotify.com/{}/{}", resource_type, id), + "/", + resource_type, + ), + ) + } + + #[test] + fn artist() { + let expected_artist_id = "2ye2Wgw4gimLv2eAKyk1NB"; + run_test_for_id_and_resource_type(expected_artist_id, "artist"); + } + + #[test] + fn album() { + let expected_album_id = "5gzLOflH95LkKYE6XSXE9k"; + run_test_for_id_and_resource_type(expected_album_id, "album"); + } + + #[test] + fn playlist() { + let expected_playlist_id = "1cJ6lPBYj2fscs0kqBHsVV"; + run_test_for_id_and_resource_type(expected_playlist_id, "playlist"); + } + + #[test] + fn show() { + let expected_show_id = "3aNsrV6lkzmcU1w8u8kA7N"; + run_test_for_id_and_resource_type(expected_show_id, "show"); + } + + #[test] + fn track() { + let expected_track_id = "10igKaIKsSB6ZnWxPxPvKO"; + run_test_for_id_and_resource_type(expected_track_id, "track"); + } + + #[test] + fn invalid_format_doesnt_match() { + let swapped = "show:spotify:3aNsrV6lkzmcU1w8u8kA7N"; + let totally_wrong = "hehe-haha-3aNsrV6lkzmcU1w8u8kA7N"; + let random = "random string"; + let (_, matched) = spotify_resource_id(URI_BASE, swapped, ":", "track"); + assert_eq!(matched, false); + let (_, matched) = spotify_resource_id(URI_BASE, totally_wrong, ":", "track"); + assert_eq!(matched, false); + let (_, matched) = spotify_resource_id(URL_BASE, totally_wrong, "/", "track"); + assert_eq!(matched, false); + let (_, matched) = spotify_resource_id(URL_BASE, random, "/", "track"); + assert_eq!(matched, false); + } + + #[test] + fn parse_with_query_parameters() { + // If this test ever fails due to some change to the parsing logic, it is likely a sign we + // should just integrate the url crate instead of trying to do things ourselves. + let playlist_url_with_query = + "https://open.spotify.com/playlist/1cJ6lPBYj2fscs0kqBHsVV?si=OdwuJsbsSeuUAOadehng3A"; + let playlist_url = "https://open.spotify.com/playlist/1cJ6lPBYj2fscs0kqBHsVV"; + let expected_id = "1cJ6lPBYj2fscs0kqBHsVV"; + + let (actual_id, matched) = spotify_resource_id(URL_BASE, playlist_url, "/", "playlist"); + assert_eq!(matched, true); + assert_eq!(actual_id, expected_id); + + let (actual_id, matched) = + spotify_resource_id(URL_BASE, playlist_url_with_query, "/", "playlist"); + assert_eq!(matched, true); + assert_eq!(actual_id, expected_id); + } + + #[test] + fn mismatched_resource_types_do_not_match() { + let playlist_url = + "https://open.spotify.com/playlist/1cJ6lPBYj2fscs0kqBHsVV?si=OdwuJsbsSeuUAOadehng3A"; + let (_, matched) = spotify_resource_id(URL_BASE, playlist_url, "/", "album"); + assert_eq!(matched, false); + } + } } diff --git a/src/network.rs b/src/network.rs index 4d31a5c1..4d9df992 100644 --- a/src/network.rs +++ b/src/network.rs @@ -76,6 +76,7 @@ pub enum IoEvent { UserArtistFollowCheck(Vec), GetAlbum(String), TransferPlaybackToDevice(String), + GetAlbumForTrack(String), CurrentUserSavedTracksContains(Vec), GetShowEpisodes(String), AddItemToQueue(String), @@ -260,6 +261,9 @@ impl<'a> Network<'a> { IoEvent::TransferPlaybackToDevice(device_id) => { self.transfert_playback_to_device(device_id).await; } + IoEvent::GetAlbumForTrack(track_id) => { + self.get_album_for_track(track_id).await; + } IoEvent::Shuffle(shuffle_state) => { self.shuffle(shuffle_state).await; } @@ -377,9 +381,7 @@ impl<'a> Network<'a> { let mut app = self.app.lock().await; app.playlist_tracks = Some(playlist_tracks); - if app.get_current_route().id != RouteId::TrackTable { - app.push_navigation_stack(RouteId::TrackTable, ActiveBlock::TrackTable); - }; + app.push_navigation_stack(RouteId::TrackTable, ActiveBlock::TrackTable); }; } @@ -1255,6 +1257,39 @@ impl<'a> Network<'a> { } } + async fn get_album_for_track(&mut self, track_id: String) { + match self.spotify.track(&track_id).await { + Ok(track) => { + // It is unclear when the id can ever be None, but perhaps a track can be album-less. If + // so, there isn't much to do here anyways, since we're looking for the parent album. + let album_id = match track.album.id { + Some(id) => id, + None => return, + }; + + if let Ok(album) = self.spotify.album(&album_id).await { + // The way we map to the UI is zero-indexed, but Spotify is 1-indexed. + let zero_indexed_track_number = track.track_number - 1; + let selected_album = SelectedFullAlbum { + album, + // Overflow should be essentially impossible here, so we prefer the cleaner 'as'. + selected_index: zero_indexed_track_number as usize, + }; + + let mut app = self.app.lock().await; + + app.selected_album_full = Some(selected_album.clone()); + app.saved_album_tracks_index = selected_album.selected_index; + app.album_table_context = AlbumTableContext::Full; + app.push_navigation_stack(RouteId::AlbumTracks, ActiveBlock::AlbumTracks); + } + } + Err(e) => { + self.handle_error(anyhow!(e)).await; + } + } + } + async fn transfert_playback_to_device(&mut self, device_id: String) { match self.spotify.transfer_playback(&device_id, true).await { Ok(()) => { From b6b29ad0403f87f5cee450ce9bc5cebccb020207 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Thu, 22 Oct 2020 11:48:51 +0100 Subject: [PATCH 198/311] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fb546c4..5f4980d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Show saved albums when getting an artist [#612](https://github.com/Rigellute/spotify-tui/pull/612) - Transfer playback when changing device [#408](https://github.com/Rigellute/spotify-tui/pull/408) - Make layout more responsive to large/small screens [#502](https://github.com/Rigellute/spotify-tui/pull/502) +- Search using Spotify share URLs and URIs like the desktop client [#623](https://github.com/Rigellute/spotify-tui/pull/623) ## [0.22.0] - 2020-10-05 From d1d7acd34af8363cf8083bd5e0875037742047e1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2020 11:49:50 +0100 Subject: [PATCH 199/311] Bump backtrace from 0.3.52 to 0.3.53 (#617) Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.52 to 0.3.53. - [Release notes](https://github.com/rust-lang/backtrace-rs/releases) - [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.52...0.3.53) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 46 ++++++++++++++++++++++++++-------------------- Cargo.toml | 2 +- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0309f574..288045e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,12 +82,12 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.52" +version = "0.3.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f813291114c186a042350e787af10c26534601062603d888be110f59f85ef8fa" +checksum = "707b586e0e2f247cbde68cdd2c3ce69ea7b7be43e1c5b426e37c9319c4b9838e" dependencies = [ "addr2line", - "cfg-if", + "cfg-if 1.0.0", "libc", "miniz_oxide", "object", @@ -184,6 +184,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "chrono" version = "0.4.13" @@ -281,7 +287,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" dependencies = [ "autocfg 1.0.0", - "cfg-if", + "cfg-if 0.1.10", "lazy_static", ] @@ -435,7 +441,7 @@ version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8ac63f94732332f44fe654443c46f6375d1939684c17b0afb6cb56b0456e171" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] @@ -617,7 +623,7 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "wasi", ] @@ -782,7 +788,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63312a18f7ea8760cdd0a7c5aac1a619752a246b833545e3e36d1f81f7cd9e66" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] @@ -870,7 +876,7 @@ version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] @@ -925,7 +931,7 @@ version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "fuchsia-zircon", "fuchsia-zircon-sys", "iovec", @@ -1021,7 +1027,7 @@ version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "winapi 0.3.9", ] @@ -1095,9 +1101,9 @@ dependencies = [ [[package]] name = "object" -version = "0.20.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" +checksum = "37fd5004feb2ce328a52b0b3d01dbf4ffff72583493900ed15f22d4111c51693" [[package]] name = "once_cell" @@ -1112,7 +1118,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4" dependencies = [ "bitflags", - "cfg-if", + "cfg-if 0.1.10", "foreign-types", "lazy_static", "libc", @@ -1165,7 +1171,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "cloudabi 0.0.3", "libc", "redox_syscall", @@ -1179,7 +1185,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "cloudabi 0.1.0", "instant", "libc", @@ -1729,7 +1735,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "redox_syscall", "winapi 0.3.9", @@ -1807,7 +1813,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "rand 0.7.3", "redox_syscall", @@ -1962,7 +1968,7 @@ version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbdf4ccd1652592b01286a5dbe1e2a77d78afaa34beadd9872a5f7396f92aaa9" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "log", "tracing-core", ] @@ -2108,7 +2114,7 @@ version = "0.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3edbcc9536ab7eababcc6d2374a0b7bfe13a2b6d562c5e07f370456b1a8f33d" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "serde", "serde_json", "wasm-bindgen-macro", @@ -2135,7 +2141,7 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41ad6e4e8b2b7f8c90b6e09a9b590ea15cb0d1dbe28502b5a405cd95d1981671" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "js-sys", "wasm-bindgen", "web-sys", diff --git a/Cargo.toml b/Cargo.toml index 254dc35b..3a94f20b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ serde_yaml = "0.8" dirs = "3.0.1" clap = "2.33.3" unicode-width = "0.1.8" -backtrace = "0.3.52" +backtrace = "0.3.53" clipboard = "0.5.0" crossterm = "0.18" tokio = { version = "0.2", features = ["full"] } From 4764bf85006136482a4dda242260279b89ed1ffb Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2020 11:50:16 +0100 Subject: [PATCH 200/311] Bump serde_json from 1.0.58 to 1.0.59 (#619) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.58 to 1.0.59. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.58...v1.0.59) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 288045e8..a0c079fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1663,9 +1663,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a230ea9107ca2220eea9d46de97eddcb04cd00e92d13dda78e478dd33fa82bd4" +checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" dependencies = [ "itoa", "ryu", From 4218bf3d84b5078b009787665e40e3a6cf3db58f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 26 Oct 2020 10:09:23 +0000 Subject: [PATCH 201/311] Bump serde from 1.0.116 to 1.0.117 (#622) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.116 to 1.0.117. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.116...v1.0.117) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a0c079fe..eee9f1c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1643,18 +1643,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" +checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" +checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" dependencies = [ "proc-macro2 1.0.19", "quote 1.0.7", From 4382a32cb9ed845561fa20b7cebe4f96570b0810 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 26 Oct 2020 10:09:49 +0000 Subject: [PATCH 202/311] Bump crossterm from 0.18.0 to 0.18.1 (#634) Bumps [crossterm](https://github.com/crossterm-rs/crossterm) from 0.18.0 to 0.18.1. - [Release notes](https://github.com/crossterm-rs/crossterm/releases) - [Changelog](https://github.com/crossterm-rs/crossterm/blob/master/CHANGELOG.md) - [Commits](https://github.com/crossterm-rs/crossterm/commits) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eee9f1c8..fa2a2ba6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -309,9 +309,9 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2fcdc3c9cf8ee446222e8ee8691a6d21b563b8fe1a64b1873080db7b5b23cf0" +checksum = "cef9149b29071d44c9fb98fd9c27fcf74405bbdb761889ad6a03f36be93b0b15" dependencies = [ "bitflags", "crossterm_winapi", @@ -325,9 +325,9 @@ dependencies = [ [[package]] name = "crossterm_winapi" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057b7146d02fb50175fd7dbe5158f6097f33d02831f43b4ee8ae4ddf67b68f5c" +checksum = "c2265c3f8e080075d9b6417aa72293fc71662f34b4af2612d8d1b074d29510db" dependencies = [ "winapi 0.3.9", ] @@ -1749,7 +1749,7 @@ dependencies = [ "backtrace", "clap", "clipboard", - "crossterm 0.18.0", + "crossterm 0.18.1", "dirs", "rand 0.7.3", "rspotify", From 9500654ba3f3f55e0471afc0a19cc42a9ab8fdbe Mon Sep 17 00:00:00 2001 From: May Date: Tue, 27 Oct 2020 05:32:51 -0400 Subject: [PATCH 203/311] Fix use of incorrect playlist index when playing from an associated track table (#632) --- src/app.rs | 2 ++ src/handlers/playlist.rs | 1 + src/handlers/track_table.rs | 7 +++---- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/app.rs b/src/app.rs index 00010c41..a5185312 100644 --- a/src/app.rs +++ b/src/app.rs @@ -285,6 +285,7 @@ pub struct App { pub selected_album_full: Option, pub selected_device_index: Option, pub selected_playlist_index: Option, + pub active_playlist_index: Option, pub size: Rect, pub small_search_limit: u32, pub song_progress_ms: u128, @@ -368,6 +369,7 @@ impl Default for App { song_progress_ms: 0, selected_device_index: None, selected_playlist_index: None, + active_playlist_index: None, track_table: Default::default(), episode_table: Default::default(), user: None, diff --git a/src/handlers/playlist.rs b/src/handlers/playlist.rs index 8eb50b2a..f88caea5 100644 --- a/src/handlers/playlist.rs +++ b/src/handlers/playlist.rs @@ -62,6 +62,7 @@ pub fn handler(key: Key, app: &mut App) { if let (Some(playlists), Some(selected_playlist_index)) = (&app.playlists, &app.selected_playlist_index) { + app.active_playlist_index = Some(selected_playlist_index.to_owned()); app.track_table.context = Some(TrackTableContext::MyPlaylists); app.playlist_offset = 0; if let Some(selected_playlist) = playlists.items.get(selected_playlist_index.to_owned()) { diff --git a/src/handlers/track_table.rs b/src/handlers/track_table.rs index 9dd81876..93e5db24 100644 --- a/src/handlers/track_table.rs +++ b/src/handlers/track_table.rs @@ -320,10 +320,9 @@ fn on_enter(app: &mut App) { Some(context) => match context { TrackTableContext::MyPlaylists => { if let Some(_track) = tracks.get(*selected_index) { - let context_uri = match (&app.selected_playlist_index, &app.playlists) { - (Some(selected_playlist_index), Some(playlists)) => { - if let Some(selected_playlist) = - playlists.items.get(selected_playlist_index.to_owned()) + let context_uri = match (&app.active_playlist_index, &app.playlists) { + (Some(active_playlist_index), Some(playlists)) => { + if let Some(selected_playlist) = playlists.items.get(active_playlist_index.to_owned()) { Some(selected_playlist.uri.to_owned()) } else { From c8603131e8635030ae23a47d63ddb3cc741f2a34 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Tue, 27 Oct 2020 09:44:21 +0000 Subject: [PATCH 204/311] Update CHANGELOG (#637) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f4980d9..4e219697 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Transfer playback when changing device [#408](https://github.com/Rigellute/spotify-tui/pull/408) - Make layout more responsive to large/small screens [#502](https://github.com/Rigellute/spotify-tui/pull/502) - Search using Spotify share URLs and URIs like the desktop client [#623](https://github.com/Rigellute/spotify-tui/pull/623) +- Fix use of incorrect playlist index when playing from an associated track table [#632](https://github.com/Rigellute/spotify-tui/pull/632) ## [0.22.0] - 2020-10-05 From c6493ec21128003bcba2d538ab57551c1742e977 Mon Sep 17 00:00:00 2001 From: dp304 <34493835+dp304@users.noreply.github.com> Date: Fri, 30 Oct 2020 10:44:21 +0100 Subject: [PATCH 205/311] Issue #533 (#638) * Reformat help menu table to have one column (#533) If the terminal width is small, then the constraints on table column widths cannot be satisfied. In this case, the Cassowary solver chooses a constraint to be violated non-deterministically, which causes a flickering rendering. This workaround formats each row of the table into a single string, creating a single-column table. With one column and a "Max" constraint on its width, the non-determinism is eliminated. * Simplify style setting in help menu renderer * Reformat --- src/ui/mod.rs | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/ui/mod.rs b/src/ui/mod.rs index a458eb23..8c455f0c 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -82,31 +82,35 @@ where .margin(2) .split(f.size()); - let white = Style::default().fg(app.user_config.theme.text); - let gray = Style::default().fg(app.user_config.theme.text); + // Create a one-column table to avoid flickering due to non-determinism when + // resolving constraints on widths of table columns. + let format_row = |r: Vec| vec![format!("{:50}{:40}{:20}", r[0], r[1], r[2])]; + + let help_menu_style = Style::default().fg(app.user_config.theme.text); let header = ["Description", "Event", "Context"]; + let header = format_row(header.iter().map(|s| s.to_string()).collect()); let help_docs = get_help_docs(&app.user_config.keys); + let help_docs = help_docs.into_iter().map(format_row).collect::>(); let help_docs = &help_docs[app.help_menu_offset as usize..]; let rows = help_docs .iter() - .map(|item| Row::StyledData(item.iter(), gray)); + .map(|item| Row::StyledData(item.iter(), help_menu_style)); let help_menu = Table::new(header.iter(), rows) .block( Block::default() .borders(Borders::ALL) - .style(white) - .title(Span::styled("Help (press to go back)", gray)) - .border_style(gray), + .style(help_menu_style) + .title(Span::styled( + "Help (press to go back)", + help_menu_style, + )) + .border_style(help_menu_style), ) - .style(Style::default().fg(app.user_config.theme.text)) - .widths(&[ - Constraint::Length(50), - Constraint::Length(40), - Constraint::Length(20), - ]); + .style(help_menu_style) + .widths(&[Constraint::Max(110)]); f.render_widget(help_menu, chunks[0]); } From 414d9daff95d44ea2614102bb5763da8e7e77db3 Mon Sep 17 00:00:00 2001 From: dp304 <34493835+dp304@users.noreply.github.com> Date: Fri, 30 Oct 2020 10:51:24 +0100 Subject: [PATCH 206/311] Optimize seek (#523) (#640) Instead of immediately sending the API request when '<' or '>' is pressed, the offsets are accummulated. The seek request is sent periodically along with the playback update request. Also, the progress bar in the UI shows the desired seek position even before the actual seek is performed. --- src/app.rs | 72 +++++++++++++++++++++++++++++++++++++------------- src/network.rs | 4 +++ src/ui/mod.rs | 10 +++++-- 3 files changed, 66 insertions(+), 20 deletions(-) diff --git a/src/app.rs b/src/app.rs index a5185312..2c2dfab2 100644 --- a/src/app.rs +++ b/src/app.rs @@ -289,6 +289,7 @@ pub struct App { pub size: Rect, pub small_search_limit: u32, pub song_progress_ms: u128, + pub seek_ms: Option, pub track_table: TrackTable, pub episode_table: EpisodeTable, pub user: Option, @@ -367,6 +368,7 @@ impl Default for App { tracks: None, }, song_progress_ms: 0, + seek_ms: None, selected_device_index: None, selected_playlist_index: None, active_playlist_index: None, @@ -416,6 +418,26 @@ impl App { } } + fn apply_seek(&mut self, seek_ms: u32) { + if let Some(CurrentlyPlaybackContext { + item: Some(item), .. + }) = &self.current_playback_context + { + let duration_ms = match item { + PlayingItem::Track(track) => track.duration_ms, + PlayingItem::Episode(episode) => episode.duration_ms, + }; + + let event = if seek_ms < duration_ms { + IoEvent::Seek(seek_ms) + } else { + IoEvent::NextTrack + }; + + self.dispatch(event); + } + } + fn poll_current_playback(&mut self) { // Poll every 5 seconds let poll_interval_ms = 5_000; @@ -427,7 +449,11 @@ impl App { if !self.is_fetching_current_playback && elapsed >= poll_interval_ms { self.is_fetching_current_playback = true; - self.dispatch(IoEvent::GetCurrentPlayback); + // Trigger the seek if the user has set a new position + match self.seek_ms { + Some(seek_ms) => self.apply_seek(seek_ms as u32), + None => self.dispatch(IoEvent::GetCurrentPlayback), + } } } @@ -436,15 +462,20 @@ impl App { if let Some(CurrentlyPlaybackContext { item: Some(item), progress_ms: Some(progress_ms), - is_playing: true, + is_playing, .. }) = &self.current_playback_context { - let elapsed = self - .instant_since_last_current_playback_poll - .elapsed() - .as_millis() - + u128::from(*progress_ms); + // Update progress even when the song is not playing, + // because seeking is possible while paused + let elapsed = if *is_playing { + self + .instant_since_last_current_playback_poll + .elapsed() + .as_millis() + } else { + 0u128 + } + u128::from(*progress_ms); let duration_ms = match item { PlayingItem::Track(track) => track.duration_ms, @@ -469,26 +500,31 @@ impl App { PlayingItem::Episode(episode) => episode.duration_ms, }; - let event = if duration_ms - self.song_progress_ms as u32 - > self.user_config.behavior.seek_milliseconds - { - IoEvent::Seek(self.song_progress_ms as u32 + self.user_config.behavior.seek_milliseconds) - } else { - IoEvent::NextTrack + let old_progress = match self.seek_ms { + Some(seek_ms) => seek_ms, + None => self.song_progress_ms, }; - self.dispatch(event); + let new_progress = min( + old_progress as u32 + self.user_config.behavior.seek_milliseconds, + duration_ms, + ); + + self.seek_ms = Some(new_progress as u128); } } pub fn seek_backwards(&mut self) { - let new_progress = if self.song_progress_ms as u32 > self.user_config.behavior.seek_milliseconds - { - self.song_progress_ms as u32 - self.user_config.behavior.seek_milliseconds + let old_progress = match self.seek_ms { + Some(seek_ms) => seek_ms, + None => self.song_progress_ms, + }; + let new_progress = if old_progress as u32 > self.user_config.behavior.seek_milliseconds { + old_progress as u32 - self.user_config.behavior.seek_milliseconds } else { 0u32 }; - self.dispatch(IoEvent::Seek(new_progress)); + self.seek_ms = Some(new_progress as u128); } pub fn get_recommendations_for_seed( diff --git a/src/network.rs b/src/network.rs index 4d9df992..cb31a7b8 100644 --- a/src/network.rs +++ b/src/network.rs @@ -338,6 +338,7 @@ impl<'a> Network<'a> { } let mut app = self.app.lock().await; + app.seek_ms.take(); app.is_fetching_current_playback = false; } @@ -644,6 +645,9 @@ impl<'a> Network<'a> { .await { Ok(()) => { + // Wait between seek and status query. + // Without it, the Spotify API may return the old progress. + tokio::time::delay_for(Duration::from_millis(1000)).await; self.get_current_playback().await; } Err(e) => { diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 8c455f0c..d4d44c10 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -951,9 +951,15 @@ where )), ); f.render_widget(artist, chunks[0]); - let perc = get_track_progress_percentage(app.song_progress_ms, duration_ms); - let song_progress_label = display_track_progress(app.song_progress_ms, duration_ms); + let progress_ms = match app.seek_ms { + Some(seek_ms) => seek_ms, + None => app.song_progress_ms, + }; + + let perc = get_track_progress_percentage(progress_ms, duration_ms); + + let song_progress_label = display_track_progress(progress_ms, duration_ms); let modifier = if app.user_config.behavior.enable_text_emphasis { Modifier::ITALIC | Modifier::BOLD } else { From 58a3292a9256cc7b7fae1516eeb968ae9d051afc Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 30 Oct 2020 09:55:35 +0000 Subject: [PATCH 207/311] docs: add dp304 as a contributor (#642) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 6 ++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 89b44f7b..c913d33e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -679,6 +679,15 @@ "contributions": [ "code" ] + }, + { + "login": "dp304", + "name": "dp304", + "avatar_url": "https://avatars1.githubusercontent.com/u/34493835?v=4", + "profile": "https://github.com/dp304", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index d2e605f6..0d330479 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) - -[![All Contributors](https://img.shields.io/badge/all_contributors-72-orange.svg?style=flat-square)](#contributors-) - +[![All Contributors](https://img.shields.io/badge/all_contributors-74-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -399,12 +397,12 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
May

πŸ’»
Bruno A. MuciΓ±o

πŸ’»
Finn Hediger

πŸ’» +
dp304

πŸ’» - This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! From 0d00bbf5f160fe24a99b98782f4a40dd1635d768 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 30 Oct 2020 09:56:01 +0000 Subject: [PATCH 208/311] Bump crossterm from 0.18.1 to 0.18.2 (#641) Bumps [crossterm](https://github.com/crossterm-rs/crossterm) from 0.18.1 to 0.18.2. - [Release notes](https://github.com/crossterm-rs/crossterm/releases) - [Changelog](https://github.com/crossterm-rs/crossterm/blob/master/CHANGELOG.md) - [Commits](https://github.com/crossterm-rs/crossterm/commits) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa2a2ba6..8df0e7e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -309,9 +309,9 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef9149b29071d44c9fb98fd9c27fcf74405bbdb761889ad6a03f36be93b0b15" +checksum = "4e86d73f2a0b407b5768d10a8c720cf5d2df49a9efc10ca09176d201ead4b7fb" dependencies = [ "bitflags", "crossterm_winapi", @@ -1749,7 +1749,7 @@ dependencies = [ "backtrace", "clap", "clipboard", - "crossterm 0.18.1", + "crossterm 0.18.2", "dirs", "rand 0.7.3", "rspotify", From 4c68e1d8918649eccd82b95d50a85e1c1cdad944 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Fri, 30 Oct 2020 10:30:33 +0000 Subject: [PATCH 209/311] Update CHANGELOG (#643) --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e219697..0b8fe453 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ - Make layout more responsive to large/small screens [#502](https://github.com/Rigellute/spotify-tui/pull/502) - Search using Spotify share URLs and URIs like the desktop client [#623](https://github.com/Rigellute/spotify-tui/pull/623) - Fix use of incorrect playlist index when playing from an associated track table [#632](https://github.com/Rigellute/spotify-tui/pull/632) +- Fix flickering help menu in small screens [#638](https://github.com/Rigellute/spotify-tui/pull/638) +- Optimize seek [#640](https://github.com/Rigellute/spotify-tui/pull/640) ## [0.22.0] - 2020-10-05 From 6f01c09f2c6b2059315e824dbe1c66bb3a7e87e4 Mon Sep 17 00:00:00 2001 From: May Date: Tue, 24 Nov 2020 04:40:20 -0500 Subject: [PATCH 210/311] Make the liked icon configurable (#659) * Add liked icon to config and use it over the default * Add padding to the liked icon * Add new liked_icon option to README.md * Fix issue with double-padding --- README.md | 5 ++++- src/ui/mod.rs | 22 +++++++++++++--------- src/user_config.rs | 11 +++++++++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 0d330479..4196bd44 100644 --- a/README.md +++ b/README.md @@ -223,8 +223,11 @@ behavior: tick_rate_milliseconds: 250 # Enable text emphasis (typically italic/bold text styling). Disabling this might be important if the terminal config is otherwise restricted and rendering text escapes interferes with the UI. enable_text_emphasis: true - # controls whether to show a loading indicator in the top right of the UI whenever communicating with Spotify API + # Controls whether to show a loading indicator in the top right of the UI whenever communicating with Spotify API show_loading_indicator: true + # Determines the text icon to display next to "liked" Spotify items, such as + # liked songs and albums, or followed artists. Can be any length string. + liked_icon: "β™₯" keybindings: # Key stroke can be used if it only uses two keys: diff --git a/src/ui/mod.rs b/src/ui/mod.rs index d4d44c10..e0d36f59 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -395,7 +395,7 @@ where song_name += "β–Ά " } if app.liked_song_ids_set.contains(&id) { - song_name += "β™₯ "; + song_name += &app.user_config.padded_liked_icon(); } song_name += &item.name; @@ -423,7 +423,7 @@ where .map(|item| { let mut artist = String::new(); if app.followed_artist_ids_set.contains(&item.id.to_owned()) { - artist.push_str("β™₯ "); + artist.push_str(&app.user_config.padded_liked_icon()); } artist.push_str(&item.name.to_owned()); artist @@ -457,7 +457,7 @@ where let mut album_artist = String::new(); if let Some(album_id) = &item.id { if app.saved_album_ids_set.contains(&album_id.to_owned()) { - album_artist.push_str("β™₯ "); + album_artist.push_str(&app.user_config.padded_liked_icon()); } } album_artist.push_str(&format!( @@ -925,7 +925,7 @@ where }; let track_name = if app.liked_song_ids_set.contains(&item_id) { - format!("β™₯ {}", name) + format!("{}{}", &app.user_config.padded_liked_icon(), name) } else { name }; @@ -1191,7 +1191,7 @@ where let mut album_artist = String::new(); if let Some(album_id) = &item.id { if app.saved_album_ids_set.contains(&album_id.to_owned()) { - album_artist.push_str("β™₯ "); + album_artist.push_str(&app.user_config.padded_liked_icon()); } } album_artist.push_str(&format!( @@ -1219,7 +1219,7 @@ where .map(|item| { let mut artist = String::new(); if app.followed_artist_ids_set.contains(&item.id.to_owned()) { - artist.push_str("β™₯ "); + artist.push_str(&app.user_config.padded_liked_icon()); } artist.push_str(&item.name.to_owned()); artist @@ -1347,7 +1347,11 @@ where .map(|album_page| TableItem { id: album_page.album.id.to_owned(), format: vec![ - format!("β™₯ {}", &album_page.album.name), + format!( + "{}{}", + app.user_config.padded_liked_icon(), + &album_page.album.name + ), create_artist_string(&album_page.album.artists), album_page.album.release_date.to_owned(), ], @@ -1731,10 +1735,10 @@ fn draw_table( } } - // Show this β™₯ if the song is liked + // Show this the liked icon if the song is liked if let Some(liked_idx) = header.get_index(ColumnId::Liked) { if app.liked_song_ids_set.contains(item.id.as_str()) { - formatted_row[liked_idx] = " β™₯".to_string(); + formatted_row[liked_idx] = app.user_config.padded_liked_icon(); } } } diff --git a/src/user_config.rs b/src/user_config.rs index 7125f343..d880a1b8 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -212,6 +212,7 @@ pub struct BehaviorConfigString { pub tick_rate_milliseconds: Option, pub enable_text_emphasis: Option, pub show_loading_indicator: Option, + pub liked_icon: Option, } #[derive(Clone)] @@ -221,6 +222,7 @@ pub struct BehaviorConfig { pub tick_rate_milliseconds: u64, pub enable_text_emphasis: bool, pub show_loading_indicator: bool, + pub liked_icon: String, } #[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -276,6 +278,7 @@ impl UserConfig { tick_rate_milliseconds: 250, enable_text_emphasis: true, show_loading_indicator: true, + liked_icon: "β™₯".to_string(), }, path_to_config: None, } @@ -405,6 +408,10 @@ impl UserConfig { self.behavior.show_loading_indicator = loading_indicator; } + if let Some(liked_icon) = behavior_config.liked_icon { + self.behavior.liked_icon = liked_icon; + } + Ok(()) } @@ -441,6 +448,10 @@ impl UserConfig { Ok(()) } } + + pub fn padded_liked_icon(&self) -> String { + format!("{} ", &self.behavior.liked_icon) + } } fn parse_theme_item(theme_item: &str) -> Result { From e5577aad84e653c75320dc71f0f172791ed4b9fc Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 24 Nov 2020 09:47:25 +0000 Subject: [PATCH 211/311] Bump serde_yaml from 0.8.13 to 0.8.14 (#647) Bumps [serde_yaml](https://github.com/dtolnay/serde-yaml) from 0.8.13 to 0.8.14. - [Release notes](https://github.com/dtolnay/serde-yaml/releases) - [Commits](https://github.com/dtolnay/serde-yaml/compare/0.8.13...0.8.14) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8df0e7e9..af805ea3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1686,9 +1686,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae3e2dd40a7cdc18ca80db804b7f461a39bb721160a85c9a1fa30134bf3c02a5" +checksum = "f7baae0a99f1a324984bcdc5f0718384c1f69775f1c7eec8b859b71b443e3fd7" dependencies = [ "dtoa", "linked-hash-map", From 709f306aeb69575c65b37c28d661c8425490cd0e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 24 Nov 2020 09:47:39 +0000 Subject: [PATCH 212/311] Bump anyhow from 1.0.33 to 1.0.34 (#648) Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.33 to 1.0.34. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.33...1.0.34) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index af805ea3..97259b51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,9 +35,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.33" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fd36ffbb1fb7c834eac128ea8d0e310c5aeb635548f9d58861e1308d46e71c" +checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7" [[package]] name = "arc-swap" diff --git a/Cargo.toml b/Cargo.toml index 3a94f20b..b54907c8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ clipboard = "0.5.0" crossterm = "0.18" tokio = { version = "0.2", features = ["full"] } rand = "0.7.3" -anyhow = "1.0.33" +anyhow = "1.0.34" [[bin]] bench = false From 58967a809f191a6f3fe6961b84be5c66bb5bfb63 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 24 Nov 2020 09:55:54 +0000 Subject: [PATCH 213/311] Bump tokio from 0.2.22 to 0.2.23 (#658) Bumps [tokio](https://github.com/tokio-rs/tokio) from 0.2.22 to 0.2.23. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-0.2.22...tokio-0.2.23) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 97259b51..b52029a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1886,9 +1886,9 @@ checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" [[package]] name = "tokio" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd" +checksum = "a6d7ad61edd59bfcc7e80dababf0f4aed2e6d5e0ba1659356ae889752dfc12ff" dependencies = [ "bytes 0.5.6", "fnv", @@ -1910,9 +1910,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" +checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a" dependencies = [ "proc-macro2 1.0.19", "quote 1.0.7", From 93a18c91874aed6ae48470a362265ce3bb478977 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 24 Nov 2020 09:59:06 +0000 Subject: [PATCH 214/311] Bump tui from 0.12.0 to 0.13.0 (#660) Bumps [tui](https://github.com/fdehau/tui-rs) from 0.12.0 to 0.13.0. - [Release notes](https://github.com/fdehau/tui-rs/releases) - [Changelog](https://github.com/fdehau/tui-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/fdehau/tui-rs/compare/v0.12.0...v0.13.0) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 63 ++++++------------------------------------------------ Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b52029a9..df222ddb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -291,22 +291,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "crossterm" -version = "0.17.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f4919d60f26ae233e14233cc39746c8c8bb8cd7b05840ace83604917b51b6c7" -dependencies = [ - "bitflags", - "crossterm_winapi", - "lazy_static", - "libc", - "mio 0.7.0", - "parking_lot 0.10.2", - "signal-hook", - "winapi 0.3.9", -] - [[package]] name = "crossterm" version = "0.18.2" @@ -318,7 +302,7 @@ dependencies = [ "lazy_static", "libc", "mio 0.7.0", - "parking_lot 0.11.0", + "parking_lot", "signal-hook", "winapi 0.3.9", ] @@ -852,15 +836,6 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" -[[package]] -name = "lock_api" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" -dependencies = [ - "scopeguard", -] - [[package]] name = "lock_api" version = "0.4.1" @@ -1144,16 +1119,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "parking_lot" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" -dependencies = [ - "lock_api 0.3.4", - "parking_lot_core 0.7.2", -] - [[package]] name = "parking_lot" version = "0.11.0" @@ -1161,22 +1126,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733" dependencies = [ "instant", - "lock_api 0.4.1", - "parking_lot_core 0.8.0", -] - -[[package]] -name = "parking_lot_core" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi 0.0.3", - "libc", - "redox_syscall", - "smallvec", - "winapi 0.3.9", + "lock_api", + "parking_lot_core", ] [[package]] @@ -1749,7 +1700,7 @@ dependencies = [ "backtrace", "clap", "clipboard", - "crossterm 0.18.2", + "crossterm", "dirs", "rand 0.7.3", "rspotify", @@ -1990,13 +1941,13 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "tui" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2eaeee894a1e9b90f80aa466fe59154fdb471980b5e104d8836fcea309ae17e" +checksum = "5d4e6c82bb967df89f20b875fa8835fab5d5622c6a5efa574a1f0b6d0aa6e8f6" dependencies = [ "bitflags", "cassowary", - "crossterm 0.17.7", + "crossterm", "unicode-segmentation", "unicode-width", ] diff --git a/Cargo.toml b/Cargo.toml index b54907c8..a157ab49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ license = "MIT OR Apache-2.0" [dependencies] rspotify = "0.10.0" -tui = { version = "0.12.0", features = ["crossterm"], default-features = false } +tui = { version = "0.13.0", features = ["crossterm"], default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" From 24b411b5af56bbed8e411655aedb5c5705fde603 Mon Sep 17 00:00:00 2001 From: Finn Hediger Date: Tue, 24 Nov 2020 11:06:49 +0100 Subject: [PATCH 215/311] Fix issue #508 by calculating space manually (#664) This commit improves the centering of the basic_view_widget and thus fixeds the issue #508 by manually calculating the space between the top and the bottom bezel of the terminal. --- src/ui/mod.rs | 31 +++++++++++++++++-------------- src/ui/util.rs | 1 + 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/ui/mod.rs b/src/ui/mod.rs index e0d36f59..baf532fa 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -23,7 +23,7 @@ use tui::{ use util::{ create_artist_string, display_track_progress, get_artist_highlight_state, get_color, get_percentage_width, get_search_results_highlight_state, get_track_progress_percentage, - millis_to_minutes, SMALL_TERMINAL_WIDTH, + millis_to_minutes, BASIC_VIEW_HEIGHT, SMALL_TERMINAL_WIDTH, }; pub enum TableId { @@ -831,20 +831,23 @@ pub fn draw_basic_view(f: &mut Frame, app: &App) where B: Backend, { - let chunks = Layout::default() - .direction(Direction::Vertical) - .constraints( - [ - Constraint::Percentage(44), - Constraint::Min(6), - Constraint::Percentage(44), - ] - .as_ref(), - ) - .margin(4) - .split(f.size()); + // If space is negative, do nothing because the widget would not fit + if let Some(s) = app.size.height.checked_sub(BASIC_VIEW_HEIGHT) { + let space = s / 2; + let chunks = Layout::default() + .direction(Direction::Vertical) + .constraints( + [ + Constraint::Length(space), + Constraint::Length(BASIC_VIEW_HEIGHT), + Constraint::Length(space), + ] + .as_ref(), + ) + .split(f.size()); - draw_playbar(f, app, chunks[1]); + draw_playbar(f, app, chunks[1]); + } } pub fn draw_playbar(f: &mut Frame, app: &App, layout_chunk: Rect) diff --git a/src/ui/util.rs b/src/ui/util.rs index 0b4b506c..67ebeda0 100644 --- a/src/ui/util.rs +++ b/src/ui/util.rs @@ -3,6 +3,7 @@ use crate::user_config::Theme; use rspotify::model::artist::SimplifiedArtist; use tui::style::Style; +pub const BASIC_VIEW_HEIGHT: u16 = 6; pub const SMALL_TERMINAL_WIDTH: u16 = 150; pub const SMALL_TERMINAL_HEIGHT: u16 = 45; From 7f2bff23bb1dde9e1160c42e85f7fdf6ff757a24 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 24 Nov 2020 10:08:22 +0000 Subject: [PATCH 216/311] Bump backtrace from 0.3.53 to 0.3.55 (#666) Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.53 to 0.3.55. - [Release notes](https://github.com/rust-lang/backtrace-rs/releases) - [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.53...0.3.55) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 16 ++++++++-------- Cargo.toml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df222ddb..2b0352e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,9 +2,9 @@ # It is not intended for manual editing. [[package]] name = "addr2line" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072" +checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423" dependencies = [ "gimli", ] @@ -82,9 +82,9 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.53" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707b586e0e2f247cbde68cdd2c3ce69ea7b7be43e1c5b426e37c9319c4b9838e" +checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598" dependencies = [ "addr2line", "cfg-if 1.0.0", @@ -614,9 +614,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.22.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" +checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" [[package]] name = "h2" @@ -1076,9 +1076,9 @@ dependencies = [ [[package]] name = "object" -version = "0.21.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37fd5004feb2ce328a52b0b3d01dbf4ffff72583493900ed15f22d4111c51693" +checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" [[package]] name = "once_cell" diff --git a/Cargo.toml b/Cargo.toml index a157ab49..f94ce3c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ serde_yaml = "0.8" dirs = "3.0.1" clap = "2.33.3" unicode-width = "0.1.8" -backtrace = "0.3.53" +backtrace = "0.3.55" clipboard = "0.5.0" crossterm = "0.18" tokio = { version = "0.2", features = ["full"] } From b6b51517033896a8f8c85144c7f5baef09cda395 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Tue, 24 Nov 2020 10:08:38 +0000 Subject: [PATCH 217/311] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b8fe453..d7b72a73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ - Fix use of incorrect playlist index when playing from an associated track table [#632](https://github.com/Rigellute/spotify-tui/pull/632) - Fix flickering help menu in small screens [#638](https://github.com/Rigellute/spotify-tui/pull/638) - Optimize seek [#640](https://github.com/Rigellute/spotify-tui/pull/640) +- Make the liked icon configurable [#659](https://github.com/Rigellute/spotify-tui/pull/659) +- Fix centering of basic_view [#664](https://github.com/Rigellute/spotify-tui/pull/664) ## [0.22.0] - 2020-10-05 From cbd2d8375812ee801aa86558016665c735db9e49 Mon Sep 17 00:00:00 2001 From: Marco Micera Date: Tue, 24 Nov 2020 16:45:54 +0100 Subject: [PATCH 218/311] Updated Spotify API connection instructions (#662) * Updated Spotify API connection instructions * Added custom port suggestion to main README file According to Rigellute's suggestion Co-authored-by: Alexander Keliris Co-authored-by: Alexander Keliris --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4196bd44..02a60277 100644 --- a/README.md +++ b/README.md @@ -169,14 +169,17 @@ Instructions on how to set this up will be shown when you first run the app. But here they are again: 1. Go to the [Spotify dashboard](https://developer.spotify.com/dashboard/applications) -1. Click `Create a Client ID` and create an app +1. Click `Create an app` + - You now can see your `Client ID` and `Client Secret` 1. Now click `Edit Settings` 1. Add `http://localhost:8888/callback` to the Redirect URIs +1. Scroll down and click `Save` 1. You are now ready to authenticate with Spotify! 1. Go back to the terminal 1. Run `spt` 1. Enter your `Client ID` 1. Enter your `Client Secret` +1. Press enter to confirm the default port (8888) or enter a custom port 1. You will be redirected to an official Spotify webpage to ask you for permissions. 1. After accepting the permissions, you'll be redirected to localhost. If all goes well, the redirect URL will be parsed automatically and now you're done. If the local webserver fails for some reason you'll be redirected to a blank webpage that might say something like "Connection Refused" since no server is running. Regardless, copy the URL and paste into the prompt in the terminal. From 5bbc0848bfaa4a63b744f5cd045874d87d87c7ac Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 24 Nov 2020 15:46:48 +0000 Subject: [PATCH 219/311] docs: add marcomicera as a contributor (#667) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index c913d33e..ac508baa 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -688,6 +688,15 @@ "contributions": [ "code" ] + }, + { + "login": "marcomicera", + "name": "Marco Micera", + "avatar_url": "https://avatars0.githubusercontent.com/u/13918587?v=4", + "profile": "http://marcomicera.github.io", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 02a60277..c2680955 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-74-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-75-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -404,6 +404,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Bruno A. MuciΓ±o

πŸ’»
Finn Hediger

πŸ’»
dp304

πŸ’» +
Marco Micera

πŸ“– From 9b649b7ea2b893d265dbf799f605d680c7cfce3f Mon Sep 17 00:00:00 2001 From: Marco Ieni <11428655+MarcoIeni@users.noreply.github.com> Date: Tue, 8 Dec 2020 11:47:49 +0100 Subject: [PATCH 220/311] ci - clippy: upgrade toolchain (#672) Signed-off-by: MarcoIeni <11428655+MarcoIeni@users.noreply.github.com> --- .github/workflows/ci.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3475e1f6..a132cd56 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,7 @@ jobs: - uses: actions-rs/toolchain@v1 with: toolchain: stable + profile: minimal override: true - uses: actions-rs/cargo@v1 with: @@ -43,6 +44,7 @@ jobs: - uses: actions-rs/toolchain@v1 with: toolchain: stable + profile: minimal override: true # These dependencies are required for `clipboard` - run: sudo apt-get install -y -qq libxcb1-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev @@ -59,8 +61,9 @@ jobs: - uses: actions-rs/toolchain@v1 with: toolchain: stable + profile: minimal override: true - - run: rustup component add rustfmt + components: rustfmt - uses: actions-rs/cargo@v1 with: command: fmt @@ -72,12 +75,12 @@ jobs: needs: prepare steps: - uses: actions/checkout@master - # Temporarily downgrade Clippy until a new stable release includes a fix for CI breaking on 1.47 https://github.com/rust-lang/rust-clippy/issues/6147 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.46.0 + toolchain: stable + profile: minimal override: true - - run: rustup component add clippy + components: clippy - uses: actions-rs/cargo@v1 with: command: clippy From 6cd364d33f23ebd5540ba7b25bdb010d1cd76bf6 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 8 Dec 2020 10:49:21 +0000 Subject: [PATCH 221/311] docs: add MarcoIeni as a contributor (#677) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index ac508baa..ef9ecf59 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -697,6 +697,15 @@ "contributions": [ "doc" ] + }, + { + "login": "MarcoIeni", + "name": "Marco Ieni", + "avatar_url": "https://avatars3.githubusercontent.com/u/11428655?v=4", + "profile": "http://marcoieni.com", + "contributions": [ + "infra" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index c2680955..b68005dd 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-75-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-76-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -405,6 +405,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Finn Hediger

πŸ’»
dp304

πŸ’»
Marco Micera

πŸ“– +
Marco Ieni

πŸš‡ From eb8ea0ef095a2396baf8b9056b1144098722cd73 Mon Sep 17 00:00:00 2001 From: Marco Ieni <11428655+MarcoIeni@users.noreply.github.com> Date: Tue, 8 Dec 2020 11:50:30 +0100 Subject: [PATCH 222/311] cd: extract variables in order to simplify script (#673) Signed-off-by: MarcoIeni <11428655+MarcoIeni@users.noreply.github.com> --- .github/workflows/cd.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 3ec2b5da..020a0d30 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -55,13 +55,16 @@ jobs: run: | cd target/${{ matrix.target }}/release - strip spt${{ matrix.binary_postfix }} - tar czvf spotify-tui-${{ matrix.artifact_prefix }}.tar.gz spt${{ matrix.binary_postfix }} - + BINARY_NAME=spt${{ matrix.binary_postfix }} + strip $BINARY_NAME + + RELEASE_NAME=spotify-tui-${{ matrix.artifact_prefix }} + tar czvf $RELEASE_NAME.tar.gz $BINARY_NAME + if [[ ${{ runner.os }} == 'Windows' ]]; then - certutil -hashfile spotify-tui-${{ matrix.artifact_prefix }}.tar.gz sha256 | grep -E [A-Fa-f0-9]{64} > spotify-tui-${{ matrix.artifact_prefix }}.sha256 + certutil -hashfile $RELEASE_NAME.tar.gz sha256 | grep -E [A-Fa-f0-9]{64} > $RELEASE_NAME.sha256 else - shasum -a 256 spotify-tui-${{ matrix.artifact_prefix }}.tar.gz > spotify-tui-${{ matrix.artifact_prefix }}.sha256 + shasum -a 256 $RELEASE_NAME.tar.gz > $RELEASE_NAME.sha256 fi - name: Releasing assets uses: softprops/action-gh-release@v1 From 092165e58a5c8fc4226c75b5d84f34bf298feaa6 Mon Sep 17 00:00:00 2001 From: Finn Hediger Date: Wed, 30 Dec 2020 11:10:10 +0100 Subject: [PATCH 223/311] Cli interface (#645) * Start implementing a cli This is the start of a new feature: control spotify from the command line. There are almost no changes to the backend, I think this is favourable. A list of new features: status, toggle playback, play uri, list avaible devices. * Change all args to subcommands Added some new commands as well which are not implemented yet. * Add new cli interface + playing track, playlist and search The cli interface now mainly consists of subcommands. New working features: - play a uri - search for tracks and more - list playlists * Fix .about of certain subcommands * Remove forgotten println statement used for debugging * Add -f format specifier This format specifier works with: - %a -> artist - %l -> album - %t -> track - %p -> playlist - %s -> playback status - %u -> uri - %h -> show It can be used by 'status', 'list' and 'query'. The default values change according to the arguments. * Change default value of status format * Format code by 'cargo fmt' * Add api error handling * Fix small bugs * Add short one char aliases * Add new transfer command Transfer playback to another device by specifying the name. * Add new %d for device name to format * Fix bug that toggle does not pause music * Replace some .clone() with references * Replace some subcommands with args Simplyfies usage a whole lot. Changes: - toggle -> pb -t (or playback -t) - status -> pb -s (or playback -s) - transfer -> pb -r (or playback -r) * Add option to set flags to current playback You can set flags with -m. Possible values are: - l | like - r | repeat - s | shuffle * Replave list and query with query -s and query -l This commit changes the way list and query work: - list -> query -l -d / -p - query -> query -s SEARCH -a / -p / -t / -b / -h Perhaps you saw it, unfortunately I had to change -l to -b (album) and -s to -h (show). * Clean up function format_output * Replave -c / --category ... with appropriate flags After testing it a little, I decided to switch back to normal flags. You can like, repeat and shuffle with --... Searching and listing works with -d for devices, -p for playlists etc. I also changed the emojis. They look a lot better now. * Add new default formats to playback subcommand * Add ability to list liked songs * Add format option for list -d (devices) * Add new struct CliApp that holds network Purely to make the code more readable. I also added some comments Also replaced emoji strings with constant variables. * Add arg to jump to next and previous song New arguments: -p / --previous and -n / --next. Also removed the explicit lifetime of emoji constants. * Add -n / --name to 'spt play' You can now play songs, artists, albums, playlists and more directly by specifying the name. After that, spt will just play the first result. * Fix warnings by cargo clippy * Add --volume to playback This commit adds the option to specify the volume of a device. It also allows the user to output the volume with '%v' as a format specifier, now used by 'spt query -l -d'. * Remove short option '-r' for transfer * Add long help to --format This should make it easier to understand. * Fix formatting * Remove forgotten println statement used for debugging * Remove --device argument, misunderstanding I'm removing the --device DEVICE argument. After testing I found that it actually does not do anything. You can still transfer your playback to another device with --transfer. I thought that spotify allows you to have different playbacks on different devices, but I was wrong. * Add 'Err: ' in front of some fail messages * Clean up function format_output even more I move the flags and playing boolean into the Format enum. * Add option to add a track to queue with '-q' Instead of directly playing a track you can now add the track to the queue with 'spt play ... -q'. This only works with tracks though. If you specify a different ui, spt will return an API error. * Change '-h' shortcut for '--shows' to '-w' * Fix space between pause emoji * Add .trim() to format so leading and trailing whitspaces get removed * Format code * Add '--device' flag again to specify device to use This will set the current playing device and will also update the device id stored in the client.yml file. You can specify the device name. * Add anyhow Result type to most cli functions The output now gets directly returned to the main function. This automatically handles exit statuses etc. * Add feature to autoselect first device avaible If the device_id in the client.yml file is empty, the user needed to specify the device he wanted. This conveniently now just uses the first device avaible. * Fix formatting * Add example to format arg in help menu * Fix missing tick in help * Add 'listable' to '--list' command as a requirement * Add '--limit' option to specify query limit * Add ability to change icons throught config * Change default liked icon * Add padding function for the icons * Remove type requirement and use fallback The fallback options are: track for playing and searching, devices for listing. * Update default format values to match other defaults * Move default to bottom '.default_value_ifs' will just take the first match, like if/else statements. * Move cli clap apps and file to new folder 'cli' * Remove required contexts from play and fallback to track * Remove padded function because the whitespace is unnecessary in the cli * Rename cli file (proposed by clippy) * Add config options to README.md * Fmt * Fix spacing with pause icon * Fix cli not recognizing older liked songs * Make line smaller * Add shell completions for most popular shells Can be printed to standard out with 'spt --completions SHELL' * Improve error messages for '--limit' and '--volume' * Change name of cli arguments file to 'clap.rs' * Change description for subcommand 'play' * Improve help messages for subcommand 'play' * Add '.possible_values' to '--completions' * Shorten subcommand handling * Add '--format' option to subcommand 'play' * Add smart device selection * Fix grammar and make error messages more consistent * Fix formatting * Split up the initial 'cli_app.rs' file All the enums (Type, Format etc.) and utility functions are now in 'util.rs'. The struct 'CliApp' is now the only thing in 'cli_app.rs'. The handle_matches function is now in 'handle.rs'. * Improve help messages * Fix default formats for albums and shows * Change help strings to third person This matches the defaults ('--help') of the clap crate. * Change powershell to power-shell * Fix some forgotten help messages * Expand on help for the 'query' subcommand * Change default formats to make them more uniform and reduce confusion * Add message if no liked songs were found * Allow multiple actions with the same command Something like 'spt pb --like --repeat' is now possible. * Fix formatting * Add ranges to '--volume' and '--limit' in help * Jump multiple times by using '-n' or '-p' multiple times For example: 'spt pb -n -n -n' jumps to the 3. song and 'spt pb -p -p' actually jumps to the previous song. * Fix multiple flags ('--repeat', '--like', '--shuffle') not working * Remove some comments * Add new '--share-track' and '--share-album' flags + default: '--status' By default 'spt playback' will just display the playback status. This makes a lot of sense and also simplifies usage. * Improve ArgGroups for 'playback' subcommand * Fix formatting * Replace String::new() with unreachable!() (success is enforced by clap) * Add '--random' flag to play a random song from a playlist + '--queue' and '--random' now work with uris * Split up 'query' in 'list' and 'search' * Fix formatting * Improve help for '-n' and '-p' * Add long_abouts and long_helps for some commands to make the experience easier * Small improvement to help for '--status' * Fix formatting * Fix typos and remove some info from short help * Remove context requirement for `play --uri=...` * Improve short and long help for `--previous` --- README.md | 7 +- src/cli/clap.rs | 364 ++++++++++++++++++++++++++++ src/cli/cli_app.rs | 581 +++++++++++++++++++++++++++++++++++++++++++++ src/cli/handle.rs | 148 ++++++++++++ src/cli/mod.rs | 8 + src/cli/util.rs | 259 ++++++++++++++++++++ src/main.rs | 107 ++++++--- src/network.rs | 6 +- src/user_config.rs | 37 ++- 9 files changed, 1484 insertions(+), 33 deletions(-) create mode 100644 src/cli/clap.rs create mode 100644 src/cli/cli_app.rs create mode 100644 src/cli/handle.rs create mode 100644 src/cli/mod.rs create mode 100644 src/cli/util.rs diff --git a/README.md b/README.md index b68005dd..f84158af 100644 --- a/README.md +++ b/README.md @@ -230,7 +230,12 @@ behavior: show_loading_indicator: true # Determines the text icon to display next to "liked" Spotify items, such as # liked songs and albums, or followed artists. Can be any length string. - liked_icon: "β™₯" + liked_icon: " " + shuffle_icon: "咽" + repeat_track_icon: "ο₯—" + repeat_context_icon: "ο₯•" + playing_icon: "" + paused_icon: "ο££" keybindings: # Key stroke can be used if it only uses two keys: diff --git a/src/cli/clap.rs b/src/cli/clap.rs new file mode 100644 index 00000000..f7b7483c --- /dev/null +++ b/src/cli/clap.rs @@ -0,0 +1,364 @@ +use clap::{App, Arg, ArgGroup, SubCommand}; + +fn device_arg() -> Arg<'static, 'static> { + Arg::with_name("device") + .short("d") + .long("device") + .takes_value(true) + .value_name("DEVICE") + .help("Specifies the spotify device to use") +} + +fn format_arg() -> Arg<'static, 'static> { + Arg::with_name("format") + .short("f") + .long("format") + .takes_value(true) + .value_name("FORMAT") + .help("Specifies the output format") + .long_help( + "There are multiple format specifiers you can use: %a: artist, %b: album, %p: playlist, \ +%t: track, %h: show, %f: flags (shuffle, repeat, like), %s: playback status, %v: volume, %d: current device. \ +Example: spt pb -s -f 'playing on %d at %v%'", + ) +} + +pub fn playback_subcommand() -> App<'static, 'static> { + SubCommand::with_name("playback") + .version(env!("CARGO_PKG_VERSION")) + .author(env!("CARGO_PKG_AUTHORS")) + .about("Interacts with the playback of a device") + .long_about( + "Use `playback` to interact with the playback of the current or any other device. \ +You can specify another device with `--device`. If no options were provided, spt \ +will default to just displaying the current playback. Actually, after every action \ +spt will display the updated playback. The output format is configurable with the \ +`--format` flag. Some options can be used together, other options have to be alone. + +Here's a list: + +* `--next` and `--previous` cannot be used with other options +* `--status`, `--toggle`, `--transfer`, `--volume`, `--like`, `--repeat` and `--shuffle` \ +can be used together +* `--share-track` and `--share-album` cannot be used with other options", + ) + .visible_alias("pb") + .arg(device_arg()) + .arg( + format_arg() + .default_value("%f %s %t - %a") + .default_value_ifs(&[ + ("volume", None, "%v% %f %s %t - %a"), + ("transfer", None, "%f %s %t - %a on %d"), + ]), + ) + .arg( + Arg::with_name("toggle") + .short("t") + .long("toggle") + .help("Pauses/resumes the playback of a device"), + ) + .arg( + Arg::with_name("status") + .short("s") + .long("status") + .help("Prints out the current status of a device (default)"), + ) + .arg( + Arg::with_name("share-track") + .long("share-track") + .help("Returns the url to the current track"), + ) + .arg( + Arg::with_name("share-album") + .long("share-album") + .help("Returns the url to the album of the current track"), + ) + .arg( + Arg::with_name("transfer") + .long("transfer") + .takes_value(true) + .value_name("DEVICE") + .help("Transfers the playback to new DEVICE"), + ) + .arg( + Arg::with_name("like") + .long("like") + .help("Likes the current song"), + ) + .arg( + Arg::with_name("shuffle") + .long("shuffle") + .help("Toggles shuffle mode"), + ) + .arg( + Arg::with_name("repeat") + .long("repeat") + .help("Switches between repeat modes"), + ) + .arg( + Arg::with_name("next") + .short("n") + .long("next") + .multiple(true) + .help("Jumps to the next song") + .long_help( + "This jumps to the next song if specied once. If you want to jump, let's say 3 songs \ +forward, you can use `--next` 3 times: `spt pb -nnn`.", + ), + ) + .arg( + Arg::with_name("previous") + .short("p") + .long("previous") + .multiple(true) + .help("Jumps to the previous song") + .long_help( + "This jumps to the beginning of the current song if specied once. You probably want to \ +jump to the previous song though, so you can use the previous flag twice: `spt pb -pp`. To jump \ +two songs back, you can use `spt pb -ppp` and so on.", + ), + ) + .arg( + Arg::with_name("volume") + .short("v") + .long("volume") + .takes_value(true) + .value_name("VOLUME") + .help("Sets the volume of a device to VOLUME (1 - 100)"), + ) + .group( + ArgGroup::with_name("jumps") + .args(&["next", "previous"]) + .multiple(false) + .conflicts_with_all(&["single", "flags", "actions"]), + ) + .group( + ArgGroup::with_name("flags") + .args(&["like", "shuffle", "repeat"]) + .multiple(true) + .conflicts_with_all(&["single", "jumps"]), + ) + .group( + ArgGroup::with_name("actions") + .args(&["toggle", "status", "transfer", "volume"]) + .multiple(true) + .conflicts_with_all(&["single", "jumps"]), + ) + .group( + ArgGroup::with_name("single") + .args(&["share-track", "share-album"]) + .multiple(false) + .conflicts_with_all(&["actions", "flags", "jumps"]), + ) +} + +pub fn play_subcommand() -> App<'static, 'static> { + SubCommand::with_name("play") + .version(env!("CARGO_PKG_VERSION")) + .author(env!("CARGO_PKG_AUTHORS")) + .about("Plays a uri or another spotify item by name") + .long_about( + "If you specify a uri, the type can be inferred. If you want to play something by \ +name, you have to specify the type: `--track`, `--album`, `--artist`, `--playlist` \ +or `--show`. The first item which was found will be played without confirmation. \ +To add a track to the queue, use `--queue`. To play a random song from a playlist, \ +use `--random`. Again, with `--format` you can specify how the output will look. \ +The same function as found in `playback` will be called.", + ) + .visible_alias("p") + .arg(device_arg()) + .arg(format_arg().default_value("%f %s %t - %a")) + .arg( + Arg::with_name("uri") + .short("u") + .long("uri") + .takes_value(true) + .value_name("URI") + .help("Plays the URI"), + ) + .arg( + Arg::with_name("name") + .short("n") + .long("name") + .takes_value(true) + .value_name("NAME") + .requires("contexts") + .help("Plays the first match with NAME from the specified category"), + ) + .arg( + Arg::with_name("queue") + .short("q") + .long("queue") + // Only works with tracks + .conflicts_with_all(&["album", "artist", "playlist", "show"]) + .help("Adds track to queue instead of playing it directly"), + ) + .arg( + Arg::with_name("random") + .short("r") + .long("random") + // Only works with playlists + .conflicts_with_all(&["track", "album", "artist", "show"]) + .help("Plays a random track (only works with playlists)"), + ) + .arg( + Arg::with_name("album") + .short("b") + .long("album") + .help("Looks for an album"), + ) + .arg( + Arg::with_name("artist") + .short("a") + .long("artist") + .help("Looks for an artist"), + ) + .arg( + Arg::with_name("track") + .short("t") + .long("track") + .help("Looks for a track"), + ) + .arg( + Arg::with_name("show") + .short("w") + .long("show") + .help("Looks for a show"), + ) + .arg( + Arg::with_name("playlist") + .short("p") + .long("playlist") + .help("Looks for a playlist"), + ) + .group( + ArgGroup::with_name("contexts") + .args(&["track", "artist", "playlist", "album", "show"]) + .multiple(false), + ) + .group( + ArgGroup::with_name("actions") + .args(&["uri", "name"]) + .multiple(false) + .required(true), + ) +} + +pub fn list_subcommand() -> App<'static, 'static> { + SubCommand::with_name("list") + .version(env!("CARGO_PKG_VERSION")) + .author(env!("CARGO_PKG_AUTHORS")) + .about("Lists devices, liked songs and playlists") + .long_about( + "This will list devices, liked songs or playlists. With the `--limit` flag you are \ +able to specify the amount of results (between 1 and 50). Here, the `--format` is \ +even more awesome, get your output exactly the way you want. The format option will \ +be applied to every item found.", + ) + .visible_alias("l") + .arg(format_arg().default_value_ifs(&[ + ("devices", None, "%v% %d"), + ("liked", None, "%t - %a (%u)"), + ("playlists", None, "%p (%u)"), + ])) + .arg( + Arg::with_name("devices") + .short("d") + .long("devices") + .help("Lists devices"), + ) + .arg( + Arg::with_name("playlists") + .short("p") + .long("playlists") + .help("Lists playlists"), + ) + .arg( + Arg::with_name("liked") + .long("liked") + .help("Lists liked songs"), + ) + .arg( + Arg::with_name("limit") + .long("limit") + .takes_value(true) + .help("Specifies the maximum number of results (1 - 50)"), + ) + .group( + ArgGroup::with_name("listable") + .args(&["devices", "playlists", "liked"]) + .required(true) + .multiple(false), + ) +} + +pub fn search_subcommand() -> App<'static, 'static> { + SubCommand::with_name("search") + .version(env!("CARGO_PKG_VERSION")) + .author(env!("CARGO_PKG_AUTHORS")) + .about("Searches for tracks, albums and more") + .long_about( + "This will search for something on spotify and displays you the items. The output \ +format can be changed with the `--format` flag and the limit can be changed with \ +the `--limit` flag (between 1 and 50). The type can't be inferred, so you have to \ +specify it.", + ) + .visible_alias("s") + .arg(format_arg().default_value_ifs(&[ + ("tracks", None, "%t - %a (%u)"), + ("playlists", None, "%p (%u)"), + ("artists", None, "%a (%u)"), + ("albums", None, "%b - %a (%u)"), + ("shows", None, "%h - %a (%u)"), + ])) + .arg( + Arg::with_name("search") + .required(true) + .takes_value(true) + .value_name("SEARCH") + .help("Specifies the search query"), + ) + .arg( + Arg::with_name("albums") + .short("b") + .long("albums") + .help("Looks for albums"), + ) + .arg( + Arg::with_name("artists") + .short("a") + .long("artists") + .help("Looks for artists"), + ) + .arg( + Arg::with_name("playlists") + .short("p") + .long("playlists") + .help("Looks for playlists"), + ) + .arg( + Arg::with_name("tracks") + .short("t") + .long("tracks") + .help("Looks for tracks"), + ) + .arg( + Arg::with_name("shows") + .short("w") + .long("shows") + .help("Looks for shows"), + ) + .arg( + Arg::with_name("limit") + .long("limit") + .takes_value(true) + .help("Specifies the maximum number of results (1 - 50)"), + ) + .group( + ArgGroup::with_name("searchable") + .args(&["playlists", "tracks", "albums", "artists", "shows"]) + .required(true) + .multiple(false), + ) +} diff --git a/src/cli/cli_app.rs b/src/cli/cli_app.rs new file mode 100644 index 00000000..13dcbb80 --- /dev/null +++ b/src/cli/cli_app.rs @@ -0,0 +1,581 @@ +use crate::network::{IoEvent, Network}; +use crate::user_config::UserConfig; + +use super::util::{Flag, Format, FormatType, JumpDirection, Type}; + +use anyhow::{anyhow, Result}; +use rand::{thread_rng, Rng}; +use rspotify::model::{context::CurrentlyPlaybackContext, PlayingItem}; + +pub struct CliApp<'a> { + pub net: Network<'a>, + pub config: UserConfig, +} + +// Non-concurrent functions +// I feel that async in a cli is not working +// I just .await all processes and directly interact +// by calling network.handle_network_event +impl<'a> CliApp<'a> { + pub fn new(net: Network<'a>, config: UserConfig) -> Self { + Self { net, config } + } + + async fn is_a_saved_track(&mut self, id: String) -> bool { + // Update the liked_song_ids_set + self + .net + .handle_network_event(IoEvent::CurrentUserSavedTracksContains(vec![id.clone()])) + .await; + self.net.app.lock().await.liked_song_ids_set.contains(&id) + } + + pub fn format_output(&self, mut format: String, values: Vec) -> String { + for val in values { + format = format.replace(val.get_placeholder(), &val.inner(self.config.clone())); + } + // Replace unsupported flags with 'None' + for p in &["%a", "%b", "%t", "%p", "%h", "%u", "%d", "%v", "%f", "%s"] { + format = format.replace(p, "None"); + } + format.trim().to_string() + } + + // spt playback -t + pub async fn toggle_playback(&mut self) { + let context = self.net.app.lock().await.current_playback_context.clone(); + if let Some(c) = context { + if c.is_playing { + self.net.handle_network_event(IoEvent::PausePlayback).await; + return; + } + } + self + .net + .handle_network_event(IoEvent::StartPlayback(None, None, None)) + .await; + } + + // spt pb --share-track (share the current playing song) + // Basically copy-pasted the 'copy_song_url' function + pub async fn share_track_or_episode(&mut self) -> Result { + let app = self.net.app.lock().await; + if let Some(CurrentlyPlaybackContext { + item: Some(item), .. + }) = &app.current_playback_context + { + match item { + PlayingItem::Track(track) => Ok(format!( + "https://open.spotify.com/track/{}", + track.id.to_owned().unwrap_or_default() + )), + PlayingItem::Episode(episode) => Ok(format!( + "https://open.spotify.com/episode/{}", + episode.id.to_owned() + )), + } + } else { + Err(anyhow!( + "failed to generate a shareable url for the current song" + )) + } + } + + // spt pb --share-album (share the current album) + // Basically copy-pasted the 'copy_album_url' function + pub async fn share_album_or_show(&mut self) -> Result { + let app = self.net.app.lock().await; + if let Some(CurrentlyPlaybackContext { + item: Some(item), .. + }) = &app.current_playback_context + { + match item { + PlayingItem::Track(track) => Ok(format!( + "https://open.spotify.com/album/{}", + track.album.id.to_owned().unwrap_or_default() + )), + PlayingItem::Episode(episode) => Ok(format!( + "https://open.spotify.com/show/{}", + episode.show.id.to_owned() + )), + } + } else { + Err(anyhow!( + "failed to generate a shareable url for the current song" + )) + } + } + + // spt ... -d ... (specify device to control) + pub async fn set_device(&mut self, name: String) -> Result<()> { + // Change the device if specified by user + let mut app = self.net.app.lock().await; + let mut device_index = 0; + if let Some(dp) = &app.devices { + for (i, d) in dp.devices.iter().enumerate() { + if d.name == name { + device_index = i; + // Save the id of the device + self + .net + .client_config + .set_device_id(d.id.clone()) + .map_err(|_e| anyhow!("failed to use device with name '{}'", d.name))?; + } + } + } else { + // Error out if no device is available + return Err(anyhow!("no device available")); + } + app.selected_device_index = Some(device_index); + Ok(()) + } + + // spt query ... --limit LIMIT (set max search limit) + pub async fn update_query_limits(&mut self, max: String) -> Result<()> { + let num = max + .parse::() + .map_err(|_e| anyhow!("limit must be between 1 and 50"))?; + + // 50 seems to be the maximum limit + if num > 50 || num == 0 { + return Err(anyhow!("limit must be between 1 and 50")); + }; + + self + .net + .handle_network_event(IoEvent::UpdateSearchLimits(num, num)) + .await; + Ok(()) + } + + pub async fn volume(&mut self, vol: String) -> Result<()> { + let num = vol + .parse::() + .map_err(|_e| anyhow!("volume must be between 0 and 100"))?; + + // Check if it's in range + if num > 100 { + return Err(anyhow!("volume must be between 0 and 100")); + }; + + self + .net + .handle_network_event(IoEvent::ChangeVolume(num as u8)) + .await; + Ok(()) + } + + // spt playback --next / --previous + pub async fn jump(&mut self, d: &JumpDirection) { + match d { + JumpDirection::Next => self.net.handle_network_event(IoEvent::NextTrack).await, + JumpDirection::Previous => self.net.handle_network_event(IoEvent::PreviousTrack).await, + } + } + + // spt query -l ... + pub async fn list(&mut self, item: Type, format: &str) -> String { + match item { + Type::Device => { + if let Some(devices) = &self.net.app.lock().await.devices { + devices + .devices + .iter() + .map(|d| { + self.format_output( + format.to_string(), + vec![ + Format::Device(d.name.clone()), + Format::Volume(d.volume_percent), + ], + ) + }) + .collect::>() + .join("\n") + } else { + "No devices available".to_string() + } + } + Type::Playlist => { + self.net.handle_network_event(IoEvent::GetPlaylists).await; + if let Some(playlists) = &self.net.app.lock().await.playlists { + playlists + .items + .iter() + .map(|p| { + self.format_output( + format.to_string(), + Format::from_type(FormatType::Playlist(Box::new(p.clone()))), + ) + }) + .collect::>() + .join("\n") + } else { + "No playlists found".to_string() + } + } + Type::Liked => { + self + .net + .handle_network_event(IoEvent::GetCurrentSavedTracks(None)) + .await; + let liked_songs = self + .net + .app + .lock() + .await + .track_table + .tracks + .iter() + .map(|t| { + self.format_output( + format.to_string(), + Format::from_type(FormatType::Track(Box::new(t.clone()))), + ) + }) + .collect::>(); + // Check if there are any liked songs + if liked_songs.is_empty() { + "No liked songs found".to_string() + } else { + liked_songs.join("\n") + } + } + // Enforced by clap + _ => unreachable!(), + } + } + + // spt playback --transfer DEVICE + pub async fn transfer_playback(&mut self, device: &str) -> Result<()> { + // Get the device id by name + let mut id = String::new(); + if let Some(devices) = &self.net.app.lock().await.devices { + for d in &devices.devices { + if d.name == device { + id.push_str(d.id.as_str()); + break; + } + } + }; + + if id.is_empty() { + Err(anyhow!("no device with name '{}'", device)) + } else { + self + .net + .handle_network_event(IoEvent::TransferPlaybackToDevice(id.to_string())) + .await; + Ok(()) + } + } + + // spt playback --like / --shuffle / --repeat + pub async fn mark(&mut self, flag: Flag) -> Result<()> { + let c = { + let app = self.net.app.lock().await; + app + .current_playback_context + .clone() + .ok_or_else(|| anyhow!("no context available"))? + }; + + match flag { + Flag::Like => { + // Get the id of the current song + let id = match c.item { + Some(i) => match i { + PlayingItem::Track(t) => t.id.ok_or_else(|| anyhow!("item has no id")), + PlayingItem::Episode(_) => Err(anyhow!("saving episodes not yet implemented")), + }, + None => Err(anyhow!("no item playing")), + }; + self + .net + .handle_network_event(IoEvent::ToggleSaveTrack(id?)) + .await; + } + Flag::Shuffle => { + self + .net + .handle_network_event(IoEvent::Shuffle(c.shuffle_state)) + .await + } + Flag::Repeat => { + self + .net + .handle_network_event(IoEvent::Repeat(c.repeat_state)) + .await; + } + } + + Ok(()) + } + + // spt playback -s + pub async fn get_status(&mut self, format: String) -> Result { + // Update info on current playback + self + .net + .handle_network_event(IoEvent::GetCurrentPlayback) + .await; + self + .net + .handle_network_event(IoEvent::GetCurrentSavedTracks(None)) + .await; + + let context = self + .net + .app + .lock() + .await + .current_playback_context + .clone() + .ok_or_else(|| anyhow!("no context available"))?; + + let playing_item = context.item.ok_or_else(|| anyhow!("no track playing"))?; + + let mut hs = match playing_item { + PlayingItem::Track(track) => { + let id = track.id.clone().unwrap_or_default(); + let mut hs = Format::from_type(FormatType::Track(Box::new(track))); + hs.push(Format::Flags(( + context.repeat_state, + context.shuffle_state, + self.is_a_saved_track(id).await, + ))); + hs + } + PlayingItem::Episode(episode) => { + let mut hs = Format::from_type(FormatType::Episode(Box::new(episode))); + hs.push(Format::Flags(( + context.repeat_state, + context.shuffle_state, + false, + ))); + hs + } + }; + + hs.push(Format::Device(context.device.name)); + hs.push(Format::Volume(context.device.volume_percent)); + hs.push(Format::Playing(context.is_playing)); + + Ok(self.format_output(format, hs)) + } + + // spt play -u URI + pub async fn play_uri(&mut self, uri: String, queue: bool, random: bool) { + let offset = if random { + // Only works with playlists for now + if uri.contains("spotify:playlist:") { + let id = uri.split(':').last().unwrap(); + match self.net.spotify.playlist(id, None, None).await { + Ok(p) => { + let num = p.tracks.total; + Some(thread_rng().gen_range(0, num) as usize) + } + Err(e) => { + self + .net + .app + .lock() + .await + .handle_error(anyhow!(e.to_string())); + return; + } + } + } else { + None + } + } else { + None + }; + + if uri.contains("spotify:track:") { + if queue { + self + .net + .handle_network_event(IoEvent::AddItemToQueue(uri)) + .await; + } else { + self + .net + .handle_network_event(IoEvent::StartPlayback( + None, + Some(vec![uri.clone()]), + Some(0), + )) + .await; + } + } else { + self + .net + .handle_network_event(IoEvent::StartPlayback(Some(uri.clone()), None, offset)) + .await; + } + } + + // spt play -n NAME ... + pub async fn play(&mut self, name: String, item: Type, queue: bool, random: bool) -> Result<()> { + self + .net + .handle_network_event(IoEvent::GetSearchResults(name.clone(), None)) + .await; + // Get the uri of the first found + // item + the offset or return an error message + let uri = { + let results = &self.net.app.lock().await.search_results; + match item { + Type::Track => { + if let Some(r) = &results.tracks { + r.items[0].uri.clone() + } else { + return Err(anyhow!("no tracks with name '{}'", name)); + } + } + Type::Album => { + if let Some(r) = &results.albums { + let album = &r.items[0]; + if let Some(uri) = &album.uri { + uri.clone() + } else { + return Err(anyhow!("album {} has no uri", album.name)); + } + } else { + return Err(anyhow!("no albums with name '{}'", name)); + } + } + Type::Artist => { + if let Some(r) = &results.artists { + r.items[0].uri.clone() + } else { + return Err(anyhow!("no artists with name '{}'", name)); + } + } + Type::Show => { + if let Some(r) = &results.shows { + r.items[0].uri.clone() + } else { + return Err(anyhow!("no shows with name '{}'", name)); + } + } + Type::Playlist => { + if let Some(r) = &results.playlists { + let p = &r.items[0]; + // For a random song, create a random offset + p.uri.clone() + } else { + return Err(anyhow!("no playlists with name '{}'", name)); + } + } + _ => unreachable!(), + } + }; + + // Play or queue the uri + self.play_uri(uri, queue, random).await; + + Ok(()) + } + + // spt query -s SEARCH ... + pub async fn query(&mut self, search: String, format: String, item: Type) -> String { + self + .net + .handle_network_event(IoEvent::GetSearchResults(search.clone(), None)) + .await; + + let app = self.net.app.lock().await; + match item { + Type::Playlist => { + if let Some(results) = &app.search_results.playlists { + results + .items + .iter() + .map(|r| { + self.format_output( + format.clone(), + Format::from_type(FormatType::Playlist(Box::new(r.clone()))), + ) + }) + .collect::>() + .join("\n") + } else { + format!("no playlists with name '{}'", search) + } + } + Type::Track => { + if let Some(results) = &app.search_results.tracks { + results + .items + .iter() + .map(|r| { + self.format_output( + format.clone(), + Format::from_type(FormatType::Track(Box::new(r.clone()))), + ) + }) + .collect::>() + .join("\n") + } else { + format!("no tracks with name '{}'", search) + } + } + Type::Artist => { + if let Some(results) = &app.search_results.artists { + results + .items + .iter() + .map(|r| { + self.format_output( + format.clone(), + Format::from_type(FormatType::Artist(Box::new(r.clone()))), + ) + }) + .collect::>() + .join("\n") + } else { + format!("no artists with name '{}'", search) + } + } + Type::Show => { + if let Some(results) = &app.search_results.shows { + results + .items + .iter() + .map(|r| { + self.format_output( + format.clone(), + Format::from_type(FormatType::Show(Box::new(r.clone()))), + ) + }) + .collect::>() + .join("\n") + } else { + format!("no shows with name '{}'", search) + } + } + Type::Album => { + if let Some(results) = &app.search_results.albums { + results + .items + .iter() + .map(|r| { + self.format_output( + format.clone(), + Format::from_type(FormatType::Album(Box::new(r.clone()))), + ) + }) + .collect::>() + .join("\n") + } else { + format!("no albums with name '{}'", search) + } + } + // Enforced by clap + _ => unreachable!(), + } + } +} diff --git a/src/cli/handle.rs b/src/cli/handle.rs new file mode 100644 index 00000000..53bbb386 --- /dev/null +++ b/src/cli/handle.rs @@ -0,0 +1,148 @@ +use crate::network::{IoEvent, Network}; +use crate::user_config::UserConfig; + +use super::{ + util::{Flag, JumpDirection, Type}, + CliApp, +}; + +use anyhow::{anyhow, Result}; +use clap::ArgMatches; + +// Handle the different subcommands +pub async fn handle_matches( + matches: &ArgMatches<'_>, + cmd: String, + net: Network<'_>, + config: UserConfig, +) -> Result { + let mut cli = CliApp::new(net, config); + + cli.net.handle_network_event(IoEvent::GetDevices).await; + cli + .net + .handle_network_event(IoEvent::GetCurrentPlayback) + .await; + + let devices_list = match &cli.net.app.lock().await.devices { + Some(p) => p + .devices + .iter() + .map(|d| d.id.clone()) + .collect::>(), + None => Vec::new(), + }; + + // If the device_id is not specified, select the first available device + let device_id = cli.net.client_config.device_id.clone(); + if device_id.is_none() || !devices_list.contains(&device_id.unwrap()) { + // Select the first device available + if let Some(d) = devices_list.get(0) { + cli.net.client_config.set_device_id(d.clone())?; + } + } + + if let Some(d) = matches.value_of("device") { + cli.set_device(d.to_string()).await?; + } + + // Evalute the subcommand + let output = match cmd.as_str() { + "playback" => { + let format = matches.value_of("format").unwrap(); + + // Commands that are 'single' + if matches.is_present("share-track") { + return cli.share_track_or_episode().await; + } else if matches.is_present("share-album") { + return cli.share_album_or_show().await; + } + + // Run the action, and print out the status + // No 'else if's because multiple different commands are possible + if matches.is_present("toggle") { + cli.toggle_playback().await; + } + if let Some(d) = matches.value_of("transfer") { + cli.transfer_playback(d).await?; + } + // Multiple flags are possible + if matches.is_present("flags") { + let flags = Flag::from_matches(matches); + for f in flags { + cli.mark(f).await?; + } + } + if matches.is_present("jumps") { + let (direction, amount) = JumpDirection::from_matches(matches); + for _ in 0..amount { + cli.jump(&direction).await; + } + } + if let Some(vol) = matches.value_of("volume") { + cli.volume(vol.to_string()).await?; + } + + // Print out the status if no errors were found + cli.get_status(format.to_string()).await + } + "play" => { + let queue = matches.is_present("queue"); + let random = matches.is_present("random"); + let format = matches.value_of("format").unwrap(); + + if let Some(uri) = matches.value_of("uri") { + cli.play_uri(uri.to_string(), queue, random).await; + } else if let Some(name) = matches.value_of("name") { + let category = Type::play_from_matches(matches); + cli.play(name.to_string(), category, queue, random).await?; + } + + cli.get_status(format.to_string()).await + } + "list" => { + let format = matches.value_of("format").unwrap().to_string(); + + // Update the limits for the list and search functions + // I think the small and big search limits are very confusing + // so I just set them both to max, is this okay? + if let Some(max) = matches.value_of("limit") { + cli.update_query_limits(max.to_string()).await?; + } + + let category = Type::list_from_matches(matches); + Ok(cli.list(category, &format).await) + } + "search" => { + let format = matches.value_of("format").unwrap().to_string(); + + // Update the limits for the list and search functions + // I think the small and big search limits are very confusing + // so I just set them both to max, is this okay? + if let Some(max) = matches.value_of("limit") { + cli.update_query_limits(max.to_string()).await?; + } + + let category = Type::search_from_matches(matches); + Ok( + cli + .query( + matches.value_of("search").unwrap().to_string(), + format, + category, + ) + .await, + ) + } + // Clap enforces that one of the things above is specified + _ => unreachable!(), + }; + + // Check if there was an error + let api_error = cli.net.app.lock().await.api_error.clone(); + if api_error.is_empty() { + output + } else { + Err(anyhow!("{}", api_error)) + } +} diff --git a/src/cli/mod.rs b/src/cli/mod.rs new file mode 100644 index 00000000..2236dfec --- /dev/null +++ b/src/cli/mod.rs @@ -0,0 +1,8 @@ +mod clap; +mod cli_app; +mod handle; +mod util; + +pub use self::clap::{list_subcommand, play_subcommand, playback_subcommand, search_subcommand}; +use cli_app::CliApp; +pub use handle::handle_matches; diff --git a/src/cli/util.rs b/src/cli/util.rs new file mode 100644 index 00000000..71304c7d --- /dev/null +++ b/src/cli/util.rs @@ -0,0 +1,259 @@ +use clap::ArgMatches; +use rspotify::{ + model::{ + album::SimplifiedAlbum, artist::FullArtist, artist::SimplifiedArtist, + playlist::SimplifiedPlaylist, show::FullEpisode, show::SimplifiedShow, track::FullTrack, + }, + senum::RepeatState, +}; + +use crate::user_config::UserConfig; + +// Possible types to list or search +#[derive(Debug)] +pub enum Type { + Playlist, + Track, + Artist, + Album, + Show, + Device, + Liked, +} + +impl Type { + pub fn play_from_matches(m: &ArgMatches<'_>) -> Self { + if m.is_present("playlist") { + Self::Playlist + } else if m.is_present("track") { + Self::Track + } else if m.is_present("artist") { + Self::Artist + } else if m.is_present("album") { + Self::Album + } else if m.is_present("show") { + Self::Show + } + // Enforced by clap + else { + unreachable!() + } + } + + pub fn search_from_matches(m: &ArgMatches<'_>) -> Self { + if m.is_present("playlists") { + Self::Playlist + } else if m.is_present("tracks") { + Self::Track + } else if m.is_present("artists") { + Self::Artist + } else if m.is_present("albums") { + Self::Album + } else if m.is_present("shows") { + Self::Show + } + // Enforced by clap + else { + unreachable!() + } + } + + pub fn list_from_matches(m: &ArgMatches<'_>) -> Self { + if m.is_present("playlists") { + Self::Playlist + } else if m.is_present("devices") { + Self::Device + } else if m.is_present("liked") { + Self::Liked + } + // Enforced by clap + else { + unreachable!() + } + } +} + +// +// Possible flags to set +// + +pub enum Flag { + Like, + Shuffle, + Repeat, +} + +impl Flag { + pub fn from_matches(m: &ArgMatches<'_>) -> Vec { + // Multiple flags are possible + let mut flags = Vec::new(); + if m.is_present("like") { + flags.push(Self::Like); + } + if m.is_present("shuffle") { + flags.push(Self::Shuffle); + } + if m.is_present("repeat") { + flags.push(Self::Repeat); + } + flags + } +} + +// Possible directions to jump to +pub enum JumpDirection { + Next, + Previous, +} + +impl JumpDirection { + pub fn from_matches(m: &ArgMatches<'_>) -> (Self, u64) { + if m.is_present("next") { + (Self::Next, m.occurrences_of("next")) + } else if m.is_present("previous") { + (Self::Previous, m.occurrences_of("previous")) + // Enforced by clap + } else { + unreachable!() + } + } +} + +// For fomatting (-f / --format flag) + +// Types to create a Format enum from +// Boxing was proposed by cargo clippy +// to reduce the size of this enum +pub enum FormatType { + Album(Box), + Artist(Box), + Playlist(Box), + Track(Box), + Episode(Box), + Show(Box), +} + +// Types that can be formatted +#[derive(Clone)] +pub enum Format { + Album(String), + Artist(String), + Playlist(String), + Track(String), + Show(String), + Uri(String), + Device(String), + Volume(u32), + // This is a bit long, should it be splitted up? + Flags((RepeatState, bool, bool)), + Playing(bool), +} + +pub fn join_artists(a: Vec) -> String { + a.iter() + .map(|l| l.name.clone()) + .collect::>() + .join(", ") +} + +impl Format { + // Extract important information from types + pub fn from_type(t: FormatType) -> Vec { + match t { + FormatType::Album(a) => { + let joined_artists = join_artists(a.artists.clone()); + let mut vec = vec![Self::Album(a.name), Self::Artist(joined_artists)]; + if let Some(uri) = a.uri { + vec.push(Self::Uri(uri)); + } + vec + } + FormatType::Artist(a) => vec![Self::Artist(a.name), Self::Uri(a.uri)], + FormatType::Playlist(p) => vec![Self::Playlist(p.name), Self::Uri(p.uri)], + FormatType::Track(t) => { + let joined_artists = join_artists(t.artists.clone()); + vec![ + Self::Album(t.album.name), + Self::Artist(joined_artists), + Self::Track(t.name), + Self::Uri(t.uri), + ] + } + FormatType::Show(r) => vec![ + Self::Artist(r.publisher), + Self::Show(r.name), + Self::Uri(r.uri), + ], + FormatType::Episode(e) => vec![ + Self::Show(e.show.name), + Self::Artist(e.show.publisher), + Self::Track(e.name), + Self::Uri(e.uri), + ], + } + } + + // Is there a better way? + pub fn inner(&self, conf: UserConfig) -> String { + match self { + Self::Album(s) => s.clone(), + Self::Artist(s) => s.clone(), + Self::Playlist(s) => s.clone(), + Self::Track(s) => s.clone(), + Self::Show(s) => s.clone(), + Self::Uri(s) => s.clone(), + Self::Device(s) => s.clone(), + // Because this match statements + // needs to return a &String, I have to do it this way + Self::Volume(s) => s.to_string(), + Self::Flags((r, s, l)) => { + let like = if *l { + conf.behavior.liked_icon + } else { + String::new() + }; + let shuffle = if *s { + conf.behavior.shuffle_icon + } else { + String::new() + }; + let repeat = match r { + RepeatState::Off => String::new(), + RepeatState::Track => conf.behavior.repeat_track_icon, + RepeatState::Context => conf.behavior.repeat_context_icon, + }; + + // Add them together (only those that aren't empty) + [shuffle, repeat, like] + .iter() + .filter(|a| !a.is_empty()) + // Convert &String to String to join them + .map(|s| s.to_string()) + .collect::>() + .join(" ") + } + Self::Playing(s) => { + if *s { + conf.behavior.playing_icon + } else { + conf.behavior.paused_icon + } + } + } + } + + pub fn get_placeholder(&self) -> &str { + match self { + Self::Album(_) => "%b", + Self::Artist(_) => "%a", + Self::Playlist(_) => "%p", + Self::Track(_) => "%t", + Self::Show(_) => "%h", + Self::Uri(_) => "%u", + Self::Device(_) => "%d", + Self::Volume(_) => "%v", + Self::Flags(_) => "%f", + Self::Playing(_) => "%s", + } + } +} diff --git a/src/main.rs b/src/main.rs index 8b4e941f..adb0de5b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ mod app; mod banner; +mod cli; mod config; mod event; mod handlers; @@ -10,11 +11,11 @@ mod user_config; use crate::app::RouteId; use crate::event::Key; -use anyhow::Result; +use anyhow::{anyhow, Result}; use app::{ActiveBlock, App}; use backtrace::Backtrace; use banner::BANNER; -use clap::{App as ClapApp, Arg}; +use clap::{App as ClapApp, Arg, Shell}; use config::ClientConfig; use crossterm::{ cursor::MoveTo, @@ -123,24 +124,63 @@ async fn main() -> Result<()> { panic_hook(info); })); - let matches = ClapApp::new(env!("CARGO_PKG_NAME")) - .version(env!("CARGO_PKG_VERSION")) - .author(env!("CARGO_PKG_AUTHORS")) - .about(env!("CARGO_PKG_DESCRIPTION")) - .usage("Press `?` while running the app to see keybindings") - .before_help(BANNER) - .after_help("Your spotify Client ID and Client Secret are stored in $HOME/.config/spotify-tui/client.yml") - .arg(Arg::with_name("tick-rate") - .short("t") - .long("tick-rate") - .help("Set the tick rate (milliseconds): the lower the number the higher the FPS. It can be nicer to have a lower value when you want to use the audio analysis view of the app. Beware that this comes at a CPU cost!") - .takes_value(true)) - .arg(Arg::with_name("config") - .short("c") - .long("config") - .help("Specify configuration file path.") - .takes_value(true)) - .get_matches(); + let mut clap_app = ClapApp::new(env!("CARGO_PKG_NAME")) + .version(env!("CARGO_PKG_VERSION")) + .author(env!("CARGO_PKG_AUTHORS")) + .about(env!("CARGO_PKG_DESCRIPTION")) + .usage("Press `?` while running the app to see keybindings") + .before_help(BANNER) + .after_help( + "Your spotify Client ID and Client Secret are stored in $HOME/.config/spotify-tui/client.yml", + ) + .arg( + Arg::with_name("tick-rate") + .short("t") + .long("tick-rate") + .help("Set the tick rate (milliseconds): the lower the number the higher the FPS.") + .long_help( + "Specify the tick rate in milliseconds: the lower the number the \ +higher the FPS. It can be nicer to have a lower value when you want to use the audio analysis view \ +of the app. Beware that this comes at a CPU cost!", + ) + .takes_value(true), + ) + .arg( + Arg::with_name("config") + .short("c") + .long("config") + .help("Specify configuration file path.") + .takes_value(true), + ) + .arg( + Arg::with_name("completions") + .long("completions") + .help("Generates completions for your preferred shell") + .takes_value(true) + .possible_values(&["bash", "zsh", "fish", "power-shell", "elvish"]) + .value_name("SHELL"), + ) + // Control spotify from the command line + .subcommand(cli::playback_subcommand()) + .subcommand(cli::play_subcommand()) + .subcommand(cli::list_subcommand()) + .subcommand(cli::search_subcommand()); + + let matches = clap_app.clone().get_matches(); + + // Shell completions don't need any spotify work + if let Some(s) = matches.value_of("completions") { + let shell = match s { + "fish" => Shell::Fish, + "bash" => Shell::Bash, + "zsh" => Shell::Zsh, + "power-shell" => Shell::PowerShell, + "elvish" => Shell::Elvish, + _ => return Err(anyhow!("no completions avaible for '{}'", s)), + }; + clap_app.gen_completions_to("spt", shell, &mut io::stdout()); + return Ok(()); + } let mut user_config = UserConfig::new(); if let Some(config_file_path) = matches.value_of("config") { @@ -189,14 +229,25 @@ async fn main() -> Result<()> { token_expiry, ))); - let cloned_app = Arc::clone(&app); - std::thread::spawn(move || { - let mut network = Network::new(oauth, spotify, client_config, &app); - start_tokio(sync_io_rx, &mut network); - }); - - // The UI must run in the "main" thread - start_ui(user_config, &cloned_app).await?; + // Work with the cli (not really async) + if let Some(cmd) = matches.subcommand_name() { + // Save, because we checked if the subcommand is present at runtime + let m = matches.subcommand_matches(cmd).unwrap(); + let network = Network::new(oauth, spotify, client_config, &app); + println!( + "{}", + cli::handle_matches(m, cmd.to_string(), network, user_config).await? + ); + // Launch the UI (async) + } else { + let cloned_app = Arc::clone(&app); + std::thread::spawn(move || { + let mut network = Network::new(oauth, spotify, client_config, &app); + start_tokio(sync_io_rx, &mut network); + }); + // The UI must run in the "main" thread + start_ui(user_config, &cloned_app).await?; + } } None => println!("\nSpotify auth failed"), } diff --git a/src/network.rs b/src/network.rs index cb31a7b8..1635a681 100644 --- a/src/network.rs +++ b/src/network.rs @@ -108,11 +108,11 @@ pub fn get_spotify(token_info: TokenInfo) -> (Spotify, SystemTime) { #[derive(Clone)] pub struct Network<'a> { oauth: SpotifyOAuth, - spotify: Spotify, + pub spotify: Spotify, large_search_limit: u32, small_search_limit: u32, - client_config: ClientConfig, - app: &'a Arc>, + pub client_config: ClientConfig, + pub app: &'a Arc>, } impl<'a> Network<'a> { diff --git a/src/user_config.rs b/src/user_config.rs index d880a1b8..f348e3fd 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -213,6 +213,11 @@ pub struct BehaviorConfigString { pub enable_text_emphasis: Option, pub show_loading_indicator: Option, pub liked_icon: Option, + pub shuffle_icon: Option, + pub repeat_track_icon: Option, + pub repeat_context_icon: Option, + pub playing_icon: Option, + pub paused_icon: Option, } #[derive(Clone)] @@ -223,6 +228,11 @@ pub struct BehaviorConfig { pub enable_text_emphasis: bool, pub show_loading_indicator: bool, pub liked_icon: String, + pub shuffle_icon: String, + pub repeat_track_icon: String, + pub repeat_context_icon: String, + pub playing_icon: String, + pub paused_icon: String, } #[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -278,7 +288,12 @@ impl UserConfig { tick_rate_milliseconds: 250, enable_text_emphasis: true, show_loading_indicator: true, - liked_icon: "β™₯".to_string(), + liked_icon: " ".to_string(), + shuffle_icon: "咽".to_string(), + repeat_track_icon: "ο₯—".to_string(), + repeat_context_icon: "ο₯•".to_string(), + playing_icon: "".to_string(), + paused_icon: "ο££ ".to_string(), }, path_to_config: None, } @@ -412,6 +427,26 @@ impl UserConfig { self.behavior.liked_icon = liked_icon; } + if let Some(paused_icon) = behavior_config.paused_icon { + self.behavior.paused_icon = paused_icon; + } + + if let Some(playing_icon) = behavior_config.playing_icon { + self.behavior.playing_icon = playing_icon; + } + + if let Some(shuffle_icon) = behavior_config.shuffle_icon { + self.behavior.shuffle_icon = shuffle_icon; + } + + if let Some(repeat_track_icon) = behavior_config.repeat_track_icon { + self.behavior.repeat_track_icon = repeat_track_icon; + } + + if let Some(repeat_context_icon) = behavior_config.repeat_context_icon { + self.behavior.repeat_context_icon = repeat_context_icon; + } + Ok(()) } From 89b612bc872e4e72c391653169ff5d1825e2c641 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Wed, 6 Jan 2021 09:53:58 +0000 Subject: [PATCH 224/311] Fix clippy warnings after new Rust release (#697) --- src/handlers/search_results.rs | 25 +++++-------------------- src/network.rs | 2 +- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/src/handlers/search_results.rs b/src/handlers/search_results.rs index aafbe917..71ec1090 100644 --- a/src/handlers/search_results.rs +++ b/src/handlers/search_results.rs @@ -350,46 +350,31 @@ fn handle_enter_event_on_selected_block(app: &mut App) { fn handle_enter_event_on_hovered_block(app: &mut App) { match app.search_results.hovered_block { SearchResultBlock::AlbumSearch => { - let next_index = match app.search_results.selected_album_index { - Some(index) => index, - None => 0, - }; + let next_index = app.search_results.selected_album_index.unwrap_or(0); app.search_results.selected_album_index = Some(next_index); app.search_results.selected_block = SearchResultBlock::AlbumSearch; } SearchResultBlock::SongSearch => { - let next_index = match app.search_results.selected_tracks_index { - Some(index) => index, - None => 0, - }; + let next_index = app.search_results.selected_tracks_index.unwrap_or(0); app.search_results.selected_tracks_index = Some(next_index); app.search_results.selected_block = SearchResultBlock::SongSearch; } SearchResultBlock::ArtistSearch => { - let next_index = match app.search_results.selected_artists_index { - Some(index) => index, - None => 0, - }; + let next_index = app.search_results.selected_artists_index.unwrap_or(0); app.search_results.selected_artists_index = Some(next_index); app.search_results.selected_block = SearchResultBlock::ArtistSearch; } SearchResultBlock::PlaylistSearch => { - let next_index = match app.search_results.selected_playlists_index { - Some(index) => index, - None => 0, - }; + let next_index = app.search_results.selected_playlists_index.unwrap_or(0); app.search_results.selected_playlists_index = Some(next_index); app.search_results.selected_block = SearchResultBlock::PlaylistSearch; } SearchResultBlock::ShowSearch => { - let next_index = match app.search_results.selected_shows_index { - Some(index) => index, - None => 0, - }; + let next_index = app.search_results.selected_shows_index.unwrap_or(0); app.search_results.selected_shows_index = Some(next_index); app.search_results.selected_block = SearchResultBlock::ShowSearch; diff --git a/src/network.rs b/src/network.rs index 1635a681..b9251a21 100644 --- a/src/network.rs +++ b/src/network.rs @@ -776,7 +776,7 @@ impl<'a> Network<'a> { Some(self.large_search_limit), Some(0), ); - let artist_name = if input_artist_name == "" { + let artist_name = if input_artist_name.is_empty() { self .spotify .artist(&artist_id) From 7d9c61dfd2a116af9d5f9f031e89a7f6c85dbcca Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Wed, 6 Jan 2021 10:01:57 +0000 Subject: [PATCH 225/311] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7b72a73..0440dc25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Optimize seek [#640](https://github.com/Rigellute/spotify-tui/pull/640) - Make the liked icon configurable [#659](https://github.com/Rigellute/spotify-tui/pull/659) - Fix centering of basic_view [#664](https://github.com/Rigellute/spotify-tui/pull/664) +- Add CLI for controlling Spotify [#645](https://github.com/Rigellute/spotify-tui/pull/645) ## [0.22.0] - 2020-10-05 From 753423ed47f8cc0e5f0d08e16076bd38430e3a09 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 6 Jan 2021 10:05:16 +0000 Subject: [PATCH 226/311] Bump serde_yaml from 0.8.14 to 0.8.15 (#696) Bumps [serde_yaml](https://github.com/dtolnay/serde-yaml) from 0.8.14 to 0.8.15. - [Release notes](https://github.com/dtolnay/serde-yaml/releases) - [Commits](https://github.com/dtolnay/serde-yaml/compare/0.8.14...0.8.15) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2b0352e3..69541e83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1637,9 +1637,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7baae0a99f1a324984bcdc5f0718384c1f69775f1c7eec8b859b71b443e3fd7" +checksum = "971be8f6e4d4a47163b405a3df70d14359186f9ab0f3a3ec37df144ca1ce089f" dependencies = [ "dtoa", "linked-hash-map", @@ -2237,9 +2237,9 @@ dependencies = [ [[package]] name = "yaml-rust" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" dependencies = [ "linked-hash-map", ] From 560ff5478c3e484f50057b64193f414ba87f1e5a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 6 Jan 2021 10:05:57 +0000 Subject: [PATCH 227/311] Bump anyhow from 1.0.34 to 1.0.37 (#687) Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.34 to 1.0.37. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.34...1.0.37) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 69541e83..8ef913bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,9 +35,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.34" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7" +checksum = "ee67c11feeac938fae061b232e38e0b6d94f97a9df10e6271319325ac4c56a86" [[package]] name = "arc-swap" diff --git a/Cargo.toml b/Cargo.toml index f94ce3c4..8b8036ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ clipboard = "0.5.0" crossterm = "0.18" tokio = { version = "0.2", features = ["full"] } rand = "0.7.3" -anyhow = "1.0.34" +anyhow = "1.0.37" [[bin]] bench = false From 4f71b9756e8ff3612c8ac8f2d6cb02dc86da337c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 6 Jan 2021 10:06:12 +0000 Subject: [PATCH 228/311] Bump serde_json from 1.0.59 to 1.0.61 (#686) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.59 to 1.0.61. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.59...v1.0.61) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ef913bb..0005d84e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1614,9 +1614,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.59" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" +checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" dependencies = [ "itoa", "ryu", From b42bc337bc8d034b2826de554c2f640c7b83d80e Mon Sep 17 00:00:00 2001 From: Leon G Date: Wed, 6 Jan 2021 11:12:32 +0100 Subject: [PATCH 229/311] Implement Podcasts Library page (#650) * Implement Podcasts Library page * Fix formatting issues * Implement Podcast functionalities search results * Comment * Handle left, down events for ActiveBlock EpisodeTable, Podcasts when no block is selected * Use 'liked' icon from user config for followed podcast search results * Remove draw_not_impemented yet (no longer used) * Use 'get' for retrieving a show by index from search results --- src/app.rs | 76 ++++++++++++++++++++++++--- src/handlers/empty.rs | 4 ++ src/handlers/library.rs | 1 + src/handlers/podcasts.rs | 52 ++++++++++++++++++- src/handlers/search_results.rs | 6 +-- src/network.rs | 91 ++++++++++++++++++++++++++++++++ src/ui/mod.rs | 95 ++++++++++++++++++++++------------ 7 files changed, 280 insertions(+), 45 deletions(-) diff --git a/src/app.rs b/src/app.rs index 2c2dfab2..7c001252 100644 --- a/src/app.rs +++ b/src/app.rs @@ -11,7 +11,7 @@ use rspotify::{ page::{CursorBasedPage, Page}, playing::PlayHistory, playlist::{PlaylistTrack, SimplifiedPlaylist}, - show::{SimplifiedEpisode, SimplifiedShow}, + show::{Show, SimplifiedEpisode, SimplifiedShow}, track::{FullTrack, SavedTrack, SimplifiedTrack}, user::PrivateUser, PlayingItem, @@ -85,6 +85,7 @@ pub struct Library { pub saved_tracks: ScrollableResultPages>, pub made_for_you_playlists: ScrollableResultPages>, pub saved_albums: ScrollableResultPages>, + pub saved_shows: ScrollableResultPages>, pub saved_artists: ScrollableResultPages>, } @@ -260,7 +261,7 @@ pub struct App { // Inputs: // input is the string for input; // input_idx is the index of the cursor in terms of character; - // input_cursor_position is the sum of the width of charaters preceding the cursor. + // input_cursor_position is the sum of the width of characters preceding the cursor. // Reason for this complication is due to non-ASCII characters, they may // take more than 1 bytes to store and more than 1 character width to display. pub input: Vec, @@ -269,6 +270,7 @@ pub struct App { pub liked_song_ids_set: HashSet, pub followed_artist_ids_set: HashSet, pub saved_album_ids_set: HashSet, + pub saved_show_ids_set: HashSet, pub large_search_limit: u32, pub library: Library, pub playlist_offset: u32, @@ -296,6 +298,7 @@ pub struct App { pub album_list_index: usize, pub made_for_you_index: usize, pub artists_list_index: usize, + pub shows_list_index: usize, pub clipboard_context: Option, pub help_docs_size: u32, pub help_menu_page: u32, @@ -317,6 +320,7 @@ impl Default for App { album_list_index: 0, made_for_you_index: 0, artists_list_index: 0, + shows_list_index: 0, artists: vec![], artist: None, user_config: UserConfig::new(), @@ -330,12 +334,14 @@ impl Default for App { saved_tracks: ScrollableResultPages::new(), made_for_you_playlists: ScrollableResultPages::new(), saved_albums: ScrollableResultPages::new(), + saved_shows: ScrollableResultPages::new(), saved_artists: ScrollableResultPages::new(), selected_index: 0, }, liked_song_ids_set: HashSet::new(), followed_artist_ids_set: HashSet::new(), saved_album_ids_set: HashSet::new(), + saved_show_ids_set: HashSet::new(), navigation_stack: vec![DEFAULT_ROUTE], large_search_limit: 20, small_search_limit: 4, @@ -878,6 +884,29 @@ impl App { } } + pub fn get_current_user_saved_shows_next(&mut self) { + match self + .library + .saved_shows + .get_results(Some(self.library.saved_shows.index + 1)) + .cloned() + { + Some(_) => self.library.saved_shows.index += 1, + None => { + if let Some(saved_shows) = &self.library.saved_shows.get_results(None) { + let offset = Some(saved_shows.offset + saved_shows.limit); + self.dispatch(IoEvent::GetCurrentUserSavedShows(offset)); + } + } + } + } + + pub fn get_current_user_saved_shows_previous(&mut self) { + if self.library.saved_shows.index > 0 { + self.library.saved_shows.index -= 1; + } + } + pub fn user_unfollow_artists(&mut self, block: ActiveBlock) { match block { ActiveBlock::SearchResultBlock => { @@ -973,12 +1002,47 @@ impl App { } } - pub fn user_follow_show(&mut self) { - unimplemented!(); + pub fn user_follow_show(&mut self, block: ActiveBlock) { + match block { + ActiveBlock::SearchResultBlock => { + if let Some(shows) = &self.search_results.shows { + if let Some(selected_index) = self.search_results.selected_shows_index { + if let Some(show_id) = shows.items.get(selected_index).map(|item| item.id.clone()) { + self.dispatch(IoEvent::CurrentUserSavedShowAdd(show_id)); + } + } + } + } + ActiveBlock::EpisodeTable => { + unimplemented!(); + } + _ => (), + } } - pub fn user_unfollow_show(&mut self) { - unimplemented!(); + pub fn user_unfollow_show(&mut self, block: ActiveBlock) { + match block { + ActiveBlock::Podcasts => { + if let Some(shows) = self.library.saved_shows.get_results(None) { + if let Some(selected_show) = shows.items.get(self.shows_list_index) { + let show_id = selected_show.show.id.clone(); + self.dispatch(IoEvent::CurrentUserSavedShowDelete(show_id)); + } + } + } + ActiveBlock::SearchResultBlock => { + if let Some(shows) = &self.search_results.shows { + if let Some(selected_index) = self.search_results.selected_shows_index { + let show_id = shows.items[selected_index].id.to_owned(); + self.dispatch(IoEvent::CurrentUserSavedShowDelete(show_id)); + } + } + } + ActiveBlock::EpisodeTable => { + unimplemented!(); + } + _ => (), + } } pub fn get_made_for_you(&mut self) { diff --git a/src/handlers/empty.rs b/src/handlers/empty.rs index d28654dd..abafdf4a 100644 --- a/src/handlers/empty.rs +++ b/src/handlers/empty.rs @@ -19,6 +19,8 @@ pub fn handler(key: Key, app: &mut App) { | ActiveBlock::AlbumList | ActiveBlock::AlbumTracks | ActiveBlock::Artists + | ActiveBlock::Podcasts + | ActiveBlock::EpisodeTable | ActiveBlock::Home | ActiveBlock::MadeForYou | ActiveBlock::MyPlaylists @@ -42,6 +44,8 @@ pub fn handler(key: Key, app: &mut App) { | ActiveBlock::AlbumList | ActiveBlock::AlbumTracks | ActiveBlock::Artists + | ActiveBlock::Podcasts + | ActiveBlock::EpisodeTable | ActiveBlock::Home | ActiveBlock::MadeForYou | ActiveBlock::RecentlyPlayed diff --git a/src/handlers/library.rs b/src/handlers/library.rs index 38dee9c0..4f99ed87 100644 --- a/src/handlers/library.rs +++ b/src/handlers/library.rs @@ -62,6 +62,7 @@ pub fn handler(key: Key, app: &mut App) { } // Podcasts, 5 => { + app.dispatch(IoEvent::GetCurrentUserSavedShows(None)); app.push_navigation_stack(RouteId::Podcasts, ActiveBlock::Podcasts); } // This is required because Rust can't tell if this pattern in exhaustive diff --git a/src/handlers/podcasts.rs b/src/handlers/podcasts.rs index 5ac2ec4a..64f7dfdf 100644 --- a/src/handlers/podcasts.rs +++ b/src/handlers/podcasts.rs @@ -1,9 +1,57 @@ -use super::{super::app::App, common_key_events}; -use crate::event::Key; +use super::common_key_events; +use crate::{ + app::{ActiveBlock, App}, + event::Key, + network::IoEvent, +}; pub fn handler(key: Key, app: &mut App) { match key { k if common_key_events::left_event(k) => common_key_events::handle_left_event(app), + k if common_key_events::down_event(k) => { + if let Some(shows) = &mut app.library.saved_shows.get_results(None) { + let next_index = + common_key_events::on_down_press_handler(&shows.items, Some(app.shows_list_index)); + app.shows_list_index = next_index; + } + } + k if common_key_events::up_event(k) => { + if let Some(shows) = &mut app.library.saved_shows.get_results(None) { + let next_index = + common_key_events::on_up_press_handler(&shows.items, Some(app.shows_list_index)); + app.shows_list_index = next_index; + } + } + k if common_key_events::high_event(k) => { + if let Some(_shows) = app.library.saved_shows.get_results(None) { + let next_index = common_key_events::on_high_press_handler(); + app.shows_list_index = next_index; + } + } + k if common_key_events::middle_event(k) => { + if let Some(shows) = app.library.saved_shows.get_results(None) { + let next_index = common_key_events::on_middle_press_handler(&shows.items); + app.shows_list_index = next_index; + } + } + k if common_key_events::low_event(k) => { + if let Some(shows) = app.library.saved_shows.get_results(None) { + let next_index = common_key_events::on_low_press_handler(&shows.items); + app.shows_list_index = next_index; + } + } + Key::Enter => { + if let Some(shows) = app.library.saved_shows.get_results(None) { + if let Some(selected_show) = shows.items.get(app.shows_list_index) { + // Go to show tracks table + let show_id = selected_show.show.id.to_owned(); + app.dispatch(IoEvent::GetShowEpisodes(show_id)); + }; + } + } + k if k == app.user_config.keys.next_page => app.get_current_user_saved_shows_next(), + k if k == app.user_config.keys.previous_page => app.get_current_user_saved_shows_previous(), + Key::Char('D') => app.user_unfollow_show(ActiveBlock::Podcasts), _ => {} } } diff --git a/src/handlers/search_results.rs b/src/handlers/search_results.rs index 71ec1090..0a82fa2a 100644 --- a/src/handlers/search_results.rs +++ b/src/handlers/search_results.rs @@ -511,9 +511,7 @@ pub fn handler(key: Key, app: &mut App) { SearchResultBlock::PlaylistSearch => { app.user_follow_playlist(); } - SearchResultBlock::ShowSearch => { - app.user_follow_show(); - } + SearchResultBlock::ShowSearch => app.user_follow_show(ActiveBlock::SearchResultBlock), SearchResultBlock::Empty => {} }, Key::Char('D') => match app.search_results.selected_block { @@ -535,7 +533,7 @@ pub fn handler(key: Key, app: &mut App) { app.push_navigation_stack(route, ActiveBlock::Dialog(DialogContext::PlaylistSearch)); } } - SearchResultBlock::ShowSearch => app.user_unfollow_show(), + SearchResultBlock::ShowSearch => app.user_unfollow_show(ActiveBlock::SearchResultBlock), SearchResultBlock::Empty => {} }, Key::Char('r') => handle_recommended_tracks(app), diff --git a/src/network.rs b/src/network.rs index b9251a21..8953f898 100644 --- a/src/network.rs +++ b/src/network.rs @@ -78,6 +78,10 @@ pub enum IoEvent { TransferPlaybackToDevice(String), GetAlbumForTrack(String), CurrentUserSavedTracksContains(Vec), + GetCurrentUserSavedShows(Option), + CurrentUserSavedShowsContains(Vec), + CurrentUserSavedShowDelete(String), + CurrentUserSavedShowAdd(String), GetShowEpisodes(String), AddItemToQueue(String), } @@ -270,6 +274,18 @@ impl<'a> Network<'a> { IoEvent::CurrentUserSavedTracksContains(track_ids) => { self.current_user_saved_tracks_contains(track_ids).await; } + IoEvent::GetCurrentUserSavedShows(offset) => { + self.get_current_user_saved_shows(offset).await; + } + IoEvent::CurrentUserSavedShowsContains(show_ids) => { + self.current_user_saved_shows_contains(show_ids).await; + } + IoEvent::CurrentUserSavedShowDelete(show_id) => { + self.current_user_saved_shows_delete(show_id).await; + } + IoEvent::CurrentUserSavedShowAdd(show_id) => { + self.current_user_saved_shows_add(show_id).await; + } IoEvent::GetShowEpisodes(show_id) => { self.get_show_episodes(show_id).await; } @@ -446,6 +462,42 @@ impl<'a> Network<'a> { } } + async fn get_current_user_saved_shows(&mut self, offset: Option) { + match self + .spotify + .get_saved_show(self.large_search_limit, offset) + .await + { + Ok(saved_shows) => { + // not to show a blank page + if !saved_shows.items.is_empty() { + let mut app = self.app.lock().await; + app.library.saved_shows.add_pages(saved_shows); + } + } + Err(e) => { + self.handle_error(anyhow!(e)).await; + } + } + } + + async fn current_user_saved_shows_contains(&mut self, show_ids: Vec) { + if let Ok(are_followed) = self + .spotify + .check_users_saved_shows(show_ids.to_owned()) + .await + { + let mut app = self.app.lock().await; + show_ids.iter().enumerate().for_each(|(i, id)| { + if are_followed[i] { + app.saved_show_ids_set.insert(id.to_owned()); + } else { + app.saved_show_ids_set.remove(id); + } + }) + } + } + async fn get_show_episodes(&mut self, show_id: String) { match self .spotify @@ -546,6 +598,15 @@ impl<'a> Network<'a> { // Check if these albums are saved app.dispatch(IoEvent::CurrentUserSavedAlbumsContains(album_ids)); + let show_ids = show_results + .items + .iter() + .map(|show| show.id.to_owned()) + .collect(); + + // check if these shows are saved + app.dispatch(IoEvent::CurrentUserSavedShowsContains(show_ids)); + app.search_results.tracks = Some(track_results); app.search_results.artists = Some(artist_results); app.search_results.albums = Some(album_results); @@ -1073,6 +1134,36 @@ impl<'a> Network<'a> { } } + async fn current_user_saved_shows_delete(&mut self, show_id: String) { + match self + .spotify + .remove_users_saved_shows(vec![show_id.to_owned()], None) + .await + { + Ok(_) => { + self.get_current_user_saved_shows(None).await; + let mut app = self.app.lock().await; + app.saved_show_ids_set.remove(&show_id.to_owned()); + } + Err(e) => { + self.handle_error(anyhow!(e)).await; + } + } + } + + async fn current_user_saved_shows_add(&mut self, show_id: String) { + match self.spotify.save_shows(vec![show_id.to_owned()]).await { + Ok(_) => { + self.get_current_user_saved_shows(None).await; + let mut app = self.app.lock().await; + app.saved_show_ids_set.insert(show_id.to_owned()); + } + Err(e) => { + self.handle_error(anyhow!(e)).await; + } + } + } + async fn user_unfollow_artists(&mut self, artist_ids: Vec) { match self.spotify.user_unfollow_artists(&artist_ids).await { Ok(_) => { diff --git a/src/ui/mod.rs b/src/ui/mod.rs index baf532fa..ac2e7a55 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -30,6 +30,7 @@ pub enum TableId { Album, AlbumList, Artist, + Podcast, Song, RecentlyPlayed, MadeForYou, @@ -258,7 +259,7 @@ where draw_artist_table(f, app, chunks[1]); } RouteId::Podcasts => { - draw_not_implemented_yet(f, app, chunks[1], ActiveBlock::Podcasts, "Podcasts"); + draw_podcast_table(f, app, chunks[1]); } RouteId::Recommendations => { draw_recommendations_table(f, app, chunks[1]); @@ -510,7 +511,14 @@ where Some(podcasts) => podcasts .items .iter() - .map(|item| format!("{:} - {}", item.name, item.publisher)) + .map(|item| { + let mut show_name = String::new(); + if app.saved_show_ids_set.contains(&item.id.to_owned()) { + show_name.push_str(&app.user_config.padded_liked_icon()); + } + show_name.push_str(&format!("{:} - {}", item.name, item.publisher)); + show_name + }) .collect(), None => vec![], }; @@ -570,6 +578,58 @@ where ) } +pub fn draw_podcast_table(f: &mut Frame, app: &App, layout_chunk: Rect) +where + B: Backend, +{ + let header = TableHeader { + id: TableId::Podcast, + items: vec![ + TableHeaderItem { + text: "Name", + width: get_percentage_width(layout_chunk.width, 2.0 / 5.0), + ..Default::default() + }, + TableHeaderItem { + text: "Publisher(s)", + width: get_percentage_width(layout_chunk.width, 2.0 / 5.0), + ..Default::default() + }, + ], + }; + + let current_route = app.get_current_route(); + + let highlight_state = ( + current_route.active_block == ActiveBlock::Podcasts, + current_route.hovered_block == ActiveBlock::Podcasts, + ); + + if let Some(saved_shows) = app.library.saved_shows.get_results(None) { + let items = saved_shows + .items + .iter() + .map(|show_page| TableItem { + id: show_page.show.id.to_owned(), + format: vec![ + show_page.show.name.to_owned(), + show_page.show.publisher.to_owned(), + ], + }) + .collect::>(); + + draw_table( + f, + app, + layout_chunk, + ("Podcasts", &header), + &items, + app.shows_list_index, + highlight_state, + ) + }; +} + pub fn draw_album_table(f: &mut Frame, app: &App, layout_chunk: Rect) where B: Backend, @@ -1107,37 +1167,6 @@ where f.render_widget(bottom_text, chunks[1]); } -fn draw_not_implemented_yet( - f: &mut Frame, - app: &App, - layout_chunk: Rect, - block: ActiveBlock, - title: &str, -) where - B: Backend, -{ - let current_route = app.get_current_route(); - let highlight_state = ( - current_route.active_block == block, - current_route.hovered_block == block, - ); - let display_block = Block::default() - .title(Span::styled( - title, - get_color(highlight_state, app.user_config.theme), - )) - .borders(Borders::ALL) - .border_style(get_color(highlight_state, app.user_config.theme)); - - let text = Text::from("Not implemented yet!"); - - let not_implemented = Paragraph::new(text) - .style(Style::default().fg(app.user_config.theme.text)) - .block(display_block) - .wrap(Wrap { trim: true }); - f.render_widget(not_implemented, layout_chunk); -} - fn draw_artist_albums(f: &mut Frame, app: &App, layout_chunk: Rect) where B: Backend, From 07a8e574bb4a60ae9282accf82e1678e795ba8ea Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Wed, 6 Jan 2021 10:18:59 +0000 Subject: [PATCH 230/311] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0440dc25..4c5c7b27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - Make the liked icon configurable [#659](https://github.com/Rigellute/spotify-tui/pull/659) - Fix centering of basic_view [#664](https://github.com/Rigellute/spotify-tui/pull/664) - Add CLI for controlling Spotify [#645](https://github.com/Rigellute/spotify-tui/pull/645) +- Implement Podcasts Library page [#650](https://github.com/Rigellute/spotify-tui/pull/650) ## [0.22.0] - 2020-10-05 From d8d953858fb49796af9b846c0dac15b910b39ad5 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Wed, 6 Jan 2021 10:22:59 +0000 Subject: [PATCH 231/311] Prepare release 0.23.0 --- CHANGELOG.md | 17 ++++++++++++----- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c5c7b27..d3a8ec1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,17 +2,24 @@ ## [Unreleased] -- Implement next/previous page behavior for the Artists table [#604](https://github.com/Rigellute/spotify-tui/pull/604) +## [0.23.0] - 2021-01-06 + +### Fixed + - Fix app crash when pressing Enter before a screen has loaded [#599](https://github.com/Rigellute/spotify-tui/pull/599) -- Show saved albums when getting an artist [#612](https://github.com/Rigellute/spotify-tui/pull/612) -- Transfer playback when changing device [#408](https://github.com/Rigellute/spotify-tui/pull/408) - Make layout more responsive to large/small screens [#502](https://github.com/Rigellute/spotify-tui/pull/502) -- Search using Spotify share URLs and URIs like the desktop client [#623](https://github.com/Rigellute/spotify-tui/pull/623) - Fix use of incorrect playlist index when playing from an associated track table [#632](https://github.com/Rigellute/spotify-tui/pull/632) - Fix flickering help menu in small screens [#638](https://github.com/Rigellute/spotify-tui/pull/638) - Optimize seek [#640](https://github.com/Rigellute/spotify-tui/pull/640) -- Make the liked icon configurable [#659](https://github.com/Rigellute/spotify-tui/pull/659) - Fix centering of basic_view [#664](https://github.com/Rigellute/spotify-tui/pull/664) + +### Added + +- Implement next/previous page behavior for the Artists table [#604](https://github.com/Rigellute/spotify-tui/pull/604) +- Show saved albums when getting an artist [#612](https://github.com/Rigellute/spotify-tui/pull/612) +- Transfer playback when changing device [#408](https://github.com/Rigellute/spotify-tui/pull/408) +- Search using Spotify share URLs and URIs like the desktop client [#623](https://github.com/Rigellute/spotify-tui/pull/623) +- Make the liked icon configurable [#659](https://github.com/Rigellute/spotify-tui/pull/659) - Add CLI for controlling Spotify [#645](https://github.com/Rigellute/spotify-tui/pull/645) - Implement Podcasts Library page [#650](https://github.com/Rigellute/spotify-tui/pull/650) diff --git a/Cargo.lock b/Cargo.lock index 0005d84e..0e764c6e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1694,7 +1694,7 @@ dependencies = [ [[package]] name = "spotify-tui" -version = "0.22.0" +version = "0.23.0" dependencies = [ "anyhow", "backtrace", diff --git a/Cargo.toml b/Cargo.toml index 8b8036ac..fe3f18cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ documentation = "https://github.com/Rigellute/spotify-tui" repository = "https://github.com/Rigellute/spotify-tui" keywords = ["spotify", "tui", "cli", "terminal"] categories = ["command-line-utilities"] -version = "0.22.0" +version = "0.23.0" authors = ["Alexander Keliris "] edition = "2018" license = "MIT OR Apache-2.0" From 74cdb771de2b1779fea1cba58aa8f5e2d4ecd96a Mon Sep 17 00:00:00 2001 From: Finn Hediger Date: Wed, 6 Jan 2021 11:44:01 +0100 Subject: [PATCH 232/311] Add some short examples + inform the user about the cli in the README (#690) --- README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f84158af..a50797a2 100644 --- a/README.md +++ b/README.md @@ -191,7 +191,24 @@ You can edit the config at anytime at `${HOME}/.config/spotify-tui/client.yml`. The binary is named `spt`. -When running `spotify-tui` press `?` to bring up a help menu that shows currently implemented key events and their actions. +Running `spt` with no arguments will bring up the UI. Press `?` to bring up a help menu that shows currently implemented key events and their actions. +There is also a CLI that is able to do most of the stuff the UI does. Use `spt --help` to learn more. + +Here are some example to get you excited. +``` +spt --completions zsh # Prints shell completions for zsh to stdout (bash, power-shell and more are supported) + +spt play --name "Your Playlist" --playlist --random # Plays a random song from "Your Playlist" +spt play --name "A cool song" --track # Plays 'A cool song' + +spt playback --like --shuffle # Likes the current song and toggles shuffle mode +spt playback --toggle # Plays/pauses the current playback + +spt list --liked --limit 50 # See your liked songs (50 is the max limit) + +# Looks for 'An even cooler song' and gives you the '{name} from {album}' of up to 30 matches +spt search "An even cooler song" --tracks --format "%t from %b" --limit 30 +``` # Configuration @@ -230,6 +247,7 @@ behavior: show_loading_indicator: true # Determines the text icon to display next to "liked" Spotify items, such as # liked songs and albums, or followed artists. Can be any length string. + # These icons require a patched nerd font. liked_icon: " " shuffle_icon: "咽" repeat_track_icon: "ο₯—" From 5bf52706cd8eda3b85125e480f59183b27b906f2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 6 Jan 2021 10:56:43 +0000 Subject: [PATCH 233/311] Bump serde from 1.0.117 to 1.0.118 (#675) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.117 to 1.0.118. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.117...v1.0.118) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0e764c6e..93e11a57 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1594,18 +1594,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.117" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" +checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.117" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" +checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" dependencies = [ "proc-macro2 1.0.19", "quote 1.0.7", From 03046afc86cdde46f5f72af5cd9f263979675460 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 6 Jan 2021 10:57:08 +0000 Subject: [PATCH 234/311] Bump tokio from 0.2.23 to 0.2.24 (#678) Bumps [tokio](https://github.com/tokio-rs/tokio) from 0.2.23 to 0.2.24. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/commits) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93e11a57..23d2f65a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1837,9 +1837,9 @@ checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" [[package]] name = "tokio" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6d7ad61edd59bfcc7e80dababf0f4aed2e6d5e0ba1659356ae889752dfc12ff" +checksum = "099837d3464c16a808060bb3f02263b412f6fafcb5d01c533d309985fbeebe48" dependencies = [ "bytes 0.5.6", "fnv", From eb11470e3c67429cc342969387fc8ad3dac02637 Mon Sep 17 00:00:00 2001 From: Finn Hediger Date: Wed, 6 Jan 2021 17:50:04 +0100 Subject: [PATCH 235/311] Fix url to share the current album/show (#688) --- src/app.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.rs b/src/app.rs index 7c001252..88c6e483 100644 --- a/src/app.rs +++ b/src/app.rs @@ -692,7 +692,7 @@ impl App { PlayingItem::Track(track) => { if let Err(e) = clipboard.set_contents(format!( "https://open.spotify.com/album/{}", - track.id.to_owned().unwrap_or_default() + track.album.id.to_owned().unwrap_or_default() )) { self.handle_error(anyhow!("failed to set clipboard content: {}", e)); } From c0387a06c88597774974798f2348a87687aae24f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Art=C3=BAr=20Kov=C3=A1cs?= Date: Fri, 8 Jan 2021 11:16:53 +0100 Subject: [PATCH 236/311] Replace `clipboard` with `arboard` (#691) --- Cargo.lock | 235 +++++++++++++++++++++++++++++++++++++++++++++-------- Cargo.toml | 2 +- src/app.rs | 18 ++-- 3 files changed, 211 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 23d2f65a..32ad9d55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,6 +15,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "aho-corasick" version = "0.7.13" @@ -39,6 +45,26 @@ version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee67c11feeac938fae061b232e38e0b6d94f97a9df10e6271319325ac4c56a86" +[[package]] +name = "arboard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85149eb4159516fbc261f362153822672e4bdb5b3accc863a5777627c6d9fe72" +dependencies = [ + "clipboard-win", + "core-graphics", + "image", + "lazy_static", + "libc", + "objc", + "objc-foundation", + "objc_id", + "scopeguard", + "thiserror", + "winapi 0.3.9", + "xcb", +] + [[package]] name = "arc-swap" version = "0.4.7" @@ -89,7 +115,7 @@ dependencies = [ "addr2line", "cfg-if 1.0.0", "libc", - "miniz_oxide", + "miniz_oxide 0.4.3", "object", "rustc-demangle", ] @@ -144,6 +170,12 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" +[[package]] +name = "bytemuck" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41aa2ec95ca3b5c54cf73c91acf06d24f4495d5f1b1c12506ae3483d646177ac" + [[package]] name = "byteorder" version = "1.3.4" @@ -218,25 +250,14 @@ dependencies = [ "vec_map", ] -[[package]] -name = "clipboard" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a904646c0340239dcf7c51677b33928bf24fdf424b79a57909c0109075b2e7" -dependencies = [ - "clipboard-win", - "objc", - "objc-foundation", - "objc_id", - "x11-clipboard", -] - [[package]] name = "clipboard-win" -version = "2.2.0" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a093d6fed558e5fe24c3dfc85a68bb68f1c824f440d3ba5aca189e2998786b" +checksum = "5123c6b97286809fea9e38d2c9bf530edbcb9fc0d8f8272c28b0c95f067fa92d" dependencies = [ + "error-code", + "str-buf", "winapi 0.3.9", ] @@ -258,6 +279,12 @@ dependencies = [ "bitflags", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -270,7 +297,17 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" dependencies = [ - "core-foundation-sys", + "core-foundation-sys 0.7.0", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" +dependencies = [ + "core-foundation-sys 0.8.2", "libc", ] @@ -280,6 +317,33 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" +[[package]] +name = "core-foundation-sys" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" + +[[package]] +name = "core-graphics" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52a67c4378cf203eace8fb6567847eb641fd6ff933c1145a115c6ee820ebb978" +dependencies = [ + "bitflags", + "core-foundation 0.9.1", + "foreign-types", + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "crossbeam-utils" version = "0.7.2" @@ -351,6 +415,16 @@ dependencies = [ "syn 0.15.44", ] +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + [[package]] name = "derive_builder" version = "0.7.2" @@ -441,6 +515,16 @@ dependencies = [ "termcolor", ] +[[package]] +name = "error-code" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49c94f66f2d2c5ee8685039e458b4e6c9f13af7c28736baf10ce42966a5ab52" +dependencies = [ + "libc", + "str-buf", +] + [[package]] name = "failure" version = "0.1.8" @@ -756,6 +840,22 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "image" +version = "0.23.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ce04077ead78e39ae8610ad26216aed811996b043d47beed5090db674f9e9b5" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "num-iter", + "num-rational", + "num-traits", + "png", + "tiff", +] + [[package]] name = "indexmap" version = "1.5.0" @@ -799,6 +899,15 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" +[[package]] +name = "jpeg-decoder" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc797adac5f083b8ff0ca6f6294a999393d76e197c36488e2ef732c4715f6fa3" +dependencies = [ + "byteorder", +] + [[package]] name = "js-sys" version = "0.3.42" @@ -893,11 +1002,21 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.4.0" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" dependencies = [ "adler", + "autocfg 1.0.0", ] [[package]] @@ -1026,6 +1145,28 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg 1.0.0", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +dependencies = [ + "autocfg 1.0.0", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.12" @@ -1195,6 +1336,18 @@ version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +dependencies = [ + "bitflags", + "crc32fast", + "deflate", + "miniz_oxide 0.3.7", +] + [[package]] name = "ppv-lite86" version = "0.2.8" @@ -1576,8 +1729,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535" dependencies = [ "bitflags", - "core-foundation", - "core-foundation-sys", + "core-foundation 0.7.0", + "core-foundation-sys 0.7.0", "libc", "security-framework-sys", ] @@ -1588,7 +1741,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405" dependencies = [ - "core-foundation-sys", + "core-foundation-sys 0.7.0", "libc", ] @@ -1697,9 +1850,9 @@ name = "spotify-tui" version = "0.23.0" dependencies = [ "anyhow", + "arboard", "backtrace", "clap", - "clipboard", "crossterm", "dirs", "rand 0.7.3", @@ -1712,6 +1865,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "str-buf" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d44a3643b4ff9caf57abcee9c2c621d6c03d9135e0d8b589bd9afb5992cb176a" + [[package]] name = "strsim" version = "0.7.0" @@ -1819,6 +1978,17 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "tiff" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437" +dependencies = [ + "jpeg-decoder", + "miniz_oxide 0.4.3", + "weezl", +] + [[package]] name = "time" version = "0.1.43" @@ -2148,6 +2318,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "weezl" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2bb9fc8309084dd7cd651336673844c1d47f8ef6d2091ec160b27f5c4aa277" + [[package]] name = "widestring" version = "0.4.2" @@ -2216,20 +2392,11 @@ dependencies = [ "winapi-build", ] -[[package]] -name = "x11-clipboard" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89bd49c06c9eb5d98e6ba6536cf64ac9f7ee3a009b2f53996d405b3944f6bcea" -dependencies = [ - "xcb", -] - [[package]] name = "xcb" -version = "0.8.2" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de" +checksum = "62056f63138b39116f82a540c983cc11f1c90cd70b3d492a70c25eaa50bd22a6" dependencies = [ "libc", "log", diff --git a/Cargo.toml b/Cargo.toml index fe3f18cd..bb8037d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ dirs = "3.0.1" clap = "2.33.3" unicode-width = "0.1.8" backtrace = "0.3.55" -clipboard = "0.5.0" +arboard = "1.1.0" crossterm = "0.18" tokio = { version = "0.2", features = ["full"] } rand = "0.7.3" diff --git a/src/app.rs b/src/app.rs index 88c6e483..ef353853 100644 --- a/src/app.rs +++ b/src/app.rs @@ -27,7 +27,7 @@ use std::{ }; use tui::layout::Rect; -use clipboard::{ClipboardContext, ClipboardProvider}; +use arboard::Clipboard; pub const LIBRARY_OPTIONS: [&str; 6] = [ "Made For You", @@ -298,8 +298,8 @@ pub struct App { pub album_list_index: usize, pub made_for_you_index: usize, pub artists_list_index: usize, + pub clipboard: Option, pub shows_list_index: usize, - pub clipboard_context: Option, pub help_docs_size: u32, pub help_menu_page: u32, pub help_menu_max_lines: u32, @@ -382,7 +382,7 @@ impl Default for App { episode_table: Default::default(), user: None, instant_since_last_current_playback_poll: Instant::now(), - clipboard_context: clipboard::ClipboardProvider::new().ok(), + clipboard: Clipboard::new().ok(), help_docs_size: 0, help_menu_page: 0, help_menu_max_lines: 0, @@ -648,7 +648,7 @@ impl App { } pub fn copy_song_url(&mut self) { - let clipboard = match &mut self.clipboard_context { + let clipboard = match &mut self.clipboard { Some(ctx) => ctx, None => return, }; @@ -659,7 +659,7 @@ impl App { { match item { PlayingItem::Track(track) => { - if let Err(e) = clipboard.set_contents(format!( + if let Err(e) = clipboard.set_text(format!( "https://open.spotify.com/track/{}", track.id.to_owned().unwrap_or_default() )) { @@ -667,7 +667,7 @@ impl App { } } PlayingItem::Episode(episode) => { - if let Err(e) = clipboard.set_contents(format!( + if let Err(e) = clipboard.set_text(format!( "https://open.spotify.com/episode/{}", episode.id.to_owned() )) { @@ -679,7 +679,7 @@ impl App { } pub fn copy_album_url(&mut self) { - let clipboard = match &mut self.clipboard_context { + let clipboard = match &mut self.clipboard { Some(ctx) => ctx, None => return, }; @@ -690,7 +690,7 @@ impl App { { match item { PlayingItem::Track(track) => { - if let Err(e) = clipboard.set_contents(format!( + if let Err(e) = clipboard.set_text(format!( "https://open.spotify.com/album/{}", track.album.id.to_owned().unwrap_or_default() )) { @@ -698,7 +698,7 @@ impl App { } } PlayingItem::Episode(episode) => { - if let Err(e) = clipboard.set_contents(format!( + if let Err(e) = clipboard.set_text(format!( "https://open.spotify.com/show/{}", episode.show.id.to_owned() )) { From 65ee9c219c70dd5dae9e879ad7519fcee0a14c75 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 8 Jan 2021 10:17:27 +0000 Subject: [PATCH 237/311] docs: add ArturKovacs as a contributor (#699) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++ README.md | 158 ++++++++++++++++++++++---------------------- 2 files changed, 89 insertions(+), 78 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index ef9ecf59..1cab52e6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -706,6 +706,15 @@ "contributions": [ "infra" ] + }, + { + "login": "ArturKovacs", + "name": "ArtΓΊr KovΓ‘cs", + "avatar_url": "https://avatars3.githubusercontent.com/u/8320264?v=4", + "profile": "https://github.com/ArturKovacs", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index a50797a2..580f5eac 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-76-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-77-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -333,107 +333,109 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - + + + + + + +

Alexander Keliris

πŸ’» πŸ“– 🎨 πŸ“ πŸ€” πŸš‡ 🚧 πŸ“¦ πŸ‘€

Mickael Marques

πŸ’΅

Grzegorz Koperwas

πŸ“–

Austin Gassert

πŸ’»

Calen Robinette

πŸ’»

M*C*O

πŸš‡

Andrew Chin

πŸ’»

Alexander Keliris

πŸ’» πŸ“– 🎨 πŸ“ πŸ€” πŸš‡ 🚧 πŸ“¦ πŸ‘€

Mickael Marques

πŸ’΅

Grzegorz Koperwas

πŸ“–

Austin Gassert

πŸ’»

Calen Robinette

πŸ’»

M*C*O

πŸš‡

Andrew Chin

πŸ’»

Sam Naser

πŸ’»

Micha

πŸ’»

neriglissar

πŸ’»

Timon

πŸ’»

echoSayonara

πŸ’»

D-Nice

πŸ“– πŸš‡

Grzegorz Pawlik

πŸ’»

Sam Naser

πŸ’»

Micha

πŸ’»

neriglissar

πŸ’»

Timon

πŸ’»

echoSayonara

πŸ’»

D-Nice

πŸ“– πŸš‡

Grzegorz Pawlik

πŸ’»

Lennart Bernhardt

πŸ’»

Arnaud Lefebvre

πŸ’»

tem1029

πŸ’»

Peter K. Moss

πŸ’»

Geoff Shannon

πŸ’»

Zachary Mayhew

πŸ’»

jfaltis

πŸ’»

Lennart Bernhardt

πŸ’»

Arnaud Lefebvre

πŸ’»

tem1029

πŸ’»

Peter K. Moss

πŸ’»

Geoff Shannon

πŸ’»

Zachary Mayhew

πŸ’»

jfaltis

πŸ’»

Marcel Schramm

πŸ“–

Fangyi Zhou

πŸ’»

Max

πŸ’»

Sven van der Vlist

πŸ’»

jacobchrismarsh

πŸ’»

Nils Rauch

πŸ’»

Nick Stockton

πŸ’» πŸ› 🚧 πŸ’¬ πŸ“–

Marcel Schramm

πŸ“–

Fangyi Zhou

πŸ’»

Max

πŸ’»

Sven van der Vlist

πŸ’»

jacobchrismarsh

πŸ’»

Nils Rauch

πŸ’»

Nick Stockton

πŸ’» πŸ› 🚧 πŸ’¬ πŸ“–

Stuart Hinson

πŸ’»

Sam Calvert

πŸ’» πŸ“–

Jeroen Wijenbergh

πŸ“–

Kimberley Cook

πŸ“–

Audrey Baxter

πŸ’»

Norman

πŸ“–

Peter Maatman

πŸ’»

Stuart Hinson

πŸ’»

Sam Calvert

πŸ’» πŸ“–

Jeroen Wijenbergh

πŸ“–

Kimberley Cook

πŸ“–

Audrey Baxter

πŸ’»

Norman

πŸ“–

Peter Maatman

πŸ’»

AlexandreS

πŸ’»

Finn Vos

πŸ’»

Carlos Hernandez

πŸ“¦

Pedro Alves

πŸ’»

jtagcat

πŸ“–

Benjamin Kitor

πŸ’»

AleΕ‘ Najmann

πŸ“– πŸ“¦

AlexandreS

πŸ’»

Finn Vos

πŸ’»

Carlos Hernandez

πŸ“¦

Pedro Alves

πŸ’»

jtagcat

πŸ“–

Benjamin Kitor

πŸ’»

AleΕ‘ Najmann

πŸ“– πŸ“¦

Jeremy Stucki

πŸ’»

(´⌣`ΚƒΖͺ)

πŸ’»

Artem Polishchuk

πŸ“¦

Chris Sosnin

πŸ’»

Ben Buhse

πŸ“–

Sean Li

πŸ’»

TimotheeGerber

πŸ’» πŸ“–

Jeremy Stucki

πŸ’»

(´⌣`ΚƒΖͺ)

πŸ’»

Artem Polishchuk

πŸ“¦

Chris Sosnin

πŸ’»

Ben Buhse

πŸ“–

Sean Li

πŸ’»

TimotheeGerber

πŸ’» πŸ“–

Ferdinand Ratajczak

πŸ’»

Sheel Choksi

πŸ’»

Michael Hellwig

πŸ“–

Oliver Daniel

πŸ’»

Drew Fisher

πŸ’»

ncoder-1

πŸ“–

Macguire Rintoul

πŸ“–

Ferdinand Ratajczak

πŸ’»

Sheel Choksi

πŸ’»

Michael Hellwig

πŸ“–

Oliver Daniel

πŸ’»

Drew Fisher

πŸ’»

ncoder-1

πŸ“–

Macguire Rintoul

πŸ“–

Ricardo Holguin

πŸ’»

Keisuke Toyota

πŸ’»

Craig Astill

πŸ’»

Onielfa

πŸ’»

usrme

πŸ“–

Sergey A.

πŸ’»

Hideyuki Okada

πŸ’»

Ricardo Holguin

πŸ’»

Keisuke Toyota

πŸ’»

Craig Astill

πŸ’»

Onielfa

πŸ’»

usrme

πŸ“–

Sergey A.

πŸ’»

Hideyuki Okada

πŸ’»

kepae

πŸ’» πŸ“–

Γ‰rico Nogueira Rolim

πŸ’»

Alexander Meinhardt Scheurer

πŸ’»

OndΕ™ej KinΕ‘t

πŸ’»

Kryan90

πŸ“–

n-ivanov

πŸ’»

bi1yeu

πŸ’» πŸ“–

kepae

πŸ’» πŸ“–

Γ‰rico Nogueira Rolim

πŸ’»

Alexander Meinhardt Scheurer

πŸ’»

OndΕ™ej KinΕ‘t

πŸ’»

Kryan90

πŸ“–

n-ivanov

πŸ’»

bi1yeu

πŸ’» πŸ“–

May

πŸ’»

Bruno A. MuciΓ±o

πŸ’»

Finn Hediger

πŸ’»

dp304

πŸ’»

Marco Micera

πŸ“–

Marco Ieni

πŸš‡

May

πŸ’»

Bruno A. MuciΓ±o

πŸ’»

Finn Hediger

πŸ’»

dp304

πŸ’»

Marco Micera

πŸ“–

Marco Ieni

πŸš‡

ArtΓΊr KovΓ‘cs

πŸ’»
- + + This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! From 6d7ab43129d83a5b88509e16e9fadc399441584f Mon Sep 17 00:00:00 2001 From: Finn Hediger Date: Fri, 8 Jan 2021 11:19:29 +0100 Subject: [PATCH 238/311] Add ability to seek from the CLI (#692) * Add new `--seek` to jump forward, backwards To jump forward, prepend a + to the number of seconds. To jump backwards, prepend a -. To jump to an absolute position, do not prepend anything. * Add new `%r` to the format options to display the current progress Utilised by the `--seek` option. * Add a longer help to the `--seek` option * Fix formatting * Add checks to prevent underflows + check to jump to next song if new duration is bigger than the duration of the song * Fix formatting * Fix clippy errors * Add more comments --- src/cli/clap.rs | 13 +++++++++ src/cli/cli_app.rs | 72 ++++++++++++++++++++++++++++++++++++++++++++-- src/cli/handle.rs | 3 ++ src/cli/util.rs | 6 ++++ 4 files changed, 92 insertions(+), 2 deletions(-) diff --git a/src/cli/clap.rs b/src/cli/clap.rs index f7b7483c..200e39de 100644 --- a/src/cli/clap.rs +++ b/src/cli/clap.rs @@ -48,6 +48,7 @@ can be used together format_arg() .default_value("%f %s %t - %a") .default_value_ifs(&[ + ("seek", None, "%f %s %t - %a %r"), ("volume", None, "%v% %f %s %t - %a"), ("transfer", None, "%f %s %t - %a on %d"), ]), @@ -119,6 +120,18 @@ jump to the previous song though, so you can use the previous flag twice: `spt p two songs back, you can use `spt pb -ppp` and so on.", ), ) + .arg( + Arg::with_name("seek") + .long("seek") + .takes_value(true) + .value_name("Β±SECONDS") + .allow_hyphen_values(true) + .help("Jumps SECONDS forwards (+) or backwards (-)") + .long_help( + "For example: `spt pb --seek +10` jumps ten second forwards, `spt pb --seek -10` ten \ +seconds backwards and `spt pb --seek 10` to the tenth second of the track.", + ), + ) .arg( Arg::with_name("volume") .short("v") diff --git a/src/cli/cli_app.rs b/src/cli/cli_app.rs index 13dcbb80..543dfdfa 100644 --- a/src/cli/cli_app.rs +++ b/src/cli/cli_app.rs @@ -271,6 +271,68 @@ impl<'a> CliApp<'a> { } } + pub async fn seek(&mut self, seconds_str: String) -> Result<()> { + let seconds = match seconds_str.parse::() { + Ok(s) => s.abs() as u32, + Err(_) => return Err(anyhow!("failed to convert seconds to i32")), + }; + + let (current_pos, duration) = { + self + .net + .handle_network_event(IoEvent::GetCurrentPlayback) + .await; + let app = self.net.app.lock().await; + if let Some(CurrentlyPlaybackContext { + progress_ms: Some(ms), + item: Some(item), + .. + }) = &app.current_playback_context + { + let duration = match item { + PlayingItem::Track(track) => track.duration_ms, + PlayingItem::Episode(episode) => episode.duration_ms, + }; + + (*ms as u32, duration) + } else { + return Err(anyhow!("no context available")); + } + }; + + // Convert secs to ms + let ms = seconds * 1000; + // Calculate new positon + let position_to_seek = if seconds_str.starts_with('+') { + current_pos + ms + } else if seconds_str.starts_with('-') { + // Jump to the beginning if the position_to_seek would be + // negative, must be checked before the calculation to avoid + // an 'underflow' + if ms > current_pos { + 0u32 + } else { + current_pos - ms + } + } else { + // Absolute value of the track + seconds * 1000 + }; + + // Check if position_to_seek is greater than duration (next track) + if position_to_seek > duration { + self.jump(&JumpDirection::Next).await; + } else { + // This seeks to a position in the current song + self + .net + .handle_network_event(IoEvent::Seek(position_to_seek)) + .await; + } + + Ok(()) + } + // spt playback --like / --shuffle / --repeat pub async fn mark(&mut self, flag: Flag) -> Result<()> { let c = { @@ -339,7 +401,10 @@ impl<'a> CliApp<'a> { let mut hs = match playing_item { PlayingItem::Track(track) => { let id = track.id.clone().unwrap_or_default(); - let mut hs = Format::from_type(FormatType::Track(Box::new(track))); + let mut hs = Format::from_type(FormatType::Track(Box::new(track.clone()))); + if let Some(ms) = context.progress_ms { + hs.push(Format::Position((ms, track.duration_ms))) + } hs.push(Format::Flags(( context.repeat_state, context.shuffle_state, @@ -348,7 +413,10 @@ impl<'a> CliApp<'a> { hs } PlayingItem::Episode(episode) => { - let mut hs = Format::from_type(FormatType::Episode(Box::new(episode))); + let mut hs = Format::from_type(FormatType::Episode(Box::new(episode.clone()))); + if let Some(ms) = context.progress_ms { + hs.push(Format::Position((ms, episode.duration_ms))) + } hs.push(Format::Flags(( context.repeat_state, context.shuffle_state, diff --git a/src/cli/handle.rs b/src/cli/handle.rs index 53bbb386..1e964a87 100644 --- a/src/cli/handle.rs +++ b/src/cli/handle.rs @@ -82,6 +82,9 @@ pub async fn handle_matches( if let Some(vol) = matches.value_of("volume") { cli.volume(vol.to_string()).await?; } + if let Some(secs) = matches.value_of("seek") { + cli.seek(secs.to_string()).await?; + } // Print out the status if no errors were found cli.get_status(format.to_string()).await diff --git a/src/cli/util.rs b/src/cli/util.rs index 71304c7d..22e6f177 100644 --- a/src/cli/util.rs +++ b/src/cli/util.rs @@ -144,6 +144,8 @@ pub enum Format { Uri(String), Device(String), Volume(u32), + // Current position, duration + Position((u32, u32)), // This is a bit long, should it be splitted up? Flags((RepeatState, bool, bool)), Playing(bool), @@ -206,6 +208,9 @@ impl Format { // Because this match statements // needs to return a &String, I have to do it this way Self::Volume(s) => s.to_string(), + Self::Position((curr, duration)) => { + crate::ui::util::display_track_progress(*curr as u128, *duration) + } Self::Flags((r, s, l)) => { let like = if *l { conf.behavior.liked_icon @@ -252,6 +257,7 @@ impl Format { Self::Uri(_) => "%u", Self::Device(_) => "%d", Self::Volume(_) => "%v", + Self::Position(_) => "%r", Self::Flags(_) => "%f", Self::Playing(_) => "%s", } From 1060facfad47831261051c77a4dd6008f8875fb8 Mon Sep 17 00:00:00 2001 From: Antony Kellermann Date: Wed, 27 Jan 2021 03:35:25 -0500 Subject: [PATCH 239/311] Handle invalid Client ID/Secret (#668) * Implemented client id/secret validation * Abstract out common function * Fix * Implemented error * Address clippy --- src/config.rs | 58 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/src/config.rs b/src/config.rs index 849d9160..88105e3c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,5 @@ use super::banner::BANNER; -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Error, Result}; use serde::{Deserialize, Serialize}; use std::{ fs, @@ -127,14 +127,8 @@ impl ClientConfig { number += 1; } - // TODO: Handle empty input? - let mut client_id = String::new(); - println!("\nEnter your Client ID: "); - stdin().read_line(&mut client_id)?; - - let mut client_secret = String::new(); - println!("\nEnter your Client Secret: "); - stdin().read_line(&mut client_secret)?; + let client_id = ClientConfig::get_client_key_from_input("Client ID")?; + let client_secret = ClientConfig::get_client_key_from_input("Client Secret")?; let mut port = String::new(); println!("\nEnter port of redirect uri (default {}): ", DEFAULT_PORT); @@ -142,8 +136,8 @@ impl ClientConfig { let port = port.trim().parse::().unwrap_or(DEFAULT_PORT); let config_yml = ClientConfig { - client_id: client_id.trim().to_string(), - client_secret: client_secret.trim().to_string(), + client_id, + client_secret, device_id: None, port: Some(port), }; @@ -161,4 +155,46 @@ impl ClientConfig { Ok(()) } } + + fn get_client_key_from_input(type_label: &'static str) -> Result { + let mut client_key = String::new(); + const MAX_RETRIES: u8 = 5; + let mut num_retries = 0; + loop { + println!("\nEnter your {}: ", type_label); + stdin().read_line(&mut client_key)?; + client_key = client_key.trim().to_string(); + match ClientConfig::validate_client_key(&client_key) { + Ok(_) => return Ok(client_key), + Err(error_string) => { + println!("{}", error_string); + client_key.clear(); + num_retries += 1; + if num_retries == MAX_RETRIES { + return Err(Error::from(std::io::Error::new( + std::io::ErrorKind::Other, + format!("Maximum retries ({}) exceeded.", MAX_RETRIES), + ))); + } + } + }; + } + } + + fn validate_client_key(key: &str) -> Result<()> { + const EXPECTED_LEN: usize = 32; + if key.len() != EXPECTED_LEN { + Err(Error::from(std::io::Error::new( + std::io::ErrorKind::InvalidInput, + format!("invalid length: {} (must be {})", key.len(), EXPECTED_LEN,), + ))) + } else if !key.chars().all(|c| c.is_digit(16)) { + Err(Error::from(std::io::Error::new( + std::io::ErrorKind::InvalidInput, + "invalid character found (must be hex digits)", + ))) + } else { + Ok(()) + } + } } From 4553b3fd70de80aff694e22f6d1e575a0b7ade8c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 27 Jan 2021 08:36:18 +0000 Subject: [PATCH 240/311] docs: add aokellermann as a contributor (#722) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 1cab52e6..28586c10 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -715,6 +715,15 @@ "contributions": [ "code" ] + }, + { + "login": "aokellermann", + "name": "Antony Kellermann", + "avatar_url": "https://avatars.githubusercontent.com/u/26678747?v=4", + "profile": "https://github.com/aokellermann", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 580f5eac..cdd8afe6 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-77-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-78-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -431,6 +431,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Marco Ieni

πŸš‡
ArtΓΊr KovΓ‘cs

πŸ’» + +
Antony Kellermann

πŸ’» + From e471bb73f36f728b3b7e332aa9f1f6dc69a05be4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 27 Jan 2021 08:43:30 +0000 Subject: [PATCH 241/311] Bump anyhow from 1.0.37 to 1.0.38 (#700) Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.37 to 1.0.38. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.37...1.0.38) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 32ad9d55..3eb179a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,9 +41,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee67c11feeac938fae061b232e38e0b6d94f97a9df10e6271319325ac4c56a86" +checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" [[package]] name = "arboard" diff --git a/Cargo.toml b/Cargo.toml index bb8037d4..0f294a97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ arboard = "1.1.0" crossterm = "0.18" tokio = { version = "0.2", features = ["full"] } rand = "0.7.3" -anyhow = "1.0.37" +anyhow = "1.0.38" [[bin]] bench = false From a3e214cac84fe36dd2ba62b4d627ced972dda390 Mon Sep 17 00:00:00 2001 From: Rasmus Pedersen Date: Wed, 27 Jan 2021 09:47:38 +0100 Subject: [PATCH 242/311] Fix default liked, shuffle, etc. icons to more recognizable symbols (#702) --- README.md | 12 ++++++------ src/user_config.rs | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index cdd8afe6..a5d77fb4 100644 --- a/README.md +++ b/README.md @@ -248,12 +248,12 @@ behavior: # Determines the text icon to display next to "liked" Spotify items, such as # liked songs and albums, or followed artists. Can be any length string. # These icons require a patched nerd font. - liked_icon: " " - shuffle_icon: "咽" - repeat_track_icon: "ο₯—" - repeat_context_icon: "ο₯•" - playing_icon: "" - paused_icon: "ο££" + liked_icon: β™₯ + shuffle_icon: πŸ”€ + repeat_track_icon: πŸ”‚ + repeat_context_icon: πŸ” + playing_icon: β–Ά + paused_icon: ⏸ keybindings: # Key stroke can be used if it only uses two keys: diff --git a/src/user_config.rs b/src/user_config.rs index f348e3fd..3873457d 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -288,12 +288,12 @@ impl UserConfig { tick_rate_milliseconds: 250, enable_text_emphasis: true, show_loading_indicator: true, - liked_icon: " ".to_string(), - shuffle_icon: "咽".to_string(), - repeat_track_icon: "ο₯—".to_string(), - repeat_context_icon: "ο₯•".to_string(), - playing_icon: "".to_string(), - paused_icon: "ο££ ".to_string(), + liked_icon: "β™₯".to_string(), + shuffle_icon: "πŸ”€".to_string(), + repeat_track_icon: "πŸ”‚".to_string(), + repeat_context_icon: "πŸ”".to_string(), + playing_icon: "β–Ά".to_string(), + paused_icon: "⏸".to_string(), }, path_to_config: None, } From 80ae64dde3f5d9553aea30ce9b183ae8c74509ff Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 27 Jan 2021 08:48:48 +0000 Subject: [PATCH 243/311] docs: add rasmuspeders1 as a contributor (#723) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 28586c10..eb124951 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -724,6 +724,15 @@ "contributions": [ "code" ] + }, + { + "login": "rasmuspeders1", + "name": "Rasmus Pedersen", + "avatar_url": "https://avatars.githubusercontent.com/u/1898960?v=4", + "profile": "https://github.com/rasmuspeders1", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index a5d77fb4..247f5885 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-78-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-79-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -433,6 +433,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Antony Kellermann

πŸ’» +
Rasmus Pedersen

πŸ’» From b6ba25699939ebfb7ccd86ce735e92fab0c9f166 Mon Sep 17 00:00:00 2001 From: noir-Z <45096516+noir-Z@users.noreply.github.com> Date: Wed, 27 Jan 2021 09:54:46 +0100 Subject: [PATCH 244/311] Update README.md (#712) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 247f5885..7d8075f8 100644 --- a/README.md +++ b/README.md @@ -231,6 +231,7 @@ theme: inactive: Gray # borders of inactive panes playbar_background: Black # background of progress bar playbar_progress: LightCyan # filled-in part of the progress bar + playbar_progress_text: Cyan # song length and time played/left indicator in the progress bar playbar_text: White # artist name in player pane selected: LightCyan # a) selected pane border, b) hovered item in list, & c) track title in player text: "255, 255, 255" # text in panes From 5cc68ec801ab7690295b7211f573144ef2bd5c8f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 27 Jan 2021 08:55:06 +0000 Subject: [PATCH 245/311] docs: add noir-Z as a contributor (#724) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index eb124951..bb214d45 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -733,6 +733,15 @@ "contributions": [ "code" ] + }, + { + "login": "noir-Z", + "name": "noir-Z", + "avatar_url": "https://avatars.githubusercontent.com/u/45096516?v=4", + "profile": "https://github.com/noir-Z", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 7d8075f8..1ac8db0b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-79-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-80-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -435,6 +435,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Antony Kellermann

πŸ’»
Rasmus Pedersen

πŸ’» +
noir-Z

πŸ“– From b33034a10de4504d64eca95659316e2d4ab57322 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 27 Jan 2021 08:55:34 +0000 Subject: [PATCH 246/311] Bump backtrace from 0.3.55 to 0.3.56 (#716) Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.55 to 0.3.56. - [Release notes](https://github.com/rust-lang/backtrace-rs/releases) - [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.55...0.3.56) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 16 ++++++++-------- Cargo.toml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3eb179a5..fe747d30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,9 +2,9 @@ # It is not intended for manual editing. [[package]] name = "addr2line" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423" +checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7" dependencies = [ "gimli", ] @@ -108,9 +108,9 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.55" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598" +checksum = "9d117600f438b1707d4e4ae15d3595657288f8235a0eb593e80ecc98ab34e1bc" dependencies = [ "addr2line", "cfg-if 1.0.0", @@ -935,9 +935,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.73" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9" +checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929" [[package]] name = "linked-hash-map" @@ -1217,9 +1217,9 @@ dependencies = [ [[package]] name = "object" -version = "0.22.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" +checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4" [[package]] name = "once_cell" diff --git a/Cargo.toml b/Cargo.toml index 0f294a97..030cec73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ serde_yaml = "0.8" dirs = "3.0.1" clap = "2.33.3" unicode-width = "0.1.8" -backtrace = "0.3.55" +backtrace = "0.3.56" arboard = "1.1.0" crossterm = "0.18" tokio = { version = "0.2", features = ["full"] } From dc5c862ddf7ea0f6c60e8de1f1228fb8cb51dfa7 Mon Sep 17 00:00:00 2001 From: Finn Hediger Date: Wed, 27 Jan 2021 09:58:13 +0100 Subject: [PATCH 247/311] Change `--like` that toggles the state to explicit `--like` and `--dislike` flags (#717) * Change `--like` that toggled to manual `--like` and `--dislike`. * Fix formatting + clippy --- src/cli/clap.rs | 14 ++++++++++++-- src/cli/cli_app.rs | 36 +++++++++++++++++++++++++----------- src/cli/util.rs | 12 ++++++++++-- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/cli/clap.rs b/src/cli/clap.rs index 200e39de..81f6dcee 100644 --- a/src/cli/clap.rs +++ b/src/cli/clap.rs @@ -85,7 +85,12 @@ can be used together .arg( Arg::with_name("like") .long("like") - .help("Likes the current song"), + .help("Likes the current song if possible"), + ) + .arg( + Arg::with_name("dislike") + .long("dislike") + .help("Dislikes the current song if possible"), ) .arg( Arg::with_name("shuffle") @@ -146,9 +151,14 @@ seconds backwards and `spt pb --seek 10` to the tenth second of the track.", .multiple(false) .conflicts_with_all(&["single", "flags", "actions"]), ) + .group( + ArgGroup::with_name("likes") + .args(&["like", "dislike"]) + .multiple(false), + ) .group( ArgGroup::with_name("flags") - .args(&["like", "shuffle", "repeat"]) + .args(&["like", "dislike", "shuffle", "repeat"]) .multiple(true) .conflicts_with_all(&["single", "jumps"]), ) diff --git a/src/cli/cli_app.rs b/src/cli/cli_app.rs index 543dfdfa..c8601f88 100644 --- a/src/cli/cli_app.rs +++ b/src/cli/cli_app.rs @@ -21,13 +21,15 @@ impl<'a> CliApp<'a> { Self { net, config } } - async fn is_a_saved_track(&mut self, id: String) -> bool { + async fn is_a_saved_track(&mut self, id: &str) -> bool { // Update the liked_song_ids_set self .net - .handle_network_event(IoEvent::CurrentUserSavedTracksContains(vec![id.clone()])) + .handle_network_event(IoEvent::CurrentUserSavedTracksContains( + vec![id.to_string()], + )) .await; - self.net.app.lock().await.liked_song_ids_set.contains(&id) + self.net.app.lock().await.liked_song_ids_set.contains(id) } pub fn format_output(&self, mut format: String, values: Vec) -> String { @@ -333,7 +335,7 @@ impl<'a> CliApp<'a> { Ok(()) } - // spt playback --like / --shuffle / --repeat + // spt playback --like / --dislike / --shuffle / --repeat pub async fn mark(&mut self, flag: Flag) -> Result<()> { let c = { let app = self.net.app.lock().await; @@ -344,7 +346,7 @@ impl<'a> CliApp<'a> { }; match flag { - Flag::Like => { + Flag::Like(s) => { // Get the id of the current song let id = match c.item { Some(i) => match i { @@ -352,11 +354,23 @@ impl<'a> CliApp<'a> { PlayingItem::Episode(_) => Err(anyhow!("saving episodes not yet implemented")), }, None => Err(anyhow!("no item playing")), - }; - self - .net - .handle_network_event(IoEvent::ToggleSaveTrack(id?)) - .await; + }?; + + // Want to like but is already liked -> do nothing + // Want to like and is not liked yet -> like + if s && !self.is_a_saved_track(&id).await { + self + .net + .handle_network_event(IoEvent::ToggleSaveTrack(id)) + .await; + // Want to dislike but is already disliked -> do nothing + // Want to dislike and is liked currently -> remove like + } else if !s && self.is_a_saved_track(&id).await { + self + .net + .handle_network_event(IoEvent::ToggleSaveTrack(id)) + .await; + } } Flag::Shuffle => { self @@ -408,7 +422,7 @@ impl<'a> CliApp<'a> { hs.push(Format::Flags(( context.repeat_state, context.shuffle_state, - self.is_a_saved_track(id).await, + self.is_a_saved_track(&id).await, ))); hs } diff --git a/src/cli/util.rs b/src/cli/util.rs index 22e6f177..8aef1a10 100644 --- a/src/cli/util.rs +++ b/src/cli/util.rs @@ -78,7 +78,10 @@ impl Type { // pub enum Flag { - Like, + // Does not get toggled + // * User chooses like -> Flag::Like(true) + // * User chooses dislike -> Flag::Like(false) + Like(bool), Shuffle, Repeat, } @@ -87,9 +90,14 @@ impl Flag { pub fn from_matches(m: &ArgMatches<'_>) -> Vec { // Multiple flags are possible let mut flags = Vec::new(); + + // Only one of these two if m.is_present("like") { - flags.push(Self::Like); + flags.push(Self::Like(true)); + } else if m.is_present("dislike") { + flags.push(Self::Like(false)); } + if m.is_present("shuffle") { flags.push(Self::Shuffle); } From ab431a872ad13fb3c3c3a17b20b2536bf47576b4 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Wed, 27 Jan 2021 08:59:19 +0000 Subject: [PATCH 248/311] Update CHANGELOG --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3a8ec1e..9c09f311 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## [Unreleased] +- Add ability to seek from the CLI [#692](https://github.com/Rigellute/spotify-tui/pull/692) +- Replace `clipboard` with `arboard` [#691](https://github.com/Rigellute/spotify-tui/pull/691) +- Handle invalid Client ID/Secret [#668](https://github.com/Rigellute/spotify-tui/pull/668) +- Implement some episode table functions [#698](https://github.com/Rigellute/spotify-tui/pull/698) +- Fix default liked, shuffle, etc. icons to more recognizable symbols [#702](https://github.com/Rigellute/spotify-tui/pull/702) +- Change `--like` that toggled the liked-state to explicit `--like` and `--dislike` flags [#717](https://github.com/Rigellute/spotify-tui/pull/717) + ## [0.23.0] - 2021-01-06 ### Fixed From 8a9d8d3427984f6da457bcffe881ce18682f7072 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 27 Jan 2021 09:07:05 +0000 Subject: [PATCH 249/311] Bump serde from 1.0.118 to 1.0.123 (#720) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.118 to 1.0.123. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.118...v1.0.123) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 56 +++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fe747d30..398e20f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -541,9 +541,9 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ - "proc-macro2 1.0.19", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.35", + "syn 1.0.60", "synstructure", ] @@ -645,9 +645,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.19", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.35", + "syn 1.0.60", ] [[package]] @@ -1313,9 +1313,9 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7" dependencies = [ - "proc-macro2 1.0.19", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.35", + "syn 1.0.60", ] [[package]] @@ -1377,9 +1377,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.19" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ "unicode-xid 0.2.1", ] @@ -1405,7 +1405,7 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" dependencies = [ - "proc-macro2 1.0.19", + "proc-macro2 1.0.24", ] [[package]] @@ -1747,22 +1747,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.118" +version = "1.0.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" +checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.118" +version = "1.0.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" +checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31" dependencies = [ - "proc-macro2 1.0.19", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.35", + "syn 1.0.60", ] [[package]] @@ -1896,11 +1896,11 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.35" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb7f4c519df8c117855e19dd8cc851e89eb746fe7a73f0157e0d95fdec5369b0" +checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" dependencies = [ - "proc-macro2 1.0.19", + "proc-macro2 1.0.24", "quote 1.0.7", "unicode-xid 0.2.1", ] @@ -1911,9 +1911,9 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" dependencies = [ - "proc-macro2 1.0.19", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.35", + "syn 1.0.60", "unicode-xid 0.2.1", ] @@ -1964,9 +1964,9 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" dependencies = [ - "proc-macro2 1.0.19", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.35", + "syn 1.0.60", ] [[package]] @@ -2035,9 +2035,9 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a" dependencies = [ - "proc-macro2 1.0.19", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.35", + "syn 1.0.60", ] [[package]] @@ -2250,9 +2250,9 @@ dependencies = [ "bumpalo", "lazy_static", "log", - "proc-macro2 1.0.19", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.35", + "syn 1.0.60", "wasm-bindgen-shared", ] @@ -2284,9 +2284,9 @@ version = "0.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf592c807080719d1ff2f245a687cbadb3ed28b2077ed7084b47aba8b691f2c6" dependencies = [ - "proc-macro2 1.0.19", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.35", + "syn 1.0.60", "wasm-bindgen-backend", "wasm-bindgen-shared", ] From 7ef19e69fb58b94898bd024958232e622fa0fd33 Mon Sep 17 00:00:00 2001 From: David Bailey Date: Wed, 3 Feb 2021 18:15:21 +0000 Subject: [PATCH 250/311] Update README.md (#729) --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index 1ac8db0b..b0f8a1e0 100644 --- a/README.md +++ b/README.md @@ -124,11 +124,7 @@ cargo install spotify-tui This method will build the binary from source. -To update, run - -```bash -cargo install spotify-tui --force -``` +To update, run the same command again. #### Note on Linux From 6752411b3f55d47ce36c91423bf2ab18b28bda0b Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 3 Feb 2021 18:16:22 +0000 Subject: [PATCH 251/311] docs: add davidbailey00 as a contributor (#731) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index bb214d45..8b4c0eef 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -742,6 +742,15 @@ "contributions": [ "doc" ] + }, + { + "login": "davidbailey00", + "name": "David Bailey", + "avatar_url": "https://avatars.githubusercontent.com/u/4248177?v=4", + "profile": "https://davidbailey.codes/", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index b0f8a1e0..b8abe49c 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-80-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-81-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -432,6 +432,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Antony Kellermann

πŸ’»
Rasmus Pedersen

πŸ’»
noir-Z

πŸ“– +
David Bailey

πŸ“– From 38c095884919bebc6c592d3662ddd1f9a93131f1 Mon Sep 17 00:00:00 2001 From: Leon G Date: Thu, 4 Feb 2021 09:31:59 +0100 Subject: [PATCH 252/311] Implement some episode table functions (#698) * Add show name to episode table header The episode table now works the similarly to the album table. * Add proper episode table context support * Make episode table scrollable * Add follow & unfollow functionaly to EpisodeTable block * Clear episode_table pages when opening a different show This prevents the previous_page action showing a different show when used at the top of a list of episodes. --- src/app.rs | 90 +++++++++++++++++---- src/handlers/episode_table.rs | 142 +++++++++++++++++++++------------ src/handlers/input.rs | 2 +- src/handlers/library.rs | 2 +- src/handlers/mod.rs | 4 +- src/handlers/podcasts.rs | 6 +- src/handlers/search_results.rs | 5 +- src/network.rs | 70 +++++++++++++--- src/ui/mod.rs | 118 ++++++++++++++++----------- 9 files changed, 307 insertions(+), 132 deletions(-) diff --git a/src/app.rs b/src/app.rs index ef353853..ffd1f531 100644 --- a/src/app.rs +++ b/src/app.rs @@ -11,7 +11,7 @@ use rspotify::{ page::{CursorBasedPage, Page}, playing::PlayHistory, playlist::{PlaylistTrack, SimplifiedPlaylist}, - show::{Show, SimplifiedEpisode, SimplifiedShow}, + show::{FullShow, Show, SimplifiedEpisode, SimplifiedShow}, track::{FullTrack, SavedTrack, SimplifiedTrack}, user::PrivateUser, PlayingItem, @@ -87,6 +87,7 @@ pub struct Library { pub saved_albums: ScrollableResultPages>, pub saved_shows: ScrollableResultPages>, pub saved_artists: ScrollableResultPages>, + pub show_episodes: ScrollableResultPages>, } #[derive(PartialEq, Debug)] @@ -184,6 +185,12 @@ pub enum AlbumTableContext { Full, } +#[derive(Clone, PartialEq, Debug, Copy)] +pub enum EpisodeTableContext { + Simplified, + Full, +} + #[derive(Clone, PartialEq, Debug)] pub enum RecommendationsContext { Artist, @@ -212,11 +219,14 @@ pub struct TrackTable { pub context: Option, } -#[derive(Default)] -pub struct EpisodeTable { - pub episodes: Vec, - pub selected_index: usize, - pub reversed: bool, +#[derive(Clone)] +pub struct SelectedShow { + pub show: SimplifiedShow, +} + +#[derive(Clone)] +pub struct SelectedFullShow { + pub show: FullShow, } #[derive(Clone)] @@ -293,13 +303,16 @@ pub struct App { pub song_progress_ms: u128, pub seek_ms: Option, pub track_table: TrackTable, - pub episode_table: EpisodeTable, + pub episode_table_context: EpisodeTableContext, + pub selected_show_simplified: Option, + pub selected_show_full: Option, pub user: Option, pub album_list_index: usize, pub made_for_you_index: usize, pub artists_list_index: usize, pub clipboard: Option, pub shows_list_index: usize, + pub episode_list_index: usize, pub help_docs_size: u32, pub help_menu_page: u32, pub help_menu_max_lines: u32, @@ -321,6 +334,7 @@ impl Default for App { made_for_you_index: 0, artists_list_index: 0, shows_list_index: 0, + episode_list_index: 0, artists: vec![], artist: None, user_config: UserConfig::new(), @@ -336,6 +350,7 @@ impl Default for App { saved_albums: ScrollableResultPages::new(), saved_shows: ScrollableResultPages::new(), saved_artists: ScrollableResultPages::new(), + show_episodes: ScrollableResultPages::new(), selected_index: 0, }, liked_song_ids_set: HashSet::new(), @@ -379,7 +394,9 @@ impl Default for App { selected_playlist_index: None, active_playlist_index: None, track_table: Default::default(), - episode_table: Default::default(), + episode_table_context: EpisodeTableContext::Full, + selected_show_simplified: None, + selected_show_full: None, user: None, instant_since_last_current_playback_poll: Instant::now(), clipboard: Clipboard::new().ok(), @@ -907,6 +924,29 @@ impl App { } } + pub fn get_episode_table_next(&mut self, show_id: String) { + match self + .library + .show_episodes + .get_results(Some(self.library.show_episodes.index + 1)) + .cloned() + { + Some(_) => self.library.show_episodes.index += 1, + None => { + if let Some(show_episodes) = &self.library.show_episodes.get_results(None) { + let offset = Some(show_episodes.offset + show_episodes.limit); + self.dispatch(IoEvent::GetCurrentShowEpisodes(show_id, offset)); + } + } + } + } + + pub fn get_episode_table_previous(&mut self) { + if self.library.show_episodes.index > 0 { + self.library.show_episodes.index -= 1; + } + } + pub fn user_unfollow_artists(&mut self, block: ActiveBlock) { match block { ActiveBlock::SearchResultBlock => { @@ -1013,9 +1053,20 @@ impl App { } } } - ActiveBlock::EpisodeTable => { - unimplemented!(); - } + ActiveBlock::EpisodeTable => match self.episode_table_context { + EpisodeTableContext::Full => { + if let Some(selected_episode) = self.selected_show_full.clone() { + let show_id = selected_episode.show.id; + self.dispatch(IoEvent::CurrentUserSavedShowAdd(show_id)); + } + } + EpisodeTableContext::Simplified => { + if let Some(selected_episode) = self.selected_show_simplified.clone() { + let show_id = selected_episode.show.id; + self.dispatch(IoEvent::CurrentUserSavedShowAdd(show_id)); + } + } + }, _ => (), } } @@ -1038,9 +1089,20 @@ impl App { } } } - ActiveBlock::EpisodeTable => { - unimplemented!(); - } + ActiveBlock::EpisodeTable => match self.episode_table_context { + EpisodeTableContext::Full => { + if let Some(selected_episode) = self.selected_show_full.clone() { + let show_id = selected_episode.show.id; + self.dispatch(IoEvent::CurrentUserSavedShowDelete(show_id)); + } + } + EpisodeTableContext::Simplified => { + if let Some(selected_episode) = self.selected_show_simplified.clone() { + let show_id = selected_episode.show.id; + self.dispatch(IoEvent::CurrentUserSavedShowDelete(show_id)); + } + } + }, _ => (), } } diff --git a/src/handlers/episode_table.rs b/src/handlers/episode_table.rs index 3b760571..1c8b368a 100644 --- a/src/handlers/episode_table.rs +++ b/src/handlers/episode_table.rs @@ -1,7 +1,8 @@ use super::{ - super::app::{App, EpisodeTable}, + super::app::{App, EpisodeTableContext}, common_key_events, }; +use crate::app::ActiveBlock; use crate::event::Key; use crate::network::IoEvent; @@ -9,40 +10,47 @@ pub fn handler(key: Key, app: &mut App) { match key { k if common_key_events::left_event(k) => common_key_events::handle_left_event(app), k if common_key_events::down_event(k) => { - let next_index = common_key_events::on_down_press_handler( - &app.episode_table.episodes, - Some(app.episode_table.selected_index), - ); - app.episode_table.selected_index = next_index; + if let Some(episodes) = &mut app.library.show_episodes.get_results(None) { + let next_index = + common_key_events::on_down_press_handler(&episodes.items, Some(app.episode_list_index)); + app.episode_list_index = next_index; + } } k if common_key_events::up_event(k) => { - let next_index = common_key_events::on_up_press_handler( - &app.episode_table.episodes, - Some(app.episode_table.selected_index), - ); - app.episode_table.selected_index = next_index; + if let Some(episodes) = &mut app.library.show_episodes.get_results(None) { + let next_index = + common_key_events::on_up_press_handler(&episodes.items, Some(app.episode_list_index)); + app.episode_list_index = next_index; + } } k if common_key_events::high_event(k) => { - let next_index = common_key_events::on_high_press_handler(); - app.episode_table.selected_index = next_index; + if let Some(_episodes) = app.library.show_episodes.get_results(None) { + let next_index = common_key_events::on_high_press_handler(); + app.episode_list_index = next_index; + } } k if common_key_events::middle_event(k) => { - let next_index = common_key_events::on_middle_press_handler(&app.episode_table.episodes); - app.episode_table.selected_index = next_index; + if let Some(episodes) = app.library.show_episodes.get_results(None) { + let next_index = common_key_events::on_middle_press_handler(&episodes.items); + app.episode_list_index = next_index; + } } k if common_key_events::low_event(k) => { - let next_index = common_key_events::on_low_press_handler(&app.episode_table.episodes); - app.episode_table.selected_index = next_index; + if let Some(episodes) = app.library.show_episodes.get_results(None) { + let next_index = common_key_events::on_low_press_handler(&episodes.items); + app.episode_list_index = next_index; + } } Key::Enter => { on_enter(app); } // Scroll down - k if k == app.user_config.keys.next_page => {} + k if k == app.user_config.keys.next_page => handle_next_event(app), // Scroll up - k if k == app.user_config.keys.previous_page => {} + k if k == app.user_config.keys.previous_page => handle_prev_event(app), Key::Char('S') => toggle_sort_by_date(app), - Key::Char('s') => {} // TODO: handle saving the show + Key::Char('s') => handle_follow_event(app), + Key::Char('D') => handle_unfollow_event(app), Key::Ctrl('e') => jump_to_end(app), Key::Ctrl('a') => jump_to_start(app), _ => {} @@ -50,47 +58,79 @@ pub fn handler(key: Key, app: &mut App) { } fn jump_to_end(app: &mut App) { - let last_idx = &app.episode_table.episodes.len() - 1; - app.episode_table.selected_index = last_idx; + if let Some(episodes) = app.library.show_episodes.get_results(None) { + let last_idx = episodes.items.len() - 1; + app.episode_list_index = last_idx; + } } fn on_enter(app: &mut App) { - let EpisodeTable { - selected_index: _, - episodes, - reversed: _, - } = &app.episode_table; - let episode_uris = episodes - .iter() - .map(|episode| episode.uri.to_owned()) - .collect::>(); - app.dispatch(IoEvent::StartPlayback( - None, - Some(episode_uris), - Some(app.episode_table.selected_index), - )); + if let Some(episodes) = app.library.show_episodes.get_results(None) { + let episode_uris = episodes + .items + .iter() + .map(|episode| episode.uri.to_owned()) + .collect::>(); + app.dispatch(IoEvent::StartPlayback( + None, + Some(episode_uris), + Some(app.episode_list_index), + )); + } +} + +fn handle_prev_event(app: &mut App) { + app.get_episode_table_previous(); +} + +fn handle_next_event(app: &mut App) { + match app.episode_table_context { + EpisodeTableContext::Full => { + if let Some(selected_episode) = app.selected_show_full.clone() { + let show_id = selected_episode.show.id; + app.get_episode_table_next(show_id) + } + } + EpisodeTableContext::Simplified => { + if let Some(selected_episode) = app.selected_show_simplified.clone() { + let show_id = selected_episode.show.id; + app.get_episode_table_next(show_id) + } + } + } +} + +fn handle_follow_event(app: &mut App) { + app.user_follow_show(ActiveBlock::EpisodeTable); +} + +fn handle_unfollow_event(app: &mut App) { + app.user_unfollow_show(ActiveBlock::EpisodeTable); } fn jump_to_start(app: &mut App) { - app.episode_table.selected_index = 0; + app.episode_list_index = 0; } fn toggle_sort_by_date(app: &mut App) { - let selected_id = app - .episode_table - .episodes - .get(app.episode_table.selected_index) - .map(|e| e.id.clone()); - app.episode_table.episodes.reverse(); - app.episode_table.reversed ^= true; + //TODO: reverse whole list and not just currently visible episodes + let selected_id = match app.library.show_episodes.get_results(None) { + Some(episodes) => episodes + .items + .get(app.episode_list_index) + .map(|e| e.id.clone()), + None => None, + }; + + if let Some(episodes) = app.library.show_episodes.get_mut_results(None) { + episodes.items.reverse(); + } + if let Some(id) = selected_id { - app.episode_table.selected_index = app - .episode_table - .episodes - .iter() - .position(|e| e.id == id) - .unwrap_or(0); + if let Some(episodes) = app.library.show_episodes.get_results(None) { + app.episode_list_index = episodes.items.iter().position(|e| e.id == id).unwrap_or(0); + } } else { - app.episode_table.selected_index = 0; + app.episode_list_index = 0; } } diff --git a/src/handlers/input.rs b/src/handlers/input.rs index f7d79fa0..5150b33c 100644 --- a/src/handlers/input.rs +++ b/src/handlers/input.rs @@ -155,7 +155,7 @@ fn attempt_process_uri(app: &mut App, input: &str, base: &str, sep: &str) -> boo let (show_id, matched) = spotify_resource_id(base, input, sep, "show"); if matched { - app.dispatch(IoEvent::GetShowEpisodes(show_id)); + app.dispatch(IoEvent::GetShow(show_id)); return true; } diff --git a/src/handlers/library.rs b/src/handlers/library.rs index 4f99ed87..0e38b5d6 100644 --- a/src/handlers/library.rs +++ b/src/handlers/library.rs @@ -52,7 +52,7 @@ pub fn handler(key: Key, app: &mut App) { } // Albums, 3 => { - app.dispatch(IoEvent::GetCurrentUserSavedAlbums(Some(0))); + app.dispatch(IoEvent::GetCurrentUserSavedAlbums(None)); app.push_navigation_stack(RouteId::AlbumList, ActiveBlock::AlbumList); } // Artists, diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index de595673..8c01d97d 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -219,8 +219,8 @@ fn handle_jump_to_album(app: &mut App) { PlayingItem::Track(track) => { app.dispatch(IoEvent::GetAlbumTracks(Box::new(track.album))); } - PlayingItem::Episode(_episode) => { - // Do nothing for episode (yet!) + PlayingItem::Episode(episode) => { + app.dispatch(IoEvent::GetShowEpisodes(Box::new(episode.show))); } }; } diff --git a/src/handlers/podcasts.rs b/src/handlers/podcasts.rs index 64f7dfdf..9f7ed53e 100644 --- a/src/handlers/podcasts.rs +++ b/src/handlers/podcasts.rs @@ -42,10 +42,8 @@ pub fn handler(key: Key, app: &mut App) { } Key::Enter => { if let Some(shows) = app.library.saved_shows.get_results(None) { - if let Some(selected_show) = shows.items.get(app.shows_list_index) { - // Go to show tracks table - let show_id = selected_show.show.id.to_owned(); - app.dispatch(IoEvent::GetShowEpisodes(show_id)); + if let Some(selected_show) = shows.items.get(app.shows_list_index).cloned() { + app.dispatch(IoEvent::GetShowEpisodes(Box::new(selected_show.show))); }; } } diff --git a/src/handlers/search_results.rs b/src/handlers/search_results.rs index 0a82fa2a..bd559fa9 100644 --- a/src/handlers/search_results.rs +++ b/src/handlers/search_results.rs @@ -336,10 +336,9 @@ fn handle_enter_event_on_selected_block(app: &mut App) { app.search_results.selected_shows_index, &app.search_results.shows, ) { - if let Some(show) = shows_result.items.get(index) { + if let Some(show) = shows_result.items.get(index).cloned() { // Go to show tracks table - let show_id = show.id.to_owned(); - app.dispatch(IoEvent::GetShowEpisodes(show_id)); + app.dispatch(IoEvent::GetShowEpisodes(Box::new(show))); }; } } diff --git a/src/network.rs b/src/network.rs index 8953f898..96a747f1 100644 --- a/src/network.rs +++ b/src/network.rs @@ -1,6 +1,7 @@ use crate::app::{ - ActiveBlock, AlbumTableContext, App, Artist, ArtistBlock, RouteId, SelectedAlbum, - SelectedFullAlbum, TrackTableContext, + ActiveBlock, AlbumTableContext, App, Artist, ArtistBlock, EpisodeTableContext, RouteId, + ScrollableResultPages, SelectedAlbum, SelectedFullAlbum, SelectedFullShow, SelectedShow, + TrackTableContext, }; use crate::config::ClientConfig; use anyhow::anyhow; @@ -14,6 +15,7 @@ use rspotify::{ playlist::{PlaylistTrack, SimplifiedPlaylist}, recommend::Recommendations, search::SearchResult, + show::SimplifiedShow, track::FullTrack, PlayingItem, }, @@ -82,7 +84,9 @@ pub enum IoEvent { CurrentUserSavedShowsContains(Vec), CurrentUserSavedShowDelete(String), CurrentUserSavedShowAdd(String), - GetShowEpisodes(String), + GetShowEpisodes(Box), + GetShow(String), + GetCurrentShowEpisodes(String, Option), AddItemToQueue(String), } @@ -286,8 +290,14 @@ impl<'a> Network<'a> { IoEvent::CurrentUserSavedShowAdd(show_id) => { self.current_user_saved_shows_add(show_id).await; } - IoEvent::GetShowEpisodes(show_id) => { - self.get_show_episodes(show_id).await; + IoEvent::GetShowEpisodes(show) => { + self.get_show_episodes(show).await; + } + IoEvent::GetShow(show_id) => { + self.get_show(show_id).await; + } + IoEvent::GetCurrentShowEpisodes(show_id, offset) => { + self.get_current_show_episodes(show_id, offset).await; } IoEvent::AddItemToQueue(item) => { self.add_item_to_queue(item).await; @@ -498,17 +508,41 @@ impl<'a> Network<'a> { } } - async fn get_show_episodes(&mut self, show_id: String) { + async fn get_show_episodes(&mut self, show: Box) { match self .spotify - .get_shows_episodes(show_id, self.large_search_limit, 0, None) + .get_shows_episodes(show.id.clone(), self.large_search_limit, 0, None) .await { Ok(episodes) => { + if !episodes.items.is_empty() { + let mut app = self.app.lock().await; + app.library.show_episodes = ScrollableResultPages::new(); + app.library.show_episodes.add_pages(episodes); + + app.selected_show_simplified = Some(SelectedShow { show: *show }); + + app.episode_table_context = EpisodeTableContext::Simplified; + + app.push_navigation_stack(RouteId::PodcastEpisodes, ActiveBlock::EpisodeTable); + } + } + Err(e) => { + self.handle_error(anyhow!(e)).await; + } + } + } + + async fn get_show(&mut self, show_id: String) { + match self.spotify.get_a_show(show_id, None).await { + Ok(show) => { + let selected_show = SelectedFullShow { show }; + let mut app = self.app.lock().await; - app.episode_table.episodes = episodes.items; - app.episode_table.reversed = false; + app.selected_show_full = Some(selected_show); + + app.episode_table_context = EpisodeTableContext::Full; app.push_navigation_stack(RouteId::PodcastEpisodes, ActiveBlock::EpisodeTable); } Err(e) => { @@ -517,6 +551,24 @@ impl<'a> Network<'a> { } } + async fn get_current_show_episodes(&mut self, show_id: String, offset: Option) { + match self + .spotify + .get_shows_episodes(show_id, self.large_search_limit, offset, None) + .await + { + Ok(episodes) => { + if !episodes.items.is_empty() { + let mut app = self.app.lock().await; + app.library.show_episodes.add_pages(episodes); + } + } + Err(e) => { + self.handle_error(anyhow!(e)).await; + } + } + } + async fn get_search_results(&mut self, search_term: String, country: Option) { let search_track = self.spotify.search( &search_term, diff --git a/src/ui/mod.rs b/src/ui/mod.rs index ac2e7a55..acfe818e 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -3,8 +3,8 @@ pub mod help; pub mod util; use super::{ app::{ - ActiveBlock, AlbumTableContext, App, ArtistBlock, RecommendationsContext, RouteId, - SearchResultBlock, LIBRARY_OPTIONS, + ActiveBlock, AlbumTableContext, App, ArtistBlock, EpisodeTableContext, RecommendationsContext, + RouteId, SearchResultBlock, LIBRARY_OPTIONS, }, banner::BANNER, }; @@ -1440,53 +1440,77 @@ where current_route.hovered_block == ActiveBlock::EpisodeTable, ); - let items = app - .episode_table - .episodes - .iter() - .map(|episode| { - let (played_str, time_str) = match episode.resume_point { - Some(ResumePoint { - fully_played, - resume_position_ms, - }) => ( - if fully_played { - " βœ”".to_owned() - } else { - "".to_owned() - }, - format!( - "{} / {}", - millis_to_minutes(u128::from(resume_position_ms)), - millis_to_minutes(u128::from(episode.duration_ms)) + if let Some(episodes) = app.library.show_episodes.get_results(None) { + let items = episodes + .items + .iter() + .map(|episode| { + let (played_str, time_str) = match episode.resume_point { + Some(ResumePoint { + fully_played, + resume_position_ms, + }) => ( + if fully_played { + " βœ”".to_owned() + } else { + "".to_owned() + }, + format!( + "{} / {}", + millis_to_minutes(u128::from(resume_position_ms)), + millis_to_minutes(u128::from(episode.duration_ms)) + ), ), - ), - None => ( - "".to_owned(), - millis_to_minutes(u128::from(episode.duration_ms)), - ), - }; - TableItem { - id: episode.id.to_owned(), - format: vec![ - played_str, - episode.release_date.to_owned(), - episode.name.to_owned(), - time_str, - ], - } - }) - .collect::>(); + None => ( + "".to_owned(), + millis_to_minutes(u128::from(episode.duration_ms)), + ), + }; + TableItem { + id: episode.id.to_owned(), + format: vec![ + played_str, + episode.release_date.to_owned(), + episode.name.to_owned(), + time_str, + ], + } + }) + .collect::>(); - draw_table( - f, - app, - layout_chunk, - ("Episodes", &header), - &items, - app.episode_table.selected_index, - highlight_state, - ); + let title = match &app.episode_table_context { + EpisodeTableContext::Simplified => match &app.selected_show_simplified { + Some(selected_show) => { + format!( + "{} by {}", + selected_show.show.name.to_owned(), + selected_show.show.publisher + ) + } + None => "Episodes".to_owned(), + }, + EpisodeTableContext::Full => match &app.selected_show_full { + Some(selected_show) => { + format!( + "{} by {}", + selected_show.show.name.to_owned(), + selected_show.show.publisher + ) + } + None => "Episodes".to_owned(), + }, + }; + + draw_table( + f, + app, + layout_chunk, + (&title, &header), + &items, + app.episode_list_index, + highlight_state, + ); + }; } pub fn draw_made_for_you(f: &mut Frame, app: &App, layout_chunk: Rect) From e94f8519b022021a67ee7c037fb20994ebd8e9e3 Mon Sep 17 00:00:00 2001 From: Finn Hediger Date: Sat, 27 Feb 2021 11:01:09 +0100 Subject: [PATCH 253/311] `enforce_wide_search_bar` to make search bar bigger (#738) * Add a new bool option: 'show_big_search' to force the big search bar This completely disables the responsive layout and instead displays the big search bar used in previus spt builds. * Rename option to 'enforce_wide_search_bar' * Formatting * Add the option to the README --- README.md | 3 +++ src/ui/mod.rs | 17 ++++++++++------- src/user_config.rs | 7 +++++++ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b8abe49c..b64c1b2f 100644 --- a/README.md +++ b/README.md @@ -242,6 +242,9 @@ behavior: enable_text_emphasis: true # Controls whether to show a loading indicator in the top right of the UI whenever communicating with Spotify API show_loading_indicator: true + # Disables the responsive layout that makes the search bar smaller on bigger + # screens and enforces a wide search bar + enforce_wide_search_bar: false # Determines the text icon to display next to "liked" Spotify items, such as # liked songs and albums, or followed artists. Can be any length string. # These icons require a patched nerd font. diff --git a/src/ui/mod.rs b/src/ui/mod.rs index acfe818e..76bd279f 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -122,11 +122,14 @@ where // Check for the width and change the contraints accordingly let chunks = Layout::default() .direction(Direction::Horizontal) - .constraints(if app.size.width >= SMALL_TERMINAL_WIDTH { - [Constraint::Percentage(65), Constraint::Percentage(35)].as_ref() - } else { - [Constraint::Percentage(90), Constraint::Percentage(10)].as_ref() - }) + .constraints( + if app.size.width >= SMALL_TERMINAL_WIDTH && !app.user_config.behavior.enforce_wide_search_bar + { + [Constraint::Percentage(65), Constraint::Percentage(35)].as_ref() + } else { + [Constraint::Percentage(90), Constraint::Percentage(10)].as_ref() + }, + ) .split(layout_chunk); let current_route = app.get_current_route(); @@ -174,7 +177,7 @@ where { let margin = util::get_main_layout_margin(app); // Responsive layout: new one kicks in at width 150 or higher - if app.size.width >= SMALL_TERMINAL_WIDTH { + if app.size.width >= SMALL_TERMINAL_WIDTH && !app.user_config.behavior.enforce_wide_search_bar { let parent_layout = Layout::default() .direction(Direction::Vertical) .constraints([Constraint::Min(1), Constraint::Length(6)].as_ref()) @@ -323,7 +326,7 @@ where B: Backend, { // Check for width to make a responsive layout - if app.size.width >= SMALL_TERMINAL_WIDTH { + if app.size.width >= SMALL_TERMINAL_WIDTH && !app.user_config.behavior.enforce_wide_search_bar { let chunks = Layout::default() .direction(Direction::Vertical) .constraints( diff --git a/src/user_config.rs b/src/user_config.rs index 3873457d..682e2ca5 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -212,6 +212,7 @@ pub struct BehaviorConfigString { pub tick_rate_milliseconds: Option, pub enable_text_emphasis: Option, pub show_loading_indicator: Option, + pub enforce_wide_search_bar: Option, pub liked_icon: Option, pub shuffle_icon: Option, pub repeat_track_icon: Option, @@ -227,6 +228,7 @@ pub struct BehaviorConfig { pub tick_rate_milliseconds: u64, pub enable_text_emphasis: bool, pub show_loading_indicator: bool, + pub enforce_wide_search_bar: bool, pub liked_icon: String, pub shuffle_icon: String, pub repeat_track_icon: String, @@ -288,6 +290,7 @@ impl UserConfig { tick_rate_milliseconds: 250, enable_text_emphasis: true, show_loading_indicator: true, + enforce_wide_search_bar: false, liked_icon: "β™₯".to_string(), shuffle_icon: "πŸ”€".to_string(), repeat_track_icon: "πŸ”‚".to_string(), @@ -423,6 +426,10 @@ impl UserConfig { self.behavior.show_loading_indicator = loading_indicator; } + if let Some(wide_search_bar) = behavior_config.enforce_wide_search_bar { + self.behavior.enforce_wide_search_bar = wide_search_bar; + } + if let Some(liked_icon) = behavior_config.liked_icon { self.behavior.liked_icon = liked_icon; } From 42b3670b553557fbed96cdfc5c087d3f9d53da16 Mon Sep 17 00:00:00 2001 From: sheepwall Date: Sat, 27 Feb 2021 11:26:40 +0100 Subject: [PATCH 254/311] app: add Daily Drive to Made For You lists search. (#743) --- src/app.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app.rs b/src/app.rs index ffd1f531..15770c96 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1113,6 +1113,7 @@ impl App { const RELEASE_RADAR: &str = "Release Radar"; const ON_REPEAT: &str = "On Repeat"; const REPEAT_REWIND: &str = "Repeat Rewind"; + const DAILY_DRIVE: &str = "Daily Drive"; if self.library.made_for_you_playlists.pages.is_empty() { // We shouldn't be fetching all the results immediately - only load the data when the @@ -1121,6 +1122,7 @@ impl App { self.made_for_you_search_and_add(RELEASE_RADAR); self.made_for_you_search_and_add(ON_REPEAT); self.made_for_you_search_and_add(REPEAT_REWIND); + self.made_for_you_search_and_add(DAILY_DRIVE); } } From e6711f60d689d7f0eb6b946ebf29c65fddbd7b88 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 27 Feb 2021 10:29:15 +0000 Subject: [PATCH 255/311] docs: add sheepwall as a contributor (#747) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8b4c0eef..c29eae97 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -751,6 +751,15 @@ "contributions": [ "doc" ] + }, + { + "login": "sheepwall", + "name": "sheepwall", + "avatar_url": "https://avatars.githubusercontent.com/u/22132993?v=4", + "profile": "https://github.com/sheepwall", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index b64c1b2f..35b9fdff 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-81-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-82-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -436,6 +436,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Rasmus Pedersen

πŸ’»
noir-Z

πŸ“–
David Bailey

πŸ“– +
sheepwall

πŸ’» From b8b4ba2b714808ed912e85fec0041996145d18a4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 27 Feb 2021 13:39:13 +0000 Subject: [PATCH 256/311] Bump serde_yaml from 0.8.15 to 0.8.17 (#735) Bumps [serde_yaml](https://github.com/dtolnay/serde-yaml) from 0.8.15 to 0.8.17. - [Release notes](https://github.com/dtolnay/serde-yaml/releases) - [Commits](https://github.com/dtolnay/serde-yaml/compare/0.8.15...0.8.17) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 398e20f7..5ab8f1bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1790,9 +1790,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.15" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "971be8f6e4d4a47163b405a3df70d14359186f9ab0f3a3ec37df144ca1ce089f" +checksum = "15654ed4ab61726bf918a39cb8d98a2e2995b002387807fa6ba58fdf7f59bb23" dependencies = [ "dtoa", "linked-hash-map", From 1a79c6de8d798c946308c5c2286ffc138720cf00 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 27 Feb 2021 13:39:37 +0000 Subject: [PATCH 257/311] Bump serde_json from 1.0.61 to 1.0.63 (#746) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.61 to 1.0.63. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.61...v1.0.63) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ab8f1bb..a97f76f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1767,9 +1767,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" +checksum = "43535db9747a4ba938c0ce0a98cc631a46ebf943c9e1d604e091df6007620bf6" dependencies = [ "itoa", "ryu", From a903517a14a6b30ab03da023bf331ee1b4618775 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Sat, 27 Feb 2021 13:39:58 +0000 Subject: [PATCH 258/311] Update tui lib to 0.14.0 (#748) --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/ui/mod.rs | 22 +++++++++++++++------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a97f76f4..facd0ebb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2111,9 +2111,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "tui" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4e6c82bb967df89f20b875fa8835fab5d5622c6a5efa574a1f0b6d0aa6e8f6" +checksum = "9ced152a8e9295a5b168adc254074525c17ac4a83c90b2716274cc38118bddc9" dependencies = [ "bitflags", "cassowary", diff --git a/Cargo.toml b/Cargo.toml index 030cec73..4b05b41c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ license = "MIT OR Apache-2.0" [dependencies] rspotify = "0.10.0" -tui = { version = "0.13.0", features = ["crossterm"], default-features = false } +tui = { version = "0.14.0", features = ["crossterm"], default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 76bd279f..ea27077d 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -85,21 +85,26 @@ where // Create a one-column table to avoid flickering due to non-determinism when // resolving constraints on widths of table columns. - let format_row = |r: Vec| vec![format!("{:50}{:40}{:20}", r[0], r[1], r[2])]; + let format_row = + |r: Vec| -> Vec { vec![format!("{:50}{:40}{:20}", r[0], r[1], r[2])] }; let help_menu_style = Style::default().fg(app.user_config.theme.text); let header = ["Description", "Event", "Context"]; let header = format_row(header.iter().map(|s| s.to_string()).collect()); let help_docs = get_help_docs(&app.user_config.keys); - let help_docs = help_docs.into_iter().map(format_row).collect::>(); + let help_docs = help_docs + .into_iter() + .map(format_row) + .collect::>>(); let help_docs = &help_docs[app.help_menu_offset as usize..]; let rows = help_docs .iter() - .map(|item| Row::StyledData(item.iter(), help_menu_style)); + .map(|item| Row::new(item.clone()).style(help_menu_style)); - let help_menu = Table::new(header.iter(), rows) + let help_menu = Table::new(rows) + .header(Row::new(header)) .block( Block::default() .borders(Borders::ALL) @@ -1824,7 +1829,7 @@ fn draw_table( } // Return row styled data - Row::StyledData(formatted_row.into_iter(), style) + Row::new(formatted_row).style(style) }); let widths = header @@ -1833,7 +1838,11 @@ fn draw_table( .map(|h| Constraint::Length(h.width)) .collect::>(); - let table = Table::new(header.items.iter().map(|h| h.text), rows) + let table = Table::new(rows) + .header( + Row::new(header.items.iter().map(|h| h.text)) + .style(Style::default().fg(app.user_config.theme.header)), + ) .block( Block::default() .borders(Borders::ALL) @@ -1845,7 +1854,6 @@ fn draw_table( .border_style(get_color(highlight_state, app.user_config.theme)), ) .style(Style::default().fg(app.user_config.theme.text)) - .header_style(Style::default().fg(app.user_config.theme.header)) .widths(&widths); f.render_widget(table, layout_chunk); } From bb8a7640daa848c078894189e2fd5c887802b5f5 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 27 Feb 2021 13:40:09 +0000 Subject: [PATCH 259/311] Bump tokio from 0.2.24 to 0.2.25 (#728) Bumps [tokio](https://github.com/tokio-rs/tokio) from 0.2.24 to 0.2.25. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-0.2.24...tokio-0.2.25) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index facd0ebb..ccb8727a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1021,9 +1021,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.22" +version = "0.6.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" +checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" dependencies = [ "cfg-if 0.1.10", "fuchsia-zircon", @@ -1032,7 +1032,7 @@ dependencies = [ "kernel32-sys", "libc", "log", - "miow 0.2.1", + "miow 0.2.2", "net2", "slab", "winapi 0.2.8", @@ -1059,7 +1059,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" dependencies = [ "log", - "mio 0.6.22", + "mio 0.6.23", "miow 0.3.5", "winapi 0.3.9", ] @@ -1072,14 +1072,14 @@ checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" dependencies = [ "iovec", "libc", - "mio 0.6.22", + "mio 0.6.23", ] [[package]] name = "miow" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" dependencies = [ "kernel32-sys", "net2", @@ -1117,9 +1117,9 @@ dependencies = [ [[package]] name = "net2" -version = "0.2.34" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" +checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" dependencies = [ "cfg-if 0.1.10", "libc", @@ -2007,9 +2007,9 @@ checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" [[package]] name = "tokio" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099837d3464c16a808060bb3f02263b412f6fafcb5d01c533d309985fbeebe48" +checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" dependencies = [ "bytes 0.5.6", "fnv", @@ -2018,7 +2018,7 @@ dependencies = [ "lazy_static", "libc", "memchr", - "mio 0.6.22", + "mio 0.6.23", "mio-named-pipes", "mio-uds", "num_cpus", From 43452ca44f0d6eb6085673ac15400ff6bf1ef93d Mon Sep 17 00:00:00 2001 From: Hwatwasthat Date: Sat, 27 Feb 2021 14:33:25 +0000 Subject: [PATCH 260/311] updated rand crate (#749) Co-authored-by: Chris Bury --- Cargo.lock | 67 ++++++++++++++++++++++++++++++++++--- Cargo.toml | 2 +- src/cli/cli_app.rs | 2 +- src/handlers/track_table.rs | 8 ++--- 4 files changed, 68 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ccb8727a..20d35a41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -693,7 +693,18 @@ checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" dependencies = [ "cfg-if 0.1.10", "libc", - "wasi", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] @@ -1433,13 +1444,25 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom", + "getrandom 0.1.14", "libc", "rand_chacha 0.2.2", "rand_core 0.5.1", "rand_hc 0.2.0", ] +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha 0.3.0", + "rand_core 0.6.2", + "rand_hc 0.3.0", +] + [[package]] name = "rand_chacha" version = "0.1.1" @@ -1460,6 +1483,16 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.2", +] + [[package]] name = "rand_core" version = "0.3.1" @@ -1481,7 +1514,16 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom", + "getrandom 0.1.14", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom 0.2.2", ] [[package]] @@ -1502,6 +1544,15 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core 0.6.2", +] + [[package]] name = "rand_isaac" version = "0.1.1" @@ -1582,7 +1633,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" dependencies = [ - "getrandom", + "getrandom 0.1.14", "redox_syscall", "rust-argon2", ] @@ -1855,7 +1906,7 @@ dependencies = [ "clap", "crossterm", "dirs", - "rand 0.7.3", + "rand 0.8.3", "rspotify", "serde", "serde_json", @@ -2229,6 +2280,12 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + [[package]] name = "wasm-bindgen" version = "0.2.65" diff --git a/Cargo.toml b/Cargo.toml index 4b05b41c..15793589 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ backtrace = "0.3.56" arboard = "1.1.0" crossterm = "0.18" tokio = { version = "0.2", features = ["full"] } -rand = "0.7.3" +rand = "0.8.3" anyhow = "1.0.38" [[bin]] diff --git a/src/cli/cli_app.rs b/src/cli/cli_app.rs index c8601f88..bd9867f8 100644 --- a/src/cli/cli_app.rs +++ b/src/cli/cli_app.rs @@ -456,7 +456,7 @@ impl<'a> CliApp<'a> { match self.net.spotify.playlist(id, None, None).await { Ok(p) => { let num = p.tracks.total; - Some(thread_rng().gen_range(0, num) as usize) + Some(thread_rng().gen_range(0..num) as usize) } Err(e) => { self diff --git a/src/handlers/track_table.rs b/src/handlers/track_table.rs index 93e5db24..08c9f165 100644 --- a/src/handlers/track_table.rs +++ b/src/handlers/track_table.rs @@ -178,7 +178,7 @@ fn play_random_song(app: &mut App) { app.dispatch(IoEvent::StartPlayback( context_uri, None, - Some(thread_rng().gen_range(0, num_tracks)), + Some(thread_rng().gen_range(0..num_tracks)), )); } } @@ -190,7 +190,7 @@ fn play_random_song(app: &mut App) { .iter() .map(|item| item.track.uri.to_owned()) .collect(); - let rand_idx = thread_rng().gen_range(0, track_uris.len()); + let rand_idx = thread_rng().gen_range(0..track_uris.len()); app.dispatch(IoEvent::StartPlayback( None, Some(track_uris), @@ -224,7 +224,7 @@ fn play_random_song(app: &mut App) { app.dispatch(IoEvent::StartPlayback( context_uri, None, - Some(thread_rng().gen_range(0, num_tracks)), + Some(thread_rng().gen_range(0..num_tracks)), )) } } @@ -244,7 +244,7 @@ fn play_random_song(app: &mut App) { app.dispatch(IoEvent::StartPlayback( uri, None, - Some(thread_rng().gen_range(0, num_tracks)), + Some(thread_rng().gen_range(0..*num_tracks)), )) }; }; From 6dec94179ccbc5fdc7ad9c57c582664f80b5e84e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 27 Feb 2021 14:35:13 +0000 Subject: [PATCH 261/311] docs: add Hwatwasthat as a contributor (#750) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index c29eae97..797cec78 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -760,6 +760,15 @@ "contributions": [ "code" ] + }, + { + "login": "Hwatwasthat", + "name": "Hwatwasthat", + "avatar_url": "https://avatars.githubusercontent.com/u/29790143?v=4", + "profile": "https://github.com/Hwatwasthat", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 35b9fdff..f2e88d73 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-82-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-83-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -437,6 +437,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
noir-Z

πŸ“–
David Bailey

πŸ“–
sheepwall

πŸ’» +
Hwatwasthat

πŸ’» From c5b340025f0b7e4129f5f4af9c01b7765af356a7 Mon Sep 17 00:00:00 2001 From: Hwatwasthat Date: Sat, 27 Feb 2021 15:06:33 +0000 Subject: [PATCH 262/311] crossterm updated (#752) * crossterm updated * crossterm updated, removed write import * crossterm updated, removed write import Co-authored-by: Chris Bury --- Cargo.lock | 31 ++++++++++++++++++++++++++++--- Cargo.toml | 2 +- src/main.rs | 2 +- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 20d35a41..88f5072b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -362,7 +362,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e86d73f2a0b407b5768d10a8c720cf5d2df49a9efc10ca09176d201ead4b7fb" dependencies = [ "bitflags", - "crossterm_winapi", + "crossterm_winapi 0.6.2", + "lazy_static", + "libc", + "mio 0.7.0", + "parking_lot", + "signal-hook", + "winapi 0.3.9", +] + +[[package]] +name = "crossterm" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c36c10130df424b2f3552fcc2ddcd9b28a27b1e54b358b45874f88d1ca6888c" +dependencies = [ + "bitflags", + "crossterm_winapi 0.7.0", "lazy_static", "libc", "mio 0.7.0", @@ -380,6 +396,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "crossterm_winapi" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0da8964ace4d3e4a044fd027919b2237000b24315a37c916f61809f1ff2140b9" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "darling" version = "0.9.0" @@ -1904,7 +1929,7 @@ dependencies = [ "arboard", "backtrace", "clap", - "crossterm", + "crossterm 0.19.0", "dirs", "rand 0.8.3", "rspotify", @@ -2168,7 +2193,7 @@ checksum = "9ced152a8e9295a5b168adc254074525c17ac4a83c90b2716274cc38118bddc9" dependencies = [ "bitflags", "cassowary", - "crossterm", + "crossterm 0.18.2", "unicode-segmentation", "unicode-width", ] diff --git a/Cargo.toml b/Cargo.toml index 15793589..a69ce934 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ clap = "2.33.3" unicode-width = "0.1.8" backtrace = "0.3.56" arboard = "1.1.0" -crossterm = "0.18" +crossterm = "0.19" tokio = { version = "0.2", features = ["full"] } rand = "0.8.3" anyhow = "1.0.38" diff --git a/src/main.rs b/src/main.rs index adb0de5b..177257c0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,7 +33,7 @@ use rspotify::{ }; use std::{ cmp::{max, min}, - io::{self, stdout, Write}, + io::{self, stdout}, panic::{self, PanicInfo}, path::PathBuf, sync::Arc, From 7fa28899635b199501784cdeb50cb03de9389174 Mon Sep 17 00:00:00 2001 From: Jesse Date: Sat, 27 Feb 2021 18:17:01 +0100 Subject: [PATCH 263/311] Replace black and white default colors with reset. (#742) Previously, text would be white, which is not visible on bright color schemes. The color for non-highlighted text now uses the default foreground color of the users terminal emulator, making it visible in any theme. The only visual change in dark color schemes is that the playbar text might go from black to white, depending on the users terminal emulator (some terminal emulators swap fore- and background colors on a colored background depending on the background color; this is IMO the correct behavior anyway). --- src/user_config.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/user_config.rs b/src/user_config.rs index 682e2ca5..98aa3e62 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -53,7 +53,7 @@ impl Default for Theme { fn default() -> Self { Theme { analysis_bar: Color::LightCyan, - analysis_bar_text: Color::Black, + analysis_bar_text: Color::Reset, active: Color::Cyan, banner: Color::LightCyan, error_border: Color::Red, @@ -64,10 +64,10 @@ impl Default for Theme { playbar_background: Color::Black, playbar_progress: Color::LightCyan, playbar_progress_text: Color::LightCyan, - playbar_text: Color::White, + playbar_text: Color::Reset, selected: Color::LightCyan, - text: Color::White, - header: Color::White, + text: Color::Reset, + header: Color::Reset, } } } From ef21eedbab6d858985d23ba29639dfba0a46c632 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Sat, 27 Feb 2021 17:17:34 +0000 Subject: [PATCH 264/311] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c09f311..cc7803a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ - Implement some episode table functions [#698](https://github.com/Rigellute/spotify-tui/pull/698) - Fix default liked, shuffle, etc. icons to more recognizable symbols [#702](https://github.com/Rigellute/spotify-tui/pull/702) - Change `--like` that toggled the liked-state to explicit `--like` and `--dislike` flags [#717](https://github.com/Rigellute/spotify-tui/pull/717) +- Add to config: `enforce_wide_search_bar` to make search bar bigger [#738](https://github.com/Rigellute/spotify-tui/pull/738) +- Add Daily Drive to Made For You lists search [#743](https://github.com/Rigellute/spotify-tui/pull/743) +- Replace black and white default colors with reset [#742](https://github.com/Rigellute/spotify-tui/pull/742) ## [0.23.0] - 2021-01-06 From 4fd7bdf81d2f640b0fa25fb7b9cac5fec0500dc9 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 27 Feb 2021 17:18:14 +0000 Subject: [PATCH 265/311] docs: add Jesse-Bakker as a contributor (#753) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 797cec78..10228ff0 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -769,6 +769,15 @@ "contributions": [ "code" ] + }, + { + "login": "Jesse-Bakker", + "name": "Jesse", + "avatar_url": "https://avatars.githubusercontent.com/u/22473248?v=4", + "profile": "https://github.com/Jesse-Bakker", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index f2e88d73..531a4d32 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-83-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-84-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -438,6 +438,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
David Bailey

πŸ“–
sheepwall

πŸ’»
Hwatwasthat

πŸ’» +
Jesse

πŸ’» From e77060c58d5dfa638845ce97328d5e1dc3e9f6b5 Mon Sep 17 00:00:00 2001 From: Sang <11912225+hantatsang@users.noreply.github.com> Date: Mon, 15 Mar 2021 10:06:08 +1100 Subject: [PATCH 266/311] docs(README): fix default shortcut for shuffle config (#759) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 531a4d32..87eff8f4 100644 --- a/README.md +++ b/README.md @@ -278,7 +278,7 @@ keybindings: copy_song_url: "c" copy_album_url: "C" help: "?" - shuffle: "s" + shuffle: "ctrl-s" repeat: "r" search: "/" audio_analysis: "v" From 0a6d304509d598dbee19743ee5a04a39f79ab647 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 14 Mar 2021 23:06:48 +0000 Subject: [PATCH 267/311] Bump serde from 1.0.123 to 1.0.124 (#761) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.123 to 1.0.124. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.123...v1.0.124) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88f5072b..ee661eb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1823,18 +1823,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.123" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" +checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.123" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31" +checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", From aa86c64d9bf2f346068a7c0b4cac5fc6eec227a3 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 14 Mar 2021 23:07:07 +0000 Subject: [PATCH 268/311] Bump serde_json from 1.0.63 to 1.0.64 (#755) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.63 to 1.0.64. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.63...v1.0.64) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee661eb8..067a11b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1843,9 +1843,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43535db9747a4ba938c0ce0a98cc631a46ebf943c9e1d604e091df6007620bf6" +checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" dependencies = [ "itoa", "ryu", From 5b2fe949386e7517a2ba3557410a76c23562ef70 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sun, 14 Mar 2021 23:07:19 +0000 Subject: [PATCH 269/311] docs: add hantatsang as a contributor (#764) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 10228ff0..555e1340 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -778,6 +778,15 @@ "contributions": [ "code" ] + }, + { + "login": "hantatsang", + "name": "Sang", + "avatar_url": "https://avatars.githubusercontent.com/u/11912225?v=4", + "profile": "https://github.com/hantatsang", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 87eff8f4..04e6e550 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-84-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-85-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -440,6 +440,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Hwatwasthat

πŸ’»
Jesse

πŸ’» + +
Sang

πŸ“– + From d1f1c67abd735121675eec2cdd116ae7eeab413b Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Tue, 30 Mar 2021 11:53:37 +0100 Subject: [PATCH 270/311] Fix clippy warnings --- src/handlers/help_menu.rs | 16 ++++++++-------- src/ui/mod.rs | 6 +++--- src/user_config.rs | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/handlers/help_menu.rs b/src/handlers/help_menu.rs index c0cfab21..29b90c18 100644 --- a/src/handlers/help_menu.rs +++ b/src/handlers/help_menu.rs @@ -3,34 +3,34 @@ use crate::{app::App, event::Key}; #[derive(PartialEq)] enum Direction { - UP, - DOWN, + Up, + Down, } pub fn handler(key: Key, app: &mut App) { match key { k if common_key_events::down_event(k) => { - move_page(Direction::DOWN, app); + move_page(Direction::Down, app); } k if common_key_events::up_event(k) => { - move_page(Direction::UP, app); + move_page(Direction::Up, app); } Key::Ctrl('d') => { - move_page(Direction::DOWN, app); + move_page(Direction::Down, app); } Key::Ctrl('u') => { - move_page(Direction::UP, app); + move_page(Direction::Up, app); } _ => {} }; } fn move_page(direction: Direction, app: &mut App) { - if direction == Direction::UP { + if direction == Direction::Up { if app.help_menu_page > 0 { app.help_menu_page -= 1; } - } else if direction == Direction::DOWN { + } else if direction == Direction::Down { app.help_menu_page += 1; } app.calculate_help_menu_offset(); diff --git a/src/ui/mod.rs b/src/ui/mod.rs index ea27077d..b2c712e4 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -542,7 +542,7 @@ where } } -struct AlbumUI { +struct AlbumUi { selected_index: usize, items: Vec, title: String, @@ -681,7 +681,7 @@ where let album_ui = match &app.album_table_context { AlbumTableContext::Simplified => match &app.selected_album_simplified { - Some(selected_album_simplified) => Some(AlbumUI { + Some(selected_album_simplified) => Some(AlbumUi { items: selected_album_simplified .tracks .items @@ -707,7 +707,7 @@ where None => None, }, AlbumTableContext::Full => match app.selected_album_full.clone() { - Some(selected_album) => Some(AlbumUI { + Some(selected_album) => Some(AlbumUi { items: selected_album .album .tracks diff --git a/src/user_config.rs b/src/user_config.rs index 98aa3e62..e7d2bfb3 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -337,7 +337,7 @@ impl UserConfig { check_reserved_keys(self.keys.$name)?; } }; - }; + } to_keys!(back); to_keys!(next_page); @@ -376,7 +376,7 @@ impl UserConfig { self.theme.$name = parse_theme_item(&theme_item)?; } }; - }; + } to_theme_item!(active); to_theme_item!(banner); From c789a6a5b5a9940128b144927711a0bc9b852bc1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 30 Mar 2021 11:56:42 +0100 Subject: [PATCH 271/311] Bump serde from 1.0.124 to 1.0.125 (#771) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.124 to 1.0.125. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.124...v1.0.125) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 067a11b5..9ec852b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1823,18 +1823,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.124" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f" +checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.124" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b" +checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", From d5c6411d33ea47d57f4759e82b8f4392b1412d79 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 26 Apr 2021 11:46:55 +0100 Subject: [PATCH 272/311] Prepare release 0.24.0 --- CHANGELOG.md | 13 ++++++++++--- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc7803a2..82d35fac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,15 +2,22 @@ ## [Unreleased] +## [0.24.0] - 2021-04-26 + +### Fixed + +- Handle invalid Client ID/Secret [#668](https://github.com/Rigellute/spotify-tui/pull/668) +- Fix default liked, shuffle, etc. icons to be more recognizable symbols [#702](https://github.com/Rigellute/spotify-tui/pull/702) +- Replace black and white default colors with reset [#742](https://github.com/Rigellute/spotify-tui/pull/742) + +### Added + - Add ability to seek from the CLI [#692](https://github.com/Rigellute/spotify-tui/pull/692) - Replace `clipboard` with `arboard` [#691](https://github.com/Rigellute/spotify-tui/pull/691) -- Handle invalid Client ID/Secret [#668](https://github.com/Rigellute/spotify-tui/pull/668) - Implement some episode table functions [#698](https://github.com/Rigellute/spotify-tui/pull/698) -- Fix default liked, shuffle, etc. icons to more recognizable symbols [#702](https://github.com/Rigellute/spotify-tui/pull/702) - Change `--like` that toggled the liked-state to explicit `--like` and `--dislike` flags [#717](https://github.com/Rigellute/spotify-tui/pull/717) - Add to config: `enforce_wide_search_bar` to make search bar bigger [#738](https://github.com/Rigellute/spotify-tui/pull/738) - Add Daily Drive to Made For You lists search [#743](https://github.com/Rigellute/spotify-tui/pull/743) -- Replace black and white default colors with reset [#742](https://github.com/Rigellute/spotify-tui/pull/742) ## [0.23.0] - 2021-01-06 diff --git a/Cargo.lock b/Cargo.lock index 9ec852b8..209754ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1923,7 +1923,7 @@ dependencies = [ [[package]] name = "spotify-tui" -version = "0.23.0" +version = "0.24.0" dependencies = [ "anyhow", "arboard", diff --git a/Cargo.toml b/Cargo.toml index a69ce934..1b4a2d81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ documentation = "https://github.com/Rigellute/spotify-tui" repository = "https://github.com/Rigellute/spotify-tui" keywords = ["spotify", "tui", "cli", "terminal"] categories = ["command-line-utilities"] -version = "0.23.0" +version = "0.24.0" authors = ["Alexander Keliris "] edition = "2018" license = "MIT OR Apache-2.0" From a86726ecb1b2a915290b9a476bdf6bea39540e2b Mon Sep 17 00:00:00 2001 From: Yuuki Takahashi <20282867+yktakaha4@users.noreply.github.com> Date: Mon, 26 Apr 2021 21:17:00 +0900 Subject: [PATCH 273/311] docs: client.yml file path in snap (#778) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 04e6e550..73d0dca9 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ But here they are again: And now you are ready to use the `spotify-tui` πŸŽ‰ -You can edit the config at anytime at `${HOME}/.config/spotify-tui/client.yml`. +You can edit the config at anytime at `${HOME}/.config/spotify-tui/client.yml`. (for snap `${HOME}/snap/spt/current/.config/spotify-tui/client.yml`) ## Usage From 6a999d81ee768b05fdaf1e2697b78cde2b8fd456 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 26 Apr 2021 13:17:32 +0100 Subject: [PATCH 274/311] docs: add yktakaha4 as a contributor (#802) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 555e1340..62556898 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -787,6 +787,15 @@ "contributions": [ "doc" ] + }, + { + "login": "yktakaha4", + "name": "Yuuki Takahashi", + "avatar_url": "https://avatars.githubusercontent.com/u/20282867?v=4", + "profile": "https://yktakaha4.github.io/", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 73d0dca9..22bf3987 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-85-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-86-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -442,6 +442,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Sang

πŸ“– +
Yuuki Takahashi

πŸ“– From 5884dd69da32634d3bc0ca063be2118714b26e29 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 23 Aug 2021 11:24:22 +0100 Subject: [PATCH 275/311] Fix clippy warnings after Rust upgrade (#858) --- .gitignore | 2 ++ src/app.rs | 4 +-- src/handlers/search_results.rs | 7 ++--- src/handlers/track_table.rs | 32 +++++++------------- src/network.rs | 5 +--- src/ui/mod.rs | 54 ++++++++++++++++++---------------- 6 files changed, 46 insertions(+), 58 deletions(-) diff --git a/.gitignore b/.gitignore index dcdf4a12..d242bf66 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ secrets.tar *.swp tags + +.idea \ No newline at end of file diff --git a/src/app.rs b/src/app.rs index 15770c96..ff7c08f2 100644 --- a/src/app.rs +++ b/src/app.rs @@ -779,7 +779,7 @@ impl App { } if let Some(saved_artists) = &self.library.saved_artists.get_results(None).cloned() { - self.set_saved_artists_to_table(&saved_artists); + self.set_saved_artists_to_table(saved_artists); } } @@ -810,7 +810,7 @@ impl App { } if let Some(saved_tracks) = &self.library.saved_tracks.get_results(None).cloned() { - self.set_saved_tracks_to_table(&saved_tracks); + self.set_saved_tracks_to_table(saved_tracks); } } diff --git a/src/handlers/search_results.rs b/src/handlers/search_results.rs index bd559fa9..0d4ac743 100644 --- a/src/handlers/search_results.rs +++ b/src/handlers/search_results.rs @@ -389,10 +389,9 @@ fn handle_recommended_tracks(app: &mut App) { if let Some(index) = &app.search_results.selected_tracks_index { if let Some(result) = app.search_results.tracks.clone() { if let Some(track) = result.items.get(index.to_owned()) { - let track_id_list: Option> = match &track.id { - Some(id) => Some(vec![id.to_string()]), - None => None, - }; + let track_id_list: Option> = + track.id.as_ref().map(|id| vec![id.to_string()]); + app.recommendations_context = Some(RecommendationsContext::Song); app.recommendations_seed = track.name.clone(); app.get_recommendations_for_seed(None, track_id_list, Some(track.clone())); diff --git a/src/handlers/track_table.rs b/src/handlers/track_table.rs index 08c9f165..4bffda26 100644 --- a/src/handlers/track_table.rs +++ b/src/handlers/track_table.rs @@ -267,10 +267,8 @@ fn handle_recommended_tracks(app: &mut App) { let (selected_index, tracks) = (&app.track_table.selected_index, &app.track_table.tracks); if let Some(track) = tracks.get(*selected_index) { let first_track = track.clone(); - let track_id_list: Option> = match &track.id { - Some(id) => Some(vec![id.to_string()]), - None => None, - }; + let track_id_list = track.id.as_ref().map(|id| vec![id.to_string()]); + app.recommendations_context = Some(RecommendationsContext::Song); app.recommendations_seed = first_track.name.clone(); app.get_recommendations_for_seed(None, track_id_list, Some(first_track)); @@ -321,14 +319,10 @@ fn on_enter(app: &mut App) { TrackTableContext::MyPlaylists => { if let Some(_track) = tracks.get(*selected_index) { let context_uri = match (&app.active_playlist_index, &app.playlists) { - (Some(active_playlist_index), Some(playlists)) => { - if let Some(selected_playlist) = playlists.items.get(active_playlist_index.to_owned()) - { - Some(selected_playlist.uri.to_owned()) - } else { - None - } - } + (Some(active_playlist_index), Some(playlists)) => playlists + .items + .get(active_playlist_index.to_owned()) + .map(|selected_playlist| selected_playlist.uri.to_owned()), _ => None, }; @@ -379,16 +373,10 @@ fn on_enter(app: &mut App) { &app.search_results.selected_playlists_index, &app.search_results.playlists, ) { - (Some(selected_playlist_index), Some(playlist_result)) => { - if let Some(selected_playlist) = playlist_result - .items - .get(selected_playlist_index.to_owned()) - { - Some(selected_playlist.uri.to_owned()) - } else { - None - } - } + (Some(selected_playlist_index), Some(playlist_result)) => playlist_result + .items + .get(selected_playlist_index.to_owned()) + .map(|selected_playlist| selected_playlist.uri.to_owned()), _ => None, }; diff --git a/src/network.rs b/src/network.rs index 96a747f1..e35a8d5c 100644 --- a/src/network.rs +++ b/src/network.rs @@ -1035,10 +1035,7 @@ impl<'a> Network<'a> { async fn get_recommendations_for_track_id(&mut self, id: String, country: Option) { if let Ok(track) = self.spotify.track(&id).await { - let track_id_list: Option> = match &track.id { - Some(id) => Some(vec![id.to_string()]), - None => None, - }; + let track_id_list = track.id.as_ref().map(|id| vec![id.to_string()]); self .get_recommendations_for_seed(None, track_id_list, Box::new(Some(track)), country) .await; diff --git a/src/ui/mod.rs b/src/ui/mod.rs index b2c712e4..a3cb0c1c 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -680,32 +680,34 @@ where ); let album_ui = match &app.album_table_context { - AlbumTableContext::Simplified => match &app.selected_album_simplified { - Some(selected_album_simplified) => Some(AlbumUi { - items: selected_album_simplified - .tracks - .items - .iter() - .map(|item| TableItem { - id: item.id.clone().unwrap_or_else(|| "".to_string()), - format: vec![ - "".to_string(), - item.track_number.to_string(), - item.name.to_owned(), - create_artist_string(&item.artists), - millis_to_minutes(u128::from(item.duration_ms)), - ], - }) - .collect::>(), - title: format!( - "{} by {}", - selected_album_simplified.album.name, - create_artist_string(&selected_album_simplified.album.artists) - ), - selected_index: selected_album_simplified.selected_index, - }), - None => None, - }, + AlbumTableContext::Simplified => { + app + .selected_album_simplified + .as_ref() + .map(|selected_album_simplified| AlbumUi { + items: selected_album_simplified + .tracks + .items + .iter() + .map(|item| TableItem { + id: item.id.clone().unwrap_or_else(|| "".to_string()), + format: vec![ + "".to_string(), + item.track_number.to_string(), + item.name.to_owned(), + create_artist_string(&item.artists), + millis_to_minutes(u128::from(item.duration_ms)), + ], + }) + .collect::>(), + title: format!( + "{} by {}", + selected_album_simplified.album.name, + create_artist_string(&selected_album_simplified.album.artists) + ), + selected_index: selected_album_simplified.selected_index, + }) + } AlbumTableContext::Full => match app.selected_album_full.clone() { Some(selected_album) => Some(AlbumUi { items: selected_album From 9179f3fbb9bb4f02e2cd0937e44a6528d85d63a7 Mon Sep 17 00:00:00 2001 From: Anton Kostin Date: Mon, 23 Aug 2021 17:29:28 +0700 Subject: [PATCH 276/311] Update LICENSE (#856) --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 96ae81b0..60d21aa9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Alexander Keliris +Copyright (c) 2021 Alexander Keliris Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 100feac945ba7a8dacc3414be40152cc4ba7c595 Mon Sep 17 00:00:00 2001 From: Alejandro Angulo <5242883+alejandro-angulo@users.noreply.github.com> Date: Mon, 23 Aug 2021 03:31:10 -0700 Subject: [PATCH 277/311] Fixed instant not being updated on empty responses (#852) Merging due to upstream clippy fixes --- src/network.rs | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/network.rs b/src/network.rs index e35a8d5c..6a58efba 100644 --- a/src/network.rs +++ b/src/network.rs @@ -346,21 +346,30 @@ impl<'a> Network<'a> { ) .await; - if let Ok(Some(c)) = context { - let mut app = self.app.lock().await; - app.current_playback_context = Some(c.clone()); - app.instant_since_last_current_playback_poll = Instant::now(); - - if let Some(item) = c.item { - match item { - PlayingItem::Track(track) => { - if let Some(track_id) = track.id { - app.dispatch(IoEvent::CurrentUserSavedTracksContains(vec![track_id])); - }; + match context { + Ok(Some(c)) => { + let mut app = self.app.lock().await; + app.current_playback_context = Some(c.clone()); + app.instant_since_last_current_playback_poll = Instant::now(); + + if let Some(item) = c.item { + match item { + PlayingItem::Track(track) => { + if let Some(track_id) = track.id { + app.dispatch(IoEvent::CurrentUserSavedTracksContains(vec![track_id])); + }; + } + PlayingItem::Episode(_episode) => { /*should map this to following the podcast show*/ } } - PlayingItem::Episode(_episode) => { /*should map this to following the podcast show*/ } - } - }; + }; + } + Ok(None) => { + let mut app = self.app.lock().await; + app.instant_since_last_current_playback_poll = Instant::now(); + } + Err(e) => { + self.handle_error(anyhow!(e)).await; + } } let mut app = self.app.lock().await; From c356a98c585f2c2c80843049bff765da9d221a7e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 11:34:54 +0100 Subject: [PATCH 278/311] docs: add masguit42 as a contributor for doc (#859) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 62556898..f4b789ad 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -796,6 +796,15 @@ "contributions": [ "doc" ] + }, + { + "login": "masguit42", + "name": "Anton Kostin", + "avatar_url": "https://avatars.githubusercontent.com/u/11005780?v=4", + "profile": "http://t.me/lego1as", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 22bf3987..c0114929 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-86-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-87-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -443,6 +443,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Sang

πŸ“–
Yuuki Takahashi

πŸ“– +
Anton Kostin

πŸ“– From 5f1840decb8d2d677c22d49842c9ad44a1405332 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 11:38:05 +0100 Subject: [PATCH 279/311] Bump serde from 1.0.125 to 1.0.127 (#847) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.125 to 1.0.127. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.125...v1.0.127) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 209754ff..7baa943e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1823,18 +1823,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.125" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" +checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.125" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" +checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", From ebf75d98a0b1bd331a33dbba2ddfb92a5a2936ce Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 11:41:05 +0100 Subject: [PATCH 280/311] docs: add alejandro-angulo as a contributor for code (#860) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Alexander Keliris --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index f4b789ad..52513e3b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -797,6 +797,15 @@ "doc" ] }, + { + "login": "alejandro-angulo", + "name": "Alejandro Angulo", + "avatar_url": "https://avatars.githubusercontent.com/u/5242883?v=4", + "profile": "https://alejandr0angul0.dev/", + "contributions": [ + "code" + ], + }, { "login": "masguit42", "name": "Anton Kostin", diff --git a/README.md b/README.md index c0114929..64bc1851 100644 --- a/README.md +++ b/README.md @@ -443,6 +443,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Sang

πŸ“–
Yuuki Takahashi

πŸ“– +
Alejandro Angulo

πŸ’»
Anton Kostin

πŸ“– From 84b29bb97f51c846b043867185681766d0093372 Mon Sep 17 00:00:00 2001 From: Justin Sexton Date: Mon, 23 Aug 2021 05:48:27 -0500 Subject: [PATCH 281/311] Fixed typo (#850) Overriding due to new clippy rules that are fixed in the upstream. These changes do not break the new rules. --- src/event/key.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/event/key.rs b/src/event/key.rs index d8336b16..10de642a 100644 --- a/src/event/key.rs +++ b/src/event/key.rs @@ -64,7 +64,7 @@ pub enum Key { Char(char), Ctrl(char), Alt(char), - Unkown, + Unknown, } impl Key { @@ -199,7 +199,7 @@ impl From for Key { .. } => Key::Char(c), - _ => Key::Unkown, + _ => Key::Unknown, } } } From f77049a152b3a2e7d55d44ceaffaa49702b55a32 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 23 Aug 2021 11:52:03 +0100 Subject: [PATCH 282/311] Fix bad all-contributors JSON --- .all-contributorsrc | 2 +- CHANGELOG.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 52513e3b..6e0b379e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -804,7 +804,7 @@ "profile": "https://alejandr0angul0.dev/", "contributions": [ "code" - ], + ] }, { "login": "masguit42", diff --git a/CHANGELOG.md b/CHANGELOG.md index 82d35fac..bc9df47a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +- Fixed rate limiting issue [#852](https://github.com/Rigellute/spotify-tui/pull/852) + ## [0.24.0] - 2021-04-26 ### Fixed From 57f8895b83faedd578f9b8a892d7014d3bdb4b7c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 11:52:42 +0100 Subject: [PATCH 283/311] docs: add JSextonn as a contributor for code (#861) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 6e0b379e..357902cb 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -814,6 +814,15 @@ "contributions": [ "doc" ] + }, + { + "login": "JSextonn", + "name": "Justin Sexton", + "avatar_url": "https://avatars.githubusercontent.com/u/20236003?v=4", + "profile": "https://justinsexton.net", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 64bc1851..5484350b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-87-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-89-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -445,6 +445,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Yuuki Takahashi

πŸ“–
Alejandro Angulo

πŸ’»
Anton Kostin

πŸ“– +
Justin Sexton

πŸ’» From ddb2525a0c51b2c9c188ae8861f6653152636eaa Mon Sep 17 00:00:00 2001 From: Jiati Le <6442124+lejiati@users.noreply.github.com> Date: Mon, 23 Aug 2021 03:52:49 -0700 Subject: [PATCH 284/311] Fix typo (#834) --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 177257c0..0c2622f5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -302,7 +302,7 @@ async fn start_ui(user_config: UserConfig, app: &Arc>) -> Result<()> )); // Based on the size of the terminal, adjust how many lines are - // dislayed in the help menu + // displayed in the help menu if app.size.height > 8 { app.help_menu_max_lines = (app.size.height as u32) - 8; } else { From 2a945e21fa02bc2279ff56ee84d67d37d737b0bf Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 11:55:04 +0100 Subject: [PATCH 285/311] docs: add lejiati as a contributor for doc (#862) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 357902cb..af7df57c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -823,6 +823,15 @@ "contributions": [ "code" ] + }, + { + "login": "lejiati", + "name": "Jiati Le", + "avatar_url": "https://avatars.githubusercontent.com/u/6442124?v=4", + "profile": "https://github.com/lejiati", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 5484350b..f6147fb4 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-89-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-90-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -446,6 +446,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Alejandro Angulo

πŸ’»
Anton Kostin

πŸ“–
Justin Sexton

πŸ’» +
Jiati Le

πŸ“– From 612656845ff996329120b409c55fe50bdca21517 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 23 Aug 2021 12:01:24 +0100 Subject: [PATCH 286/311] Add dependabot.yml The dependabot preview has now ended, so we need to explicitly enable with this file. --- .github/dependabot.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..4082571a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: "monthly" \ No newline at end of file From 67c647afe474ea3688b4411c0301406b45f5d7a5 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 12:07:48 +0100 Subject: [PATCH 287/311] Bump arboard from 1.1.0 to 1.2.0 (#780) Bumps [arboard](https://github.com/ArturKovacs/arboard) from 1.1.0 to 1.2.0. - [Release notes](https://github.com/ArturKovacs/arboard/releases) - [Changelog](https://github.com/ArturKovacs/arboard/blob/master/CHANGELOG.md) - [Commits](https://github.com/ArturKovacs/arboard/compare/v1.1.0...v1.2.0) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 51 ++++++++++++++++++++++++++++++++++++++++++--------- Cargo.toml | 2 +- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7baa943e..101b0c56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,22 +47,22 @@ checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" [[package]] name = "arboard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85149eb4159516fbc261f362153822672e4bdb5b3accc863a5777627c6d9fe72" +checksum = "c3ac39a01d5684967619a6755f3cfc397e5202b5f012d0954ac5016f4b2a33eb" dependencies = [ "clipboard-win", "core-graphics", "image", "lazy_static", - "libc", + "log", "objc", "objc-foundation", "objc_id", "scopeguard", "thiserror", "winapi 0.3.9", - "xcb", + "x11rb", ] [[package]] @@ -710,6 +710,16 @@ dependencies = [ "slab", ] +[[package]] +name = "gethostname" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e692e296bfac1d2533ef168d0b60ff5897b8b70a4009276834014dd8924cc028" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "getrandom" version = "0.1.14" @@ -1162,6 +1172,18 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "nix" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" +dependencies = [ + "bitflags", + "cc", + "cfg-if 1.0.0", + "libc", +] + [[package]] name = "ntapi" version = "0.3.4" @@ -2449,6 +2471,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "winapi-wsapoll" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c17110f57155602a80dca10be03852116403c9ff3cd25b079d666f2aa3df6e" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -2475,13 +2506,15 @@ dependencies = [ ] [[package]] -name = "xcb" -version = "0.9.0" +name = "x11rb" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62056f63138b39116f82a540c983cc11f1c90cd70b3d492a70c25eaa50bd22a6" +checksum = "6ffb080b3f2f616242a4eb8e7d325035312127901025b0052bc3154a282d0f19" dependencies = [ - "libc", - "log", + "gethostname", + "nix", + "winapi 0.3.9", + "winapi-wsapoll", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 1b4a2d81..16168e12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ dirs = "3.0.1" clap = "2.33.3" unicode-width = "0.1.8" backtrace = "0.3.56" -arboard = "1.1.0" +arboard = "1.2.0" crossterm = "0.19" tokio = { version = "0.2", features = ["full"] } rand = "0.8.3" From eba6390e5be1c787434904432f1934aa4073491e Mon Sep 17 00:00:00 2001 From: Matthew Cobbing Date: Mon, 23 Aug 2021 12:16:22 +0100 Subject: [PATCH 288/311] Pressing `d` twice requires `q` twice to exit (#826) * dedup selected device routes from nav stack * dedup any matching routes from nav stack * catch duplicate route id on push * remove return * remove id from variable name --- src/app.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/app.rs b/src/app.rs index ff7c08f2..4477c8b5 100644 --- a/src/app.rs +++ b/src/app.rs @@ -626,11 +626,18 @@ impl App { // The navigation_stack actually only controls the large block to the right of `library` and // `playlists` pub fn push_navigation_stack(&mut self, next_route_id: RouteId, next_active_block: ActiveBlock) { - self.navigation_stack.push(Route { - id: next_route_id, - active_block: next_active_block, - hovered_block: next_active_block, - }); + if !self + .navigation_stack + .last() + .map(|last_route| last_route.id == next_route_id) + .unwrap_or(false) + { + self.navigation_stack.push(Route { + id: next_route_id, + active_block: next_active_block, + hovered_block: next_active_block, + }); + } } pub fn pop_navigation_stack(&mut self) -> Option { From 8651e8c54769211df35ae5cc30db9c1ebe7b454c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 12:17:53 +0100 Subject: [PATCH 289/311] docs: add cobbinma as a contributor for code (#866) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index af7df57c..975f2e3b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -832,6 +832,15 @@ "contributions": [ "doc" ] + }, + { + "login": "cobbinma", + "name": "Matthew Cobbing", + "avatar_url": "https://avatars.githubusercontent.com/u/578718?v=4", + "profile": "https://github.com/cobbinma", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index f6147fb4..adb8c711 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-90-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-91-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -447,6 +447,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Anton Kostin

πŸ“–
Justin Sexton

πŸ’»
Jiati Le

πŸ“– +
Matthew Cobbing

πŸ’» From 605df49826909f698275eb65148c73237e75b1d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 12:18:58 +0100 Subject: [PATCH 290/311] Bump anyhow from 1.0.38 to 1.0.43 (#865) Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.38 to 1.0.43. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.38...1.0.43) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 101b0c56..e4844c7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,9 +41,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.38" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" +checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" [[package]] name = "arboard" diff --git a/Cargo.toml b/Cargo.toml index 16168e12..fd099cf9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ arboard = "1.2.0" crossterm = "0.19" tokio = { version = "0.2", features = ["full"] } rand = "0.8.3" -anyhow = "1.0.38" +anyhow = "1.0.43" [[bin]] bench = false From 379dc759fbe448ea70530e530ac1162e7f6d47b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 12:19:06 +0100 Subject: [PATCH 291/311] Bump serde from 1.0.127 to 1.0.128 (#864) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.127 to 1.0.128. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.127...v1.0.128) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e4844c7b..91cc6cb2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1845,18 +1845,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.127" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +checksum = "1056a0db1978e9dbf0f6e4fca677f6f9143dc1c19de346f22cac23e422196834" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.127" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +checksum = "13af2fbb8b60a8950d6c72a56d2095c28870367cc8e10c55e9745bac4995a2c4" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.7", From 86c40e22ddb8b2a2f32980006ae6157e8d7af0de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 12:19:12 +0100 Subject: [PATCH 292/311] Bump serde_yaml from 0.8.17 to 0.8.19 (#863) Bumps [serde_yaml](https://github.com/dtolnay/serde-yaml) from 0.8.17 to 0.8.19. - [Release notes](https://github.com/dtolnay/serde-yaml/releases) - [Commits](https://github.com/dtolnay/serde-yaml/compare/0.8.17...0.8.19) --- updated-dependencies: - dependency-name: serde_yaml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 91cc6cb2..34b49674 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1888,12 +1888,12 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.17" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15654ed4ab61726bf918a39cb8d98a2e2995b002387807fa6ba58fdf7f59bb23" +checksum = "6375dbd828ed6964c3748e4ef6d18e7a175d408ffe184bca01698d0c73f915a9" dependencies = [ "dtoa", - "linked-hash-map", + "indexmap", "serde", "yaml-rust", ] From 77f41dfc873e9e1070dbcc6adb3f778822ee573e Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 23 Aug 2021 12:21:53 +0100 Subject: [PATCH 293/311] Update README --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc9df47a..801d8e5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [Unreleased] - Fixed rate limiting issue [#852](https://github.com/Rigellute/spotify-tui/pull/852) +- Fix double navigation to same route [#826](https://github.com/Rigellute/spotify-tui/pull/826) ## [0.24.0] - 2021-04-26 From 1ef37e7551b05ffba8b0a1eed2132ff9b97a15a6 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Mon, 23 Aug 2021 15:24:41 +0100 Subject: [PATCH 294/311] Upgrade tui and crossterm deps (#867) --- Cargo.lock | 74 ++++++++++++++++++++---------------------------------- Cargo.toml | 4 +-- 2 files changed, 29 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34b49674..6e24cbe7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "addr2line" version = "0.14.1" @@ -65,12 +67,6 @@ dependencies = [ "x11rb", ] -[[package]] -name = "arc-swap" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" - [[package]] name = "arrayref" version = "0.3.6" @@ -357,50 +353,25 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e86d73f2a0b407b5768d10a8c720cf5d2df49a9efc10ca09176d201ead4b7fb" -dependencies = [ - "bitflags", - "crossterm_winapi 0.6.2", - "lazy_static", - "libc", - "mio 0.7.0", - "parking_lot", - "signal-hook", - "winapi 0.3.9", -] - -[[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 0.7.0", - "lazy_static", + "crossterm_winapi", "libc", "mio 0.7.0", "parking_lot", "signal-hook", + "signal-hook-mio", "winapi 0.3.9", ] [[package]] name = "crossterm_winapi" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2265c3f8e080075d9b6417aa72293fc71662f34b4af2612d8d1b074d29510db" -dependencies = [ - "winapi 0.3.9", -] - -[[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 0.3.9", ] @@ -1900,22 +1871,31 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.1.16" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604508c1418b99dfe1925ca9224829bb2a8a9a04dda655cc01fcad46f4ab05ed" +checksum = "470c5a6397076fae0094aaf06a08e6ba6f37acb77d3b1b91ea92b4d6c8650c39" dependencies = [ "libc", - "mio 0.7.0", "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 0.7.0", + "signal-hook", +] + [[package]] name = "signal-hook-registry" -version = "1.2.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" dependencies = [ - "arc-swap", "libc", ] @@ -1951,7 +1931,7 @@ dependencies = [ "arboard", "backtrace", "clap", - "crossterm 0.19.0", + "crossterm", "dirs", "rand 0.8.3", "rspotify", @@ -2209,13 +2189,13 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "tui" -version = "0.14.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ced152a8e9295a5b168adc254074525c17ac4a83c90b2716274cc38118bddc9" +checksum = "39c8ce4e27049eed97cfa363a5048b09d995e209994634a0efc26a14ab6c0c23" dependencies = [ "bitflags", "cassowary", - "crossterm 0.18.2", + "crossterm", "unicode-segmentation", "unicode-width", ] diff --git a/Cargo.toml b/Cargo.toml index fd099cf9..8db29413 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ license = "MIT OR Apache-2.0" [dependencies] rspotify = "0.10.0" -tui = { version = "0.14.0", features = ["crossterm"], default-features = false } +tui = { version = "0.16.0", features = ["crossterm"], default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" @@ -24,7 +24,7 @@ clap = "2.33.3" unicode-width = "0.1.8" backtrace = "0.3.56" arboard = "1.2.0" -crossterm = "0.19" +crossterm = "0.20" tokio = { version = "0.2", features = ["full"] } rand = "0.8.3" anyhow = "1.0.43" From cb70ea13439c795f1c74e8317140ce0333a5df27 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Tue, 24 Aug 2021 10:47:21 +0100 Subject: [PATCH 295/311] Fix help table The upgrade to `tui` seems to have changed the way constraints work slightly. --- src/ui/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/mod.rs b/src/ui/mod.rs index a3cb0c1c..02f26b4d 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -116,7 +116,7 @@ where .border_style(help_menu_style), ) .style(help_menu_style) - .widths(&[Constraint::Max(110)]); + .widths(&[Constraint::Percentage(100)]); f.render_widget(help_menu, chunks[0]); } From 9fa978e99518b144f2c45706af2e04401bac5972 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Tue, 24 Aug 2021 10:55:52 +0100 Subject: [PATCH 296/311] Prepare release 0.25.0 --- CHANGELOG.md | 4 ++++ Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 801d8e5f..c9b31f3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +## [0.25.0] - 2021-08-24 + +### Fixed + - Fixed rate limiting issue [#852](https://github.com/Rigellute/spotify-tui/pull/852) - Fix double navigation to same route [#826](https://github.com/Rigellute/spotify-tui/pull/826) diff --git a/Cargo.lock b/Cargo.lock index 6e24cbe7..fa129f0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1925,7 +1925,7 @@ dependencies = [ [[package]] name = "spotify-tui" -version = "0.24.0" +version = "0.25.0" dependencies = [ "anyhow", "arboard", diff --git a/Cargo.toml b/Cargo.toml index 8db29413..83499517 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ documentation = "https://github.com/Rigellute/spotify-tui" repository = "https://github.com/Rigellute/spotify-tui" keywords = ["spotify", "tui", "cli", "terminal"] categories = ["command-line-utilities"] -version = "0.24.0" +version = "0.25.0" authors = ["Alexander Keliris "] edition = "2018" license = "MIT OR Apache-2.0" From e483b572970c3348950ff6470cec4be6c328d7f7 Mon Sep 17 00:00:00 2001 From: Craig Astill Date: Fri, 1 Oct 2021 10:41:44 +0100 Subject: [PATCH 297/311] Feature/show album type in search panes (#869) * Added `album_type` in search panes. This updates the Album search panes to the format: ` - ()`, so that it is easier to find an `album` vs `single`. Issue: #868 * Added `CHANGELOG.md` note for `album_type` in Search panes. Issue: #868 * Added "unknown" for missing album types. Picked up from review by @sputnick1124 on PR #869 Issue: #868 --- CHANGELOG.md | 4 ++++ src/ui/mod.rs | 10 ++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9b31f3a..5ef0d892 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Added + +- Show `album_type` in Search panes [#868](https://github.com/Rigellute/spotify-tui/pull/868) + ## [0.25.0] - 2021-08-24 ### Fixed diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 02f26b4d..f679bfb8 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -470,9 +470,10 @@ where } } album_artist.push_str(&format!( - "{} - {}", + "{} - {} ({})", item.name.to_owned(), - create_artist_string(&item.artists) + create_artist_string(&item.artists), + item.album_type.as_deref().unwrap_or("unknown") )); album_artist }) @@ -1237,9 +1238,10 @@ where } } album_artist.push_str(&format!( - "{} - {}", + "{} - {} ({})", item.name.to_owned(), - create_artist_string(&item.artists) + create_artist_string(&item.artists), + item.album_type.as_deref().unwrap_or("unknown") )); album_artist }) From b4fbbbf1a554e16dd249eab65051a1b01be771b3 Mon Sep 17 00:00:00 2001 From: Milo <50248166+Milo123459@users.noreply.github.com> Date: Fri, 1 Oct 2021 10:44:50 +0100 Subject: [PATCH 298/311] cache (#890) --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a132cd56..ede9f5dc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,6 +48,7 @@ jobs: override: true # These dependencies are required for `clipboard` - run: sudo apt-get install -y -qq libxcb1-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev + - uses: Swatinem/rust-cache@v1 - uses: actions-rs/cargo@v1 with: command: test @@ -64,6 +65,7 @@ jobs: profile: minimal override: true components: rustfmt + - uses: Swatinem/rust-cache@v1 - uses: actions-rs/cargo@v1 with: command: fmt @@ -81,6 +83,7 @@ jobs: profile: minimal override: true components: clippy + - uses: Swatinem/rust-cache@v1 - uses: actions-rs/cargo@v1 with: command: clippy From e70bfad9a9a4c581e8bfeebcb98629703bb7a09c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 1 Oct 2021 10:45:25 +0100 Subject: [PATCH 299/311] docs: add Milo123459 as a contributor for infra (#895) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 975f2e3b..5e3863a6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -841,6 +841,15 @@ "contributions": [ "code" ] + }, + { + "login": "Milo123459", + "name": "Milo", + "avatar_url": "https://avatars.githubusercontent.com/u/50248166?v=4", + "profile": "https://milo123459.vercel.app", + "contributions": [ + "infra" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index adb8c711..8d90b770 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-91-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-92-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -449,6 +449,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Jiati Le

πŸ“–
Matthew Cobbing

πŸ’» + +
Milo

πŸš‡ + From c2434a302feef48e595f188630a6fbd203ace046 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Oct 2021 10:45:45 +0100 Subject: [PATCH 300/311] Bump serde_json from 1.0.64 to 1.0.67 (#875) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.64 to 1.0.67. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.64...v1.0.67) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa129f0a..83ffa7d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1836,9 +1836,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" dependencies = [ "itoa", "ryu", From 3881defc1ed0bcf79df1aef4836b857f64be657c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Oct 2021 10:46:03 +0100 Subject: [PATCH 301/311] Bump dirs from 3.0.1 to 3.0.2 (#876) Bumps [dirs](https://github.com/soc/dirs-rs) from 3.0.1 to 3.0.2. - [Release notes](https://github.com/soc/dirs-rs/releases) - [Commits](https://github.com/soc/dirs-rs/commits) --- updated-dependencies: - dependency-name: dirs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 90 ++++++++++++------------------------------------------ Cargo.toml | 2 +- 2 files changed, 21 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 83ffa7d8..33758085 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,18 +67,6 @@ dependencies = [ "x11rb", ] -[[package]] -name = "arrayref" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" - -[[package]] -name = "arrayvec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" - [[package]] name = "atty" version = "0.2.14" @@ -125,12 +113,6 @@ dependencies = [ "byteorder", ] -[[package]] -name = "base64" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" - [[package]] name = "base64" version = "0.12.3" @@ -143,17 +125,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -[[package]] -name = "blake2b_simd" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" -dependencies = [ - "arrayref", - "arrayvec", - "constant_time_eq", -] - [[package]] name = "block" version = "0.1.6" @@ -281,12 +252,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - [[package]] name = "core-foundation" version = "0.7.0" @@ -340,17 +305,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "crossbeam-utils" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -dependencies = [ - "autocfg 1.0.0", - "cfg-if 0.1.10", - "lazy_static", -] - [[package]] name = "crossterm" version = "0.20.0" @@ -448,18 +402,18 @@ dependencies = [ [[package]] name = "dirs" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "142995ed02755914747cc6ca76fc7e4583cd18578746716d0508ea6ed558b9ff" +checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" +checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" dependencies = [ "libc", "redox_users", @@ -1310,7 +1264,7 @@ dependencies = [ "cloudabi 0.1.0", "instant", "libc", - "redox_syscall", + "redox_syscall 0.1.57", "smallvec", "winapi 0.3.9", ] @@ -1645,15 +1599,23 @@ version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" -version = "0.3.4" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" dependencies = [ - "getrandom 0.1.14", - "redox_syscall", - "rust-argon2", + "getrandom 0.2.2", + "redox_syscall 0.2.10", ] [[package]] @@ -1745,18 +1707,6 @@ dependencies = [ "webbrowser", ] -[[package]] -name = "rust-argon2" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" -dependencies = [ - "base64 0.11.0", - "blake2b_simd", - "constant_time_eq", - "crossbeam-utils", -] - [[package]] name = "rustc-demangle" version = "0.1.16" @@ -1919,7 +1869,7 @@ checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" dependencies = [ "cfg-if 0.1.10", "libc", - "redox_syscall", + "redox_syscall 0.1.57", "winapi 0.3.9", ] @@ -2004,7 +1954,7 @@ dependencies = [ "cfg-if 0.1.10", "libc", "rand 0.7.3", - "redox_syscall", + "redox_syscall 0.1.57", "remove_dir_all", "winapi 0.3.9", ] diff --git a/Cargo.toml b/Cargo.toml index 83499517..b5466d6a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ tui = { version = "0.16.0", features = ["crossterm"], default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.8" -dirs = "3.0.1" +dirs = "3.0.2" clap = "2.33.3" unicode-width = "0.1.8" backtrace = "0.3.56" From 04de85343dfa3b1a5721a0871dae302821c364b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Oct 2021 10:46:15 +0100 Subject: [PATCH 302/311] Bump serde_yaml from 0.8.19 to 0.8.20 (#877) Bumps [serde_yaml](https://github.com/dtolnay/serde-yaml) from 0.8.19 to 0.8.20. - [Release notes](https://github.com/dtolnay/serde-yaml/releases) - [Commits](https://github.com/dtolnay/serde-yaml/compare/0.8.19...0.8.20) --- updated-dependencies: - dependency-name: serde_yaml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33758085..b5fd7195 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1809,9 +1809,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6375dbd828ed6964c3748e4ef6d18e7a175d408ffe184bca01698d0c73f915a9" +checksum = "ad104641f3c958dab30eb3010e834c2622d1f3f4c530fef1dee20ad9485f3c09" dependencies = [ "dtoa", "indexmap", From 93fd30fa55accc3df6f1c1548de28c5465b97074 Mon Sep 17 00:00:00 2001 From: Diego Veralli Date: Fri, 1 Oct 2021 11:47:33 +0200 Subject: [PATCH 303/311] Add option to set window title to "spt - Spotify TUI" on startup (#844) --- README.md | 2 ++ src/main.rs | 11 +++++++++-- src/user_config.rs | 7 +++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8d90b770..8109b7c5 100644 --- a/README.md +++ b/README.md @@ -254,6 +254,8 @@ behavior: repeat_context_icon: πŸ” playing_icon: β–Ά paused_icon: ⏸ + # Sets the window title to "spt - Spotify TUI" via ANSI escape code. + set_window_title: true keybindings: # Key stroke can be used if it only uses two keys: diff --git a/src/main.rs b/src/main.rs index 0c2622f5..a7c85ef1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,9 @@ use crossterm::{ event::{DisableMouseCapture, EnableMouseCapture}, execute, style::Print, - terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, + terminal::{ + disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen, SetTitle, + }, ExecutableCommand, }; use network::{get_spotify, IoEvent, Network}; @@ -268,7 +270,12 @@ async fn start_ui(user_config: UserConfig, app: &Arc>) -> Result<()> execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?; enable_raw_mode()?; - let backend = CrosstermBackend::new(stdout); + let mut backend = CrosstermBackend::new(stdout); + + if user_config.behavior.set_window_title { + backend.execute(SetTitle("spt - Spotify TUI"))?; + } + let mut terminal = Terminal::new(backend)?; terminal.hide_cursor()?; diff --git a/src/user_config.rs b/src/user_config.rs index e7d2bfb3..d5ed3b36 100644 --- a/src/user_config.rs +++ b/src/user_config.rs @@ -219,6 +219,7 @@ pub struct BehaviorConfigString { pub repeat_context_icon: Option, pub playing_icon: Option, pub paused_icon: Option, + pub set_window_title: Option, } #[derive(Clone)] @@ -235,6 +236,7 @@ pub struct BehaviorConfig { pub repeat_context_icon: String, pub playing_icon: String, pub paused_icon: String, + pub set_window_title: bool, } #[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -297,6 +299,7 @@ impl UserConfig { repeat_context_icon: "πŸ”".to_string(), playing_icon: "β–Ά".to_string(), paused_icon: "⏸".to_string(), + set_window_title: true, }, path_to_config: None, } @@ -454,6 +457,10 @@ impl UserConfig { self.behavior.repeat_context_icon = repeat_context_icon; } + if let Some(set_window_title) = behavior_config.set_window_title { + self.behavior.set_window_title = set_window_title; + } + Ok(()) } From 451be07710315633471fa96e1f0f75c5fd24b547 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 1 Oct 2021 10:48:02 +0100 Subject: [PATCH 304/311] docs: add diegov as a contributor for code (#897) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 5e3863a6..2005a95c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -850,6 +850,15 @@ "contributions": [ "infra" ] + }, + { + "login": "diegov", + "name": "Diego Veralli", + "avatar_url": "https://avatars.githubusercontent.com/u/297206?v=4", + "profile": "https://www.diegoveralli.com", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 8109b7c5..219b5bb1 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-92-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-93-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -453,6 +453,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Milo

πŸš‡ +
Diego Veralli

πŸ’» From 4680eac9b8a09026b2a1c77bb94275a766b7439e Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Fri, 1 Oct 2021 10:49:05 +0100 Subject: [PATCH 305/311] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ef0d892..968c253b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Added - Show `album_type` in Search panes [#868](https://github.com/Rigellute/spotify-tui/pull/868) +- Add option to set window title to "spt - Spotify TUI" on startup [#844](https://github.com/Rigellute/spotify-tui/pull/844) ## [0.25.0] - 2021-08-24 From 243a50a68aad02264de2944da43346c7b46f4f7a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Oct 2021 10:53:05 +0100 Subject: [PATCH 306/311] Bump rand from 0.8.3 to 0.8.4 (#878) Bumps [rand](https://github.com/rust-random/rand) from 0.8.3 to 0.8.4. - [Release notes](https://github.com/rust-random/rand/releases) - [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-random/rand/compare/0.8.3...0.8.4) --- updated-dependencies: - dependency-name: rand dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b5fd7195..e5d5a348 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1425,9 +1425,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", "rand_chacha 0.3.0", @@ -1883,7 +1883,7 @@ dependencies = [ "clap", "crossterm", "dirs", - "rand 0.8.3", + "rand 0.8.4", "rspotify", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index b5466d6a..82f031fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ backtrace = "0.3.56" arboard = "1.2.0" crossterm = "0.20" tokio = { version = "0.2", features = ["full"] } -rand = "0.8.3" +rand = "0.8.4" anyhow = "1.0.43" [[bin]] From 054b248c662b1bdccf387218b7cbfed02f9f10ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Oct 2021 10:53:20 +0100 Subject: [PATCH 307/311] Bump backtrace from 0.3.56 to 0.3.57 (#879) Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.56 to 0.3.57. - [Release notes](https://github.com/rust-lang/backtrace-rs/releases) - [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.56...0.3.57) --- updated-dependencies: - dependency-name: backtrace dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e5d5a348..a50e2f96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -92,9 +92,9 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.56" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d117600f438b1707d4e4ae15d3595657288f8235a0eb593e80ecc98ab34e1bc" +checksum = "78ed203b9ba68b242c62b3fb7480f589dd49829be1edb3fe8fc8b4ffda2dcb8d" dependencies = [ "addr2line", "cfg-if 1.0.0", @@ -906,9 +906,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.82" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929" +checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" [[package]] name = "linked-hash-map" diff --git a/Cargo.toml b/Cargo.toml index 82f031fd..aacc2937 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ serde_yaml = "0.8" dirs = "3.0.2" clap = "2.33.3" unicode-width = "0.1.8" -backtrace = "0.3.56" +backtrace = "0.3.57" arboard = "1.2.0" crossterm = "0.20" tokio = { version = "0.2", features = ["full"] } From ecddb5eb4fb441bf46075d44cf12cd2294a251c7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Oct 2021 10:57:34 +0100 Subject: [PATCH 308/311] Bump serde_yaml from 0.8.20 to 0.8.21 (#896) Bumps [serde_yaml](https://github.com/dtolnay/serde-yaml) from 0.8.20 to 0.8.21. - [Release notes](https://github.com/dtolnay/serde-yaml/releases) - [Commits](https://github.com/dtolnay/serde-yaml/compare/0.8.20...0.8.21) --- updated-dependencies: - dependency-name: serde_yaml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a50e2f96..a6c08281 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1809,9 +1809,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad104641f3c958dab30eb3010e834c2622d1f3f4c530fef1dee20ad9485f3c09" +checksum = "d8c608a35705a5d3cdc9fbe403147647ff34b921f8e833e49306df898f9b20af" dependencies = [ "dtoa", "indexmap", From 7550d6ebd51c20bc1188540698a38b112927391b Mon Sep 17 00:00:00 2001 From: Maja Bojarska Date: Wed, 17 Nov 2021 21:26:52 +0100 Subject: [PATCH 309/311] Fix confirmation dialog handling on playlist delete. (#910) * Fix playlist deletion handling. * Refactor get_current_user_saved_artists_next. --- src/app.rs | 10 +++------- src/handlers/common_key_events.rs | 1 + src/handlers/playlist.rs | 8 +++++--- src/handlers/search_results.rs | 6 ++++-- src/ui/mod.rs | 1 + 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/app.rs b/src/app.rs index 4477c8b5..d7af0fc7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -158,6 +158,7 @@ pub enum RouteId { Podcasts, PodcastEpisodes, Recommendations, + Dialog, } #[derive(Debug)] @@ -767,13 +768,8 @@ impl App { } None => { if let Some(saved_artists) = &self.library.saved_artists.clone().get_results(None) { - match saved_artists.items.last() { - Some(last_artist) => { - self.dispatch(IoEvent::GetFollowedArtists(Some(last_artist.id.clone()))); - } - None => { - return; - } + if let Some(last_artist) = saved_artists.items.last() { + self.dispatch(IoEvent::GetFollowedArtists(Some(last_artist.id.clone()))); } } } diff --git a/src/handlers/common_key_events.rs b/src/handlers/common_key_events.rs index f1c2b3fc..f9097122 100644 --- a/src/handlers/common_key_events.rs +++ b/src/handlers/common_key_events.rs @@ -134,6 +134,7 @@ pub fn handle_right_event(app: &mut App) { RouteId::Error => {} RouteId::Analysis => {} RouteId::BasicView => {} + RouteId::Dialog => {} }, _ => {} }; diff --git a/src/handlers/playlist.rs b/src/handlers/playlist.rs index f88caea5..76f43b07 100644 --- a/src/handlers/playlist.rs +++ b/src/handlers/playlist.rs @@ -2,7 +2,7 @@ use super::{ super::app::{App, DialogContext, TrackTableContext}, common_key_events, }; -use crate::app::ActiveBlock; +use crate::app::{ActiveBlock, RouteId}; use crate::event::Key; use crate::network::IoEvent; @@ -78,8 +78,10 @@ pub fn handler(key: Key, app: &mut App) { app.dialog = Some(selected_playlist.clone()); app.confirm = false; - let route = app.get_current_route().id.clone(); - app.push_navigation_stack(route, ActiveBlock::Dialog(DialogContext::PlaylistWindow)); + app.push_navigation_stack( + RouteId::Dialog, + ActiveBlock::Dialog(DialogContext::PlaylistWindow), + ); } } _ => {} diff --git a/src/handlers/search_results.rs b/src/handlers/search_results.rs index 0d4ac743..c87dacee 100644 --- a/src/handlers/search_results.rs +++ b/src/handlers/search_results.rs @@ -527,8 +527,10 @@ pub fn handler(key: Key, app: &mut App) { app.dialog = Some(selected_playlist.clone()); app.confirm = false; - let route = app.get_current_route().id.clone(); - app.push_navigation_stack(route, ActiveBlock::Dialog(DialogContext::PlaylistSearch)); + app.push_navigation_stack( + RouteId::Dialog, + ActiveBlock::Dialog(DialogContext::PlaylistSearch), + ); } } SearchResultBlock::ShowSearch => app.user_unfollow_show(ActiveBlock::SearchResultBlock), diff --git a/src/ui/mod.rs b/src/ui/mod.rs index f679bfb8..83723571 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -276,6 +276,7 @@ where RouteId::SelectedDevice => {} // This is handled as a "full screen" route in main.rs RouteId::Analysis => {} // This is handled as a "full screen" route in main.rs RouteId::BasicView => {} // This is handled as a "full screen" route in main.rs + RouteId::Dialog => {} // This is handled in the draw_dialog function in mod.rs }; } From 6db38fb19b72b7c2e32482deb9bbe76989f3b5a4 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 17 Nov 2021 20:27:31 +0000 Subject: [PATCH 310/311] docs: add majabojarska as a contributor for code (#916) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 2005a95c..b25e946b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -859,6 +859,15 @@ "contributions": [ "code" ] + }, + { + "login": "majabojarska", + "name": "Maja Bojarska", + "avatar_url": "https://avatars.githubusercontent.com/u/33836570?v=4", + "profile": "https://github.com/majabojarska", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 219b5bb1..51145a31 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![](https://img.shields.io/github/v/release/Rigellute/spotify-tui?color=%23c694ff) -[![All Contributors](https://img.shields.io/badge/all_contributors-93-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-94-orange.svg?style=flat-square)](#contributors-) [![Follow Alexander Keliris (Rigellute)](https://img.shields.io/twitter/follow/AlexKeliris?label=Follow%20Alexander%20Keliris%20%28Rigellute%29&style=social)](https://twitter.com/intent/follow?screen_name=AlexKeliris) @@ -454,6 +454,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Milo

πŸš‡
Diego Veralli

πŸ’» +
Maja Bojarska

πŸ’» From c4dcf6b9fd8318017acbdd7ec005955e26cf2794 Mon Sep 17 00:00:00 2001 From: Alexander Keliris Date: Wed, 17 Nov 2021 20:29:15 +0000 Subject: [PATCH 311/311] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 968c253b..4d0299ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +- Fix confirmation dialog handling on playlist delete [#910](https://github.com/Rigellute/spotify-tui/pull/910) + ### Added - Show `album_type` in Search panes [#868](https://github.com/Rigellute/spotify-tui/pull/868)