Skip to content

Commit d41a69a

Browse files
Fix push notification on safari (#1110)
* fix push notificaiton in safari * text fix notification * restore actions
1 parent 0db4456 commit d41a69a

File tree

5 files changed

+35
-33
lines changed

5 files changed

+35
-33
lines changed

docs/src/notifications-page.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,13 @@ func (p *notificationsPage) testNotification(ctx app.Context, e app.Event) {
103103
Title: fmt.Sprintln("go-app test", n),
104104
Body: fmt.Sprintln("Test notification for go-app number", n),
105105
Path: "/notifications#example",
106-
// Actions: []app.NotificationAction{
107-
// {
108-
// Title: "test",
109-
// Action: ":test",
110-
// Path: "/notifications",
111-
// },
112-
// },
106+
Actions: []app.NotificationAction{
107+
{
108+
Title: "test",
109+
Action: ":test",
110+
Path: "/notifications",
111+
},
112+
},
113113
})
114114
}
115115

docs/web/app.wasm

2.5 KB
Binary file not shown.

docs/web/documents/reference.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1643,7 +1643,7 @@ <h2 id="pkg-constants">Constants</h2>
16431643

16441644
<pre>const (
16451645
<span class="comment">// The default template used to generate app-worker.js.</span>
1646-
<span id="DefaultAppWorkerJS">DefaultAppWorkerJS</span> = &#34;// -----------------------------------------------------------------------------\n// PWA\n// -----------------------------------------------------------------------------\nconst cacheName = \&#34;app-\&#34; + \&#34;{{.Version}}\&#34;;\nconst resourcesToCache = {{.ResourcesToCache}};\n\nself.addEventListener(\&#34;install\&#34;, async (event) =&gt; {\n try {\n console.log(\&#34;installing app worker {{.Version}}\&#34;);\n await installWorker();\n await self.skipWaiting();\n } catch (error) {\n console.error(\&#34;error during installation:\&#34;, error);\n }\n});\n\nasync function installWorker() {\n const cache = await caches.open(cacheName);\n await cache.addAll(resourcesToCache);\n}\n\nself.addEventListener(\&#34;activate\&#34;, async (event) =&gt; {\n try {\n await deletePreviousCaches(); // Await cache cleanup\n await self.clients.claim(); // Ensure the service worker takes control of the clients\n console.log(\&#34;app worker {{.Version}} is activated\&#34;);\n } catch (error) {\n console.error(\&#34;error during activation:\&#34;, error);\n }\n});\n\nasync function deletePreviousCaches() {\n const keys = await caches.keys();\n await Promise.all(\n keys.map(async (key) =&gt; {\n if (key !== cacheName) {\n try {\n console.log(\&#34;deleting\&#34;, key, \&#34;cache\&#34;);\n await caches.delete(key);\n } catch (err) {\n console.error(\&#34;deleting\&#34;, key, \&#34;cache failed:\&#34;, err);\n }\n }\n })\n );\n}\n\nself.addEventListener(\&#34;fetch\&#34;, (event) =&gt; {\n event.respondWith(fetchWithCache(event.request));\n});\n\nasync function fetchWithCache(request) {\n const cachedResponse = await caches.match(request);\n if (cachedResponse) {\n return cachedResponse;\n }\n return await fetch(request);\n}\n\n// -----------------------------------------------------------------------------\n// Push Notifications\n// -----------------------------------------------------------------------------\nself.addEventListener(\&#34;push\&#34;, (event) =&gt; {\n if (!event.data || !event.data.text()) {\n return;\n }\n\n const notification = JSON.parse(event.data.text());\n if (!notification) {\n return;\n }\n\n event.waitUntil(\n showNotification(self.registration, notification)\n );\n});\n\nself.addEventListener(\&#34;message\&#34;, (event) =&gt; {\n const msg = event.data;\n if (!msg || msg.type !== \&#34;goapp:notify\&#34;) {\n return;\n }\n\n event.waitUntil(\n showNotification(self.registration, msg.options)\n );\n});\n\nasync function showNotification(registration, notification) {\n const title = notification.title || \&#34;\&#34;;\n\n let actions = [];\n for (let i in notification.actions) {\n const action = notification.actions[i];\n actions.push({\n action: action.action,\n path: action.path,\n });\n delete action.path;\n }\n\n notification.data = notification.data || {};\n notification.data.goapp = {\n path: notification.path,\n actions: actions,\n };\n delete notification.title;\n delete notification.path;\n\n await registration.showNotification(title, notification);\n}\n\nfunction sleep(ms) {\n return new Promise((resolve) =&gt; setTimeout(resolve, ms));\n}\n\nself.addEventListener(\&#34;notificationclick\&#34;, (event) =&gt; {\n event.notification.close();\n\n const notification = event.notification;\n let path = notification.data.goapp.path;\n\n for (let i in notification.data.goapp.actions) {\n const action = notification.data.goapp.actions[i];\n if (action.action === event.action) {\n path = action.path;\n break;\n }\n }\n\n event.waitUntil(\n clients\n .matchAll({\n type: \&#34;window\&#34;,\n })\n .then((clientList) =&gt; {\n for (var i = 0; i &lt; clientList.length; i++) {\n let client = clientList[i];\n if (\&#34;focus\&#34; in client) {\n client.focus();\n client.postMessage({\n goapp: {\n type: \&#34;notification\&#34;,\n path: path,\n },\n });\n return;\n }\n }\n\n if (clients.openWindow) {\n return clients.openWindow(path);\n }\n })\n );\n});&#34;
1646+
<span id="DefaultAppWorkerJS">DefaultAppWorkerJS</span> = &#34;// -----------------------------------------------------------------------------\n// PWA\n// -----------------------------------------------------------------------------\nconst cacheName = \&#34;app-\&#34; + \&#34;{{.Version}}\&#34;;\nconst resourcesToCache = {{.ResourcesToCache}};\n\nself.addEventListener(\&#34;install\&#34;, async (event) =&gt; {\n try {\n console.log(\&#34;installing app worker {{.Version}}\&#34;);\n await installWorker();\n await self.skipWaiting();\n } catch (error) {\n console.error(\&#34;error during installation:\&#34;, error);\n }\n});\n\nasync function installWorker() {\n const cache = await caches.open(cacheName);\n await cache.addAll(resourcesToCache);\n}\n\nself.addEventListener(\&#34;activate\&#34;, async (event) =&gt; {\n try {\n await deletePreviousCaches(); // Await cache cleanup\n await self.clients.claim(); // Ensure the service worker takes control of the clients\n console.log(\&#34;app worker {{.Version}} is activated\&#34;);\n } catch (error) {\n console.error(\&#34;error during activation:\&#34;, error);\n }\n});\n\nasync function deletePreviousCaches() {\n const keys = await caches.keys();\n await Promise.all(\n keys.map(async (key) =&gt; {\n if (key !== cacheName) {\n try {\n console.log(\&#34;deleting\&#34;, key, \&#34;cache\&#34;);\n await caches.delete(key);\n } catch (err) {\n console.error(\&#34;deleting\&#34;, key, \&#34;cache failed:\&#34;, err);\n }\n }\n })\n );\n}\n\nself.addEventListener(\&#34;fetch\&#34;, (event) =&gt; {\n event.respondWith(fetchWithCache(event.request));\n});\n\nasync function fetchWithCache(request) {\n const cachedResponse = await caches.match(request);\n if (cachedResponse) {\n return cachedResponse;\n }\n return await fetch(request);\n}\n\n// -----------------------------------------------------------------------------\n// Push Notifications\n// -----------------------------------------------------------------------------\nself.addEventListener(\&#34;push\&#34;, (event) =&gt; {\n event.waitUntil((async () =&gt; {\n let notification;\n\n try {\n notification = event.data ? event.data.json() : null;\n } catch {\n notification = null;\n }\n\n if (!notification) {\n return;\n }\n\n await showNotification(self.registration, notification);\n })());\n});\n\nself.addEventListener(\&#34;message\&#34;, (event) =&gt; {\n const msg = event.data;\n if (!msg || msg.type !== \&#34;goapp:notify\&#34;) {\n return;\n }\n\n event.waitUntil(\n showNotification(self.registration, msg.options)\n );\n});\n\nasync function showNotification(registration, notification) {\n const title = notification.title || \&#34;Notification\&#34;;\n\n let actions = [];\n for (let i in notification.actions) {\n const action = notification.actions[i];\n actions.push({\n action: action.action,\n path: action.path,\n });\n delete action.path;\n }\n\n await registration.showNotification(title, {\n body: notification.body,\n icon: notification.icon,\n badge: notification.badge,\n actions: notification.actions,\n data: {\n goapp: {\n path: notification.path,\n actions: actions\n }\n }\n });\n}\n\nself.addEventListener(\&#34;notificationclick\&#34;, (event) =&gt; {\n event.notification.close();\n\n const notification = event.notification;\n let path = notification.data.goapp.path;\n\n for (let i in notification.data.goapp.actions) {\n const action = notification.data.goapp.actions[i];\n if (action.action === event.action) {\n path = action.path;\n break;\n }\n }\n\n event.waitUntil(\n clients\n .matchAll({\n type: \&#34;window\&#34;,\n })\n .then((clientList) =&gt; {\n for (var i = 0; i &lt; clientList.length; i++) {\n let client = clientList[i];\n if (\&#34;focus\&#34; in client) {\n client.focus();\n client.postMessage({\n goapp: {\n type: \&#34;notification\&#34;,\n path: path,\n },\n });\n return;\n }\n }\n\n if (clients.openWindow) {\n return clients.openWindow(path);\n }\n })\n );\n});&#34;
16471647
)</pre>
16481648

16491649

pkg/app/gen/app-worker.js

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,21 @@ async function fetchWithCache(request) {
6161
// Push Notifications
6262
// -----------------------------------------------------------------------------
6363
self.addEventListener("push", (event) => {
64-
if (!event.data || !event.data.text()) {
65-
return;
66-
}
64+
event.waitUntil((async () => {
65+
let notification;
6766

68-
const notification = JSON.parse(event.data.text());
69-
if (!notification) {
70-
return;
71-
}
67+
try {
68+
notification = event.data ? event.data.json() : null;
69+
} catch {
70+
notification = null;
71+
}
7272

73-
event.waitUntil(
74-
showNotification(self.registration, notification)
75-
);
73+
if (!notification) {
74+
return;
75+
}
76+
77+
await showNotification(self.registration, notification);
78+
})());
7679
});
7780

7881
self.addEventListener("message", (event) => {
@@ -87,7 +90,7 @@ self.addEventListener("message", (event) => {
8790
});
8891

8992
async function showNotification(registration, notification) {
90-
const title = notification.title || "";
93+
const title = notification.title || "Notification";
9194

9295
let actions = [];
9396
for (let i in notification.actions) {
@@ -99,19 +102,18 @@ async function showNotification(registration, notification) {
99102
delete action.path;
100103
}
101104

102-
notification.data = notification.data || {};
103-
notification.data.goapp = {
104-
path: notification.path,
105-
actions: actions,
106-
};
107-
delete notification.title;
108-
delete notification.path;
109-
110-
await registration.showNotification(title, notification);
111-
}
112-
113-
function sleep(ms) {
114-
return new Promise((resolve) => setTimeout(resolve, ms));
105+
await registration.showNotification(title, {
106+
body: notification.body,
107+
icon: notification.icon,
108+
badge: notification.badge,
109+
actions: notification.actions,
110+
data: {
111+
goapp: {
112+
path: notification.path,
113+
actions: actions
114+
}
115+
}
116+
});
115117
}
116118

117119
self.addEventListener("notificationclick", (event) => {

pkg/app/scripts.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)