aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/collections/CollectionStackedTimeline.tsx3
-rw-r--r--src/client/views/nodes/VideoBox.scss1
-rw-r--r--src/client/views/nodes/VideoBox.tsx50
3 files changed, 42 insertions, 12 deletions
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 372629ddf..77ed83278 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -183,7 +183,8 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
@action
keyEvents = (e: KeyboardEvent) => {
if (
- !(e.target instanceof HTMLInputElement) &&
+ // need to include range inputs because after dragging video time slider it becomes target element
+ !(e.target instanceof HTMLInputElement && !(e.target.type === "range")) &&
this.props.isSelected(true)
) {
// if shift pressed scrub 1 second otherwise 1/10th
diff --git a/src/client/views/nodes/VideoBox.scss b/src/client/views/nodes/VideoBox.scss
index 47867b128..da29c291f 100644
--- a/src/client/views/nodes/VideoBox.scss
+++ b/src/client/views/nodes/VideoBox.scss
@@ -97,6 +97,7 @@
z-index: 2001;
height: 40px;
padding: 0 10px 0 7px;
+ transition: opacity 0.3s;
.timecode-controls {
display: flex;
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index c8bea2a44..4c6680dcf 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -29,8 +29,8 @@ import { MarqueeAnnotator } from "../MarqueeAnnotator";
import { AnchorMenu } from "../pdf/AnchorMenu";
import { StyleProp } from "../StyleProvider";
import { FieldView, FieldViewProps } from './FieldView';
-import "./VideoBox.scss";
import { RecordingBox } from "./RecordingBox/RecordingBox";
+import "./VideoBox.scss";
const path = require('path');
/**
@@ -104,6 +104,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
@observable _muted: boolean = false;
@observable _controlsTransform?: { X: number, Y: number };
@observable _controlsVisible: boolean = true;
+ @observable _scrubbing: boolean = false;
@computed get links() { return DocListCast(this.dataDoc.links); }
@computed get heightPercent() { return NumCast(this.layoutDoc._timelineHeightPercent, 100); } // current percent of video relative to VideoBox height
@@ -148,14 +149,35 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
}
}
this.player && this.setPlayheadTime(0);
+ document.addEventListener("keydown", this.keyEvents, true);
}
componentWillUnmount() {
this.removeCurrentlyPlaying();
this.Pause();
Object.keys(this._disposers).forEach(d => this._disposers[d]?.());
+ document.removeEventListener("keydown", this.keyEvents, true);
}
+ // handles key events, when timeline scrubs fade controls
+ @action
+ keyEvents = (e: KeyboardEvent) => {
+ if (
+ // need to include range inputs because after dragging time slider it becomes target element
+ !(e.target instanceof HTMLInputElement && !(e.target.type === "range")) &&
+ this.props.isSelected(true)
+ ) {
+ switch (e.key) {
+ case "ArrowLeft":
+ case "ArrowRight":
+ clearTimeout(this._controlsFadeTimer);
+ this._scrubbing = true;
+ this._controlsFadeTimer = setTimeout(action(() => this._scrubbing = false), 500);
+ e.stopPropagation();
+ break;
+ }
+ }
+ }
// plays video
@action public Play = (update: boolean = true) => {
@@ -168,11 +190,11 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
// if presentation isn't null, call followmovements on the recording api
if (this.presentation) {
- console.log("presentation isn't null")
+ // console.log("presentation isn't null")
const err = RecordingApi.Instance.playMovements(this.presentation, this.player?.currentTime || 0, this);
err && console.log(err)
} else {
- console.log("presentation is null")
+ // console.log("presentation is null")
}
this._playing = true;
@@ -262,9 +284,11 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
// fades out controls in fullscreen after mouse stops moving
@action controlsFade = (e: PointerEvent) => {
e.stopPropagation();
- this._controlsVisible = true;
- clearTimeout(this._controlsFadeTimer);
- this._controlsFadeTimer = setTimeout(action(() => this._controlsVisible = false), 3000);
+ if (!this._scrubbing) {
+ clearTimeout(this._controlsFadeTimer);
+ this._controlsVisible = true;
+ this._controlsFadeTimer = setTimeout(action(() => this._controlsVisible = false), 3000);
+ }
}
@@ -447,10 +471,11 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
if (cref) {
cref.onfullscreenchange = action((e) => {
this._fullScreen = (document.fullscreenElement === cref);
+ this._controlsVisible = true;
+ this._scrubbing = false;
+ clearTimeout(this._controlsFadeTimer);
if (this._fullScreen) {
document.addEventListener('pointermove', this.controlsFade);
- this._controlsVisible = true;
- this._controlsFadeTimer = setTimeout(action(() => this._controlsVisible = false), 3000)
}
else {
document.removeEventListener('pointermove', this.controlsFade);
@@ -508,11 +533,12 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
const field = Cast(this.dataDoc[this.fieldKey], VideoField);
const interactive = CurrentUserUtils.ActiveTool !== InkTool.None || !this.props.isSelected() ? "" : "-interactive";
const classname = "videoBox-content" + (this._fullScreen ? "-fullScreen" : "") + interactive;
+ const opacity = this._scrubbing ? 0.5 : (this._controlsVisible ? 1 : 0);
return !field ? <div key="loading">Loading</div> :
<div className="videoBox-contentContainer" key="container" style={{ mixBlendMode: "multiply", cursor: this._fullScreen && !this._controlsVisible ? 'none' : 'pointer' }}>
<div className={classname} ref={this.setContentRef} onPointerDown={(e) => this._fullScreen && e.stopPropagation()}>
{this._fullScreen && <div className="videoBox-ui" onPointerDown={this.controlsDrag}
- style={{ left: this._controlsTransform && this._controlsTransform.X, top: this._controlsTransform && this._controlsTransform.Y, visibility: this._controlsVisible ? 'visible' : 'hidden', opacity: this._controlsVisible ? 1 : 0 }}>
+ style={{ left: this._controlsTransform && this._controlsTransform.X, top: this._controlsTransform && this._controlsTransform.Y, visibility: this._controlsVisible || this._scrubbing ? 'visible' : 'hidden', opacity: opacity }}>
{this.UIButtons}
</div>}
<video key="video" autoPlay={this._screenCapture} ref={this.setVideoRef} style={this._fullScreen ? this.fullScreenSize() : {}}
@@ -836,8 +862,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
const vidHeight = height * this.heightPercent / 100;
const yPos = top + vidHeight - uiHeight - uiMargin;
const xPos = uiHeight / vidHeight > 0.4 ? right + 10 : left + 10;
+ const opacity = this._scrubbing ? 0.5 : (this._controlsVisible ? 1 : 0);
return this._fullScreen || (right - left) < 50 ? null : <div className="videoBox-ui-wrapper" style={{ clip: `rect(${boundsTop}px, 10000px, 10000px, ${boundsLeft}px)` }}>
- <div className="videoBox-ui" style={{ left: xPos, top: yPos, height: uiHeight, width: width - 20, transition: this._clicking ? "top 0.5s" : "" }}>
+ <div className="videoBox-ui" style={{ left: xPos, top: yPos, height: uiHeight, width: width - 20, transition: this._clicking ? "top 0.5s" : "", opacity: opacity}}>
{this.UIButtons}
</div>
</div>
@@ -863,8 +890,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
<div className="timeline-slider">
<input type="range" step="0.1" min={this.timeline.clipStart} max={this.timeline.clipEnd} value={curTime}
className="toolbar-slider time-progress"
- onPointerDown={(e: React.PointerEvent) => { e.stopPropagation(); }}
+ onPointerDown={action((e: React.PointerEvent) => { e.stopPropagation(); this._scrubbing = true;})}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => this.setPlayheadTime(Number(e.target.value))}
+ onPointerUp={action((e: React.PointerEvent) => {e.stopPropagation(); this._scrubbing = false;})}
/>
</div>
: