Fix album bugs
Fix bugs with the album items & detail fragments.
This commit is contained in:
parent
af4c32eb5b
commit
aad42b5201
11 changed files with 68 additions and 27 deletions
|
|
@ -63,16 +63,18 @@ class AlbumDetailFragment : Fragment() {
|
||||||
findNavController().navigateUp()
|
findNavController().navigateUp()
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the album was shown directly from LibraryFragment [No parent artist stored]
|
// If the album was shown directly from LibraryFragment, Then enable the ability to
|
||||||
// Then enable the ability to navigate upwards to the parent artist
|
// navigate upwards to the parent artist
|
||||||
if (detailModel.currentArtist.value!!.id != detailModel.currentAlbum.value!!.artist.id) {
|
if (args.fromLibrary) {
|
||||||
detailModel.currentArtist.observe(viewLifecycleOwner) {
|
detailModel.navToParent.observe(viewLifecycleOwner) {
|
||||||
if (it.id == detailModel.currentAlbum.value!!.artist.id) {
|
if (it) {
|
||||||
findNavController().navigate(
|
findNavController().navigate(
|
||||||
AlbumDetailFragmentDirections.actionShowParentArtist(
|
AlbumDetailFragmentDirections.actionShowParentArtist(
|
||||||
detailModel.currentAlbum.value!!.artist.id
|
detailModel.currentAlbum.value!!.artist.id
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
detailModel.doneWithNavToParent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,6 +82,8 @@ class AlbumDetailFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
detailModel.albumSortMode.observe(viewLifecycleOwner) { mode ->
|
detailModel.albumSortMode.observe(viewLifecycleOwner) { mode ->
|
||||||
|
Log.d(this::class.simpleName, "Updating sort mode to $mode")
|
||||||
|
|
||||||
// Update the current sort icon
|
// Update the current sort icon
|
||||||
binding.albumSortButton.setImageResource(mode.iconRes)
|
binding.albumSortButton.setImageResource(mode.iconRes)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,8 @@ class ArtistDetailFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
detailModel.artistSortMode.observe(viewLifecycleOwner) { mode ->
|
detailModel.artistSortMode.observe(viewLifecycleOwner) { mode ->
|
||||||
|
Log.d(this::class.simpleName, "Updating sort mode to $mode")
|
||||||
|
|
||||||
// Update the current sort icon
|
// Update the current sort icon
|
||||||
binding.artistSortButton.setImageResource(mode.iconRes)
|
binding.artistSortButton.setImageResource(mode.iconRes)
|
||||||
|
|
||||||
|
|
@ -107,7 +109,7 @@ class ArtistDetailFragment : Fragment() {
|
||||||
detailModel.isAlreadyNavigating = true
|
detailModel.isAlreadyNavigating = true
|
||||||
|
|
||||||
findNavController().navigate(
|
findNavController().navigate(
|
||||||
ArtistDetailFragmentDirections.actionShowAlbum(album.id)
|
ArtistDetailFragmentDirections.actionShowAlbum(album.id, false)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,17 +21,25 @@ class DetailViewModel : ViewModel() {
|
||||||
val albumSortMode: LiveData<SortMode> get() = mAlbumSortMode
|
val albumSortMode: LiveData<SortMode> get() = mAlbumSortMode
|
||||||
|
|
||||||
// Current music models being shown
|
// Current music models being shown
|
||||||
// These have placeholder values in them so that they don't
|
// These have placeholder values initially so that they don't have to be checked if they're null
|
||||||
// have to be checked if they're null.
|
private val mCurrentGenre = MutableLiveData(
|
||||||
private val mCurrentGenre = MutableLiveData(Genre(name = ""))
|
Genre(id = Long.MIN_VALUE, name = "")
|
||||||
|
)
|
||||||
val currentGenre: LiveData<Genre> get() = mCurrentGenre
|
val currentGenre: LiveData<Genre> get() = mCurrentGenre
|
||||||
|
|
||||||
private val mCurrentArtist = MutableLiveData(Artist(name = ""))
|
private val mCurrentArtist = MutableLiveData(
|
||||||
|
Artist(id = Long.MIN_VALUE, name = "")
|
||||||
|
)
|
||||||
val currentArtist: LiveData<Artist> get() = mCurrentArtist
|
val currentArtist: LiveData<Artist> get() = mCurrentArtist
|
||||||
|
|
||||||
private val mCurrentAlbum = MutableLiveData(Album(name = "", artistName = ""))
|
private val mCurrentAlbum = MutableLiveData(
|
||||||
|
Album(id = Long.MIN_VALUE, name = "", artistName = "")
|
||||||
|
)
|
||||||
val currentAlbum: LiveData<Album> get() = mCurrentAlbum
|
val currentAlbum: LiveData<Album> get() = mCurrentAlbum
|
||||||
|
|
||||||
|
private val mNavToParent = MutableLiveData<Boolean>()
|
||||||
|
val navToParent: LiveData<Boolean> get() = mNavToParent
|
||||||
|
|
||||||
fun updateGenre(genre: Genre) {
|
fun updateGenre(genre: Genre) {
|
||||||
mCurrentGenre.value = genre
|
mCurrentGenre.value = genre
|
||||||
}
|
}
|
||||||
|
|
@ -44,6 +52,14 @@ class DetailViewModel : ViewModel() {
|
||||||
mCurrentAlbum.value = album
|
mCurrentAlbum.value = album
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun doNavToParent() {
|
||||||
|
mNavToParent.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doneWithNavToParent() {
|
||||||
|
mNavToParent.value = false
|
||||||
|
}
|
||||||
|
|
||||||
fun incrementGenreSortMode() {
|
fun incrementGenreSortMode() {
|
||||||
mGenreSortMode.value = when (mGenreSortMode.value) {
|
mGenreSortMode.value = when (mGenreSortMode.value) {
|
||||||
SortMode.ALPHA_DOWN -> SortMode.ALPHA_UP
|
SortMode.ALPHA_DOWN -> SortMode.ALPHA_UP
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,8 @@ class GenreDetailFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
detailModel.genreSortMode.observe(viewLifecycleOwner) { mode ->
|
detailModel.genreSortMode.observe(viewLifecycleOwner) { mode ->
|
||||||
|
Log.d(this::class.simpleName, "Updating sort mode to $mode")
|
||||||
|
|
||||||
// Update the current sort icon
|
// Update the current sort icon
|
||||||
binding.genreSortButton.setImageResource(mode.iconRes)
|
binding.genreSortButton.setImageResource(mode.iconRes)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ class LibraryFragment : Fragment() {
|
||||||
|
|
||||||
findNavController().navigate(
|
findNavController().navigate(
|
||||||
MainFragmentDirections.actionShowAlbum(
|
MainFragmentDirections.actionShowAlbum(
|
||||||
album.id
|
album.id, true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ sealed class BaseModel {
|
||||||
|
|
||||||
// Song
|
// Song
|
||||||
data class Song(
|
data class Song(
|
||||||
override val id: Long,
|
override val id: Long = -1,
|
||||||
override var name: String,
|
override var name: String,
|
||||||
val albumId: Long,
|
val albumId: Long,
|
||||||
val track: Int,
|
val track: Int,
|
||||||
|
|
@ -25,7 +25,7 @@ data class Song(
|
||||||
|
|
||||||
// Album
|
// Album
|
||||||
data class Album(
|
data class Album(
|
||||||
override val id: Long = Long.MIN_VALUE,
|
override val id: Long = -1,
|
||||||
override val name: String,
|
override val name: String,
|
||||||
val artistName: String,
|
val artistName: String,
|
||||||
val coverUri: Uri = Uri.EMPTY,
|
val coverUri: Uri = Uri.EMPTY,
|
||||||
|
|
@ -47,7 +47,7 @@ data class Album(
|
||||||
|
|
||||||
// Artist
|
// Artist
|
||||||
data class Artist(
|
data class Artist(
|
||||||
override val id: Long = Long.MIN_VALUE,
|
override val id: Long = -1,
|
||||||
override var name: String,
|
override var name: String,
|
||||||
val givenGenres: MutableList<Genre> = mutableListOf()
|
val givenGenres: MutableList<Genre> = mutableListOf()
|
||||||
) : BaseModel() {
|
) : BaseModel() {
|
||||||
|
|
@ -67,7 +67,7 @@ data class Artist(
|
||||||
|
|
||||||
// Genre
|
// Genre
|
||||||
data class Genre(
|
data class Genre(
|
||||||
override val id: Long = Long.MIN_VALUE,
|
override val id: Long = -1,
|
||||||
override var name: String,
|
override var name: String,
|
||||||
) : BaseModel() {
|
) : BaseModel() {
|
||||||
val artists = mutableListOf<Artist>()
|
val artists = mutableListOf<Artist>()
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package org.oxycblt.auxio.music
|
package org.oxycblt.auxio.music
|
||||||
|
|
||||||
import android.content.ContentUris
|
import android.content.ContentUris
|
||||||
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
|
|
@ -79,6 +80,14 @@ fun Long.toDuration(): String {
|
||||||
return durationString
|
return durationString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert an integer to its formatted year
|
||||||
|
fun Int.toYear(context: Context): String {
|
||||||
|
return if (this > 0) {
|
||||||
|
this.toString()
|
||||||
|
} else {
|
||||||
|
context.getString(R.string.placeholder_no_date)
|
||||||
|
}
|
||||||
|
}
|
||||||
// --- BINDING ADAPTERS ---
|
// --- BINDING ADAPTERS ---
|
||||||
|
|
||||||
@BindingAdapter("genreCounts")
|
@BindingAdapter("genreCounts")
|
||||||
|
|
@ -87,7 +96,7 @@ fun TextView.bindGenreCounts(genre: Genre) {
|
||||||
R.plurals.format_artist_count, genre.numArtists, genre.numArtists
|
R.plurals.format_artist_count, genre.numArtists, genre.numArtists
|
||||||
)
|
)
|
||||||
val albums = context.resources.getQuantityString(
|
val albums = context.resources.getQuantityString(
|
||||||
R.plurals.format_album_count, genre.numAlbums, genre.numAlbums
|
R.plurals.format_song_count, genre.numAlbums, genre.numAlbums
|
||||||
)
|
)
|
||||||
|
|
||||||
text = context.getString(R.string.format_double_counts, artists, albums)
|
text = context.getString(R.string.format_double_counts, artists, albums)
|
||||||
|
|
@ -122,7 +131,7 @@ fun TextView.bindArtistCounts(artist: Artist) {
|
||||||
fun TextView.bindAlbumDetails(album: Album) {
|
fun TextView.bindAlbumDetails(album: Album) {
|
||||||
text = context.getString(
|
text = context.getString(
|
||||||
R.string.format_double_info,
|
R.string.format_double_info,
|
||||||
album.year.toString(),
|
album.year.toYear(context),
|
||||||
context.resources.getQuantityString(
|
context.resources.getQuantityString(
|
||||||
R.plurals.format_song_count,
|
R.plurals.format_song_count,
|
||||||
album.numSongs, album.numSongs
|
album.numSongs, album.numSongs
|
||||||
|
|
@ -131,7 +140,12 @@ fun TextView.bindAlbumDetails(album: Album) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@BindingAdapter("albumSongs")
|
@BindingAdapter("albumYear")
|
||||||
|
fun TextView.bindAlbumDate(album: Album) {
|
||||||
|
text = album.year.toYear(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter("albumSongCount")
|
||||||
// Format the amount of songs in an album
|
// Format the amount of songs in an album
|
||||||
fun TextView.bindAlbumSongs(album: Album) {
|
fun TextView.bindAlbumSongs(album: Album) {
|
||||||
text = context.resources.getQuantityString(
|
text = context.resources.getQuantityString(
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@
|
||||||
android:layout_marginStart="@dimen/margin_medium"
|
android:layout_marginStart="@dimen/margin_medium"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:onClick="@{() -> detailModel.updateArtist(album.artist)}"
|
android:onClick="@{() -> detailModel.doNavToParent()}"
|
||||||
android:text="@{album.artist.name}"
|
android:text="@{album.artist.name}"
|
||||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
|
@ -86,11 +86,10 @@
|
||||||
tools:text="Artist Name" />
|
tools:text="Artist Name" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/album_song_count"
|
android:id="@+id/album_details"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/margin_medium"
|
android:layout_marginStart="@dimen/margin_medium"
|
||||||
android:text="@{album.year != 0 ? String.valueOf(album.year) : @string/placeholder_no_date}"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
app:albumDetails="@{album}"
|
app:albumDetails="@{album}"
|
||||||
|
|
@ -112,7 +111,7 @@
|
||||||
android:text="@string/label_songs"
|
android:text="@string/label_songs"
|
||||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Overline"
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Overline"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/album_song_count" />
|
app:layout_constraintTop_toBottomOf="@+id/album_details" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/album_sort_button"
|
android:id="@+id/album_sort_button"
|
||||||
|
|
@ -127,9 +126,9 @@
|
||||||
android:paddingBottom="@dimen/padding_small"
|
android:paddingBottom="@dimen/padding_small"
|
||||||
android:onClick="@{() -> detailModel.incrementAlbumSortMode()}"
|
android:onClick="@{() -> detailModel.incrementAlbumSortMode()}"
|
||||||
tools:src="@drawable/ic_sort_numeric_down"
|
tools:src="@drawable/ic_sort_numeric_down"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/album_recycler"
|
app:layout_constraintBottom_toTopOf="@+id/album_song_recycler"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/album_song_count" />
|
app:layout_constraintTop_toBottomOf="@+id/album_details" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/album_song_recycler"
|
android:id="@+id/album_song_recycler"
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@
|
||||||
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
|
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
|
app:albumSongCount="@{album}"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@+id/album_cover"
|
app:layout_constraintStart_toEndOf="@+id/album_cover"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/album_name"
|
app:layout_constraintTop_toBottomOf="@+id/album_name"
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,10 @@
|
||||||
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
|
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text="@{String.valueOf(album.year)}"
|
app:albumYear="@{album}"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@+id/album_cover"
|
app:layout_constraintStart_toEndOf="@+id/album_cover"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/album_name"
|
app:layout_constraintTop_toBottomOf="@+id/album_name"
|
||||||
tools:text="10 Songs" />
|
tools:text="2020" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
@ -72,6 +72,9 @@
|
||||||
<argument
|
<argument
|
||||||
android:name="albumId"
|
android:name="albumId"
|
||||||
app:argType="long" />
|
app:argType="long" />
|
||||||
|
<argument
|
||||||
|
android:name="fromLibrary"
|
||||||
|
app:argType="boolean" />
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_show_parent_artist"
|
android:id="@+id/action_show_parent_artist"
|
||||||
app:enterAnim="@anim/fragment_fade_enter"
|
app:enterAnim="@anim/fragment_fade_enter"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue