diff --git a/app/build.gradle b/app/build.gradle index b7544c6fb..74413472f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -86,7 +86,7 @@ dependencies { // Media // TODO: Migrate to media2 when I can figure out how to use it - implementation "androidx.media:media:1.4.2" + implementation "androidx.media:media:1.4.3" // Preferences implementation "androidx.preference:preference-ktx:1.1.1" @@ -102,6 +102,8 @@ dependencies { // Material implementation "com.google.android.material:material:1.5.0-alpha04" + implementation 'me.zhanghai.android.fastscroll:library:1.1.7' + // --- DEBUG --- // Lint diff --git a/app/src/main/java/org/oxycblt/auxio/accent/AccentDialog.kt b/app/src/main/java/org/oxycblt/auxio/accent/AccentDialog.kt index 0d1f03979..3a6df6535 100644 --- a/app/src/main/java/org/oxycblt/auxio/accent/AccentDialog.kt +++ b/app/src/main/java/org/oxycblt/auxio/accent/AccentDialog.kt @@ -29,7 +29,6 @@ import org.oxycblt.auxio.databinding.DialogAccentBinding import org.oxycblt.auxio.settings.SettingsManager import org.oxycblt.auxio.ui.LifecycleDialog import org.oxycblt.auxio.util.logD -import org.oxycblt.auxio.util.resolveColor /** * Dialog responsible for showing the list of accents to select. @@ -55,13 +54,9 @@ class AccentDialog : LifecycleDialog() { binding.accentRecycler.apply { adapter = AccentAdapter(pendingAccent) { accent -> pendingAccent = accent - - updateAccent() } } - updateAccent() - logD("Dialog created.") return binding.root @@ -90,15 +85,6 @@ class AccentDialog : LifecycleDialog() { builder.setNegativeButton(android.R.string.cancel, null) } - private fun updateAccent() { - val accentColor = pendingAccent.color.resolveColor(requireContext()) - - (requireDialog() as AlertDialog).apply { - getButton(AlertDialog.BUTTON_POSITIVE)?.setTextColor(accentColor) - getButton(AlertDialog.BUTTON_NEGATIVE)?.setTextColor(accentColor) - } - } - companion object { const val TAG = BuildConfig.APPLICATION_ID + ".tag.ACCENT_PICKER" const val KEY_PENDING_ACCENT = BuildConfig.APPLICATION_ID + ".key.PENDING_ACCENT" diff --git a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt index 505e8aff9..5a6f20dc2 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt @@ -23,14 +23,17 @@ import android.view.LayoutInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup +import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.view.iterator import androidx.core.view.updatePadding +import androidx.core.view.updatePaddingRelative import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.adapter.FragmentStateAdapter import androidx.viewpager2.widget.ViewPager2 +import com.google.android.material.appbar.AppBarLayout import com.google.android.material.tabs.TabLayoutMediator import org.oxycblt.auxio.MainFragmentDirections import org.oxycblt.auxio.R @@ -46,10 +49,10 @@ import org.oxycblt.auxio.music.Genre import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.ui.DisplayMode import org.oxycblt.auxio.ui.SortMode +import org.oxycblt.auxio.ui.memberBinding import org.oxycblt.auxio.util.applyEdge import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logE -import org.oxycblt.auxio.util.makeScrollingViewFade /** * The main "Launching Point" fragment of Auxio, allowing navigation to the detail @@ -63,6 +66,7 @@ import org.oxycblt.auxio.util.makeScrollingViewFade * @author OxygenCobalt */ class HomeFragment : Fragment() { + private val binding: FragmentHomeBinding by memberBinding(FragmentHomeBinding::inflate) private val detailModel: DetailViewModel by activityViewModels() private val homeModel: HomeViewModel by activityViewModels() @@ -71,7 +75,6 @@ class HomeFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View { - val binding = FragmentHomeBinding.inflate(inflater) val sortItem: MenuItem // --- UI SETUP --- @@ -82,7 +85,34 @@ class HomeFragment : Fragment() { binding.homeAppbar.updatePadding(top = bars.top) } - binding.homeAppbar.makeScrollingViewFade(binding.homeToolbar) + binding.homeAppbar.apply { + addOnOffsetChangedListener( + AppBarLayout.OnOffsetChangedListener { _, verticalOffset -> + binding.homeToolbar.alpha = (binding.homeToolbar.height + verticalOffset) / + binding.homeToolbar.height.toFloat() + } + ) + + post { + // To add our fast scroller, we need to + val vOffset = ( + (layoutParams as CoordinatorLayout.LayoutParams) + .behavior as AppBarLayout.Behavior + ).topAndBottomOffset + + binding.homePager.updatePaddingRelative( + bottom = binding.homeAppbar.totalScrollRange + vOffset + ) + + binding.homeAppbar.addOnOffsetChangedListener( + AppBarLayout.OnOffsetChangedListener { _, verticalOffset -> + binding.homePager.updatePaddingRelative( + bottom = binding.homeAppbar.totalScrollRange + verticalOffset + ) + } + ) + } + } binding.homeToolbar.apply { setOnMenuItemClickListener { item -> diff --git a/app/src/main/java/org/oxycblt/auxio/home/list/AlbumListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/list/AlbumListFragment.kt index 1a7b35ec8..a733b089b 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/list/AlbumListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/list/AlbumListFragment.kt @@ -23,11 +23,15 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.navigation.fragment.findNavController +import me.zhanghai.android.fastscroll.PopupTextProvider import org.oxycblt.auxio.R import org.oxycblt.auxio.home.HomeFragmentDirections import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.ui.AlbumViewHolder +import org.oxycblt.auxio.ui.DisplayMode +import org.oxycblt.auxio.ui.SortMode import org.oxycblt.auxio.ui.newMenu +import org.oxycblt.auxio.ui.sliceArticle class AlbumListFragment : HomeListFragment() { override fun onCreateView( @@ -51,6 +55,23 @@ class AlbumListFragment : HomeListFragment() { return binding.root } + override val popupProvider: PopupTextProvider + get() = PopupTextProvider { idx -> + val album = homeModel.albums.value!![idx] + + when (homeModel.getSortForDisplay(DisplayMode.SHOW_ALBUMS)) { + SortMode.ASCENDING, SortMode.DESCENDING -> album.name.sliceArticle() + .first().uppercase() + + SortMode.ARTIST -> album.artist.name.sliceArticle() + .first().uppercase() + + SortMode.YEAR -> album.year.toString() + + else -> "" + } + } + class AlbumAdapter( private val doOnClick: (data: Album) -> Unit, private val doOnLongClick: (view: View, data: Album) -> Unit, diff --git a/app/src/main/java/org/oxycblt/auxio/home/list/ArtistListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/list/ArtistListFragment.kt index 55a05a181..a477e1fd2 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/list/ArtistListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/list/ArtistListFragment.kt @@ -23,11 +23,13 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.navigation.fragment.findNavController +import me.zhanghai.android.fastscroll.PopupTextProvider import org.oxycblt.auxio.R import org.oxycblt.auxio.home.HomeFragmentDirections import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.ui.ArtistViewHolder import org.oxycblt.auxio.ui.newMenu +import org.oxycblt.auxio.ui.sliceArticle class ArtistListFragment : HomeListFragment() { override fun onCreateView( @@ -51,6 +53,11 @@ class ArtistListFragment : HomeListFragment() { return binding.root } + override val popupProvider: PopupTextProvider + get() = PopupTextProvider { idx -> + homeModel.artists.value!![idx].name.sliceArticle().first().uppercase() + } + class ArtistAdapter( private val doOnClick: (data: Artist) -> Unit, private val doOnLongClick: (view: View, data: Artist) -> Unit, diff --git a/app/src/main/java/org/oxycblt/auxio/home/list/GenreListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/list/GenreListFragment.kt index 7b97b0189..a57945642 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/list/GenreListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/list/GenreListFragment.kt @@ -23,11 +23,13 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.navigation.fragment.findNavController +import me.zhanghai.android.fastscroll.PopupTextProvider import org.oxycblt.auxio.R import org.oxycblt.auxio.home.HomeFragmentDirections import org.oxycblt.auxio.music.Genre import org.oxycblt.auxio.ui.GenreViewHolder import org.oxycblt.auxio.ui.newMenu +import org.oxycblt.auxio.ui.sliceArticle class GenreListFragment : HomeListFragment() { override fun onCreateView( @@ -51,6 +53,11 @@ class GenreListFragment : HomeListFragment() { return binding.root } + override val popupProvider: PopupTextProvider + get() = PopupTextProvider { idx -> + homeModel.genres.value!![idx].name.sliceArticle().first().uppercase() + } + class GenreAdapter( private val doOnClick: (data: Genre) -> Unit, private val doOnLongClick: (view: View, data: Genre) -> Unit, diff --git a/app/src/main/java/org/oxycblt/auxio/home/list/HomeListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/list/HomeListFragment.kt index 1e2b4c66e..c06cb1a14 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/list/HomeListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/list/HomeListFragment.kt @@ -19,19 +19,25 @@ package org.oxycblt.auxio.home.list import android.annotation.SuppressLint +import android.os.Bundle +import android.view.View import androidx.annotation.IdRes import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.LiveData import androidx.recyclerview.widget.RecyclerView +import me.zhanghai.android.fastscroll.FastScrollerBuilder +import me.zhanghai.android.fastscroll.PopupTextProvider +import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.FragmentHomeListBinding import org.oxycblt.auxio.home.HomeViewModel import org.oxycblt.auxio.music.BaseModel import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.ui.memberBinding import org.oxycblt.auxio.util.applySpans +import org.oxycblt.auxio.util.resolveDrawable -open class HomeListFragment : Fragment() { +abstract class HomeListFragment : Fragment() { protected val binding: FragmentHomeListBinding by memberBinding( FragmentHomeListBinding::inflate ) @@ -39,6 +45,20 @@ open class HomeListFragment : Fragment() { protected val homeModel: HomeViewModel by activityViewModels() protected val playbackModel: PlaybackViewModel by activityViewModels() + abstract val popupProvider: PopupTextProvider + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding.homeRecycler.apply { + FastScrollerBuilder(this) + .useMd2Style() + .setPopupTextProvider(popupProvider) + .setTrackDrawable(R.drawable.ui_scroll_track.resolveDrawable(context)) + .build() + } + } + protected fun setupRecycler( @IdRes uniqueId: Int, homeAdapter: HomeAdapter, diff --git a/app/src/main/java/org/oxycblt/auxio/home/list/SongListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/list/SongListFragment.kt index 01705a52a..ea036d7ab 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/list/SongListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/list/SongListFragment.kt @@ -23,11 +23,16 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView +import me.zhanghai.android.fastscroll.PopupTextProvider import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.ItemPlayShuffleBinding import org.oxycblt.auxio.music.Song +import org.oxycblt.auxio.ui.DisplayMode import org.oxycblt.auxio.ui.SongViewHolder +import org.oxycblt.auxio.ui.SortMode import org.oxycblt.auxio.ui.newMenu +import org.oxycblt.auxio.ui.sliceArticle +import org.oxycblt.auxio.util.applySpans import org.oxycblt.auxio.util.inflater class SongListFragment : HomeListFragment() { @@ -46,10 +51,33 @@ class SongListFragment : HomeListFragment() { ) setupRecycler(R.id.home_song_list, adapter, homeModel.songs) + binding.homeRecycler.applySpans { it == 0 } return binding.root } + override val popupProvider: PopupTextProvider + get() = PopupTextProvider { idx -> + if (idx == 0) { + return@PopupTextProvider "" + } + + val song = homeModel.songs.value!![idx] + + when (homeModel.getSortForDisplay(DisplayMode.SHOW_SONGS)) { + SortMode.ASCENDING, SortMode.DESCENDING -> song.name.sliceArticle() + .first().uppercase() + + SortMode.ARTIST -> song.album.artist.name.sliceArticle() + .first().uppercase() + + SortMode.ALBUM -> song.album.name.sliceArticle() + .first().uppercase() + + SortMode.YEAR -> song.album.year.toString() + } + } + inner class SongsAdapter( private val doOnClick: (data: Song) -> Unit, private val doOnLongClick: (view: View, data: Song) -> Unit, 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 b4780c20b..73359a9fd 100644 --- a/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt @@ -46,7 +46,6 @@ import org.oxycblt.auxio.util.applyEdge import org.oxycblt.auxio.util.applySpans import org.oxycblt.auxio.util.getSystemServiceSafe import org.oxycblt.auxio.util.logD -import org.oxycblt.auxio.util.makeScrollingViewFade /** * A [Fragment] that allows for the searching of the entire music library. @@ -81,8 +80,6 @@ class SearchFragment : Fragment() { binding.searchAppbar.updatePadding(top = bars.top) } - binding.searchAppbar.makeScrollingViewFade(binding.searchToolbar) - binding.searchToolbar.apply { val itemId = when (searchModel.filterMode) { DisplayMode.SHOW_SONGS -> R.id.option_filter_songs diff --git a/app/src/main/res/drawable/ui_scroll_track.xml b/app/src/main/res/drawable/ui_scroll_track.xml new file mode 100644 index 000000000..936ce4bf1 --- /dev/null +++ b/app/src/main/res/drawable/ui_scroll_track.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/values/styles_core.xml b/app/src/main/res/values/styles_core.xml index ab5ca7cb4..7fa19105c 100644 --- a/app/src/main/res/values/styles_core.xml +++ b/app/src/main/res/values/styles_core.xml @@ -6,6 +6,7 @@ @@ -31,7 +29,9 @@ @color/overlay_stroke - + + @color/overlay_text_highlight + @color/overlay_text_highlight_inverse ?attr/colorSurface ?attr/colorSurface @font/inter