From 53747186cf6157b8f604345f241e9df9a893c768 Mon Sep 17 00:00:00 2001
From: Jacek Kowalski <Jacek@jacekk.info>
Date: Thu, 04 May 2017 11:33:28 +0000
Subject: [PATCH] Service worker draft

---
 index.js                 |    3 
 map.js                   |    1 
 common.js                |   27 ------
 version.php              |    9 ++
 index.html               |    1 
 map.html                 |    1 
 serviceworker-install.js |   10 ++
 serviceworker.js         |  135 +++++++++++++++++++++++++++++++++
 8 files changed, 160 insertions(+), 27 deletions(-)

diff --git a/common.js b/common.js
index 64f0167..faca5a0 100644
--- a/common.js
+++ b/common.js
@@ -4,31 +4,10 @@
 	'Zajezdnia Podgórze' : 'P',
 };
 
-var script_version;
-var script_version_xhr;
-
-// Check for website updates
+/* Check for website updates */
 function checkVersion() {
-	if(script_version_xhr) script_version_xhr.abort();
-	
-	script_version_xhr = $.get(
-		'version.php'
-	).done(function(data) {
-		if(!script_version) {
-			script_version = data;
-			return;
-		}
-		
-		if(script_version != data) {
-			fail(lang.error_new_version);
-			location.reload(true);
-		}
-	});
-}
-
-function checkVersionInit() {
-	checkVersion();
-	setInterval(checkVersion, 3600000);
+	$.get('version.php');
+	setTimeout(checkVersion, 600000);
 }
 
 /* Parsing of received JSON parts */
diff --git a/index.html b/index.html
index f4e3a0e..4939a22 100644
--- a/index.html
+++ b/index.html
@@ -137,5 +137,6 @@
 		<script tyle="text/javascript" src="lang_pl.js" id="lang_script"></script>
 		<script tyle="text/javascript" src="common.js"></script>
 		<script type="text/javascript" src="index.js"></script>
+		<script tyle="text/javascript" src="serviceworker-install.js"></script>
 	</body>
 </html>
diff --git a/index.js b/index.js
index fc4a34d..019c763 100644
--- a/index.js
+++ b/index.js
@@ -403,8 +403,7 @@
 	hash();
 	
 	window.addEventListener('hashchange', hash);
-	
-	checkVersionInit();
 }
 
 init();
+checkVersion();
diff --git a/map.html b/map.html
index ab987b6..896fa82 100644
--- a/map.html
+++ b/map.html
@@ -19,5 +19,6 @@
 <script tyle="text/javascript" src="lang_pl.js" id="lang_script"></script>
 <script tyle="text/javascript" src="common.js"></script>
 <script tyle="text/javascript" src="map.js"></script>
+<script tyle="text/javascript" src="serviceworker-install.js"></script>
 </body>
 </html>
diff --git a/map.js b/map.js
index f791391..2e3614d 100644
--- a/map.js
+++ b/map.js
@@ -761,3 +761,4 @@
 }
 
 init();
+checkVersion();
diff --git a/serviceworker-install.js b/serviceworker-install.js
new file mode 100644
index 0000000..1d3d1b5
--- /dev/null
+++ b/serviceworker-install.js
@@ -0,0 +1,10 @@
+if('serviceWorker' in navigator) {
+	window.addEventListener('load', function() {
+		navigator.serviceWorker.register('/serviceworker.js').then(function(registration) {
+			console.log('Service Worker registration successful. ', registration);
+			navigator.serviceWorker.controller.postMessage({action: 'skipWaiting'});
+		}).catch(function(err) {
+			console.log('Service Worker registration failed. ', err);
+		});
+	});
+}
diff --git a/serviceworker.js b/serviceworker.js
new file mode 100644
index 0000000..9693f91
--- /dev/null
+++ b/serviceworker.js
@@ -0,0 +1,135 @@
+'use strict';
+
+var CACHE = 'ttss-app-v1';
+var CACHE_RESOURCES = [
+	'/version.php',
+	'/',
+	'/common.js',
+	'/index.css',
+	'/index.html',
+	'/index.js',
+	'/lang_en.js',
+	'/lang_pl.js',
+	'/map.css',
+	'/map.html',
+	'/map.js',
+	'/serviceworker-install.js',
+	'https://code.jquery.com/jquery-3.1.1.min.js',
+	'https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList',
+	'https://openlayers.org/en/v4.1.0/build/ol.js'
+];
+
+var self = this;
+
+this.addEventListener('install', event => {
+	event.waitUntil(
+		caches.open(CACHE).then(cache => {
+			return cache.addAll(CACHE_RESOURCES);
+		})
+	);
+});
+
+this.addEventListener('fetch', event => {
+	event.respondWith(
+		caches.match(event.request).then(response => response || fetch(event.request))
+	);
+	
+	if(event.request.url.endsWith('/version.php')) {
+		event.waitUntil(
+			Promise.all([
+				caches.open(CACHE),
+				fetch(event.request)
+			]).then(results => {
+				var cache = results[0];
+				var v2 = results[1];
+				var v2copy = v2.clone();
+				
+				return Promise.all([
+					cache.match(event.request).then(v1 => v1.json()),
+					v2copy.json()
+				]).then(results => {
+					var v1json = results[0];
+					var v2json = results[1];
+					
+					return updateCache(cache, v1json, v2json).then(_ => cache.put(event.request, v2)).then(function() {
+						console.log('Service Worker: update successful!');
+						self.skipWaiting();
+						postMessage({action: 'updated'});
+					});
+				});
+			}).catch(function(error) {
+				console.log('Service Worker: update failed: ', error);
+				postMessage({action: 'updateFailed'});
+			})
+		);
+	}
+});
+
+this.addEventListener('activate', event => {
+	event.waitUntil(
+		caches.keys().then(keyList => Promise.all(
+			keyList.map(key => {
+				if (key != CACHE) {
+					return caches.delete(key);
+				}
+			})
+		)).then(caches.open(CACHE)).then(cache => cache.keys()).then(keys => 
+			console.log(keys)
+		
+			/*Promise.all(
+			keys.map(key => {
+				console.log(key);
+				if(!(key in CACHE_RESOURCES)) {
+					//return cache.delete(key);
+				}
+			})*/
+		)
+	);
+});
+
+function postMessage(message) {
+	self.clients.matchAll().then(clients => {
+		clients.forEach(client => {
+			client.postMessage(message);
+		});
+	});
+}
+
+function updateCache(cache, cachedVersion, currentVersion) {
+	var remove = [];
+	var add = [];
+	
+	for(var cachedFile in cachedVersion) {
+		if(!currentVersion[cachedFile]) {
+			remove.push('/' + cachedFile);
+		} else if(cachedVersion[cachedFile] != currentVersion[cachedFile]) {
+			add.push('/' + cachedFile);
+		}
+	}
+	for(var currentFile in currentVersion) {
+		if(CACHE_RESOURCES.indexOf('/' + currentFile) === -1) {
+			continue;
+		} else if(!cachedVersion[currentFile]) {
+			add.push('/' + currentFile);
+		}
+	}
+	
+	console.log('Service Worker: updating files: ', add);
+	console.log('Service Worker: deleting files: ', remove);
+	
+	return cache.addAll(add).then(function() {
+		return Promise.all(
+			remove.map(filename => {
+				return caches.delete(filename)
+			})
+		);
+	});
+}
+
+this.addEventListener('message', function(event) {
+	switch(event.data.action) {
+		case 'skipWaiting':
+			self.skipWaiting();
+		break;
+	}
+});
diff --git a/version.php b/version.php
index 569683e..a518c36 100644
--- a/version.php
+++ b/version.php
@@ -1,2 +1,9 @@
 <?php
-echo max(array_map('filemtime', glob('*.{html,js,css}', GLOB_NOSORT|GLOB_BRACE)));
+$files = glob('*.{html,js,css}', GLOB_NOSORT|GLOB_BRACE);
+
+echo json_encode(
+	array_combine(
+		$files,
+		array_map('filemtime', $files)
+	)
+);

--
Gitblit v1.9.1