all: cleanup
Clean up the slightly rushed changes I made as I worked on the split UI.
This commit is contained in:
parent
7543f1defc
commit
a9515e19c0
10 changed files with 114 additions and 115 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,8 +120,6 @@ class BottomSheetContentBehavior<V : View>(context: Context, attributeSet: Attri
|
|||
setup = true
|
||||
}
|
||||
|
||||
child.requestApplyInsets()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue