Update dialog
This commit is contained in:
parent
64cd9fc1f5
commit
47dd4d2fe0
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
`;
|
||||
|
|
@ -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');
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue