mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Remove some dead code
This commit is contained in:
		@@ -1,8 +1,6 @@
 | 
			
		||||
package eu.kanade.tachiyomi.util.system
 | 
			
		||||
 | 
			
		||||
import android.app.ActivityManager
 | 
			
		||||
import android.app.KeyguardManager
 | 
			
		||||
import android.app.Notification
 | 
			
		||||
import android.app.NotificationManager
 | 
			
		||||
import android.content.ClipData
 | 
			
		||||
import android.content.ClipboardManager
 | 
			
		||||
@@ -24,11 +22,9 @@ import android.util.TypedValue
 | 
			
		||||
import android.view.Display
 | 
			
		||||
import android.view.View
 | 
			
		||||
import android.view.WindowManager
 | 
			
		||||
import android.view.inputmethod.InputMethodManager
 | 
			
		||||
import androidx.annotation.AttrRes
 | 
			
		||||
import androidx.annotation.ColorInt
 | 
			
		||||
import androidx.appcompat.view.ContextThemeWrapper
 | 
			
		||||
import androidx.core.app.NotificationCompat
 | 
			
		||||
import androidx.core.content.ContextCompat
 | 
			
		||||
import androidx.core.content.getSystemService
 | 
			
		||||
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.
 | 
			
		||||
 *
 | 
			
		||||
@@ -146,12 +114,6 @@ fun Context.hasPermission(permission: String) = ContextCompat.checkSelfPermissio
 | 
			
		||||
val getDisplayMaxHeightInPx: Int
 | 
			
		||||
    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.
 | 
			
		||||
 */
 | 
			
		||||
@@ -182,12 +144,6 @@ val Context.wifiManager: WifiManager
 | 
			
		||||
val Context.powerManager: PowerManager
 | 
			
		||||
    get() = getSystemService()!!
 | 
			
		||||
 | 
			
		||||
val Context.keyguardManager: KeyguardManager
 | 
			
		||||
    get() = getSystemService()!!
 | 
			
		||||
 | 
			
		||||
val Context.inputMethodManager: InputMethodManager
 | 
			
		||||
    get() = getSystemService()!!
 | 
			
		||||
 | 
			
		||||
val Context.displayCompat: Display?
 | 
			
		||||
    get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
 | 
			
		||||
        display
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,11 @@
 | 
			
		||||
package eu.kanade.tachiyomi.util.system
 | 
			
		||||
 | 
			
		||||
import android.app.Notification
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import androidx.core.app.NotificationChannelCompat
 | 
			
		||||
import androidx.core.app.NotificationChannelGroupCompat
 | 
			
		||||
import androidx.core.app.NotificationCompat
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Helper method to build a notification channel group.
 | 
			
		||||
@@ -36,3 +40,31 @@ fun buildNotificationChannel(
 | 
			
		||||
    builder.block()
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.graphics.drawable.Animatable
 | 
			
		||||
import android.graphics.drawable.ColorDrawable
 | 
			
		||||
import android.widget.ImageView
 | 
			
		||||
import androidx.annotation.AttrRes
 | 
			
		||||
import androidx.annotation.DrawableRes
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -29,33 +19,3 @@ fun ImageView.setVectorCompat(@DrawableRes drawable: Int, @AttrRes tint: Int? =
 | 
			
		||||
    }
 | 
			
		||||
    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.MenuItem
 | 
			
		||||
import android.view.View
 | 
			
		||||
import android.view.ViewGroup
 | 
			
		||||
import androidx.activity.ComponentActivity
 | 
			
		||||
import androidx.activity.compose.setContent
 | 
			
		||||
import androidx.annotation.MenuRes
 | 
			
		||||
@@ -29,15 +28,11 @@ import androidx.compose.runtime.CompositionContext
 | 
			
		||||
import androidx.compose.runtime.CompositionLocalProvider
 | 
			
		||||
import androidx.compose.ui.platform.ComposeView
 | 
			
		||||
import androidx.compose.ui.platform.ViewCompositionStrategy
 | 
			
		||||
import androidx.core.view.children
 | 
			
		||||
import androidx.core.view.descendants
 | 
			
		||||
import androidx.core.view.forEach
 | 
			
		||||
import com.google.android.material.shape.MaterialShapeDrawable
 | 
			
		||||
import com.google.android.material.snackbar.Snackbar
 | 
			
		||||
import eu.kanade.presentation.theme.TachiyomiTheme
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.getResourceColor
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.inputMethodManager
 | 
			
		||||
 | 
			
		||||
inline fun ComposeView.setComposeContent(crossinline content: @Composable () -> Unit) {
 | 
			
		||||
    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.
 | 
			
		||||
 *
 | 
			
		||||
@@ -173,20 +150,6 @@ inline fun View.popupMenu(
 | 
			
		||||
    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]
 | 
			
		||||
 */
 | 
			
		||||
@@ -210,7 +173,3 @@ fun View?.isVisibleOnScreen(): Boolean {
 | 
			
		||||
    val screen = Rect(0, 0, Resources.getSystem().displayMetrics.widthPixels, Resources.getSystem().displayMetrics.heightPixels)
 | 
			
		||||
    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
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user