-
Notifications
You must be signed in to change notification settings - Fork 30
/
ClassifierContainer.js
164 lines (149 loc) · 4.76 KB
/
ClassifierContainer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import { GraphQLClient } from 'graphql-request'
import { Paragraph } from 'grommet'
import { Provider } from 'mobx-react'
import PropTypes from 'prop-types'
import React, { useEffect } from 'react'
import '../../translations/i18n'
import {
env,
panoptes as panoptesClient,
projects as projectsClient,
tutorials as tutorialsClient
} from '@zooniverse/panoptes-js'
import { useHydratedStore, useStore, useWorkflowSnapshot } from './hooks'
import { unregisterWorkers } from '../../workers'
import Classifier from './Classifier'
// import { isBackgroundSyncAvailable } from '../../helpers/featureDetection'
function caesarClient (env) {
switch (env) {
case 'production': {
return new GraphQLClient('https://caesar.zooniverse.org/graphql')
}
default: {
return new GraphQLClient('https://caesar-staging.zooniverse.org/graphql')
}
}
}
const client = {
caesar: caesarClient(env),
panoptes: panoptesClient,
projects: projectsClient,
tutorials: tutorialsClient
}
// We don't register the queue service worker if background sync API is not available
// We might want to move this check elsewhere once we add other service workers for other tasks
// if (isBackgroundSyncAvailable()) registerWorkers()
// TODO: The workbox background sync queue isn't working as expected
// It doesn't work with superagent/XHR req for interception
// We need to migrate to fetch API, otherwise the POST will occur twice
// Once in our store, once in the worker
// So we'll unregister the worker for now.
unregisterWorkers('./queue.js')
export default function ClassifierContainer({
authClient,
cachePanoptesData = false,
locale,
onAddToCollection = () => true,
onCompleteClassification = () => true,
onError = () => true,
onSubjectChange = () => true,
onSubjectReset = () => true,
onToggleFavourite = () => true,
project,
subjectID,
subjectSetID,
workflowID
}) {
const classifierStore = useStore({
authClient,
client,
initialState: {}
})
const workflowSnapshot = useWorkflowSnapshot(workflowID)
const loaded = useHydratedStore(classifierStore, cachePanoptesData, `fem-classifier-${project.id}`)
useEffect(function onLoad() {
const { classifications, subjects, workflows } = classifierStore
/*
If the project uses session storage, we need to do some
processing of the store after it loads.
*/
if (cachePanoptesData && loaded) {
if (!workflows.active?.prioritized) {
/*
In this case, we delete the saved queue so that
refreshing the classifier will load a new, randomised
subject queue.
*/
console.log('randomising the subject queue.')
subjects.reset()
subjects.advance()
}
if (subjects.active) {
/*
This is a hack to start a new classification from a snapshot.
*/
console.log('store hydrated with active subject', subjects.active.id)
classifierStore.startClassification()
}
}
/*
This should run after the store is created and hydrated.
Otherwise, hydration will overwrite the callbacks with
their defaults.
*/
if (loaded) {
console.log('setting classifier event callbacks')
classifierStore.setOnAddToCollection(onAddToCollection)
classifications.setOnComplete(onCompleteClassification)
classifierStore.setOnSubjectChange(onSubjectChange)
subjects.setOnReset(onSubjectReset)
classifierStore.setOnToggleFavourite(onToggleFavourite)
}
}, [cachePanoptesData, loaded])
useEffect(function onAuthChange() {
if (loaded) {
classifierStore.userProjectPreferences.checkForUser()
}
}, [loaded, authClient])
try {
if (loaded) {
return (
<Provider classifierStore={classifierStore}>
<Classifier
classifierStore={classifierStore}
locale={locale}
onError={onError}
project={project}
subjectSetID={subjectSetID}
subjectID={subjectID}
workflowSnapshot={workflowSnapshot}
workflowVersion={workflowSnapshot?.version}
workflowID={workflowSnapshot?.id}
/>
</Provider>
)
}
return <Paragraph>Loading…</Paragraph>
} catch (error) {
const info = {
package: '@zooniverse/classifier'
}
onError(error, info);
}
return null
}
ClassifierContainer.propTypes = {
authClient: PropTypes.object.isRequired,
cachePanoptesData: PropTypes.bool,
locale: PropTypes.string,
mode: PropTypes.string,
onAddToCollection: PropTypes.func,
onCompleteClassification: PropTypes.func,
onError: PropTypes.func,
onSubjectReset: PropTypes.func,
onToggleFavourite: PropTypes.func,
project: PropTypes.shape({
id: PropTypes.string.isRequired
}).isRequired,
theme: PropTypes.object
}