From 53ccc81df262ca43cc960840553721298669374f Mon Sep 17 00:00:00 2001 From: Kirill Zhukov Date: Sat, 8 Feb 2025 11:40:43 +0300 Subject: [PATCH] Favorites screens for albums and artists --- app/build.gradle | 4 +- app/src/main/java/ru/stersh/youamp/Di.kt | 24 +- .../ru/stersh/youamp/main/ui/MainActivity.kt | 42 +++- .../ru/stersh/youamp/main/ui/Navigation.kt | 8 +- buildscripts/android-feature-module.gradle | 4 + .../java/ru/stersh/youamp/core/api/Album.kt | 4 +- .../java/ru/stersh/youamp/core/api/Artist.kt | 2 + .../list => album/favorites}/.gitignore | 0 feature/album/favorites/build.gradle | 22 ++ .../favorites}/consumer-rules.pro | 0 .../favorites}/proguard-rules.pro | 0 .../favorites}/src/main/AndroidManifest.xml | 0 .../youamp/feature/album/favorites/Di.kt | 12 + .../data/FavoriteAlbumsRepositoryImpl.kt | 33 +++ .../feature/album/favorites/domain/Album.kt | 9 + .../domain/FavoriteAlbumsRepository.kt | 7 + .../album/favorites/domain/Favorites.kt | 5 + .../favorites/ui/FavoriteAlbumsScreen.kt | 221 ++++++++++++++++++ .../favorites/ui/FavoriteAlbumsViewModel.kt | 100 ++++++++ .../feature/album/favorites/ui/Mapper.kt | 17 ++ .../feature/album/favorites/ui/StateUi.kt | 22 ++ .../favorites/src/main/res/values/strings.xml | 4 + .../ru/stersh/youamp/feature/albums/Di.kt | 2 +- feature/artist/favorites/.gitignore | 1 + feature/artist/favorites/build.gradle | 22 ++ feature/artist/favorites/consumer-rules.pro | 0 feature/artist/favorites/proguard-rules.pro | 21 ++ .../favorites/src/main/AndroidManifest.xml | 4 + .../youamp/feature/artist/favorites/Di.kt | 12 + .../data/FavoriteArtistsRepositoryImpl.kt | 32 +++ .../feature/artist/favorites/domain/Artist.kt | 8 + .../domain/FavoriteArtistsRepository.kt | 7 + .../artist/favorites/domain/Favorites.kt | 5 + .../favorites/ui/FavoriteArtistScreen.kt | 215 +++++++++++++++++ .../favorites/ui/FavoriteArtistViewModel.kt | 100 ++++++++ .../feature/artist/favorites/ui/Mapper.kt | 16 ++ .../feature/artist/favorites/ui/StateUi.kt | 21 ++ .../favorites/src/main/res/values/strings.xml | 4 + .../ru/stersh/youamp/feature/artists/Di.kt | 2 +- .../stresh/youamp/feature/favorite/list/Di.kt | 12 - feature/song/favorites/.gitignore | 1 + .../list => song/favorites}/build.gradle | 2 +- feature/song/favorites/consumer-rules.pro | 0 feature/song/favorites/proguard-rules.pro | 21 ++ .../favorites/src/main/AndroidManifest.xml | 4 + .../youamp/feature/song/favorites/Di.kt | 12 + .../data/FavoriteSongsRepositoryImpl.kt | 8 +- .../domain/FavoriteSongsRepository.kt | 2 +- .../song/favorites}/domain/Favorites.kt | 2 +- .../feature/song/favorites}/domain/Song.kt | 2 +- .../song/favorites}/ui/FavoriteSongsScreen.kt | 4 +- .../favorites}/ui/FavoriteSongsViewModel.kt | 4 +- .../feature/song/favorites}/ui/Mapper.kt | 6 +- .../feature/song/favorites}/ui/StateUi.kt | 2 +- .../src/main/res/values-fr-rFR/strings.xml | 0 .../src/main/res/values-it-rIT/strings.xml | 0 .../src/main/res/values-ru-rRU/strings.xml | 0 .../src/main/res/values/strings.xml | 0 settings.gradle | 4 +- .../stresh/youamp/shared/favorites/Album.kt | 3 +- .../stresh/youamp/shared/favorites/Artist.kt | 3 +- .../shared/favorites/FavoritesStorageImpl.kt | 6 +- 62 files changed, 1059 insertions(+), 51 deletions(-) rename feature/{favorite/list => album/favorites}/.gitignore (100%) create mode 100644 feature/album/favorites/build.gradle rename feature/{favorite/list => album/favorites}/consumer-rules.pro (100%) rename feature/{favorite/list => album/favorites}/proguard-rules.pro (100%) rename feature/{favorite/list => album/favorites}/src/main/AndroidManifest.xml (100%) create mode 100644 feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/Di.kt create mode 100644 feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/data/FavoriteAlbumsRepositoryImpl.kt create mode 100644 feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/domain/Album.kt create mode 100644 feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/domain/FavoriteAlbumsRepository.kt create mode 100644 feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/domain/Favorites.kt create mode 100644 feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/FavoriteAlbumsScreen.kt create mode 100644 feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/FavoriteAlbumsViewModel.kt create mode 100644 feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/Mapper.kt create mode 100644 feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/StateUi.kt create mode 100644 feature/album/favorites/src/main/res/values/strings.xml create mode 100644 feature/artist/favorites/.gitignore create mode 100644 feature/artist/favorites/build.gradle create mode 100644 feature/artist/favorites/consumer-rules.pro create mode 100644 feature/artist/favorites/proguard-rules.pro create mode 100644 feature/artist/favorites/src/main/AndroidManifest.xml create mode 100644 feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/Di.kt create mode 100644 feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/data/FavoriteArtistsRepositoryImpl.kt create mode 100644 feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/domain/Artist.kt create mode 100644 feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/domain/FavoriteArtistsRepository.kt create mode 100644 feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/domain/Favorites.kt create mode 100644 feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/FavoriteArtistScreen.kt create mode 100644 feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/FavoriteArtistViewModel.kt create mode 100644 feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/Mapper.kt create mode 100644 feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/StateUi.kt create mode 100644 feature/artist/favorites/src/main/res/values/strings.xml delete mode 100644 feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/Di.kt create mode 100644 feature/song/favorites/.gitignore rename feature/{favorite/list => song/favorites}/build.gradle (91%) create mode 100644 feature/song/favorites/consumer-rules.pro create mode 100644 feature/song/favorites/proguard-rules.pro create mode 100644 feature/song/favorites/src/main/AndroidManifest.xml create mode 100644 feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/Di.kt rename feature/{favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list => song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites}/data/FavoriteSongsRepositoryImpl.kt (76%) rename feature/{favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list => song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites}/domain/FavoriteSongsRepository.kt (69%) rename feature/{favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list => song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites}/domain/Favorites.kt (52%) rename feature/{favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list => song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites}/domain/Song.kt (73%) rename feature/{favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list => song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites}/ui/FavoriteSongsScreen.kt (98%) rename feature/{favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list => song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites}/ui/FavoriteSongsViewModel.kt (96%) rename feature/{favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list => song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites}/ui/Mapper.kt (56%) rename feature/{favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list => song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites}/ui/StateUi.kt (88%) rename feature/{favorite/list => song/favorites}/src/main/res/values-fr-rFR/strings.xml (100%) rename feature/{favorite/list => song/favorites}/src/main/res/values-it-rIT/strings.xml (100%) rename feature/{favorite/list => song/favorites}/src/main/res/values-ru-rRU/strings.xml (100%) rename feature/{favorite/list => song/favorites}/src/main/res/values/strings.xml (100%) diff --git a/app/build.gradle b/app/build.gradle index 1dfaaa1f..1df32dd6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -79,8 +79,10 @@ dependencies { implementation project(":shared:song:random") implementation project(':feature:album:list') implementation project(':feature:album:info') + implementation project(':feature:album:favorites') implementation project(':feature:artist:list') implementation project(':feature:artist:info') + implementation project(':feature:artist:favorites') implementation project(':feature:playlist:list') implementation project(':feature:playlist:info') implementation project(":feature:main") @@ -91,7 +93,7 @@ dependencies { implementation project(":feature:server:list") implementation project(":feature:search") implementation project(":feature:song:info") - implementation project(":feature:favorite:list") + implementation project(":feature:song:favorites") implementation project(":feature:settings") implementation project(":feature:about") implementation project(":feature:personal") diff --git a/app/src/main/java/ru/stersh/youamp/Di.kt b/app/src/main/java/ru/stersh/youamp/Di.kt index 0f9a7c6f..c586ba35 100644 --- a/app/src/main/java/ru/stersh/youamp/Di.kt +++ b/app/src/main/java/ru/stersh/youamp/Di.kt @@ -10,9 +10,9 @@ import org.koin.dsl.module import ru.stersh.youamp.core.api.provider.ApiProvider import ru.stersh.youamp.core.room.roomModule import ru.stersh.youamp.feature.album.albumInfoModule -import ru.stersh.youamp.feature.albums.albumsModule +import ru.stersh.youamp.feature.albums.albumListModule import ru.stersh.youamp.feature.artist.artistInfoModule -import ru.stersh.youamp.feature.artists.artistsModule +import ru.stersh.youamp.feature.artists.artistListModule import ru.stersh.youamp.feature.main.mainModule import ru.stersh.youamp.feature.personal.personalModule import ru.stersh.youamp.feature.player.mini.playerMiniModule @@ -33,9 +33,11 @@ import ru.stersh.youamp.shared.player.playerSharedModule import ru.stresh.youamp.core.properties.app.AppProperties import ru.stresh.youamp.core.propertiesModule import ru.stresh.youamp.feature.about.aboutModule +import ru.stresh.youamp.feature.album.favorites.albumFavoritesModule +import ru.stresh.youamp.feature.artist.favorites.artistFavoritesModule import ru.stresh.youamp.feature.explore.exploreModule -import ru.stresh.youamp.feature.favorite.list.favoriteListModule import ru.stresh.youamp.feature.library.libraryModule +import ru.stresh.youamp.feature.song.favorites.songFavoritesModule import ru.stresh.youamp.feature.song.random.songRandomModule import ru.stresh.youamp.shared.favorites.favoritesSharedModule import ru.stresh.youamp.shared.song.random.songRandomSharedModule @@ -63,22 +65,24 @@ private val feature = listOf( playerScreenModule, playerQueueScreenModule, albumInfoModule, - albumsModule, - artistsModule, + albumFavoritesModule, + albumListModule, + artistListModule, artistInfoModule, + artistFavoritesModule, serverCreateModule, serverListModule, playlistListModule, - searchModule, playlistInfoModule, - favoriteListModule, + searchModule, + songFavoritesModule, + songInfoModule, + songRandomModule, aboutModule, personalModule, exploreModule, mainModule, - libraryModule, - songInfoModule, - songRandomModule + libraryModule ) private val impl = module { diff --git a/app/src/main/java/ru/stersh/youamp/main/ui/MainActivity.kt b/app/src/main/java/ru/stersh/youamp/main/ui/MainActivity.kt index dd3a2ca3..439b5265 100644 --- a/app/src/main/java/ru/stersh/youamp/main/ui/MainActivity.kt +++ b/app/src/main/java/ru/stersh/youamp/main/ui/MainActivity.kt @@ -50,10 +50,12 @@ import ru.stersh.youamp.feature.server.create.ui.ServerScreen import ru.stersh.youamp.feature.server.list.ui.ServerListScreen import ru.stersh.youamp.feature.song.info.ui.SongInfoScreen import ru.stresh.youamp.feature.about.ui.AboutScreen +import ru.stresh.youamp.feature.album.favorites.ui.FavoriteAlbumsScreen +import ru.stresh.youamp.feature.artist.favorites.ui.FavoriteArtistsScreen import ru.stresh.youamp.feature.explore.ui.ExploreScreen -import ru.stresh.youamp.feature.favorite.list.ui.FavoriteSongsScreen import ru.stresh.youamp.feature.library.ui.LibraryScreen import ru.stresh.youamp.feature.settings.ui.SettingsScreen +import ru.stresh.youamp.feature.song.favorites.ui.FavoriteSongsScreen import ru.stresh.youamp.feature.song.random.ui.RandomSongsScreen class MainActivity : ComponentActivity() { @@ -143,8 +145,8 @@ class MainActivity : ComponentActivity() { onPlaylistClick = { rootNavController.navigate(PlaylistInfo(it)) }, onPlaylistsClick = { rootNavController.navigate(Playlists) }, onFavoriteSongsClick = { rootNavController.navigate(FavoriteSongs) }, - onFavoriteAlbumsClick = {}, - onFavoriteArtistsClick = {} + onFavoriteAlbumsClick = { rootNavController.navigate(FavoriteAlbums) }, + onFavoriteArtistsClick = { rootNavController.navigate(FavoriteArtists) } ) }, explore = { @@ -437,6 +439,40 @@ class MainActivity : ComponentActivity() { ) } } + composable { + ScreenWithMiniPlayer( + viewModelStoreOwner = viewModelStoreOwner, + onMiniPlayerClick = { + rootNavController.navigate(Player) + } + ) { + FavoriteAlbumsScreen( + onBackClick = { + rootNavController.popBackStack() + }, + onAlbumClick = { + rootNavController.navigate(AlbumInfo(it)) + } + ) + } + } + composable { + ScreenWithMiniPlayer( + viewModelStoreOwner = viewModelStoreOwner, + onMiniPlayerClick = { + rootNavController.navigate(Player) + } + ) { + FavoriteArtistsScreen( + onBackClick = { + rootNavController.popBackStack() + }, + onArtistClick = { + rootNavController.navigate(ArtistInfo(it)) + } + ) + } + } } songInfoProperties?.let { songProperties -> ModalBottomSheet( diff --git a/app/src/main/java/ru/stersh/youamp/main/ui/Navigation.kt b/app/src/main/java/ru/stersh/youamp/main/ui/Navigation.kt index ac280872..79955395 100644 --- a/app/src/main/java/ru/stersh/youamp/main/ui/Navigation.kt +++ b/app/src/main/java/ru/stersh/youamp/main/ui/Navigation.kt @@ -59,4 +59,10 @@ object Playlists object FavoriteSongs @Serializable -object RandomSongs \ No newline at end of file +object RandomSongs + +@Serializable +object FavoriteAlbums + +@Serializable +object FavoriteArtists \ No newline at end of file diff --git a/buildscripts/android-feature-module.gradle b/buildscripts/android-feature-module.gradle index 0c3fad56..bc2c0f72 100644 --- a/buildscripts/android-feature-module.gradle +++ b/buildscripts/android-feature-module.gradle @@ -7,6 +7,10 @@ android { freeCompilerArgs.add('-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi') } } + composeCompiler { + reportsDestination = layout.buildDirectory.dir("compose_compiler") + metricsDestination = layout.buildDirectory.dir("compose_compiler") + } buildFeatures { compose true } diff --git a/core/api/src/main/java/ru/stersh/youamp/core/api/Album.kt b/core/api/src/main/java/ru/stersh/youamp/core/api/Album.kt index f2e49c69..be1e35e9 100644 --- a/core/api/src/main/java/ru/stersh/youamp/core/api/Album.kt +++ b/core/api/src/main/java/ru/stersh/youamp/core/api/Album.kt @@ -54,7 +54,9 @@ data class Album( @Json(name = "songCount") val songCount: Int?, @Json(name = "year") - val year: Int? + val year: Int?, + @Json(name = "userRating") + val userRating: Int? ) @JsonClass(generateAdapter = true) diff --git a/core/api/src/main/java/ru/stersh/youamp/core/api/Artist.kt b/core/api/src/main/java/ru/stersh/youamp/core/api/Artist.kt index 965b1caa..81a8f014 100644 --- a/core/api/src/main/java/ru/stersh/youamp/core/api/Artist.kt +++ b/core/api/src/main/java/ru/stersh/youamp/core/api/Artist.kt @@ -41,4 +41,6 @@ data class Artist( val artistImageUrl: String?, @Json(name = "album") val albums: List?, + @Json(name = "userRating") + val userRating: Int? ) diff --git a/feature/favorite/list/.gitignore b/feature/album/favorites/.gitignore similarity index 100% rename from feature/favorite/list/.gitignore rename to feature/album/favorites/.gitignore diff --git a/feature/album/favorites/build.gradle b/feature/album/favorites/build.gradle new file mode 100644 index 00000000..c3261f32 --- /dev/null +++ b/feature/album/favorites/build.gradle @@ -0,0 +1,22 @@ +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose.compiler) +} + +apply from: "${project.rootDir}/buildscripts/android-feature-module.gradle" + +android { + namespace 'ru.stersh.youamp.feature.album.favorites' +} + +dependencies { + implementation project(":core:ui") + implementation project(":core:api") + implementation project(":shared:player") + implementation project(":shared:favorites") + implementation(libs.bundles.lifecycle) + implementation(libs.coil.compose) + implementation(libs.bundles.koin) + implementation(libs.timber) +} \ No newline at end of file diff --git a/feature/favorite/list/consumer-rules.pro b/feature/album/favorites/consumer-rules.pro similarity index 100% rename from feature/favorite/list/consumer-rules.pro rename to feature/album/favorites/consumer-rules.pro diff --git a/feature/favorite/list/proguard-rules.pro b/feature/album/favorites/proguard-rules.pro similarity index 100% rename from feature/favorite/list/proguard-rules.pro rename to feature/album/favorites/proguard-rules.pro diff --git a/feature/favorite/list/src/main/AndroidManifest.xml b/feature/album/favorites/src/main/AndroidManifest.xml similarity index 100% rename from feature/favorite/list/src/main/AndroidManifest.xml rename to feature/album/favorites/src/main/AndroidManifest.xml diff --git a/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/Di.kt b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/Di.kt new file mode 100644 index 00000000..4c3a29ba --- /dev/null +++ b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/Di.kt @@ -0,0 +1,12 @@ +package ru.stresh.youamp.feature.album.favorites + +import org.koin.core.module.dsl.viewModel +import org.koin.dsl.module +import ru.stresh.youamp.feature.album.favorites.data.FavoriteAlbumsRepositoryImpl +import ru.stresh.youamp.feature.album.favorites.domain.FavoriteAlbumsRepository +import ru.stresh.youamp.feature.album.favorites.ui.FavoriteAlbumsViewModel + +val albumFavoritesModule = module { + single { FavoriteAlbumsRepositoryImpl(get()) } + viewModel { FavoriteAlbumsViewModel(get(), get()) } +} \ No newline at end of file diff --git a/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/data/FavoriteAlbumsRepositoryImpl.kt b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/data/FavoriteAlbumsRepositoryImpl.kt new file mode 100644 index 00000000..0d22398d --- /dev/null +++ b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/data/FavoriteAlbumsRepositoryImpl.kt @@ -0,0 +1,33 @@ +package ru.stresh.youamp.feature.album.favorites.data + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import ru.stresh.youamp.feature.album.favorites.domain.Album +import ru.stresh.youamp.feature.album.favorites.domain.FavoriteAlbumsRepository +import ru.stresh.youamp.feature.album.favorites.domain.Favorites +import ru.stresh.youamp.shared.favorites.AlbumFavoritesStorage + +internal class FavoriteAlbumsRepositoryImpl( + private val albumFavoritesStorage: AlbumFavoritesStorage +) : FavoriteAlbumsRepository { + + override fun getFavorites(): Flow { + return albumFavoritesStorage + .flowAlbums() + .map { favoriteAlbums -> + Favorites( + albums = favoriteAlbums.map { it.toDomain() } + ) + } + } + + private fun ru.stresh.youamp.shared.favorites.Album.toDomain(): Album { + return Album( + id = id, + title = title, + artist = artist, + artworkUrl = artworkUrl, + userRating = userRating + ) + } +} \ No newline at end of file diff --git a/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/domain/Album.kt b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/domain/Album.kt new file mode 100644 index 00000000..5138985c --- /dev/null +++ b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/domain/Album.kt @@ -0,0 +1,9 @@ +package ru.stresh.youamp.feature.album.favorites.domain + +internal data class Album( + val id: String, + val title: String, + val artist: String?, + val artworkUrl: String?, + val userRating: Int? +) diff --git a/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/domain/FavoriteAlbumsRepository.kt b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/domain/FavoriteAlbumsRepository.kt new file mode 100644 index 00000000..ab1e972c --- /dev/null +++ b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/domain/FavoriteAlbumsRepository.kt @@ -0,0 +1,7 @@ +package ru.stresh.youamp.feature.album.favorites.domain + +import kotlinx.coroutines.flow.Flow + +internal interface FavoriteAlbumsRepository { + fun getFavorites(): Flow +} \ No newline at end of file diff --git a/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/domain/Favorites.kt b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/domain/Favorites.kt new file mode 100644 index 00000000..149bb8dc --- /dev/null +++ b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/domain/Favorites.kt @@ -0,0 +1,5 @@ +package ru.stresh.youamp.feature.album.favorites.domain + +internal data class Favorites( + val albums: List +) diff --git a/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/FavoriteAlbumsScreen.kt b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/FavoriteAlbumsScreen.kt new file mode 100644 index 00000000..a21e50af --- /dev/null +++ b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/FavoriteAlbumsScreen.kt @@ -0,0 +1,221 @@ +package ru.stresh.youamp.feature.album.favorites.ui + +import android.content.res.Configuration +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.GridItemSpan +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.lazy.grid.items +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.ListItem +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.pulltorefresh.PullToRefreshBox +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import org.koin.androidx.compose.koinViewModel +import ru.stersh.youamp.core.ui.AlbumItem +import ru.stersh.youamp.core.ui.BackNavigationButton +import ru.stersh.youamp.core.ui.EmptyLayout +import ru.stersh.youamp.core.ui.ErrorLayout +import ru.stersh.youamp.core.ui.HeaderLayout +import ru.stersh.youamp.core.ui.HeaderTitle +import ru.stersh.youamp.core.ui.PlayAllButton +import ru.stersh.youamp.core.ui.PlayShuffledButton +import ru.stersh.youamp.core.ui.SkeletonLayout +import ru.stersh.youamp.feature.album.favorites.R + +@Composable +fun FavoriteAlbumsScreen( + onAlbumClick: (id: String) -> Unit, + onBackClick: () -> Unit +) { + val viewModel: FavoriteAlbumsViewModel = koinViewModel() + val state by viewModel.state.collectAsStateWithLifecycle() + + FavoriteAlbumsScreen( + state = state, + onPlayAll = viewModel::playAll, + onPlayShuffled = viewModel::playShuffled, + onRetry = viewModel::retry, + onRefresh = viewModel::refresh, + onAlbumClick = onAlbumClick, + onBackClick = onBackClick + ) +} + +@Composable +private fun FavoriteAlbumsScreen( + state: StateUi, + onPlayAll: () -> Unit, + onPlayShuffled: () -> Unit, + onRetry: () -> Unit, + onRefresh: () -> Unit, + onAlbumClick: (id: String) -> Unit, + onBackClick: () -> Unit +) { + Scaffold( + topBar = { + TopAppBar( + title = {}, + navigationIcon = { + BackNavigationButton(onClick = onBackClick) + } + ) + } + ) { + PullToRefreshBox( + isRefreshing = state.isRefreshing, + onRefresh = onRefresh, + modifier = Modifier.padding(it) + ) { + when { + state.progress -> { + Progress() + } + + state.error -> { + ErrorLayout(onRetry = onRetry) + } + + state.data != null && state.data.albums.isEmpty() -> { + EmptyLayout( + modifier = Modifier.verticalScroll( + state = rememberScrollState() + ) + ) + } + + state.data?.albums != null -> { + LazyVerticalGrid( + columns = GridCells.Fixed(2), + contentPadding = PaddingValues(16.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + modifier = Modifier.fillMaxSize() + ) { + item( + contentType = "header", + key = "header", + span = { GridItemSpan(2) } + ) { + HeaderLayout( + title = { + HeaderTitle(text = stringResource(R.string.favorite_albums_title)) + }, + actions = { + PlayAllButton( + onClick = onPlayAll + ) + PlayShuffledButton( + onClick = onPlayShuffled + ) + } + ) + } + items( + items = state.data.albums, + contentType = { "album" }, + key = { "album_${it.id}" } + ) { album -> + AlbumItem( + title = album.title, + onClick = { onAlbumClick(album.id) }, + artist = album.artist, + artworkUrl = album.artworkUrl + ) + } + } + } + } + } + } +} + +@Composable +private fun Progress() { + SkeletonLayout { + repeat(10) { + ListItem( + headlineContent = { + Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { + SkeletonItem(modifier = Modifier.size(width = 130.dp, height = 16.dp)) + SkeletonItem(modifier = Modifier.size(width = 200.dp, height = 16.dp)) + } + }, + leadingContent = { + SkeletonItem(modifier = Modifier.size(48.dp)) + } + ) + } + } +} + +@Preview +@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun FavoriteAlbumsScreenPreview() { + MaterialTheme { + val albums = listOf( + AlbumUi( + id = "1", + title = "Best alubm in the world 1", + artist = "Best artist in the world 1", + artworkUrl = null + ), + AlbumUi( + id = "2", + title = "Best alubm in the world 2", + artist = "Best artist in the world 1", + artworkUrl = null + ), + AlbumUi( + id = "3", + title = "Best alubm in the world 3", + artist = "Best artist in the world 1", + artworkUrl = null + ), + AlbumUi( + id = "4", + title = "Best alubm in the world 4", + artist = "Best artist in the world 1", + artworkUrl = null + ), + AlbumUi( + id = "5", + title = "Best alubm in the world 5", + artist = "Best artist in the world 1", + artworkUrl = null + ), + ) + val state = StateUi( + progress = false, + isRefreshing = false, + error = false, + data = DataUi( + albums = albums + ) + ) + FavoriteAlbumsScreen( + state = state, + onPlayAll = {}, + onPlayShuffled = {}, + onRetry = {}, + onRefresh = {}, + onAlbumClick = {}, + onBackClick = {} + ) + } +} \ No newline at end of file diff --git a/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/FavoriteAlbumsViewModel.kt b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/FavoriteAlbumsViewModel.kt new file mode 100644 index 00000000..bdde0a47 --- /dev/null +++ b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/FavoriteAlbumsViewModel.kt @@ -0,0 +1,100 @@ +package ru.stresh.youamp.feature.album.favorites.ui + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import ru.stersh.youamp.shared.player.queue.AudioSource +import ru.stersh.youamp.shared.player.queue.PlayerQueueAudioSourceManager +import ru.stresh.youamp.feature.album.favorites.domain.FavoriteAlbumsRepository +import timber.log.Timber + +internal class FavoriteAlbumsViewModel( + private val favoriteAlbumsRepository: FavoriteAlbumsRepository, + private val playerQueueAudioSourceManager: PlayerQueueAudioSourceManager +) : ViewModel() { + private val _state = MutableStateFlow(StateUi()) + val state: StateFlow + get() = _state + + private var getFavoritesJob: Job? = null + + init { + retry() + } + + fun playAll() = viewModelScope.launch { + playFavorites() + } + + fun playShuffled() = viewModelScope.launch { + playFavorites(true) + } + + fun refresh() { + _state.update { + it.copy(isRefreshing = true) + } + getFavorites() + } + + fun retry() { + _state.update { + it.copy( + progress = true, + isRefreshing = false, + error = false, + data = null + ) + } + getFavorites() + } + + private suspend fun playFavorites(shuffled: Boolean = false) { + val favorites = runCatching { favoriteAlbumsRepository.getFavorites().first() } + .onFailure { Timber.w(it) } + .getOrNull() + ?: return + + val sources = favorites.albums.map { + AudioSource.Album(id = it.id) + } + playerQueueAudioSourceManager.playSource(*sources.toTypedArray(), shuffled = shuffled) + } + + private fun getFavorites() { + getFavoritesJob?.cancel() + getFavoritesJob = viewModelScope.launch { + favoriteAlbumsRepository + .getFavorites() + .map { it.toUi() } + .catch { throwable -> + Timber.w(throwable) + _state.update { + it.copy( + progress = false, + isRefreshing = false, + error = true, + data = null + ) + } + } + .collect { favorites -> + _state.update { + it.copy( + progress = false, + isRefreshing = false, + error = false, + data = favorites + ) + } + } + } + } +} \ No newline at end of file diff --git a/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/Mapper.kt b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/Mapper.kt new file mode 100644 index 00000000..4503d2a3 --- /dev/null +++ b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/Mapper.kt @@ -0,0 +1,17 @@ +package ru.stresh.youamp.feature.album.favorites.ui + +import ru.stresh.youamp.feature.album.favorites.domain.Album +import ru.stresh.youamp.feature.album.favorites.domain.Favorites + +internal fun Favorites.toUi(): DataUi { + return DataUi( + albums = albums.map { it.toUi() } + ) +} + +private fun Album.toUi() = AlbumUi( + id = id, + title = title, + artist = artist, + artworkUrl = artworkUrl +) \ No newline at end of file diff --git a/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/StateUi.kt b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/StateUi.kt new file mode 100644 index 00000000..23a2937c --- /dev/null +++ b/feature/album/favorites/src/main/java/ru/stresh/youamp/feature/album/favorites/ui/StateUi.kt @@ -0,0 +1,22 @@ +package ru.stresh.youamp.feature.album.favorites.ui + +import androidx.compose.runtime.Immutable + +internal data class StateUi( + val progress: Boolean = true, + val isRefreshing: Boolean = false, + val error: Boolean = false, + val data: DataUi? = null +) + +@Immutable +internal data class DataUi( + val albums: List +) + +internal class AlbumUi( + val id: String, + val title: String, + val artist: String?, + val artworkUrl: String? +) \ No newline at end of file diff --git a/feature/album/favorites/src/main/res/values/strings.xml b/feature/album/favorites/src/main/res/values/strings.xml new file mode 100644 index 00000000..3b200c84 --- /dev/null +++ b/feature/album/favorites/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Favorite albums + \ No newline at end of file diff --git a/feature/album/list/src/main/java/ru/stersh/youamp/feature/albums/Di.kt b/feature/album/list/src/main/java/ru/stersh/youamp/feature/albums/Di.kt index 305d109d..eac9449c 100644 --- a/feature/album/list/src/main/java/ru/stersh/youamp/feature/albums/Di.kt +++ b/feature/album/list/src/main/java/ru/stersh/youamp/feature/albums/Di.kt @@ -6,7 +6,7 @@ import ru.stersh.youamp.feature.albums.data.AlbumsRepositoryImpl import ru.stersh.youamp.feature.albums.domain.AlbumsRepository import ru.stersh.youamp.feature.albums.ui.AlbumsViewModel -val albumsModule = module { +val albumListModule = module { single { AlbumsRepositoryImpl(get()) } viewModel { AlbumsViewModel(get(), get()) } } \ No newline at end of file diff --git a/feature/artist/favorites/.gitignore b/feature/artist/favorites/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/feature/artist/favorites/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/artist/favorites/build.gradle b/feature/artist/favorites/build.gradle new file mode 100644 index 00000000..95c501cd --- /dev/null +++ b/feature/artist/favorites/build.gradle @@ -0,0 +1,22 @@ +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose.compiler) +} + +apply from: "${project.rootDir}/buildscripts/android-feature-module.gradle" + +android { + namespace 'ru.stersh.youamp.feature.artist.favorites' +} + +dependencies { + implementation project(":core:ui") + implementation project(":core:api") + implementation project(":shared:player") + implementation project(":shared:favorites") + implementation(libs.bundles.lifecycle) + implementation(libs.coil.compose) + implementation(libs.bundles.koin) + implementation(libs.timber) +} \ No newline at end of file diff --git a/feature/artist/favorites/consumer-rules.pro b/feature/artist/favorites/consumer-rules.pro new file mode 100644 index 00000000..e69de29b diff --git a/feature/artist/favorites/proguard-rules.pro b/feature/artist/favorites/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/feature/artist/favorites/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/feature/artist/favorites/src/main/AndroidManifest.xml b/feature/artist/favorites/src/main/AndroidManifest.xml new file mode 100644 index 00000000..44008a43 --- /dev/null +++ b/feature/artist/favorites/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/Di.kt b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/Di.kt new file mode 100644 index 00000000..1f1e083e --- /dev/null +++ b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/Di.kt @@ -0,0 +1,12 @@ +package ru.stresh.youamp.feature.artist.favorites + +import org.koin.core.module.dsl.viewModel +import org.koin.dsl.module +import ru.stresh.youamp.feature.artist.favorites.data.FavoriteArtistsRepositoryImpl +import ru.stresh.youamp.feature.artist.favorites.domain.FavoriteArtistsRepository +import ru.stresh.youamp.feature.artist.favorites.ui.FavoriteArtistViewModel + +val artistFavoritesModule = module { + single { FavoriteArtistsRepositoryImpl(get()) } + viewModel { FavoriteArtistViewModel(get(), get()) } +} \ No newline at end of file diff --git a/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/data/FavoriteArtistsRepositoryImpl.kt b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/data/FavoriteArtistsRepositoryImpl.kt new file mode 100644 index 00000000..be931fbf --- /dev/null +++ b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/data/FavoriteArtistsRepositoryImpl.kt @@ -0,0 +1,32 @@ +package ru.stresh.youamp.feature.artist.favorites.data + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import ru.stresh.youamp.feature.artist.favorites.domain.Artist +import ru.stresh.youamp.feature.artist.favorites.domain.FavoriteArtistsRepository +import ru.stresh.youamp.feature.artist.favorites.domain.Favorites +import ru.stresh.youamp.shared.favorites.ArtistFavoritesStorage + +internal class FavoriteArtistsRepositoryImpl( + private val artistFavoritesStorage: ArtistFavoritesStorage +) : FavoriteArtistsRepository { + + override fun getFavorites(): Flow { + return artistFavoritesStorage + .flowArtists() + .map { favoriteAlbums -> + Favorites( + artists = favoriteAlbums.map { it.toDomain() } + ) + } + } + + private fun ru.stresh.youamp.shared.favorites.Artist.toDomain(): Artist { + return Artist( + id = id, + name = name, + artworkUrl = artworkUrl, + userRating = userRating + ) + } +} \ No newline at end of file diff --git a/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/domain/Artist.kt b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/domain/Artist.kt new file mode 100644 index 00000000..f0e93e69 --- /dev/null +++ b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/domain/Artist.kt @@ -0,0 +1,8 @@ +package ru.stresh.youamp.feature.artist.favorites.domain + +internal data class Artist( + val id: String, + val name: String, + val artworkUrl: String?, + val userRating: Int? +) diff --git a/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/domain/FavoriteArtistsRepository.kt b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/domain/FavoriteArtistsRepository.kt new file mode 100644 index 00000000..bf638f02 --- /dev/null +++ b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/domain/FavoriteArtistsRepository.kt @@ -0,0 +1,7 @@ +package ru.stresh.youamp.feature.artist.favorites.domain + +import kotlinx.coroutines.flow.Flow + +internal interface FavoriteArtistsRepository { + fun getFavorites(): Flow +} \ No newline at end of file diff --git a/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/domain/Favorites.kt b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/domain/Favorites.kt new file mode 100644 index 00000000..53389a49 --- /dev/null +++ b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/domain/Favorites.kt @@ -0,0 +1,5 @@ +package ru.stresh.youamp.feature.artist.favorites.domain + +internal data class Favorites( + val artists: List +) diff --git a/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/FavoriteArtistScreen.kt b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/FavoriteArtistScreen.kt new file mode 100644 index 00000000..10aa8241 --- /dev/null +++ b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/FavoriteArtistScreen.kt @@ -0,0 +1,215 @@ +package ru.stresh.youamp.feature.artist.favorites.ui + +import android.content.res.Configuration +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.GridItemSpan +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.lazy.grid.items +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.ListItem +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.pulltorefresh.PullToRefreshBox +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import org.koin.androidx.compose.koinViewModel +import ru.stersh.youamp.core.ui.ArtistItem +import ru.stersh.youamp.core.ui.BackNavigationButton +import ru.stersh.youamp.core.ui.EmptyLayout +import ru.stersh.youamp.core.ui.ErrorLayout +import ru.stersh.youamp.core.ui.HeaderLayout +import ru.stersh.youamp.core.ui.HeaderTitle +import ru.stersh.youamp.core.ui.PlayAllButton +import ru.stersh.youamp.core.ui.PlayShuffledButton +import ru.stersh.youamp.core.ui.SkeletonLayout +import ru.stersh.youamp.feature.artist.favorites.R + +@Composable +fun FavoriteArtistsScreen( + onArtistClick: (id: String) -> Unit, + onBackClick: () -> Unit +) { + val viewModel: FavoriteArtistViewModel = koinViewModel() + val state by viewModel.state.collectAsStateWithLifecycle() + + FavoriteArtistsScreen( + state = state, + onPlayAll = viewModel::playAll, + onPlayShuffled = viewModel::playShuffled, + onRetry = viewModel::retry, + onRefresh = viewModel::refresh, + onArtistClick = onArtistClick, + onBackClick = onBackClick + ) +} + +@Composable +private fun FavoriteArtistsScreen( + state: StateUi, + onPlayAll: () -> Unit, + onPlayShuffled: () -> Unit, + onRetry: () -> Unit, + onRefresh: () -> Unit, + onArtistClick: (id: String) -> Unit, + onBackClick: () -> Unit +) { + Scaffold( + topBar = { + TopAppBar( + title = {}, + navigationIcon = { + BackNavigationButton(onClick = onBackClick) + } + ) + } + ) { + PullToRefreshBox( + isRefreshing = state.isRefreshing, + onRefresh = onRefresh, + modifier = Modifier.padding(it) + ) { + when { + state.progress -> { + Progress() + } + + state.error -> { + ErrorLayout(onRetry = onRetry) + } + + state.data != null && state.data.artists.isEmpty() -> { + EmptyLayout( + modifier = Modifier.verticalScroll( + state = rememberScrollState() + ) + ) + } + + state.data?.artists != null -> { + LazyVerticalGrid( + columns = GridCells.Fixed(2), + contentPadding = PaddingValues(16.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + modifier = Modifier.fillMaxSize() + ) { + item( + contentType = "header", + key = "header", + span = { GridItemSpan(2) } + ) { + HeaderLayout( + title = { + HeaderTitle(text = stringResource(R.string.favorite_artists_title)) + }, + actions = { + PlayAllButton( + onClick = onPlayAll + ) + PlayShuffledButton( + onClick = onPlayShuffled + ) + } + ) + } + items( + items = state.data.artists, + contentType = { "artist" }, + key = { "artist_${it.id}" } + ) { album -> + ArtistItem( + name = album.name, + onClick = { onArtistClick(album.id) }, + artworkUrl = album.artworkUrl + ) + } + } + } + } + } + } +} + +@Composable +private fun Progress() { + SkeletonLayout { + repeat(10) { + ListItem( + headlineContent = { + Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { + SkeletonItem(modifier = Modifier.size(width = 130.dp, height = 16.dp)) + SkeletonItem(modifier = Modifier.size(width = 200.dp, height = 16.dp)) + } + }, + leadingContent = { + SkeletonItem(modifier = Modifier.size(48.dp)) + } + ) + } + } +} + +@Preview +@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun FavoriteArtistsScreenPreview() { + MaterialTheme { + val albums = listOf( + ArtistUi( + id = "1", + name = "Artist 1", + artworkUrl = null + ), + ArtistUi( + id = "2", + name = "Artist 2", + artworkUrl = null + ), + ArtistUi( + id = "3", + name = "Artist 3", + artworkUrl = null + ), + ArtistUi( + id = "4", + name = "Artist 4", + artworkUrl = null + ), + ArtistUi( + id = "5", + name = "Artist 5", + artworkUrl = null + ), + ) + val state = StateUi( + progress = false, + isRefreshing = false, + error = false, + data = DataUi( + artists = albums + ) + ) + FavoriteArtistsScreen( + state = state, + onPlayAll = {}, + onPlayShuffled = {}, + onRetry = {}, + onRefresh = {}, + onArtistClick = {}, + onBackClick = {} + ) + } +} \ No newline at end of file diff --git a/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/FavoriteArtistViewModel.kt b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/FavoriteArtistViewModel.kt new file mode 100644 index 00000000..e976fc5c --- /dev/null +++ b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/FavoriteArtistViewModel.kt @@ -0,0 +1,100 @@ +package ru.stresh.youamp.feature.artist.favorites.ui + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import ru.stersh.youamp.shared.player.queue.AudioSource +import ru.stersh.youamp.shared.player.queue.PlayerQueueAudioSourceManager +import ru.stresh.youamp.feature.artist.favorites.domain.FavoriteArtistsRepository +import timber.log.Timber + +internal class FavoriteArtistViewModel( + private val favoriteArtistsRepository: FavoriteArtistsRepository, + private val playerQueueAudioSourceManager: PlayerQueueAudioSourceManager +) : ViewModel() { + private val _state = MutableStateFlow(StateUi()) + val state: StateFlow + get() = _state + + private var getFavoritesJob: Job? = null + + init { + retry() + } + + fun playAll() = viewModelScope.launch { + playFavorites() + } + + fun playShuffled() = viewModelScope.launch { + playFavorites(true) + } + + fun refresh() { + _state.update { + it.copy(isRefreshing = true) + } + getFavorites() + } + + fun retry() { + _state.update { + it.copy( + progress = true, + isRefreshing = false, + error = false, + data = null + ) + } + getFavorites() + } + + private suspend fun playFavorites(shuffled: Boolean = false) { + val favorites = runCatching { favoriteArtistsRepository.getFavorites().first() } + .onFailure { Timber.w(it) } + .getOrNull() + ?: return + + val sources = favorites.artists.map { + AudioSource.Artist(id = it.id) + } + playerQueueAudioSourceManager.playSource(*sources.toTypedArray(), shuffled = shuffled) + } + + private fun getFavorites() { + getFavoritesJob?.cancel() + getFavoritesJob = viewModelScope.launch { + favoriteArtistsRepository + .getFavorites() + .map { it.toUi() } + .catch { throwable -> + Timber.w(throwable) + _state.update { + it.copy( + progress = false, + isRefreshing = false, + error = true, + data = null + ) + } + } + .collect { favorites -> + _state.update { + it.copy( + progress = false, + isRefreshing = false, + error = false, + data = favorites + ) + } + } + } + } +} \ No newline at end of file diff --git a/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/Mapper.kt b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/Mapper.kt new file mode 100644 index 00000000..96241f66 --- /dev/null +++ b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/Mapper.kt @@ -0,0 +1,16 @@ +package ru.stresh.youamp.feature.artist.favorites.ui + +import ru.stresh.youamp.feature.artist.favorites.domain.Artist +import ru.stresh.youamp.feature.artist.favorites.domain.Favorites + +internal fun Favorites.toUi(): DataUi { + return DataUi( + artists = artists.map { it.toUi() } + ) +} + +private fun Artist.toUi() = ArtistUi( + id = id, + name = name, + artworkUrl = artworkUrl +) \ No newline at end of file diff --git a/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/StateUi.kt b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/StateUi.kt new file mode 100644 index 00000000..e91e1065 --- /dev/null +++ b/feature/artist/favorites/src/main/java/ru/stresh/youamp/feature/artist/favorites/ui/StateUi.kt @@ -0,0 +1,21 @@ +package ru.stresh.youamp.feature.artist.favorites.ui + +import androidx.compose.runtime.Immutable + +internal data class StateUi( + val progress: Boolean = true, + val isRefreshing: Boolean = false, + val error: Boolean = false, + val data: DataUi? = null +) + +@Immutable +internal data class DataUi( + val artists: List +) + +internal class ArtistUi( + val id: String, + val name: String, + val artworkUrl: String? +) \ No newline at end of file diff --git a/feature/artist/favorites/src/main/res/values/strings.xml b/feature/artist/favorites/src/main/res/values/strings.xml new file mode 100644 index 00000000..71b90385 --- /dev/null +++ b/feature/artist/favorites/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Favorite artists + \ No newline at end of file diff --git a/feature/artist/list/src/main/java/ru/stersh/youamp/feature/artists/Di.kt b/feature/artist/list/src/main/java/ru/stersh/youamp/feature/artists/Di.kt index a6986e03..119e51dc 100644 --- a/feature/artist/list/src/main/java/ru/stersh/youamp/feature/artists/Di.kt +++ b/feature/artist/list/src/main/java/ru/stersh/youamp/feature/artists/Di.kt @@ -6,7 +6,7 @@ import ru.stersh.youamp.feature.artists.data.ArtistsRepositoryImpl import ru.stersh.youamp.feature.artists.domain.ArtistsRepository import ru.stersh.youamp.feature.artists.ui.ArtistsViewModel -val artistsModule = module { +val artistListModule = module { single { ArtistsRepositoryImpl(get()) } viewModel { ArtistsViewModel(get()) } } \ No newline at end of file diff --git a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/Di.kt b/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/Di.kt deleted file mode 100644 index 864115bd..00000000 --- a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/Di.kt +++ /dev/null @@ -1,12 +0,0 @@ -package ru.stresh.youamp.feature.favorite.list - -import org.koin.core.module.dsl.viewModel -import org.koin.dsl.module -import ru.stresh.youamp.feature.favorite.list.data.FavoriteSongsRepositoryImpl -import ru.stresh.youamp.feature.favorite.list.domain.FavoriteSongsRepository -import ru.stresh.youamp.feature.favorite.list.ui.FavoriteSongsViewModel - -val favoriteListModule = module { - single { FavoriteSongsRepositoryImpl(get()) } - viewModel { FavoriteSongsViewModel(get(), get()) } -} \ No newline at end of file diff --git a/feature/song/favorites/.gitignore b/feature/song/favorites/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/feature/song/favorites/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/favorite/list/build.gradle b/feature/song/favorites/build.gradle similarity index 91% rename from feature/favorite/list/build.gradle rename to feature/song/favorites/build.gradle index a9e1c1e7..0b8f4889 100644 --- a/feature/favorite/list/build.gradle +++ b/feature/song/favorites/build.gradle @@ -7,7 +7,7 @@ plugins { apply from: "${project.rootDir}/buildscripts/android-feature-module.gradle" android { - namespace 'ru.stersh.youamp.feature.favorite.list' + namespace 'ru.stersh.youamp.feature.song.favorites' } dependencies { diff --git a/feature/song/favorites/consumer-rules.pro b/feature/song/favorites/consumer-rules.pro new file mode 100644 index 00000000..e69de29b diff --git a/feature/song/favorites/proguard-rules.pro b/feature/song/favorites/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/feature/song/favorites/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/feature/song/favorites/src/main/AndroidManifest.xml b/feature/song/favorites/src/main/AndroidManifest.xml new file mode 100644 index 00000000..44008a43 --- /dev/null +++ b/feature/song/favorites/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/Di.kt b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/Di.kt new file mode 100644 index 00000000..37ddc6a0 --- /dev/null +++ b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/Di.kt @@ -0,0 +1,12 @@ +package ru.stresh.youamp.feature.song.favorites + +import org.koin.core.module.dsl.viewModel +import org.koin.dsl.module +import ru.stresh.youamp.feature.song.favorites.data.FavoriteSongsRepositoryImpl +import ru.stresh.youamp.feature.song.favorites.domain.FavoriteSongsRepository +import ru.stresh.youamp.feature.song.favorites.ui.FavoriteSongsViewModel + +val songFavoritesModule = module { + single { FavoriteSongsRepositoryImpl(get()) } + viewModel { FavoriteSongsViewModel(get(), get()) } +} \ No newline at end of file diff --git a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/data/FavoriteSongsRepositoryImpl.kt b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/data/FavoriteSongsRepositoryImpl.kt similarity index 76% rename from feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/data/FavoriteSongsRepositoryImpl.kt rename to feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/data/FavoriteSongsRepositoryImpl.kt index 18360d56..6799ce53 100644 --- a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/data/FavoriteSongsRepositoryImpl.kt +++ b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/data/FavoriteSongsRepositoryImpl.kt @@ -1,10 +1,10 @@ -package ru.stresh.youamp.feature.favorite.list.data +package ru.stresh.youamp.feature.song.favorites.data import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -import ru.stresh.youamp.feature.favorite.list.domain.FavoriteSongsRepository -import ru.stresh.youamp.feature.favorite.list.domain.Favorites -import ru.stresh.youamp.feature.favorite.list.domain.Song +import ru.stresh.youamp.feature.song.favorites.domain.FavoriteSongsRepository +import ru.stresh.youamp.feature.song.favorites.domain.Favorites +import ru.stresh.youamp.feature.song.favorites.domain.Song import ru.stresh.youamp.shared.favorites.SongFavoritesStorage internal class FavoriteSongsRepositoryImpl( diff --git a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/domain/FavoriteSongsRepository.kt b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/domain/FavoriteSongsRepository.kt similarity index 69% rename from feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/domain/FavoriteSongsRepository.kt rename to feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/domain/FavoriteSongsRepository.kt index c1cff606..04503589 100644 --- a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/domain/FavoriteSongsRepository.kt +++ b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/domain/FavoriteSongsRepository.kt @@ -1,4 +1,4 @@ -package ru.stresh.youamp.feature.favorite.list.domain +package ru.stresh.youamp.feature.song.favorites.domain import kotlinx.coroutines.flow.Flow diff --git a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/domain/Favorites.kt b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/domain/Favorites.kt similarity index 52% rename from feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/domain/Favorites.kt rename to feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/domain/Favorites.kt index 93a4ffd3..285d73f1 100644 --- a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/domain/Favorites.kt +++ b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/domain/Favorites.kt @@ -1,4 +1,4 @@ -package ru.stresh.youamp.feature.favorite.list.domain +package ru.stresh.youamp.feature.song.favorites.domain internal data class Favorites( val songs: List diff --git a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/domain/Song.kt b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/domain/Song.kt similarity index 73% rename from feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/domain/Song.kt rename to feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/domain/Song.kt index 9f6d25e5..18a167f4 100644 --- a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/domain/Song.kt +++ b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/domain/Song.kt @@ -1,4 +1,4 @@ -package ru.stresh.youamp.feature.favorite.list.domain +package ru.stresh.youamp.feature.song.favorites.domain internal data class Song( val id: String, diff --git a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/ui/FavoriteSongsScreen.kt b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/ui/FavoriteSongsScreen.kt similarity index 98% rename from feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/ui/FavoriteSongsScreen.kt rename to feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/ui/FavoriteSongsScreen.kt index 7713ba85..746a2053 100644 --- a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/ui/FavoriteSongsScreen.kt +++ b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/ui/FavoriteSongsScreen.kt @@ -1,4 +1,4 @@ -package ru.stresh.youamp.feature.favorite.list.ui +package ru.stresh.youamp.feature.song.favorites.ui import android.content.res.Configuration import androidx.compose.foundation.background @@ -39,7 +39,7 @@ import ru.stersh.youamp.core.ui.HeaderTitle import ru.stersh.youamp.core.ui.PlayAllButton import ru.stersh.youamp.core.ui.PlayShuffledButton import ru.stersh.youamp.core.ui.SkeletonLayout -import ru.stersh.youamp.feature.favorite.list.R +import ru.stersh.youamp.feature.song.favorites.R @Composable fun FavoriteSongsScreen( diff --git a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/ui/FavoriteSongsViewModel.kt b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/ui/FavoriteSongsViewModel.kt similarity index 96% rename from feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/ui/FavoriteSongsViewModel.kt rename to feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/ui/FavoriteSongsViewModel.kt index 9336ddfb..13219cfd 100644 --- a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/ui/FavoriteSongsViewModel.kt +++ b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/ui/FavoriteSongsViewModel.kt @@ -1,4 +1,4 @@ -package ru.stresh.youamp.feature.favorite.list.ui +package ru.stresh.youamp.feature.song.favorites.ui import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -12,7 +12,7 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import ru.stersh.youamp.shared.player.queue.AudioSource import ru.stersh.youamp.shared.player.queue.PlayerQueueAudioSourceManager -import ru.stresh.youamp.feature.favorite.list.domain.FavoriteSongsRepository +import ru.stresh.youamp.feature.song.favorites.domain.FavoriteSongsRepository import timber.log.Timber internal class FavoriteSongsViewModel( diff --git a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/ui/Mapper.kt b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/ui/Mapper.kt similarity index 56% rename from feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/ui/Mapper.kt rename to feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/ui/Mapper.kt index 488cd084..3534575f 100644 --- a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/ui/Mapper.kt +++ b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/ui/Mapper.kt @@ -1,7 +1,7 @@ -package ru.stresh.youamp.feature.favorite.list.ui +package ru.stresh.youamp.feature.song.favorites.ui -import ru.stresh.youamp.feature.favorite.list.domain.Favorites -import ru.stresh.youamp.feature.favorite.list.domain.Song +import ru.stresh.youamp.feature.song.favorites.domain.Favorites +import ru.stresh.youamp.feature.song.favorites.domain.Song internal fun Favorites.toUi(): DataUi { return DataUi( diff --git a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/ui/StateUi.kt b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/ui/StateUi.kt similarity index 88% rename from feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/ui/StateUi.kt rename to feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/ui/StateUi.kt index 15736394..95c83791 100644 --- a/feature/favorite/list/src/main/java/ru/stresh/youamp/feature/favorite/list/ui/StateUi.kt +++ b/feature/song/favorites/src/main/java/ru/stresh/youamp/feature/song/favorites/ui/StateUi.kt @@ -1,4 +1,4 @@ -package ru.stresh.youamp.feature.favorite.list.ui +package ru.stresh.youamp.feature.song.favorites.ui import androidx.compose.runtime.Immutable diff --git a/feature/favorite/list/src/main/res/values-fr-rFR/strings.xml b/feature/song/favorites/src/main/res/values-fr-rFR/strings.xml similarity index 100% rename from feature/favorite/list/src/main/res/values-fr-rFR/strings.xml rename to feature/song/favorites/src/main/res/values-fr-rFR/strings.xml diff --git a/feature/favorite/list/src/main/res/values-it-rIT/strings.xml b/feature/song/favorites/src/main/res/values-it-rIT/strings.xml similarity index 100% rename from feature/favorite/list/src/main/res/values-it-rIT/strings.xml rename to feature/song/favorites/src/main/res/values-it-rIT/strings.xml diff --git a/feature/favorite/list/src/main/res/values-ru-rRU/strings.xml b/feature/song/favorites/src/main/res/values-ru-rRU/strings.xml similarity index 100% rename from feature/favorite/list/src/main/res/values-ru-rRU/strings.xml rename to feature/song/favorites/src/main/res/values-ru-rRU/strings.xml diff --git a/feature/favorite/list/src/main/res/values/strings.xml b/feature/song/favorites/src/main/res/values/strings.xml similarity index 100% rename from feature/favorite/list/src/main/res/values/strings.xml rename to feature/song/favorites/src/main/res/values/strings.xml diff --git a/settings.gradle b/settings.gradle index e9de362a..636dc2e0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -23,6 +23,7 @@ include ':core:properties' include ':shared:player' include ':feature:album:list' include ':feature:album:info' +include ':feature:album:favorites' include ':feature:main' include ':feature:player:mini' include ':feature:player:screen' @@ -31,11 +32,11 @@ include ':feature:server:create' include ':feature:server:list' include ':feature:artist:list' include ':feature:artist:info' +include ':feature:artist:favorites' include ':feature:playlist:list' include ':feature:playlist:info' include ':feature:search' include ':feature:song:info' -include ':feature:favorite:list' include ':feature:about' include ':feature:settings' include ':feature:personal' @@ -44,3 +45,4 @@ include ':feature:library' include ':shared:favorites' include ':shared:song:random' include ':feature:song:random' +include ':feature:song:favorites' diff --git a/shared/favorites/src/main/java/ru/stresh/youamp/shared/favorites/Album.kt b/shared/favorites/src/main/java/ru/stresh/youamp/shared/favorites/Album.kt index 5a2f9542..f25eef29 100644 --- a/shared/favorites/src/main/java/ru/stresh/youamp/shared/favorites/Album.kt +++ b/shared/favorites/src/main/java/ru/stresh/youamp/shared/favorites/Album.kt @@ -5,5 +5,6 @@ data class Album( val title: String, val artist: String?, val artistId: String?, - val artworkUrl: String? + val artworkUrl: String?, + val userRating: Int? ) diff --git a/shared/favorites/src/main/java/ru/stresh/youamp/shared/favorites/Artist.kt b/shared/favorites/src/main/java/ru/stresh/youamp/shared/favorites/Artist.kt index 0eef2522..2f0c549e 100644 --- a/shared/favorites/src/main/java/ru/stresh/youamp/shared/favorites/Artist.kt +++ b/shared/favorites/src/main/java/ru/stresh/youamp/shared/favorites/Artist.kt @@ -3,5 +3,6 @@ package ru.stresh.youamp.shared.favorites data class Artist( val id: String, val name: String, - val artworkUrl: String? + val artworkUrl: String?, + val userRating: Int? ) \ No newline at end of file diff --git a/shared/favorites/src/main/java/ru/stresh/youamp/shared/favorites/FavoritesStorageImpl.kt b/shared/favorites/src/main/java/ru/stresh/youamp/shared/favorites/FavoritesStorageImpl.kt index 91077580..3b487f53 100644 --- a/shared/favorites/src/main/java/ru/stresh/youamp/shared/favorites/FavoritesStorageImpl.kt +++ b/shared/favorites/src/main/java/ru/stresh/youamp/shared/favorites/FavoritesStorageImpl.kt @@ -133,14 +133,16 @@ internal class FavoritesStorageImpl( title = requireNotNull(it.name ?: it.album), artist = it.artist, artistId = it.artistId, - artworkUrl = api.getCoverArtUrl(it.coverArt) + artworkUrl = api.getCoverArtUrl(it.coverArt), + userRating = it.userRating ) }.orEmpty(), artists = newFavorites.starred2Result.artist?.map { Artist( id = it.id, name = it.name, - artworkUrl = api.getCoverArtUrl(it.coverArt) + artworkUrl = api.getCoverArtUrl(it.coverArt), + userRating = it.userRating ) }.orEmpty() )