Skip to content

Commit 05652a2

Browse files
committed
feat: add student mode switch
1 parent 614cfa3 commit 05652a2

17 files changed

+231
-2
lines changed

public/app/config/channels.js

+2
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,6 @@ module.exports = {
4646
IS_AUTHENTICATED_CHANNEL: 'auth:authenticated:get',
4747
GET_SYNC_MODE_CHANNEL: 'sync:mode:get',
4848
SET_SYNC_MODE_CHANNEL: 'sync:mode:set',
49+
GET_STUDENT_MODE_CHANNEL: 'user:student-mode:get',
50+
SET_STUDENT_MODE_CHANNEL: 'user:student-mode:set',
4951
};

public/app/config/config.js

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const PRODUCT_NAME = 'Graasp';
4343
const TMP_FOLDER = 'tmp';
4444
const DEFAULT_LANG = 'en';
4545
const DEFAULT_DEVELOPER_MODE = false;
46+
const DEFAULT_STUDENT_MODE = false;
4647
const DEFAULT_GEOLOCATION_ENABLED = false;
4748
const VISUAL_SYNC_MODE = 'visual';
4849
const DEFAULT_SYNC_MODE = VISUAL_SYNC_MODE;
@@ -83,4 +84,5 @@ module.exports = {
8384
ANONYMOUS_USERNAME,
8485
VISUAL_SYNC_MODE,
8586
DEFAULT_SYNC_MODE,
87+
DEFAULT_STUDENT_MODE,
8688
};

public/app/config/messages.js

+6
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ const ERROR_GETTING_SYNC_MODE =
5757
'There was an error getting the sync mode for Space Synchronization';
5858
const ERROR_SETTING_SYNC_MODE =
5959
'There was an error setting the sync mode for Space Synchronization';
60+
const ERROR_GETTING_STUDENT_MODE =
61+
'There was an error getting the student mode';
62+
const ERROR_SETTING_STUDENT_MODE =
63+
'There was an error setting the student mode';
6064

