ui: fix lollipop bugs

Fix more lollipop bugs, as I usually do. Except for the drawing
issues I may or may not have produced. Don't really care enough to
fix them though.
This commit is contained in:
OxygenCobalt 2022-08-05 11:47:26 -06:00
parent e12c7cb419
commit 5978e124d2
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
14 changed files with 85 additions and 93 deletions

View file

@ -44,9 +44,6 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat
*
* TODO: Add multi-select
*
* LEFT-OFF: Add RecyclerView styles, queue issue is caused by tiny scroll and then replace op, not
* enough to change scroll apparently
*
* @author OxygenCobalt
*/
class MainActivity : AppCompatActivity() {

View file

@ -128,9 +128,6 @@ private constructor(
binding.background.isInvisible = true
binding.songName.requestLayout()
binding.songInfo.requestLayout()
binding.body.setOnClickListener { listener.onClick(this) }
// Roll our own drag handlers as the default ones suck

View file

@ -49,12 +49,14 @@ class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemList
binding.queueRecycler.apply {
adapter = queueAdapter
touchHelper.attachToRecyclerView(this)
// Sometimes the scroll can change without the listener being updated, so we also
// check for relayout events.
addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> invalidateDivider() }
addOnScrollListener(
object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
binding.queueDivider.isInvisible =
(layoutManager as LinearLayoutManager)
.findFirstCompletelyVisibleItemPosition() < 1
invalidateDivider()
}
})
}
@ -78,6 +80,8 @@ class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemList
}
private fun updateQueue(queue: List<Song>, index: Int) {
val binding = requireBinding()
val replaceQueue = queueModel.replaceQueue
if (replaceQueue == true) {
logD("Replacing queue")
@ -87,11 +91,14 @@ class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemList
queueAdapter.data.submitList(queue)
}
binding.queueDivider.isInvisible =
(binding.queueRecycler.layoutManager as LinearLayoutManager)
.findFirstCompletelyVisibleItemPosition() < 1
queueModel.finishReplace()
val scrollTo = queueModel.scrollTo
if (scrollTo != null) {
val binding = requireBinding()
val lmm = binding.queueRecycler.layoutManager as LinearLayoutManager
val start = lmm.findFirstCompletelyVisibleItemPosition()
val end = lmm.findLastCompletelyVisibleItemPosition()
@ -106,4 +113,11 @@ class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemList
queueAdapter.updateIndex(index)
}
private fun invalidateDivider() {
val binding = requireBinding()
binding.queueDivider.isInvisible =
(binding.queueRecycler.layoutManager as LinearLayoutManager)
.findFirstCompletelyVisibleItemPosition() < 1
}
}

View file

@ -17,7 +17,6 @@
package org.oxycblt.auxio.settings
import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.annotation.DrawableRes
@ -154,45 +153,38 @@ class SettingsListFragment : PreferenceFragmentCompat() {
if (!preference.isVisible) return
if (preference is PreferenceCategory) {
for (child in preference.children) {
setupPreference(child)
}
preference.children.forEach(::setupPreference)
return
}
preference.apply {
when (key) {
context.getString(R.string.set_key_theme) -> {
// Android 12 is the first version I deem to have universal dark and light
// mode toggles. No need for our setting.
isVisible = Build.VERSION.SDK_INT < Build.VERSION_CODES.S
when (preference.key) {
context.getString(R.string.set_key_theme) -> {
preference.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, value ->
AppCompatDelegate.setDefaultNightMode(value as Int)
true
}
}
context.getString(R.string.set_key_accent) -> {
preference.summary = context.getString(settings.accent.name)
}
context.getString(R.string.set_key_black_theme) -> {
preference.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, _ ->
if (context.isNight) {
context.recreate()
}
onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, value ->
AppCompatDelegate.setDefaultNightMode(value as Int)
true
}
}
context.getString(R.string.set_key_accent) -> {
summary = context.getString(settings.accent.name)
}
context.getString(R.string.set_key_black_theme) -> {
onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, _ ->
if (context.isNight) {
context.recreate()
}
true
}
}
context.getString(R.string.set_key_show_covers),
context.getString(R.string.set_key_quality_covers) -> {
onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, _ ->
Coil.imageLoader(context).apply { this.memoryCache?.clear() }
true
}
}
true
}
}
context.getString(R.string.set_key_show_covers),
context.getString(R.string.set_key_quality_covers) -> {
preference.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, _ ->
Coil.imageLoader(context).memoryCache?.clear()
true
}
}
}
}

View file

@ -20,6 +20,7 @@ package org.oxycblt.auxio.ui
import android.content.Context
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.LayerDrawable
import android.os.Build
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
@ -79,8 +80,12 @@ abstract class AuxioSheetBehavior<V : View>(context: Context, attributeSet: Attr
context.getAttrColorCompat(R.attr.colorSurface).defaultColor),
sheetBackgroundDrawable))
// Try to disable drop shadows if possible.
disableDropShadowCompat()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val transparent =
context.getColorCompat(android.R.color.transparent).defaultColor
outlineAmbientShadowColor = transparent
outlineSpotShadowColor = transparent
}
setOnApplyWindowInsetsListener(::applyWindowInsets)
}

View file

@ -55,11 +55,7 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
override fun onScrolled(dx: Int, dy: Int) {
super.onScrolled(dx, dy)
val manager = layoutManager as LinearLayoutManager
topDivider.isInvisible = manager.findFirstCompletelyVisibleItemPosition() < 1
bottomDivider.isInvisible =
manager.findLastCompletelyVisibleItemPosition() == (manager.itemCount - 1)
invalidateDividers()
}
override fun onMeasure(widthSpec: Int, heightSpec: Int) {
@ -88,5 +84,13 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
super.onLayout(changed, l, t, r, b)
topDivider.layout(l, spacingMedium, r, spacingMedium + topDivider.measuredHeight)
bottomDivider.layout(l, measuredHeight - bottomDivider.measuredHeight, r, b)
invalidateDividers()
}
private fun invalidateDividers() {
val manager = layoutManager as LinearLayoutManager
topDivider.isInvisible = manager.findFirstCompletelyVisibleItemPosition() < 1
bottomDivider.isInvisible =
manager.findLastCompletelyVisibleItemPosition() == (manager.itemCount - 1)
}
}

View file

@ -47,18 +47,6 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
import org.oxycblt.auxio.R
/**
* Disables drop shadows on a view programmatically in a version-compatible manner. This only works
* on Android 9 and above. Below that version, shadows will remain visible.
*/
fun View.disableDropShadowCompat() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val transparent = context.getColorCompat(android.R.color.transparent).defaultColor
outlineAmbientShadowColor = transparent
outlineSpotShadowColor = transparent
}
}
/**
* Determines if the point given by [x] and [y] falls within this view.
* @param minTouchTargetSize The minimum touch size, independent of the view's size (Optional)

View file

@ -34,8 +34,7 @@ fun Any.logD(obj: Any?) = logD("$obj")
* objects
*/
fun Any.logD(msg: String) {
if (BuildConfig.DEBUG) {
basedCopyleftNotice()
if (BuildConfig.DEBUG && !basedCopyleftNotice()) {
Log.d(autoTag, msg)
}
}
@ -58,18 +57,6 @@ fun Any.logEOrThrow(msg: String) {
}
}
/**
* Logs an error in production while still throwing it in debug mode. This is useful for
* non-showstopper bugs that I would still prefer to be caught in debug mode.
*/
fun Throwable.logTraceOrThrow() {
if (BuildConfig.DEBUG) {
throw this
} else {
logE(stackTraceToString())
}
}
/** Automatically creates a tag that identifies the object currently logging. */
private val Any.autoTag: String
get() = "Auxio.${this::class.simpleName ?: "Anonymous Object"}"
@ -84,31 +71,33 @@ private val Any.autoTag: String
*
* JUNE 1989 TIANAMEN SQUARE PROTESTS AND MASSACRE 六四事件
*
* KASHMIR INDEPENDENCE MOVEMENT
* 2022 RUSSIAN INVASION OF UKRAINE Вторжение России на Украину
*
* WOMEN'S RIGHTS IN THE ISLAMIC REPUBLIC OF IRAN حقوق زنان در ایران
*
* FREE TIBET 西藏自由
*
* 1971 BANGLADESHI GENOCIDE BY PAKISTAN
*
* 2022 RUSSIAN INVASION OF UKRAINE Вторжение России на Украину
*
* UYGHUR GENOCIDE/XINJIANG INTERNMENT CAMPS 新疆种族灭绝指控/新疆再教育營
*
* KURDISTAN WORKERS PARTY KÜRDISTAN İŞÇI PARTISI (PKK)
* KASHMIR INDEPENDENCE MOVEMENT
*
* TORTURE AND ASSASSINATION OF JAMAL KHASHOGGI مقتل جمال خاشقجي
* FREE TIBET 西藏自由
*
* 1915-1916 ARMENIAN GENOCIDE Ermeni Kırımı
*
* 2018 TORTURE AND ASSASSINATION OF JAMAL KHASHOGGI مقتل جمال خاشقجي
*
* UNITED ARAB EMIRATES ENSLAVED MIGRANT WORKERS
*/
@Suppress("KotlinConstantConditions")
private fun basedCopyleftNotice() {
private fun basedCopyleftNotice(): Boolean {
if (BuildConfig.APPLICATION_ID != "org.oxycblt.auxio" &&
BuildConfig.APPLICATION_ID != "org.oxycblt.auxio.debug") {
Log.d(
"Auxio Project",
"Friendly reminder: Auxio is licensed under the " +
"GPLv3 and all derivative apps must be made open source!")
return true
}
return false
}

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Widget.Auxio.RecyclerView.Grid" parent="Widget.Auxio.RecyclerView.Grid.Base">
<item name="spanCount">3</item>
</style>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="enable_theme_settings">false</bool>
</resources>

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="enable_theme_settings">true</bool>
<!-- Note: The old way of naming keys was to prefix them with KEY_. Now it's to prefix them with auxio_. -->
<string name="set_key_theme" translatable="false">KEY_THEME2</string>
<string name="set_key_black_theme" translatable="false">KEY_BLACK_THEME</string>

View file

@ -2,7 +2,7 @@
<resources>
<!-- Master parent theme -->
<style name="Theme.Auxio" parent="Theme.Material3.DynamicColors.DayNight" />
<!-- Adds nicer selector attributes not supported on lollipop-->
<!-- Adds nicer selector attributes not supported on lollipop -->
<style name="Theme.Auxio.V23" parent="Theme.Auxio" />
<!-- Handles edge-to-edge on other styles variants -->
<style name="Theme.Auxio.V27" parent="Theme.Auxio.V23">

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- SHARED RE-USABLE UI STYLES -->
<style name="Widget.Auxio.AppBarLayout" parent="Widget.Material3.AppBarLayout">

View file

@ -8,6 +8,7 @@
app:entryIcons="@array/icons_theme"
app:entryValues="@array/values_theme"
app:icon="@drawable/ic_light_24"
app:isPreferenceVisible="@bool/enable_theme_settings"
app:key="@string/set_key_theme"
app:title="@string/set_theme" />