Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/src/notifications-page.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ func (p *notificationsPage) testNotification(ctx app.Context, e app.Event) {
// Path: "/notifications",
// },
// },
// Delay: time.Second * 2,
})
}

Expand Down
Binary file modified docs/web/app.wasm
Binary file not shown.
27 changes: 10 additions & 17 deletions docs/web/documents/reference.html
Original file line number Diff line number Diff line change
Expand Up @@ -1643,7 +1643,7 @@ <h2 id="pkg-constants">Constants</h2>

<pre>const (
<span class="comment">// The default template used to generate app-worker.js.</span>
<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 let delay = notification.delay || 0;\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 delete notification.delay;\n\n if (delay &gt; 0) {\n delay = Math.floor(delay / 1e6);\n await sleep(delay);\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;
<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;
)</pre>


Expand Down Expand Up @@ -26221,7 +26221,7 @@ <h2 id="Navigator">type <a href="/src/github.com/maxence-charriere/go-app/v10/pk



<h2 id="Notification">type <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=153:2377#L1">Notification</a>
<h2 id="Notification">type <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=145:2047#L1">Notification</a>
<a class="permalink" href="#Notification">&#xb6;</a>


Expand Down Expand Up @@ -26275,13 +26275,6 @@ <h2 id="Notification">type <a href="/src/github.com/maxence-charriere/go-app/v10
<span class="comment">// See: https://developer.mozilla.org/en-US/docs/Web/API/Vibration_API</span>
Vibrate []<a href="/pkg/builtin/#int">int</a> `json:&#34;vibrate,omitempty&#34;`

<span id="Notification.Delay"></span> <span class="comment">// Delay specifies how long to wait before displaying the notification.</span>
<span class="comment">//</span>
<span class="comment">// The duration is serialized as a Go time.Duration and interpreted</span>
<span class="comment">// client-side. Actual delivery time is best-effort and may be delayed</span>
<span class="comment">// further depending on browser and system constraints.</span>
Delay <a href="/pkg/time/">time</a>.<a href="/pkg/time/#Duration">Duration</a> `json:&#34;delay,omitempty&#34;`

<span id="Notification.Actions"></span> <span class="comment">// Actions lists the available actions displayed within the notification.</span>
Actions []<a href="#NotificationAction">NotificationAction</a> `json:&#34;actions,omitempty&#34;`
}
Expand All @@ -26301,7 +26294,7 @@ <h2 id="Notification">type <a href="/src/github.com/maxence-charriere/go-app/v10



<h2 id="NotificationAction">type <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=2454:2882#L60">NotificationAction</a>
<h2 id="NotificationAction">type <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=2124:2552#L52">NotificationAction</a>
<a class="permalink" href="#NotificationAction">&#xb6;</a>


Expand Down Expand Up @@ -26338,7 +26331,7 @@ <h2 id="NotificationAction">type <a href="/src/github.com/maxence-charriere/go-a



<h2 id="NotificationPermission">type <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=3464:3498#L93">NotificationPermission</a>
<h2 id="NotificationPermission">type <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=3134:3168#L85">NotificationPermission</a>
<a class="permalink" href="#NotificationPermission">&#xb6;</a>


Expand Down Expand Up @@ -26379,7 +26372,7 @@ <h2 id="NotificationPermission">type <a href="/src/github.com/maxence-charriere/



<h2 id="NotificationService">type <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=4180:4213#L112">NotificationService</a>
<h2 id="NotificationService">type <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=3850:3883#L104">NotificationService</a>
<a class="permalink" href="#NotificationService">&#xb6;</a>


Expand All @@ -26401,7 +26394,7 @@ <h2 id="NotificationService">type <a href="/src/github.com/maxence-charriere/go-



<h3 id="NotificationService.New">func (NotificationService) <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=5063:5111#L142">New</a>
<h3 id="NotificationService.New">func (NotificationService) <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=4733:4781#L134">New</a>
<a class="permalink" href="#NotificationService.New">&#xb6;</a>


Expand All @@ -26414,7 +26407,7 @@ <h3 id="NotificationService.New">func (NotificationService) <a href="/src/github



<h3 id="NotificationService.Permission">func (NotificationService) <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=4283:4347#L115">Permission</a>
<h3 id="NotificationService.Permission">func (NotificationService) <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=3953:4017#L107">Permission</a>
<a class="permalink" href="#NotificationService.Permission">&#xb6;</a>


Expand All @@ -26427,7 +26420,7 @@ <h3 id="NotificationService.Permission">func (NotificationService) <a href="/src



<h3 id="NotificationService.RequestPermission">func (NotificationService) <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=4617:4688#L125">RequestPermission</a>
<h3 id="NotificationService.RequestPermission">func (NotificationService) <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=4287:4358#L117">RequestPermission</a>
<a class="permalink" href="#NotificationService.RequestPermission">&#xb6;</a>


Expand All @@ -26440,7 +26433,7 @@ <h3 id="NotificationService.RequestPermission">func (NotificationService) <a hre



<h3 id="NotificationService.Subscribe">func (NotificationService) <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=5390:5485#L150">Subscribe</a>
<h3 id="NotificationService.Subscribe">func (NotificationService) <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=5060:5155#L142">Subscribe</a>
<a class="permalink" href="#NotificationService.Subscribe">&#xb6;</a>


Expand All @@ -26457,7 +26450,7 @@ <h3 id="NotificationService.Subscribe">func (NotificationService) <a href="/src/



<h2 id="NotificationSubscription">type <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=2963:3365#L76">NotificationSubscription</a>
<h2 id="NotificationSubscription">type <a href="/src/github.com/maxence-charriere/go-app/v10/pkg/app/notification.go?s=2633:3035#L68">NotificationSubscription</a>
<a class="permalink" href="#NotificationSubscription">&#xb6;</a>


Expand Down
6 changes: 0 additions & 6 deletions pkg/app/gen/app-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ self.addEventListener("message", (event) => {

async function showNotification(registration, notification) {
const title = notification.title || "";
let delay = notification.delay || 0;

let actions = [];
for (let i in notification.actions) {
Expand All @@ -107,12 +106,7 @@ async function showNotification(registration, notification) {
};
delete notification.title;
delete notification.path;
delete notification.delay;

if (delay > 0) {
delay = Math.floor(delay / 1e6);
await sleep(delay);
}
await registration.showNotification(title, notification);
}

Expand Down
8 changes: 0 additions & 8 deletions pkg/app/notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package app

import (
"encoding/json"
"time"

"github.com/maxence-charriere/go-app/v10/pkg/errors"
)
Expand Down Expand Up @@ -55,13 +54,6 @@ type Notification struct {
// See: https://developer.mozilla.org/en-US/docs/Web/API/Vibration_API
Vibrate []int `json:"vibrate,omitempty"`

// Delay specifies how long to wait before displaying the notification.
//
// The duration is serialized as a Go time.Duration and interpreted
// client-side. Actual delivery time is best-effort and may be delayed
// further depending on browser and system constraints.
Delay time.Duration `json:"delay,omitempty"`

// Actions lists the available actions displayed within the notification.
Actions []NotificationAction `json:"actions,omitempty"`
}
Expand Down
Loading