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

Expand out offline app features for smoother cache clearing and version tracking #1384

Merged
merged 32 commits into from
Jan 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
9cece82
Merge pull request #1 from publiclab/main
anthony-zhou Dec 22, 2019
392149b
Add version number to bottom
anthony-zhou Dec 22, 2019
1d165d6
Get latest version number from GitHub
anthony-zhou Dec 23, 2019
c03f981
Create versionManagement.js
anthony-zhou Dec 28, 2019
526f2de
Add popup to prompt for refresh when a new version is available
anthony-zhou Dec 28, 2019
20aac76
Add version number fixed in top right corner
anthony-zhou Dec 29, 2019
27c7c97
Fix Codeclimate issues
anthony-zhou Dec 30, 2019
6a6b408
Update versionManagement.js
anthony-zhou Dec 30, 2019
f97411e
Update versionManagement.js
anthony-zhou Dec 30, 2019
56003b3
Make update prompt appear at front of page
anthony-zhou Dec 30, 2019
e5c1faf
Delete unecessary code
anthony-zhou Dec 30, 2019
64378a6
Create task to automatically update sw.js
anthony-zhou Dec 30, 2019
b0e9ff6
Uninstall semver
anthony-zhou Dec 31, 2019
6b9d16c
Add replace task to serve and production tasks
anthony-zhou Dec 31, 2019
124ff32
Update demo.js
anthony-zhou Dec 31, 2019
c294505
Update versionManagement.js
anthony-zhou Dec 31, 2019
37979fb
Change URL for getting latest version
anthony-zhou Jan 1, 2020
0ba020b
Merge branch 'main' into main
harshkhandeparkar Jan 2, 2020
59eebad
Update index.html
anthony-zhou Jan 3, 2020
be8f8f3
Update demo.css
anthony-zhou Jan 3, 2020
45dff6d
Merge branch 'main' into main
harshkhandeparkar Jan 3, 2020
01e9882
Merge branch 'main' into main
jywarren Jan 6, 2020
47b3a39
Added explanatory comments
anthony-zhou Jan 6, 2020
839f637
Update versionManagement.js
anthony-zhou Jan 6, 2020
ef337b8
Merge branch 'main' into main
jywarren Jan 6, 2020
0b34074
Update versionManagement.js
anthony-zhou Jan 7, 2020
384d526
Merge branch 'main' of https://github.com/anthony-zhou/image-sequence…
anthony-zhou Jan 7, 2020
3e10399
Merge branch 'main' into main
harshkhandeparkar Jan 7, 2020
3d54f41
Merge branch 'main' into main
jywarren Jan 7, 2020
a4f0b43
Updates for readability
anthony-zhou Jan 7, 2020
405a3b0
Update versionManagement.js
anthony-zhou Jan 7, 2020
c5b8fc2
Update versionManagement.js
anthony-zhou Jan 7, 2020
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
18 changes: 15 additions & 3 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-contrib-uglify-es');
grunt.loadNpmTasks('grunt-browser-sync');
grunt.loadNpmTasks('grunt-text-replace');

require('matchdep')
.filterDev('grunt-*')
Expand Down Expand Up @@ -48,6 +49,17 @@ module.exports = function(grunt) {
}
},

replace: {
version: {
src: ['examples/sw.js'],
overwrite: true,
replacements: [{
from: /image-sequencer-static-v.*/g,
to: "image-sequencer-static-v<%= pkg.version %>';"
}]
}
},

uglify: {
core: {
src: ['./dist/image-sequencer.js'],
Expand Down Expand Up @@ -78,10 +90,10 @@ module.exports = function(grunt) {

/* Default (development): Watch files and build on change. */
grunt.registerTask('default', ['watch']);
grunt.registerTask('build', ['browserify:core', 'browserify:ui', 'uglify:core', 'uglify:ui']);
grunt.registerTask('serve', ['browserify:core', 'browserify:ui', 'browserSync', 'watch']);
grunt.registerTask('build', ['browserify:core', 'browserify:ui', 'replace:version', 'uglify:core', 'uglify:ui']);
harshkhandeparkar marked this conversation as resolved.
Show resolved Hide resolved
grunt.registerTask('serve', ['browserify:core', 'browserify:ui', 'replace:version', 'browserSync', 'watch']);
grunt.registerTask('compile', ['browserify:core', 'browserify:ui']);
grunt.registerTask('production', ['browserify:prodcore', 'browserify:produi', 'uglify:prodcore', 'uglify:produi']);
grunt.registerTask('production', ['browserify:prodcore', 'browserify:produi', 'replace:version', 'uglify:prodcore', 'uglify:produi']);

grunt.registerTask('tests', ['browserify:tests']);
};
47 changes: 47 additions & 0 deletions examples/demo.css
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,55 @@ a.name-header{
color: #444;
}

#version-number-text {
text-align: center;
padding-top: 100px;
color: gray;
}
#version-number-top-right {
position: fixed;
right: 2%;
top: 5%;
color: lightgray;
}
/* Non float rightward alignment*/
.right {
margin-left: auto;
display: block;
}

#update-prompt-modal {
visibility: hidden;
min-width: 250px;
margin-left: -125px;
background-color: #333;
color: #fff;
text-align: center;
border-radius: 2px;
padding: 16px;
position: fixed;
z-index: 1000;
left: 10%;
top: 30px;
}
#update-prompt-modal.show {
visibility: visible;
-webkit-animation: fadein 0.5s;
animation: fadein 0.5s;
}
@-webkit-keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
17 changes: 15 additions & 2 deletions examples/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ var defaultHtmlSequencerUi = require('./lib/defaultHtmlSequencerUi.js'),
intermediateHtmlStepUi = require('./lib/intermediateHtmlStepUi.js'),
DefaultHtmlStepUi = require('./lib/defaultHtmlStepUi.js'),
urlHash = require('./lib/urlHash.js'),
insertPreview = require('./lib/insertPreview.js');
insertPreview = require('./lib/insertPreview.js'),
versionManagement = require('./lib/versionManagement.js');


window.onload = function () {
sequencer = ImageSequencer(); // Set the global sequencer variable
Expand All @@ -28,6 +30,17 @@ window.onload = function () {
}
};

versionManagement.getLatestVersionNumber(function(versionNumber) {
console.log("The latest NPM version number for Image Sequencer (from GitHub) is v" + versionNumber);
});
console.log("The local version number for Image Sequencer is v" + versionManagement.getLocalVersionNumber());

function displayVersionNumber() {
$('#version-number-text').text("Image Sequencer v" + versionManagement.getLocalVersionNumber());
$('#version-number-top-right').text("v" + versionManagement.getLocalVersionNumber());
}
displayVersionNumber();

function refreshOptions(options) {
// Default options if parameter is empty.
if (options == undefined) options = { sortField: 'text' };
Expand Down Expand Up @@ -310,7 +323,7 @@ window.onload = function () {
step.options.step.imgElement.src = reader.result;
else
step.imgElement.src = reader.result;

insertPreview.updatePreviews(reader.result, document.querySelector('#addStep'));
DefaultHtmlStepUi(sequencer).updateDimensions(step);
},
Expand Down
10 changes: 8 additions & 2 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<!-- jspdf to enable save image as pdf -->
<script src="../node_modules/jspdf/dist/jspdf.min.js" type="text/javascript" ></script>

<script src="lib/scrollToTop.js"></script>
<!-- <script src="lib/scrollToTop.js"></script> -->
harshkhandeparkar marked this conversation as resolved.
Show resolved Hide resolved
<script src="../node_modules/selectize/dist/js/standalone/selectize.min.js"></script>
</head>

Expand All @@ -56,6 +56,8 @@
<link href="./selectize.default.css" rel="stylesheet">
<link rel="stylesheet" href="demo.css">

<div id="update-prompt-modal">A new version of image sequencer is available. Click <a href="#" id="reload">here</a> to update.</div>

<div class="container-fluid">

<header class="text-center" style="min-width: 450px">
Expand All @@ -73,6 +75,7 @@ <h1><a href="/" target='_blank' class="name-header">Image Sequencer</a></h1>
</a>
by <a href="https://publiclab.org" title="Publiclab Website"><i class="fa fa-globe"></i> Publiclab</a>
</p>
<span id="version-number-top-right"></span>
</header>

<div id="dropzone" class="dropzone">
Expand Down Expand Up @@ -228,6 +231,9 @@ <h2>Improve this tool</h2>
</p>
</div>
</div>
<div class="row">
<p id="version-number-text">Unable to load version number</p>
</div>
</footer>

<button id="move-up"><i class="fa fa-arrow-circle-o-up"></i></button>
Expand All @@ -241,4 +247,4 @@ <h2>Improve this tool</h2>

</body>

</html>
</html>
50 changes: 50 additions & 0 deletions examples/lib/cache.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,41 @@
var setupCache = function() {
let newWorker; // When sw.js is changed, this is the new service worker generated.

// Toggle a CSS class to display a popup prompting the user to fetch a new version.
function showUpdateModal() {
$('#update-prompt-modal').addClass('show');
}

/**
* When a new service worker has been loaded, the button in the update prompt
* modal should trigger the skipWaiting event to replace the current
* service worker with the new one.
*/
$('#reload').on('click', function() {
newWorker.postMessage({ action: 'skipWaiting' });
});

if ('serviceWorker' in navigator) {
// Register the service worker.
navigator.serviceWorker.register('sw.js', { scope: '/examples/' })
.then(function(registration) {
registration.addEventListener('updatefound', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, here we can detect if there's a new version, but we don't actually tie this to getLatestVersionNumber(), as far as I can read it? How might we do that - could we say Click to install version X here? Or is getLatestVersionNumber() not reading from the same source as updatefound here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have to change things; i like how this looks. But let's leave enough inline comments to make the answer to this question really clear! Esp. because this is complicated stuff, so future coders should be able to follow what you've done. Thanks!

// When sw.js has been changed, get a reference to the new service worker.
newWorker = registration.installing;
newWorker.addEventListener('statechange', () => {
// Check if service worker state has changed.
switch(newWorker.state) {
case 'installed':
if(navigator.serviceWorker.controller) {
// New service worker available; prompt the user to update.
showUpdateModal();
}
// No updates available; do nothing.
break;
}
});
});

const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
console.log(installingWorker);
Expand All @@ -14,6 +48,17 @@ var setupCache = function() {
.catch(function(error) {
console.log('Service worker registration failed, error:', error);
});

/**
* This is the event listener for when the service worker updates.
* When the service worker updates, reload the page.
*/
let refreshing;
navigator.serviceWorker.addEventListener('controllerchange', function() {
if(refreshing) return;
window.location.reload();
refreshing = true;
});
}

if ('serviceWorker' in navigator) {
Expand All @@ -34,6 +79,11 @@ var setupCache = function() {
}
location.reload();
});





};

module.exports = setupCache;
43 changes: 43 additions & 0 deletions examples/lib/versionManagement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Functions for getting version information.
* Note: these functions are not used by the service worker to check for updates;
* the service worker updates whenever sw.js has changed.
harshkhandeparkar marked this conversation as resolved.
Show resolved Hide resolved
* sw.js is changed when grunt replace:version is run. This task is run during
* grunt build, serve, and productions tasks.
*/

const package = require('../../package.json');

/**
* Get the current version number from package.json on the homepage.
* @param {function} callback The function that uses the version number.
*/
function getLatestVersionNumber(callback) {
// Get the homepage reference from the local package.json.
var homepage = package.homepage;
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
var response = JSON.parse(this.responseText);
var latestVersionNumber = response.version;

// Do something with the version number using a callback function.
harshkhandeparkar marked this conversation as resolved.
Show resolved Hide resolved
if (callback)
callback(latestVersionNumber);
}
}

// Get the package.json file from online using a GET request.
request.open("GET", homepage + "/package.json", true);
request.send();
}

// Get the version number from the local package.json file.
function getLocalVersionNumber() {
return package.version;
}

module.exports = {
getLatestVersionNumber,
getLocalVersionNumber
}
10 changes: 8 additions & 2 deletions examples/sw.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const staticCacheName = 'image-sequencer-static-v3';

const staticCacheName = 'image-sequencer-static-v3.5.1';
harshkhandeparkar marked this conversation as resolved.
Show resolved Hide resolved
self.addEventListener('install', event => {
console.log('Attempting to install service worker');
});
Expand Down Expand Up @@ -33,3 +32,10 @@ self.addEventListener('fetch', function(event) {
})
);
});

// When the update modal sends a 'skipWaiting' message, call the skipWaiting method.
self.addEventListener('message', function(event) {
if(event.data.action === 'skipWaiting') {
self.skipWaiting();
}
});
Loading