755
									
								
								frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						| @@ -15,6 +15,7 @@ | |||||||
|     "fast-levenshtein": "^3.0.0", |     "fast-levenshtein": "^3.0.0", | ||||||
|     "fuse.js": "^6.4.6", |     "fuse.js": "^6.4.6", | ||||||
|     "qs": "^6.9.6", |     "qs": "^6.9.6", | ||||||
|  |     "register-service-worker": "^1.7.1", | ||||||
|     "typeface-roboto": "^1.1.13", |     "typeface-roboto": "^1.1.13", | ||||||
|     "v-jsoneditor": "^1.4.2", |     "v-jsoneditor": "^1.4.2", | ||||||
|     "vue": "^2.6.11", |     "vue": "^2.6.11", | ||||||
| @@ -30,6 +31,7 @@ | |||||||
|     "@mdi/font": "^5.9.55", |     "@mdi/font": "^5.9.55", | ||||||
|     "@vue/cli-plugin-babel": "^4.5.11", |     "@vue/cli-plugin-babel": "^4.5.11", | ||||||
|     "@vue/cli-plugin-eslint": "^4.5.11", |     "@vue/cli-plugin-eslint": "^4.5.11", | ||||||
|  |     "@vue/cli-plugin-pwa": "~4.5.0", | ||||||
|     "@vue/cli-service": "^4.5.12", |     "@vue/cli-service": "^4.5.12", | ||||||
|     "babel-eslint": "^10.1.0", |     "babel-eslint": "^10.1.0", | ||||||
|     "eslint": "^6.7.2", |     "eslint": "^6.7.2", | ||||||
| @@ -55,16 +57,16 @@ | |||||||
|     }, |     }, | ||||||
|     "rules": {} |     "rules": {} | ||||||
|   }, |   }, | ||||||
|   "browserslist": [ |  | ||||||
|     "> 1%", |  | ||||||
|     "last 2 versions", |  | ||||||
|     "not dead" |  | ||||||
|   ], |  | ||||||
|   "prettier": { |   "prettier": { | ||||||
|     "trailingComma": "es5", |     "trailingComma": "es5", | ||||||
|     "tabWidth": 2, |     "tabWidth": 2, | ||||||
|     "semi": true, |     "semi": true, | ||||||
|     "singleQuote": false, |     "singleQuote": false, | ||||||
|     "printWidth": 120 |     "printWidth": 120 | ||||||
|   } |   }, | ||||||
|  |   "browserslist": [ | ||||||
|  |     "> 1%", | ||||||
|  |     "last 2 versions", | ||||||
|  |     "not dead" | ||||||
|  |   ] | ||||||
| } | } | ||||||
|   | |||||||
| Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 32 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/img/icons/android-chrome-192x192.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 12 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/img/icons/android-chrome-512x512.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 26 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/img/icons/android-chrome-maskable-192x192.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 12 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/img/icons/android-chrome-maskable-512x512.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 26 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/img/icons/apple-touch-icon-120x120.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 6.8 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/img/icons/apple-touch-icon-152x152.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 10 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/img/icons/apple-touch-icon-180x180.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 13 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/img/icons/apple-touch-icon-60x60.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 2.8 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/img/icons/apple-touch-icon-76x76.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.8 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/img/icons/apple-touch-icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 13 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/img/icons/favicon-16x16.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 574 B | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/img/icons/favicon-32x32.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.2 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/img/icons/msapplication-icon-144x144.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 8.7 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/img/icons/mstile-150x150.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 10 KiB | 
							
								
								
									
										3
									
								
								frontend/public/img/icons/safari-pinned-tab.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,3 @@ | |||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 256 256" version="1.1"> | ||||||
