all: misc changes

Miscellanious changes that accumulated over time.
This commit is contained in:
OxygenCobalt 2022-07-31 15:51:12 -06:00
parent 170cdf80ef
commit b42dfd0b53
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
14 changed files with 105 additions and 83 deletions

View file

@ -27,6 +27,8 @@ at the cost of longer loading times
- Fixed default material theme being used before app shows up - Fixed default material theme being used before app shows up
- Fixed shuffle shortcut and file opening not working on startup on some devices - Fixed shuffle shortcut and file opening not working on startup on some devices
- Fixed issue where the notification position would not match if one seeked when paused - Fixed issue where the notification position would not match if one seeked when paused
- Fixed issue where widget covers would not load
- Fixed issue where widget could not be sized to it's smallest form
#### What's Changed #### What's Changed
- Play and skip icons are filled again - Play and skip icons are filled again

View file

@ -82,6 +82,8 @@ import java.util.Map;
* <p>To send useful accessibility events, set a title on bottom sheets that are windows or are * <p>To send useful accessibility events, set a title on bottom sheets that are windows or are
* window-like. For BottomSheetDialog use {@link BottomSheetDialog#setTitle(int)}, and for * window-like. For BottomSheetDialog use {@link BottomSheetDialog#setTitle(int)}, and for
* BottomSheetDialogFragment use {@link ViewCompat#setAccessibilityPaneTitle(View, CharSequence)}. * BottomSheetDialogFragment use {@link ViewCompat#setAccessibilityPaneTitle(View, CharSequence)}.
*
* Modified at several points by OxygenCobalt to fix insane issues.
*/ */
public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Behavior<V> { public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Behavior<V> {

View file

@ -29,10 +29,21 @@ import org.oxycblt.auxio.ui.AuxioSheetBehavior
import org.oxycblt.auxio.util.systemBarInsetsCompat import org.oxycblt.auxio.util.systemBarInsetsCompat
import org.oxycblt.auxio.util.systemGestureInsetsCompat import org.oxycblt.auxio.util.systemGestureInsetsCompat
/**
* The coordinator layout behavior used for the playback sheet, hacking in the many fixes required
* to make bottom sheets like this work.
* @author OxygenCobalt
*
* TODO: Implement hiding because I have to
*/
class PlaybackSheetBehavior<V : View>(context: Context, attributeSet: AttributeSet?) : class PlaybackSheetBehavior<V : View>(context: Context, attributeSet: AttributeSet?) :
AuxioSheetBehavior<V>(context, attributeSet) { AuxioSheetBehavior<V>(context, attributeSet) {
private var lastInsets: WindowInsets? = null private var lastInsets: WindowInsets? = null
init {
isHideable = true
}
// Hack around issue where the playback sheet will try to intercept nested scrolling events // Hack around issue where the playback sheet will try to intercept nested scrolling events
// before the queue sheet. // before the queue sheet.
override fun onInterceptTouchEvent( override fun onInterceptTouchEvent(
@ -58,13 +69,16 @@ class PlaybackSheetBehavior<V : View>(context: Context, attributeSet: AttributeS
} }
fun hideSafe() { fun hideSafe() {
isDraggable = false if (state != STATE_HIDDEN) {
isHideable = true isDraggable = false
state = STATE_HIDDEN state = STATE_HIDDEN
}
} }
fun unhideSafe() { fun unhideSafe() {
isHideable = false if (state == STATE_HIDDEN) {
isDraggable = true state = STATE_COLLAPSED
isDraggable = true
}
} }
} }

View file

@ -58,8 +58,8 @@ private constructor(
elevation = binding.context.getDimenSafe(R.dimen.elevation_normal) * 5 elevation = binding.context.getDimenSafe(R.dimen.elevation_normal) * 5
} }
val isEnabled: Boolean val isPrevious: Boolean
get() = binding.songDragHandle.isEnabled get() = binding.songDragHandle.alpha == 0.5f
init { init {
binding.body.background = binding.body.background =
@ -87,17 +87,11 @@ private constructor(
binding.body.setOnClickListener { listener.onClick(this) } binding.body.setOnClickListener { listener.onClick(this) }
if (item.previous) { val alpha = if (item.previous) 0.5f else 1f
binding.songName.alpha = 0.5f binding.songAlbumCover.alpha = alpha
binding.songInfo.alpha = 0.5f binding.songName.alpha = alpha
binding.songAlbumCover.alpha = 0.5f binding.songInfo.alpha = alpha
binding.songDragHandle.isEnabled = false binding.songDragHandle.alpha = alpha
} else {
binding.songName.alpha = 1f
binding.songInfo.alpha = 1f
binding.songAlbumCover.alpha = 1f
binding.songDragHandle.isEnabled = true
}
// Roll our own drag handlers as the default ones suck // Roll our own drag handlers as the default ones suck
binding.songDragHandle.setOnTouchListener { _, motionEvent -> binding.songDragHandle.setOnTouchListener { _, motionEvent ->

View file

@ -40,7 +40,7 @@ class QueueDragCallback(private val playbackModel: QueueViewModel) : ItemTouchHe
viewHolder: RecyclerView.ViewHolder viewHolder: RecyclerView.ViewHolder
): Int { ): Int {
val queueHolder = viewHolder as QueueSongViewHolder val queueHolder = viewHolder as QueueSongViewHolder
return if (queueHolder.isEnabled) { return if (!queueHolder.isPrevious) {
makeFlag( makeFlag(
ItemTouchHelper.ACTION_STATE_DRAG, ItemTouchHelper.UP or ItemTouchHelper.DOWN) or ItemTouchHelper.ACTION_STATE_DRAG, ItemTouchHelper.UP or ItemTouchHelper.DOWN) or
makeFlag(ItemTouchHelper.ACTION_STATE_SWIPE, ItemTouchHelper.START) makeFlag(ItemTouchHelper.ACTION_STATE_SWIPE, ItemTouchHelper.START)

View file

@ -19,6 +19,7 @@ package org.oxycblt.auxio.playback.queue
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import androidx.core.view.isInvisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
@ -31,6 +32,13 @@ import org.oxycblt.auxio.util.collectImmediately
/** /**
* A [Fragment] that shows the queue and enables editing as well. * A [Fragment] that shows the queue and enables editing as well.
*
* TODO: Improve index updates
*
* TODO: Test older versions
*
* TODO: Test restoration and song loss
*
* @author OxygenCobalt * @author OxygenCobalt
*/ */
class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemListener { class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemListener {
@ -46,6 +54,14 @@ class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemList
binding.queueRecycler.apply { binding.queueRecycler.apply {
adapter = queueAdapter adapter = queueAdapter
touchHelper.attachToRecyclerView(this) touchHelper.attachToRecyclerView(this)
addOnScrollListener(
object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
binding.queueDivider.isInvisible =
(layoutManager as LinearLayoutManager)
.findFirstCompletelyVisibleItemPosition() < 1
}
})
} }
// --- VIEWMODEL SETUP ---- // --- VIEWMODEL SETUP ----
@ -78,11 +94,12 @@ class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemList
if (instructions.scrollTo != null) { if (instructions.scrollTo != null) {
val binding = requireBinding() val binding = requireBinding()
val lmm = binding.queueRecycler.layoutManager as LinearLayoutManager val lmm = binding.queueRecycler.layoutManager as LinearLayoutManager
val indices = val start = lmm.findFirstCompletelyVisibleItemPosition()
lmm.findFirstCompletelyVisibleItemPosition()..lmm val end = lmm.findLastCompletelyVisibleItemPosition()
.findLastCompletelyVisibleItemPosition()
if (instructions.scrollTo !in indices) { if (start != RecyclerView.NO_POSITION &&
end != RecyclerView.NO_POSITION &&
instructions.scrollTo !in start..end) {
binding.queueRecycler.scrollToPosition(instructions.scrollTo) binding.queueRecycler.scrollToPosition(instructions.scrollTo)
} }
} }

View file

@ -73,7 +73,7 @@ class QueueViewModel : ViewModel(), PlaybackStateManager.Callback {
playbackManager.moveQueueItem(adapterFrom, adapterTo) playbackManager.moveQueueItem(adapterFrom, adapterTo)
return false return true
} }
fun finishInstructions() { fun finishInstructions() {

View file

@ -25,7 +25,6 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.bottomsheet.NeoBottomSheetBehavior import com.google.android.material.bottomsheet.NeoBottomSheetBehavior
import kotlin.math.abs import kotlin.math.abs
import org.oxycblt.auxio.util.coordinatorLayoutBehavior import org.oxycblt.auxio.util.coordinatorLayoutBehavior
import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.replaceSystemBarInsetsCompat import org.oxycblt.auxio.util.replaceSystemBarInsetsCompat
import org.oxycblt.auxio.util.systemBarInsetsCompat import org.oxycblt.auxio.util.systemBarInsetsCompat
@ -61,7 +60,6 @@ class BottomSheetContentBehavior<V : View>(context: Context, attributeSet: Attri
layoutContent(child) layoutContent(child)
if (!setup) { if (!setup) {
child.setOnApplyWindowInsetsListener { v, insets -> child.setOnApplyWindowInsetsListener { v, insets ->
lastInsets = insets lastInsets = insets
val dep = dep ?: return@setOnApplyWindowInsetsListener insets val dep = dep ?: return@setOnApplyWindowInsetsListener insets
@ -94,8 +92,6 @@ class BottomSheetContentBehavior<V : View>(context: Context, attributeSet: Attri
} }
private fun layoutContent(child: View) { private fun layoutContent(child: View) {
logD("Measure")
child.layout(0, 0, child.measuredWidth, child.measuredHeight) child.layout(0, 0, child.measuredWidth, child.measuredHeight)
} }
@ -126,8 +122,6 @@ class BottomSheetContentBehavior<V : View>(context: Context, attributeSet: Attri
child: V, child: V,
dependency: View dependency: View
): Boolean { ): Boolean {
logD("Dependent view changed $child")
val behavior = dependency.coordinatorLayoutBehavior as NeoBottomSheetBehavior val behavior = dependency.coordinatorLayoutBehavior as NeoBottomSheetBehavior
val consumed = behavior.calculateConsumedByBar() val consumed = behavior.calculateConsumedByBar()
if (consumed < Int.MIN_VALUE) { if (consumed < Int.MIN_VALUE) {
@ -135,8 +129,6 @@ class BottomSheetContentBehavior<V : View>(context: Context, attributeSet: Attri
} }
if (consumed != lastConsumed) { if (consumed != lastConsumed) {
logD("Dependent view changed important $child")
lastConsumed = consumed lastConsumed = consumed
val insets = lastInsets val insets = lastInsets

View file

@ -95,16 +95,14 @@ class WidgetComponent(private val context: Context) :
} }
// Resize the image in a such a way that we don't hit the RemoteView size // Resize the image in a such a way that we don't hit the RemoteView size
// limit. The limit is technically the byte-size of an RGB_8888 bitmap 1.5x // limit, which is the size of an RGB_8888 bitmap 1.5x the screen size. Note
// the screen size, but the size of a RemoteView can for some reason be 10x // that we actually set the limit to be half the memory limit so that it's
// the size of the binded bitmaps, which means we need to heavily reduce // less likely for us to hit it. it to really ensure we don't hit the limit.
// our image size as to make sure we stay around an order of magnitude below // This also creates the consistent sizes required for round bitmaps.
// the memory limit. This fixed size is also needed to ensure consistent
// outlines on rounded images.
val metrics = context.resources.displayMetrics val metrics = context.resources.displayMetrics
val sw = metrics.widthPixels val sw = metrics.widthPixels
val sh = metrics.heightPixels val sh = metrics.heightPixels
builder.size((sqrt((6f * sw * sh)) / 8f).toInt()) builder.size((sqrt((6f * sw * sh) / 8f)).toInt())
return if (cornerRadius > 0) { return if (cornerRadius > 0) {
this@WidgetComponent.logD("Loading round covers: $cornerRadius") this@WidgetComponent.logD("Loading round covers: $cornerRadius")

View file

@ -63,7 +63,7 @@ class WidgetProvider : AppWidgetProvider() {
SizeF(180f, 272f) to createMediumWidget(context, state), SizeF(180f, 272f) to createMediumWidget(context, state),
SizeF(272f, 272f) to createLargeWidget(context, state)) SizeF(272f, 272f) to createLargeWidget(context, state))
AppWidgetManager.getInstance(context).applyViewsCompat(context, views) AppWidgetManager.getInstance(context).updateAppWidgetCompat(context, views)
} }
/* /*
@ -114,7 +114,7 @@ class WidgetProvider : AppWidgetProvider() {
context.sendBroadcast(intent) context.sendBroadcast(intent)
} }
private fun AppWidgetManager.applyViewsCompat( private fun AppWidgetManager.updateAppWidgetCompat(
context: Context, context: Context,
views: Map<SizeF, RemoteViews> views: Map<SizeF, RemoteViews>
) { ) {

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="0.24" android:color="?attr/colorOnSurface" android:state_enabled="false" />
<item android:color="?attr/colorPrimary" android:state_activated="true" /> <item android:color="?attr/colorPrimary" android:state_activated="true" />
<item android:color="?android:attr/textColorPrimary" /> <item android:color="?android:attr/textColorPrimary" />
</selector> </selector>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="0.24" android:color="?attr/colorOnSurface" android:state_enabled="false" />
<item android:color="?attr/colorPrimary" android:state_activated="true" /> <item android:color="?attr/colorPrimary" android:state_activated="true" />
<item android:color="?android:attr/textColorSecondary" /> <item android:color="?android:attr/textColorSecondary" />
</selector> </selector>

View file

@ -17,6 +17,7 @@
tools:listitem="@layout/item_queue_song" /> tools:listitem="@layout/item_queue_song" />
<com.google.android.material.divider.MaterialDivider <com.google.android.material.divider.MaterialDivider
android:id="@+id/queue_divider"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />

View file

@ -32,51 +32,51 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"> android:background="?attr/selectableItemBackground">
<org.oxycblt.auxio.image.StyledImageView <org.oxycblt.auxio.image.StyledImageView
android:id="@+id/song_album_cover" android:id="@+id/song_album_cover"
style="@style/Widget.Auxio.Image.Small" style="@style/Widget.Auxio.Image.Small"
android:layout_margin="@dimen/spacing_medium" android:layout_margin="@dimen/spacing_medium"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:staticIcon="@drawable/ic_song_24" /> tools:staticIcon="@drawable/ic_song_24" />
<TextView <TextView
android:id="@+id/song_name" android:id="@+id/song_name"
style="@style/Widget.Auxio.TextView.Item.Primary" style="@style/Widget.Auxio.TextView.Item.Primary"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_medium" android:layout_marginEnd="@dimen/spacing_medium"
app:layout_constraintBottom_toTopOf="@+id/song_info" app:layout_constraintBottom_toTopOf="@+id/song_info"
app:layout_constraintEnd_toStartOf="@+id/song_drag_handle" app:layout_constraintEnd_toStartOf="@+id/song_drag_handle"
app:layout_constraintStart_toEndOf="@+id/song_album_cover" app:layout_constraintStart_toEndOf="@+id/song_album_cover"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" app:layout_constraintVertical_chainStyle="packed"
tools:text="Song Name" /> tools:text="Song Name" />
<TextView <TextView
android:id="@+id/song_info" android:id="@+id/song_info"
style="@style/Widget.Auxio.TextView.Item.Secondary" style="@style/Widget.Auxio.TextView.Item.Secondary"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_medium" android:layout_marginEnd="@dimen/spacing_medium"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/song_drag_handle" app:layout_constraintEnd_toStartOf="@+id/song_drag_handle"
app:layout_constraintStart_toEndOf="@+id/song_album_cover" app:layout_constraintStart_toEndOf="@+id/song_album_cover"
app:layout_constraintTop_toBottomOf="@+id/song_name" app:layout_constraintTop_toBottomOf="@+id/song_name"
tools:text="Artist / Album" /> tools:text="Artist / Album" />
<Button <Button
android:id="@+id/song_drag_handle" android:id="@+id/song_drag_handle"
style="@style/Widget.Auxio.Button.Icon.Small" style="@style/Widget.Auxio.Button.Icon.Small"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_mid_medium" android:layout_marginEnd="@dimen/spacing_mid_medium"
android:contentDescription="@string/desc_queue_handle" android:contentDescription="@string/desc_queue_handle"
app:icon="@drawable/ic_handle_24" app:icon="@drawable/ic_handle_24"
app:layout_constraintBottom_toBottomOf="@+id/song_album_cover" app:layout_constraintBottom_toBottomOf="@+id/song_album_cover"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/song_album_cover" /> app:layout_constraintTop_toTopOf="@+id/song_album_cover" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>