diff --git a/app/build.gradle b/app/build.gradle
index 60b5954dc..b4941e512 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -73,10 +73,9 @@ dependencies {
implementation 'androidx.media:media:1.2.0'
// Database
- def room_version = '2.2.5'
+ def room_version = '2.3.0-alpha03'
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
- implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation "androidx.room:room-ktx:$room_version"
// --- THIRD PARTY ---
diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt
index 5aaecde3a..c57bcefcd 100644
--- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt
@@ -1,22 +1,20 @@
package org.oxycblt.auxio
+import android.content.res.ColorStateList
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
+import androidx.navigation.findNavController
+import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.fragment.findNavController
-import androidx.viewpager2.adapter.FragmentStateAdapter
-import com.google.android.material.tabs.TabLayout
-import com.google.android.material.tabs.TabLayoutMediator
+import androidx.navigation.ui.setupWithNavController
import org.oxycblt.auxio.databinding.FragmentMainBinding
-import org.oxycblt.auxio.library.LibraryFragment
import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.playback.PlaybackViewModel
-import org.oxycblt.auxio.songs.SongsFragment
import org.oxycblt.auxio.ui.accent
import org.oxycblt.auxio.ui.getInactiveAlpha
import org.oxycblt.auxio.ui.getTransparentAccent
@@ -52,40 +50,24 @@ class MainFragment : Fragment() {
accent.first,
getInactiveAlpha(accent.first)
)
+ val navIconTints = ColorStateList(
+ arrayOf(
+ intArrayOf(-android.R.attr.state_checked),
+ intArrayOf(android.R.attr.state_checked)
+ ),
+ intArrayOf(colorInactive, colorActive)
+ )
// --- UI SETUP ---
- // TODO: Add nested viewpager navigation [If practical]
-
binding.lifecycleOwner = this
- binding.mainViewPager.adapter = PagerAdapter()
- // Link the ViewPager & Tab View
- TabLayoutMediator(binding.mainTabs, binding.mainViewPager) { tab, position ->
- tab.icon = ContextCompat.getDrawable(requireContext(), tabIcons[position])
-
- // Set the icon tint to deselected if its not the default tab
- if (position > 0) {
- tab.icon?.setTint(colorInactive)
- }
- }.attach()
-
- // Set up the selected/deselected colors
- binding.mainTabs.addOnTabSelectedListener(
- object : TabLayout.OnTabSelectedListener {
-
- override fun onTabSelected(tab: TabLayout.Tab) {
- tab.icon?.setTint(colorActive)
- }
-
- override fun onTabUnselected(tab: TabLayout.Tab) {
- tab.icon?.setTint(colorInactive)
- }
-
- override fun onTabReselected(tab: TabLayout.Tab?) {
- }
- }
- )
+ binding.navBar.itemIconTintList = navIconTints
+ binding.navBar.itemTextColor = navIconTints
+ ((childFragmentManager.findFragmentById(R.id.explore_nav_host) as NavHostFragment?))?.let {
+ // TODO: Add animation with BottomNavigationView navs
+ binding.navBar.setupWithNavController(it.findNavController())
+ }
// --- VIEWMODEL SETUP ---
@@ -107,35 +89,4 @@ class MainFragment : Fragment() {
return binding.root
}
-
- private fun fragmentAt(position: Int): Fragment {
- return when (position) {
- 0 -> LibraryFragment()
- 1 -> SongsFragment()
-
- else -> SongsFragment()
- }
- }
-
- private inner class PagerAdapter :
- FragmentStateAdapter(childFragmentManager, viewLifecycleOwner.lifecycle) {
- override fun getItemCount(): Int = shownFragments.size
-
- override fun createFragment(position: Int): Fragment {
- Log.d(this::class.simpleName, "Switching to fragment $position.")
-
- if (shownFragments.contains(position)) {
- return fragmentAt(position)
- }
-
- // If a fragment that shouldn't be shown is somehow shown anyway, just return
- // its intended fragment.
- Log.e(
- this::class.simpleName,
- "Attempted to index a fragment that shouldn't be shown."
- )
-
- return fragmentAt(position)
- }
- }
}
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 4e3fbba5a..42790078f 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt
@@ -6,7 +6,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.PopupMenu
-import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
@@ -20,7 +19,7 @@ import org.oxycblt.auxio.ui.applyDivider
import org.oxycblt.auxio.ui.disable
import org.oxycblt.auxio.ui.setupAlbumSongActions
-class AlbumDetailFragment : Fragment() {
+class AlbumDetailFragment : DetailFragment() {
private val args: AlbumDetailFragmentArgs by navArgs()
private val detailModel: DetailViewModel by activityViewModels()
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 4739d5846..1addcf673 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt
@@ -5,7 +5,6 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
@@ -17,7 +16,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.ui.applyDivider
import org.oxycblt.auxio.ui.disable
-class ArtistDetailFragment : Fragment() {
+class ArtistDetailFragment : DetailFragment() {
private val args: ArtistDetailFragmentArgs by navArgs()
private val detailModel: DetailViewModel by activityViewModels()
private val playbackModel: PlaybackViewModel by activityViewModels()
@@ -107,10 +106,4 @@ class ArtistDetailFragment : Fragment() {
return binding.root
}
-
- override fun onResume() {
- super.onResume()
-
- detailModel.updateNavigationStatus(false)
- }
}
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt
new file mode 100644
index 000000000..87ba8147f
--- /dev/null
+++ b/app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt
@@ -0,0 +1,44 @@
+package org.oxycblt.auxio.detail
+
+import android.os.Bundle
+import android.view.View
+import androidx.activity.OnBackPressedCallback
+import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.findNavController
+
+/**
+ * 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.
+ * @author OxygenCobalt
+ */
+abstract class DetailFragment : Fragment() {
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, callback)
+ }
+
+ override fun onResume() {
+ super.onResume()
+
+ callback.isEnabled = true
+ }
+
+ override fun onPause() {
+ super.onPause()
+ callback.isEnabled = false
+ }
+
+ private val callback = object : OnBackPressedCallback(false) {
+
+ override fun handleOnBackPressed() {
+ val navController = findNavController()
+ // Check if it's the root of nested fragments in this navhost
+ if (navController.currentDestination?.id == navController.graph.startDestination) {
+ isEnabled = false
+ requireActivity().onBackPressed()
+ isEnabled = true
+ } else {
+ navController.navigateUp()
+ }
+ }
+ }
+}
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 501bde764..a3d3c5760 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt
@@ -5,7 +5,6 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
@@ -17,7 +16,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.ui.applyDivider
import org.oxycblt.auxio.ui.disable
-class GenreDetailFragment : Fragment() {
+class GenreDetailFragment : DetailFragment() {
private val args: GenreDetailFragmentArgs by navArgs()
private val detailModel: DetailViewModel by activityViewModels()
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 bdf60282d..a1b00305b 100644
--- a/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt
@@ -203,9 +203,9 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
findNavController().navigate(
when (baseModel) {
- is Genre -> MainFragmentDirections.actionShowGenre(baseModel.id)
- is Artist -> MainFragmentDirections.actionShowArtist(baseModel.id)
- is Album -> MainFragmentDirections.actionShowAlbum(baseModel.id, true)
+ is Genre -> LibraryFragmentDirections.actionShowGenre(baseModel.id)
+ is Artist -> LibraryFragmentDirections.actionShowArtist(baseModel.id)
+ is Album -> LibraryFragmentDirections.actionShowAlbum(baseModel.id, true)
// If given model wasn't valid, then reset the navigation status
// and abort the navigation.
diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueDragCallback.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueDragCallback.kt
index 4cbb0984b..cb1838ae5 100644
--- a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueDragCallback.kt
+++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueDragCallback.kt
@@ -53,7 +53,11 @@ class QueueDragCallback(private val playbackModel: PlaybackViewModel) : ItemTouc
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
- return playbackModel.moveQueueItems(viewHolder.adapterPosition, target.adapterPosition, queueAdapter)
+ return playbackModel.moveQueueItems(
+ viewHolder.adapterPosition,
+ target.adapterPosition,
+ queueAdapter
+ )
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt
index 728ed9202..d9569f72f 100644
--- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt
+++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt
@@ -539,7 +539,10 @@ class PlaybackStateManager private constructor() {
// If the parent was somehow dropped during saving, attempt to restore it.
mSong?.let {
if (mParent == null && mMode != PlaybackMode.ALL_SONGS) {
- Log.d(this::class.simpleName, "Parent was corrupted while in mode $mMode. Attempting to restore.")
+ Log.d(
+ this::class.simpleName,
+ "Parent was corrupted while in mode $mMode. Attempting to restore."
+ )
mParent = when (mMode) {
PlaybackMode.IN_ARTIST -> it.album.artist
PlaybackMode.IN_ALBUM -> it.album
diff --git a/app/src/main/res/layout/fragment_compact_playback.xml b/app/src/main/res/layout/fragment_compact_playback.xml
index 0f7cb94ea..031ca55be 100644
--- a/app/src/main/res/layout/fragment_compact_playback.xml
+++ b/app/src/main/res/layout/fragment_compact_playback.xml
@@ -15,6 +15,8 @@
type="org.oxycblt.auxio.playback.PlaybackViewModel" />
+
+