Skip to content

Commit a1cbb0d

Browse files
authored
feat: Extend WebPushMessage with the custom settings (#20304)
Add an API to set custom options as described in https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/showNotification#parameters Fixes #20285
1 parent 9378d46 commit a1cbb0d

File tree

6 files changed

+109
-14
lines changed

6 files changed

+109
-14
lines changed

flow-server/src/main/resources/com/vaadin/flow/server/frontend/sw.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,7 @@ self.addEventListener('message', (event) => {
149149
self.addEventListener('push', (e) => {
150150
const data = e.data?.json();
151151
if (data) {
152-
self.registration.showNotification(data.title, {
153-
body: data.body,
154-
});
152+
self.registration.showNotification(data.title, data.options);
155153
}
156154
});
157155

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.vaadin.flow.webpush;
2+
3+
import java.io.Serializable;
4+
5+
public record WebPushAction(String action, String title, String icon) implements Serializable {
6+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.vaadin.flow.webpush;
2+
3+
import java.io.Serializable;
4+
import java.util.List;
5+
6+
public record WebPushOptions(List<WebPushAction> actions,
7+
String badge,
8+
String body,
9+
Serializable data,
10+
String dir,
11+
String icon,
12+
String image,
13+
String lang,
14+
boolean renotify,
15+
boolean requireInteraction,
16+
boolean silent,
17+
String tag,
18+
long timestamp,
19+
List<Integer> vibrate) implements Serializable {
20+
}

flow-tests/test-webpush/src/main/java/com/vaadin/flow/webpush/WebPushView.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.vaadin.flow.webpush;
1818

19+
import java.util.List;
20+
1921
import nl.martijndwars.webpush.Subscription;
2022

2123
import com.vaadin.flow.component.Text;
@@ -44,6 +46,12 @@ public class WebPushView extends Div {
4446
WebPush webPush;
4547

4648
private final Div log;
49+
private final WebPushAction webPushAction = new WebPushAction(
50+
"dashboard",
51+
"Open Dashboard",
52+
"https://upload.wikimedia.org/wikipedia/commons/0/0e/Message-icon-blue-symbol-double.png"
53+
);
54+
4755
private Subscription subscription;
4856

4957
public WebPushView() {
@@ -73,8 +81,25 @@ public WebPushView() {
7381

7482
notify = new NativeButton("Notify", event -> {
7583
if (subscription != null) {
84+
WebPushOptions webPushOptions = new WebPushOptions(
85+
List.of(webPushAction),
86+
"https://upload.wikimedia.org/wikipedia/commons/0/0e/Message-icon-blue-symbol-double.png",
87+
"Testing notification",
88+
"This is my data!",
89+
"rtl",
90+
"https://upload.wikimedia.org/wikipedia/commons/0/0e/Message-icon-blue-symbol-double.png",
91+
"https://upload.wikimedia.org/wikipedia/commons/0/0e/Message-icon-blue-symbol-double.png",
92+
"de-DE",
93+
true,
94+
true,
95+
false,
96+
"My Notification",
97+
System.currentTimeMillis(),
98+
List.of(500, 500, 500)
99+
);
100+
76101
webPush.sendNotification(subscription,
77-
new WebPushMessage(TEST_TITLE, "Testing notification"));
102+
new WebPushMessage(TEST_TITLE, webPushOptions));
78103
addLogEntry("Sent notification");
79104
} else {
80105
addLogEntry("No notification sent due to missing subscription");

flow-tests/test-webpush/src/test/java/com/vaadin/flow/webpush/WebPushIT.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,18 @@ public boolean isNotificationPresent(WebDriver driver) {
153153
.then( (notifications) => {
154154
return notifications.length == 1 &&
155155
notifications[0].title === 'Test title' &&
156-
notifications[0].body === 'Testing notification';
156+
notifications[0].body === 'Testing notification' &&
157+
notifications[0].badge === 'https://upload.wikimedia.org/wikipedia/commons/0/0e/Message-icon-blue-symbol-double.png' &&
158+
notifications[0].data === 'This is my data!' &&
159+
notifications[0].dir === 'rtl' &&
160+
notifications[0].icon === 'https://upload.wikimedia.org/wikipedia/commons/0/0e/Message-icon-blue-symbol-double.png' &&
161+
notifications[0].lang === 'de-DE' &&
162+
notifications[0].renotify === true &&
163+
notifications[0].requireInteraction === true &&
164+
notifications[0].silent === false &&
165+
notifications[0].tag === 'My Notification' &&
166+
Array.isArray(notifications[0].actions) && notifications[0].actions.length > 0 && notifications[0].actions[0].action === 'dashboard' &&
167+
Array.isArray(notifications[0].vibrate) && notifications[0].vibrate.length > 0 && notifications[0].vibrate[0] === 500;
157168
});
158169
""");
159170
}

flow-webpush/src/main/java/com/vaadin/flow/server/webpush/WebPushMessage.java

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,49 @@
1717

1818
import java.io.Serializable;
1919

20-
import elemental.json.Json;
21-
import elemental.json.JsonObject;
20+
import com.fasterxml.jackson.databind.ObjectMapper;
21+
import com.fasterxml.jackson.databind.node.ObjectNode;
2222

2323
/**
2424
* Web Push message object containing an information to be shown in the
2525
* notification.
2626
*
2727
* @since 24.2
2828
*/
29-
public record WebPushMessage(String title, String body) implements Serializable {
29+
public record WebPushMessage(String title, ObjectNode options) implements Serializable {
30+
31+
private static final ObjectMapper objectMapper = new ObjectMapper();
32+
33+
/**
34+
* Creates a new Web Push notification message with the specified title and various options
35+
* fetched from a given Java object.
36+
*
37+
* @param title the notification title
38+
* @param options any {@code Serializable} Java object representing custom settings to apply to the notification
39+
* @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/showNotification#parameters">
40+
* showNotification parameters</a>
41+
*/
42+
public WebPushMessage(String title, Serializable options) {
43+
this(title, objectMapper.convertValue(options, ObjectNode.class));
44+
}
45+
46+
/**
47+
* Creates a new Web Push notification message with just a title and body.
48+
*
49+
* @param title notification title
50+
* @param body notification body
51+
*/
52+
public WebPushMessage(String title, String body) {
53+
this(title, getBodyOption(body));
54+
}
3055

3156
/**
32-
* Creates a new Web Push notification message with title and body.
57+
* Creates a new Web Push notification message with just a title.
3358
*
3459
* @param title notification title
35-
* @param body notification body
3660
*/
37-
public WebPushMessage {
61+
public WebPushMessage(String title) {
62+
this(title, (ObjectNode) null);
3863
}
3964

4065
@Override
@@ -48,9 +73,19 @@ public String toString() {
4873
* @return JSON representation of this message
4974
*/
5075
public String toJson() {
51-
JsonObject json = Json.createObject();
76+
ObjectNode json = objectMapper.createObjectNode();
5277
json.put("title", title);
53-
json.put("body", body);
54-
return json.toJson();
78+
if (options != null) {
79+
json.set("options", options);
80+
}
81+
return json.toString();
82+
}
83+
84+
private static ObjectNode getBodyOption(String body) {
85+
ObjectNode objectNode = objectMapper.createObjectNode();
86+
if (body != null) {
87+
objectNode.put("body", body);
88+
}
89+
return objectNode;
5590
}
5691
}

0 commit comments

Comments
 (0)