diff --git a/ServiceWorkerUpdateListener.min.js b/ServiceWorkerUpdateListener.min.js
new file mode 100644
index 0000000..7e9982c
--- /dev/null
+++ b/ServiceWorkerUpdateListener.min.js
@@ -0,0 +1 @@
+class ServiceWorkerUpdateListener extends EventTarget{addRegistration(t){if(this._registrations||(this._registrations=[]),!this._registrations.includes(t)){this._registrations.push(t);var e=(t,e,i,s)=>{this._eventListeners||(this._eventListeners=[]),this._eventListeners.push({registration:t,target:e,type:i,listener:s}),e.addEventListener(i,s)},i=(t,e,i)=>{var s="update"+t,n="on"+s,r=new CustomEvent(s,{detail:{serviceWorker:e,registration:i}});this.dispatchEvent(r),this[n]&&"function"==typeof this[n]&&this[n].call(this,r)};t.waiting&&i("waiting",t.waiting,t),e(t,t,"updatefound",s=>{t.active&&t.installing&&(e(t,t.installing,"statechange",e=>{"installed"===e.target.state&&i("waiting",t.waiting,t)}),i("installing",t.installing,t))}),e(t,navigator.serviceWorker,"controllerchange",t=>{t.target.ready.then(t=>{i("ready",t.active,t)})})}}removeRegistration(t){if(this._registrations&&!(this._registrations.length<=0)){var e=t=>{this._eventListeners||(this._eventListeners=[]),this._eventListeners=this._eventListeners.filter(e=>e.registration!==t||(e.target.removeEventListener(e.type,e.listener),!1))};this._registrations=this._registrations.filter(i=>i!==t||(e(t),!1))}}skipWaiting(t){t.postMessage("skipWaiting")}}
\ No newline at end of file
diff --git a/_headers b/_headers
new file mode 100644
index 0000000..b84780c
--- /dev/null
+++ b/_headers
@@ -0,0 +1,5 @@
+/*
+ cache-control: max-age=0
+ cache-control: no-cache
+ cache-control: no-store
+ cache-control: must-revalidate
diff --git a/afterLogin.html b/afterLogin.html
new file mode 100644
index 0000000..0d18d38
--- /dev/null
+++ b/afterLogin.html
@@ -0,0 +1,177 @@
+
+
+
+
+ Firebase Store and auth PWA
+
+
+ Firebase PWA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/index-old.html b/index-old.html
new file mode 100644
index 0000000..f314706
--- /dev/null
+++ b/index-old.html
@@ -0,0 +1,148 @@
+
+
+
+
+ Sample FirebaseUI App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Firebase PWA Sign in ver.002
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/index.html b/index.html
index ce6c7ea..9b0add3 100644
--- a/index.html
+++ b/index.html
@@ -1,91 +1,83 @@
-
-
-
-
-
- Food Ninja
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ My Web Application
+
+
+
+
+
+
+
No update available
+
Waiting for an update to become available
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/index1.html b/index1.html
new file mode 100644
index 0000000..7ed89cb
--- /dev/null
+++ b/index1.html
@@ -0,0 +1,93 @@
+
+
+
+
+
+ Food Ninja
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/index2.html b/index2.html
new file mode 100644
index 0000000..04d1978
--- /dev/null
+++ b/index2.html
@@ -0,0 +1,226 @@
+
+
+
+
+
+
+
+
+
+
+ By Firebase
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Login
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/indexold3.html b/indexold3.html
new file mode 100644
index 0000000..79462ee
--- /dev/null
+++ b/indexold3.html
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+
+
+ My Web Application
+
+
+
+
+
+
+
No update available
+
Waiting for an update to become available
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/js/auth.js b/js/auth.js
new file mode 100644
index 0000000..25fba78
--- /dev/null
+++ b/js/auth.js
@@ -0,0 +1,106 @@
+// listen for auth status changes
+auth.onAuthStateChanged(user => {
+ if (user) {
+ console.log(user);
+ db.collection('guides').onSnapshot(snapshot => {
+ setupGuides(snapshot.docs);
+ setupUI(user);
+ }, err => console.log(err.message));
+ } else {
+ console.log("No user login")
+ setupUI();
+ setupGuides([]);
+ }
+ });
+
+ // create new guide
+ const createForm = document.querySelector('#create-form');
+ createForm.addEventListener('submit', (e) => {
+ e.preventDefault();
+ db.collection('guides').add({
+ title: createForm.title.value,
+ content: createForm.content.value
+ }).then(() => {
+ // close the create modal & reset form
+ const modal = document.querySelector('#modal-create');
+ M.Modal.getInstance(modal).close();
+ createForm.reset();
+ }).catch(err => {
+ console.log(err.message);
+ });
+ });
+
+ // signup
+ const signupForm = document.querySelector('#signup-form');
+ signupForm.addEventListener('submit', (e) => {
+ e.preventDefault();
+
+ // get user info
+ const email = signupForm['signup-email'].value;
+ const password = signupForm['signup-password'].value;
+
+ // sign up the user & add firestore data
+ auth.createUserWithEmailAndPassword(email, password).then(cred => {
+ return db.collection('users').doc(cred.user.uid).set({
+ bio: signupForm['signup-bio'].value
+ });
+ }).then(() => {
+ // close the signup modal & reset form
+ const modal = document.querySelectorAll('#modal-signup');
+ M.Modal.getInstance(modal).close();
+ signupForm.reset();
+ });
+ });
+
+ // logout
+ const logouts = document.querySelectorAll('#logout');
+
+ logouts.forEach(logout => {logout.addEventListener('click', (e) => {
+ e.preventDefault();
+ auth.signOut();
+ });
+ });
+
+ /* const logout1 = document.querySelector('#logout-sidebar');
+
+ logout1.addEventListener('click', (e) => {
+ e.preventDefault();
+ auth.signOut();
+ });
+ */
+
+ // login
+ const loginForm = document.querySelector('#login-form');
+ loginForm.addEventListener('submit', (e) => {
+ e.preventDefault();
+
+ // get user info
+ const email = loginForm['login-email'].value;
+ const password = loginForm['login-password'].value;
+
+ // log the user in
+ auth.signInWithEmailAndPassword(email, password).then((cred) => {
+ // close the signup modal & reset form
+ const modal = document.querySelector('#modal-login');
+ M.Modal.getInstance(modal).close();
+ loginForm.reset();
+ });
+
+ });
+
+ //Anonymously login
+
+ const anonymously = document.getElementById('Anon_login');
+ //console.log("anonymously");
+ anonymously.addEventListener('click', () => {
+ firebase.auth().signInAnonymously()
+ .then(() => {
+ // Signed in..
+ console.log("Anonymously login");
+ })
+ .catch((error) => {
+ var errorCode = error.code;
+ var errorMessage = error.message;
+ // ...
+ });
+ });
\ No newline at end of file
diff --git a/js/index.js b/js/index.js
new file mode 100644
index 0000000..1be1327
--- /dev/null
+++ b/js/index.js
@@ -0,0 +1,64 @@
+// DOM elements
+const guideList = document.querySelector('.guides');
+const loggedOutLinks = document.querySelectorAll('.logged-out');
+const loggedInLinks = document.querySelectorAll('.logged-in');
+const accountDetails = document.querySelector('.account-details');
+
+const setupUI = (user) => {
+ if (user) {
+ // account info
+ db.collection('users').doc(user.uid).get().then(doc => {
+ const html = `
+ Logged in as ${user.email}
+ ${doc.data().bio}
+ `;
+ accountDetails.innerHTML = html;
+ });
+ // toggle user UI elements
+ loggedInLinks.forEach(item => item.style.display = 'block');
+ loggedOutLinks.forEach(item => item.style.display = 'none');
+ } else {
+ // clear account info
+ accountDetails.innerHTML = '';
+ // toggle user elements
+ loggedInLinks.forEach(item => item.style.display = 'none');
+ loggedOutLinks.forEach(item => item.style.display = 'block');
+ }
+};
+
+// setup guides
+const setupGuides = (data) => {
+
+ if (data.length) {
+ let html = '';
+ data.forEach(doc => {
+ const guide = doc.data();
+ const li = `
+
+
+ ${guide.content}
+
+ `;
+ html += li;
+ });
+ guideList.innerHTML = html
+ } else {
+ guideList.innerHTML = 'Login to view guides
';
+ }
+
+
+};
+
+// setup materialize components
+document.addEventListener('DOMContentLoaded', function() {
+
+ var modals = document.querySelectorAll('.modal');
+ M.Modal.init(modals);
+
+ var items = document.querySelectorAll('.collapsible');
+ M.Collapsible.init(items);
+
+ var elems = document.querySelectorAll('.sidenav');
+ M.Sidenav.init(elems,{edge: 'right'});
+
+});
\ No newline at end of file
diff --git a/offline.html b/offline.html
new file mode 100644
index 0000000..6d0be9e
--- /dev/null
+++ b/offline.html
@@ -0,0 +1,50 @@
+
+
+
+
+
+ Food Ninja
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
OOPS!
+
Currently you can't view this page without a connection.
+
Go to the Homepage
+
+
+
+
+
+
\ No newline at end of file
diff --git a/service-worker.js b/service-worker.js
new file mode 100644
index 0000000..48a160b
--- /dev/null
+++ b/service-worker.js
@@ -0,0 +1,54 @@
+var CACHE_NAME = 'my-web-app-version-v9';
+
+self.addEventListener('install', event => {
+ event.waitUntil(
+ caches.open(CACHE_NAME)
+ .then(cache => {
+ return cache.addAll([
+ './',
+ './index.html',
+ './ServiceWorkerUpdateListener.min.js'
+ ]);
+ })
+ );
+});
+
+self.addEventListener('activate', event => {
+ event.waitUntil(
+ caches.keys().then(cacheNames => {
+ return Promise.all(
+ cacheNames.map(cacheName => {
+ if (cacheName !== CACHE_NAME)
+ return caches.delete(cacheName);
+ })
+ );
+ })
+ );
+});
+
+self.addEventListener('fetch', event => {
+ event.respondWith(
+ caches.match(event.request)
+ .then(response => {
+ if (response) return response;
+
+ return fetch(event.request)
+ .then(response => {
+ if (!response || response.status !== 200 || response.type !== 'basic') return response;
+
+ var responseToCache = response.clone();
+
+ caches.open(CACHE_NAME).then(cache => {
+ cache.put(event.request, responseToCache)
+ });
+ });
+ })
+ )
+});
+
+self.addEventListener('message', event => {
+ console.log(event.data);
+ if (event.data === 'skipWaiting') return skipWaiting();
+
+});
+
diff --git a/sw.js b/sw.js
index 8196bbb..ccae175 100644
--- a/sw.js
+++ b/sw.js
@@ -1,5 +1,5 @@
-const staticCacheName = 'site-static-v3';
-const dynamicCacheName = 'site-dynamic-v3';
+const staticCacheName = 'site-static-v7';
+const dynamicCacheName = 'site-dynamic-v7';
const assets = [
'/',
'/index.html',
@@ -27,7 +27,30 @@ const limitCacheSize = (name, size) => {
// install event
self.addEventListener('install', evt => {
- //console.log('service worker installed');
+ // if cached, delete all first
+ /* limitCacheSize(dynamicCacheName, 0);
+ limitCacheSize(staticCacheName, 0); */
+ evt.waitUntil(
+
+ caches.keys().then(function(cacheNames) {
+ console.log('delete ...');
+ return Promise.all(
+ cacheNames.filter(function(cacheName) {
+ console.log('delete caches:'+cacheName);
+ limitCacheSize(cacheName, 0);
+ // Return true if you want to remove this cache,
+ // but remember that caches are shared across
+ // the whole origin
+ }).map(function(cacheName) {
+ console.log('delete caches:'+cacheName);
+ return caches.delete(cacheName);
+ })
+ );
+ })
+ );
+
+ console.log('service worker installed');
+
evt.waitUntil(
caches.open(staticCacheName).then((cache) => {
console.log('caching shell assets');
@@ -38,7 +61,7 @@ self.addEventListener('install', evt => {
// activate event
self.addEventListener('activate', evt => {
- //console.log('service worker activated');
+ console.log('service worker activated');
evt.waitUntil(
caches.keys().then(keys => {
//console.log(keys);
@@ -48,6 +71,8 @@ self.addEventListener('activate', evt => {
);
})
);
+
+
});
// fetch events
diff --git a/sw2.js b/sw2.js
new file mode 100644
index 0000000..a0be068
--- /dev/null
+++ b/sw2.js
@@ -0,0 +1,13 @@
+importScripts(
+ 'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
+ );
+
+ workbox.recipes.pageCache();
+
+ workbox.recipes.googleFontsCache();
+
+ workbox.recipes.staticResourceCache();
+
+ workbox.recipes.imageCache();
+
+ workbox.recipes.offlineFallback();
\ No newline at end of file