From 37a8cdccb67b8ab0ff94f0b6eb8876880c7fb1b5 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Wed, 25 Aug 2021 18:13:38 -0600 Subject: [PATCH] playback: fix more queue issues Fix more issues with the queue, such as landscape edge-to-edge not working correctly and drag scroll events not resulting in the appbar lifting. --- .../auxio/playback/queue/QueueDragCallback.kt | 17 ++++++-- .../auxio/playback/queue/QueueFragment.kt | 34 +++++++++++---- .../playback/state/PlaybackStateDatabase.kt | 1 + .../java/org/oxycblt/auxio/util/ViewUtil.kt | 43 ------------------- app/src/main/res/layout/fragment_main.xml | 2 +- app/src/main/res/layout/fragment_queue.xml | 4 +- app/src/main/res/values/dimens.xml | 1 + 7 files changed, 44 insertions(+), 58 deletions(-) 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 553afdd38..7aa567279 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 @@ -32,9 +32,14 @@ import kotlin.math.sign /** * The Drag callback used by the queue recyclerview. Delivers updates to [PlaybackViewModel] * and [QueueAdapter] simultaneously. + * @param onItemScroll Callback for when an item begins to scroll off-screen. Argument passed + * is the dY value. * @author OxygenCobalt */ -class QueueDragCallback(private val playbackModel: PlaybackViewModel) : ItemTouchHelper.Callback() { +class QueueDragCallback( + private val playbackModel: PlaybackViewModel, + private val onItemScroll: (Int) -> Unit +) : ItemTouchHelper.Callback() { private lateinit var queueAdapter: QueueAdapter private var shouldLift = true @@ -57,7 +62,7 @@ class QueueDragCallback(private val playbackModel: PlaybackViewModel) : ItemTouc totalSize: Int, msSinceStartScroll: Long ): Int { - // Fix to make QueueFragment scroll when an item is scrolled out of bounds. + // Fix to make QueueFragment scroll slower when an item is scrolled out of bounds. // Adapted from NewPipe: https://github.com/TeamNewPipe/NewPipe val standardSpeed = super.interpolateOutOfBoundsScroll( recyclerView, viewSize, viewSizeOutOfBounds, totalSize, msSinceStartScroll @@ -71,7 +76,13 @@ class QueueDragCallback(private val playbackModel: PlaybackViewModel) : ItemTouc ) ) - return clampedAbsVelocity * sign(viewSizeOutOfBounds.toDouble()).toInt() + val result = clampedAbsVelocity * sign(viewSizeOutOfBounds.toDouble()).toInt() + + recyclerView.post { + onItemScroll(result) + } + + return result } override fun onMove( diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt index 8a9437f14..09c9caf36 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt @@ -24,6 +24,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.WindowInsets +import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.view.updatePadding import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels @@ -38,10 +39,8 @@ import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.util.isEdgeOn /** - * A [Fragment] that contains both the user queue and the next queue, with the abielity to + * A [Fragment] that contains both the user queue and the next queue, with the ability to * edit them as well. - * TODO: Edge can be improved here by turning off the landscape checks and simply padding the - * root view on the irregular landscape mode [I think] * @author OxygenCobalt */ class QueueFragment : Fragment() { @@ -54,7 +53,17 @@ class QueueFragment : Fragment() { ): View { val binding = FragmentQueueBinding.inflate(inflater) - val callback = QueueDragCallback(playbackModel) + val callback = QueueDragCallback(playbackModel) { dY -> + // By default, CoordinatorLayout is not aware of scroll events originating from + // when an item is scrolled off-screen, so we manually add a scroll event ourselves. + (binding.queueAppbar.layoutParams as CoordinatorLayout.LayoutParams).behavior + ?.onNestedPreScroll( + binding.queueCoordinator, binding.queueAppbar, + binding.queueRecycler, 0, dY, + IntArray(2), 0 + ) + } + val helper = ItemTouchHelper(callback) val queueAdapter = QueueAdapter(helper, playbackModel) var lastShuffle = playbackModel.isShuffling.value @@ -101,6 +110,7 @@ class QueueFragment : Fragment() { if (isShuffling != lastShuffle) { lastShuffle = isShuffling + binding.queueRecycler.scrollBy(0, 100) binding.queueRecycler.scrollToPosition(0) } } @@ -112,15 +122,21 @@ class QueueFragment : Fragment() { if (isEdgeOn()) { // Account for the side navigation bar if required. binding.root.setOnApplyWindowInsetsListener { v, insets -> - val right = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - insets.getInsets(WindowInsets.Type.systemBars()).right + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + val bars = insets.getInsets(WindowInsets.Type.systemBars()) + + v.updatePadding( + left = bars.left, + right = bars.right + ) } else { @Suppress("DEPRECATION") - insets.systemWindowInsetRight + v.updatePadding( + left = insets.systemWindowInsetLeft, + right = insets.systemWindowInsetRight + ) } - v.updatePadding(right = right) - insets } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateDatabase.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateDatabase.kt index ecdfc38c3..376609cd9 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateDatabase.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateDatabase.kt @@ -30,6 +30,7 @@ import org.oxycblt.auxio.util.queryAll /** * A SQLite database for managing the persistent playback state and queue. * Yes. I know Room exists. But that would needlessly bloat my app and has crippling bugs. + * TODO: Improve the boundary between this and [PlaybackStateManager] * @author OxygenCobalt */ class PlaybackStateDatabase(context: Context) : diff --git a/app/src/main/java/org/oxycblt/auxio/util/ViewUtil.kt b/app/src/main/java/org/oxycblt/auxio/util/ViewUtil.kt index 387d0676b..d48024eec 100644 --- a/app/src/main/java/org/oxycblt/auxio/util/ViewUtil.kt +++ b/app/src/main/java/org/oxycblt/auxio/util/ViewUtil.kt @@ -18,14 +18,11 @@ package org.oxycblt.auxio.util -import android.app.Activity import android.content.Context import android.content.res.ColorStateList import android.content.res.Resources import android.os.Build -import android.util.DisplayMetrics import android.util.TypedValue -import android.view.WindowManager import android.widget.ImageButton import android.widget.TextView import androidx.annotation.AttrRes @@ -142,43 +139,3 @@ fun @receiver:AttrRes Int.resolveAttr(context: Context): Int { * Check if edge-to-edge is on. Really a glorified version check. */ fun isEdgeOn(): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1 - -/** - * Check if we are in the "Irregular" landscape mode (e.g landscape, but nav bar is on the sides) - * Used to disable most of edge-to-edge if that's the case, as I cant get it to work on this mode. - * @return True if we are in the irregular landscape mode, false if not. - */ -fun Activity.isIrregularLandscape(): Boolean { - return isLandscape() && !isSystemBarOnBottom(this) -} - -/** - * Check if the system bars are on the bottom. - * @return If the system bars are on the bottom, false if no. - */ -private fun isSystemBarOnBottom(activity: Activity): Boolean { - val metrics = DisplayMetrics() - - var width: Int - var height: Int - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - activity.windowManager.currentWindowMetrics.bounds.also { - width = it.width() - height = it.height() - } - } else { - @Suppress("DEPRECATION") - activity.getSystemServiceSafe(WindowManager::class).apply { - defaultDisplay.getMetrics(metrics) - - width = metrics.widthPixels - height = metrics.heightPixels - } - } - - val config = activity.resources.configuration - val canMove = (width != height && config.smallestScreenWidthDp < 600) - - return (!canMove || width < height) -} diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml index ccee4c219..04344fd86 100644 --- a/app/src/main/res/layout/fragment_main.xml +++ b/app/src/main/res/layout/fragment_main.xml @@ -26,7 +26,7 @@ android:name="org.oxycblt.auxio.playback.CompactPlaybackFragment" android:layout_width="match_parent" android:layout_height="wrap_content" - android:elevation="8dp" + android:elevation="@dimen/elevation_normal" android:background="?attr/colorSurface" tools:layout="@layout/fragment_compact_playback" /> diff --git a/app/src/main/res/layout/fragment_queue.xml b/app/src/main/res/layout/fragment_queue.xml index 0d0e82577..e178ba6d2 100644 --- a/app/src/main/res/layout/fragment_queue.xml +++ b/app/src/main/res/layout/fragment_queue.xml @@ -5,6 +5,7 @@ tools:context=".playback.queue.QueueFragment"> - 2dp 4dp + 8dp 4dp \ No newline at end of file