Skip to content

Commit

Permalink
Rewrite the context page state's structure (#25)
Browse files Browse the repository at this point in the history
## Brief description of changes

- use `PageState::Context` as a combination of `PageState::Browsing`, `PageState::CurrentPlaying`
- handle window state update logic and context data request logic in the `ui::handle_page_state_change` function
  • Loading branch information
aome510 authored Oct 31, 2021
1 parent f2d85f8 commit 166407f
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 250 deletions.
13 changes: 9 additions & 4 deletions spotify_player/src/event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ fn handle_key_event(
match ui.current_page() {
PageState::Library => {
drop(ui);
window::handle_key_sequence_for_library_window(&key_sequence, send, state)?
window::handle_key_sequence_for_library_window(&key_sequence, state)?
}
PageState::Recommendations(..) => {
drop(ui);
Expand All @@ -131,7 +131,7 @@ fn handle_key_event(
state,
)?
}
PageState::Browsing(_) | PageState::CurrentPlaying => {
PageState::Context(..) => {
drop(ui);
window::handle_key_sequence_for_context_window(&key_sequence, send, state)?
}
Expand Down Expand Up @@ -228,7 +228,7 @@ fn handle_global_command(
}
}
Command::BrowsePlayingContext => {
ui.create_new_page(PageState::CurrentPlaying);
ui.create_new_page(PageState::Context(None, ContextPageType::CurrentPlaying));
}
Command::BrowseUserPlaylists => {
send.send(ClientRequest::GetUserPlaylists)?;
Expand All @@ -253,13 +253,18 @@ fn handle_global_command(
input: "".to_owned(),
current_query: "".to_owned(),
});
ui.window = WindowState::new_search_state();
}
Command::PreviousPage => {
if ui.history.len() > 1 {
ui.history.pop();
ui.popup = None;
ui.window = WindowState::Unknown;

// empty the previous page's `context_id` to force
// updating the context page's window state and requesting the context data
if let PageState::Context(ref mut context_id, _) = ui.current_page_mut() {
*context_id = None;
}
}
}
Command::SwitchDevice => {
Expand Down
35 changes: 15 additions & 20 deletions spotify_player/src/event/popup.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{command::Action, utils::new_table_state};
use crate::command::Action;

use super::*;

Expand Down Expand Up @@ -31,8 +31,10 @@ pub fn handle_key_sequence_for_popup(
};

let context_id = ContextId::Artist(artists[id].id.clone());
send.send(ClientRequest::GetContext(context_id.clone()))?;
ui.create_new_page(PageState::Browsing(context_id));
ui.create_new_page(PageState::Context(
None,
ContextPageType::Browsing(context_id),
));

Ok(())
},
Expand All @@ -56,7 +58,6 @@ pub fn handle_key_sequence_for_popup(
drop(ui);
handle_key_sequence_for_context_browsing_list_popup(
key_sequence,
send,
state,
playlist_uris,
rspotify_model::Type::Playlist,
Expand Down Expand Up @@ -116,7 +117,6 @@ pub fn handle_key_sequence_for_popup(
drop(ui);
handle_key_sequence_for_context_browsing_list_popup(
key_sequence,
send,
state,
artist_uris,
rspotify_model::Type::Artist,
Expand All @@ -135,7 +135,6 @@ pub fn handle_key_sequence_for_popup(
drop(ui);
handle_key_sequence_for_context_browsing_list_popup(
key_sequence,
send,
state,
album_uris,
rspotify_model::Type::Album,
Expand Down Expand Up @@ -249,13 +248,13 @@ fn handle_key_sequence_for_search_popup(
_ => match ui.current_page() {
PageState::Library => {
drop(ui);
window::handle_key_sequence_for_library_window(key_sequence, send, state)
window::handle_key_sequence_for_library_window(key_sequence, state)
}
PageState::Recommendations(..) => {
drop(ui);
window::handle_key_sequence_for_recommendation_window(key_sequence, send, state)
}
PageState::Browsing(_) | PageState::CurrentPlaying => {
PageState::Context(..) => {
drop(ui);
window::handle_key_sequence_for_context_window(key_sequence, send, state)
}
Expand All @@ -275,7 +274,6 @@ fn handle_key_sequence_for_search_popup(
/// - `uri_type`: an enum represents the type of a context in the list (`playlist`, `artist`, etc)
fn handle_key_sequence_for_context_browsing_list_popup(
key_sequence: &KeySequence,
send: &mpsc::Sender<ClientRequest>,
state: &SharedState,
uris: Vec<String>,
context_type: rspotify_model::Type,
Expand All @@ -296,9 +294,10 @@ fn handle_key_sequence_for_context_browsing_list_popup(
}
};

send.send(ClientRequest::GetContext(context_id.clone()))?;

ui.create_new_page(PageState::Browsing(context_id));
ui.create_new_page(PageState::Context(
None,
ContextPageType::Browsing(context_id),
));

Ok(())
},
Expand Down Expand Up @@ -423,8 +422,10 @@ fn handle_key_sequence_for_action_list_popup(
if let Some(ref album) = track.album {
let uri = album.id.uri();
let context_id = ContextId::Album(AlbumId::from_uri(&uri)?);
send.send(ClientRequest::GetContext(context_id.clone()))?;
ui.create_new_page(PageState::Browsing(context_id));
ui.create_new_page(PageState::Context(
None,
ContextPageType::Browsing(context_id),
));
}
}
Action::BrowseArtist => {
Expand All @@ -448,9 +449,6 @@ fn handle_key_sequence_for_action_list_popup(
let seed = SeedItem::Track(track.clone());
send.send(ClientRequest::GetRecommendations(seed.clone()))?;
ui.create_new_page(PageState::Recommendations(seed));
ui.window = WindowState::Recommendations {
track_table: new_table_state(),
};
}
},
Item::Album(album) => match actions[id] {
Expand All @@ -475,9 +473,6 @@ fn handle_key_sequence_for_action_list_popup(
let seed = SeedItem::Artist(artist.clone());
send.send(ClientRequest::GetRecommendations(seed.clone()))?;
ui.create_new_page(PageState::Recommendations(seed));
ui.window = WindowState::Recommendations {
track_table: new_table_state(),
};
}
_ => {}
},
Expand Down
107 changes: 54 additions & 53 deletions spotify_player/src/event/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,33 @@ pub fn handle_key_sequence_for_context_window(
});
}
Command::PlayRandom => {
let player = state.player.read();
let data = state.data.read();
let context = player.context(&data.caches);

// randomly play a track from the current context
if let Some(context) = context {
let tracks = context.tracks();
let offset = match context {
// Spotify does not allow to manually specify `offset` for artist context
Context::Artist { .. } => None,
_ => {
let id = rand::thread_rng().gen_range(0..tracks.len());
Some(rspotify_model::Offset::for_uri(&tracks[id].id.uri()))
}
};
if let Some(uri) = ui.current_page().context_uri() {
let data = state.data.read();

// randomly play a track from the current context
if let Some(context) = data.caches.context.peek(&uri) {
let tracks = context.tracks();
let offset = match context {
// Spotify does not allow to manually specify `offset` for artist context
Context::Artist { .. } => None,
_ => {
let id = rand::thread_rng().gen_range(0..tracks.len());
Some(rspotify_model::Offset::for_uri(&tracks[id].id.uri()))
}
};

send.send(ClientRequest::Player(PlayerRequest::StartPlayback(
Playback::Context(player.context_id.clone().unwrap(), offset),
)))?;
let context_id = match ui.current_page() {
PageState::Context(context_id, _) => context_id.clone().unwrap(),
_ => unreachable!(),
};

send.send(ClientRequest::Player(PlayerRequest::StartPlayback(
Playback::Context(context_id, offset),
)))?;
}
}
}
_ => {
drop(ui);

// handle sort/reverse tracks commands
let order = match command {
Command::SortTrackByTitle => Some(TrackOrder::TrackName),
Expand All @@ -64,27 +67,26 @@ pub fn handle_key_sequence_for_context_window(
};

if let Some(order) = order {
let player = state.player.read();
let mut data = state.data.write();
let context = player.context_mut(&mut data.caches);

if let Some(context) = context {
context.sort_tracks(order);
if let Some(uri) = ui.current_page().context_uri() {
let mut data = state.data.write();
if let Some(context) = data.caches.context.peek_mut(&uri) {
context.sort_tracks(order);
}
}
return Ok(true);
}
if command == Command::ReverseTrackOrder {
let player = state.player.read();
let mut data = state.data.write();
let context = player.context_mut(&mut data.caches);

if let Some(context) = context {
context.reverse_tracks();
if let Some(uri) = ui.current_page().context_uri() {
let mut data = state.data.write();
if let Some(context) = data.caches.context.peek_mut(&uri) {
context.reverse_tracks();
}
}
return Ok(true);
}

// the command hasn't been handled, assign the job to the focused subwindow's handler
drop(ui);
return handle_command_for_focused_context_subwindow(command, send, state);
}
}
Expand All @@ -94,7 +96,6 @@ pub fn handle_key_sequence_for_context_window(
/// handles a key sequence for a library window
pub fn handle_key_sequence_for_library_window(
key_sequence: &KeySequence,
send: &mpsc::Sender<ClientRequest>,
state: &SharedState,
) -> Result<bool> {
let command = match state
Expand Down Expand Up @@ -132,19 +133,16 @@ pub fn handle_key_sequence_for_library_window(
match focus_state {
LibraryFocusState::Playlists => handle_command_for_playlist_list_subwindow(
command,
send,
state,
state.filtered_items_by_search(&data.user_data.playlists),
),
LibraryFocusState::SavedAlbums => handle_command_for_album_list_subwindow(
command,
send,
state,
state.filtered_items_by_search(&data.user_data.saved_albums),
),
LibraryFocusState::FollowedArtists => handle_command_for_artist_list_subwindow(
command,
send,
state,
state.filtered_items_by_search(&data.user_data.followed_artists),
),
Expand Down Expand Up @@ -301,19 +299,19 @@ pub fn handle_key_sequence_for_search_window(
let artists = search_results
.map(|s| s.artists.iter().collect())
.unwrap_or_default();
handle_command_for_artist_list_subwindow(command, send, state, artists)
handle_command_for_artist_list_subwindow(command, state, artists)
}
SearchFocusState::Albums => {
let albums = search_results
.map(|s| s.albums.iter().collect())
.unwrap_or_default();
handle_command_for_album_list_subwindow(command, send, state, albums)
handle_command_for_album_list_subwindow(command, state, albums)
}
SearchFocusState::Playlists => {
let playlists = search_results
.map(|s| s.playlists.iter().collect())
.unwrap_or_default();
handle_command_for_playlist_list_subwindow(command, send, state, playlists)
handle_command_for_playlist_list_subwindow(command, state, playlists)
}
}
}
Expand All @@ -329,10 +327,12 @@ pub fn handle_command_for_focused_context_subwindow(
send: &mpsc::Sender<ClientRequest>,
state: &SharedState,
) -> Result<bool> {
let data = state.data.read();
let context = state.player.read().context(&data.caches);
let uri = match state.ui.lock().current_page().context_uri() {
Some(uri) => uri,
None => return Ok(false),
};

match context {
match state.data.read().caches.context.peek(&uri) {
Some(context) => match context {
Context::Artist {
top_tracks,
Expand All @@ -348,13 +348,11 @@ pub fn handle_command_for_focused_context_subwindow(
match focus_state {
ArtistFocusState::Albums => handle_command_for_album_list_subwindow(
command,
send,
state,
state.filtered_items_by_search(albums),
),
ArtistFocusState::RelatedArtists => handle_command_for_artist_list_subwindow(
command,
send,
state,
state.filtered_items_by_search(related_artists),
),
Expand Down Expand Up @@ -493,7 +491,6 @@ fn handle_command_for_track_list_subwindow(

fn handle_command_for_artist_list_subwindow(
command: Command,
send: &mpsc::Sender<ClientRequest>,
state: &SharedState,
artists: Vec<&Artist>,
) -> Result<bool> {
Expand All @@ -513,8 +510,10 @@ fn handle_command_for_artist_list_subwindow(
}
Command::ChooseSelected => {
let context_id = ContextId::Artist(artists[id].id.clone());
send.send(ClientRequest::GetContext(context_id.clone()))?;
ui.create_new_page(PageState::Browsing(context_id));
ui.create_new_page(PageState::Context(
None,
ContextPageType::Browsing(context_id),
));
}
Command::ShowActionsOnSelectedItem => {
ui.popup = Some(PopupState::ActionList(
Expand All @@ -529,7 +528,6 @@ fn handle_command_for_artist_list_subwindow(

fn handle_command_for_album_list_subwindow(
command: Command,
send: &mpsc::Sender<ClientRequest>,
state: &SharedState,
albums: Vec<&Album>,
) -> Result<bool> {
Expand All @@ -549,8 +547,10 @@ fn handle_command_for_album_list_subwindow(
}
Command::ChooseSelected => {
let context_id = ContextId::Album(albums[id].id.clone());
send.send(ClientRequest::GetContext(context_id.clone()))?;
ui.create_new_page(PageState::Browsing(context_id));
ui.create_new_page(PageState::Context(
None,
ContextPageType::Browsing(context_id),
));
}
Command::ShowActionsOnSelectedItem => {
ui.popup = Some(PopupState::ActionList(
Expand All @@ -565,7 +565,6 @@ fn handle_command_for_album_list_subwindow(

fn handle_command_for_playlist_list_subwindow(
command: Command,
send: &mpsc::Sender<ClientRequest>,
state: &SharedState,
playlists: Vec<&Playlist>,
) -> Result<bool> {
Expand All @@ -585,8 +584,10 @@ fn handle_command_for_playlist_list_subwindow(
}
Command::ChooseSelected => {
let context_id = ContextId::Playlist(playlists[id].id.clone());
send.send(ClientRequest::GetContext(context_id.clone()))?;
ui.create_new_page(PageState::Browsing(context_id));
ui.create_new_page(PageState::Context(
None,
ContextPageType::Browsing(context_id),
));
}
Command::ShowActionsOnSelectedItem => {
ui.popup = Some(PopupState::ActionList(
Expand Down
Loading

0 comments on commit 166407f

Please sign in to comment.