diff --git a/feature/notification/api/build.gradle.kts b/feature/notification/api/build.gradle.kts
index 71404a2198d..67b5e7687af 100644
--- a/feature/notification/api/build.gradle.kts
+++ b/feature/notification/api/build.gradle.kts
@@ -1,3 +1,5 @@
+import org.jetbrains.kotlin.gradle.internal.config.LanguageFeature
+
plugins {
id(ThunderbirdPlugins.Library.kmpCompose)
}
@@ -9,6 +11,10 @@ kotlin {
implementation(projects.core.outcome)
}
}
+
+ sourceSets.all {
+ languageSettings.enableLanguageFeature(LanguageFeature.ExpectActualClasses.name)
+ }
}
android {
diff --git a/feature/notification/api/src/androidMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/NotificationIcons.android.kt b/feature/notification/api/src/androidMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/NotificationIcons.android.kt
new file mode 100644
index 00000000000..6fdb31ad979
--- /dev/null
+++ b/feature/notification/api/src/androidMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/NotificationIcons.android.kt
@@ -0,0 +1,75 @@
+package net.thunderbird.feature.notification.api.ui.icon
+
+import net.thunderbird.feature.notification.api.R
+import net.thunderbird.feature.notification.api.ui.icon.atom.Notification
+import net.thunderbird.feature.notification.api.ui.icon.atom.Warning
+
+internal actual val NotificationIcons.AuthenticationError: NotificationIcon
+ get() = NotificationIcon(
+ systemNotificationIcon = R.drawable.ic_warning,
+ inAppNotificationIcon = Warning,
+ )
+
+internal actual val NotificationIcons.CertificateError: NotificationIcon
+ get() = NotificationIcon(
+ systemNotificationIcon = R.drawable.ic_warning,
+ inAppNotificationIcon = Warning,
+ )
+
+internal actual val NotificationIcons.FailedToCreate: NotificationIcon
+ get() = NotificationIcon(
+ systemNotificationIcon = R.drawable.ic_warning,
+ inAppNotificationIcon = Warning,
+ )
+
+internal actual val NotificationIcons.MailFetching: NotificationIcon
+ get() = NotificationIcon(
+ systemNotificationIcon = R.drawable.ic_sync_animated,
+ )
+
+internal actual val NotificationIcons.MailSending: NotificationIcon
+ get() = NotificationIcon(
+ systemNotificationIcon = R.drawable.ic_sync_animated,
+ )
+
+internal actual val NotificationIcons.MailSendFailed: NotificationIcon
+ get() = NotificationIcon(
+ systemNotificationIcon = R.drawable.ic_warning,
+ inAppNotificationIcon = Warning,
+ )
+
+internal actual val NotificationIcons.NewMailSingleMail: NotificationIcon
+ get() = NotificationIcon(
+ systemNotificationIcon = R.drawable.ic_new_email,
+ )
+
+internal actual val NotificationIcons.NewMailSummaryMail: NotificationIcon
+ get() = NotificationIcon(
+ systemNotificationIcon = R.drawable.ic_new_email,
+ )
+
+internal actual val NotificationIcons.PushServiceInitializing: NotificationIcon
+ get() = NotificationIcon(
+ systemNotificationIcon = R.drawable.ic_notification,
+ )
+
+internal actual val NotificationIcons.PushServiceListening: NotificationIcon
+ get() = NotificationIcon(
+ systemNotificationIcon = R.drawable.ic_notification,
+ )
+
+internal actual val NotificationIcons.PushServiceWaitBackgroundSync: NotificationIcon
+ get() = NotificationIcon(
+ systemNotificationIcon = R.drawable.ic_notification,
+ )
+
+internal actual val NotificationIcons.PushServiceWaitNetwork: NotificationIcon
+ get() = NotificationIcon(
+ systemNotificationIcon = R.drawable.ic_notification,
+ )
+
+internal actual val NotificationIcons.AlarmPermissionMissing: NotificationIcon
+ get() = NotificationIcon(
+ systemNotificationIcon = R.drawable.ic_notification,
+ inAppNotificationIcon = Notification,
+ )
diff --git a/feature/notification/api/src/androidMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/SystemNotificationIcon.android.kt b/feature/notification/api/src/androidMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/SystemNotificationIcon.android.kt
new file mode 100644
index 00000000000..9b05b039eff
--- /dev/null
+++ b/feature/notification/api/src/androidMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/SystemNotificationIcon.android.kt
@@ -0,0 +1,3 @@
+package net.thunderbird.feature.notification.api.ui.icon
+
+actual typealias SystemNotificationIcon = Int
diff --git a/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_0.png b/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_0.png
new file mode 100644
index 00000000000..837495c235e
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_0.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_1.png b/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_1.png
new file mode 100644
index 00000000000..6db06a75c76
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_1.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_2.png b/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_2.png
new file mode 100644
index 00000000000..d27b881a7b9
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_2.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_3.png b/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_3.png
new file mode 100644
index 00000000000..2d5837622f6
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_3.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_4.png b/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_4.png
new file mode 100644
index 00000000000..cc8891de58c
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_4.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_5.png b/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_5.png
new file mode 100644
index 00000000000..396582de5c6
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-hdpi/notification_icon_check_mail_anim_5.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_0.png b/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_0.png
new file mode 100644
index 00000000000..a8ea61f4eec
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_0.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_1.png b/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_1.png
new file mode 100644
index 00000000000..7dc44ba1934
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_1.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_2.png b/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_2.png
new file mode 100644
index 00000000000..c05e17a4ea8
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_2.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_3.png b/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_3.png
new file mode 100644
index 00000000000..93f0ea1c034
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_3.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_4.png b/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_4.png
new file mode 100644
index 00000000000..2ab90799e5a
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_4.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_5.png b/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_5.png
new file mode 100644
index 00000000000..f2b77f4eed8
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-mdpi/notification_icon_check_mail_anim_5.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_0.png b/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_0.png
new file mode 100644
index 00000000000..aa48274d0d0
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_0.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_1.png b/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_1.png
new file mode 100644
index 00000000000..de8b57e1823
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_1.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_2.png b/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_2.png
new file mode 100644
index 00000000000..a9d28b9ff6b
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_2.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_3.png b/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_3.png
new file mode 100644
index 00000000000..5212e3bfdf5
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_3.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_4.png b/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_4.png
new file mode 100644
index 00000000000..9c3dbdd5b84
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_4.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_5.png b/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_5.png
new file mode 100644
index 00000000000..3a4557820c1
Binary files /dev/null and b/feature/notification/api/src/androidMain/res/drawable-xhdpi/notification_icon_check_mail_anim_5.png differ
diff --git a/feature/notification/api/src/androidMain/res/drawable/ic_archive.xml b/feature/notification/api/src/androidMain/res/drawable/ic_archive.xml
new file mode 100644
index 00000000000..cff1ed18e49
--- /dev/null
+++ b/feature/notification/api/src/androidMain/res/drawable/ic_archive.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/feature/notification/api/src/androidMain/res/drawable/ic_delete.xml b/feature/notification/api/src/androidMain/res/drawable/ic_delete.xml
new file mode 100644
index 00000000000..9102cf11eb9
--- /dev/null
+++ b/feature/notification/api/src/androidMain/res/drawable/ic_delete.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/feature/notification/api/src/androidMain/res/drawable/ic_mark_email_read.xml b/feature/notification/api/src/androidMain/res/drawable/ic_mark_email_read.xml
new file mode 100644
index 00000000000..96fb7e36af8
--- /dev/null
+++ b/feature/notification/api/src/androidMain/res/drawable/ic_mark_email_read.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/feature/notification/api/src/androidMain/res/drawable/ic_new_email.xml b/feature/notification/api/src/androidMain/res/drawable/ic_new_email.xml
new file mode 100644
index 00000000000..39bced6ef3d
--- /dev/null
+++ b/feature/notification/api/src/androidMain/res/drawable/ic_new_email.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/feature/notification/api/src/androidMain/res/drawable/ic_notification.xml b/feature/notification/api/src/androidMain/res/drawable/ic_notification.xml
new file mode 100644
index 00000000000..eb14b87e968
--- /dev/null
+++ b/feature/notification/api/src/androidMain/res/drawable/ic_notification.xml
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/feature/notification/api/src/androidMain/res/drawable/ic_refresh.xml b/feature/notification/api/src/androidMain/res/drawable/ic_refresh.xml
new file mode 100644
index 00000000000..5a0f23ae303
--- /dev/null
+++ b/feature/notification/api/src/androidMain/res/drawable/ic_refresh.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/feature/notification/api/src/androidMain/res/drawable/ic_reply.xml b/feature/notification/api/src/androidMain/res/drawable/ic_reply.xml
new file mode 100644
index 00000000000..ace979916ce
--- /dev/null
+++ b/feature/notification/api/src/androidMain/res/drawable/ic_reply.xml
@@ -0,0 +1,14 @@
+
+
+
diff --git a/feature/notification/api/src/androidMain/res/drawable/ic_report.xml b/feature/notification/api/src/androidMain/res/drawable/ic_report.xml
new file mode 100644
index 00000000000..4bb9c95a395
--- /dev/null
+++ b/feature/notification/api/src/androidMain/res/drawable/ic_report.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/feature/notification/api/src/androidMain/res/drawable/ic_settings.xml b/feature/notification/api/src/androidMain/res/drawable/ic_settings.xml
new file mode 100644
index 00000000000..66954d3f97f
--- /dev/null
+++ b/feature/notification/api/src/androidMain/res/drawable/ic_settings.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/feature/notification/api/src/androidMain/res/drawable/ic_sync_animated.xml b/feature/notification/api/src/androidMain/res/drawable/ic_sync_animated.xml
new file mode 100644
index 00000000000..51302173b4f
--- /dev/null
+++ b/feature/notification/api/src/androidMain/res/drawable/ic_sync_animated.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/feature/notification/api/src/androidMain/res/drawable/ic_warning.xml b/feature/notification/api/src/androidMain/res/drawable/ic_warning.xml
new file mode 100644
index 00000000000..faf88abe7cf
--- /dev/null
+++ b/feature/notification/api/src/androidMain/res/drawable/ic_warning.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/AppNotification.kt b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/AppNotification.kt
index 85b119853b8..431f63b18c7 100644
--- a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/AppNotification.kt
+++ b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/AppNotification.kt
@@ -11,6 +11,7 @@ import net.thunderbird.feature.notification.api.NotificationGroup
import net.thunderbird.feature.notification.api.NotificationId
import net.thunderbird.feature.notification.api.NotificationSeverity
import net.thunderbird.feature.notification.api.ui.action.NotificationAction
+import net.thunderbird.feature.notification.api.ui.icon.NotificationIcon
/**
* Represents a notification that can be displayed to the user.
@@ -28,6 +29,7 @@ import net.thunderbird.feature.notification.api.ui.action.NotificationAction
* @property authenticationRequired Indicates whether authentication is required to view the notification.
* @property channel The notification channel to which this notification belongs.
* @property group The notification group to which this notification belongs, can be null.
+ * @property icon The notification icon.
* @see AppNotification
*/
sealed interface Notification {
@@ -41,6 +43,7 @@ sealed interface Notification {
val authenticationRequired: Boolean
val channel: NotificationChannel
val group: NotificationGroup?
+ val icon: NotificationIcon
}
/**
diff --git a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/AuthenticationErrorNotification.kt b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/AuthenticationErrorNotification.kt
index 5812fb8262d..35153a008aa 100644
--- a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/AuthenticationErrorNotification.kt
+++ b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/AuthenticationErrorNotification.kt
@@ -4,6 +4,9 @@ import net.thunderbird.feature.notification.api.NotificationChannel
import net.thunderbird.feature.notification.api.NotificationId
import net.thunderbird.feature.notification.api.NotificationSeverity
import net.thunderbird.feature.notification.api.ui.action.NotificationAction
+import net.thunderbird.feature.notification.api.ui.icon.AuthenticationError
+import net.thunderbird.feature.notification.api.ui.icon.NotificationIcon
+import net.thunderbird.feature.notification.api.ui.icon.NotificationIcons
import net.thunderbird.feature.notification.resources.api.Res
import net.thunderbird.feature.notification.resources.api.notification_authentication_error_text
import net.thunderbird.feature.notification.resources.api.notification_authentication_error_title
@@ -20,6 +23,7 @@ data class AuthenticationErrorNotification private constructor(
override val title: String,
override val contentText: String?,
override val channel: NotificationChannel,
+ override val icon: NotificationIcon = NotificationIcons.AuthenticationError,
) : AppNotification(), SystemNotification, InAppNotification {
override val severity: NotificationSeverity = NotificationSeverity.Fatal
override val actions: Set = setOf(
diff --git a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/CertificateErrorNotification.kt b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/CertificateErrorNotification.kt
index ebec693fed8..4133df03072 100644
--- a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/CertificateErrorNotification.kt
+++ b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/CertificateErrorNotification.kt
@@ -4,6 +4,9 @@ import net.thunderbird.feature.notification.api.NotificationChannel
import net.thunderbird.feature.notification.api.NotificationId
import net.thunderbird.feature.notification.api.NotificationSeverity
import net.thunderbird.feature.notification.api.ui.action.NotificationAction
+import net.thunderbird.feature.notification.api.ui.icon.CertificateError
+import net.thunderbird.feature.notification.api.ui.icon.NotificationIcon
+import net.thunderbird.feature.notification.api.ui.icon.NotificationIcons
import net.thunderbird.feature.notification.resources.api.Res
import net.thunderbird.feature.notification.resources.api.notification_certificate_error_public
import net.thunderbird.feature.notification.resources.api.notification_certificate_error_text
@@ -22,6 +25,7 @@ data class CertificateErrorNotification private constructor(
override val contentText: String,
val lockScreenTitle: String,
override val channel: NotificationChannel,
+ override val icon: NotificationIcon = NotificationIcons.CertificateError,
) : AppNotification(), SystemNotification, InAppNotification {
override val severity: NotificationSeverity = NotificationSeverity.Fatal
override val actions: Set = setOf(NotificationAction.UpdateServerSettings)
diff --git a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/FailedToCreateNotification.kt b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/FailedToCreateNotification.kt
index 264f1e9a5a1..01591e3fae6 100644
--- a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/FailedToCreateNotification.kt
+++ b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/FailedToCreateNotification.kt
@@ -3,6 +3,9 @@ package net.thunderbird.feature.notification.api.content
import net.thunderbird.feature.notification.api.NotificationChannel
import net.thunderbird.feature.notification.api.NotificationId
import net.thunderbird.feature.notification.api.NotificationSeverity
+import net.thunderbird.feature.notification.api.ui.icon.FailedToCreate
+import net.thunderbird.feature.notification.api.ui.icon.NotificationIcon
+import net.thunderbird.feature.notification.api.ui.icon.NotificationIcons
import net.thunderbird.feature.notification.resources.api.Res
import net.thunderbird.feature.notification.resources.api.notification_notify_error_text
import net.thunderbird.feature.notification.resources.api.notification_notify_error_title
@@ -21,6 +24,7 @@ data class FailedToCreateNotification private constructor(
override val contentText: String?,
override val channel: NotificationChannel,
val failedNotification: AppNotification,
+ override val icon: NotificationIcon = NotificationIcons.FailedToCreate,
) : AppNotification(), SystemNotification, InAppNotification {
override val severity: NotificationSeverity = NotificationSeverity.Critical
diff --git a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/MailNotification.kt b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/MailNotification.kt
index c9429f75526..0ae67e180a8 100644
--- a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/MailNotification.kt
+++ b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/MailNotification.kt
@@ -6,6 +6,13 @@ import net.thunderbird.feature.notification.api.NotificationGroup
import net.thunderbird.feature.notification.api.NotificationId
import net.thunderbird.feature.notification.api.NotificationSeverity
import net.thunderbird.feature.notification.api.ui.action.NotificationAction
+import net.thunderbird.feature.notification.api.ui.icon.MailFetching
+import net.thunderbird.feature.notification.api.ui.icon.MailSendFailed
+import net.thunderbird.feature.notification.api.ui.icon.MailSending
+import net.thunderbird.feature.notification.api.ui.icon.NewMailSingleMail
+import net.thunderbird.feature.notification.api.ui.icon.NewMailSummaryMail
+import net.thunderbird.feature.notification.api.ui.icon.NotificationIcon
+import net.thunderbird.feature.notification.api.ui.icon.NotificationIcons
import net.thunderbird.feature.notification.resources.api.Res
import net.thunderbird.feature.notification.resources.api.notification_additional_messages
import net.thunderbird.feature.notification.resources.api.notification_bg_send_ticker
@@ -32,6 +39,7 @@ sealed class MailNotification : AppNotification(), SystemNotification {
override val accessibilityText: String,
override val contentText: String?,
override val channel: NotificationChannel,
+ override val icon: NotificationIcon = NotificationIcons.MailFetching,
) : MailNotification() {
override val lockscreenNotification: SystemNotification get() = copy(contentText = null)
@@ -81,6 +89,7 @@ sealed class MailNotification : AppNotification(), SystemNotification {
override val accessibilityText: String,
override val contentText: String?,
override val channel: NotificationChannel,
+ override val icon: NotificationIcon = NotificationIcons.MailSending,
) : MailNotification() {
override val lockscreenNotification: SystemNotification get() = copy(contentText = null)
@@ -115,6 +124,7 @@ sealed class MailNotification : AppNotification(), SystemNotification {
override val title: String,
override val contentText: String?,
override val channel: NotificationChannel,
+ override val icon: NotificationIcon = NotificationIcons.MailSendFailed,
) : MailNotification(), InAppNotification {
override val severity: NotificationSeverity = NotificationSeverity.Critical
override val lockscreenNotification: SystemNotification get() = copy(contentText = null)
@@ -193,6 +203,7 @@ sealed class MailNotification : AppNotification(), SystemNotification {
val subject: String,
val preview: String,
override val group: NotificationGroup?,
+ override val icon: NotificationIcon = NotificationIcons.NewMailSingleMail,
) : NewMail() {
override val title: String = sender
override val contentText: String = subject
@@ -218,6 +229,7 @@ sealed class MailNotification : AppNotification(), SystemNotification {
override val title: String,
override val contentText: String?,
override val group: NotificationGroup,
+ override val icon: NotificationIcon = NotificationIcons.NewMailSummaryMail,
) : NewMail() {
companion object {
/**
diff --git a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/PushServiceNotification.kt b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/PushServiceNotification.kt
index a84c5c68565..df5ca85feaf 100644
--- a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/PushServiceNotification.kt
+++ b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/PushServiceNotification.kt
@@ -4,6 +4,13 @@ import net.thunderbird.feature.notification.api.NotificationChannel
import net.thunderbird.feature.notification.api.NotificationId
import net.thunderbird.feature.notification.api.NotificationSeverity
import net.thunderbird.feature.notification.api.ui.action.NotificationAction
+import net.thunderbird.feature.notification.api.ui.icon.AlarmPermissionMissing
+import net.thunderbird.feature.notification.api.ui.icon.NotificationIcon
+import net.thunderbird.feature.notification.api.ui.icon.NotificationIcons
+import net.thunderbird.feature.notification.api.ui.icon.PushServiceInitializing
+import net.thunderbird.feature.notification.api.ui.icon.PushServiceListening
+import net.thunderbird.feature.notification.api.ui.icon.PushServiceWaitBackgroundSync
+import net.thunderbird.feature.notification.api.ui.icon.PushServiceWaitNetwork
import net.thunderbird.feature.notification.resources.api.Res
import net.thunderbird.feature.notification.resources.api.push_info_disable_push_action
import net.thunderbird.feature.notification.resources.api.push_notification_grant_alarm_permission
@@ -33,6 +40,7 @@ sealed class PushServiceNotification : AppNotification(), SystemNotification {
override val title: String,
override val contentText: String?,
override val actions: Set,
+ override val icon: NotificationIcon = NotificationIcons.PushServiceInitializing,
) : PushServiceNotification() {
companion object {
/**
@@ -60,6 +68,7 @@ sealed class PushServiceNotification : AppNotification(), SystemNotification {
override val title: String,
override val contentText: String?,
override val actions: Set,
+ override val icon: NotificationIcon = NotificationIcons.PushServiceListening,
) : PushServiceNotification() {
companion object {
/**
@@ -87,6 +96,7 @@ sealed class PushServiceNotification : AppNotification(), SystemNotification {
override val title: String,
override val contentText: String?,
override val actions: Set,
+ override val icon: NotificationIcon = NotificationIcons.PushServiceWaitBackgroundSync,
) : PushServiceNotification() {
companion object {
/**
@@ -114,6 +124,7 @@ sealed class PushServiceNotification : AppNotification(), SystemNotification {
override val title: String,
override val contentText: String?,
override val actions: Set,
+ override val icon: NotificationIcon = NotificationIcons.PushServiceWaitNetwork,
) : PushServiceNotification() {
companion object {
/**
@@ -144,6 +155,7 @@ sealed class PushServiceNotification : AppNotification(), SystemNotification {
override val id: NotificationId,
override val title: String,
override val contentText: String?,
+ override val icon: NotificationIcon = NotificationIcons.AlarmPermissionMissing,
) : PushServiceNotification(), InAppNotification {
override val severity: NotificationSeverity = NotificationSeverity.Critical
diff --git a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/NotificationIcon.kt b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/NotificationIcon.kt
new file mode 100644
index 00000000000..6280242d575
--- /dev/null
+++ b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/NotificationIcon.kt
@@ -0,0 +1,25 @@
+package net.thunderbird.feature.notification.api.ui.icon
+
+import androidx.compose.ui.graphics.vector.ImageVector
+
+/**
+ * Represents the icon to be displayed for a notification.
+ *
+ * This class allows specifying different icons for system notifications and in-app notifications.
+ * At least one type of icon must be provided.
+ *
+ * @property systemNotificationIcon The icon to be used for system notifications.
+ * @property inAppNotificationIcon The icon to be used for in-app notifications.
+ */
+data class NotificationIcon(
+ private val systemNotificationIcon: SystemNotificationIcon? = null,
+ private val inAppNotificationIcon: ImageVector? = null,
+) {
+
+ init {
+ check(systemNotificationIcon != null || inAppNotificationIcon != null) {
+ "Both systemNotificationIcon and inAppNotificationIcon are null. " +
+ "You must specify at least one type of icon."
+ }
+ }
+}
diff --git a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/NotificationIcons.kt b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/NotificationIcons.kt
new file mode 100644
index 00000000000..2d7cac73b20
--- /dev/null
+++ b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/NotificationIcons.kt
@@ -0,0 +1,101 @@
+package net.thunderbird.feature.notification.api.ui.icon
+
+/**
+ * Represents a set of icons specifically designed for notifications within the application.
+ *
+ * This object serves as a namespace for various notification icons, allowing for easy access
+ * and organization of these visual assets. Each property within this object is expected to
+ * represent a specific notification icon.
+ */
+internal object NotificationIcons
+
+/**
+ * Represents the icon for authentication error notifications.
+ *
+ * @see net.thunderbird.feature.notification.api.content.AuthenticationErrorNotification
+ */
+internal expect val NotificationIcons.AuthenticationError: NotificationIcon
+
+/**
+ * Represents the icon for the "Certificate Error" notification.
+ *
+ * @see net.thunderbird.feature.notification.api.content.CertificateErrorNotification
+ */
+internal expect val NotificationIcons.CertificateError: NotificationIcon
+
+/**
+ * Represents the icon for the "Failed To Create notification" notification.
+ *
+ * @see net.thunderbird.feature.notification.api.content.FailedToCreateNotification
+ */
+internal expect val NotificationIcons.FailedToCreate: NotificationIcon
+
+/**
+ * Represents the icon for the "Mail Fetching" notification.
+ *
+ * @see net.thunderbird.feature.notification.api.content.MailNotification.Fetching
+ */
+internal expect val NotificationIcons.MailFetching: NotificationIcon
+
+/**
+ * Represents the icon for the "Mail Sending" notification.
+ *
+ * @see net.thunderbird.feature.notification.api.content.MailNotification.Sending
+ */
+internal expect val NotificationIcons.MailSending: NotificationIcon
+
+/**
+ * Represents the icon for the "Mail Send Failed" notification.
+ *
+ * @see net.thunderbird.feature.notification.api.content.MailNotification.SendFailed
+ */
+internal expect val NotificationIcons.MailSendFailed: NotificationIcon
+
+/**
+ * Represents the icon for the "New Mail (Single)" notification.
+ *
+ * @see net.thunderbird.feature.notification.api.content.MailNotification.NewMail.SingleMail
+ */
+internal expect val NotificationIcons.NewMailSingleMail: NotificationIcon
+
+/**
+ * Represents the icon for the "New Mail Summary" notification.
+ *
+ * @see net.thunderbird.feature.notification.api.content.MailNotification.NewMail.SummaryMail
+ */
+internal expect val NotificationIcons.NewMailSummaryMail: NotificationIcon
+
+/**
+ * Represents the icon for the "Push Service Initializing" notification.
+ *
+ * @see net.thunderbird.feature.notification.api.content.PushServiceNotification.Initializing
+ */
+internal expect val NotificationIcons.PushServiceInitializing: NotificationIcon
+
+/**
+ * Represents the icon for the "Push Service Listening" notification.
+ *
+ * @see net.thunderbird.feature.notification.api.content.PushServiceNotification.Listening
+ */
+internal expect val NotificationIcons.PushServiceListening: NotificationIcon
+
+/**
+ * Represents the icon for the "Push Service Wait Background Sync" notification.
+ *
+ * @see net.thunderbird.feature.notification.api.content.PushServiceNotification.WaitBackgroundSync
+ */
+internal expect val NotificationIcons.PushServiceWaitBackgroundSync: NotificationIcon
+
+/**
+ * Represents the icon for the "Push Service Wait Network" notification.
+ *
+ * @see net.thunderbird.feature.notification.api.content.PushServiceNotification.WaitNetwork
+ */
+internal expect val NotificationIcons.PushServiceWaitNetwork: NotificationIcon
+
+/**
+ * Represents the icon for the "Alarm Permission Missing" notification.
+ *
+ * @see net.thunderbird.feature.notification.api.content.PushServiceNotification.AlarmPermissionMissing
+ */
+internal expect val NotificationIcons.AlarmPermissionMissing: NotificationIcon
diff --git a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/SystemNotificationIcon.kt b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/SystemNotificationIcon.kt
new file mode 100644
index 00000000000..dca7f88cabf
--- /dev/null
+++ b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/SystemNotificationIcon.kt
@@ -0,0 +1,10 @@
+package net.thunderbird.feature.notification.api.ui.icon
+
+/**
+ * Represents an icon for a system notification.
+ *
+ * This is an expect class, meaning its actual implementation is provided by platform-specific modules.
+ * On Android, this would typically wrap a drawable resource ID.
+ * On other platforms, it might represent a file path or another platform-specific icon identifier.
+ */
+expect class SystemNotificationIcon
diff --git a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/atom/NewEmail.kt b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/atom/NewEmail.kt
new file mode 100644
index 00000000000..3822f0fe308
--- /dev/null
+++ b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/atom/NewEmail.kt
@@ -0,0 +1,85 @@
+package net.thunderbird.feature.notification.api.ui.icon.atom
+
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.graphics.vector.path
+import androidx.compose.ui.unit.dp
+
+@Suppress("MagicNumber", "MaxLineLength")
+internal val NewEmail: ImageVector
+ get() {
+ val current = _newEmail
+ if (current != null) return current
+
+ return ImageVector.Builder(
+ name = "net.thunderbird.feature.notification.api.ui.icon.atom.NewEmail",
+ defaultWidth = 24.0.dp,
+ defaultHeight = 24.0.dp,
+ viewportWidth = 960.0f,
+ viewportHeight = 960.0f,
+ ).apply {
+ path(
+ fill = SolidColor(Color(0xFFFFFFFF)),
+ ) {
+ moveTo(x = 160.0f, y = 800.0f)
+ quadTo(x1 = 127.0f, y1 = 800.0f, x2 = 103.5f, y2 = 776.5f)
+ quadTo(x1 = 80.0f, y1 = 753.0f, x2 = 80.0f, y2 = 720.0f)
+ lineTo(x = 80.0f, y = 240.0f)
+ quadTo(x1 = 80.0f, y1 = 207.0f, x2 = 103.5f, y2 = 183.5f)
+ quadTo(x1 = 127.0f, y1 = 160.0f, x2 = 160.0f, y2 = 160.0f)
+ lineTo(x = 564.0f, y = 160.0f)
+ quadTo(x1 = 560.0f, y1 = 180.0f, x2 = 560.0f, y2 = 200.0f)
+ quadTo(x1 = 560.0f, y1 = 220.0f, x2 = 564.0f, y2 = 240.0f)
+ lineTo(x = 160.0f, y = 240.0f)
+ lineTo(x = 480.0f, y = 440.0f)
+ lineTo(x = 626.0f, y = 349.0f)
+ quadTo(x1 = 640.0f, y1 = 362.0f, x2 = 656.5f, y2 = 371.5f)
+ quadTo(x1 = 673.0f, y1 = 381.0f, x2 = 691.0f, y2 = 388.0f)
+ lineTo(x = 480.0f, y = 520.0f)
+ lineTo(x = 160.0f, y = 320.0f)
+ lineTo(x = 160.0f, y = 720.0f)
+ quadTo(x1 = 160.0f, y1 = 720.0f, x2 = 160.0f, y2 = 720.0f)
+ quadTo(x1 = 160.0f, y1 = 720.0f, x2 = 160.0f, y2 = 720.0f)
+ lineTo(x = 800.0f, y = 720.0f)
+ quadTo(x1 = 800.0f, y1 = 720.0f, x2 = 800.0f, y2 = 720.0f)
+ quadTo(x1 = 800.0f, y1 = 720.0f, x2 = 800.0f, y2 = 720.0f)
+ lineTo(x = 800.0f, y = 396.0f)
+ quadTo(x1 = 823.0f, y1 = 391.0f, x2 = 843.0f, y2 = 382.0f)
+ quadTo(x1 = 863.0f, y1 = 373.0f, x2 = 880.0f, y2 = 360.0f)
+ lineTo(x = 880.0f, y = 720.0f)
+ quadTo(x1 = 880.0f, y1 = 753.0f, x2 = 856.5f, y2 = 776.5f)
+ quadTo(x1 = 833.0f, y1 = 800.0f, x2 = 800.0f, y2 = 800.0f)
+ lineTo(x = 160.0f, y = 800.0f)
+ close()
+ moveTo(x = 160.0f, y = 240.0f)
+ lineTo(x = 160.0f, y = 240.0f)
+ lineTo(x = 160.0f, y = 240.0f)
+ lineTo(x = 160.0f, y = 720.0f)
+ quadTo(x1 = 160.0f, y1 = 720.0f, x2 = 160.0f, y2 = 720.0f)
+ quadTo(x1 = 160.0f, y1 = 720.0f, x2 = 160.0f, y2 = 720.0f)
+ lineTo(x = 160.0f, y = 720.0f)
+ quadTo(x1 = 160.0f, y1 = 720.0f, x2 = 160.0f, y2 = 720.0f)
+ quadTo(x1 = 160.0f, y1 = 720.0f, x2 = 160.0f, y2 = 720.0f)
+ lineTo(x = 160.0f, y = 240.0f)
+ quadTo(x1 = 160.0f, y1 = 240.0f, x2 = 160.0f, y2 = 240.0f)
+ quadTo(x1 = 160.0f, y1 = 240.0f, x2 = 160.0f, y2 = 240.0f)
+ quadTo(x1 = 160.0f, y1 = 240.0f, x2 = 160.0f, y2 = 240.0f)
+ quadTo(x1 = 160.0f, y1 = 240.0f, x2 = 160.0f, y2 = 240.0f)
+ close()
+ moveTo(x = 760.0f, y = 320.0f)
+ quadTo(x1 = 710.0f, y1 = 320.0f, x2 = 675.0f, y2 = 285.0f)
+ quadTo(x1 = 640.0f, y1 = 250.0f, x2 = 640.0f, y2 = 200.0f)
+ quadTo(x1 = 640.0f, y1 = 150.0f, x2 = 675.0f, y2 = 115.0f)
+ quadTo(x1 = 710.0f, y1 = 80.0f, x2 = 760.0f, y2 = 80.0f)
+ quadTo(x1 = 810.0f, y1 = 80.0f, x2 = 845.0f, y2 = 115.0f)
+ quadTo(x1 = 880.0f, y1 = 150.0f, x2 = 880.0f, y2 = 200.0f)
+ quadTo(x1 = 880.0f, y1 = 250.0f, x2 = 845.0f, y2 = 285.0f)
+ quadTo(x1 = 810.0f, y1 = 320.0f, x2 = 760.0f, y2 = 320.0f)
+ close()
+ }
+ }.build().also { _newEmail = it }
+ }
+
+@Suppress("ObjectPropertyName")
+private var _newEmail: ImageVector? = null
diff --git a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/atom/Notification.kt b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/atom/Notification.kt
new file mode 100644
index 00000000000..fa8a0f2bfc0
--- /dev/null
+++ b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/atom/Notification.kt
@@ -0,0 +1,105 @@
+package net.thunderbird.feature.notification.api.ui.icon.atom
+
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.graphics.vector.path
+import androidx.compose.ui.unit.dp
+
+@Suppress("MagicNumber", "MaxLineLength")
+internal val Notification: ImageVector
+ get() {
+ val current = _notification
+ if (current != null) return current
+
+ return ImageVector.Builder(
+ name = "net.thunderbird.feature.notification.api.ui.icon.atom.Notification",
+ defaultWidth = 24.0.dp,
+ defaultHeight = 24.0.dp,
+ viewportWidth = 24.0f,
+ viewportHeight = 24.0f,
+ ).apply {
+ path(
+ fill = SolidColor(Color(0xFF1A202C)),
+ fillAlpha = 0.2f,
+ strokeAlpha = 0.2f,
+ ) {
+ moveTo(x = 12.0f, y = 3.5f)
+ curveTo(x1 = 8.953f, y1 = 3.5f, x2 = 6.5f, y2 = 5.953f, x3 = 6.5f, y3 = 9.0f)
+ verticalLineTo(y = 12.0f)
+ verticalLineTo(y = 13.5f)
+ curveTo(x1 = 5.392f, y1 = 13.5f, x2 = 4.5f, y2 = 14.392f, x3 = 4.5f, y3 = 15.5f)
+ verticalLineTo(y = 17.0f)
+ curveTo(x1 = 4.5f, y1 = 17.277f, x2 = 4.723f, y2 = 17.5f, x3 = 5.0f, y3 = 17.5f)
+ horizontalLineTo(x = 6.5f)
+ horizontalLineTo(x = 7.0f)
+ horizontalLineTo(x = 17.0f)
+ horizontalLineTo(x = 17.5f)
+ horizontalLineTo(x = 19.0f)
+ curveTo(x1 = 19.277f, y1 = 17.5f, x2 = 19.5f, y2 = 17.277f, x3 = 19.5f, y3 = 17.0f)
+ verticalLineTo(y = 15.5f)
+ curveTo(x1 = 19.5f, y1 = 14.392f, x2 = 18.608f, y2 = 13.5f, x3 = 17.5f, y3 = 13.5f)
+ verticalLineTo(y = 10.5f)
+ verticalLineTo(y = 9.0f)
+ curveTo(x1 = 17.5f, y1 = 5.953f, x2 = 15.047f, y2 = 3.5f, x3 = 12.0f, y3 = 3.5f)
+ close()
+ }
+ path(
+ fill = SolidColor(Color(0xFF1A202C)),
+ ) {
+ moveTo(x = 12.0f, y = 3.0f)
+ curveTo(x1 = 8.68466f, y1 = 3.0f, x2 = 6.0f, y2 = 5.68465f, x3 = 6.0f, y3 = 9.0f)
+ verticalLineTo(y = 12.0f)
+ verticalLineTo(y = 13.207f)
+ curveTo(x1 = 4.89477f, y1 = 13.4651f, x2 = 4.0f, y2 = 14.3184f, x3 = 4.0f, y3 = 15.5f)
+ verticalLineTo(y = 17.0f)
+ curveTo(x1 = 4.0f, y1 = 17.5454f, x2 = 4.45465f, y2 = 18.0f, x3 = 5.0f, y3 = 18.0f)
+ horizontalLineTo(x = 6.5f)
+ horizontalLineTo(x = 7.0f)
+ horizontalLineTo(x = 9.0f)
+ curveTo(x1 = 9.0f, y1 = 19.6534f, x2 = 10.3467f, y2 = 21.0f, x3 = 12.0f, y3 = 21.0f)
+ curveTo(x1 = 13.6533f, y1 = 21.0f, x2 = 15.0f, y2 = 19.6534f, x3 = 15.0f, y3 = 18.0f)
+ horizontalLineTo(x = 17.0f)
+ horizontalLineTo(x = 17.5f)
+ horizontalLineTo(x = 19.0f)
+ curveTo(x1 = 19.5454f, y1 = 18.0f, x2 = 20.0f, y2 = 17.5454f, x3 = 20.0f, y3 = 17.0f)
+ verticalLineTo(y = 15.5f)
+ curveTo(x1 = 20.0f, y1 = 14.3184f, x2 = 19.1052f, y2 = 13.4651f, x3 = 18.0f, y3 = 13.207f)
+ verticalLineTo(y = 10.5f)
+ verticalLineTo(y = 9.0f)
+ curveTo(x1 = 18.0f, y1 = 5.68465f, x2 = 15.3153f, y2 = 3.0f, x3 = 12.0f, y3 = 3.0f)
+ close()
+ moveTo(x = 12.0f, y = 4.0f)
+ curveTo(x1 = 14.7786f, y1 = 4.0f, x2 = 17.0f, y2 = 6.22136f, x3 = 17.0f, y3 = 9.0f)
+ verticalLineTo(y = 10.5f)
+ verticalLineTo(y = 13.5f)
+ curveTo(x1 = 17.0f, y1 = 13.6326f, x2 = 17.0527f, y2 = 13.7598f, x3 = 17.1465f, y3 = 13.8535f)
+ curveTo(x1 = 17.2402f, y1 = 13.9473f, x2 = 17.3674f, y2 = 14.0f, x3 = 17.5f, y3 = 14.0f)
+ curveTo(x1 = 18.3396f, y1 = 14.0f, x2 = 19.0f, y2 = 14.6603f, x3 = 19.0f, y3 = 15.5f)
+ verticalLineTo(y = 17.0f)
+ horizontalLineTo(x = 17.5f)
+ horizontalLineTo(x = 17.0f)
+ horizontalLineTo(x = 14.5f)
+ horizontalLineTo(x = 9.5f)
+ horizontalLineTo(x = 7.0f)
+ horizontalLineTo(x = 6.5f)
+ horizontalLineTo(x = 5.0f)
+ verticalLineTo(y = 15.5f)
+ curveTo(x1 = 5.0f, y1 = 14.6603f, x2 = 5.66036f, y2 = 14.0f, x3 = 6.5f, y3 = 14.0f)
+ curveTo(x1 = 6.6326f, y1 = 14.0f, x2 = 6.75977f, y2 = 13.9473f, x3 = 6.85354f, y3 = 13.8535f)
+ curveTo(x1 = 6.9473f, y1 = 13.7598f, x2 = 6.99999f, y2 = 13.6326f, x3 = 7.0f, y3 = 13.5f)
+ verticalLineTo(y = 12.0f)
+ verticalLineTo(y = 9.0f)
+ curveTo(x1 = 7.0f, y1 = 6.22136f, x2 = 9.22136f, y2 = 4.0f, x3 = 12.0f, y3 = 4.0f)
+ close()
+ moveTo(x = 10.0f, y = 18.0f)
+ horizontalLineTo(x = 14.0f)
+ curveTo(x1 = 14.0f, y1 = 19.1166f, x2 = 13.1166f, y2 = 20.0f, x3 = 12.0f, y3 = 20.0f)
+ curveTo(x1 = 10.8834f, y1 = 20.0f, x2 = 10.0f, y2 = 19.1166f, x3 = 10.0f, y3 = 18.0f)
+ close()
+ }
+ }.build().also { _notification = it }
+ }
+
+@Suppress("ObjectPropertyName")
+private var _notification: ImageVector? = null
diff --git a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/atom/Warning.kt b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/atom/Warning.kt
new file mode 100644
index 00000000000..83222c58407
--- /dev/null
+++ b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/atom/Warning.kt
@@ -0,0 +1,61 @@
+package net.thunderbird.feature.notification.api.ui.icon.atom
+
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.graphics.vector.path
+import androidx.compose.ui.unit.dp
+
+@Suppress("MagicNumber", "MaxLineLength")
+internal val Warning: ImageVector
+ get() {
+ val current = _warning
+ if (current != null) return current
+
+ return ImageVector.Builder(
+ name = "net.thunderbird.feature.notification.api.ui.icon.atom.Warning",
+ defaultWidth = 24.0.dp,
+ defaultHeight = 24.0.dp,
+ viewportWidth = 960.0f,
+ viewportHeight = 960.0f,
+ ).apply {
+ path(
+ fill = SolidColor(Color(0xFFFFFFFF)),
+ ) {
+ moveTo(x = 40.0f, y = 840.0f)
+ lineTo(x = 480.0f, y = 80.0f)
+ lineTo(x = 920.0f, y = 840.0f)
+ lineTo(x = 40.0f, y = 840.0f)
+ close()
+ moveTo(x = 178.0f, y = 760.0f)
+ lineTo(x = 782.0f, y = 760.0f)
+ lineTo(x = 480.0f, y = 240.0f)
+ lineTo(x = 178.0f, y = 760.0f)
+ close()
+ moveTo(x = 480.0f, y = 720.0f)
+ quadTo(x1 = 497.0f, y1 = 720.0f, x2 = 508.5f, y2 = 708.5f)
+ quadTo(x1 = 520.0f, y1 = 697.0f, x2 = 520.0f, y2 = 680.0f)
+ quadTo(x1 = 520.0f, y1 = 663.0f, x2 = 508.5f, y2 = 651.5f)
+ quadTo(x1 = 497.0f, y1 = 640.0f, x2 = 480.0f, y2 = 640.0f)
+ quadTo(x1 = 463.0f, y1 = 640.0f, x2 = 451.5f, y2 = 651.5f)
+ quadTo(x1 = 440.0f, y1 = 663.0f, x2 = 440.0f, y2 = 680.0f)
+ quadTo(x1 = 440.0f, y1 = 697.0f, x2 = 451.5f, y2 = 708.5f)
+ quadTo(x1 = 463.0f, y1 = 720.0f, x2 = 480.0f, y2 = 720.0f)
+ close()
+ moveTo(x = 440.0f, y = 600.0f)
+ lineTo(x = 520.0f, y = 600.0f)
+ lineTo(x = 520.0f, y = 400.0f)
+ lineTo(x = 440.0f, y = 400.0f)
+ lineTo(x = 440.0f, y = 600.0f)
+ close()
+ moveTo(x = 480.0f, y = 500.0f)
+ lineTo(x = 480.0f, y = 500.0f)
+ lineTo(x = 480.0f, y = 500.0f)
+ lineTo(x = 480.0f, y = 500.0f)
+ close()
+ }
+ }.build().also { _warning = it }
+ }
+
+@Suppress("ObjectPropertyName")
+private var _warning: ImageVector? = null
diff --git a/feature/notification/api/src/commonTest/kotlin/net/thunderbird/feature/notification/api/ui/icon/NotificationIconTest.kt b/feature/notification/api/src/commonTest/kotlin/net/thunderbird/feature/notification/api/ui/icon/NotificationIconTest.kt
new file mode 100644
index 00000000000..b0f31959193
--- /dev/null
+++ b/feature/notification/api/src/commonTest/kotlin/net/thunderbird/feature/notification/api/ui/icon/NotificationIconTest.kt
@@ -0,0 +1,30 @@
+package net.thunderbird.feature.notification.api.ui.icon
+
+import androidx.compose.ui.graphics.vector.ImageVector
+import assertk.assertThat
+import assertk.assertions.hasMessage
+import assertk.assertions.isInstanceOf
+import kotlin.test.Test
+import kotlin.test.assertFails
+
+class NotificationIconTest {
+ @Test
+ fun `NotificationIcon should throw IllegalStateException when both system and inApp icons are null`() {
+ // Arrange
+ val systemNotificationIcon: SystemNotificationIcon? = null
+ val inAppNotificationIcon: ImageVector? = null
+
+ // Act
+ val exception = assertFails {
+ NotificationIcon(systemNotificationIcon, inAppNotificationIcon)
+ }
+
+ // Assert
+ assertThat(exception)
+ .isInstanceOf()
+ .hasMessage(
+ "Both systemNotificationIcon and inAppNotificationIcon are null. " +
+ "You must specify at least one type of icon.",
+ )
+ }
+}
diff --git a/feature/notification/api/src/jvmMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/NotificationIcons.jvm.kt b/feature/notification/api/src/jvmMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/NotificationIcons.jvm.kt
new file mode 100644
index 00000000000..c51755d2485
--- /dev/null
+++ b/feature/notification/api/src/jvmMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/NotificationIcons.jvm.kt
@@ -0,0 +1,17 @@
+package net.thunderbird.feature.notification.api.ui.icon
+
+private const val ERROR_MESSAGE = "Can't send notifications from a jvm library. Use android library or app instead."
+
+internal actual val NotificationIcons.AlarmPermissionMissing: NotificationIcon get() = error(ERROR_MESSAGE)
+internal actual val NotificationIcons.AuthenticationError: NotificationIcon get() = error(ERROR_MESSAGE)
+internal actual val NotificationIcons.CertificateError: NotificationIcon get() = error(ERROR_MESSAGE)
+internal actual val NotificationIcons.FailedToCreate: NotificationIcon get() = error(ERROR_MESSAGE)
+internal actual val NotificationIcons.MailFetching: NotificationIcon get() = error(ERROR_MESSAGE)
+internal actual val NotificationIcons.MailSending: NotificationIcon get() = error(ERROR_MESSAGE)
+internal actual val NotificationIcons.MailSendFailed: NotificationIcon get() = error(ERROR_MESSAGE)
+internal actual val NotificationIcons.NewMailSingleMail: NotificationIcon get() = error(ERROR_MESSAGE)
+internal actual val NotificationIcons.NewMailSummaryMail: NotificationIcon get() = error(ERROR_MESSAGE)
+internal actual val NotificationIcons.PushServiceInitializing: NotificationIcon get() = error(ERROR_MESSAGE)
+internal actual val NotificationIcons.PushServiceListening: NotificationIcon get() = error(ERROR_MESSAGE)
+internal actual val NotificationIcons.PushServiceWaitBackgroundSync: NotificationIcon get() = error(ERROR_MESSAGE)
+internal actual val NotificationIcons.PushServiceWaitNetwork: NotificationIcon get() = error(ERROR_MESSAGE)
diff --git a/feature/notification/api/src/jvmMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/SystemNotificationIcon.jvm.kt b/feature/notification/api/src/jvmMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/SystemNotificationIcon.jvm.kt
new file mode 100644
index 00000000000..9b05b039eff
--- /dev/null
+++ b/feature/notification/api/src/jvmMain/kotlin/net/thunderbird/feature/notification/api/ui/icon/SystemNotificationIcon.jvm.kt
@@ -0,0 +1,3 @@
+package net.thunderbird.feature.notification.api.ui.icon
+
+actual typealias SystemNotificationIcon = Int