Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move items in a playlist #224

Merged
merged 6 commits into from
Jul 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,8 @@ List of supported commands:
| `SortTrackByDuration` | sort the track table (if any) by track's duration | `s d` |
| `SortTrackByAddedDate` | sort the track table (if any) by track's added date | `s D` |
| `ReverseOrder` | reverse the order of the track table (if any) | `s r` |
| `MovePlaylistItemUp` | move playlist item up one position | `C-k` |
| `MovePlaylistItemDown` | move playlist item down one position | `C-j` |

To add new shortcuts or modify the default shortcuts, please refer to the [keymaps section](docs/config.md#keymaps) in the configuration documentation.

Expand Down
57 changes: 57 additions & 0 deletions spotify_player/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,23 @@ impl Client {
state.player.write().queue = Some(queue);
}
}
ClientRequest::ReorderPlaylistItems {
playlist_id,
insert_index,
range_start,
range_length,
snapshot_id,
} => {
self.reorder_playlist_items(
state,
playlist_id,
insert_index,
range_start,
range_length,
snapshot_id.as_deref(),
)
.await?;
}
};

tracing::info!(
Expand Down Expand Up @@ -866,6 +883,46 @@ impl Client {
Ok(())
}

/// reorder items in a playlist
pub async fn reorder_playlist_items(
&self,
state: &SharedState,
playlist_id: PlaylistId<'_>,
insert_index: usize,
range_start: usize,
range_length: Option<usize>,
snapshot_id: Option<&str>,
) -> Result<()> {
let insert_before = match insert_index > range_start {
true => insert_index + 1,
false => insert_index,
};

self.spotify
.playlist_reorder_items(
playlist_id.clone(),
Some(range_start as i32),
Some(insert_before as i32),
range_length.map(|range_length| range_length as u32),
snapshot_id,
)
.await?;

// After making a reorder request, update the playlist in-memory data stored inside the app caches.
if let Some(Context::Playlist { tracks, .. }) = state
.data
.write()
.caches
.context
.get_mut(&playlist_id.uri())
{
let track = tracks.remove(range_start);
tracks.insert(insert_index, track);
}

Ok(())
}

/// adds a Spotify item to current user's library.
/// Before adding new item, the function checks if that item already exists in the library
/// to avoid adding a duplicated item.
Expand Down
5 changes: 5 additions & 0 deletions spotify_player/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ pub enum Command {
SortTrackByDuration,
SortTrackByAddedDate,
ReverseTrackOrder,

MovePlaylistItemUp,
MovePlaylistItemDown,
}

#[derive(Debug, Copy, Clone)]
Expand Down Expand Up @@ -196,6 +199,8 @@ impl Command {
Self::SortTrackByDuration => "sort the track table (if any) by track's duration",
Self::SortTrackByAddedDate => "sort the track table (if any) by track's added date",
Self::ReverseTrackOrder => "reverse the order of the track table (if any)",
Self::MovePlaylistItemUp => "move playlist item up one position",
Self::MovePlaylistItemDown => "move playlist item down one position",
}
}
}
8 changes: 8 additions & 0 deletions spotify_player/src/config/keymap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,14 @@ impl Default for KeymapConfig {
key_sequence: "s r".into(),
command: Command::ReverseTrackOrder,
},
Keymap {
key_sequence: "C-k".into(),
command: Command::MovePlaylistItemUp,
},
Keymap {
key_sequence: "C-j".into(),
command: Command::MovePlaylistItemDown,
},
],
}
}
Expand Down
7 changes: 7 additions & 0 deletions spotify_player/src/event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ pub enum ClientRequest {
AddTrackToQueue(TrackId<'static>),
AddTrackToPlaylist(PlaylistId<'static>, TrackId<'static>),
DeleteTrackFromPlaylist(PlaylistId<'static>, TrackId<'static>),
ReorderPlaylistItems {
playlist_id: PlaylistId<'static>,
insert_index: usize,
range_start: usize,
range_length: Option<usize>,
snapshot_id: Option<String>,
},
AddToLibrary(Item),
DeleteFromLibrary(ItemId),
ConnectDevice(Option<String>),
Expand Down
52 changes: 52 additions & 0 deletions spotify_player/src/event/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,58 @@ pub fn handle_command_for_track_table_window(
Command::AddSelectedItemToQueue => {
client_pub.send(ClientRequest::AddTrackToQueue(tracks[id].id.clone()))?;
}
Command::MovePlaylistItemUp => {
if let PageState::Context {
id: Some(ContextId::Playlist(playlist_id)),
..
} = ui.current_page()
{
if id > 0
&& data.user_data.playlists.iter().any(|playlist| {
&playlist.id == playlist_id
&& Some(&playlist.owner.1)
== data.user_data.user.as_ref().map(|user| &user.id)
Copy link
Owner

@aome510 aome510 Jul 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This owner check can be moved inside the find function right.

Edit: then you can use .any instead of .find.is_some() to make the code cleaner

})
{
let insert_index = id - 1;
client_pub.send(ClientRequest::ReorderPlaylistItems {
playlist_id: playlist_id.clone_static(),
insert_index,
range_start: id,
range_length: None,
snapshot_id: None,
})?;
ui.current_page_mut().select(insert_index);
};
}
ui.popup = None;
}
Command::MovePlaylistItemDown => {
if let PageState::Context {
id: Some(ContextId::Playlist(playlist_id)),
..
} = ui.current_page()
{
let insert_index = id + 1;
if insert_index < tracks.len()
&& data.user_data.playlists.iter().any(|playlist| {
&playlist.id == playlist_id
&& Some(&playlist.owner.1)
== data.user_data.user.as_ref().map(|user| &user.id)
})
{
client_pub.send(ClientRequest::ReorderPlaylistItems {
playlist_id: playlist_id.clone_static(),
insert_index,
range_start: id,
range_length: None,
snapshot_id: None,
})?;
ui.current_page_mut().select(insert_index);
};
}
ui.popup = None;
}
_ => return Ok(false),
}
Ok(true)
Expand Down
Loading