diff options
author | bob <bcz@cs.brown.edu> | 2019-05-01 10:51:17 -0400 |
---|---|---|
committer | bob <bcz@cs.brown.edu> | 2019-05-01 10:51:17 -0400 |
commit | 105ba2402ad0da59d3d0750fa045a0f47eb73848 (patch) | |
tree | c458b14686bc40d0b49e26c4f4fd7521436022d9 /src | |
parent | 8f9baace2a0fd25e8a1cbdbb153cee1f286ad8e3 (diff) |
cleaned up videos a bit.
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/collections/CollectionVideoView.tsx | 90 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 4 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 5 | ||||
-rw-r--r-- | src/client/views/nodes/FieldView.tsx | 1 | ||||
-rw-r--r-- | src/client/views/nodes/VideoBox.tsx | 37 |
5 files changed, 55 insertions, 82 deletions
diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx index 7232ecea2..9dee217cb 100644 --- a/src/client/views/collections/CollectionVideoView.tsx +++ b/src/client/views/collections/CollectionVideoView.tsx @@ -7,17 +7,16 @@ import "./CollectionVideoView.scss"; import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormView"; import { FieldView, FieldViewProps } from "../nodes/FieldView"; import { emptyFunction } from "../../../Utils"; -import { NumCast } from "../../../new_fields/Types"; import { Id } from "../../../new_fields/RefField"; +import { VideoBox } from "../nodes/VideoBox"; @observer export class CollectionVideoView extends React.Component<FieldViewProps> { - private _intervalTimer: any = undefined; - private _player: HTMLVideoElement | undefined = undefined; + private _videoBox: VideoBox | undefined = undefined; + @observable _playTimer?: NodeJS.Timeout = undefined; @observable _currentTimecode: number = 0; - @observable _isPlaying: boolean = false; public static LayoutString(fieldKey: string = "data") { return FieldView.LayoutString(CollectionVideoView, fieldKey); @@ -30,7 +29,7 @@ export class CollectionVideoView extends React.Component<FieldViewProps> { <span style={{ fontSize: 8 }}>{" " + Math.round((this._currentTimecode - Math.trunc(this._currentTimecode)) * 100)}</span> </div>, <div className="collectionVideoView-play" key="play" onPointerDown={this.onPlayDown} style={{ transform: `scale(${scaling}, ${scaling})` }}> - {this._isPlaying ? "\"" : ">"} + {this._playTimer ? "\"" : ">"} </div>, <div className="collectionVideoView-full" key="full" onPointerDown={this.onFullDown} style={{ transform: `scale(${scaling}, ${scaling})` }}> F @@ -38,61 +37,37 @@ export class CollectionVideoView extends React.Component<FieldViewProps> { ]); } - _ele: HTMLDivElement | null = null; @action - mainCont = (ele: HTMLDivElement | null) => { - this._ele = ele; - if (ele) { - this._player = ele.getElementsByTagName("video")[0]; - console.log(this._player); - const curPage = NumCast(this.props.Document.curPage, -1); - if (curPage >= 0) { - this._currentTimecode = curPage; - } + updateTimecode = () => { + if (this._videoBox && this._videoBox.player) { + this._currentTimecode = this._videoBox.player.currentTime; + this.props.Document.curPage = Math.round(this._currentTimecode); } } - componentDidMount() { - this._intervalTimer = setInterval(this.updateTimecode, 1000); - } + componentDidMount() { this.updateTimecode(); } - componentWillUnmount() { - clearInterval(this._intervalTimer); - } - - @action - updateTimecode = () => { - this._player = this._player ? this._player : this._ele ? this._ele.getElementsByTagName("video")[0] : undefined; - if (this._player) { - let timecode = (this._player as any).hasOwnProperty("AHackBecauseSomethingResetsTheVideoToZero") ? - (this._player as any).AHackBecauseSomethingResetsTheVideoToZero : -1; - if (timecode !== -1 && Object) { - this._player.currentTime = timecode; - (this._player as any).AHackBecauseSomethingResetsTheVideoToZero = -1; - } else { - this._currentTimecode = this._player.currentTime; - this.props.Document.curPage = Math.round(this._currentTimecode); - } - } - } + componentWillUnmount() { if (this._playTimer) clearInterval(this._playTimer); } @action onPlayDown = () => { - if (this._player) { - if (this._player.paused) { - this._player.play(); - this._isPlaying = true; + if (this._videoBox && this._videoBox.player) { + if (this._videoBox.player.paused) { + this._videoBox.player.play(); + if (!this._playTimer) this._playTimer = setInterval(this.updateTimecode, 1000); } else { - this._player.pause(); - this._isPlaying = false; + this._videoBox.player.pause(); + if (this._playTimer) clearInterval(this._playTimer); + this._playTimer = undefined; + } } } @action onFullDown = (e: React.PointerEvent) => { - if (this._player) { - this._player.requestFullscreen(); + if (this._videoBox && this._videoBox.player) { + this._videoBox.player.requestFullscreen(); e.stopPropagation(); e.preventDefault(); } @@ -100,11 +75,13 @@ export class CollectionVideoView extends React.Component<FieldViewProps> { @action onResetDown = () => { - if (this._player) { - this._player.pause(); - this._player.currentTime = 0; + if (this._videoBox && this._videoBox.player) { + this._videoBox.player.pause(); + this._videoBox.player.currentTime = 0; + if (this._playTimer) clearInterval(this._playTimer); + this._playTimer = undefined; + this.updateTimecode(); } - } onContextMenu = (e: React.MouseEvent): void => { @@ -113,20 +90,19 @@ export class CollectionVideoView extends React.Component<FieldViewProps> { } } + setVideoBox = (player: VideoBox) => { this._videoBox = player; } + private subView = (_type: CollectionViewType, renderProps: CollectionRenderProps) => { let props = { ...this.props, ...renderProps }; - return ( - <> - <CollectionFreeFormView {...props} CollectionView={this} /> - {this.props.isSelected() ? this.uIButtons : (null)} - </> - ); + return (<> + <CollectionFreeFormView {...props} setVideoBox={this.setVideoBox} CollectionView={this} /> + {this.props.isSelected() ? this.uIButtons : (null)} + </>); } render() { - trace(); return ( - <CollectionBaseView {...this.props} className="collectionVideoView-cont" contentRef={this.mainCont} onContextMenu={this.onContextMenu}> + <CollectionBaseView {...this.props} className="collectionVideoView-cont" onContextMenu={this.onContextMenu}> {this.subView} </CollectionBaseView>); } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 4b759b948..54b721f7b 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -71,7 +71,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { public getActiveDocuments = () => { const curPage = FieldValue(this.Document.curPage, -1); return FieldValue(this.children, [] as Doc[]).filter(doc => { - var page = Cast(doc.page, "number", -1); + var page = NumCast(doc.page, -1); return page === curPage || page === -1; }); } @@ -274,7 +274,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { let curPage = FieldValue(this.Document.curPage, -1); let docviews = (this.children || []).filter(doc => doc).reduce((prev, doc) => { if (!FieldValue(doc)) return prev; - var page = Cast(doc.page, "number", -1); + var page = NumCast(doc.page, -1); if (page === curPage || page === -1) { let minim = Cast(doc.isMinimized, "boolean"); if (minim === undefined || !minim) { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index cda9f9473..f58dc4a02 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -18,12 +18,11 @@ import "./DocumentView.scss"; import React = require("react"); import { Opt, Doc } from "../../../new_fields/Doc"; import { DocComponent } from "../DocComponent"; -import { createSchema, makeInterface, listSpec } from "../../../new_fields/Schema"; -import { FieldValue, Cast, PromiseValue, StrCast } from "../../../new_fields/Types"; +import { createSchema, makeInterface } from "../../../new_fields/Schema"; +import { FieldValue, StrCast } from "../../../new_fields/Types"; import { List } from "../../../new_fields/List"; import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; -import { MarqueeView } from "../collections/collectionFreeForm/MarqueeView"; import { DocServer } from "../../DocServer"; import { Id } from "../../../new_fields/RefField"; diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index c04b91c21..63009f2db 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -41,6 +41,7 @@ export interface FieldViewProps { focus: (doc: Doc) => void; PanelWidth: () => number; PanelHeight: () => number; + setVideoBox?: (player: VideoBox) => void; } @observer diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 184a89dbc..422508f90 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -2,15 +2,16 @@ import React = require("react"); import { observer } from "mobx-react"; import { FieldView, FieldViewProps } from './FieldView'; import "./VideoBox.scss"; -import { action, computed } from "mobx"; +import { action, computed, trace } from "mobx"; import { DocComponent } from "../DocComponent"; import { positionSchema } from "./DocumentView"; import { makeInterface } from "../../../new_fields/Schema"; import { pageSchema } from "./ImageBox"; -import { Cast, FieldValue, NumCast } from "../../../new_fields/Types"; +import { Cast, FieldValue, NumCast, ToConstructor, ListSpec } from "../../../new_fields/Types"; import { VideoField } from "../../../new_fields/URLField"; import Measure from "react-measure"; import "./VideoBox.scss"; +import { Field, FieldResult, Opt } from "../../../new_fields/Doc"; type VideoDocument = makeInterface<[typeof positionSchema, typeof pageSchema]>; const VideoDocument = makeInterface(positionSchema, pageSchema); @@ -18,24 +19,20 @@ const VideoDocument = makeInterface(positionSchema, pageSchema); @observer export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoDocument) { - private _videoRef = React.createRef<HTMLVideoElement>(); + private _videoRef: HTMLVideoElement | null = null; + private _loaded: boolean = false; + private get initialTimecode() { return FieldValue(this.Document.curPage, -1); } public static LayoutString() { return FieldView.LayoutString(VideoBox); } - constructor(props: FieldViewProps) { - super(props); + public get player(): HTMLVideoElement | undefined { + if (this._videoRef) { + return this._videoRef; + } } - - @computed private get curPage() { return FieldValue(this.Document.curPage, -1); } - - - _loaded: boolean = false; - @action setScaling = (r: any) => { if (this._loaded) { // bcz: the nativeHeight should really be set when the document is imported. - // also, the native dimensions could be different for different pages of the PDF - // so this design is flawed. var nativeWidth = FieldValue(this.Document.nativeWidth, 0); var nativeHeight = FieldValue(this.Document.nativeHeight, 0); var newNativeHeight = nativeWidth * r.entry.height / r.entry.width; @@ -48,26 +45,26 @@ export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoD } } - get player(): HTMLVideoElement | undefined { - return this._videoRef.current ? this._videoRef.current.getElementsByTagName("video")[0] : undefined; + componentDidMount() { + if (this.props.setVideoBox) this.props.setVideoBox(this); } @action setVideoRef = (vref: HTMLVideoElement | null) => { - if (this.curPage >= 0 && vref) { - vref.currentTime = this.curPage; - (vref as any).AHackBecauseSomethingResetsTheVideoToZero = this.curPage; + this._videoRef = vref; + if (this.initialTimecode >= 0 && vref) { + vref.currentTime = this.initialTimecode; } } videoContent(path: string) { return <video className="videobox-cont" ref={this.setVideoRef}> <source src={path} type="video/mp4" /> Not supported. - </video>; + </video>; } render() { - let field = FieldValue(Cast(this.Document[this.props.fieldKey], VideoField)); + let field = Cast(this.Document[this.props.fieldKey], VideoField); if (!field) { return <div>Loading</div>; } |