* chore(deps): bump the cargo group with 8 updates Bumps the cargo group with 8 updates: | Package | From | To | | --- | --- | --- | | [clap](https://github.com/clap-rs/clap) | `4.4.11` | `4.4.12` | | [crossbeam-channel](https://github.com/crossbeam-rs/crossbeam) | `0.5.9` | `0.5.10` | | [futures](https://github.com/rust-lang/futures-rs) | `0.3.29` | `0.3.30` | | [reqwest](https://github.com/seanmonstar/reqwest) | `0.11.22` | `0.11.23` | | [serde_json](https://github.com/serde-rs/json) | `1.0.108` | `1.0.109` | | [tokio](https://github.com/tokio-rs/tokio) | `1.35.0` | `1.35.1` | | [clap_mangen](https://github.com/clap-rs/clap) | `0.2.15` | `0.2.16` | | [clap_complete](https://github.com/clap-rs/clap) | `4.4.4` | `4.4.5` | Updates `clap` from 4.4.11 to 4.4.12 - [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/compare/v4.4.11...v4.4.12) Updates `crossbeam-channel` from 0.5.9 to 0.5.10 - [Release notes](https://github.com/crossbeam-rs/crossbeam/releases) - [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md) - [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-channel-0.5.9...crossbeam-channel-0.5.10) Updates `futures` from 0.3.29 to 0.3.30 - [Release notes](https://github.com/rust-lang/futures-rs/releases) - [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.29...0.3.30) Updates `reqwest` from 0.11.22 to 0.11.23 - [Release notes](https://github.com/seanmonstar/reqwest/releases) - [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md) - [Commits](https://github.com/seanmonstar/reqwest/compare/v0.11.22...v0.11.23) Updates `serde_json` from 1.0.108 to 1.0.109 - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.108...v1.0.109) Updates `tokio` from 1.35.0 to 1.35.1 - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.35.0...tokio-1.35.1) Updates `clap_mangen` from 0.2.15 to 0.2.16 - [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/compare/clap_mangen-v0.2.15...clap_mangen-v0.2.16) Updates `clap_complete` from 4.4.4 to 4.4.5 - [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/compare/clap_complete-v4.4.4...clap_complete-v4.4.5) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: crossbeam-channel dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: futures dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: reqwest dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: tokio dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: clap_mangen dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: clap_complete dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo ... Signed-off-by: dependabot[bot] <support@github.com> * Use `.first()` instead of `.get(0)` * Update dependencies --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Henrik Friedrichsen <henrik@affekt.org>
167 lines
4.3 KiB
Rust
167 lines
4.3 KiB
Rust
use crate::library::Library;
|
|
use crate::model::episode::Episode;
|
|
use crate::model::playable::Playable;
|
|
use crate::queue::Queue;
|
|
use crate::spotify::Spotify;
|
|
use crate::traits::{IntoBoxedViewExt, ListItem, ViewExt};
|
|
use crate::ui::show::ShowView;
|
|
use rspotify::model::show::{FullShow, SimplifiedShow};
|
|
use rspotify::model::Id;
|
|
use std::fmt;
|
|
use std::sync::Arc;
|
|
|
|
#[derive(Clone, Deserialize, Serialize)]
|
|
pub struct Show {
|
|
pub id: String,
|
|
pub uri: String,
|
|
pub name: String,
|
|
pub publisher: String,
|
|
pub description: String,
|
|
pub cover_url: Option<String>,
|
|
pub episodes: Option<Vec<Episode>>,
|
|
}
|
|
|
|
impl Show {
|
|
pub fn load_all_episodes(&mut self, spotify: Spotify) {
|
|
if self.episodes.is_some() {
|
|
return;
|
|
}
|
|
|
|
let episodes_result = spotify.api.show_episodes(&self.id);
|
|
while !episodes_result.at_end() {
|
|
episodes_result.next();
|
|
}
|
|
|
|
let episodes = episodes_result.items.read().unwrap().clone();
|
|
self.episodes = Some(episodes);
|
|
}
|
|
}
|
|
|
|
impl From<&SimplifiedShow> for Show {
|
|
fn from(show: &SimplifiedShow) -> Self {
|
|
Self {
|
|
id: show.id.id().to_string(),
|
|
uri: show.id.uri(),
|
|
name: show.name.clone(),
|
|
publisher: show.publisher.clone(),
|
|
description: show.description.clone(),
|
|
cover_url: show.images.first().map(|i| i.url.clone()),
|
|
episodes: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&FullShow> for Show {
|
|
fn from(show: &FullShow) -> Self {
|
|
Self {
|
|
id: show.id.id().to_string(),
|
|
uri: show.id.uri(),
|
|
name: show.name.clone(),
|
|
publisher: show.publisher.clone(),
|
|
description: show.description.clone(),
|
|
cover_url: show.images.first().map(|i| i.url.clone()),
|
|
episodes: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Show {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
write!(f, "{} - {}", self.publisher, self.name)
|
|
}
|
|
}
|
|
|
|
impl ListItem for Show {
|
|
fn is_playing(&self, _queue: &Queue) -> bool {
|
|
false
|
|
}
|
|
|
|
fn display_left(&self, _library: &Library) -> String {
|
|
format!("{self}")
|
|
}
|
|
|
|
fn display_right(&self, library: &Library) -> String {
|
|
let saved = if library.is_saved_show(self) {
|
|
if library.cfg.values().use_nerdfont.unwrap_or(false) {
|
|
"\u{f012c} "
|
|
} else {
|
|
"✓ "
|
|
}
|
|
} else {
|
|
""
|
|
};
|
|
saved.to_owned()
|
|
}
|
|
|
|
fn play(&mut self, queue: &Queue) {
|
|
self.load_all_episodes(queue.get_spotify());
|
|
|
|
let playables = self
|
|
.episodes
|
|
.as_ref()
|
|
.unwrap_or(&Vec::new())
|
|
.iter()
|
|
.map(|ep| Playable::Episode(ep.clone()))
|
|
.collect();
|
|
|
|
let index = queue.append_next(&playables);
|
|
queue.play(index, true, true);
|
|
}
|
|
|
|
fn play_next(&mut self, queue: &Queue) {
|
|
self.load_all_episodes(queue.get_spotify());
|
|
|
|
if let Some(episodes) = self.episodes.as_ref() {
|
|
for ep in episodes.iter().rev() {
|
|
queue.insert_after_current(Playable::Episode(ep.clone()));
|
|
}
|
|
}
|
|
}
|
|
|
|
fn queue(&mut self, queue: &Queue) {
|
|
self.load_all_episodes(queue.get_spotify());
|
|
|
|
for ep in self.episodes.as_ref().unwrap_or(&Vec::new()) {
|
|
queue.append(Playable::Episode(ep.clone()));
|
|
}
|
|
}
|
|
|
|
fn toggle_saved(&mut self, library: &Library) {
|
|
if library.is_saved_show(self) {
|
|
self.unsave(library);
|
|
} else {
|
|
self.save(library);
|
|
}
|
|
}
|
|
|
|
fn save(&mut self, library: &Library) {
|
|
library.save_show(self);
|
|
}
|
|
|
|
fn unsave(&mut self, library: &Library) {
|
|
library.unsave_show(self);
|
|
}
|
|
|
|
fn open(&self, queue: Arc<Queue>, library: Arc<Library>) -> Option<Box<dyn ViewExt>> {
|
|
Some(ShowView::new(queue, library, self).into_boxed_view_ext())
|
|
}
|
|
|
|
fn share_url(&self) -> Option<String> {
|
|
Some(format!("https://open.spotify.com/show/{}", self.id))
|
|
}
|
|
|
|
#[inline]
|
|
fn is_saved(&self, library: &Library) -> Option<bool> {
|
|
Some(library.is_saved_show(self))
|
|
}
|
|
|
|
#[inline]
|
|
fn is_playable(&self) -> bool {
|
|
true
|
|
}
|
|
|
|
fn as_listitem(&self) -> Box<dyn ListItem> {
|
|
Box::new(self.clone())
|
|
}
|
|
}
|