Notification color & icon (#620)

* add color to notification

* add app icon to extension update notification

* add app icon to download error notification

* add large app icon to all the notification

* set large image for chapter update & save image notification
This commit is contained in:
Cuong-Tran 2025-01-26 01:58:08 +07:00 committed by GitHub
parent af77a962c1
commit 4c7563294d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 104 additions and 17 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher">#c837ab</color>
</resources>

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher">#ffe680</color>
</resources>

View file

@ -7,6 +7,7 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.BitmapFactory
import android.os.Build
import android.os.Looper
import android.webkit.WebView
@ -156,6 +157,8 @@ class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.Factor
setContentTitle(stringResource(MR.strings.pref_incognito_mode))
setContentText(stringResource(MR.strings.notification_incognito_text))
setSmallIcon(R.drawable.ic_glasses_24dp)
setColor(ContextCompat.getColor(applicationContext, R.color.ic_launcher))
setLargeIcon(BitmapFactory.decodeResource(applicationContext.resources, R.drawable.komikku))
setOngoing(true)
val pendingIntent = PendingIntent.getBroadcast(

View file

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.data.backup
import android.content.Context
import android.graphics.BitmapFactory
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.core.security.SecurityPreferences
@ -34,8 +35,9 @@ class BackupNotifier(private val context: Context) {
private val progressNotificationBuilder = context.notificationBuilder(
Notifications.CHANNEL_BACKUP_RESTORE_PROGRESS,
) {
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher))
setSmallIcon(R.drawable.ic_komikku)
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.komikku))
setAutoCancel(false)
setOngoing(true)
setOnlyAlertOnce(true)
@ -44,8 +46,9 @@ class BackupNotifier(private val context: Context) {
private val completeNotificationBuilder = context.notificationBuilder(
Notifications.CHANNEL_BACKUP_RESTORE_COMPLETE,
) {
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher))
setSmallIcon(R.drawable.ic_komikku)
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.komikku))
setAutoCancel(false)
}

View file

@ -2,7 +2,9 @@ package eu.kanade.tachiyomi.data.download
import android.content.Context
import android.content.pm.ServiceInfo
import android.graphics.BitmapFactory
import android.os.Build
import androidx.core.content.ContextCompat
import androidx.lifecycle.asFlow
import androidx.work.CoroutineWorker
import androidx.work.ExistingWorkPolicy
@ -32,7 +34,7 @@ import uy.kohesive.injekt.api.get
* This worker is used to manage the downloader. The system can decide to stop the worker, in
* which case the downloader is also stopped. It's also stopped while there's no network available.
*/
class DownloadJob(context: Context, workerParams: WorkerParameters) : CoroutineWorker(context, workerParams) {
class DownloadJob(private val context: Context, workerParams: WorkerParameters) : CoroutineWorker(context, workerParams) {
private val downloadManager: DownloadManager = Injekt.get()
private val downloadPreferences: DownloadPreferences = Injekt.get()
@ -41,6 +43,8 @@ class DownloadJob(context: Context, workerParams: WorkerParameters) : CoroutineW
val notification = applicationContext.notificationBuilder(Notifications.CHANNEL_DOWNLOADER_PROGRESS) {
setContentTitle(applicationContext.getString(R.string.download_notifier_downloader_title))
setSmallIcon(android.R.drawable.stat_sys_download)
setColor(ContextCompat.getColor(applicationContext, R.color.ic_launcher))
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.komikku))
}.build()
return ForegroundInfo(
Notifications.ID_DOWNLOAD_CHAPTER_PROGRESS,

View file

@ -4,6 +4,7 @@ import android.app.PendingIntent
import android.content.Context
import android.graphics.BitmapFactory
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.data.download.model.Download
@ -30,7 +31,8 @@ internal class DownloadNotifier(private val context: Context) {
private val progressNotificationBuilder by lazy {
context.notificationBuilder(Notifications.CHANNEL_DOWNLOADER_PROGRESS) {
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher))
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.komikku))
setAutoCancel(false)
setOnlyAlertOnce(true)
}
@ -38,6 +40,8 @@ internal class DownloadNotifier(private val context: Context) {
private val errorNotificationBuilder by lazy {
context.notificationBuilder(Notifications.CHANNEL_DOWNLOADER_ERROR) {
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.komikku))
setAutoCancel(false)
}
}

View file

