mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-09 04:05:09 +01:00
Version 0.9.2
Fixes to 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
This commit is contained in:
parent
74644ec54e
commit
cebed39b20
@ -38,8 +38,8 @@ android {
|
|||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
versionCode 43
|
versionCode 44
|
||||||
versionName "0.9.1"
|
versionName '0.9.2'
|
||||||
|
|
||||||
buildConfigField "String", "COMMIT_COUNT", "\"${getCommitCount()}\""
|
buildConfigField "String", "COMMIT_COUNT", "\"${getCommitCount()}\""
|
||||||
buildConfigField "String", "COMMIT_SHA", "\"${getGitSha()}\""
|
buildConfigField "String", "COMMIT_SHA", "\"${getGitSha()}\""
|
||||||
|
@ -20,4 +20,5 @@ object BackupConst {
|
|||||||
const val EXTRA_TIME = "$ID.$INTENT_FILTER.EXTRA_TIME"
|
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_PATH = "$ID.$INTENT_FILTER.EXTRA_ERROR_FILE_PATH"
|
||||||
const val EXTRA_ERROR_FILE = "$ID.$INTENT_FILTER.EXTRA_ERROR_FILE"
|
const val EXTRA_ERROR_FILE = "$ID.$INTENT_FILTER.EXTRA_ERROR_FILE"
|
||||||
|
const val EXTRA_MINI_ERROR= "$ID.$INTENT_FILTER.EXTRA_MINI_ERROR"
|
||||||
}
|
}
|
@ -23,6 +23,7 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
|||||||
import eu.kanade.tachiyomi.data.database.models.*
|
import eu.kanade.tachiyomi.data.database.models.*
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
|
import eu.kanade.tachiyomi.source.SourceNotFoundException
|
||||||
import eu.kanade.tachiyomi.util.chop
|
import eu.kanade.tachiyomi.util.chop
|
||||||
import eu.kanade.tachiyomi.util.isServiceRunning
|
import eu.kanade.tachiyomi.util.isServiceRunning
|
||||||
import eu.kanade.tachiyomi.util.sendLocalBroadcast
|
import eu.kanade.tachiyomi.util.sendLocalBroadcast
|
||||||
@ -104,6 +105,17 @@ class BackupRestoreService : Service() {
|
|||||||
*/
|
*/
|
||||||
private val errors = mutableListOf<Pair<Date, String>>()
|
private val errors = mutableListOf<Pair<Date, String>>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List containing distinct errors
|
||||||
|
*/
|
||||||
|
private val errorsMini = mutableListOf<String>()
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List containing missing sources
|
||||||
|
*/
|
||||||
|
private val sourcesMissing = mutableListOf<Long>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Backup manager
|
* Backup manager
|
||||||
*/
|
*/
|
||||||
@ -203,6 +215,7 @@ class BackupRestoreService : Service() {
|
|||||||
restoreAmount = mangasJson.size() + 1 // +1 for categories
|
restoreAmount = mangasJson.size() + 1 // +1 for categories
|
||||||
restoreProgress = 0
|
restoreProgress = 0
|
||||||
errors.clear()
|
errors.clear()
|
||||||
|
errorsMini.clear()
|
||||||
|
|
||||||
// Restore categories
|
// Restore categories
|
||||||
json.get(CATEGORIES)?.let {
|
json.get(CATEGORIES)?.let {
|
||||||
@ -243,6 +256,14 @@ class BackupRestoreService : Service() {
|
|||||||
putExtra(BackupConst.EXTRA_ERRORS, errors.size)
|
putExtra(BackupConst.EXTRA_ERRORS, errors.size)
|
||||||
putExtra(BackupConst.EXTRA_ERROR_FILE_PATH, logFile.parent)
|
putExtra(BackupConst.EXTRA_ERROR_FILE_PATH, logFile.parent)
|
||||||
putExtra(BackupConst.EXTRA_ERROR_FILE, logFile.name)
|
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)
|
putExtra(BackupConst.ACTION, BackupConst.ACTION_RESTORE_COMPLETED_DIALOG)
|
||||||
}
|
}
|
||||||
sendLocalBroadcast(completeIntent)
|
sendLocalBroadcast(completeIntent)
|
||||||
@ -323,6 +344,12 @@ class BackupRestoreService : Service() {
|
|||||||
return backupManager.restoreMangaFetchObservable(source, manga)
|
return backupManager.restoreMangaFetchObservable(source, manga)
|
||||||
.onErrorReturn {
|
.onErrorReturn {
|
||||||
errors.add(Date() to "${manga.title} - ${it.message}")
|
errors.add(Date() to "${manga.title} - ${it.message}")
|
||||||
|
if (it is SourceNotFoundException) {
|
||||||
|
sourcesMissing.add(it.id)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errorsMini.add(it.message ?: "")
|
||||||
|
}
|
||||||
manga
|
manga
|
||||||
}
|
}
|
||||||
.filter { it.id != null }
|
.filter { it.id != null }
|
||||||
@ -395,6 +422,7 @@ class BackupRestoreService : Service() {
|
|||||||
// If there's any error, return empty update and continue.
|
// If there's any error, return empty update and continue.
|
||||||
.onErrorReturn {
|
.onErrorReturn {
|
||||||
errors.add(Date() to "${manga.title} - ${it.message}")
|
errors.add(Date() to "${manga.title} - ${it.message}")
|
||||||
|
errorsMini.add(it.message ?: "")
|
||||||
Pair(emptyList(), emptyList())
|
Pair(emptyList(), emptyList())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -414,10 +442,13 @@ class BackupRestoreService : Service() {
|
|||||||
.doOnNext { db.insertTrack(it).executeAsBlocking() }
|
.doOnNext { db.insertTrack(it).executeAsBlocking() }
|
||||||
.onErrorReturn {
|
.onErrorReturn {
|
||||||
errors.add(Date() to "${manga.title} - ${it.message}")
|
errors.add(Date() to "${manga.title} - ${it.message}")
|
||||||
|
errorsMini.add(it.message ?: "")
|
||||||
track
|
track
|
||||||
}
|
}
|
||||||
} else {
|
} 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()
|
Observable.empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -465,12 +465,12 @@ class LibraryUpdateService(
|
|||||||
catch (e: Exception) { }
|
catch (e: Exception) { }
|
||||||
setContentTitle(manga.title.chop(45))
|
setContentTitle(manga.title.chop(45))
|
||||||
color = ContextCompat.getColor(this@LibraryUpdateService, R.color.colorAccentLight)
|
color = ContextCompat.getColor(this@LibraryUpdateService, R.color.colorAccentLight)
|
||||||
setContentText(chapterNames.first())
|
val chaptersNames = if (chapterNames.size > 5) {
|
||||||
setStyle(NotificationCompat.BigTextStyle().bigText(
|
|
||||||
if (chapterNames.size > 5) {
|
|
||||||
"${chapterNames.take(4).joinToString(", ")}, " +
|
"${chapterNames.take(4).joinToString(", ")}, " +
|
||||||
getString(R.string.notification_and_n_more, (chapterNames.size - 4))
|
getString(R.string.notification_and_n_more, (chapterNames.size - 4))
|
||||||
} else chapterNames.joinToString(", ")))
|
} else chapterNames.joinToString(", ")
|
||||||
|
setContentText(chaptersNames)
|
||||||
|
setStyle(NotificationCompat.BigTextStyle().bigText(chaptersNames))
|
||||||
priority = NotificationCompat.PRIORITY_HIGH
|
priority = NotificationCompat.PRIORITY_HIGH
|
||||||
setGroup(Notifications.GROUP_NEW_CHAPTERS)
|
setGroup(Notifications.GROUP_NEW_CHAPTERS)
|
||||||
setContentIntent(
|
setContentIntent(
|
||||||
@ -498,7 +498,15 @@ class LibraryUpdateService(
|
|||||||
setLargeIcon(notificationBitmap)
|
setLargeIcon(notificationBitmap)
|
||||||
setContentTitle(getString(R.string.notification_new_chapters))
|
setContentTitle(getString(R.string.notification_new_chapters))
|
||||||
color = ContextCompat.getColor(applicationContext, R.color.colorAccentLight)
|
color = ContextCompat.getColor(applicationContext, R.color.colorAccentLight)
|
||||||
|
if (updates.size > 1) {
|
||||||
setContentText(getString(R.string.notification_new_chapters_text, updates.size))
|
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
|
priority = NotificationCompat.PRIORITY_HIGH
|
||||||
setGroup(Notifications.GROUP_NEW_CHAPTERS)
|
setGroup(Notifications.GROUP_NEW_CHAPTERS)
|
||||||
setGroupSummary(true)
|
setGroupSummary(true)
|
||||||
|
@ -68,7 +68,10 @@ open class SourceManager(private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getSourceNotInstalledException(): Exception {
|
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)
|
@ -360,11 +360,13 @@ class SettingsBackupController : SettingsController() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class RestoredBackupDialog(bundle: Bundle? = null) : DialogController(bundle) {
|
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)
|
putLong(KEY_TIME, time)
|
||||||
putInt(KEY_ERROR_COUNT, errorCount)
|
putInt(KEY_ERROR_COUNT, errorCount)
|
||||||
putString(KEY_PATH, path)
|
putString(KEY_PATH, path)
|
||||||
putString(KEY_FILE, file)
|
putString(KEY_FILE, file)
|
||||||
|
putString(KEY_MINI_ERRORS, errors)
|
||||||
})
|
})
|
||||||
|
|
||||||
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
||||||
@ -373,16 +375,22 @@ class SettingsBackupController : SettingsController() {
|
|||||||
val errors = args.getInt(KEY_ERROR_COUNT)
|
val errors = args.getInt(KEY_ERROR_COUNT)
|
||||||
val path = args.getString(KEY_PATH)
|
val path = args.getString(KEY_PATH)
|
||||||
val file = args.getString(KEY_FILE)
|
val file = args.getString(KEY_FILE)
|
||||||
|
val miniErrors = args.getString(KEY_MINI_ERRORS)
|
||||||
val timeString = String.format("%02d min, %02d sec",
|
val timeString = String.format("%02d min, %02d sec",
|
||||||
TimeUnit.MILLISECONDS.toMinutes(time),
|
TimeUnit.MILLISECONDS.toMinutes(time),
|
||||||
TimeUnit.MILLISECONDS.toSeconds(time) - TimeUnit.MINUTES.toSeconds(
|
TimeUnit.MILLISECONDS.toSeconds(time) - TimeUnit.MINUTES.toSeconds(
|
||||||
TimeUnit.MILLISECONDS.toMinutes(time))
|
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)
|
return MaterialDialog.Builder(activity)
|
||||||
.title(R.string.restore_completed)
|
.title(R.string.restore_completed)
|
||||||
.content(activity.getString(R.string.restore_completed_content, timeString,
|
.content("$errorString\n$miniErrors")
|
||||||
if (errors > 0) "$errors" else activity.getString(android.R.string.no)))
|
|
||||||
.positiveText(R.string.action_close)
|
.positiveText(R.string.action_close)
|
||||||
.negativeText(R.string.action_open_log)
|
.negativeText(R.string.action_open_log)
|
||||||
.onNegative { _, _ ->
|
.onNegative { _, _ ->
|
||||||
@ -408,6 +416,7 @@ class SettingsBackupController : SettingsController() {
|
|||||||
const val KEY_ERROR_COUNT = "RestoredBackupDialog.errors"
|
const val KEY_ERROR_COUNT = "RestoredBackupDialog.errors"
|
||||||
const val KEY_PATH = "RestoredBackupDialog.path"
|
const val KEY_PATH = "RestoredBackupDialog.path"
|
||||||
const val KEY_FILE = "RestoredBackupDialog.file"
|
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 errors = intent.getIntExtra(BackupConst.EXTRA_ERRORS, 0)
|
||||||
val path = intent.getStringExtra(BackupConst.EXTRA_ERROR_FILE_PATH)
|
val path = intent.getStringExtra(BackupConst.EXTRA_ERROR_FILE_PATH)
|
||||||
val file = intent.getStringExtra(BackupConst.EXTRA_ERROR_FILE)
|
val file = intent.getStringExtra(BackupConst.EXTRA_ERROR_FILE)
|
||||||
|
val miniErrors = intent.getStringExtra(BackupConst.EXTRA_MINI_ERROR)
|
||||||
if (errors > 0) {
|
if (errors > 0) {
|
||||||
RestoredBackupDialog(time, errors, path, file).showDialog(router)
|
RestoredBackupDialog(time, errors, path, file, miniErrors).showDialog(router)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BackupConst.ACTION_ERROR_BACKUP_DIALOG -> {
|
BackupConst.ACTION_ERROR_BACKUP_DIALOG -> {
|
||||||
|
@ -84,6 +84,11 @@ fun syncChaptersWithSource(db: DatabaseHelper,
|
|||||||
|
|
||||||
// Return if there's nothing to add, delete or change, avoiding unnecessary db transactions.
|
// Return if there's nothing to add, delete or change, avoiding unnecessary db transactions.
|
||||||
if (toAdd.isEmpty() && toDelete.isEmpty() && toChange.isEmpty()) {
|
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())
|
return Pair(emptyList(), emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +134,9 @@ fun syncChaptersWithSource(db: DatabaseHelper,
|
|||||||
db.fixChaptersSourceOrder(sourceChapters).executeAsBlocking()
|
db.fixChaptersSourceOrder(sourceChapters).executeAsBlocking()
|
||||||
|
|
||||||
// Set this manga as updated since chapters were changed
|
// 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()
|
db.updateLastUpdated(manga).executeAsBlocking()
|
||||||
}
|
}
|
||||||
return Pair(toAdd.subtract(readded).toList(), toDelete.subtract(readded).toList())
|
return Pair(toAdd.subtract(readded).toList(), toDelete.subtract(readded).toList())
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<changelog bulletedList="true">
|
<changelog bulletedList="true">
|
||||||
|
<changelogversion versionName="v0.9.2" changeDate="">
|
||||||
|
<changelogtext>Fixes notification text when there are multiple chapters</changelogtext>
|
||||||
|
<changelogtext>Simplified errors now show after restoring a backup on the popup dialog</changelogtext>
|
||||||
|
<changelogtext>Fixed last updated sorting being in a jumbled order after restoring (Note:
|
||||||
|
if the list is still jumbled after restore, refersh your library)</changelogtext>
|
||||||
|
<changelogtext>Fixed notifcations not expanding on older devices</changelogtext>
|
||||||
|
</changelogversion>
|
||||||
|
|
||||||
<changelogversion versionName="v0.9.1" changeDate="">
|
<changelogversion versionName="v0.9.1" changeDate="">
|
||||||
<changelogtext>Range Select for Library and Chapters: long Press on an item
|
<changelogtext>Range Select for Library and Chapters: long Press on an item
|
||||||
then long press on another to select everything in between</changelogtext>
|
then long press on another to select everything in between</changelogtext>
|
||||||
|
@ -374,6 +374,8 @@
|
|||||||
<string name="delete_downloads_for_manga">Delete downloaded chapters?</string>
|
<string name="delete_downloads_for_manga">Delete downloaded chapters?</string>
|
||||||
<string name="copied_to_clipboard">%1$s copied to clipboard</string>
|
<string name="copied_to_clipboard">%1$s copied to clipboard</string>
|
||||||
<string name="source_not_installed">Source not installed: %1$s</string>
|
<string name="source_not_installed">Source not installed: %1$s</string>
|
||||||
|
<string name="sources_missing">Sources missing: %1$d</string>
|
||||||
|
<string name="not_logged_into">Not logged into %1$s</string>
|
||||||
|
|
||||||
<!-- Manga chapters fragment -->
|
<!-- Manga chapters fragment -->
|
||||||
<string name="manga_chapters_tab">Chapters</string>
|
<string name="manga_chapters_tab">Chapters</string>
|
||||||
|
@ -7,7 +7,7 @@ buildscript {
|
|||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
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.ben-manes:gradle-versions-plugin:0.22.0'
|
||||||
classpath 'com.github.zellius:android-shortcut-gradle-plugin:0.1.2'
|
classpath 'com.github.zellius:android-shortcut-gradle-plugin:0.1.2'
|
||||||
classpath 'com.google.gms:google-services:4.3.2'
|
classpath 'com.google.gms:google-services:4.3.2'
|
||||||
|
Loading…
Reference in New Issue
Block a user