瀏覽代碼

Base activities cleanup (#6848)

* secure delegate

* theming delegate
Ivan Iskandar 3 年之前
父節點
當前提交
dbad60d03b

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/App.kt

@@ -29,7 +29,7 @@ import eu.kanade.tachiyomi.data.notification.Notifications
 import eu.kanade.tachiyomi.data.preference.PreferenceValues
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import eu.kanade.tachiyomi.network.NetworkHelper
-import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
+import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate
 import eu.kanade.tachiyomi.util.preference.asImmediateFlow
 import eu.kanade.tachiyomi.util.system.AuthenticatorUtil
 import eu.kanade.tachiyomi.util.system.animatorDurationScale

+ 29 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseActivity.kt

@@ -0,0 +1,29 @@
+package eu.kanade.tachiyomi.ui.base.activity
+
+import android.content.Context
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import eu.kanade.tachiyomi.data.preference.PreferencesHelper
+import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate
+import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegateImpl
+import eu.kanade.tachiyomi.ui.base.delegate.ThemingDelegate
+import eu.kanade.tachiyomi.ui.base.delegate.ThemingDelegateImpl
+import eu.kanade.tachiyomi.util.system.prepareTabletUiContext
+import uy.kohesive.injekt.injectLazy
+
+open class BaseActivity :
+    AppCompatActivity(),
+    SecureActivityDelegate by SecureActivityDelegateImpl(),
+    ThemingDelegate by ThemingDelegateImpl() {
+
+    protected val preferences: PreferencesHelper by injectLazy()
+
+    override fun attachBaseContext(newBase: Context) {
+        super.attachBaseContext(newBase.prepareTabletUiContext())
+    }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        applyAppTheme(this)
+        super.onCreate(savedInstanceState)
+    }
+}

+ 12 - 15
app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseRxActivity.kt

@@ -2,32 +2,29 @@ package eu.kanade.tachiyomi.ui.base.activity
 
 import android.content.Context
 import android.os.Bundle
-import androidx.viewbinding.ViewBinding
+import eu.kanade.tachiyomi.data.preference.PreferencesHelper
+import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate
+import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegateImpl
+import eu.kanade.tachiyomi.ui.base.delegate.ThemingDelegate
+import eu.kanade.tachiyomi.ui.base.delegate.ThemingDelegateImpl
 import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
-import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
 import eu.kanade.tachiyomi.util.system.prepareTabletUiContext
 import nucleus.view.NucleusAppCompatActivity
+import uy.kohesive.injekt.injectLazy
 
-abstract class BaseRxActivity<VB : ViewBinding, P : BasePresenter<*>> : NucleusAppCompatActivity<P>() {
+open class BaseRxActivity<P : BasePresenter<*>> :
+    NucleusAppCompatActivity<P>(),
+    SecureActivityDelegate by SecureActivityDelegateImpl(),
+    ThemingDelegate by ThemingDelegateImpl() {
 
-    @Suppress("LeakingThis")
-    private val secureActivityDelegate = SecureActivityDelegate(this)
-
-    lateinit var binding: VB
+    protected val preferences: PreferencesHelper by injectLazy()
 
     override fun attachBaseContext(newBase: Context) {
         super.attachBaseContext(newBase.prepareTabletUiContext())
     }
 
     override fun onCreate(savedInstanceState: Bundle?) {
+        applyAppTheme(this)
         super.onCreate(savedInstanceState)
-
-        secureActivityDelegate.onCreate()
-    }
-
-    override fun onResume() {
-        super.onResume()
-
-        secureActivityDelegate.onResume()
     }
 }

+ 0 - 25
app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseViewBindingActivity.kt

@@ -1,25 +0,0 @@
-package eu.kanade.tachiyomi.ui.base.activity
-
-import android.os.Bundle
-import androidx.viewbinding.ViewBinding
-import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
-
-abstract class BaseViewBindingActivity<VB : ViewBinding> : BaseThemedActivity() {
-
-    lateinit var binding: VB
-
-    @Suppress("LeakingThis")
-    private val secureActivityDelegate = SecureActivityDelegate(this)
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-
-        secureActivityDelegate.onCreate()
-    }
-
-    override fun onResume() {
-        super.onResume()
-
-        secureActivityDelegate.onResume()
-    }
-}

+ 73 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/base/delegate/SecureActivityDelegate.kt

@@ -0,0 +1,73 @@
+package eu.kanade.tachiyomi.ui.base.delegate
+
+import android.content.Intent
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.DefaultLifecycleObserver
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import eu.kanade.tachiyomi.data.preference.PreferenceValues
+import eu.kanade.tachiyomi.data.preference.PreferencesHelper
+import eu.kanade.tachiyomi.ui.security.UnlockActivity
+import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.isAuthenticationSupported
+import eu.kanade.tachiyomi.util.view.setSecureScreen
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import uy.kohesive.injekt.injectLazy
+import java.util.Date
+
+interface SecureActivityDelegate {
+    fun registerSecureActivity(activity: AppCompatActivity)
+
+    companion object {
+        var locked: Boolean = true
+    }
+}
+
+class SecureActivityDelegateImpl : SecureActivityDelegate, DefaultLifecycleObserver {
+
+    private lateinit var activity: AppCompatActivity
+
+    private val preferences: PreferencesHelper by injectLazy()
+
+    override fun registerSecureActivity(activity: AppCompatActivity) {
+        this.activity = activity
+        activity.lifecycle.addObserver(this)
+    }
+
+    override fun onCreate(owner: LifecycleOwner) {
+        setSecureScreen()
+    }
+
+    override fun onResume(owner: LifecycleOwner) {
+        setAppLock()
+    }
+
+    private fun setSecureScreen() {
+        val secureScreenFlow = preferences.secureScreen().asFlow()
+        val incognitoModeFlow = preferences.incognitoMode().asFlow()
+        combine(secureScreenFlow, incognitoModeFlow) { secureScreen, incognitoMode ->
+            secureScreen == PreferenceValues.SecureScreenMode.ALWAYS ||
+                secureScreen == PreferenceValues.SecureScreenMode.INCOGNITO && incognitoMode
+        }
+            .onEach { activity.window.setSecureScreen(it) }
+            .launchIn(activity.lifecycleScope)
+    }
+
+    private fun setAppLock() {
+        if (!preferences.useAuthenticator().get()) return
+        if (activity.isAuthenticationSupported()) {
+            if (!isAppLocked()) return
+            activity.startActivity(Intent(activity, UnlockActivity::class.java))
+            activity.overridePendingTransition(0, 0)
+        } else {
+            preferences.useAuthenticator().set(false)
+        }
+    }
+
+    private fun isAppLocked(): Boolean {
+        if (!SecureActivityDelegate.locked) return false
+        return preferences.lockAppAfter().get() <= 0 ||
+            Date().time >= preferences.lastAppUnlock().get() + 60 * 1000 * preferences.lockAppAfter().get()
+    }
+}

+ 14 - 23
app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt → app/src/main/java/eu/kanade/tachiyomi/ui/base/delegate/ThemingDelegate.kt

@@ -1,33 +1,16 @@
-package eu.kanade.tachiyomi.ui.base.activity
+package eu.kanade.tachiyomi.ui.base.delegate
 
-import android.content.Context
-import android.os.Bundle
-import androidx.appcompat.app.AppCompatActivity
+import android.app.Activity
 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.prepareTabletUiContext
-import uy.kohesive.injekt.injectLazy
+import uy.kohesive.injekt.Injekt
+import uy.kohesive.injekt.api.get
 
