Refactor notification builder extension

This commit is contained in:
arkon 2020-01-16 08:53:55 -05:00
parent a5fadcda15
commit 8aa48effaa
6 changed files with 66 additions and 51 deletions

View file

@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.data.notification.NotificationHandler
import eu.kanade.tachiyomi.data.notification.NotificationReceiver import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.util.lang.chop import eu.kanade.tachiyomi.util.lang.chop
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
@ -19,12 +20,9 @@ import java.util.regex.Pattern
* @param context context of application * @param context context of application
*/ */
internal class DownloadNotifier(private val context: Context) { internal class DownloadNotifier(private val context: Context) {
/**
* Notification builder. private val notificationBuilder = context.notificationBuilder(Notifications.CHANNEL_DOWNLOADER) {
*/ setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher))
private val notification by lazy {
NotificationCompat.Builder(context, Notifications.CHANNEL_DOWNLOADER)
.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher))
} }
/** /**
@ -70,10 +68,11 @@ internal class DownloadNotifier(private val context: Context) {
/** /**
* Clear old actions if they exist. * Clear old actions if they exist.
*/ */
private fun clearActions() = with(notification) { private fun clearActions() = with(notificationBuilder) {
if (!mActions.isEmpty()) if (mActions.isNotEmpty()) {
mActions.clear() mActions.clear()
} }
}
/** /**
* Dismiss the downloader's notification. Downloader error notifications use a different id, so * Dismiss the downloader's notification. Downloader error notifications use a different id, so
@ -90,7 +89,7 @@ internal class DownloadNotifier(private val context: Context) {
*/ */
fun onProgressChange(download: Download) { fun onProgressChange(download: Download) {
// Create notification // Create notification
with(notification) { 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)
@ -114,14 +113,14 @@ internal class DownloadNotifier(private val context: Context) {
setProgress(download.pages!!.size, download.downloadedImages, false) setProgress(download.pages!!.size, download.downloadedImages, false)
} }
// Displays the progress bar on notification // Displays the progress bar on notification
notification.show() notificationBuilder.show()
} }
/** /**
* Show notification when download is paused. * Show notification when download is paused.
*/ */
fun onDownloadPaused() { fun onDownloadPaused() {
with(notification) { with(notificationBuilder) {
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_white_24dp) setSmallIcon(R.drawable.ic_pause_white_24dp)
@ -141,7 +140,7 @@ internal class DownloadNotifier(private val context: Context) {
} }
// Show notification. // Show notification.
notification.show() notificationBuilder.show()
// Reset initial values // Reset initial values
isDownloading = false isDownloading = false
@ -159,7 +158,7 @@ internal class DownloadNotifier(private val context: Context) {
return return
} }
// Create notification. // Create notification.
with(notification) { with(notificationBuilder) {
val title = download.manga.title.chop(15) val title = download.manga.title.chop(15)
val quotedTitle = Pattern.quote(title) val quotedTitle = Pattern.quote(title)
val chapter = download.chapter.name.replaceFirst("$quotedTitle[\\s]*[-]*[\\s]*".toRegex(RegexOption.IGNORE_CASE), "") val chapter = download.chapter.name.replaceFirst("$quotedTitle[\\s]*[-]*[\\s]*".toRegex(RegexOption.IGNORE_CASE), "")
@ -173,7 +172,7 @@ internal class DownloadNotifier(private val context: Context) {
} }
// Show notification. // Show notification.
notification.show() notificationBuilder.show()
// Reset initial values // Reset initial values
isDownloading = false isDownloading = false
@ -186,7 +185,7 @@ internal class DownloadNotifier(private val context: Context) {
* @param reason the text to show. * @param reason the text to show.
*/ */
fun onWarning(reason: String) { fun onWarning(reason: String) {
with(notification) { with(notificationBuilder) {
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)
@ -195,7 +194,7 @@ internal class DownloadNotifier(private val context: Context) {
setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context)) setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context))
setProgress(0, 0, false) setProgress(0, 0, false)
} }
notification.show() notificationBuilder.show()
// Reset download information // Reset download information
isDownloading = false isDownloading = false
@ -210,7 +209,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(notification) { with(notificationBuilder) {
setContentTitle(chapter ?: context.getString(R.string.download_notifier_downloader_title)) setContentTitle(chapter ?: context.getString(R.string.download_notifier_downloader_title))
setContentText(error ?: context.getString(R.string.download_notifier_unkown_error)) setContentText(error ?: context.getString(R.string.download_notifier_unkown_error))
setSmallIcon(android.R.drawable.stat_sys_warning) setSmallIcon(android.R.drawable.stat_sys_warning)
@ -219,7 +218,7 @@ internal class DownloadNotifier(private val context: Context) {
setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context)) setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context))
setProgress(0, 0, false) setProgress(0, 0, false)
} }
notification.show(Notifications.ID_DOWNLOAD_CHAPTER_ERROR) notificationBuilder.show(Notifications.ID_DOWNLOAD_CHAPTER_ERROR)
// Reset download information // Reset download information
errorThrown = true errorThrown = true

