Skip to content
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

Update notification and permission handling #274

Merged
merged 4 commits into from
Feb 28, 2025

Conversation

zsmb13
Copy link
Contributor

@zsmb13 zsmb13 commented Feb 11, 2025

Updates the notification system (and related permission handling) to some new APIs, still implemented with separate native APIs on each platform, as no suitable KMP library was found that covered our use cases (including scheduled notifications).

Makes notification handling depend on TimeProvider as well, allowing tests of notifications with fake time values and sped up clocks within the app.

@zsmb13 zsmb13 force-pushed the feature/permissions branch from ee7c7d3 to 216d3fa Compare February 11, 2025 16:03
@zsmb13 zsmb13 changed the base branch from kotlinconf-2025 to kotlinx-datetime February 11, 2025 16:03
@zsmb13 zsmb13 changed the base branch from kotlinx-datetime to feature/notifications February 11, 2025 16:04
@zsmb13 zsmb13 force-pushed the feature/permissions branch 2 times, most recently from 2cdeaa3 to eeda6bb Compare February 11, 2025 16:44
Base automatically changed from feature/notifications to kotlinconf-2025 February 12, 2025 08:37
@zsmb13 zsmb13 force-pushed the feature/permissions branch 2 times, most recently from e5f29ea to 709d0de Compare February 12, 2025 11:00
@zsmb13 zsmb13 force-pushed the feature/permissions branch 9 times, most recently from 9d0fec6 to be9d82f Compare February 26, 2025 13:48
}
val request = UNNotificationRequest.requestWithIdentifier(notificationId, content, trigger)
notificationCenter.addNotificationRequest(request) { error: NSError? ->
// TODO use logger
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a TODO for all the println calls added here and later. Please ignore these for now, I created #285 to fix this in a follow-up PR (to not add even more changes within this one).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That PR is already here: #286

@zsmb13 zsmb13 changed the title Feature/permissions Notifications and permission handling Feb 26, 2025
@zsmb13 zsmb13 changed the title Notifications and permission handling Update notification and permission handling Feb 26, 2025
@zsmb13 zsmb13 requested review from e5l and kropp February 26, 2025 14:02
Comment on lines +141 to +145
if (items.isNotEmpty() && firstLiveIndex != -1) {
LaunchedEffect(Unit) {
listState.scrollToItem(firstLiveIndex)
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick random fix: scroll to current time in schedule when first loaded

@zsmb13 zsmb13 force-pushed the feature/permissions branch from be9d82f to 56453ad Compare February 26, 2025 14:04
@zsmb13 zsmb13 marked this pull request as ready for review February 26, 2025 16:02
message: String
): Unit =
js(
"""{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make external declarations for this instead or check if they are in the browser dependency? I really want to avoid string js code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll see if this can be moved to the JS side easily, but this is something I moved over from the old implementation as-is. I'd also be happy to just leave it and not touch it, since it works :D


@OptIn(ExperimentalComposeUiApi::class)
fun main() {
initCoil()
CanvasBasedWindow {
App(ApplicationContext())
App(platformModule = module {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we may have last block parameter outside of the (), so it can be a bit more readable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't work here as we're also calling the module function, but I'd also avoid it either way because it would look confusing in Compose code

suspend fun requestPermission(): Boolean

fun post(
notificationId: String,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to use value class NotificationId here, similar to other places.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to serialize it into an intent at some point on Android, and pass it to JS for interop, I don't want to complicate its type for now

private const val EXTRA_MESSAGE = "message"
private const val EXTRA_NOTIFICATION_ID = "notificationId"
private const val EXTRA_ICON_ID = "iconId"
private const val NOTIFICATION_CHANNEL_ID = "channel_all_notifications"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we introduce separate channels for different notification types (session alerts vs news)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not without putting in a lot more work for managing these channels. The ideal setup for Android users would probably be to use 3 different notification channels and not have in-app settings for notification categories at all, only a button that sends them to the system settings where they can configure each channel. But it's a bunch of extra work just for the one platform, so not critical for the time being.

(We can't read or change the state of notification channels from the app, so we can't sync our own toggles to what the user sets on the channels in settings.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the bright side, we'll bump the minimum API to 26 on the icons PR, which is where notification channels were introduced, so that eliminates a whole problem where on 24-25 we'd have to have the in-app switcher instead anyway.

@zsmb13 zsmb13 force-pushed the feature/permissions branch from 0a80097 to 818db79 Compare February 27, 2025 11:05
@zsmb13 zsmb13 merged commit 3267162 into kotlinconf-2025 Feb 28, 2025
5 checks passed
@zsmb13 zsmb13 deleted the feature/permissions branch February 28, 2025 09:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants