Skip to content

Commit 4ad182b

Browse files
committed
fix: replace filter inputs by sliders
1 parent 6a463e1 commit 4ad182b

File tree

1 file changed

+174
-101
lines changed

1 file changed

+174
-101
lines changed

src/components/VideoExplorer/Home/MainView.js

+174-101
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,42 @@ import RightPanel from "../commons/RightPanel";
1212
import SourceFolderSelector from "../../widgets/VideoExplorer/SourceFolderSelector"
1313
import Frame from "../../widgets/VideoExplorer/Frame"
1414

15+
import Slider, { SliderTooltip } from 'rc-slider';
16+
17+
const createSliderWithTooltip = Slider.createSliderWithTooltip;
18+
const Range = createSliderWithTooltip(Slider.Range);
19+
const { Handle } = Slider;
20+
21+
const intHandle = props => {
22+
const { value, dragging, index, ...restProps } = props;
23+
return (
24+
<SliderTooltip
25+
prefixCls="rc-slider-tooltip"
26+
overlay={value}
27+
visible={dragging}
28+
placement="top"
29+
key={index}
30+
>
31+
<Handle value={value} {...restProps} />
32+
</SliderTooltip>
33+
);
34+
};
35+
36+
const percentHandle = props => {
37+
const { value, dragging, index, ...restProps } = props;
38+
return (
39+
<SliderTooltip
40+
prefixCls="rc-slider-tooltip"
41+
overlay={`${value} %`}
42+
visible={dragging}
43+
placement="top"
44+
key={index}
45+
>
46+
<Handle value={value} {...restProps} />
47+
</SliderTooltip>
48+
);
49+
};
50+
1551
@inject("videoExplorerStore")
1652
@inject("configStore")
1753
@inject("gpuStore")
@@ -32,11 +68,14 @@ class MainView extends React.Component {
3268
cableDistanceFilter: 0,
3369
cableMinNumberFilter: 0,
3470
cableMaxNumberFilter: 4,
71+
isFeedbackSubmitted: false,
3572
};
3673

3774
this.frameRef = React.createRef();
3875
this.feedbackRef = React.createRef();
3976

