From c929357d76acaffce2bb391414609ea14c61796a Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Tue, 7 Jun 2022 17:14:02 -0600 Subject: [PATCH] ui: add edge-to-edge toggle Add a toggle for edge-to-edge mode. Normally we would want to enable edge-to-edge by default (in fact, we still do). However, some phones (once again, samsung) don't provide Auxio with actual window insets. As a result, we need to add a toggle so that it can be disabled on busted devices. Did you know that even when Auxio has it's edge-to-edge functionality busted, Samsung Music works just fine? Very interesting. Resolves #149. --- .../java/org/oxycblt/auxio/MainActivity.kt | 42 +++++++++++++------ .../auxio/settings/SettingsListFragment.kt | 19 ++++++--- .../oxycblt/auxio/settings/SettingsManager.kt | 5 +++ .../org/oxycblt/auxio/util/FrameworkUtil.kt | 5 ++- app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/prefs_main.xml | 8 ++++ 6 files changed, 61 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt index 576e4f152..c6dbcbbef 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt @@ -32,6 +32,8 @@ import org.oxycblt.auxio.music.IndexerService import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.system.PlaybackService import org.oxycblt.auxio.settings.SettingsManager +import org.oxycblt.auxio.ui.accent.Accent +import org.oxycblt.auxio.util.getColorSafe import org.oxycblt.auxio.util.isNight import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.systemBarInsetsCompat @@ -54,11 +56,13 @@ class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setupTheme() + val settingsManager = SettingsManager.getInstance() + + setupTheme(settingsManager.theme, settingsManager.accent, settingsManager.useBlackTheme) val binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) - applyEdgeToEdgeWindow(binding.root) + setupEdgeToEdge(binding.root, settingsManager.edgeToEdge) logD("Activity created") } @@ -87,9 +91,12 @@ class MainActivity : AppCompatActivity() { } } + /** + * Extracts a [Uri] from an intent as long as: + * - The intent is ACTION_VIEW + * - The intent has not already been used. + */ private fun retrieveViewUri(intent: Intent?): Uri? { - // If this intent is a valid view intent that has not been used already, give it - // to PlaybackViewModel to be used later. if (intent != null) { val action = intent.action val isConsumed = intent.getBooleanExtra(KEY_INTENT_USED, false) @@ -104,22 +111,18 @@ class MainActivity : AppCompatActivity() { return null } - private fun setupTheme() { - val settingsManager = SettingsManager.getInstance() - + private fun setupTheme(theme: Int, accent: Accent, useBlackTheme: Boolean) { // Disable theme customization above Android 12, as it's far enough in as a version to // the point where most phones should have an automatic option for light/dark theming. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { - AppCompatDelegate.setDefaultNightMode(settingsManager.theme) + AppCompatDelegate.setDefaultNightMode(theme) } else { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) } - val accent = settingsManager.accent - // The black theme has a completely separate set of styles since style attributes cannot // be modified at runtime. - if (isNight && settingsManager.useBlackTheme) { + if (isNight && useBlackTheme) { logD("Applying black theme [accent $accent]") setTheme(accent.blackTheme) } else { @@ -128,8 +131,21 @@ class MainActivity : AppCompatActivity() { } } - private fun applyEdgeToEdgeWindow(contentView: View) { - WindowCompat.setDecorFitsSystemWindows(window, false) + private fun setupEdgeToEdge(contentView: View, enabled: Boolean) { + val fitsSystemWindows = !enabled + WindowCompat.setDecorFitsSystemWindows(window, fitsSystemWindows) + if (fitsSystemWindows) { + // Auxio's theme is normally set up to anticipate edge to edge mode being + // enabled. In the case that it is not, we have to update the values during + // runtime. + val controller = WindowCompat.getInsetsController(window, window.decorView) + val black = getColorSafe(android.R.color.black) + + window.statusBarColor = black + controller.isAppearanceLightStatusBars = false + window.navigationBarColor = black + controller.isAppearanceLightNavigationBars = false + } contentView.setOnApplyWindowInsetsListener { view, insets -> val bars = insets.systemBarInsetsCompat diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt index 5ac98a832..234e7bae4 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt @@ -122,6 +122,15 @@ class SettingsListFragment : PreferenceFragmentCompat() { true } } + SettingsManager.KEY_ACCENT -> { + onPreferenceClickListener = + Preference.OnPreferenceClickListener { + AccentDialog().show(childFragmentManager, AccentDialog.TAG) + true + } + + summary = context.getString(settingsManager.accent.name) + } SettingsManager.KEY_BLACK_THEME -> { onPreferenceClickListener = Preference.OnPreferenceClickListener { @@ -132,14 +141,12 @@ class SettingsListFragment : PreferenceFragmentCompat() { true } } - SettingsManager.KEY_ACCENT -> { - onPreferenceClickListener = - Preference.OnPreferenceClickListener { - AccentDialog().show(childFragmentManager, AccentDialog.TAG) + SettingsManager.KEY_EDGE_TO_EDGE -> { + onPreferenceChangeListener = + Preference.OnPreferenceChangeListener { _, _ -> + requireActivity().recreate() true } - - summary = context.getString(settingsManager.accent.name) } SettingsManager.KEY_LIB_TABS -> { onPreferenceClickListener = diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt index 16e506a02..266859c9d 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt @@ -62,6 +62,10 @@ class SettingsManager private constructor(context: Context) : } } + /** Whether edge-to-edge is enabled. */ + val edgeToEdge: Boolean + get() = inner.getBoolean(KEY_EDGE_TO_EDGE, true) + /** * Whether to display the RepeatMode or the shuffle status on the notification. False if repeat, * true if shuffle. @@ -304,6 +308,7 @@ class SettingsManager private constructor(context: Context) : const val KEY_THEME = "KEY_THEME2" const val KEY_BLACK_THEME = "KEY_BLACK_THEME" const val KEY_ACCENT = "auxio_accent2" + const val KEY_EDGE_TO_EDGE = "auxio_edge" const val KEY_LIB_TABS = "auxio_lib_tabs" const val KEY_SHOW_COVERS = "KEY_SHOW_COVERS" 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 dc57d7550..9f59c7d9f 100644 --- a/app/src/main/java/org/oxycblt/auxio/util/FrameworkUtil.kt +++ b/app/src/main/java/org/oxycblt/auxio/util/FrameworkUtil.kt @@ -173,7 +173,10 @@ fun Fragment.launch( * bit of a dumb hack with [combine], as when we have to combine flows, we often just want to call * the same block with both functions, and not do any transformations. */ -suspend fun Flow.collectWith(other: Flow, block: suspend (T1, T2) -> Unit) { +suspend inline fun Flow.collectWith( + other: Flow, + crossinline block: (T1, T2) -> Unit +) { combine(this, other) { a, b -> a to b }.collect { block(it.first, it.second) } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 745100758..19dbe5ad4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -76,6 +76,8 @@ Color scheme Black theme Use a pure-black dark theme + Edge-to-edge + May not work on all devices Display Library tabs diff --git a/app/src/main/res/xml/prefs_main.xml b/app/src/main/res/xml/prefs_main.xml index 2458059f7..c4994105f 100644 --- a/app/src/main/res/xml/prefs_main.xml +++ b/app/src/main/res/xml/prefs_main.xml @@ -27,6 +27,14 @@ app:summary="@string/set_black_mode_desc" app:title="@string/set_black_mode" /> + +