|  | 	<path d="M 162.083 54.642 C 148.745 68.272, 137.170 80.703, 136.362 82.266 C 133.689 87.435, 133.522 94.130, 135.929 99.573 C 137.122 102.269, 139.070 105.510, 140.258 106.775 L 142.418 109.074 90.974 160.526 L 39.529 211.979 46.999 219.499 L 54.470 227.020 91.235 190.265 L 128 153.510 164.765 190.265 L 201.530 227.020 209 219.500 L 216.470 211.980 179.725 175.225 L 142.980 138.470 150.320 131.178 C 156.858 124.685, 157.808 124.063, 159.001 125.501 C 162.066 129.195, 168.873 132.163, 174.392 132.213 C 183.508 132.295, 186.374 130.174, 212.477 104.038 L 236.454 80.030 231.501 75.001 L 226.548 69.973 209.288 87.212 L 192.027 104.452 187 99.500 L 181.973 94.548 199.212 77.288 L 216.452 60.027 211.500 55 L 206.548 49.973 189.288 67.212 L 172.027 84.452 167 79.500 L 161.973 74.548 179.225 57.275 L 196.477 40.001 191.406 34.930 L 186.335 29.859 162.083 54.642 M 38.429 41.250 C 31.557 49.376, 28.011 62.815, 29.835 73.824 C 31.955 86.615, 34.508 90.093, 61.720 117.253 L 86.520 142.005 101.501 126.999 L 116.482 111.993 79.496 74.996 C 59.154 54.648, 42.210 38, 41.844 38 C 41.478 38, 39.941 39.462, 38.429 41.250" stroke="none" fill="black" fill-rule="evenodd"/> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 1.2 KiB | 
| @@ -1,21 +1,24 @@ | |||||||
| <!DOCTYPE html> | <!DOCTYPE html> | ||||||
| <html lang="en"> | <html lang="en"> | ||||||
|  |  | ||||||
| <head> | <head> | ||||||
|   <meta charset="utf-8"> |   <meta charset="utf-8"> | ||||||
|   <meta http-equiv="X-UA-Compatible" content="IE=edge"> |   <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||||||
|   <meta name="viewport" content="width=device-width,initial-scale=1.0"> |   <meta name="viewport" content="width=device-width,initial-scale=1.0"> | ||||||
|  |   <meta name="description" content="Mealie is a self hosted recipe manager and meal planner."> | ||||||
|   <link rel="icon" href="<%= BASE_URL %>favicon.ico"> |   <link rel="icon" href="<%= BASE_URL %>favicon.ico"> | ||||||
|     <link rel="apple-touch-icon" sizes="256x256" href="<%= BASE_URL %>favicon.ico"> |  | ||||||
|     <link rel="manifest" href='data:application/manifest+json,{"name":"Mealie","icons":[{"src":"<%= BASE_URL %>favicon.ico","sizes":"256x256","type":"image/png"}],"scope":"<%= BASE_URL %>","start_url":"<%= BASE_URL %>","display":"standalone"}'> |  | ||||||
|   <title> Mealie </title> |   <title> Mealie </title> | ||||||
|   <!-- <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900"> --> |   <!-- <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900"> --> | ||||||
|   <!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css"> --> |   <!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css"> --> | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
| <body> | <body> | ||||||
|   <noscript> |   <noscript> | ||||||
|       <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> |     <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. | ||||||
|  |         Please enable it to continue.</strong> | ||||||
|   </noscript> |   </noscript> | ||||||
|   <div id="app"></div> |   <div id="app"></div> | ||||||
|   <!-- built files will be auto injected --> |   <!-- built files will be auto injected --> | ||||||
| </body> | </body> | ||||||
|  |  | ||||||
| </html> | </html> | ||||||
							
								
								
									
										82
									
								
								frontend/public/manifest.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,82 @@ | |||||||
|  | { | ||||||
|  |   "name": "Mealie", | ||||||
|  |   "short_name": "Mealie", | ||||||
|  |   "icons": [ | ||||||
|  |     { | ||||||
|  |       "src": "./img/icons/android-chrome-192x192.png", | ||||||
|  |       "sizes": "192x192", | ||||||
|  |       "type": "image/png" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "src": "./img/icons/android-chrome-512x512.png", | ||||||
|  |       "sizes": "512x512", | ||||||
|  |       "type": "image/png" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "src": "./img/icons/android-chrome-maskable-192x192.png", | ||||||
|  |       "sizes": "192x192", | ||||||
|  |       "type": "image/png", | ||||||
|  |       "purpose": "maskable" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "src": "./img/icons/android-chrome-maskable-512x512.png", | ||||||
|  |       "sizes": "512x512", | ||||||
|  |       "type": "image/png", | ||||||
|  |       "purpose": "maskable" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "src": "./img/icons/apple-touch-icon-60x60.png", | ||||||
|  |       "sizes": "60x60", | ||||||
|  |       "type": "image/png" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "src": "./img/icons/apple-touch-icon-76x76.png", | ||||||
|  |       "sizes": "76x76", | ||||||
|  |       "type": "image/png" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "src": "./img/icons/apple-touch-icon-120x120.png", | ||||||
|  |       "sizes": "120x120", | ||||||
|  |       "type": "image/png" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "src": "./img/icons/apple-touch-icon-152x152.png", | ||||||
|  |       "sizes": "152x152", | ||||||
|  |       "type": "image/png" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "src": "./img/icons/apple-touch-icon-180x180.png", | ||||||
|  |       "sizes": "180x180", | ||||||
|  |       "type": "image/png" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "src": "./img/icons/apple-touch-icon.png", | ||||||
|  |       "sizes": "180x180", | ||||||
|  |       "type": "image/png" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "src": "./img/icons/favicon-16x16.png", | ||||||
|  |       "sizes": "16x16", | ||||||
|  |       "type": "image/png" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "src": "./img/icons/favicon-32x32.png", | ||||||
|  |       "sizes": "32x32", | ||||||
|  |       "type": "image/png" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "src": "./img/icons/msapplication-icon-144x144.png", | ||||||
|  |       "sizes": "144x144", | ||||||
|  |       "type": "image/png" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "src": "./img/icons/mstile-150x150.png", | ||||||
|  |       "sizes": "150x150", | ||||||
|  |       "type": "image/png" | ||||||
|  |     } | ||||||
|  |   ], | ||||||
|  |   "start_url": ".", | ||||||
|  |   "display": "standalone", | ||||||
|  |   "background_color": "#FFFFFF", | ||||||
|  |   "theme_color": "#E58325" | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								frontend/public/robots.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,2 @@ | |||||||
|  | User-agent: * | ||||||
|  | Disallow: | ||||||
| @@ -9,6 +9,17 @@ | |||||||
|         </div> |         </div> | ||||||
|       </v-banner> |       </v-banner> | ||||||
|       <GlobalSnackbar /> |       <GlobalSnackbar /> | ||||||
|  |       <v-snackbar v-model="snackWithButtons" bottom left timeout="-1"> | ||||||
|  |         {{ snackWithBtnText }} | ||||||
|  |         <template v-slot:action="{ attrs }"> | ||||||
|  |           <v-btn text color="primary" v-bind="attrs" @click.stop="refreshApp"> | ||||||
|  |             {{ snackBtnText }} | ||||||
|  |           </v-btn> | ||||||
|  |           <v-btn icon class="ml-4" @click="snackWithButtons = false"> | ||||||
|  |             <v-icon>{{ $globals.icons.close }}</v-icon> | ||||||
|  |           </v-btn> | ||||||
|  |         </template> | ||||||
|  |       </v-snackbar> | ||||||
|       <router-view></router-view> |       <router-view></router-view> | ||||||
|     </v-main> |     </v-main> | ||||||
|   </v-app> |   </v-app> | ||||||
| @@ -51,6 +62,29 @@ export default { | |||||||
|     this.$store.dispatch("requestSiteSettings"); |     this.$store.dispatch("requestSiteSettings"); | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       refreshing: false, | ||||||
|  |       registration: null, | ||||||
|  |       snackBtnText: "", | ||||||
|  |       snackWithBtnText: "", | ||||||
|  |       snackWithButtons: false, | ||||||
|  |     }; | ||||||
|  |   }, | ||||||
|  |  | ||||||
|  |   created() { | ||||||
|  |     // Listen for swUpdated event and display refresh snackbar as required. | ||||||
|  |     document.addEventListener("swUpdated", this.showRefreshUI, { once: true }); | ||||||
|  |     // Refresh all open app tabs when a new service worker is installed. | ||||||
|  |     if (navigator.serviceWorker) { | ||||||
|  |       navigator.serviceWorker.addEventListener("controllerchange", () => { | ||||||
|  |         if (this.refreshing) return; | ||||||
|  |         this.refreshing = true; | ||||||
|  |         window.location.reload(); | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |  | ||||||
|   methods: { |   methods: { | ||||||
|     // For Later! |     // For Later! | ||||||
|  |  | ||||||
| @@ -70,6 +104,25 @@ export default { | |||||||
|         this.darkModeSystemCheck(); |         this.darkModeSystemCheck(); | ||||||
|       }); |       }); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|  |     showRefreshUI(e) { | ||||||
|  |       // Display a snackbar inviting the user to refresh/reload the app due | ||||||
|  |       // to an app update being available. | ||||||
|  |       // The new service worker is installed, but not yet active. | ||||||
|  |       // Store the ServiceWorkerRegistration instance for later use. | ||||||
|  |       this.registration = e.detail; | ||||||
|  |       this.snackBtnText = "Refresh"; | ||||||
|  |       this.snackWithBtnText = "New version available!"; | ||||||
|  |       this.snackWithButtons = true; | ||||||
|  |     }, | ||||||
|  |     refreshApp() { | ||||||
|  |       this.snackWithButtons = false; | ||||||
|  |       // Protect against missing registration.waiting. | ||||||
|  |       if (!this.registration || !this.registration.waiting) { | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |       this.registration.waiting.postMessage("skipWaiting"); | ||||||
|  |     }, | ||||||
|   }, |   }, | ||||||
| }; | }; | ||||||
| </script> | </script> | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import { globals } from "@/utils/globals"; | |||||||
| import i18n from "./i18n"; | import i18n from "./i18n"; | ||||||
| import "@mdi/font/css/materialdesignicons.css"; | import "@mdi/font/css/materialdesignicons.css"; | ||||||
| import "typeface-roboto/index.css"; | import "typeface-roboto/index.css"; | ||||||
|  | import './registerServiceWorker' | ||||||
|  |  | ||||||
| Vue.config.productionTip = false; | Vue.config.productionTip = false; | ||||||
| Vue.use(VueRouter); | Vue.use(VueRouter); | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								frontend/src/registerServiceWorker.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,39 @@ | |||||||
|  | /* eslint-disable no-console */ | ||||||
|  |  | ||||||
|  | import { register } from "register-service-worker"; | ||||||
|  |  | ||||||
|  | if (process.env.NODE_ENV === "production") { | ||||||
|  |   register(`${process.env.BASE_URL}service-worker.js`, { | ||||||
|  |     ready() { | ||||||
|  |       console.log("Service worker is active."); | ||||||
|  |     }, | ||||||
|  |     registered(registration) { | ||||||
|  |       console.log("Service worker has been registered."); | ||||||
|  |  | ||||||
|  |       // Routinely check for app updates by testing for a new service worker. | ||||||
|  |       setInterval(() => { | ||||||
|  |         registration.update(); | ||||||
|  |       }, 1000 * 60 * 60); // hourly checks | ||||||
|  |     }, | ||||||
|  |     cached() { | ||||||
|  |       console.log("Content has been cached for offline use."); | ||||||
|  |     }, | ||||||
|  |     updatefound() { | ||||||
|  |       console.log("New content is downloading."); | ||||||
|  |     }, | ||||||
|  |     updated(registration) { | ||||||
|  |       console.log("New content is available; please refresh."); | ||||||
|  |  | ||||||
|  |       // Add a custom event and dispatch it. | ||||||
|  |       // Used to display of a 'refresh' banner following a service worker update. | ||||||
|  |       // Set the event payload to the service worker registration object. | ||||||
|  |       document.dispatchEvent(new CustomEvent("swUpdated", { detail: registration })); | ||||||
|  |     }, | ||||||
|  |     offline() { | ||||||
|  |       console.log("No internet connection found. App is running in offline mode."); | ||||||
|  |     }, | ||||||
|  |     error(error) { | ||||||
|  |       console.error("Error during service worker registration:", error); | ||||||
|  |     }, | ||||||
|  |   }); | ||||||
|  | } | ||||||
							
								
								
									
										75
									
								
								frontend/src/sw.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,75 @@ | |||||||
|  | /* eslint-disable no-undef, no-underscore-dangle, no-restricted-globals */ | ||||||
|  |  | ||||||
|  | self.addEventListener("install", event => { | ||||||
|  |   event.waitUntil(preLoad()); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | var preLoad = async () => { | ||||||
|  |   console.log("Installing web app"); | ||||||
|  |   const cache = await caches.open("offline"); | ||||||
|  |   console.log("caching index and important routes"); | ||||||
|  |   return await cache.addAll(["/", "/recipes/all"]); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | self.addEventListener("fetch", event => { | ||||||
|  |   event.respondWith( | ||||||
|  |     checkResponse(event.request).catch(() => { | ||||||
|  |       return returnFromCache(event.request); | ||||||
|  |     }) | ||||||
|  |   ); | ||||||
|  |   event.waitUntil(addToCache(event.request)); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | var checkResponse = request => { | ||||||
|  |   return new Promise(function(fulfill, reject) { | ||||||
|  |     fetch(request).then(function(response) { | ||||||
|  |       if (response.status !== 404) { | ||||||
|  |         fulfill(response); | ||||||
|  |       } else { | ||||||
|  |         reject(); | ||||||
|  |       } | ||||||
|  |     }, reject); | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | var addToCache = async request => { | ||||||
|  |   const cache = await caches.open("offline"); | ||||||
|  |   const response = await fetch(request); | ||||||
|  |   console.log(response.url + " was cached"); | ||||||
|  |   return await cache.put(request, response); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | var returnFromCache = async request => { | ||||||
|  |   const cache = await caches.open("offline"); | ||||||
|  |   const matching = await cache.match(request); | ||||||
|  |   if (!matching || matching.status == 404) { | ||||||
|  |     return cache.match("offline.html"); | ||||||
|  |   } else { | ||||||
|  |     return matching; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // This is the code piece that GenerateSW mode can't provide for us. | ||||||
|  | // This code listens for the user's confirmation to update the app. | ||||||
|  | self.addEventListener("message", e => { | ||||||
|  |   if (!e.data) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   switch (e.data) { | ||||||
|  |     case "skipWaiting": | ||||||
|  |       self.skipWaiting(); | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       // NOOP | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | workbox.core.clientsClaim(); // Vue CLI 4 and Workbox v4, else | ||||||
|  | // workbox.clientsClaim(); // Vue CLI 3 and Workbox v3. | ||||||
|  |  | ||||||
|  | // The precaching code provided by Workbox. | ||||||
|  | self.__precacheManifest = [].concat(self.__precacheManifest || []); | ||||||
|  | // workbox.precaching.suppressWarnings(); // Only used with Vue CLI 3 and Workbox v3. | ||||||
|  | workbox.precaching.precacheAndRoute(self.__precacheManifest, {}); | ||||||
| @@ -1,4 +1,5 @@ | |||||||
| const path = require("path"); | const path = require("path"); | ||||||
|  | const manifestJSON = require("./public/manifest.json"); | ||||||
| module.exports = { | module.exports = { | ||||||
|   transpileDependencies: ["vuetify"], |   transpileDependencies: ["vuetify"], | ||||||
|   publicPath: process.env.NODE_ENV === "production" ? "/" : "/", |   publicPath: process.env.NODE_ENV === "production" ? "/" : "/", | ||||||
| @@ -26,4 +27,17 @@ module.exports = { | |||||||
|       }, |       }, | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|  |   pwa: { | ||||||
|  |     name: manifestJSON.short_name, | ||||||
|  |     themeColor: manifestJSON.theme_color, | ||||||
|  |     msTileColor: manifestJSON.background_color, | ||||||
|  |     appleMobileWebAppCapable: "yes", | ||||||
|  |     appleMobileWebAppStatusBarStyle: "black", | ||||||
|  |  | ||||||
|  |     workboxPluginMode: "InjectManifest", | ||||||
|  |     workboxOptions: { | ||||||
|  |       swSrc: "./src/sw.js", | ||||||
|  |       swDest: "service-worker.js", | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
| }; | }; | ||||||
|   | |||||||