77+
this.handleVideoSelection = this.handleVideoSelection.bind(this)
78+
4079
this.onPlayerReady = this.onPlayerReady.bind(this);
4180
this.onPlayerProgress = this.onPlayerProgress.bind(this);
4281
this.onPlayerPause = this.onPlayerPause.bind(this);
@@ -46,8 +85,7 @@ class MainView extends React.Component {
4685
this.toggleAutoScroll = this.toggleAutoScroll.bind(this);
4786

4887
this.handleCableDistanceChange = this.handleCableDistanceChange.bind(this);
49-
this.handleCableMinNumberChange = this.handleCableMinNumberChange.bind(this);
50-
this.handleCableMaxNumberChange = this.handleCableMaxNumberChange.bind(this);
88+
this.handleCableNumberChange = this.handleCableNumberChange.bind(this);
5189

5290
this.handleFeedbackSubmit = this.handleFeedbackSubmit.bind(this)
5391

@@ -87,6 +125,19 @@ class MainView extends React.Component {
87125
this.setState({autoScroll: !this.state.autoScroll});
88126
}
89127

128+
handleVideoSelection(value) {
129+
const { videoExplorerStore } = this.props;
130+
videoExplorerStore.setVideoPath(value);
131+
132+
// reset state when a video is selected
133+
this.setState({
134+
currentTime: null,
135+
cableDistanceFilter: 0,
136+
cableMinNumberFilter: 0,
137+
cableMaxNumberFilter: 4,
138+
});
139+
}
140+
90141
onPlayerReady() {
91142
if(this.state.currentTime) {
92143
this.player.seekTo(this.state.currentTime, 'seconds');
@@ -142,16 +193,18 @@ class MainView extends React.Component {
142193
this.setState({currentTime: currentTime});
143194
}
144195

145-
handleCableDistanceChange(event) {
146-
this.setState({cableDistanceFilter: event.target.value})
147-
}
196+
handleCableDistanceChange(value) {
197+
this.setState({cableDistanceFilter: value})
148198

149-
handleCableMinNumberChange(event) {
150-
this.setState({cableMinNumberFilter: event.target.value})
199+
if(value > 0)
200+
this.setState({cableMinNumberFilter: 1})
151201
}
152202

153-
handleCableMaxNumberChange(event) {
154-
this.setState({cableMaxNumberFilter: event.target.value})
203+
handleCableNumberChange(values) {
204+
this.setState({
205+
cableMinNumberFilter: values[0],
206+
cableMaxNumberFilter: values[1]
207+
})
155208
}
156209

157210
handleFeedbackSubmit(event) {
@@ -161,6 +214,11 @@ class MainView extends React.Component {
161214

162215
videoExplorerStore.writeFeedback(this.feedbackRef.current.value)
163216
this.feedbackRef.current.value = "";
217+
218+
this.setState({ isFeedbackSubmitted: true });
219+
setTimeout(() => {
220+
this.setState({ isFeedbackSubmitted: false });
221+
}, 2000);
164222
}
165223

166224
render() {
@@ -218,6 +276,46 @@ class MainView extends React.Component {
218276
typeof settings.feedbackPath !== 'undefined' &&
219277
settings.feedbackPath.length > 0;
220278

279+
const visibleFrames = frames
280+
.filter(f => {
281+
282+
let visible = typeof f !== undefined;
283+
284+
visible = visible &&
285+
f.stats &&
286+
f.stats['cables'] &&
287+
f.stats['cables'].length >= cableMinNumberFilter &&
288+
f.stats['cables'].length <= cableMaxNumberFilter
289+
290+
if(
291+
cableDistanceFilter > 0 &&
292+
f.stats &&
293+
f.stats['cables'] &&
294+
f.stats['cables'].length > 0
295+
) {
296+
visible = visible &&
297+
f.stats['cables'].some(c => {
298+
299+
// If cable value is inferior to 0
300+
// - cable on the left position from center
301+
// - value is visible if inferior to negative cableDistanceFilter
302+
303+
// If cable value is superior to 0
304+
// - cable on the right position from center
305+
// - value is visible if superior to cableDistanceFilter
306+
307+
const value = parseInt(c * 100);
308+
309+
return value < 0 ?
310+
value <= 0 - cableDistanceFilter
311+
:
312+
value >= cableDistanceFilter
313+
})
314+
}
315+
316+
return visible;
317+
})
318+
221319
if(selectedVideo) {
222320

223321
return (
@@ -285,19 +383,27 @@ class MainView extends React.Component {
285383
<p>
286384
<a
287385
href={`${selectedVideo.path}${selectedFrame.jsonFile}`}
288-
download={`${selectedVideo.name}_{selectedFrame.jsonFile}`}
386+
download={`${selectedVideo.name}_${selectedFrame.jsonFile}`}
289387
className="badge badge-secondary"
290388
>
291389
<i className="fas fa-download" /> JSON
292390
</a>
293391
&nbsp;
294392
<a
295393
href={`${selectedVideo.path}${selectedFrame.jsonFile.replace('.json', '.png')}`}
296-
download={`${selectedVideo.name}_{selectedFrame.jsonFile.replace('.json', '.png')}`}
394+
download={`${selectedVideo.name}_${selectedFrame.jsonFile.replace('.json', '.png')}`}
297395
className="badge badge-secondary"
298396
>
299397
<i className="fas fa-download" /> Image
300398
</a>
399+
&nbsp;
400+
<a
401+
href={`${selectedVideo.path}${settings.folders.bbox_images}${selectedFrame.jsonFile.replace('.json', '.png')}`}
402+
download={`${selectedVideo.name}_${selectedFrame.jsonFile.replace('.json', '_bbox.png')}`}
403+
className="badge badge-secondary"
404+
>
405+
<i className="fas fa-download" /> Image with bounding-boxes
406+
</a>
301407
</p>
302408
<SyntaxHighlighter
303409
language={"json"}
@@ -318,9 +424,9 @@ class MainView extends React.Component {
318424
>
319425
<div className="form-group">
320426
<label
321-
for="feedbackTextArea"
427+
htmlFor="feedbackTextArea"
322428
>
323-
Leave a feedback about this frame:
429+
Leave a feedback on frame {selectedFrame.index}:
324430
</label>
325431
<textarea
326432
className="form-control"
@@ -334,6 +440,11 @@ class MainView extends React.Component {
334440
>
335441
Send feedback
336442
</button>
443+
{ this.state.isFeedbackSubmitted ?
444+
<span>&nbsp;Feedback has been submitted</span>
445+
:
446+
null
447+
}
337448
</div>
338449
</form>
339450
</div>
@@ -352,59 +463,58 @@ class MainView extends React.Component {
352463
<div className="d-flex">
353464
<form>
354465
<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>
466+
<legend className="col-form-label">Number of Cables</legend>
467+
<br/>
468+
<Range
469+
handle={intHandle}
470+
min={0}
471+
max={4}
472+
defaultValue={[
473+
this.state.cableMinNumberFilter,
474+
this.state.cableMaxNumberFilter
475+
]}
476+
onAfterChange={this.handleCableNumberChange}
477+
/>
386478
</div>
387479
<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>
480+
<legend className="col-form-label">Exclude cable distance from center</legend>
481+
<br/>
482+
<Slider
483+
id="cableDistanceFilter"
484+
handle={percentHandle}
485+
onAfterChange={this.handleCableDistanceChange}
486+
/>
398487
</div>
399488
</form>
400489
</div>
401490

402-
<div className="toggleAutoScroll d-flex justify-content-end">
403-
Auto-scroll frames &nbsp;
404-
<input
405-
type="checkbox"
406-
onChange={this.toggleAutoScroll}
407-
checked={this.state.autoScroll}/>
491+
<div className="row">
492+
<div className="col">
493+
Frames {visibleFrames.length} / {frames.length}
494+
</div>
495+
<div
496+
id="autoScrollToggle"
497+
className="col"
498+
>
499+
<form className="form-inline">
500+
<div className="form-check">
501+
<legend
502+
className="form-check-label"
503+
htmlFor="autoScrollCheckbox"
504+
style={{"font-size": "unset"}}
505+
>
506+
Autoscroll frames &nbsp;
507+
</legend>
508+
<input
509+
id="autoScrollCheckbox"
510+
type="checkbox"
511+
className="form-check-input"
512+
onChange={this.toggleAutoScroll}
513+
checked={this.state.autoScroll}
514+
/>
515+
</div>
516+
</form>
517+
</div>
408518
</div>
409519

410520
<div className='video-chrono'>
@@ -417,46 +527,7 @@ class MainView extends React.Component {
417527
: null
418528
}
419529
{
420-
frames
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-
})
459-
.map(f =>
530+
visibleFrames.map(f =>
460531
<div
461532
key={f.id}
462533
className="scrollFrame"
@@ -487,7 +558,9 @@ class MainView extends React.Component {
487558
<div className={mainClassNames.join(" ")}>
488559
<div className="container-fluid">
489560
<div className="content">
490-
<SourceFolderSelector/>
561+
<SourceFolderSelector
562+
handleVideoSelection={this.handleVideoSelection}
563+
/>
491564
<RightPanel />
492565
</div>
493566
</div>

0 commit comments

Comments
 (0)