mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-25 22:29:45 +03:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
96713f6793
32 changed files with 148 additions and 180 deletions
|
@ -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") {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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<GithubRelease>()
|
||||
.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"
|
||||
|
|
|
@ -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<AnimeExtension.Installed> {
|
||||
// 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)
|
||||
|
|
|
@ -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<Extension.Installed> {
|
||||
// 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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<MainActivityBinding>() {
|
|||
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<MainActivityBinding>() {
|
|||
}
|
||||
)
|
||||
|
||||
syncActivityViewWithController(router.backstack.lastOrNull()?.controller)
|
||||
syncActivityViewWithController()
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
// Reset Incognito Mode on relaunch
|
||||
|
@ -340,38 +339,26 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
|
|||
|
||||
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<MainActivityBinding>() {
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -152,7 +152,7 @@
|
|||
<string name="action_reset">Reset</string>
|
||||
<string name="action_undo">Undo</string>
|
||||
<string name="action_open_log">Open log</string>
|
||||
<string name="action_show_errors">Show errors</string>
|
||||
<string name="action_show_errors">See full error details</string>
|
||||
<string name="action_create">Create</string>
|
||||
<string name="action_restore">Restore</string>
|
||||
<string name="action_webview_back">Back</string>
|
||||
|
@ -249,13 +249,11 @@
|
|||
<string name="pref_category_library_update">Global update</string>
|
||||
<string name="pref_library_update_interval">Update frequency</string>
|
||||
<string name="update_never">Manual</string>
|
||||
<string name="update_3hour">Every 3 hours</string>
|
||||
<string name="update_4hour">Every 4 hours</string>
|
||||
<string name="update_6hour">Every 6 hours</string>
|
||||
<string name="update_8hour">Every 8 hours</string>
|
||||
<string name="update_12hour">Every 12 hours</string>
|
||||
<string name="update_24hour">Daily</string>
|
||||
<string name="update_48hour">Every 2 days</string>
|
||||
<string name="update_72hour">Every 3 days</string>
|
||||
<string name="update_weekly">Weekly</string>
|
||||
<string name="pref_library_update_prioritization">Update order</string>
|
||||
<string name="pref_library_update_restriction">Update restrictions</string>
|
||||
|
@ -416,7 +414,7 @@
|
|||
<string name="webtoon_side_padding_15">15%</string>
|
||||
<string name="webtoon_side_padding_20">20%</string>
|
||||
<string name="webtoon_side_padding_25">25%</string>
|
||||
<string name="pref_hide_threshold">Auto hide menu on scroll sensitivity</string>
|
||||
<string name="pref_hide_threshold">Sensitivity for hiding menu on scroll</string>
|
||||
<string name="pref_highest">Highest</string>
|
||||
<string name="pref_high">High</string>
|
||||
<string name="pref_low">Low</string>
|
||||
|
@ -805,11 +803,12 @@
|
|||
<!-- Downloads activity and service -->
|
||||
<string name="download_queue_error">Couldn\'t download chapters. You can try again in the downloads section</string>
|
||||
<string name="download_insufficient_space">Couldn\'t download chapters due to low storage space</string>
|
||||
<string name="download_queue_size_warning">Warning: large bulk downloads may lead to sources becoming slower and/or blocking Tachiyomi</string>
|
||||
|
||||
<!-- Library update service notifications -->
|
||||
<string name="notification_check_updates">Checking for new chapters</string>
|
||||
<string name="notification_updating">Updating library… (%1$d/%2$d)</string>
|
||||
<string name="notification_size_warning">Large updates may lead to increased battery usage and sources becoming slower</string>
|
||||
<string name="notification_size_warning">Warning: large updates harm sources and may lead to slower updates and also increased battery usage</string>
|
||||
<string name="notification_new_chapters">New chapters found</string>
|
||||
<string name="notification_new_episodes">New episodes found</string>
|
||||
<plurals name="notification_new_chapters_summary">
|
||||
|
|
|
@ -11,7 +11,6 @@ allprojects {
|
|||
mavenCentral()
|
||||
google()
|
||||
maven { setUrl("https://www.jitpack.io") }
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue