diff options
author | Bob Zeleznik <zzzman@gmail.com> | 2019-03-13 20:33:51 -0400 |
---|---|---|
committer | Bob Zeleznik <zzzman@gmail.com> | 2019-03-13 20:33:51 -0400 |
commit | 41f458fb4f383bfbf8d5b651189c2f4731262ff8 (patch) | |
tree | 9317e63ddb81b38e7bcbd2de8c551b7c71211103 | |
parent | b8c0dc61d535caeb2142678dffea2a841776e3a8 (diff) |
added annotations for videos. added custom play controls for videos.
-rw-r--r-- | src/client/documents/Documents.ts | 5 | ||||
-rw-r--r-- | src/client/views/InkingCanvas.tsx | 6 | ||||
-rw-r--r-- | src/client/views/collections/CollectionFreeFormView.tsx | 8 | ||||
-rw-r--r-- | src/client/views/collections/CollectionPDFView.tsx | 13 | ||||
-rw-r--r-- | src/client/views/collections/CollectionVideoView.scss | 35 | ||||
-rw-r--r-- | src/client/views/collections/CollectionVideoView.tsx | 83 | ||||
-rw-r--r-- | src/client/views/collections/CollectionView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/PDFBox.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/VideoBox.tsx | 2 | ||||
-rw-r--r-- | src/fields/KeyStore.ts | 1 |
10 files changed, 126 insertions, 31 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f35d553b1..15e16a491 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -23,6 +23,7 @@ import { PDFField } from "../../fields/PDFField"; import { PDFBox } from "../views/nodes/PDFBox"; import { CollectionPDFView } from "../views/collections/CollectionPDFView"; import { RichTextField } from "../../fields/RichTextField"; +import { CollectionVideoView } from "../views/collections/CollectionVideoView"; export interface DocumentOptions { x?: number; @@ -138,9 +139,9 @@ export namespace Documents { } function GetVideoPrototype(): Document { if (!videoProto) { - videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionView.LayoutString("AnnotationsKey"), + videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionVideoView.LayoutString("AnnotationsKey"), { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] }); - videoProto.SetNumber(KeyStore.CurFrame, 1); + videoProto.SetNumber(KeyStore.CurPage, 0); videoProto.SetText(KeyStore.BackgroundLayout, VideoBox.LayoutString()); } return videoProto; diff --git a/src/client/views/InkingCanvas.tsx b/src/client/views/InkingCanvas.tsx index 0d87c1239..064d1cba2 100644 --- a/src/client/views/InkingCanvas.tsx +++ b/src/client/views/InkingCanvas.tsx @@ -74,7 +74,7 @@ export class InkingCanvas extends React.Component<InkCanvasProps> { color: InkingControl.Instance.selectedColor, width: InkingControl.Instance.selectedWidth, tool: InkingControl.Instance.selectedTool, - page: this.props.Document.GetNumber(KeyStore.CurPage, 0) + page: this.props.Document.GetNumber(KeyStore.CurPage, -1) }); this.inkData = data; this._isDrawing = true; @@ -145,11 +145,11 @@ export class InkingCanvas extends React.Component<InkCanvasProps> { // parse data from server let paths: Array<JSX.Element> = [] - let curPage = this.props.Document.GetNumber(KeyStore.CurPage, 0) + let curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1) Array.from(lines).map(item => { let id = item[0]; let strokeData = item[1]; - if (strokeData.page == 0 || strokeData.page == curPage) + if (strokeData.page == -1 || strokeData.page == curPage) paths.push(<InkingStroke key={id} id={id} line={strokeData.pathData} color={strokeData.color} diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 71f429e80..08f3a338b 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -52,13 +52,13 @@ export class CollectionFreeFormView extends CollectionViewBase { } public getActiveDocuments = () => { - var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1); + var curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1); const lvalue = this.props.Document.GetT<ListField<Document>>(this.props.fieldKey, ListField); let active: Document[] = []; if (lvalue && lvalue != FieldWaiting) { lvalue.Data.map(doc => { - var page = doc.GetNumber(KeyStore.Page, 0); - if (page == curPage || page == 0) { + var page = doc.GetNumber(KeyStore.Page, -1); + if (page == curPage || page == -1) { active.push(doc); } }) @@ -257,7 +257,7 @@ export class CollectionFreeFormView extends CollectionViewBase { @computed get views() { - var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1); + var curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1); const lvalue = this.props.Document.GetT<ListField<Document>>(this.props.fieldKey, ListField); if (lvalue && lvalue != FieldWaiting) { return lvalue.Data.map(doc => { diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx index f22c07060..91ffc9500 100644 --- a/src/client/views/collections/CollectionPDFView.tsx +++ b/src/client/views/collections/CollectionPDFView.tsx @@ -18,13 +18,12 @@ export class CollectionPDFView extends React.Component<CollectionViewProps> { isTopMost={isTopMost} SelectOnLoad={selectOnLoad} BackgroundView={BackgroundView} focus={focus}/>`; } - public SelectedDocs: FieldId[] = [] - @action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : 0; - @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : 0; + private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, -1); } + private get numPages() { return this.props.Document.GetNumber(KeyStore.NumPages, 0); } + @action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : -1; + @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : -1; - @computed private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, 0); } - @computed private get numPages() { return this.props.Document.GetNumber(KeyStore.NumPages, 0); } - @computed private get uIButtons() { + private get uIButtons() { return ( <div className="pdfBox-buttonTray" key="tray"> <button className="pdfButton" onClick={this.onPageBack}>{"<"}</button> @@ -33,7 +32,7 @@ export class CollectionPDFView extends React.Component<CollectionViewProps> { } // "inherited" CollectionView API starts here... - + public SelectedDocs: FieldId[] = [] public active: () => boolean = () => CollectionView.Active(this); addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); } diff --git a/src/client/views/collections/CollectionVideoView.scss b/src/client/views/collections/CollectionVideoView.scss new file mode 100644 index 000000000..6c2f5a62a --- /dev/null +++ b/src/client/views/collections/CollectionVideoView.scss @@ -0,0 +1,35 @@ +.collectionVideoView-controls{ + width: 100%; + height: 100%; + position: absolute; +} +.collectionVideoView-time{ + color : white; + top :25px; + left : 25px; + position: absolute; + background-color: rgba(50, 50, 50, 0.2); +} +.collectionVideoView-play { + width: 25px; + height: 20px; + bottom: 25px; + left : 25px; + position: absolute; + color : white; + background-color: rgba(50, 50, 50, 0.2); + border-radius: 4px; + text-align: center; +} +.collectionVideoView-full { + width: 25px; + height: 20px; + bottom: 25px; + right : 25px; + position: absolute; + color : white; + background-color: rgba(50, 50, 50, 0.2); + border-radius: 4px; + text-align: center; + +}
\ No newline at end of file diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx index a6471f53c..058325b21 100644 --- a/src/client/views/collections/CollectionVideoView.tsx +++ b/src/client/views/collections/CollectionVideoView.tsx @@ -1,4 +1,4 @@ -import { action, computed } from "mobx"; +import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import { Document } from "../../../fields/Document"; import { KeyStore } from "../../../fields/KeyStore"; @@ -7,6 +7,8 @@ import { CollectionView, CollectionViewType } from "./CollectionView"; import { CollectionViewProps } from "./CollectionViewBase"; import React = require("react"); import { FieldId } from "../../../fields/Field"; +import { ReplaceAroundStep } from "prosemirror-transform"; +import "./CollectionVideoView.scss" @observer @@ -18,14 +20,10 @@ export class CollectionVideoView extends React.Component<CollectionViewProps> { isTopMost={isTopMost} SelectOnLoad={selectOnLoad} BackgroundView={BackgroundView} focus={focus}/>`; } - public SelectedDocs: FieldId[] = [] - @action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : 0; - @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : 0; - - @computed private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, 0); } - @computed private get numPages() { return this.props.Document.GetNumber(KeyStore.NumPages, 0); } + private _mainCont = React.createRef<HTMLDivElement>(); // "inherited" CollectionView API starts here... + public SelectedDocs: FieldId[] = [] public active: () => boolean = () => CollectionView.Active(this); addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); } @@ -40,11 +38,74 @@ export class CollectionVideoView extends React.Component<CollectionViewProps> { get collectionViewType(): CollectionViewType { return CollectionViewType.Freeform; } get subView(): any { return CollectionView.SubView(this); } + componentDidMount() { + this.repete(); + } + + player = (): HTMLVideoElement => { + return this._mainCont.current!.getElementsByTagName("video")[0]; + } + + @action + repete = () => { + if (this.player()) { + this.ctime = this.player().currentTime; + this.props.Document.SetNumber(KeyStore.CurPage, Math.round(this.ctime)); + } + setTimeout(() => this.repete(), 100) + } + + + @observable + ctime: number = 0 + @observable + playing: boolean = false; + + @action + onPlayDown = () => { + if (this.player()) { + if (this.player().paused) { + this.player().play(); + this.playing = true; + } else { + this.player().pause(); + this.playing = false; + } + } + } + @action + onFullDown = (e: React.PointerEvent) => { + if (this.player()) { + this.player().requestFullscreen(); + e.stopPropagation(); + e.preventDefault(); + } + } + + @action + onResetDown = () => { + if (this.player()) { + this.player().pause(); + this.player().currentTime = 0; + } + + } + render() { - return (<div className="collectionView-cont" onContextMenu={this.specificContextMenu}> - {/* <video controls className="videobox-cont"> */} - {this.subView} - {/* </video> */} + return (<div className="collectionVideoView-cont" ref={this._mainCont} onContextMenu={this.specificContextMenu}> + <div className="collectionVideoView-controls" > + {this.subView} + <div className="collectionVideoView-time" onPointerDown={this.onResetDown}> + <span>{"" + Math.round(this.ctime)}</span> + <span style={{ fontSize: 8 }}>{" " + Math.round((this.ctime - Math.trunc(this.ctime)) * 100)}</span> + </div> + <div className="collectionVideoView-play" onPointerDown={this.onPlayDown}> + {this.playing ? "\"" : ">"} + </div> + <div className="collectionVideoView-full" onPointerDown={this.onFullDown}> + F + </div> + </div> </div>) } }
\ No newline at end of file diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 17a0fbd23..bbb4a5d83 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -50,7 +50,7 @@ export class CollectionView extends React.Component<CollectionViewProps> { @action public static AddDocument(props: CollectionViewProps, doc: Document) { - doc.SetNumber(KeyStore.Page, props.Document.GetNumber(KeyStore.CurPage, 0)); + doc.SetNumber(KeyStore.Page, props.Document.GetNumber(KeyStore.CurPage, -1)); if (props.Document.Get(props.fieldKey) instanceof Field) { //TODO This won't create the field if it doesn't already exist const value = props.Document.GetData(props.fieldKey, ListField, new Array<Document>()) diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 544af41a2..b0b5a63a4 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -86,7 +86,7 @@ export class PDFBox extends React.Component<FieldViewProps> { @observable private _interactive: boolean = false; @observable private _loaded: boolean = false; - @computed private get curPage() { return this.props.doc.GetNumber(KeyStore.CurPage, 0); } + @computed private get curPage() { return this.props.doc.GetNumber(KeyStore.CurPage, -1); } componentDidMount() { this._reactionDisposer = reaction( diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 9c60d4348..053d9dd56 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -51,7 +51,7 @@ export class VideoBox extends React.Component<FieldViewProps> { <div style={{ width: "100%", height: "Auto" }} > <Measure onResize={this.setScaling}> {({ measureRef }) => - <video controls className="videobox-cont" ref={measureRef}> + <video className="videobox-cont" ref={measureRef}> <source src={path} type="video/mp4" /> Not supported. </video> diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index 6481e14fe..f93a68c85 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -33,7 +33,6 @@ export namespace KeyStore { export const LinkTags = new Key("LinkTag"); export const Thumbnail = new Key("Thumbnail"); export const CurPage = new Key("CurPage"); - export const CurFrame = new Key("CurFrame"); export const NumPages = new Key("NumPages"); export const Ink = new Key("Ink"); } |