1
- import React from 'react' ;
2
- import { compose , lifecycle , branch , renderNothing } from 'recompose' ;
3
- import { connect } from 'react-redux' ;
4
- import { bindActionCreators } from 'redux' ;
1
+ import React , { useEffect } from 'react' ;
2
+ import { useSelector } from 'react-redux' ;
5
3
6
- import { withStyles } from '@material-ui/core/styles' ;
7
- import Button from '@material-ui/core/Button' ;
8
- import Container from '@material-ui/core/Container' ;
9
- import Paper from '@material-ui/core/Paper' ;
10
- import Typography from '@material-ui/core/Typography' ;
4
+ import { makeStyles } from '@material-ui/core/styles' ;
5
+ import { Button , Container , Paper , Typography } from '@material-ui/core' ;
11
6
12
7
import { ResponsesSelectors , ResponsesActions } from 'modules/responses' ;
13
8
import PaperPage from 'components/PaperPage' ;
9
+ import { useActions , useCallbackRef , useErrorContext } from 'hooks' ;
14
10
15
- const styles = theme => ( {
11
+ const useStyles = makeStyles ( theme => ( {
16
12
videoContainer : {
17
13
padding : 10 ,
18
14
display : 'flex' ,
@@ -29,88 +25,84 @@ const styles = theme => ({
29
25
width : '80%' ,
30
26
margin : theme . spacing ( 2 ) ,
31
27
} ,
32
- } ) ;
28
+ } ) ) ;
33
29
34
- class ResponseViewer extends React . Component {
35
- constructor ( props ) {
36
- super ( props ) ;
37
- this . videoChallenge = React . createRef ( ) ;
38
- this . videoResponse = React . createRef ( ) ;
39
- }
30
+ const ResponseViewer = props => {
31
+ const classes = useStyles ( ) ;
32
+ const [ videoChallengeRef , videoChallenge ] = useCallbackRef ( ) ;
33
+ const [ videoResponseRef , videoResponse ] = useCallbackRef ( ) ;
34
+
35
+ const isLoading = useSelector ( state => ResponsesSelectors . isLoading ( state ) ) ;
36
+ const isLoaded = useSelector ( state => ResponsesSelectors . isLoaded ( state ) ) ;
37
+ const response = useSelector ( state =>
38
+ ResponsesSelectors . response ( state , props )
39
+ ) ;
40
+ const challenge = ( response || { } ) . challenge ;
41
+ const actions = useActions ( ResponsesActions ) ;
42
+ const errorHandler = useErrorContext ( ) ;
40
43
41
- startPlaying = ( ) => {
42
- let self = this ;
43
- self . videoChallenge . current . play ( ) ;
44
- self . videoResponse . current . play ( ) ;
44
+ useEffect (
45
+ ( ) => {
46
+ if ( ! isLoaded && ! isLoading ) {
47
+ actions . fetchResponses ( ) . catch ( error => {
48
+ errorHandler ( error , 'Failed to load challenges' , true ) ;
49
+ } ) ;
50
+ }
51
+ } ,
52
+ // TODO: Stop the warning from happening.
53
+ [ isLoaded , isLoading ] // This wouldn't make sense to include other vars.
54
+ ) ;
55
+
56
+ const startPlaying = ( ) => {
57
+ videoChallenge . play ( ) ;
58
+ videoResponse . play ( ) ;
45
59
// Mute the response video until the challenge is played.
46
60
// This should be done more react-ily.
47
- self . videoResponse . current . volume = 0 ;
48
- self . videoChallenge . current . onended = ( ) => {
49
- self . videoResponse . current . volume = 1 ;
61
+ videoResponse . volume = 0 ;
62
+ videoChallenge . onended = ( ) => {
63
+ videoResponse . volume = 1 ;
50
64
} ;
51
65
} ;
52
66
53
- render ( ) {
54
- const { classes, response } = this . props ;
55
- // TODO(Alex): I don't understand why the branch below doesn't make
56
- // this unncessary.
57
- if ( ! response || response === undefined ) {
58
- return (
59
- < Paper className = { classes . paper } >
60
- < Typography variant = "h2" > Unknown Challenge</ Typography >
61
- </ Paper >
62
- ) ;
63
- }
64
- const challenge = response . challenge ;
67
+ if ( ! response || response === undefined ) {
65
68
return (
66
- < PaperPage
67
- superTitle = { `${ response . user . full_name } responds to` }
68
- title = { challenge . title }
69
- >
70
- < Container className = { classes . instructionsContainer } >
71
- < Typography variant = "h4" > Instructions:</ Typography >
72
- < Typography variant = "body1" > { challenge . instructions } </ Typography >
73
- </ Container >
74
-
75
- < div className = { classes . videoContainer } >
76
- < video width = "250" ref = { this . videoChallenge } >
77
- < source src = { challenge . video . url } type = "video/webm" />
78
- </ video >
79
- < video width = "250" ref = { this . videoResponse } >
80
- < source src = { response . video . url } type = "video/webm" />
81
- </ video >
82
- </ div >
83
-
84
- < div className = { classes . toggleCenterer } >
85
- < Button
86
- className = { classes . toggleButton }
87
- onClick = { this . startPlaying }
88
- variant = "contained"
89
- color = "primary"
90
- >
91
- Play
92
- </ Button >
93
- </ div >
94
- </ PaperPage >
69
+ < Paper className = { classes . paper } >
70
+ < Typography variant = "h2" > Unknown Challenge</ Typography >
71
+ </ Paper >
95
72
) ;
96
73
}
97
- }
98
74
99
- export default compose (
100
- connect (
101
- ( state , ownProps ) => ( {
102
- isLoading : ResponsesSelectors . isLoading ( state ) ,
103
- response : ResponsesSelectors . response ( state , ownProps ) ,
104
- } ) ,
105
- dispatch => ( {
106
- actions : bindActionCreators ( ResponsesActions , dispatch ) ,
107
- } )
108
- ) ,
109
- lifecycle ( {
110
- componentDidMount ( ) {
111
- this . props . actions . fetchResponses ( ) ;
112
- } ,
113
- } ) ,
114
- branch ( props => props . isLoading , renderNothing ) , // TODO: replace with a loading component
115
- withStyles ( styles )
116
- ) ( ResponseViewer ) ;
75
+ return (
76
+ < PaperPage
77
+ superTitle = { `${ response . user . full_name } responds to` }
78
+ title = { challenge . title }
79
+ >
80
+ < Container className = { classes . instructionsContainer } >
81
+ < Typography variant = "h4" > Instructions:</ Typography >
82
+ < Typography variant = "body1" > { challenge . instructions } </ Typography >
83
+ </ Container >
84
+
85
+ < div className = { classes . videoContainer } >
86
+ < video width = "350" ref = { videoChallengeRef } >
87
+ < source src = { challenge . video . url } type = "video/webm" />
88
+ </ video >
89
+ < video width = "350" ref = { videoResponseRef } >
90
+ < source src = { response . video . url } type = "video/webm" />
91
+ </ video >
92
+ </ div >
93
+
94
+ < div className = { classes . toggleCenterer } >
95
+ < Button
96
+ className = { classes . toggleButton }
97
+ onClick = { startPlaying }
98
+ variant = "contained"
99
+ color = "primary"
100
+ >
101
+ Play
102
+ </ Button >
103
+ </ div >
104
+ </ PaperPage >
105
+ ) ;
106
+ } ;
107
+
108
+ export default ResponseViewer ;
0 commit comments