Remove some dead code

This commit is contained in:
arkon 2022-12-02 22:48:08 -05:00
parent 3d66eaea83
commit b0dc20e00c
10 changed files with 33 additions and 490 deletions

View file

@ -273,9 +273,6 @@ dependencies {
implementation(libs.bundles.voyager)
implementation(libs.wheelpicker)
// FlowBinding
implementation(libs.flowbinding.android)
// Logging
implementation(libs.logcat)

View file

@ -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

View file

@ -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()
}

View file

@ -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) },
)
}
}

View file

@ -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)
}

View file

@ -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()
}
}

View file

@ -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)
}
}
}
}
}

View file

@ -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
}
}

View file

@ -65,8 +65,6 @@ insetter = "dev.chrisbanes.insetter:insetter:0.6.1"
cascade = "me.saket.cascade:cascade-compose:2.0.0-beta1"
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"
acra-http = "ch.acra:acra-http:5.9.7"