diff --git a/README.md b/README.md
index 3bc6f4907..085974bf1 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@
## About
-Auxio is a local music player for android partially inspired by both Spotify and other FOSS music players such as [Music Player GO](https://github.com/enricocid/Music-Player-GO) and [Phonograph](https://github.com/kabouzeid/Phonograph), albeit with a heavy emphasis on a simple and sensible, however customizable UI/UX.
+Auxio is a local music player for android partially inspired by both Spotify and other FOSS music players such as [Music Player GO](https://github.com/enricocid/Music-Player-GO) and [Phonograph](https://github.com/kabouzeid/Phonograph), albeit with a heavy emphasis on a simple and straightfoward, however customizable UI/UX.
Unlike other music players, Auxio is based off of [ExoPlayer](https://exoplayer.dev/), allowing for much better listening experience compared to the native [MediaPlayer](https://developer.android.com/guide/topics/media/mediaplayer) API. Auxio's codebase is also designed to be extendable, allowing for the addition of features that are not included in the main app.
@@ -53,7 +53,7 @@ Unlike other music players, Auxio is based off of [ExoPlayer](https://exoplayer.
- Better music loading system
- Improved genre/artist/album UIs
-- Dedicated search tab
+- New search setup
- Swipe-to-next-track function
- Artist Images
- Black theme
diff --git a/app/build.gradle b/app/build.gradle
index 2e69f1b8d..478ffc4f3 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,7 +97,7 @@ dependencies {
implementation "com.google.android.exoplayer:extension-mediasession:$exoplayer_version"
// Image loading
- implementation 'io.coil-kt:coil:0.13.0'
+ implementation 'io.coil-kt:coil:1.1.0'
// Material
implementation 'com.google.android.material:material:1.3.0-beta01'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 83315b942..037771b66 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,26 +1,25 @@
-
+
+ android:theme="@style/Theme.Base">
@@ -32,12 +31,12 @@
\ No newline at end of file
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt
index 4931f8e28..64ceee535 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt
@@ -5,20 +5,19 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.PopupMenu
-import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import org.oxycblt.auxio.R
-import org.oxycblt.auxio.databinding.FragmentAlbumDetailBinding
-import org.oxycblt.auxio.detail.adapters.AlbumSongAdapter
+import org.oxycblt.auxio.databinding.FragmentDetailBinding
+import org.oxycblt.auxio.detail.adapters.AlbumDetailAdapter
import org.oxycblt.auxio.logD
import org.oxycblt.auxio.music.Album
+import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.music.Song
-import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.playback.state.PlaybackMode
+import org.oxycblt.auxio.recycler.LinearCenterScroller
import org.oxycblt.auxio.ui.createToast
-import org.oxycblt.auxio.ui.disable
import org.oxycblt.auxio.ui.setupAlbumSongActions
/**
@@ -26,17 +25,13 @@ import org.oxycblt.auxio.ui.setupAlbumSongActions
* @author OxygenCobalt
*/
class AlbumDetailFragment : DetailFragment() {
-
private val args: AlbumDetailFragmentArgs by navArgs()
- private val playbackModel: PlaybackViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
- val binding = FragmentAlbumDetailBinding.inflate(inflater)
-
// If DetailViewModel isn't already storing the album, get it from MusicStore
// using the ID given by the navigation arguments.
if (detailModel.currentAlbum.value == null ||
@@ -49,7 +44,8 @@ class AlbumDetailFragment : DetailFragment() {
)
}
- val songAdapter = AlbumSongAdapter(
+ val detailAdapter = AlbumDetailAdapter(
+ detailModel, viewLifecycleOwner,
doOnClick = { playbackModel.playSong(it, PlaybackMode.IN_ALBUM) },
doOnLongClick = { data, view ->
PopupMenu(requireContext(), view).setupAlbumSongActions(
@@ -58,59 +54,43 @@ class AlbumDetailFragment : DetailFragment() {
}
)
- var lastHolder: AlbumSongAdapter.ViewHolder? = null
-
// --- UI SETUP ---
binding.lifecycleOwner = this
- binding.detailModel = detailModel
- binding.playbackModel = playbackModel
- binding.album = detailModel.currentAlbum.value!!
- binding.albumToolbar.apply {
- setNavigationOnClickListener {
- findNavController().navigateUp()
- }
+ setupToolbar(R.menu.menu_album_actions) {
+ when (it) {
+ R.id.action_shuffle -> {
+ playbackModel.playAlbum(
+ detailModel.currentAlbum.value!!, true
+ )
- setOnMenuItemClickListener {
- when (it.itemId) {
- R.id.action_shuffle -> {
- playbackModel.playAlbum(
- detailModel.currentAlbum.value!!, true
- )
-
- true
- }
- R.id.action_play -> {
- playbackModel.playAlbum(
- detailModel.currentAlbum.value!!, false
- )
-
- true
- }
-
- R.id.action_queue_add -> {
- playbackModel.addToUserQueue(detailModel.currentAlbum.value!!)
- context.getString(R.string.label_queue_added).createToast(requireContext())
-
- true
- }
-
- else -> false
+ true
}
+ R.id.action_play -> {
+ playbackModel.playAlbum(
+ detailModel.currentAlbum.value!!, false
+ )
+
+ true
+ }
+
+ R.id.action_queue_add -> {
+ playbackModel.addToUserQueue(detailModel.currentAlbum.value!!)
+ getString(R.string.label_queue_added).createToast(requireContext())
+
+ true
+ }
+
+ else -> false
}
}
- binding.albumSongRecycler.apply {
- adapter = songAdapter
+ binding.detailRecycler.apply {
+ adapter = detailAdapter
setHasFixedSize(true)
}
- // Don't enable the sort button if there's only one song [or less]
- if (detailModel.currentAlbum.value!!.songs.size < 2) {
- binding.albumSortButton.disable()
- }
-
// If this fragment was created in order to nav to an item, then snap scroll to that item.
playbackModel.navToItem.value?.let {
if (it is Song) {
@@ -123,13 +103,11 @@ class AlbumDetailFragment : DetailFragment() {
detailModel.albumSortMode.observe(viewLifecycleOwner) { mode ->
logD("Updating sort mode to $mode")
- // Update the current sort icon
- binding.albumSortButton.setImageResource(mode.iconRes)
+ val data = mutableListOf(detailModel.currentAlbum.value!!).also {
+ it.addAll(mode.getSortedSongList(detailModel.currentAlbum.value!!.songs))
+ }
- // Then update the sort mode of the album adapter.
- songAdapter.submitList(
- mode.getSortedSongList(detailModel.currentAlbum.value!!.songs)
- )
+ detailAdapter.submitList(data)
}
detailModel.doneWithNavToParent()
@@ -148,32 +126,6 @@ class AlbumDetailFragment : DetailFragment() {
}
}
- playbackModel.song.observe(viewLifecycleOwner) { song ->
- if (song != null) {
- val pos = detailModel.albumSortMode.value!!.getSortedSongList(
- detailModel.currentAlbum.value!!.songs
- ).indexOfFirst { it.id == song.id }
-
- if (pos != -1) {
- binding.albumSongRecycler.post {
- lastHolder?.removePlaying()
-
- lastHolder = binding.albumSongRecycler.getChildViewHolder(
- binding.albumSongRecycler.getChildAt(pos)
- ) as AlbumSongAdapter.ViewHolder
-
- lastHolder?.setPlaying(requireContext())
- }
-
- return@observe
- } else {
- lastHolder?.removePlaying()
- }
- }
-
- lastHolder?.removePlaying()
- }
-
playbackModel.navToItem.observe(viewLifecycleOwner) {
if (it != null) {
if (it is Song) {
@@ -196,22 +148,18 @@ class AlbumDetailFragment : DetailFragment() {
* @param binding The binding required
* @param smooth Whether to scroll smoothly or not, true for yes, false for no.
*/
- private fun scrollToPlayingItem(binding: FragmentAlbumDetailBinding, smooth: Boolean) {
+ private fun scrollToPlayingItem(binding: FragmentDetailBinding, smooth: Boolean) {
// Calculate where the item for the currently played song is, and scroll to there
val pos = detailModel.albumSortMode.value!!.getSortedSongList(
detailModel.currentAlbum.value!!.songs
).indexOf(playbackModel.song.value)
if (pos != -1) {
- binding.albumSongRecycler.post {
- val y = binding.albumSongRecycler.y +
- binding.albumSongRecycler.getChildAt(pos).y
-
- if (smooth) {
- binding.nestedScroll.smoothScrollTo(0, y.toInt())
- } else {
- binding.nestedScroll.scrollTo(0, y.toInt())
- }
+ // TODO: Re-add snap scrolling.
+ binding.detailRecycler.post {
+ binding.detailRecycler.layoutManager?.startSmoothScroll(
+ LinearCenterScroller(pos)
+ )
}
playbackModel.doneWithNavToItem()
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt
index 1411f4e0e..9b1cff939 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt
@@ -5,17 +5,14 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.PopupMenu
-import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import org.oxycblt.auxio.R
-import org.oxycblt.auxio.databinding.FragmentDetailBinding
-import org.oxycblt.auxio.detail.adapters.ArtistAlbumAdapter
+import org.oxycblt.auxio.detail.adapters.ArtistDetailAdapter
import org.oxycblt.auxio.logD
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.MusicStore
-import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.ui.setupAlbumActions
/**
@@ -24,15 +21,12 @@ import org.oxycblt.auxio.ui.setupAlbumActions
*/
class ArtistDetailFragment : DetailFragment() {
private val args: ArtistDetailFragmentArgs by navArgs()
- private val playbackModel: PlaybackViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
- val binding = FragmentDetailBinding.inflate(inflater)
-
// If DetailViewModel isn't already storing the artist, get it from MusicStore
// using the ID given by the navigation arguments
if (detailModel.currentArtist.value == null ||
@@ -45,7 +39,7 @@ class ArtistDetailFragment : DetailFragment() {
)
}
- val albumAdapter = ArtistAlbumAdapter(
+ val detailAdapter = ArtistDetailAdapter(
detailModel, viewLifecycleOwner,
doOnClick = {
if (!detailModel.isNavigating) {
@@ -67,39 +61,31 @@ class ArtistDetailFragment : DetailFragment() {
binding.lifecycleOwner = this
- binding.detailToolbar.apply {
- inflateMenu(R.menu.menu_artist_detail)
-
- setNavigationOnClickListener {
- findNavController().navigateUp()
- }
-
- setOnMenuItemClickListener {
- when (it.itemId) {
- R.id.action_shuffle -> {
- playbackModel.playArtist(
- detailModel.currentArtist.value!!,
- true
- )
-
+ setupToolbar(R.menu.menu_artist_actions) {
+ when (it) {
+ R.id.action_shuffle -> {
+ playbackModel.playArtist(
+ detailModel.currentArtist.value!!,
true
- }
+ )
- R.id.action_play_albums -> {
- playbackModel.playArtist(
- detailModel.currentArtist.value!!, false
- )
-
- true
- }
-
- else -> false
+ true
}
+
+ R.id.action_play_albums -> {
+ playbackModel.playArtist(
+ detailModel.currentArtist.value!!, false
+ )
+
+ true
+ }
+
+ else -> false
}
}
binding.detailRecycler.apply {
- adapter = albumAdapter
+ adapter = detailAdapter
setHasFixedSize(true)
}
@@ -112,7 +98,7 @@ class ArtistDetailFragment : DetailFragment() {
it.addAll(mode.getSortedAlbumList(detailModel.currentArtist.value!!.albums))
}
- albumAdapter.submitList(data)
+ detailAdapter.submitList(data)
}
playbackModel.navToItem.observe(viewLifecycleOwner) {
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt
index ce1f70570..b1bdd0478 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt
@@ -3,20 +3,26 @@ package org.oxycblt.auxio.detail
import android.os.Bundle
import android.view.View
import androidx.activity.OnBackPressedCallback
+import androidx.annotation.MenuRes
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
+import org.oxycblt.auxio.databinding.FragmentDetailBinding
+import org.oxycblt.auxio.playback.PlaybackViewModel
+import org.oxycblt.auxio.ui.memberBinding
/**
- * A Base [Fragment] implementing a [OnBackPressedCallback] so that Auxio will navigate upwards
- * instead of out of the app if a Detail Fragment is currently open. Also carries the
- * multi-navigation fix.
- * TODO: Migrate to a more powerful/efficient CoordinatorLayout instead of NestedScrollView
+ * A Base [Fragment] implementing the base features shared across all detail fragments.
* TODO: Add custom artist images
+ * TODO: Add playing item highlighting
* @author OxygenCobalt
*/
abstract class DetailFragment : Fragment() {
protected val detailModel: DetailViewModel by activityViewModels()
+ protected val playbackModel: PlaybackViewModel by activityViewModels()
+ protected val binding: FragmentDetailBinding by memberBinding(
+ FragmentDetailBinding::inflate
+ )
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, callback)
@@ -34,6 +40,25 @@ abstract class DetailFragment : Fragment() {
callback.isEnabled = false
}
+ /**
+ * Shortcut method for doing setup of the detail toolbar.
+ */
+ protected fun setupToolbar(@MenuRes menu: Int, onMenuClick: (id: Int) -> Boolean) {
+ binding.detailToolbar.apply {
+ inflateMenu(menu)
+
+ setNavigationOnClickListener {
+ findNavController().navigateUp()
+ }
+
+ setOnMenuItemClickListener {
+ onMenuClick(it.itemId)
+ }
+ }
+ }
+
+ // Override the back button so that going back will only exit the detail fragments instead of
+ // the entire app.
private val callback = object : OnBackPressedCallback(false) {
override fun handleOnBackPressed() {
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt
index 1c53bb3d9..7debf9571 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt
@@ -5,17 +5,13 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.PopupMenu
-import androidx.fragment.app.activityViewModels
-import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.GridLayoutManager
import org.oxycblt.auxio.R
-import org.oxycblt.auxio.databinding.FragmentDetailBinding
-import org.oxycblt.auxio.detail.adapters.GenreSongAdapter
+import org.oxycblt.auxio.detail.adapters.GenreDetailAdapter
import org.oxycblt.auxio.logD
import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.MusicStore
-import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.playback.state.PlaybackMode
import org.oxycblt.auxio.ui.isLandscape
import org.oxycblt.auxio.ui.setupGenreSongActions
@@ -25,17 +21,13 @@ import org.oxycblt.auxio.ui.setupGenreSongActions
* @author OxygenCobalt
*/
class GenreDetailFragment : DetailFragment() {
-
private val args: GenreDetailFragmentArgs by navArgs()
- private val playbackModel: PlaybackViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
- val binding = FragmentDetailBinding.inflate(inflater)
-
// If DetailViewModel isn't already storing the genre, get it from MusicStore
// using the ID given by the navigation arguments
if (detailModel.currentGenre.value == null ||
@@ -48,7 +40,7 @@ class GenreDetailFragment : DetailFragment() {
)
}
- val songAdapter = GenreSongAdapter(
+ val detailAdapter = GenreDetailAdapter(
detailModel, viewLifecycleOwner,
doOnClick = {
playbackModel.playSong(it, PlaybackMode.IN_GENRE)
@@ -64,30 +56,23 @@ class GenreDetailFragment : DetailFragment() {
binding.lifecycleOwner = this
- binding.detailToolbar.apply {
- inflateMenu(R.menu.menu_songs)
- setNavigationOnClickListener {
- findNavController().navigateUp()
- }
-
- setOnMenuItemClickListener {
- when (it.itemId) {
- R.id.action_shuffle -> {
- playbackModel.playGenre(
- detailModel.currentGenre.value!!,
- true
- )
-
+ setupToolbar(R.menu.menu_genre_actions) {
+ when (it) {
+ R.id.action_shuffle -> {
+ playbackModel.playGenre(
+ detailModel.currentGenre.value!!,
true
- }
+ )
- else -> false
+ true
}
+
+ else -> false
}
}
binding.detailRecycler.apply {
- adapter = songAdapter
+ adapter = detailAdapter
setHasFixedSize(true)
if (isLandscape(resources)) {
@@ -110,7 +95,7 @@ class GenreDetailFragment : DetailFragment() {
it.addAll(mode.getSortedSongList(detailModel.currentGenre.value!!.songs))
}
- songAdapter.submitList(data)
+ detailAdapter.submitList(data)
}
logD("Fragment created.")
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/adapters/AlbumDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/adapters/AlbumDetailAdapter.kt
new file mode 100644
index 000000000..d4aa5d971
--- /dev/null
+++ b/app/src/main/java/org/oxycblt/auxio/detail/adapters/AlbumDetailAdapter.kt
@@ -0,0 +1,85 @@
+package org.oxycblt.auxio.detail.adapters
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.lifecycle.LifecycleOwner
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.oxycblt.auxio.databinding.ItemAlbumHeaderBinding
+import org.oxycblt.auxio.databinding.ItemAlbumSongBinding
+import org.oxycblt.auxio.detail.DetailViewModel
+import org.oxycblt.auxio.music.Album
+import org.oxycblt.auxio.music.BaseModel
+import org.oxycblt.auxio.music.Song
+import org.oxycblt.auxio.recycler.DiffCallback
+import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
+import org.oxycblt.auxio.ui.disable
+
+/**
+ * An adapter for displaying the details and [Song]s of an [Album]
+ */
+class AlbumDetailAdapter(
+ private val detailModel: DetailViewModel,
+ private val lifecycleOwner: LifecycleOwner,
+ private val doOnClick: (data: Song) -> Unit,
+ private val doOnLongClick: (data: Song, view: View) -> Unit
+) : ListAdapter(DiffCallback()) {
+ override fun getItemViewType(position: Int): Int {
+ return when (getItem(position)) {
+ is Album -> ALBUM_HEADER_ITEM_TYPE
+ is Song -> ALBUM_SONG_ITEM_TYPE
+
+ else -> -1
+ }
+ }
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return when (viewType) {
+ ALBUM_HEADER_ITEM_TYPE -> AlbumHeaderViewHolder(
+ ItemAlbumHeaderBinding.inflate(LayoutInflater.from(parent.context))
+ )
+ ALBUM_SONG_ITEM_TYPE -> AlbumSongViewHolder(
+ ItemAlbumSongBinding.inflate(LayoutInflater.from(parent.context))
+ )
+
+ else -> error("Invalid ViewHolder item type $viewType")
+ }
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ when (val item = getItem(position)) {
+ is Album -> (holder as AlbumHeaderViewHolder).bind(item)
+ is Song -> (holder as AlbumSongViewHolder).bind(item)
+ }
+ }
+
+ inner class AlbumHeaderViewHolder(
+ private val binding: ItemAlbumHeaderBinding
+ ) : BaseViewHolder(binding, null, null) {
+
+ override fun onBind(data: Album) {
+ binding.album = data
+ binding.detailModel = detailModel
+ binding.lifecycleOwner = lifecycleOwner
+
+ if (data.songs.size < 2) {
+ binding.albumSortButton.disable()
+ }
+ }
+ }
+
+ inner class AlbumSongViewHolder(
+ private val binding: ItemAlbumSongBinding,
+ ) : BaseViewHolder(binding, doOnClick, doOnLongClick) {
+ override fun onBind(data: Song) {
+ binding.song = data
+
+ binding.songName.requestLayout()
+ }
+ }
+
+ companion object {
+ const val ALBUM_HEADER_ITEM_TYPE = 0xA024
+ const val ALBUM_SONG_ITEM_TYPE = 0xA025
+ }
+}
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/adapters/AlbumSongAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/adapters/AlbumSongAdapter.kt
deleted file mode 100644
index 59bd1a091..000000000
--- a/app/src/main/java/org/oxycblt/auxio/detail/adapters/AlbumSongAdapter.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.oxycblt.auxio.detail.adapters
-
-import android.content.Context
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.recyclerview.widget.ListAdapter
-import org.oxycblt.auxio.databinding.ItemAlbumSongBinding
-import org.oxycblt.auxio.music.Song
-import org.oxycblt.auxio.recycler.DiffCallback
-import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
-import org.oxycblt.auxio.ui.accent
-import org.oxycblt.auxio.ui.toColor
-
-/**
- * An adapter for displaying the [Song]s of an album.
- */
-class AlbumSongAdapter(
- private val doOnClick: (data: Song) -> Unit,
- private val doOnLongClick: (data: Song, view: View) -> Unit
-) : ListAdapter(DiffCallback()) {
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
- return ViewHolder(
- ItemAlbumSongBinding.inflate(LayoutInflater.from(parent.context))
- )
- }
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- holder.bind(getItem(position))
- }
-
- // Generic ViewHolder for a song
- inner class ViewHolder(
- private val binding: ItemAlbumSongBinding,
- ) : BaseViewHolder(binding, doOnClick, doOnLongClick) {
- private val normalColor = binding.songName.currentTextColor
- private val inactiveColor = binding.songTrack.currentTextColor
-
- override fun onBind(data: Song) {
- binding.song = data
-
- binding.songName.requestLayout()
- }
-
- fun setPlaying(context: Context) {
- val accentColor = accent.first.toColor(context)
-
- binding.songName.setTextColor(accentColor)
- binding.songTrack.setTextColor(accentColor)
- }
-
- fun removePlaying() {
- binding.songName.setTextColor(normalColor)
- binding.songTrack.setTextColor(inactiveColor)
- }
- }
-}
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistAlbumAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistDetailAdapter.kt
similarity index 99%
rename from app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistAlbumAdapter.kt
rename to app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistDetailAdapter.kt
index f86d27478..708cc169e 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistAlbumAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistDetailAdapter.kt
@@ -19,7 +19,7 @@ import org.oxycblt.auxio.ui.disable
/**
* An adapter for displaying the [Album]s of an artist.
*/
-class ArtistAlbumAdapter(
+class ArtistDetailAdapter(
private val detailModel: DetailViewModel,
private val lifecycleOwner: LifecycleOwner,
private val doOnClick: (data: Album) -> Unit,
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/adapters/GenreSongAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/adapters/GenreDetailAdapter.kt
similarity index 99%
rename from app/src/main/java/org/oxycblt/auxio/detail/adapters/GenreSongAdapter.kt
rename to app/src/main/java/org/oxycblt/auxio/detail/adapters/GenreDetailAdapter.kt
index 9f57b5f95..210b1d557 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/adapters/GenreSongAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/adapters/GenreDetailAdapter.kt
@@ -19,7 +19,7 @@ import org.oxycblt.auxio.ui.disable
/**
* An adapter for displaying the [Song]s of a genre.
*/
-class GenreSongAdapter(
+class GenreDetailAdapter(
private val detailModel: DetailViewModel,
private val lifecycleOwner: LifecycleOwner,
private val doOnClick: (data: Song) -> Unit,
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 ebeb85d3a..8352d50c8 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt
+++ b/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt
@@ -9,7 +9,6 @@ import android.widget.ImageButton
import android.widget.TextView
import androidx.databinding.BindingAdapter
import org.oxycblt.auxio.R
-import org.oxycblt.auxio.logD
import org.oxycblt.auxio.recycler.SortMode
/**
@@ -174,7 +173,6 @@ fun TextView.bindAlbumYear(album: Album) {
* Bind the [SortMode] icon for an ImageButton.
*/
@BindingAdapter("sortIcon")
-fun ImageButton.bindSortIcon(data: SortMode) {
- logD("YOU STUPID FUCKING RETARD JUST FUNCITON")
- setImageResource(data.iconRes)
+fun ImageButton.bindSortIcon(mode: SortMode) {
+ setImageResource(mode.iconRes)
}
diff --git a/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt b/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt
index 9402b59ca..c09c34fe1 100644
--- a/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt
@@ -196,7 +196,7 @@ fun PopupMenu.setupAlbumActions(
else -> false
}
}
- inflateAndShow(R.menu.menu_album_detail)
+ inflateAndShow(R.menu.menu_album_actions)
}
/**
@@ -220,7 +220,7 @@ fun PopupMenu.setupArtistActions(artist: Artist, playbackModel: PlaybackViewMode
else -> false
}
}
- inflateAndShow(R.menu.menu_artist_detail)
+ inflateAndShow(R.menu.menu_artist_actions)
}
/**
@@ -239,7 +239,7 @@ fun PopupMenu.setupGenreActions(genre: Genre, playbackModel: PlaybackViewModel)
else -> false
}
}
- inflateAndShow(R.menu.menu_genre_detail)
+ inflateAndShow(R.menu.menu_genre_actions)
}
/**
diff --git a/app/src/main/res/layout-land/fragment_album_detail.xml b/app/src/main/res/layout-land/fragment_album_detail.xml
deleted file mode 100644
index 70dd928e8..000000000
--- a/app/src/main/res/layout-land/fragment_album_detail.xml
+++ /dev/null
@@ -1,139 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout-land/item_album_header.xml b/app/src/main/res/layout-land/item_album_header.xml
new file mode 100644
index 000000000..a736160bd
--- /dev/null
+++ b/app/src/main/res/layout-land/item_album_header.xml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout-land/item_artist_header.xml b/app/src/main/res/layout-land/item_artist_header.xml
index 85552589d..9faa2588e 100644
--- a/app/src/main/res/layout-land/item_artist_header.xml
+++ b/app/src/main/res/layout-land/item_artist_header.xml
@@ -84,10 +84,10 @@
style="@style/HeaderAction"
android:contentDescription="@string/description_sort_button"
android:onClick="@{() -> detailModel.incrementArtistSortMode()}"
- app:sortIcon="@{detailModel.artistSortMode}"
app:layout_constraintBottom_toBottomOf="@+id/artist_album_header"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/artist_album_header"
+ app:sortIcon="@{detailModel.artistSortMode}"
tools:src="@drawable/ic_sort_numeric_down" />
diff --git a/app/src/main/res/layout-land/item_genre_header.xml b/app/src/main/res/layout-land/item_genre_header.xml
index 4af287b0f..1ae2c3030 100644
--- a/app/src/main/res/layout-land/item_genre_header.xml
+++ b/app/src/main/res/layout-land/item_genre_header.xml
@@ -1,7 +1,7 @@
-
+
@@ -17,9 +17,7 @@
+ android:layout_height="match_parent">
diff --git a/app/src/main/res/layout/fragment_album_detail.xml b/app/src/main/res/layout/fragment_album_detail.xml
deleted file mode 100644
index 5c363e2e2..000000000
--- a/app/src/main/res/layout/fragment_album_detail.xml
+++ /dev/null
@@ -1,135 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_detail.xml b/app/src/main/res/layout/fragment_detail.xml
index b871cb253..72a020057 100644
--- a/app/src/main/res/layout/fragment_detail.xml
+++ b/app/src/main/res/layout/fragment_detail.xml
@@ -14,9 +14,9 @@
style="@style/Toolbar.Style.Icon"
android:background="?android:attr/windowBackground"
android:elevation="@dimen/elevation_normal"
- app:title="@string/label_library"
app:contentInsetStartWithNavigation="0dp"
- tools:menu="@menu/menu_artist_detail"/>
+ app:title="@string/label_library"
+ tools:menu="@menu/menu_artist_actions" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_artist_header.xml b/app/src/main/res/layout/item_artist_header.xml
index 0d9dbb0af..08a865f96 100644
--- a/app/src/main/res/layout/item_artist_header.xml
+++ b/app/src/main/res/layout/item_artist_header.xml
@@ -82,10 +82,10 @@
style="@style/HeaderAction"
android:contentDescription="@string/description_sort_button"
android:onClick="@{() -> detailModel.incrementArtistSortMode()}"
- app:sortIcon="@{detailModel.artistSortMode}"
app:layout_constraintBottom_toBottomOf="@+id/artist_album_header"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/artist_album_header"
+ app:sortIcon="@{detailModel.artistSortMode}"
tools:src="@drawable/ic_sort_numeric_down" />
diff --git a/app/src/main/res/layout/item_genre_header.xml b/app/src/main/res/layout/item_genre_header.xml
index a01681e63..1fa61f14c 100644
--- a/app/src/main/res/layout/item_genre_header.xml
+++ b/app/src/main/res/layout/item_genre_header.xml
@@ -1,7 +1,7 @@
-
+
@@ -17,9 +17,7 @@
+ android:layout_height="match_parent">
+ tools:layout="@layout/fragment_detail">