Backup restorng fixes
This commit is contained in:
@@ -20,7 +20,7 @@ class BookmarkBackup(
|
||||
@SerialName("chapter_id") val chapterId: Long,
|
||||
@SerialName("page") val page: Int,
|
||||
@SerialName("scroll") val scroll: Int,
|
||||
@SerialName("image") val imageUrl: String,
|
||||
@SerialName("image_url") val imageUrl: String,
|
||||
@SerialName("created_at") val createdAt: Long,
|
||||
@SerialName("percent") val percent: Float,
|
||||
) {
|
||||
|
||||
@@ -1,20 +1,25 @@
|
||||
package org.koitharu.kotatsu.backups.ui
|
||||
|
||||
import android.app.Notification
|
||||
import android.net.Uri
|
||||
import androidx.core.app.NotificationChannelCompat
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.core.app.PendingIntentCompat
|
||||
import androidx.core.app.ShareCompat
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ErrorReporterReceiver
|
||||
import org.koitharu.kotatsu.core.nav.AppRouter
|
||||
import org.koitharu.kotatsu.core.ui.CoroutineIntentService
|
||||
import org.koitharu.kotatsu.core.util.CompositeResult
|
||||
import org.koitharu.kotatsu.core.util.ext.checkNotificationPermission
|
||||
import org.koitharu.kotatsu.core.util.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.core.util.ext.getFileDisplayName
|
||||
import androidx.appcompat.R as appcompatR
|
||||
|
||||
abstract class BaseBackupRestoreService : CoroutineIntentService() {
|
||||
|
||||
protected abstract val notificationTag: String
|
||||
protected abstract val isRestoreService: Boolean
|
||||
|
||||
protected lateinit var notificationManager: NotificationManagerCompat
|
||||
private set
|
||||
@@ -26,10 +31,7 @@ abstract class BaseBackupRestoreService : CoroutineIntentService() {
|
||||
}
|
||||
|
||||
override fun IntentJobContext.onError(error: Throwable) {
|
||||
if (applicationContext.checkNotificationPermission(CHANNEL_ID)) {
|
||||
val notification = createErrorNotification(error)
|
||||
notificationManager.notify(notificationTag, startId, notification)
|
||||
}
|
||||
showResultNotification(null, CompositeResult.failure(error))
|
||||
}
|
||||
|
||||
private fun createNotificationChannel() {
|
||||
@@ -43,33 +45,93 @@ abstract class BaseBackupRestoreService : CoroutineIntentService() {
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
}
|
||||
|
||||
protected fun createErrorNotification(error: Throwable): Notification {
|
||||
protected fun IntentJobContext.showResultNotification(
|
||||
fileUri: Uri?,
|
||||
result: CompositeResult,
|
||||
) {
|
||||
if (!applicationContext.checkNotificationPermission(CHANNEL_ID)) {
|
||||
return
|
||||
}
|
||||
val notification = NotificationCompat.Builder(applicationContext, CHANNEL_ID)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setDefaults(0)
|
||||
.setSilent(true)
|
||||
.setAutoCancel(true)
|
||||
.setContentText(error.getDisplayMessage(resources))
|
||||
.setSmallIcon(android.R.drawable.stat_notify_error)
|
||||
ErrorReporterReceiver.getPendingIntent(applicationContext, error)?.let { reportIntent ->
|
||||
notification.addAction(
|
||||
R.drawable.ic_alert_outline,
|
||||
applicationContext.getString(R.string.report),
|
||||
reportIntent,
|
||||
)
|
||||
.setSubText(fileUri?.let { contentResolver.getFileDisplayName(it) })
|
||||
when {
|
||||
result.isAllSuccess -> {
|
||||
if (isRestoreService) {
|
||||
notification
|
||||
.setContentTitle(getString(R.string.restoring_backup))
|
||||
.setContentText(getString(R.string.data_restored_success))
|
||||
} else {
|
||||
notification
|
||||
.setContentTitle(getString(R.string.backup_saved))
|
||||
.setContentText(fileUri?.let { contentResolver.getFileDisplayName(it) })
|
||||
.setSubText(null)
|
||||
|
||||
}
|
||||
notification.setSmallIcon(R.drawable.ic_stat_done)
|
||||
}
|
||||
|
||||
result.isAllFailed || !isRestoreService -> {
|
||||
val title = getString(if (isRestoreService) R.string.data_not_restored else R.string.error_occurred)
|
||||
val message = result.failures.joinToString("\n") {
|
||||
it.getDisplayMessage(applicationContext.resources)
|
||||
}
|
||||
notification
|
||||
.setContentText(if (isRestoreService) getString(R.string.data_not_restored_text) else message)
|
||||
.setBigText(title, message)
|
||||
.setSmallIcon(android.R.drawable.stat_notify_error)
|
||||
result.failures.firstNotNullOfOrNull { error ->
|
||||
ErrorReporterReceiver.getPendingIntent(applicationContext, error)
|
||||
}?.let { reportIntent ->
|
||||
notification.addAction(
|
||||
R.drawable.ic_alert_outline,
|
||||
applicationContext.getString(R.string.report),
|
||||
reportIntent,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
notification
|
||||
.setContentTitle(getString(R.string.restoring_backup))
|
||||
.setContentText(getString(R.string.data_restored_with_errors))
|
||||
.setSmallIcon(R.drawable.ic_stat_done)
|
||||
}
|
||||
}
|
||||
notification.setContentIntent(
|
||||
PendingIntentCompat.getActivity(
|
||||
applicationContext,
|
||||
0,
|
||||
AppRouter.homeIntent(this),
|
||||
AppRouter.homeIntent(this@BaseBackupRestoreService),
|
||||
0,
|
||||
false,
|
||||
),
|
||||
)
|
||||
return notification.build()
|
||||
if (!isRestoreService && fileUri != null) {
|
||||
val shareIntent = ShareCompat.IntentBuilder(this@BaseBackupRestoreService)
|
||||
.setStream(fileUri)
|
||||
.setType("application/zip")
|
||||
.setChooserTitle(R.string.share_backup)
|
||||
.createChooserIntent()
|
||||
notification.addAction(
|
||||
appcompatR.drawable.abc_ic_menu_share_mtrl_alpha,
|
||||
getString(R.string.share),
|
||||
PendingIntentCompat.getActivity(this@BaseBackupRestoreService, 0, shareIntent, 0, false),
|
||||
)
|
||||
}
|
||||
notificationManager.notify(notificationTag, startId, notification.build())
|
||||
}
|
||||
|
||||
protected fun NotificationCompat.Builder.setBigText(title: String, text: CharSequence) = setStyle(
|
||||
NotificationCompat.BigTextStyle()
|
||||
.bigText(text)
|
||||
.setSummaryText(text)
|
||||
.setBigContentTitle(title),
|
||||
)
|
||||
|
||||
protected companion object {
|
||||
|
||||
const val CHANNEL_ID = "backup_restore"
|
||||
|
||||
@@ -8,8 +8,6 @@ import android.content.pm.ServiceInfo
|
||||
import android.net.Uri
|
||||
import androidx.annotation.CheckResult
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.PendingIntentCompat
|
||||
import androidx.core.app.ShareCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.cancelAndJoin
|
||||
@@ -19,6 +17,7 @@ import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.backups.data.BackupRepository
|
||||
import org.koitharu.kotatsu.backups.ui.BaseBackupRestoreService
|
||||
import org.koitharu.kotatsu.core.nav.AppRouter
|
||||
import org.koitharu.kotatsu.core.util.CompositeResult
|
||||
import org.koitharu.kotatsu.core.util.ext.checkNotificationPermission
|
||||
import org.koitharu.kotatsu.core.util.ext.powerManager
|
||||
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
|
||||
@@ -35,6 +34,7 @@ import androidx.appcompat.R as appcompatR
|
||||
class BackupService : BaseBackupRestoreService() {
|
||||
|
||||
override val notificationTag = TAG
|
||||
override val isRestoreService = false
|
||||
|
||||
@Inject
|
||||
lateinit var repository: BackupRepository
|
||||
@@ -63,9 +63,7 @@ class BackupService : BaseBackupRestoreService() {
|
||||
}
|
||||
progressUpdateJob?.cancelAndJoin()
|
||||
contentResolver.notifyChange(destination, null)
|
||||
if (checkNotificationPermission(CHANNEL_ID)) {
|
||||
notificationManager.notify(notificationTag, startId, createResultNotification(destination))
|
||||
}
|
||||
showResultNotification(destination, CompositeResult.success())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,31 +96,6 @@ class BackupService : BaseBackupRestoreService() {
|
||||
).build()
|
||||
}
|
||||
|
||||
private fun createResultNotification(uri: Uri): Notification {
|
||||
val notification = NotificationCompat.Builder(applicationContext, CHANNEL_ID)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setDefaults(0)
|
||||
.setSilent(true)
|
||||
.setAutoCancel(true)
|
||||
.setContentText(getString(R.string.backup_saved))
|
||||
.setSmallIcon(R.drawable.ic_stat_done)
|
||||
val shareIntent = ShareCompat.IntentBuilder(this)
|
||||
.setStream(uri)
|
||||
.setType(contentResolver.getType(uri) ?: "application/zip")
|
||||
.setChooserTitle(R.string.share_backup)
|
||||
.createChooserIntent()
|
||||
notification.setContentIntent(
|
||||
PendingIntentCompat.getActivity(
|
||||
applicationContext,
|
||||
0,
|
||||
shareIntent,
|
||||
0,
|
||||
false,
|
||||
),
|
||||
)
|
||||
return notification.build()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val TAG = "BACKUP"
|
||||
|
||||
@@ -8,8 +8,6 @@ import android.content.pm.ServiceInfo
|
||||
import android.net.Uri
|
||||
import androidx.annotation.CheckResult
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.PendingIntentCompat
|
||||
import androidx.core.app.ShareCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.cancelAndJoin
|
||||
@@ -37,6 +35,7 @@ import androidx.appcompat.R as appcompatR
|
||||
class RestoreService : BaseBackupRestoreService() {
|
||||
|
||||
override val notificationTag = TAG
|
||||
override val isRestoreService = true
|
||||
|
||||
@Inject
|
||||
lateinit var repository: BackupRepository
|
||||
@@ -62,13 +61,11 @@ class RestoreService : BaseBackupRestoreService() {
|
||||
} else {
|
||||
null
|
||||
}
|
||||
ZipInputStream(contentResolver.openInputStream(source)).use { input ->
|
||||
val result = ZipInputStream(contentResolver.openInputStream(source)).use { input ->
|
||||
repository.restoreBackup(input, sections, progress)
|
||||
}
|
||||
progressUpdateJob?.cancelAndJoin()
|
||||
if (checkNotificationPermission(CHANNEL_ID)) {
|
||||
notificationManager.notify(notificationTag, startId, createResultNotification(source))
|
||||
}
|
||||
showResultNotification(source, result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,31 +98,6 @@ class RestoreService : BaseBackupRestoreService() {
|
||||
).build()
|
||||
}
|
||||
|
||||
private fun createResultNotification(uri: Uri): Notification {
|
||||
val notification = NotificationCompat.Builder(applicationContext, CHANNEL_ID)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setDefaults(0)
|
||||
.setSilent(true)
|
||||
.setAutoCancel(true)
|
||||
.setContentText(getString(R.string.backup_saved))
|
||||
.setSmallIcon(R.drawable.ic_stat_done)
|
||||
val shareIntent = ShareCompat.IntentBuilder(this)
|
||||
.setStream(uri)
|
||||
.setType(contentResolver.getType(uri) ?: "application/zip")
|
||||
.setChooserTitle(R.string.share_backup)
|
||||
.createChooserIntent()
|
||||
notification.setContentIntent(
|
||||
PendingIntentCompat.getActivity(
|
||||
applicationContext,
|
||||
0,
|
||||
shareIntent,
|
||||
0,
|
||||
false,
|
||||
),
|
||||
)
|
||||
return notification.build()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val TAG = "RESTORE"
|
||||
|
||||
Reference in New Issue
Block a user