Skip to content

Commit ed604ff

Browse files
committed
feat(notification): add SystemNotificationCommand implementation
1 parent 1cc8fc8 commit ed604ff

File tree

8 files changed

+437
-22
lines changed

8 files changed

+437
-22
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package net.thunderbird.feature.notification.api.command
2+
3+
class NotificationCommandException @JvmOverloads constructor(
4+
override val message: String?,
5+
override val cause: Throwable? = null,
6+
) : Exception(message, cause)

feature/notification/impl/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
plugins {
22
id(ThunderbirdPlugins.Library.kmpCompose)
3+
alias(libs.plugins.dev.mokkery)
34
}
45

56
kotlin {
67
sourceSets {
78
commonMain.dependencies {
89
implementation(projects.core.common)
10+
implementation(projects.core.featureflag)
911
implementation(projects.core.outcome)
1012
implementation(projects.core.logging.api)
1113
implementation(projects.feature.notification.api)

feature/notification/impl/src/commonMain/kotlin/net/thunderbird/feature/notification/impl/command/NotificationCommandFactory.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package net.thunderbird.feature.notification.impl.command
22

3+
import net.thunderbird.core.featureflag.FeatureFlagProvider
34
import net.thunderbird.core.logging.Logger
5+
import net.thunderbird.feature.notification.api.NotificationRegistry
46
import net.thunderbird.feature.notification.api.command.NotificationCommand
57
import net.thunderbird.feature.notification.api.content.InAppNotification
68
import net.thunderbird.feature.notification.api.content.Notification
@@ -13,6 +15,8 @@ import net.thunderbird.feature.notification.impl.receiver.SystemNotificationNoti
1315
*/
1416
internal class NotificationCommandFactory(
1517
private val logger: Logger,
18+
private val featureFlagProvider: FeatureFlagProvider,
19+
private val notificationRegistry: NotificationRegistry,
1620
private val systemNotificationNotifier: SystemNotificationNotifier,
1721
private val inAppNotificationNotifier: InAppNotificationNotifier,
1822
) {
@@ -31,6 +35,8 @@ internal class NotificationCommandFactory(
3135
commands.add(
3236
SystemNotificationCommand(
3337
logger = logger,
38+
featureFlagProvider = featureFlagProvider,
39+
notificationRegistry = notificationRegistry,
3440
notification = notification,
3541
notifier = systemNotificationNotifier,
3642
),
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
package net.thunderbird.feature.notification.impl.command
22

3+
import net.thunderbird.core.featureflag.FeatureFlagKey
4+
import net.thunderbird.core.featureflag.FeatureFlagProvider
5+
import net.thunderbird.core.featureflag.FeatureFlagResult
36
import net.thunderbird.core.logging.Logger
47
import net.thunderbird.core.outcome.Outcome
8+
import net.thunderbird.feature.notification.api.NotificationRegistry
9+
import net.thunderbird.feature.notification.api.NotificationSeverity
510
import net.thunderbird.feature.notification.api.command.NotificationCommand
11+
import net.thunderbird.feature.notification.api.command.NotificationCommandException
12+
import net.thunderbird.feature.notification.api.content.InAppNotification
613
import net.thunderbird.feature.notification.api.content.SystemNotification
714
import net.thunderbird.feature.notification.api.receiver.NotificationNotifier
815

16+
private const val TAG = "SystemNotificationCommand"
17+
918
/**
1019
* Command for displaying system notifications.
1120
*
@@ -14,13 +23,64 @@ import net.thunderbird.feature.notification.api.receiver.NotificationNotifier
1423
*/
1524
internal class SystemNotificationCommand(
1625
private val logger: Logger,
26+
private val featureFlagProvider: FeatureFlagProvider,
27+
private val notificationRegistry: NotificationRegistry,
1728
notification: SystemNotification,
1829
notifier: NotificationNotifier<SystemNotification>,
30+
private val isAppInBackground: () -> Boolean = {
31+
// TODO(#9391): Verify if the app is backgrounded.
32+
false
33+
},
1934
) : NotificationCommand<SystemNotification>(notification, notifier) {
35+
36+
private val isFeatureFlagEnabled: Boolean
37+
get() = featureFlagProvider
38+
.provide(FeatureFlagKey.UseNotificationSenderForSystemNotifications) == FeatureFlagResult.Enabled
39+
2040
override suspend fun execute(): Outcome<Success<SystemNotification>, Failure<SystemNotification>> {
21-
logger.debug {
22-
"TODO: Implementation on GitHub Issue #9245. Notification = $notification."
41+
logger.debug(TAG) { "execute() called" }
42+
return when {
43+
isFeatureFlagEnabled.not() ->
44+
Outcome.failure(
45+
error = Failure(
46+
command = this,
47+
throwable = NotificationCommandException(
48+
message = "${FeatureFlagKey.UseNotificationSenderForSystemNotifications.key} feature flag" +
49+
"is not enabled",
50+
),
51+
),
52+
)
53+
54+
canExecuteCommand() -> {
55+
notifier.show(
56+
id = notificationRegistry.register(notification),
57+
notification = notification,
58+
)
59+
Outcome.success(Success(command = this))
60+
}
61+
62+
else -> {
63+
Outcome.failure(
64+
error = Failure(
65+
command = this,
66+
throwable = NotificationCommandException("Can't execute command."),
67+
),
68+
)
69+
}
70+
}
71+
}
72+
73+
private fun canExecuteCommand(): Boolean {
74+
val shouldAlwaysShow = when (notification.severity) {
75+
NotificationSeverity.Fatal, NotificationSeverity.Critical -> true
76+
else -> false
77+
}
78+
79+
return when {
80+
shouldAlwaysShow -> true
81+
isAppInBackground() -> true
82+
notification !is InAppNotification -> true
83+
else -> false
2384
}
24-
return Outcome.success(data = Success(command = this))
2585
}
2686
}

feature/notification/impl/src/commonMain/kotlin/net/thunderbird/feature/notification/impl/inject/NotificationModule.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ val featureNotificationModule = module {
2121
factory<NotificationCommandFactory> {
2222
NotificationCommandFactory(
2323
logger = get(),
24+
notificationRegistry = get(),
25+
featureFlagProvider = get(),
2426
systemNotificationNotifier = get(),
2527
inAppNotificationNotifier = get(),
2628
)

feature/notification/impl/src/commonTest/kotlin/net/thunderbird/feature/notification/impl/DefaultNotificationRegistryTest.kt

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package net.thunderbird.feature.notification.impl
22

3-
import androidx.compose.ui.graphics.vector.ImageVector
4-
import androidx.compose.ui.unit.dp
53
import assertk.assertThat
64
import assertk.assertions.containsAtLeast
75
import assertk.assertions.hasSize
@@ -13,9 +11,7 @@ import kotlin.test.Test
1311
import kotlinx.coroutines.runBlocking
1412
import kotlinx.coroutines.test.runTest
1513
import net.thunderbird.feature.notification.api.NotificationId
16-
import net.thunderbird.feature.notification.api.NotificationSeverity
17-
import net.thunderbird.feature.notification.api.content.AppNotification
18-
import net.thunderbird.feature.notification.api.ui.icon.NotificationIcon
14+
import net.thunderbird.feature.notification.impl.fake.FakeNotification
1915

2016
@Suppress("MaxLineLength")
2117
class DefaultNotificationRegistryTest {
@@ -176,18 +172,4 @@ class DefaultNotificationRegistryTest {
176172
// Assert
177173
assertThat(registry[notification]).isNull()
178174
}
179-
180-
data class FakeNotification(
181-
override val title: String = "fake title",
182-
override val contentText: String? = "fake content",
183-
override val severity: NotificationSeverity = NotificationSeverity.Information,
184-
override val icon: NotificationIcon = NotificationIcon(
185-
inAppNotificationIcon = ImageVector.Builder(
186-
defaultWidth = 0.dp,
187-
defaultHeight = 0.dp,
188-
viewportWidth = 0f,
189-
viewportHeight = 0f,
190-
).build(),
191-
),
192-
) : AppNotification()
193175
}

0 commit comments

Comments
 (0)