1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
import React from 'react';
import { Outlet, useNavigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { LinearProgress, useMediaQuery, useTheme } from '@mui/material';
import makeStyles from '@mui/styles/makeStyles';
import BottomMenu from './common/components/BottomMenu';
import SocketController from './SocketController';
import CachingController from './CachingController';
import { useCatch, useEffectAsync } from './reactHelper';
import { sessionActions } from './store';
import UpdateController from './UpdateController';
import TermsDialog from './common/components/TermsDialog';
const useStyles = makeStyles(() => ({
page: {
flexGrow: 1,
overflow: 'auto',
},
menu: {
zIndex: 4,
},
}));
const App = () => {
const classes = useStyles();
const theme = useTheme();
const dispatch = useDispatch();
const navigate = useNavigate();
const desktop = useMediaQuery(theme.breakpoints.up('md'));
const newServer = useSelector((state) => state.session.server.newServer);
const termsUrl = useSelector((state) => state.session.server.attributes.termsUrl);
const user = useSelector((state) => state.session.user);
const acceptTerms = useCatch(async () => {
const response = await fetch(`/api/users/${user.id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ...user, attributes: { ...user.attributes, termsAccepted: true } }),
});
if (response.ok) {
dispatch(sessionActions.updateUser(await response.json()));
} else {
throw Error(await response.text());
}
});
useEffectAsync(async () => {
if (!user) {
const response = await fetch('/api/session');
if (response.ok) {
dispatch(sessionActions.updateUser(await response.json()));
} else if (newServer) {
navigate('/register');
} else {
navigate('/login');
}
}
return null;
}, [user]);
if (user == null) {
return (<LinearProgress />);
}
if (termsUrl && !user.attributes.termsAccepted) {
return (<TermsDialog open onCancel={() => navigate('/login')} onAccept={() => acceptTerms()} />);
}
return (
<>
<SocketController />
<CachingController />
<UpdateController />
<div className={classes.page}>
<Outlet />
</div>
{!desktop && (
<div className={classes.menu}>
<BottomMenu />
</div>
)}
</>
);
};
export default App;
|