Remove some dead code
This commit is contained in:
parent
3d66eaea83
commit
b0dc20e00c
@ -273,9 +273,6 @@ dependencies {
|
|||||||
implementation(libs.bundles.voyager)
|
implementation(libs.bundles.voyager)
|
||||||
implementation(libs.wheelpicker)
|
implementation(libs.wheelpicker)
|
||||||
|
|
||||||
// FlowBinding
|
|
||||||
implementation(libs.flowbinding.android)
|
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
implementation(libs.logcat)
|
implementation(libs.logcat)
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.util.system
|
package eu.kanade.tachiyomi.util.system
|
||||||
|
|
||||||
import android.app.ActivityManager
|
import android.app.ActivityManager
|
||||||
import android.app.KeyguardManager
|
|
||||||
import android.app.Notification
|
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
@ -24,11 +22,9 @@ import android.util.TypedValue
|
|||||||
import android.view.Display
|
import android.view.Display
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.view.inputmethod.InputMethodManager
|
|
||||||
import androidx.annotation.AttrRes
|
import androidx.annotation.AttrRes
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.appcompat.view.ContextThemeWrapper
|
import androidx.appcompat.view.ContextThemeWrapper
|
||||||
import androidx.core.app.NotificationCompat
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import androidx.core.graphics.alpha
|
import androidx.core.graphics.alpha
|
||||||
@ -75,34 +71,6 @@ fun Context.copyToClipboard(label: String, content: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to create a notification builder.
|
|
||||||
*
|
|
||||||
* @param id the channel id.
|
|
||||||
* @param block the function that will execute inside the builder.
|
|
||||||
* @return a notification to be displayed or updated.
|
|
||||||
*/
|
|
||||||
fun Context.notificationBuilder(channelId: String, block: (NotificationCompat.Builder.() -> Unit)? = null): NotificationCompat.Builder {
|
|
||||||
val builder = NotificationCompat.Builder(this, channelId)
|
|
||||||
.setColor(getColor(R.color.accent_blue))
|
|
||||||
if (block != null) {
|
|
||||||
builder.block()
|
|
||||||
}
|
|
||||||
return builder
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to create a notification.
|
|
||||||
*
|
|
||||||
* @param id the channel id.
|
|
||||||
* @param block the function that will execute inside the builder.
|
|
||||||
* @return a notification to be displayed or updated.
|
|
||||||
*/
|
|
||||||
fun Context.notification(channelId: String, block: (NotificationCompat.Builder.() -> Unit)?): Notification {
|
|
||||||
val builder = notificationBuilder(channelId, block)
|
|
||||||
return builder.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the give permission is granted.
|
* Checks if the give permission is granted.
|
||||||
*
|
*
|
||||||
@ -146,12 +114,6 @@ fun Context.hasPermission(permission: String) = ContextCompat.checkSelfPermissio
|
|||||||
val getDisplayMaxHeightInPx: Int
|
val getDisplayMaxHeightInPx: Int
|
||||||
get() = Resources.getSystem().displayMetrics.let { max(it.heightPixels, it.widthPixels) }
|
get() = Resources.getSystem().displayMetrics.let { max(it.heightPixels, it.widthPixels) }
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts to dp.
|
|
||||||
*/
|
|
||||||
val Int.pxToDp: Int
|
|
||||||
get() = (this / Resources.getSystem().displayMetrics.density).toInt()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts to px.
|
* Converts to px.
|
||||||
*/
|
*/
|
||||||
@ -182,12 +144,6 @@ val Context.wifiManager: WifiManager
|
|||||||
val Context.powerManager: PowerManager
|
val Context.powerManager: PowerManager
|
||||||
get() = getSystemService()!!
|
get() = getSystemService()!!
|
||||||
|
|
||||||
val Context.keyguardManager: KeyguardManager
|
|
||||||
get() = getSystemService()!!
|
|
||||||
|
|
||||||
val Context.inputMethodManager: InputMethodManager
|
|
||||||
get() = getSystemService()!!
|
|
||||||
|
|
||||||
val Context.displayCompat: Display?
|
val Context.displayCompat: Display?
|
||||||
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
display
|
display
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package eu.kanade.tachiyomi.util.system
|
package eu.kanade.tachiyomi.util.system
|
||||||
|
|
||||||
|
import android.app.Notification
|
||||||
|
import android.content.Context
|
||||||
import androidx.core.app.NotificationChannelCompat
|
import androidx.core.app.NotificationChannelCompat
|
||||||
import androidx.core.app.NotificationChannelGroupCompat
|
import androidx.core.app.NotificationChannelGroupCompat
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to build a notification channel group.
|
* Helper method to build a notification channel group.
|
||||||
@ -36,3 +40,31 @@ fun buildNotificationChannel(
|
|||||||
builder.block()
|
builder.block()
|
||||||
return builder.build()
|
return builder.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to create a notification builder.
|
||||||
|
*
|
||||||
|
* @param id the channel id.
|
||||||
|
* @param block the function that will execute inside the builder.
|
||||||
|
* @return a notification to be displayed or updated.
|
||||||
|
*/
|
||||||
|
fun Context.notificationBuilder(channelId: String, block: (NotificationCompat.Builder.() -> Unit)? = null): NotificationCompat.Builder {
|
||||||
|
val builder = NotificationCompat.Builder(this, channelId)
|
||||||
|
.setColor(getColor(R.color.accent_blue))
|
||||||
|
if (block != null) {
|
||||||
|
builder.block()
|
||||||
|
}
|
||||||
|
return builder
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to create a notification.
|
||||||
|
*
|
||||||
|
* @param id the channel id.
|
||||||
|
* @param block the function that will execute inside the builder.
|
||||||
|
* @return a notification to be displayed or updated.
|
||||||
|
*/
|
||||||
|
fun Context.notification(channelId: String, block: (NotificationCompat.Builder.() -> Unit)?): Notification {
|
||||||
|
val builder = notificationBuilder(channelId, block)
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
@ -1,19 +1,9 @@
|
|||||||
package eu.kanade.tachiyomi.util.view
|
package eu.kanade.tachiyomi.util.view
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.graphics.drawable.Animatable
|
|
||||||
import android.graphics.drawable.ColorDrawable
|
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import androidx.annotation.AttrRes
|
import androidx.annotation.AttrRes
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
import coil.ImageLoader
|
|
||||||
import coil.imageLoader
|
|
||||||
import coil.load
|
|
||||||
import coil.request.ImageRequest
|
|
||||||
import coil.target.ImageViewTarget
|
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.util.system.animatorDurationScale
|
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,33 +19,3 @@ fun ImageView.setVectorCompat(@DrawableRes drawable: Int, @AttrRes tint: Int? =
|
|||||||
}
|
}
|
||||||
setImageDrawable(vector)
|
setImageDrawable(vector)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the image referenced by [data] and set it on this [ImageView],
|
|
||||||
* and if the image is animated, this will also disable that animation
|
|
||||||
* if [Context.animatorDurationScale] is 0
|
|
||||||
*/
|
|
||||||
fun ImageView.loadAutoPause(
|
|
||||||
data: Any?,
|
|
||||||
loader: ImageLoader = context.imageLoader,
|
|
||||||
builder: ImageRequest.Builder.() -> Unit = {},
|
|
||||||
) {
|
|
||||||
load(data, loader) {
|
|
||||||
placeholder(ColorDrawable(context.getColor(R.color.cover_placeholder)))
|
|
||||||
error(R.drawable.cover_error)
|
|
||||||
|
|
||||||
// Build the original request so we can add on our success listener
|
|
||||||
val originalListener = apply(builder).build().listener
|
|
||||||
listener(
|
|
||||||
onSuccess = { request, metadata ->
|
|
||||||
(request.target as? ImageViewTarget)?.drawable.let {
|
|
||||||
if (it is Animatable && context.animatorDurationScale == 0f) it.stop()
|
|
||||||
}
|
|
||||||
originalListener?.onSuccess(request, metadata)
|
|
||||||
},
|
|
||||||
onStart = { request -> originalListener?.onStart(request) },
|
|
||||||
onCancel = { request -> originalListener?.onCancel(request) },
|
|
||||||
onError = { request, throwable -> originalListener?.onError(request, throwable) },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -11,7 +11,6 @@ import android.view.Gravity
|
|||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.annotation.MenuRes
|
import androidx.annotation.MenuRes
|
||||||
@ -29,15 +28,11 @@ import androidx.compose.runtime.CompositionContext
|
|||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.ui.platform.ComposeView
|
import androidx.compose.ui.platform.ComposeView
|
||||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||||
import androidx.core.view.children
|
|
||||||
import androidx.core.view.descendants
|
|
||||||
import androidx.core.view.forEach
|
import androidx.core.view.forEach
|
||||||
import com.google.android.material.shape.MaterialShapeDrawable
|
import com.google.android.material.shape.MaterialShapeDrawable
|
||||||
import com.google.android.material.snackbar.Snackbar
|
|
||||||
import eu.kanade.presentation.theme.TachiyomiTheme
|
import eu.kanade.presentation.theme.TachiyomiTheme
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
import eu.kanade.tachiyomi.util.system.inputMethodManager
|
|
||||||
|
|
||||||
inline fun ComposeView.setComposeContent(crossinline content: @Composable () -> Unit) {
|
inline fun ComposeView.setComposeContent(crossinline content: @Composable () -> Unit) {
|
||||||
consumeWindowInsets = false
|
consumeWindowInsets = false
|
||||||
@ -70,24 +65,6 @@ inline fun ComponentActivity.setComposeContent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows a snackbar in this view.
|
|
||||||
*
|
|
||||||
* @param message the message to show.
|
|
||||||
* @param length the duration of the snack.
|
|
||||||
* @param f a function to execute in the snack, allowing for example to define a custom action.
|
|
||||||
*/
|
|
||||||
inline fun View.snack(
|
|
||||||
message: String,
|
|
||||||
length: Int = 10_000,
|
|
||||||
f: Snackbar.() -> Unit = {},
|
|
||||||
): Snackbar {
|
|
||||||
val snack = Snackbar.make(this, message, length)
|
|
||||||
snack.f()
|
|
||||||
snack.show()
|
|
||||||
return snack
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a tooltip shown on long press.
|
* Adds a tooltip shown on long press.
|
||||||
*
|
*
|
||||||
@ -173,20 +150,6 @@ inline fun View.popupMenu(
|
|||||||
return popup
|
return popup
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns this ViewGroup's first child of specified class
|
|
||||||
*/
|
|
||||||
inline fun <reified T> ViewGroup.findChild(): T? {
|
|
||||||
return children.find { it is T } as? T
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns this ViewGroup's first descendant of specified class
|
|
||||||
*/
|
|
||||||
inline fun <reified T> ViewGroup.findDescendant(): T? {
|
|
||||||
return descendants.find { it is T } as? T
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a deep copy of the provided [Drawable]
|
* Returns a deep copy of the provided [Drawable]
|
||||||
*/
|
*/
|
||||||
@ -210,7 +173,3 @@ fun View?.isVisibleOnScreen(): Boolean {
|
|||||||
val screen = Rect(0, 0, Resources.getSystem().displayMetrics.widthPixels, Resources.getSystem().displayMetrics.heightPixels)
|
val screen = Rect(0, 0, Resources.getSystem().displayMetrics.widthPixels, Resources.getSystem().displayMetrics.heightPixels)
|
||||||
return actualPosition.intersect(screen)
|
return actualPosition.intersect(screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun View.hideKeyboard() {
|
|
||||||
context.inputMethodManager.hideSoftInputFromWindow(windowToken, 0)
|
|
||||||
}
|
|
||||||
|
@ -1,214 +0,0 @@
|
|||||||
@file:Suppress("PackageDirectoryMismatch")
|
|
||||||
|
|
||||||
package com.google.android.material.appbar
|
|
||||||
|
|
||||||
import android.animation.AnimatorSet
|
|
||||||
import android.animation.ValueAnimator
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.Context
|
|
||||||
import android.graphics.Canvas
|
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import android.util.AttributeSet
|
|
||||||
import android.view.animation.LinearInterpolator
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.annotation.FloatRange
|
|
||||||
import androidx.core.graphics.withTranslation
|
|
||||||
import androidx.lifecycle.coroutineScope
|
|
||||||
import androidx.lifecycle.findViewTreeLifecycleOwner
|
|
||||||
import com.google.android.material.shape.MaterialShapeDrawable
|
|
||||||
import dev.chrisbanes.insetter.applyInsetter
|
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.util.view.findChild
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import reactivecircus.flowbinding.android.view.HierarchyChangeEvent
|
|
||||||
import reactivecircus.flowbinding.android.view.hierarchyChangeEvents
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [AppBarLayout] with our own lift state handler and custom title alpha.
|
|
||||||
*
|
|
||||||
* Inside this package to access some package-private methods.
|
|
||||||
*/
|
|
||||||
class TachiyomiAppBarLayout @JvmOverloads constructor(
|
|
||||||
context: Context,
|
|
||||||
attrs: AttributeSet? = null,
|
|
||||||
) : AppBarLayout(context, attrs) {
|
|
||||||
|
|
||||||
private var lifted = true
|
|
||||||
|
|
||||||
private val toolbar by lazy { findViewById<MaterialToolbar>(R.id.toolbar) }
|
|
||||||
|
|
||||||
@FloatRange(from = 0.0, to = 1.0)
|
|
||||||
var titleTextAlpha = 1F
|
|
||||||
set(value) {
|
|
||||||
field = value
|
|
||||||
titleTextView?.alpha = field
|
|
||||||
}
|
|
||||||
|
|
||||||
private var titleTextView: TextView? = null
|
|
||||||
set(value) {
|
|
||||||
field = value
|
|
||||||
field?.alpha = titleTextAlpha
|
|
||||||
}
|
|
||||||
|
|
||||||
private var animatorSet: AnimatorSet? = null
|
|
||||||
|
|
||||||
private var statusBarForegroundAnimator: ValueAnimator? = null
|
|
||||||
private var currentOffset = 0
|
|
||||||
|
|
||||||
var isTransparentWhenNotLifted = false
|
|
||||||
set(value) {
|
|
||||||
if (field != value) {
|
|
||||||
field = value
|
|
||||||
updateStates()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disabled. Lift on scroll is handled manually with [eu.kanade.tachiyomi.widget.TachiyomiCoordinatorLayout]
|
|
||||||
*/
|
|
||||||
override fun isLiftOnScroll(): Boolean = false
|
|
||||||
|
|
||||||
override fun isLifted(): Boolean = lifted
|
|
||||||
|
|
||||||
override fun setLifted(lifted: Boolean): Boolean {
|
|
||||||
return if (this.lifted != lifted) {
|
|
||||||
this.lifted = lifted
|
|
||||||
updateStates()
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setLiftedState(lifted: Boolean, force: Boolean): Boolean = false
|
|
||||||
|
|
||||||
override fun draw(canvas: Canvas) {
|
|
||||||
super.draw(canvas)
|
|
||||||
canvas.withTranslation(y = -currentOffset.toFloat()) {
|
|
||||||
statusBarForeground?.draw(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
|
|
||||||
super.onLayout(changed, l, t, r, b)
|
|
||||||
statusBarForeground?.setBounds(0, 0, width, paddingTop)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onOffsetChanged(offset: Int) {
|
|
||||||
currentOffset = offset
|
|
||||||
super.onOffsetChanged(offset)
|
|
||||||
|
|
||||||
// Show status bar foreground when offset
|
|
||||||
val foreground = (statusBarForeground as? MaterialShapeDrawable) ?: return
|
|
||||||
val start = foreground.alpha
|
|
||||||
val end = if (offset != 0) 255 else 0
|
|
||||||
|
|
||||||
statusBarForegroundAnimator?.cancel()
|
|
||||||
if (animatorSet?.isRunning == true) {
|
|
||||||
foreground.alpha = end
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (start != end) {
|
|
||||||
statusBarForegroundAnimator = ValueAnimator.ofInt(start, end).apply {
|
|
||||||
duration = resources.getInteger(R.integer.app_bar_elevation_anim_duration).toLong()
|
|
||||||
interpolator = LINEAR_INTERPOLATOR
|
|
||||||
addUpdateListener {
|
|
||||||
foreground.alpha = it.animatedValue as Int
|
|
||||||
}
|
|
||||||
start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAttachedToWindow() {
|
|
||||||
super.onAttachedToWindow()
|
|
||||||
toolbar.background.alpha = 0 // Use app bar background
|
|
||||||
|
|
||||||
titleTextView = toolbar.findChild<TextView>()
|
|
||||||
findViewTreeLifecycleOwner()?.lifecycle?.coroutineScope?.let { scope ->
|
|
||||||
toolbar.hierarchyChangeEvents()
|
|
||||||
.onEach {
|
|
||||||
when (it) {
|
|
||||||
is HierarchyChangeEvent.ChildAdded -> {
|
|
||||||
if (it.child is TextView) {
|
|
||||||
titleTextView = it.child as TextView
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is HierarchyChangeEvent.ChildRemoved -> {
|
|
||||||
if (it.child == titleTextView) {
|
|
||||||
titleTextView = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.launchIn(scope)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setStatusBarForeground(drawable: Drawable?) {
|
|
||||||
super.setStatusBarForeground(drawable)
|
|
||||||
setWillNotDraw(statusBarForeground == null)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("Recycle")
|
|
||||||
private fun updateStates() {
|
|
||||||
val animators = mutableListOf<ValueAnimator>()
|
|
||||||
|
|
||||||
val fromElevation = elevation
|
|
||||||
val toElevation = if (lifted) {
|
|
||||||
resources.getDimension(R.dimen.design_appbar_elevation)
|
|
||||||
} else {
|
|
||||||
0F
|
|
||||||
}
|
|
||||||
if (fromElevation != toElevation) {
|
|
||||||
ValueAnimator.ofFloat(fromElevation, toElevation).apply {
|
|
||||||
addUpdateListener {
|
|
||||||
elevation = it.animatedValue as Float
|
|
||||||
(statusBarForeground as? MaterialShapeDrawable)?.elevation = it.animatedValue as Float
|
|
||||||
}
|
|
||||||
animators.add(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val transparent = if (lifted) false else isTransparentWhenNotLifted
|
|
||||||
val fromAlpha = (background as? MaterialShapeDrawable)?.alpha ?: background.alpha
|
|
||||||
val toAlpha = if (transparent) 0 else 255
|
|
||||||
if (fromAlpha != toAlpha) {
|
|
||||||
ValueAnimator.ofInt(fromAlpha, toAlpha).apply {
|
|
||||||
addUpdateListener {
|
|
||||||
val value = it.animatedValue as Int
|
|
||||||
background.alpha = value
|
|
||||||
}
|
|
||||||
animators.add(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (animators.isNotEmpty()) {
|
|
||||||
animatorSet?.cancel()
|
|
||||||
animatorSet = AnimatorSet().apply {
|
|
||||||
duration = resources.getInteger(R.integer.app_bar_elevation_anim_duration).toLong()
|
|
||||||
interpolator = LINEAR_INTERPOLATOR
|
|
||||||
playTogether(*animators.toTypedArray())
|
|
||||||
start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
statusBarForeground = MaterialShapeDrawable.createWithElevationOverlay(context)
|
|
||||||
applyInsetter {
|
|
||||||
type(navigationBars = true) {
|
|
||||||
margin(horizontal = true)
|
|
||||||
}
|
|
||||||
type(statusBars = true) {
|
|
||||||
padding(top = true)
|
|
||||||
}
|
|
||||||
ignoreVisibility(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val LINEAR_INTERPOLATOR = LinearInterpolator()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,130 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.widget
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.Parcel
|
|
||||||
import android.os.Parcelable
|
|
||||||
import android.util.AttributeSet
|
|
||||||
import android.view.View
|
|
||||||
import androidx.compose.ui.platform.ComposeView
|
|
||||||
import androidx.coordinatorlayout.R
|
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
||||||
import androidx.core.view.ViewCompat
|
|
||||||
import androidx.core.view.doOnLayout
|
|
||||||
import androidx.core.view.isVisible
|
|
||||||
import androidx.customview.view.AbsSavedState
|
|
||||||
import com.google.android.material.appbar.AppBarLayout
|
|
||||||
import com.google.android.material.tabs.TabLayout
|
|
||||||
import eu.kanade.tachiyomi.util.system.isTabletUi
|
|
||||||
import eu.kanade.tachiyomi.util.view.findChild
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [CoordinatorLayout] with its own app bar lift state handler.
|
|
||||||
* This parent view checks for the app bar lift state from the following:
|
|
||||||
*
|
|
||||||
* 1. When nested scroll detected, lift state will be decided from the nested
|
|
||||||
* scroll target. (See [onNestedScroll])
|
|
||||||
*
|
|
||||||
* With those conditions, this view expects the following direct child:
|
|
||||||
*
|
|
||||||
* 1. An [AppBarLayout].
|
|
||||||
*/
|
|
||||||
class TachiyomiCoordinatorLayout @JvmOverloads constructor(
|
|
||||||
context: Context,
|
|
||||||
attrs: AttributeSet? = null,
|
|
||||||
defStyleAttr: Int = R.attr.coordinatorLayoutStyle,
|
|
||||||
) : CoordinatorLayout(context, attrs, defStyleAttr) {
|
|
||||||
|
|
||||||
private var appBarLayout: AppBarLayout? = null
|
|
||||||
private var tabLayout: TabLayout? = null
|
|
||||||
|
|
||||||
override fun onNestedScroll(
|
|
||||||
target: View,
|
|
||||||
dxConsumed: Int,
|
|
||||||
dyConsumed: Int,
|
|
||||||
dxUnconsumed: Int,
|
|
||||||
dyUnconsumed: Int,
|
|
||||||
type: Int,
|
|
||||||
consumed: IntArray,
|
|
||||||
) {
|
|
||||||
super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type, consumed)
|
|
||||||
// Disable elevation overlay when tabs are visible
|
|
||||||
if (context.isTabletUi().not()) {
|
|
||||||
if (target is ComposeView) {
|
|
||||||
val scrollCondition = if (type == ViewCompat.TYPE_NON_TOUCH) {
|
|
||||||
dyUnconsumed >= 0
|
|
||||||
} else {
|
|
||||||
dyConsumed != 0 || dyUnconsumed >= 0
|
|
||||||
}
|
|
||||||
appBarLayout?.isLifted = scrollCondition && tabLayout?.isVisible == false
|
|
||||||
} else {
|
|
||||||
appBarLayout?.isLifted = (dyConsumed != 0 || dyUnconsumed >= 0) && tabLayout?.isVisible == false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAttachedToWindow() {
|
|
||||||
super.onAttachedToWindow()
|
|
||||||
appBarLayout = findChild()
|
|
||||||
tabLayout = appBarLayout?.findChild()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDetachedFromWindow() {
|
|
||||||
super.onDetachedFromWindow()
|
|
||||||
appBarLayout = null
|
|
||||||
tabLayout = null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSaveInstanceState(): Parcelable? {
|
|
||||||
val superState = super.onSaveInstanceState()
|
|
||||||
return if (superState != null) {
|
|
||||||
SavedState(superState).also {
|
|
||||||
it.appBarLifted = appBarLayout?.isLifted ?: false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
superState
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onRestoreInstanceState(state: Parcelable?) {
|
|
||||||
if (state is SavedState) {
|
|
||||||
super.onRestoreInstanceState(state.superState)
|
|
||||||
doOnLayout {
|
|
||||||
appBarLayout?.isLifted = state.appBarLifted
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
super.onRestoreInstanceState(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class SavedState : AbsSavedState {
|
|
||||||
var appBarLifted = false
|
|
||||||
|
|
||||||
constructor(superState: Parcelable) : super(superState)
|
|
||||||
|
|
||||||
constructor(source: Parcel, loader: ClassLoader?) : super(source, loader) {
|
|
||||||
appBarLifted = source.readByte().toInt() == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun writeToParcel(out: Parcel, flags: Int) {
|
|
||||||
super.writeToParcel(out, flags)
|
|
||||||
out.writeByte((if (appBarLifted) 1 else 0).toByte())
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@JvmField
|
|
||||||
val CREATOR: Parcelable.ClassLoaderCreator<SavedState> = object : Parcelable.ClassLoaderCreator<SavedState> {
|
|
||||||
override fun createFromParcel(source: Parcel, loader: ClassLoader): SavedState {
|
|
||||||
return SavedState(source, loader)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createFromParcel(source: Parcel): SavedState {
|
|
||||||
return SavedState(source, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun newArray(size: Int): Array<SavedState> {
|
|
||||||
return newArray(size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.widget
|
|
||||||
|
|
||||||
import com.google.android.material.appbar.AppBarLayout
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [AppBarLayout.ScrollingViewBehavior] that lets the app bar overlaps the scrolling child.
|
|
||||||
*/
|
|
||||||
class TachiyomiScrollingViewBehavior : AppBarLayout.ScrollingViewBehavior() {
|
|
||||||
|
|
||||||
var shouldHeaderOverlap = false
|
|
||||||
|
|
||||||
override fun shouldHeaderOverlapScrollingChild(): Boolean {
|
|
||||||
return shouldHeaderOverlap
|
|
||||||
}
|
|
||||||
}
|
|
@ -39,4 +39,4 @@ workmanager = ["work-runtime", "guava"]
|
|||||||
[plugins]
|
[plugins]
|
||||||
application = { id = "com.android.application", version.ref = "agp_version" }
|
application = { id = "com.android.application", version.ref = "agp_version" }
|
||||||
library = { id = "com.android.library", version.ref = "agp_version" }
|
library = { id = "com.android.library", version.ref = "agp_version" }
|
||||||
test = { id = "com.android.test", version.ref = "agp_version"}
|
test = { id = "com.android.test", version.ref = "agp_version" }
|
||||||
|
@ -65,8 +65,6 @@ insetter = "dev.chrisbanes.insetter:insetter:0.6.1"
|
|||||||
cascade = "me.saket.cascade:cascade-compose:2.0.0-beta1"
|
cascade = "me.saket.cascade:cascade-compose:2.0.0-beta1"
|
||||||
wheelpicker = "com.github.commandiron:WheelPickerCompose:1.0.11"
|
wheelpicker = "com.github.commandiron:WheelPickerCompose:1.0.11"
|
||||||
|
|
||||||
flowbinding-android = "io.github.reactivecircus.flowbinding:flowbinding-android:1.2.0"
|
|
||||||
|
|
||||||
logcat = "com.squareup.logcat:logcat:0.1"
|
logcat = "com.squareup.logcat:logcat:0.1"
|
||||||
|
|
||||||
acra-http = "ch.acra:acra-http:5.9.7"
|
acra-http = "ch.acra:acra-http:5.9.7"
|
||||||
|
Loading…
Reference in New Issue
Block a user