all: cleanup

Clean up the slightly rushed changes I made as I worked on the split
UI.
This commit is contained in:
OxygenCobalt 2022-08-03 19:54:14 -06:00
parent 7543f1defc
commit a9515e19c0
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
10 changed files with 114 additions and 115 deletions

View file

@ -83,7 +83,7 @@ import java.util.Map;
* window-like. For BottomSheetDialog use {@link BottomSheetDialog#setTitle(int)}, and for
* BottomSheetDialogFragment use {@link ViewCompat#setAccessibilityPaneTitle(View, CharSequence)}.
*
* Modified at several points by OxygenCobalt to fix insane issues.
* Modified at several points by OxygenCobalt to work around miscellaneous insanity.
*/
public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Behavior<V> {
@ -720,8 +720,8 @@ public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Be
}
} else if (dy < 0) { // Downward
if (!target.canScrollVertically(-1)) {
// MODIFICATION: Add enableHidingGestures method
if (newTop <= collapsedOffset || (hideable && enableHidingGestures())) {
// MODIFICATION: Add isHideableWhenDragging method
if (newTop <= collapsedOffset || (hideable && isHideableWhenDragging())) {
if (!draggable) {
// Prevent dragging
return;
@ -775,8 +775,8 @@ public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Be
}
}
}
// MODIFICATION: Add enableHidingGestures method
} else if (hideable && shouldHide(child, getYVelocity()) && enableHidingGestures()) {
// MODIFICATION: Add isHideableWhenDragging method
} else if (hideable && shouldHide(child, getYVelocity()) && isHideableWhenDragging()) {
targetState = STATE_HIDDEN;
} else if (lastNestedScrollDy == 0) {
int currentTop = child.getTop();
@ -1725,8 +1725,8 @@ public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Be
}
}
}
// MODIFICATION: Add enableHidingGestures method
} else if (hideable && shouldHide(releasedChild, yvel) && enableHidingGestures()) {
// MODIFICATION: Add isHideableWhenDragging method
} else if (hideable && shouldHide(releasedChild, yvel) && isHideableWhenDragging()) {
// Hide if the view was either released low or it was a significant vertical swipe
// otherwise settle to closest expanded state.
if ((Math.abs(xvel) < Math.abs(yvel) && yvel > SIGNIFICANT_VEL_THRESHOLD)
@ -1798,9 +1798,9 @@ public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Be
@Override
public int clampViewPositionVertical(@NonNull View child, int top, int dy) {
// MODIFICATION: Add enableHidingGestures method
// MODIFICATION: Add isHideableWhenDragging method
return MathUtils.clamp(
top, getExpandedOffset(), (hideable && enableHidingGestures()) ? parentHeight : collapsedOffset);
top, getExpandedOffset(), (hideable && isHideableWhenDragging()) ? parentHeight : collapsedOffset);
}
@Override
@ -1810,8 +1810,8 @@ public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Be
@Override
public int getViewVerticalDragRange(@NonNull View child) {
// MODIFICATION: Add enableHidingGestures method
if (hideable && enableHidingGestures()) {
// MODIFICATION: Add isHideableWhenDragging method
if (hideable && isHideableWhenDragging()) {
return parentHeight;
} else {
return collapsedOffset;
@ -1886,7 +1886,7 @@ public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Be
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
public boolean enableHidingGestures() {
public boolean isHideableWhenDragging() {
return true;
}

View file

@ -44,6 +44,10 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat
*
* TODO: Add multi-select
*
* TODO: Separate playback views by height
*
* TODO: Find better way to handler recycler divider visibility
*
* @author OxygenCobalt
*/
class MainActivity : AppCompatActivity() {

View file

@ -76,9 +76,7 @@ class MainFragment :
val playbackSheetBehavior =
binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior
val queueSheetBehavior = binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior?
if (queueSheetBehavior != null) {
unlikelyToBeNull(binding.handleWrapper).setOnClickListener {
if (playbackSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED &&
@ -87,6 +85,8 @@ class MainFragment :
}
}
} else {
// Dual-pane mode, color/pad the queue sheet manually. Note that we do not round
// corners, as the queue sheet cannot be dragged.
binding.queueSheet.apply {
background =
MaterialShapeDrawable.createWithElevationOverlay(context).apply {
@ -133,8 +133,10 @@ class MainFragment :
override fun onPreDraw(): Boolean {
// CoordinatorLayout is insane and thus makes bottom sheet callbacks insane. Do our
// checks before every draw.
// checks before every draw, which is not ideal in the slightest but also has minimal
// performance impact since we are only mutating attributes used during drawing.
val binding = requireBinding()
val playbackSheetBehavior =
binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior
@ -144,6 +146,30 @@ class MainFragment :
val halfOutRatio = min(playbackRatio * 2, 1f)
val halfInPlaybackRatio = max(playbackRatio - 0.5f, 0f) * 2
val queueSheetBehavior = binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior?
if (queueSheetBehavior != null) {
// Queue sheet, take queue into account so the playback bar is shown and the playback
// panel is hidden when the queue sheet is expanded.
val queueRatio = max(queueSheetBehavior.calculateSlideOffset(), 0f)
val halfOutQueueRatio = min(queueRatio * 2, 1f)
val halfInQueueRatio = max(queueRatio - 0.5f, 0f) * 2
binding.playbackBarFragment.alpha = max(1 - halfOutRatio, halfInQueueRatio)
binding.playbackPanelFragment.alpha = min(halfInPlaybackRatio, 1 - halfOutQueueRatio)
binding.queueFragment.alpha = queueRatio
if (playbackModel.song.value != null) {
// Hack around the playback sheet intercepting swipe events on the queue bar
playbackSheetBehavior.isDraggable =
queueSheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED
}
} else {
// No queue sheet, fade normally based on the playback sheet
binding.playbackBarFragment.alpha = 1 - halfOutRatio
binding.playbackPanelFragment.alpha = halfInPlaybackRatio
binding.queueSheet.alpha = halfInPlaybackRatio
}
binding.exploreNavHost.apply {
alpha = outPlaybackRatio
isInvisible = alpha == 0f
@ -153,61 +179,18 @@ class MainFragment :
requireContext().getDimenSafe(R.dimen.elevation_normal) * outPlaybackRatio
playbackSheetBehavior.sheetBackgroundDrawable.alpha = (outPlaybackRatio * 255).toInt()
val queueSheetBehavior = binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior?
binding.playbackBarFragment.apply {
isInvisible = alpha == 0f
lastInsets?.let { translationY = it.systemBarInsetsCompat.top * halfOutRatio }
}
if (queueSheetBehavior != null) {
val queueRatio = max(queueSheetBehavior.calculateSlideOffset(), 0f)
val halfOutQueueRatio = min(queueRatio * 2, 1f)
val halfInQueueRatio = max(queueRatio - 0.5f, 0f) * 2
binding.playbackPanelFragment.isInvisible = binding.playbackPanelFragment.alpha == 0f
binding.queueFragment.isInvisible = binding.queueFragment.alpha == 0f
binding.playbackBarFragment.apply {
alpha = max(1 - halfOutRatio, halfInQueueRatio)
isInvisible = alpha == 0f
lastInsets?.let { translationY = it.systemBarInsetsCompat.top * halfOutRatio }
}
binding.playbackPanelFragment.apply {
alpha = min(halfInPlaybackRatio, 1 - halfOutQueueRatio)
isInvisible = alpha == 0f
}
binding.queueFragment.apply {
alpha = queueRatio
isInvisible = alpha == 0f
}
if (playbackModel.song.value != null) {
// Hack around the playback sheet intercepting swipe events on the queue bar
playbackSheetBehavior.isDraggable =
queueSheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED
} else {
// Sometimes lingering drags can un-hide the playback sheet even when we intend to
// hide it, make sure we keep it hidden.
tryHideAll()
}
} else {
binding.playbackBarFragment.apply {
alpha = 1 - halfOutRatio
isInvisible = alpha == 0f
lastInsets?.let { translationY = it.systemBarInsetsCompat.top * halfOutRatio }
}
binding.playbackPanelFragment.apply {
alpha = halfInPlaybackRatio
isInvisible = alpha == 0f
}
binding.queueSheet.apply {
alpha = halfInPlaybackRatio
isInvisible = alpha == 0f
}
if (playbackModel.song.value == null) {
// Sometimes lingering drags can un-hide the playback sheet even when we intend to
// hide it, make sure we keep it hidden.
tryHideAll()
}
if (playbackModel.song.value == null) {
// Sometimes lingering drags can un-hide the playback sheet even when we intend to
// hide it, make sure we keep it hidden.
tryHideAll()
}
return true
@ -250,8 +233,8 @@ class MainFragment :
val playbackSheetBehavior =
binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior
if (playbackSheetBehavior.state != BottomSheetBehavior.STATE_HIDDEN &&
playbackSheetBehavior.state != BottomSheetBehavior.STATE_EXPANDED) {
if (playbackSheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED) {
// State is collapsed and non-hidden, expand
playbackSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
}
}
@ -261,8 +244,8 @@ class MainFragment :
val playbackSheetBehavior =
binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior
if (playbackSheetBehavior.state != BottomSheetBehavior.STATE_HIDDEN &&
playbackSheetBehavior.state != BottomSheetBehavior.STATE_COLLAPSED) {
if (playbackSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) {
// Make sure the queue is also collapsed here.
val queueSheetBehavior =
binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior?
@ -277,13 +260,17 @@ class MainFragment :
binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior
if (playbackSheetBehavior.state == BottomSheetBehavior.STATE_HIDDEN) {
playbackSheetBehavior.isDraggable = true
playbackSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
val queueSheetBehavior =
binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior?
// Queue sheet behavior is either collapsed or expanded, no hiding needed
queueSheetBehavior?.isDraggable = true
playbackSheetBehavior.apply {
// Make sure the view is draggable, at least until the draw checks kick in.
isDraggable = true
state = BottomSheetBehavior.STATE_COLLAPSED
}
}
}
@ -296,6 +283,8 @@ class MainFragment :
val queueSheetBehavior =
binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior?
// Make these views non-draggable so the user can't halt the hiding event.
queueSheetBehavior?.apply {
isDraggable = false
state = BottomSheetBehavior.STATE_COLLAPSED
@ -314,30 +303,33 @@ class MainFragment :
*
* TODO: Migrate to new predictive API
*/
inner class DynamicBackPressedCallback : OnBackPressedCallback(false) {
private inner class DynamicBackPressedCallback : OnBackPressedCallback(false) {
override fun handleOnBackPressed() {
val binding = requireBinding()
val playbackSheetBehavior =
binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior
val queueSheetBehavior =
binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior?
if (queueSheetBehavior != null &&
queueSheetBehavior.state != BottomSheetBehavior.STATE_COLLAPSED) {
queueSheetBehavior.state != BottomSheetBehavior.STATE_COLLAPSED &&
playbackSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) {
// Collapse the queue first if it is expanded.
queueSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
return
}
val playbackSheetBehavior =
binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior
if (playbackSheetBehavior.state != BottomSheetBehavior.STATE_COLLAPSED &&
playbackSheetBehavior.state != BottomSheetBehavior.STATE_HIDDEN) {
// Then collapse the playback sheet.
playbackSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
return
}
// First navigate upwards in the explore graph, then navigate back in the activity.
val navController = binding.exploreNavHost.findNavController()
if (navController.currentDestination?.id == navController.graph.startDestinationId) {
isEnabled = false
requireActivity().onBackPressed()

View file

@ -246,6 +246,8 @@ class DetailViewModel(application: Application) :
}
when (it.releaseType.refinement) {
ReleaseType.Refinement.LIVE -> R.string.lbl_live_group
ReleaseType.Refinement.REMIX -> R.string.lbl_remix_group
null ->
when (it.releaseType) {
is ReleaseType.Album -> R.string.lbl_albums
@ -255,8 +257,6 @@ class DetailViewModel(application: Application) :
is ReleaseType.Soundtrack -> R.string.lbl_soundtracks
is ReleaseType.Mixtape -> R.string.lbl_mixtapes
}
ReleaseType.Refinement.LIVE -> R.string.lbl_live_group
ReleaseType.Refinement.REMIX -> R.string.lbl_remix_group
}
}

View file

@ -41,5 +41,5 @@ class PlaybackSheetBehavior<V : View>(context: Context, attributeSet: AttributeS
super.onInterceptTouchEvent(parent, child, event) && state != STATE_EXPANDED
// Note: This is an extension to Auxio's vendored BottomSheetBehavior
override fun enableHidingGestures() = false
override fun isHideableWhenDragging() = false
}

View file

@ -156,10 +156,9 @@ class PlaybackViewModel(application: Application) :
private fun performActionImpl(action: DelayedAction, library: MusicStore.Library) {
when (action) {
is DelayedAction.RestoreState -> {
if (!playbackManager.isInitialized) {
viewModelScope.launch {
playbackManager.restoreState(PlaybackStateDatabase.getInstance(application))
}
viewModelScope.launch {
playbackManager.restoreState(
PlaybackStateDatabase.getInstance(application), false)
}
}
is DelayedAction.ShuffleAll -> shuffleAll()
@ -273,7 +272,7 @@ class PlaybackViewModel(application: Application) :
fun tryRestorePlaybackState(onDone: (Boolean) -> Unit) {
viewModelScope.launch {
val restored =
playbackManager.restoreState(PlaybackStateDatabase.getInstance(application))
playbackManager.restoreState(PlaybackStateDatabase.getInstance(application), true)
onDone(restored)
}
}

View file

@ -357,36 +357,37 @@ class PlaybackStateManager private constructor() {
// --- PERSISTENCE FUNCTIONS ---
/** Restore the state from the [database]. Returns if a state was restored. */
suspend fun restoreState(database: PlaybackStateDatabase): Boolean {
suspend fun restoreState(database: PlaybackStateDatabase, force: Boolean): Boolean {
if (isInitialized && !force) {
return false
}
val library = musicStore.library ?: return false
val state = withContext(Dispatchers.IO) { database.read(library) }
synchronized(this) {
val exists =
if (state != null && !isInitialized) {
// Continuing playback while also possibly doing drastic state updates is
// a bad idea, so pause.
isPlaying = false
if (state != null && (!isInitialized || force)) {
// Continuing playback while also possibly doing drastic state updates is
// a bad idea, so pause.
isPlaying = false
index = state.index
parent = state.parent
_queue = state.queue.toMutableList()
repeatMode = state.repeatMode
isShuffled = state.isShuffled
index = state.index
parent = state.parent
_queue = state.queue.toMutableList()
repeatMode = state.repeatMode
isShuffled = state.isShuffled
notifyNewPlayback()
seekTo(state.positionMs)
notifyRepeatModeChanged()
notifyShuffledChanged()
notifyNewPlayback()
seekTo(state.positionMs)
notifyRepeatModeChanged()
notifyShuffledChanged()
true
} else {
false
}
isInitialized = true
isInitialized = true
return exists
return true
} else {
return false
}
}
}

View file

@ -31,7 +31,8 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.util.*
/**
* Implements the fundamental bottom sheet attributes used across the entire app.
* Implements a reasonable enough skeleton around BottomSheetBehavior (Excluding auxio extensions in
* the vendored code because I course I have to) for normal use without absurd bugs.
* @author OxygenCobalt
*/
abstract class AuxioSheetBehavior<V : View>(context: Context, attributeSet: AttributeSet?) :
@ -86,6 +87,10 @@ abstract class AuxioSheetBehavior<V : View>(context: Context, attributeSet: Attr
setup = true
}
// Sometimes CoordinatorLayout tries to be "hElpfUl" and just does not dispatch window
// insets sometimes. Ensure that we get them.
child.requestApplyInsets()
return layout
}
}

View file

@ -120,8 +120,6 @@ class BottomSheetContentBehavior<V : View>(context: Context, attributeSet: Attri
setup = true
}
child.requestApplyInsets()
return true
}

View file

@ -98,7 +98,7 @@ class WidgetComponent(private val context: Context) :
// limit, which is the size of an RGB_8888 bitmap 1.5x the screen size. When
// enabling rounded corners, we further reduce it by a factor of 8 to get 16-dp
// rounded corners, whereas we only downsize it by 2 when there is rounded
// corners just to ensure that we do not hit the memory limit.
// corners just to ensure that we *really* do not hit the memory limit.
val metrics = context.resources.displayMetrics
val sw = metrics.widthPixels
val sh = metrics.heightPixels