@@ -28,10 +28,14 @@ class MainView extends React.Component {
28
28
29
29
this . state = {
30
30
currentTime : null ,
31
- autoScroll : false
31
+ autoScroll : false ,
32
+ cableDistanceFilter : 0 ,
33
+ cableMinNumberFilter : 0 ,
34
+ cableMaxNumberFilter : 4 ,
32
35
} ;
33
36
34
37
this . frameRef = React . createRef ( ) ;
38
+ this . feedbackRef = React . createRef ( ) ;
35
39
36
40
this . onPlayerReady = this . onPlayerReady . bind ( this ) ;
37
41
this . onPlayerProgress = this . onPlayerProgress . bind ( this ) ;
@@ -41,6 +45,12 @@ class MainView extends React.Component {
41
45
this . toggleBoundingBoxes = this . toggleBoundingBoxes . bind ( this ) ;
42
46
this . toggleAutoScroll = this . toggleAutoScroll . bind ( this ) ;
43
47
48
+ this . handleCableDistanceChange = this . handleCableDistanceChange . bind ( this ) ;
49
+ this . handleCableMinNumberChange = this . handleCableMinNumberChange . bind ( this ) ;
50
+ this . handleCableMaxNumberChange = this . handleCableMaxNumberChange . bind ( this ) ;
51
+
52
+ this . handleFeedbackSubmit = this . handleFeedbackSubmit . bind ( this )
53
+
44
54
}
45
55
46
56
componentDidMount ( ) {
@@ -92,13 +102,18 @@ class MainView extends React.Component {
92
102
const currentTime = this . player . getCurrentTime ( ) ;
93
103
const duration = this . player . getDuration ( ) ;
94
104
95
- const frameIndex = parseInt (
105
+ const frameIndex = Math . round (
96
106
currentTime * videoExplorerStore . frames . length / duration
97
107
) ;
98
- videoExplorerStore . setFrameIndex ( frameIndex + 1 )
108
+ videoExplorerStore . setFrameIndex ( frameIndex )
99
109
100
- this . frameRef . current . parentNode . scrollTop =
101
- this . frameRef . current . offsetTop ;
110
+ if (
111
+ this . frameRef &&
112
+ this . frameRef . current
113
+ ) {
114
+ this . frameRef . current . parentNode . scrollTop =
115
+ this . frameRef . current . offsetTop ;
116
+ }
102
117
103
118
this . setState ( { currentTime : currentTime } ) ;
104
119
}
@@ -110,19 +125,51 @@ class MainView extends React.Component {
110
125
const currentTime = this . player . getCurrentTime ( ) ;
111
126
const duration = this . player . getDuration ( ) ;
112
127
113
- const frameIndex = parseInt (
128
+ const frameIndex = Math . round (
114
129
currentTime * videoExplorerStore . frames . length / duration
115
130
) ;
116
- videoExplorerStore . setFrameIndex ( frameIndex + 1 )
117
131
118
- this . frameRef . current . parentNode . scrollTop =
119
- this . frameRef . current . offsetTop ;
132
+ videoExplorerStore . setFrameIndex ( frameIndex )
133
+
134
+ if (
135
+ this . frameRef &&
136
+ this . frameRef . current
137
+ ) {
138
+ this . frameRef . current . parentNode . scrollTop =
139
+ this . frameRef . current . offsetTop ;
140
+ }
120
141
121
142
this . setState ( { currentTime : currentTime } ) ;
122
143
}
123
144
145
+ handleCableDistanceChange ( event ) {
146
+ this . setState ( { cableDistanceFilter : event . target . value } )
147
+ }
148
+
149
+ handleCableMinNumberChange ( event ) {
150
+ this . setState ( { cableMinNumberFilter : event . target . value } )
151
+ }
152
+
153
+ handleCableMaxNumberChange ( event ) {
154
+ this . setState ( { cableMaxNumberFilter : event . target . value } )
155
+ }
156
+
157
+ handleFeedbackSubmit ( event ) {
158
+ const { videoExplorerStore } = this . props ;
159
+
160
+ event . preventDefault ( ) ;
161
+
162
+ videoExplorerStore . writeFeedback ( this . feedbackRef . current . value )
163
+ this . feedbackRef . current . value = "" ;
164
+ }
165
+
124
166
render ( ) {
125
167
const { configStore, gpuStore, videoExplorerStore } = this . props ;
168
+ const {
169
+ cableMinNumberFilter,
170
+ cableMaxNumberFilter,
171
+ cableDistanceFilter
172
+ } = this . state ;
126
173
127
174
let mainClassNames = [
128
175
"main-view" ,
@@ -145,6 +192,32 @@ class MainView extends React.Component {
145
192
146
193
const isLoadingFrames = selectedVideo && frames . length === 0 ;
147
194
195
+ let frameTitle = ""
196
+
197
+ if ( selectedFrame ) {
198
+ frameTitle = `Frame ${ selectedFrame . index } `
199
+
200
+ if (
201
+ settings . selectedFrameTitleAttributes &&
202
+ settings . selectedFrameTitleAttributes . length > 0 &&
203
+ selectedFrame . stats
204
+ ) {
205
+
206
+ settings . selectedFrameTitleAttributes . forEach ( attr => {
207
+
208
+ if ( selectedFrame . stats [ attr ] ) {
209
+ frameTitle += ` - ${ attr } : ${ selectedFrame . stats [ attr ] } ` ;
210
+ }
211
+
212
+ } )
213
+
214
+ }
215
+ }
216
+
217
+ const feedbackAvailable =
218
+ typeof settings . feedbackPath !== 'undefined' &&
219
+ settings . feedbackPath . length > 0 ;
220
+
148
221
if ( selectedVideo ) {
149
222
150
223
return (
@@ -207,7 +280,7 @@ class MainView extends React.Component {
207
280
selectedFrame ?
208
281
< div className = "col-md-6" key = { selectedFrame . id } >
209
282
< h4 >
210
- < i className = "far fa-image" > </ i > Frame { selectedFrame . index }
283
+ < i className = "far fa-image" > </ i > { frameTitle }
211
284
</ h4 >
212
285
< p >
213
286
< a
@@ -232,6 +305,42 @@ class MainView extends React.Component {
232
305
>
233
306
{ JSON . stringify ( selectedFrame . stats , null , 2 ) }
234
307
</ SyntaxHighlighter >
308
+
309
+ {
310
+ feedbackAvailable ?
311
+ < div >
312
+ < h4 >
313
+ < i className = "fas fa-pencil-alt" > </ i > Feedback
314
+ </ h4 >
315
+
316
+ < form
317
+ onSubmit = { this . handleFeedbackSubmit }
318
+ >
319
+ < div className = "form-group" >
320
+ < label
321
+ for = "feedbackTextArea"
322
+ >
323
+ Leave a feedback about this frame:
324
+ </ label >
325
+ < textarea
326
+ className = "form-control"
327
+ id = "feedbackTextArea"
328
+ rows = "3"
329
+ ref = { this . feedbackRef }
330
+ />
331
+ < button
332
+ type = "submit"
333
+ className = "btn btn-primary"
334
+ >
335
+ Send feedback
336
+ </ button >
337
+ </ div >
338
+ </ form >
339
+ </ div >
340
+ :
341
+ null
342
+ }
343
+
235
344
</ div >
236
345
: null
237
346
}
@@ -240,6 +349,55 @@ class MainView extends React.Component {
240
349
</ div >
241
350
242
351
< div className = "col-3" >
352
+ < div className = "d-flex" >
353
+ < form >
354
+ < div className = "form-group row" >
355
+ < legend className = "col-form-label col-4" > Number of Cables</ legend >
356
+ < div className = "col-4" >
357
+ < input
358
+ id = "cableMinNumberFilter"
359
+ type = "number"
360
+ className = "form-control"
361
+ onChange = { this . handleCableMinNumberChange }
362
+ value = { this . state . cableMinNumberFilter }
363
+ />
364
+ < label
365
+ for = "cableMinNumberFilter"
366
+ className = "col-form-label"
367
+ >
368
+ Min
369
+ </ label >
370
+ </ div >
371
+ < div className = "col-4" >
372
+ < input
373
+ id = "cableMaxNumberFilter"
374
+ className = "form-control"
375
+ type = "number"
376
+ onChange = { this . handleCableMaxNumberChange }
377
+ value = { this . state . cableMaxNumberFilter }
378
+ />
379
+ < label
380
+ for = "cableMaxNumberFilter"
381
+ className = "col-form-label"
382
+ >
383
+ Max
384
+ </ label >
385
+ </ div >
386
+ </ div >
387
+ < div className = "form-group row" >
388
+ < legend className = "col-form-label col-4" > Exclude cable distance from center</ legend >
389
+ < div class = "col-8" >
390
+ < input
391
+ id = "cableDistanceFilter"
392
+ type = "number"
393
+ className = "form-control"
394
+ onChange = { this . handleCableDistanceChange }
395
+ value = { this . state . cableDistanceFilter }
396
+ />
397
+ </ div >
398
+ </ div >
399
+ </ form >
400
+ </ div >
243
401
244
402
< div className = "toggleAutoScroll d-flex justify-content-end" >
245
403
Auto-scroll frames
@@ -260,7 +418,44 @@ class MainView extends React.Component {
260
418
}
261
419
{
262
420
frames
263
- . filter ( f => f )
421
+ . filter ( f => {
422
+
423
+ let visible = typeof f !== undefined ;
424
+
425
+ visible = visible &&
426
+ f . stats &&
427
+ f . stats [ 'cables' ] &&
428
+ f . stats [ 'cables' ] . length >= cableMinNumberFilter &&
429
+ f . stats [ 'cables' ] . length <= cableMaxNumberFilter
430
+
431
+ if (
432
+ cableDistanceFilter > 0 &&
433
+ f . stats &&
434
+ f . stats [ 'cables' ] &&
435
+ f . stats [ 'cables' ] . length > 0
436
+ ) {
437
+ visible = visible &&
438
+ f . stats [ 'cables' ] . some ( c => {
439
+
440
+ // If cable value is inferior to 0
441
+ // - cable on the left position from center
442
+ // - value is visible if inferior to negative cableDistanceFilter
443
+
444
+ // If cable value is superior to 0
445
+ // - cable on the right position from center
446
+ // - value is visible if superior to cableDistanceFilter
447
+
448
+ const value = parseInt ( c * 100 ) ;
449
+
450
+ return value < 0 ?
451
+ value <= 0 - cableDistanceFilter
452
+ :
453
+ value >= cableDistanceFilter
454
+ } )
455
+ }
456
+
457
+ return visible ;
458
+ } )
264
459
. map ( f =>
265
460
< div
266
461
key = { f . id }
0 commit comments