Skip to content

Commit e399a16

Browse files
committed
feat: add filters and feedback form on VideoExplorer component
1 parent e6abf8d commit e399a16

File tree

4 files changed

+283
-12
lines changed

4 files changed

+283
-12
lines changed

src/agent.js

+36
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,42 @@ const Webserver = {
257257
console.log(res);
258258
})
259259
},
260+
writePathContent: async (path, content, loginAccess = {
261+
url: "/filebrowser/api/#",
262+
username: "",
263+
password: ""
264+
}) => {
265+
266+
let token = null;
267+
268+
if (
269+
loginAccess &&
270+
typeof loginAccess.url !== "undefined" &&
271+
typeof loginAccess.username !== "undefined" &&
272+
typeof loginAccess.password !== "undefined"
273+
) {
274+
275+
const res = await superagent
276+
.post(loginAccess.url)
277+
.send({username: loginAccess.username})
278+
.send({password: loginAccess.password})
279+
280+
if (res.status === 200) {
281+
token = res.text;
282+
}
283+
284+
}
285+
286+
superagent
287+
.post(`${path}?override=false`)
288+
.send(content)
289+
.set('X-Auth', token)
290+
.withCredentials()
291+
.catch(handleErrors)
292+
.then(res => {
293+
console.log(res);
294+
})
295+
},
260296
getFile: path =>
261297
superagent
262298
.get(URL_JSON_PREFIX + path)

src/components/VideoExplorer/Home/MainView.js

+206-11
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@ class MainView extends React.Component {
2828

2929
this.state = {
3030
currentTime: null,
31-
autoScroll: false
31+
autoScroll: false,
32+
cableDistanceFilter: 0,
33+
cableMinNumberFilter: 0,
34+
cableMaxNumberFilter: 4,
3235
};
3336

3437
this.frameRef = React.createRef();
38+
this.feedbackRef = React.createRef();
3539

3640
this.onPlayerReady = this.onPlayerReady.bind(this);
3741
this.onPlayerProgress = this.onPlayerProgress.bind(this);
@@ -41,6 +45,12 @@ class MainView extends React.Component {
4145
this.toggleBoundingBoxes = this.toggleBoundingBoxes.bind(this);
4246
this.toggleAutoScroll = this.toggleAutoScroll.bind(this);
4347

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+
4454
}
4555

4656
componentDidMount() {
@@ -92,13 +102,18 @@ class MainView extends React.Component {
92102
const currentTime = this.player.getCurrentTime();
93103
const duration = this.player.getDuration();
94104

95-
const frameIndex = parseInt(
105+
const frameIndex = Math.round(
96106
currentTime * videoExplorerStore.frames.length / duration
97107
);
98-
videoExplorerStore.setFrameIndex(frameIndex + 1)
108+
videoExplorerStore.setFrameIndex(frameIndex)
99109

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+
}
102117

103118
this.setState({currentTime: currentTime});
104119
}
@@ -110,19 +125,51 @@ class MainView extends React.Component {
110125
const currentTime = this.player.getCurrentTime();
111126
const duration = this.player.getDuration();
112127

113-
const frameIndex = parseInt(
128+
const frameIndex = Math.round(
114129
currentTime * videoExplorerStore.frames.length / duration
115130
);
116-
videoExplorerStore.setFrameIndex(frameIndex + 1)
117131

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+
}
120141

121142
this.setState({currentTime: currentTime});
122143
}
123144

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+
124166
render() {
125167
const { configStore, gpuStore, videoExplorerStore } = this.props;
168+
const {
169+
cableMinNumberFilter,
170+
cableMaxNumberFilter,
171+
cableDistanceFilter
172+
} = this.state;
126173

127174
let mainClassNames = [
128175
"main-view",
@@ -145,6 +192,32 @@ class MainView extends React.Component {
145192

146193
const isLoadingFrames = selectedVideo && frames.length === 0;
147194

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+
148221
if(selectedVideo) {
149222

150223
return (
@@ -207,7 +280,7 @@ class MainView extends React.Component {
207280
selectedFrame ?
208281
<div className="col-md-6" key={selectedFrame.id}>
209282
<h4>
210-
<i className="far fa-image"></i> Frame {selectedFrame.index}
283+
<i className="far fa-image"></i> {frameTitle}
211284
</h4>
212285
<p>
213286
<a
@@ -232,6 +305,42 @@ class MainView extends React.Component {
232305
>
233306
{JSON.stringify(selectedFrame.stats, null, 2)}
234307
</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+
235344
</div>
236345
: null
237346
}
@@ -240,6 +349,55 @@ class MainView extends React.Component {
240349
</div>
241350

242351
<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>
243401

244402
<div className="toggleAutoScroll d-flex justify-content-end">
245403
Auto-scroll frames &nbsp;
@@ -260,7 +418,44 @@ class MainView extends React.Component {
260418
}
261419
{
262420
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+
})
264459
.map(f =>
265460
<div
266461
key={f.id}

src/components/widgets/VideoExplorer/Frame/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class Frame extends React.Component {
2929

3030
switch(subtitle.format){
3131
case 'leftRightPercentArray':
32-
value = value
32+
value = value.slice()
3333
.sort((a, b) => a - b)
3434
.map(v => {
3535
return `${v > 0 ? 'right' : 'left'}: ${Math.abs(parseInt(v * 100))}/100`;

0 commit comments

Comments
 (0)