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 + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + add + +
+ + +
+
+
New Recipe
+
+
+ + +
+
+ + +
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + \ 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 - - - - - - - - - - - - - - - - - - - - -
- -
- -
- - add - -
- - -
-
-
New Recipe
-
-
- - -
-
- - -
-
- -
-
-
- - - - - - - - - + + + + + + + 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 + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + add + +
+ + +
+
+
New Recipe
+
+
+ + +
+
+ + +
+
+ +
+
+
+ + + + + + + + + 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 + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + \ 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.title}
    +
    ${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