diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt
index c10c4605e9..9a8d4ae406 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt
@@ -483,5 +483,21 @@ class NotificationReceiver : BroadcastReceiver() {
}
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
+
+ /**
+ * Returns [PendingIntent] that opens the error log file in an external viewer
+ *
+ * @param context context of application
+ * @param uri uri of error log file
+ * @return [PendingIntent]
+ */
+ internal fun openErrorLog(context: Context, uri: Uri): PendingIntent {
+ val intent = Intent().apply {
+ action = Intent.ACTION_VIEW
+ setDataAndType(uri, "text/plain")
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
+ }
+ return PendingIntent.getActivity(context, 0, intent, 0)
+ }
}
}
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 819344c4ba..9bf6cf1f3f 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
@@ -50,6 +50,7 @@ object Notifications {
*/
const val CHANNEL_BACKUP_RESTORE = "backup_restore_channel"
const val ID_BACKUP = -501
+ const val ID_RESTORE = -502
/**
* Creates the notification channels introduced in Android Oreo.
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 16358e1012..e4e5d94681 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
@@ -35,13 +35,10 @@ import eu.kanade.tachiyomi.util.preference.preference
import eu.kanade.tachiyomi.util.preference.preferenceCategory
import eu.kanade.tachiyomi.util.preference.summaryRes
import eu.kanade.tachiyomi.util.preference.titleRes
-import eu.kanade.tachiyomi.util.storage.getUriCompat
import eu.kanade.tachiyomi.util.system.getFilePicker
import eu.kanade.tachiyomi.util.system.registerLocalReceiver
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.system.unregisterLocalReceiver
-import java.io.File
-import java.util.concurrent.TimeUnit
class SettingsBackupController : SettingsController() {
@@ -199,7 +196,6 @@ class SettingsBackupController : SettingsController() {
fun createBackup(flags: Int) {
backupFlags = flags
- // Setup custom file picker intent
// Get dirs
val currentDir = preferences.backupsDirectory().getOrDefault()
@@ -309,58 +305,6 @@ class SettingsBackupController : SettingsController() {
}
}
- class RestoredBackupDialog(bundle: Bundle? = null) : DialogController(bundle) {
- constructor(time: Long, errorCount: Int, path: String, file: String) : this(Bundle().apply {
- putLong(KEY_TIME, time)
- putInt(KEY_ERROR_COUNT, errorCount)
- putString(KEY_PATH, path)
- putString(KEY_FILE, file)
- })
-
- override fun onCreateDialog(savedViewState: Bundle?): Dialog {
- val activity = activity!!
- val time = args.getLong(KEY_TIME)
- val errors = args.getInt(KEY_ERROR_COUNT)
- val path = args.getString(KEY_PATH)
- val file = args.getString(KEY_FILE)
- val timeString = String.format("%02d min, %02d sec",
- TimeUnit.MILLISECONDS.toMinutes(time),
- TimeUnit.MILLISECONDS.toSeconds(time) - TimeUnit.MINUTES.toSeconds(
- TimeUnit.MILLISECONDS.toMinutes(time))
- )
-
- 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.cancel)))
- .positiveText(R.string.action_close)
- .negativeText(R.string.action_open_log)
- .onNegative { _, _ ->
- val context = applicationContext ?: return@onNegative
- if (!path.isNullOrEmpty()) {
- val destFile = File(path, file)
- val uri = destFile.getUriCompat(context)
- val sendIntent = Intent(Intent.ACTION_VIEW).apply {
- setDataAndType(uri, "text/plain")
- flags = Intent.FLAG_ACTIVITY_NEW_TASK or
- Intent.FLAG_GRANT_READ_URI_PERMISSION
- }
- startActivity(sendIntent)
- } else {
- context.toast(context.getString(R.string.error_opening_log))
- }
- }
- .build()
- }
-
- private companion object {
- const val KEY_TIME = "RestoredBackupDialog.time"
- const val KEY_ERROR_COUNT = "RestoredBackupDialog.errors"
- const val KEY_PATH = "RestoredBackupDialog.path"
- const val KEY_FILE = "RestoredBackupDialog.file"
- }
- }
-
inner class BackupBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.getStringExtra(BackupConst.ACTION)) {
@@ -382,16 +326,14 @@ class SettingsBackupController : SettingsController() {
BackupConst.ACTION_RESTORE_COMPLETED_DIALOG -> {
router.popControllerWithTag(TAG_RESTORING_BACKUP_DIALOG)
val time = intent.getLongExtra(BackupConst.EXTRA_TIME, 0)
- val errors = intent.getIntExtra(BackupConst.EXTRA_ERRORS, 0)
+ val errorCount = intent.getIntExtra(BackupConst.EXTRA_ERRORS, 0)
val path = intent.getStringExtra(BackupConst.EXTRA_ERROR_FILE_PATH)
val file = intent.getStringExtra(BackupConst.EXTRA_ERROR_FILE)
- if (errors > 0) {
- RestoredBackupDialog(time, errors, path, file).showDialog(router)
- }
+ notifier.showRestoreComplete(time, errorCount, path, file)
}
BackupConst.ACTION_ERROR_RESTORE_DIALOG -> {
router.popControllerWithTag(TAG_RESTORING_BACKUP_DIALOG)
- context.toast(intent.getStringExtra(BackupConst.EXTRA_ERROR_MESSAGE))
+ notifier.showRestoreError(intent.getStringExtra(BackupConst.EXTRA_ERROR_MESSAGE))
}
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/backup/BackupNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/backup/BackupNotifier.kt
index e3dd42c805..bf57becfdd 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/backup/BackupNotifier.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/backup/BackupNotifier.kt
@@ -7,13 +7,18 @@ import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.data.notification.Notifications
+import eu.kanade.tachiyomi.util.storage.getUriCompat
import eu.kanade.tachiyomi.util.system.notificationBuilder
import eu.kanade.tachiyomi.util.system.notificationManager
+import java.io.File
+import java.util.concurrent.TimeUnit
internal class BackupNotifier(private val context: Context) {
private val notificationBuilder = context.notificationBuilder(Notifications.CHANNEL_BACKUP_RESTORE) {
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher))
+ setSmallIcon(R.drawable.ic_tachi)
+ setAutoCancel(false)
}
private fun NotificationCompat.Builder.show(id: Int) {
@@ -22,9 +27,6 @@ internal class BackupNotifier(private val context: Context) {
fun showBackupProgress() {
with(notificationBuilder) {
- setSmallIcon(R.drawable.ic_tachi)
- setAutoCancel(false)
-
setContentTitle(context.getString(R.string.backup))
setContentText(context.getString(R.string.creating_backup))
@@ -34,11 +36,8 @@ internal class BackupNotifier(private val context: Context) {
notificationBuilder.show(Notifications.ID_BACKUP)
}
- fun showBackupError(error: String) {
+ fun showBackupError(error: String?) {
with(notificationBuilder) {
- setSmallIcon(R.drawable.ic_tachi)
- setAutoCancel(false)
-
setContentTitle(context.getString(R.string.creating_backup_error))
setContentText(error)
@@ -51,9 +50,6 @@ internal class BackupNotifier(private val context: Context) {
fun showBackupComplete(unifile: UniFile) {
with(notificationBuilder) {
- setSmallIcon(R.drawable.ic_tachi)
- setAutoCancel(false)
-
setContentTitle(context.getString(R.string.backup_created))
if (unifile.filePath != null) {
@@ -75,4 +71,55 @@ internal class BackupNotifier(private val context: Context) {
notificationBuilder.show(Notifications.ID_BACKUP)
}
+
+ fun showRestoreProgress() {
+ // TODO
+ }
+
+ fun showRestoreError(error: String?) {
+ with(notificationBuilder) {
+ setContentTitle(context.getString(R.string.restoring_backup_error))
+ setContentText(error)
+
+ // Remove progress bar
+ setProgress(0, 0, false)
+ }
+
+ notificationBuilder.show(Notifications.ID_RESTORE)
+ }
+
+ fun showRestoreComplete(time: Long, errorCount: Int, path: String?, file: String?) {
+ val timeString = String.format("%02d min, %02d sec",
+ TimeUnit.MILLISECONDS.toMinutes(time),
+ TimeUnit.MILLISECONDS.toSeconds(time) - TimeUnit.MINUTES.toSeconds(
+ TimeUnit.MILLISECONDS.toMinutes(time))
+ )
+
+ with(notificationBuilder) {
+ setSmallIcon(R.drawable.ic_tachi)
+ setAutoCancel(false)
+
+ setContentTitle(context.getString(R.string.restore_completed))
+ setContentText(context.getString(R.string.restore_completed_content, timeString, errorCount))
+
+ // Remove progress bar
+ setProgress(0, 0, false)
+
+ // Clear old actions if they exist
+ if (mActions.isNotEmpty()) {
+ mActions.clear()
+ }
+
+ if (errorCount > 0 && !path.isNullOrEmpty() && !file.isNullOrEmpty()) {
+ val destFile = File(path, file)
+ val uri = destFile.getUriCompat(context)
+
+ addAction(R.drawable.nnf_ic_file_folder,
+ context.getString(R.string.action_open_log),
+ NotificationReceiver.openErrorLog(context, uri))
+ }
+ }
+
+ notificationBuilder.show(Notifications.ID_RESTORE)
+ }
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c70734d445..d80cc824e4 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -320,14 +320,14 @@
Restoring backup\n%1$s source not found
Backup created
Restore completed
- Could not open log
- Restore took %1$s.\n%2$s errors found.
+ Restore took %1$s with %2$s errors
Restore uses sources to fetch data, carrier costs may apply.\n\nMake sure you have installed all necessary extensions and are logged in to sources and tracking services before restoring.
File saved at %1$s
What do you want to backup?
- Restoring backup
Creating backup
Backup failed
+ Restoring backup
+ Restoring backup failed
Clear chapter cache