diff --git a/app/js/dbhelper.js b/app/js/dbhelper.js index d368e01..56091fa 100644 --- a/app/js/dbhelper.js +++ b/app/js/dbhelper.js @@ -27,7 +27,7 @@ class DBHelper { * Fetch all restaurants. */ static fetchRestaurants(callback) { - console.log(`In fetchRestaurants - callback: ${callback}`); + //console.log(`In fetchRestaurants - callback: ${callback}`); let requestURL = DBHelper.DATABASE_URL; // console.log(`Request URL: ${requestURL}`); // Fetch restaurant data from server @@ -304,7 +304,7 @@ class DBHelper { console.log("In addToUpdateQueue catch, error: ", error.message); }) // TODO : attempt push of updates - .then(DBHelper.pushUpdates()); + //.then(DBHelper.pushUpdates()); } /* @@ -337,7 +337,7 @@ class DBHelper { // Recursive call to push next update record. Will retrun in next call if empty. .then(function() { console.log("Record deleted, calling next..."); - DBHelper.pushUpdates(); + //DBHelper.pushUpdates(); }) }) }) @@ -372,7 +372,7 @@ class DBHelper { /* * Function to check idb for restaurant information - */ + * static idbRestaurantRequest() { return dbPromise.then(function(db) { return db.transaction('restaurantData').objectStore('restaurantData').get(id); @@ -393,7 +393,7 @@ class DBHelper { /* * Function to check idb for review information - */ + * static idbReviewRequest() { return dbPromise.then(function(db) { return db.transaction('reviewData').objectStore('reviewData').index('restaurant_id').getAll(id); @@ -420,6 +420,6 @@ class DBHelper { return new Response(JSON.stringify(endResponse)); }) .catch(function(error) { console.log(`In apiFetch catch-reviewData, error: ${error.message}`); }) - } + }*/ } diff --git a/app/js/main.js b/app/js/main.js index e72c34d..ad6c77d 100644 --- a/app/js/main.js +++ b/app/js/main.js @@ -79,7 +79,7 @@ window.initMap = () => { scrollwheel: false }); updateRestaurants(); - DBHelper.pushUpdates(); + //DBHelper.pushUpdates(); } /* diff --git a/app/js/restaurant_info.js b/app/js/restaurant_info.js index 27efd2a..4007b3c 100644 --- a/app/js/restaurant_info.js +++ b/app/js/restaurant_info.js @@ -18,7 +18,7 @@ window.initMap = () => { DBHelper.mapMarkerForRestaurant(self.restaurant, self.map); } }); - DBHelper.pushUpdates(); + //DBHelper.pushUpdates(); } /* diff --git a/app/js/swregister.js b/app/js/swregister.js index bd62401..4558d2e 100644 --- a/app/js/swregister.js +++ b/app/js/swregister.js @@ -1,6 +1,6 @@ // Registering the Service Worker if ('serviceWorker' in navigator) { - navigator.serviceWorker.register('/sw.js') + navigator.serviceWorker.register('sw.js') .then(function(registration) { console.log('Registration successful, scope is: ', registration.scope); }) diff --git a/app/sw.js b/app/sw.js index 5ba260f..be9418d 100644 --- a/app/sw.js +++ b/app/sw.js @@ -3,20 +3,22 @@ */ // Include DBHelper functions for fetching restaurants and putting in indexedDB -self.importScripts('js/dbhelper.js', 'js/idb.js'); +// self.importScripts('js/dbhelper.js', 'js/idb.js'); + self.importScripts('js/idb.js'); +// import idb from "idb"; // Cache Information -var myCache = 'restaurantReview_301'; +var myCache = 'restaurantReview_302'; var cacheFiles = [ - '/index.html', - '/restaurant.html', - '/css/styles.css', - '/img/', - '/js/dbhelper.js', - '/js/main.js', - '/js/restaurant_info.js', - '/js/swregister.js' , - '/js/idb.js' + 'index.html', + 'restaurant.html', + 'css/styles.css', + 'img/', + 'js/dbhelper.js', + 'js/main.js', + 'js/restaurant_info.js', + 'js/swregister.js' , + 'js/idb.js' ]; // IDB Information @@ -78,11 +80,49 @@ function apiFetch(event, id) { // Restaurant Request if(event.request.url.indexOf('restaurants') > -1) { - event.respondWith(DBHelper.idbRestaurantRequest()); + event.respondWith(dbPromise.then(function(db) { + return db.transaction('restaurantData').objectStore('restaurantData').get(id); + }) + .then(function(data) { + return (data && data.data) || fetch(event.request) + .then(function(response) { + return dbPromise + .then(function(db) { + db.transaction('restaurantData', 'readwrite').objectStore('restaurantData').put({ id: id, data: response.json() }); + return response.json(); + }); + }); + }) + .then(function(endResponse) { return new Response(JSON.stringify(endResponse)); }) + .catch(function(error) { console.log(`In DBHelper.idbRestaurantRequest, error: ${error.message}`); })); } // Review Request - event.respondWith(DBHelper.idbReviewRequest()); + event.respondWith(dbPromise.then(function(db) { + return db.transaction('reviewData').objectStore('reviewData').index('restaurant_id').getAll(id); + }) + .then(function(data) { + return (data && data.data) || fetch(event.request) + .then(function(response) { + return dbPromise + .then(function(db) { + let store = db.transaction('reviewData', 'readwrite').objectStore('reviewData'); + let r = response.json(); + r.forEach(function(review) { + store.put({id: review.id, 'restaurant_id': review.restaurant_id, data: review}); + }) + return r; + }); + }); + }) + .then(function(endResponse) { + if(endResponse[0].data) { + let formatted = endResponse.map(review => review.data); + return new Response(JSON.stringify(formatted)); + } + return new Response(JSON.stringify(endResponse)); + }) + .catch(function(error) { console.log(`In apiFetch catch-reviewData, error: ${error.message}`); })); } function cacheFetch(event, request) { diff --git a/dist/js/dbhelper.js b/dist/js/dbhelper.js index 5d6c127..e3e782d 100644 --- a/dist/js/dbhelper.js +++ b/dist/js/dbhelper.js @@ -1 +1 @@ -const port=1337,dbPromise=idb.open("restaurantReviews",3,t=>{switch(t.oldVersion){case 0:t.createObjectStore("restaurantData",{keyPath:"id"});case 1:t.createObjectStore("reviewData",{keypath:"id"}).createIndex("restaurant_id","restaurant_id");case 2:t.createObjectStore("updateData",{keyPath:"id",autoIncrement:!0})}});class DBHelper{static get DATABASE_URL(){return`http://localhost:${port}/restaurants`}static get DATABASE_URL_REVIEWS(){return`http://localhost:${port}/reviews`}static fetchRestaurants(t){console.log(`In fetchRestaurants - callback: ${t}`);let e=DBHelper.DATABASE_URL;fetch(e,{method:"GET"}).then(function(t){if(t.ok)return t.json()}).then(function(e){t(null,e)}).catch(function(t){console.log("In fetchRestaurants catch, error: ",t.message)})}static fetchRestaurantById(t,e){console.log(`In fetchRestaurantsById - id: ${t}`),DBHelper.fetchRestaurants((a,n)=>{if(a)e(a,null);else{const a=n.find(e=>e.id==t);a?e(null,a):e("Restaurant does not exist",null)}})}static fetchRestaurantByCuisine(t,e){DBHelper.fetchRestaurants((a,n)=>{if(a)e(a,null);else{const a=n.filter(e=>e.cuisine_type==t);e(null,a)}})}static fetchRestaurantByNeighborhood(t,e){DBHelper.fetchRestaurants((a,n)=>{if(a)e(a,null);else{const a=n.filter(e=>e.neighborhood==t);e(null,a)}})}static fetchRestaurantByCuisineAndNeighborhood(t,e,a){DBHelper.fetchRestaurants((n,r)=>{if(n)a(n,null);else{let n=r;"all"!=t&&(n=n.filter(e=>e.cuisine_type==t)),"all"!=e&&(n=n.filter(t=>t.neighborhood==e)),a(null,n)}})}static fetchNeighborhoods(t){DBHelper.fetchRestaurants((e,a)=>{if(e)t(e,null);else{const e=a.map((t,e)=>a[e].neighborhood),n=e.filter((t,a)=>e.indexOf(t)==a);t(null,n)}})}static fetchCuisines(t){DBHelper.fetchRestaurants((e,a)=>{if(e)t(e,null);else{const e=a.map((t,e)=>a[e].cuisine_type),n=e.filter((t,a)=>e.indexOf(t)==a);t(null,n)}})}static urlForRestaurant(t){return`./restaurant.html?id=${t.id}`}static imageUrlForRestaurant(t){return`/img/${t.photograph}`}static mapMarkerForRestaurant(t,e){return new google.maps.Marker({position:t.latlng,title:t.name,url:DBHelper.urlForRestaurant(t),map:e,animation:google.maps.Animation.DROP})}static fetchReviewsById(t){let e=DBHelper.DATABASE_URL_REVIEWS+"/?restaurant_id="+t;return console.log(`In DBHelper.fetchReviewsById - request: ${e}, id: ${t}`),fetch(e,{method:"GET"}).then(function(t){if(console.log("response: ",t),t.ok)return t.json()}).then(function(t){return console.log("reviewData: ",t),t}).catch(function(t){console.log("In fetchReviewsBy...ID catch, error:",t.message)})}static updateRestaurantCache(t,e){console.log(`In updateRestaurantCache - id: ${t}, update: ${e}`);let a=idb.open("restaurantReviews");a.then(function(n){n.transaction("restaurantData","readwrite").objectStore("restaurantData").get("-1").then(function(n){if(!n)return void console.log("No value, update all, in updateRestaurantCache");let r=n.data.filter(e=>e.id===t)[0];r&&(Object.keys(e).forEach(t=>{r[t]=e[t]}),a.then(function(t){return t.transaction("restaurantData","readwrite").objectStore("restaurantData").put({id:"-1",data:n.data}).complete}))})}),a.then(function(n){n.transaction("restaurantData","readwrite").objectStore("restaurantData").get(t+"").then(function(n){if(!n)return void console.log("No value, update individual, in updateRestaurantCache");let r=n.data;r&&(Object.keys(e).forEach(t=>{r[t]=e[t]}),a.then(function(e){return e.transaction("restaurantData","readwrite").objectStore("restaurantData").put({id:t+"",data:n.data}).complete}))})})}static updateReviewCache(t,e){console.log(`In updateReviewCache - id: ${t}, update: ${e}`),idb.open("restaurantReviews").then(function(a){return a.transaction("reviewData","readwrite").objectStore("reviewData").put({id:Date.now(),restaurant_id:t,data:e}).complete})}static addToUpdateQueue(t,e,a){console.log(`In addToUpdateQueue - url: ${t}, method: ${e}, update: ${a}`),idb.open("restaurantReviews").then(function(n){n.transaction("updateData","readwrite").objectStore("updateData").put({data:{url:t,method:e,update:a}})}).catch(function(t){console.log("In addToUpdateQueue catch, error: ",t.message)}).then(DBHelper.pushUpdates())}static pushUpdates(){console.log("In pushUpdates"),idb.open("restaurantReviews").then(function(t){t.transaction("updateData","readwrite").objectStore("updateData").openCursor().then(function(e){if(!e)return;let a=e.value.data,n={body:JSON.stringify(a.body),method:a.method};fetch(a.url,n).then(function(t){t.ok}).then(function(){t.transaction("updateData","readwrite").objectStore("updateData").openCursor().then(function(t){t.delete().then(function(){console.log("Record deleted, calling next..."),DBHelper.pushUpdates()})})})}).catch(function(t){console.log("In pushUpdates catch, error: ",t.message)})})}static saveReview(t,e,a,n,r){let o=`${DBHelper.DATABASE_URL_REVIEWS}`,s={restaurant_id:t,name:e,rating:a,comments:n,createdAt:r};console.log(`In saveReview - url: ${o}, method: POST, body: ${s}`),DBHelper.updateReviewCache(t,s),DBHelper.addToUpdateQueue(o,"POST",s)}static idbRestaurantRequest(){return dbPromise.then(function(t){return t.transaction("restaurantData").objectStore("restaurantData").get(id)}).then(function(t){return t&&t.data||fetch(event.request).then(function(t){return dbPromise.then(function(e){return e.transaction("restaurantData","readwrite").objectStore("restaurantData").put({id:id,data:t.json()}),t.json()})})}).then(function(t){return new Response(JSON.stringify(t))}).catch(function(t){console.log(`In DBHelper.idbRestaurantRequest, error: ${t.message}`)})}static idbReviewRequest(){return dbPromise.then(function(t){return t.transaction("reviewData").objectStore("reviewData").index("restaurant_id").getAll(id)}).then(function(t){return t&&t.data||fetch(event.request).then(function(t){return dbPromise.then(function(e){let a=e.transaction("reviewData","readwrite").objectStore("reviewData"),n=t.json();return n.forEach(function(t){a.put({id:t.id,restaurant_id:t.restaurant_id,data:t})}),n})})}).then(function(t){if(t[0].data){let e=t.map(t=>t.data);return new Response(JSON.stringify(e))}return new Response(JSON.stringify(t))}).catch(function(t){console.log(`In apiFetch catch-reviewData, error: ${t.message}`)})}} \ No newline at end of file +const port=1337,dbPromise=idb.open("restaurantReviews",3,e=>{switch(e.oldVersion){case 0:e.createObjectStore("restaurantData",{keyPath:"id"});case 1:e.createObjectStore("reviewData",{keypath:"id"}).createIndex("restaurant_id","restaurant_id");case 2:e.createObjectStore("updateData",{keyPath:"id",autoIncrement:!0})}});class DBHelper{static get DATABASE_URL(){return`http://localhost:${port}/restaurants`}static get DATABASE_URL_REVIEWS(){return`http://localhost:${port}/reviews`}static fetchRestaurants(e){let t=DBHelper.DATABASE_URL;fetch(t,{method:"GET"}).then(function(e){if(e.ok)return e.json()}).then(function(t){e(null,t)}).catch(function(e){console.log("In fetchRestaurants catch, error: ",e.message)})}static fetchRestaurantById(e,t){console.log(`In fetchRestaurantsById - id: ${e}`),DBHelper.fetchRestaurants((a,n)=>{if(a)t(a,null);else{const a=n.find(t=>t.id==e);a?t(null,a):t("Restaurant does not exist",null)}})}static fetchRestaurantByCuisine(e,t){DBHelper.fetchRestaurants((a,n)=>{if(a)t(a,null);else{const a=n.filter(t=>t.cuisine_type==e);t(null,a)}})}static fetchRestaurantByNeighborhood(e,t){DBHelper.fetchRestaurants((a,n)=>{if(a)t(a,null);else{const a=n.filter(t=>t.neighborhood==e);t(null,a)}})}static fetchRestaurantByCuisineAndNeighborhood(e,t,a){DBHelper.fetchRestaurants((n,r)=>{if(n)a(n,null);else{let n=r;"all"!=e&&(n=n.filter(t=>t.cuisine_type==e)),"all"!=t&&(n=n.filter(e=>e.neighborhood==t)),a(null,n)}})}static fetchNeighborhoods(e){DBHelper.fetchRestaurants((t,a)=>{if(t)e(t,null);else{const t=a.map((e,t)=>a[t].neighborhood),n=t.filter((e,a)=>t.indexOf(e)==a);e(null,n)}})}static fetchCuisines(e){DBHelper.fetchRestaurants((t,a)=>{if(t)e(t,null);else{const t=a.map((e,t)=>a[t].cuisine_type),n=t.filter((e,a)=>t.indexOf(e)==a);e(null,n)}})}static urlForRestaurant(e){return`./restaurant.html?id=${e.id}`}static imageUrlForRestaurant(e){return`/img/${e.photograph}`}static mapMarkerForRestaurant(e,t){return new google.maps.Marker({position:e.latlng,title:e.name,url:DBHelper.urlForRestaurant(e),map:t,animation:google.maps.Animation.DROP})}static fetchReviewsById(e){let t=DBHelper.DATABASE_URL_REVIEWS+"/?restaurant_id="+e;return console.log(`In DBHelper.fetchReviewsById - request: ${t}, id: ${e}`),fetch(t,{method:"GET"}).then(function(e){if(console.log("response: ",e),e.ok)return e.json()}).then(function(e){return console.log("reviewData: ",e),e}).catch(function(e){console.log("In fetchReviewsBy...ID catch, error:",e.message)})}static updateRestaurantCache(e,t){console.log(`In updateRestaurantCache - id: ${e}, update: ${t}`);let a=idb.open("restaurantReviews");a.then(function(n){n.transaction("restaurantData","readwrite").objectStore("restaurantData").get("-1").then(function(n){if(!n)return void console.log("No value, update all, in updateRestaurantCache");let r=n.data.filter(t=>t.id===e)[0];r&&(Object.keys(t).forEach(e=>{r[e]=t[e]}),a.then(function(e){return e.transaction("restaurantData","readwrite").objectStore("restaurantData").put({id:"-1",data:n.data}).complete}))})}),a.then(function(n){n.transaction("restaurantData","readwrite").objectStore("restaurantData").get(e+"").then(function(n){if(!n)return void console.log("No value, update individual, in updateRestaurantCache");let r=n.data;r&&(Object.keys(t).forEach(e=>{r[e]=t[e]}),a.then(function(t){return t.transaction("restaurantData","readwrite").objectStore("restaurantData").put({id:e+"",data:n.data}).complete}))})})}static updateReviewCache(e,t){console.log(`In updateReviewCache - id: ${e}, update: ${t}`),idb.open("restaurantReviews").then(function(a){return a.transaction("reviewData","readwrite").objectStore("reviewData").put({id:Date.now(),restaurant_id:e,data:t}).complete})}static addToUpdateQueue(e,t,a){console.log(`In addToUpdateQueue - url: ${e}, method: ${t}, update: ${a}`),idb.open("restaurantReviews").then(function(n){n.transaction("updateData","readwrite").objectStore("updateData").put({data:{url:e,method:t,update:a}})}).catch(function(e){console.log("In addToUpdateQueue catch, error: ",e.message)})}static pushUpdates(){console.log("In pushUpdates"),idb.open("restaurantReviews").then(function(e){e.transaction("updateData","readwrite").objectStore("updateData").openCursor().then(function(t){if(!t)return;let a=t.value.data,n={body:JSON.stringify(a.body),method:a.method};fetch(a.url,n).then(function(e){e.ok}).then(function(){e.transaction("updateData","readwrite").objectStore("updateData").openCursor().then(function(e){e.delete().then(function(){console.log("Record deleted, calling next...")})})})}).catch(function(e){console.log("In pushUpdates catch, error: ",e.message)})})}static saveReview(e,t,a,n,r){let o=`${DBHelper.DATABASE_URL_REVIEWS}`,s={restaurant_id:e,name:t,rating:a,comments:n,createdAt:r};console.log(`In saveReview - url: ${o}, method: POST, body: ${s}`),DBHelper.updateReviewCache(e,s),DBHelper.addToUpdateQueue(o,"POST",s)}} \ No newline at end of file diff --git a/dist/js/main.js b/dist/js/main.js index 31ba433..9ef069c 100644 --- a/dist/js/main.js +++ b/dist/js/main.js @@ -1 +1 @@ -let restaurants,neighborhoods,cuisines;var map,markers=[];document.addEventListener("DOMContentLoaded",e=>{fetchNeighborhoods(),fetchCuisines()}),fetchNeighborhoods=(()=>{DBHelper.fetchNeighborhoods((e,t)=>{e?console.error(e):(self.neighborhoods=t,fillNeighborhoodsHTML())})}),fillNeighborhoodsHTML=((e=self.neighborhoods)=>{const t=document.getElementById("neighborhoods-select");e.forEach(e=>{const n=document.createElement("option");n.innerHTML=e,n.value=e,t.append(n)})}),fetchCuisines=(()=>{DBHelper.fetchCuisines((e,t)=>{e?console.error(e):(self.cuisines=t,fillCuisinesHTML())})}),fillCuisinesHTML=((e=self.cuisines)=>{const t=document.getElementById("cuisines-select");e.forEach(e=>{const n=document.createElement("option");n.innerHTML=e,n.value=e,t.append(n)})}),window.initMap=(()=>{self.map=new google.maps.Map(document.getElementById("map"),{zoom:12,center:{lat:40.722216,lng:-73.987501},scrollwheel:!1}),updateRestaurants(),DBHelper.pushUpdates()}),updateRestaurants=(()=>{const e=document.getElementById("cuisines-select"),t=document.getElementById("neighborhoods-select"),n=e.selectedIndex,s=t.selectedIndex,r=e[n].value,a=t[s].value;DBHelper.fetchRestaurantByCuisineAndNeighborhood(r,a,(e,t)=>{e?console.error(e):(resetRestaurants(t),fillRestaurantsHTML())})}),resetRestaurants=(e=>{self.restaurants=[],document.getElementById("restaurants-list").innerHTML="",self.markers.forEach(e=>e.setMap(null)),self.markers=[],self.restaurants=e}),fillRestaurantsHTML=((e=self.restaurants)=>{const t=document.getElementById("restaurants-list");e.forEach(e=>{t.append(createRestaurantHTML(e))}),addMarkersToMap()}),createRestaurantHTML=(e=>{const t=document.createElement("li"),n=document.createElement("img");n.className="restaurant-img",n.src=`/img/${e.id}@1x.webp`,n.srcset=`/img/${e.id}@1x.webp 300w,\n /img/${e.id}@2x.webp 600w,\n /img/${e.id}@3x.webp 900w`,n.alt=`Image of ${e.name} restaurant`,t.append(n);const s=document.createElement("h3");s.innerHTML=e.name,t.append(s);const r=document.createElement("button");r.className="favButton";let a=!(!e.is_favorite||"true"!==e.is_favorite.toString());r.setAttribute("aria-pressed",a),r.setAttribute("aria-label",`Make ${e.name} a favorite!`),r.innerHTML=a?"♥":"♡",r.onclick=(t=>favoriteClicked(e,r)),t.append(r);const o=document.createElement("p");o.innerHTML=e.neighborhood,t.append(o);const i=document.createElement("p");i.innerHTML=e.address,t.append(i);const l=document.createElement("a");return l.innerHTML="View Details",l.href=DBHelper.urlForRestaurant(e),t.append(l),t}),favoriteClicked=((e,t)=>{let n=!(!t.getAttribute("aria-pressed")||"true"!==t.getAttribute("aria-pressed")),s=`${DBHelper.DATABASE_URL}/${e.id}/?is_favorite=${!n}`;DBHelper.updateRestaurantCache(e.id,{is_favorite:!n}),DBHelper.addToUpdateQueue(s,"PUT"),t.setAttribute("aria-pressed",!n),t.innerHTML=n?"♡":"♥",t.onclick=(n=>favoriteClicked(e,t))}),addMarkersToMap=((e=self.restaurants)=>{e.forEach(e=>{const t=DBHelper.mapMarkerForRestaurant(e,self.map);google.maps.event.addListener(t,"click",()=>{window.location.href=t.url}),self.markers.push(t)})}); \ No newline at end of file +let restaurants,neighborhoods,cuisines;var map,markers=[];document.addEventListener("DOMContentLoaded",e=>{fetchNeighborhoods(),fetchCuisines()}),fetchNeighborhoods=(()=>{DBHelper.fetchNeighborhoods((e,t)=>{e?console.error(e):(self.neighborhoods=t,fillNeighborhoodsHTML())})}),fillNeighborhoodsHTML=((e=self.neighborhoods)=>{const t=document.getElementById("neighborhoods-select");e.forEach(e=>{const n=document.createElement("option");n.innerHTML=e,n.value=e,t.append(n)})}),fetchCuisines=(()=>{DBHelper.fetchCuisines((e,t)=>{e?console.error(e):(self.cuisines=t,fillCuisinesHTML())})}),fillCuisinesHTML=((e=self.cuisines)=>{const t=document.getElementById("cuisines-select");e.forEach(e=>{const n=document.createElement("option");n.innerHTML=e,n.value=e,t.append(n)})}),window.initMap=(()=>{self.map=new google.maps.Map(document.getElementById("map"),{zoom:12,center:{lat:40.722216,lng:-73.987501},scrollwheel:!1}),updateRestaurants()}),updateRestaurants=(()=>{const e=document.getElementById("cuisines-select"),t=document.getElementById("neighborhoods-select"),n=e.selectedIndex,s=t.selectedIndex,r=e[n].value,a=t[s].value;DBHelper.fetchRestaurantByCuisineAndNeighborhood(r,a,(e,t)=>{e?console.error(e):(resetRestaurants(t),fillRestaurantsHTML())})}),resetRestaurants=(e=>{self.restaurants=[],document.getElementById("restaurants-list").innerHTML="",self.markers.forEach(e=>e.setMap(null)),self.markers=[],self.restaurants=e}),fillRestaurantsHTML=((e=self.restaurants)=>{const t=document.getElementById("restaurants-list");e.forEach(e=>{t.append(createRestaurantHTML(e))}),addMarkersToMap()}),createRestaurantHTML=(e=>{const t=document.createElement("li"),n=document.createElement("img");n.className="restaurant-img",n.src=`/img/${e.id}@1x.webp`,n.srcset=`/img/${e.id}@1x.webp 300w,\n /img/${e.id}@2x.webp 600w,\n /img/${e.id}@3x.webp 900w`,n.alt=`Image of ${e.name} restaurant`,t.append(n);const s=document.createElement("h3");s.innerHTML=e.name,t.append(s);const r=document.createElement("button");r.className="favButton";let a=!(!e.is_favorite||"true"!==e.is_favorite.toString());r.setAttribute("aria-pressed",a),r.setAttribute("aria-label",`Make ${e.name} a favorite!`),r.innerHTML=a?"♥":"♡",r.onclick=(t=>favoriteClicked(e,r)),t.append(r);const o=document.createElement("p");o.innerHTML=e.neighborhood,t.append(o);const i=document.createElement("p");i.innerHTML=e.address,t.append(i);const l=document.createElement("a");return l.innerHTML="View Details",l.href=DBHelper.urlForRestaurant(e),t.append(l),t}),favoriteClicked=((e,t)=>{let n=!(!t.getAttribute("aria-pressed")||"true"!==t.getAttribute("aria-pressed")),s=`${DBHelper.DATABASE_URL}/${e.id}/?is_favorite=${!n}`;DBHelper.updateRestaurantCache(e.id,{is_favorite:!n}),DBHelper.addToUpdateQueue(s,"PUT"),t.setAttribute("aria-pressed",!n),t.innerHTML=n?"♡":"♥",t.onclick=(n=>favoriteClicked(e,t))}),addMarkersToMap=((e=self.restaurants)=>{e.forEach(e=>{const t=DBHelper.mapMarkerForRestaurant(e,self.map);google.maps.event.addListener(t,"click",()=>{window.location.href=t.url}),self.markers.push(t)})}); \ No newline at end of file diff --git a/dist/js/restaurant_info.js b/dist/js/restaurant_info.js index d4b8551..c770747 100644 --- a/dist/js/restaurant_info.js +++ b/dist/js/restaurant_info.js @@ -1 +1 @@ -let restaurant;var map;window.initMap=(()=>{fetchRestaurantFromURL((e,t)=>{e?console.error(e):(self.map=new google.maps.Map(document.getElementById("map"),{zoom:16,center:t.latlng,scrollwheel:!1}),fillBreadcrumb(),DBHelper.mapMarkerForRestaurant(self.restaurant,self.map))}),DBHelper.pushUpdates()}),fetchRestaurantFromURL=(e=>{if(self.restaurant)return void e(null,self.restaurant);const t=getParameterByName("id");if(t)DBHelper.fetchRestaurantById(t,(t,n)=>{self.restaurant=n,n?(fillRestaurantHTML(),e(null,n)):console.error(t)});else{e("No restaurant id in URL",null)}}),fillRestaurantHTML=((e=self.restaurant)=>{const t=document.getElementById("restaurant-name");t.innerHTML=e.name;const n=document.createElement("button");n.className="favButton";let r=!(!e.is_favorite||"true"!==e.is_favorite.toString());n.setAttribute("aria-pressed",r),n.setAttribute("aria-label",`Make ${e.name} a favorite!`),n.innerHTML=r?"♥":"♡",n.onclick=(t=>favoriteClicked(e,n)),t.appendChild(n),document.getElementById("restaurant-address").innerHTML=e.address;const a=document.getElementById("restaurant-img");a.className="restaurant-img",a.src=`/img/${e.id}@1x.webp`,a.srcset=`/img/${e.id}@1x.webp 300w,\n /img/${e.id}@2x.webp 600w,\n /img/${e.id}@3x.webp 900w`,a.alt=`Image of ${e.name} restaurant`,document.getElementById("restaurant-cuisine").innerHTML=e.cuisine_type,e.operating_hours&&fillRestaurantHoursHTML(),console.log(`In fillRestaurantHTML, about to call fetch then fill with id: ${e.id}`),DBHelper.fetchReviewsById(e.id).then(fillReviewsHTML)}),favoriteClicked=((e,t)=>{let n=!(!t.getAttribute("aria-pressed")||"true"!==t.getAttribute("aria-pressed")),r=`${DBHelper.DATABASE_URL}/${e.id}/?is_favorite=${!n}`;DBHelper.updateRestaurantCache(e.id,{is_favorite:!n}),DBHelper.addToUpdateQueue(r,"PUT"),t.setAttribute("aria-pressed",!n),t.innerHTML=n?"♡":"♥",t.onclick=(n=>favoriteClicked(e,t))}),fillRestaurantHoursHTML=((e=self.restaurant.operating_hours)=>{const t=document.getElementById("restaurant-hours");for(let n in e){const r=document.createElement("tr"),a=document.createElement("th");a.innerHTML=n,r.appendChild(a);const i=document.createElement("td");i.innerHTML=e[n],r.appendChild(i),t.appendChild(r)}}),fillReviewsHTML=((e=self.restaurant.reviews)=>{console.log("In fillReviewsHTML ",e);const t=document.getElementById("reviews-container"),n=document.createElement("h3");n.innerHTML="Reviews",t.appendChild(n);const r=document.createElement("button");if(r.innerHTML="Add a Review",r.id="reviewButton",r.onclick=addReviewForm,t.appendChild(r),!e){const e=document.createElement("h3");return e.innerHTML="
No reviews yet!
",void t.appendChild(e)}const a=document.getElementById("reviews-list");e.forEach(e=>{a.appendChild(createReviewHTML(e))}),t.appendChild(a)}),createReviewHTML=(e=>{const t=document.createElement("li"),n=document.createElement("p");n.id="reviewer-name",n.innerHTML=e.name,t.appendChild(n);const r=document.createElement("p");r.innerHTML=new Date(e.createdAt).toLocaleDateString(),t.appendChild(r);const a=document.createElement("p");a.innerHTML=`Rating: ${e.rating}`,t.appendChild(a);const l=document.createElement("p");var d="";for(i=0;i{const t=document.getElementById("breadcrumb"),n=document.createElement("li");n.setAttribute("aria-current","page"),n.innerHTML=e.name,t.appendChild(n)}),getParameterByName=((e,t)=>{t||(t=window.location.href),e=e.replace(/[\[\]]/g,"\\$&");const n=new RegExp(`[?&]${e}(=([^&#]*)|&|#|$)`).exec(t);return n?n[2]?decodeURIComponent(n[2].replace(/\+/g," ")):"":null}),addReviewForm=(()=>{document.getElementById("reviewButton").style.display="none",document.getElementById("reviews-list").appendChild(reviewForm()),document.getElementById("name").focus()}),reviewForm=(()=>{let e=document.createElement("li"),t=document.createElement("form");t.id="reviewForm";let n=document.createElement("p");n.innerHTML="New Review",n.id="reviewer-name",t.appendChild(n);let r=document.createElement("p"),a=document.createElement("input"),i=document.createElement("label");i.setAttribute("for","name"),i.innerHTML="First Name: ",a.id="name",a.setAttribute("type","text"),r.appendChild(i),r.appendChild(a),t.appendChild(r),r=document.createElement("p");let l=document.createElement("label");l.setAttribute("for","rating"),l.innerText="Your rating: ",r.appendChild(l);let d=document.createElement("select");d.id="rating",d.name="rating",d.classList.add("rating"),["--",1,2,3,4,5].forEach(e=>{const t=document.createElement("option");t.value=e,t.innerHTML=e,"--"===e&&(t.selected=!0),d.appendChild(t)}),r.appendChild(d),t.appendChild(r),r=document.createElement("p");let m=document.createElement("textarea"),o=document.createElement("label");o.setAttribute("for","comments"),o.innerHTML="Comments: ",m.id="comments",m.setAttribute("rows","10"),r.appendChild(o),r.appendChild(m),r.style.display="flex",r.style.alignItems="center",t.appendChild(r),r=document.createElement("p");let c=document.createElement("button");return c.id="submitReview",c.setAttribute("type","submit"),c.innerHTML="Submit Review",r.appendChild(c),t.appendChild(r),t.onsubmit=handleSubmit,e.appendChild(t),e}),handleSubmit=(e=>{e.preventDefault();let t=self.restaurant.id,n=document.getElementById("name").value,r=document.getElementById("rating").value-0,a=document.getElementById("comments").value;const l=document.getElementById("reviews-list"),d=document.createElement("li"),m=document.createElement("p");m.id="reviewer-name",m.innerHTML=n,d.appendChild(m);const o=document.createElement("p");o.innerHTML="Date",d.appendChild(o);const c=document.createElement("p");c.innerHTML=`Rating: ${r}`,d.appendChild(c);const s=document.createElement("p");var u="";for(i=0;i{fetchRestaurantFromURL((e,t)=>{e?console.error(e):(self.map=new google.maps.Map(document.getElementById("map"),{zoom:16,center:t.latlng,scrollwheel:!1}),fillBreadcrumb(),DBHelper.mapMarkerForRestaurant(self.restaurant,self.map))})}),fetchRestaurantFromURL=(e=>{if(self.restaurant)return void e(null,self.restaurant);const t=getParameterByName("id");if(t)DBHelper.fetchRestaurantById(t,(t,n)=>{self.restaurant=n,n?(fillRestaurantHTML(),e(null,n)):console.error(t)});else{e("No restaurant id in URL",null)}}),fillRestaurantHTML=((e=self.restaurant)=>{const t=document.getElementById("restaurant-name");t.innerHTML=e.name;const n=document.createElement("button");n.className="favButton";let r=!(!e.is_favorite||"true"!==e.is_favorite.toString());n.setAttribute("aria-pressed",r),n.setAttribute("aria-label",`Make ${e.name} a favorite!`),n.innerHTML=r?"♥":"♡",n.onclick=(t=>favoriteClicked(e,n)),t.appendChild(n),document.getElementById("restaurant-address").innerHTML=e.address;const a=document.getElementById("restaurant-img");a.className="restaurant-img",a.src=`/img/${e.id}@1x.webp`,a.srcset=`/img/${e.id}@1x.webp 300w,\n /img/${e.id}@2x.webp 600w,\n /img/${e.id}@3x.webp 900w`,a.alt=`Image of ${e.name} restaurant`,document.getElementById("restaurant-cuisine").innerHTML=e.cuisine_type,e.operating_hours&&fillRestaurantHoursHTML(),console.log(`In fillRestaurantHTML, about to call fetch then fill with id: ${e.id}`),DBHelper.fetchReviewsById(e.id).then(fillReviewsHTML)}),favoriteClicked=((e,t)=>{let n=!(!t.getAttribute("aria-pressed")||"true"!==t.getAttribute("aria-pressed")),r=`${DBHelper.DATABASE_URL}/${e.id}/?is_favorite=${!n}`;DBHelper.updateRestaurantCache(e.id,{is_favorite:!n}),DBHelper.addToUpdateQueue(r,"PUT"),t.setAttribute("aria-pressed",!n),t.innerHTML=n?"♡":"♥",t.onclick=(n=>favoriteClicked(e,t))}),fillRestaurantHoursHTML=((e=self.restaurant.operating_hours)=>{const t=document.getElementById("restaurant-hours");for(let n in e){const r=document.createElement("tr"),a=document.createElement("th");a.innerHTML=n,r.appendChild(a);const i=document.createElement("td");i.innerHTML=e[n],r.appendChild(i),t.appendChild(r)}}),fillReviewsHTML=((e=self.restaurant.reviews)=>{console.log("In fillReviewsHTML ",e);const t=document.getElementById("reviews-container"),n=document.createElement("h3");n.innerHTML="Reviews",t.appendChild(n);const r=document.createElement("button");if(r.innerHTML="Add a Review",r.id="reviewButton",r.onclick=addReviewForm,t.appendChild(r),!e){const e=document.createElement("h3");return e.innerHTML="
No reviews yet!
",void t.appendChild(e)}const a=document.getElementById("reviews-list");e.forEach(e=>{a.appendChild(createReviewHTML(e))}),t.appendChild(a)}),createReviewHTML=(e=>{const t=document.createElement("li"),n=document.createElement("p");n.id="reviewer-name",n.innerHTML=e.name,t.appendChild(n);const r=document.createElement("p");r.innerHTML=new Date(e.createdAt).toLocaleDateString(),t.appendChild(r);const a=document.createElement("p");a.innerHTML=`Rating: ${e.rating}`,t.appendChild(a);const l=document.createElement("p");var d="";for(i=0;i{const t=document.getElementById("breadcrumb"),n=document.createElement("li");n.setAttribute("aria-current","page"),n.innerHTML=e.name,t.appendChild(n)}),getParameterByName=((e,t)=>{t||(t=window.location.href),e=e.replace(/[\[\]]/g,"\\$&");const n=new RegExp(`[?&]${e}(=([^&#]*)|&|#|$)`).exec(t);return n?n[2]?decodeURIComponent(n[2].replace(/\+/g," ")):"":null}),addReviewForm=(()=>{document.getElementById("reviewButton").style.display="none",document.getElementById("reviews-list").appendChild(reviewForm()),document.getElementById("name").focus()}),reviewForm=(()=>{let e=document.createElement("li"),t=document.createElement("form");t.id="reviewForm";let n=document.createElement("p");n.innerHTML="New Review",n.id="reviewer-name",t.appendChild(n);let r=document.createElement("p"),a=document.createElement("input"),i=document.createElement("label");i.setAttribute("for","name"),i.innerHTML="First Name: ",a.id="name",a.setAttribute("type","text"),r.appendChild(i),r.appendChild(a),t.appendChild(r),r=document.createElement("p");let l=document.createElement("label");l.setAttribute("for","rating"),l.innerText="Your rating: ",r.appendChild(l);let d=document.createElement("select");d.id="rating",d.name="rating",d.classList.add("rating"),["--",1,2,3,4,5].forEach(e=>{const t=document.createElement("option");t.value=e,t.innerHTML=e,"--"===e&&(t.selected=!0),d.appendChild(t)}),r.appendChild(d),t.appendChild(r),r=document.createElement("p");let m=document.createElement("textarea"),o=document.createElement("label");o.setAttribute("for","comments"),o.innerHTML="Comments: ",m.id="comments",m.setAttribute("rows","10"),r.appendChild(o),r.appendChild(m),r.style.display="flex",r.style.alignItems="center",t.appendChild(r),r=document.createElement("p");let c=document.createElement("button");return c.id="submitReview",c.setAttribute("type","submit"),c.innerHTML="Submit Review",r.appendChild(c),t.appendChild(r),t.onsubmit=handleSubmit,e.appendChild(t),e}),handleSubmit=(e=>{e.preventDefault();let t=self.restaurant.id,n=document.getElementById("name").value,r=document.getElementById("rating").value-0,a=document.getElementById("comments").value;const l=document.getElementById("reviews-list"),d=document.createElement("li"),m=document.createElement("p");m.id="reviewer-name",m.innerHTML=n,d.appendChild(m);const o=document.createElement("p");o.innerHTML="Date",d.appendChild(o);const c=document.createElement("p");c.innerHTML=`Rating: ${r}`,d.appendChild(c);const s=document.createElement("p");var u="";for(i=0;i-1&&e.respondWith(DBHelper.idbRestaurantRequest()),e.respondWith(DBHelper.idbReviewRequest())}function cacheFetch(e,t){console.log("In cacheFetch"),e.respondWith(caches.match(t)).then(function(t){return t||fetch(e.request).then(function(t){return caches.open(myCache).then(function(n){return-1===t.url.indexOf("browsersync")&&n.put(e.request,t.clone()),t})}).catch(function(e){console.log(`In cacheFetch catch, error: ${e.message}`)})})}self.addEventListener("install",function(e){console.log("In eventListener for install"),e.waitUntil(caches.open(myCache).then(function(e){return e.addAll(cacheFiles).then(function(){console.log("Cache worked!")}).catch(function(e){console.log("Caching failed, error: ",e)})}))}),self.addEventListener("fetch",function(e){console.log("In eventListener for fetch, event");let t=new URL(e.request.url);if("1337"===t.port){let n=t.searchParams.get("restaurant_id")-0;if(n){let t=e.request;t.url.indexOf("restaurant.html")>-1&&(t=new Request("restaurant.html")),cacheFetch(e,t)}else{if(t.pathname.indexOf("restaurants")){let e=t.pathname.split("/");n="restaurants"===e[e.length-1]?"-1":e[e.length-1]}else n=t.searchParams.get("restaurant_id");apiFetch(e,n)}}}); \ No newline at end of file +self.importScripts("js/idb.js");var myCache="restaurantReview_302",cacheFiles=["index.html","restaurant.html","css/styles.css","img/","js/dbhelper.js","js/main.js","js/restaurant_info.js","js/swregister.js","js/idb.js"];function apiFetch(e,t){if(console.log("In apiFetch"),"GET"!=e.request.method)return fetch(e.request).then(function(e){return e.json()});e.request.url.indexOf("restaurants")>-1&&e.respondWith(dbPromise.then(function(e){return e.transaction("restaurantData").objectStore("restaurantData").get(t)}).then(function(n){return n&&n.data||fetch(e.request).then(function(e){return dbPromise.then(function(n){return n.transaction("restaurantData","readwrite").objectStore("restaurantData").put({id:t,data:e.json()}),e.json()})})}).then(function(e){return new Response(JSON.stringify(e))}).catch(function(e){console.log(`In DBHelper.idbRestaurantRequest, error: ${e.message}`)})),e.respondWith(dbPromise.then(function(e){return e.transaction("reviewData").objectStore("reviewData").index("restaurant_id").getAll(t)}).then(function(t){return t&&t.data||fetch(e.request).then(function(e){return dbPromise.then(function(t){let n=t.transaction("reviewData","readwrite").objectStore("reviewData"),r=e.json();return r.forEach(function(e){n.put({id:e.id,restaurant_id:e.restaurant_id,data:e})}),r})})}).then(function(e){if(e[0].data){let t=e.map(e=>e.data);return new Response(JSON.stringify(t))}return new Response(JSON.stringify(e))}).catch(function(e){console.log(`In apiFetch catch-reviewData, error: ${e.message}`)}))}function cacheFetch(e,t){console.log("In cacheFetch"),e.respondWith(caches.match(t)).then(function(t){return t||fetch(e.request).then(function(t){return caches.open(myCache).then(function(n){return-1===t.url.indexOf("browsersync")&&n.put(e.request,t.clone()),t})}).catch(function(e){console.log(`In cacheFetch catch, error: ${e.message}`)})})}self.addEventListener("install",function(e){console.log("In eventListener for install"),e.waitUntil(caches.open(myCache).then(function(e){return e.addAll(cacheFiles).then(function(){console.log("Cache worked!")}).catch(function(e){console.log("Caching failed, error: ",e)})}))}),self.addEventListener("fetch",function(e){console.log("In eventListener for fetch, event");let t=new URL(e.request.url);if("1337"===t.port){let n=t.searchParams.get("restaurant_id")-0;if(n){let t=e.request;t.url.indexOf("restaurant.html")>-1&&(t=new Request("restaurant.html")),cacheFetch(e,t)}else{if(t.pathname.indexOf("restaurants")){let e=t.pathname.split("/");n="restaurants"===e[e.length-1]?"-1":e[e.length-1]}else n=t.searchParams.get("restaurant_id");apiFetch(e,n)}}}); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 249ded6..20db41e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5758,6 +5758,11 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "idb": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/idb/-/idb-2.1.3.tgz", + "integrity": "sha512-1He6QAuavrD38HCiJasi4lEEK87Y22ldFuM+ZHkp433n4Fd5jXjWKutClYFp8w4mgx3zgrjnWxL8dpjMzcQ+WQ==" + }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", diff --git a/package.json b/package.json index e7ac935..bcf87ee 100644 --- a/package.json +++ b/package.json @@ -43,5 +43,8 @@ "gulp-util": "^3.0.8", "gulp-webp": "^3.0.0", "uglify-es": "^3.3.9" + }, + "dependencies": { + "idb": "^2.1.3" } }