diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/MainActivity.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/MainActivity.kt index 8ed65ad40..b68986296 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/MainActivity.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/MainActivity.kt @@ -9,7 +9,6 @@ import android.os.Bundle import android.os.Handler import android.support.v4.app.DialogFragment import android.support.v7.app.AlertDialog -import android.util.Log import android.view.LayoutInflater import android.view.Menu import android.view.MenuItem diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/data/IDataProvider.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/data/IDataProvider.kt index acc57bd2d..e8293cbfc 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/data/IDataProvider.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/data/IDataProvider.kt @@ -30,7 +30,11 @@ interface IDataProvider { fun getCategoryValues(type: String, filter: String = ""): Observable> + fun createPlaylist(playlistName: String, categoryType: String = "", categoryId: Long = -1, filter: String = ""): Observable + fun createPlaylist(playlistName: String, tracks: List = ArrayList()): Observable fun appendToPlaylist(playlistId: Long, categoryType: String = "", categoryId: Long = -1, filter: String = "", offset: Long = -1): Observable + fun renamePlaylist(playlistId: Long, newName: String): Observable + fun deletePlaylist(playlistId: Long): Observable val state: State } diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/data/impl/remote/RemoteDataProvider.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/data/impl/remote/RemoteDataProvider.kt index c8ba3be64..c751c0bd9 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/data/impl/remote/RemoteDataProvider.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/data/impl/remote/RemoteDataProvider.kt @@ -159,30 +159,78 @@ class RemoteDataProvider(private val service: WebSocketService) : IDataProvider .compose(applySchedulers()) } + override fun createPlaylist(playlistName: String, categoryType: String, categoryId: Long, filter: String): Observable { + if (playlistName.isBlank()) { + return Observable.just(0) + } + + val message = SocketMessage.Builder + .request(Messages.Request.SavePlaylist) + .addOption(Messages.Key.PLAYLIST_NAME, playlistName) + .addOption(Messages.Key.SUBQUERY, createTrackListSubquery(categoryType, categoryId, filter)) + .build() + + return service.observe(message, client) + .flatMap { socketMessage -> extractId(socketMessage, Messages.Key.PLAYLIST_ID) } + .compose(applySchedulers()) + } + + override fun createPlaylist(playlistName: String, tracks: List): Observable { + if (playlistName.isBlank()) { + return Observable.just(0) + } + + val externalIds = JSONArray() + tracks.forEach { + if (it.externalId.isNotEmpty()) { + externalIds.put(it.externalId) + } + } + + val message = SocketMessage.Builder + .request(Messages.Request.SavePlaylist) + .addOption(Messages.Key.PLAYLIST_NAME, playlistName) + .addOption(Messages.Key.EXTERNAL_IDS, externalIds) + .build() + + return service.observe(message, client) + .flatMap { socketMessage -> extractId(socketMessage, Messages.Key.PLAYLIST_ID) } + .compose(applySchedulers()) + } + override fun appendToPlaylist(playlistId: Long, categoryType: String, categoryId: Long, filter: String, offset: Long): Observable { - val type = if (categoryType.isNotEmpty() && categoryId > 0) - Messages.Request.QueryTracksByCategory else Messages.Request.QueryTracks - - val suboptions = JSONObject() - - if (type == Messages.Request.QueryTracksByCategory) { - suboptions.put(Messages.Key.CATEGORY, categoryType) - suboptions.put(Messages.Key.ID, categoryId) - } - - if (filter.isNotEmpty()) { - suboptions.put(Messages.Key.FILTER, filter) - } - - val subquery = JSONObject() - .put(Messages.Key.TYPE, type.toString()) - .put(Messages.Key.OPTIONS, suboptions) - val message = SocketMessage.Builder .request(Messages.Request.AppendToPlaylist) .addOption(Messages.Key.PLAYLIST_ID, playlistId) .addOption(Messages.Key.OFFSET, offset) - .addOption(Messages.Key.SUBQUERY, subquery) + .addOption(Messages.Key.SUBQUERY, createTrackListSubquery(categoryType, categoryId, filter)) + .build() + + return service.observe(message, client) + .flatMap { socketMessage -> isSuccessful(socketMessage) } + .compose(applySchedulers()) + } + + override fun renamePlaylist(playlistId: Long, newName: String): Observable { + if (newName.isBlank()) { + return Observable.just(false) + } + + val message = SocketMessage.Builder + .request(Messages.Request.RenamePlaylist) + .addOption(Messages.Key.PLAYLIST_ID, playlistId) + .addOption(Messages.Key.PLAYLIST_NAME, newName) + .build() + + return service.observe(message, client) + .flatMap { socketMessage -> isSuccessful(socketMessage) } + .compose(applySchedulers()) + } + + override fun deletePlaylist(playlistId: Long): Observable { + val message = SocketMessage.Builder + .request(Messages.Request.DeletePlaylist) + .addOption(Messages.Key.PLAYLIST_ID, playlistId) .build() return service.observe(message, client) @@ -253,6 +301,26 @@ class RemoteDataProvider(private val service: WebSocketService) : IDataProvider } } + private fun createTrackListSubquery(categoryType: String, categoryId: Long, filter: String): JSONObject { + val type = if (categoryType.isNotEmpty() && categoryId > 0) + Messages.Request.QueryTracksByCategory else Messages.Request.QueryTracks + + val suboptions = JSONObject() + + if (type == Messages.Request.QueryTracksByCategory) { + suboptions.put(Messages.Key.CATEGORY, categoryType) + suboptions.put(Messages.Key.ID, categoryId) + } + + if (filter.isNotBlank()) { + suboptions.put(Messages.Key.FILTER, filter) + } + + return JSONObject() + .put(Messages.Key.TYPE, type.toString()) + .put(Messages.Key.OPTIONS, suboptions) + } + private val toAlbumArtist: (JSONObject, String) -> ICategoryValue = { json, type -> RemoteAlbumArtist(json) } private val toCategoryValue: (JSONObject, String) -> ICategoryValue = { json, type -> RemoteCategoryValue(type, json) } @@ -294,5 +362,9 @@ class RemoteDataProvider(private val service: WebSocketService) : IDataProvider private fun isSuccessful(message: SocketMessage): Observable { return Observable.just(message.getBooleanOption(Messages.Key.SUCCESS, false)) } + + private fun extractId(message: SocketMessage, idKey: String): Observable { + return Observable.just(message.getLongOption(idKey, 0)) + } } } \ No newline at end of file diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/websocket/Messages.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/websocket/Messages.kt index 222e2f489..b5ce7e2ab 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/websocket/Messages.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/websocket/Messages.kt @@ -96,10 +96,12 @@ class Messages { val RELATIVE = "relative" val PLAYING_CURRENT_TIME = "playing_current_time" val PLAYLIST_ID = "playlist_id" + val PLAYLIST_NAME = "playlist_name" val SUBQUERY = "subquery" val TYPE = "type" val OPTIONS = "options" - val SUCCESS = "success"; + val SUCCESS = "success" + val EXTERNAL_IDS = "external_ids" } }