-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
feat(in-app-notification): Create NotificationSender to manage notification providers #9415
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(in-app-notification): Create NotificationSender to manage notification providers #9415
Conversation
a6d0aea to
f2bec5d
Compare
39fffb5 to
3d77f38
Compare
6a7b93d to
5569f5e
Compare
…ed by using MainTheme outside the composition local context
…ewWithThemesLightDark and ThemePreview to PreviewWithThemeLightDark
5569f5e to
adc0b53
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your work on the notification system overhaul. I've partially reviewed the code and have several observations that I'd like to share to help improve both this PR and future contributions.
I'm wondering if the debug section should work as it doesn't trigger any notifications on my side.
Complexity and API Surface
The notification system you've designed is quite comprehensive, but the API surface is unnecessarily large and complex. For example:
- The hierarchy of notification types (
SystemNotification,InAppNotification, various subtypes likeMailNotification.NewMail.SingleMail,PushServiceNotification, etc.) creates a complex inheritance tree - The extensive use of sealed interfaces and classes adds layers of abstraction that make the code harder to follow
- The notification styling system with multiple styles (
NotificationStyle.System.BigTextStyle,NotificationStyle.System.InboxStyle, etc.) adds another dimension of complexity
Consider simplifying the API by:
- Reducing the number of notification types and consolidating similar ones
- Flattening the inheritance hierarchy where possible
- Using composition over inheritance for specialized behavior
Test Coverage
Despite the complexity of the implementation, the tests are sparse. This makes it difficult to verify the behavior of the code changes and increases the risk of regressions. For a system as critical as notifications, comprehensive test coverage is essential.
I would recommend:
- Adding unit tests for each notification type
- Creating integration tests that verify the end-to-end notification flow
- Adding tests for edge cases (e.g., permission denied, notification channels not available)
- Including tests for the command pattern implementation
PR Size and Structure
The PR is too large and tackles too many concerns at once. This makes it difficult to review thoroughly and increases the chance of issues slipping through. Breaking it down into smaller, focused PRs would have been more manageable.
Specific components that could have been separate PRs:
- Debug Tools: The
feature/debug-settingsmodule with its comprehensive UI for testing notifications could have been a standalone PR - Parcelize Support: The KMP parcelize implementation in
core/commoncould have been separated - Notification API: The base interfaces and types could have been introduced first
- System Notification Implementation: Android-specific implementation
- In-App Notification Implementation: The broadcast mechanism
- Resources: The notification icons
- Legacy Integration: Connection with existing notification settings
Architectural Concerns
The command pattern implementation (NotificationCommandFactory, SystemNotificationCommand, etc.) is a good approach for handling different notification types, but it adds complexity without clear documentation on how it fits into the larger architecture.
Recommendations
For this PR:
- Consider simplifying the API before merging
- Add more tests to cover critical functionality
- Provide better documentation explaining the architectural decisions
For future PRs:
- Break down large features into smaller, focused PRs
- Implement core functionality before adding specialized features
- Add tests alongside implementation
- Consider using feature flags to merge incomplete features safely
I appreciate the effort put into this comprehensive notification system, but addressing these concerns would make it more maintainable and easier to integrate into the codebase.
...em/src/main/kotlin/app/k9mail/core/ui/compose/designsystem/atom/divider/HorizontalDivider.kt
Show resolved
Hide resolved
core/ui/compose/theme2/common/src/main/kotlin/app/k9mail/core/ui/compose/theme2/ThemeSizes.kt
Show resolved
Hide resolved
...debug-settings/src/debug/kotlin/net/thunderbird/feature/debugSettings/DebugSectionPreview.kt
Show resolved
Hide resolved
.../src/debug/kotlin/net/thunderbird/feature/debugSettings/inject/FeatureDebugSettingsModule.kt
Show resolved
Hide resolved
|
|
||
| plugins { | ||
| id(ThunderbirdPlugins.Library.kmpCompose) | ||
| id("kotlin-parcelize") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be alias(libs.plugins.kotlin.parcelize)
| androidMain.dependencies { | ||
| implementation(projects.core.ui.compose.designsystem) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about adding the icons here directly instead of the design system? Otherwise we could consider moving icons to their own module.
feature/notification/api/src/commonMain/composeResources/values/strings.xml
Show resolved
Hide resolved
| implementation(projects.core.ui.theme.api) | ||
| implementation(projects.feature.launcher) | ||
| implementation(projects.core.common) | ||
| implementation(projects.core.outcome) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It this required?
|
Hi @wmontwe, thanks for reviewing the PR! I will answer your comments/concerns in separate comments, so it makes it easier to discuss each section |
PR Size and StructureI agree with you, the PR is quite long. Would you prefer me splitting it into different PRs right now so it would be easier to focus on some areas? |
Complexity and API SurfaceAbout the hierarchy:The concept of using sealed classes with a nested hierarchy for notifications is designed to make it easier for developers to locate a specific notification based on its group or name. For instance, if someone wants to trigger a notification after a new email is sent but encounters a failure, they could search for:
By searching for I find this approach to be organized rather than complex. However, if you believe that flattening the notifications and creating a Notification class without utilizing sealed classes would enhance the API surface, I can certainly do that. About the Notification styling system:I need to highlight that there is a difference between a Notification type ( The same notification can be displayed via different providers (System and/or In-App) and with different styles. Additionally, in the case of an in-app notification, we could show the same notification using multiple styles. The changes present in this PR only consider the system notification styles we are already using in the app. Nonetheless, this new API is making it a bit more platform-agnostic. Even though we use the same names as the Android Notification system, we could implement the visual representation of it differently depending on the platform. Regarding the number of notification types and consolidating similar onesThe current types of notifications are a direct one-to-one mapping of each notification that we are already triggering in the app. Apart from the I’m open to any suggestions you might have. Using composition over inheritance for specialized behaviourTo be honest, I'm not sure where that would be applied here. Could you please point out where you believe that could be applied? |
Test Coverage
I will add them.
Sure, I'll try to add them.
These are all related to the System Notification command execution and is going to be handled in a different task (#9391)
I will add them. |
Architectural Concerns
There is a task (#9252) that focuses on documenting the new API. Is that what you are referring to? Additionally, I would appreciate it if you could provide a few specific examples of what you would like me to emphasize in the documentation. Thank you! |
|
This PR will be split into smaller PRs to improve the review |
Resolves #9245
This pull request introduces a
NotificationSenderresponsible for managing and dispatching notifications through various providers. As the application now supports both in-app and system notifications, this manager simplifies the process of triggering a notification by abstracting the provider-specific logic.The
NotificationSenderreceives a notification object and determines the appropriate provider to use for delivery.Changes Included
NotificationSenderImplementation: Core manager for handling notification logic.InAppNotificationNotifier: Implementation for displaying notifications within the app UI.SystemNotificationNotifier: Implementation for triggering native system notifications.