-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
feat(notification): add service worker support for `@ng-web-apis/noti…
…fication`
- Loading branch information
1 parent
c115836
commit c79b71d
Showing
14 changed files
with
242 additions
and
18 deletions.
There are no files selected for viewing
1 change: 1 addition & 0 deletions
1
apps/demo/src/app/pages/notification/examples/03-close-notification/index.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import {inject, InjectionToken} from '@angular/core'; | ||
import {NAVIGATOR} from './navigator'; | ||
|
||
export const SERVICE_WORKER = new InjectionToken( | ||
`An abstraction over window.navigator.serviceWorker object`, | ||
{ | ||
factory: () => inject(NAVIGATOR).serviceWorker, | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import {inject, InjectFlags, InjectionToken} from '@angular/core'; | ||
import {SwPush} from '@angular/service-worker'; | ||
import {NEVER} from 'rxjs'; | ||
|
||
export const NOTIFICATION_SW_CLICKS = new InjectionToken( | ||
`Global listener for events when ANY system notification spawned by Notification API (and only inside Service Worker!) has been clicked`, | ||
{ | ||
factory: () => { | ||
const swPush = inject(SwPush, InjectFlags.Optional); | ||
|
||
return swPush && swPush.isEnabled ? swPush.notificationClicks : NEVER; | ||
}, | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import {inject, InjectionToken, NgZone} from '@angular/core'; | ||
import {ANIMATION_FRAME, SERVICE_WORKER} from '@ng-web-apis/common'; | ||
import { | ||
combineLatest, | ||
filter, | ||
from, | ||
map, | ||
NEVER, | ||
Observable, | ||
pairwise, | ||
share, | ||
switchMap, | ||
} from 'rxjs'; | ||
import {zoneOptimized} from '../utils/zone'; | ||
|
||
export const NOTIFICATION_SW_CLOSES = new InjectionToken( | ||
`Global listener for events when ANY system notification spawned by Notification API (and only inside Service Worker!) has been closed`, | ||
{ | ||
/** | ||
* TODO: refactor the token's factory after this issue will be solved: | ||
* https://github.com/angular/angular/issues/52244 | ||
* ``` | ||
* const swPush = inject(SwPush, InjectFlags.Optional); | ||
* return swPush && swPush.isEnabled ? swPush.notificationCloses : NEVER; | ||
* ``` | ||
*/ | ||
factory: (): Observable<Notification> => { | ||
return combineLatest([ | ||
from(inject(SERVICE_WORKER).getRegistration()), | ||
inject(ANIMATION_FRAME), | ||
]).pipe( | ||
switchMap(([reg]) => (reg ? from(reg.getNotifications()) : NEVER)), | ||
pairwise(), | ||
filter(([prev, cur]) => prev.length > cur.length), | ||
map( | ||
([prev, cur]) => | ||
prev.find((notification, i) => notification !== cur[i])!, | ||
), | ||
zoneOptimized(inject(NgZone)), | ||
share(), | ||
); | ||
}, | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import {inject, InjectionToken} from '@angular/core'; | ||
import {SERVICE_WORKER} from '@ng-web-apis/common'; | ||
|
||
export const NOTIFICATION_FACTORY = new InjectionToken( | ||
'An async function to create Notification using Notification API (with and without service worker)', | ||
{ | ||
factory: () => { | ||
const sw = inject(SERVICE_WORKER); | ||
|
||
return async ( | ||
...args: ConstructorParameters<typeof Notification> | ||
): Promise<Notification> => { | ||
const registration = await sw.getRegistration(); | ||
|
||
if (registration) { | ||
await registration.showNotification(...args); | ||
|
||
const notifications = await registration.getNotifications(); | ||
|
||
return notifications[notifications.length - 1]; | ||
} else { | ||
return new Notification(...args); | ||
} | ||
}; | ||
}, | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import type {InjectionToken} from '@angular/core'; | ||
|
||
// TODO: discuss with team what should we do with this code duplication | ||
// Could we use `@taiga-ui/cdk` inside `@ng-web-apis/notification` ? | ||
|
||
export type InjectionTokenType<Token> = Token extends InjectionToken<infer T> ? T : never; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import {NgZone} from '@angular/core'; | ||
import {MonoTypeOperatorFunction, Observable, pipe} from 'rxjs'; | ||
|
||
// TODO: discuss with team what should we do with this code duplication | ||
// Could we use `@taiga-ui/cdk` inside `@ng-web-apis/notification` ? | ||
|
||
export function zonefree<T>(zone: NgZone): MonoTypeOperatorFunction<T> { | ||
return source => | ||
new Observable(subscriber => | ||
zone.runOutsideAngular(() => source.subscribe(subscriber)), | ||
); | ||
} | ||
|
||
export function zonefull<T>(zone: NgZone): MonoTypeOperatorFunction<T> { | ||
return source => | ||
new Observable(subscriber => | ||
source.subscribe({ | ||
next: value => zone.run(() => subscriber.next(value)), | ||
error: (error: unknown) => zone.run(() => subscriber.error(error)), | ||
complete: () => zone.run(() => subscriber.complete()), | ||
}), | ||
); | ||
} | ||
|
||
export function zoneOptimized<T>(zone: NgZone): MonoTypeOperatorFunction<T> { | ||
return pipe(zonefree(zone), zonefull(zone)); | ||
} |