Add push notifications for forgotten departures #26
|
@ -13,25 +13,27 @@
|
||||||
'departure': 'I have cleaned my workspace'
|
'departure': 'I have cleaned my workspace'
|
||||||
}
|
}
|
||||||
var testCheckBox = '<label class="checkbox"><input type="checkbox" name="tested" id="tested"><span>I have been tested negative for COVID in the last 24 hours</span></label>'
|
var testCheckBox = '<label class="checkbox"><input type="checkbox" name="tested" id="tested"><span>I have been tested negative for COVID in the last 24 hours</span></label>'
|
||||||
|
var editTimeBox = '<label>Departure Date/Time:<input type="datetime-local" name="datetime" id="datetime" required></label>'
|
||||||
function getParams() {
|
function getParams() {
|
||||||
var h = document.location.href
|
var qparams = document.location.search.substr(1)
|
||||||
var qparam = h.split('?')[1] || null
|
if (qparams == "") return {}
|
||||||
if (qparam == null)
|
qparams = qparams.split('&')
|
||||||
return null
|
var qps = {}
|
||||||
|
for (var qparam of qparams) {
|
||||||
var vals = qparam.split('=')
|
var vals = qparam.split('=')
|
||||||
if (vals.length < 2 || !cbt.hasOwnProperty(vals[0]))
|
qps[vals[0]] = vals[1] || null
|
||||||
return null
|
|
||||||
return {
|
|
||||||
action: vals[0],
|
|
||||||
room: vals[1]
|
|
||||||
}
|
}
|
||||||
|
// Backwards compat
|
||||||
|
if (qps.arrival) {qps.action = 'arrival'; qps.room = qps.arrival}
|
||||||
|
if (qps.departure) {qps.action = 'departure'; qps.room = qps.departure}
|
||||||
|
return qps
|
||||||
}
|
}
|
||||||
var qp = getParams()
|
var qp = getParams()
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1><script>
|
<h1><script>
|
||||||
document.write(qp ? (qp.action + "<br>Room " + qp.room) : 'FTracker<br>V1')
|
document.write(qp.action ? (qp.action + "<br>Room " + qp.room) : 'FTracker<br>V1')
|
||||||
</script></h1>
|
</script></h1>
|
||||||
<div id="startpage">
|
<div id="startpage">
|
||||||
This is a web app to track which people
|
This is a web app to track which people
|
||||||
|
@ -56,6 +58,10 @@
|
||||||
Full Name:<br>
|
Full Name:<br>
|
||||||
<input type="text" name="name" id="name" placeholder="John Doe" required>
|
<input type="text" name="name" id="name" placeholder="John Doe" required>
|
||||||
</label>
|
</label>
|
||||||
|
<script>
|
||||||
|
if (qp.edittime && qp.edittime == 1)
|
||||||
|
document.write(editTimeBox)
|
||||||
|
</script>
|
||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
<input type="checkbox" name="agree" id="agree" required>
|
<input type="checkbox" name="agree" id="agree" required>
|
||||||
<span><script>
|
<span><script>
|
||||||
|
@ -63,7 +69,7 @@
|
||||||
</script></span>
|
</script></span>
|
||||||
</label>
|
</label>
|
||||||
<script>
|
<script>
|
||||||
if (qp && qp.action == 'arrival')
|
if (qp.action && qp.action == 'arrival')
|
||||||
document.write(testCheckBox)
|
document.write(testCheckBox)
|
||||||
</script>
|
</script>
|
||||||
<input type="submit">
|
<input type="submit">
|
||||||
|
|
99
web/main.js
99
web/main.js
|
@ -1,7 +1,9 @@
|
||||||
|
var pushServerPublicKey = 'BBwBPYxhogHLU3B1FpxfQNzO3q7qZpmD1n1KaaL8WJbcVmJSHhi1uB-VmvsVjjUHWYCeqKyLT7w-1LBfpIcbbcg'
|
||||||
|
|
||||||
var spage = document.getElementById('startpage')
|
var spage = document.getElementById('startpage')
|
||||||
var mform = document.getElementById('mainform')
|
var mform = document.getElementById('mainform')
|
||||||
|
|
||||||
if (qp) {
|
if (qp.action) {
|
||||||
spage.style.display = 'none'
|
spage.style.display = 'none'
|
||||||
mform.style.display = 'block'
|
mform.style.display = 'block'
|
||||||
}
|
}
|
||||||
|
@ -12,18 +14,26 @@ if (savedName && qp)
|
||||||
document.getElementById('name').value = savedName
|
document.getElementById('name').value = savedName
|
||||||
|
|
||||||
// 2nd script, server API communication
|
// 2nd script, server API communication
|
||||||
var name, agreed, tested
|
var name, datetime, agreed, tested
|
||||||
mform.onsubmit = function(e) {
|
mform.onsubmit = function(e) {
|
||||||
|
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
name = e.srcElement[0].value
|
var i = 0;
|
||||||
agreed = e.srcElement[1].checked
|
name = e.srcElement[i++].value
|
||||||
if (e.srcElement.length > 2)
|
if (qp.edittime && qp.edittime == 1) {
|
||||||
tested = e.srcElement[2].checked
|
var value = e.srcElement[i++].value
|
||||||
|
datetime = new Date(value).toISOString()
|
||||||
|
}
|
||||||
|
agreed = e.srcElement[i++].checked
|
||||||
|
if (qp.action && qp.action == 'arrival')
|
||||||
|
tested = e.srcElement[i++].checked
|
||||||
|
|
||||||
|
|
||||||
sendMainData()
|
sendMainData()
|
||||||
|
|
||||||
|
initPush(name)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendMainData() {
|
function sendMainData() {
|
||||||
|
@ -33,11 +43,13 @@ function sendMainData() {
|
||||||
{
|
{
|
||||||
'room': qp.room,
|
'room': qp.room,
|
||||||
'name': name,
|
'name': name,
|
||||||
|
'arrival': datetime,
|
||||||
'agreetoguidelines': agreed,
|
'agreetoguidelines': agreed,
|
||||||
'tested': tested
|
'tested': tested
|
||||||
} :
|
} :
|
||||||
{
|
{
|
||||||
'name': name,
|
'name': name,
|
||||||
|
'departure': datetime,
|
||||||
'cleanedworkspace': agreed
|
'cleanedworkspace': agreed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +171,7 @@ function handleRequest(res) {
|
||||||
<form id="reqform">
|
<form id="reqform">
|
||||||
<label>
|
<label>
|
||||||
${reqt[json.request]}
|
${reqt[json.request]}
|
||||||
<input type="datetime-local" id="datetime" ${minD} max="${now}" required>
|
<input type="datetime-local" ${minD} max="${now}" required>
|
||||||
${aInfo}
|
${aInfo}
|
||||||
</label>
|
</label>
|
||||||
${doubleT}
|
${doubleT}
|
||||||
|
@ -179,3 +191,76 @@ function handleRequest(res) {
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (qp.edittime && qp.edittime == 1) {
|
||||||
|
var now = localISOTimeMinutes(new Date())
|
||||||
|
document.getElementById('datetime').value = now;
|
||||||
|
document.getElementById('datetime').max = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Push Notifications */
|
||||||
|
|
||||||
|
function sendNotification() {
|
||||||
|
|
||||||
|
navigator.serviceWorker.ready.then(function(serviceWorker) {
|
||||||
|
serviceWorker.showNotification("Forgot to sign out?", {
|
||||||
|
body: "You didn't sign out of ftracker yet",
|
||||||
|
icon: "/favicon.ico",
|
||||||
|
actions: [{
|
||||||
|
action: "depart",
|
||||||
|
title: "Sign Out"
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function initPush(name) {
|
||||||
|
|
||||||
|
// Check availability
|
||||||
|
var supported = "serviceWorker" in navigator && "PushManager" in window
|
||||||
|
if (!supported) {
|
||||||
|
console.warn("Push Notifications not supported!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register service worker
|
||||||
|
navigator.serviceWorker.register("/sw.js").then(function(swRegistration) {
|
||||||
|
console.log("ServiceWorker registered:", swRegistration)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Request permission
|
||||||
|
// TODO: Only do this AFTER the first? SUCCESSFUL sign-in
|
||||||
|
Notification.requestPermission(function(result) {
|
||||||
|
return (result === 'granted')
|
||||||
|
}).then(function(consent) {
|
||||||
|
console.log('Notifications', consent ? 'enabled' : 'denied');
|
||||||
|
})
|
||||||
|
|
||||||
|
// Check if already initialized
|
||||||
|
if (localStorage.getItem('pushsub'))
|
||||||
|
return
|
||||||
|
|
||||||
|
// Register push service
|
||||||
|
navigator.serviceWorker.ready.then(function(serviceWorker) {
|
||||||
|
serviceWorker.pushManager.subscribe({
|
||||||
|
userVisibleOnly: true,
|
||||||
|
applicationServerKey: pushServerPublicKey
|
||||||
|
}).then(function(subscription) {
|
||||||
|
console.log("User is subscribed:", subscription);
|
||||||
|
localStorage.setItem('pushsub', subscription);
|
||||||
|
|
||||||
|
fetch('/pushsubscribe', {
|
||||||
|
method: "POST",
|
||||||
|
headers: {"Content-Type": "application/json"},
|
||||||
|
body: JSON.stringify({
|
||||||
|
name: name,
|
||||||
|
sub: subscription
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
function receivePushNotification(event) {
|
||||||
|
|
||||||
|
var data = event.data.json();
|
||||||
|
|
||||||
|
console.log("[Service Worker] Push Received:", data)
|
||||||
|
|
||||||
|
var room = data.arr ? data.arr.room : 'test'
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
data: `/?departure=${room}&edittime=1`,
|
||||||
|
body: data.body,
|
||||||
|
icon: "/favicon.ico",
|
||||||
|
actions: [{
|
||||||
|
action: "depart",
|
||||||
|
title: "Sign Out"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
event.waitUntil(self.registration.showNotification(data.title, options))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
self.addEventListener("push", receivePushNotification)
|
||||||
|
|
||||||
|
|
||||||
|
function openPushNotification(event) {
|
||||||
|
|
||||||
|
console.log("[Service Worker] Notification click Received.", event.notification.data)
|
||||||
|
|
||||||
|
event.notification.close()
|
||||||
|
event.waitUntil(clients.openWindow(event.notification.data))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
self.addEventListener("notificationclick", openPushNotification)
|
Loading…
Reference in New Issue