diff --git a/app/build.gradle b/app/build.gradle index d2bb2f36b..3ddc1cfef 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,7 +17,7 @@ android { // API 33 is still busted, waiting until the XML element issue is fixed // noinspection OldTargetApi minSdk 21 - targetSdk 32 + targetSdk 33 buildFeatures { viewBinding true @@ -70,8 +70,8 @@ dependencies { // General implementation "androidx.core:core-ktx:1.8.0" - implementation "androidx.activity:activity-ktx:1.5.0" - implementation "androidx.fragment:fragment-ktx:1.5.0" + implementation "androidx.activity:activity-ktx:1.5.1" + implementation "androidx.fragment:fragment-ktx:1.5.1" // UI implementation "androidx.recyclerview:recyclerview:1.2.1" @@ -79,7 +79,7 @@ dependencies { implementation "androidx.viewpager2:viewpager2:1.1.0-beta01" // Lifecycle - def lifecycle_version = "2.5.0" + def lifecycle_version = "2.5.1" implementation "androidx.lifecycle:lifecycle-common:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" diff --git a/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt b/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt index 9776e7001..a31893b75 100644 --- a/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt +++ b/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt @@ -46,9 +46,8 @@ class AuxioApp : Application(), ImageLoaderFactory { .setLongLabel(getString(R.string.lbl_shuffle_shortcut_long)) .setIcon(IconCompat.createWithResource(this, R.drawable.ic_shortcut_shuffle_24)) .setIntent( - Intent(this, MainActivity::class.java).apply { - action = INTENT_KEY_SHORTCUT_SHUFFLE - }) + Intent(this, MainActivity::class.java) + .setAction(INTENT_KEY_SHORTCUT_SHUFFLE)) .build())) } diff --git a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt index 37619f679..05fdf113a 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt @@ -44,8 +44,6 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat * * TODO: Add multi-select * - * TODO: Find better way to handler recycler divider visibility - * * @author OxygenCobalt */ class MainActivity : AppCompatActivity() { diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt index b984004e5..04052b8c7 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt @@ -22,12 +22,13 @@ import android.view.LayoutInflater import android.view.ViewTreeObserver import android.view.WindowInsets import androidx.activity.OnBackPressedCallback +import androidx.core.view.ViewCompat import androidx.core.view.isInvisible import androidx.core.view.updatePadding import androidx.fragment.app.activityViewModels import androidx.navigation.findNavController import androidx.navigation.fragment.findNavController -import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.NeoBottomSheetBehavior import com.google.android.material.shape.MaterialShapeDrawable import com.google.android.material.transition.MaterialFadeThrough import kotlin.math.max @@ -74,14 +75,20 @@ class MainFragment : insets } - val playbackSheetBehavior = - binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior + // Send meaningful accessibility events for bottom sheets + ViewCompat.setAccessibilityPaneTitle( + binding.playbackSheet, getString(R.string.lbl_playback)) + ViewCompat.setAccessibilityPaneTitle(binding.queueSheet, getString(R.string.lbl_queue)) + val queueSheetBehavior = binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior? if (queueSheetBehavior != null) { + val playbackSheetBehavior = + binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior + unlikelyToBeNull(binding.handleWrapper).setOnClickListener { - if (playbackSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED && - queueSheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED) { - queueSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED + if (playbackSheetBehavior.state == NeoBottomSheetBehavior.STATE_EXPANDED && + queueSheetBehavior.state == NeoBottomSheetBehavior.STATE_COLLAPSED) { + queueSheetBehavior.state = NeoBottomSheetBehavior.STATE_EXPANDED } } } else { @@ -161,7 +168,7 @@ class MainFragment : if (playbackModel.song.value != null) { // Hack around the playback sheet intercepting swipe events on the queue bar playbackSheetBehavior.isDraggable = - queueSheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED + queueSheetBehavior.state == NeoBottomSheetBehavior.STATE_COLLAPSED } } else { // No queue sheet, fade normally based on the playback sheet @@ -233,9 +240,9 @@ class MainFragment : val playbackSheetBehavior = binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior - if (playbackSheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED) { + if (playbackSheetBehavior.state == NeoBottomSheetBehavior.STATE_COLLAPSED) { // State is collapsed and non-hidden, expand - playbackSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED + playbackSheetBehavior.state = NeoBottomSheetBehavior.STATE_EXPANDED } } @@ -244,13 +251,13 @@ class MainFragment : val playbackSheetBehavior = binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior - if (playbackSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) { + if (playbackSheetBehavior.state == NeoBottomSheetBehavior.STATE_EXPANDED) { // Make sure the queue is also collapsed here. val queueSheetBehavior = binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior? - playbackSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED - queueSheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED + playbackSheetBehavior.state = NeoBottomSheetBehavior.STATE_COLLAPSED + queueSheetBehavior?.state = NeoBottomSheetBehavior.STATE_COLLAPSED } } @@ -259,7 +266,7 @@ class MainFragment : val playbackSheetBehavior = binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior - if (playbackSheetBehavior.state == BottomSheetBehavior.STATE_HIDDEN) { + if (playbackSheetBehavior.state == NeoBottomSheetBehavior.STATE_HIDDEN) { val queueSheetBehavior = binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior? @@ -269,7 +276,7 @@ class MainFragment : playbackSheetBehavior.apply { // Make sure the view is draggable, at least until the draw checks kick in. isDraggable = true - state = BottomSheetBehavior.STATE_COLLAPSED + state = NeoBottomSheetBehavior.STATE_COLLAPSED } } } @@ -279,7 +286,7 @@ class MainFragment : val playbackSheetBehavior = binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior - if (playbackSheetBehavior.state != BottomSheetBehavior.STATE_HIDDEN) { + if (playbackSheetBehavior.state != NeoBottomSheetBehavior.STATE_HIDDEN) { val queueSheetBehavior = binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior? @@ -287,12 +294,12 @@ class MainFragment : queueSheetBehavior?.apply { isDraggable = false - state = BottomSheetBehavior.STATE_COLLAPSED + state = NeoBottomSheetBehavior.STATE_COLLAPSED } playbackSheetBehavior.apply { isDraggable = false - state = BottomSheetBehavior.STATE_HIDDEN + state = NeoBottomSheetBehavior.STATE_HIDDEN } } } @@ -314,17 +321,17 @@ class MainFragment : binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior? if (queueSheetBehavior != null && - queueSheetBehavior.state != BottomSheetBehavior.STATE_COLLAPSED && - playbackSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) { + queueSheetBehavior.state != NeoBottomSheetBehavior.STATE_COLLAPSED && + playbackSheetBehavior.state == NeoBottomSheetBehavior.STATE_EXPANDED) { // Collapse the queue first if it is expanded. - queueSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED + queueSheetBehavior.state = NeoBottomSheetBehavior.STATE_COLLAPSED return } - if (playbackSheetBehavior.state != BottomSheetBehavior.STATE_COLLAPSED && - playbackSheetBehavior.state != BottomSheetBehavior.STATE_HIDDEN) { + if (playbackSheetBehavior.state != NeoBottomSheetBehavior.STATE_COLLAPSED && + playbackSheetBehavior.state != NeoBottomSheetBehavior.STATE_HIDDEN) { // Then collapse the playback sheet. - playbackSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED + playbackSheetBehavior.state = NeoBottomSheetBehavior.STATE_COLLAPSED return } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBarFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBarFragment.kt index 7d4afef3b..706b1d3f5 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBarFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBarFragment.kt @@ -20,7 +20,6 @@ package org.oxycblt.auxio.playback import android.os.Bundle import android.view.LayoutInflater import androidx.fragment.app.activityViewModels -import kotlin.math.max import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.FragmentPlaybackBarBinding import org.oxycblt.auxio.music.Song @@ -33,8 +32,8 @@ import org.oxycblt.auxio.util.getColorStateListSafe import org.oxycblt.auxio.util.textSafe /** - * A fragment showing the current playback state in a compact manner. Placed at the bottom of the - * screen. This expands into [PlaybackPanelFragment]. + * A fragment showing the current playback state in a compact manner. Used as the bar for the + * playback sheet. * @author OxygenCobalt */ class PlaybackBarFragment : ViewBindingFragment() { diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt index ae70ca67a..9f455004d 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt @@ -25,7 +25,6 @@ import android.view.View import androidx.core.view.isInvisible import androidx.recyclerview.widget.RecyclerView import com.google.android.material.shape.MaterialShapeDrawable -import java.util.* import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.ItemQueueSongBinding @@ -107,7 +106,7 @@ private constructor( get() = binding.interactBody.isActivated set(value) { // Activation does not affect clicking, make everything activated. - binding.interactBody.setActivated(value) + binding.interactBody.isActivated = value } init { diff --git a/app/src/main/java/org/oxycblt/auxio/util/FrameworkUtil.kt b/app/src/main/java/org/oxycblt/auxio/util/FrameworkUtil.kt index 01186b86d..5ef93e57d 100644 --- a/app/src/main/java/org/oxycblt/auxio/util/FrameworkUtil.kt +++ b/app/src/main/java/org/oxycblt/auxio/util/FrameworkUtil.kt @@ -22,7 +22,6 @@ import android.content.Context import android.content.res.ColorStateList import android.database.Cursor import android.database.sqlite.SQLiteDatabase -import android.graphics.Insets import android.graphics.drawable.Drawable import android.os.Build import android.view.View @@ -30,8 +29,10 @@ import android.view.WindowInsets import android.widget.TextView import androidx.activity.viewModels import androidx.annotation.ColorRes +import androidx.annotation.RequiresApi import androidx.appcompat.app.AppCompatActivity import androidx.coordinatorlayout.widget.CoordinatorLayout +import androidx.core.graphics.Insets import androidx.core.graphics.drawable.DrawableCompat import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels @@ -251,9 +252,9 @@ val WindowInsets.systemBarInsetsCompat: Insets get() = when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> { - getInsets(WindowInsets.Type.systemBars()) + getCompatInsets(WindowInsets.Type.systemBars()) } - else -> systemWindowInsetsCompat + else -> getSystemWindowCompatInsets() } /** @@ -271,23 +272,30 @@ val WindowInsets.systemGestureInsetsCompat: Insets when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> { Insets.max( - getInsets(WindowInsets.Type.systemGestures()), - getInsets(WindowInsets.Type.systemBars())) + getCompatInsets(WindowInsets.Type.systemGestures()), + getCompatInsets(WindowInsets.Type.systemBars())) } Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> { - @Suppress("DEPRECATION") Insets.max(systemGestureInsets, systemBarInsetsCompat) + @Suppress("DEPRECATION") + Insets.max(getSystemGestureCompatInsets(), getSystemWindowCompatInsets()) } - else -> systemWindowInsetsCompat + else -> getSystemWindowCompatInsets() } @Suppress("DEPRECATION") -val WindowInsets.systemWindowInsetsCompat: Insets - get() = - Insets.of( - systemWindowInsetLeft, - systemWindowInsetTop, - systemWindowInsetRight, - systemWindowInsetBottom) +fun WindowInsets.getSystemWindowCompatInsets() = + Insets.of( + systemWindowInsetLeft, + systemWindowInsetTop, + systemWindowInsetRight, + systemWindowInsetBottom) + +@Suppress("DEPRECATION") +@RequiresApi(Build.VERSION_CODES.Q) +fun WindowInsets.getSystemGestureCompatInsets() = Insets.toCompatInsets(systemGestureInsets) + +@RequiresApi(Build.VERSION_CODES.R) +fun WindowInsets.getCompatInsets(typeMask: Int) = Insets.toCompatInsets(getInsets(typeMask)) /** * Replaces the system bar insets in a version-aware manner. This can be used to modify the insets @@ -302,7 +310,9 @@ fun WindowInsets.replaceSystemBarInsetsCompat( return when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> { WindowInsets.Builder(this) - .setInsets(WindowInsets.Type.systemBars(), Insets.of(left, top, right, bottom)) + .setInsets( + WindowInsets.Type.systemBars(), + Insets.of(left, top, right, bottom).toPlatformInsets()) .build() } else -> { diff --git a/app/src/main/java/org/oxycblt/auxio/util/LogUtil.kt b/app/src/main/java/org/oxycblt/auxio/util/LogUtil.kt index 5b7ed3a52..4561484e8 100644 --- a/app/src/main/java/org/oxycblt/auxio/util/LogUtil.kt +++ b/app/src/main/java/org/oxycblt/auxio/util/LogUtil.kt @@ -99,6 +99,8 @@ private val Any.autoTag: String * KURDISTAN WORKERS PARTY KÜRDISTAN İŞÇI PARTISI (PKK) * * TORTURE AND ASSASSINATION OF JAMAL KHASHOGGI مقتل جمال خاشقجي + * + * UNITED ARAB EMIRATES ENSLAVED MIGRANT WORKERS */ private fun basedCopyleftNotice() { if (BuildConfig.APPLICATION_ID != "org.oxycblt.auxio" && diff --git a/app/src/main/res/drawable/ui_queue_drag_handle.xml b/app/src/main/res/drawable/ui_queue_drag_handle.xml new file mode 100644 index 000000000..cf53b046f --- /dev/null +++ b/app/src/main/res/drawable/ui_queue_drag_handle.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml index 5b70dd4c3..e54a712d3 100644 --- a/app/src/main/res/layout/fragment_main.xml +++ b/app/src/main/res/layout/fragment_main.xml @@ -40,8 +40,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - app:layout_behavior="org.oxycblt.auxio.playback.queue.QueueSheetBehavior" - app:behavior_hideable="false"> + app:layout_behavior="org.oxycblt.auxio.playback.queue.QueueSheetBehavior"> diff --git a/build.gradle b/build.gradle index d82580729..cca8f7776 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext.kotlin_version = '1.7.10' - ext.navigation_version = "2.5.0" + ext.navigation_version = "2.5.1" repositories { google() @@ -9,7 +9,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.2.1' + classpath 'com.android.tools.build:gradle:7.2.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigation_version" classpath "com.diffplug.spotless:spotless-plugin-gradle:6.6.1"