Using Controller Extensions

Cleanup some unused backup consts/methods
This commit is contained in:
Jay 2020-04-22 20:56:11 -04:00
parent bd4a839b9e
commit 39aceea9da
5 changed files with 179 additions and 193 deletions

View File

@ -6,16 +6,7 @@ object BackupConst {
const val INTENT_FILTER = "SettingsBackupFragment"
const val ACTION_BACKUP_COMPLETED_DIALOG = "$ID.$INTENT_FILTER.ACTION_BACKUP_COMPLETED_DIALOG"
const val ACTION_ERROR_BACKUP_DIALOG = "$ID.$INTENT_FILTER.ACTION_ERROR_BACKUP_DIALOG"
const val ACTION_ERROR_RESTORE_DIALOG = "$ID.$INTENT_FILTER.ACTION_ERROR_RESTORE_DIALOG"
const val ACTION = "$ID.$INTENT_FILTER.ACTION"
const val EXTRA_PROGRESS = "$ID.$INTENT_FILTER.EXTRA_PROGRESS"
const val EXTRA_AMOUNT = "$ID.$INTENT_FILTER.EXTRA_AMOUNT"
const val EXTRA_ERRORS = "$ID.$INTENT_FILTER.EXTRA_ERRORS"
const val EXTRA_CONTENT = "$ID.$INTENT_FILTER.EXTRA_CONTENT"
const val EXTRA_ERROR_MESSAGE = "$ID.$INTENT_FILTER.EXTRA_ERROR_MESSAGE"
const val EXTRA_URI = "$ID.$INTENT_FILTER.EXTRA_URI"
const val EXTRA_TIME = "$ID.$INTENT_FILTER.EXTRA_TIME"
const val EXTRA_ERROR_FILE_PATH = "$ID.$INTENT_FILTER.EXTRA_ERROR_FILE_PATH"
const val EXTRA_ERROR_FILE = "$ID.$INTENT_FILTER.EXTRA_ERROR_FILE"
const val EXTRA_MINI_ERROR = "$ID.$INTENT_FILTER.EXTRA_MINI_ERROR"
}

View File

@ -1,32 +0,0 @@
package eu.kanade.tachiyomi.ui.base.controller
import android.content.pm.PackageManager.PERMISSION_GRANTED
import androidx.core.content.ContextCompat
import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.Router
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
fun Router.popControllerWithTag(tag: String): Boolean {
val controller = getControllerWithTag(tag)
if (controller != null) {
popController(controller)
return true
}
return false
}
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(FadeChangeHandler())
.popChangeHandler(FadeChangeHandler())
}

View File

@ -23,12 +23,11 @@ import eu.kanade.tachiyomi.data.backup.BackupRestoreService
import eu.kanade.tachiyomi.data.backup.models.Backup
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.base.controller.popControllerWithTag
import eu.kanade.tachiyomi.ui.base.controller.requestPermissionsSafe
import eu.kanade.tachiyomi.util.system.getFilePicker
import eu.kanade.tachiyomi.util.system.registerLocalReceiver
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.system.unregisterLocalReceiver
import eu.kanade.tachiyomi.util.view.requestPermissionsSafe
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
class SettingsBackupController : SettingsController() {
@ -285,16 +284,10 @@ class SettingsBackupController : SettingsController() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.getStringExtra(BackupConst.ACTION)) {
BackupConst.ACTION_BACKUP_COMPLETED_DIALOG -> {
router.popControllerWithTag(TAG_CREATING_BACKUP_DIALOG)
val uri = Uri.parse(intent.getStringExtra(BackupConst.EXTRA_URI))
CreatedBackupDialog(uri).showDialog(router)
}
BackupConst.ACTION_ERROR_BACKUP_DIALOG -> {
router.popControllerWithTag(TAG_CREATING_BACKUP_DIALOG)
context.toast(intent.getStringExtra(BackupConst.EXTRA_ERROR_MESSAGE))
}
BackupConst.ACTION_ERROR_RESTORE_DIALOG -> {
router.popControllerWithTag(TAG_RESTORING_BACKUP_DIALOG)
context.toast(intent.getStringExtra(BackupConst.EXTRA_ERROR_MESSAGE))
}
}
@ -305,8 +298,5 @@ class SettingsBackupController : SettingsController() {
const val CODE_BACKUP_CREATE = 501
const val CODE_BACKUP_RESTORE = 502
const val CODE_BACKUP_DIR = 503
const val TAG_CREATING_BACKUP_DIALOG = "CreatingBackupDialog"
const val TAG_RESTORING_BACKUP_DIALOG = "RestoringBackupDialog"
}
}

View File

@ -0,0 +1,178 @@
package eu.kanade.tachiyomi.util.view
import android.R
import android.animation.ValueAnimator
import android.content.Context
import android.content.pm.PackageManager
import android.view.WindowInsets
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.widget.SearchView
import androidx.core.content.ContextCompat
import androidx.core.math.MathUtils
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
import eu.kanade.tachiyomi.util.system.dpToPx
import kotlinx.android.synthetic.main.main_activity.*
import kotlin.math.abs
fun Controller.setOnQueryTextChangeListener(
searchView: SearchView,
onlyOnSubmit: Boolean = false,
f: (text: String?) -> Boolean
) {
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextChange(newText: String?): Boolean {
if (!onlyOnSubmit && router.backstack.lastOrNull()
?.controller() == this@setOnQueryTextChangeListener
) {
return f(newText)
}
return false
}
override fun onQueryTextSubmit(query: String?): Boolean {
if (router.backstack.lastOrNull()?.controller() == this@setOnQueryTextChangeListener) {
val imm =
activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
?: return f(query)
imm.hideSoftInputFromWindow(searchView.windowToken, 0)
return f(query)
}
return true
}
})
}
fun Controller.scrollViewWith(
recycler: RecyclerView,
padBottom: Boolean = false,
customPadding: Boolean = false,
skipFirstSnap: Boolean = false,
swipeRefreshLayout: SwipeRefreshLayout? = null,
afterInsets: ((WindowInsets) -> Unit)? = null
) {
var statusBarHeight = -1
activity?.appbar?.y = 0f
val attrsArray = intArrayOf(R.attr.actionBarSize)
val array = recycler.context.obtainStyledAttributes(attrsArray)
var appBarHeight = if (activity!!.toolbar.height > 0) activity!!.toolbar.height
else array.getDimensionPixelSize(0, 0)
array.recycle()
swipeRefreshLayout?.setDistanceToTriggerSync(150.dpToPx)
activity!!.toolbar.post {
if (activity!!.toolbar.height > 0) {
appBarHeight = activity!!.toolbar.height
recycler.requestApplyInsets()
}
}
recycler.doOnApplyWindowInsets { view, insets, _ ->
val headerHeight = insets.systemWindowInsetTop + appBarHeight
if (!customPadding) view.updatePaddingRelative(
top = headerHeight,
bottom = if (padBottom) insets.systemWindowInsetBottom else view.paddingBottom
)
swipeRefreshLayout?.setProgressViewOffset(
true, headerHeight + (-60).dpToPx, headerHeight + 10.dpToPx
)
statusBarHeight = insets.systemWindowInsetTop
afterInsets?.invoke(insets)
}
var elevationAnim: ValueAnimator? = null
var elevate = false
val elevateFunc: (Boolean) -> Unit = { el ->
elevate = el
elevationAnim?.cancel()
elevationAnim = ValueAnimator.ofFloat(
activity!!.appbar.elevation, if (el) 15f else 0f
)
elevationAnim?.addUpdateListener { valueAnimator ->
activity!!.appbar.elevation = valueAnimator.animatedValue as Float
}
elevationAnim?.start()
}
addLifecycleListener(object : Controller.LifecycleListener() {
override fun onChangeStart(
controller: Controller,
changeHandler: ControllerChangeHandler,
changeType: ControllerChangeType
) {
super.onChangeStart(controller, changeHandler, changeType)
if (changeType.isEnter)
elevateFunc(elevate)
}
})
elevateFunc(recycler.canScrollVertically(-1))
recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if (router?.backstack?.lastOrNull()
?.controller() == this@scrollViewWith && statusBarHeight > -1 && activity != null && activity!!.appbar.height > 0
) {
if (!recycler.canScrollVertically(-1)) {
val shortAnimationDuration = resources?.getInteger(
android.R.integer.config_shortAnimTime
) ?: 0
activity!!.appbar.animate().y(0f).setDuration(shortAnimationDuration.toLong())
.start()
if (elevate) elevateFunc(false)
} else {
activity!!.appbar.y -= dy
activity!!.appbar.y = MathUtils.clamp(
activity!!.appbar.y, -activity!!.appbar.height.toFloat(), 0f
)
if ((activity!!.appbar.y <= -activity!!.appbar.height.toFloat() ||
dy == 0 && activity!!.appbar.y == 0f) && !elevate)
elevateFunc(true)
}
}
}
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
if (router?.backstack?.lastOrNull()
?.controller() == this@scrollViewWith && statusBarHeight > -1 && activity != null && activity!!.appbar.height > 0
) {
val halfWay = abs((-activity!!.appbar.height.toFloat()) / 2)
val shortAnimationDuration = resources?.getInteger(
android.R.integer.config_shortAnimTime
) ?: 0
val closerToTop = abs(activity!!.appbar.y) - halfWay > 0
val atTop = (!customPadding &&
(recycler.layoutManager as LinearLayoutManager)
.findFirstVisibleItemPosition() < 2 && !skipFirstSnap) ||
!recycler.canScrollVertically(-1)
activity!!.appbar.animate().y(
if (closerToTop && !atTop) (-activity!!.appbar.height.toFloat())
else 0f
).setDuration(shortAnimationDuration.toLong()).start()
if (recycler.canScrollVertically(-1) && !elevate)
elevateFunc(true)
else if (!recycler.canScrollVertically(-1) && elevate)
elevateFunc(false)
}
}
}
})
}
fun Controller.requestPermissionsSafe(permissions: Array<String>, requestCode: Int) {
val activity = activity ?: return
permissions.forEach { permission ->
if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(arrayOf(permission), requestCode)
}
}
}
fun Controller.withFadeTransaction(): RouterTransaction {
return RouterTransaction.with(this)
.pushChangeHandler(FadeChangeHandler())
.popChangeHandler(FadeChangeHandler())
}

