Split download notifications into progress and complete channels

This commit is contained in:
arkon 2020-07-29 21:57:43 -04:00
parent 9bb2334b69
commit 3813743e3d
4 changed files with 67 additions and 59 deletions

View file

@ -13,8 +13,8 @@ import eu.kanade.tachiyomi.util.lang.chop
import eu.kanade.tachiyomi.util.system.notificationBuilder import eu.kanade.tachiyomi.util.system.notificationBuilder
import eu.kanade.tachiyomi.util.system.notificationManager import eu.kanade.tachiyomi.util.system.notificationManager
import java.util.regex.Pattern import java.util.regex.Pattern
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
/** /**
* DownloadNotifier is used to show notifications when downloading one or multiple chapters. * DownloadNotifier is used to show notifications when downloading one or multiple chapters.
@ -23,16 +23,19 @@ import uy.kohesive.injekt.api.get
*/ */
internal class DownloadNotifier(private val context: Context) { internal class DownloadNotifier(private val context: Context) {
private val notificationBuilder = context.notificationBuilder(Notifications.CHANNEL_DOWNLOADER) { private val preferences: PreferencesHelper by injectLazy()
private val progressNotificationBuilder = context.notificationBuilder(Notifications.CHANNEL_DOWNLOADER_PROGRESS) {
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher)) setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher))
} }
private val preferences by lazy { Injekt.get<PreferencesHelper>() } private val completeNotificationBuilder = context.notificationBuilder(Notifications.CHANNEL_DOWNLOADER_COMPLETE) {
setAutoCancel(false)
}
/** /**
* Status of download. Used for correct notification icon. * Status of download. Used for correct notification icon.
*/ */
@Volatile
private var isDownloading = false private var isDownloading = false
/** /**
@ -57,7 +60,7 @@ internal class DownloadNotifier(private val context: Context) {
/** /**
* Clear old actions if they exist. * Clear old actions if they exist.
*/ */
private fun clearActions() = with(notificationBuilder) { private fun NotificationCompat.Builder.clearActions() {
if (mActions.isNotEmpty()) { if (mActions.isNotEmpty()) {
mActions.clear() mActions.clear()
} }
@ -71,35 +74,13 @@ internal class DownloadNotifier(private val context: Context) {
context.notificationManager.cancel(Notifications.ID_DOWNLOAD_CHAPTER) context.notificationManager.cancel(Notifications.ID_DOWNLOAD_CHAPTER)
} }
/**
* This function shows a notification to inform download tasks are done.
*/
fun downloadFinished() {
// Create notification
with(notificationBuilder) {
setContentTitle(context.getString(R.string.download_notifier_downloader_title))
setContentText(context.getString(R.string.download_notifier_download_finish))
setSmallIcon(android.R.drawable.stat_sys_download_done)
clearActions()
setAutoCancel(true)
setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context))
setProgress(0, 0, false)
}
notificationBuilder.show(Notifications.ID_DOWNLOAD_CHAPTER_COMPLETE)
// Reset states to default
errorThrown = false
isDownloading = false
}
/** /**
* Called when download progress changes. * Called when download progress changes.
* *
* @param download download object containing download information. * @param download download object containing download information.
*/ */
fun onProgressChange(download: Download) { fun onProgressChange(download: Download) {
// Create notification with(progressNotificationBuilder) {
with(notificationBuilder) {
// Check if first call. // Check if first call.
if (!isDownloading) { if (!isDownloading) {
setSmallIcon(android.R.drawable.stat_sys_download) setSmallIcon(android.R.drawable.stat_sys_download)
@ -132,16 +113,14 @@ internal class DownloadNotifier(private val context: Context) {
setProgress(download.pages!!.size, download.downloadedImages, false) setProgress(download.pages!!.size, download.downloadedImages, false)
} }
progressNotificationBuilder.show()
// Displays the progress bar on notification
notificationBuilder.show()
} }
/** /**
* Show notification when download is paused. * Show notification when download is paused.
*/ */
fun onDownloadPaused() { fun onDownloadPaused() {
with(notificationBuilder) { with(progressNotificationBuilder) {
setContentTitle(context.getString(R.string.chapter_paused)) setContentTitle(context.getString(R.string.chapter_paused))
setContentText(context.getString(R.string.download_notifier_download_paused)) setContentText(context.getString(R.string.download_notifier_download_paused))
setSmallIcon(R.drawable.ic_pause_24dp) setSmallIcon(R.drawable.ic_pause_24dp)
@ -163,21 +142,40 @@ internal class DownloadNotifier(private val context: Context) {
NotificationReceiver.clearDownloadsPendingBroadcast(context) NotificationReceiver.clearDownloadsPendingBroadcast(context)
) )
} }
progressNotificationBuilder.show()
// Show notification.
notificationBuilder.show()
// Reset initial values // Reset initial values
isDownloading = false isDownloading = false
} }
/**
* This function shows a notification to inform download tasks are done.
*/
fun downloadFinished() {
// Create notification
with(completeNotificationBuilder) {
setContentTitle(context.getString(R.string.download_notifier_downloader_title))
setContentText(context.getString(R.string.download_notifier_download_finish))
setSmallIcon(android.R.drawable.stat_sys_download_done)
clearActions()
setAutoCancel(true)
setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context))
setProgress(0, 0, false)
}
completeNotificationBuilder.show(Notifications.ID_DOWNLOAD_CHAPTER_COMPLETE)
// Reset states to default
errorThrown = false
isDownloading = false
}
/** /**
* Called when the downloader receives a warning. * Called when the downloader receives a warning.
* *
* @param reason the text to show. * @param reason the text to show.
*/ */
fun onWarning(reason: String) { fun onWarning(reason: String) {
with(notificationBuilder) { with(completeNotificationBuilder) {
setContentTitle(context.getString(R.string.download_notifier_downloader_title)) setContentTitle(context.getString(R.string.download_notifier_downloader_title))
setContentText(reason) setContentText(reason)
setSmallIcon(android.R.drawable.stat_sys_warning) setSmallIcon(android.R.drawable.stat_sys_warning)
@ -186,7 +184,7 @@ internal class DownloadNotifier(private val context: Context) {
setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context)) setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context))
setProgress(0, 0, false) setProgress(0, 0, false)
} }
notificationBuilder.show() completeNotificationBuilder.show()
// Reset download information // Reset download information
isDownloading = false isDownloading = false
@ -201,7 +199,7 @@ internal class DownloadNotifier(private val context: Context) {
*/ */
fun onError(error: String? = null, chapter: String? = null) { fun onError(error: String? = null, chapter: String? = null) {
// Create notification // Create notification
with(notificationBuilder) { with(completeNotificationBuilder) {
setContentTitle( setContentTitle(
chapter chapter
?: context.getString(R.string.download_notifier_downloader_title) ?: context.getString(R.string.download_notifier_downloader_title)
@ -213,7 +211,7 @@ internal class DownloadNotifier(private val context: Context) {
setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context)) setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context))
setProgress(0, 0, false) setProgress(0, 0, false)
} }
notificationBuilder.show(Notifications.ID_DOWNLOAD_CHAPTER_ERROR) completeNotificationBuilder.show(Notifications.ID_DOWNLOAD_CHAPTER_ERROR)
// Reset download information // Reset download information
errorThrown = true errorThrown = true

View file

@ -188,7 +188,7 @@ class DownloadService : Service() {
} }
private fun getPlaceholderNotification(): Notification { private fun getPlaceholderNotification(): Notification {
return notification(Notifications.CHANNEL_DOWNLOADER) { return notification(Notifications.CHANNEL_DOWNLOADER_PROGRESS) {
setContentTitle(getString(R.string.download_notifier_downloader_title)) setContentTitle(getString(R.string.download_notifier_downloader_title))
} }
} }

View file

@ -30,8 +30,10 @@ object Notifications {
/** /**
* Notification channel and ids used by the downloader. * Notification channel and ids used by the downloader.
*/ */
const val CHANNEL_DOWNLOADER = "downloader_channel" private const val GROUP_DOWNLOADER = "group_downloader"
const val CHANNEL_DOWNLOADER_PROGRESS = "downloader_progress_channel"
const val ID_DOWNLOAD_CHAPTER = -201 const val ID_DOWNLOAD_CHAPTER = -201
const val CHANNEL_DOWNLOADER_COMPLETE = "downloader_complete_channel"
const val ID_DOWNLOAD_CHAPTER_ERROR = -202 const val ID_DOWNLOAD_CHAPTER_ERROR = -202
const val ID_DOWNLOAD_CHAPTER_COMPLETE = -203 const val ID_DOWNLOAD_CHAPTER_COMPLETE = -203
@ -51,7 +53,7 @@ object Notifications {
/** /**
* Notification channel and ids used by the backup/restore system. * Notification channel and ids used by the backup/restore system.
*/ */
private const val GROUP_BACK_RESTORE = "group_backup_restore" private const val GROUP_BACKUP_RESTORE = "group_backup_restore"
const val CHANNEL_BACKUP_RESTORE_PROGRESS = "backup_restore_progress_channel" const val CHANNEL_BACKUP_RESTORE_PROGRESS = "backup_restore_progress_channel"
const val ID_BACKUP_PROGRESS = -501 const val ID_BACKUP_PROGRESS = -501
const val ID_RESTORE_PROGRESS = -503 const val ID_RESTORE_PROGRESS = -503
@ -60,6 +62,7 @@ object Notifications {
const val ID_RESTORE_COMPLETE = -504 const val ID_RESTORE_COMPLETE = -504
private val deprecatedChannels = listOf( private val deprecatedChannels = listOf(
"downloader_channel",
"backup_restore_complete_channel" "backup_restore_complete_channel"
) )
@ -71,10 +74,12 @@ object Notifications {
fun createChannels(context: Context) { fun createChannels(context: Context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
val backupRestoreGroup = NotificationChannelGroup(GROUP_BACK_RESTORE, context.getString(R.string.channel_backup_restore)) listOf(
context.notificationManager.createNotificationChannelGroup(backupRestoreGroup) NotificationChannelGroup(GROUP_BACKUP_RESTORE, context.getString(R.string.group_backup_restore)),
NotificationChannelGroup(GROUP_DOWNLOADER, context.getString(R.string.group_downloader))
).forEach(context.notificationManager::createNotificationChannelGroup)
val channels = listOf( listOf(
NotificationChannel( NotificationChannel(
CHANNEL_COMMON, context.getString(R.string.channel_common), CHANNEL_COMMON, context.getString(R.string.channel_common),
NotificationManager.IMPORTANCE_LOW NotificationManager.IMPORTANCE_LOW
@ -86,9 +91,17 @@ object Notifications {
setShowBadge(false) setShowBadge(false)
}, },
NotificationChannel( NotificationChannel(
CHANNEL_DOWNLOADER, context.getString(R.string.channel_downloader), CHANNEL_DOWNLOADER_PROGRESS, context.getString(R.string.channel_progress),
NotificationManager.IMPORTANCE_LOW NotificationManager.IMPORTANCE_LOW
).apply { ).apply {
group = GROUP_DOWNLOADER
setShowBadge(false)
},
NotificationChannel(
CHANNEL_DOWNLOADER_COMPLETE, context.getString(R.string.channel_complete),
NotificationManager.IMPORTANCE_LOW
).apply {
group = GROUP_DOWNLOADER
setShowBadge(false) setShowBadge(false)
}, },
NotificationChannel( NotificationChannel(
@ -100,26 +113,23 @@ object Notifications {
NotificationManager.IMPORTANCE_DEFAULT NotificationManager.IMPORTANCE_DEFAULT
), ),
NotificationChannel( NotificationChannel(
CHANNEL_BACKUP_RESTORE_PROGRESS, context.getString(R.string.channel_backup_restore_progress), CHANNEL_BACKUP_RESTORE_PROGRESS, context.getString(R.string.channel_progress),
NotificationManager.IMPORTANCE_LOW NotificationManager.IMPORTANCE_LOW
).apply { ).apply {
group = GROUP_BACK_RESTORE group = GROUP_BACKUP_RESTORE
setShowBadge(false) setShowBadge(false)
}, },
NotificationChannel( NotificationChannel(
CHANNEL_BACKUP_RESTORE_COMPLETE, context.getString(R.string.channel_backup_restore_complete), CHANNEL_BACKUP_RESTORE_COMPLETE, context.getString(R.string.channel_complete),
NotificationManager.IMPORTANCE_HIGH NotificationManager.IMPORTANCE_HIGH
).apply { ).apply {
group = GROUP_BACK_RESTORE group = GROUP_BACKUP_RESTORE
setShowBadge(false) setShowBadge(false)
setSound(null, null) setSound(null, null)
} }
) ).forEach(context.notificationManager::createNotificationChannel)
context.notificationManager.createNotificationChannels(channels)
// Delete old notification channels // Delete old notification channels
deprecatedChannels.forEach { deprecatedChannels.forEach(context.notificationManager::deleteNotificationChannel)
context.notificationManager.deleteNotificationChannel(it)
}
} }
} }

View file

@ -676,13 +676,13 @@
<!-- Notification channels --> <!-- Notification channels -->
<string name="channel_common">Common</string> <string name="channel_common">Common</string>
<string name="channel_progress">Progress</string>
<string name="channel_complete">Complete</string>
<string name="channel_library">Library</string> <string name="channel_library">Library</string>
<string name="channel_downloader">Downloader</string> <string name="group_downloader">Downloads</string>
<string name="group_backup_restore">Backup and restore</string>
<string name="channel_new_chapters">Chapter updates</string> <string name="channel_new_chapters">Chapter updates</string>
<string name="channel_ext_updates">Extension updates</string> <string name="channel_ext_updates">Extension updates</string>
<string name="channel_backup_restore">Backup and restore</string>
<string name="channel_backup_restore_progress">Progress</string>
<string name="channel_backup_restore_complete">Complete</string>
<string name="pref_read_with_tapping_inverted">Invert tapping</string> <string name="pref_read_with_tapping_inverted">Invert tapping</string>
<string name="tapping_inverted_none">None</string> <string name="tapping_inverted_none">None</string>
<string name="tapping_inverted_horizontal">Horizontal</string> <string name="tapping_inverted_horizontal">Horizontal</string>