188 lines
5.0 KiB
TypeScript
Raw Normal View History

import {
PropsWithChildren,
2022-09-05 17:35:40 -05:00
SyntheticEvent,
forwardRef,
useCallback,
2022-09-05 17:35:40 -05:00
useContext,
useEffect,
useMemo,
useState,
} from 'react'
2022-08-31 21:44:00 -05:00
import CssBaseline from '@mui/material/CssBaseline'
2022-09-02 09:49:00 -05:00
import { ThemeProvider, createTheme, styled } from '@mui/material/styles'
import Box from '@mui/material/Box'
import Snackbar from '@mui/material/Snackbar'
import MuiAlert, { AlertProps, AlertColor } from '@mui/material/Alert'
import { ShellContext } from 'contexts/ShellContext'
2022-09-05 17:35:40 -05:00
import { SettingsContext } from 'contexts/SettingsContext'
import { AlertOptions } from 'models/shell'
import { Drawer, drawerWidth } from './Drawer'
import { UpgradeDialog } from './UpgradeDialog'
import { DrawerHeader } from './DrawerHeader'
import { ShellAppBar } from './ShellAppBar'
2022-08-31 21:44:00 -05:00
const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert(
props,
ref
) {
return <MuiAlert elevation={6} ref={ref} variant="filled" {...props} />
})
2022-08-31 21:44:00 -05:00
const Main = styled('main', { shouldForwardProp: prop => prop !== 'open' })<{
open?: boolean
}>(({ theme, open }) => ({
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
marginLeft: `-${drawerWidth}px`,
...(open && {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
marginLeft: 0,
}),
}))
2022-09-11 13:44:23 -05:00
export interface ShellProps extends PropsWithChildren {
userPeerId: string
appNeedsUpdate: boolean
}
export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => {
2022-09-05 17:35:40 -05:00
const settingsContext = useContext(SettingsContext)
const [isAlertShowing, setIsAlertShowing] = useState(false)
2022-08-31 21:44:00 -05:00
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
2022-09-01 21:28:45 -05:00
const [doShowPeers, setDoShowPeers] = useState(false)
const [alertSeverity, setAlertSeverity] = useState<AlertColor>('info')
const [title, setTitle] = useState('')
const [alertText, setAlertText] = useState('')
const [numberOfPeers, setNumberOfPeers] = useState(1)
const showAlert = useCallback<
(message: string, options?: AlertOptions) => void
>((message, options) => {
setAlertText(message)
setAlertSeverity(options?.severity ?? 'info')
setIsAlertShowing(true)
}, [])
const shellContextValue = useMemo(
2022-09-01 21:28:45 -05:00
() => ({
numberOfPeers,
setDoShowPeers,
setNumberOfPeers,
setTitle,
showAlert,
}),
[numberOfPeers, setDoShowPeers, setNumberOfPeers, setTitle, showAlert]
)
2022-09-05 17:35:40 -05:00
const colorMode = settingsContext.getUserSettings().colorMode
2022-09-02 09:49:00 -05:00
const theme = useMemo(
() =>
createTheme({
palette: {
2022-09-05 17:35:40 -05:00
mode: colorMode,
2022-09-02 09:49:00 -05:00
},
}),
2022-09-05 17:35:40 -05:00
[colorMode]
2022-09-02 09:49:00 -05:00
)
const handleAlertClose = (
_event?: SyntheticEvent | Event,
reason?: string
) => {
if (reason === 'clickaway') {
return
}
setIsAlertShowing(false)
}
useEffect(() => {
document.title = title
}, [title])
2022-08-31 21:44:00 -05:00
const handleDrawerOpen = () => {
setIsDrawerOpen(true)
}
2022-09-05 17:52:18 -05:00
const handleLinkButtonClick = async () => {
await navigator.clipboard.writeText(window.location.href)
shellContextValue.showAlert('Current URL copied to clipboard', {
severity: 'success',
})
}
const handleDrawerClose = () => {
setIsDrawerOpen(false)
}
const handleHomeLinkClick = () => {
setIsDrawerOpen(false)
}
return (
<ShellContext.Provider value={shellContextValue}>
2022-09-02 09:49:00 -05:00
<ThemeProvider theme={theme}>
2022-08-31 22:05:24 -05:00
<CssBaseline />
<UpgradeDialog appNeedsUpdate={appNeedsUpdate} />
2022-08-31 22:05:24 -05:00
<Box
className="Chitchatter"
sx={{
2022-08-31 22:05:24 -05:00
height: '100vh',
display: 'flex',
}}
>
2022-08-31 22:05:24 -05:00
<Snackbar
open={isAlertShowing}
autoHideDuration={6000}
onClose={handleAlertClose}
2022-08-31 22:05:24 -05:00
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
>
2022-08-31 22:05:24 -05:00
<Alert
onClose={handleAlertClose}
severity={alertSeverity}
variant="standard"
>
{alertText}
</Alert>
</Snackbar>
<ShellAppBar
doShowPeers={doShowPeers}
handleDrawerOpen={handleDrawerOpen}
handleLinkButtonClick={handleLinkButtonClick}
isDrawerOpen={isDrawerOpen}
numberOfPeers={numberOfPeers}
title={title}
/>
2022-08-31 22:05:24 -05:00
<Drawer
isDrawerOpen={isDrawerOpen}
onDrawerClose={handleDrawerClose}
onHomeLinkClick={handleHomeLinkClick}
theme={theme}
userPeerId={userPeerId}
/>
<Main
open={isDrawerOpen}
sx={{
display: 'flex',
flexDirection: 'column',
width: '100%',
}}
>
2022-09-05 12:12:54 -05:00
<DrawerHeader />
<Box sx={{ overflow: 'auto', flexGrow: 1 }}>{children}</Box>
</Main>
2022-08-31 22:05:24 -05:00
</Box>
</ThemeProvider>
</ShellContext.Provider>
)
}