From 976507eaf0c8f201ff75db3c9f7aeafc05063c36 Mon Sep 17 00:00:00 2001 From: Brayan Oliveira <69634269+brayandso@users.noreply.github.com> Date: Sun, 30 Jun 2024 10:17:31 -0300 Subject: [PATCH] feat(new reviewer): immersive mode https://developer.android.com/develop/ui/views/layout/immersive magic numbers are used for the preferences values because they can be reported in analytics --- .../anki/previewer/CardViewerActivity.kt | 6 +++ .../ui/windows/reviewer/HideSystemBars.kt | 38 +++++++++++++++++++ .../ui/windows/reviewer/ReviewerFragment.kt | 32 ++++++++++++++++ .../src/main/res/values/10-preferences.xml | 13 ++++++- AnkiDroid/src/main/res/values/constants.xml | 19 ++++++++++ AnkiDroid/src/main/res/values/preferences.xml | 3 ++ .../src/main/res/xml/preferences_reviewer.xml | 10 ++++- 7 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/HideSystemBars.kt diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/previewer/CardViewerActivity.kt b/AnkiDroid/src/main/java/com/ichi2/anki/previewer/CardViewerActivity.kt index 07865796dcc7..962d22710428 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/previewer/CardViewerActivity.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/previewer/CardViewerActivity.kt @@ -18,6 +18,7 @@ package com.ichi2.anki.previewer import android.content.Context import android.content.Intent import android.os.Bundle +import androidx.activity.enableEdgeToEdge import com.ichi2.anki.SingleFragmentActivity import kotlin.reflect.KClass import kotlin.reflect.jvm.jvmName @@ -27,6 +28,11 @@ import kotlin.reflect.jvm.jvmName * @see TemplatePreviewerFragment */ class CardViewerActivity : SingleFragmentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + enableEdgeToEdge() // TODO assess moving this to SingleFragmentActivity + super.onCreate(savedInstanceState) + } + companion object { fun getIntent(context: Context, fragmentClass: KClass, arguments: Bundle? = null): Intent { return Intent(context, CardViewerActivity::class.java).apply { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/HideSystemBars.kt b/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/HideSystemBars.kt new file mode 100644 index 000000000000..af59eb254cd9 --- /dev/null +++ b/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/HideSystemBars.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 Brayan Oliveira + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 3 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +package com.ichi2.anki.ui.windows.reviewer + +import android.content.Context +import androidx.annotation.StringRes +import com.ichi2.anki.R +import com.ichi2.anki.preferences.sharedPrefs + +enum class HideSystemBars(@StringRes val valueRes: Int) { + NONE(R.string.hide_system_bars_none_value), + STATUS_BAR(R.string.hide_system_bars_status_bar_value), + NAVIGATION_BAR(R.string.hide_system_bars_navigation_bar_value), + ALL(R.string.hide_system_bars_all_value); + + companion object { + fun defaultValue(context: Context): String = context.getString(NONE.valueRes) + + fun from(context: Context): HideSystemBars { + val prefKey = context.getString(R.string.hide_system_bars_key) + val value = context.sharedPrefs().getString(prefKey, HideSystemBars.defaultValue(context)) + return entries.first { value == context.getString(it.valueRes) } + } + } +} diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/ReviewerFragment.kt b/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/ReviewerFragment.kt index e7641fbfbc4b..55d3c111c12c 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/ReviewerFragment.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/reviewer/ReviewerFragment.kt @@ -30,7 +30,11 @@ import androidx.appcompat.view.menu.MenuBuilder import androidx.appcompat.widget.ThemeUtils import androidx.appcompat.widget.Toolbar import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.WindowInsetsControllerCompat import androidx.core.view.isVisible +import androidx.core.view.updatePadding import androidx.fragment.app.viewModels import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope @@ -83,6 +87,7 @@ class ReviewerFragment : setupAnswerButtons(view) setupCounts(view) + setupImmersiveMode(view) view.findViewById(R.id.toolbar).apply { setOnMenuItemClickListener(this@ReviewerFragment) @@ -298,6 +303,33 @@ class ReviewerFragment : } } + private fun setupImmersiveMode(view: View) { + val hideSystemBarsSetting = HideSystemBars.from(requireContext()) + val barsToHide = when (hideSystemBarsSetting) { + HideSystemBars.NONE -> return + HideSystemBars.STATUS_BAR -> WindowInsetsCompat.Type.statusBars() + HideSystemBars.NAVIGATION_BAR -> WindowInsetsCompat.Type.navigationBars() + HideSystemBars.ALL -> WindowInsetsCompat.Type.systemBars() + } + + val window = requireActivity().window + with(WindowInsetsControllerCompat(window, window.decorView)) { + hide(barsToHide) + systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + } + + ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets -> + val bars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + v.updatePadding( + left = bars.left, + top = bars.top, + right = bars.right, + bottom = bars.bottom + ) + WindowInsetsCompat.CONSUMED + } + } + private val noteEditorLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.data?.getBooleanExtra(NoteEditor.RELOAD_REQUIRED_EXTRA_KEY, false) == true || diff --git a/AnkiDroid/src/main/res/values/10-preferences.xml b/AnkiDroid/src/main/res/values/10-preferences.xml index 61da788a90db..976dede5ab39 100644 --- a/AnkiDroid/src/main/res/values/10-preferences.xml +++ b/AnkiDroid/src/main/res/values/10-preferences.xml @@ -76,7 +76,7 @@ Allow touch gestures in screen corners Full screen navigation drawer Open navigation drawer when swiped right from anywhere on the screen - None + None Swipe up Swipe down Swipe left @@ -431,4 +431,15 @@ this formatter is used if the bind only applies to both the question and the ans Collection does not exist + + Hide system bars + None + Status bar + Navigation bar + All diff --git a/AnkiDroid/src/main/res/values/constants.xml b/AnkiDroid/src/main/res/values/constants.xml index a63dc1b90bd7..19614061d0e9 100644 --- a/AnkiDroid/src/main/res/values/constants.xml +++ b/AnkiDroid/src/main/res/values/constants.xml @@ -223,6 +223,25 @@ @string/sync_media_never_value + + @string/hide_system_bars_none + @string/hide_system_bars_status_bar + @string/hide_system_bars_navigation_bar + @string/hide_system_bars_all_bars + + + 0 + 1 + 2 + 3 + + + @string/hide_system_bars_none_value + @string/hide_system_bars_status_bar_value + @string/hide_system_bars_navigation_bar_value + @string/hide_system_bars_all_value + + @string/language diff --git a/AnkiDroid/src/main/res/values/preferences.xml b/AnkiDroid/src/main/res/values/preferences.xml index 614ba40e8e2d..0f885dbd17a5 100644 --- a/AnkiDroid/src/main/res/values/preferences.xml +++ b/AnkiDroid/src/main/res/values/preferences.xml @@ -199,4 +199,7 @@ openInstantEditor + + + hideSystemBars \ No newline at end of file diff --git a/AnkiDroid/src/main/res/xml/preferences_reviewer.xml b/AnkiDroid/src/main/res/xml/preferences_reviewer.xml index 06bf9b1e94cf..0c7e3bce6ea3 100644 --- a/AnkiDroid/src/main/res/xml/preferences_reviewer.xml +++ b/AnkiDroid/src/main/res/xml/preferences_reviewer.xml @@ -1,4 +1,12 @@ - + + \ No newline at end of file