From 7db0071a1f1232112597176b0b077e6b7e37679d Mon Sep 17 00:00:00 2001 From: Eleanor Eng Date: Mon, 18 Mar 2019 19:00:13 -0400 Subject: Added icons --- src/client/views/collections/CollectionView.tsx | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 548a51bf1..b76426429 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -13,6 +13,17 @@ import { CollectionSchemaView } from "./CollectionSchemaView"; import { CollectionViewProps } from "./CollectionViewBase"; import { CollectionTreeView } from "./CollectionTreeView"; import { Field, FieldId } from "../../../fields/Field"; +import { library } from '@fortawesome/fontawesome-svg-core'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faTh } from '@fortawesome/free-solid-svg-icons'; +import { faTree } from '@fortawesome/free-solid-svg-icons'; +import { faSquare } from '@fortawesome/free-solid-svg-icons'; +import { faProjectDiagram } from '@fortawesome/free-solid-svg-icons'; + +library.add(faTh); +library.add(faTree); +library.add(faSquare); +library.add(faProjectDiagram); export enum CollectionViewType { Invalid, @@ -96,10 +107,10 @@ export class CollectionView extends React.Component { specificContextMenu = (e: React.MouseEvent): void => { if (!e.isPropagationStopped() && this.props.Document.Id != "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 - ContextMenu.Instance.addItem({ description: "Freeform", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Freeform) }) - ContextMenu.Instance.addItem({ description: "Schema", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Schema) }) - ContextMenu.Instance.addItem({ description: "Treeview", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Tree) }) - ContextMenu.Instance.addItem({ description: "Docking", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) }) + ContextMenu.Instance.addItem({ description: "Freeform", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Freeform), icon: "project-diagram" }) + ContextMenu.Instance.addItem({ description: "Schema", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Schema), icon: "th" }) + ContextMenu.Instance.addItem({ description: "Treeview", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Tree), icon: "tree" }) + ContextMenu.Instance.addItem({ description: "Docking", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking), icon: "square" }) } } -- cgit v1.2.3-70-g09d2 From 19fca408a19c5f7a759ff6c3bfefe27b96ec3563 Mon Sep 17 00:00:00 2001 From: Eleanor Eng Date: Tue, 19 Mar 2019 17:51:25 -0400 Subject: contextmenu --- src/client/views/ContextMenu.scss | 2 +- src/client/views/ContextMenuItem.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 1 - src/client/views/nodes/DocumentView.tsx | 1 - src/client/views/nodes/FormattedTextBox.tsx | 1 - src/client/views/nodes/ImageBox.tsx | 1 - 6 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss index e5d41fcb6..8bc7708f7 100644 --- a/src/client/views/ContextMenu.scss +++ b/src/client/views/ContextMenu.scss @@ -18,7 +18,7 @@ width: 11vw; //10vw height: 2.5vh; //2vh background: #DDDDDD; - display: flex; + display: flex; //comment out to allow search icon to be inline with search text justify-content: left; align-items: center; -webkit-touch-callout: none; diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index 80d9ff6a5..fac7342aa 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -1,7 +1,7 @@ import React = require("react"); import { observable, action } from "mobx"; import { observer } from "mobx-react"; -import { library, IconProp } from '@fortawesome/fontawesome-svg-core'; +import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; export interface OriginalMenuProps { diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index b76426429..d0e2162b1 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -14,7 +14,6 @@ import { CollectionViewProps } from "./CollectionViewBase"; import { CollectionTreeView } from "./CollectionTreeView"; import { Field, FieldId } from "../../../fields/Field"; import { library } from '@fortawesome/fontawesome-svg-core'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTh } from '@fortawesome/free-solid-svg-icons'; import { faTree } from '@fortawesome/free-solid-svg-icons'; import { faSquare } from '@fortawesome/free-solid-svg-icons'; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 53a3aaa18..907762837 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -28,7 +28,6 @@ import { TextField } from "../../../fields/TextField"; import { DocumentManager } from "../../util/DocumentManager"; const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? import { library } from '@fortawesome/fontawesome-svg-core'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTrash } from '@fortawesome/free-solid-svg-icons'; import { faExpandArrowsAlt } from '@fortawesome/free-solid-svg-icons'; import { faCompressArrowsAlt } from '@fortawesome/free-solid-svg-icons'; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 7a8dbddcc..648037e31 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -15,7 +15,6 @@ import { Decoration, DecorationSet } from 'prosemirror-view' import { TooltipTextMenu } from "../../util/TooltipTextMenu" import { ContextMenu } from "../../views/ContextMenu"; import { library } from '@fortawesome/fontawesome-svg-core'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faEdit } from '@fortawesome/free-solid-svg-icons'; import { faSmile } from '@fortawesome/free-solid-svg-icons'; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 62ecea583..7532e23c8 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,4 +1,3 @@ - import { action, observable } from 'mobx'; import { observer } from "mobx-react"; import Lightbox from 'react-image-lightbox'; -- cgit v1.2.3-70-g09d2 From 0b677567dce5673bc45f08704485901801c90646 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 May 2019 22:46:08 -0400 Subject: fixed following links to video frames --- src/client/util/DocumentManager.ts | 12 ++--- .../views/collections/CollectionBaseView.tsx | 2 +- .../views/collections/CollectionSchemaView.scss | 2 +- .../views/collections/CollectionVideoView.tsx | 51 +++++++-------------- src/client/views/collections/CollectionView.tsx | 2 - src/client/views/nodes/KeyValuePair.scss | 2 +- src/client/views/nodes/PDFBox.tsx | 7 +-- src/client/views/nodes/VideoBox.scss | 6 ++- src/client/views/nodes/VideoBox.tsx | 53 ++++++++++++++++++---- 9 files changed, 76 insertions(+), 61 deletions(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 49c5d8c19..51f5fbe9f 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -111,19 +111,19 @@ export class DocumentManager { @undoBatch public jumpToDocument = async (doc: Doc): Promise => { + const page = NumCast(doc.page, undefined); + const contextDoc = await Cast(doc.annotationOn, Doc); + if (contextDoc) { + const curPage = NumCast(contextDoc.curPage, page); + if (page !== curPage) contextDoc.curPage = page; + } let docView = DocumentManager.Instance.getDocumentView(doc); if (docView) { docView.props.focus(docView.props.Document); } else { - const contextDoc = await Cast(doc.annotationOn, Doc); if (!contextDoc) { CollectionDockingView.Instance.AddRightSplit(Doc.MakeDelegate(doc)); } else { - const page = NumCast(doc.page, undefined); - const curPage = NumCast(contextDoc.curPage, undefined); - if (page !== curPage) { - contextDoc.curPage = page; - } let contextView = DocumentManager.Instance.getDocumentView(contextDoc); if (contextView) { contextDoc.panTransformType = "Ease"; diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 645296d27..31bdf213e 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -87,7 +87,7 @@ export class CollectionBaseView extends React.Component { @action.bound addDocument(doc: Doc, allowDuplicates: boolean = false): boolean { let props = this.props; - var curPage = Cast(props.Document.curPage, "number", -1); + var curPage = NumCast(props.Document.curPage, -1); Doc.SetOnPrototype(doc, "page", curPage); if (curPage >= 0) { Doc.SetOnPrototype(doc, "annotationOn", props.Document); diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index b9ed99155..5e9d2ac67 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -127,7 +127,7 @@ max-width: 100%; height: 100%; } - .videobox-cont { + .videoBox-cont { object-fit: contain; width: auto; height: 100%; diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx index cb3fd1ba4..16121bb1b 100644 --- a/src/client/views/collections/CollectionVideoView.tsx +++ b/src/client/views/collections/CollectionVideoView.tsx @@ -9,27 +9,26 @@ import { FieldView, FieldViewProps } from "../nodes/FieldView"; import { emptyFunction } from "../../../Utils"; import { Id } from "../../../new_fields/RefField"; import { VideoBox } from "../nodes/VideoBox"; +import { NumCast } from "../../../new_fields/Types"; @observer export class CollectionVideoView extends React.Component { - private _videoBox: VideoBox | undefined = undefined; - @observable _playTimer?: NodeJS.Timeout = undefined; - - @observable _currentTimecode: number = 0; + private _videoBox?: VideoBox; public static LayoutString(fieldKey: string = "data") { return FieldView.LayoutString(CollectionVideoView, fieldKey); } private get uIButtons() { let scaling = Math.min(1.8, this.props.ScreenToLocalTransform().Scale); + let curTime = NumCast(this.props.Document.curPage); return ([
- {"" + Math.round(this._currentTimecode)} - {" " + Math.round((this._currentTimecode - Math.trunc(this._currentTimecode)) * 100)} + {"" + Math.round(curTime)} + {" " + Math.round((curTime - Math.trunc(curTime)) * 100)}
,
- {this._playTimer ? "\"" : ">"} + {this._videoBox && this._videoBox.Playing ? "\"" : ">"}
,
F @@ -37,37 +36,21 @@ export class CollectionVideoView extends React.Component { ]); } - @action - updateTimecode = () => { - if (this._videoBox && this._videoBox.player) { - this._currentTimecode = this._videoBox.player.currentTime; - this.props.Document.curPage = Math.round(this._currentTimecode); - } - } - - componentDidMount() { this.updateTimecode(); } - - componentWillUnmount() { if (this._playTimer) clearInterval(this._playTimer); } - @action onPlayDown = () => { if (this._videoBox && this._videoBox.player) { - if (this._videoBox.player.paused) { - this._videoBox.player.play(); - if (!this._playTimer) this._playTimer = setInterval(this.updateTimecode, 1000); + if (this._videoBox.Playing) { + this._videoBox.Pause(); } else { - this._videoBox.player.pause(); - if (this._playTimer) clearInterval(this._playTimer); - this._playTimer = undefined; - + this._videoBox.Play(); } } } @action onFullDown = (e: React.PointerEvent) => { - if (this._videoBox && this._videoBox.player) { - this._videoBox.player.requestFullscreen(); + if (this._videoBox) { + this._videoBox.FullScreen(); e.stopPropagation(); e.preventDefault(); } @@ -75,12 +58,9 @@ export class CollectionVideoView extends React.Component { @action onResetDown = () => { - 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(); + if (this._videoBox) { + this._videoBox.Pause(); + this.props.Document.curPage = 0; } } @@ -90,7 +70,7 @@ export class CollectionVideoView extends React.Component { } } - setVideoBox = (player: VideoBox) => { this._videoBox = player; }; + setVideoBox = (videoBox: VideoBox) => { this._videoBox = videoBox; }; private subView = (_type: CollectionViewType, renderProps: CollectionRenderProps) => { let props = { ...this.props, ...renderProps }; @@ -101,6 +81,7 @@ export class CollectionVideoView extends React.Component { } render() { + trace(); return ( {this.subView} diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 8c1442d38..55fd2a284 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -9,9 +9,7 @@ import { ContextMenu } from '../ContextMenu'; import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils'; import { observer } from 'mobx-react'; import { undoBatch } from '../../util/UndoManager'; -import { trace } from 'mobx'; import { Id } from '../../../new_fields/RefField'; -import { Main } from '../Main'; @observer export class CollectionView extends React.Component { diff --git a/src/client/views/nodes/KeyValuePair.scss b/src/client/views/nodes/KeyValuePair.scss index 4f305dc91..a1c5d5537 100644 --- a/src/client/views/nodes/KeyValuePair.scss +++ b/src/client/views/nodes/KeyValuePair.scss @@ -30,7 +30,7 @@ max-height: 36px; width: auto; } - .videobox-cont{ + .videoBox-cont{ width: auto; max-height: 36px; } diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 6cbf066ca..14fe2df80 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -58,7 +58,7 @@ export class PDFBox extends DocComponent(PdfDocumen @observable private _renderAsSvg = true; @observable private _alt = false; - private _reactionDisposer: Opt; + private _reactionDisposer?: IReactionDisposer; @observable private _perPageInfo: Object[] = []; //stores pageInfo @observable private _pageInfo: any = { area: [], divs: [], anno: [] }; //divs is array of objects linked to anno @@ -84,9 +84,7 @@ export class PDFBox extends DocComponent(PdfDocumen } componentWillUnmount() { - if (this._reactionDisposer) { - this._reactionDisposer(); - } + if (this._reactionDisposer) this._reactionDisposer(); } /** @@ -338,7 +336,6 @@ export class PDFBox extends DocComponent(PdfDocumen @action onKeyDown = (e: React.KeyboardEvent) => e.key === "Alt" && (this._alt = true); @action onKeyUp = (e: React.KeyboardEvent) => e.key === "Alt" && (this._alt = false); render() { - trace(); let classname = "pdfBox-cont"; // + (this.props.isSelected() && !InkingControl.Instance.selectedTool && !this._alt ? "-interactive" : ""); return (
diff --git a/src/client/views/nodes/VideoBox.scss b/src/client/views/nodes/VideoBox.scss index 76bbeb37c..35db64cf4 100644 --- a/src/client/views/nodes/VideoBox.scss +++ b/src/client/views/nodes/VideoBox.scss @@ -1,4 +1,8 @@ -.videobox-cont{ +.videoBox-cont, .videoBox-cont-fullScreen{ width: 100%; height: Auto; +} + +.videoBox-cont-fullScreen { + pointer-events: all; } \ No newline at end of file diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 740d4cc1b..96dc884c8 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -3,16 +3,15 @@ import { observer } from "mobx-react"; import { FieldView, FieldViewProps } from './FieldView'; import * as rp from "request-promise"; import "./VideoBox.scss"; -import { action, computed, trace } from "mobx"; +import { action, IReactionDisposer, reaction, observable } from "mobx"; import { DocComponent } from "../DocComponent"; import { positionSchema } from "./DocumentView"; import { makeInterface } from "../../../new_fields/Schema"; import { pageSchema } from "./ImageBox"; -import { Cast, FieldValue, NumCast, ToConstructor, ListSpec } from "../../../new_fields/Types"; +import { Cast, FieldValue, NumCast } 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"; import { RouteStore } from "../../../server/RouteStore"; import { DocServer } from "../../DocServer"; @@ -21,10 +20,12 @@ const VideoDocument = makeInterface(positionSchema, pageSchema); @observer export class VideoBox extends DocComponent(VideoDocument) { - + private _reactionDisposer?: IReactionDisposer; private _videoRef: HTMLVideoElement | null = null; private _loaded: boolean = false; - private get initialTimecode() { return FieldValue(this.Document.curPage, -1); } + @observable _playTimer?: NodeJS.Timeout = undefined; + @observable _fullScreen = false; + @observable public Playing: boolean = false; public static LayoutString() { return FieldView.LayoutString(VideoBox); } public get player(): HTMLVideoElement | undefined { @@ -48,19 +49,50 @@ export class VideoBox extends DocComponent(VideoD } } + @action public Play() { + this.Playing = true; + if (this.player) this.player.play(); + if (!this._playTimer) this._playTimer = setInterval(this.updateTimecode, 1000); + } + + @action public Pause() { + this.Playing = false; + if (this.player) this.player.pause(); + if (this._playTimer) { + clearInterval(this._playTimer); + this._playTimer = undefined; + } + } + + @action public FullScreen() { + this._fullScreen = true; + this.player && this.player.requestFullscreen(); + } + + @action + updateTimecode = () => this.player && (this.props.Document.curPage = this.player.currentTime); + componentDidMount() { if (this.props.setVideoBox) this.props.setVideoBox(this); } + componentWillUnmount() { + this.Pause(); + if (this._reactionDisposer) this._reactionDisposer(); + } @action setVideoRef = (vref: HTMLVideoElement | null) => { this._videoRef = vref; - if (this.initialTimecode >= 0 && vref) { - vref.currentTime = this.initialTimecode; + if (vref) { + vref.onfullscreenchange = action((e) => this._fullScreen = vref.webkitDisplayingFullscreen); + if (this._reactionDisposer) this._reactionDisposer(); + this._reactionDisposer = reaction(() => this.props.Document.curPage, () => + vref.currentTime = NumCast(this.props.Document.curPage, 0), { fireImmediately: true }); } } videoContent(path: string) { - return