diff --git a/psst-gui/src/data/mod.rs b/psst-gui/src/data/mod.rs index 76f8067c..a23db90a 100644 --- a/psst-gui/src/data/mod.rs +++ b/psst-gui/src/data/mod.rs @@ -133,9 +133,10 @@ impl AppState { }, home_detail: HomeDetail { made_for_you: Promise::Empty, + user_top_mixes: Promise::Empty, + jump_back_in: Promise::Empty, user_top_tracks: Promise::Empty, user_top_artists: Promise::Empty, - made_for_x_hub: Promise::Empty, }, album_detail: AlbumDetail { album: Promise::Empty, @@ -516,10 +517,11 @@ pub type WithCtx = Ctx, T>; #[derive(Clone, Data, Lens)] pub struct HomeDetail { - pub made_for_you: Promise>, + pub made_for_you: Promise, + pub user_top_mixes: Promise, + pub jump_back_in: Promise, pub user_top_tracks: Promise>>, pub user_top_artists: Promise>, - pub made_for_x_hub: Promise, } #[derive(Clone, Data, Lens)] diff --git a/psst-gui/src/ui/home.rs b/psst-gui/src/ui/home.rs index 25bd928e..52b8a744 100644 --- a/psst-gui/src/ui/home.rs +++ b/psst-gui/src/ui/home.rs @@ -24,7 +24,11 @@ pub fn home_widget() -> impl Widget { Flex::column() .with_child(Label::new("Made for you").with_text_size(theme::grid(2.5)).align_left().padding((theme::grid(1.5), 0.0))) .with_default_spacer() - .with_child(results_widget()) + .with_child(made_for_you()) + .with_default_spacer() + .with_child(Label::new("Your top mixes").with_text_size(theme::grid(2.5)).align_left().padding((theme::grid(1.5), 0.0))) + .with_default_spacer() + .with_child(user_top_mixes()) .with_default_spacer() .with_child(Label::new("Your top artists").with_text_size(theme::grid(2.5)).align_left().padding((theme::grid(1.5), 0.0))) .with_default_spacer() @@ -35,24 +39,46 @@ pub fn home_widget() -> impl Widget { .with_child(user_top_tracks_widget()) } -pub fn results_widget() -> impl Widget { +pub fn made_for_you() -> impl Widget { Async::new( spinner_widget, - loaded_results_widget, + loaded_results_widget.clone(), error_widget, ) .lens( Ctx::make( AppState::common_ctx, - AppState::home_detail.then(HomeDetail::made_for_x_hub), + AppState::home_detail.then(HomeDetail::made_for_you), ) .then(Ctx::in_promise()), ) .on_command_async( LOAD_MADE_FOR_YOU, |q| WebApi::global().get_made_for_you(), - |_, data, q| data.home_detail.made_for_x_hub.defer(q), - |_, data, r| data.home_detail.made_for_x_hub.update(r), + |_, data, q| data.home_detail.made_for_you.defer(q), + |_, data, r| data.home_detail.made_for_you.update(r), + ) +} + +pub fn user_top_mixes() -> impl Widget { + // We need a way to parse HTML + Async::new( + spinner_widget, + loaded_results_widget.clone(), + error_widget, + ) + .lens( + Ctx::make( + AppState::common_ctx, + AppState::home_detail.then(HomeDetail::user_top_mixes), + ) + .then(Ctx::in_promis_e()), + ) + .on_command_async( + LOAD_MADE_FOR_YOU, + || WebApi::global().get_top_mixes(), + |_, data, q| data.home_detail.user_top_mixes.defer(q), + |_, data, r| data.home_detail.user_top_mixes.update(r), ) } diff --git a/psst-gui/src/webapi/client.rs b/psst-gui/src/webapi/client.rs index f313384d..b05bc898 100644 --- a/psst-gui/src/webapi/client.rs +++ b/psst-gui/src/webapi/client.rs @@ -877,7 +877,6 @@ impl WebApi { pub fn get_made_for_you(&self) -> Result { // 0JQ5DAUnp4wcj0bCb3wh3S -> Daily mixes - // 0JQ5DAnM3wGh0gz1MXnu89 -> Top mixes let json_query = self.build_home_request("spotify:section:0JQ5DAUnp4wcj0bCb3wh3S"); let request = self.get("pathfinder/v1/query", Some("api-partner.spotify.com"))? .query("operationName", "homeSection") @@ -889,7 +888,36 @@ impl WebApi { Ok(result) } + + pub fn get_top_mixes(&self) -> Result { + // 0JQ5DAnM3wGh0gz1MXnu89 -> Top mixes + let json_query = self.build_home_request("spotify:section:0JQ5DAnM3wGh0gz1MXnu89"); + let request = self.get("pathfinder/v1/query", Some("api-partner.spotify.com"))? + .query("operationName", "homeSection") + .query("variables", &json_query.0.to_string()) + .query("extensions", &json_query.1.to_string()); + + // Extract the playlists + let result = self.load_and_return_home_section(request)?; + + Ok(result) + } + + pub fn jump_back_in(&self) -> Result { + // 0JQ5DAIiKWzVFULQfUm85X -> Jump back in + // This is where we need to get the laod and return to return everything!!! + let json_query = self.build_home_request("spotify:section:0JQ5DAIiKWzVFULQfUm85X"); + let request = self.get("pathfinder/v1/query", Some("api-partner.spotify.com"))? + .query("operationName", "homeSection") + .query("variables", &json_query.0.to_string()) + .query("extensions", &json_query.1.to_string()); + // Extract the playlists + let result = self.load_and_return_home_section(request)?; + + Ok(result) + } + pub fn podcasts_and_more(&self) -> Result, Error> { #[derive(Deserialize)] struct View {