mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Remove unnecessary base Nucleus classes
The reader still uses it, but we just move stuff to there.
This commit is contained in:
		@@ -3,21 +3,17 @@ package eu.kanade.tachiyomi.ui.base.activity
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity
 | 
			
		||||
import eu.kanade.domain.base.BasePreferences
 | 
			
		||||
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: BasePreferences by injectLazy()
 | 
			
		||||
 | 
			
		||||
    override fun attachBaseContext(newBase: Context) {
 | 
			
		||||
        super.attachBaseContext(newBase.prepareTabletUiContext())
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +0,0 @@
 | 
			
		||||
package eu.kanade.tachiyomi.ui.base.activity
 | 
			
		||||
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import eu.kanade.domain.base.BasePreferences
 | 
			
		||||
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.util.system.prepareTabletUiContext
 | 
			
		||||
import nucleus.view.NucleusAppCompatActivity
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
 | 
			
		||||
open class BaseRxActivity<P : BasePresenter<*>> :
 | 
			
		||||
    NucleusAppCompatActivity<P>(),
 | 
			
		||||
    SecureActivityDelegate by SecureActivityDelegateImpl(),
 | 
			
		||||
    ThemingDelegate by ThemingDelegateImpl() {
 | 
			
		||||
 | 
			
		||||
    protected val preferences: BasePreferences by injectLazy()
 | 
			
		||||
 | 
			
		||||
    override fun attachBaseContext(newBase: Context) {
 | 
			
		||||
        super.attachBaseContext(newBase.prepareTabletUiContext())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        applyAppTheme(this)
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -9,37 +9,6 @@ import androidx.compose.runtime.CompositionLocalProvider
 | 
			
		||||
import eu.kanade.presentation.util.LocalRouter
 | 
			
		||||
import eu.kanade.tachiyomi.databinding.ComposeControllerBinding
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.setComposeContent
 | 
			
		||||
import nucleus.presenter.Presenter
 | 
			
		||||
 | 
			
		||||
abstract class FullComposeController<P : Presenter<*>>(bundle: Bundle? = null) :
 | 
			
		||||
    NucleusController<ComposeControllerBinding, P>(bundle),
 | 
			
		||||
    ComposeContentController {
 | 
			
		||||
 | 
			
		||||
    override fun createBinding(inflater: LayoutInflater) =
 | 
			
		||||
        ComposeControllerBinding.inflate(inflater)
 | 
			
		||||
 | 
			
		||||
    override fun onViewCreated(view: View) {
 | 
			
		||||
        super.onViewCreated(view)
 | 
			
		||||
 | 
			
		||||
        binding.root.apply {
 | 
			
		||||
            setComposeContent {
 | 
			
		||||
                CompositionLocalProvider(LocalRouter provides router) {
 | 
			
		||||
                    ComposeContent()
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun handleBack(): Boolean {
 | 
			
		||||
        val dispatcher = (activity as? OnBackPressedDispatcherOwner)?.onBackPressedDispatcher ?: return false
 | 
			
		||||
        return if (dispatcher.hasEnabledCallbacks()) {
 | 
			
		||||
            dispatcher.onBackPressed()
 | 
			
		||||
            true
 | 
			
		||||
        } else {
 | 
			
		||||
            false
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Basic Compose controller without a presenter.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
package eu.kanade.tachiyomi.ui.base.controller
 | 
			
		||||
 | 
			
		||||
import android.content.pm.PackageManager.PERMISSION_GRANTED
 | 
			
		||||
import androidx.core.content.ContextCompat
 | 
			
		||||
import androidx.core.net.toUri
 | 
			
		||||
import com.bluelinelabs.conductor.Controller
 | 
			
		||||
import com.bluelinelabs.conductor.Router
 | 
			
		||||
@@ -12,28 +10,10 @@ fun Router.setRoot(controller: Controller, id: Int) {
 | 
			
		||||
    setRoot(controller.withFadeTransaction().tag(id.toString()))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun Router.popControllerWithTag(tag: String): Boolean {
 | 
			
		||||
    val controller = getControllerWithTag(tag)
 | 
			
		||||
    if (controller != null) {
 | 
			
		||||
        popController(controller)
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
    return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun Router.pushController(controller: Controller) {
 | 
			
		||||
    pushController(controller.withFadeTransaction())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun Controller.requestPermissionsSafe(permissions: Array<String>, requestCode: Int) {
 | 
			
		||||
    val activity = activity ?: return
 | 
			
		||||
    permissions.forEach { permission ->
 | 
			
		||||
        if (ContextCompat.checkSelfPermission(activity, permission) != PERMISSION_GRANTED) {
 | 
			
		||||
            requestPermissions(arrayOf(permission), requestCode)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun Controller.withFadeTransaction(): RouterTransaction {
 | 
			
		||||
    return RouterTransaction.with(this)
 | 
			
		||||
        .pushChangeHandler(OneWayFadeChangeHandler())
 | 
			
		||||
 
 | 
			
		||||
@@ -1,23 +0,0 @@
 | 
			
		||||
package eu.kanade.tachiyomi.ui.base.controller
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import androidx.viewbinding.ViewBinding
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.presenter.NucleusConductorDelegate
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.presenter.NucleusConductorLifecycleListener
 | 
			
		||||
import nucleus.factory.PresenterFactory
 | 
			
		||||
import nucleus.presenter.Presenter
 | 
			
		||||
 | 
			
		||||
@Suppress("LeakingThis")
 | 
			
		||||
abstract class NucleusController<VB : ViewBinding, P : Presenter<*>>(val bundle: Bundle? = null) :
 | 
			
		||||
    BaseController<VB>(bundle),
 | 
			
		||||
    PresenterFactory<P> {
 | 
			
		||||
 | 
			
		||||
    private val delegate = NucleusConductorDelegate(this)
 | 
			
		||||
 | 
			
		||||
    val presenter: P
 | 
			
		||||
        get() = delegate.presenter!!
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        addLifecycleListener(NucleusConductorLifecycleListener(delegate))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,36 +0,0 @@
 | 
			
		||||
package eu.kanade.tachiyomi.ui.base.presenter
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import eu.kanade.core.prefs.PreferenceMutableState
 | 
			
		||||
import eu.kanade.tachiyomi.core.preference.Preference
 | 
			
		||||
import kotlinx.coroutines.CoroutineScope
 | 
			
		||||
import kotlinx.coroutines.MainScope
 | 
			
		||||
import kotlinx.coroutines.cancel
 | 
			
		||||
import nucleus.presenter.RxPresenter
 | 
			
		||||
 | 
			
		||||
open class BasePresenter<V> : RxPresenter<V>() {
 | 
			
		||||
 | 
			
		||||
    var presenterScope: CoroutineScope = MainScope()
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(savedState: Bundle?) {
 | 
			
		||||
        try {
 | 
			
		||||
            super.onCreate(savedState)
 | 
			
		||||
        } catch (e: NullPointerException) {
 | 
			
		||||
            // Swallow this error. This should be fixed in the library but since it's not critical
 | 
			
		||||
            // (only used by restartables) it should be enough. It saves me a fork.
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onDestroy() {
 | 
			
		||||
        super.onDestroy()
 | 
			
		||||
        presenterScope.cancel()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // We're trying to avoid using Rx, so we "undeprecate" this
 | 
			
		||||
    @Suppress("DEPRECATION")
 | 
			
		||||
    override fun getView(): V? {
 | 
			
		||||
        return super.getView()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun <T> Preference<T>.asState() = PreferenceMutableState(this, presenterScope)
 | 
			
		||||
}
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
package eu.kanade.tachiyomi.ui.base.presenter
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import nucleus.factory.PresenterFactory
 | 
			
		||||
import nucleus.presenter.Presenter
 | 
			
		||||
 | 
			
		||||
class NucleusConductorDelegate<P : Presenter<*>>(private val factory: PresenterFactory<P>) {
 | 
			
		||||
 | 
			
		||||
    var presenter: P? = null
 | 
			
		||||
        get() {
 | 
			
		||||
            if (field == null) {
 | 
			
		||||
                field = factory.createPresenter()
 | 
			
		||||
                field!!.create(bundle)
 | 
			
		||||
                bundle = null
 | 
			
		||||
            }
 | 
			
		||||
            return field
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    private var bundle: Bundle? = null
 | 
			
		||||
 | 
			
		||||
    fun onSaveInstanceState(): Bundle {
 | 
			
		||||
        val bundle = Bundle()
 | 
			
		||||
        //        getPresenter(); // Workaround a crash related to saving instance state with child routers
 | 
			
		||||
        presenter?.save(bundle)
 | 
			
		||||
        return bundle
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun onRestoreInstanceState(presenterState: Bundle?) {
 | 
			
		||||
        bundle = presenterState
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Suppress("UNCHECKED_CAST")
 | 
			
		||||
    private fun <View> Presenter<View>.takeView(view: Any) = takeView(view as View)
 | 
			
		||||
 | 
			
		||||
    fun onTakeView(view: Any) {
 | 
			
		||||
        presenter?.takeView(view)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun onDropView() {
 | 
			
		||||
        presenter?.dropView()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun onDestroy() {
 | 
			
		||||
        presenter?.destroy()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,32 +0,0 @@
 | 
			
		||||
package eu.kanade.tachiyomi.ui.base.presenter
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.view.View
 | 
			
		||||
import com.bluelinelabs.conductor.Controller
 | 
			
		||||
 | 
			
		||||
class NucleusConductorLifecycleListener(private val delegate: NucleusConductorDelegate<*>) : Controller.LifecycleListener() {
 | 
			
		||||
 | 
			
		||||
    override fun postCreateView(controller: Controller, view: View) {
 | 
			
		||||
        delegate.onTakeView(controller)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun preDestroyView(controller: Controller, view: View) {
 | 
			
		||||
        delegate.onDropView()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun preDestroy(controller: Controller) {
 | 
			
		||||
        delegate.onDestroy()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onSaveInstanceState(controller: Controller, outState: Bundle) {
 | 
			
		||||
        outState.putBundle(PRESENTER_STATE_KEY, delegate.onSaveInstanceState())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onRestoreInstanceState(controller: Controller, savedInstanceState: Bundle) {
 | 
			
		||||
        delegate.onRestoreInstanceState(savedInstanceState.getBundle(PRESENTER_STATE_KEY))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        private const val PRESENTER_STATE_KEY = "presenter_state"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -21,7 +21,6 @@ import androidx.core.view.isVisible
 | 
			
		||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
 | 
			
		||||
import androidx.interpolator.view.animation.LinearOutSlowInInterpolator
 | 
			
		||||
import androidx.lifecycle.lifecycleScope
 | 
			
		||||
import androidx.preference.PreferenceDialogController
 | 
			
		||||
import com.bluelinelabs.conductor.Conductor
 | 
			
		||||
import com.bluelinelabs.conductor.Controller
 | 
			
		||||
import com.bluelinelabs.conductor.ControllerChangeHandler
 | 
			
		||||
@@ -30,6 +29,7 @@ import com.bluelinelabs.conductor.RouterTransaction
 | 
			
		||||
import com.google.android.material.navigation.NavigationBarView
 | 
			
		||||
import com.google.android.material.transition.platform.MaterialContainerTransformSharedElementCallback
 | 
			
		||||
import dev.chrisbanes.insetter.applyInsetter
 | 
			
		||||
import eu.kanade.domain.base.BasePreferences
 | 
			
		||||
import eu.kanade.domain.library.service.LibraryPreferences
 | 
			
		||||
import eu.kanade.domain.source.service.SourcePreferences
 | 
			
		||||
import eu.kanade.domain.ui.UiPreferences
 | 
			
		||||
@@ -84,6 +84,7 @@ class MainActivity : BaseActivity() {
 | 
			
		||||
    private val sourcePreferences: SourcePreferences by injectLazy()
 | 
			
		||||
    private val libraryPreferences: LibraryPreferences by injectLazy()
 | 
			
		||||
    private val uiPreferences: UiPreferences by injectLazy()
 | 
			
		||||
    private val preferences: BasePreferences by injectLazy()
 | 
			
		||||
 | 
			
		||||
    lateinit var binding: MainActivityBinding
 | 
			
		||||
 | 
			
		||||
@@ -565,7 +566,7 @@ class MainActivity : BaseActivity() {
 | 
			
		||||
            // Then we'll assume the top controller is the parent controller of this dialog
 | 
			
		||||
            val backstack = router.backstack
 | 
			
		||||
            internalTo = backstack.lastOrNull()?.controller
 | 
			
		||||
            if (internalTo is DialogController || internalTo is PreferenceDialogController) {
 | 
			
		||||
            if (internalTo is DialogController) {
 | 
			
		||||
                internalTo = backstack.getOrNull(backstack.size - 2)?.controller ?: return
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -573,9 +574,6 @@ class MainActivity : BaseActivity() {
 | 
			
		||||
            if (from is DialogController || internalTo is DialogController) {
 | 
			
		||||
                return
 | 
			
		||||
            }
 | 
			
		||||
            if (from is PreferenceDialogController || internalTo is PreferenceDialogController) {
 | 
			
		||||
                return
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        supportActionBar?.setDisplayHomeAsUpEnabled(router.backstackSize != 1)
 | 
			
		||||
 
 | 
			
		||||
@@ -44,13 +44,17 @@ import com.google.android.material.slider.Slider
 | 
			
		||||
import com.google.android.material.transition.platform.MaterialContainerTransform
 | 
			
		||||
import com.google.android.material.transition.platform.MaterialContainerTransformSharedElementCallback
 | 
			
		||||
import dev.chrisbanes.insetter.applyInsetter
 | 
			
		||||
import eu.kanade.domain.base.BasePreferences
 | 
			
		||||
import eu.kanade.tachiyomi.BuildConfig
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
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.databinding.ReaderActivityBinding
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity
 | 
			
		||||
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.main.MainActivity
 | 
			
		||||
import eu.kanade.tachiyomi.ui.manga.MangaController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.AddToLibraryFirst
 | 
			
		||||
@@ -74,6 +78,7 @@ import eu.kanade.tachiyomi.util.system.getThemeColor
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.hasDisplayCutout
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.isNightMode
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.logcat
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.prepareTabletUiContext
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.toShareIntent
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.toast
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.copy
 | 
			
		||||
@@ -87,6 +92,7 @@ import kotlinx.coroutines.flow.onEach
 | 
			
		||||
import kotlinx.coroutines.flow.sample
 | 
			
		||||
import logcat.LogPriority
 | 
			
		||||
import nucleus.factory.RequiresPresenter
 | 
			
		||||
import nucleus.view.NucleusAppCompatActivity
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
import kotlin.math.abs
 | 
			
		||||
import kotlin.math.max
 | 
			
		||||
@@ -96,10 +102,12 @@ import kotlin.math.max
 | 
			
		||||
 * viewers, to which calls from the presenter or UI events are delegated.
 | 
			
		||||
 */
 | 
			
		||||
@RequiresPresenter(ReaderPresenter::class)
 | 
			
		||||
class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
 | 
			
		||||
class ReaderActivity :
 | 
			
		||||
    NucleusAppCompatActivity<ReaderPresenter>(),
 | 
			
		||||
    SecureActivityDelegate by SecureActivityDelegateImpl(),
 | 
			
		||||
    ThemingDelegate by ThemingDelegateImpl() {
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
 | 
			
		||||
        fun newIntent(context: Context, mangaId: Long?, chapterId: Long?): Intent {
 | 
			
		||||
            return Intent(context, ReaderActivity::class.java).apply {
 | 
			
		||||
                putExtra("manga", mangaId)
 | 
			
		||||
@@ -116,6 +124,7 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private val readerPreferences: ReaderPreferences by injectLazy()
 | 
			
		||||
    private val preferences: BasePreferences by injectLazy()
 | 
			
		||||
 | 
			
		||||
    lateinit var binding: ReaderActivityBinding
 | 
			
		||||
 | 
			
		||||
@@ -155,10 +164,15 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
 | 
			
		||||
    var isScrollingThroughPages = false
 | 
			
		||||
        private set
 | 
			
		||||
 | 
			
		||||
    override fun attachBaseContext(newBase: Context) {
 | 
			
		||||
        super.attachBaseContext(newBase.prepareTabletUiContext())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Called when the activity is created. Initializes the presenter and configuration.
 | 
			
		||||
     */
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        applyAppTheme(this)
 | 
			
		||||
        registerSecureActivity(this)
 | 
			
		||||
 | 
			
		||||
        // Setup shared element transitions
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,6 @@ import eu.kanade.tachiyomi.data.track.TrackManager
 | 
			
		||||
import eu.kanade.tachiyomi.source.SourceManager
 | 
			
		||||
import eu.kanade.tachiyomi.source.model.Page
 | 
			
		||||
import eu.kanade.tachiyomi.source.online.HttpSource
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.loader.ChapterLoader
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.loader.DownloadPageLoader
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.loader.HttpPageLoader
 | 
			
		||||
@@ -60,17 +59,20 @@ import eu.kanade.tachiyomi.util.storage.DiskUtil
 | 
			
		||||
import eu.kanade.tachiyomi.util.storage.cacheImageDir
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.isOnline
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.logcat
 | 
			
		||||
import kotlinx.coroutines.CoroutineScope
 | 
			
		||||
import kotlinx.coroutines.MainScope
 | 
			
		||||
import kotlinx.coroutines.async
 | 
			
		||||
import kotlinx.coroutines.awaitAll
 | 
			
		||||
import kotlinx.coroutines.cancel
 | 
			
		||||
import kotlinx.coroutines.runBlocking
 | 
			
		||||
import logcat.LogPriority
 | 
			
		||||
import nucleus.presenter.RxPresenter
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import rx.Subscription
 | 
			
		||||
import rx.android.schedulers.AndroidSchedulers
 | 
			
		||||
import rx.schedulers.Schedulers
 | 
			
		||||
import uy.kohesive.injekt.Injekt
 | 
			
		||||
import uy.kohesive.injekt.api.get
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
import java.util.Date
 | 
			
		||||
import java.util.concurrent.TimeUnit
 | 
			
		||||
import eu.kanade.domain.manga.model.Manga as DomainManga
 | 
			
		||||
@@ -82,6 +84,7 @@ class ReaderPresenter(
 | 
			
		||||
    private val sourceManager: SourceManager = Injekt.get(),
 | 
			
		||||
    private val downloadManager: DownloadManager = Injekt.get(),
 | 
			
		||||
    private val downloadProvider: DownloadProvider = Injekt.get(),
 | 
			
		||||
    private val imageSaver: ImageSaver = Injekt.get(),
 | 
			
		||||
    preferences: BasePreferences = Injekt.get(),
 | 
			
		||||
    private val downloadPreferences: DownloadPreferences = Injekt.get(),
 | 
			
		||||
    private val readerPreferences: ReaderPreferences = Injekt.get(),
 | 
			
		||||
@@ -95,7 +98,9 @@ class ReaderPresenter(
 | 
			
		||||
    private val upsertHistory: UpsertHistory = Injekt.get(),
 | 
			
		||||
    private val updateChapter: UpdateChapter = Injekt.get(),
 | 
			
		||||
    private val setMangaViewerFlags: SetMangaViewerFlags = Injekt.get(),
 | 
			
		||||
) : BasePresenter<ReaderActivity>() {
 | 
			
		||||
) : RxPresenter<ReaderActivity>() {
 | 
			
		||||
 | 
			
		||||
    private val coroutineScope: CoroutineScope = MainScope()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The manga loaded in the reader. It can be null when instantiated for a short time.
 | 
			
		||||
@@ -133,8 +138,6 @@ class ReaderPresenter(
 | 
			
		||||
     */
 | 
			
		||||
    private val isLoadingAdjacentChapterRelay = BehaviorRelay.create<Boolean>()
 | 
			
		||||
 | 
			
		||||
    private val imageSaver: ImageSaver by injectLazy()
 | 
			
		||||
 | 
			
		||||
    private var chapterToDownload: Download? = null
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -205,6 +208,7 @@ class ReaderPresenter(
 | 
			
		||||
     */
 | 
			
		||||
    override fun onDestroy() {
 | 
			
		||||
        super.onDestroy()
 | 
			
		||||
        coroutineScope.cancel()
 | 
			
		||||
        val currentChapters = viewerChaptersRelay.value
 | 
			
		||||
        if (currentChapters != null) {
 | 
			
		||||
            currentChapters.unref()
 | 
			
		||||
@@ -242,7 +246,7 @@ class ReaderPresenter(
 | 
			
		||||
     */
 | 
			
		||||
    fun onSaveInstanceStateNonConfigurationChange() {
 | 
			
		||||
        val currentChapter = getCurrentChapter() ?: return
 | 
			
		||||
        presenterScope.launchNonCancellable {
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
            saveChapterProgress(currentChapter)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -261,7 +265,7 @@ class ReaderPresenter(
 | 
			
		||||
    fun init(mangaId: Long, initialChapterId: Long) {
 | 
			
		||||
        if (!needsInit()) return
 | 
			
		||||
 | 
			
		||||
        presenterScope.launchIO {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
            try {
 | 
			
		||||
                val manga = getManga.await(mangaId)
 | 
			
		||||
                withUIContext {
 | 
			
		||||
@@ -467,7 +471,7 @@ class ReaderPresenter(
 | 
			
		||||
        if (getCurrentChapter()?.pageLoader !is DownloadPageLoader) return
 | 
			
		||||
        val nextChapter = viewerChaptersRelay.value?.nextChapter?.chapter ?: return
 | 
			
		||||
 | 
			
		||||
        presenterScope.launchIO {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
            val isNextChapterDownloaded = downloadManager.isChapterDownloaded(
 | 
			
		||||
                nextChapter.name,
 | 
			
		||||
                nextChapter.scanlator,
 | 
			
		||||
@@ -523,7 +527,7 @@ class ReaderPresenter(
 | 
			
		||||
     * Called when reader chapter is changed in reader or when activity is paused.
 | 
			
		||||
     */
 | 
			
		||||
    private fun saveReadingProgress(readerChapter: ReaderChapter) {
 | 
			
		||||
        presenterScope.launchNonCancellable {
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
            saveChapterProgress(readerChapter)
 | 
			
		||||
            saveChapterHistory(readerChapter)
 | 
			
		||||
        }
 | 
			
		||||
@@ -613,7 +617,7 @@ class ReaderPresenter(
 | 
			
		||||
    fun bookmarkCurrentChapter(bookmarked: Boolean) {
 | 
			
		||||
        val chapter = getCurrentChapter()?.chapter ?: return
 | 
			
		||||
        chapter.bookmark = bookmarked // Otherwise the bookmark icon doesn't update
 | 
			
		||||
        presenterScope.launchNonCancellable {
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
            updateChapter.await(
 | 
			
		||||
                ChapterUpdate(
 | 
			
		||||
                    id = chapter.id!!.toLong(),
 | 
			
		||||
@@ -726,7 +730,7 @@ class ReaderPresenter(
 | 
			
		||||
 | 
			
		||||
        // Copy file in background.
 | 
			
		||||
        try {
 | 
			
		||||
            presenterScope.launchNonCancellable {
 | 
			
		||||
            coroutineScope.launchNonCancellable {
 | 
			
		||||
                val uri = imageSaver.save(
 | 
			
		||||
                    image = Image.Page(
 | 
			
		||||
                        inputStream = page.stream!!,
 | 
			
		||||
@@ -762,7 +766,7 @@ class ReaderPresenter(
 | 
			
		||||
        val filename = generateFilename(manga, page)
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            presenterScope.launchNonCancellable {
 | 
			
		||||
            coroutineScope.launchNonCancellable {
 | 
			
		||||
                destDir.deleteRecursively()
 | 
			
		||||
                val uri = imageSaver.save(
 | 
			
		||||
                    image = Image.Page(
 | 
			
		||||
@@ -788,7 +792,7 @@ class ReaderPresenter(
 | 
			
		||||
        val manga = manga?.toDomainManga() ?: return
 | 
			
		||||
        val stream = page.stream ?: return
 | 
			
		||||
 | 
			
		||||
        presenterScope.launchNonCancellable {
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
            try {
 | 
			
		||||
                manga.editCover(context, stream())
 | 
			
		||||
                withUIContext {
 | 
			
		||||
@@ -834,7 +838,7 @@ class ReaderPresenter(
 | 
			
		||||
        val trackManager = Injekt.get<TrackManager>()
 | 
			
		||||
        val context = Injekt.get<Application>()
 | 
			
		||||
 | 
			
		||||
        presenterScope.launchNonCancellable {
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
            getTracks.await(manga.id!!)
 | 
			
		||||
                .mapNotNull { track ->
 | 
			
		||||
                    val service = trackManager.getService(track.syncId)
 | 
			
		||||
@@ -874,7 +878,7 @@ class ReaderPresenter(
 | 
			
		||||
        if (!chapter.chapter.read) return
 | 
			
		||||
        val manga = manga ?: return
 | 
			
		||||
 | 
			
		||||
        presenterScope.launchNonCancellable {
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
            downloadManager.enqueueChaptersToDelete(listOf(chapter.chapter.toDomainChapter()!!), manga.toDomainManga()!!)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -884,11 +888,17 @@ class ReaderPresenter(
 | 
			
		||||
     * are ignored.
 | 
			
		||||
     */
 | 
			
		||||
    private fun deletePendingChapters() {
 | 
			
		||||
        presenterScope.launchNonCancellable {
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
            downloadManager.deletePendingChapters()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // We're trying to avoid using Rx, so we "undeprecate" this
 | 
			
		||||
    @Suppress("DEPRECATION")
 | 
			
		||||
    override fun getView(): ReaderActivity? {
 | 
			
		||||
        return super.getView()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Subscribes an observable with [deliverFirst] and adds it to the presenter's lifecycle
 | 
			
		||||
     * subscription list.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user