diff --git a/public/offline.html b/public/offline.html
new file mode 100644
index 000000000..b216ae2ea
--- /dev/null
+++ b/public/offline.html
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+ You are offline
+
+
+
+
+
+
+
+
+
You are offline
+
+
Click the button below to try reloading.
+
+
+
+
+
+
+
+
+
diff --git a/public/sw.js b/public/sw.js
new file mode 100644
index 000000000..b88112cf2
--- /dev/null
+++ b/public/sw.js
@@ -0,0 +1,45 @@
+const OFFLINE_VERSION = 1;
+const CACHE_NAME = "offline";
+const OFFLINE_URL = "/offline.html";
+
+self.addEventListener("install", (event) => {
+ event.waitUntil(
+ (async () => {
+ const cache = await caches.open(CACHE_NAME);
+ await cache.add(new Request(OFFLINE_URL, { cache: "reload" }));
+ })()
+ );
+ self.skipWaiting();
+});
+
+self.addEventListener("activate", (event) => {
+ event.waitUntil(
+ (async () => {
+ if ("navigationPreload" in self.registration) {
+ await self.registration.navigationPreload.enable();
+ }
+ })()
+ );
+ self.clients.claim();
+});
+
+self.addEventListener("fetch", (event) => {
+ if (event.request.mode === "navigate") {
+ event.respondWith(
+ (async () => {
+ try {
+ const preloadResponse = await event.preloadResponse;
+ if (preloadResponse) {
+ return preloadResponse;
+ }
+ const networkResponse = await fetch(event.request);
+ return networkResponse;
+ } catch (error) {
+ const cache = await caches.open(CACHE_NAME);
+ const cachedResponse = await cache.match(OFFLINE_URL);
+ return cachedResponse;
+ }
+ })()
+ );
+ }
+});
diff --git a/resources/assets/js/app.js b/resources/assets/js/app.js
index 2d1af4b41..8471cd6d4 100644
--- a/resources/assets/js/app.js
+++ b/resources/assets/js/app.js
@@ -34,6 +34,12 @@ window.App.boot = function() {
new Vue({ el: '#content'});
}
+window.addEventListener("load", () => {
+ if ("serviceWorker" in navigator) {
+ navigator.serviceWorker.register("/sw.js");
+ }
+});
+
window.App.util = {
compose: {
post: (function() {
@@ -230,4 +236,4 @@ window.App.util = {
.attr('width', 34).attr('height', 34);
})
-};
\ No newline at end of file
+};