View File

@ -274,147 +274,6 @@ data class ViewPaddingState(
val end: Int
)
fun Controller.setOnQueryTextChangeListener(
searchView: SearchView,
onlyOnSubmit: Boolean = false,
f: (text: String?) -> Boolean
) {
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextChange(newText: String?): Boolean {
if (!onlyOnSubmit && router.backstack.lastOrNull()
?.controller() == this@setOnQueryTextChangeListener
) {
return f(newText)
}
return false
}
override fun onQueryTextSubmit(query: String?): Boolean {
if (router.backstack.lastOrNull()?.controller() == this@setOnQueryTextChangeListener) {
val imm =
activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
?: return f(query)
imm.hideSoftInputFromWindow(searchView.windowToken, 0)
return f(query)
}
return true
}
})
}
fun Controller.scrollViewWith(
recycler: RecyclerView,
padBottom: Boolean = false,
customPadding: Boolean = false,
skipFirstSnap: Boolean = false,
swipeRefreshLayout: SwipeRefreshLayout? = null,
afterInsets: ((WindowInsets) -> Unit)? = null
) {
var statusBarHeight = -1
activity?.appbar?.y = 0f
val attrsArray = intArrayOf(android.R.attr.actionBarSize)
val array = recycler.context.obtainStyledAttributes(attrsArray)
var appBarHeight = if (activity!!.toolbar.height > 0) activity!!.toolbar.height
else array.getDimensionPixelSize(0, 0)
array.recycle()
swipeRefreshLayout?.setDistanceToTriggerSync(150.dpToPx)
activity!!.toolbar.post {
if (activity!!.toolbar.height > 0) {
appBarHeight = activity!!.toolbar.height
recycler.requestApplyInsets()
}
}
recycler.doOnApplyWindowInsets { view, insets, _ ->
val headerHeight = insets.systemWindowInsetTop + appBarHeight
if (!customPadding) view.updatePaddingRelative(
top = headerHeight,
bottom = if (padBottom) insets.systemWindowInsetBottom else view.paddingBottom
)
swipeRefreshLayout?.setProgressViewOffset(
true, headerHeight + (-60).dpToPx, headerHeight + 10.dpToPx
)
statusBarHeight = insets.systemWindowInsetTop
afterInsets?.invoke(insets)
}
var elevationAnim: ValueAnimator? = null
var elevate = false
val elevateFunc: (Boolean) -> Unit = { el ->
elevate = el
elevationAnim?.cancel()
elevationAnim = ValueAnimator.ofFloat(
activity!!.appbar.elevation, if (el) 15f else 0f
)
elevationAnim?.addUpdateListener { valueAnimator ->
activity!!.appbar.elevation = valueAnimator.animatedValue as Float
}
elevationAnim?.start()
}
addLifecycleListener(object : Controller.LifecycleListener() {
override fun onChangeStart(
controller: Controller,
changeHandler: ControllerChangeHandler,
changeType: ControllerChangeType
) {
super.onChangeStart(controller, changeHandler, changeType)
if (changeType.isEnter)
elevateFunc(elevate)
}
})
elevateFunc(recycler.canScrollVertically(-1))
recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if (router?.backstack?.lastOrNull()
?.controller() == this@scrollViewWith && statusBarHeight > -1 && activity != null && activity!!.appbar.height > 0
) {
if (!recycler.canScrollVertically(-1)) {
val shortAnimationDuration = resources?.getInteger(
android.R.integer.config_shortAnimTime
) ?: 0
activity!!.appbar.animate().y(0f).setDuration(shortAnimationDuration.toLong())
.start()
if (elevate) elevateFunc(false)
} else {
activity!!.appbar.y -= dy
activity!!.appbar.y = clamp(
activity!!.appbar.y, -activity!!.appbar.height.toFloat(), 0f
)
if ((activity!!.appbar.y <= -activity!!.appbar.height.toFloat() ||
dy == 0 && activity!!.appbar.y == 0f) && !elevate)
elevateFunc(true)
}
}
}
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
if (router?.backstack?.lastOrNull()
?.controller() == this@scrollViewWith && statusBarHeight > -1 && activity != null && activity!!.appbar.height > 0
) {
val halfWay = abs((-activity!!.appbar.height.toFloat()) / 2)
val shortAnimationDuration = resources?.getInteger(
android.R.integer.config_shortAnimTime
) ?: 0
val closerToTop = abs(activity!!.appbar.y) - halfWay > 0
val atTop = (!customPadding &&
(recycler.layoutManager as LinearLayoutManager)
.findFirstVisibleItemPosition() < 2 && !skipFirstSnap) ||
!recycler.canScrollVertically(-1)
activity!!.appbar.animate().y(
if (closerToTop && !atTop) (-activity!!.appbar.height.toFloat())
else 0f
).setDuration(shortAnimationDuration.toLong()).start()
if (recycler.canScrollVertically(-1) && !elevate)
elevateFunc(true)
else if (!recycler.canScrollVertically(-1) && elevate)
elevateFunc(false)
}
}
}
})
}
inline fun View.updatePaddingRelative(
@Px start: Int = paddingStart,
@Px top: Int = paddingTop,