From 7a2c779fe28390f8d03d479e307b1b2857bd6f35 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Fri, 4 Sep 2020 17:11:16 -0600 Subject: [PATCH] Add Artist item Add the Artist item and switch LibraryFragment over to it. --- .../oxycblt/auxio/library/LibraryFragment.kt | 10 +-- .../oxycblt/auxio/loading/LoadingFragment.kt | 4 +- .../org/oxycblt/auxio/music/MusicUtils.kt | 31 ++++++++-- .../org/oxycblt/auxio/music/models/Artist.kt | 1 + .../auxio/music/processing/MusicSorter.kt | 8 ++- .../auxio/recycler/adapters/AlbumAdapter.kt | 4 -- .../auxio/recycler/adapters/ArtistAdapter.kt | 34 +++++++++++ .../recycler/viewholders/ArtistViewHolder.kt | 20 ++++++ app/src/main/res/layout/album_item.xml | 5 +- app/src/main/res/layout/artist_item.xml | 61 +++++++++++++++++++ app/src/main/res/layout/fragment_library.xml | 4 +- app/src/main/res/layout/fragment_loading.xml | 4 +- app/src/main/res/layout/fragment_songs.xml | 4 +- app/src/main/res/layout/song_item.xml | 5 +- app/src/main/res/values/strings.xml | 6 +- 15 files changed, 172 insertions(+), 29 deletions(-) create mode 100644 app/src/main/java/org/oxycblt/auxio/recycler/adapters/ArtistAdapter.kt create mode 100644 app/src/main/java/org/oxycblt/auxio/recycler/viewholders/ArtistViewHolder.kt create mode 100644 app/src/main/res/layout/artist_item.xml diff --git a/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt b/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt index 9d557af78..b42247f72 100644 --- a/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt @@ -10,7 +10,7 @@ import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.FragmentLibraryBinding -import org.oxycblt.auxio.recycler.adapters.AlbumAdapter +import org.oxycblt.auxio.recycler.adapters.ArtistAdapter import org.oxycblt.auxio.recycler.applyDivider import org.oxycblt.auxio.recycler.viewholders.ClickListener @@ -29,10 +29,10 @@ class LibraryFragment : Fragment() { inflater, R.layout.fragment_library, container, false ) - binding.libraryRecycler.adapter = AlbumAdapter( - libraryModel.albums.value!!, - ClickListener { album -> - Log.d(this::class.simpleName, album.title) + binding.libraryRecycler.adapter = ArtistAdapter( + libraryModel.artists.value!!, + ClickListener { artist -> + Log.d(this::class.simpleName, artist.name) } ) binding.libraryRecycler.applyDivider() diff --git a/app/src/main/java/org/oxycblt/auxio/loading/LoadingFragment.kt b/app/src/main/java/org/oxycblt/auxio/loading/LoadingFragment.kt index da5aa5128..b0f766f37 100644 --- a/app/src/main/java/org/oxycblt/auxio/loading/LoadingFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/loading/LoadingFragment.kt @@ -21,6 +21,8 @@ import org.oxycblt.auxio.music.processing.MusicLoaderResponse class LoadingFragment : Fragment(R.layout.fragment_loading) { + // TODO: Phase out LoadingFragment + private val loadingModel: LoadingViewModel by lazy { ViewModelProvider( this, @@ -108,6 +110,7 @@ class LoadingFragment : Fragment(R.layout.fragment_loading) { // Don't run this if the value is null, Which is what the value changes to after // this is run. repoResponse?.let { response -> + binding.loadingBar.visibility = View.GONE if (response == MusicLoaderResponse.DONE) { val inflater = TransitionInflater.from(requireContext()) @@ -119,7 +122,6 @@ class LoadingFragment : Fragment(R.layout.fragment_loading) { } else { // If the response wasn't a success, then show the specific error message // depending on which error response was given, along with a retry button - binding.loadingBar.visibility = View.GONE binding.errorText.visibility = View.VISIBLE binding.statusIcon.visibility = View.VISIBLE binding.retryButton.visibility = View.VISIBLE diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt index 658ccd07f..cc6e7c7c5 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt @@ -9,6 +9,7 @@ import androidx.databinding.BindingAdapter import coil.load import org.oxycblt.auxio.R import org.oxycblt.auxio.music.models.Album +import org.oxycblt.auxio.music.models.Artist import org.oxycblt.auxio.music.models.Song private val ID3_GENRES = arrayOf( @@ -83,12 +84,32 @@ fun ImageView.getCoverArt(any: Any) { } } +fun Int.toSongCount(): Int { + return if (this < 2) { + R.string.label_single_song + } else { + R.string.format_multi_song_count + } +} + +fun Int.toAlbumCount(): Int { + return if (this < 2) { + R.string.label_single_album + } else { + R.string.format_album_count + } +} + // Format the amount of songs in an album @BindingAdapter("songCount") fun TextView.getAlbumSongs(album: Album) { - text = if (album.numSongs < 2) { - context.getString(R.string.label_single_song) - } else { - context.getString(R.string.format_multi_song_count, album.numSongs.toString()) - } + text = context.getString(album.numSongs.toSongCount(), album.numSongs) +} + +@BindingAdapter("albumSongCount") +fun TextView.getSongAlbumCount(artist: Artist) { + val albums = context.getString(artist.numAlbums.toAlbumCount(), artist.numAlbums) + val songs = context.getString(artist.numSongs.toSongCount(), artist.numSongs) + + text = context.getString(R.string.format_combined_song_album, albums, songs) } diff --git a/app/src/main/java/org/oxycblt/auxio/music/models/Artist.kt b/app/src/main/java/org/oxycblt/auxio/music/models/Artist.kt index 308eec0e4..91f11ebb2 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/models/Artist.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/models/Artist.kt @@ -8,4 +8,5 @@ data class Artist( ) { val albums = mutableListOf() var numAlbums = 0 + var numSongs = 0 } diff --git a/app/src/main/java/org/oxycblt/auxio/music/processing/MusicSorter.kt b/app/src/main/java/org/oxycblt/auxio/music/processing/MusicSorter.kt index 1ea473b7c..2ff58d371 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/processing/MusicSorter.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/processing/MusicSorter.kt @@ -80,6 +80,9 @@ class MusicSorter( } artist.numAlbums = artist.albums.size + artist.albums.forEach { album -> + artist.numSongs += album.numSongs + } unknownAlbums.removeAll(artistAlbums) } @@ -95,7 +98,10 @@ class MusicSorter( unknownArtist.albums.add(album) } - unknownArtist.numAlbums = albums.size + unknownArtist.numAlbums = unknownArtist.albums.size + unknownArtist.albums.forEach { album -> + unknownArtist.numSongs += album.numSongs + } artists.add(unknownArtist) diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/adapters/AlbumAdapter.kt b/app/src/main/java/org/oxycblt/auxio/recycler/adapters/AlbumAdapter.kt index 2c5018b74..4603884bb 100644 --- a/app/src/main/java/org/oxycblt/auxio/recycler/adapters/AlbumAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/recycler/adapters/AlbumAdapter.kt @@ -29,10 +29,6 @@ class AlbumAdapter( override fun onBindViewHolder(holder: AlbumViewHolder, position: Int) { val album = data[position] - holder.itemView.setOnClickListener { - listener.onClick(album) - } - holder.bind(album) } } diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/adapters/ArtistAdapter.kt b/app/src/main/java/org/oxycblt/auxio/recycler/adapters/ArtistAdapter.kt new file mode 100644 index 000000000..64bc6ce3a --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/recycler/adapters/ArtistAdapter.kt @@ -0,0 +1,34 @@ +package org.oxycblt.auxio.recycler.adapters + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import org.oxycblt.auxio.databinding.ArtistItemBinding +import org.oxycblt.auxio.music.models.Artist +import org.oxycblt.auxio.recycler.viewholders.ArtistViewHolder +import org.oxycblt.auxio.recycler.viewholders.ClickListener + +class ArtistAdapter( + private val data: List, + private val listener: ClickListener +) : RecyclerView.Adapter() { + + override fun getItemCount(): Int = data.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ArtistViewHolder { + val binding = ArtistItemBinding.inflate(LayoutInflater.from(parent.context)) + + // Force the item to *actually* be the screen width so ellipsizing can work. + binding.root.layoutParams = RecyclerView.LayoutParams( + RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT + ) + + return ArtistViewHolder(binding) + } + + override fun onBindViewHolder(holder: ArtistViewHolder, position: Int) { + val album = data[position] + + holder.bind(album) + } +} diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/ArtistViewHolder.kt b/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/ArtistViewHolder.kt new file mode 100644 index 000000000..f64dbdbc5 --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/ArtistViewHolder.kt @@ -0,0 +1,20 @@ +package org.oxycblt.auxio.recycler.viewholders + +import androidx.recyclerview.widget.RecyclerView +import org.oxycblt.auxio.databinding.ArtistItemBinding +import org.oxycblt.auxio.music.models.Artist + +// Generic ViewHolder for an album +class ArtistViewHolder( + private val binding: ArtistItemBinding +) : RecyclerView.ViewHolder(binding.root) { + + // Bind the view w/new data + fun bind(artist: Artist) { + binding.artist = artist + + binding.artistName.requestLayout() + + binding.executePendingBindings() + } +} diff --git a/app/src/main/res/layout/album_item.xml b/app/src/main/res/layout/album_item.xml index 207652fbd..716f71872 100644 --- a/app/src/main/res/layout/album_item.xml +++ b/app/src/main/res/layout/album_item.xml @@ -13,7 +13,6 @@ + tools:src="@tools:sample/backgrounds/scenic" + tools:ignore="ContentDescription" /> + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_library.xml b/app/src/main/res/layout/fragment_library.xml index 437ccf841..6505e74fe 100644 --- a/app/src/main/res/layout/fragment_library.xml +++ b/app/src/main/res/layout/fragment_library.xml @@ -6,6 +6,7 @@ + app:title="@string/title_library_fragment" + tools:titleTextColor="@color/blue"/> + tools:tint="@color/blue" + tools:ignore="ContentDescription" /> + app:title="@string/title_all_songs" + tools:titleTextColor="@color/blue"/> + tools:src="@tools:sample/backgrounds/scenic" + tools:ignore="ContentDescription" /> Retry Grant 1 Song + 1 Album Unknown Genre Unknown Artist @@ -19,7 +20,6 @@ %s Songs %s / %s - - Cover art for - Error Icon + %s Albums + %s, %s \ No newline at end of file