-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
119 lines (92 loc) · 2.6 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import {
createEventHook,
on_destroy,
toReadable,
toWritable,
unstore,
} from "@sveu/shared"
import type { EventHook } from "@sveu/shared"
import { on } from "../eventListener"
import { support } from "../support"
import type { WebNotificationOptions } from "../utils"
/**
* Reactive notification
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/notification
* @param options - options
*
* @example
* ```ts
* const { supported, notify, show, close, onClick, onShow, onError, onClose } = notification()
* ```
*
* @returns
* - `supported` - Whether the browser supports the Notification API.
* - `notify` - The notification instance.
* - `show` - Show the notification.
* - `close` - Close the notification.
* - `onClick` - The click event.
* - `onShow` - The show event.
* - `onError` - The error event.
* - `onClose` - The close event.
*/
export function notification(options: WebNotificationOptions = {}) {
const supported = support("Notification", "window")
const notification = toWritable<Notification | null>(null)
const on_click: EventHook = createEventHook<Event>()
const on_show: EventHook = createEventHook<Event>()
const on_error: EventHook = createEventHook<Event>()
const on_close: EventHook = createEventHook<Event>()
async function request_permission() {
if (!unstore(supported)) return
if (
"permission" in Notification &&
Notification.permission !== "denied"
)
await Notification.requestPermission()
}
function close() {
const n = unstore(notification)
if (n) n.close()
notification.set(null)
}
/**
* Show the notification.
*
* @param overrides - Overrides the default options.
*
* @returns The notification instance.
*/
async function show(overrides?: WebNotificationOptions) {
if (!unstore(supported)) return
await request_permission()
const _options = Object.assign({}, options, overrides)
notification.set(new Notification(_options.title || "", _options))
const n = unstore(notification)
if (n) {
n.onclick = (event: Event) => on_click.trigger(event)
n.onshow = (event: Event) => on_show.trigger(event)
n.onerror = (event: Event) => on_error.trigger(event)
n.onclose = (event: Event) => on_close.trigger(event)
return n
}
}
if (unstore(supported)) {
request_permission()
on(document, "visibilitychange", (e: Event) => {
e.preventDefault()
if (document.visibilityState === "visible") close()
})
}
on_destroy(close)
return {
supported,
notify: toReadable(notification),
show,
close,
onClick: on_click.on,
onShow: on_show.on,
onError: on_error.on,
onClose: on_close.on,
}
}