Skip to content

Commit

Permalink
Feat: versioning & refresh banner (#7)
Browse files Browse the repository at this point in the history
* versioning & refresh banner

* add version.json to network first strategy

* Change update banner style to be flex by default

* update app version
  • Loading branch information
rajatkantinandi authored Jul 18, 2020
1 parent 45a874d commit 256d232
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 4 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"editor.tabSize": 2
"editor.tabSize": 2,
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "weather-here",
"version": "0.1.0",
"version": "1.1.0",
"private": true,
"dependencies": {
"react": "^16.8.6",
Expand Down Expand Up @@ -47,4 +47,4 @@
"react-app-rewired": "^2.1.3",
"workbox-webpack-plugin": "^4.3.1"
}
}
}
1 change: 1 addition & 0 deletions public/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ if (workbox) {
workbox.routing.registerRoute(new RegExp('/images/backgrounds/'), new workbox.strategies.StaleWhileRevalidate());
workbox.routing.registerRoute(new RegExp('/favicon.png'), new workbox.strategies.StaleWhileRevalidate());
workbox.routing.registerRoute(/\.(?:js|css|html)$/, new workbox.strategies.StaleWhileRevalidate());
workbox.routing.registerRoute('/version.json', new workbox.strategies.NetworkFirst());
} else {
console.log(`Boo! Workbox didn't load 😬`);
}
1 change: 1 addition & 0 deletions public/version.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"1.1.0"
33 changes: 33 additions & 0 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,39 @@ footer a:active {
text-shadow: none;
}

.updateBanner {
display: flex;
position: fixed;
background: rgba(0, 0, 0, 0.85);
padding: 10px;
left: 0;
right: 0;
justify-content: center;
align-items: center;
font-weight: bold;
color: hotpink;
top: auto;
bottom: 0;
z-index: 2;
}

.updateBanner .refresh-btn {
padding: 5px 15px;
border-radius: 15px;
font-size: 1.1em;
color: white;
background-color: teal;
font-weight: bold;
border: none;
margin-left: 10px;
box-sizing: border-box;
}

.updateBanner .refresh-btn:hover,
.updateBanner .refresh-btn:focus {
background-color: darkgreen;
}

@media (max-width: 740px) {
main {
padding-top: 5em;
Expand Down
4 changes: 4 additions & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { fromCtoF, fromFtoC } from './helpers/tempHelper';
import useFetchTemp from './hooks/useFetchTemp';
import useBgImageURL from './hooks/useBgImageURL';
import useAQI from './hooks/useAQI';
import useVersionInfo from './hooks/useVersionInfo';
import AppUpdateBanner from './Components/AppUpdateBanner';

const { useState, Fragment } = React;

Expand All @@ -21,6 +23,7 @@ export default function App(props) {
const [upcomingFilter, setUpcomingFilter] = useState(null);
const [mainTransform, setTransform] = useState(null);
const { aqi, cityName } = useAQI(location);
const { isUpToDate } = useVersionInfo();

const handleUnitChange = () => {
if (temp !== '---') {
Expand Down Expand Up @@ -48,6 +51,7 @@ export default function App(props) {
<WeekWeather {...{ temps, unit, comingWeather, upcomingFilter, mainTransform }} />
</main>
<Footer {...{ location }} />
{!isUpToDate && <AppUpdateBanner />}
</Fragment>
);
}
13 changes: 13 additions & 0 deletions src/Components/AppUpdateBanner.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import { clearCacheAndRefresh } from '../hooks/useVersionInfo';

export default function AppUpdateBanner() {
return (
<div className="updateBanner">
The app is out of date &amp; please click the "Refresh Now" button to have a better experience.
<button onClick={clearCacheAndRefresh} className="refresh-btn">
Refresh Now
</button>
</div>
);
}
4 changes: 3 additions & 1 deletion src/hooks/useAQI.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ export default function useAQI(location) {
const [data, setData] = useState({ data: { aqi: null, city: { name: null } } });

useEffect(() => {
fetchAQI();
if (location) {
fetchAQI();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location]);

Expand Down
47 changes: 47 additions & 0 deletions src/hooks/useVersionInfo.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useEffect, useState } from 'react';

export default function useVersionInfo() {
const [isUpToDate, setIsUpToDate] = useState(true);

useEffect(() => {
if (wasUpToDate()) {
fetch('/version.json')
.then((versionJSON) => versionJSON.json())
.then((versionString) => {
const localVersion = getLocalVersion();
if (versionString !== localVersion) {
console.log('## The app is out of date & needs update!');
setIsUpToDate(false);
localStorage.setItem('wasUpToDate', false);
} else {
localStorage.setItem('wasUpToDate', true);
setIsUpToDate(true);
}

localStorage.setItem('version', versionString);
})
.catch((err) => {
console.log('App offline, assuming up to date');
});
} else {
clearCacheAndRefresh();
}
}, []);

return { isUpToDate };
}

function getLocalVersion() {
return localStorage.getItem('version') || '';
}

function wasUpToDate() {
return localStorage.getItem('wasUpToDate') === false ? false : true;
}

export function clearCacheAndRefresh() {
const currentVersion = getLocalVersion();
localStorage.clear();
localStorage.setItem('version', currentVersion);
window.location.reload();
}

1 comment on commit 256d232

@vercel
Copy link

@vercel vercel bot commented on 256d232 Jul 18, 2020

Choose a reason for hiding this comment

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

Please sign in to comment.