@@ -4,8 +4,13 @@ import { connect } from 'react-redux'
44import _get from 'lodash/get'
55import _isObject from 'lodash/isObject'
66import _isFinite from 'lodash/isFinite'
7+ import _debounce from 'lodash/debounce'
78import _find from 'lodash/find'
89import _omit from 'lodash/omit'
10+ import { fetchChallenge }
11+ from '../../../services/Challenge/Challenge'
12+
13+ const FRESHNESS_THRESHOLD = 5000 // 5 seconds
914
1015/**
1116 * WithBrowsedChallenge provides functions for starting and stopping browsing
@@ -19,6 +24,7 @@ export const WithBrowsedChallenge = function(WrappedComponent) {
1924 class _WithBrowsedChallenge extends Component {
2025 state = {
2126 browsedChallenge : null ,
27+ loadingBrowsedChallenge : false ,
2228 isVirtual : false ,
2329 }
2430
@@ -67,21 +73,37 @@ export const WithBrowsedChallenge = function(WrappedComponent) {
6773
6874 if ( _isFinite ( challengeId ) ) {
6975 if ( _get ( this . state , 'browsedChallenge.id' ) !== challengeId ||
70- this . state . isVirtual !== isVirtual ) {
76+ this . state . isVirtual !== isVirtual ||
77+ this . state . loadingBrowsedChallenge ) {
7178 const challenge = isVirtual ? this . props . virtualChallenge :
7279 _find ( props . challenges , { id : challengeId } )
7380
7481 if ( _isObject ( challenge ) ) {
75- this . setState ( { browsedChallenge : challenge , isVirtual} )
82+ this . setState ( {
83+ browsedChallenge : challenge ,
84+ loadingBrowsedChallenge : false ,
85+ isVirtual
86+ } )
7687
7788 if ( challenge . id !== _get ( this . props , 'clusteredTasks.challengeId' ) ||
7889 isVirtual !== _get ( this . props , 'clusteredTasks.isVirtualChallenge' ) ) {
7990 this . props . fetchClusteredTasks ( challenge . id , isVirtual )
8091 }
8192 }
93+ else if ( ! isVirtual ) {
94+ // We don't have the challenge available, so fetch it.
95+ this . setState ( {
96+ browsedChallenge : { id : challengeId } ,
97+ loadingBrowsedChallenge : true ,
98+ isVirtual,
99+ } )
100+
101+ props . loadChallenge ( challengeId )
102+ }
82103 }
83104 }
84- else if ( _isObject ( this . state . browsedChallenge ) ) {
105+ else if ( _isObject ( this . state . browsedChallenge &&
106+ ! this . state . loadingBrowsedChallenge ) ) {
85107 this . setState ( { browsedChallenge : null , isVirtual : false } )
86108 }
87109 }
@@ -128,10 +150,13 @@ export const WithBrowsedChallenge = function(WrappedComponent) {
128150
129151 return (
130152 < WrappedComponent browsedChallenge = { this . state . browsedChallenge }
153+ loadingBrowsedChallenge = { this . state . loadingBrowsedChallenge }
131154 startBrowsingChallenge = { this . startBrowsingChallenge }
132155 stopBrowsingChallenge = { this . stopBrowsingChallenge }
133156 clusteredTasks = { clusteredTasks }
134- { ..._omit ( this . props , [ 'entities' , 'clusteredTasks' ] ) } />
157+ { ..._omit ( this . props , [ 'entities' ,
158+ 'clusteredTasks' ,
159+ 'loadChallenge' ] ) } />
135160 )
136161 }
137162 }
@@ -148,5 +173,17 @@ const mapStateToProps = state => ({
148173 entities : state . entities ,
149174} )
150175
176+ export const mapDispatchToProps = ( dispatch , ownProps ) => {
177+ return {
178+ loadChallenge : _debounce (
179+ challengeId => {
180+ return dispatch ( fetchChallenge ( challengeId ) )
181+ } ,
182+ FRESHNESS_THRESHOLD ,
183+ { leading : true } ,
184+ ) ,
185+ }
186+ }
187+
151188export default WrappedComponent =>
152- connect ( mapStateToProps ) ( WithBrowsedChallenge ( WrappedComponent ) )
189+ connect ( mapStateToProps , mapDispatchToProps ) ( WithBrowsedChallenge ( WrappedComponent ) )
0 commit comments