Utilize more KTX extensions (#7348)

This commit is contained in:
Taco 2022-06-20 22:54:42 -04:00 committed by GitHub
parent cd5bcc3673
commit c2520bff12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 89 additions and 98 deletions

View file

@ -29,7 +29,7 @@ class BackupCreatorJob(private val context: Context, workerParams: WorkerParamet
override suspend fun doWork(): Result {
val preferences = Injekt.get<PreferencesHelper>()
val notifier = BackupNotifier(context)
val uri = inputData.getString(LOCATION_URI_KEY)?.let { Uri.parse(it) }
val uri = inputData.getString(LOCATION_URI_KEY)?.toUri()
?: preferences.backupsDirectory().get().toUri()
val flags = inputData.getInt(BACKUP_FLAGS_KEY, BackupConst.BACKUP_ALL)
val isAutoBackup = inputData.getBoolean(IS_AUTO_BACKUP_KEY, true)

View file

@ -4,6 +4,7 @@ import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.core.net.toUri
import eu.kanade.tachiyomi.extension.util.ExtensionInstaller
import eu.kanade.tachiyomi.ui.main.MainActivity
@ -53,7 +54,7 @@ object NotificationHandler {
}
fun openUrl(context: Context, url: String): PendingIntent {
val notificationIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
val notificationIntent = Intent(Intent.ACTION_VIEW, url.toUri())
return PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE)
}
}

View file

@ -1,13 +1,13 @@
package eu.kanade.tachiyomi.data.saver
import android.annotation.SuppressLint
import android.content.ContentValues
import android.content.Context
import android.graphics.Bitmap
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import androidx.core.content.contentValuesOf
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.storage.cacheImageDir
@ -39,15 +39,13 @@ class ImageSaver(
val pictureDir =
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val contentValues = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, image.name)
put(MediaStore.Images.Media.MIME_TYPE, type.mime)
put(
MediaStore.Images.Media.RELATIVE_PATH,
val contentValues = contentValuesOf(
MediaStore.Images.Media.DISPLAY_NAME to image.name,
MediaStore.Images.Media.MIME_TYPE to type.mime,
MediaStore.Images.Media.RELATIVE_PATH to
"${Environment.DIRECTORY_PICTURES}/${context.getString(R.string.app_name)}/" +
(image.location as Location.Pictures).relativePath,
)
}
(image.location as Location.Pictures).relativePath,
)
val picture = context.contentResolver.insert(
pictureDir,

View file

@ -2,14 +2,14 @@ package eu.kanade.tachiyomi.ui.base.controller
import android.app.Activity
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.text.style.CharacterStyle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import androidx.annotation.StringRes
import androidx.appcompat.widget.SearchView
import androidx.core.text.getSpans
import androidx.core.widget.doAfterTextChanged
import androidx.viewbinding.ViewBinding
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
@ -59,17 +59,9 @@ abstract class SearchableNucleusController<VB : ViewBinding, P : BasePresenter<*
val searchAutoComplete: SearchView.SearchAutoComplete = searchView.findViewById(
R.id.search_src_text,
)
searchAutoComplete.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
override fun afterTextChanged(editable: Editable) {
editable.getSpans(0, editable.length, CharacterStyle::class.java)
.forEach { editable.removeSpan(it) }
}
},
)
searchAutoComplete.doAfterTextChanged { editable ->
editable?.getSpans<CharacterStyle>()?.forEach { editable.removeSpan(it) }
}
searchView.queryTextEvents()
.onEach {

View file

@ -19,7 +19,9 @@ import androidx.preference.Preference
import androidx.preference.PreferenceGroupAdapter
import androidx.preference.PreferenceManager
import androidx.preference.PreferenceScreen
import androidx.preference.get
import androidx.preference.getOnBindEditTextListener
import androidx.preference.isNotEmpty
import androidx.recyclerview.widget.LinearLayoutManager
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore
@ -111,8 +113,8 @@ class SourcePreferencesController(bundle: Bundle? = null) :
source.setupPreferenceScreen(newScreen)
// Reparent the preferences
while (newScreen.preferenceCount != 0) {
val pref = newScreen.getPreference(0)
while (newScreen.isNotEmpty()) {
val pref = newScreen[0]
pref.isIconSpaceReserved = false
pref.order = Int.MAX_VALUE // reset to default order
@ -143,7 +145,7 @@ class SourcePreferencesController(bundle: Bundle? = null) :
val screen = preference.parent!!
lastOpenPreferencePosition = (0 until screen.preferenceCount).indexOfFirst {
screen.getPreference(it) === preference
screen[it] === preference
}
val f = when (preference) {
@ -169,7 +171,7 @@ class SourcePreferencesController(bundle: Bundle? = null) :
override fun <T : Preference> findPreference(key: CharSequence): T? {
// We track [lastOpenPreferencePosition] when displaying the dialog
// [key] isn't useful since there may be duplicates
return preferenceScreen!!.getPreference(lastOpenPreferencePosition!!) as T
return preferenceScreen!![lastOpenPreferencePosition!!] as T
}
}

View file

@ -8,6 +8,7 @@ import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.core.view.get
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.GridLayoutManager
@ -202,7 +203,7 @@ open class BrowseSourceController(bundle: Bundle) :
numColumnsJob?.cancel()
var oldPosition = RecyclerView.NO_POSITION
val oldRecycler = binding.catalogueView.getChildAt(1)
val oldRecycler = binding.catalogueView[1]
if (oldRecycler is RecyclerView) {
oldPosition = (oldRecycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
oldRecycler.adapter = null

View file

@ -6,6 +6,7 @@ import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.get
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.databinding.SourceFilterSheetBinding
@ -55,7 +56,7 @@ class SourceFilterSheet(
init {
recycler.adapter = adapter
recycler.setHasFixedSize(true)
(binding.root.getChildAt(1) as ViewGroup).addView(recycler)
(binding.root[1] as ViewGroup).addView(recycler)
addView(binding.root)
binding.filterBtn.setOnClickListener { onFilterClicked() }
binding.resetBtn.setOnClickListener { onResetClicked() }

View file

@ -3,11 +3,11 @@ package eu.kanade.tachiyomi.ui.reader
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.text.Spannable
import android.text.SpannableString
import android.text.style.ScaleXSpan
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.text.set
import eu.kanade.tachiyomi.widget.OutlineSpan
/**
@ -31,10 +31,10 @@ class PageIndicatorTextView(
// Also add a bit of spacing between each character, as the stroke overlaps them
val finalText = SpannableString(currText.asIterable().joinToString("\u00A0")).apply {
// Apply text outline
setSpan(spanOutline, 1, length - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
set(1, length - 1, spanOutline)
for (i in 1..lastIndex step 2) {
setSpan(ScaleXSpan(0.2f), i, i + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
set(i, i + 1, ScaleXSpan(0.2f))
}
}

View file

@ -30,7 +30,7 @@ import android.view.animation.AnimationUtils
import android.widget.FrameLayout
import android.widget.Toast
import androidx.core.graphics.ColorUtils
import androidx.core.transition.addListener
import androidx.core.transition.doOnEnd
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
@ -621,9 +621,9 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
updateCropBordersShortcut()
if (window.sharedElementEnterTransition is MaterialContainerTransform) {
// Wait until transition is complete to avoid crash on API 26
window.sharedElementEnterTransition.addListener(
onEnd = { setOrientation(presenter.getMangaOrientationType()) },
)
window.sharedElementEnterTransition.doOnEnd {
setOrientation(presenter.getMangaOrientationType())
}
} else {
setOrientation(presenter.getMangaOrientationType())
}

View file

@ -8,7 +8,8 @@ import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewPropertyAnimator
import androidx.core.graphics.withSave
import androidx.core.graphics.withScale
import androidx.core.graphics.withTranslation
import androidx.core.view.isVisible
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
import eu.kanade.tachiyomi.ui.reader.viewer.navigation.DisabledNavigation
@ -63,17 +64,15 @@ class ReaderNavigationOverlayView(context: Context, attributeSet: AttributeSet)
navigation?.regions?.forEach { region ->
val rect = region.rectF
canvas?.withSave {
// Scale rect from 1f,1f to screen width and height
scale(width.toFloat(), height.toFloat())
// Scale rect from 1f,1f to screen width and height
canvas?.withScale(width.toFloat(), height.toFloat()) {
regionPaint.color = context.getColor(region.type.colorRes)
drawRect(rect, regionPaint)
}
// Don't want scale anymore because it messes with drawText
canvas?.withSave {
// Translate origin to rect start (left, top)
translate((width * rect.left), (height * rect.top))
// Don't want scale anymore because it messes with drawText
// Translate origin to rect start (left, top)
canvas?.withTranslation(x = (width * rect.left), y = (height * rect.top)) {
// Calculate center of rect width on screen
val x = width * (abs(rect.left - rect.right) / 2)

View file

@ -16,6 +16,7 @@ import androidx.annotation.AttrRes
import androidx.annotation.CallSuper
import androidx.annotation.StyleRes
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.os.postDelayed
import androidx.core.view.isVisible
import coil.dispose
import coil.imageLoader
@ -110,7 +111,7 @@ open class ReaderPageImageView @JvmOverloads constructor(
private fun SubsamplingScaleImageView.landscapeZoom(forward: Boolean) {
if (config != null && config!!.landscapeZoom && config!!.minimumScaleType == SCALE_TYPE_CENTER_INSIDE && sWidth > sHeight && scale == minScale) {
handler?.postDelayed({
handler?.postDelayed(500) {
val point = when (config!!.zoomStartPosition) {
ZoomStartPosition.LEFT -> if (forward) PointF(0F, 0F) else PointF(sWidth.toFloat(), 0F)
ZoomStartPosition.RIGHT -> if (forward) PointF(sWidth.toFloat(), 0F) else PointF(0F, 0F)
@ -123,7 +124,7 @@ open class ReaderPageImageView @JvmOverloads constructor(
.withEasing(EASE_IN_OUT_QUAD)
.withInterruptible(true)
.start()
}, 500,)
}
}
}

View file

@ -9,6 +9,7 @@ import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.LinearLayout
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.view.updatePadding
import com.google.android.material.progressindicator.CircularProgressIndicator
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
@ -55,7 +56,7 @@ class PagerTransitionHolder(
orientation = VERTICAL
gravity = Gravity.CENTER
val sidePadding = 64.dpToPx
setPadding(sidePadding, 0, sidePadding, 0)
updatePadding(left = sidePadding, right = sidePadding)
val transitionView = ReaderTransitionView(context)
addView(transitionView)

View file

@ -7,6 +7,8 @@ import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceGroup
import androidx.preference.PreferenceManager
import androidx.preference.forEach
import androidx.preference.get
import eu.kanade.tachiyomi.ui.setting.SettingsAdvancedController
import eu.kanade.tachiyomi.ui.setting.SettingsAppearanceController
import eu.kanade.tachiyomi.ui.setting.SettingsBackupController
@ -56,7 +58,7 @@ object SettingsSearchHelper {
val settingsPrefScreen = ctrl.setupPreferenceScreen(preferenceManager.createPreferenceScreen(context))
val prefCount = settingsPrefScreen.preferenceCount
for (i in 0 until prefCount) {
val rootPref = settingsPrefScreen.getPreference(i)
val rootPref = settingsPrefScreen[i]
if (rootPref.title == null) continue // no title, not a preference. (note: only info notes appear to not have titles)
getSettingSearchResult(ctrl, rootPref, "${settingsPrefScreen.title}")
}
@ -86,18 +88,14 @@ object SettingsSearchHelper {
when {
pref is PreferenceGroup -> {
val breadcrumbsStr = addLocalizedBreadcrumb(breadcrumbs, "${pref.title}")
for (x in 0 until pref.preferenceCount) {
val subPref = pref.getPreference(x)
getSettingSearchResult(ctrl, subPref, breadcrumbsStr) // recursion
pref.forEach {
getSettingSearchResult(ctrl, it, breadcrumbsStr) // recursion
}
}
pref is PreferenceCategory -> {
val breadcrumbsStr = addLocalizedBreadcrumb(breadcrumbs, "${pref.title}")
for (x in 0 until pref.preferenceCount) {
val subPref = pref.getPreference(x)
getSettingSearchResult(ctrl, subPref, breadcrumbsStr) // recursion
pref.forEach {
getSettingSearchResult(ctrl, it, breadcrumbsStr) // recursion
}
}
(pref.title != null && pref.isVisible) -> {

View file

@ -1,7 +1,6 @@
package eu.kanade.tachiyomi.util.lang
import android.os.Build
import android.text.Html
import androidx.core.text.parseAsHtml
import net.greypanther.natsort.CaseInsensitiveSimpleNaturalComparator
import java.nio.charset.StandardCharsets
import kotlin.math.floor
@ -64,9 +63,5 @@ fun String.takeBytes(n: Int): String {
* HTML-decode the string
*/
fun String.htmlDecode(): String {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY).toString()
} else {
Html.fromHtml(this).toString()
}
return this.parseAsHtml().toString()
}

View file

@ -262,7 +262,7 @@ fun Context.openInBrowser(uri: Uri, forceDefaultBrowser: Boolean = false) {
}
fun Context.defaultBrowserPackageName(): String? {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("http://"))
val browserIntent = Intent(Intent.ACTION_VIEW, "http://".toUri())
return packageManager.resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY)
?.activityInfo?.packageName
?.takeUnless { it in DeviceUtil.invalidDefaultBrowsers }

View file

@ -16,6 +16,7 @@ import androidx.core.graphics.alpha
import androidx.core.graphics.applyCanvas
import androidx.core.graphics.blue
import androidx.core.graphics.createBitmap
import androidx.core.graphics.get
import androidx.core.graphics.green
import androidx.core.graphics.red
import com.hippo.unifile.UniFile
@ -273,14 +274,14 @@ object ImageUtil {
val leftOffsetX = left - offsetX
val rightOffsetX = right + offsetX
val topLeftPixel = image.getPixel(left, top)
val topRightPixel = image.getPixel(right, top)
val midLeftPixel = image.getPixel(left, midY)
val midRightPixel = image.getPixel(right, midY)
val topCenterPixel = image.getPixel(midX, top)
val botLeftPixel = image.getPixel(left, bot)
val bottomCenterPixel = image.getPixel(midX, bot)
val botRightPixel = image.getPixel(right, bot)
val topLeftPixel = image[left, top]
val topRightPixel = image[right, top]
val midLeftPixel = image[left, midY]
val midRightPixel = image[right, midY]
val topCenterPixel = image[midX, top]
val botLeftPixel = image[left, bot]
val bottomCenterPixel = image[midX, bot]
val botRightPixel = image[right, bot]
val topLeftIsDark = topLeftPixel.isDark()
val topRightIsDark = topRightPixel.isDark()
@ -333,8 +334,8 @@ object ImageUtil {
var whiteStreak = false
val notOffset = x == left || x == right
inner@ for ((index, y) in (0 until image.height step image.height / 25).withIndex()) {
val pixel = image.getPixel(x, y)
val pixelOff = image.getPixel(x + (if (x < image.width / 2) -offsetX else offsetX), y)
val pixel = image[x, y]
val pixelOff = image[x + (if (x < image.width / 2) -offsetX else offsetX), y]
if (pixel.isWhite()) {
whitePixelsStreak++
whitePixels++
@ -425,8 +426,8 @@ object ImageUtil {
val topCornersIsDark = topLeftIsDark && topRightIsDark
val botCornersIsDark = botLeftIsDark && botRightIsDark
val topOffsetCornersIsDark = image.getPixel(leftOffsetX, top).isDark() && image.getPixel(rightOffsetX, top).isDark()
val botOffsetCornersIsDark = image.getPixel(leftOffsetX, bot).isDark() && image.getPixel(rightOffsetX, bot).isDark()
val topOffsetCornersIsDark = image[leftOffsetX, top].isDark() && image[rightOffsetX, top].isDark()
val botOffsetCornersIsDark = image[leftOffsetX, bot].isDark() && image[rightOffsetX, bot].isDark()
val gradient = when {
darkBG && botCornersIsWhite -> {

View file

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.widget
import android.content.Context
import android.util.AttributeSet
import androidx.core.content.withStyledAttributes
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlin.math.max
@ -27,9 +28,9 @@ class AutofitRecyclerView @JvmOverloads constructor(context: Context, attrs: Att
init {
if (attrs != null) {
val attrsArray = intArrayOf(android.R.attr.columnWidth)
val array = context.obtainStyledAttributes(attrs, attrsArray)
columnWidth = array.getDimensionPixelSize(0, -1)
array.recycle()
context.withStyledAttributes(attrs, attrsArray) {
columnWidth = getDimensionPixelSize(0, -1)
}
}
layoutManager = manager

View file

@ -9,6 +9,7 @@ import androidx.annotation.AttrRes
import androidx.annotation.CallSuper
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.RecyclerView
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.getResourceColor
@ -230,7 +231,7 @@ open class ExtendedNavigationView @JvmOverloads constructor(
is SeparatorHolder -> {
val view = holder.itemView
val item = items[position] as Item.Separator
view.setPadding(0, item.paddingTop, 0, item.paddingBottom)
view.updatePadding(top = item.paddingTop, bottom = item.paddingBottom)
}
is RadioHolder -> {
val item = items[position] as Item.Radio

View file

@ -11,6 +11,7 @@ import androidx.annotation.ArrayRes
import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.view.menu.MenuBuilder
import androidx.appcompat.widget.PopupMenu
import androidx.core.content.withStyledAttributes
import androidx.core.view.forEach
import androidx.core.view.get
import com.fredporciuncula.flow.preferences.Preference
@ -51,16 +52,15 @@ class MaterialSpinnerView @JvmOverloads constructor(context: Context, attrs: Att
init {
addView(binding.root)
val attr = context.obtainStyledAttributes(attrs, R.styleable.MaterialSpinnerView)
context.withStyledAttributes(set = attrs, attrs = R.styleable.MaterialSpinnerView) {
val title = getString(R.styleable.MaterialSpinnerView_title).orEmpty()
binding.title.text = title
val title = attr.getString(R.styleable.MaterialSpinnerView_title).orEmpty()
binding.title.text = title
val entries = (attr.getTextArray(R.styleable.MaterialSpinnerView_android_entries) ?: emptyArray()).map { it.toString() }
this.entries = entries
binding.details.text = entries.firstOrNull().orEmpty()
attr.recycle()
val viewEntries = (getTextArray(R.styleable.MaterialSpinnerView_android_entries)
?: emptyArray()).map { it.toString() }
entries = viewEntries
binding.details.text = viewEntries.firstOrNull().orEmpty()
}
}
fun setSelection(selection: Int) {
@ -152,9 +152,7 @@ class MaterialSpinnerView @JvmOverloads constructor(context: Context, attrs: Att
popup.menu.forEach {
it.icon = emptyIcon
}
popup.menu.getItem(selectedPosition)?.let {
it.icon = checkmarkIcon
}
popup.menu[selectedPosition].icon = checkmarkIcon
popup.setOnMenuItemClickListener { menuItem ->
val pos = menuClicked(menuItem)
onItemClick(pos)

View file

@ -12,6 +12,8 @@ import android.util.AttributeSet
import android.view.animation.LinearInterpolator
import android.widget.TextView
import androidx.annotation.FloatRange
import androidx.core.graphics.drawable.updateBounds
import androidx.core.graphics.withTranslation
import androidx.lifecycle.coroutineScope
import androidx.lifecycle.findViewTreeLifecycleOwner
import com.google.android.material.shape.MaterialShapeDrawable
@ -84,15 +86,14 @@ class TachiyomiAppBarLayout @JvmOverloads constructor(
override fun draw(canvas: Canvas) {
super.draw(canvas)
val saveCount = canvas.save()
canvas.translate(0f, -currentOffset.toFloat())
statusBarForeground?.draw(canvas)
canvas.restoreToCount(saveCount)
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)
statusBarForeground?.updateBounds(right = width, bottom = paddingTop)
}
override fun onOffsetChanged(offset: Int) {