arkon 4 жил өмнө
parent
commit
ec56c27071
29 өөрчлөгдсөн 121 нэмэгдсэн , 134 устгасан
  1. 2 1
      app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreateService.kt
  2. 2 2
      app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreatorJob.kt
  3. 2 2
      app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt
  4. 3 3
      app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt
  5. 12 16
      app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
  6. 2 1
      app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt
  7. 6 5
      app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt
  8. 6 6
      app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt
  9. 5 5
      app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt
  10. 4 3
      app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstaller.kt
  11. 2 2
      app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
  12. 3 4
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDividerItemDecoration.kt
  13. 2 2
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackController.kt
  14. 7 7
      app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt
  15. 2 1
      app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
  16. 10 11
      app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterView.kt
  17. 1 0
      app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt
  18. 9 12
      app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderProgressBar.kt
  19. 3 3
      app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerTransitionHolder.kt
  20. 5 16
      app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonRecyclerView.kt
  21. 5 4
      app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonTransitionHolder.kt
  22. 2 2
      app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
  23. 2 1
      app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt
  24. 3 3
      app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt
  25. 2 1
      app/src/main/java/eu/kanade/tachiyomi/util/storage/DiskUtil.kt
  26. 2 1
      app/src/main/java/eu/kanade/tachiyomi/util/storage/FileExtensions.kt
  27. 9 8
      app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt
  28. 4 5
      app/src/main/java/eu/kanade/tachiyomi/widget/MaxHeightViewPager.kt
  29. 4 7
      app/src/main/java/eu/kanade/tachiyomi/widget/RevealAnimationView.kt

+ 2 - 1
app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreateService.kt

@@ -7,6 +7,7 @@ import android.net.Uri
 import android.os.Build
 import android.os.IBinder
 import android.os.PowerManager
+import androidx.core.net.toUri
 import com.hippo.unifile.UniFile
 import eu.kanade.tachiyomi.data.notification.Notifications
 import eu.kanade.tachiyomi.util.system.acquireWakeLock
@@ -106,7 +107,7 @@ class BackupCreateService : Service() {
             val backupFlags = intent.getIntExtra(BackupConst.EXTRA_FLAGS, 0)
             backupManager = BackupManager(this)
 
-            val backupFileUri = Uri.parse(backupManager.createBackup(uri, backupFlags, false))
+            val backupFileUri = backupManager.createBackup(uri, backupFlags, false)?.toUri()
             val unifile = UniFile.fromUri(this, backupFileUri)
             notifier.showBackupComplete(unifile)
         } catch (e: Exception) {

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreatorJob.kt

@@ -1,7 +1,7 @@
 package eu.kanade.tachiyomi.data.backup
 
 import android.content.Context
-import android.net.Uri
+import androidx.core.net.toUri
 import androidx.work.ExistingPeriodicWorkPolicy
 import androidx.work.PeriodicWorkRequestBuilder
 import androidx.work.WorkManager
@@ -18,7 +18,7 @@ class BackupCreatorJob(private val context: Context, workerParams: WorkerParamet
     override fun doWork(): Result {
         val preferences = Injekt.get<PreferencesHelper>()
         val backupManager = BackupManager(context)
-        val uri = Uri.parse(preferences.backupsDirectory().get())
+        val uri = preferences.backupsDirectory().get().toUri()
         val flags = BackupCreateService.BACKUP_ALL
         return try {
             backupManager.createBackup(uri, flags, true)

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt

@@ -1,7 +1,7 @@
 package eu.kanade.tachiyomi.data.download
 
 import android.content.Context
-import android.net.Uri
+import androidx.core.net.toUri
 import com.hippo.unifile.UniFile
 import eu.kanade.tachiyomi.data.database.models.Chapter
 import eu.kanade.tachiyomi.data.database.models.Manga
@@ -59,7 +59,7 @@ class DownloadCache(
      */
     private fun getDirectoryFromPreference(): UniFile {
         val dir = preferences.downloadsDirectory().get()
-        return UniFile.fromUri(context, Uri.parse(dir))
+        return UniFile.fromUri(context, dir.toUri())
     }
 
     /**

+ 3 - 3
app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt

@@ -1,7 +1,7 @@
 package eu.kanade.tachiyomi.data.download
 
 import android.content.Context
-import android.net.Uri
+import androidx.core.net.toUri
 import com.hippo.unifile.UniFile
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.database.models.Chapter
@@ -32,14 +32,14 @@ class DownloadProvider(private val context: Context) {
      * The root directory for downloads.
      */
     private var downloadsDir = preferences.downloadsDirectory().get().let {
-        val dir = UniFile.fromUri(context, Uri.parse(it))
+        val dir = UniFile.fromUri(context, it.toUri())
         DiskUtil.createNoMediaFile(dir, context)
         dir
     }
 
     init {
         preferences.downloadsDirectory().asFlow()
-            .onEach { downloadsDir = UniFile.fromUri(context, Uri.parse(it)) }
+            .onEach { downloadsDir = UniFile.fromUri(context, it.toUri()) }
             .launchIn(scope)
     }
 

+ 12 - 16
app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt

@@ -1,8 +1,8 @@
 package eu.kanade.tachiyomi.data.preference
 
 import android.content.Context
-import android.net.Uri
 import android.os.Environment
+import androidx.core.net.toUri
 import androidx.preference.PreferenceManager
 import com.tfcporciuncula.flow.FlowSharedPreferences
 import com.tfcporciuncula.flow.Preference
@@ -41,21 +41,17 @@ class PreferencesHelper(val context: Context) {
     private val prefs = PreferenceManager.getDefaultSharedPreferences(context)
     private val flowPrefs = FlowSharedPreferences(prefs)
 
-    private val defaultDownloadsDir = Uri.fromFile(
-        File(
-            Environment.getExternalStorageDirectory().absolutePath + File.separator +
-                context.getString(R.string.app_name),
-            "downloads"
-        )
-    )
-
-    private val defaultBackupDir = Uri.fromFile(
-        File(
-            Environment.getExternalStorageDirectory().absolutePath + File.separator +
-                context.getString(R.string.app_name),
-            "backup"
-        )
-    )
+    private val defaultDownloadsDir = File(
+        Environment.getExternalStorageDirectory().absolutePath + File.separator +
+            context.getString(R.string.app_name),
+        "downloads"
+    ).toUri()
+
+    private val defaultBackupDir = File(
+        Environment.getExternalStorageDirectory().absolutePath + File.separator +
+            context.getString(R.string.app_name),
+        "backup"
+    ).toUri()
 
     fun startScreen() = prefs.getInt(Keys.startScreen, 1)
 

+ 2 - 1
app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt

@@ -1,6 +1,7 @@
 package eu.kanade.tachiyomi.data.track.anilist
 
 import android.net.Uri
+import androidx.core.net.toUri
 import com.github.salomonbrys.kotson.array
 import com.github.salomonbrys.kotson.get
 import com.github.salomonbrys.kotson.jsonObject
@@ -291,7 +292,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
             return baseMangaUrl + mediaId
         }
 
-        fun authUrl() = Uri.parse("${baseUrl}oauth/authorize").buildUpon()
+        fun authUrl(): Uri = "${baseUrl}oauth/authorize".toUri().buildUpon()
             .appendQueryParameter("client_id", clientId)
             .appendQueryParameter("response_type", "token")
             .build()

+ 6 - 5
app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt

@@ -1,6 +1,7 @@
 package eu.kanade.tachiyomi.data.track.bangumi
 
 import android.net.Uri
+import androidx.core.net.toUri
 import com.github.salomonbrys.kotson.array
 import com.github.salomonbrys.kotson.obj
 import com.google.gson.Gson
@@ -72,9 +73,9 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
     }
 
     fun search(search: String): Observable<List<TrackSearch>> {
-        val url = Uri.parse(
-            "$apiUrl/search/subject/${URLEncoder.encode(search, Charsets.UTF_8.name())}"
-        ).buildUpon()
+        val url = "$apiUrl/search/subject/${URLEncoder.encode(search, Charsets.UTF_8.name())}"
+            .toUri()
+            .buildUpon()
             .appendQueryParameter("max_results", "20")
             .build()
         val request = Request.Builder()
@@ -196,8 +197,8 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
             return "$baseMangaUrl/$remoteId"
         }
 
-        fun authUrl() =
-            Uri.parse(loginUrl).buildUpon()
+        fun authUrl(): Uri =
+            loginUrl.toUri().buildUpon()
                 .appendQueryParameter("client_id", clientId)
                 .appendQueryParameter("response_type", "code")
                 .appendQueryParameter("redirect_uri", redirectUrl)

+ 6 - 6
app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt

@@ -1,6 +1,6 @@
 package eu.kanade.tachiyomi.data.track.myanimelist
 
-import android.net.Uri
+import androidx.core.net.toUri
 import eu.kanade.tachiyomi.data.database.models.Track
 import eu.kanade.tachiyomi.data.track.TrackManager
 import eu.kanade.tachiyomi.data.track.model.TrackSearch
@@ -260,13 +260,13 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
 
         private fun mangaUrl(remoteId: Int) = baseMangaUrl + remoteId
 
-        private fun loginUrl() = Uri.parse(baseUrl).buildUpon()
+        private fun loginUrl() = baseUrl.toUri().buildUpon()
             .appendPath("login.php")
             .toString()
 
         private fun searchUrl(query: String): String {
             val col = "c[]"
-            return Uri.parse(baseUrl).buildUpon()
+            return baseUrl.toUri().buildUpon()
                 .appendPath("manga.php")
                 .appendQueryParameter("q", query)
                 .appendQueryParameter(col, "a")
@@ -278,17 +278,17 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
                 .toString()
         }
 
-        private fun exportListUrl() = Uri.parse(baseUrl).buildUpon()
+        private fun exportListUrl() = baseUrl.toUri().buildUpon()
             .appendPath("panel.php")
             .appendQueryParameter("go", "export")
             .toString()
 
-        private fun editPageUrl(mediaId: Int) = Uri.parse(baseModifyListUrl).buildUpon()
+        private fun editPageUrl(mediaId: Int) = baseModifyListUrl.toUri().buildUpon()
             .appendPath(mediaId.toString())
             .appendPath("edit")
             .toString()
 
-        private fun addUrl() = Uri.parse(baseModifyListUrl).buildUpon()
+        private fun addUrl() = baseModifyListUrl.toUri().buildUpon()
             .appendPath("add.json")
             .toString()
 

+ 5 - 5
app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt

@@ -1,6 +1,6 @@
 package eu.kanade.tachiyomi.data.track.shikimori
 
-import android.net.Uri
+import androidx.core.net.toUri
 import com.github.salomonbrys.kotson.array
 import com.github.salomonbrys.kotson.jsonObject
 import com.github.salomonbrys.kotson.nullString
@@ -54,7 +54,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
     fun updateLibManga(track: Track, user_id: String): Observable<Track> = addLibManga(track, user_id)
 
     fun search(search: String): Observable<List<TrackSearch>> {
-        val url = Uri.parse("$apiUrl/mangas").buildUpon()
+        val url = "$apiUrl/mangas".toUri().buildUpon()
             .appendQueryParameter("order", "popularity")
             .appendQueryParameter("search", search)
             .appendQueryParameter("limit", "20")
@@ -102,7 +102,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
     }
 
     fun findLibManga(track: Track, user_id: String): Observable<Track?> {
-        val url = Uri.parse("$apiUrl/v2/user_rates").buildUpon()
+        val url = "$apiUrl/v2/user_rates".toUri().buildUpon()
             .appendQueryParameter("user_id", user_id)
             .appendQueryParameter("target_id", track.media_id.toString())
             .appendQueryParameter("target_type", "Manga")
@@ -112,7 +112,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
             .get()
             .build()
 
-        val urlMangas = Uri.parse("$apiUrl/mangas").buildUpon()
+        val urlMangas = "$apiUrl/mangas".toUri().buildUpon()
             .appendPath(track.media_id.toString())
             .build()
         val requestMangas = Request.Builder()
@@ -187,7 +187,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
         }
 
         fun authUrl() =
-            Uri.parse(loginUrl).buildUpon()
+            loginUrl.toUri().buildUpon()
                 .appendQueryParameter("client_id", clientId)
                 .appendQueryParameter("redirect_uri", redirectUrl)
                 .appendQueryParameter("response_type", "code")

+ 4 - 3
app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstaller.kt

@@ -7,6 +7,8 @@ import android.content.Intent
 import android.content.IntentFilter
 import android.net.Uri
 import android.os.Environment
+import androidx.core.content.getSystemService
+import androidx.core.net.toUri
 import com.jakewharton.rxrelay.PublishRelay
 import eu.kanade.tachiyomi.extension.model.Extension
 import eu.kanade.tachiyomi.extension.model.InstallStep
@@ -63,7 +65,7 @@ internal class ExtensionInstaller(private val context: Context) {
         // Register the receiver after removing (and unregistering) the previous download
         downloadReceiver.register()
 
-        val downloadUri = Uri.parse(url)
+        val downloadUri = url.toUri()
         val request = DownloadManager.Request(downloadUri)
             .setTitle(extension.name)
             .setMimeType(APK_MIME)
@@ -138,8 +140,7 @@ internal class ExtensionInstaller(private val context: Context) {
      * @param pkgName The package name of the extension to uninstall
      */
     fun uninstallApk(pkgName: String) {
-        val packageUri = Uri.parse("package:$pkgName")
-        val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri)
+        val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE, "package:$pkgName".toUri())
             .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
 
         context.startActivity(intent)

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt

@@ -3,13 +3,13 @@ package eu.kanade.tachiyomi.ui.main
 import android.app.Activity
 import android.app.SearchManager
 import android.content.Intent
-import android.net.Uri
 import android.os.Bundle
 import android.view.Gravity
 import android.view.View
 import android.view.ViewGroup
 import android.widget.Toast
 import androidx.coordinatorlayout.widget.CoordinatorLayout
+import androidx.core.net.toUri
 import androidx.core.view.isVisible
 import androidx.core.view.updateLayoutParams
 import com.bluelinelabs.conductor.Conductor
@@ -389,7 +389,7 @@ class MainActivity : BaseActivity<MainActivityBinding>() {
         ) {
             setAction(R.string.whats_new) {
                 val url = "https://github.com/inorichi/tachiyomi/releases/tag/v${BuildConfig.VERSION_NAME}"
-                val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
+                val intent = Intent(Intent.ACTION_VIEW, url.toUri())
                 startActivity(intent)
             }
 

+ 3 - 4
app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChapterDividerItemDecoration.kt

@@ -5,6 +5,7 @@ import android.graphics.Canvas
 import android.graphics.Rect
 import android.graphics.drawable.Drawable
 import android.view.View
+import androidx.core.view.forEach
 import androidx.core.view.marginBottom
 import androidx.recyclerview.widget.RecyclerView
 
@@ -30,10 +31,8 @@ class ChapterDividerItemDecoration(context: Context) : RecyclerView.ItemDecorati
         }
 
         canvas.save()
-        val childCount = parent.childCount
-        for (i in 1 until childCount) {
-            val child = parent.getChildAt(i)
-            val top = child.bottom + child.marginBottom
+        parent.forEach {
+            val top = it.bottom + it.marginBottom
             val bottom = top + divider.intrinsicHeight
             val left = parent.paddingStart
             val right = parent.width - parent.paddingEnd

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackController.kt

@@ -1,11 +1,11 @@
 package eu.kanade.tachiyomi.ui.manga.track
 
 import android.content.Intent
-import android.net.Uri
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
+import androidx.core.net.toUri
 import androidx.recyclerview.widget.LinearLayoutManager
 import eu.kanade.tachiyomi.data.database.DatabaseHelper
 import eu.kanade.tachiyomi.data.database.models.Manga
@@ -120,7 +120,7 @@ class TrackController :
         val track = adapter?.getItem(position)?.track ?: return
 
         if (track.tracking_url.isNotBlank()) {
-            activity?.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(track.tracking_url)))
+            activity?.startActivity(Intent(Intent.ACTION_VIEW, track.tracking_url.toUri()))
         }
     }
 

+ 7 - 7
app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt

@@ -2,9 +2,9 @@ package eu.kanade.tachiyomi.ui.more
 
 import android.app.Dialog
 import android.content.Intent
-import android.net.Uri
 import android.os.Build
 import android.os.Bundle
+import androidx.core.net.toUri
 import androidx.preference.PreferenceScreen
 import com.afollestad.materialdialogs.MaterialDialog
 import com.mikepenz.aboutlibraries.LibsBuilder
@@ -75,7 +75,7 @@ class AboutController : SettingsController() {
                     "https://github.com/inorichi/tachiyomi/releases/tag/v${BuildConfig.VERSION_NAME}"
                 }
 
-                val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
+                val intent = Intent(Intent.ACTION_VIEW, url.toUri())
                 startActivity(intent)
             }
         }
@@ -84,7 +84,7 @@ class AboutController : SettingsController() {
                 titleRes = R.string.notices
 
                 onClick {
-                    val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/inorichi/tachiyomi/blob/dev/PREVIEW_RELEASE_NOTES.md"))
+                    val intent = Intent(Intent.ACTION_VIEW, "https://github.com/inorichi/tachiyomi/blob/dev/PREVIEW_RELEASE_NOTES.md".toUri())
                     startActivity(intent)
                 }
             }
@@ -96,7 +96,7 @@ class AboutController : SettingsController() {
                 val url = "https://tachiyomi.org"
                 summary = url
                 onClick {
-                    val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
+                    val intent = Intent(Intent.ACTION_VIEW, url.toUri())
                     startActivity(intent)
                 }
             }
@@ -105,7 +105,7 @@ class AboutController : SettingsController() {
                 val url = "https://discord.gg/tachiyomi"
                 summary = url
                 onClick {
-                    val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
+                    val intent = Intent(Intent.ACTION_VIEW, url.toUri())
                     startActivity(intent)
                 }
             }
@@ -114,7 +114,7 @@ class AboutController : SettingsController() {
                 val url = "https://github.com/inorichi/tachiyomi"
                 summary = url
                 onClick {
-                    val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
+                    val intent = Intent(Intent.ACTION_VIEW, url.toUri())
                     startActivity(intent)
                 }
             }
@@ -123,7 +123,7 @@ class AboutController : SettingsController() {
                 val url = "https://github.com/inorichi/tachiyomi-extensions"
                 summary = url
                 onClick {
-                    val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
+                    val intent = Intent(Intent.ACTION_VIEW, url.toUri())
                     startActivity(intent)
                 }
             }

+ 2 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt

@@ -22,6 +22,7 @@ import android.view.animation.AnimationUtils
 import android.widget.SeekBar
 import androidx.core.view.ViewCompat
 import androidx.core.view.isVisible
+import androidx.core.view.setPadding
 import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
 import com.google.android.material.snackbar.Snackbar
 import eu.kanade.tachiyomi.R
@@ -391,7 +392,7 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
      * Reset menu padding and system bar
      */
     private fun resetDefaultMenuAndBar() {
-        binding.readerMenu.setPadding(0, 0, 0, 0)
+        binding.readerMenu.setPadding(0)
         window.defaultBar()
     }
 

+ 10 - 11
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterView.kt

@@ -4,9 +4,9 @@ import android.content.Context
 import android.graphics.Canvas
 import android.graphics.Paint
 import android.graphics.PorterDuff
-import android.graphics.PorterDuffXfermode
 import android.util.AttributeSet
 import android.view.View
+import androidx.core.graphics.toXfermode
 
 class ReaderColorFilterView(
     context: Context,
@@ -17,16 +17,15 @@ class ReaderColorFilterView(
 
     fun setFilterColor(color: Int, filterMode: Int) {
         colorFilterPaint.color = color
-        colorFilterPaint.xfermode = PorterDuffXfermode(
-            when (filterMode) {
-                1 -> PorterDuff.Mode.MULTIPLY
-                2 -> PorterDuff.Mode.SCREEN
-                3 -> PorterDuff.Mode.OVERLAY
-                4 -> PorterDuff.Mode.LIGHTEN
-                5 -> PorterDuff.Mode.DARKEN
-                else -> PorterDuff.Mode.SRC_OVER
-            }
-        )
+        colorFilterPaint.xfermode = when (filterMode) {
+            1 -> PorterDuff.Mode.MULTIPLY
+            2 -> PorterDuff.Mode.SCREEN
+            3 -> PorterDuff.Mode.OVERLAY
+            4 -> PorterDuff.Mode.LIGHTEN
+            5 -> PorterDuff.Mode.DARKEN
+            else -> PorterDuff.Mode.SRC_OVER
+        }.toXfermode()
+
         invalidate()
     }
 

+ 1 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt

@@ -6,6 +6,7 @@ import android.widget.Spinner
 import androidx.annotation.ArrayRes
 import androidx.core.view.isInvisible
 import androidx.core.view.isVisible
+import androidx.core.view.plusAssign
 import androidx.core.widget.NestedScrollView
 import com.google.android.material.bottomsheet.BottomSheetDialog
 import com.tfcporciuncula.flow.Preference

+ 9 - 12
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderProgressBar.kt

@@ -1,7 +1,5 @@
 package eu.kanade.tachiyomi.ui.reader.viewer
 
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
 import android.animation.ObjectAnimator
 import android.animation.ValueAnimator
 import android.content.Context
@@ -14,6 +12,8 @@ import android.view.animation.Animation
 import android.view.animation.DecelerateInterpolator
 import android.view.animation.LinearInterpolator
 import android.view.animation.RotateAnimation
+import androidx.core.animation.doOnCancel
+import androidx.core.animation.doOnEnd
 import androidx.core.view.isGone
 import androidx.core.view.isVisible
 import eu.kanade.tachiyomi.R
@@ -163,16 +163,13 @@ class ReaderProgressBar @JvmOverloads constructor(
             ObjectAnimator.ofFloat(this, "alpha", 1f, 0f).apply {
                 interpolator = DecelerateInterpolator()
                 duration = 1000
-                addListener(object : AnimatorListenerAdapter() {
-                    override fun onAnimationEnd(animation: Animator?) {
-                        isVisible = false
-                        alpha = 1f
-                    }
-
-                    override fun onAnimationCancel(animation: Animator?) {
-                        alpha = 1f
-                    }
-                })
+                doOnEnd {
+                    isVisible = false
+                    alpha = 1f
+                }
+                doOnCancel {
+                    alpha = 1f
+                }
                 start()
             }
         }

+ 3 - 3
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerTransitionHolder.kt

@@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.ui.reader.viewer.pager
 
 import android.annotation.SuppressLint
 import android.graphics.Typeface
-import android.text.SpannableStringBuilder
 import android.text.Spanned
 import android.text.style.StyleSpan
 import android.view.Gravity
@@ -14,6 +13,7 @@ import android.widget.LinearLayout
 import android.widget.ProgressBar
 import android.widget.TextView
 import androidx.appcompat.widget.AppCompatTextView
+import androidx.core.text.buildSpannedString
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
 import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
@@ -90,7 +90,7 @@ class PagerTransitionHolder(
         val nextChapter = transition.to
 
         textView.text = if (nextChapter != null) {
-            SpannableStringBuilder().apply {
+            buildSpannedString {
                 append(context.getString(R.string.transition_finished))
                 setSpan(StyleSpan(Typeface.BOLD), 0, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
                 append("\n${transition.from.chapter.name}\n\n")
@@ -115,7 +115,7 @@ class PagerTransitionHolder(
         val prevChapter = transition.to
 
         textView.text = if (prevChapter != null) {
-            SpannableStringBuilder().apply {
+            buildSpannedString {
                 append(context.getString(R.string.transition_current))
                 setSpan(StyleSpan(Typeface.BOLD), 0, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
                 append("\n${transition.from.chapter.name}\n\n")

+ 5 - 16
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonRecyclerView.kt

@@ -1,6 +1,5 @@
 package eu.kanade.tachiyomi.ui.reader.viewer.webtoon
 
-import android.animation.Animator
 import android.animation.AnimatorSet
 import android.animation.ValueAnimator
 import android.content.Context
@@ -9,6 +8,7 @@ import android.view.HapticFeedbackConstants
 import android.view.MotionEvent
 import android.view.ViewConfiguration
 import android.view.animation.DecelerateInterpolator
+import androidx.core.animation.doOnEnd
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
 import eu.kanade.tachiyomi.ui.reader.viewer.GestureDetectorWithLongTap
@@ -112,21 +112,10 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
         animatorSet.duration = ANIMATOR_DURATION_TIME.toLong()
         animatorSet.interpolator = DecelerateInterpolator()
         animatorSet.start()
-        animatorSet.addListener(object : Animator.AnimatorListener {
-            override fun onAnimationStart(animation: Animator) {
-            }
-
-            override fun onAnimationEnd(animation: Animator) {
-                isZooming = false
-                currentScale = toRate
-            }
-
-            override fun onAnimationCancel(animation: Animator) {
-            }
-
-            override fun onAnimationRepeat(animation: Animator) {
-            }
-        })
+        animatorSet.doOnEnd {
+            isZooming = false
+            currentScale = toRate
+        }
     }
 
     fun zoomFling(velocityX: Int, velocityY: Int): Boolean {

+ 5 - 4
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonTransitionHolder.kt

@@ -1,7 +1,6 @@
 package eu.kanade.tachiyomi.ui.reader.viewer.webtoon
 
 import android.graphics.Typeface
-import android.text.SpannableStringBuilder
 import android.text.Spanned
 import android.text.style.StyleSpan
 import android.view.Gravity
@@ -12,6 +11,8 @@ import android.widget.ProgressBar
 import android.widget.TextView
 import androidx.appcompat.widget.AppCompatButton
 import androidx.appcompat.widget.AppCompatTextView
+import androidx.core.text.buildSpannedString
+import androidx.core.view.isNotEmpty
 import androidx.core.view.isVisible
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
@@ -92,7 +93,7 @@ class WebtoonTransitionHolder(
         val nextChapter = transition.to
 
         textView.text = if (nextChapter != null) {
-            SpannableStringBuilder().apply {
+            buildSpannedString {
                 append(context.getString(R.string.transition_finished))
                 setSpan(StyleSpan(Typeface.BOLD), 0, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
                 append("\n${transition.from.chapter.name}\n\n")
@@ -117,7 +118,7 @@ class WebtoonTransitionHolder(
         val prevChapter = transition.to
 
         textView.text = if (prevChapter != null) {
-            SpannableStringBuilder().apply {
+            buildSpannedString {
                 append(context.getString(R.string.transition_current))
                 setSpan(StyleSpan(Typeface.BOLD), 0, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
                 append("\n${transition.from.chapter.name}\n\n")
@@ -153,7 +154,7 @@ class WebtoonTransitionHolder(
                     is ReaderChapter.State.Error -> setError(state.error, transition)
                     is ReaderChapter.State.Loaded -> setLoaded()
                 }
-                pagesContainer.isVisible = pagesContainer.childCount > 0
+                pagesContainer.isVisible = pagesContainer.isNotEmpty()
             }
 
         addSubscription(statusSubscription)

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt

@@ -4,10 +4,10 @@ import android.annotation.SuppressLint
 import android.app.Dialog
 import android.content.ActivityNotFoundException
 import android.content.Intent
-import android.net.Uri
 import android.os.Build
 import android.os.Bundle
 import android.provider.Settings
+import androidx.core.net.toUri
 import androidx.preference.PreferenceScreen
 import com.afollestad.materialdialogs.MaterialDialog
 import eu.kanade.tachiyomi.R
@@ -62,7 +62,7 @@ class SettingsAdvancedController : SettingsController() {
                         try {
                             val intent = Intent().apply {
                                 action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
-                                data = Uri.parse("package:$packageName")
+                                data = "package:$packageName".toUri()
                             }
                             startActivity(intent)
                         } catch (e: ActivityNotFoundException) {

+ 2 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt

@@ -8,6 +8,7 @@ import android.content.Intent
 import android.net.Uri
 import android.os.Bundle
 import android.view.View
+import androidx.core.net.toUri
 import androidx.preference.PreferenceScreen
 import com.afollestad.materialdialogs.MaterialDialog
 import com.afollestad.materialdialogs.list.listItemsMultiChoice
@@ -126,7 +127,7 @@ class SettingsBackupController : SettingsController() {
 
                 preferences.backupsDirectory().asFlow()
                     .onEach { path ->
-                        val dir = UniFile.fromUri(context, Uri.parse(path))
+                        val dir = UniFile.fromUri(context, path.toUri())
                         summary = dir.filePath + "/automatic"
                     }
                     .launchIn(scope)

+ 3 - 3
app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt

@@ -4,10 +4,10 @@ import android.app.Activity
 import android.app.Dialog
 import android.content.ActivityNotFoundException
 import android.content.Intent
-import android.net.Uri
 import android.os.Bundle
 import android.os.Environment
 import androidx.core.content.ContextCompat
+import androidx.core.net.toUri
 import androidx.preference.PreferenceScreen
 import com.afollestad.materialdialogs.MaterialDialog
 import com.afollestad.materialdialogs.list.listItemsSingleChoice
@@ -54,7 +54,7 @@ class SettingsDownloadController : SettingsController() {
 
             preferences.downloadsDirectory().asFlow()
                 .onEach { path ->
-                    val dir = UniFile.fromUri(context, Uri.parse(path))
+                    val dir = UniFile.fromUri(context, path.toUri())
                     summary = dir.filePath ?: path
                 }
                 .launchIn(scope)
@@ -143,7 +143,7 @@ class SettingsDownloadController : SettingsController() {
     }
 
     fun predefinedDirectorySelected(selectedDir: String) {
-        val path = Uri.fromFile(File(selectedDir))
+        val path = File(selectedDir).toUri()
         preferences.downloadsDirectory().set(path.toString())
     }
 

+ 2 - 1
app/src/main/java/eu/kanade/tachiyomi/util/storage/DiskUtil.kt

@@ -6,6 +6,7 @@ import android.net.Uri
 import android.os.Environment
 import android.os.StatFs
 import androidx.core.content.ContextCompat
+import androidx.core.net.toUri
 import androidx.core.os.EnvironmentCompat
 import com.hippo.unifile.UniFile
 import eu.kanade.tachiyomi.util.lang.Hash
@@ -77,7 +78,7 @@ object DiskUtil {
      * Scans the given file so that it can be shown in gallery apps, for example.
      */
     fun scanMedia(context: Context, file: File) {
-        scanMedia(context, Uri.fromFile(file))
+        scanMedia(context, file.toUri())
     }
 
     /**

+ 2 - 1
app/src/main/java/eu/kanade/tachiyomi/util/storage/FileExtensions.kt

@@ -4,6 +4,7 @@ import android.content.Context
 import android.net.Uri
 import android.os.Build
 import androidx.core.content.FileProvider
+import androidx.core.net.toUri
 import eu.kanade.tachiyomi.BuildConfig
 import java.io.File
 
@@ -16,6 +17,6 @@ fun File.getUriCompat(context: Context): Uri {
     return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
         FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", this)
     } else {
-        Uri.fromFile(this)
+        this.toUri()
     }
 }

+ 9 - 8
app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt

@@ -13,7 +13,6 @@ import android.content.pm.PackageManager
 import android.content.res.Resources
 import android.graphics.Color
 import android.net.ConnectivityManager
-import android.net.Uri
 import android.os.PowerManager
 import android.view.View
 import android.widget.Toast
@@ -23,6 +22,12 @@ import androidx.annotation.StringRes
 import androidx.browser.customtabs.CustomTabsIntent
 import androidx.core.app.NotificationCompat
 import androidx.core.content.ContextCompat
+import androidx.core.content.getSystemService
+import androidx.core.graphics.alpha
+import androidx.core.graphics.blue
+import androidx.core.graphics.green
+import androidx.core.graphics.red
+import androidx.core.net.toUri
 import androidx.localbroadcastmanager.content.LocalBroadcastManager
 import com.nononsenseapps.filepicker.FilePickerActivity
 import eu.kanade.tachiyomi.R
@@ -126,11 +131,8 @@ fun Context.hasPermission(permission: String) = ContextCompat.checkSelfPermissio
     typedArray.recycle()
 
     if (alphaFactor < 1f) {
-        val alpha = (Color.alpha(color) * alphaFactor).roundToInt()
-        val red = Color.red(color)
-        val green = Color.green(color)
-        val blue = Color.blue(color)
-        return Color.argb(alpha, red, green, blue)
+        val alpha = (color.alpha * alphaFactor).roundToInt()
+        return Color.argb(alpha, color.red, color.green, color.blue)
     }
 
     return color
@@ -239,11 +241,10 @@ fun Context.isServiceRunning(serviceClass: Class<*>): Boolean {
  */
 fun Context.openInBrowser(url: String) {
     try {
-        val parsedUrl = Uri.parse(url)
         val intent = CustomTabsIntent.Builder()
             .setToolbarColor(getResourceColor(R.attr.colorPrimary))
             .build()
-        intent.launchUrl(this, parsedUrl)
+        intent.launchUrl(this, url.toUri())
     } catch (e: Exception) {
         toast(e.message)
     }

+ 4 - 5
app/src/main/java/eu/kanade/tachiyomi/widget/MaxHeightViewPager.kt

@@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.widget
 
 import android.content.Context
 import android.util.AttributeSet
+import androidx.core.view.forEach
 import androidx.viewpager.widget.ViewPager
 
 /**
@@ -14,13 +15,11 @@ class MaxHeightViewPager(context: Context, attrs: AttributeSet?) : ViewPager(con
         var measuredHeight = heightMeasureSpec
 
         var height = 0
-        for (i in 0 until childCount) {
-            val child = getChildAt(i)
-            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED))
-            val h = child.measuredHeight
+        forEach {
+            it.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED))
+            val h = it.measuredHeight
             if (h > height) height = h
         }
-
         if (height != 0) {
             measuredHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
         }

+ 4 - 7
app/src/main/java/eu/kanade/tachiyomi/widget/RevealAnimationView.kt

@@ -1,11 +1,11 @@
 package eu.kanade.tachiyomi.widget
 
 import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
 import android.content.Context
 import android.util.AttributeSet
 import android.view.View
 import android.view.ViewAnimationUtils
+import androidx.core.animation.doOnEnd
 import androidx.core.view.isInvisible
 import androidx.core.view.isVisible
 
@@ -32,12 +32,9 @@ class RevealAnimationView @JvmOverloads constructor(context: Context, attrs: Att
         anim.duration = 500
 
         // make the view invisible when the animation is done
-        anim.addListener(object : AnimatorListenerAdapter() {
-            override fun onAnimationEnd(animation: Animator) {
-                super.onAnimationEnd(animation)
-                [email protected] = true
-            }
-        })
+        anim.doOnEnd {
+            [email protected] = true
+        }
 
         anim.start()
     }