diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 0ce869d62..704752c40 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -1,6 +1,7 @@ package eu.kanade.tachiyomi.data.preference import android.content.Context +import android.content.res.Configuration import android.os.Environment import androidx.core.content.edit import androidx.core.net.toUri @@ -10,6 +11,7 @@ import com.tfcporciuncula.flow.Preference import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode +import eu.kanade.tachiyomi.data.preference.PreferenceValues.ThemeMode.* import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.anilist.Anilist import eu.kanade.tachiyomi.ui.reader.setting.OrientationType @@ -84,7 +86,7 @@ class PreferencesHelper(val context: Context) { fun showLibraryUpdateErrors() = prefs.getBoolean(Keys.showLibraryUpdateErrors, true) - fun themeMode() = flowPrefs.getEnum(Keys.themeMode, Values.ThemeMode.system) + fun themeMode() = flowPrefs.getEnum(Keys.themeMode, system) fun themeLight() = flowPrefs.getEnum(Keys.themeLight, Values.LightThemeVariant.default) @@ -322,4 +324,15 @@ class PreferencesHelper(val context: Context) { putInt(Keys.defaultChapterSortByAscendingOrDescending, if (manga.sortDescending()) Manga.CHAPTER_SORT_DESC else Manga.CHAPTER_SORT_ASC) } } + + fun isDarkMode(): Boolean { + return when (themeMode().get()) { + light -> false + dark -> true + system -> { + context.applicationContext.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == + Configuration.UI_MODE_NIGHT_YES + } + } + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt index f5e22cf68..28c9bffab 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt @@ -1,14 +1,11 @@ package eu.kanade.tachiyomi.ui.base.activity -import android.content.res.Configuration.UI_MODE_NIGHT_MASK -import android.content.res.Configuration.UI_MODE_NIGHT_YES import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferenceValues.DarkThemeVariant import eu.kanade.tachiyomi.data.preference.PreferenceValues.LightThemeVariant -import eu.kanade.tachiyomi.data.preference.PreferenceValues.ThemeMode import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.asImmediateFlow import eu.kanade.tachiyomi.util.view.setSecureScreen @@ -22,29 +19,7 @@ abstract class BaseThemedActivity : AppCompatActivity() { val preferences: PreferencesHelper by injectLazy() override fun onCreate(savedInstanceState: Bundle?) { - val isDarkMode = when (preferences.themeMode().get()) { - ThemeMode.light -> false - ThemeMode.dark -> true - ThemeMode.system -> resources.configuration.uiMode and UI_MODE_NIGHT_MASK == UI_MODE_NIGHT_YES - } - val themeId = if (isDarkMode) { - when (preferences.themeDark().get()) { - DarkThemeVariant.default -> R.style.Theme_Tachiyomi_Dark - DarkThemeVariant.blue -> R.style.Theme_Tachiyomi_Dark_Blue - DarkThemeVariant.greenapple -> R.style.Theme_Tachiyomi_Dark_GreenApple - DarkThemeVariant.midnightdusk -> R.style.Theme_Tachiyomi_Dark_MidnightDusk - DarkThemeVariant.amoled -> R.style.Theme_Tachiyomi_Amoled - DarkThemeVariant.hotpink -> R.style.Theme_Tachiyomi_Amoled_HotPink - } - } else { - when (preferences.themeLight().get()) { - LightThemeVariant.default -> R.style.Theme_Tachiyomi_Light - LightThemeVariant.blue -> R.style.Theme_Tachiyomi_Light_Blue - LightThemeVariant.strawberrydaiquiri -> R.style.Theme_Tachiyomi_Light_StrawberryDaiquiri - LightThemeVariant.yotsuba -> R.style.Theme_Tachiyomi_Light_Yotsuba - } - } - setTheme(themeId) + setTheme(getThemeResourceId(preferences)) Injekt.get().incognitoMode() .asImmediateFlow { @@ -54,4 +29,26 @@ abstract class BaseThemedActivity : AppCompatActivity() { super.onCreate(savedInstanceState) } + + companion object { + fun getThemeResourceId(preferences: PreferencesHelper): Int { + return if (preferences.isDarkMode()) { + when (preferences.themeDark().get()) { + DarkThemeVariant.default -> R.style.Theme_Tachiyomi_Dark + DarkThemeVariant.blue -> R.style.Theme_Tachiyomi_Dark_Blue + DarkThemeVariant.greenapple -> R.style.Theme_Tachiyomi_Dark_GreenApple + DarkThemeVariant.midnightdusk -> R.style.Theme_Tachiyomi_Dark_MidnightDusk + DarkThemeVariant.amoled -> R.style.Theme_Tachiyomi_Amoled + DarkThemeVariant.hotpink -> R.style.Theme_Tachiyomi_Amoled_HotPink + } + } else { + when (preferences.themeLight().get()) { + LightThemeVariant.default -> R.style.Theme_Tachiyomi_Light + LightThemeVariant.blue -> R.style.Theme_Tachiyomi_Light_Blue + LightThemeVariant.strawberrydaiquiri -> R.style.Theme_Tachiyomi_Light_StrawberryDaiquiri + LightThemeVariant.yotsuba -> R.style.Theme_Tachiyomi_Light_Yotsuba + } + } + } + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index dd5ccca66..754d1295f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -6,11 +6,13 @@ import android.app.ProgressDialog import android.content.ClipData import android.content.Context import android.content.Intent +import android.content.res.ColorStateList import android.graphics.Bitmap import android.graphics.Color import android.graphics.ColorMatrix import android.graphics.ColorMatrixColorFilter import android.graphics.Paint +import android.graphics.drawable.ColorDrawable import android.os.Build import android.os.Bundle import android.view.KeyEvent @@ -23,12 +25,14 @@ import android.view.animation.Animation import android.view.animation.AnimationUtils import android.widget.SeekBar import android.widget.Toast -import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat +import androidx.core.view.WindowInsetsControllerCompat import androidx.core.view.isVisible -import androidx.core.view.setPadding import androidx.lifecycle.lifecycleScope import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView +import com.google.android.material.shape.MaterialShapeDrawable +import dev.chrisbanes.insetter.applyInsetter import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Manga @@ -38,6 +42,7 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.toggle import eu.kanade.tachiyomi.databinding.ReaderActivityBinding import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity +import eu.kanade.tachiyomi.ui.base.activity.BaseThemedActivity import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.AddToLibraryFirst @@ -55,12 +60,8 @@ import eu.kanade.tachiyomi.util.storage.getUriCompat import eu.kanade.tachiyomi.util.system.GLUtil import eu.kanade.tachiyomi.util.system.hasDisplayCutout import eu.kanade.tachiyomi.util.system.toast -import eu.kanade.tachiyomi.util.view.defaultBar -import eu.kanade.tachiyomi.util.view.hideBar -import eu.kanade.tachiyomi.util.view.isDefaultBar import eu.kanade.tachiyomi.util.view.popupMenu import eu.kanade.tachiyomi.util.view.setTooltip -import eu.kanade.tachiyomi.util.view.showBar import eu.kanade.tachiyomi.widget.listener.SimpleAnimationListener import eu.kanade.tachiyomi.widget.listener.SimpleSeekBarListener import kotlinx.coroutines.flow.drop @@ -129,22 +130,20 @@ class ReaderActivity : BaseRxActivity() private var readingModeToast: Toast? = null + private val windowInsetsController by lazy { WindowInsetsControllerCompat(window, binding.root) } + /** * Called when the activity is created. Initializes the presenter and configuration. */ override fun onCreate(savedInstanceState: Bundle?) { - setTheme( - when (preferences.readerTheme().get()) { - 0 -> R.style.Theme_Reader_Light - 2 -> R.style.Theme_Reader_Dark_Grey - else -> R.style.Theme_Reader_Dark - } - ) + setTheme(BaseThemedActivity.getThemeResourceId(preferences)) super.onCreate(savedInstanceState) binding = ReaderActivityBinding.inflate(layoutInflater) setContentView(binding.root) + windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + if (presenter.needsInit()) { val manga = intent.extras!!.getLong("manga", -1) val chapter = intent.extras!!.getLong("chapter", -1) @@ -163,9 +162,10 @@ class ReaderActivity : BaseRxActivity() config = ReaderConfig() initializeMenu() - // Avoid status bar showing up on rotation - window.decorView.setOnSystemUiVisibilityChangeListener { - setMenuVisibility(menuVisible, animate = false) + binding.pageNumber.applyInsetter { + type(navigationBars = true) { + margin() + } } // Finish when incognito mode is disabled @@ -299,17 +299,15 @@ class ReaderActivity : BaseRxActivity() onBackPressed() } - ViewCompat.setOnApplyWindowInsetsListener(binding.readerMenu) { _, insets -> - if (!window.isDefaultBar()) { - val systemInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()) - binding.readerMenu.setPadding( - systemInsets.left, - systemInsets.top, - systemInsets.right, - systemInsets.bottom - ) + binding.toolbar.applyInsetter { + type(navigationBars = true, statusBars = true) { + margin(top = true, horizontal = true) + } + } + binding.readerMenuBottom.applyInsetter { + type(navigationBars = true) { + margin(bottom = true, horizontal = true) } - insets } binding.toolbar.setOnClickListener { @@ -355,6 +353,21 @@ class ReaderActivity : BaseRxActivity() initBottomShortcuts() + val alpha = if (preferences.isDarkMode()) 230 else 242 // 90% dark 95% light + listOf( + binding.toolbarBottom, + binding.leftChapter, + binding.readerSeekbar, + binding.rightChapter + ).forEach { + it.background.alpha = alpha + } + + val systemBarsColor = (binding.toolbarBottom.background as ColorDrawable).color + window.statusBarColor = systemBarsColor + window.navigationBarColor = systemBarsColor + (binding.toolbar.background as MaterialShapeDrawable).fillColor = ColorStateList.valueOf(systemBarsColor) + // Set initial visibility setMenuVisibility(menuVisible) } @@ -475,11 +488,7 @@ class ReaderActivity : BaseRxActivity() fun setMenuVisibility(visible: Boolean, animate: Boolean = true) { menuVisible = visible if (visible) { - if (preferences.fullscreen().get()) { - window.showBar() - } else { - resetDefaultMenuAndBar() - } + windowInsetsController.show(WindowInsetsCompat.Type.systemBars()) binding.readerMenu.isVisible = true if (animate) { @@ -503,9 +512,7 @@ class ReaderActivity : BaseRxActivity() } } else { if (preferences.fullscreen().get()) { - window.hideBar() - } else { - resetDefaultMenuAndBar() + windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) } if (animate) { @@ -529,14 +536,6 @@ class ReaderActivity : BaseRxActivity() } } - /** - * Reset menu padding and system bar - */ - private fun resetDefaultMenuAndBar() { - binding.readerMenu.setPadding(0) - window.defaultBar() - } - /** * Called from the presenter when a manga is ready. Used to instantiate the appropriate viewer * and the toolbar title. @@ -557,6 +556,7 @@ class ReaderActivity : BaseRxActivity() binding.viewerContainer.removeAllViews() } viewer = newViewer + updateViewerInset(preferences.fullscreen().get()) binding.viewerContainer.addView(newViewer.getView()) if (preferences.showReadingMode()) { @@ -811,6 +811,19 @@ class ReaderActivity : BaseRxActivity() updateOrientationShortcut(presenter.getMangaOrientationType(resolveDefault = false)) } + /** + * Updates viewer inset depending on fullscreen reader preferences. + */ + fun updateViewerInset(fullscreen: Boolean) { + viewer?.getView()?.applyInsetter { + if (!fullscreen) { + type(navigationBars = true, statusBars = true) { + padding() + } + } + } + } + /** * Class that handles the user preferences of the reader. */ @@ -831,8 +844,15 @@ class ReaderActivity : BaseRxActivity() */ init { preferences.readerTheme().asFlow() - .drop(1) // We only care about updates - .onEach { recreate() } + .onEach { + binding.readerContainer.setBackgroundResource( + when (preferences.readerTheme().get()) { + 0 -> android.R.color.white + 2 -> R.color.background_dark + else -> android.R.color.black + } + ) + } .launchIn(lifecycleScope) preferences.showPageNumber().asFlow() @@ -868,6 +888,13 @@ class ReaderActivity : BaseRxActivity() preferences.grayscale().asFlow() .onEach { setGrayscale(it) } .launchIn(lifecycleScope) + + preferences.fullscreen().asFlow() + .onEach { + WindowCompat.setDecorFitsSystemWindows(window, !it) + updateViewerInset(it) + } + .launchIn(lifecycleScope) } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/view/WindowExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/view/WindowExtensions.kt index cefe188d3..e3f8724a2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/view/WindowExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/view/WindowExtensions.kt @@ -3,32 +3,11 @@ package eu.kanade.tachiyomi.util.view import android.content.Context import android.graphics.Color import android.os.Build -import android.view.View import android.view.Window import android.view.WindowManager import eu.kanade.tachiyomi.util.system.InternalResourceHelper import eu.kanade.tachiyomi.util.system.getResourceColor -fun Window.showBar() { - decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or - View.SYSTEM_UI_FLAG_LAYOUT_STABLE -} - -fun Window.hideBar() { - decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or - View.SYSTEM_UI_FLAG_FULLSCREEN or - View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or - View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY -} - -fun Window.defaultBar() { - decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE -} - -fun Window.isDefaultBar() = decorView.systemUiVisibility == View.SYSTEM_UI_FLAG_VISIBLE - /** * Sets navigation bar color to transparent if system's config_navBarNeedsScrim is false, * otherwise it will use the theme navigationBarColor with 70% opacity. diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/sheet/BaseBottomSheetDialog.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/sheet/BaseBottomSheetDialog.kt index c4b213208..8f592af24 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/widget/sheet/BaseBottomSheetDialog.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/sheet/BaseBottomSheetDialog.kt @@ -1,7 +1,6 @@ package eu.kanade.tachiyomi.widget.sheet import android.content.Context -import android.content.res.Configuration import android.os.Build import android.os.Bundle import android.util.DisplayMetrics @@ -10,7 +9,6 @@ import android.view.View import android.view.ViewGroup import com.google.android.material.bottomsheet.BottomSheetDialog import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.preference.PreferenceValues import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.util.system.displayCompat import eu.kanade.tachiyomi.util.view.setNavigationBarTransparentCompat @@ -45,16 +43,9 @@ abstract class BaseBottomSheetDialog(context: Context) : BottomSheetDialog(conte @Suppress("DEPRECATION") if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { window?.setNavigationBarTransparentCompat(context) - val isDarkMode = when (Injekt.get().themeMode().get()) { - PreferenceValues.ThemeMode.light -> false - PreferenceValues.ThemeMode.dark -> true - PreferenceValues.ThemeMode.system -> - context.resources.configuration.uiMode and - Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES - } val bottomSheet = rootView.parent as ViewGroup var flags = bottomSheet.systemUiVisibility - flags = if (isDarkMode) { + flags = if (Injekt.get().isDarkMode()) { flags and View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.inv() } else { flags or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR diff --git a/app/src/main/res/layout/reader_activity.xml b/app/src/main/res/layout/reader_activity.xml index 9217591b4..09a7373cb 100644 --- a/app/src/main/res/layout/reader_activity.xml +++ b/app/src/main/res/layout/reader_activity.xml @@ -61,7 +61,6 @@ android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?attr/colorToolbar" android:minHeight="?attr/actionBarSize" /> #FF3399 #1FFF3399 - - #242529 - #FFC107 #FFEB3B #FFEB3B diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 4e38b20f2..94e44ce70 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -219,11 +219,6 @@ - - - - - - - - - - - - - - - -