diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b695c8260..8f2401737 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -29,7 +29,7 @@ android { minSdk = AndroidConfig.minSdk targetSdk = AndroidConfig.targetSdk testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - versionCode = 70 + versionCode = 71 versionName = "0.12.3.2" buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"") @@ -231,8 +231,8 @@ dependencies { // UI libraries implementation("com.google.android.material:material:1.5.0-alpha04") implementation("com.github.dmytrodanylyk.android-process-button:library:1.0.4") - implementation("eu.davidea:flexible-adapter:5.1.0") - implementation("eu.davidea:flexible-adapter-ui:1.0.0") + implementation("com.github.arkon.FlexibleAdapter:flexible-adapter:c8013533") + implementation("com.github.arkon.FlexibleAdapter:flexible-adapter-ui:c8013533") implementation("com.nightlynexus.viewstatepageradapter:viewstatepageradapter:1.1.0") implementation("com.github.chrisbanes:PhotoView:2.3.0") implementation("com.github.tachiyomiorg:DirectionalViewPager:1.0.0") { diff --git a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt index c16465988..e107423a1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt @@ -254,6 +254,15 @@ object Migrations { preferences.enabledLanguages() += "all" } } + if (oldVersion < 71) { + // Handle removed every 3, 4, 6, and 8 hour library updates + val updateInterval = preferences.libraryUpdateInterval().get() + if (updateInterval in listOf(3, 4, 6, 8)) { + preferences.libraryUpdateInterval().set(12) + LibraryUpdateJob.setupTask(context, 12) + AnimelibUpdateJob.setupTask(context, 12) + } + } return true } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/animelib/AnimelibUpdateNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/data/animelib/AnimelibUpdateNotifier.kt index 8de980d76..a5bc5344c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/animelib/AnimelibUpdateNotifier.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/animelib/AnimelibUpdateNotifier.kt @@ -88,20 +88,6 @@ class AnimelibUpdateNotifier(private val context: Context) { ) } - fun showQueueSizeWarningNotification() { - val notification = context.notificationBuilder(Notifications.CHANNEL_LIBRARY_PROGRESS) { - setContentTitle(context.getString(R.string.label_warning)) - setSmallIcon(R.drawable.ic_warning_white_24dp) - setStyle(NotificationCompat.BigTextStyle().bigText(context.getString(R.string.notification_size_warning))) - } - .build() - - context.notificationManager.notify( - Notifications.ID_LIBRARY_SIZE_WARNING, - notification, - ) - } - /** * Shows notification containing update entries that failed with action to open full log. * @@ -117,23 +103,10 @@ class AnimelibUpdateNotifier(private val context: Context) { Notifications.ID_LIBRARY_ERROR, context.notificationBuilder(Notifications.CHANNEL_LIBRARY_ERROR) { setContentTitle(context.resources.getQuantityString(R.plurals.notification_update_error, errors.size, errors.size)) - setStyle( - NotificationCompat.BigTextStyle().bigText( - errors.joinToString("\n") { - it.chop(NOTIF_TITLE_MAX_LEN) - } - ) - ) + setContentText(context.getString(R.string.action_show_errors)) setSmallIcon(R.drawable.ic_tachi) - val errorLogIntent = NotificationReceiver.openErrorLogPendingActivity(context, uri) - - setContentIntent(errorLogIntent) - addAction( - R.drawable.ic_folder_24dp, - context.getString(R.string.action_show_errors), - errorLogIntent - ) + setContentIntent(NotificationReceiver.openErrorLogPendingActivity(context, uri)) } .build() ) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/animelib/AnimelibUpdateService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/animelib/AnimelibUpdateService.kt index ac7dc40c9..bbf33712c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/animelib/AnimelibUpdateService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/animelib/AnimelibUpdateService.kt @@ -5,6 +5,7 @@ import android.content.Context import android.content.Intent import android.os.IBinder import android.os.PowerManager +import android.widget.Toast import androidx.core.content.ContextCompat import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.animesource.AnimeSourceManager @@ -38,6 +39,7 @@ import eu.kanade.tachiyomi.util.system.acquireWakeLock import eu.kanade.tachiyomi.util.system.createFileInCacheDir import eu.kanade.tachiyomi.util.system.isServiceRunning import eu.kanade.tachiyomi.util.system.logcat +import eu.kanade.tachiyomi.util.system.toast import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -267,8 +269,8 @@ class AnimelibUpdateService( // Warn when excessively checking a single source val maxUpdatesFromSource = animeToUpdate.groupBy { it.source }.maxOf { it.value.size } - if (maxUpdatesFromSource > PER_SOURCE_QUEUE_WARNING_THRESHOLD) { - notifier.showQueueSizeWarningNotification() + if (maxUpdatesFromSource > ANIME_PER_SOURCE_QUEUE_WARNING_THRESHOLD) { + toast(R.string.notification_size_warning, Toast.LENGTH_LONG) } } @@ -443,14 +445,6 @@ class AnimelibUpdateService( logcat(LogPriority.ERROR, e) } } - - currentlyUpdatingAnime.remove(anime) - progressCount.andIncrement - notifier.showProgressNotification( - currentlyUpdatingAnime, - progressCount.get(), - animeToUpdate.size - ) } } } @@ -574,4 +568,4 @@ class AnimelibUpdateService( } } -const val PER_SOURCE_QUEUE_WARNING_THRESHOLD = 60 +private const val ANIME_PER_SOURCE_QUEUE_WARNING_THRESHOLD = 60 diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupNotifier.kt index faf7fc92f..f0c9873a3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupNotifier.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupNotifier.kt @@ -139,10 +139,12 @@ class BackupNotifier(private val context: Context) { val destFile = File(path, file) val uri = destFile.getUriCompat(context) + val errorLogIntent = NotificationReceiver.openErrorLogPendingActivity(context, uri) + setContentIntent(errorLogIntent) addAction( R.drawable.ic_folder_24dp, context.getString(R.string.action_show_errors), - NotificationReceiver.openErrorLogPendingActivity(context, uri) + errorLogIntent, ) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/AnimeDownloadNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/AnimeDownloadNotifier.kt index cec0ec16f..f1122bf1f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/AnimeDownloadNotifier.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/AnimeDownloadNotifier.kt @@ -186,7 +186,7 @@ internal class AnimeDownloadNotifier(private val context: Context) { */ fun onWarning(reason: String) { with(errorNotificationBuilder) { - setContentTitle(context.getString(R.string.label_warning)) + setContentTitle(context.getString(R.string.download_notifier_downloader_title)) setStyle(NotificationCompat.BigTextStyle().bigText(reason)) setSmallIcon(R.drawable.ic_warning_white_24dp) setAutoCancel(true) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/AnimeDownloader.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/AnimeDownloader.kt index 3e47e7578..fcdb91127 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/AnimeDownloader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/AnimeDownloader.kt @@ -5,6 +5,7 @@ import android.content.Context import android.content.Intent import android.net.Uri import android.webkit.MimeTypeMap +import android.widget.Toast import com.arthenica.ffmpegkit.ExecuteCallback import com.arthenica.ffmpegkit.FFmpegKitConfig import com.arthenica.ffmpegkit.FFmpegSession @@ -19,7 +20,6 @@ import eu.kanade.tachiyomi.animesource.AnimeSourceManager import eu.kanade.tachiyomi.animesource.model.Video import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource import eu.kanade.tachiyomi.animesource.online.fetchUrlFromVideo -import eu.kanade.tachiyomi.data.animelib.PER_SOURCE_QUEUE_WARNING_THRESHOLD import eu.kanade.tachiyomi.data.cache.EpisodeCache import eu.kanade.tachiyomi.data.database.models.Anime import eu.kanade.tachiyomi.data.database.models.Episode @@ -29,10 +29,12 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchNow import eu.kanade.tachiyomi.util.lang.plusAssign +import eu.kanade.tachiyomi.util.lang.withUIContext import eu.kanade.tachiyomi.util.storage.DiskUtil import eu.kanade.tachiyomi.util.storage.saveTo import eu.kanade.tachiyomi.util.system.ImageUtil import eu.kanade.tachiyomi.util.system.logcat +import eu.kanade.tachiyomi.util.system.toast import kotlinx.coroutines.async import logcat.LogPriority import okhttp3.HttpUrl.Companion.toHttpUrl @@ -290,8 +292,10 @@ class AnimeDownloader( // Start downloader if needed if (autoStart && wasEmpty) { val maxDownloadsFromSource = queue.groupBy { it.source }.maxOf { it.value.size } - if (maxDownloadsFromSource > PER_SOURCE_QUEUE_WARNING_THRESHOLD) { - notifier.onWarning(context.getString(R.string.notification_size_warning)) + if (maxDownloadsFromSource > EPISODES_PER_SOURCE_QUEUE_WARNING_THRESHOLD) { + withUIContext { + context.toast(R.string.download_queue_size_warning, Toast.LENGTH_LONG) + } } AnimeDownloadService.start(context) } @@ -676,8 +680,10 @@ class AnimeDownloader( companion object { const val TMP_DIR_SUFFIX = "_tmp" - - // Arbitrary minimum required space to start a download: 50 MB - const val MIN_DISK_SPACE = 50 * 1024 * 1024 } } + +private const val EPISODES_PER_SOURCE_QUEUE_WARNING_THRESHOLD = 15 + +// Arbitrary minimum required space to start a download: 50 MB +private const val MIN_DISK_SPACE = 50 * 1024 * 1024 diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt index d3c7b46a8..e73acf1f1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt @@ -187,7 +187,7 @@ internal class DownloadNotifier(private val context: Context) { */ fun onWarning(reason: String) { with(errorNotificationBuilder) { - setContentTitle(context.getString(R.string.label_warning)) + setContentTitle(context.getString(R.string.download_notifier_downloader_title)) setStyle(NotificationCompat.BigTextStyle().bigText(reason)) setSmallIcon(R.drawable.ic_warning_white_24dp) setAutoCancel(true) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt index 8cd520cbf..7a75e633b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt @@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.data.download import android.content.Context import android.webkit.MimeTypeMap +import android.widget.Toast import com.hippo.unifile.UniFile import com.jakewharton.rxrelay.BehaviorRelay import com.jakewharton.rxrelay.PublishRelay @@ -11,7 +12,6 @@ import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.DownloadQueue -import eu.kanade.tachiyomi.data.library.PER_SOURCE_QUEUE_WARNING_THRESHOLD import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.online.HttpSource @@ -20,10 +20,12 @@ import eu.kanade.tachiyomi.util.lang.RetryWithDelay import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchNow import eu.kanade.tachiyomi.util.lang.plusAssign +import eu.kanade.tachiyomi.util.lang.withUIContext import eu.kanade.tachiyomi.util.storage.DiskUtil import eu.kanade.tachiyomi.util.storage.saveTo import eu.kanade.tachiyomi.util.system.ImageUtil import eu.kanade.tachiyomi.util.system.logcat +import eu.kanade.tachiyomi.util.system.toast import kotlinx.coroutines.async import logcat.LogPriority import okhttp3.Response @@ -265,8 +267,10 @@ class Downloader( // Start downloader if needed if (autoStart && wasEmpty) { val maxDownloadsFromSource = queue.groupBy { it.source }.maxOf { it.value.size } - if (maxDownloadsFromSource > PER_SOURCE_QUEUE_WARNING_THRESHOLD) { - notifier.onWarning(context.getString(R.string.notification_size_warning)) + if (maxDownloadsFromSource > CHAPTERS_PER_SOURCE_QUEUE_WARNING_THRESHOLD) { + withUIContext { + context.toast(R.string.download_queue_size_warning, Toast.LENGTH_LONG) + } } DownloadService.start(context) } @@ -506,8 +510,10 @@ class Downloader( companion object { const val TMP_DIR_SUFFIX = "_tmp" - - // Arbitrary minimum required space to start a download: 50 MB - const val MIN_DISK_SPACE = 50 * 1024 * 1024 } } + +private const val CHAPTERS_PER_SOURCE_QUEUE_WARNING_THRESHOLD = 15 + +// Arbitrary minimum required space to start a download: 50 MB +private const val MIN_DISK_SPACE = 50 * 1024 * 1024 diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateNotifier.kt index ac9a7618e..991ae3011 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateNotifier.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateNotifier.kt @@ -88,20 +88,6 @@ class LibraryUpdateNotifier(private val context: Context) { ) } - fun showQueueSizeWarningNotification() { - val notification = context.notificationBuilder(Notifications.CHANNEL_LIBRARY_PROGRESS) { - setContentTitle(context.getString(R.string.label_warning)) - setSmallIcon(R.drawable.ic_warning_white_24dp) - setStyle(NotificationCompat.BigTextStyle().bigText(context.getString(R.string.notification_size_warning))) - } - .build() - - context.notificationManager.notify( - Notifications.ID_LIBRARY_SIZE_WARNING, - notification, - ) - } - /** * Shows notification containing update entries that failed with action to open full log. * @@ -117,23 +103,10 @@ class LibraryUpdateNotifier(private val context: Context) { Notifications.ID_LIBRARY_ERROR, context.notificationBuilder(Notifications.CHANNEL_LIBRARY_ERROR) { setContentTitle(context.resources.getQuantityString(R.plurals.notification_update_error, errors.size, errors.size)) - setStyle( - NotificationCompat.BigTextStyle().bigText( - errors.joinToString("\n") { - it.chop(NOTIF_TITLE_MAX_LEN) - } - ) - ) + setContentText(context.getString(R.string.action_show_errors)) setSmallIcon(R.drawable.ic_tachi) - val errorLogIntent = NotificationReceiver.openErrorLogPendingActivity(context, uri) - - setContentIntent(errorLogIntent) - addAction( - R.drawable.ic_folder_24dp, - context.getString(R.string.action_show_errors), - errorLogIntent - ) + setContentIntent(NotificationReceiver.openErrorLogPendingActivity(context, uri)) } .build() ) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt index 87843f511..7ddd0ce29 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt @@ -5,6 +5,7 @@ import android.content.Context import android.content.Intent import android.os.IBinder import android.os.PowerManager +import android.widget.Toast import androidx.core.content.ContextCompat import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.cache.CoverCache @@ -38,6 +39,7 @@ import eu.kanade.tachiyomi.util.system.acquireWakeLock import eu.kanade.tachiyomi.util.system.createFileInCacheDir import eu.kanade.tachiyomi.util.system.isServiceRunning import eu.kanade.tachiyomi.util.system.logcat +import eu.kanade.tachiyomi.util.system.toast import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -267,8 +269,8 @@ class LibraryUpdateService( // Warn when excessively checking a single source val maxUpdatesFromSource = mangaToUpdate.groupBy { it.source }.maxOf { it.value.size } - if (maxUpdatesFromSource > PER_SOURCE_QUEUE_WARNING_THRESHOLD) { - notifier.showQueueSizeWarningNotification() + if (maxUpdatesFromSource > MANGA_PER_SOURCE_QUEUE_WARNING_THRESHOLD) { + toast(R.string.notification_size_warning, Toast.LENGTH_LONG) } } @@ -443,14 +445,6 @@ class LibraryUpdateService( logcat(LogPriority.ERROR, e) } } - - currentlyUpdatingManga.remove(manga) - progressCount.andIncrement - notifier.showProgressNotification( - currentlyUpdatingManga, - progressCount.get(), - mangaToUpdate.size - ) } } } @@ -574,4 +568,4 @@ class LibraryUpdateService( } } -const val PER_SOURCE_QUEUE_WARNING_THRESHOLD = 60 +private const val MANGA_PER_SOURCE_QUEUE_WARNING_THRESHOLD = 60 diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt index f114093f8..2d576bc29 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt @@ -27,7 +27,6 @@ object Notifications { private const val GROUP_LIBRARY = "group_library" const val CHANNEL_LIBRARY_PROGRESS = "library_progress_channel" const val ID_LIBRARY_PROGRESS = -101 - const val ID_LIBRARY_SIZE_WARNING = -103 const val CHANNEL_LIBRARY_ERROR = "library_errors_channel" const val ID_LIBRARY_ERROR = -102 diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/updater/AppUpdateChecker.kt b/app/src/main/java/eu/kanade/tachiyomi/data/updater/AppUpdateChecker.kt index 8b7580c74..6c05098a6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/updater/AppUpdateChecker.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/updater/AppUpdateChecker.kt @@ -10,24 +10,22 @@ import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.util.lang.withIOContext import uy.kohesive.injekt.injectLazy import java.util.Date +import java.util.concurrent.TimeUnit class AppUpdateChecker { private val networkService: NetworkHelper by injectLazy() private val preferences: PreferencesHelper by injectLazy() - private val repo: String by lazy { - if (BuildConfig.PREVIEW) { - "jmir1/aniyomi-preview" - } else { - "jmir1/aniyomi" - } - } - suspend fun checkForUpdate(context: Context): AppUpdateResult { + // Limit checks to once a day at most + if (Date().time < preferences.lastAppCheck().get() + TimeUnit.DAYS.toMillis(1)) { + return AppUpdateResult.NoNewUpdate + } + return withIOContext { val result = networkService.client - .newCall(GET("https://api.github.com/repos/$repo/releases/latest")) + .newCall(GET("https://api.github.com/repos/$GITHUB_REPO/releases/latest")) .await() .parseAs() .let { @@ -64,3 +62,21 @@ class AppUpdateChecker { } } } + +val GITHUB_REPO: String by lazy { + if (BuildConfig.PREVIEW) { + "jmir1/aniyomi-preview" + } else { + "jmir1/aniyomi" + } +} + +val RELEASE_TAG: String by lazy { + if (BuildConfig.PREVIEW) { + "r${BuildConfig.COMMIT_COUNT}" + } else { + "v${BuildConfig.VERSION_NAME}" + } +} + +val RELEASE_URL = "https://github.com/$GITHUB_REPO/releases/tag/$RELEASE_TAG" diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/api/AnimeExtensionGithubApi.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/api/AnimeExtensionGithubApi.kt index c9c59640e..b6275f62b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/api/AnimeExtensionGithubApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/api/AnimeExtensionGithubApi.kt @@ -13,6 +13,7 @@ import eu.kanade.tachiyomi.util.lang.withIOContext import kotlinx.serialization.Serializable import uy.kohesive.injekt.injectLazy import java.util.Date +import java.util.concurrent.TimeUnit internal class AnimeExtensionGithubApi { @@ -30,6 +31,11 @@ internal class AnimeExtensionGithubApi { } suspend fun checkForUpdates(context: Context): List { + // Limit checks to once a day at most + if (Date().time < preferences.lastExtCheck().get() + TimeUnit.DAYS.toMillis(1)) { + return emptyList() + } + val extensions = findExtensions() preferences.lastAnimeExtCheck().set(Date().time) diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt index 3ba47d7af..ba4d8750f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt @@ -13,6 +13,7 @@ import eu.kanade.tachiyomi.util.lang.withIOContext import kotlinx.serialization.Serializable import uy.kohesive.injekt.injectLazy import java.util.Date +import java.util.concurrent.TimeUnit internal class ExtensionGithubApi { @@ -30,6 +31,11 @@ internal class ExtensionGithubApi { } suspend fun checkForUpdates(context: Context): List { + // Limit checks to once a day at most + if (Date().time < preferences.lastExtCheck().get() + TimeUnit.DAYS.toMillis(1)) { + return emptyList() + } + val extensions = findExtensions() preferences.lastExtCheck().set(Date().time) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/ConductorExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/ConductorExtensions.kt index d225bec56..bc7ef0b6f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/ConductorExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/ConductorExtensions.kt @@ -9,6 +9,10 @@ import com.bluelinelabs.conductor.RouterTransaction import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.util.system.openInBrowser +fun Router.setRoot(controller: Controller, id: Int) { + setRoot(controller.withFadeTransaction().tag(id.toString())) +} + fun Router.popControllerWithTag(tag: String): Boolean { val controller = getControllerWithTag(tag) if (controller != null) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 385226028..6e191060d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -48,6 +48,7 @@ import eu.kanade.tachiyomi.ui.base.controller.FabController import eu.kanade.tachiyomi.ui.base.controller.NoAppBarElevationController import eu.kanade.tachiyomi.ui.base.controller.RootController import eu.kanade.tachiyomi.ui.base.controller.TabbedController +import eu.kanade.tachiyomi.ui.base.controller.setRoot import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.browse.BrowseController import eu.kanade.tachiyomi.ui.browse.animesource.browse.BrowseAnimeSourceController @@ -73,8 +74,6 @@ import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import logcat.LogPriority -import java.util.Date -import java.util.concurrent.TimeUnit import eu.kanade.tachiyomi.ui.download.anime.DownloadController as AnimeDownloadController import eu.kanade.tachiyomi.ui.download.manga.DownloadController as MangaDownloadController @@ -160,11 +159,11 @@ class MainActivity : BaseViewBindingActivity() { val currentRoot = router.backstack.firstOrNull() if (currentRoot?.tag()?.toIntOrNull() != id) { when (id) { - R.id.nav_library -> setRoot(LibraryController(), id) - R.id.nav_animelib -> setRoot(AnimelibController(), id) - R.id.nav_updates -> setRoot(UpdatesTabsController(), id) - R.id.nav_browse -> setRoot(BrowseController(), id) - R.id.nav_more -> setRoot(MoreController(), id) + R.id.nav_library -> router.setRoot(LibraryController(), id) + R.id.nav_animelib -> router.setRoot(AnimelibController(), id) + R.id.nav_updates -> router.setRoot(UpdatesTabsController(), id) + R.id.nav_browse -> router.setRoot(BrowseController(), id) + R.id.nav_more -> router.setRoot(MoreController(), id) } } else if (!isHandlingShortcut) { when (id) { @@ -227,7 +226,7 @@ class MainActivity : BaseViewBindingActivity() { } ) - syncActivityViewWithController(router.backstack.lastOrNull()?.controller) + syncActivityViewWithController() if (savedInstanceState == null) { // Reset Incognito Mode on relaunch @@ -340,38 +339,26 @@ class MainActivity : BaseViewBindingActivity() { override fun onResume() { super.onResume() + syncActivityViewWithController() - checkForExtensionUpdates() - if (BuildConfig.INCLUDE_UPDATER) { - checkForAppUpdates() - } + checkForUpdates() } - private fun checkForAppUpdates() { - // Limit checks to once a day at most - if (Date().time < preferences.lastAppCheck().get() + TimeUnit.DAYS.toMillis(1)) { - return - } - + private fun checkForUpdates() { lifecycleScope.launchIO { - try { - val result = AppUpdateChecker().checkForUpdate(this@MainActivity) - if (result is AppUpdateResult.NewUpdate) { - NewUpdateDialogController(result).showDialog(router) + // App updates + if (BuildConfig.INCLUDE_UPDATER) { + try { + val result = AppUpdateChecker().checkForUpdate(this@MainActivity) + if (result is AppUpdateResult.NewUpdate) { + NewUpdateDialogController(result).showDialog(router) + } + } catch (e: Exception) { + logcat(LogPriority.ERROR, e) } - } catch (e: Exception) { - logcat(LogPriority.ERROR, e) } - } - } - private fun checkForExtensionUpdates() { - // Limit checks to once a day at most - if (Date().time < preferences.lastExtCheck().get() + TimeUnit.DAYS.toMillis(1)) { - return - } - - lifecycleScope.launchIO { + // Extension updates try { val pendingUpdates = ExtensionGithubApi().checkForUpdates(this@MainActivity) val pendingAnimeUpdates = AnimeExtensionGithubApi().checkForUpdates(this@MainActivity) @@ -549,11 +536,11 @@ class MainActivity : BaseViewBindingActivity() { } } - private fun setRoot(controller: Controller, id: Int) { - router.setRoot(controller.withFadeTransaction().tag(id.toString())) - } - - private fun syncActivityViewWithController(to: Controller?, from: Controller? = null, isPush: Boolean = true) { + private fun syncActivityViewWithController( + to: Controller? = router.backstack.lastOrNull()?.controller, + from: Controller? = null, + isPush: Boolean = true, + ) { if (from is DialogController || to is DialogController) { return } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/WhatsNewDialogController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/WhatsNewDialogController.kt index cd479d83b..f69eb34c9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/WhatsNewDialogController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/WhatsNewDialogController.kt @@ -5,6 +5,7 @@ import android.os.Bundle import com.google.android.material.dialog.MaterialAlertDialogBuilder import eu.kanade.tachiyomi.BuildConfig import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.updater.RELEASE_URL import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.openInBrowser @@ -16,7 +17,7 @@ class WhatsNewDialogController(bundle: Bundle? = null) : DialogController(bundle .setTitle(activity!!.getString(R.string.updated_version, BuildConfig.VERSION_NAME)) .setPositiveButton(android.R.string.ok, null) .setNeutralButton(R.string.whats_new) { _, _ -> - openInBrowser("https://github.com/jmir1/aniyomi/releases/tag/v${BuildConfig.VERSION_NAME}") + openInBrowser(RELEASE_URL) } .create() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt index 1bba2aab7..81794456a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt @@ -5,6 +5,7 @@ import eu.kanade.tachiyomi.BuildConfig import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.updater.AppUpdateChecker import eu.kanade.tachiyomi.data.updater.AppUpdateResult +import eu.kanade.tachiyomi.data.updater.RELEASE_URL import eu.kanade.tachiyomi.ui.base.controller.NoAppBarElevationController import eu.kanade.tachiyomi.ui.base.controller.openInBrowser import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction @@ -73,12 +74,7 @@ class AboutController : SettingsController(), NoAppBarElevationController { titleRes = R.string.whats_new onClick { - val url = if (BuildConfig.PREVIEW) { - "https://github.com/jmir1/aniyomi-preview/releases/tag/r${BuildConfig.COMMIT_COUNT}" - } else { - "https://github.com/jmir1/aniyomi/releases/tag/v${BuildConfig.VERSION_NAME}" - } - openInBrowser(url) + openInBrowser(RELEASE_URL) } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderPageImageView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderPageImageView.kt index 8806bd09e..975505f45 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderPageImageView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderPageImageView.kt @@ -141,7 +141,7 @@ open class ReaderPageImageView @JvmOverloads constructor( setOnImageEventListener( object : SubsamplingScaleImageView.DefaultOnImageEventListener() { override fun onReady() { - // 3x zoom + // 5x zoom maxScale = scale * MAX_ZOOM_SCALE setDoubleTapZoomScale(scale * 2) @@ -261,4 +261,4 @@ open class ReaderPageImageView @JvmOverloads constructor( } } -private const val MAX_ZOOM_SCALE = 3F +private const val MAX_ZOOM_SCALE = 5F diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBrowseController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBrowseController.kt index 0ce909d81..b927e6fbd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBrowseController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBrowseController.kt @@ -58,8 +58,8 @@ class SettingsBrowseController : SettingsController() { if (context.isAuthenticationSupported() && activity != null) { requireAuthentication( activity as? FragmentActivity, - activity!!.getString(R.string.pref_category_nsfw_content), - activity!!.getString(R.string.confirm_lock_change), + context.getString(R.string.pref_category_nsfw_content), + context.getString(R.string.confirm_lock_change), ) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt index 178169a39..07ae4bafd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt @@ -177,16 +177,13 @@ class SettingsLibraryController : SettingsController() { titleRes = R.string.pref_library_update_interval entriesRes = arrayOf( R.string.update_never, - R.string.update_3hour, - R.string.update_4hour, - R.string.update_6hour, - R.string.update_8hour, R.string.update_12hour, R.string.update_24hour, R.string.update_48hour, + R.string.update_72hour, R.string.update_weekly ) - entryValues = arrayOf("0", "3", "4", "6", "8", "12", "24", "48", "168") + entryValues = arrayOf("0", "12", "24", "48", "72", "168") defaultValue = "24" summary = "%s" diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt index 195ab4d21..e0e5e4c39 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt @@ -32,8 +32,8 @@ class SettingsSecurityController : SettingsController() { requireAuthentication( activity as? FragmentActivity, - activity!!.getString(R.string.lock_with_biometrics), - activity!!.getString(R.string.confirm_lock_change), + context.getString(R.string.lock_with_biometrics), + context.getString(R.string.confirm_lock_change), ) } 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 f02bef0e1..b97e2f6b6 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 @@ -307,10 +307,10 @@ fun Context.createFileInCacheDir(name: String): File { } /** - * We consider anything with a width of >= 720dp as a tablet, i.e. with layouts in layout-sw720dp. + * We consider anything with a width of >= 720dp as a tablet, i.e. with layouts in layout-w720dp. */ fun Context.isTablet(): Boolean { - return resources.configuration.smallestScreenWidthDp >= TABLET_UI_MIN_SCREEN_WIDTH_DP + return resources.configuration.screenWidthDp >= TABLET_UI_MIN_SCREEN_WIDTH_DP } fun Context.prepareTabletUiContext(): Context { @@ -320,13 +320,13 @@ fun Context.prepareTabletUiContext(): Context { PreferenceValues.TabletUiMode.LANDSCAPE -> configuration.orientation == Configuration.ORIENTATION_LANDSCAPE PreferenceValues.TabletUiMode.NEVER -> false } - if (configuration.smallestScreenWidthDp >= TABLET_UI_MIN_SCREEN_WIDTH_DP != expected) { + if (configuration.screenWidthDp >= TABLET_UI_MIN_SCREEN_WIDTH_DP != expected) { val overrideConf = Configuration() overrideConf.setTo(configuration) - overrideConf.smallestScreenWidthDp = if (expected) { - overrideConf.smallestScreenWidthDp.coerceAtLeast(TABLET_UI_MIN_SCREEN_WIDTH_DP) + overrideConf.screenWidthDp = if (expected) { + overrideConf.screenWidthDp.coerceAtLeast(TABLET_UI_MIN_SCREEN_WIDTH_DP) } else { - overrideConf.smallestScreenWidthDp.coerceAtMost(TABLET_UI_MIN_SCREEN_WIDTH_DP - 1) + overrideConf.screenWidthDp.coerceAtMost(TABLET_UI_MIN_SCREEN_WIDTH_DP - 1) } return createConfigurationContext(overrideConf) } diff --git a/app/src/main/res/layout-sw720dp/main_activity.xml b/app/src/main/res/layout-w720dp/main_activity.xml similarity index 100% rename from app/src/main/res/layout-sw720dp/main_activity.xml rename to app/src/main/res/layout-w720dp/main_activity.xml diff --git a/app/src/main/res/layout-sw720dp/manga_controller.xml b/app/src/main/res/layout-w720dp/manga_controller.xml similarity index 100% rename from app/src/main/res/layout-sw720dp/manga_controller.xml rename to app/src/main/res/layout-w720dp/manga_controller.xml diff --git a/app/src/main/res/layout-sw720dp/manga_info_header.xml b/app/src/main/res/layout-w720dp/manga_info_header.xml similarity index 100% rename from app/src/main/res/layout-sw720dp/manga_info_header.xml rename to app/src/main/res/layout-w720dp/manga_info_header.xml diff --git a/app/src/main/res/layout/anime_updates_item.xml b/app/src/main/res/layout/anime_updates_item.xml index 6b8d476d7..2a44dcf3d 100644 --- a/app/src/main/res/layout/anime_updates_item.xml +++ b/app/src/main/res/layout/anime_updates_item.xml @@ -29,7 +29,7 @@ android:layout_marginStart="16dp" android:ellipsize="end" android:maxLines="1" - android:textAppearance="?attr/textAppearanceSubtitle2" + android:textAppearance="?attr/textAppearanceBody2" app:layout_constraintBottom_toTopOf="@+id/chapter_title" app:layout_constraintEnd_toStartOf="@+id/download" app:layout_constraintStart_toEndOf="@+id/manga_cover" diff --git a/app/src/main/res/layout/global_search_controller_card.xml b/app/src/main/res/layout/global_search_controller_card.xml index 1ede433d3..a1794195d 100644 --- a/app/src/main/res/layout/global_search_controller_card.xml +++ b/app/src/main/res/layout/global_search_controller_card.xml @@ -17,7 +17,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" - android:textAppearance="?attr/textAppearanceSubtitle2" + android:textAppearance="?attr/textAppearanceBody2" app:layout_constraintBottom_toTopOf="@+id/subtitle" app:layout_constraintEnd_toStartOf="@+id/title_more_icon" app:layout_constraintStart_toStartOf="parent" @@ -34,6 +34,7 @@ android:textAppearance="?attr/textAppearanceBody2" android:textSize="12sp" android:visibility="gone" + android:textColor="?android:attr/textColorSecondary" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/title_more_icon" app:layout_constraintStart_toStartOf="parent" diff --git a/app/src/main/res/layout/updates_item.xml b/app/src/main/res/layout/updates_item.xml index 0064745b8..4547d16e2 100644 --- a/app/src/main/res/layout/updates_item.xml +++ b/app/src/main/res/layout/updates_item.xml @@ -29,7 +29,7 @@ android:layout_marginStart="16dp" android:ellipsize="end" android:maxLines="1" - android:textAppearance="?attr/textAppearanceSubtitle2" + android:textAppearance="?attr/textAppearanceBody2" app:layout_constraintBottom_toTopOf="@+id/chapter_title" app:layout_constraintEnd_toStartOf="@+id/download" app:layout_constraintStart_toEndOf="@+id/manga_cover" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6e16c7f06..b7088559d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -152,7 +152,7 @@ Reset Undo Open log - Show errors + See full error details Create Restore Back @@ -249,13 +249,11 @@ Global update Update frequency Manual - Every 3 hours - Every 4 hours Every 6 hours - Every 8 hours Every 12 hours Daily Every 2 days + Every 3 days Weekly Update order Update restrictions @@ -416,7 +414,7 @@ 15% 20% 25% - Auto hide menu on scroll sensitivity + Sensitivity for hiding menu on scroll Highest High Low @@ -805,11 +803,12 @@ Couldn\'t download chapters. You can try again in the downloads section Couldn\'t download chapters due to low storage space + Warning: large bulk downloads may lead to sources becoming slower and/or blocking Tachiyomi Checking for new chapters Updating library… (%1$d/%2$d) - Large updates may lead to increased battery usage and sources becoming slower + Warning: large updates harm sources and may lead to slower updates and also increased battery usage New chapters found New episodes found diff --git a/build.gradle.kts b/build.gradle.kts index 634a4fb04..c5607aa82 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,6 @@ allprojects { mavenCentral() google() maven { setUrl("https://www.jitpack.io") } - jcenter() } }