Merge Voyager screens (#8656)

* Merge Voyager screens

* cleanups
This commit is contained in:
Ivan Iskandar
2022-12-03 10:35:30 +07:00
committed by GitHub
parent 5313a5d5d2
commit 3d66eaea83
67 changed files with 1180 additions and 1991 deletions
@@ -1,86 +0,0 @@
package eu.kanade.tachiyomi.ui.base.controller
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.view.hideKeyboard
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) : Controller(bundle) {
protected lateinit var binding: VB
private set
lateinit var viewScope: CoroutineScope
init {
retainViewMode = RetainViewMode.RETAIN_DETACH
addLifecycleListener(
object : LifecycleListener() {
override fun postCreateView(controller: Controller, view: View) {
onViewCreated(view)
}
override fun preCreateView(controller: Controller) {
viewScope = MainScope()
logcat { "Create view for ${controller.instance()}" }
}
override fun preAttach(controller: Controller, view: View) {
logcat { "Attach view for ${controller.instance()}" }
}
override fun preDetach(controller: Controller, view: View) {
logcat { "Detach view for ${controller.instance()}" }
}
override fun preDestroyView(controller: Controller, view: View) {
viewScope.cancel()
logcat { "Destroy view for ${controller.instance()}" }
}
},
)
}
abstract fun createBinding(inflater: LayoutInflater): VB
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedViewState: Bundle?): View {
binding = createBinding(inflater)
return binding.root
}
open fun onViewCreated(view: View) {}
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
view?.hideKeyboard()
if (type.isEnter) {
setTitle()
setHasOptionsMenu(true)
}
super.onChangeStarted(handler, type)
}
open fun getTitle(): String? {
return null
}
fun setTitle(title: String? = null) {
(activity as? AppCompatActivity)?.supportActionBar?.title = title ?: getTitle()
}
private fun Controller.instance(): String {
return "${javaClass.simpleName}@${Integer.toHexString(hashCode())}"
}
}
@@ -1,49 +0,0 @@
package eu.kanade.tachiyomi.ui.base.controller
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import androidx.activity.OnBackPressedDispatcherOwner
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import eu.kanade.presentation.util.LocalRouter
import eu.kanade.tachiyomi.databinding.ComposeControllerBinding
import eu.kanade.tachiyomi.util.view.setComposeContent
/**
* Basic Compose controller without a presenter.
*/
abstract class BasicFullComposeController(bundle: Bundle? = null) :
BaseController<ComposeControllerBinding>(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()
}
}
}
}
// Let Compose view handle this
override fun handleBack(): Boolean {
val dispatcher = (activity as? OnBackPressedDispatcherOwner)?.onBackPressedDispatcher ?: return false
return if (dispatcher.hasEnabledCallbacks()) {
dispatcher.onBackPressed()
true
} else {
false
}
}
}
interface ComposeContentController {
@Composable fun ComposeContent()
}
@@ -1,25 +0,0 @@
package eu.kanade.tachiyomi.ui.base.controller
import androidx.core.net.toUri
import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.Router
import com.bluelinelabs.conductor.RouterTransaction
import eu.kanade.tachiyomi.util.system.openInBrowser
fun Router.setRoot(controller: Controller, id: Int) {
setRoot(controller.withFadeTransaction().tag(id.toString()))
}
fun Router.pushController(controller: Controller) {
pushController(controller.withFadeTransaction())
}
fun Controller.withFadeTransaction(): RouterTransaction {
return RouterTransaction.with(this)
.pushChangeHandler(OneWayFadeChangeHandler())
.popChangeHandler(OneWayFadeChangeHandler())
}
fun Controller.openInBrowser(url: String) {
activity?.openInBrowser(url.toUri())
}
@@ -1,119 +0,0 @@
package eu.kanade.tachiyomi.ui.base.controller
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.Router
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler
/**
* A controller that displays a dialog window, floating on top of its activity's window.
* This is a wrapper over [Dialog] object like [android.app.DialogFragment].
*
* Implementations should override this class and implement [.onCreateDialog] to create a custom dialog, such as an [android.app.AlertDialog]
*/
abstract class DialogController : Controller {
protected var dialog: Dialog? = null
private set
private var dismissed = false
/**
* Convenience constructor for use when no arguments are needed.
*/
protected constructor() : super(null)
/**
* Constructor that takes arguments that need to be retained across restarts.
*
* @param args Any arguments that need to be retained.
*/
protected constructor(args: Bundle?) : super(args)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedViewState: Bundle?): View {
dialog = onCreateDialog(savedViewState)
dialog!!.setOwnerActivity(activity!!)
dialog!!.setOnDismissListener { dismissDialog() }
if (savedViewState != null) {
val dialogState = savedViewState.getBundle(SAVED_DIALOG_STATE_TAG)
if (dialogState != null) {
dialog!!.onRestoreInstanceState(dialogState)
}
}
return View(activity) // stub view
}
override fun onSaveViewState(view: View, outState: Bundle) {
super.onSaveViewState(view, outState)
val dialogState = dialog!!.onSaveInstanceState()
outState.putBundle(SAVED_DIALOG_STATE_TAG, dialogState)
}
override fun onAttach(view: View) {
super.onAttach(view)
dialog!!.show()
}
override fun onDetach(view: View) {
super.onDetach(view)
dialog!!.hide()
}
override fun onDestroyView(view: View) {
super.onDestroyView(view)
dialog!!.setOnDismissListener(null)
dialog!!.dismiss()
dialog = null
}
/**
* Display the dialog, create a transaction and pushing the controller.
* @param router The router on which the transaction will be applied
*/
open fun showDialog(router: Router) {
showDialog(router, null)
}
/**
* Display the dialog, create a transaction and pushing the controller.
* @param router The router on which the transaction will be applied
* @param tag The tag for this controller
*/
fun showDialog(router: Router, tag: String?) {
dismissed = false
router.pushController(
RouterTransaction.with(this)
.pushChangeHandler(SimpleSwapChangeHandler(false))
.popChangeHandler(SimpleSwapChangeHandler(false))
.tag(tag),
)
}
/**
* Dismiss the dialog and pop this controller
*/
fun dismissDialog() {
if (dismissed) {
return
}
router.popController(this)
dismissed = true
}
/**
* Build your own custom Dialog container such as an [android.app.AlertDialog]
*
* @param savedViewState A bundle for the view's state, which would have been created in [.onSaveViewState] or `null` if no saved state exists.
* @return Return a new Dialog instance to be displayed by the Controller
*/
protected abstract fun onCreateDialog(savedViewState: Bundle?): Dialog
companion object {
private const val SAVED_DIALOG_STATE_TAG = "android:savedDialogState"
}
}
@@ -1,46 +0,0 @@
package eu.kanade.tachiyomi.ui.base.controller
import android.animation.Animator
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.view.View
import android.view.ViewGroup
import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
/**
* A variation of [FadeChangeHandler] that only fades in.
*/
class OneWayFadeChangeHandler : FadeChangeHandler {
constructor()
constructor(removesFromViewOnPush: Boolean) : super(removesFromViewOnPush)
constructor(duration: Long) : super(duration)
constructor(duration: Long, removesFromViewOnPush: Boolean) : super(
duration,
removesFromViewOnPush,
)
override fun getAnimator(
container: ViewGroup,
from: View?,
to: View?,
isPush: Boolean,
toAddedToContainer: Boolean,
): Animator {
val animator = AnimatorSet()
if (to != null) {
val start: Float = if (toAddedToContainer) 0F else to.alpha
animator.play(ObjectAnimator.ofFloat(to, View.ALPHA, start, 1f))
}
if (from != null && (!isPush || removesFromViewOnPush())) {
from.alpha = 0f
}
return animator
}
override fun copy(): ControllerChangeHandler {
return OneWayFadeChangeHandler(animationDuration, removesFromViewOnPush())
}
}
@@ -1,3 +0,0 @@
package eu.kanade.tachiyomi.ui.base.controller
interface RootController