Skip to content

Instantly share code, notes, and snippets.

@shahryarjb
Last active October 14, 2022 16:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save shahryarjb/34ce794cbabb266f2dc86e0c3d534007 to your computer and use it in GitHub Desktop.
Save shahryarjb/34ce794cbabb266f2dc86e0c3d534007 to your computer and use it in GitHub Desktop.
app.js
var deferredPrompt;
var enableNotificationsButtons = document.querySelectorAll('.enable-notifications');
if (!window.Promise) {
window.Promise = Promise;
}
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/sw.js')
.then(function () {
console.log('Service worker registered!');
})
.catch(function (err) {
console.log(err);
});
}
window.addEventListener('beforeinstallprompt', function (event) {
console.log('beforeinstallprompt fired');
event.preventDefault();
deferredPrompt = event;
return false;
});
function displayConfirmNotification() {
if ('serviceWorker' in navigator) {
var options = {
body: 'You successfully subscribed to our Notification service!',
icon: '/src/images/icons/app-icon-96x96.png',
image: '/src/images/sf-boat.jpg',
dir: 'ltr',
lang: 'en-US', // BCP 47,
vibrate: [100, 50, 200],
badge: '/src/images/icons/app-icon-96x96.png',
tag: 'confirm-notification',
renotify: true,
actions: [
{ action: 'confirm', title: 'Okay', icon: '/src/images/icons/app-icon-96x96.png' },
{ action: 'cancel', title: 'Cancel', icon: '/src/images/icons/app-icon-96x96.png' },
],
};
navigator.serviceWorker.ready.then(function (swreg) {
swreg.showNotification('Successfully subscribed!', options);
});
}
}
function configurePushSub() {
if (!('serviceWorker' in navigator)) {
return;
}
var reg;
navigator.serviceWorker.ready
.then(function (swreg) {
reg = swreg;
return swreg.pushManager.getSubscription();
})
.then(function (sub) {
if (sub === null) {
// Create a new subscription
var vapidPublicKey = 'YOUR_PUBLIC_CODE';
var convertedVapidPublicKey = urlBase64ToUint8Array(vapidPublicKey);
return reg.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: convertedVapidPublicKey,
});
} else {
// We have a subscription
}
})
.then(function (newSub) {
return fetch('YOUR_DB', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify(newSub),
});
})
.then(function (res) {
if (res.ok) {
displayConfirmNotification();
}
})
.catch(function (err) {
console.log(err);
});
}
function askForNotificationPermission() {
Notification.requestPermission(function (result) {
console.log('User Choice', result);
if (result !== 'granted') {
console.log('No notification permission granted!');
} else {
configurePushSub();
// displayConfirmNotification();
}
});
}
if ('Notification' in window && 'serviceWorker' in navigator) {
for (var i = 0; i < enableNotificationsButtons.length; i++) {
enableNotificationsButtons[i].style.display = 'inline-block';
enableNotificationsButtons[i].addEventListener('click', askForNotificationPermission);
}
}
importScripts('/src/js/idb.js');
importScripts('/src/js/utility.js');
var CACHE_STATIC_NAME = 'static-v30';
var CACHE_DYNAMIC_NAME = 'dynamic-v2';
var STATIC_FILES = [
'/',
'/index.html',
'/offline.html',
'/src/js/app.js',
'/src/js/feed.js',
'/src/js/idb.js',
'/src/js/promise.js',
'/src/js/fetch.js',
'/src/js/material.min.js',
'/src/css/app.css',
'/src/css/feed.css',
'/src/images/main-image.jpg',
'https://fonts.googleapis.com/css?family=Roboto:400,700',
'https://fonts.googleapis.com/icon?family=Material+Icons',
'https://cdnjs.cloudflare.com/ajax/libs/material-design-lite/1.3.0/material.indigo-pink.min.css'
];
// function trimCache(cacheName, maxItems) {
// caches.open(cacheName)
// .then(function (cache) {
// return cache.keys()
// .then(function (keys) {
// if (keys.length > maxItems) {
// cache.delete(keys[0])
// .then(trimCache(cacheName, maxItems));
// }
// });
// })
// }
self.addEventListener('install', function (event) {
console.log('[Service Worker] Installing Service Worker ...', event);
event.waitUntil(
caches.open(CACHE_STATIC_NAME)
.then(function (cache) {
console.log('[Service Worker] Precaching App Shell');
cache.addAll(STATIC_FILES);
})
)
});
self.addEventListener('activate', function (event) {
console.log('[Service Worker] Activating Service Worker ....', event);
event.waitUntil(
caches.keys()
.then(function (keyList) {
return Promise.all(keyList.map(function (key) {
if (key !== CACHE_STATIC_NAME && key !== CACHE_DYNAMIC_NAME) {
console.log('[Service Worker] Removing old cache.', key);
return caches.delete(key);
}
}));
})
);
return self.clients.claim();
});
function isInArray(string, array) {
var cachePath;
if (string.indexOf(self.origin) === 0) { // request targets domain where we serve the page from (i.e. NOT a CDN)
console.log('matched ', string);
cachePath = string.substring(self.origin.length); // take the part of the URL AFTER the domain (e.g. after localhost:8080)
} else {
cachePath = string; // store the full request (for CDNs)
}
return array.indexOf(cachePath) > -1;
}
self.addEventListener('fetch', function (event) {
var url = 'https://pwagram-99adf.firebaseio.com/posts';
if (event.request.url.indexOf(url) > -1) {
event.respondWith(fetch(event.request)
.then(function (res) {
var clonedRes = res.clone();
clearAllData('posts')
.then(function () {
return clonedRes.json();
})
.then(function (data) {
for (var key in data) {
writeData('posts', data[key])
}
});
return res;
})
);
} else if (isInArray(event.request.url, STATIC_FILES)) {
event.respondWith(
caches.match(event.request)
);
} else {
event.respondWith(
caches.match(event.request)
.then(function (response) {
if (response) {
return response;
} else {
return fetch(event.request)
.then(function (res) {
return caches.open(CACHE_DYNAMIC_NAME)
.then(function (cache) {
// trimCache(CACHE_DYNAMIC_NAME, 3);
cache.put(event.request.url, res.clone());
return res;
})
})
.catch(function (err) {
return caches.open(CACHE_STATIC_NAME)
.then(function (cache) {
if (event.request.headers.get('accept').includes('text/html')) {
return cache.match('/offline.html');
}
});
});
}
})
);
}
});
// self.addEventListener('fetch', function(event) {
// event.respondWith(
// caches.match(event.request)
// .then(function(response) {
// if (response) {
// return response;
// } else {
// return fetch(event.request)
// .then(function(res) {
// return caches.open(CACHE_DYNAMIC_NAME)
// .then(function(cache) {
// cache.put(event.request.url, res.clone());
// return res;
// })
// })
// .catch(function(err) {
// return caches.open(CACHE_STATIC_NAME)
// .then(function(cache) {
// return cache.match('/offline.html');
// });
// });
// }
// })
// );
// });
// self.addEventListener('fetch', function(event) {
// event.respondWith(
// fetch(event.request)
// .then(function(res) {
// return caches.open(CACHE_DYNAMIC_NAME)
// .then(function(cache) {
// cache.put(event.request.url, res.clone());
// return res;
// })
// })
// .catch(function(err) {
// return caches.match(event.request);
// })
// );
// });
// Cache-only
// self.addEventListener('fetch', function (event) {
// event.respondWith(
// caches.match(event.request)
// );
// });
// Network-only
// self.addEventListener('fetch', function (event) {
// event.respondWith(
// fetch(event.request)
// );
// });
self.addEventListener('sync', function(event) {
console.log('[Service Worker] Background syncing', event);
if (event.tag === 'sync-new-posts') {
console.log('[Service Worker] Syncing new Posts');
event.waitUntil(
readAllData('sync-posts')
.then(function(data) {
for (var dt of data) {
fetch('YOUR_DB', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
id: dt.id,
title: dt.title,
location: dt.location,
image: 'https://firebasestorage.googleapis.com/v0/b/pwagram-99adf.appspot.com/o/sf-boat.jpg?alt=media&token=19f4770c-fc8c-4882-92f1-62000ff06f16'
})
})
.then(function(res) {
console.log('Sent data', res);
if (res.ok) {
res.json()
.then(function(resData) {
deleteItemFromData('sync-posts', resData.id);
});
}
})
.catch(function(err) {
console.log('Error while sending data', err);
});
}
})
);
}
});
self.addEventListener('notificationclick', function(event) {
var notification = event.notification;
var action = event.action;
console.log(notification);
if (action === 'confirm') {
console.log('Confirm was chosen');
notification.close();
} else {
console.log(action);
event.waitUntil(
clients.matchAll()
.then(function(clis) {
var client = clis.find(function(c) {
return c.visibilityState === 'visible';
});
if (client !== undefined) {
client.navigate(notification.data.url);
client.focus();
} else {
clients.openWindow(notification.data.url);
}
notification.close();
})
);
}
});
self.addEventListener('notificationclose', function(event) {
console.log('Notification was closed', event);
});
self.addEventListener('push', function(event) {
console.log('Push Notification received', JSON.parse(event.data.text()));
var data = {title: 'New!', content: 'Something new happened!', openUrl: '/'};
if (event.data) {
data = JSON.parse(event.data.text());
}
var options = {
body: data.content,
icon: '/src/images/icons/app-icon-96x96.png',
badge: '/src/images/icons/app-icon-96x96.png',
data: {
url: data.openUrl
}
};
event.waitUntil(
self.registration.showNotification(data.title, options)
);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment