More core-ktx usages

This commit is contained in:
arkon 2020-07-31 10:29:32 -04:00
parent eb0e0a1952
commit ec56c27071
29 changed files with 120 additions and 133 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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