diff --git a/app/build.gradle b/app/build.gradle index ba64bc8ef1..ab1c627797 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -38,8 +38,8 @@ android { minSdkVersion 21 targetSdkVersion 29 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - versionCode 43 - versionName "0.9.1" + versionCode 44 + versionName '0.9.2' buildConfigField "String", "COMMIT_COUNT", "\"${getCommitCount()}\"" buildConfigField "String", "COMMIT_SHA", "\"${getGitSha()}\"" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupConst.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupConst.kt index f2427c3fe0..d7c48f09cd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupConst.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupConst.kt @@ -20,4 +20,5 @@ object BackupConst { const val EXTRA_TIME = "$ID.$INTENT_FILTER.EXTRA_TIME" const val EXTRA_ERROR_FILE_PATH = "$ID.$INTENT_FILTER.EXTRA_ERROR_FILE_PATH" const val EXTRA_ERROR_FILE = "$ID.$INTENT_FILTER.EXTRA_ERROR_FILE" + const val EXTRA_MINI_ERROR= "$ID.$INTENT_FILTER.EXTRA_MINI_ERROR" } \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt index 365dd8804f..fa4206989c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt @@ -23,6 +23,7 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.* import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.source.Source +import eu.kanade.tachiyomi.source.SourceNotFoundException import eu.kanade.tachiyomi.util.chop import eu.kanade.tachiyomi.util.isServiceRunning import eu.kanade.tachiyomi.util.sendLocalBroadcast @@ -104,6 +105,17 @@ class BackupRestoreService : Service() { */ private val errors = mutableListOf>() + /** + * List containing distinct errors + */ + private val errorsMini = mutableListOf() + + + /** + * List containing missing sources + */ + private val sourcesMissing = mutableListOf() + /** * Backup manager */ @@ -203,6 +215,7 @@ class BackupRestoreService : Service() { restoreAmount = mangasJson.size() + 1 // +1 for categories restoreProgress = 0 errors.clear() + errorsMini.clear() // Restore categories json.get(CATEGORIES)?.let { @@ -243,6 +256,14 @@ class BackupRestoreService : Service() { putExtra(BackupConst.EXTRA_ERRORS, errors.size) putExtra(BackupConst.EXTRA_ERROR_FILE_PATH, logFile.parent) putExtra(BackupConst.EXTRA_ERROR_FILE, logFile.name) + val sourceMissingCount = sourcesMissing.distinct().size + val sourceErrors = getString(R.string.sources_missing, sourceMissingCount) + val otherErrors = errorsMini.distinct().joinToString("\n") + putExtra(BackupConst.EXTRA_MINI_ERROR, + if (sourceMissingCount > 0) sourceErrors + "\n" + otherErrors + else otherErrors + ) + putExtra(BackupConst.EXTRA_ERRORS, errors.size) putExtra(BackupConst.ACTION, BackupConst.ACTION_RESTORE_COMPLETED_DIALOG) } sendLocalBroadcast(completeIntent) @@ -323,6 +344,12 @@ class BackupRestoreService : Service() { return backupManager.restoreMangaFetchObservable(source, manga) .onErrorReturn { errors.add(Date() to "${manga.title} - ${it.message}") + if (it is SourceNotFoundException) { + sourcesMissing.add(it.id) + } + else { + errorsMini.add(it.message ?: "") + } manga } .filter { it.id != null } @@ -395,6 +422,7 @@ class BackupRestoreService : Service() { // If there's any error, return empty update and continue. .onErrorReturn { errors.add(Date() to "${manga.title} - ${it.message}") + errorsMini.add(it.message ?: "") Pair(emptyList(), emptyList()) } } @@ -414,10 +442,13 @@ class BackupRestoreService : Service() { .doOnNext { db.insertTrack(it).executeAsBlocking() } .onErrorReturn { errors.add(Date() to "${manga.title} - ${it.message}") + errorsMini.add(it.message ?: "") track } } else { - errors.add(Date() to "${manga.title} - ${service?.name} not logged in") + val notLoggedIn = getString(R.string.not_logged_into, service?.name) + errors.add(Date() to "${manga.title} - $notLoggedIn") + errorsMini.add(notLoggedIn) Observable.empty() } } 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 17aad93ec3..33aa3b6a7a 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 @@ -465,12 +465,12 @@ class LibraryUpdateService( catch (e: Exception) { } setContentTitle(manga.title.chop(45)) color = ContextCompat.getColor(this@LibraryUpdateService, R.color.colorAccentLight) - setContentText(chapterNames.first()) - setStyle(NotificationCompat.BigTextStyle().bigText( - if (chapterNames.size > 5) { - "${chapterNames.take(4).joinToString(", ")}, " + - getString(R.string.notification_and_n_more, (chapterNames.size - 4)) - } else chapterNames.joinToString(", "))) + val chaptersNames = if (chapterNames.size > 5) { + "${chapterNames.take(4).joinToString(", ")}, " + + getString(R.string.notification_and_n_more, (chapterNames.size - 4)) + } else chapterNames.joinToString(", ") + setContentText(chaptersNames) + setStyle(NotificationCompat.BigTextStyle().bigText(chaptersNames)) priority = NotificationCompat.PRIORITY_HIGH setGroup(Notifications.GROUP_NEW_CHAPTERS) setContentIntent( @@ -498,7 +498,15 @@ class LibraryUpdateService( setLargeIcon(notificationBitmap) setContentTitle(getString(R.string.notification_new_chapters)) color = ContextCompat.getColor(applicationContext, R.color.colorAccentLight) - setContentText(getString(R.string.notification_new_chapters_text, updates.size)) + if (updates.size > 1) { + setContentText(getString(R.string.notification_new_chapters_text, updates.size)) + setStyle(NotificationCompat.BigTextStyle().bigText(updates.joinToString("\n") { + it.first.title.chop(45) + })) + } + else { + setContentText(updates.first().first.title.chop(45)) + } priority = NotificationCompat.PRIORITY_HIGH setGroup(Notifications.GROUP_NEW_CHAPTERS) setGroupSummary(true) diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt b/app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt index a8d0fed162..118f2f0939 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt @@ -68,7 +68,10 @@ open class SourceManager(private val context: Context) { } private fun getSourceNotInstalledException(): Exception { - return Exception(context.getString(R.string.source_not_installed, id.toString())) + return SourceNotFoundException(context.getString(R.string.source_not_installed, id + .toString()), id) } } } + +class SourceNotFoundException(message: String, val id: Long) : Exception(message) \ No newline at end of file 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 3cad1d5f6d..9977e9f465 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 @@ -360,11 +360,13 @@ class SettingsBackupController : SettingsController() { } class RestoredBackupDialog(bundle: Bundle? = null) : DialogController(bundle) { - constructor(time: Long, errorCount: Int, path: String, file: String) : this(Bundle().apply { + constructor(time: Long, errorCount: Int, path: String, file: String, errors: String) : this + (Bundle().apply { putLong(KEY_TIME, time) putInt(KEY_ERROR_COUNT, errorCount) putString(KEY_PATH, path) putString(KEY_FILE, file) + putString(KEY_MINI_ERRORS, errors) }) override fun onCreateDialog(savedViewState: Bundle?): Dialog { @@ -373,16 +375,22 @@ class SettingsBackupController : SettingsController() { val errors = args.getInt(KEY_ERROR_COUNT) val path = args.getString(KEY_PATH) val file = args.getString(KEY_FILE) + val miniErrors = args.getString(KEY_MINI_ERRORS) val timeString = String.format("%02d min, %02d sec", TimeUnit.MILLISECONDS.toMinutes(time), TimeUnit.MILLISECONDS.toSeconds(time) - TimeUnit.MINUTES.toSeconds( TimeUnit.MILLISECONDS.toMinutes(time)) ) + var errorString = activity.getString(R.string.restore_completed_content, timeString, + if (errors > 0) "$errors" else activity.getString(android.R.string + .no)) + if (errors > 0) + errorString = errorString.trimEnd('.') + ":" + return MaterialDialog.Builder(activity) .title(R.string.restore_completed) - .content(activity.getString(R.string.restore_completed_content, timeString, - if (errors > 0) "$errors" else activity.getString(android.R.string.no))) + .content("$errorString\n$miniErrors") .positiveText(R.string.action_close) .negativeText(R.string.action_open_log) .onNegative { _, _ -> @@ -408,6 +416,7 @@ class SettingsBackupController : SettingsController() { const val KEY_ERROR_COUNT = "RestoredBackupDialog.errors" const val KEY_PATH = "RestoredBackupDialog.path" const val KEY_FILE = "RestoredBackupDialog.file" + const val KEY_MINI_ERRORS = "RestoredBackupDialog.miniErrors" } } @@ -432,8 +441,9 @@ class SettingsBackupController : SettingsController() { val errors = intent.getIntExtra(BackupConst.EXTRA_ERRORS, 0) val path = intent.getStringExtra(BackupConst.EXTRA_ERROR_FILE_PATH) val file = intent.getStringExtra(BackupConst.EXTRA_ERROR_FILE) + val miniErrors = intent.getStringExtra(BackupConst.EXTRA_MINI_ERROR) if (errors > 0) { - RestoredBackupDialog(time, errors, path, file).showDialog(router) + RestoredBackupDialog(time, errors, path, file, miniErrors).showDialog(router) } } BackupConst.ACTION_ERROR_BACKUP_DIALOG -> { diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ChapterSourceSync.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ChapterSourceSync.kt index 60aff194a3..1ee3ee010c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ChapterSourceSync.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ChapterSourceSync.kt @@ -84,6 +84,11 @@ fun syncChaptersWithSource(db: DatabaseHelper, // Return if there's nothing to add, delete or change, avoiding unnecessary db transactions. if (toAdd.isEmpty() && toDelete.isEmpty() && toChange.isEmpty()) { + val newestDate = dbChapters.maxBy { it.date_upload }?.date_upload ?: 0L + if (newestDate != 0L && newestDate != manga.last_update) { + manga.last_update = newestDate + db.updateLastUpdated(manga).executeAsBlocking() + } return Pair(emptyList(), emptyList()) } @@ -129,7 +134,9 @@ fun syncChaptersWithSource(db: DatabaseHelper, db.fixChaptersSourceOrder(sourceChapters).executeAsBlocking() // Set this manga as updated since chapters were changed - manga.last_update = Date().time + val newestChaper = db.getChapters(manga).executeAsBlocking().maxBy { it.date_fetch } + val dateFetch = newestChaper?.date_fetch ?: Date().time + manga.last_update = if (dateFetch == 0L) Date().time else dateFetch db.updateLastUpdated(manga).executeAsBlocking() } return Pair(toAdd.subtract(readded).toList(), toDelete.subtract(readded).toList()) diff --git a/app/src/main/res/raw/changelog_release.xml b/app/src/main/res/raw/changelog_release.xml index e53159809b..699959e4da 100644 --- a/app/src/main/res/raw/changelog_release.xml +++ b/app/src/main/res/raw/changelog_release.xml @@ -1,5 +1,13 @@ + + Fixes notification text when there are multiple chapters + Simplified errors now show after restoring a backup on the popup dialog + Fixed last updated sorting being in a jumbled order after restoring (Note: + if the list is still jumbled after restore, refersh your library) + Fixed notifcations not expanding on older devices + + Range Select for Library and Chapters: long Press on an item then long press on another to select everything in between diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 72fd2e9ed1..bff1857c2a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -374,6 +374,8 @@ Delete downloaded chapters? %1$s copied to clipboard Source not installed: %1$s + Sources missing: %1$d + Not logged into %1$s Chapters diff --git a/build.gradle b/build.gradle index 493af30669..0a2870f087 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.2' + classpath 'com.android.tools.build:gradle:3.5.3' classpath 'com.github.ben-manes:gradle-versions-plugin:0.22.0' classpath 'com.github.zellius:android-shortcut-gradle-plugin:0.1.2' classpath 'com.google.gms:google-services:4.3.2'