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

Conversation

anthony-zhou
Copy link
Member

@anthony-zhou anthony-zhou commented Dec 22, 2019

Fixes #1364

So far, I've displayed the NPM version number at the bottom of the page by parsing it from the package.json file. I'm working on also adding the version number to the top right and detecting when a new version has successfully been fetched.

  • tests pass -- look for a green checkbox ✔️ a few minutes after opening your PR -- or run tests locally with npm test
  • code is in uniquely-named feature branch and has no merge conflicts
  • PR is descriptively titled
  • Insert-step functionality is working correct as expected.

Screenshots

Here is a gif of the version number text, in the top right and at the bottom of the page:
Image Sequencer Version Number Screenshot

Here is a screenshot of the prompt to update to the latest version (in the top left):
image

@codecov
Copy link

codecov bot commented Dec 22, 2019

Codecov Report

Merging #1384 into main will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1384   +/-   ##
=======================================
  Coverage   66.35%   66.35%           
=======================================
  Files         125      125           
  Lines        2574     2574           
  Branches      406      406           
=======================================
  Hits         1708     1708           
  Misses        866      866

Copy link
Member

@harshkhandeparkar harshkhandeparkar left a comment

Choose a reason for hiding this comment

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

Your fix will display the current version number but won't show the latest version number without clearing the cache.

@anthony-zhou
Copy link
Member Author

anthony-zhou commented Dec 23, 2019

@harshkhandeparkar I'm working on the feature you mentioned, but as part of this I'd like to use the Node module semver. I'm currently working in demo.js. For some reason the traditional const semver = require('semver') is throwing a Javascript error of

