Skip to content

Commit 107fcbe

Browse files
committed
completely converted stateful components into functional components with hooks
1 parent 12dc140 commit 107fcbe

File tree

6 files changed

+288
-250
lines changed

6 files changed

+288
-250
lines changed

src/app/components/Action.jsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ import PropTypes from 'prop-types';
33

44
const Action = (props) => {
55
const {
6-
selected, handleChangeSnapshot, handleJumpSnapshot, index, sliderIndex,
6+
selected, index, sliderIndex, dispatch,
77
} = props;
88

99
return (
1010
<div
1111
className={selected ? 'action-component selected' : 'action-component'}
12-
onClick={() => handleChangeSnapshot(index)}
12+
onClick={() => dispatch({
13+
type: 'changeView',
14+
payload: index,
15+
})}
1316
role="presentation"
1417
style={index > sliderIndex ? { color: '#5f6369' } : {}}
1518
>
@@ -18,7 +21,10 @@ const Action = (props) => {
1821
className="jump-button"
1922
onClick={(e) => {
2023
e.stopPropagation();
21-
handleJumpSnapshot(index);
24+
dispatch({
25+
type: 'changeSlider',
26+
payload: index,
27+
});
2228
}}
2329
tabIndex={index}
2430
type="button"
@@ -30,10 +36,10 @@ const Action = (props) => {
3036
};
3137

3238
Action.propTypes = {
39+
sliderIndex: PropTypes.number.isRequired,
3340
selected: PropTypes.bool.isRequired,
3441
index: PropTypes.number.isRequired,
35-
handleChangeSnapshot: PropTypes.func.isRequired,
36-
handleJumpSnapshot: PropTypes.func.isRequired,
42+
dispatch: PropTypes.func.isRequired,
3743
};
3844

3945
export default Action;

src/app/components/MainSlider.jsx

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,28 @@ const handle = (props) => {
2424
};
2525

2626
const MainSlider = ({
27-
snapshotLength,
27+
snapshotsLength,
2828
sliderIndex,
29-
handleJumpSnapshot,
30-
pause,
29+
dispatch,
3130
}) =>
3231
(
3332
<Slider
3433
min={0}
35-
max={snapshotLength - 1}
34+
max={snapshotsLength - 1}
3635
value={sliderIndex}
3736
onChange={(index) => {
3837
const newIndex = index === -1 ? 0 : index;
39-
handleJumpSnapshot(newIndex);
40-
pause();
38+
dispatch({ type: 'changeSlider', payload: newIndex });
39+
dispatch({ type: 'pause' });
4140
}}
4241
handle={handle}
4342
/>
4443
);
4544

4645
MainSlider.propTypes = {
47-
snapshotLength: PropTypes.number.isRequired,
46+
snapshotsLength: PropTypes.number.isRequired,
4847
sliderIndex: PropTypes.number.isRequired,
49-
handleJumpSnapshot: PropTypes.func.isRequired,
50-
pause: PropTypes.func.isRequired,
48+
dispatch: PropTypes.func.isRequired,
5149
};
5250

5351
export default MainSlider;

src/app/containers/ActionContainer.jsx

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ import Action from '../components/Action';
44

55
const ActionContainer = ({
66
snapshots,
7-
viewIndex,
8-
handleChangeSnapshot,
9-
handleJumpSnapshot,
10-
emptySnapshot,
117
sliderIndex,
8+
viewIndex,
9+
dispatch,
1210
}) => {
1311
let actionsArr = [];
1412
if (snapshots.length > 0) {
@@ -18,19 +16,17 @@ const ActionContainer = ({
1816
<Action
1917
key={`action${index}`}
2018
index={index}
21-
snapshot={snapshot}
2219
selected={selected}
20+
dispatch={dispatch}
2321
sliderIndex={sliderIndex}
24-
handleChangeSnapshot={handleChangeSnapshot}
25-
handleJumpSnapshot={handleJumpSnapshot}
2622
/>
2723
);
2824
});
2925
}
3026
return (
3127
<div className="action-container">
3228
<div className="action-component exclude">
33-
<button className="empty-button" onClick={emptySnapshot} type="button">
29+
<button className="empty-button" onClick={() => dispatch({ type: 'empty' })} type="button">
3430
emptySnapshot
3531
</button>
3632
</div>
@@ -41,11 +37,9 @@ const ActionContainer = ({
4137

4238
ActionContainer.propTypes = {
4339
snapshots: PropTypes.arrayOf(PropTypes.object).isRequired,
44-
viewIndex: PropTypes.number.isRequired,
40+
dispatch: PropTypes.func.isRequired,
4541
sliderIndex: PropTypes.number.isRequired,
46-
handleChangeSnapshot: PropTypes.func.isRequired,
47-
handleJumpSnapshot: PropTypes.func.isRequired,
48-
emptySnapshot: PropTypes.func.isRequired,
42+
viewIndex: PropTypes.number.isRequired,
4943
};
5044

5145
export default ActionContainer;

src/app/containers/ButtonsContainer.jsx

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,69 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33

4+
5+
function exportSnapshots(snapshots) {
6+
// create invisible download anchor link
7+
const fileDownload = document.createElement('a');
8+
9+
// set file in anchor link
10+
fileDownload.href = URL.createObjectURL(
11+
new Blob([JSON.stringify(snapshots)], { type: 'application/json' }),
12+
);
13+
14+
// set anchor as file download and click it
15+
fileDownload.setAttribute('download', 'snapshot.json');
16+
fileDownload.click();
17+
18+
// remove file url
19+
URL.revokeObjectURL(fileDownload.href);
20+
}
21+
22+
function importSnapshots(dispatch) {
23+
const fileUpload = document.createElement('input');
24+
fileUpload.setAttribute('type', 'file');
25+
26+
fileUpload.onchange = (event) => {
27+
const reader = new FileReader();
28+
reader.onload = () => {
29+
dispatch({ type: 'import', payload: JSON.parse(reader.result) });
30+
};
31+
reader.readAsText(event.target.files[0]);
32+
};
33+
34+
fileUpload.click();
35+
}
36+
437
const ButtonsContainer = ({
538
mode: { paused, locked, persist },
6-
toggleMode,
7-
importSnapshots,
8-
exportSnapshots,
9-
}) => (
10-
<div className="buttons-container">
11-
<button className="pause-button" type="button" onClick={() => toggleMode('paused')}>
12-
{paused ? 'Resume' : 'Pause'}
13-
</button>
14-
<button className="lock-button" type="button" onClick={() => toggleMode('locked')}>
15-
{locked ? 'Unlock' : 'Lock'}
16-
</button>
17-
<button className="persist-button" type="button" onClick={() => toggleMode('persist')}>
18-
{persist ? 'Unpersist' : 'Persist'}
19-
</button>
20-
<button className="import-button" type="button" onClick={importSnapshots}>
21-
Import
22-
</button>
23-
<button className="export-button" type="button" onClick={exportSnapshots}>
24-
Export
25-
</button>
26-
</div>
27-
);
39+
dispatch,
40+
snapshots,
41+
}) =>
42+
(
43+
<div className="buttons-container">
44+
<button className="pause-button" type="button" onClick={() => dispatch({ type: 'toggleMode', payload: 'paused' })}>
45+
{paused ? 'Resume' : 'Pause'}
46+
</button>
47+
<button className="lock-button" type="button" onClick={() => dispatch({ type: 'toggleLocked', payload: 'locked' })}>
48+
{locked ? 'Unlock' : 'Lock'}
49+
</button>
50+
<button className="persist-button" type="button" onClick={() => dispatch({ type: 'togglePersist', payload: 'persist' })}>
51+
{persist ? 'Unpersist' : 'Persist'}
52+
</button>
53+
<button className="export-button" type="button" onClick={() => exportSnapshots(snapshots)}>
54+
Export
55+
</button>
56+
<button className="import-button" type="button" onClick={() => importSnapshots(dispatch)}>
57+
Import
58+
</button>
59+
</div>
60+
);
2861

2962
ButtonsContainer.propTypes = {
30-
toggleMode: PropTypes.func.isRequired,
31-
importSnapshots: PropTypes.func.isRequired,
32-
exportSnapshots: PropTypes.func.isRequired,
63+
dispatch: PropTypes.func.isRequired,
64+
snapshots: PropTypes.arrayOf(
65+
PropTypes.object,
66+
).isRequired,
3367
mode: PropTypes.shape({
3468
paused: PropTypes.bool,
3569
locked: PropTypes.bool,

0 commit comments

Comments
 (0)