Twelve: Make RequestStatus even more generic
Change-Id: If20ff3cb0cb7731752ae491d734160c6c32b4893
diff --git a/app/src/main/java/org/lineageos/twelve/datasources/LocalDataSource.kt b/app/src/main/java/org/lineageos/twelve/datasources/LocalDataSource.kt
index c587804..b2a7835 100644
--- a/app/src/main/java/org/lineageos/twelve/datasources/LocalDataSource.kt
+++ b/app/src/main/java/org/lineageos/twelve/datasources/LocalDataSource.kt
@@ -198,26 +198,26 @@
albumsUri,
albumsProjection,
).mapEachRow(albumsProjection, mapAlbum).map {
- RequestStatus.Success(it)
+ RequestStatus.Success<_, MediaError>(it)
}
override fun artists() = contentResolver.queryFlow(
artistsUri,
artistsProjection,
).mapEachRow(artistsProjection, mapArtist).map {
- RequestStatus.Success(it)
+ RequestStatus.Success<_, MediaError>(it)
}
override fun genres() = contentResolver.queryFlow(
genresUri,
genresProjection,
).mapEachRow(genresProjection, mapGenre).map {
- RequestStatus.Success(it)
+ RequestStatus.Success<_, MediaError>(it)
}
override fun playlists() = database.getPlaylistDao().getAll()
.mapLatest { playlists ->
- RequestStatus.Success(playlists.map { it.toModel() })
+ RequestStatus.Success<_, MediaError>(playlists.map { it.toModel() })
}
override fun search(query: String) = combine(
@@ -263,7 +263,7 @@
).mapEachRow(genresProjection, mapGenre),
) { albums, artists, audios, genres ->
albums + artists + audios + genres
- }.map { RequestStatus.Success(it) }
+ }.map { RequestStatus.Success<_, MediaError>(it) }
override fun audio(audioUri: Uri) = contentResolver.queryFlow(
audiosUri,
@@ -278,8 +278,8 @@
)
).mapEachRow(audiosProjection, mapAudio).mapLatest { audios ->
audios.firstOrNull()?.let {
- RequestStatus.Success(it)
- } ?: RequestStatus.Error(RequestStatus.Error.Type.NOT_FOUND)
+ RequestStatus.Success<_, MediaError>(it)
+ } ?: RequestStatus.Error(MediaError.NOT_FOUND)
}
override fun album(albumUri: Uri) = combine(
@@ -312,8 +312,8 @@
).mapEachRow(audiosProjection, mapAudio)
) { albums, audios ->
albums.firstOrNull()?.let {
- RequestStatus.Success(Pair(it, audios))
- } ?: RequestStatus.Error(RequestStatus.Error.Type.NOT_FOUND)
+ RequestStatus.Success<_, MediaError>(Pair(it, audios))
+ } ?: RequestStatus.Error(MediaError.NOT_FOUND)
}
override fun artist(artistUri: Uri) = combine(
@@ -384,8 +384,8 @@
listOf(),
)
- RequestStatus.Success(Pair(it, artistWorks))
- } ?: RequestStatus.Error(RequestStatus.Error.Type.NOT_FOUND)
+ RequestStatus.Success<_, MediaError>(Pair(it, artistWorks))
+ } ?: RequestStatus.Error(MediaError.NOT_FOUND)
}
override fun genre(genreUri: Uri) = combine(
@@ -415,8 +415,8 @@
).mapEachRow(audiosProjection, mapAudio)
) { genres, audios ->
genres.firstOrNull()?.let {
- RequestStatus.Success(Pair(it, audios))
- } ?: RequestStatus.Error(RequestStatus.Error.Type.NOT_FOUND)
+ RequestStatus.Success<_, MediaError>(Pair(it, audios))
+ } ?: RequestStatus.Error(MediaError.NOT_FOUND)
}
override fun playlist(playlistUri: Uri) = database.getPlaylistDao().getPlaylistWithItems(
@@ -427,11 +427,11 @@
audios(playlistWithItems.items.map(Item::audioUri))
.mapLatest {
- RequestStatus.Success(Pair(playlist, it))
+ RequestStatus.Success<_, MediaError>(Pair(playlist, it))
}
} ?: flowOf(
RequestStatus.Error(
- RequestStatus.Error.Type.NOT_FOUND
+ MediaError.NOT_FOUND
)
)
}
@@ -440,7 +440,7 @@
database.getPlaylistWithItemsDao().getPlaylistsWithItemStatus(
audioUri
).mapLatest { data ->
- RequestStatus.Success(
+ RequestStatus.Success<_, MediaError>(
data.map {
it.playlist.toModel() to it.value
}
@@ -450,20 +450,20 @@
override suspend fun createPlaylist(name: String) = database.getPlaylistDao().create(
name
).let {
- RequestStatus.Success(ContentUris.withAppendedId(playlistsBaseUri, it))
+ RequestStatus.Success<_, MediaError>(ContentUris.withAppendedId(playlistsBaseUri, it))
}
override suspend fun renamePlaylist(playlistUri: Uri, name: String) =
database.getPlaylistDao().rename(
ContentUris.parseId(playlistUri), name
).let {
- RequestStatus.Success(Unit)
+ RequestStatus.Success<_, MediaError>(Unit)
}
override suspend fun deletePlaylist(playlistUri: Uri) = database.getPlaylistDao().delete(
ContentUris.parseId(playlistUri)
).let {
- RequestStatus.Success(Unit)
+ RequestStatus.Success<_, MediaError>(Unit)
}
override suspend fun addAudioToPlaylist(
@@ -473,7 +473,7 @@
ContentUris.parseId(playlistUri),
audioUri
).let {
- RequestStatus.Success(Unit)
+ RequestStatus.Success<_, MediaError>(Unit)
}
override suspend fun removeAudioFromPlaylist(
@@ -483,7 +483,7 @@
ContentUris.parseId(playlistUri),
audioUri
).let {
- RequestStatus.Success(Unit)
+ RequestStatus.Success<_, MediaError>(Unit)
}
/**
diff --git a/app/src/main/java/org/lineageos/twelve/datasources/MediaDataSource.kt b/app/src/main/java/org/lineageos/twelve/datasources/MediaDataSource.kt
index 26de920..eba50ca 100644
--- a/app/src/main/java/org/lineageos/twelve/datasources/MediaDataSource.kt
+++ b/app/src/main/java/org/lineageos/twelve/datasources/MediaDataSource.kt
@@ -16,6 +16,8 @@
import org.lineageos.twelve.models.Playlist
import org.lineageos.twelve.models.RequestStatus
+typealias MediaRequestStatus<T> = RequestStatus<T, MediaError>
+
/**
* A data source for media.
*/
@@ -31,60 +33,60 @@
/**
* Get all the albums. All albums must have at least one audio associated with them.
*/
- fun albums(): Flow<RequestStatus<List<Album>>>
+ fun albums(): Flow<MediaRequestStatus<List<Album>>>
/**
* Get all the artists. All artists must have at least one audio associated with them.
*/
- fun artists(): Flow<RequestStatus<List<Artist>>>
+ fun artists(): Flow<MediaRequestStatus<List<Artist>>>
/**
* Get all the genres. All genres must have at least one audio associated with them.
*/
- fun genres(): Flow<RequestStatus<List<Genre>>>
+ fun genres(): Flow<MediaRequestStatus<List<Genre>>>
/**
* Get all the playlists. A playlist can be empty.
*/
- fun playlists(): Flow<RequestStatus<List<Playlist>>>
+ fun playlists(): Flow<MediaRequestStatus<List<Playlist>>>
/**
* Start a search for the given query.
* Only the following items can be returned: [Album], [Artist], [Audio], [Genre], [Playlist].
*/
- fun search(query: String): Flow<RequestStatus<List<MediaItem<*>>>>
+ fun search(query: String): Flow<MediaRequestStatus<List<MediaItem<*>>>>
/**
* Get the audio information of the given audio.
*/
- fun audio(audioUri: Uri): Flow<RequestStatus<Audio>>
+ fun audio(audioUri: Uri): Flow<MediaRequestStatus<Audio>>
/**
* Get the album information and all the tracks of the given album.
*/
- fun album(albumUri: Uri): Flow<RequestStatus<Pair<Album, List<Audio>>>>
+ fun album(albumUri: Uri): Flow<MediaRequestStatus<Pair<Album, List<Audio>>>>
/**
* Get the artist information and all the works associated with them.
*/
- fun artist(artistUri: Uri): Flow<RequestStatus<Pair<Artist, ArtistWorks>>>
+ fun artist(artistUri: Uri): Flow<MediaRequestStatus<Pair<Artist, ArtistWorks>>>
/**
* Get the genre information and all the tracks of the given genre.
*/
- fun genre(genreUri: Uri): Flow<RequestStatus<Pair<Genre, List<Audio>>>>
+ fun genre(genreUri: Uri): Flow<MediaRequestStatus<Pair<Genre, List<Audio>>>>
/**
* Get the playlist information and all the tracks of the given playlist.
* If the playlist contains an audio that is unavailable, it will be mapped to null.
*/
- fun playlist(playlistUri: Uri): Flow<RequestStatus<Pair<Playlist, List<Audio?>>>>
+ fun playlist(playlistUri: Uri): Flow<MediaRequestStatus<Pair<Playlist, List<Audio?>>>>
/**
* Get an audio status within all playlists.
* @param audioUri The URI of the audio
*/
- fun audioPlaylistsStatus(audioUri: Uri): Flow<RequestStatus<List<Pair<Playlist, Boolean>>>>
+ fun audioPlaylistsStatus(audioUri: Uri): Flow<MediaRequestStatus<List<Pair<Playlist, Boolean>>>>
/**
* Create a new playlist. Note that the name shouldn't be considered unique if possible, but
@@ -92,7 +94,7 @@
* @param name The name of the playlist
* @return A [RequestStatus] with the [Uri] of the new playlist if succeeded, an error otherwise
*/
- suspend fun createPlaylist(name: String): RequestStatus<Uri>
+ suspend fun createPlaylist(name: String): MediaRequestStatus<Uri>
/**
* Rename a playlist.
@@ -100,14 +102,14 @@
* @param name The new name of the playlist
* @return [RequestStatus.Success] if success, [RequestStatus.Error] with an error otherwise
*/
- suspend fun renamePlaylist(playlistUri: Uri, name: String): RequestStatus<Unit>
+ suspend fun renamePlaylist(playlistUri: Uri, name: String): MediaRequestStatus<Unit>
/**
* Delete a playlist.
* @param playlistUri The URI of the playlist
* @return [RequestStatus.Success] if success, [RequestStatus.Error] with an error otherwise
*/
- suspend fun deletePlaylist(playlistUri: Uri): RequestStatus<Unit>
+ suspend fun deletePlaylist(playlistUri: Uri): MediaRequestStatus<Unit>
/**
* Add an audio to a playlist.
@@ -115,7 +117,7 @@
* @param audioUri The URI of the audio
* @return [RequestStatus.Success] if success, [RequestStatus.Error] with an error otherwise
*/
- suspend fun addAudioToPlaylist(playlistUri: Uri, audioUri: Uri): RequestStatus<Unit>
+ suspend fun addAudioToPlaylist(playlistUri: Uri, audioUri: Uri): MediaRequestStatus<Unit>
/**
* Remove an audio from a playlist.
@@ -123,5 +125,5 @@
* @param audioUri The URI of the audio
* @return [RequestStatus.Success] if success, [RequestStatus.Error] with an error otherwise
*/
- suspend fun removeAudioFromPlaylist(playlistUri: Uri, audioUri: Uri): RequestStatus<Unit>
+ suspend fun removeAudioFromPlaylist(playlistUri: Uri, audioUri: Uri): MediaRequestStatus<Unit>
}
diff --git a/app/src/main/java/org/lineageos/twelve/datasources/MediaError.kt b/app/src/main/java/org/lineageos/twelve/datasources/MediaError.kt
new file mode 100644
index 0000000..5a1e558
--- /dev/null
+++ b/app/src/main/java/org/lineageos/twelve/datasources/MediaError.kt
@@ -0,0 +1,41 @@
+/*
+ * SPDX-FileCopyrightText: 2024 The LineageOS Project
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.lineageos.twelve.datasources
+
+/**
+ * [MediaDataSource] errors.
+ */
+enum class MediaError {
+ /**
+ * This feature isn't implemented.
+ */
+ NOT_IMPLEMENTED,
+
+ /**
+ * I/O error, can also be network.
+ */
+ IO,
+
+ /**
+ * Authentication error.
+ */
+ AUTHENTICATION_REQUIRED,
+
+ /**
+ * Invalid credentials.
+ */
+ INVALID_CREDENTIALS,
+
+ /**
+ * The item was not found.
+ */
+ NOT_FOUND,
+
+ /**
+ * Value returned on write requests: The value already exists.
+ */
+ ALREADY_EXISTS,
+}
diff --git a/app/src/main/java/org/lineageos/twelve/datasources/SubsonicDataSource.kt b/app/src/main/java/org/lineageos/twelve/datasources/SubsonicDataSource.kt
index 07e7bd4..84df2a8 100644
--- a/app/src/main/java/org/lineageos/twelve/datasources/SubsonicDataSource.kt
+++ b/app/src/main/java/org/lineageos/twelve/datasources/SubsonicDataSource.kt
@@ -268,26 +268,24 @@
private suspend fun <T, O> SubsonicClient.MethodResult<T>.toRequestStatus(
resultGetter: suspend T.() -> O
- ) = when (this) {
+ ): RequestStatus<O, MediaError> = when (this) {
is SubsonicClient.MethodResult.Success -> RequestStatus.Success(result.resultGetter())
- is SubsonicClient.MethodResult.HttpError -> RequestStatus.Error(RequestStatus.Error.Type.IO)
+ is SubsonicClient.MethodResult.HttpError -> RequestStatus.Error(MediaError.IO)
is SubsonicClient.MethodResult.SubsonicError -> RequestStatus.Error(
- error?.code?.toRequestStatusType() ?: RequestStatus.Error.Type.IO
+ error?.code?.toRequestStatusType() ?: MediaError.IO
)
}
private fun Error.Code.toRequestStatusType() = when (this) {
- Error.Code.GENERIC_ERROR -> RequestStatus.Error.Type.IO
- Error.Code.REQUIRED_PARAMETER_MISSING -> RequestStatus.Error.Type.IO
- Error.Code.OUTDATED_CLIENT -> RequestStatus.Error.Type.IO
- Error.Code.OUTDATED_SERVER -> RequestStatus.Error.Type.IO
- Error.Code.WRONG_CREDENTIALS -> RequestStatus.Error.Type.INVALID_CREDENTIALS
- Error.Code.TOKEN_AUTHENTICATION_NOT_SUPPORTED ->
- RequestStatus.Error.Type.INVALID_CREDENTIALS
-
- Error.Code.USER_NOT_AUTHORIZED -> RequestStatus.Error.Type.INVALID_CREDENTIALS
- Error.Code.SUBSONIC_PREMIUM_TRIAL_ENDED -> RequestStatus.Error.Type.INVALID_CREDENTIALS
- Error.Code.NOT_FOUND -> RequestStatus.Error.Type.NOT_FOUND
+ Error.Code.GENERIC_ERROR -> MediaError.IO
+ Error.Code.REQUIRED_PARAMETER_MISSING -> MediaError.IO
+ Error.Code.OUTDATED_CLIENT -> MediaError.IO
+ Error.Code.OUTDATED_SERVER -> MediaError.IO
+ Error.Code.WRONG_CREDENTIALS -> MediaError.INVALID_CREDENTIALS
+ Error.Code.TOKEN_AUTHENTICATION_NOT_SUPPORTED -> MediaError.INVALID_CREDENTIALS
+ Error.Code.USER_NOT_AUTHORIZED -> MediaError.INVALID_CREDENTIALS
+ Error.Code.SUBSONIC_PREMIUM_TRIAL_ENDED -> MediaError.INVALID_CREDENTIALS
+ Error.Code.NOT_FOUND -> MediaError.NOT_FOUND
}
private fun getAlbumUri(albumId: String) = albumsUri.buildUpon()
diff --git a/app/src/main/java/org/lineageos/twelve/ext/LinearProgressIndicator.kt b/app/src/main/java/org/lineageos/twelve/ext/LinearProgressIndicator.kt
index 3ec0320..6ce27e3 100644
--- a/app/src/main/java/org/lineageos/twelve/ext/LinearProgressIndicator.kt
+++ b/app/src/main/java/org/lineageos/twelve/ext/LinearProgressIndicator.kt
@@ -11,8 +11,8 @@
/**
* @see LinearProgressIndicator.setProgressCompat
*/
-fun <T> LinearProgressIndicator.setProgressCompat(
- status: RequestStatus<T>, animated: Boolean
+fun <T, E> LinearProgressIndicator.setProgressCompat(
+ status: RequestStatus<T, E>, animated: Boolean
) {
when (status) {
is RequestStatus.Loading -> {
diff --git a/app/src/main/java/org/lineageos/twelve/fragments/AlbumFragment.kt b/app/src/main/java/org/lineageos/twelve/fragments/AlbumFragment.kt
index 8bf86a5..edaee44 100644
--- a/app/src/main/java/org/lineageos/twelve/fragments/AlbumFragment.kt
+++ b/app/src/main/java/org/lineageos/twelve/fragments/AlbumFragment.kt
@@ -33,6 +33,7 @@
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.lineageos.twelve.R
+import org.lineageos.twelve.datasources.MediaError
import org.lineageos.twelve.ext.getParcelable
import org.lineageos.twelve.ext.getViewProperty
import org.lineageos.twelve.ext.setProgressCompat
@@ -318,7 +319,7 @@
toolbar.title = ""
albumTitleTextView.text = ""
- if (it.error == RequestStatus.Error.Type.NOT_FOUND) {
+ if (it.error == MediaError.NOT_FOUND) {
// Get out of here
findNavController().navigateUp()
}
diff --git a/app/src/main/java/org/lineageos/twelve/fragments/ArtistFragment.kt b/app/src/main/java/org/lineageos/twelve/fragments/ArtistFragment.kt
index 14779e6..a9bb169 100644
--- a/app/src/main/java/org/lineageos/twelve/fragments/ArtistFragment.kt
+++ b/app/src/main/java/org/lineageos/twelve/fragments/ArtistFragment.kt
@@ -31,6 +31,7 @@
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.lineageos.twelve.R
+import org.lineageos.twelve.datasources.MediaError
import org.lineageos.twelve.ext.getParcelable
import org.lineageos.twelve.ext.getViewProperty
import org.lineageos.twelve.ext.setProgressCompat
@@ -257,7 +258,7 @@
nestedScrollView.isVisible = false
noElementsNestedScrollView.isVisible = true
- if (it.error == RequestStatus.Error.Type.NOT_FOUND) {
+ if (it.error == MediaError.NOT_FOUND) {
// Get out of here
findNavController().navigateUp()
}
diff --git a/app/src/main/java/org/lineageos/twelve/fragments/AudioBottomSheetDialogFragment.kt b/app/src/main/java/org/lineageos/twelve/fragments/AudioBottomSheetDialogFragment.kt
index 31fa7b2..be2863b 100644
--- a/app/src/main/java/org/lineageos/twelve/fragments/AudioBottomSheetDialogFragment.kt
+++ b/app/src/main/java/org/lineageos/twelve/fragments/AudioBottomSheetDialogFragment.kt
@@ -20,6 +20,7 @@
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.coroutines.launch
import org.lineageos.twelve.R
+import org.lineageos.twelve.datasources.MediaError
import org.lineageos.twelve.ext.getParcelable
import org.lineageos.twelve.ext.getViewProperty
import org.lineageos.twelve.models.RequestStatus
@@ -141,7 +142,7 @@
is RequestStatus.Error -> {
Log.e(LOG_TAG, "Failed to load audio, error: ${it.error}")
- if (it.error == RequestStatus.Error.Type.NOT_FOUND) {
+ if (it.error == MediaError.NOT_FOUND) {
// Get out of here
findNavController().navigateUp()
}
diff --git a/app/src/main/java/org/lineageos/twelve/fragments/ManageProviderFragment.kt b/app/src/main/java/org/lineageos/twelve/fragments/ManageProviderFragment.kt
index daa3ca8..a0236a3 100644
--- a/app/src/main/java/org/lineageos/twelve/fragments/ManageProviderFragment.kt
+++ b/app/src/main/java/org/lineageos/twelve/fragments/ManageProviderFragment.kt
@@ -29,6 +29,7 @@
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.lineageos.twelve.R
+import org.lineageos.twelve.datasources.MediaError
import org.lineageos.twelve.ext.getSerializable
import org.lineageos.twelve.ext.getViewProperty
import org.lineageos.twelve.ext.selectItem
@@ -247,7 +248,7 @@
is RequestStatus.Error -> {
Log.e(LOG_TAG, "Failed to load provider")
- if (it.error == RequestStatus.Error.Type.NOT_FOUND) {
+ if (it.error == MediaError.NOT_FOUND) {
// Get out of here
findNavController().navigateUp()
}
diff --git a/app/src/main/java/org/lineageos/twelve/fragments/PlaylistFragment.kt b/app/src/main/java/org/lineageos/twelve/fragments/PlaylistFragment.kt
index 6cd20bc..0b894c2 100644
--- a/app/src/main/java/org/lineageos/twelve/fragments/PlaylistFragment.kt
+++ b/app/src/main/java/org/lineageos/twelve/fragments/PlaylistFragment.kt
@@ -30,6 +30,7 @@
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.lineageos.twelve.R
+import org.lineageos.twelve.datasources.MediaError
import org.lineageos.twelve.ext.getParcelable
import org.lineageos.twelve.ext.getViewProperty
import org.lineageos.twelve.ext.setProgressCompat
@@ -277,7 +278,7 @@
noElementsNestedScrollView.isVisible = true
playAllFloatingActionButton.isVisible = false
- if (it.error == RequestStatus.Error.Type.NOT_FOUND) {
+ if (it.error == MediaError.NOT_FOUND) {
// Get out of here
findNavController().navigateUp()
}
diff --git a/app/src/main/java/org/lineageos/twelve/models/RequestStatus.kt b/app/src/main/java/org/lineageos/twelve/models/RequestStatus.kt
index 560bfa1..50ee9b9 100644
--- a/app/src/main/java/org/lineageos/twelve/models/RequestStatus.kt
+++ b/app/src/main/java/org/lineageos/twelve/models/RequestStatus.kt
@@ -8,59 +8,27 @@
/**
* Request status for flows.
*/
-sealed class RequestStatus<T> {
+sealed class RequestStatus<T, E> {
/**
* Result is not ready yet.
*
* @param progress An optional percentage of the request progress
*/
- class Loading<T>(
+ class Loading<T, E>(
@androidx.annotation.IntRange(from = 0, to = 100) val progress: Int? = null
- ) : RequestStatus<T>()
+ ) : RequestStatus<T, E>()
/**
* The result is ready.
*
* @param data The obtained data
*/
- class Success<T>(val data: T) : RequestStatus<T>()
+ class Success<T, E>(val data: T) : RequestStatus<T, E>()
/**
* The request failed.
*
* @param error The error
*/
- class Error<T>(val error: Type) : RequestStatus<T>() {
- enum class Type {
- /**
- * This feature isn't implemented.
- */
- NOT_IMPLEMENTED,
-
- /**
- * I/O error, can also be network.
- */
- IO,
-
- /**
- * Authentication error.
- */
- AUTHENTICATION_REQUIRED,
-
- /**
- * Invalid credentials.
- */
- INVALID_CREDENTIALS,
-
- /**
- * The item was not found.
- */
- NOT_FOUND,
-
- /**
- * Value returned on write requests: The value already exists.
- */
- ALREADY_EXISTS,
- }
- }
+ class Error<T, E>(val error: E) : RequestStatus<T, E>()
}
diff --git a/app/src/main/java/org/lineageos/twelve/repositories/MediaRepository.kt b/app/src/main/java/org/lineageos/twelve/repositories/MediaRepository.kt
index 9b1162e..9f08828 100644
--- a/app/src/main/java/org/lineageos/twelve/repositories/MediaRepository.kt
+++ b/app/src/main/java/org/lineageos/twelve/repositories/MediaRepository.kt
@@ -25,14 +25,8 @@
import org.lineageos.twelve.database.TwelveDatabase
import org.lineageos.twelve.datasources.LocalDataSource
import org.lineageos.twelve.datasources.MediaDataSource
+import org.lineageos.twelve.datasources.MediaError
import org.lineageos.twelve.datasources.SubsonicDataSource
-import org.lineageos.twelve.models.Album
-import org.lineageos.twelve.models.Artist
-import org.lineageos.twelve.models.ArtistWorks
-import org.lineageos.twelve.models.Audio
-import org.lineageos.twelve.models.Genre
-import org.lineageos.twelve.models.MediaItem
-import org.lineageos.twelve.models.Playlist
import org.lineageos.twelve.models.Provider
import org.lineageos.twelve.models.ProviderArgument.Companion.requireArgument
import org.lineageos.twelve.models.ProviderType
@@ -309,87 +303,78 @@
/**
* @see MediaDataSource.albums
*/
- fun albums(): Flow<RequestStatus<List<Album>>> =
- navigationDataSource.flatMapLatest { it.albums() }
+ fun albums() = navigationDataSource.flatMapLatest { it.albums() }
/**
* @see MediaDataSource.artists
*/
- fun artists(): Flow<RequestStatus<List<Artist>>> =
- navigationDataSource.flatMapLatest { it.artists() }
+ fun artists() = navigationDataSource.flatMapLatest { it.artists() }
/**
* @see MediaDataSource.genres
*/
- fun genres(): Flow<RequestStatus<List<Genre>>> =
- navigationDataSource.flatMapLatest { it.genres() }
+ fun genres() = navigationDataSource.flatMapLatest { it.genres() }
/**
* @see MediaDataSource.playlists
*/
- fun playlists(): Flow<RequestStatus<List<Playlist>>> =
- navigationDataSource.flatMapLatest { it.playlists() }
+ fun playlists() = navigationDataSource.flatMapLatest { it.playlists() }
/**
* @see MediaDataSource.search
*/
- fun search(query: String): Flow<RequestStatus<List<MediaItem<*>>>> =
- navigationDataSource.flatMapLatest { it.search(query) }
+ fun search(query: String) = navigationDataSource.flatMapLatest { it.search(query) }
/**
* @see MediaDataSource.audio
*/
- fun audio(audioUri: Uri): Flow<RequestStatus<Audio>> = withMediaItemsDataSourceFlow(audioUri) {
+ fun audio(audioUri: Uri) = withMediaItemsDataSourceFlow(audioUri) {
audio(audioUri)
}
/**
* @see MediaDataSource.album
*/
- fun album(albumUri: Uri): Flow<RequestStatus<Pair<Album, List<Audio>>>> =
- withMediaItemsDataSourceFlow(albumUri) {
- album(albumUri)
- }
+ fun album(albumUri: Uri) = withMediaItemsDataSourceFlow(albumUri) {
+ album(albumUri)
+ }
/**
* @see MediaDataSource.artist
*/
- fun artist(artistUri: Uri): Flow<RequestStatus<Pair<Artist, ArtistWorks>>> =
- withMediaItemsDataSourceFlow(artistUri) {
- artist(artistUri)
- }
+ fun artist(artistUri: Uri) = withMediaItemsDataSourceFlow(artistUri) {
+ artist(artistUri)
+ }
/**
* @see MediaDataSource.playlist
*/
- fun playlist(playlistUri: Uri): Flow<RequestStatus<Pair<Playlist, List<Audio?>>>> =
- withMediaItemsDataSourceFlow(playlistUri) {
- playlist(playlistUri)
- }
+ fun playlist(playlistUri: Uri) = withMediaItemsDataSourceFlow(playlistUri) {
+ playlist(playlistUri)
+ }
/**
* @see MediaDataSource.audioPlaylistsStatus
*/
- fun audioPlaylistsStatus(audioUri: Uri): Flow<RequestStatus<List<Pair<Playlist, Boolean>>>> =
- withMediaItemsDataSourceFlow(audioUri) {
- audioPlaylistsStatus(audioUri)
- }
+ fun audioPlaylistsStatus(audioUri: Uri) = withMediaItemsDataSourceFlow(audioUri) {
+ audioPlaylistsStatus(audioUri)
+ }
/**
* @see MediaDataSource.createPlaylist
*/
suspend fun createPlaylist(
provider: Provider, name: String
- ): RequestStatus<Uri> = getDataSource(provider)?.createPlaylist(
+ ) = getDataSource(provider)?.createPlaylist(
name
) ?: RequestStatus.Error(
- RequestStatus.Error.Type.NOT_FOUND
+ MediaError.NOT_FOUND
)
/**
* @see MediaDataSource.renamePlaylist
*/
- suspend fun renamePlaylist(playlistUri: Uri, name: String): RequestStatus<Unit> =
+ suspend fun renamePlaylist(playlistUri: Uri, name: String) =
withMediaItemsDataSource(playlistUri) {
renamePlaylist(playlistUri, name)
}
@@ -397,15 +382,14 @@
/**
* @see MediaDataSource.deletePlaylist
*/
- suspend fun deletePlaylist(playlistUri: Uri): RequestStatus<Unit> =
- withMediaItemsDataSource(playlistUri) {
- deletePlaylist(playlistUri)
- }
+ suspend fun deletePlaylist(playlistUri: Uri) = withMediaItemsDataSource(playlistUri) {
+ deletePlaylist(playlistUri)
+ }
/**
* @see MediaDataSource.addAudioToPlaylist
*/
- suspend fun addAudioToPlaylist(playlistUri: Uri, audioUri: Uri): RequestStatus<Unit> =
+ suspend fun addAudioToPlaylist(playlistUri: Uri, audioUri: Uri) =
withMediaItemsDataSource(playlistUri, audioUri) {
addAudioToPlaylist(playlistUri, audioUri)
}
@@ -413,7 +397,7 @@
/**
* @see MediaDataSource.removeAudioFromPlaylist
*/
- suspend fun removeAudioFromPlaylist(playlistUri: Uri, audioUri: Uri): RequestStatus<Unit> =
+ suspend fun removeAudioFromPlaylist(playlistUri: Uri, audioUri: Uri) =
withMediaItemsDataSource(playlistUri, audioUri) {
removeAudioFromPlaylist(playlistUri, audioUri)
}
@@ -463,11 +447,11 @@
* no [MediaDataSource] can handle the given URIs
*/
private fun <T> withMediaItemsDataSourceFlow(
- vararg uris: Uri, predicate: MediaDataSource.() -> Flow<RequestStatus<T>>
+ vararg uris: Uri, predicate: MediaDataSource.() -> Flow<RequestStatus<T, MediaError>>
) = allProvidersToDataSource.flatMapLatest {
it.firstOrNull { (_, dataSource) ->
uris.all { uri -> dataSource.isMediaItemCompatible(uri) }
- }?.second?.predicate() ?: flowOf(RequestStatus.Error(RequestStatus.Error.Type.NOT_FOUND))
+ }?.second?.predicate() ?: flowOf(RequestStatus.Error(MediaError.NOT_FOUND))
}
/**
@@ -479,10 +463,10 @@
* error if no [MediaDataSource] can handle the given URIs
*/
private suspend fun <T> withMediaItemsDataSource(
- vararg uris: Uri, predicate: suspend MediaDataSource.() -> RequestStatus<T>
+ vararg uris: Uri, predicate: suspend MediaDataSource.() -> RequestStatus<T, MediaError>
) = allProvidersToDataSource.value.firstOrNull { (_, dataSource) ->
uris.all { uri -> dataSource.isMediaItemCompatible(uri) }
- }?.second?.predicate() ?: RequestStatus.Error(RequestStatus.Error.Type.NOT_FOUND)
+ }?.second?.predicate() ?: RequestStatus.Error(MediaError.NOT_FOUND)
companion object {
private const val LOCAL_PROVIDER_ID = 0L
diff --git a/app/src/main/java/org/lineageos/twelve/services/MediaRepositoryTree.kt b/app/src/main/java/org/lineageos/twelve/services/MediaRepositoryTree.kt
index 3af5a86..8ad3265 100644
--- a/app/src/main/java/org/lineageos/twelve/services/MediaRepositoryTree.kt
+++ b/app/src/main/java/org/lineageos/twelve/services/MediaRepositoryTree.kt
@@ -261,7 +261,7 @@
* Converts a flow of [RequestStatus] to a one-shot result of [T].
* Raises an exception on error.
*/
- private suspend fun <T> Flow<RequestStatus<T>>.toOneShotResult() = mapNotNull {
+ private suspend fun <T, E> Flow<RequestStatus<T, E>>.toOneShotResult() = mapNotNull {
when (it) {
is RequestStatus.Loading -> {
null
diff --git a/app/src/main/java/org/lineageos/twelve/viewmodels/ManageProviderViewModel.kt b/app/src/main/java/org/lineageos/twelve/viewmodels/ManageProviderViewModel.kt
index e9fcb16..bb0b907 100644
--- a/app/src/main/java/org/lineageos/twelve/viewmodels/ManageProviderViewModel.kt
+++ b/app/src/main/java/org/lineageos/twelve/viewmodels/ManageProviderViewModel.kt
@@ -20,6 +20,7 @@
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
+import org.lineageos.twelve.datasources.MediaError
import org.lineageos.twelve.models.ProviderType
import org.lineageos.twelve.models.RequestStatus
@@ -57,8 +58,8 @@
providerIds.first, providerIds.second
).mapLatest { provider ->
provider?.let {
- RequestStatus.Success(it)
- } ?: RequestStatus.Error(RequestStatus.Error.Type.NOT_FOUND)
+ RequestStatus.Success<_, MediaError>(it)
+ } ?: RequestStatus.Error(MediaError.NOT_FOUND)
}
} ?: flowOf(RequestStatus.Success(null))
}
diff --git a/app/src/main/java/org/lineageos/twelve/viewmodels/NowPlayingViewModel.kt b/app/src/main/java/org/lineageos/twelve/viewmodels/NowPlayingViewModel.kt
index d882028..dc42c54 100644
--- a/app/src/main/java/org/lineageos/twelve/viewmodels/NowPlayingViewModel.kt
+++ b/app/src/main/java/org/lineageos/twelve/viewmodels/NowPlayingViewModel.kt
@@ -157,7 +157,7 @@
when (playbackState) {
PlaybackState.BUFFERING -> RequestStatus.Loading()
- else -> RequestStatus.Success(
+ else -> RequestStatus.Success<_, Nothing>(
mediaMetadata.artworkUri?.let {
Thumbnail(uri = it)
} ?: mediaMetadata.artworkData?.let {
diff --git a/app/src/main/java/org/lineageos/twelve/viewmodels/ProvidersViewModel.kt b/app/src/main/java/org/lineageos/twelve/viewmodels/ProvidersViewModel.kt
index 283cded..2fb5545 100644
--- a/app/src/main/java/org/lineageos/twelve/viewmodels/ProvidersViewModel.kt
+++ b/app/src/main/java/org/lineageos/twelve/viewmodels/ProvidersViewModel.kt
@@ -19,7 +19,7 @@
open class ProvidersViewModel(application: Application) : TwelveViewModel(application) {
@OptIn(ExperimentalCoroutinesApi::class)
val providers = mediaRepository.allProviders
- .mapLatest { RequestStatus.Success(it) }
+ .mapLatest { RequestStatus.Success<_, Nothing>(it) }
.flowOn(Dispatchers.IO)
.stateIn(
viewModelScope,