[closes #4] Merge pull request #8 from jeremyckahn/feature/4__update-dialog

feat: App update flow
This commit is contained in:
Jeremy Kahn 2022-09-11 16:00:22 -05:00 committed by GitHub
commit 32e741c7f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 10 deletions

View File

@ -3,6 +3,7 @@ import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import { v4 as uuid } from 'uuid' import { v4 as uuid } from 'uuid'
import localforage from 'localforage' import localforage from 'localforage'
import * as serviceWorkerRegistration from 'serviceWorkerRegistration'
import { SettingsContext } from 'contexts/SettingsContext' import { SettingsContext } from 'contexts/SettingsContext'
import { Home } from 'pages/Home/' import { Home } from 'pages/Home/'
import { PublicRoom } from 'pages/PublicRoom/' import { PublicRoom } from 'pages/PublicRoom/'
@ -22,6 +23,7 @@ function Bootstrap({
}), }),
getUuid = uuid, getUuid = uuid,
}: BootstrapProps) { }: BootstrapProps) {
const [appNeedsUpdate, setAppNeedsUpdate] = useState(false)
const [hasLoadedSettings, setHasLoadedSettings] = useState(false) const [hasLoadedSettings, setHasLoadedSettings] = useState(false)
const [userSettings, setUserSettings] = useState<UserSettings>({ const [userSettings, setUserSettings] = useState<UserSettings>({
userId: getUuid(), userId: getUuid(),
@ -29,6 +31,14 @@ function Bootstrap({
}) })
const { userId } = userSettings const { userId } = userSettings
const handleServiceWorkerUpdate = () => {
setAppNeedsUpdate(true)
}
useEffect(() => {
serviceWorkerRegistration.register({ onUpdate: handleServiceWorkerUpdate })
}, [])
useEffect(() => { useEffect(() => {
;(async () => { ;(async () => {
if (hasLoadedSettings) return if (hasLoadedSettings) return
@ -71,7 +81,7 @@ function Bootstrap({
return ( return (
<Router> <Router>
<SettingsContext.Provider value={settingsContextValue}> <SettingsContext.Provider value={settingsContextValue}>
<Shell userPeerId={userId}> <Shell appNeedsUpdate={appNeedsUpdate} userPeerId={userId}>
{hasLoadedSettings ? ( {hasLoadedSettings ? (
<Routes> <Routes>
{['/', '/index.html'].map(path => ( {['/', '/index.html'].map(path => (

View File

@ -7,7 +7,7 @@ import { Shell, ShellProps } from './Shell'
const ShellStub = (overrides: Partial<ShellProps> = {}) => { const ShellStub = (overrides: Partial<ShellProps> = {}) => {
return ( return (
<Router> <Router>
<Shell userPeerId="abc123" {...overrides} /> <Shell appNeedsUpdate={false} userPeerId="abc123" {...overrides} />
</Router> </Router>
) )
} }

View File

@ -23,7 +23,14 @@ import Tooltip from '@mui/material/Tooltip'
import Snackbar from '@mui/material/Snackbar' import Snackbar from '@mui/material/Snackbar'
import MuiAlert, { AlertProps, AlertColor } from '@mui/material/Alert' import MuiAlert, { AlertProps, AlertColor } from '@mui/material/Alert'
import IconButton from '@mui/material/IconButton' import IconButton from '@mui/material/IconButton'
import Button from '@mui/material/Button'
import Dialog from '@mui/material/Dialog'
import DialogActions from '@mui/material/DialogActions'
import DialogContent from '@mui/material/DialogContent'
import DialogContentText from '@mui/material/DialogContentText'
import DialogTitle from '@mui/material/DialogTitle'
import MenuIcon from '@mui/icons-material/Menu' import MenuIcon from '@mui/icons-material/Menu'
import WarningIcon from '@mui/icons-material/Warning'
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft' import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'
import ChevronRightIcon from '@mui/icons-material/ChevronRight' import ChevronRightIcon from '@mui/icons-material/ChevronRight'
import ListItem from '@mui/material/ListItem' import ListItem from '@mui/material/ListItem'
@ -40,10 +47,6 @@ import { SettingsContext } from 'contexts/SettingsContext'
import { AlertOptions } from 'models/shell' import { AlertOptions } from 'models/shell'
import { PeerNameDisplay } from 'components/PeerNameDisplay' import { PeerNameDisplay } from 'components/PeerNameDisplay'
export interface ShellProps extends PropsWithChildren {
userPeerId: string
}
const drawerWidth = 240 const drawerWidth = 240
const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert( const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert(
@ -100,7 +103,12 @@ const DrawerHeader = styled('div')(({ theme }) => ({
justifyContent: 'flex-end', justifyContent: 'flex-end',
})) }))
export const Shell = ({ children, userPeerId }: ShellProps) => { export interface ShellProps extends PropsWithChildren {
userPeerId: string
appNeedsUpdate: boolean
}
export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => {
const settingsContext = useContext(SettingsContext) const settingsContext = useContext(SettingsContext)
const [isAlertShowing, setIsAlertShowing] = useState(false) const [isAlertShowing, setIsAlertShowing] = useState(false)
const [isDrawerOpen, setIsDrawerOpen] = useState(false) const [isDrawerOpen, setIsDrawerOpen] = useState(false)
@ -181,10 +189,44 @@ export const Shell = ({ children, userPeerId }: ShellProps) => {
}) })
} }
const handleRestartClick = () => {
window.location.reload()
}
return ( return (
<ShellContext.Provider value={shellContextValue}> <ShellContext.Provider value={shellContextValue}>
<ThemeProvider theme={theme}> <ThemeProvider theme={theme}>
<CssBaseline /> <CssBaseline />
<Dialog
open={appNeedsUpdate}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<WarningIcon
fontSize="medium"
sx={theme => ({
color: theme.palette.warning.main,
mr: theme.spacing(1),
})}
/>
Update needed
</Box>
</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
In order to function properly, Chitchatter needs to be updated.
The update has already been installed in the background. All you
need to do is reload the page or click "Refresh" below.
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleRestartClick} autoFocus>
Refresh
</Button>
</DialogActions>
</Dialog>
<Box <Box
className="Chitchatter" className="Chitchatter"
sx={{ sx={{

View File

@ -1,7 +1,6 @@
import ReactDOM from 'react-dom/client' import ReactDOM from 'react-dom/client'
import 'typeface-roboto' import 'typeface-roboto'
import * as serviceWorkerRegistration from 'serviceWorkerRegistration'
import 'index.sass' import 'index.sass'
import Bootstrap from 'Bootstrap' import Bootstrap from 'Bootstrap'
import reportWebVitals from 'reportWebVitals' import reportWebVitals from 'reportWebVitals'
@ -13,5 +12,3 @@ root.render(<Bootstrap />)
// to log results (for example: reportWebVitals(console.log)) // to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals() reportWebVitals()
serviceWorkerRegistration.register()