diff --git a/app/build.gradle.kts b/app/build.gradle.kts index eae53fa958..19b8a8ff46 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -90,7 +90,7 @@ dependencies { implementation("com.github.inorichi:subsampling-scale-image-view:ac0dae7") implementation("com.github.inorichi:junrar-android:634c1f5") - // Android support library + // Android X libraries implementation("androidx.appcompat:appcompat:1.1.0") implementation("androidx.cardview:cardview:1.0.0") implementation("com.google.android.material:material:1.1.0") @@ -100,12 +100,13 @@ dependencies { implementation("androidx.browser:browser:1.2.0") implementation("androidx.biometric:biometric:1.0.1") implementation("androidx.palette:palette:1.0.0") + implementation ("androidx.core:core-ktx:$1.3.1") implementation("androidx.constraintlayout:constraintlayout:1.1.3") implementation("androidx.multidex:multidex:2.0.1") - implementation("com.google.firebase:firebase-core:17.3.0") + implementation("com.google.firebase:firebase-core:17.4.4") val lifecycleVersion = "2.2.0" implementation("androidx.lifecycle:lifecycle-extensions:$lifecycleVersion") diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreateService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreateService.kt index a212db9de4..9e3120774d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreateService.kt +++ b/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.isServiceRunning @@ -108,7 +109,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) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreatorJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreatorJob.kt index bfce0dc367..b4c9f1f312 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreatorJob.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreatorJob.kt @@ -2,6 +2,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 @@ -19,7 +20,7 @@ class BackupCreatorJob(private val context: Context, workerParams: WorkerParamet override fun doWork(): Result { val preferences = Injekt.get() val backupManager = BackupManager(context) - val uri = Uri.parse(preferences.backupsDirectory().getOrDefault()) + val uri = preferences.backupsDirectory().getOrDefault().toUri() val flags = BackupCreateService.BACKUP_ALL return try { backupManager.createBackup(uri, flags, true) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt index d38a2318f9..0d4387ff80 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt +++ b/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.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Chapter @@ -57,7 +57,7 @@ class DownloadCache( */ private fun getDirectoryFromPreference(): UniFile { val dir = preferences.downloadsDirectory().getOrDefault() - return UniFile.fromUri(context, Uri.parse(dir)) + return UniFile.fromUri(context, dir.toUri()) } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt index 963151ab89..1c2cf6d42d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt @@ -2,6 +2,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.DatabaseHelper @@ -31,14 +32,14 @@ class DownloadProvider(private val context: Context) { * The root directory for downloads. */ private var downloadsDir = preferences.downloadsDirectory().getOrDefault().let { - val dir = UniFile.fromUri(context, Uri.parse(it)) + val dir = UniFile.fromUri(context, it.toUri()) DiskUtil.createNoMediaFile(dir, context) dir } init { preferences.downloadsDirectory().asObservable().skip(1) - .subscribe { downloadsDir = UniFile.fromUri(context, Uri.parse(it)) } + .subscribe { downloadsDir = UniFile.fromUri(context, it.toUri()) } } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt index 96c9f3a609..b167cb85bf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt +++ b/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 @@ -232,7 +233,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) { return baseMangaUrl + mediaId } - fun authUrl() = Uri.parse("${baseUrl}oauth/authorize").buildUpon() + fun authUrl() = "${baseUrl.toUri()}oauth/authorize".toUri().buildUpon() .appendQueryParameter("client_id", clientId) .appendQueryParameter("response_type", "token") .build()!! diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt index 3a60e60f2c..42d6b8a881 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt +++ b/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 @@ -56,9 +57,8 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept suspend fun search(search: String): List { return withContext(Dispatchers.IO) { - val url = Uri.parse( - "$apiUrl/search/subject/${URLEncoder.encode(search, Charsets.UTF_8.name())}" - ).buildUpon().appendQueryParameter("max_results", "20").build() + val url = "$apiUrl/search/subject/${URLEncoder.encode(search, Charsets.UTF_8.name())}" + .toUri().buildUpon().appendQueryParameter("max_results", "20").build() val request = Request.Builder().url(url.toString()).get().build() val netResponse = authClient.newCall(request).await() @@ -159,7 +159,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept return "$baseMangaUrl/$remoteId" } - fun authUrl() = Uri.parse(loginUrl).buildUpon().appendQueryParameter("client_id", clientId) + fun authUrl() = loginUrl.toUri().buildUpon().appendQueryParameter("client_id", clientId) .appendQueryParameter("response_type", "code") .appendQueryParameter("redirect_uri", redirectUrl).build() diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt index 3fd51a0454..8626531d86 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt @@ -1,6 +1,7 @@ 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 @@ -182,31 +183,31 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI private fun mangaUrl(remoteId: Int) = baseMangaUrl + remoteId - private fun loginUrl() = Uri.parse(baseUrl).buildUpon().appendPath("login.php").toString() + private fun loginUrl() = baseUrl.toUri().buildUpon().appendPath("login.php").toString() private fun searchUrl(query: String): String { val col = "c[]" - return Uri.parse(baseUrl).buildUpon().appendPath("manga.php") + return baseUrl.toUri().buildUpon().appendPath("manga.php") .appendQueryParameter("q", query).appendQueryParameter(col, "a") .appendQueryParameter(col, "b").appendQueryParameter(col, "c") .appendQueryParameter(col, "d").appendQueryParameter(col, "e") .appendQueryParameter(col, "g").toString() } - private fun exportListUrl() = Uri.parse(baseUrl).buildUpon().appendPath("panel.php") + private fun exportListUrl() = baseUrl.toUri().buildUpon().appendPath("panel.php") .appendQueryParameter("go", "export").toString() private fun updateUrl() = - Uri.parse(baseModifyListUrl).buildUpon().appendPath("edit.json").toString() + baseModifyListUrl.toUri().buildUpon().appendPath("edit.json").toString() - private fun removeUrl(mediaId: Int) = Uri.parse(baseModifyListUrl).buildUpon().appendPath(mediaId.toString()) + private fun removeUrl(mediaId: Int) = baseModifyListUrl.toUri().buildUpon().appendPath(mediaId.toString()) .appendPath("delete").toString() private fun addUrl() = - Uri.parse(baseModifyListUrl).buildUpon().appendPath("add.json").toString() + baseModifyListUrl.toUri().buildUpon().appendPath("add.json").toString() private fun listEntryUrl(mediaId: Int) = - Uri.parse(baseModifyListUrl).buildUpon().appendPath(mediaId.toString()) + baseModifyListUrl.toUri().buildUpon().appendPath(mediaId.toString()) .appendPath("edit").toString() private fun loginPostBody(username: String, password: String, csrf: String): RequestBody { diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt index 378ac7dc4b..f9addd78b4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt @@ -1,6 +1,7 @@ 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 @@ -52,7 +53,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter suspend fun search(search: String): List { return withContext(Dispatchers.IO) { val url = - Uri.parse("$apiUrl/mangas").buildUpon().appendQueryParameter("order", "popularity") + "$apiUrl/mangas".toUri().buildUpon().appendQueryParameter("order", "popularity") .appendQueryParameter("search", search).appendQueryParameter("limit", "20") .build() val request = Request.Builder().url(url.toString()).get().build() @@ -96,14 +97,13 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter suspend fun findLibManga(track: Track, user_id: String): Track? { return withContext(Dispatchers.IO) { - 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").build() val request = Request.Builder().url(url.toString()).get().build() - val urlMangas = - Uri.parse("$apiUrl/mangas").buildUpon().appendPath(track.media_id.toString()) + val urlMangas ="$apiUrl/mangas".toUri().buildUpon().appendPath(track.media_id.toString()) .build() val requestMangas = Request.Builder().url(urlMangas.toString()).get().build() @@ -171,7 +171,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter return "$baseMangaUrl/$remoteId" } - fun authUrl() = Uri.parse(loginUrl).buildUpon().appendQueryParameter("client_id", clientId) + fun authUrl() = loginUrl.toUri().buildUpon().appendQueryParameter("client_id", clientId) .appendQueryParameter("redirect_uri", redirectUrl) .appendQueryParameter("response_type", "code").build() diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstaller.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstaller.kt index 26a3f9fe1c..64d717a973 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstaller.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstaller.kt @@ -7,6 +7,7 @@ import android.content.Intent import android.content.IntentFilter import android.net.Uri import android.os.Environment +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 +64,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) @@ -141,7 +142,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 packageUri = "package:$pkgName".toUri() val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt b/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt index 8a7ac531fb..692fc11514 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt @@ -31,17 +31,19 @@ import java.util.zip.ZipFile class LocalSource(private val context: Context) : CatalogueSource { companion object { + const val ID = 0L const val HELP_URL = "https://tachiyomi.org/help/guides/reading-local-manga/" private const val COVER_NAME = "cover.jpg" + private val SUPPORTED_ARCHIVE_TYPES = setOf("zip", "rar", "cbr", "cbz", "epub") + private val POPULAR_FILTERS = FilterList(OrderBy()) private val LATEST_FILTERS = FilterList(OrderBy().apply { state = Filter.Sort.Selection(1, false) }) private val LATEST_THRESHOLD = TimeUnit.MILLISECONDS.convert(7, TimeUnit.DAYS) - const val ID = 0L fun updateCover(context: Context, manga: SManga, input: InputStream): File? { - val dir = getBaseDirectories(context).firstOrNull() + val dir = getBaseDirectories(context).asSequence().firstOrNull() if (dir == null) { input.close() return null @@ -85,12 +87,12 @@ class LocalSource(private val context: Context) : CatalogueSource { val time = if (filters === LATEST_FILTERS) System.currentTimeMillis() - LATEST_THRESHOLD else 0L - var mangaDirs = baseDirs.mapNotNull { it.listFiles()?.toList() }.flatten().filter { - it.isDirectory && if (time == 0L) it.name.contains( - query, - ignoreCase = true - ) else it.lastModified() >= time - }.distinctBy { it.name } + var mangaDirs = baseDirs + .asSequence() + .mapNotNull { it.listFiles()?.toList() }.flatten() + .filter { it.isDirectory } + .filter { if (time == 0L) it.name.contains(query, ignoreCase = true) else it.lastModified() >= time } + .distinctBy { it.name } val state = ((if (filters.isEmpty()) POPULAR_FILTERS else filters)[0] as OrderBy).state when (state?.index) { @@ -134,15 +136,17 @@ class LocalSource(private val context: Context) : CatalogueSource { } } } - return Observable.just(MangasPage(mangas, false)) + return Observable.just(MangasPage(mangas.toList(), false)) } override fun fetchLatestUpdates(page: Int) = fetchSearchManga(page, "", LATEST_FILTERS) override fun fetchMangaDetails(manga: SManga): Observable { val baseDirs = getBaseDirectories(context) - baseDirs.mapNotNull { File(it, manga.url).listFiles()?.toList() } - .flatten().filter { it.extension == "json" }.firstOrNull()?.apply { + baseDirs + .mapNotNull { File(it, manga.url).listFiles()?.toList() } + .flatten() + .filter { it.extension == "json" }.firstOrNull()?.apply { val json = Gson().fromJson( Scanner(this).useDelimiter("\\Z").next(), JsonObject::class.java @@ -155,6 +159,7 @@ class LocalSource(private val context: Context) : CatalogueSource { ?: manga.genre manga.status = json["status"]?.asInt ?: manga.status } + val url = manga.url // Try to find the cover for (dir in baseDirs) { @@ -249,7 +254,7 @@ class LocalSource(private val context: Context) : CatalogueSource { } private fun isSupportedFile(extension: String): Boolean { - return extension.toLowerCase() in setOf("zip", "rar", "cbr", "cbz", "epub") + return extension.toLowerCase() in SUPPORTED_ARCHIVE_TYPES } fun getFormat(chapter: SChapter): Format { @@ -283,22 +288,23 @@ class LocalSource(private val context: Context) : CatalogueSource { val format = getFormat(chapter) return when (format) { is Format.Directory -> { - val entry = format.file.listFiles().sortedWith(Comparator { f1, f2 -> + val entry = format.file.listFiles() + ?.sortedWith(Comparator { f1, f2 -> f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) }) - .find { !it.isDirectory && ImageUtil.isImage(it.name) { FileInputStream(it) } } + ?.find { !it.isDirectory && ImageUtil.isImage(it.name) { FileInputStream(it) } } entry?.let { updateCover(context, manga, it.inputStream()) } } is Format.Zip -> { ZipFile(format.file).use { zip -> val entry = zip.entries().toList().sortedWith(Comparator { f1, f2 -> - f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) - }).find { - !it.isDirectory && ImageUtil.isImage(it.name) { - zip.getInputStream(it) - } + f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) + }).find { + !it.isDirectory && ImageUtil.isImage(it.name) { + zip.getInputStream(it) } + } entry?.let { updateCover(context, manga, zip.getInputStream(it)) } } @@ -306,12 +312,12 @@ class LocalSource(private val context: Context) : CatalogueSource { is Format.Rar -> { Archive(format.file).use { archive -> val entry = archive.fileHeaders.sortedWith(Comparator { f1, f2 -> - f1.fileNameString.compareToCaseInsensitiveNaturalOrder(f2.fileNameString) - }).find { - !it.isDirectory && ImageUtil.isImage(it.fileNameString) { - archive.getInputStream(it) - } + f1.fileNameString.compareToCaseInsensitiveNaturalOrder(f2.fileNameString) + }).find { + !it.isDirectory && ImageUtil.isImage(it.fileNameString) { + archive.getInputStream(it) } + } entry?.let { updateCover(context, manga, archive.getInputStream(it)) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackingBottomSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackingBottomSheet.kt index 4aadcb72a3..ba4f98ad8c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackingBottomSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackingBottomSheet.kt @@ -5,6 +5,7 @@ import android.net.Uri import android.os.Bundle import android.view.View import android.view.ViewGroup +import androidx.core.net.toUri import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog @@ -117,7 +118,7 @@ class TrackingBottomSheet(private val controller: MangaDetailsController) : Bott if (track.tracking_url.isBlank()) { activity.toast(R.string.url_not_set_click_again) } else { - activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(track.tracking_url))) + activity.startActivity(Intent(Intent.ACTION_VIEW, track.tracking_url.toUri())) controller.refreshTracker = position } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt index 1fb9c833fd..86e6bbb850 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt @@ -18,6 +18,7 @@ import android.widget.FrameLayout import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView +import androidx.core.net.toUri import coil.api.loadAny import coil.request.CachePolicy import com.davemorrissey.labs.subscaleview.ImageSource @@ -465,7 +466,7 @@ class PagerPageHolder( } setText(R.string.open_in_browser) setOnClickListener { - val intent = Intent(Intent.ACTION_VIEW, Uri.parse(imageUrl)) + val intent = Intent(Intent.ACTION_VIEW, imageUrl.toUri()) context.startActivity(intent) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt index 12b4aab5ea..a91b90b20e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt @@ -15,6 +15,7 @@ import android.widget.LinearLayout import android.widget.TextView import androidx.appcompat.widget.AppCompatButton import androidx.appcompat.widget.AppCompatImageView +import androidx.core.net.toUri import coil.api.clear import coil.api.loadAny import coil.request.CachePolicy @@ -458,7 +459,7 @@ class WebtoonPageHolder( } setText(R.string.open_in_browser) setOnClickListener { - val intent = Intent(Intent.ACTION_VIEW, Uri.parse(imageUrl)) + val intent = Intent(Intent.ACTION_VIEW, imageUrl.toUri()) context.startActivity(intent) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/security/BiometricActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/security/BiometricActivity.kt index 944b3e1f3c..f097e2ca42 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/security/BiometricActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/security/BiometricActivity.kt @@ -33,7 +33,7 @@ class BiometricActivity : BaseActivity() { val promptInfo = BiometricPrompt.PromptInfo.Builder() .setTitle(getString(R.string.unlock_library)) - .setNegativeButtonText(getString(android.R.string.cancel)) + .setDeviceCredentialAllowed(true) .build() biometricPrompt.authenticate(promptInfo) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/AboutController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/AboutController.kt index 8d7060e530..9575a7c521 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/AboutController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/AboutController.kt @@ -4,6 +4,7 @@ import android.app.Dialog import android.content.Intent import android.net.Uri import android.os.Bundle +import androidx.core.net.toUri import androidx.preference.PreferenceScreen import com.afollestad.materialdialogs.MaterialDialog import com.google.android.gms.oss.licenses.OssLicensesMenuActivity @@ -58,7 +59,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) } } @@ -68,7 +69,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) } } @@ -77,7 +78,7 @@ class AboutController : SettingsController() { val url = "https://github.com/Jays2Kings/tachiyomiJ2K" summary = url onClick { - val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + val intent = Intent(Intent.ACTION_VIEW, url.toUri()) startActivity(intent) } } @@ -86,13 +87,12 @@ class AboutController : SettingsController() { titleRes = R.string.whats_new onClick { val intent = Intent( - Intent.ACTION_VIEW, Uri.parse( + Intent.ACTION_VIEW, if (BuildConfig.DEBUG) { "https://github.com/Jays2Kings/tachiyomiJ2K/commits/master" } else { "https://github.com/Jays2Kings/tachiyomiJ2K/releases/tag/v${BuildConfig.VERSION_NAME}" - } - ) + }.toUri() ) startActivity(intent) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt index dd39b4ed17..992328a33e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt @@ -10,6 +10,7 @@ import android.os.Bundle import android.os.PowerManager import android.provider.Settings import android.widget.Toast +import androidx.core.net.toUri import androidx.preference.PreferenceScreen import com.afollestad.materialdialogs.MaterialDialog import eu.kanade.tachiyomi.R @@ -122,7 +123,7 @@ class SettingsAdvancedController : SettingsController() { if (!pm.isIgnoringBatteryOptimizations(packageName)) { val intent = Intent().apply { action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS - data = Uri.parse("package:$packageName") + data = "package:$packageName".toUri() } startActivity(intent) } else { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt index 1be34017a6..e085caac36 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt +++ b/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 @@ -102,7 +103,7 @@ class SettingsBackupController : SettingsController() { preferences.backupsDirectory().asObservable() .subscribeUntilDestroy { path -> - val dir = UniFile.fromUri(context, Uri.parse(path)) + val dir = UniFile.fromUri(context, path.toUri()) summary = dir.filePath + "/automatic" } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt index 995352527e..8af76d799d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt @@ -8,6 +8,7 @@ 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 @@ -42,7 +43,7 @@ class SettingsDownloadController : SettingsController() { preferences.downloadsDirectory().asObservable() .subscribeUntilDestroy { path -> - val dir = UniFile.fromUri(context, Uri.parse(path)) + val dir = UniFile.fromUri(context, path.toUri()) summary = dir.filePath ?: path } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt index fb6fc3769d..cbd2b5f760 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt @@ -25,6 +25,7 @@ import androidx.annotation.StringRes import androidx.browser.customtabs.CustomTabsIntent import androidx.core.app.NotificationCompat import androidx.core.content.ContextCompat +import androidx.core.net.toUri import com.nononsenseapps.filepicker.FilePickerActivity import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.widget.CustomLayoutPickerActivity @@ -223,7 +224,7 @@ fun Context.isServiceRunning(serviceClass: Class<*>): Boolean { */ fun Context.openInBrowser(url: String) { try { - val parsedUrl = Uri.parse(url) + val parsedUrl = url.toUri() val intent = CustomTabsIntent.Builder() .setToolbarColor(getResourceColor(R.attr.colorPrimaryVariant)) .build()