feat(notifications): add branded monochrome icon and color to all notifications
Replace generic system icons (info bubble, stock alarm clock) with a custom equalizer-bars vector drawable across all 4 notification builders: pre-notice, snooze countdown, ringing alarm, and the audio player. Apply the app's cyan brand color to the 3 alarm notifications that previously had none. Audio notification now explicitly declares its icon instead of falling back to the full-color launcher icon, which Android was auto-silhouetting into an illegible status-bar blob.
This commit is contained in:
@@ -577,7 +577,8 @@ class AlarmScheduler(private val context: Context) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val notification = NotificationCompat.Builder(appContext, PluriWaveAlarmReceiver.CHANNEL_ID)
|
val notification = NotificationCompat.Builder(appContext, PluriWaveAlarmReceiver.CHANNEL_ID)
|
||||||
.setSmallIcon(android.R.drawable.ic_lock_idle_alarm)
|
.setSmallIcon(R.drawable.ic_stat_pluriwave)
|
||||||
|
.setColor(NotificationBrand.CYAN)
|
||||||
.setContentTitle(spec.title)
|
.setContentTitle(spec.title)
|
||||||
.setContentText(text)
|
.setContentText(text)
|
||||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package es.freetimelab.pluriwave
|
||||||
|
|
||||||
|
import androidx.annotation.ColorInt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared brand color for native notification icons.
|
||||||
|
*
|
||||||
|
* Single source of truth for the cyan tint applied via `NotificationCompat.Builder.setColor()`
|
||||||
|
* across all PluriWave alarm and audio notifications, mirroring the [AlarmNotificationStrings]
|
||||||
|
* shared-constants precedent.
|
||||||
|
*/
|
||||||
|
object NotificationBrand {
|
||||||
|
@ColorInt const val CYAN: Int = 0xFF21D4D9.toInt()
|
||||||
|
}
|
||||||
@@ -181,7 +181,8 @@ class PluriWaveAlarmReceiver : BroadcastReceiver() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
|
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
|
||||||
.setSmallIcon(android.R.drawable.ic_dialog_info)
|
.setSmallIcon(R.drawable.ic_stat_pluriwave)
|
||||||
|
.setColor(NotificationBrand.CYAN)
|
||||||
.setContentTitle(title)
|
.setContentTitle(title)
|
||||||
.setContentText(contentText)
|
.setContentText(contentText)
|
||||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||||
|
|||||||
@@ -387,7 +387,8 @@ class PluriWaveAlarmService : Service() {
|
|||||||
snoozeMinutes: Int
|
snoozeMinutes: Int
|
||||||
) =
|
) =
|
||||||
NotificationCompat.Builder(this, CHANNEL_ID)
|
NotificationCompat.Builder(this, CHANNEL_ID)
|
||||||
.setSmallIcon(android.R.drawable.ic_lock_idle_alarm)
|
.setSmallIcon(R.drawable.ic_stat_pluriwave)
|
||||||
|
.setColor(NotificationBrand.CYAN)
|
||||||
.setContentTitle(AlarmNotificationStrings.ringTitle(this))
|
.setContentTitle(AlarmNotificationStrings.ringTitle(this))
|
||||||
.setContentText(
|
.setContentText(
|
||||||
if (stationName.isNullOrBlank()) title else "$title - $stationName"
|
if (stationName.isNullOrBlank()) title else "$title - $stationName"
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
||||||
|
<path android:fillColor="#FFFFFF" android:pathData="M7,18h2L9,6L7,6v12zM3,14h2v-4L3,10v4zM11,20h2L13,4h-2v16zM19,10v4h2v-4h-2zM15,18h2L17,6h-2v12z" />
|
||||||
|
</vector>
|
||||||
@@ -12,6 +12,10 @@ import 'tema/pluriwave_tokens.dart';
|
|||||||
|
|
||||||
const _anchoMinimoLandscape = 600.0;
|
const _anchoMinimoLandscape = 600.0;
|
||||||
|
|
||||||
|
/// Branded monochrome status-bar icon, replacing the default full-color
|
||||||
|
/// launcher silhouette fallback.
|
||||||
|
const androidNotificationIconResource = 'drawable/ic_stat_pluriwave';
|
||||||
|
|
||||||
/// S5-R8: media notification accent uses the brand color, not the M3
|
/// S5-R8: media notification accent uses the brand color, not the M3
|
||||||
/// default purple. Top-level const so tests can assert it.
|
/// default purple. Top-level const so tests can assert it.
|
||||||
const configuracionAudioService = AudioServiceConfig(
|
const configuracionAudioService = AudioServiceConfig(
|
||||||
@@ -20,6 +24,7 @@ const configuracionAudioService = AudioServiceConfig(
|
|||||||
androidNotificationOngoing: true,
|
androidNotificationOngoing: true,
|
||||||
androidStopForegroundOnPause: true,
|
androidStopForegroundOnPause: true,
|
||||||
notificationColor: PluriWaveTokens.brand,
|
notificationColor: PluriWaveTokens.brand,
|
||||||
|
androidNotificationIcon: androidNotificationIconResource,
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
|
|||||||
@@ -13,4 +13,15 @@ void main() {
|
|||||||
isNot(const Color(0xFF6750A4)),
|
isNot(const Color(0xFF6750A4)),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('AudioServiceConfig usa el icono monocromo de marca', () {
|
||||||
|
expect(
|
||||||
|
configuracionAudioService.androidNotificationIcon,
|
||||||
|
'drawable/ic_stat_pluriwave',
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
configuracionAudioService.androidNotificationIcon,
|
||||||
|
isNot('mipmap/ic_launcher'),
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user