-abstract class BaseThemedActivity : AppCompatActivity() {
-
-    val preferences: PreferencesHelper by injectLazy()
-
-    override fun attachBaseContext(newBase: Context) {
-        super.attachBaseContext(newBase.prepareTabletUiContext())
-    }
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        applyAppTheme(preferences)
-        super.onCreate(savedInstanceState)
-    }
+interface ThemingDelegate {
+    fun applyAppTheme(activity: Activity)
 
     companion object {
-        fun AppCompatActivity.applyAppTheme(preferences: PreferencesHelper) {
-            getThemeResIds(preferences.appTheme().get(), preferences.themeDarkAmoled().get())
-                .forEach { setTheme(it) }
-        }
-
         fun getThemeResIds(appTheme: PreferenceValues.AppTheme, isAmoled: Boolean): List<Int> {
             val resIds = mutableListOf<Int>()
             when (appTheme) {
@@ -68,3 +51,11 @@ abstract class BaseThemedActivity : AppCompatActivity() {
         }
     }
 }
+
+class ThemingDelegateImpl : ThemingDelegate {
+    override fun applyAppTheme(activity: Activity) {
+        val preferences = Injekt.get<PreferencesHelper>()
+        ThemingDelegate.getThemeResIds(preferences.appTheme().get(), preferences.themeDarkAmoled().get())
+            .forEach { activity.setTheme(it) }
+    }
+}

+ 8 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt

@@ -40,7 +40,7 @@ import eu.kanade.tachiyomi.data.updater.AppUpdateChecker
 import eu.kanade.tachiyomi.data.updater.AppUpdateResult
 import eu.kanade.tachiyomi.databinding.MainActivityBinding
 import eu.kanade.tachiyomi.extension.api.ExtensionGithubApi
-import eu.kanade.tachiyomi.ui.base.activity.BaseViewBindingActivity
+import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
 import eu.kanade.tachiyomi.ui.base.controller.DialogController
 import eu.kanade.tachiyomi.ui.base.controller.FabController
 import eu.kanade.tachiyomi.ui.base.controller.NoAppBarElevationController
@@ -77,7 +77,9 @@ import kotlinx.coroutines.flow.onEach
 import logcat.LogPriority
 import uy.kohesive.injekt.injectLazy
 
-class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
+class MainActivity : BaseActivity() {
+
+    lateinit var binding: MainActivityBinding
 
     private lateinit var router: Router
 
@@ -627,6 +629,10 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
     private val nav: NavigationBarView
         get() = binding.bottomNav ?: binding.sideNav!!
 
+    init {
+        registerSecureActivity(this)
+    }
+
     companion object {
         // Splash screen
         private const val SPLASH_MIN_DURATION = 500 // ms

+ 3 - 6
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt

@@ -50,10 +50,8 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
 import eu.kanade.tachiyomi.data.database.models.Manga
 import eu.kanade.tachiyomi.data.notification.NotificationReceiver
 import eu.kanade.tachiyomi.data.notification.Notifications
-import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import eu.kanade.tachiyomi.databinding.ReaderActivityBinding
 import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity
-import eu.kanade.tachiyomi.ui.base.activity.BaseThemedActivity.Companion.applyAppTheme
 import eu.kanade.tachiyomi.ui.main.MainActivity
 import eu.kanade.tachiyomi.ui.manga.MangaController
 import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.AddToLibraryFirst
@@ -88,7 +86,6 @@ import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.sample
 import logcat.LogPriority
 import nucleus.factory.RequiresPresenter
-import uy.kohesive.injekt.injectLazy
 import kotlin.math.abs
 import kotlin.math.max
 
@@ -97,7 +94,7 @@ import kotlin.math.max
  * viewers, to which calls from the presenter or UI events are delegated.
  */
 @RequiresPresenter(ReaderPresenter::class)
-class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>() {
+class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
 
     companion object {
         fun newIntent(context: Context, manga: Manga, chapter: Chapter): Intent {
@@ -115,7 +112,7 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
         const val SHARED_ELEMENT_NAME = "reader_shared_element_root"
     }
 
-    private val preferences: PreferencesHelper by injectLazy()
+    lateinit var binding: ReaderActivityBinding
 
     val hasCutout by lazy { hasDisplayCutout() }
 
@@ -157,7 +154,7 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
      * Called when the activity is created. Initializes the presenter and configuration.
      */
     override fun onCreate(savedInstanceState: Bundle?) {
-        applyAppTheme(preferences)
+        registerSecureActivity(this)
 
         // Setup shared element transitions
         if (intent.extras?.getBoolean(EXTRA_IS_TRANSITION) == true) {

+ 0 - 55
app/src/main/java/eu/kanade/tachiyomi/ui/security/SecureActivityDelegate.kt

@@ -1,55 +0,0 @@
-package eu.kanade.tachiyomi.ui.security
-
-import android.content.Intent
-import androidx.fragment.app.FragmentActivity
-import androidx.lifecycle.lifecycleScope
-import eu.kanade.tachiyomi.data.preference.PreferenceValues
-import eu.kanade.tachiyomi.data.preference.PreferencesHelper
-import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.isAuthenticationSupported
-import eu.kanade.tachiyomi.util.view.setSecureScreen
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import uy.kohesive.injekt.injectLazy
-import java.util.Date
-
-class SecureActivityDelegate(private val activity: FragmentActivity) {
-
-    private val preferences: PreferencesHelper by injectLazy()
-
-    fun onCreate() {
-        val secureScreenFlow = preferences.secureScreen().asFlow()
-        val incognitoModeFlow = preferences.incognitoMode().asFlow()
-        combine(secureScreenFlow, incognitoModeFlow) { secureScreen, incognitoMode ->
-            secureScreen == PreferenceValues.SecureScreenMode.ALWAYS || secureScreen == PreferenceValues.SecureScreenMode.INCOGNITO && incognitoMode
-        }
-            .onEach { activity.window.setSecureScreen(it) }
-            .launchIn(activity.lifecycleScope)
-    }
-
-    fun onResume() {
-        if (preferences.useAuthenticator().get()) {
-            if (activity.isAuthenticationSupported()) {
-                if (isAppLocked()) {
-                    activity.startActivity(Intent(activity, UnlockActivity::class.java))
-                    activity.overridePendingTransition(0, 0)
-                }
-            } else {
-                preferences.useAuthenticator().set(false)
-            }
-        }
-    }
-
-    private fun isAppLocked(): Boolean {
-        if (!locked) {
-            return false
-        }
-
-        return preferences.lockAppAfter().get() <= 0 ||
-            Date().time >= preferences.lastAppUnlock().get() + 60 * 1000 * preferences.lockAppAfter().get()
-    }
-
-    companion object {
-        var locked: Boolean = true
-    }
-}

+ 3 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/security/UnlockActivity.kt

@@ -4,7 +4,8 @@ import android.os.Bundle
 import androidx.biometric.BiometricPrompt
 import androidx.fragment.app.FragmentActivity
 import eu.kanade.tachiyomi.R
-import eu.kanade.tachiyomi.ui.base.activity.BaseThemedActivity
+import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
+import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate
 import eu.kanade.tachiyomi.util.system.AuthenticatorUtil
 import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.startAuthentication
 import eu.kanade.tachiyomi.util.system.logcat
@@ -14,7 +15,7 @@ import java.util.Date
 /**
  * Blank activity with a BiometricPrompt.
  */
-class UnlockActivity : BaseThemedActivity() {
+class UnlockActivity : BaseActivity() {
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/setting/track/BaseOAuthLoginActivity.kt

@@ -8,11 +8,11 @@ import android.view.ViewGroup
 import android.widget.FrameLayout
 import android.widget.ProgressBar
 import eu.kanade.tachiyomi.data.track.TrackManager
-import eu.kanade.tachiyomi.ui.base.activity.BaseThemedActivity
+import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
 import eu.kanade.tachiyomi.ui.main.MainActivity
 import uy.kohesive.injekt.injectLazy
 
-abstract class BaseOAuthLoginActivity : BaseThemedActivity() {
+abstract class BaseOAuthLoginActivity : BaseActivity() {
 
     internal val trackManager: TrackManager by injectLazy()
 

+ 8 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewActivity.kt

@@ -19,7 +19,7 @@ import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.databinding.WebviewActivityBinding
 import eu.kanade.tachiyomi.source.SourceManager
 import eu.kanade.tachiyomi.source.online.HttpSource
-import eu.kanade.tachiyomi.ui.base.activity.BaseViewBindingActivity
+import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
 import eu.kanade.tachiyomi.util.system.WebViewClientCompat
 import eu.kanade.tachiyomi.util.system.WebViewUtil
 import eu.kanade.tachiyomi.util.system.getResourceColor
@@ -32,7 +32,9 @@ import reactivecircus.flowbinding.appcompat.navigationClicks
 import reactivecircus.flowbinding.swiperefreshlayout.refreshes
 import uy.kohesive.injekt.injectLazy
 
-class WebViewActivity : BaseViewBindingActivity<WebviewActivityBinding>() {
+class WebViewActivity : BaseActivity() {
+
+    private lateinit var binding: WebviewActivityBinding
 
     private val sourceManager: SourceManager by injectLazy()
 
@@ -203,6 +205,10 @@ class WebViewActivity : BaseViewBindingActivity<WebviewActivityBinding>() {
         openInBrowser(binding.webview.url!!, forceDefaultBrowser = true)
     }
 
+    init {
+        registerSecureActivity(this)
+    }
+
     companion object {
         private const val URL_KEY = "url_key"
         private const val SOURCE_KEY = "source_key"

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt

@@ -41,7 +41,7 @@ import com.hippo.unifile.UniFile
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.preference.PreferenceValues
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
-import eu.kanade.tachiyomi.ui.base.activity.BaseThemedActivity
+import eu.kanade.tachiyomi.ui.base.delegate.ThemingDelegate
 import eu.kanade.tachiyomi.util.lang.truncateCenter
 import logcat.LogPriority
 import uy.kohesive.injekt.Injekt
@@ -325,7 +325,7 @@ fun Context.createReaderThemeContext(): Context {
 
         val wrappedContext = ContextThemeWrapper(this, R.style.Theme_Tachiyomi)
         wrappedContext.applyOverrideConfiguration(overrideConf)
-        BaseThemedActivity.getThemeResIds(prefs.appTheme().get(), prefs.themeDarkAmoled().get())
+        ThemingDelegate.getThemeResIds(prefs.appTheme().get(), prefs.themeDarkAmoled().get())
             .forEach { wrappedContext.theme.applyStyle(it, true) }
         return wrappedContext
     }

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/widget/preference/ThemesPreferenceAdapter.kt

@@ -9,7 +9,7 @@ import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.preference.PreferenceValues
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import eu.kanade.tachiyomi.databinding.PrefThemeItemBinding
-import eu.kanade.tachiyomi.ui.base.activity.BaseThemedActivity
+import eu.kanade.tachiyomi.ui.base.delegate.ThemingDelegate
 import eu.kanade.tachiyomi.util.system.getResourceColor
 import uy.kohesive.injekt.injectLazy
 
@@ -23,7 +23,7 @@ class ThemesPreferenceAdapter(private val clickListener: OnItemClickListener) :
     private lateinit var binding: PrefThemeItemBinding
 
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ThemeViewHolder {
-        val themeResIds = BaseThemedActivity.getThemeResIds(themes[viewType], preferences.themeDarkAmoled().get())
+        val themeResIds = ThemingDelegate.getThemeResIds(themes[viewType], preferences.themeDarkAmoled().get())
         val themedContext = themeResIds.fold(parent.context) {
             context, themeResId ->
             ContextThemeWrapper(context, themeResId)