Update dialog

This commit is contained in:
Ben Grant 2021-06-17 00:20:46 +10:00
parent 64cd9fc1f5
commit 47dd4d2fe0
6 changed files with 92 additions and 16 deletions

View file

@ -54,5 +54,13 @@
"language": {
"label": "Language"
}
},
"update": {
"heading": "Crab Fit has been updated",
"body": "A new version of Crab Fit is available, which includes updates, fixes, and new features.",
"buttons": {
"close": "Close",
"reload": "Reload"
}
}
}

View file

@ -1,8 +1,9 @@
import { useState, useEffect, useCallback, Suspense, lazy } from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import { ThemeProvider, Global } from '@emotion/react';
import { Workbox } from 'workbox-window';
import { Settings, Loading, Egg } from 'components';
import { Settings, Loading, Egg, UpdateDialog } from 'components';
import { useSettingsStore } from 'stores';
import theme from 'theme';
@ -15,6 +16,8 @@ const Create = lazy(() => import('pages/Create/Create'));
const Help = lazy(() => import('pages/Help/Help'));
const Privacy = lazy(() => import('pages/Privacy/Privacy'));
const wb = new Workbox('sw.js');
const App = () => {
const colortheme = useSettingsStore(state => state.theme);
const darkQuery = window.matchMedia('(prefers-color-scheme: dark)');
@ -25,6 +28,8 @@ const App = () => {
const [eggVisible, setEggVisible] = useState(false);
const [eggKey, setEggKey] = useState(0);
const [updateAvailable, setUpdateAvailable] = useState(false);
const eggHandler = useCallback(
event => {
if (EGG_PATTERN.indexOf(event.key) < 0 || event.key !== EGG_PATTERN[eggCount]) {
@ -56,6 +61,19 @@ const App = () => {
};
}, []);
useEffect(() => {
// Register service worker
if ('serviceWorker' in navigator && process.env.NODE_ENV === 'production') {
wb.addEventListener('installed', event => {
if (event.isUpdate) {
setUpdateAvailable(true);
}
});
wb.register();
}
}, []);
useEffect(() => {
document.addEventListener('keyup', eggHandler, false);
@ -140,6 +158,12 @@ const App = () => {
)} />
</Switch>
{updateAvailable && (
<Suspense fallback={<Loading />}>
<UpdateDialog onClose={() => setUpdateAvailable(false)} />
</Suspense>
)}
{eggVisible && <Egg eggKey={eggKey} onClose={() => setEggVisible(false)} />}
</ThemeProvider>
</BrowserRouter>

View file

@ -0,0 +1,24 @@
import { Button } from 'components';
import { useTranslation } from 'react-i18next';
import {
Wrapper,
ButtonWrapper,
} from './updateDialogStyle';
const UpdateDialog = ({ onClose }) => {
const { t } = useTranslation('common');
return (
<Wrapper>
<h2>{t('common:update.heading')}</h2>
<p>{t('common:update.body')}</p>
<ButtonWrapper>
<Button secondary onClick={onClose}>{t('common:update.buttons.close')}</Button>
<Button onClick={() => window.location.reload()}>{t('common:update.buttons.reload')}</Button>
</ButtonWrapper>
</Wrapper>
);
}
export default UpdateDialog;

View file

@ -0,0 +1,34 @@
import styled from '@emotion/styled';
export const Wrapper = styled.div`
position: fixed;
bottom: 20px;
right: 20px;
background-color: ${props => props.theme.background};
${props => props.theme.mode === 'dark' && `
border: 1px solid ${props.theme.primaryBackground};
`}
z-index: 900;
padding: 20px 26px;
border-radius: 3px;
width: 400px;
box-sizing: border-box;
max-width: calc(100% - 20px);
box-shadow: 0 3px 6px 0 rgba(0,0,0,.3);
& h2 {
margin: 0;
font-size: 1.3rem;
}
& p {
margin: 16px 0 24px;
font-size: 1rem;
}
`;
export const ButtonWrapper = styled.div`
display: flex;
align-items: center;
justify-content: flex-end;
gap: 16px;
`;

View file

@ -18,6 +18,7 @@ export { default as Egg } from './Egg/Egg';
export { default as Footer } from './Footer/Footer';
export { default as Recents } from './Recents/Recents';
export { default as Logo } from './Logo/Logo';
export { default as UpdateDialog } from './UpdateDialog/UpdateDialog';
export const _GoogleCalendar = () => import('./GoogleCalendar/GoogleCalendar');
export const _OutlookCalendar = () => import('./OutlookCalendar/OutlookCalendar');

View file

@ -1,7 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { Workbox } from 'workbox-window';
import 'i18n';
ReactDOM.render(
@ -10,17 +9,3 @@ ReactDOM.render(
</React.StrictMode>,
document.getElementById('root')
);
if ('serviceWorker' in navigator) {
const wb = new Workbox('sw.js');
wb.addEventListener('installed', event => {
if (event.isUpdate) {
if (window.confirm(`New content is available!. Click OK to refresh`)) {
window.location.reload();
}
}
});
wb.register();
}