@ -8,11 +8,10 @@ import android.graphics.Bitmap
import android.graphics.BitmapFactory
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import coil3.asDrawable
import coil3.imageLoader
import coil3.request.ImageRequest
import coil3.request.transformations
import coil3.transform.CircleCropTransformation
import eu.kanade.presentation.util.formatChapterNumber
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.core.security.SecurityPreferences
@ -70,7 +69,7 @@ class LibraryUpdateNotifier(
* Bitmap of the app for notifications.
*/
private val notificationBitmap by lazy {
BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher)
BitmapFactory.decodeResource(context.resources, R.drawable.komikku)
}
/**
@ -80,6 +79,7 @@ class LibraryUpdateNotifier(
context.notificationBuilder(Notifications.CHANNEL_LIBRARY_PROGRESS) {
setContentTitle(context.stringResource(MR.strings.app_name))
setSmallIcon(R.drawable.ic_refresh_24dp)
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
setLargeIcon(notificationBitmap)
setOngoing(true)
setOnlyAlertOnce(true)
@ -142,6 +142,7 @@ class LibraryUpdateNotifier(
NotificationCompat.BigTextStyle().bigText(context.stringResource(MR.strings.notification_size_warning)),
)
setSmallIcon(R.drawable.ic_warning_white_24dp)
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
setTimeoutAfter(Downloader.WARNING_NOTIF_TIMEOUT_MS)
setContentIntent(NotificationHandler.openUrl(context, HELP_WARNING_URL))
}
@ -164,6 +165,7 @@ class LibraryUpdateNotifier(
setContentTitle(context.stringResource(MR.strings.notification_update_error, failed))
setContentText(context.stringResource(MR.strings.action_show_errors))
setSmallIcon(R.drawable.ic_komikku)
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
setContentIntent(NotificationReceiver.openErrorLogPendingActivity(context))
}
@ -204,6 +206,7 @@ class LibraryUpdateNotifier(
}
setSmallIcon(R.drawable.ic_komikku)
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
setLargeIcon(notificationBitmap)
setGroup(Notifications.GROUP_NEW_CHAPTERS)
@ -237,12 +240,23 @@ class LibraryUpdateNotifier(
val description = getNewChaptersDescription(chapters)
setContentText(description)
setStyle(NotificationCompat.BigTextStyle().bigText(description))
setSmallIcon(R.drawable.ic_komikku)
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
if (icon != null) {
setLargeIcon(icon)
// KMK -->
setStyle(
NotificationCompat.BigPictureStyle()
.bigPicture(icon)
.bigLargeIcon(notificationBitmap)
.setBigContentTitle(manga.title)
.setSummaryText(description),
)
// KMK <--
} else {
setStyle(NotificationCompat.BigTextStyle().bigText(description))
}
setGroup(Notifications.GROUP_NEW_CHAPTERS)
@ -301,8 +315,10 @@ class LibraryUpdateNotifier(
private suspend fun getMangaIcon(manga: Manga): Bitmap? {
val request = ImageRequest.Builder(context)
.data(manga)
.transformations(CircleCropTransformation())
.size(NOTIF_ICON_SIZE)
// KMK -->
// .transformations(CircleCropTransformation())
// .size(NOTIF_ICON_SIZE)
// KMK <--
.build()
val drawable = context.imageLoader.execute(request).image?.asDrawable(context.resources)
return drawable?.getBitmapOrNull()

View file

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.data.sync
import android.content.Context
import android.graphics.BitmapFactory
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.data.SyncStatus
@ -26,8 +27,9 @@ class SyncNotifier(private val context: Context) {
private val progressNotificationBuilder = context.notificationBuilder(
Notifications.CHANNEL_BACKUP_RESTORE_PROGRESS,
) {
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher))
setSmallIcon(R.drawable.ic_komikku)
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.komikku))
setAutoCancel(false)
setOngoing(true)
setOnlyAlertOnce(true)
@ -36,8 +38,9 @@ class SyncNotifier(private val context: Context) {
private val completeNotificationBuilder = context.notificationBuilder(
Notifications.CHANNEL_BACKUP_RESTORE_PROGRESS,
) {
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher))
setSmallIcon(R.drawable.ic_komikku)
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.komikku))
setAutoCancel(false)
}

View file

@ -3,8 +3,10 @@ package eu.kanade.tachiyomi.data.updater
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.net.Uri
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R
@ -20,7 +22,10 @@ import tachiyomi.i18n.kmk.KMR
internal class AppUpdateNotifier(private val context: Context) {
private val notificationBuilder = context.notificationBuilder(Notifications.CHANNEL_APP_UPDATE)
private val notificationBuilder = context.notificationBuilder(Notifications.CHANNEL_APP_UPDATE) {
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.komikku))
}
/**
* Call to show notification.

View file

@ -1,7 +1,9 @@
package eu.kanade.tachiyomi.extension.api
import android.content.Context
import android.graphics.BitmapFactory
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
@ -35,6 +37,8 @@ class ExtensionUpdateNotifier(
setStyle(NotificationCompat.BigTextStyle().bigText(extNames))
}
setSmallIcon(R.drawable.ic_extension_24dp)
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.komikku))
setContentIntent(NotificationReceiver.openExtensionsPendingActivity(context))
setAutoCancel(true)
}

View file

@ -3,8 +3,10 @@ package eu.kanade.tachiyomi.extension.util
import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.IBinder
import androidx.core.content.ContextCompat
import eu.kanade.domain.base.BasePreferences
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.notification.Notifications
@ -26,6 +28,8 @@ class ExtensionInstallService : Service() {
override fun onCreate() {
val notification = notificationBuilder(Notifications.CHANNEL_EXTENSIONS_UPDATE) {
setSmallIcon(R.drawable.ic_komikku)
setColor(ContextCompat.getColor(applicationContext, R.color.ic_launcher))
setLargeIcon(BitmapFactory.decodeResource(applicationContext.resources, R.drawable.komikku))
setAutoCancel(false)
setOngoing(true)
setShowWhen(false)

View file

@ -2,8 +2,10 @@ package eu.kanade.tachiyomi.ui.reader
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import coil3.asDrawable
import coil3.imageLoader
import coil3.request.CachePolicy
@ -24,7 +26,9 @@ import tachiyomi.i18n.MR
*/
class SaveImageNotifier(private val context: Context) {
private val notificationBuilder = context.notificationBuilder(Notifications.CHANNEL_COMMON)
private val notificationBuilder = context.notificationBuilder(Notifications.CHANNEL_COMMON) {
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
}
private val notificationId: Int = Notifications.ID_DOWNLOAD_IMAGE
/**
@ -52,6 +56,15 @@ class SaveImageNotifier(private val context: Context) {
context.cancelNotification(notificationId)
}
// KMK -->
/**
* Bitmap of the app for notifications.
*/
private val notificationBitmap by lazy {
BitmapFactory.decodeResource(context.resources, R.drawable.komikku)
}
// KMK <--
/**
* Called on error while downloading image.
* @param error string containing error information.
@ -59,6 +72,9 @@ class SaveImageNotifier(private val context: Context) {
fun onError(error: String?) {
// Create notification
with(notificationBuilder) {
// KMK -->
setLargeIcon(notificationBitmap)
// KMK <--
setContentTitle(context.stringResource(MR.strings.download_notifier_title_error))
setContentText(error ?: context.stringResource(MR.strings.unknown_error))
setSmallIcon(android.R.drawable.ic_menu_report_image)
@ -70,8 +86,17 @@ class SaveImageNotifier(private val context: Context) {
with(notificationBuilder) {
setContentTitle(context.stringResource(MR.strings.picture_saved))
setSmallIcon(R.drawable.ic_photo_24dp)
image?.let { setStyle(NotificationCompat.BigPictureStyle().bigPicture(it)) }
setLargeIcon(image)
image?.let {
setStyle(
NotificationCompat.BigPictureStyle()
// KMK -->
.bigLargeIcon(notificationBitmap)
.setBigContentTitle(context.stringResource(MR.strings.picture_saved))
// KMK <--
.bigPicture(it),
)
setLargeIcon(image)
}
setAutoCancel(true)
// Clear old actions if they exist

View file

@ -4,6 +4,7 @@ import android.content.Context
import android.graphics.BitmapFactory
import android.net.Uri
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
@ -32,7 +33,7 @@ class EHentaiUpdateNotifier(private val context: Context) {
* Bitmap of the app for notifications.
*/
private val notificationBitmap by lazy {
BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher)
BitmapFactory.decodeResource(context.resources, R.drawable.komikku)
}
/**
@ -42,6 +43,7 @@ class EHentaiUpdateNotifier(private val context: Context) {
context.notificationBuilder(Notifications.CHANNEL_LIBRARY_EHENTAI) {
setContentTitle(context.stringResource(MR.strings.app_name))
setSmallIcon(R.drawable.ic_refresh_24dp)
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
setLargeIcon(notificationBitmap)
setOngoing(true)
setOnlyAlertOnce(true)
@ -95,6 +97,8 @@ class EHentaiUpdateNotifier(private val context: Context) {
setContentTitle(context.stringResource(MR.strings.notification_update_error, failed))
setContentText(context.stringResource(MR.strings.action_show_errors))
setSmallIcon(R.drawable.ic_komikku)
setColor(ContextCompat.getColor(context, R.color.ic_launcher))
setLargeIcon(notificationBitmap)
setContentIntent(NotificationReceiver.openErrorLogPendingActivity(context, uri))
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher">#ff5555</color>
</resources>