diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt
index 1de60aba4..e58029062 100644
--- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt
@@ -18,32 +18,21 @@
package org.oxycblt.auxio
-import android.content.res.ColorStateList
import android.os.Bundle
import android.view.LayoutInflater
-import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
-import androidx.core.graphics.ColorUtils
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
-import androidx.navigation.NavController
-import androidx.navigation.NavOptions
-import androidx.navigation.fragment.NavHostFragment
-import androidx.navigation.fragment.findNavController
-import com.google.android.material.bottomnavigation.BottomNavigationView
-import org.oxycblt.auxio.accent.Accent
import org.oxycblt.auxio.databinding.FragmentMainBinding
-import org.oxycblt.auxio.detail.DetailViewModel
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackViewModel
/**
- * The primary "Home" [Fragment] for Auxio.
+ * A wrapper around the home
*/
class MainFragment : Fragment() {
private val playbackModel: PlaybackViewModel by activityViewModels()
- private val detailModel: DetailViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater,
@@ -52,51 +41,10 @@ class MainFragment : Fragment() {
): View {
val binding = FragmentMainBinding.inflate(inflater)
- val colorActive = Accent.get().color.resolveColor(requireContext())
- val colorInactive = ColorUtils.setAlphaComponent(colorActive, 150)
-
- // Set up the tints for the navigation icons + text
- val navTints = ColorStateList(
- arrayOf(
- intArrayOf(-android.R.attr.state_checked),
- intArrayOf(android.R.attr.state_checked)
- ),
- intArrayOf(colorInactive, colorActive)
- )
-
- val navController = (
- childFragmentManager.findFragmentById(R.id.explore_nav_host)
- as NavHostFragment?
- )?.findNavController()
-
// --- UI SETUP ---
binding.lifecycleOwner = viewLifecycleOwner
- // Speed up the slide-in effect on the controls view, solely to improve the UX
- // and maybe hide the problem where the main view will snap-shrink before the compact
- // view can slide.
- (binding.controlsContainer as ViewGroup).layoutTransition.setDuration(150)
-
- binding.navBar.apply {
- itemIconTintList = navTints
- itemTextColor = navTints
-
- if (requireContext().isTablet() && !requireContext().isLandscape()) {
- labelVisibilityMode = BottomNavigationView.LABEL_VISIBILITY_LABELED
- }
-
- navController?.let { controller ->
- binding.navBar.setOnItemSelectedListener { item ->
- navigateWithItem(controller, item)
- }
- }
-
- // BottomNavigationView is a special little snowflake and doesn't like it when
- // we set the background in XML
- setBackgroundColor(R.attr.colorSurface.resolveAttr(requireContext()))
- }
-
// --- VIEWMODEL SETUP ---
// Change CompactPlaybackFragment's visibility here so that an animation occurs.
@@ -106,49 +54,11 @@ class MainFragment : Fragment() {
handleCompactPlaybackVisibility(binding, song)
}
- detailModel.navToItem.observe(viewLifecycleOwner) { item ->
- if (item != null && navController != null) {
- val curDest = navController.currentDestination?.id
-
- // SongsFragment and SettingsFragment have no navigation pathways, so correct
- // them to the library tab instead.
- if (curDest == R.id.songs_fragment || curDest == R.id.settings_fragment) {
- binding.navBar.selectedItemId = R.id.library_fragment
- }
- }
- }
-
- playbackModel.setupPlayback(requireContext())
-
logD("Fragment Created.")
return binding.root
}
- /**
- * Custom navigator code that has proper animations, unlike BottomNavigationView.setupWithNavController().
- */
- private fun navigateWithItem(navController: NavController, item: MenuItem): Boolean {
- if (navController.currentDestination!!.id != item.itemId) {
- val options = NavOptions.Builder()
- .setLaunchSingleTop(true)
- .setEnterAnim(R.animator.nav_default_enter_anim)
- .setExitAnim(R.animator.nav_default_exit_anim)
- .setPopEnterAnim(R.animator.nav_default_pop_enter_anim)
- .setPopExitAnim(R.animator.nav_default_pop_exit_anim)
- .build()
-
- return try {
- navController.navigate(item.itemId, null, options)
- true
- } catch (e: IllegalArgumentException) {
- false
- }
- }
-
- return false
- }
-
/**
* Handle the visibility of CompactPlaybackFragment. Done here so that there's a nice animation.
*/
@@ -156,13 +66,13 @@ class MainFragment : Fragment() {
if (song == null) {
logD("Hiding CompactPlaybackFragment since no song is being played.")
- binding.compactPlayback.visibility = if (requireContext().isLandscape()) {
+ binding.mainPlayback.visibility = if (requireContext().isLandscape()) {
View.INVISIBLE
} else {
View.GONE
}
} else {
- binding.compactPlayback.visibility = View.VISIBLE
+ binding.mainPlayback.visibility = View.VISIBLE
}
}
}
diff --git a/app/src/main/java/org/oxycblt/auxio/library/LibraryAdapter.kt b/app/src/main/java/org/oxycblt/auxio/home/HomeAdapter.kt
similarity index 78%
rename from app/src/main/java/org/oxycblt/auxio/library/LibraryAdapter.kt
rename to app/src/main/java/org/oxycblt/auxio/home/HomeAdapter.kt
index 669c92eb2..a5418f5d8 100644
--- a/app/src/main/java/org/oxycblt/auxio/library/LibraryAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/home/HomeAdapter.kt
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2021 Auxio Project
- * LibraryAdapter.kt is part of Auxio.
+ * HomeAdapter.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.library
+package org.oxycblt.auxio.home
import android.annotation.SuppressLint
import android.view.View
@@ -24,22 +24,25 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
+import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Parent
+import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.recycler.viewholders.AlbumViewHolder
import org.oxycblt.auxio.recycler.viewholders.ArtistViewHolder
import org.oxycblt.auxio.recycler.viewholders.GenreViewHolder
+import org.oxycblt.auxio.recycler.viewholders.SongViewHolder
/**
* An adapter for displaying library items. Supports [Parent]s only.
* @author OxygenCobalt
*/
-class LibraryAdapter(
- private val doOnClick: (data: Parent) -> Unit,
- private val doOnLongClick: (view: View, data: Parent) -> Unit
+class HomeAdapter(
+ private val doOnClick: (data: BaseModel) -> Unit,
+ private val doOnLongClick: (view: View, data: BaseModel) -> Unit
) : RecyclerView.Adapter() {
- private var data = listOf()
+ private var data = listOf()
override fun getItemCount(): Int = data.size
@@ -48,6 +51,8 @@ class LibraryAdapter(
is Genre -> GenreViewHolder.ITEM_TYPE
is Artist -> ArtistViewHolder.ITEM_TYPE
is Album -> AlbumViewHolder.ITEM_TYPE
+ is Song -> SongViewHolder.ITEM_TYPE
+ else -> error("Unsupported item ${data[position]::class.simpleName}")
}
}
@@ -65,6 +70,10 @@ class LibraryAdapter(
parent.context, doOnClick, doOnLongClick
)
+ SongViewHolder.ITEM_TYPE -> SongViewHolder.from(
+ parent.context, doOnClick, doOnLongClick
+ )
+
else -> error("Invalid viewholder item type.")
}
}
@@ -74,6 +83,7 @@ class LibraryAdapter(
is Genre -> (holder as GenreViewHolder).bind(item)
is Artist -> (holder as ArtistViewHolder).bind(item)
is Album -> (holder as AlbumViewHolder).bind(item)
+ is Song -> (holder as SongViewHolder).bind(item)
}
}
@@ -81,7 +91,7 @@ class LibraryAdapter(
* Update the data with [newData]. [notifyDataSetChanged] will be called.
*/
@SuppressLint("NotifyDataSetChanged")
- fun updateData(newData: List) {
+ fun updateData(newData: List) {
data = newData
notifyDataSetChanged()
diff --git a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt
new file mode 100644
index 000000000..f75b0a6fa
--- /dev/null
+++ b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2021 Auxio Project
+ * MainFragment.kt is part of Auxio.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package org.oxycblt.auxio.home
+
+import android.os.Bundle
+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.viewpager2.adapter.FragmentStateAdapter
+import com.google.android.material.tabs.TabLayoutMediator
+import org.oxycblt.auxio.MainFragmentDirections
+import org.oxycblt.auxio.R
+import org.oxycblt.auxio.databinding.FragmentHomeBinding
+import org.oxycblt.auxio.home.pager.AlbumListFragment
+import org.oxycblt.auxio.home.pager.ArtistListFragment
+import org.oxycblt.auxio.home.pager.GenreListFragment
+import org.oxycblt.auxio.home.pager.SongListFragment
+import org.oxycblt.auxio.logD
+import org.oxycblt.auxio.playback.PlaybackViewModel
+
+/**
+ * The main "Launching Point" fragment of Auxio, allowing navigation to the detail
+ * views for each respective fragment.
+ * TODO: Re-add sorting (but new and improved)
+ * @author OxygenCobalt
+ */
+class HomeFragment : Fragment() {
+ private val playbackModel: PlaybackViewModel by activityViewModels()
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ val binding = FragmentHomeBinding.inflate(inflater)
+
+ // --- UI SETUP ---
+
+ binding.lifecycleOwner = viewLifecycleOwner
+
+ binding.homeToolbar.setOnMenuItemClickListener { item ->
+ when (item.itemId) {
+ R.id.action_settings -> {
+ parentFragment?.parentFragment?.findNavController()?.navigate(
+ MainFragmentDirections.actionShowSettings()
+ )
+ }
+
+ R.id.action_search -> {
+ findNavController().navigate(HomeFragmentDirections.actionShowSearch())
+ }
+ }
+
+ true
+ }
+
+ binding.homePager.adapter = HomePagerAdapter()
+
+ TabLayoutMediator(binding.homeTabs, binding.homePager) { tab, pos ->
+ val labelRes = when (pos) {
+ 0 -> R.string.lbl_songs
+ 1 -> R.string.lbl_albums
+ 2 -> R.string.lbl_artists
+ 3 -> R.string.lbl_genres
+ else -> error("Unreachable")
+ }
+
+ tab.setText(labelRes)
+ }.attach()
+
+ // --- VIEWMODEL SETUP ---
+
+ playbackModel.setupPlayback(requireContext())
+
+ logD("Fragment Created.")
+
+ return binding.root
+ }
+
+ private inner class HomePagerAdapter :
+ FragmentStateAdapter(childFragmentManager, viewLifecycleOwner.lifecycle) {
+ override fun createFragment(position: Int): Fragment {
+ return when (position) {
+ 0 -> SongListFragment()
+ 1 -> AlbumListFragment()
+ 2 -> ArtistListFragment()
+ 3 -> GenreListFragment()
+ else -> error("Unreachable")
+ }
+ }
+
+ override fun getItemCount(): Int = 4
+ }
+}
diff --git a/app/src/main/java/org/oxycblt/auxio/home/pager/AlbumListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/pager/AlbumListFragment.kt
new file mode 100644
index 000000000..09afe9d22
--- /dev/null
+++ b/app/src/main/java/org/oxycblt/auxio/home/pager/AlbumListFragment.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021 Auxio Project
+ * GenreListFragment.kt is part of Auxio.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package org.oxycblt.auxio.home.pager
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
+import org.oxycblt.auxio.databinding.FragmentHomeListBinding
+import org.oxycblt.auxio.home.HomeAdapter
+import org.oxycblt.auxio.home.HomeFragmentDirections
+import org.oxycblt.auxio.music.MusicStore
+import org.oxycblt.auxio.playback.PlaybackViewModel
+import org.oxycblt.auxio.ui.newMenu
+
+class AlbumListFragment : Fragment() {
+ private val playbackModel: PlaybackViewModel by viewModels()
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ val binding = FragmentHomeListBinding.inflate(inflater)
+
+ val adapter = HomeAdapter(
+ doOnClick = { item ->
+ HomeFragmentDirections.actionShowAlbum(item.id)
+ },
+ ::newMenu
+ )
+
+ adapter.updateData(MusicStore.getInstance().albums)
+
+ // --- UI SETUP ---
+
+ binding.homeRecycler.adapter = adapter
+
+ return binding.root
+ }
+}
diff --git a/app/src/main/java/org/oxycblt/auxio/home/pager/ArtistListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/pager/ArtistListFragment.kt
new file mode 100644
index 000000000..2c1a656bd
--- /dev/null
+++ b/app/src/main/java/org/oxycblt/auxio/home/pager/ArtistListFragment.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021 Auxio Project
+ * GenreListFragment.kt is part of Auxio.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package org.oxycblt.auxio.home.pager
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
+import org.oxycblt.auxio.databinding.FragmentHomeListBinding
+import org.oxycblt.auxio.home.HomeAdapter
+import org.oxycblt.auxio.home.HomeFragmentDirections
+import org.oxycblt.auxio.music.MusicStore
+import org.oxycblt.auxio.playback.PlaybackViewModel
+import org.oxycblt.auxio.ui.newMenu
+
+class ArtistListFragment : Fragment() {
+ private val playbackModel: PlaybackViewModel by viewModels()
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ val binding = FragmentHomeListBinding.inflate(inflater)
+
+ val adapter = HomeAdapter(
+ doOnClick = { item ->
+ HomeFragmentDirections.actionShowArtist(item.id)
+ },
+ ::newMenu
+ )
+
+ adapter.updateData(MusicStore.getInstance().artists)
+
+ // --- UI SETUP ---
+
+ binding.homeRecycler.adapter = adapter
+
+ return binding.root
+ }
+}
diff --git a/app/src/main/java/org/oxycblt/auxio/home/pager/GenreListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/pager/GenreListFragment.kt
new file mode 100644
index 000000000..9331f0e99
--- /dev/null
+++ b/app/src/main/java/org/oxycblt/auxio/home/pager/GenreListFragment.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021 Auxio Project
+ * GenreListFragment.kt is part of Auxio.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package org.oxycblt.auxio.home.pager
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
+import org.oxycblt.auxio.databinding.FragmentHomeListBinding
+import org.oxycblt.auxio.home.HomeAdapter
+import org.oxycblt.auxio.home.HomeFragmentDirections
+import org.oxycblt.auxio.music.MusicStore
+import org.oxycblt.auxio.playback.PlaybackViewModel
+import org.oxycblt.auxio.ui.newMenu
+
+class GenreListFragment : Fragment() {
+ private val playbackModel: PlaybackViewModel by viewModels()
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ val binding = FragmentHomeListBinding.inflate(inflater)
+
+ val adapter = HomeAdapter(
+ doOnClick = { item ->
+ HomeFragmentDirections.actionShowGenre(item.id)
+ },
+ ::newMenu
+ )
+
+ adapter.updateData(MusicStore.getInstance().genres)
+
+ // --- UI SETUP ---
+
+ binding.homeRecycler.adapter = adapter
+
+ return binding.root
+ }
+}
diff --git a/app/src/main/java/org/oxycblt/auxio/home/pager/SongListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/pager/SongListFragment.kt
new file mode 100644
index 000000000..69f53bf74
--- /dev/null
+++ b/app/src/main/java/org/oxycblt/auxio/home/pager/SongListFragment.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021 Auxio Project
+ * GenreListFragment.kt is part of Auxio.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package org.oxycblt.auxio.home.pager
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
+import org.oxycblt.auxio.databinding.FragmentHomeListBinding
+import org.oxycblt.auxio.home.HomeAdapter
+import org.oxycblt.auxio.music.MusicStore
+import org.oxycblt.auxio.music.Song
+import org.oxycblt.auxio.playback.PlaybackViewModel
+import org.oxycblt.auxio.ui.newMenu
+
+class SongListFragment : Fragment() {
+ private val playbackModel: PlaybackViewModel by viewModels()
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ val binding = FragmentHomeListBinding.inflate(inflater)
+
+ val adapter = HomeAdapter(
+ doOnClick = { item ->
+ playbackModel.playSong(item as Song)
+ },
+ ::newMenu
+ )
+
+ adapter.updateData(MusicStore.getInstance().songs)
+
+ // --- UI SETUP ---
+
+ binding.homeRecycler.adapter = adapter
+
+ return binding.root
+ }
+}
diff --git a/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt b/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt
deleted file mode 100644
index 0c2f4774d..000000000
--- a/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2021 Auxio Project
- * LibraryFragment.kt is part of Auxio.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.oxycblt.auxio.library
-
-import android.os.Bundle
-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.recyclerview.widget.GridLayoutManager
-import org.oxycblt.auxio.R
-import org.oxycblt.auxio.databinding.FragmentLibraryBinding
-import org.oxycblt.auxio.detail.DetailViewModel
-import org.oxycblt.auxio.logD
-import org.oxycblt.auxio.music.Album
-import org.oxycblt.auxio.music.Artist
-import org.oxycblt.auxio.music.Genre
-import org.oxycblt.auxio.music.Parent
-import org.oxycblt.auxio.music.Song
-import org.oxycblt.auxio.recycler.sliceArticle
-import org.oxycblt.auxio.spans
-import org.oxycblt.auxio.ui.newMenu
-
-/**
- * A [Fragment] that shows a custom list of [Genre], [Artist], or [Album] data. Also allows for
- * search functionality.
- * @author OxygenCobalt
- */
-class LibraryFragment : Fragment() {
- private val libraryModel: LibraryViewModel by activityViewModels()
- private val detailModel: DetailViewModel by activityViewModels()
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
- val binding = FragmentLibraryBinding.inflate(inflater)
- val libraryAdapter = LibraryAdapter(::navToDetail, ::newMenu)
-
- // --- UI SETUP ---
-
- binding.lifecycleOwner = viewLifecycleOwner
-
- binding.libraryToolbar.apply {
- menu.findItem(libraryModel.sortMode.toMenuId()).isChecked = true
-
- setOnMenuItemClickListener { item ->
- if (item.itemId != R.id.submenu_sorting) {
- libraryModel.updateSortMode(item.itemId)
- item.isChecked = true
- true
- } else {
- false
- }
- }
- }
-
- binding.libraryRecycler.apply {
- adapter = libraryAdapter
- setHasFixedSize(true)
-
- if (spans != 1) {
- layoutManager = GridLayoutManager(requireContext(), spans)
- }
- }
-
- binding.libraryFastScroll.setup(binding.libraryRecycler) { pos ->
- val item = libraryModel.libraryData.value!![pos]
- val char = item.displayName.sliceArticle().first().uppercaseChar()
-
- if (char.isDigit()) '#' else char
- }
-
- // --- VIEWMODEL SETUP ---
-
- libraryModel.libraryData.observe(viewLifecycleOwner) { data ->
- libraryAdapter.updateData(data)
- }
-
- detailModel.navToItem.observe(viewLifecycleOwner) { item ->
- if (item != null) {
- libraryModel.setNavigating(false)
-
- if (item is Parent) {
- navToDetail(item)
- } else if (item is Song) {
- navToDetail(item.album)
- }
- }
- }
-
- logD("Fragment created.")
-
- return binding.root
- }
-
- override fun onResume() {
- super.onResume()
-
- libraryModel.setNavigating(false)
- }
-
- /**
- * Navigate to the detail UI for a [parent].
- */
- private fun navToDetail(parent: Parent) {
- requireView().rootView.clearFocus()
-
- if (!libraryModel.isNavigating) {
- libraryModel.setNavigating(true)
-
- logD("Navigating to the detail fragment for ${parent.name}")
-
- findNavController().navigate(
- when (parent) {
- is Genre -> LibraryFragmentDirections.actionShowGenre(parent.id)
- is Artist -> LibraryFragmentDirections.actionShowArtist(parent.id)
- is Album -> LibraryFragmentDirections.actionShowAlbum(parent.id)
- }
- )
- }
- }
-}
diff --git a/app/src/main/java/org/oxycblt/auxio/library/LibraryViewModel.kt b/app/src/main/java/org/oxycblt/auxio/library/LibraryViewModel.kt
deleted file mode 100644
index 0eeef5608..000000000
--- a/app/src/main/java/org/oxycblt/auxio/library/LibraryViewModel.kt
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2021 Auxio Project
- * LibraryViewModel.kt is part of Auxio.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.oxycblt.auxio.library
-
-import androidx.annotation.IdRes
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.ViewModel
-import org.oxycblt.auxio.R
-import org.oxycblt.auxio.music.MusicStore
-import org.oxycblt.auxio.music.Parent
-import org.oxycblt.auxio.recycler.DisplayMode
-import org.oxycblt.auxio.recycler.SortMode
-import org.oxycblt.auxio.settings.SettingsManager
-
-/**
- * A [ViewModel] that manages what [LibraryFragment] is currently showing, and also the search
- * functionality.
- * @author OxygenCobalt
- */
-class LibraryViewModel : ViewModel(), SettingsManager.Callback {
- private val mLibraryData = MutableLiveData(listOf())
- val libraryData: LiveData> get() = mLibraryData
-
- private var mSortMode = SortMode.ALPHA_DOWN
- val sortMode: SortMode get() = mSortMode
-
- private var mDisplayMode = DisplayMode.SHOW_ARTISTS
-
- private var mIsNavigating = false
- val isNavigating: Boolean get() = mIsNavigating
-
- private val settingsManager = SettingsManager.getInstance()
- private val musicStore = MusicStore.getInstance()
-
- init {
- settingsManager.addCallback(this)
-
- // Set up the display/sort modes
- mDisplayMode = settingsManager.libraryDisplayMode
- mSortMode = settingsManager.librarySortMode
-
- // Handle "NONE" SortMode that was removed in 1.4.1
- if (mSortMode == SortMode.NONE) {
- mSortMode = SortMode.ALPHA_DOWN
- }
-
- updateLibraryData()
- }
-
- /**
- * Update the current [SortMode] using an menu [itemId].
- */
- fun updateSortMode(@IdRes itemId: Int) {
- val mode = when (itemId) {
- R.id.option_sort_alpha_down -> SortMode.ALPHA_DOWN
- R.id.option_sort_alpha_up -> SortMode.ALPHA_UP
-
- else -> SortMode.NONE
- }
-
- if (mode != mSortMode) {
- mSortMode = mode
- settingsManager.librarySortMode = mode
-
- updateLibraryData()
- }
- }
-
- /**
- * Update the current navigation status
- */
- fun setNavigating(isNavigating: Boolean) {
- mIsNavigating = isNavigating
- }
-
- /**
- * Shortcut function for updating the library data with the current [SortMode]/[DisplayMode]
- */
- private fun updateLibraryData() {
- mLibraryData.value = when (mDisplayMode) {
- DisplayMode.SHOW_GENRES -> mSortMode.getSortedGenreList(musicStore.genres)
-
- DisplayMode.SHOW_ARTISTS -> mSortMode.getSortedArtistList(musicStore.artists)
-
- DisplayMode.SHOW_ALBUMS -> mSortMode.getSortedAlbumList(musicStore.albums)
-
- else -> error("DisplayMode $mDisplayMode is unsupported.")
- }
- }
-
- // --- OVERRIDES ---
-
- override fun onCleared() {
- super.onCleared()
-
- settingsManager.removeCallback(this)
- }
-
- override fun onLibDisplayModeUpdate(displayMode: DisplayMode) {
- mDisplayMode = displayMode
-
- updateLibraryData()
- }
-}
diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/FastScrollView.kt b/app/src/main/java/org/oxycblt/auxio/recycler/FastScrollView.kt
deleted file mode 100644
index e80750fca..000000000
--- a/app/src/main/java/org/oxycblt/auxio/recycler/FastScrollView.kt
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (c) 2021 Auxio Project
- * FastScrollView.kt is part of Auxio.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.oxycblt.auxio.recycler
-
-import android.content.Context
-import android.os.Build
-import android.util.AttributeSet
-import android.util.TypedValue
-import android.view.HapticFeedbackConstants
-import android.view.MotionEvent
-import android.view.View
-import androidx.constraintlayout.widget.ConstraintLayout
-import androidx.core.view.isVisible
-import androidx.core.view.postDelayed
-import androidx.dynamicanimation.animation.DynamicAnimation
-import androidx.dynamicanimation.animation.SpringAnimation
-import androidx.dynamicanimation.animation.SpringForce
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import org.oxycblt.auxio.accent.Accent
-import org.oxycblt.auxio.canScroll
-import org.oxycblt.auxio.databinding.ViewFastScrollBinding
-import org.oxycblt.auxio.inflater
-import org.oxycblt.auxio.logD
-import org.oxycblt.auxio.resolveAttr
-import org.oxycblt.auxio.resolveColor
-import kotlin.math.ceil
-import kotlin.math.min
-import kotlin.math.roundToInt
-
-/**
- * A view that allows for quick scrolling through a [RecyclerView] with many items. Unlike other
- * fast-scrollers, this one displays indicators and a thumb instead of simply a scroll bar.
- * This code is fundamentally an adaptation of Reddit's IndicatorFastScroll, albeit specialized
- * towards Auxio. The original library is here: https://github.com/reddit/IndicatorFastScroll/
- * TODO: Replace this with something similar to AndroidFastScroll [but optimized for Auxio],
- * since this thumb view is a blocker to a better sort system.
- * @author OxygenCobalt
- */
-class FastScrollView @JvmOverloads constructor(
- context: Context,
- attrs: AttributeSet? = null,
- defStyleAttr: Int = -1
-) : ConstraintLayout(context, attrs, defStyleAttr) {
-
- // --- UI ---
-
- private val binding = ViewFastScrollBinding.inflate(context.inflater, this, true)
- private val thumbAnim: SpringAnimation
-
- // --- RECYCLER ---
-
- private var mRecycler: RecyclerView? = null
- private var mGetItem: ((Int) -> Char)? = null
- private val mObserver = object : RecyclerView.AdapterDataObserver() {
- override fun onChanged() = postIndicatorUpdate()
-
- override fun onItemRangeChanged(
- positionStart: Int,
- itemCount: Int,
- payload: Any?
- ) = postIndicatorUpdate()
-
- override fun onItemRangeInserted(
- positionStart: Int,
- itemCount: Int
- ) = onChanged()
-
- override fun onItemRangeMoved(
- fromPosition: Int,
- toPosition: Int,
- itemCount: Int
- ) = onChanged()
-
- override fun onItemRangeRemoved(
- positionStart: Int,
- itemCount: Int
- ) = onChanged()
- }
-
- // --- INDICATORS ---
-
- private data class Indicator(val char: Char, val pos: Int)
-
- private var indicators = listOf()
- private val activeColor = Accent.get().color.resolveColor(context)
- private val inactiveColor = android.R.attr.textColorSecondary.resolveAttr(context)
-
- // --- STATE ---
-
- private var hasPostedItemUpdate = false
- private var wasValidTouch = false
- private var lastPos = -1
-
- init {
- isFocusableInTouchMode = true
- isClickable = true
-
- thumbAnim = SpringAnimation(binding.scrollThumb, DynamicAnimation.TRANSLATION_Y).apply {
- spring = SpringForce().also {
- it.dampingRatio = SpringForce.DAMPING_RATIO_NO_BOUNCY
- }
- }
-
- // Prevent the disappear animation from being displayed on startup by making the thumb
- // invisible, it will be made visible once the animation ends
- binding.scrollThumb.visibility = View.INVISIBLE
-
- postDelayed(200) {
- binding.scrollThumb.visibility = View.VISIBLE
- }
- }
-
- /**
- * Set up this view with a [RecyclerView]. [getItem] is called when the first character
- * of a piece of data is needed.
- */
- fun setup(recycler: RecyclerView, getItem: (Int) -> Char) {
- check(mRecycler == null) { "Only set up this view once." }
-
- mRecycler = recycler
- mGetItem = getItem
-
- recycler.adapter?.registerAdapterDataObserver(mObserver)
-
- postIndicatorUpdate()
- }
-
- // --- INDICATOR UPDATES ---
-
- private fun postIndicatorUpdate() {
- if (!hasPostedItemUpdate) {
- hasPostedItemUpdate = true
-
- post {
- val recycler = requireNotNull(mRecycler)
-
- if (recycler.isAttachedToWindow && recycler.adapter != null) {
- updateIndicators()
- binding.scrollIndicatorText.requestLayout()
- }
-
- // Hide this view if there is nothing to scroll
- isVisible = recycler.canScroll()
-
- hasPostedItemUpdate = false
- }
- }
- }
-
- private fun updateIndicators() {
- val recycler = requireNotNull(mRecycler)
- val getItem = requireNotNull(mGetItem)
-
- indicators = 0.until(recycler.adapter!!.itemCount).mapNotNull { pos ->
- Indicator(getItem(pos), pos)
- }.distinctBy { it.char }
-
- val textHeight = TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_SP, 14F, resources.displayMetrics
- )
-
- // If the scroller size is too small to contain all the entries, truncate entries
- // so that the fast scroller entries fit. Include the thumb in here so it isn't cut
- // off.
- val maxEntries = (height - (binding.scrollThumb.height * 2)) / textHeight
-
- if (indicators.size > maxEntries) {
- val truncateInterval = ceil(indicators.size / maxEntries).toInt()
-
- check(truncateInterval > 1) {
- "Needed to truncate, but truncateInterval was 1 or lower anyway"
- }
-
- logD("More entries than screen space, truncating by $truncateInterval.")
-
- indicators = indicators.filterIndexed { index, _ ->
- index % truncateInterval == 0
- }
- }
-
- // Then set it as the unified TextView text, for efficiency purposes.
- binding.scrollIndicatorText.text = indicators.joinToString("\n") { indicator ->
- indicator.char.toString()
- }
- }
-
- // --- TOUCH ---
-
- @Suppress("ClickableViewAccessibility")
- override fun onTouchEvent(event: MotionEvent): Boolean {
- super.onTouchEvent(event)
- performClick()
-
- val success = handleTouch(event.action, event.x.roundToInt(), event.y.roundToInt())
-
- // Depending on the results, update the visibility of the thumb and the pressed state of
- // this view.
- binding.scrollThumb.isActivated = success
- binding.scrollIndicatorText.isPressed = success
-
- return success
- }
-
- private fun handleTouch(action: Int, touchX: Int, touchY: Int): Boolean {
- when (action) {
- MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
- binding.scrollIndicatorText.setTextColor(inactiveColor)
- wasValidTouch = false
- lastPos = -1
-
- return false
- }
-
- // Since this view is unified between the thumb and the indicators, we have
- // to check if the initial pointer position was in the indicators to prevent the
- // scroll from being triggered outside its bounds.
- MotionEvent.ACTION_DOWN -> {
- wasValidTouch = binding.scrollIndicatorText.contains(touchX, touchY)
- }
- }
-
- // Try to figure out which indicator the pointer has landed on
- if (binding.scrollIndicatorText.containsY(touchY) && wasValidTouch) {
- // Get the touch position in regards to the TextView and the rough text height
- val indicatorTouchY = touchY - binding.scrollIndicatorText.top
- val textHeight = binding.scrollIndicatorText.height / indicators.size
-
- // Use that to calculate the indicator index, if the calculation is
- // invalid just ignore it.
- val index = min(indicatorTouchY / textHeight, indicators.lastIndex)
-
- // Also calculate the rough center position of the indicator for the scroll thumb
- val centerY = binding.scrollIndicatorText.y + (textHeight / 2) + (index * textHeight)
-
- selectIndicator(indicators[index], centerY)
-
- return true
- }
-
- return false
- }
-
- private fun selectIndicator(indicator: Indicator, centerY: Float) {
- if (indicator.pos != lastPos) {
- lastPos = indicator.pos
- binding.scrollIndicatorText.setTextColor(activeColor)
-
- // Stop any scroll momentum and snap-scroll to the position
- mRecycler?.apply {
- stopScroll()
- (layoutManager as LinearLayoutManager).scrollToPositionWithOffset(indicator.pos, 0)
- }
-
- // Update the thumb position/text
- binding.scrollThumbText.text = indicator.char.toString()
- thumbAnim.animateToFinalPosition(centerY - (binding.scrollThumb.measuredHeight / 2))
-
- performHapticFeedback(
- if (Build.VERSION.SDK_INT >= 27) {
- // Dragging across a scroller is closer to moving a text handle
- HapticFeedbackConstants.TEXT_HANDLE_MOVE
- } else {
- HapticFeedbackConstants.KEYBOARD_TAP
- }
- )
- }
- }
-
- private fun View.contains(x: Int, y: Int): Boolean {
- return x in (left until right) && containsY(y)
- }
-
- private fun View.containsY(y: Int): Boolean {
- return y in (top until bottom)
- }
-}
diff --git a/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt b/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt
index cc80aade9..42a66db42 100644
--- a/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt
@@ -72,6 +72,10 @@ class SearchFragment : Fragment() {
binding.searchToolbar.apply {
menu.findItem(searchModel.filterMode.toId()).isChecked = true
+ setNavigationOnClickListener {
+ findNavController().navigateUp()
+ }
+
setOnMenuItemClickListener { item ->
if (item.itemId != R.id.submenu_filtering) {
searchModel.updateFilterModeWithId(item.itemId, requireContext())
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsFragment.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsFragment.kt
index 24b393445..10be0109d 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsFragment.kt
@@ -24,7 +24,6 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
-import org.oxycblt.auxio.MainFragmentDirections
import org.oxycblt.auxio.databinding.FragmentSettingsBinding
/**
@@ -39,12 +38,18 @@ class SettingsFragment : Fragment() {
): View {
val binding = FragmentSettingsBinding.inflate(inflater)
- binding.settingsToolbar.setOnMenuItemClickListener {
- parentFragment?.parentFragment?.findNavController()?.navigate(
- MainFragmentDirections.actionShowAbout()
- )
+ binding.settingsToolbar.apply {
+ setOnMenuItemClickListener {
+ findNavController().navigate(
+ SettingsFragmentDirections.actionShowAbout()
+ )
- true
+ true
+ }
+
+ setNavigationOnClickListener {
+ findNavController().navigateUp()
+ }
}
return binding.root
diff --git a/app/src/main/java/org/oxycblt/auxio/songs/SongsAdapter.kt b/app/src/main/java/org/oxycblt/auxio/songs/SongsAdapter.kt
deleted file mode 100644
index 79df6bb79..000000000
--- a/app/src/main/java/org/oxycblt/auxio/songs/SongsAdapter.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2021 Auxio Project
- * SongsAdapter.kt is part of Auxio.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.oxycblt.auxio.songs
-
-import android.view.View
-import android.view.ViewGroup
-import androidx.recyclerview.widget.RecyclerView
-import org.oxycblt.auxio.music.Song
-import org.oxycblt.auxio.recycler.viewholders.SongViewHolder
-
-/**
- * The adapter for [SongsFragment], shows basic songs without durations.
- * @param data List of [Song]s to be shown
- * @param doOnClick What to do on a click action
- * @param doOnLongClick What to do on a long click action
- * @author OxygenCobalt
- */
-class SongsAdapter(
- private val data: List,
- private val doOnClick: (data: Song) -> Unit,
- private val doOnLongClick: (view: View, data: Song) -> Unit
-) : RecyclerView.Adapter() {
-
- override fun getItemCount(): Int = data.size
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongViewHolder {
- return SongViewHolder.from(parent.context, doOnClick, doOnLongClick)
- }
-
- override fun onBindViewHolder(holder: SongViewHolder, position: Int) {
- holder.bind(data[position])
- }
-}
diff --git a/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt b/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt
deleted file mode 100644
index a9c53f4fc..000000000
--- a/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2021 Auxio Project
- * SongsFragment.kt is part of Auxio.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.oxycblt.auxio.songs
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.activityViewModels
-import androidx.recyclerview.widget.GridLayoutManager
-import org.oxycblt.auxio.R
-import org.oxycblt.auxio.databinding.FragmentSongsBinding
-import org.oxycblt.auxio.logD
-import org.oxycblt.auxio.music.MusicStore
-import org.oxycblt.auxio.playback.PlaybackViewModel
-import org.oxycblt.auxio.recycler.sliceArticle
-import org.oxycblt.auxio.spans
-import org.oxycblt.auxio.ui.newMenu
-
-/**
- * A [Fragment] that shows a list of all songs on the device.
- * Contains options to search/shuffle them.
- * @author OxygenCobalt
- */
-class SongsFragment : Fragment() {
- private val playbackModel: PlaybackViewModel by activityViewModels()
- private val musicStore = MusicStore.getInstance()
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
- val binding = FragmentSongsBinding.inflate(inflater)
- val songAdapter = SongsAdapter(musicStore.songs, playbackModel::playSong, ::newMenu)
-
- // --- UI SETUP ---
-
- binding.songToolbar.apply {
- setOnMenuItemClickListener {
- if (it.itemId == R.id.action_shuffle) {
- playbackModel.shuffleAll()
- true
- } else false
- }
- }
-
- binding.songRecycler.apply {
- adapter = songAdapter
- setHasFixedSize(true)
-
- if (spans != 1) {
- layoutManager = GridLayoutManager(requireContext(), spans)
- }
- }
-
- binding.songFastScroll.setup(binding.songRecycler) { pos ->
- // Get the first character [respecting articles]
- val char = musicStore.songs[pos].name.sliceArticle().first().uppercaseChar()
-
- if (char.isDigit()) '#' else char
- }
-
- logD("Fragment created.")
-
- return binding.root
- }
-}
diff --git a/app/src/main/res/drawable/ui_circle.xml b/app/src/main/res/drawable/ui_circle.xml
deleted file mode 100644
index a6f3dfaa6..000000000
--- a/app/src/main/res/drawable/ui_circle.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout-land/fragment_main.xml b/app/src/main/res/layout-land/fragment_main.xml
deleted file mode 100644
index 355ddc8a4..000000000
--- a/app/src/main/res/layout-land/fragment_main.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_about.xml b/app/src/main/res/layout/fragment_about.xml
index 737a4ef15..6ac2acd18 100644
--- a/app/src/main/res/layout/fragment_about.xml
+++ b/app/src/main/res/layout/fragment_about.xml
@@ -36,8 +36,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_home_list.xml b/app/src/main/res/layout/fragment_home_list.xml
new file mode 100644
index 000000000..13c5f46f4
--- /dev/null
+++ b/app/src/main/res/layout/fragment_home_list.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ 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
deleted file mode 100644
index 3f8c0286c..000000000
--- a/app/src/main/res/layout/fragment_library.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml
index 9028f7458..ccee4c219 100644
--- a/app/src/main/res/layout/fragment_main.xml
+++ b/app/src/main/res/layout/fragment_main.xml
@@ -19,35 +19,15 @@
android:layout_height="0dp"
android:layout_weight="1"
app:navGraph="@navigation/nav_explore"
- tools:layout="@layout/fragment_library" />
+ tools:layout="@layout/fragment_home" />
-
-
-
-
-
-
-
+ android:background="?attr/colorSurface"
+ tools:layout="@layout/fragment_compact_playback" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml
index 52b71925c..583068ad3 100644
--- a/app/src/main/res/layout/fragment_search.xml
+++ b/app/src/main/res/layout/fragment_search.xml
@@ -16,7 +16,7 @@
diff --git a/app/src/main/res/layout/fragment_songs.xml b/app/src/main/res/layout/fragment_songs.xml
deleted file mode 100644
index 4605fe19f..000000000
--- a/app/src/main/res/layout/fragment_songs.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/view_fast_scroll.xml b/app/src/main/res/layout/view_fast_scroll.xml
deleted file mode 100644
index 39bf0eb44..000000000
--- a/app/src/main/res/layout/view_fast_scroll.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_library.xml b/app/src/main/res/menu/menu_home.xml
similarity index 65%
rename from app/src/main/res/menu/menu_library.xml
rename to app/src/main/res/menu/menu_home.xml
index 0c951bba0..745b3360d 100644
--- a/app/src/main/res/menu/menu_library.xml
+++ b/app/src/main/res/menu/menu_home.xml
@@ -2,11 +2,17 @@
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_nav.xml b/app/src/main/res/menu/menu_nav.xml
deleted file mode 100644
index bb7ec7cb9..000000000
--- a/app/src/main/res/menu/menu_nav.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_songs.xml b/app/src/main/res/menu/menu_songs.xml
deleted file mode 100644
index fa32396f5..000000000
--- a/app/src/main/res/menu/menu_songs.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/navigation/nav_explore.xml b/app/src/main/res/navigation/nav_explore.xml
index e39b151d7..aa1ca9425 100644
--- a/app/src/main/res/navigation/nav_explore.xml
+++ b/app/src/main/res/navigation/nav_explore.xml
@@ -2,35 +2,8 @@
+ app:startDestination="@id/home_fragment">
-
-
-
-
-
-
+ android:id="@+id/home_fragment"
+ android:name="org.oxycblt.auxio.home.HomeFragment"
+ android:label="fragment_home"
+ tools:layout="@layout/fragment_home">
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/navigation/nav_main.xml b/app/src/main/res/navigation/nav_main.xml
index 347d05f7a..49824152e 100644
--- a/app/src/main/res/navigation/nav_main.xml
+++ b/app/src/main/res/navigation/nav_main.xml
@@ -32,8 +32,8 @@
app:popEnterAnim="@anim/anim_stationary"
app:popExitAnim="@anim/anim_nav_slide_down" />
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index e26407a09..ea3854e66 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -6,7 +6,6 @@
-->
- 4dp
8dp
16dp
24dp
@@ -22,9 +21,6 @@
48dp
64dp
- 20dp
- 24dp
-
48dp
56dp
136dp
@@ -33,8 +29,8 @@
1dp
2dp
- 48dp
- 48dp
+ 20dp
+ 24dp
16sp
diff --git a/app/src/main/res/values/styles_core.xml b/app/src/main/res/values/styles_core.xml
index e738d3d4b..31b9064b0 100644
--- a/app/src/main/res/values/styles_core.xml
+++ b/app/src/main/res/values/styles_core.xml
@@ -14,7 +14,7 @@
- @color/surface
- @color/design_default_color_primary
- - #FFFFFF
+ - #00000000
- ?attr/colorAccent
- ?attr/colorAccent
diff --git a/app/src/main/res/values/styles_ui.xml b/app/src/main/res/values/styles_ui.xml
index 8d76959bc..2b6cb2adf 100644
--- a/app/src/main/res/values/styles_ui.xml
+++ b/app/src/main/res/values/styles_ui.xml
@@ -7,7 +7,6 @@
- match_parent
- ?android:attr/actionBarSize
- ?attr/colorSurface
- - @dimen/elevation_normal
- @style/ThemeOverlay.ToolbarPopup
- @style/TextAppearance.Toolbar.Header
@@ -61,6 +60,10 @@
- bounds
+
+
+