Skip to content

Commit 7660c92

Browse files
draft incoming call notification sample
1 parent 0afd76e commit 7660c92

File tree

2 files changed

+211
-0
lines changed

2 files changed

+211
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ last sync'd April 16, 2024
8888
| Selectlist demos | Demo page showing how the Open UI's `<selectlist>` element can be used. | [/selectlist/](https://github.com/MicrosoftEdge/Demos/tree/main/selectlist) | [Open UI's \<selectlist\> demos](https://microsoftedge.github.io/Demos/selectlist/) |
8989
| EditContext API demo | Demo page showing how the EditContext API can be used to build an advanced text editor. | [/edit-context/](https://github.com/MicrosoftEdge/Demos/tree/main/edit-context) | [HTML editor demo](https://microsoftedge.github.io/Demos/edit-context/) |
9090
| SVG support in the Async Clipboard API | Demo page showing how the Async Clipboard API supports SVG format. | [/svg-clipboard/](https://github.com/MicrosoftEdge/Demos/tree/main/svg-clipboard) | [SVG clipbard support demo](https://microsoftedge.github.io/Demos/svg-clipboard/) |
91+
| IndexedDB: getAllRecords() | Demo page showing how the newly proposed `getAllRecords` IndexedDB method differs from `getAll` and `getAllKeys`. | [/idb-getallrecords/](https://github.com/MicrosoftEdge/Demos/tree/main/idb-getallrecords) | [IndexedDB: getAllRecords()](https://microsoftedge.github.io/Demos/idb-getallrecords/) |
9192

9293

9394
## Adding a new demo
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Incoming Call Notifications API</title>
8+
<link rel="icon" type="image/png" href="https://edgestatic.azureedge.net/welcome/static/favicon.png">
9+
10+
<style>
11+
12+
</style>
13+
</head>
14+
15+
<body>
16+
<button onclick="requestPermission()">Request Permission</button>
17+
<button onclick="showServiceWorkerToast()">Show ServiceWorker Toast</button>
18+
<button onclick="showIncomingCallToast()">Show Incoming Call Toast</button>
19+
<button onclick="showToastHistory()">Show Toast History</button>
20+
<button onclick="clearToastHistory()">Clear Toast History</button>
21+
22+
<div id="permissionStatus"></div>
23+
<div id="log"></div><br />
24+
25+
<script>
26+
"use strict";
27+
28+
const logEl = document.getElementById("log");
29+
30+
let toastId = localStorage.getItem("toastId");
31+
if (toastId === null) {
32+
toastId = 1;
33+
localStorage.setItem("toastId", toastId);
34+
}
35+
36+
let registration = null;
37+
38+
function log(message) {
39+
logEl.innerHTML += `${message}<br>`;
40+
}
41+
42+
function logNotification(notification) {
43+
log(`<strong>${notification.title}</strong>`);
44+
log(notification.body);
45+
log("");
46+
}
47+
48+
function updatePermissionStatus() {
49+
document.getElementById("permissionStatus").innerHTML = `Notification Permission: ${Notification.permission}`;
50+
}
51+
52+
function requestPermission() {
53+
Notification.requestPermission()
54+
.then((result) => {
55+
updatePermissionStatus();
56+
log("requestPermission() succeeded");
57+
}).catch((error) => {
58+
log(`requestPermission() failed: ${error}.`);
59+
});
60+
}
61+
62+
let windowNotificationList = [];
63+
64+
function showToast() {
65+
const notification = new Notification(`Window Title ${++toastId}`, { body: `Window Body ${++toastId}`, tag: "jim-bagleaducia", icon: "../resources/happy.jpg", image: "../resources/happy.jpg", requireInteraction: false, silent: true });
66+
localStorage.setItem("toastId", toastId);
67+
windowNotificationList.push(notification);
68+
notification.onclick = () => {
69+
log(`Window 'click' event for: ${notification.title}, timestamp: ${new Date(notification.timestamp)}, requireInteraction: ${notification.requireInteraction}, silent: ${notification.silent}`);
70+
};
71+
notification.onerror = () => {
72+
log(`Window 'error' event for: ${notification.title}`);
73+
};
74+
notification.onshow = () => {
75+
log(`Window 'show' event for: ${notification.title}`);
76+
};
77+
notification.onclose = () => {
78+
log(`Window 'close' event for: ${notification.title}`);
79+
};
80+
}
81+
82+
function closeToast() {
83+
windowNotificationList.forEach((toast) => {
84+
toast.close();
85+
});
86+
windowNotificationList = [];
87+
}
88+
89+
function showToastWithInvalidImage() {
90+
const notification = new Notification(`Window Title ${++toastId}`, { body: `Window Body ${++toastId}`, icon: "../resources/happy2.jpg", requireInteraction: false, silent: true });
91+
notification.onclick = () => {
92+
log(`Window 'click' event for: ${notification.title}, timestamp: ${new Date(notification.timestamp)}, requireInteraction: ${notification.requireInteraction}, silent: ${notification.silent}`);
93+
};
94+
notification.onerror = () => {
95+
log(`Window 'error' event for: ${notification.title}`);
96+
};
97+
}
98+
99+
navigator.serviceWorker.register("service-worker.js", { scope: '/repro_pages/notifications/' })
100+
.then((result) => {
101+
registration = result;
102+
log("register() succeeded");
103+
}).catch((error) => {
104+
log(`register() failed: ${error}.`);
105+
});
106+
107+
navigator.serviceWorker.onmessage = (messageEvent) => {
108+
log(messageEvent.data);
109+
}
110+
111+
function showServiceWorkerToast() {
112+
if (registration !== null) {
113+
registration.showNotification(`ServiceWorker Title ${++toastId}`, { body: `ServiceWorker Body: ${toastId}`, icon: "../resources/happy.jpg", actions: [{ action: "open_window", title: "Open New Window" }, { action: "focus", title: "Focus Existing Window" }] })
114+
.then(() => {
115+
log("showNotification() succeeded");
116+
}).catch((error) => {
117+
log(`showNotification() failed: ${error}.`);
118+
});
119+
}
120+
}
121+
122+
function showServiceWorkerToastWithTag() {
123+
if (registration !== null) {
124+
registration.showNotification(`ServiceWorker Title with Tag ${++toastId}`, { body: `ServiceWorker Body: Tag ${toastId}`, icon: "../resources/happy.jpg", requireInteraction: false, silent: true, tag: "ServiceWorkerTag" })
125+
.then(() => {
126+
log("showNotification() succeeded");
127+
}).catch((error) => {
128+
log(`showNotification() failed: ${error}.`);
129+
});
130+
}
131+
}
132+
133+
function showServiceWorkerToastWithTagWithRenotify() {
134+
if (registration !== null) {
135+
registration.showNotification(`ServiceWorker Title with Tag with renotify ${++toastId}`, { body: `ServiceWorker Body: Tag with renotify ${toastId}`, icon: "../resources/happy.jpg", requireInteraction: false, silent: true, tag: "ServiceWorkerTagWithoutRenotify", renotify: true })
136+
.then(() => {
137+
log("showNotification() succeeded");
138+
}).catch((error) => {
139+
log(`showNotification() failed: ${error}.`);
140+
});
141+
}
142+
}
143+
144+
function showServiceWorkerGlobalScopeToast() {
145+
if (navigator.serviceWorker.controller !== null) {
146+
navigator.serviceWorker.controller.postMessage(++toastId);
147+
}
148+
}
149+
150+
const dedicatedWorker = new Worker("dedicated-worker.js");
151+
dedicatedWorker.onmessage = (messageEvent) => {
152+
log(messageEvent.data);
153+
}
154+
155+
function showDedicatedWorkerToast() {
156+
dedicatedWorker.postMessage(++toastId);
157+
}
158+
159+
function closeDedicatedWorkerToast() {
160+
dedicatedWorker.postMessage("close");
161+
}
162+
163+
function showIncomingCallToast() {
164+
if (registration !== null) {
165+
registration.showNotification(`IncomingCall Title ${++toastId}`, { body: `ServiceWorker Body: ${toastId}`, icon: "../resources/happy.jpg", scenario: "incoming-call", actions: [{ action: "accept-audio-call", title: "audio" }, { action: "accept-video-call", title: "video" }] })
166+
.then(() => {
167+
log("showNotification() succeeded");
168+
}).catch((error) => {
169+
log(`showNotification() failed: ${error}.`);
170+
});
171+
}
172+
}
173+
174+
function showToastHistory() {
175+
if (registration !== null) {
176+
registration.getNotifications()
177+
.then((resultList) => {
178+
log(`Found <b>${resultList.length}</b> notifications:`)
179+
log("");
180+
181+
resultList.forEach((notification) => {
182+
logNotification(notification);
183+
});
184+
}).catch((error) => {
185+
log(`getNotifications() failed: ${error}.`);
186+
});
187+
}
188+
}
189+
190+
function clearToastHistory() {
191+
if (registration !== null) {
192+
registration.getNotifications()
193+
.then((resultList) => {
194+
log(`Clearing <b>${resultList.length}</b> notifications!`)
195+
196+
resultList.forEach((notification) => {
197+
notification.close();
198+
});
199+
}).catch((error) => {
200+
log(`getNotifications() failed: ${error}.`);
201+
});
202+
}
203+
}
204+
205+
updatePermissionStatus();
206+
207+
</script>
208+
</body>
209+
210+
</html>

0 commit comments

Comments
 (0)