6165
module.exports = {
6266
ERROR_GETTING_DEVELOPER_MODE,
@@ -101,4 +105,6 @@ module.exports = {
101105
ERROR_GETTING_AUTHENTICATED,
102106
ERROR_GETTING_SYNC_MODE,
103107
ERROR_SETTING_SYNC_MODE,
108+
ERROR_SETTING_STUDENT_MODE,
109+
ERROR_GETTING_STUDENT_MODE,
104110
};
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const { DEFAULT_STUDENT_MODE } = require('../config/config');
2+
const { GET_STUDENT_MODE_CHANNEL } = require('../config/channels');
3+
const logger = require('../logger');
4+
const { ERROR_GENERAL } = require('../config/errors');
5+
6+
const getStudentMode = (mainWindow, db) => async () => {
7+
try {
8+
const studentMode =
9+
db.get('user.settings.studentMode').value() || DEFAULT_STUDENT_MODE;
10+
mainWindow.webContents.send(GET_STUDENT_MODE_CHANNEL, studentMode);
11+
} catch (e) {
12+
logger.error(e);
13+
mainWindow.webContents.send(GET_STUDENT_MODE_CHANNEL, ERROR_GENERAL);
14+
}
15+
};
16+
17+
module.exports = getStudentMode;

public/app/listeners/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ const getDeveloperMode = require('./getDeveloperMode');
1717
const setDeveloperMode = require('./setDeveloperMode');
1818
const getSyncMode = require('./getSyncMode');
1919
const setSyncMode = require('./setSyncMode');
20+
const getStudentMode = require('./getStudentMode');
21+
const setStudentMode = require('./setStudentMode');
2022
const clearUserInput = require('./clearUserInput');
2123
const showClearUserInputPrompt = require('./showClearUserInputPrompt');
2224
const postAction = require('./postAction');
@@ -58,4 +60,6 @@ module.exports = {
5860
postAppInstanceResource,
5961
patchAppInstanceResource,
6062
getAppInstance,
63+
getStudentMode,
64+
setStudentMode,
6165
};
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const { SET_STUDENT_MODE_CHANNEL } = require('../config/channels');
2+
const { ERROR_GENERAL } = require('../config/errors');
3+
const logger = require('../logger');
4+
5+
const setStudentMode = (mainWindow, db) => async (event, studentMode) => {
6+
try {
7+
db.set('user.settings.studentMode', studentMode).write();
8+
mainWindow.webContents.send(SET_STUDENT_MODE_CHANNEL, studentMode);
9+
} catch (e) {
10+
logger.error(e);
11+
mainWindow.webContents.send(SET_STUDENT_MODE_CHANNEL, ERROR_GENERAL);
12+
}
13+
};
14+
15+
module.exports = setStudentMode;

public/electron.js

+10
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ const {
5454
SIGN_IN_CHANNEL,
5555
SIGN_OUT_CHANNEL,
5656
IS_AUTHENTICATED_CHANNEL,
57+
GET_STUDENT_MODE_CHANNEL,
58+
SET_STUDENT_MODE_CHANNEL,
5759
} = require('./app/config/channels');
5860
const env = require('./env.json');
5961
const {
@@ -86,6 +88,8 @@ const {
8688
getAppInstance,
8789
setSyncMode,
8890
getSyncMode,
91+
setStudentMode,
92+
getStudentMode,
8993
} = require('./app/listeners');
9094
const isMac = require('./app/utils/isMac');
9195

@@ -412,6 +416,12 @@ app.on('ready', async () => {
412416
setGeolocationEnabled(mainWindow, db)
413417
);
414418

419+
// called when getting student mode
420+
ipcMain.on(GET_STUDENT_MODE_CHANNEL, getStudentMode(mainWindow, db));
421+
422+
// called when setting student mode
423+
ipcMain.on(SET_STUDENT_MODE_CHANNEL, setStudentMode(mainWindow, db));
424+
415425
// called when creating an action
416426
ipcMain.on(POST_ACTION_CHANNEL, postAction(mainWindow, db));
417427
// called when logging in a user

src/actions/user.js

+54
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ import {
2020
SET_GEOLOCATION_ENABLED_SUCCEEDED,
2121
SET_SYNC_MODE_SUCCEEDED,
2222
GET_SYNC_MODE_SUCCEEDED,
23+
FLAG_GETTING_STUDENT_MODE,
24+
FLAG_SETTING_STUDENT_MODE,
25+
GET_STUDENT_MODE_SUCCEEDED,
26+
SET_STUDENT_MODE_SUCCEEDED,
2327
} from '../types';
2428
import {
2529
ERROR_GETTING_GEOLOCATION,
@@ -33,6 +37,8 @@ import {
3337
ERROR_GETTING_GEOLOCATION_ENABLED,
3438
ERROR_GETTING_SYNC_MODE,
3539
ERROR_SETTING_SYNC_MODE,
40+
ERROR_GETTING_STUDENT_MODE,
41+
ERROR_SETTING_STUDENT_MODE,
3642
} from '../config/messages';
3743
import {
3844
GET_USER_FOLDER_CHANNEL,
@@ -44,6 +50,8 @@ import {
4450
SET_GEOLOCATION_ENABLED_CHANNEL,
4551
GET_SYNC_MODE_CHANNEL,
4652
SET_SYNC_MODE_CHANNEL,
53+
GET_STUDENT_MODE_CHANNEL,
54+
SET_STUDENT_MODE_CHANNEL,
4755
} from '../config/channels';
4856
import { createFlag } from './common';
4957
import { ERROR_GENERAL } from '../config/errors';
@@ -61,6 +69,8 @@ const flagSettingGeolocationEnabled = createFlag(
6169
);
6270
const flagGettingSyncMode = createFlag(FLAG_GETTING_SYNC_MODE);
6371
const flagSettingSyncMode = createFlag(FLAG_SETTING_SYNC_MODE);
72+
const flagGettingStudentMode = createFlag(FLAG_GETTING_STUDENT_MODE);
73+
const flagSettingStudentMode = createFlag(FLAG_SETTING_STUDENT_MODE);
6474

6575
const getGeolocation = async () => async dispatch => {
6676
// only fetch location if online
@@ -292,6 +302,48 @@ const setSyncMode = async syncMode => dispatch => {
292302
}
293303
};
294304

305+
const getStudentMode = async () => dispatch => {
306+
try {
307+
dispatch(flagGettingStudentMode(true));
308+
window.ipcRenderer.send(GET_STUDENT_MODE_CHANNEL);
309+
window.ipcRenderer.once(GET_STUDENT_MODE_CHANNEL, (event, studentMode) => {
310+
if (studentMode === ERROR_GENERAL) {
311+
toastr.error(ERROR_MESSAGE_HEADER, ERROR_GETTING_STUDENT_MODE);
312+
} else {
313+
dispatch({
314+
type: GET_STUDENT_MODE_SUCCEEDED,
315+
payload: studentMode,
316+
});
317+
}
318+
dispatch(flagGettingStudentMode(false));
319+
});
320+
} catch (e) {
321+
console.error(e);
322+
toastr.error(ERROR_MESSAGE_HEADER, ERROR_GETTING_STUDENT_MODE);
323+
}
324+
};
325+
326+
const setStudentMode = async syncAdvancedMode => dispatch => {
327+
try {
328+
dispatch(flagSettingStudentMode(true));
329+
window.ipcRenderer.send(SET_STUDENT_MODE_CHANNEL, syncAdvancedMode);
330+
window.ipcRenderer.once(SET_STUDENT_MODE_CHANNEL, (event, mode) => {
331+
if (mode === ERROR_GENERAL) {
332+
toastr.error(ERROR_MESSAGE_HEADER, ERROR_SETTING_STUDENT_MODE);
333+
} else {
334+
dispatch({
335+
type: SET_STUDENT_MODE_SUCCEEDED,
336+
payload: mode,
337+
});
338+
}
339+
dispatch(flagSettingStudentMode(false));
340+
});
341+
} catch (e) {
342+
console.error(e);
343+
toastr.error(ERROR_MESSAGE_HEADER, ERROR_SETTING_STUDENT_MODE);
344+
}
345+
};
346+
295347
export {
296348
getUserFolder,
297349
getGeolocation,
@@ -303,4 +355,6 @@ export {
303355
setGeolocationEnabled,
304356
getSyncMode,
305357
setSyncMode,
358+
getStudentMode,
359+
setStudentMode,
306360
};

src/components/Settings.js

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import GeolocationControl from './common/GeolocationControl';
1212
import Main from './common/Main';
1313
import { SETTINGS_MAIN_ID } from '../config/selectors';
1414
import SyncAdvancedSwitch from './space/sync/SyncAdvancedSwitch';
15+
import StudentModeSwitch from './common/StudentModeSwitch';
1516

1617
// eslint-disable-next-line react/prefer-stateless-function
1718
export class Settings extends Component {
@@ -44,6 +45,7 @@ export class Settings extends Component {
4445
<DeveloperSwitch />
4546
<GeolocationControl />
4647
<SyncAdvancedSwitch />
48+
<StudentModeSwitch />
4749
</FormGroup>
4850
</div>
4951
</Main>

src/components/__snapshots__/Settings.test.js.snap

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ exports[`<Settings /> renders correctly 1`] = `
1818
<withI18nextTranslation(WithStyles(Connect(DeveloperSwitch))) />
1919
<withI18nextTranslation(WithStyles(Connect(GeolocationControl))) />
2020
<withI18nextTranslation(WithStyles(Connect(SyncAdvancedSwitch))) />
21+
<withI18nextTranslation(WithStyles(Connect(StudentModeSwitch))) />
2122
</WithStyles(ForwardRef(FormGroup))>
2223
</div>
2324
</withI18nextTranslation(WithStyles(Connect(Main)))>
+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import React, { Component } from 'react';
2+
import FormControl from '@material-ui/core/FormControl';
3+
import { withStyles } from '@material-ui/core/styles';
4+
import { withTranslation } from 'react-i18next';
5+
import { connect } from 'react-redux';
6+
import PropTypes from 'prop-types';
7+
import Switch from '@material-ui/core/Switch';
8+
import FormControlLabel from '@material-ui/core/FormControlLabel';
9+
import { getStudentMode, setStudentMode } from '../../actions';
10+
import Loader from './Loader';
11+
12+
const styles = theme => ({
13+
formControl: {
14+
margin: theme.spacing(),
15+
minWidth: 120,
16+
},
17+
});
18+
19+
export class StudentModeSwitch extends Component {
20+
static propTypes = {
21+
studentMode: PropTypes.bool.isRequired,
22+
activity: PropTypes.bool.isRequired,
23+
t: PropTypes.func.isRequired,
24+
dispatchGetStudentMode: PropTypes.func.isRequired,
25+
dispatchSetStudentMode: PropTypes.func.isRequired,
26+
classes: PropTypes.shape({
27+
formControl: PropTypes.string.isRequired,
28+
button: PropTypes.string.isRequired,
29+
}).isRequired,
30+
};
31+
32+
constructor(props) {
33+
super(props);
34+
const { dispatchGetStudentMode } = this.props;
35+
dispatchGetStudentMode();
36+
}
37+
38+
handleChange = async ({ target }) => {
39+
const { dispatchSetStudentMode } = this.props;
40+
const { checked } = target;
41+
dispatchSetStudentMode(checked);
42+
};
43+
44+
render() {
45+
const { classes, t, studentMode, activity } = this.props;
46+
47+
if (activity) {
48+
return <Loader />;
49+
}
50+
51+
const switchControl = (
52+
<Switch
53+
checked={studentMode}
54+
onChange={this.handleChange}
55+
value={studentMode}
56+
color="primary"
57+
/>
58+
);
59+
60+
return (
61+
<FormControl className={classes.formControl}>
62+
<FormControlLabel
63+
control={switchControl}
64+
label={t('Student Mode Enabled')}
65+
/>
66+
</FormControl>
67+
);
68+
}
69+
}
70+
71+
const mapStateToProps = ({ authentication }) => ({
72+
studentMode: authentication.getIn(['user', 'settings', 'studentMode']),
73+
activity: Boolean(authentication.getIn(['current', 'activity']).size),
74+
});
75+
76+
const mapDispatchToProps = {
77+
dispatchGetStudentMode: getStudentMode,
78+
dispatchSetStudentMode: setStudentMode,
79+
};
80+
81+
const ConnectedComponent = connect(
82+
mapStateToProps,
83+
mapDispatchToProps
84+
)(StudentModeSwitch);
85+
86+
const StyledComponent = withStyles(styles)(ConnectedComponent);
87+
88+
const TranslatedComponent = withTranslation()(StyledComponent);
89+
90+
export default TranslatedComponent;

src/config/channels.js

+2
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,6 @@ module.exports = {
4646
IS_AUTHENTICATED_CHANNEL: 'auth:authenticated:get',
4747
GET_SYNC_MODE_CHANNEL: 'sync:mode:get',
4848
SET_SYNC_MODE_CHANNEL: 'sync:mode:set',
49+
GET_STUDENT_MODE_CHANNEL: 'user:student-mode:get',
50+
SET_STUDENT_MODE_CHANNEL: 'user:student-mode:set',
4951
};

src/config/constants.js

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const DEFAULT_RADIUS = 50;
99
export const DEFAULT_LANGUAGE = 'en';
1010
export const DEFAULT_DEVELOPER_MODE = false;
1111
export const DEFAULT_GEOLOCATION_ENABLED = false;
12+
export const DEFAULT_STUDENT_MODE = false;
1213
export const SHORT_ID_LENGTH = 6;
1314
export const LONG_ID_LENGTH = 24;
1415
export const SMART_GATEWAY_HOST = 'gateway.golabz.eu';

src/config/messages.js

+6
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ const ERROR_GETTING_SYNC_MODE =
5757
'There was an error getting the sync mode for Space Synchronization';
5858
const ERROR_SETTING_SYNC_MODE =
5959
'There was an error setting the sync mode for Space Synchronization';
60+
const ERROR_GETTING_STUDENT_MODE =
61+
'There was an error getting the student mode';
62+
const ERROR_SETTING_STUDENT_MODE =
63+
'There was an error setting the student mode';
6064

6165
module.exports = {
6266
ERROR_GETTING_DEVELOPER_MODE,
@@ -101,4 +105,6 @@ module.exports = {
101105
ERROR_GETTING_AUTHENTICATED,
102106
ERROR_GETTING_SYNC_MODE,
103107
ERROR_SETTING_SYNC_MODE,
108+
ERROR_GETTING_STUDENT_MODE,
109+
ERROR_SETTING_STUDENT_MODE,
104110
};

src/data/sample.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@
153153
"lang": "en",
154154
"developerMode": true,
155155
"geolocationEnabled": false,
156-
"syncMode": "visual"
156+
"syncMode": "visual",
157+
"studentMode": true
157158
}
158159
},
159160
"actions": [
@@ -179,7 +180,8 @@
179180
"lang": "en",
180181
"developerMode": true,
181182
"geolocationEnabled": false,
182-
"syncMode": "visual"
183+
"syncMode": "visual",
184+
"studentMode": true
183185
}
184186
}
185187
],

0 commit comments

Comments
 (0)