View file

@ -9,7 +9,6 @@ import android.net.NetworkInfo.State.DISCONNECTED
import android.os.Build import android.os.Build
import android.os.IBinder import android.os.IBinder
import android.os.PowerManager import android.os.PowerManager
import androidx.core.app.NotificationCompat
import com.github.pwittchen.reactivenetwork.library.Connectivity import com.github.pwittchen.reactivenetwork.library.Connectivity
import com.github.pwittchen.reactivenetwork.library.ReactiveNetwork import com.github.pwittchen.reactivenetwork.library.ReactiveNetwork
import com.jakewharton.rxrelay.BehaviorRelay import com.jakewharton.rxrelay.BehaviorRelay
@ -18,6 +17,7 @@ import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.util.lang.plusAssign import eu.kanade.tachiyomi.util.lang.plusAssign
import eu.kanade.tachiyomi.util.system.connectivityManager import eu.kanade.tachiyomi.util.system.connectivityManager
import eu.kanade.tachiyomi.util.system.notification
import eu.kanade.tachiyomi.util.system.powerManager import eu.kanade.tachiyomi.util.system.powerManager
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
@ -187,9 +187,9 @@ class DownloadService : Service() {
} }
private fun getPlaceholderNotification(): Notification { private fun getPlaceholderNotification(): Notification {
return NotificationCompat.Builder(this, Notifications.CHANNEL_DOWNLOADER) return notification(Notifications.CHANNEL_DOWNLOADER) {
.setContentTitle(getString(R.string.download_notifier_downloader_title)) setContentTitle(getString(R.string.download_notifier_downloader_title))
.build() }
} }
} }

View file

