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

Add new playing begin with behavior on songs in album or playlist #49

Merged
merged 1 commit into from
Apr 29, 2024
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
80 changes: 60 additions & 20 deletions BlackCandy/Store/PlayerReducer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,16 @@ struct PlayerReducer: Reducer {
case moveSongsResponse(TaskResult<APIClient.NoContentResponse>)
case getCurrentPlaylist
case currentPlaylistResponse(TaskResult<[Song]>)
case playAll(String, Int)
case playAllResponse(TaskResult<[Song]>)
case playSong(Int)
case playAlbum(Int)
case playAlbumBeginWith(Int, Int)
case playPlaylist(Int)
case playPlaylistBeginWith(Int, Int)
case playSongsResponse(TaskResult<[Song]>)
case playSongsBeginWithResponse(TaskResult<[Song]>, Int)
case playNow(Int)
case playNext(Int)
case playLast(Int)
case playSongResponse(TaskResult<Song>)
case playNowResponse(TaskResult<Song>)
case playNextResponse(TaskResult<Song>)
case playLastResponse(TaskResult<Song>)
}
Expand Down Expand Up @@ -285,37 +289,72 @@ struct PlayerReducer: Reducer {

return .none

case let .playAll(resourceType, resourceId):
case let .playAlbum(albumId):
return .run { send in
await send(
.playAllResponse(
.playSongsResponse(
TaskResult {
switch resourceType {
case "album":
return try await apiClient.replaceCurrentPlaylistWithAlbumSongs(resourceId)
case "playlist":
return try await apiClient.replaceCurrentPlaylistWithPlaylistSongs(resourceId)
default:
throw APIClient.APIError.invalidRequest
}
try await apiClient.replaceCurrentPlaylistWithAlbumSongs(albumId)
}
)
)
}

case let .playAlbumBeginWith(albumId, songId):
return .run { send in
await send(
.playSongsBeginWithResponse(
TaskResult { try await apiClient.replaceCurrentPlaylistWithAlbumSongs(albumId) },
songId
)
)
}

case let .playPlaylist(playlistId):
return .run { send in
await send(
.playSongsResponse(
TaskResult {
try await apiClient.replaceCurrentPlaylistWithPlaylistSongs(playlistId)
}
)
)
}

case let .playAllResponse(.success(songs)):
case let .playPlaylistBeginWith(playlistId, songId):
return .run { send in
await send(
.playSongsBeginWithResponse(
TaskResult { try await apiClient.replaceCurrentPlaylistWithPlaylistSongs(playlistId) },
songId
)
)
}

case let .playSongsResponse(.success(songs)):
state.playlist.update(songs: songs)
state.currentSong = songs.first

return self.playOn(state: &state, index: 0)

case let .playSong(songId):
case let .playSongsBeginWithResponse(.success(songs), songId):
state.playlist.update(songs: songs)

if let songIndex = state.playlist.index(by: songId) {
state.currentSong = state.playlist.find(byIndex: songIndex)
return self.playOn(state: &state, index: songIndex)
} else {
state.currentSong = songs.first
return self.playOn(state: &state, index: 0)
}

case let .playNow(songId):
if let songIndex = state.playlist.index(by: songId) {
return self.playOn(state: &state, index: songIndex)
} else {
return .run { [currentSong = state.currentSong] send in
await send(
.playSongResponse(
.playNowResponse(
TaskResult { try await apiClient.addSongToCurrentPlaylist(songId, currentSong, nil) }
)
)
Expand All @@ -340,7 +379,7 @@ struct PlayerReducer: Reducer {
)
}

case let .playSongResponse(.success(song)):
case let .playNowResponse(.success(song)):
let insertIndex = state.insertSongNextToCurrent(song: song)
return self.playOn(state: &state, index: insertIndex)

Expand All @@ -359,8 +398,9 @@ struct PlayerReducer: Reducer {
case let .deleteSongsResponse(.failure(error)),
let .moveSongsResponse(.failure(error)),
let .currentPlaylistResponse(.failure(error)),
let .playAllResponse(.failure(error)),
let .playSongResponse(.failure(error)),
let .playSongsResponse(.failure(error)),
let .playSongsBeginWithResponse(.failure(error), _),
let .playNowResponse(.failure(error)),
let .playNextResponse(.failure(error)),
let .playLastResponse(.failure(error)),
let .toggleFavoriteResponse(.failure(error)):
Expand Down
34 changes: 28 additions & 6 deletions BlackCandy/Turbo/TurboScriptMessageHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,51 @@ class TurboScriptMessageHandler: NSObject, WKScriptMessageHandler {
let actionName = body["name"] as? String else { return }

switch actionName {
case "playAll":
guard let resourceType = body["resourceType"] as? String,
let resourceId = body["resourceId"] as? Int else { return }
case "playAlbum":
guard let albumId = body["albumId"] as? Int else { return }
store.send(.player(.playAlbum(albumId)))

store.send(.player(.playAll(resourceType, resourceId)))
case "playSong":
case "playAlbumBeginWith":
guard
let albumId = body["albumId"] as? Int,
let songId = body["songId"] as? Int else { return }

store.send(.player(.playAlbumBeginWith(albumId, songId)))

case "playPlaylist":
guard let playlistId = body["playlistId"] as? Int else { return }
store.send(.player(.playPlaylist(playlistId)))

case "playPlaylistBeginWith":
guard
let playlistId = body["playlistId"] as? Int,
let songId = body["songId"] as? Int else { return }

store.send(.player(.playPlaylistBeginWith(playlistId, songId)))

case "playNow":
guard let songId = body["songId"] as? Int else { return }
store.send(.player(.playSong(songId)))
store.send(.player(.playNow(songId)))

case "playNext":
guard let songId = body["songId"] as? Int else { return }
store.send(.player(.playNext(songId)))

case "playLast":
guard let songId = body["songId"] as? Int else { return }
store.send(.player(.playLast(songId)))

case "showFlashMessage":
guard let message = body["message"] as? String else { return }
flashMessageClient.showMessage(message)

case "updateTheme":
guard
let theme = body["theme"] as? String,
let currentTheme = AppReducer.State.Theme(rawValue: theme) else { return }

store.send(.updateTheme(currentTheme))

default:
return
}
Expand Down
18 changes: 9 additions & 9 deletions BlackCandyTests/Store/PlayerReducerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -534,9 +534,9 @@ final class PlayerReducerTests: XCTestCase {

store.exhaustivity = .off

await store.send(.playAll("album", 1))
await store.send(.playAlbum(1))

await store.receive(.playAllResponse(.success(songs))) {
await store.receive(.playSongsResponse(.success(songs))) {
$0.playlist.orderedSongs = songs
$0.currentSong = songs.first
}
Expand All @@ -555,9 +555,9 @@ final class PlayerReducerTests: XCTestCase {

store.exhaustivity = .off

await store.send(.playAll("playlist", 1))
await store.send(.playPlaylist(1))

await store.receive(.playAllResponse(.success(songs))) {
await store.receive(.playSongsResponse(.success(songs))) {
$0.playlist.orderedSongs = songs
$0.currentSong = songs.first
}
Expand All @@ -574,7 +574,7 @@ final class PlayerReducerTests: XCTestCase {
reducer: { PlayerReducer() }
)

await store.send(.playSong(1)) {
await store.send(.playNow(1)) {
$0.currentSong = songs.first
}
}
Expand All @@ -598,9 +598,9 @@ final class PlayerReducerTests: XCTestCase {

store.exhaustivity = .off

await store.send(.playSong(2))
await store.send(.playNow(2))

await store.receive(.playSongResponse(.success(playingSong))) {
await store.receive(.playNowResponse(.success(playingSong))) {
$0.playlist.orderedSongs = [song, playingSong]
$0.currentSong = playingSong
}
Expand All @@ -621,9 +621,9 @@ final class PlayerReducerTests: XCTestCase {

store.exhaustivity = .off

await store.send(.playSong(1))
await store.send(.playNow(1))

await store.receive(.playSongResponse(.success(song))) {
await store.receive(.playNowResponse(.success(song))) {
$0.playlist.orderedSongs = [song]
$0.currentSong = song
}
Expand Down
Loading