Commit acf85360 authored by pwatraining's avatar pwatraining

starter

parent 5f17c013
......@@ -13,7 +13,6 @@
<title>PWATraining</title>
<link rel="shortcut icon" href="/favicon.ico">
<link rel="manifest" href="/manifest.json">
<link rel="canonical" href="https://uitmpwatraining.web.app/">
......
......@@ -2,25 +2,22 @@
'use strict';
var app = {
registration: null,
visibleEl: null,
state: null,
registration: null,
visibleEl: null,
state: null,
publicVapidKey: 'BAjGFaPYEOqObLkJr0ToM_S2ZDmi0xNZ6EHwtiVwhEUV7Ji9kgGsXrJOVvrlk2UE2oE4s1jTIvAL3r-vkix7rxs',
pushAppName: document.querySelector('.header__title').textContent,
appName: document.querySelector('.header__title').innerHTML,
appName: document.querySelector('.header__title').innerHTML,
isLoading: true,
daysOfWeek: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
daysOfWeek: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
page: document.querySelector('.container'),
spinner: document.querySelector('.loader'),
page: document.querySelector('.container'),
spinner: document.querySelector('.loader'),
popupBox: document.querySelector('.dialog-container'),
fsMsg: document.querySelector('.fs-message'),
toast: document.querySelector('.toast__container'),
pwahomescreen: document.querySelector('.pwahomescreen'),
buttonInstall: document.getElementById('installpwa')
fsMsg: document.querySelector('.fs-message'),
toast: document.querySelector('.toast__container'),
pwahomescreen: document.querySelector('.pwahomescreen'),
buttonInstall: document.getElementById('installpwa')
};
/*****************************************************************************
......@@ -139,166 +136,26 @@
};
app.registerPush = async function() {
toast('Subcribed for push notification.');
console.info('Registering push...');
const subscription = await app.registration.pushManager.
subscribe({
userVisibleOnly: true,
applicationServerKey: app.urlBase64ToUint8Array(app.publicVapidKey)
});
console.info('Push registered.');
console.info('Sending initial push...');
await fetch('https://api.afb.my/webpush', {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({regtoken: app.pushAppName, clientid: subscription})
})
.then(function(response) {
if (!response.ok) {
localStorage.setItem("subWebPush", 0);
document.querySelector('#toggle').checked = false;
throw new Error('Bad status code from server.');
}
return response.json();
})
.then(function(responseData) {
if (!(responseData.success)) {
localStorage.setItem("subWebPush", 0);
document.querySelector('#toggle').checked = false;
throw new Error('Bad response from server.');
}
else {
localStorage.setItem("subWebPush", 1);
localStorage.setItem("subEntry", JSON.stringify(subscription));
toast('To be implemented.');
}
});
console.info('Respond received.');
};
app.unregisterPush = function() {
toast('Push notification is cancelled.');
app.registration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription) {
console.info('Unregister push...');
fetch('https://api.afb.my/webpush/removeme', {
method: 'DELETE',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({regtoken: app.pushAppName, clientid: subscription})
})
.then(function(response) {
if (!response.ok) {
throw new Error('Bad status code from server.');
}
return response.json();
})
.then(function(responseData) {
if (!(responseData.success)) {
throw new Error('Bad response from server.');
}
else {
localStorage.setItem("subWebPush", 0);
console.info('Unsubscribed from push notification.');
}
});
return subscription.unsubscribe();
}
else {
localStorage.setItem("subWebPush", 0);
console.info('Subscription not found.');
}
toast('To be implemented.');
})
.catch(function(error) {
throw new Error('Error unsubscribing', error);
});
};
app.updateSubscriptionToTheServer = async function(subscription) {
console.info('Updating subscription...');
await fetch('https://api.afb.my/webpush/updateme', {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({regtoken: app.pushAppName, clientid: subscription})
})
.then(function(response) {
if (!response.ok) {
localStorage.setItem("subWebPush", 0);
document.querySelector('#toggle').checked = false;
throw new Error('Bad status code from server.');
}
return response.json();
})
.then(function(responseData) {
if (!(responseData.success)) {
localStorage.setItem("subWebPush", 0);
document.querySelector('#toggle').checked = false;
throw new Error('Bad response from server.');
}
else {
localStorage.setItem("subWebPush", 1);
localStorage.setItem("subEntry", JSON.stringify(subscription));
document.querySelector('#toggle').checked = true;
}
});
console.info('Subscription updated.');
};
app.askPermission = function() {
return new Promise(function(resolve, reject) {
var permissionResult = Notification.requestPermission(function(result) {
resolve(result);
});
if (permissionResult) {
permissionResult.then(resolve, reject);
}
})
.then(function(permissionResult) {
if (permissionResult !== 'granted') {
document.querySelector('#toggle').checked = false;
throw new Error('We weren\'t granted permission.');
}
else {
app.registerPush();
}
});
};
app.subWebPush = function() {
//unsubscribe
if (Notification.permission === "granted" && localStorage.getItem("subWebPush")==1) {
app.unregisterPush();
}
else if (Notification.permission === "denied") {
document.querySelector('#toggle').checked = false;
toast("Please allow notification in your<br>browser's setting first.");
console.info("Notifications permission has been blocked. Please allow notification in your browser's setting first.");
}
//requestPermission
else {
app.askPermission();
}
};
app.installPromotion = function(show = true) {
......@@ -328,25 +185,7 @@
};
app.updateOnlineStatus = function() {
if (navigator.onLine) {
// handle online status
console.info('online');
document.getElementById('menuPush').classList.remove("disabled");
document.getElementById('toggle').removeAttribute("disabled");
document.querySelector('.header').style.filter = 'grayscale(0)';
document.querySelector('.logo').style.filter = 'grayscale(0)';
} else {
// handle offline status
console.info('offline');
document.getElementById('menuPush').classList.add("disabled");
document.getElementById('toggle').setAttribute("disabled", "disabled");
document.querySelector('.header').style.filter = 'grayscale(1)';
document.querySelector('.logo').style.filter = 'grayscale(1)';
}
};
app.fullscreenMsg = function(msg, title = app.appName, obj = false) {
......@@ -382,75 +221,6 @@
async function run() {
app.registration = await navigator.serviceWorker.register('/sw.js', {scope: '/'})
.then(async function(sw) {
console.info('ServiceWorker registered: ', sw.scope);
var isUpdate = false;
// If this fires we should check if there's a new Service Worker
// waiting to be activated. If so, ask the user to force refresh.
if (sw.active)
isUpdate = true;
sw.onupdatefound = function(event) {
// If an update is found the spec says that there is a new Service
// Worker installing, so we should wait for that to complete then
// show a notification to the user.
sw.installing.onstatechange = function(event) {
if (this.state === 'installed') {
console.info("Service Worker Installed.");
if (isUpdate) {
app.fullscreenMsg(
'New version is available!<br/>We need to reload this web app to update all changes.',
app.appName,
{right: {label: 'OK', action: app.reloadWebApp}}
);
}
else {
toast(app.appName + ' ready for offline use.');
}
}
else {
console.info("New Service Worker state:", this.state);
}
};
};
await sw.pushManager.getSubscription().then(function(sub) {
if (sub === null) {
// Update UI to ask user to register for Push
//console.info('Not subscribed to push service!');
localStorage.setItem("subWebPush", 0);
document.querySelector('#toggle').checked = false;
}
else {
// We have a subscription, update the database
//console.info('Subscription object: ', sub);
if (localStorage.getItem("subWebPush") == 0) {
// insert subscription to the server
app.updateSubscriptionToTheServer(sub);
}
else if (localStorage.getItem("subWebPush") == 1 && !localStorage.getItem("subEntry")) {
// update changes subscription to the server
app.updateSubscriptionToTheServer(sub);
}
else if (localStorage.getItem("subWebPush") == 1 && localStorage.getItem("subEntry") && sub.endpoint !== JSON.parse(localStorage.getItem("subEntry")).endpoint) {
console.info("New: " + sub.endpoint);
console.info("Old: " + JSON.parse(localStorage.getItem("subEntry")).endpoint);
console.info('Subscription changed!');
// update changes subscription to the server
app.updateSubscriptionToTheServer(sub);
}
}
});
return sw;
})
.catch(function(err) {
console.error('Unable to register service worker.', err);
});
};
app.nextTick = function() {
......@@ -635,54 +405,6 @@
event.stopPropagation();
});
window.addEventListener('online', app.updateOnlineStatus);
window.addEventListener('offline', app.updateOnlineStatus);
/************************************************************************
*
* Code required to start the app
*
* NOTE: To simplify this codelab, we've used localStorage.
* localStorage is a synchronous API and has serious performance
* implications. It should not be used in production applications!
* Instead, check out IDB (https://www.npmjs.com/package/idb) or
* SimpleDB (https://gist.github.com/inexorabletash/c8069c042b734519680c)
************************************************************************/
/** custom pwa install prompt **/
var deferredPrompt;
window.addEventListener('beforeinstallprompt', function(e) {
// Prevent the mini-infobar from appearing on mobile
e.preventDefault();
// Stash the event so it can be triggered later.
deferredPrompt = e;
// Update UI notify the user they can install the PWA
app.installPromotion(true);
});
app.buttonInstall.addEventListener('click', function(e) {
// Show the install prompt
deferredPrompt.prompt();
// Wait for the user to respond to the prompt
deferredPrompt.userChoice.then(function(choiceResult) {
if (choiceResult.outcome === 'accepted') {
app.reloadWebApp();
console.info('User accepted the install prompt');
} else {
app.pwahomescreen.style.display = 'none';
console.info('User dismissed the install prompt');
}
// Hide the app provided install promotion
app.installPromotion(false);
});
});
window.addEventListener('appinstalled', function() {
// Hide the app provided install promotion
app.installPromotion(false);
// Log install to analytics
console.info('installed to homescreen');
});
window.addEventListener('load', function() {
console.group('[Starting App]');
......
(function() {
'use strict';
function webShare() {
var title = 'Training PWA UiTM';
var text = '(WIP-Working In Progress)';
var url = document.querySelector('link[rel=canonical]').href;
//console.log(title + "\n" + text + '\n⇒ ' + url);
if (navigator.share === undefined) {
//toast('Unsupported feature: Web Share');
//console.log('Error: Unsupported feature: navigator.share');
window.open("https://api.whatsapp.com/send?text=" + window.encodeURIComponent(text + '\n⇒ ' + url));
return;
}
navigator.share({title: title, text: text, url: url})
.then(function() {})
.catch(function(error) {});
}
document.querySelector('#btnShare').addEventListener('click', webShare);
})();
{
"name": "PWA Training",
"short_name": "PWATraining",
"description": "Initial release of web app. Work-in-progress (WIP).",
"theme_color": "#2f3ba2",
"background_color": "#3e4eb8",
"display": "standalone",
"orientation": "portrait",
"scope": "/",
"start_url": "/?utm_source=standalone&utm_medium=pwa",
"icons": [
{
"src": "images/icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "images/icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "images/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "images/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "images/icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "images/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "images/icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "images/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"lang": "English",
"splash_pages": null
}
......@@ -3,7 +3,7 @@
if (workbox) {
console.log(`Yay! Workbox is loaded 🎉`);
workbox.precaching.precacheAndRoute([{"revision":"56dceb8d62294cd2524cf532bdf8eec7","url":"index.html"},{"revision":"6f38b559ee2733468231d0e3589a46f2","url":"favicon.ico"},{"revision":"841ccc0972018aa8e1ff3336f9279847","url":"css/app.css"},{"revision":"64cda5a0c8525157ac311b4c0984a650","url":"js/app.js"},{"revision":"ae75e72cfa193100f2baba436c50616b","url":"js/menu.js"},{"revision":"70b828e6a680aa61b26c26b8ed704b92","url":"js/share.js"},{"revision":"862385e0c7db3e2cd56c62c89388baa7","url":"js/swipe.js"},{"revision":"609e8f6ce7aa15cd2e5effde31057a80","url":"js/toast.js"},{"revision":"9cff0b914c679f32a3c1e4162f80522a","url":"images/badges/notification_192.png"},{"revision":"784b1c63c7be412d166db4a3d49f2501","url":"images/icons/icon-128x128.png"},{"revision":"adb787791bb14d1a5a076321c886b171","url":"images/icons/icon-144x144.png"},{"revision":"e25a0afa07977ad1039a46b9ab82daee","url":"images/icons/icon-152x152.png"},{"revision":"86e1f0fae80ecb97faad31f57d88aaec","url":"images/icons/icon-192x192.png"},{"revision":"72c220ac025d55ff95abe164ffb31db4","url":"images/icons/icon-384x384.png"},{"revision":"720fb062cb6d0f37070a9d877967a894","url":"images/icons/icon-512x512.png"},{"revision":"c03ad90690383f8dc249bb6c7a407aab","url":"images/icons/icon-72x72.png"},{"revision":"2ee2cc270deb2d95e2c8773398eff1fe","url":"images/icons/icon-96x96.png"},{"revision":"1b9053762212073bbade3145680cbf41","url":"images/logoUiTM.svg"}]);
workbox.precaching.precacheAndRoute([{"revision":"b1c77f9c5225951a9c6bd70d4188fa6a","url":"index.html"},{"revision":"6f38b559ee2733468231d0e3589a46f2","url":"favicon.ico"},{"revision":"fa694d319ff249bbafc9b0ebeb5bdd8a","url":"css/app.css"},{"revision":"0d606a447f16af75e775b64b27f3c442","url":"js/app.js"},{"revision":"ae75e72cfa193100f2baba436c50616b","url":"js/menu.js"},{"revision":"07eab90e6269c3f19ddc34ddfb890adf","url":"js/share.js"},{"revision":"fc8aef5e3399c8fb6efea89b54459f11","url":"js/swipe.js"},{"revision":"609e8f6ce7aa15cd2e5effde31057a80","url":"js/toast.js"},{"revision":"9cff0b914c679f32a3c1e4162f80522a","url":"images/badges/notification_192.png"},{"revision":"784b1c63c7be412d166db4a3d49f2501","url":"images/icons/icon-128x128.png"},{"revision":"adb787791bb14d1a5a076321c886b171","url":"images/icons/icon-144x144.png"},{"revision":"e25a0afa07977ad1039a46b9ab82daee","url":"images/icons/icon-152x152.png"},{"revision":"86e1f0fae80ecb97faad31f57d88aaec","url":"images/icons/icon-192x192.png"},{"revision":"72c220ac025d55ff95abe164ffb31db4","url":"images/icons/icon-384x384.png"},{"revision":"720fb062cb6d0f37070a9d877967a894","url":"images/icons/icon-512x512.png"},{"revision":"c03ad90690383f8dc249bb6c7a407aab","url":"images/icons/icon-72x72.png"},{"revision":"2ee2cc270deb2d95e2c8773398eff1fe","url":"images/icons/icon-96x96.png"},{"revision":"1b9053762212073bbade3145680cbf41","url":"images/logoUiTM.svg"}]);
workbox.googleAnalytics.initialize();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment