@@ -32,8 +32,38 @@ class Poll extends ImmutablePureComponent {
3232
3333 state = {
3434 selected : { } ,
35+ expired : null ,
3536 } ;
3637
38+ static getDerivedStateFromProps ( props , state ) {
39+ const { poll, intl } = props ;
40+ const expired = poll . get ( 'expired' ) || ( new Date ( poll . get ( 'expires_at' ) ) ) . getTime ( ) < intl . now ( ) ;
41+ return ( expired === state . expired ) ? null : { expired } ;
42+ }
43+
44+ componentDidMount ( ) {
45+ this . _setupTimer ( ) ;
46+ }
47+
48+ componentDidUpdate ( ) {
49+ this . _setupTimer ( ) ;
50+ }
51+
52+ componentWillUnmount ( ) {
53+ clearTimeout ( this . _timer ) ;
54+ }
55+
56+ _setupTimer ( ) {
57+ const { poll, intl } = this . props ;
58+ clearTimeout ( this . _timer ) ;
59+ if ( ! this . state . expired ) {
60+ const delay = ( new Date ( poll . get ( 'expires_at' ) ) ) . getTime ( ) - intl . now ( ) ;
61+ this . _timer = setTimeout ( ( ) => {
62+ this . setState ( { expired : true } ) ;
63+ } , delay ) ;
64+ }
65+ }
66+
3767 handleOptionChange = e => {
3868 const { target : { value } } = e ;
3969
@@ -68,12 +98,11 @@ class Poll extends ImmutablePureComponent {
6898 this . props . dispatch ( fetchPoll ( this . props . poll . get ( 'id' ) ) ) ;
6999 } ;
70100
71- renderOption ( option , optionIndex ) {
101+ renderOption ( option , optionIndex , showResults ) {
72102 const { poll, disabled } = this . props ;
73103 const percent = poll . get ( 'votes_count' ) === 0 ? 0 : ( option . get ( 'votes_count' ) / poll . get ( 'votes_count' ) ) * 100 ;
74104 const leading = poll . get ( 'options' ) . filterNot ( other => other . get ( 'title' ) === option . get ( 'title' ) ) . every ( other => option . get ( 'votes_count' ) > other . get ( 'votes_count' ) ) ;
75105 const active = ! ! this . state . selected [ `${ optionIndex } ` ] ;
76- const showResults = poll . get ( 'voted' ) || poll . get ( 'expired' ) ;
77106
78107 let titleEmojified = option . get ( 'title_emojified' ) ;
79108 if ( ! titleEmojified ) {
@@ -112,19 +141,20 @@ class Poll extends ImmutablePureComponent {
112141
113142 render ( ) {
114143 const { poll, intl } = this . props ;
144+ const { expired } = this . state ;
115145
116146 if ( ! poll ) {
117147 return null ;
118148 }
119149
120- const timeRemaining = poll . get ( ' expired' ) ? intl . formatMessage ( messages . closed ) : < RelativeTimestamp timestamp = { poll . get ( 'expires_at' ) } futureDate /> ;
121- const showResults = poll . get ( 'voted' ) || poll . get ( ' expired' ) ;
150+ const timeRemaining = expired ? intl . formatMessage ( messages . closed ) : < RelativeTimestamp timestamp = { poll . get ( 'expires_at' ) } futureDate /> ;
151+ const showResults = poll . get ( 'voted' ) || expired ;
122152 const disabled = this . props . disabled || Object . entries ( this . state . selected ) . every ( item => ! item ) ;
123153
124154 return (
125155 < div className = 'poll' >
126156 < ul >
127- { poll . get ( 'options' ) . map ( ( option , i ) => this . renderOption ( option , i ) ) }
157+ { poll . get ( 'options' ) . map ( ( option , i ) => this . renderOption ( option , i , showResults ) ) }
128158 </ ul >
129159
130160 < div className = 'poll__footer' >
0 commit comments