Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Service Worker for Offline First Capabilities #192

Open
wants to merge 6 commits into
base: clay-improvements
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@
<title>Hextris</title>
<meta name="apple-itunes-app" content="app-id=903769553"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0, minimal-ui"/>
<meta property="og:url" content="http://hextris.github.io/hextris/"/>
<meta property="og:url" content="https://hextris.github.io/hextris/"/>
<meta property="og:site_name" content="Hextris"/>
<meta property="og:title" content="Hextris"/>
<meta property="og:description" content="An addictive puzzle game inspired by Tetris."/>
<meta property="og:type" content="website"/>
<meta property="og:author" content="https://www.facebook.com/hextris"/>
<meta property="og:image" content="http://hextris.github.io/hextris/images/facebook-opengraph.png"/>
<meta property="og:image" content="https://hextris.github.io/hextris/images/facebook-opengraph.png"/>
<meta property="og:image:width" content="1200"/>
<meta property="og:image:height" content="630"/>
<meta property="twitter:card" content="summary"/>
<meta property="twitter:site" content="@hextris"/>
<meta property="twitter:site:id" content="2742209678"/>
<meta property="twitter:creator" content="@hextris"/>
<meta property="twitter:creator:id" content="2742209678"/>
<meta property="twitter:domain" content="http://hextris.github.io"/>
<meta property="twitter:domain" content="https://hextris.github.io"/>
<meta property="twitter:title" content="Hextris"/>
<meta property="twitter:description" content="An addictive puzzle game inspired by Tetris."/>
<meta property="twitter:image:src" content="http://hextris.github.io/hextris/images/twitter-opengraph.png"/>
<meta property="twitter:image:src" content="https://hextris.github.io/hextris/images/twitter-opengraph.png"/>
<meta property="twitter:image:width" content="512"/>
<meta property="twitter:image:height" content="512"/>
<meta property="twitter:app:id:iphone" content="id903769553">
Expand All @@ -31,8 +31,9 @@
<meta property="twitter:app:url:iphone" content="itunes.apple.com/us/app/id903769553?mt=8">
<meta property="twitter:app:url:ipad" content="itunes.apple.com/us/app/id903769553?mt=8">
<meta property="twitter:app:url:googleplay" content="https://play.google.com/store/apps/details?id=com.hextris.hextris">
<link rel="manifest" href="manifest.json">
<link rel="icon" type="image/png" href="favicon.ico">
<link href='http://fonts.googleapis.com/css?family=Exo+2' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Exo+2' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="style/fa/css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="style/style.css">
<script type='text/javascript' src="vendor/hammer.min.js"></script>
Expand Down
31 changes: 31 additions & 0 deletions js/assets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"cache":
[
"index.html",
"vendor/hammer.min.js",
"vendor/js.cookie.js",
"vendor/jsonfn.min.js",
"vendor/keypress.min.js",
"vendor/jquery.js",
"js/save-state.js",
"js/view.js",
"js/wavegen.js",
"js/math.js",
"js/Block.js",
"js/Hex.js",
"js/Text.js",
"js/comboTimer.js",
"js/checking.js",
"js/update.js",
"js/render.js",
"js/input.js",
"js/main.js",
"js/initialization.js",
"https://fonts.googleapis.com/css?family=Exo+2",
"style/fa/css/font-awesome.min.css",
"style/style.css",
"style/rrssb.css",
"vendor/rrssb.min.js",
"vendor/sweet-alert.min.js"
]
}
65 changes: 65 additions & 0 deletions js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -374,3 +374,68 @@ function showHelp() {
$("#openSideBar").fadeIn(150,"linear");
$('#helpScreen').fadeToggle(150, "linear");
}

// ask browser if it supports service workers, if it does, register it.
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('./sw.js').then(function(reg) {
console.log('SW registered successfully');

if(!navigator.serviceWorker.controller) {
return;
}

if(reg.waiting) {
notifySWUpdates(reg.waiting);
}

if(reg.installing) {
trackSWStates(reg.installing);
}

reg.addEventListener('updatefound', function() {
trackSWStates(reg.installing);
})

var reloading;
navigator.serviceWorker.addEventListener('controllerchange', function() {
if(reloading) return;
window.location.reload();
reloading = true;
});

}, function(err) {
console.log('SW registration failed');
});

});
}

// notify user of game update available,
// when user clicks button service worker updates with new cache and page reloads.
function notifySWUpdates(reg) {
console.log('There is a new Service Worker available');
let SW_Button = document.createElement('button');
SW_Button.innerHTML = 'Update Available';
let doc_body = document.getElementsByTagName('body')[0];
doc_body.appendChild(SW_Button);
SW_Button.style.backgroundColor = 'blue';
SW_Button.style.color = '#fff';
SW_Button.style.position = 'fixed';
SW_Button.style.bottom = '0px';
SW_Button.style.right = '0px';
SW_Button.style.padding = '5px 10px';
SW_Button.addEventListener('click', function() {
console.log(reg);
reg.postMessage({activate: 'true'});
});
}

// tracks service worker state and activates notification function when installed.
function trackSWStates(reg) {
reg.addEventListener('statechange', function() {
if(this.state == 'installed') {
notifySWUpdates(reg);
}
});
}
11 changes: 11 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"background_color": "#ecf0f1",
"display": "standalone",
"icons": [],
"name": "Hextris",
"short_name": "Hextris",
"description": "Fast paced HTML5 puzzle game inspired by Tetris!",
"start_url": "/",
"scope": "/",
"theme_color": "#ecf0f1"
}
77 changes: 77 additions & 0 deletions sw.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
var CACHE_NAME = 'hextris-v3';

// install service worker on first install and load cache assets.
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(CACHE_NAME).then(function(cache) {
fetch('js/assets.json').then(function(response) {
return response.json();
}).catch(function(err) {
console.log('json fetch err:', err);
}).then(function(assetManifest) {
let cacheFiles = assetManifest.cache;
cache.addAll(cacheFiles);
}).catch(function(err) {
console.log('problem adding to cache:', err);
})
})
);
});

// respond to fetch requests by browser using service worker.
self.addEventListener('fetch', function(event) {
const requestUrl = new URL(event.request.url);

if (requestUrl.origin === location.origin) {
event.respondWith(getNetworkResponse(event.request));
return;
}

event.respondWith(fetch(event.request));
});

// If asset exists in cache, respond with cache,
// otherwise respond from network after putting asset in cache.
function getNetworkResponse(request) {
return caches.open(CACHE_NAME).then(cache => {
return cache.match(request).then(response => {
if (response) return response;

if(request.cache === 'only-if-cached') {
return fetch(request, {mode: "same-origin"}).then(networkResponse => {
cache.put(request, networkResponse.clone());
return networkResponse;
})
} else {
return fetch(request).then(networkResponse => {
cache.put(request, networkResponse.clone());
return networkResponse;
})
}
});
});
};

// Delete any unused old caches when a new service worker is activated
self.addEventListener('activate', function(event) {
event.waitUntil(
Promise.all([
clients.claim(),
caches.keys().then(function(cacheNames) {
cacheNames.filter(function(cacheName) {
if(cacheName.startsWith('hextris') && cacheName !== CACHE_NAME) {
caches.delete(cacheName);
}
})
})
]
)
)
});

// listen to messages and skip waiting state of service worker
// this basically activates service worker when notification recieved.
self.addEventListener('message', function(event) {
if(event.data.activate == 'true');
self.skipWaiting();
});