@ -33,6 +33,7 @@ import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
import eu.kanade.tachiyomi.util.lang.chop import eu.kanade.tachiyomi.util.lang.chop
import eu.kanade.tachiyomi.util.system.isServiceRunning import eu.kanade.tachiyomi.util.system.isServiceRunning
import eu.kanade.tachiyomi.util.system.notification import eu.kanade.tachiyomi.util.system.notification
import eu.kanade.tachiyomi.util.system.notificationBuilder
import eu.kanade.tachiyomi.util.system.notificationManager import eu.kanade.tachiyomi.util.system.notificationManager
import rx.Observable import rx.Observable
import rx.Subscription import rx.Subscription
@ -86,13 +87,15 @@ class LibraryUpdateService(
/** /**
* Cached progress notification to avoid creating a lot. * Cached progress notification to avoid creating a lot.
*/ */
private val progressNotification by lazy { NotificationCompat.Builder(this, Notifications.CHANNEL_LIBRARY) private val progressNotificationBuilder by lazy {
.setContentTitle(getString(R.string.app_name)) notificationBuilder(Notifications.CHANNEL_LIBRARY) {
.setSmallIcon(R.drawable.ic_refresh_white_24dp) setContentTitle(getString(R.string.app_name))
.setLargeIcon(notificationBitmap) setSmallIcon(R.drawable.ic_refresh_white_24dp)
.setOngoing(true) setLargeIcon(notificationBitmap)
.setOnlyAlertOnce(true) setOngoing(true)
.addAction(R.drawable.ic_close_white_24dp, getString(android.R.string.cancel), cancelIntent) setOnlyAlertOnce(true)
addAction(R.drawable.ic_close_white_24dp, getString(android.R.string.cancel), cancelIntent)
}
} }
/** /**
@ -165,7 +168,7 @@ class LibraryUpdateService(
*/ */
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
startForeground(Notifications.ID_LIBRARY_PROGRESS, progressNotification.build()) startForeground(Notifications.ID_LIBRARY_PROGRESS, progressNotificationBuilder.build())
wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).newWakeLock( wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, "LibraryUpdateService:WakeLock") PowerManager.PARTIAL_WAKE_LOCK, "LibraryUpdateService:WakeLock")
wakeLock.acquire() wakeLock.acquire()
@ -430,7 +433,7 @@ class LibraryUpdateService(
* @param total the total progress. * @param total the total progress.
*/ */
private fun showProgressNotification(manga: Manga, current: Int, total: Int) { private fun showProgressNotification(manga: Manga, current: Int, total: Int) {
notificationManager.notify(Notifications.ID_LIBRARY_PROGRESS, progressNotification notificationManager.notify(Notifications.ID_LIBRARY_PROGRESS, progressNotificationBuilder
.setContentTitle(manga.title) .setContentTitle(manga.title)
.setProgress(total, current, false) .setProgress(total, current, false)
.build()) .build())

View file

@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.notification.NotificationHandler import eu.kanade.tachiyomi.data.notification.NotificationHandler
import eu.kanade.tachiyomi.data.notification.NotificationReceiver import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.util.system.notificationBuilder
import eu.kanade.tachiyomi.util.system.notificationManager import eu.kanade.tachiyomi.util.system.notificationManager
/** /**
@ -16,12 +17,7 @@ import eu.kanade.tachiyomi.util.system.notificationManager
*/ */
internal class UpdaterNotifier(private val context: Context) { internal class UpdaterNotifier(private val context: Context) {
/** private val notificationBuilder = context.notificationBuilder(Notifications.CHANNEL_COMMON)
* Builder to manage notifications.
*/
private val notification by lazy {
NotificationCompat.Builder(context, Notifications.CHANNEL_COMMON)
}
/** /**
* Call to show notification. * Call to show notification.
@ -38,13 +34,13 @@ internal class UpdaterNotifier(private val context: Context) {
* @param title tile of notification. * @param title tile of notification.
*/ */
fun onDownloadStarted(title: String) { fun onDownloadStarted(title: String) {
with(notification) { with(notificationBuilder) {
setContentTitle(title) setContentTitle(title)
setContentText(context.getString(R.string.update_check_notification_download_in_progress)) setContentText(context.getString(R.string.update_check_notification_download_in_progress))
setSmallIcon(android.R.drawable.stat_sys_download) setSmallIcon(android.R.drawable.stat_sys_download)
setOngoing(true) setOngoing(true)
} }
notification.show() notificationBuilder.show()
} }
/** /**
@ -53,11 +49,11 @@ internal class UpdaterNotifier(private val context: Context) {
* @param progress progress of download (xx%/100). * @param progress progress of download (xx%/100).
*/ */
fun onProgressChange(progress: Int) { fun onProgressChange(progress: Int) {
with(notification) { with(notificationBuilder) {
setProgress(100, progress, false) setProgress(100, progress, false)
setOnlyAlertOnce(true) setOnlyAlertOnce(true)
} }
notification.show() notificationBuilder.show()
} }
/** /**
@ -66,7 +62,7 @@ internal class UpdaterNotifier(private val context: Context) {
* @param uri path location of apk. * @param uri path location of apk.
*/ */
fun onDownloadFinished(uri: Uri) { fun onDownloadFinished(uri: Uri) {
with(notification) { with(notificationBuilder) {
setContentText(context.getString(R.string.update_check_notification_download_complete)) setContentText(context.getString(R.string.update_check_notification_download_complete))
setSmallIcon(android.R.drawable.stat_sys_download_done) setSmallIcon(android.R.drawable.stat_sys_download_done)
setOnlyAlertOnce(false) setOnlyAlertOnce(false)
@ -81,7 +77,7 @@ internal class UpdaterNotifier(private val context: Context) {
context.getString(R.string.action_cancel), context.getString(R.string.action_cancel),
NotificationReceiver.dismissNotificationPendingBroadcast(context, Notifications.ID_UPDATER)) NotificationReceiver.dismissNotificationPendingBroadcast(context, Notifications.ID_UPDATER))
} }
notification.show() notificationBuilder.show()
} }
/** /**
@ -90,7 +86,7 @@ internal class UpdaterNotifier(private val context: Context) {
* @param url web location of apk to download. * @param url web location of apk to download.
*/ */
fun onDownloadError(url: String) { fun onDownloadError(url: String) {
with(notification) { with(notificationBuilder) {
setContentText(context.getString(R.string.update_check_notification_download_error)) setContentText(context.getString(R.string.update_check_notification_download_error))
setSmallIcon(android.R.drawable.stat_sys_warning) setSmallIcon(android.R.drawable.stat_sys_warning)
setOnlyAlertOnce(false) setOnlyAlertOnce(false)
@ -104,6 +100,6 @@ internal class UpdaterNotifier(private val context: Context) {
context.getString(R.string.action_cancel), context.getString(R.string.action_cancel),
NotificationReceiver.dismissNotificationPendingBroadcast(context, Notifications.ID_UPDATER)) NotificationReceiver.dismissNotificationPendingBroadcast(context, Notifications.ID_UPDATER))
} }
notification.show(Notifications.ID_UPDATER) notificationBuilder.show(Notifications.ID_UPDATER)
} }
} }

View file

@ -9,6 +9,7 @@ import eu.kanade.tachiyomi.data.glide.GlideApp
import eu.kanade.tachiyomi.data.notification.NotificationHandler import eu.kanade.tachiyomi.data.notification.NotificationHandler
import eu.kanade.tachiyomi.data.notification.NotificationReceiver import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.util.system.notificationBuilder
import eu.kanade.tachiyomi.util.system.notificationManager import eu.kanade.tachiyomi.util.system.notificationManager
import java.io.File import java.io.File
@ -20,7 +21,7 @@ class SaveImageNotifier(private val context: Context) {
/** /**
* Notification builder. * Notification builder.
*/ */
private val notificationBuilder = NotificationCompat.Builder(context, Notifications.CHANNEL_COMMON) private val notificationBuilder = context.notificationBuilder(Notifications.CHANNEL_COMMON)
/** /**
* Id of the notification. * Id of the notification.
@ -59,8 +60,9 @@ class SaveImageNotifier(private val context: Context) {
setAutoCancel(true) setAutoCancel(true)
// Clear old actions if they exist // Clear old actions if they exist
if (mActions.isNotEmpty()) if (mActions.isNotEmpty()) {
mActions.clear() mActions.clear()
}
setContentIntent(NotificationHandler.openImagePendingActivity(context, file)) setContentIntent(NotificationHandler.openImagePendingActivity(context, file))
// Share action // Share action

View file

@ -43,16 +43,31 @@ fun Context.toast(text: String?, duration: Int = Toast.LENGTH_SHORT) {
Toast.makeText(this, text.orEmpty(), duration).show() Toast.makeText(this, text.orEmpty(), duration).show()
} }
/**
* Helper method to create a notification builder.
*
* @param id the channel id.
* @param block the function that will execute inside the builder.
* @return a notification to be displayed or updated.
*/
fun Context.notificationBuilder(channelId: String, block: (NotificationCompat.Builder.() -> Unit)? = null): NotificationCompat.Builder {
val builder = NotificationCompat.Builder(this, channelId)
.setColor(ContextCompat.getColor(this, R.color.colorPrimary))
if (block != null) {
builder.block()
}
return builder
}
/** /**
* Helper method to create a notification. * Helper method to create a notification.
* *
* @param id the channel id. * @param id the channel id.
* @param func the function that will execute inside the builder. * @param block the function that will execute inside the builder.
* @return a notification to be displayed or updated. * @return a notification to be displayed or updated.
*/ */
inline fun Context.notification(channelId: String, func: NotificationCompat.Builder.() -> Unit): Notification { fun Context.notification(channelId: String, block: (NotificationCompat.Builder.() -> Unit)?): Notification {
val builder = NotificationCompat.Builder(this, channelId) val builder = notificationBuilder(channelId, block)
builder.func()
return builder.build() return builder.build()
} }