image-sequencer.js:1 Uncaught Error: Cannot find module './functions/lt'
    at o (image-sequencer.js:1)
    at o (image-sequencer-ui.js:1)
    at o (image-sequencer-ui.js:1)
    at image-sequencer-ui.js:1
    at lazyRequire (image-sequencer-ui.js:47990)
    at Object.get [as lt] (image-sequencer-ui.js:47997)
    at XMLHttpRequest.request.onreadystatechange (image-sequencer-ui.js:48)```

Would you happen to know what is causing this error? 

@keshav234156
Copy link
Member

@anthony-zhou Do you know Service Workers? It is basically a script that browsers in run in the background that enable to control network request and cache those requests. Each service Worker has a lifecycle namely registration, Installation and Activation and installation is triggered only if you visit the application for the first time or there is some difference in the new service worker. So we can add event listeners to the service worker. Then we can check whether service worker was installed or not and do all the required stuff.
Thanks

examples/demo.js Outdated
}
}
}
request.open("GET", "https://api.github.com/repos/publiclab/image-sequencer/contents/package.json", true);
Copy link
Member

Choose a reason for hiding this comment

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

This is cool. So you want to clear the cache(via demo.js) if a new version is available?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, but I'll probably end up doing this through the service worker.

Copy link
Member

Choose a reason for hiding this comment

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

This is not a bad way either. Is there a downside to this?

Fetching the latest and local version number is now done through versionManagement.js
A new version is available whenever the sw.js file is changed.
@anthony-zhou
Copy link
Member Author

I made some more changes:

  • Moved fetching of local and latest version number to versionManagement.js.
  • Added a popup in index.html that is displayed when a new service worker is loaded.
  • This works by loading a new service worker when sw.js is changed.

Currently, the popup I created is displayed whenever the sw.js file is changed, which means that when a new version of Image Sequencer is deployed we would also need to change the version number in the first line of sw.js. Then we could compare the local version number to the online version number and get the new version if needed.

I'm thinking it might be inconvenient to update sw.js each time a new version is deployed. Is there any way we could do this automatically? @harshkhandeparkar @keshav234156

@harshkhandeparkar
Copy link
Member

I don't think doing it automatically will be easy. We can't browserify it. We will either have to make a script which changes the specific line in the code or let sw.js fetch changes from the package.json file.

@anthony-zhou
Copy link
Member Author

I just pushed a commit that adds a faint version number in fixed position in the top right corner.

So now, I believe the app should fetch the newest version whenever a new version is deployed, as long as sw.js is changed when we deploy a new version. So the changes technically work now--the question is whether we need to implement automatic updates to sw.js. This would make deploying a new version easier but would require running an additional script each time changes are made to package.json.

In order to update sw.js automatically, I think the best option may be to run a script that changes the sw.js file whenever package.json is changed. However, this would probably require editing some of the configuration files here on GitHub. Does it make sense to add a script in GitHub that does this (presumably it would have to be run whenever changes are made to the repository to check if changes were made to package.json)?

@anthony-zhou
Copy link
Member Author

@keshav234156 @harshkhandeparkar I ended up creating a grunt task to update sw.js whenever grunt build is run. I used the dependency grunt-text-replace to replace the text for the version number. Now everything should be working as expected. I would appreciate if you could review this PR again. Thanks!

@anthony-zhou anthony-zhou changed the title [WIP] Expand out offline app features for smoother cache clearing and version tracking Expand out offline app features for smoother cache clearing and version tracking Dec 30, 2019
Gruntfile.js Show resolved Hide resolved
callback(latestVersionNumber);
}
}
request.open("GET", "https://api.github.com/repos/publiclab/image-sequencer/contents/package.json", true);
Copy link
Member

Choose a reason for hiding this comment

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

This will GET the latest package JSON. It may not be the one online. We need a better way of GET-ing the version number.

Copy link
Member Author

Choose a reason for hiding this comment

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

By online, do you mean at sequencer.publiclab.org? If so, it looks like we could get the version number from the stable branch here on GitHub.

Whether we do this depends on whether offline users are mainly working off the stable branch or the main branch. The current implementation of this function is getting the version number from the main branch, which may be what people are using offline anyways.

Copy link
Member

Choose a reason for hiding this comment

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

For beta.sequencer.publiclab.org, we'll have to get the version from that repo. Beta is on a separate repo btw. For the stable one, it will bw different. Anyway, it will be a mess. Can't we get it from current_location/package.json or something? Make it dynamic instead of hard coded?

return v1parts.length != v2parts.length;
}

function compare(part1, part2) {
Copy link
Member

Choose a reason for hiding this comment

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

The parts of a version number are called major.minor.patch. Could you please use that terminology here too? To make it more readable.

package.json Outdated
@@ -70,6 +70,7 @@
"readline-sync": "^1.4.7",
"save-pixels": "~2.3.4",
"selectize": "^0.12.6",
"semver": "^7.1.1",
Copy link
Member

Choose a reason for hiding this comment

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

Is semver used now?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point. I have now uninstalled it.

examples/lib/versionManagement.js Outdated Show resolved Hide resolved
@anthony-zhou
Copy link
Member Author

@harshkhandeparkar Thanks for all the feedback! I removed the versionCompare() function in versionManagement.js, which wasn't being used anyways and was responsible for most of the messy code in that file, so hopefully that addresses several of your comments. Please see my individual replies for more details.

callback(latestVersionNumber);
}
}
request.open("GET", "https://api.github.com/repos/publiclab/image-sequencer/contents/package.json", true);
Copy link
Member

Choose a reason for hiding this comment

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

For beta.sequencer.publiclab.org, we'll have to get the version from that repo. Beta is on a separate repo btw. For the stable one, it will bw different. Anyway, it will be a mess. Can't we get it from current_location/package.json or something? Make it dynamic instead of hard coded?

@keshav234156
Copy link
Member

@jywarren CAn you please review this ASAP

@jywarren
Copy link
Member

jywarren commented Jan 6, 2020

OK, thanks for your patience! I'll review this next!

@jywarren
Copy link
Member

jywarren commented Jan 6, 2020

OK, my understanding of getLatestVersionNumber() was that we were going to use it to establish whether https://sequencer.publiclab.org (or beta, but let's put that aside for now for simplicity) has a newer version available than what's been cached. So it should compare:

  1. the npm version of the cached app TO
  2. the npm version of the app available at sequencer.publiclab.org

Is that right? OK, now I'll look through the latest files to see how this connects together. Thanks!

if ('serviceWorker' in navigator) {
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!

Copy link
Member

@jywarren jywarren left a comment

Choose a reason for hiding this comment

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

OK great, we can get this merge-able if we add explanatory comments at least, or if you'd like to link updatefound to getLatestVersionNumber() more explicitly we could also do that. Thank you!

@jywarren
Copy link
Member

jywarren commented Jan 6, 2020

And thanks for your patience! Next time, perhaps we can work in smaller chunks so that it can be merged in a modular fashion, and we won't get so slowed down, as it seems this PR has several portions which are already complete and could be merged on their own!

Thanks, all!

@anthony-zhou
Copy link
Member Author

@jywarren Thanks for the feedback. I added some explanatory comments to versionManagement.js , cache.js and sw.js in the areas I worked on. Is there anything else to add?

Also, good suggestion about working in a modular fashion... I'll be sure to do that next time.

@jywarren
Copy link
Member

jywarren commented Jan 7, 2020

Oh no! Tests didn't pass this time. Was there a typo perhaps?

Copy link
Member

@harshkhandeparkar harshkhandeparkar left a comment

Choose a reason for hiding this comment

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

Sorry for the late review. Only a few changes. Everything else looks fine to me.

examples/index.html Show resolved Hide resolved
$('#update-prompt-modal').addClass('show');
}

// When a new service worker has been loaded, the button in the update prompt
Copy link
Member

Choose a reason for hiding this comment

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

Please use multi-line comments instead of multiple inline comments. That will make it easier to read. Also, please keep words like service and worker on the same line.

Copy link
Member Author

Choose a reason for hiding this comment

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

Got it, thanks!

*/
function getLatestVersionNumber(callback) {
// Get the homepage reference from the local package.json.
var homepage = require('../../package.json').homepage;
Copy link
Member

Choose a reason for hiding this comment

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

Awesome!

examples/lib/versionManagement.js Show resolved Hide resolved
var latestVersionNumber = response.version;

// Do something with the version number using a callback function.
callback(latestVersionNumber);
Copy link
Member

Choose a reason for hiding this comment

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

If it is optional then please add an

if (callback)


// Get the version number from the local package.json file.
function getLocalVersionNumber() {
return require('../../package.json').version;
Copy link
Member

Choose a reason for hiding this comment

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

Why does the require statement appear twice?

Copy link
Member

Choose a reason for hiding this comment

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

Also, I think adding all the require statements at the start of the file is a good practice.

Copy link
Member Author

Choose a reason for hiding this comment

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

I moved the require statement to the start of the file, so it's now called only once.

examples/sw.js Show resolved Hide resolved
@harshkhandeparkar
Copy link
Member

I think travis is broken. It had broken before. It could fix itself like before. Perhaps the servers are down or there are too many requests.

@jywarren
Copy link
Member

jywarren commented Jan 7, 2020

It's possible Travis is down... but looks ok here; https://www.traviscistatus.com/

@jywarren
Copy link
Member

jywarren commented Jan 7, 2020

Oh it passed now! cool. But it's out of sync. I'll sync it.

@jywarren
Copy link
Member

jywarren commented Jan 7, 2020

Just waiting on some answers to @harshkhandeparkar's questions, then ready to merge this!

@anthony-zhou
Copy link
Member Author

@jywarren @harshkhandeparkar Thanks for reviewing. I have implemented all the changes you mentioned.

@jywarren
Copy link
Member

jywarren commented Jan 7, 2020

Fantastic. Waiting for this to pass before merging. Thanks a ton, @anthony-zhou !!!

@jywarren jywarren merged commit 00ed0f1 into publiclab:main Jan 7, 2020
@jywarren
Copy link
Member

jywarren commented Jan 7, 2020

Whew!!! Great!!!!! Thanks a ton!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Expand out offline app features for smoother cache clearing and version tracking
5 participants