diff --git a/app/src/main/java/me/vanpetegem/accentor/data/albums/Album.kt b/app/src/main/java/me/vanpetegem/accentor/data/albums/Album.kt index aeadc533..be7a789c 100644 --- a/app/src/main/java/me/vanpetegem/accentor/data/albums/Album.kt +++ b/app/src/main/java/me/vanpetegem/accentor/data/albums/Album.kt @@ -25,6 +25,22 @@ data class Album( albumArtists.sortedBy { aa -> aa.order }.fold("") { acc, aa -> acc + aa.name + (aa.separator ?: "") } fun firstCharacter() = String(intArrayOf(title.codePointAt(0)), 0, 1) + + fun compareToByName(other: Album): Int { + var order = this.normalizedTitle.compareTo(other.normalizedTitle) + order = if (order == 0) this.release.compareTo(other.release) else order + order = if (order == 0) compareAlbumEditions(this, other) else order + order = if (order == 0) this.id - other.id else order + return order + } +} + +fun compareAlbumEditions(a1: Album, a2: Album): Int { + if (a1.edition == null && a2.edition == null) { return 0 } + if (a1.edition == null) { return -1 } + if (a2.edition == null) { return 1 } + val order = a1.edition.compareTo(a2.edition) + return if (order == 0) a1.editionDescription!!.compareTo(a2.editionDescription!!) else order } data class AlbumArtist( diff --git a/app/src/main/java/me/vanpetegem/accentor/data/albums/AlbumRepository.kt b/app/src/main/java/me/vanpetegem/accentor/data/albums/AlbumRepository.kt index 340a289f..422e77bf 100644 --- a/app/src/main/java/me/vanpetegem/accentor/data/albums/AlbumRepository.kt +++ b/app/src/main/java/me/vanpetegem/accentor/data/albums/AlbumRepository.kt @@ -35,6 +35,7 @@ class AlbumRepository( } fun findById(id: Int): LiveData = albumDao.findById(id) + fun getById(id: Int): Album? = albumDao.getAlbumById(id) fun findByIds(ids: List): LiveData> = albumDao.findByIds(ids) diff --git a/app/src/main/java/me/vanpetegem/accentor/data/tracks/Track.kt b/app/src/main/java/me/vanpetegem/accentor/data/tracks/Track.kt index b4b83ec3..1b554c7b 100644 --- a/app/src/main/java/me/vanpetegem/accentor/data/tracks/Track.kt +++ b/app/src/main/java/me/vanpetegem/accentor/data/tracks/Track.kt @@ -1,6 +1,8 @@ package me.vanpetegem.accentor.data.tracks +import android.util.SparseArray import java.time.Instant +import me.vanpetegem.accentor.data.albums.Album data class Track( val id: Int, @@ -20,6 +22,17 @@ data class Track( ) { fun stringifyTrackArtists() = trackArtists.sortedBy { ta -> ta.order }.joinToString(" / ") { ta -> ta.name } + fun compareTo(other: Track, albums: SparseArray): Int { + val a1 = albums[this.albumId] + val a2 = albums[other.albumId] + if (a1 == null && a2 == null) { return this.number - other.number } + if (a1 == null) { return 1 } + if (a2 == null) { return -1 } + val order = a1.compareToByName(a2) + if (order != 0) { return order } + return this.number - other.number + } + companion object { const val ALBUMARTIST = "me.vanpetegem.accentor.data.tracks.Track.ALBUMARTIST" const val ARTIST = "me.vanpetegem.accentor.data.tracks.Track.ARTIST" diff --git a/app/src/main/java/me/vanpetegem/accentor/data/tracks/TrackDao.kt b/app/src/main/java/me/vanpetegem/accentor/data/tracks/TrackDao.kt index 761223a2..1ec2e883 100644 --- a/app/src/main/java/me/vanpetegem/accentor/data/tracks/TrackDao.kt +++ b/app/src/main/java/me/vanpetegem/accentor/data/tracks/TrackDao.kt @@ -9,6 +9,7 @@ import androidx.room.Insert import androidx.room.Query import androidx.room.Transaction import me.vanpetegem.accentor.data.albums.Album +import me.vanpetegem.accentor.data.artists.Artist @Dao abstract class TrackDao { @@ -91,6 +92,32 @@ abstract class TrackDao { } } + open fun findByArtist(artist: Artist): LiveData> = switchMap(findDbTracksByArtistId(artist.id)) { tracks -> + val ids = tracks.map { it.id } + switchMap(findTrackArtistsByTrackIdWhereTrackIds(ids)) { trackArtists -> + map(findTrackGenresByTrackIdWhereTrackIds(ids)) { trackGenres -> + tracks.map { t -> + Track( + t.id, + t.title, + t.normalizedTitle, + t.number, + t.albumId, + t.reviewComment, + t.createdAt, + t.updatedAt, + trackGenres.get(t.id, ArrayList()), + trackArtists.get(t.id, ArrayList()), + t.codecId, + t.length, + t.bitrate, + t.locationId + ) + } + } + } + } + @Transaction open fun getTrackById(id: Int): Track? { val dbTrack = getDbTrackById(id) @@ -128,6 +155,9 @@ abstract class TrackDao { @Query("SELECT * FROM tracks WHERE id IN (:ids)") protected abstract fun findDbTracksByIds(ids: List): LiveData> + @Query("SELECT * FROM tracks WHERE id IN (SELECT track_id FROM track_artists WHERE artist_id = :id)") + protected abstract fun findDbTracksByArtistId(id: Int): LiveData> + @Query("SELECT * FROM track_artists WHERE track_id = :id") protected abstract fun getDbTrackArtistsById(id: Int): List diff --git a/app/src/main/java/me/vanpetegem/accentor/data/tracks/TrackRepository.kt b/app/src/main/java/me/vanpetegem/accentor/data/tracks/TrackRepository.kt index b3e2d518..f04cc5d3 100644 --- a/app/src/main/java/me/vanpetegem/accentor/data/tracks/TrackRepository.kt +++ b/app/src/main/java/me/vanpetegem/accentor/data/tracks/TrackRepository.kt @@ -3,6 +3,7 @@ package me.vanpetegem.accentor.data.tracks import androidx.lifecycle.LiveData import me.vanpetegem.accentor.api.track.index import me.vanpetegem.accentor.data.albums.Album +import me.vanpetegem.accentor.data.artists.Artist import me.vanpetegem.accentor.data.authentication.AuthenticationRepository import me.vanpetegem.accentor.util.Result @@ -10,17 +11,10 @@ class TrackRepository( private val trackDao: TrackDao, private val authenticationRepository: AuthenticationRepository ) { - fun findById(id: Int): LiveData { - return trackDao.findById(id) - } - - fun findByIds(ids: List): LiveData> { - return trackDao.findByIds(ids) - } - - fun getByAlbum(album: Album): List { - return trackDao.getByAlbum(album) - } + fun findById(id: Int): LiveData = trackDao.findById(id) + fun findByIds(ids: List): LiveData> = trackDao.findByIds(ids) + fun findByArtist(artist: Artist): LiveData> = trackDao.findByArtist(artist) + fun getByAlbum(album: Album): List = trackDao.getByAlbum(album) suspend fun refresh(handler: suspend (Result) -> Unit) { when (val result = index(authenticationRepository.server.value!!, authenticationRepository.authData.value!!)) { diff --git a/app/src/main/java/me/vanpetegem/accentor/media/MediaSessionConnection.kt b/app/src/main/java/me/vanpetegem/accentor/media/MediaSessionConnection.kt index 0c16c96f..4cc89f49 100644 --- a/app/src/main/java/me/vanpetegem/accentor/media/MediaSessionConnection.kt +++ b/app/src/main/java/me/vanpetegem/accentor/media/MediaSessionConnection.kt @@ -178,8 +178,18 @@ class MediaSessionConnection(application: Application) : AndroidViewModel(applic play(tracks) } + suspend fun play(track: Track) { + val album = albumRepository.getById(track.albumId) + album?.let { play(listOf(Pair(track, it))) } + } + + suspend fun addTrackToQueue(track: Track) = addTrackToQueue(track, _queue.value?.size ?: 0) suspend fun addTracksToQueue(album: Album) = addTracksToQueue(album, _queue.value?.size ?: 0) + suspend fun addTrackToQueue(track: Track, index: Int) { + val album = albumRepository.getById(track.albumId) + album?.let { addTracksToQueue(listOf(Pair(track, album)), index) } + } suspend fun addTracksToQueue(album: Album, index: Int) { val tracks = trackRepository.getByAlbum(album).map { Pair(it, album) } addTracksToQueue(tracks, index) diff --git a/app/src/main/java/me/vanpetegem/accentor/ui/albums/AlbumsViewModel.kt b/app/src/main/java/me/vanpetegem/accentor/ui/albums/AlbumsViewModel.kt index 006937bf..0e92580b 100644 --- a/app/src/main/java/me/vanpetegem/accentor/ui/albums/AlbumsViewModel.kt +++ b/app/src/main/java/me/vanpetegem/accentor/ui/albums/AlbumsViewModel.kt @@ -1,10 +1,8 @@ package me.vanpetegem.accentor.ui.albums import android.app.Application -import android.os.Parcelable import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import me.vanpetegem.accentor.data.AccentorDatabase import me.vanpetegem.accentor.data.albums.Album import me.vanpetegem.accentor.data.albums.AlbumRepository @@ -13,22 +11,10 @@ import me.vanpetegem.accentor.data.authentication.AuthenticationRepository import me.vanpetegem.accentor.data.tracks.TrackRepository class AlbumsViewModel(application: Application) : AndroidViewModel(application) { + private val database = AccentorDatabase.getDatabase(application) private val authenticationRepository = AuthenticationRepository(AuthenticationDataSource(application)) - private val albumRepository: AlbumRepository - private val trackRepository: TrackRepository + private val albumRepository = AlbumRepository(database.albumDao(), authenticationRepository) + private val trackRepository = TrackRepository(database.trackDao(), authenticationRepository) - val allAlbums: LiveData> - private val _scrollState = MutableLiveData() - val scrollState: LiveData = _scrollState - - init { - val database = AccentorDatabase.getDatabase(application) - albumRepository = AlbumRepository(database.albumDao(), authenticationRepository) - trackRepository = TrackRepository(database.trackDao(), authenticationRepository) - allAlbums = albumRepository.allAlbums - } - - fun saveScrollState(state: Parcelable) { - _scrollState.value = state - } + val allAlbums: LiveData> = albumRepository.allAlbums } diff --git a/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistCard.kt b/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistCard.kt index 451219a9..c7493f10 100644 --- a/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistCard.kt +++ b/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistCard.kt @@ -1,6 +1,7 @@ package me.vanpetegem.accentor.ui.artists import androidx.compose.foundation.Image +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxWidth @@ -14,14 +15,15 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import androidx.navigation.NavController import coil.compose.rememberImagePainter import me.vanpetegem.accentor.R import me.vanpetegem.accentor.data.artists.Artist @Composable -public fun ArtistCard(artist: Artist) { +public fun ArtistCard(navController: NavController, artist: Artist) { Card( - modifier = Modifier.padding(8.dp), + modifier = Modifier.padding(8.dp).clickable { navController.navigate("artists/${artist.id}") }, ) { Column { Image( diff --git a/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistGrid.kt b/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistGrid.kt index c6891bdb..63a25d3f 100644 --- a/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistGrid.kt +++ b/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistGrid.kt @@ -4,12 +4,13 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.navigation.NavController import me.vanpetegem.accentor.ui.util.FastScrollableGrid @Composable -fun ArtistGrid(artistsViewModel: ArtistsViewModel = viewModel()) { +fun ArtistGrid(navController: NavController, artistsViewModel: ArtistsViewModel = viewModel()) { val artists by artistsViewModel.allArtists.observeAsState() if (artists != null) { - FastScrollableGrid(artists!!, { it.firstCharacter().uppercase() }) { artist -> ArtistCard(artist) } + FastScrollableGrid(artists!!, { it.firstCharacter().uppercase() }) { artist -> ArtistCard(navController, artist) } } } diff --git a/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistView.kt b/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistView.kt new file mode 100644 index 00000000..f3c3bb53 --- /dev/null +++ b/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistView.kt @@ -0,0 +1,147 @@ +package me.vanpetegem.accentor.ui.artists + +import androidx.compose.foundation.Image +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.material.ContentAlpha +import androidx.compose.material.Divider +import androidx.compose.material.DropdownMenu +import androidx.compose.material.DropdownMenuItem +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.LocalContentColor +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel +import coil.compose.rememberImagePainter +import coil.transform.CircleCropTransformation +import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.launch +import me.vanpetegem.accentor.R +import me.vanpetegem.accentor.data.tracks.Track +import me.vanpetegem.accentor.media.MediaSessionConnection +import me.vanpetegem.accentor.ui.albums.AlbumCard + +@Composable +fun ArtistView(id: Int, artistViewModel: ArtistViewModel = viewModel()) { + val artistState by artistViewModel.getArtist(id).observeAsState() + if (artistState != null) { + val artist = artistState!! + val albums by artistViewModel.albumsForArtist(artist).observeAsState() + val tracks by artistViewModel.tracksForArtist(artist).observeAsState() + LazyColumn(modifier = Modifier.fillMaxSize()) { + item { + Row(modifier = Modifier.padding(8.dp), verticalAlignment = Alignment.CenterVertically) { + Image( + painter = if (artist.image500 != null) { + rememberImagePainter(artist.image500) { + placeholder(R.drawable.ic_artist) + transformations(CircleCropTransformation()) + } + } else { + painterResource(R.drawable.ic_artist) + }, + contentDescription = stringResource(R.string.artist_image), + modifier = Modifier.width(80.dp).aspectRatio(1f), + ) + Text(artist.name, style = MaterialTheme.typography.h4, modifier = Modifier.padding(start = 8.dp)) + } + } + item { + if (albums != null && albums!!.size > 0) { + Text(stringResource(R.string.albums), style = MaterialTheme.typography.h5, modifier = Modifier.padding(8.dp)) + LazyRow { + items(albums!!.size) { i -> + Box(modifier = Modifier.width(192.dp)) { + AlbumCard(albums!![i]) + } + } + } + } + } + if (tracks != null && tracks!!.size > 0) { + item { + Text(stringResource(R.string.tracks), style = MaterialTheme.typography.h5, modifier = Modifier.padding(8.dp)) + } + items(tracks!!.size) { i -> TrackRow(tracks!![i]) } + } + } + } +} + +@Composable +fun TrackRow(track: Track, mediaSessionConnection: MediaSessionConnection = viewModel()) { + val scope = rememberCoroutineScope() + Row( + modifier = Modifier.fillMaxWidth().padding(8.dp).clickable { + scope.launch(IO) { mediaSessionConnection.play(track) } + } + ) { + Column(modifier = Modifier.weight(1f)) { + Text( + track.title, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + style = MaterialTheme.typography.subtitle1, + ) + Text( + track.stringifyTrackArtists(), + maxLines = 1, + overflow = TextOverflow.Ellipsis, + style = MaterialTheme.typography.subtitle2, + color = LocalContentColor.current.copy(alpha = ContentAlpha.medium), + ) + } + var expanded by remember { mutableStateOf(false) } + Box(modifier = Modifier.height(40.dp).aspectRatio(1f).wrapContentSize(Alignment.TopStart)) { + IconButton(onClick = { expanded = true }) { + Icon(Icons.Default.MoreVert, contentDescription = stringResource(R.string.open_menu)) + } + DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) { + DropdownMenuItem( + onClick = { + expanded = false + scope.launch(IO) { mediaSessionConnection.addTrackToQueue(track, maxOf(0, mediaSessionConnection.queuePosition.value ?: 0)) } + } + ) { + Text(stringResource(R.string.play_next)) + } + DropdownMenuItem( + onClick = { + expanded = false + scope.launch(IO) { mediaSessionConnection.addTrackToQueue(track) } + } + ) { + Text(stringResource(R.string.play_last)) + } + } + } + } + Divider() +} diff --git a/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistViewModel.kt b/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistViewModel.kt new file mode 100644 index 00000000..1ceae920 --- /dev/null +++ b/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistViewModel.kt @@ -0,0 +1,42 @@ +package me.vanpetegem.accentor.ui.artists + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import androidx.lifecycle.Transformations.map +import androidx.lifecycle.Transformations.switchMap +import me.vanpetegem.accentor.data.AccentorDatabase +import me.vanpetegem.accentor.data.albums.Album +import me.vanpetegem.accentor.data.albums.AlbumRepository +import me.vanpetegem.accentor.data.artists.Artist +import me.vanpetegem.accentor.data.artists.ArtistRepository +import me.vanpetegem.accentor.data.authentication.AuthenticationDataSource +import me.vanpetegem.accentor.data.authentication.AuthenticationRepository +import me.vanpetegem.accentor.data.tracks.Track +import me.vanpetegem.accentor.data.tracks.TrackRepository + +class ArtistViewModel(application: Application) : AndroidViewModel(application) { + private val database = AccentorDatabase.getDatabase(application) + private val authenticationRepository = AuthenticationRepository(AuthenticationDataSource(application)) + private val artistRepository = ArtistRepository(database.artistDao(), authenticationRepository) + private val albumRepository = AlbumRepository(database.albumDao(), authenticationRepository) + private val trackRepository = TrackRepository(database.trackDao(), authenticationRepository) + + fun getArtist(id: Int): LiveData = map(artistRepository.allArtistsById) { artists -> + artists[id] + } + + fun albumsForArtist(artist: Artist): LiveData> = map(albumRepository.albumsByReleased) { albums -> + val result = albums.filter { it.albumArtists.any { it.artistId == artist.id } }.toMutableList() + result.reverse() + result + } + + fun tracksForArtist(artist: Artist): LiveData> = switchMap(trackRepository.findByArtist(artist)) { tracks -> + map(albumRepository.allAlbumsById) { albums -> + val copy = tracks.toMutableList() + copy.sortWith({ t1, t2 -> t1.compareTo(t2, albums) }) + copy + } + } +} diff --git a/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistsViewModel.kt b/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistsViewModel.kt index dbec3947..81344ef3 100644 --- a/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistsViewModel.kt +++ b/app/src/main/java/me/vanpetegem/accentor/ui/artists/ArtistsViewModel.kt @@ -1,10 +1,8 @@ package me.vanpetegem.accentor.ui.artists import android.app.Application -import android.os.Parcelable import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import me.vanpetegem.accentor.data.AccentorDatabase import me.vanpetegem.accentor.data.artists.Artist import me.vanpetegem.accentor.data.artists.ArtistRepository @@ -12,20 +10,9 @@ import me.vanpetegem.accentor.data.authentication.AuthenticationDataSource import me.vanpetegem.accentor.data.authentication.AuthenticationRepository class ArtistsViewModel(application: Application) : AndroidViewModel(application) { + private val database = AccentorDatabase.getDatabase(application) private val authenticationRepository = AuthenticationRepository(AuthenticationDataSource(application)) - private val artistRepository: ArtistRepository + private val artistRepository = ArtistRepository(database.artistDao(), authenticationRepository) - val allArtists: LiveData> - private val _scrollState = MutableLiveData() - val scrollState: LiveData = _scrollState - - init { - val database = AccentorDatabase.getDatabase(application) - artistRepository = ArtistRepository(database.artistDao(), authenticationRepository) - allArtists = artistRepository.allArtists - } - - fun saveScrollState(state: Parcelable) { - _scrollState.value = state - } + val allArtists: LiveData> = artistRepository.allArtists } diff --git a/app/src/main/java/me/vanpetegem/accentor/ui/main/MainActivity.kt b/app/src/main/java/me/vanpetegem/accentor/ui/main/MainActivity.kt index 1521aabb..d6d7fa6e 100644 --- a/app/src/main/java/me/vanpetegem/accentor/ui/main/MainActivity.kt +++ b/app/src/main/java/me/vanpetegem/accentor/ui/main/MainActivity.kt @@ -44,9 +44,11 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.navigation.NavType import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.compose.navArgument import androidx.navigation.compose.rememberNavController import com.google.accompanist.swiperefresh.SwipeRefresh import com.google.accompanist.swiperefresh.SwipeRefreshIndicator @@ -56,6 +58,7 @@ import me.vanpetegem.accentor.R import me.vanpetegem.accentor.ui.AccentorTheme import me.vanpetegem.accentor.ui.albums.AlbumGrid import me.vanpetegem.accentor.ui.artists.ArtistGrid +import me.vanpetegem.accentor.ui.artists.ArtistView import me.vanpetegem.accentor.ui.home.Home import me.vanpetegem.accentor.ui.login.LoginActivity import me.vanpetegem.accentor.ui.player.PlayerOverlay @@ -106,11 +109,11 @@ fun Content(mainViewModel: MainViewModel = viewModel(), playerViewModel: PlayerV navController.navigate("home") scope.launch { scaffoldState.drawerState.close() } } - DrawerRow(stringResource(R.string.menu_artists), currentNavigation?.destination?.route == "artists", R.drawable.ic_menu_artists) { + DrawerRow(stringResource(R.string.artists), currentNavigation?.destination?.route == "artists", R.drawable.ic_menu_artists) { navController.navigate("artists") scope.launch { scaffoldState.drawerState.close() } } - DrawerRow(stringResource(R.string.menu_albums), currentNavigation?.destination?.route == "albums", R.drawable.ic_menu_albums) { + DrawerRow(stringResource(R.string.albums), currentNavigation?.destination?.route == "albums", R.drawable.ic_menu_albums) { navController.navigate("albums") scope.launch { scaffoldState.drawerState.close() } } @@ -166,7 +169,10 @@ fun Content(mainViewModel: MainViewModel = viewModel(), playerViewModel: PlayerV ) { NavHost(navController = navController, startDestination = "home") { composable("home") { Home() } - composable("artists") { ArtistGrid() } + composable("artists") { ArtistGrid(navController) } + composable("artists/{artistId}", arguments = listOf(navArgument("artistId") { type = NavType.IntType })) { entry -> + ArtistView(entry.arguments!!.getInt("artistId")) + } composable("albums") { AlbumGrid() } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9f67a6d6..50ad3c2f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,9 +3,6 @@ Refresh Sign out - Albums - Artists - Server Username Password @@ -58,4 +55,7 @@ On this day Recently added albums Random albums + Artists + Albums + Tracks