diff --git a/app/serviceworkers/sw.js b/app/serviceworkers/sw.js new file mode 100644 index 0000000..23f202c --- /dev/null +++ b/app/serviceworkers/sw.js @@ -0,0 +1,78 @@ +const addonsUrl = 'https://io-builtwithember-addons-data.s3.amazonaws.com/addons.json'; +const GRAVATAR_CACHE = 'GRAVATAR_URLS'; + +/** + The addons url variable will return the addons.json that the app needs. + We will add this url to the broccoli-sw. The broccoli-sw uses sw-toolbox. + The sw-toolbox gives us handler functions that we can use to manage the request. + + We are using the networkFirst strategy in order to keep this file updated. +*/ +toolbox.router.get('/addons.json', toolbox.networkFirst, {origin: 'https://io-builtwithember-addons-data.s3.amazonaws.com'}); +toolbox.precache(addonsUrl); + +// Request the addons.js, filter the gravatar ulrs and return an array of gravatar urls. +function gravatarUrls() { + return fetch(addonsUrl).then(function(response) { + return response.json(); + }).then(function(json) { + return json.map(function(curr) { + return curr['_npmUser'].gravatar ? curr['_npmUser'].gravatar + '?s=30&d=retro':''; + }).filter(function(data, index, array) { + if (array.indexOf(data) === index) { + return data; + } + }); + }); +} + +// Go through every gravatar url and remove the origin. +function isGravatarUrl(url) { + return url.indexOf('https://secure.gravatar.com'); +} + +/** + waitUntil expects a promise and it will stop the worker execution until the promise is resolved. + The gravatarUrls will fetch the addons.json file and filter the users gravatars. + When we have the array of urls we open or create the gravatar cache and add the urls. +*/ +self.addEventListener('install', function(event) { + event.waitUntil( + gravatarUrls().then(function(urls) { + /** + Open the specified cache if it exists. If the cache doesn't exist + create it and add prefetch the urls on the array. + */ + caches.open(GRAVATAR_CACHE).then(function(cache) { + cache.addAll(urls); + }); + }) + ); +}); + +/** + Intercept every request that the app makes. If it the request matches + a request that has been stored in the cache return the response that is stored. + + If the request is not in the caches and if it's a new gravatar then fetch the new + gravatar and add it to the gravatars cache. After storing the response in the cache + we return a clone of the response to the app. +*/ +self.addEventListener('fetch', function(event) { + event.respondWith( + caches.match(event.request) + .then(function(res) { + if (res) { + return res; + } else if (isGravatarUrl(event.request.url) >= 0) { + return fetch(event.request.url).then(function(response) { + caches.open(GRAVATAR_CACHE).then(function(cache) { + cache.put(event.request, response); + }); + + return response.clone(); + }); + } + }) + ); +}); diff --git a/app/styles/app.css b/app/styles/app.css index fdd8bdf..08e13e9 100644 --- a/app/styles/app.css +++ b/app/styles/app.css @@ -152,11 +152,30 @@ a.sort-button { margin-top: 20px; } +.gravatar--wrapper { + display: inline; +} + .gravatar { border-radius: 50%; margin-right: 5px; } +.author-information { + display: inline-block; + vertical-align: middle; + max-width: 130px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + text-decoration: none; +} + +.author-information__anchor:hover { + text-decoration: none; + color: #D02714; +} + .package-link { font-size: 24px; } diff --git a/app/templates/components/em-pkg.hbs b/app/templates/components/em-pkg.hbs index fa0a748..1701e57 100644 --- a/app/templates/components/em-pkg.hbs +++ b/app/templates/components/em-pkg.hbs @@ -29,9 +29,13 @@ {{/if}} - - - {{user.name}} + +
+ +
+
+ {{user.name}} +
diff --git a/config/environment.js b/config/environment.js index 8c4b39e..50ebcd7 100644 --- a/config/environment.js +++ b/config/environment.js @@ -21,6 +21,15 @@ module.exports = function(environment) { 'ember-load': { loadingIndicatorClass: 'ember-load-indicator' + }, + + serviceWorker: { + enabled: true, + debug: true, + excludePaths: ['test.*', 'robots.txt'], + includeRegistration: true, + serviceWorkerFile: 'sw.js', + skipWaiting: true } }; diff --git a/package.json b/package.json index ed2ba5c..b09d07b 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "license": "MIT", "devDependencies": { "broccoli-asset-rev": "^2.2.0", + "broccoli-serviceworker": "0.1.0", "ember-cli": "1.13.15", "ember-cli-app-version": "^1.0.0", "ember-cli-babel": "^5.1.5",