music: add userlibrary error returns
Make UserLibrary return some kind of error indicator if something fails. I don't have the framework for how the app will display these errors just yet.
This commit is contained in:
parent
a9a6d1ccc1
commit
5ab46ba5d1
2 changed files with 63 additions and 36 deletions
|
@ -56,6 +56,7 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
packagingOptions {
|
packagingOptions {
|
||||||
jniLibs {
|
jniLibs {
|
||||||
excludes += ['**/kotlin/**', '**/okhttp3/**']
|
excludes += ['**/kotlin/**', '**/okhttp3/**']
|
||||||
|
@ -65,7 +66,6 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
viewBinding true
|
viewBinding true
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,8 +62,22 @@ interface UserLibrary {
|
||||||
|
|
||||||
/** Constructs a [UserLibrary] implementation in an asynchronous manner. */
|
/** Constructs a [UserLibrary] implementation in an asynchronous manner. */
|
||||||
interface Factory {
|
interface Factory {
|
||||||
|
/**
|
||||||
|
* Read all [RawPlaylist] information from the database, which can be transformed into a
|
||||||
|
* [UserLibrary] later.
|
||||||
|
*
|
||||||
|
* @return A list of [RawPlaylist]s.
|
||||||
|
*/
|
||||||
suspend fun query(): List<RawPlaylist>
|
suspend fun query(): List<RawPlaylist>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new [UserLibrary] from read [RawPlaylist] instances and a precursor
|
||||||
|
* [DeviceLibrary].
|
||||||
|
*
|
||||||
|
* @param rawPlaylists The [RawPlaylist]s to use.
|
||||||
|
* @param deviceLibrary The [DeviceLibrary] to use.
|
||||||
|
* @return The new [UserLibrary] instance.
|
||||||
|
*/
|
||||||
suspend fun create(
|
suspend fun create(
|
||||||
rawPlaylists: List<RawPlaylist>,
|
rawPlaylists: List<RawPlaylist>,
|
||||||
deviceLibrary: DeviceLibrary
|
deviceLibrary: DeviceLibrary
|
||||||
|
@ -83,38 +97,44 @@ interface MutableUserLibrary : UserLibrary {
|
||||||
*
|
*
|
||||||
* @param name The name of the [Playlist].
|
* @param name The name of the [Playlist].
|
||||||
* @param songs The songs to place in the [Playlist].
|
* @param songs The songs to place in the [Playlist].
|
||||||
|
* @return The new [Playlist] instance, or null if one could not be created.
|
||||||
*/
|
*/
|
||||||
suspend fun createPlaylist(name: String, songs: List<Song>)
|
suspend fun createPlaylist(name: String, songs: List<Song>): Playlist?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rename a [Playlist].
|
* Rename a [Playlist].
|
||||||
*
|
*
|
||||||
* @param playlist The [Playlist] to rename.
|
* @param playlist The [Playlist] to rename.
|
||||||
* @param name The name of the new [Playlist].
|
* @param name The name of the new [Playlist].
|
||||||
|
* @return True if the [Playlist] was successfully renamed, false otherwise.
|
||||||
*/
|
*/
|
||||||
suspend fun renamePlaylist(playlist: Playlist, name: String)
|
suspend fun renamePlaylist(playlist: Playlist, name: String): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a [Playlist].
|
* Delete a [Playlist].
|
||||||
*
|
*
|
||||||
* @param playlist The playlist to delete.
|
* @param playlist The playlist to delete.
|
||||||
|
* @return True if the [Playlist] was successfully deleted, false otherwise.
|
||||||
*/
|
*/
|
||||||
suspend fun deletePlaylist(playlist: Playlist)
|
suspend fun deletePlaylist(playlist: Playlist): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add [Song]s to a [Playlist].
|
* Add [Song]s to a [Playlist].
|
||||||
*
|
*
|
||||||
* @param playlist The [Playlist] to add to. Must currently exist.
|
* @param playlist The [Playlist] to add to. Must currently exist.
|
||||||
|
* @param songs The [Song]s to add to the [Playlist].
|
||||||
|
* @return True if the [Song]s were successfully added, false otherwise.
|
||||||
*/
|
*/
|
||||||
suspend fun addToPlaylist(playlist: Playlist, songs: List<Song>)
|
suspend fun addToPlaylist(playlist: Playlist, songs: List<Song>): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the [Song]s of a [Playlist].
|
* Update the [Song]s of a [Playlist].
|
||||||
*
|
*
|
||||||
* @param playlist The [Playlist] to update.
|
* @param playlist The [Playlist] to update.
|
||||||
* @param songs The new [Song]s to be contained in the [Playlist].
|
* @param songs The new [Song]s to be contained in the [Playlist].
|
||||||
|
* @return True if the [Playlist] was successfully updated, false otherwise.
|
||||||
*/
|
*/
|
||||||
suspend fun rewritePlaylist(playlist: Playlist, songs: List<Song>)
|
suspend fun rewritePlaylist(playlist: Playlist, songs: List<Song>): Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
class UserLibraryFactoryImpl
|
class UserLibraryFactoryImpl
|
||||||
|
@ -160,92 +180,99 @@ private class UserLibraryImpl(
|
||||||
|
|
||||||
override fun findPlaylist(name: String) = playlistMap.values.find { it.name.raw == name }
|
override fun findPlaylist(name: String) = playlistMap.values.find { it.name.raw == name }
|
||||||
|
|
||||||
override suspend fun createPlaylist(name: String, songs: List<Song>) {
|
override suspend fun createPlaylist(name: String, songs: List<Song>): Playlist? {
|
||||||
val playlistImpl = PlaylistImpl.from(name, songs, musicSettings)
|
val playlistImpl = PlaylistImpl.from(name, songs, musicSettings)
|
||||||
synchronized(this) { playlistMap[playlistImpl.uid] = playlistImpl }
|
synchronized(this) { playlistMap[playlistImpl.uid] = playlistImpl }
|
||||||
val rawPlaylist =
|
val rawPlaylist =
|
||||||
RawPlaylist(
|
RawPlaylist(
|
||||||
PlaylistInfo(playlistImpl.uid, playlistImpl.name.raw),
|
PlaylistInfo(playlistImpl.uid, playlistImpl.name.raw),
|
||||||
playlistImpl.songs.map { PlaylistSong(it.uid) })
|
playlistImpl.songs.map { PlaylistSong(it.uid) })
|
||||||
try {
|
|
||||||
|
return try {
|
||||||
playlistDao.insertPlaylist(rawPlaylist)
|
playlistDao.insertPlaylist(rawPlaylist)
|
||||||
logD("Successfully created playlist $name with ${songs.size} songs")
|
logD("Successfully created playlist $name with ${songs.size} songs")
|
||||||
|
playlistImpl
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logE("Unable to create playlist $name with ${songs.size} songs")
|
logE("Unable to create playlist $name with ${songs.size} songs")
|
||||||
logE(e.stackTraceToString())
|
logE(e.stackTraceToString())
|
||||||
synchronized(this) { playlistMap.remove(playlistImpl.uid) }
|
synchronized(this) { playlistMap.remove(playlistImpl.uid) }
|
||||||
return
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun renamePlaylist(playlist: Playlist, name: String) {
|
override suspend fun renamePlaylist(playlist: Playlist, name: String): Boolean {
|
||||||
val playlistImpl =
|
val playlistImpl =
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
requireNotNull(playlistMap[playlist.uid]) { "Cannot rename invalid playlist" }.also {
|
requireNotNull(playlistMap[playlist.uid]) { "Cannot rename invalid playlist" }
|
||||||
playlistMap[it.uid] = it.edit(name, musicSettings)
|
.also { playlistMap[it.uid] = it.edit(name, musicSettings) }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
try {
|
return try {
|
||||||
playlistDao.replacePlaylistInfo(PlaylistInfo(playlist.uid, name))
|
playlistDao.replacePlaylistInfo(PlaylistInfo(playlist.uid, name))
|
||||||
logD("Successfully renamed $playlist to $name")
|
logD("Successfully renamed $playlist to $name")
|
||||||
|
true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logE("Unable to rename $playlist to $name: $e")
|
logE("Unable to rename $playlist to $name: $e")
|
||||||
logE(e.stackTraceToString())
|
logE(e.stackTraceToString())
|
||||||
synchronized(this) { playlistMap[playlistImpl.uid] = playlistImpl }
|
synchronized(this) { playlistMap[playlistImpl.uid] = playlistImpl }
|
||||||
return
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun deletePlaylist(playlist: Playlist) {
|
override suspend fun deletePlaylist(playlist: Playlist): Boolean {
|
||||||
val playlistImpl = synchronized(this) {
|
val playlistImpl =
|
||||||
requireNotNull(playlistMap[playlist.uid]) { "Cannot remove invalid playlist" }.also {
|
synchronized(this) {
|
||||||
playlistMap.remove(it.uid)
|
requireNotNull(playlistMap[playlist.uid]) { "Cannot remove invalid playlist" }
|
||||||
|
.also { playlistMap.remove(it.uid) }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
try {
|
return try {
|
||||||
playlistDao.deletePlaylist(playlist.uid)
|
playlistDao.deletePlaylist(playlist.uid)
|
||||||
logD("Successfully deleted $playlist")
|
logD("Successfully deleted $playlist")
|
||||||
|
true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logE("Unable to delete $playlist: $e")
|
logE("Unable to delete $playlist: $e")
|
||||||
logE(e.stackTraceToString())
|
logE(e.stackTraceToString())
|
||||||
synchronized(this) { playlistMap[playlistImpl.uid] = playlistImpl }
|
synchronized(this) { playlistMap[playlistImpl.uid] = playlistImpl }
|
||||||
return
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun addToPlaylist(playlist: Playlist, songs: List<Song>) {
|
override suspend fun addToPlaylist(playlist: Playlist, songs: List<Song>): Boolean {
|
||||||
val playlistImpl = synchronized(this) {
|
val playlistImpl =
|
||||||
requireNotNull(playlistMap[playlist.uid]) { "Cannot add to invalid playlist" }.also {
|
synchronized(this) {
|
||||||
playlistMap[it.uid] = it.edit { addAll(songs) }
|
requireNotNull(playlistMap[playlist.uid]) { "Cannot add to invalid playlist" }
|
||||||
}
|
.also { playlistMap[it.uid] = it.edit { addAll(songs) } }
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
return try {
|
||||||
playlistDao.insertPlaylistSongs(playlist.uid, songs.map { PlaylistSong(it.uid) })
|
playlistDao.insertPlaylistSongs(playlist.uid, songs.map { PlaylistSong(it.uid) })
|
||||||
logD("Successfully added ${songs.size} songs to $playlist")
|
logD("Successfully added ${songs.size} songs to $playlist")
|
||||||
|
true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logE("Unable to add ${songs.size} songs to $playlist: $e")
|
logE("Unable to add ${songs.size} songs to $playlist: $e")
|
||||||
logE(e.stackTraceToString())
|
logE(e.stackTraceToString())
|
||||||
synchronized(this) { playlistMap[playlistImpl.uid] = playlistImpl }
|
synchronized(this) { playlistMap[playlistImpl.uid] = playlistImpl }
|
||||||
return
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun rewritePlaylist(playlist: Playlist, songs: List<Song>) {
|
override suspend fun rewritePlaylist(playlist: Playlist, songs: List<Song>): Boolean {
|
||||||
val playlistImpl = synchronized(this) {
|
val playlistImpl =
|
||||||
requireNotNull(playlistMap[playlist.uid]) { "Cannot rewrite invalid playlist" }.also {
|
synchronized(this) {
|
||||||
playlistMap[it.uid] = it.edit(songs)
|
requireNotNull(playlistMap[playlist.uid]) { "Cannot rewrite invalid playlist" }
|
||||||
}
|
.also { playlistMap[it.uid] = it.edit(songs) }
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
return try {
|
||||||
playlistDao.replacePlaylistSongs(playlist.uid, songs.map { PlaylistSong(it.uid) })
|
playlistDao.replacePlaylistSongs(playlist.uid, songs.map { PlaylistSong(it.uid) })
|
||||||
logD("Successfully rewrote $playlist with ${songs.size} songs")
|
logD("Successfully rewrote $playlist with ${songs.size} songs")
|
||||||
|
true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logE("Unable to rewrite $playlist with ${songs.size} songs: $e")
|
logE("Unable to rewrite $playlist with ${songs.size} songs: $e")
|
||||||
logE(e.stackTraceToString())
|
logE(e.stackTraceToString())
|
||||||
synchronized(this) { playlistMap[playlistImpl.uid] = playlistImpl }
|
synchronized(this) { playlistMap[playlistImpl.uid] = playlistImpl }
|
||||||
return
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue