From 460d90d9578a4031e182247ce62f4be58076399b Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Sat, 15 Jul 2017 01:32:06 +0200 Subject: [PATCH] Improved push notifications --- pages/notifications/notifications.go | 14 +++++++------- pages/settings/settings.pixy | 10 +++++----- scripts/Actions.ts | 10 ++++++---- scripts/AnimeNotifier.ts | 22 ++++++++++++++++++++-- scripts/PushManager.ts | 16 ++++++++++++++++ sw/service-worker.ts | 27 +++++++++++++++++++++++---- tests.go | 1 + 7 files changed, 78 insertions(+), 22 deletions(-) diff --git a/pages/notifications/notifications.go b/pages/notifications/notifications.go index 3f3d6c64..0ff4fc4d 100644 --- a/pages/notifications/notifications.go +++ b/pages/notifications/notifications.go @@ -1,10 +1,10 @@ package notifications import ( - "fmt" "net/http" "github.com/aerogo/aero" + "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/utils" ) @@ -16,13 +16,13 @@ func Test(ctx *aero.Context) string { return ctx.Error(http.StatusBadRequest, "Not logged in", nil) } - for _, sub := range user.PushSubscriptions().Items { - err := sub.SendNotification("Yay, it works!") - - if err != nil { - fmt.Println(err) - } + notification := &arn.Notification{ + Title: "Anime Notifier", + Message: "Yay, it works!", + Icon: "https://" + ctx.App.Config.Domain + "/images/brand/300", } + user.SendNotification(notification) + return "ok" } diff --git a/pages/settings/settings.pixy b/pages/settings/settings.pixy index b96a30cd..876347b7 100644 --- a/pages/settings/settings.pixy +++ b/pages/settings/settings.pixy @@ -26,19 +26,19 @@ component Settings(user *arn.User) Icon("bell") span Notifications - .widget-input + #enable-notifications.widget-input label Enable: button.action(data-action="enableNotifications", data-trigger="click") - Icon("toggle-on") + Icon("toggle-off") span Enable notifications - .widget-input + #disable-notifications.widget-input label Disable: button.action(data-action="disableNotifications", data-trigger="click") - Icon("toggle-off") + Icon("toggle-on") span Disable notifications - .widget-input + #test-notification.widget-input label Test: button.action(data-action="testNotification", data-trigger="click") Icon("paper-plane") diff --git a/scripts/Actions.ts b/scripts/Actions.ts index 2b38f95e..7b81702c 100644 --- a/scripts/Actions.ts +++ b/scripts/Actions.ts @@ -215,13 +215,15 @@ export function search(arn: AnimeNotifier, search: HTMLInputElement, e: Keyboard } // Enable notifications -export function enableNotifications(arn: AnimeNotifier, button: HTMLElement) { - arn.pushManager.subscribe(arn.user.dataset.id) +export async function enableNotifications(arn: AnimeNotifier, button: HTMLElement) { + await arn.pushManager.subscribe(arn.user.dataset.id) + arn.updatePushUI() } // Disable notifications -export function disableNotifications(arn: AnimeNotifier, button: HTMLElement) { - arn.pushManager.unsubscribe(arn.user.dataset.id) +export async function disableNotifications(arn: AnimeNotifier, button: HTMLElement) { + await arn.pushManager.unsubscribe(arn.user.dataset.id) + arn.updatePushUI() } // Test notification diff --git a/scripts/AnimeNotifier.ts b/scripts/AnimeNotifier.ts index 0c6db38c..ccceb9c0 100644 --- a/scripts/AnimeNotifier.ts +++ b/scripts/AnimeNotifier.ts @@ -111,7 +111,7 @@ export class AnimeNotifier { this.pushManager = new PushManager() } - onContentLoaded() { + async onContentLoaded() { // Stop watching all the objects from the previous page. this.visibilityObserver.disconnect() @@ -120,9 +120,11 @@ export class AnimeNotifier { Promise.resolve().then(() => this.lazyLoadImages()), Promise.resolve().then(() => this.displayLocalDates()), Promise.resolve().then(() => this.setSelectBoxValue()), - Promise.resolve().then(() => this.assignActions()) + Promise.resolve().then(() => this.assignActions()), + Promise.resolve().then(() => this.updatePushUI()) ]) + // Apply page title let headers = document.getElementsByTagName("h1") if(this.app.currentPath === "/" || headers.length === 0) { @@ -134,6 +136,22 @@ export class AnimeNotifier { } } + async updatePushUI() { + if(!this.pushManager.pushSupported) { + return + } + + let subscription = await this.pushManager.subscription() + + if(subscription) { + this.app.find("enable-notifications").style.display = "none" + this.app.find("disable-notifications").style.display = "flex" + } else { + this.app.find("enable-notifications").style.display = "flex" + this.app.find("disable-notifications").style.display = "none" + } + } + onIdle() { this.pushAnalytics() } diff --git a/scripts/PushManager.ts b/scripts/PushManager.ts index 671f6c8b..0f4195f8 100644 --- a/scripts/PushManager.ts +++ b/scripts/PushManager.ts @@ -5,6 +5,21 @@ export class PushManager { this.pushSupported = ("serviceWorker" in navigator) && ("PushManager" in window) } + async subscription(): Promise { + if(!this.pushSupported) { + return Promise.resolve(null) + } + + let registration = await navigator.serviceWorker.ready + let subscription = await registration.pushManager.getSubscription() + + if(subscription) { + return Promise.resolve(subscription) + } + + return Promise.resolve(null) + } + async subscribe(userId: string) { if(!this.pushSupported) { return @@ -59,6 +74,7 @@ export class PushManager { p256dh: key, auth: secret, platform: navigator.platform, + userAgent: navigator.userAgent, screen: { width: window.screen.width, height: window.screen.height diff --git a/sw/service-worker.ts b/sw/service-worker.ts index f888ab26..a1d9a31e 100644 --- a/sw/service-worker.ts +++ b/sw/service-worker.ts @@ -17,8 +17,25 @@ self.addEventListener("install", (evt: InstallEvent) => { self.addEventListener("activate", (evt: any) => { console.log("Service worker activate") + // Delete old cache + let cacheWhitelist = [CACHE] + + let deleteOldCache = caches.keys().then(keyList => { + return Promise.all(keyList.map(key => { + if(cacheWhitelist.indexOf(key) === -1) { + return caches.delete(key) + } + })) + }) + + let immediateClaim = (self as any).clients.claim() + + // Immediate claim evt.waitUntil( - (self as any).clients.claim() + Promise.all([ + deleteOldCache, + immediateClaim + ]) ) }) @@ -111,11 +128,13 @@ self.addEventListener("fetch", async (evt: FetchEvent) => { }) self.addEventListener("push", (evt: PushEvent) => { - var payload = evt.data ? evt.data.text() : "no payload" + var payload = evt.data ? evt.data.json() : {} evt.waitUntil( - (self as any).registration.showNotification("beta.notify.moe Service Worker", { - body: payload + (self as any).registration.showNotification(payload.title, { + body: payload.message, + icon: payload.icon, + image: payload.image }) ) }) diff --git a/tests.go b/tests.go index aae85607..48a1aadc 100644 --- a/tests.go +++ b/tests.go @@ -185,6 +185,7 @@ var routeTests = map[string][]string{ "/import/myanimelist/animelist/finish": nil, "/import/kitsu/animelist": nil, "/import/kitsu/animelist/finish": nil, + "/api/test/notification": nil, "/anime/:id/edit": nil, "/new/thread": nil, "/new/soundtrack": nil,