From e474d02cf51c5e20e42baa6b7d9c4aeb4ab51967 Mon Sep 17 00:00:00 2001 From: mehekj Date: Sat, 12 Mar 2022 16:40:40 -0500 Subject: video ui in progress, basic functions show up --- .../collections/CollectionStackedTimeline.tsx | 20 +-- .../collectionLinear/CollectionLinearView.tsx | 6 +- src/client/views/nodes/AudioBox.tsx | 7 +- src/client/views/nodes/VideoBox.scss | 90 ++++++++++- src/client/views/nodes/VideoBox.tsx | 172 ++++++++++++++++----- 5 files changed, 231 insertions(+), 64 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 25f2e0b25..dca5089f4 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -4,7 +4,7 @@ import { computed, IReactionDisposer, observable, - reaction, + reaction } from "mobx"; import { observer } from "mobx-react"; import { computedFn } from "mobx-utils"; @@ -19,35 +19,29 @@ import { formatTime, OmitKeys, returnFalse, - returnOne, - setupMoveUpEvents, - StopEvent, - returnTrue, - smoothScroll, - smoothScrollHorizontal, + returnOne, returnTrue, setupMoveUpEvents, smoothScrollHorizontal, StopEvent } from "../../../Utils"; import { Docs } from "../../documents/Documents"; +import { DocumentManager } from "../../util/DocumentManager"; +import { DragManager } from "../../util/DragManager"; import { LinkManager } from "../../util/LinkManager"; import { Scripting } from "../../util/Scripting"; import { SelectionManager } from "../../util/SelectionManager"; +import { SnappingManager } from "../../util/SnappingManager"; import { Transform } from "../../util/Transform"; import { undoBatch, UndoManager } from "../../util/UndoManager"; import { AudioWaveform } from "../AudioWaveform"; import { CollectionSubView } from "../collections/CollectionSubView"; +import { Colors } from "../global/globalEnums"; import { LightboxView } from "../LightboxView"; import { DocAfterFocusFunc, DocFocusFunc, DocumentView, - DocumentViewProps, + DocumentViewProps } from "../nodes/DocumentView"; import { LabelBox } from "../nodes/LabelBox"; import "./CollectionStackedTimeline.scss"; -import { Colors } from "../global/globalEnums"; -import { DocumentManager } from "../../util/DocumentManager"; -import { SnappingManager } from "../../util/SnappingManager"; -import { DragManager } from "../../util/DragManager"; -import { faBreadSlice } from "@fortawesome/free-solid-svg-icons"; type PanZoomDocument = makeInterface<[]>; const PanZoomDocument = makeInterface(); diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx index 4198a7979..77eed8bfc 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx @@ -3,13 +3,14 @@ import { Tooltip } from '@material-ui/core'; import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Doc, HeightSym, Opt, WidthSym, DataSym } from '../../../../fields/Doc'; +import { Doc, HeightSym, Opt, WidthSym } from '../../../../fields/Doc'; import { documentSchema } from '../../../../fields/documentSchemas'; import { Id } from '../../../../fields/FieldSymbols'; import { makeInterface } from '../../../../fields/Schema'; import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; -import { emptyFunction, returnEmptyDoclist, returnTrue, returnFalse, OmitKeys, Utils } from '../../../../Utils'; +import { emptyFunction, returnEmptyDoclist, returnTrue, Utils } from '../../../../Utils'; import { DocUtils } from '../../../documents/Documents'; +import { DocumentManager } from "../../../util/DocumentManager"; import { DragManager } from '../../../util/DragManager'; import { Transform } from '../../../util/Transform'; import { Colors, Shadows } from '../../global/globalEnums'; @@ -20,7 +21,6 @@ import { LinkDescriptionPopup } from '../../nodes/LinkDescriptionPopup'; import { StyleProp } from '../../StyleProvider'; import { CollectionSubView } from '../CollectionSubView'; import { CollectionViewType } from '../CollectionView'; -import { DocumentManager } from "../../../util/DocumentManager"; import "./CollectionLinearView.scss"; diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index c33a74325..b9046b61e 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -421,6 +421,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent { if (this._ele) { + if (this._muted) { + this._muted = false; + } this._volume = volume; this._ele.volume = volume; } @@ -503,10 +506,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent - + { e.stopPropagation(); }} onChange={(e: React.ChangeEvent) => { this.setVolume(Number(e.target.value)) }} /> diff --git a/src/client/views/nodes/VideoBox.scss b/src/client/views/nodes/VideoBox.scss index 8a3261c7d..35f5a7e65 100644 --- a/src/client/views/nodes/VideoBox.scss +++ b/src/client/views/nodes/VideoBox.scss @@ -78,10 +78,49 @@ .videoBox-ui { position: absolute; flex-direction: row; - right: 5px; - top: 5px; - display: none; - background-color: rgba($dark-gray, 0.6); + align-items: center; + justify-content: center; + display: flex; + visibility: none; + opacity: 0; + background-color: $dark-gray; + color: white; + border-radius: 100px; + left: 50%; + transform: translate(-50%, -150%); + transition: top 0.5s, opacity 0.2s, visibility 0s; + height: 5%; + width: 80%; + + .timecode-controls { + display: flex; + flex-direction: row; + margin: 0 5px; + + .timecode { + margin: 0 5px; + } + } + + .videobox-button { + margin: 5px; + cursor: pointer; + width: 30px; + height: 30px; + border-radius: 50%; + background: $dark-gray; + display: flex; + align-items: center; + justify-content: center; + + &:hover { + background: $black; + } + + svg { + width: 20px; + } + } } .videoBox-time, .videoBox-snapshot, @@ -101,6 +140,47 @@ .videoBox:hover { .videoBox-ui { - display: flex; + visibility: visible; + opacity: 1; + z-index: 10000; } } + +video::-webkit-media-controls { + display: none !important; +} + +input[type="range"] { + -webkit-appearance: none; + background: none; + margin: 5px; +} + +input[type="range"]:focus { + outline: none; +} + +input[type="range"]::-webkit-slider-runnable-track { + width: 100%; + height: 6px; + cursor: pointer; + box-shadow: 0; + background: $light-gray; + border-radius: 3px; +} + +input[type="range"]::-webkit-slider-thumb { + box-shadow: 0; + border: 0; + height: 10px; + width: 10px; + border-radius: 10px; + background: $medium-blue; + cursor: pointer; + -webkit-appearance: none; + margin-top: -2px; +} + +.toolbar-slider.volume { + width: 50px; +} \ No newline at end of file diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index d56363348..bd9423d74 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -59,6 +59,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent { - this._fullScreen = true; - this.player && this.player.requestFullscreen(); + if (document.fullscreenElement == this._contentRef) { + this._fullScreen = false; + this.player && this._contentRef && document.exitFullscreen(); + } + else { + this._fullScreen = true; + this.player && this._contentRef && this._contentRef.requestFullscreen(); + } try { this._youtubePlayer && this.props.addDocTab(this.rootDoc, "add"); } catch (e) { @@ -269,13 +278,21 @@ export class VideoBox extends ViewBoxAnnotatableComponent this._fullScreen = vref.webkitDisplayingFullscreen); + // vref.onfullscreenchange = action((e) => this._fullScreen = vref.webkitDisplayingFullscreen); this._disposers.reactionDisposer?.(); this._disposers.reactionDisposer = reaction(() => (this.layoutDoc._currentTimecode || 0), time => !this._playing && (vref.currentTime = time), { fireImmediately: true }); } } + @action + setContentRef = (cref: HTMLDivElement | null) => { + this._contentRef = cref; + if (cref) { + cref.onfullscreenchange = action((e) => this._fullScreen = (document.fullscreenElement == cref)); + } + } + specificContextMenu = (e: React.MouseEvent): void => { const field = Cast(this.dataDoc[this.props.fieldKey], VideoField); if (field) { @@ -292,10 +309,10 @@ export class VideoBox extends ViewBoxAnnotatableComponent this.layoutDoc.dontAutoFollowLinks = !this.layoutDoc.dontAutoFollowLinks, icon: "expand-arrows-alt" }); subitems.push({ description: (this.layoutDoc.dontAutoPlayFollowedLinks ? "" : "Don't") + " play when link is selected", event: () => this.layoutDoc.dontAutoPlayFollowedLinks = !this.layoutDoc.dontAutoPlayFollowedLinks, icon: "expand-arrows-alt" }); subitems.push({ description: (this.layoutDoc.autoPlayAnchors ? "Don't auto play" : "Auto play") + " anchors onClick", event: () => this.layoutDoc.autoPlayAnchors = !this.layoutDoc.autoPlayAnchors, icon: "expand-arrows-alt" }); - subitems.push({ description: "Toggle Native Controls", event: action(() => VideoBox._nativeControls = !VideoBox._nativeControls), icon: "expand-arrows-alt" }); - subitems.push({ description: "Start Trim All", event: () => this.startTrim(TrimScope.All), icon: "expand-arrows-alt" }); - subitems.push({ description: "Start Trim Clip", event: () => this.startTrim(TrimScope.Clip), icon: "expand-arrows-alt" }); - subitems.push({ description: "Stop Trim", event: () => this.finishTrim(), icon: "expand-arrows-alt" }); + // subitems.push({ description: "Toggle Native Controls", event: action(() => VideoBox._nativeControls = !VideoBox._nativeControls), icon: "expand-arrows-alt" }); + // subitems.push({ description: "Start Trim All", event: () => this.startTrim(TrimScope.All), icon: "expand-arrows-alt" }); + // subitems.push({ description: "Start Trim Clip", event: () => this.startTrim(TrimScope.Clip), icon: "expand-arrows-alt" }); + // subitems.push({ description: "Stop Trim", event: () => this.finishTrim(), icon: "expand-arrows-alt" }); subitems.push({ description: "Copy path", event: () => { Utils.CopyText(url); }, icon: "expand-arrows-alt" }); ContextMenu.Instance.addItem({ description: "Options...", subitems: subitems, icon: "video" }); } @@ -309,7 +326,8 @@ export class VideoBox extends ViewBoxAnnotatableComponentLoading :
-
+
+ {this.uIButtons}
} key="play" placement="bottom"> -
- -
- , - {"timecode"}
} key="time" placement="bottom"> -
- {formatTime(curTime)} - {" " + Math.floor((curTime - Math.trunc(curTime)) * 100).toString().padStart(2, "0")} -
- , - {"view full screen"}
} key="full" placement="bottom"> -
- -
- ]; - return
- {[...(VideoBox._nativeControls ? [] : nonNativeControls), - {"snapshot current frame"}
} key="snap" placement="bottom"> -
- + // const nonNativeControls = [ + // {"playback"}
} key="play" placement="bottom"> + //
+ // + //
+ // , + // {"timecode"}} key="time" placement="bottom"> + //
+ // {formatTime(curTime)} + // {" " + Math.floor((curTime - Math.trunc(curTime)) * 100).toString().padStart(2, "0")} + //
+ //
, + // {"view full screen"}} key="full" placement="bottom"> + //
+ // + //
+ //
]; + // return
+ // {[...(VideoBox._nativeControls ? [] : nonNativeControls), + // {"snapshot current frame"}
} key="snap" placement="bottom"> + //
+ // + //
+ // , + // {"show annotation timeline"}} key="timeline" placement="bottom"> + //
+ // + //
+ //
, + // {this.timeline?.IsTrimming !== TrimScope.None ? "finish trimming" : "start trim"}} key="trim" placement="bottom"> + //
+ // + //
+ //
,]} + // ; + return
+
+ +
+ + {this.timeline &&
+
+ {formatTime(curTime)}
- , - {"show annotation timeline"}
} key="timeline" placement="bottom"> -
- + +
+ { e.stopPropagation(); }} + onChange={(e: React.ChangeEvent) => { this.setPlayheadTime(Number(e.target.value)) }} + />
- , - {this.timeline?.IsTrimming !== TrimScope.None ? "finish trimming" : "start trim"}
} key="trim" placement="bottom"> -
- + +
+ {formatTime(this.timeline.clipDuration)}
- ,]} -
; +
} + +
+ +
+ + {!this._fullScreen &&
+ +
} + + {!this._fullScreen &&
+ +
} + +
+ +
+ { e.stopPropagation(); }} + onChange={(e: React.ChangeEvent) => { this.setVolume(Number(e.target.value)) }} + /> + } @computed get renderTimeline() { return
@@ -653,7 +744,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent} {this.renderTimeline} - {this.uIButtons}
); } -- cgit v1.2.3-70-g09d2