-
Notifications
You must be signed in to change notification settings - Fork 185
feat: web push API #16994
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: web push API #16994
Conversation
This reverts commit dde91de.
Remove WebPushToggle component and add api for registering/unregistering web push from client.
This implementation doesn't have an API for sending messages yet. Here are the criteria:
We can maybe introduce a single point for subscribing/unsubscribing and sending notifications. Main class: public class WebPush {
// singleton instances of WebPush and PushService
public static WebPush getInstance(Keys keys) {
// initialises PushService and WebPush lazily and return WebPush instance
}
public void sendNotification(WebPushRegistration.WebPushSubscription subscription, String messageJson) {
// delegates to pushService.send()
}
public static WebPushRegistration subscribe(UI ui,
WebPushRegistration.WebPushSubcriptionResponse callback) {
return new WebPushRegistration(ui, callback);
}
} "record" class for keys: public class Keys {
public static Keys of(String publicKey, String privateKey, String subject) {
return new Keys(publicKey, privateKey, subject);
}
} Example how to send messages from admin page: @Route("admin")
public class AdminView extends VerticalLayout {
private final WebPush webPush;
public AdminView(SubscriptionService subscriptionService) {
Keys keys = Keys.of("public key", "private key",
"[mailto:mikhail@vaadin.com]");
webPush = WebPush.getInstance(keys);
NativeButton broadcast = new NativeButton("Broadcast", click -> {
Collection<WebPushRegistration.WebPushSubscription> subscriptions =
subscriptionService.getAll();
subscriptions.forEach(s -> {
webPush.sendNotification(s, "Hello all");
});
});
NativeButton sendToUser = new NativeButton("Send to user",
click -> {
WebPushRegistration.WebPushSubscription subscription =
subscriptionService.getByUsername(user);
if (subscription != null) {
webPush.sendNotification(subscription, "Hello User " + user);
}
});
add(broadcast, sendToUser);
}
} Example for subscription/unsubscription on the user page: // inside some view class
private SubscriptionService subscriptionService;
private WebPushRegistration registration;
@Override
protected void onAttach(AttachEvent attachEvent) {
super.onAttach(attachEvent);
NativeButton subscribeButton = new NativeButton("Subscribe", click -> {
registration = WebPush.subscribe(attachEvent.getUI(), subscription -> {
subscriptionService.subscribe(subscription);
});
});
NativeButton unsubscribeButton = new NativeButton("Unsubscribe",
click -> {
if (registration != null) {
registration.unsubscribeWebPush(attachEvent.getUI(), subscription -> {
subscriptionService.unsubscribe(subscription);
});
}
});
} And finally a subscription service: private interface SubscriptionService {
void subscribe(WebPushRegistration.WebPushSubscription subscription);
void unsubscribe(WebPushRegistration.WebPushSubscription subscription);
Collection<WebPushRegistration.WebPushSubscription> getAll();
WebPushRegistration.WebPushSubscription getByUsername(User user);
} The way how Flow stores and provides an instances of |
@Bean(name = "WebPush")
public WebPush getWebPush() {
// keys are injected with AtValue
return new WebPush(keys);
} |
Pushed an extension for Also updated base web push example here to showcase the API. |
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.
Have some further suggestions, let's discuss.
flow-server/src/main/java/com/vaadin/flow/server/frontend/webpush/WebPushRegistration.java
Outdated
Show resolved
Hide resolved
flow-server/src/main/java/com/vaadin/flow/server/frontend/webpush/WebPushRegistration.java
Outdated
Show resolved
Hide resolved
flow-server/src/main/java/com/vaadin/flow/server/frontend/webpush/WebPushRegistration.java
Outdated
Show resolved
Hide resolved
Looking into possible further improvements of Web Push API (outside of this pull request), I made a short analysis of what we might need in the future:
So it seems like we'll need a new methods in |
Permission check is avaliable in the registration script, but doesn't have a server method. |
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.
Some minor comments about javadoc and feature flags.
About testing: unit tests are not much interesting for this feature, because half of the feature is in the browser.
We need an end-to-end test, but need a discussion how properly set up the testing environment.
flow-webpush/src/main/java/com/vaadin/flow/server/webpush/WebPush.java
Outdated
Show resolved
Hide resolved
flow-webpush/src/main/java/com/vaadin/flow/server/webpush/WebPush.java
Outdated
Show resolved
Hide resolved
flow-webpush/src/main/java/com/vaadin/flow/server/webpush/WebPush.java
Outdated
Show resolved
Hide resolved
Update bouncycastle
Kudos, SonarCloud Quality Gate passed! |
This ticket/PR has been released with Vaadin 24.2.0.alpha1 and is also targeting the upcoming stable 24.2.0 version. |
Add API to use initialize web push on the client from the server.
Related-to vaadin/platform#4037
Fixes #14606