From 2cec74403daf057d6e2e830a0544c1254722dcde Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 10 Oct 2019 10:04:46 -0400 Subject: fixed scrolltoannotation bug in pdfviewer. removed CollectionPdfView --- src/client/views/collections/CollectionSchemaCells.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaCells.tsx') diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 179e44266..fd1362848 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -13,7 +13,6 @@ import { COLLECTION_BORDER_WIDTH, MAX_ROW_HEIGHT } from '../globalCssVariables.s import '../DocumentDecorations.scss'; import { EditableView } from "../EditableView"; import { FieldView, FieldViewProps } from "../nodes/FieldView"; -import { CollectionPDFView } from "./CollectionPDFView"; import "./CollectionSchemaView.scss"; import { CollectionVideoView } from "./CollectionVideoView"; import { CollectionView } from "./CollectionView"; @@ -34,8 +33,8 @@ export interface CellProps { row: number; col: number; rowProps: CellInfo; - CollectionView: Opt; - ContainingCollection: Opt; + CollectionView: Opt; + ContainingCollection: Opt; Document: Doc; fieldKey: string; renderDepth: number; -- cgit v1.2.3-70-g09d2 From 77d66d159d75442ff5635c4bf4843b6155883cc2 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 10 Oct 2019 14:04:22 -0400 Subject: removed CollectionVideoView --- src/client/documents/Documents.ts | 3 +- src/client/util/DocumentManager.ts | 5 +- src/client/util/SharingManager.tsx | 3 +- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/PreviewCursor.tsx | 18 +-- .../views/collections/CollectionBaseView.tsx | 15 +- .../views/collections/CollectionSchemaCells.tsx | 7 +- .../views/collections/CollectionSchemaView.tsx | 9 +- src/client/views/collections/CollectionSubView.tsx | 17 +- .../views/collections/CollectionVideoView.scss | 51 ------ .../views/collections/CollectionVideoView.tsx | 115 ------------- .../CollectionFreeFormLinkView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 8 +- .../collections/collectionFreeForm/MarqueeView.tsx | 14 +- src/client/views/linking/LinkFollowBox.tsx | 2 +- src/client/views/nodes/DocumentContentsView.tsx | 3 +- src/client/views/nodes/DocumentView.tsx | 7 +- src/client/views/nodes/FieldView.tsx | 5 +- src/client/views/nodes/PDFBox.tsx | 2 +- src/client/views/nodes/VideoBox.scss | 57 ++++++- src/client/views/nodes/VideoBox.tsx | 177 +++++++++++++++++++-- src/client/views/nodes/WebBox.tsx | 2 +- src/client/views/pdf/PDFViewer.tsx | 18 ++- 23 files changed, 284 insertions(+), 258 deletions(-) delete mode 100644 src/client/views/collections/CollectionVideoView.scss delete mode 100644 src/client/views/collections/CollectionVideoView.tsx (limited to 'src/client/views/collections/CollectionSchemaCells.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 9d1a6ed3e..22aa74634 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1,7 +1,6 @@ import { HistogramField } from "../northstar/dash-fields/HistogramField"; import { HistogramBox } from "../northstar/dash-nodes/HistogramBox"; import { HistogramOperation } from "../northstar/operations/HistogramOperation"; -import { CollectionVideoView } from "../views/collections/CollectionVideoView"; import { CollectionView } from "../views/collections/CollectionView"; import { CollectionViewType } from "../views/collections/CollectionBaseView"; import { AudioBox } from "../views/nodes/AudioBox"; @@ -137,7 +136,7 @@ export namespace Docs { options: { height: 150 } }], [DocumentType.VID, { - layout: { view: VideoBox, collectionView: [CollectionVideoView, data, anno] as CollectionViewType }, + layout: { view: VideoBox, ext: anno }, options: { currentTimecode: 0 }, }], [DocumentType.AUDIO, { diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index c95d923cb..24285a70a 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -3,7 +3,6 @@ import { Doc, DocListCastAsync } from '../../new_fields/Doc'; import { Id } from '../../new_fields/FieldSymbols'; import { Cast, NumCast, StrCast } from '../../new_fields/Types'; import { CollectionDockingView } from '../views/collections/CollectionDockingView'; -import { CollectionVideoView } from '../views/collections/CollectionVideoView'; import { CollectionView } from '../views/collections/CollectionView'; import { DocumentView } from '../views/nodes/DocumentView'; import { LinkManager } from './LinkManager'; @@ -56,7 +55,7 @@ export class DocumentManager { return this.getDocumentViewsById(doc[Id]); } - public getDocumentViewById(id: string, preferredCollection?: CollectionView | CollectionVideoView): DocumentView | undefined { + public getDocumentViewById(id: string, preferredCollection?: CollectionView): DocumentView | undefined { let toReturn: DocumentView | undefined; let passes = preferredCollection ? [preferredCollection, undefined] : [undefined]; @@ -81,7 +80,7 @@ export class DocumentManager { return toReturn; } - public getDocumentView(toFind: Doc, preferredCollection?: CollectionView | CollectionVideoView): DocumentView | undefined { + public getDocumentView(toFind: Doc, preferredCollection?: CollectionView): DocumentView | undefined { return this.getDocumentViewById(toFind[Id], preferredCollection); } diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index c989b6c17..d37cd1b80 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -17,7 +17,6 @@ import * as fa from '@fortawesome/free-solid-svg-icons'; import { DocumentView } from "../views/nodes/DocumentView"; import { SelectionManager } from "./SelectionManager"; import { DocumentManager } from "./DocumentManager"; -import { CollectionVideoView } from "../views/collections/CollectionVideoView"; import { CollectionView } from "../views/collections/CollectionView"; library.add(fa.faCopy); @@ -185,7 +184,7 @@ export default class SharingManager extends React.Component<{}> { className={"focus-span"} title={title} onClick={() => { - let context: Opt; + let context: Opt; if (this.targetDoc && this.targetDocView && (context = this.targetDocView.props.ContainingCollectionView)) { DocumentManager.Instance.jumpToDocument(this.targetDoc, true, undefined, context.props.Document); } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 4f9bdbe9c..1d9f0c74b 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -333,7 +333,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> iconDoc.y = NumCast(doc.y) - 24; iconDoc.maximizedDocs = new List(selected.map(s => s.props.Document)); selected.length === 1 && (doc.minimizedDoc = iconDoc); - selected[0].props.addDocument && selected[0].props.addDocument(iconDoc, false); + selected[0].props.addDocument && selected[0].props.addDocument(iconDoc); return iconDoc; } @action diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index 1aed51e64..eed2cc5da 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -14,7 +14,7 @@ export class PreviewCursor extends React.Component<{}> { static _onKeyPress?: (e: KeyboardEvent) => void; static _getTransform: () => Transform; static _addLiveTextDoc: (doc: Doc) => void; - static _addDocument: (doc: Doc, allowDuplicates: false) => boolean; + static _addDocument: (doc: Doc) => boolean; @observable static _clickPoint = [0, 0]; @observable public static Visible = false; //when focus is lost, this will remove the preview cursor @@ -44,7 +44,7 @@ export class PreviewCursor extends React.Component<{}> { title: url, width: 400, height: 315, nativeWidth: 600, nativeHeight: 472.5, x: newPoint[0], y: newPoint[1] - }), false); + })); return; } @@ -56,7 +56,7 @@ export class PreviewCursor extends React.Component<{}> { title: url, width: 300, height: 300, // nativeWidth: 300, nativeHeight: 472.5, x: newPoint[0], y: newPoint[1] - }), false); + })); return; } @@ -79,11 +79,11 @@ export class PreviewCursor extends React.Component<{}> { let img: Doc = Docs.Create.ImageDocument( arr[1], { - width: 300, title: arr[1], - x: newPoint[0], - y: newPoint[1], - }); - PreviewCursor._addDocument(img, false); + width: 300, title: arr[1], + x: newPoint[0], + y: newPoint[1], + }); + PreviewCursor._addDocument(img); return; } @@ -113,7 +113,7 @@ export class PreviewCursor extends React.Component<{}> { onKeyPress: (e: KeyboardEvent) => void, addLiveText: (doc: Doc) => void, getTransform: () => Transform, - addDocument: (doc: Doc, allowDuplicates: false) => boolean) { + addDocument: (doc: Doc) => boolean) { this._clickPoint = [x, y]; this._onKeyPress = onKeyPress; this._addLiveTextDoc = addLiveText; diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 62be1fc31..61919427a 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -45,7 +45,7 @@ export namespace CollectionViewType { } export interface CollectionRenderProps { - addDocument: (document: Doc, allowDuplicates?: boolean) => boolean; + addDocument: (document: Doc) => boolean; removeDocument: (document: Doc) => boolean; moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean; active: () => boolean; @@ -100,22 +100,13 @@ export class CollectionBaseView extends React.Component { @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, this.props.fieldExt); } @action.bound - addDocument(doc: Doc, allowDuplicates: boolean = false): boolean { - var curTime = NumCast(this.props.Document.currentTimecode, -1); - curTime !== -1 && (doc.displayTimecode = curTime); + addDocument(doc: Doc): boolean { if (this.props.fieldExt) { // bcz: fieldExt !== undefined means this is an overlay layer Doc.GetProto(doc).annotationOn = this.props.Document; } let targetDataDoc = this.props.fieldExt || this.props.Document.isTemplate ? this.extensionDoc : this.props.Document; let targetField = (this.props.fieldExt || this.props.Document.isTemplate) && this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey; - const value = Cast(targetDataDoc[targetField], listSpec(Doc)); - if (value !== undefined) { - if (allowDuplicates || !value.some(v => v instanceof Doc && v[Id] === doc[Id])) { - value.push(doc); - } - } else { - Doc.GetProto(targetDataDoc)[targetField] = new List([doc]); - } + Doc.AddDocToList(targetDataDoc, targetField, doc); Doc.GetProto(doc).lastOpened = new DateField; return true; } diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index fd1362848..79c032723 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -14,15 +14,12 @@ import '../DocumentDecorations.scss'; import { EditableView } from "../EditableView"; import { FieldView, FieldViewProps } from "../nodes/FieldView"; import "./CollectionSchemaView.scss"; -import { CollectionVideoView } from "./CollectionVideoView"; import { CollectionView } from "./CollectionView"; import { NumCast, StrCast, BoolCast, FieldValue, Cast } from "../../../new_fields/Types"; import { Docs } from "../../documents/Documents"; -import { DocumentContentsView } from "../nodes/DocumentContentsView"; import { SelectionManager } from "../../util/SelectionManager"; import { library } from '@fortawesome/fontawesome-svg-core'; import { faExpand } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField"; import { KeyCodes } from "../../northstar/utils/KeyCodes"; import { undoBatch } from "../../util/UndoManager"; @@ -33,8 +30,8 @@ export interface CellProps { row: number; col: number; rowProps: CellInfo; - CollectionView: Opt; - ContainingCollection: Opt; + CollectionView: Opt; + ContainingCollection: Opt; Document: Doc; fieldKey: string; renderDepth: number; diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 670c6bd43..3218f630a 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -23,7 +23,6 @@ import '../DocumentDecorations.scss'; import { DocumentView } from "../nodes/DocumentView"; import "./CollectionSchemaView.scss"; import { CollectionSubView } from "./CollectionSubView"; -import { CollectionVideoView } from "./CollectionVideoView"; import { CollectionView } from "./CollectionView"; import { undoBatch } from "../../util/UndoManager"; import { CollectionSchemaHeader, CollectionSchemaAddColumnHeader } from "./CollectionSchemaHeaders"; @@ -246,8 +245,8 @@ export interface SchemaTableProps { PanelHeight: () => number; PanelWidth: () => number; childDocs?: Doc[]; - CollectionView: Opt; - ContainingCollectionView: Opt; + CollectionView: Opt; + ContainingCollectionView: Opt; ContainingCollectionDoc: Opt; fieldKey: string; renderDepth: number; @@ -904,11 +903,11 @@ interface CollectionSchemaPreviewProps { ruleProvider: Doc | undefined; focus?: (doc: Doc) => void; showOverlays?: (doc: Doc) => { title?: string, caption?: string }; - CollectionView?: CollectionView | CollectionVideoView; + CollectionView?: CollectionView; CollectionDoc?: Doc; onClick?: ScriptField; getTransform: () => Transform; - addDocument: (document: Doc, allowDuplicates?: boolean) => boolean; + addDocument: (document: Doc) => boolean; moveDocument: (document: Doc, target: Doc, addDoc: ((doc: Doc) => boolean)) => boolean; removeDocument: (document: Doc) => boolean; active: () => boolean; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 5e2b79278..689adc375 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -18,7 +18,6 @@ import { undoBatch, UndoManager } from "../../util/UndoManager"; import { DocComponent } from "../DocComponent"; import { FieldViewProps } from "../nodes/FieldView"; import { FormattedTextBox, GoogleRef } from "../nodes/FormattedTextBox"; -import { CollectionVideoView } from "./CollectionVideoView"; import { CollectionView } from "./CollectionView"; import React = require("react"); var path = require('path'); @@ -26,7 +25,7 @@ import { GooglePhotos } from "../../apis/google_docs/GooglePhotosClientUtils"; import { ImageUtils } from "../../util/Import & Export/ImageUtils"; export interface CollectionViewProps extends FieldViewProps { - addDocument: (document: Doc, allowDuplicates?: boolean) => boolean; + addDocument: (document: Doc) => boolean; removeDocument: (document: Doc) => boolean; moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean; PanelWidth: () => number; @@ -37,7 +36,7 @@ export interface CollectionViewProps extends FieldViewProps { } export interface SubCollectionViewProps extends CollectionViewProps { - CollectionView: Opt; + CollectionView: Opt; ruleProvider: Doc | undefined; } @@ -175,14 +174,14 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { DocServer.GetRefField(docid).then(f => { if (f instanceof Doc) { if (options.x || options.y) { f.x = options.x; f.y = options.y; } // should be in CollectionFreeFormView - (f instanceof Doc) && this.props.addDocument(f, false); + (f instanceof Doc) && this.props.addDocument(f); } }); } else { this.props.addDocument && this.props.addDocument(Docs.Create.WebDocument(href, options)); } } else if (text) { - this.props.addDocument && this.props.addDocument(Docs.Create.TextDocument({ ...options, width: 100, height: 25, documentText: "@@@" + text }), false); + this.props.addDocument && this.props.addDocument(Docs.Create.TextDocument({ ...options, width: 100, height: 25, documentText: "@@@" + text })); } return; } @@ -194,7 +193,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { let split = img.split("src=\"")[1].split("\"")[0]; let doc = Docs.Create.ImageDocument(split, { ...options, width: 300 }); ImageUtils.ExtractExif(doc); - this.props.addDocument(doc, false); + this.props.addDocument(doc); return; } else { let path = window.location.origin + "/doc/"; @@ -203,12 +202,12 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { DocServer.GetRefField(docid).then(f => { if (f instanceof Doc) { if (options.x || options.y) { f.x = options.x; f.y = options.y; } // should be in CollectionFreeFormView - (f instanceof Doc) && this.props.addDocument(f, false); + (f instanceof Doc) && this.props.addDocument(f); } }); } else { let htmlDoc = Docs.Create.HtmlDocument(html, { ...options, width: 300, height: 300, documentText: text }); - this.props.addDocument(htmlDoc, false); + this.props.addDocument(htmlDoc); } return; } @@ -252,7 +251,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { let type = result["content-type"]; if (type) { Docs.Get.DocumentFromType(type, str, { ...options, width: 300, nativeWidth: type.indexOf("video") !== -1 ? 600 : 300 }) - .then(doc => doc && this.props.addDocument(doc, false)); + .then(doc => doc && this.props.addDocument(doc)); } }); promises.push(prom); diff --git a/src/client/views/collections/CollectionVideoView.scss b/src/client/views/collections/CollectionVideoView.scss deleted file mode 100644 index 509851ebb..000000000 --- a/src/client/views/collections/CollectionVideoView.scss +++ /dev/null @@ -1,51 +0,0 @@ - -.collectionVideoView-cont{ - width: 100%; - height: 100%; - position: inherit; - top: 0; - left:0; - z-index: -1; - display:inline-table; -} -.collectionVideoView-time{ - color : white; - top :25px; - left : 25px; - position: absolute; - background-color: rgba(50, 50, 50, 0.2); - transform-origin: left top; -} -.collectionVideoView-snapshot{ - color : white; - top :25px; - right : 25px; - position: absolute; - background-color: rgba(50, 50, 50, 0.2); - transform-origin: left top; -} -.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; - transform-origin: left bottom; -} -.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; - transform-origin: right bottom; - -} \ No newline at end of file diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx deleted file mode 100644 index 3d898b7de..000000000 --- a/src/client/views/collections/CollectionVideoView.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import { action } from "mobx"; -import { observer } from "mobx-react"; -import { NumCast } from "../../../new_fields/Types"; -import { FieldView, FieldViewProps } from "../nodes/FieldView"; -import { VideoBox } from "../nodes/VideoBox"; -import { CollectionBaseView, CollectionRenderProps, CollectionViewType } from "./CollectionBaseView"; -import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormView"; -import "./CollectionVideoView.scss"; -import React = require("react"); -import { InkingControl } from "../InkingControl"; -import { InkTool } from "../../../new_fields/InkField"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; - - -@observer -export class CollectionVideoView extends React.Component { - private _videoBox?: VideoBox; - - public static LayoutString(fieldKey: string = "data", fieldExt: string = "annotations") { - return FieldView.LayoutString(CollectionVideoView, fieldKey, fieldExt); - } - private get uIButtons() { - let scaling = Math.min(1.8, this.props.ScreenToLocalTransform().Scale); - let curTime = NumCast(this.props.Document.currentTimecode); - return ([
- {"" + Math.round(curTime)} - {" " + Math.round((curTime - Math.trunc(curTime)) * 100)} -
, -
- -
, - VideoBox._showControls ? (null) : [ -
- -
, -
- F -
- ]]); - } - - @action - onPlayDown = () => { - if (this._videoBox) { - if (this._videoBox.Playing) { - this._videoBox.Pause(); - } else { - this._videoBox.Play(); - } - } - } - - @action - onFullDown = (e: React.PointerEvent) => { - if (this._videoBox) { - this._videoBox.FullScreen(); - e.stopPropagation(); - e.preventDefault(); - } - } - - @action - onSnapshot = (e: React.PointerEvent) => { - if (this._videoBox) { - this._videoBox.Snapshot(); - e.stopPropagation(); - e.preventDefault(); - } - } - - _isclick = 0; - @action - onResetDown = (e: React.PointerEvent) => { - if (this._videoBox) { - this._videoBox.Pause(); - e.stopPropagation(); - this._isclick = 0; - document.addEventListener("pointermove", this.onPointerMove, true); - document.addEventListener("pointerup", this.onPointerUp, true); - InkingControl.Instance.switchTool(InkTool.Eraser); - } - } - - @action - onPointerMove = (e: PointerEvent) => { - this._isclick += Math.abs(e.movementX) + Math.abs(e.movementY); - if (this._videoBox) { - this._videoBox.Seek(Math.max(0, NumCast(this.props.Document.currentTimecode, 0) + Math.sign(e.movementX) * 0.0333)); - } - e.stopImmediatePropagation(); - } - @action - onPointerUp = (e: PointerEvent) => { - document.removeEventListener("pointermove", this.onPointerMove, true); - document.removeEventListener("pointerup", this.onPointerUp, true); - InkingControl.Instance.switchTool(InkTool.None); - this._isclick < 10 && (this.props.Document.currentTimecode = 0); - } - setVideoBox = (videoBox: VideoBox) => { this._videoBox = videoBox; }; - - private subView = (_type: CollectionViewType, renderProps: CollectionRenderProps) => { - let props = { ...this.props, ...renderProps }; - return (<> - - {this.props.isSelected() ? this.uIButtons : (null)} - ); - } - - render() { - return ( - - {this.subView} - ); - } -} \ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index df089eb00..fe92eed10 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -10,7 +10,7 @@ export interface CollectionFreeFormLinkViewProps { A: Doc; B: Doc; LinkDocs: Doc[]; - addDocument: (document: Doc, allowDuplicates?: boolean) => boolean; + addDocument: (document: Doc) => boolean; removeDocument: (document: Doc) => boolean; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 38488f033..d2644480c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -93,10 +93,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { heading = !sorted.length ? Math.max(1, maxHeading) : NumCast(sorted[sorted.length - 1].heading) === 1 ? 2 : NumCast(sorted[sorted.length - 1].heading); } !this.Document.isRuleProvider && (newBox.heading = heading); - this.addDocument(newBox, false); + this.addDocument(newBox); } - private addDocument = (newBox: Doc, allowDuplicates: boolean) => { - let added = this.props.addDocument(newBox, false); + private addDocument = (newBox: Doc) => { + let added = this.props.addDocument(newBox); added && this.bringToFront(newBox); added && this.updateCluster(newBox); return added; @@ -659,7 +659,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { if (doc instanceof Doc) { const [xx, yy] = this.props.ScreenToLocalTransform().transformPoint(x, y); doc.x = xx, doc.y = yy; - this.props.addDocument && this.props.addDocument(doc, false); + this.props.addDocument && this.props.addDocument(doc); } } } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index eaf65b88c..bb787106c 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -24,7 +24,7 @@ interface MarqueeViewProps { getContainerTransform: () => Transform; getTransform: () => Transform; container: CollectionFreeFormView; - addDocument: (doc: Doc, allowDuplicates: false) => boolean; + addDocument: (doc: Doc) => boolean; activeDocuments: () => Doc[]; selectDocuments: (docs: Doc[]) => void; removeDocument: (doc: Doc) => boolean; @@ -83,7 +83,7 @@ export class MarqueeView extends React.Component ns.map(line => { let indent = line.search(/\S|$/); let newBox = Docs.Create.TextDocument({ width: 200, height: 35, x: x + indent / 3 * 10, y: y, documentText: "@@@" + line, title: line }); - this.props.addDocument(newBox, false); + this.props.addDocument(newBox); y += 40 * this.props.getTransform().Scale; }); })(); @@ -92,7 +92,7 @@ export class MarqueeView extends React.Component navigator.clipboard.readText().then(text => { let ns = text.split("\n").filter(t => t.trim() !== "\r" && t.trim() !== ""); if (ns.length === 1 && text.startsWith("http")) { - this.props.addDocument(Docs.Create.ImageDocument(text, { nativeWidth: 300, width: 300, x: x, y: y }), false);// paste an image from its URL in the paste buffer + this.props.addDocument(Docs.Create.ImageDocument(text, { nativeWidth: 300, width: 300, x: x, y: y }));// paste an image from its URL in the paste buffer } else { this.pasteTable(ns, x, y); } @@ -146,7 +146,7 @@ export class MarqueeView extends React.Component } let newCol = Docs.Create.SchemaDocument([...(groupAttr ? [new SchemaHeaderField("_group", "#f1efeb")] : []), ...columns.filter(c => c).map(c => new SchemaHeaderField(c, "#f1efeb"))], docList, { x: x, y: y, title: "droppedTable", width: 300, height: 100 }); - this.props.addDocument(newCol, false); + this.props.addDocument(newCol); } } @action @@ -202,7 +202,7 @@ export class MarqueeView extends React.Component } } - setPreviewCursor = (x: number, y: number, drag: boolean) => { + setPreviewCursor = action((x: number, y: number, drag: boolean) => { if (drag) { this._downX = this._lastX = x; this._downY = this._lastY = y; @@ -217,7 +217,7 @@ export class MarqueeView extends React.Component this._downY = y; PreviewCursor.Show(x, y, this.onKeyPress, this.props.addLiveTextDocument, this.props.getTransform, this.props.addDocument); } - } + }) @action onClick = (e: React.MouseEvent): void => { @@ -350,7 +350,7 @@ export class MarqueeView extends React.Component } } else { - this.props.addDocument(newCollection, false); + this.props.addDocument(newCollection); this.props.selectDocuments([newCollection]); } this.cleanupInteractions(false); diff --git a/src/client/views/linking/LinkFollowBox.tsx b/src/client/views/linking/LinkFollowBox.tsx index b18aa5d63..32ebe7c61 100644 --- a/src/client/views/linking/LinkFollowBox.tsx +++ b/src/client/views/linking/LinkFollowBox.tsx @@ -278,7 +278,7 @@ export class LinkFollowBox extends React.Component { alias.width = width; alias.height = height; - this.sourceView.props.addDocument(alias, false); + this.sourceView.props.addDocument(alias); } } diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index a824ae9cc..e4b2ecffd 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -9,7 +9,6 @@ import DirectoryImportBox from "../../util/Import & Export/DirectoryImportBox"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; import { CollectionSchemaView } from "../collections/CollectionSchemaView"; -import { CollectionVideoView } from "../collections/CollectionVideoView"; import { CollectionView } from "../collections/CollectionView"; import { LinkFollowBox } from "../linking/LinkFollowBox"; import { YoutubeBox } from "./../../apis/youtube/YoutubeBox"; @@ -100,7 +99,7 @@ export class DocumentContentsView extends React.Component; + ContainingCollectionView: Opt; ContainingCollectionDoc: Opt; Document: Doc; DataDoc?: Doc; fitToBox?: boolean; onClick?: ScriptField; - addDocument?: (doc: Doc, allowDuplicates?: boolean) => boolean; + addDocument?: (doc: Doc) => boolean; removeDocument?: (doc: Doc) => boolean; moveDocument?: (doc: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean; ScreenToLocalTransform: () => Transform; @@ -217,7 +216,7 @@ export class DocumentView extends DocComponent(Docu let maxLocation = StrCast(this.Document.maximizeLocation, "inPlace"); maxLocation = this.Document.maximizeLocation = (!ctrlKey ? !altKey ? maxLocation : (maxLocation !== "inPlace" ? "inPlace" : "onRight") : (maxLocation !== "inPlace" ? "inPlace" : "inTab")); if (maxLocation === "inPlace") { - expandedDocs.forEach(maxDoc => this.props.addDocument && this.props.addDocument(maxDoc, false)); + expandedDocs.forEach(maxDoc => this.props.addDocument && this.props.addDocument(maxDoc)); let scrpt = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).inverse().transformPoint(NumCast(this.Document.width) / 2, NumCast(this.Document.height) / 2); DocumentManager.Instance.animateBetweenPoint(scrpt, expandedDocs); } else { diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index c17730f48..074efaf6c 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -8,7 +8,6 @@ import { List } from "../../../new_fields/List"; import { RichTextField } from "../../../new_fields/RichTextField"; import { AudioField, ImageField, VideoField } from "../../../new_fields/URLField"; import { Transform } from "../../util/Transform"; -import { CollectionVideoView } from "../collections/CollectionVideoView"; import { CollectionView } from "../collections/CollectionView"; import { AudioBox } from "./AudioBox"; import { FormattedTextBox } from "./FormattedTextBox"; @@ -28,7 +27,7 @@ export interface FieldViewProps { fieldExt: string; leaveNativeSize?: boolean; fitToBox?: boolean; - ContainingCollectionView: Opt; + ContainingCollectionView: Opt; ContainingCollectionDoc: Opt; ruleProvider: Doc | undefined; Document: Doc; @@ -37,7 +36,7 @@ export interface FieldViewProps { isSelected: () => boolean; select: (isCtrlPressed: boolean) => void; renderDepth: number; - addDocument?: (document: Doc, allowDuplicates?: boolean) => boolean; + addDocument?: (document: Doc) => boolean; addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; pinToPres: (document: Doc) => void; removeDocument?: (document: Doc) => boolean; diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 1f3887608..57803be1f 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -174,7 +174,7 @@ export class PDFBox extends DocComponent(PdfDocumen ContextMenu.Instance.addItem({ description: "Pdf Funcs...", subitems: funcs, icon: "asterisk" }); } - _initialScale: number | undefined; + _initialScale: number | undefined; // the initial scale of the PDF when first rendered which determines whether the document will be live on startup or not. Getting bigger after startup won't make it automatically be live.... render() { const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField); let classname = "pdfBox-cont" + (InkingControl.Instance.selectedTool || !this.active ? "" : "-interactive"); diff --git a/src/client/views/nodes/VideoBox.scss b/src/client/views/nodes/VideoBox.scss index d651a8621..b3cd439aa 100644 --- a/src/client/views/nodes/VideoBox.scss +++ b/src/client/views/nodes/VideoBox.scss @@ -1,6 +1,14 @@ +// .videoBox-container { +// .collectionfreeformview-container { +// mix-blend-mode: multiply; +// } +// } + .videoBox-content-YouTube, .videoBox-content-YouTube-fullScreen, .videoBox-content, .videoBox-content-interactive, .videoBox-cont-fullScreen { width: 100%; + z-index: 0; // logically this should be 0 (or unset) which would give us transparent brush strokes over videos. However, this makes Chrome crawl to a halt + position: absolute; } .videoBox-content, .videoBox-content-interactive, .videoBox-content-fullScreen { @@ -11,7 +19,52 @@ height: 100%; } -.videoBox-content-interactive, .videoBox-content-fullScreen, -.videoBox-content-YouTube-fullScreen { +.videoBox-content-interactive, .videoBox-content-fullScreen, .videoBox-content-YouTube-fullScreen { pointer-events: all; +} + +.videoBox-time{ + color : white; + top :25px; + left : 25px; + position: absolute; + background-color: rgba(50, 50, 50, 0.2); + transform-origin: left top; + pointer-events:all; +} +.videoBox-snapshot{ + color : white; + top :25px; + right : 25px; + position: absolute; + background-color:rgba(50, 50, 50, 0.2); + transform-origin: left top; + pointer-events:all; +} +.videoBox-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; + transform-origin: left bottom; + pointer-events:all; +} +.videoBox-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; + transform-origin: right bottom; + 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 e83aa8bea..feb067d8f 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -3,11 +3,11 @@ import { action, computed, IReactionDisposer, observable, reaction, runInAction, import { observer } from "mobx-react"; import * as rp from 'request-promise'; import { InkTool } from "../../../new_fields/InkField"; -import { makeInterface, createSchema } from "../../../new_fields/Schema"; -import { Cast, FieldValue, NumCast, BoolCast } from "../../../new_fields/Types"; +import { makeInterface, createSchema, listSpec } from "../../../new_fields/Schema"; +import { Cast, FieldValue, NumCast, BoolCast, StrCast } from "../../../new_fields/Types"; import { VideoField } from "../../../new_fields/URLField"; import { RouteStore } from "../../../server/RouteStore"; -import { Utils } from "../../../Utils"; +import { Utils, emptyFunction, returnOne } from "../../../Utils"; import { Docs, DocUtils } from "../../documents/Documents"; import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from "../ContextMenuItem"; @@ -22,6 +22,8 @@ import { faVideo } from "@fortawesome/free-solid-svg-icons"; import { Doc } from "../../../new_fields/Doc"; import { ScriptField } from "../../../new_fields/ScriptField"; import { positionSchema } from "./CollectionFreeFormDocumentView"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; var path = require('path'); export const timeSchema = createSchema({ @@ -34,19 +36,24 @@ library.add(faVideo); @observer export class VideoBox extends DocComponent(VideoDocument) { + static _youtubeIframeCounter: number = 0; private _reactionDisposer?: IReactionDisposer; private _youtubeReactionDisposer?: IReactionDisposer; private _youtubePlayer: YT.Player | undefined = undefined; private _videoRef: HTMLVideoElement | null = null; private _youtubeIframeId: number = -1; private _youtubeContentCreated = false; - static _youtubeIframeCounter: number = 0; + private _downX: number = 0; + private _downY: number = 0; + private _isResetClick = 0; + private _isChildActive = false; + private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean) => void); @observable _forceCreateYouTubeIFrame = false; @observable static _showControls: boolean; @observable _playTimer?: NodeJS.Timeout = undefined; @observable _fullScreen = false; @observable public Playing: boolean = false; - public static LayoutString() { return FieldView.LayoutString(VideoBox); } + public static LayoutString(fieldExt?: string) { return FieldView.LayoutString(VideoBox, "data", fieldExt); } public get player(): HTMLVideoElement | null { return this._videoRef; @@ -123,8 +130,8 @@ export class VideoBox extends DocComponent(VideoD //convert to desired file format var dataUrl = canvas.toDataURL('image/png'); // can also use 'image/png' // if you want to preview the captured image, - let filename = path.basename(encodeURIComponent("snapshot" + this.Document.title + "_" + (this.Document.currentTimecode || 0).toString())); - VideoBox.convertDataUri(dataUrl, filename.replace(/\..*$/, "")).then(returnedFilename => { + let filename = path.basename(encodeURIComponent("snapshot" + StrCast(this.Document.title).replace(/\..*$/, "") + "_" + (this.Document.currentTimecode || 0).toString().replace(/\./, "_"))); + VideoBox.convertDataUri(dataUrl, filename).then(returnedFilename => { if (returnedFilename) { let url = this.choosePath(Utils.prepend(returnedFilename)); let imageSummary = Docs.Create.ImageDocument(url, { @@ -132,7 +139,7 @@ export class VideoBox extends DocComponent(VideoD width: 150, height: height / width * 150, title: "--snapshot" + (this.Document.currentTimecode || 0) + " image-" }); imageSummary.isButton = true; - this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.addDocument && this.props.ContainingCollectionView.props.addDocument(imageSummary, false); + this.props.addDocument && this.props.addDocument(imageSummary); DocUtils.MakeLink({ doc: imageSummary }, { doc: this.props.Document }, "snapshot from " + this.Document.title, "video frame snapshot"); } }); @@ -259,7 +266,73 @@ export class VideoBox extends DocComponent(VideoD }); } + private get uIButtons() { + let scaling = Math.min(1.8, this.props.ScreenToLocalTransform().Scale); + let curTime = NumCast(this.props.Document.currentTimecode); + return ([
+ {"" + Math.round(curTime)} + {" " + Math.round((curTime - Math.trunc(curTime)) * 100)} +
, +
+ +
, + VideoBox._showControls ? (null) : [ +
+ +
, +
+ F +
+ ]]); + } + + @action + onPlayDown = () => { + if (this.Playing) { + this.Pause(); + } else { + this.Play(); + } + } + @action + onFullDown = (e: React.PointerEvent) => { + this.FullScreen(); + e.stopPropagation(); + e.preventDefault(); + } + + @action + onSnapshot = (e: React.PointerEvent) => { + this.Snapshot(); + e.stopPropagation(); + e.preventDefault(); + } + + @action + onResetDown = (e: React.PointerEvent) => { + this.Pause(); + e.stopPropagation(); + this._isResetClick = 0; + document.addEventListener("pointermove", this.onResetMove, true); + document.addEventListener("pointerup", this.onResetUp, true); + InkingControl.Instance.switchTool(InkTool.Eraser); + } + + @action + onResetMove = (e: PointerEvent) => { + this._isResetClick += Math.abs(e.movementX) + Math.abs(e.movementY); + this.Seek(Math.max(0, NumCast(this.props.Document.currentTimecode, 0) + Math.sign(e.movementX) * 0.0333)); + e.stopImmediatePropagation(); + } + @action + onResetUp = (e: PointerEvent) => { + document.removeEventListener("pointermove", this.onResetMove, true); + document.removeEventListener("pointerup", this.onResetUp, true); + InkingControl.Instance.switchTool(InkTool.None); + this._isResetClick < 10 && (this.props.Document.currentTimecode = 0); + } + @computed get fieldExtensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); } @computed get dataDoc() { return this.props.DataDoc && this.props.Document.isTemplate ? this.props.DataDoc : Doc.GetProto(this.props.Document); } @computed get youtubeContent() { @@ -273,11 +346,95 @@ export class VideoBox extends DocComponent(VideoD >; } + + setPreviewCursor = (func?: (x: number, y: number, drag: boolean) => void) => { + this._setPreviewCursor = func; + } + + @action.bound + removeDocument(doc: Doc): boolean { + Doc.GetProto(doc).annotationOn = undefined; + //TODO This won't create the field if it doesn't already exist + let targetDataDoc = this.fieldExtensionDoc; + let targetField = this.props.fieldExt; + let value = Cast(targetDataDoc[targetField], listSpec(Doc), []); + let index = value.reduce((p, v, i) => (v instanceof Doc && v === doc) ? i : p, -1); + index = index !== -1 ? index : value.reduce((p, v, i) => (v instanceof Doc && Doc.AreProtosEqual(v, doc)) ? i : p, -1); + index !== -1 && value.splice(index, 1); + return true; + } + // this is called with the document that was dragged and the collection to move it into. + // if the target collection is the same as this collection, then the move will be allowed. + // otherwise, the document being moved must be able to be removed from its container before + // moving it into the target. + @action.bound + moveDocument(doc: Doc, targetCollection: Doc, addDocument: (doc: Doc) => boolean): boolean { + if (Doc.AreProtosEqual(this.props.Document, targetCollection)) { + return true; + } + return this.removeDocument(doc) ? addDocument(doc) : false; + } + + @action.bound + addDocument(doc: Doc): boolean { + Doc.GetProto(doc).annotationOn = this.props.Document; + var curTime = NumCast(this.props.Document.currentTimecode, -1); + curTime !== -1 && (doc.displayTimecode = curTime); + Doc.AddDocToList(this.fieldExtensionDoc, this.props.fieldExt, doc); + return true; + } + whenActiveChanged = (isActive: boolean) => { + this._isChildActive = isActive; + this.props.whenActiveChanged(isActive); + } + active = () => { + return this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0; + } + onClick = (e: React.MouseEvent) => { + this._setPreviewCursor && + e.button === 0 && + Math.abs(e.clientX - this._downX) < 3 && + Math.abs(e.clientY - this._downY) < 3 && + this._setPreviewCursor(e.clientX, e.clientY, false); + } + + onPointerDown = (e: React.PointerEvent): void => { + this._downX = e.clientX; + this._downY = e.clientY; + if ((e.button !== 0 || e.altKey) && this.active()) { + this._setPreviewCursor && this._setPreviewCursor(e.clientX, e.clientY, true); + } + } + @computed get annotationLayer() { + return + + } + render() { Doc.UpdateDocumentExtensionForField(this.dataDoc, this.props.fieldKey); - return
+ return (
{this.youtubeVideoId ? this.youtubeContent : this.content} -
; + {this.annotationLayer} + {this.uIButtons} +
); } } diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 29eef27a0..bb4c5adc9 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -91,7 +91,7 @@ export class WebBox extends React.Component { }); SelectionManager.SelectedDocuments().map(dv => { - dv.props.addDocument && dv.props.addDocument(newBox, false); + dv.props.addDocument && dv.props.addDocument(newBox); dv.props.removeDocument && dv.props.removeDocument(dv.props.Document); }); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 65ca830d9..366861144 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -18,7 +18,6 @@ import PDFMenu from "./PDFMenu"; import "./PDFViewer.scss"; import React = require("react"); import * as rp from "request-promise"; -import { CollectionVideoView } from "../collections/CollectionVideoView"; import { CollectionView } from "../collections/CollectionView"; import Annotation from "./Annotation"; import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; @@ -50,10 +49,10 @@ interface IViewerProps { GoToPage?: (n: number) => void; addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; pinToPres: (document: Doc) => void; - addDocument?: (doc: Doc, allowDuplicates?: boolean) => boolean; + addDocument?: (doc: Doc) => boolean; setPdfViewer: (view: PDFViewer) => void; ScreenToLocalTransform: () => Transform; - ContainingCollectionView: Opt; + ContainingCollectionView: Opt; whenActiveChanged: (isActive: boolean) => void; } @@ -582,12 +581,15 @@ export class PDFViewer extends React.Component { } return this.removeDocument(doc) ? addDocument(doc) : false; } - - + @action.bound + addDocument(doc: Doc): boolean { + Doc.GetProto(doc).annotationOn = this.props.Document; + Doc.AddDocToList(this.props.fieldExtensionDoc, this.props.fieldExt, doc); + return true; + } @action.bound removeDocument(doc: Doc): boolean { Doc.GetProto(doc).annotationOn = undefined; - //TODO This won't create the field if it doesn't already exist let targetDataDoc = this.props.fieldExtensionDoc; let targetField = this.props.fieldExt; let value = Cast(targetDataDoc[targetField], listSpec(Doc), []); @@ -659,8 +661,8 @@ export class PDFViewer extends React.Component { whenActiveChanged={this.whenActiveChanged} removeDocument={this.removeDocument} moveDocument={this.moveDocument} - addDocument={(doc: Doc, allow: boolean | undefined) => { Doc.GetProto(doc).annotationOn = this.props.Document; Doc.AddDocToList(this.props.fieldExtensionDoc, this.props.fieldExt, doc); return true; }} - CollectionView={this.props.ContainingCollectionView} + addDocument={this.addDocument} + CollectionView={undefined} ScreenToLocalTransform={this.scrollXf} ruleProvider={undefined} renderDepth={this.props.renderDepth + 1} -- cgit v1.2.3-70-g09d2 From 8efea66fd5723becf36dd6e3b2a95435d8528748 Mon Sep 17 00:00:00 2001 From: bob Date: Mon, 21 Oct 2019 16:16:59 -0400 Subject: got rid of fieldExt from layoutstring. set directly by annotated fields --- src/client/documents/Documents.ts | 11 +++++------ src/client/views/CollectionLinearView.tsx | 7 +------ src/client/views/DocComponent.tsx | 11 ++++++----- src/client/views/MainView.tsx | 1 - src/client/views/collections/CollectionSchemaCells.tsx | 1 - src/client/views/collections/CollectionSubView.tsx | 3 ++- src/client/views/collections/CollectionView.tsx | 2 +- .../collections/collectionFreeForm/CollectionFreeFormView.tsx | 7 ++++--- src/client/views/nodes/DocuLinkBox.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/FieldView.tsx | 5 ++--- src/client/views/nodes/FormattedTextBox.tsx | 7 +++++-- src/client/views/nodes/ImageBox.tsx | 6 +++--- src/client/views/nodes/KeyValuePair.tsx | 1 - src/client/views/nodes/PDFBox.tsx | 4 ++-- src/client/views/nodes/VideoBox.tsx | 5 +++-- src/client/views/nodes/WebBox.tsx | 6 +++--- src/client/views/pdf/PDFViewer.tsx | 3 ++- src/new_fields/Doc.ts | 2 +- 19 files changed, 42 insertions(+), 44 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaCells.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index fd5bea264..937d3c058 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -130,7 +130,6 @@ export namespace Docs { type TemplateMap = Map; type PrototypeMap = Map; const data = "data"; - const anno = "annotations"; const TemplateMap: TemplateMap = new Map([ [DocumentType.TEXT, { @@ -150,11 +149,11 @@ export namespace Docs { options: { nativeWidth: 220, nativeHeight: 300 } }], [DocumentType.IMG, { - layout: { view: ImageBox, ext: anno }, + layout: { view: ImageBox }, options: {} }], [DocumentType.WEB, { - layout: { view: WebBox, ext: anno }, + layout: { view: WebBox }, options: { height: 300 } }], [DocumentType.COL, { @@ -166,7 +165,7 @@ export namespace Docs { options: { height: 150 } }], [DocumentType.VID, { - layout: { view: VideoBox, ext: anno }, + layout: { view: VideoBox }, options: { currentTimecode: 0 }, }], [DocumentType.AUDIO, { @@ -174,7 +173,7 @@ export namespace Docs { options: { height: 32 } }], [DocumentType.PDF, { - layout: { view: PDFBox, ext: anno }, + layout: { view: PDFBox }, options: { nativeWidth: 1200, curPage: 1 } }], [DocumentType.ICON, { @@ -286,7 +285,7 @@ export namespace Docs { // synthesize the default options, the type and title from computed values and // whatever options pertain to this specific prototype let options = { title, type, baseProto: true, ...defaultOptions, ...(template.options || {}) }; - options.layout = layout.view.LayoutString(layout.ext); + options.layout = layout.view.LayoutString(); return Doc.assign(new Doc(prototypeId, true), { ...options, baseLayout: options.layout }); } diff --git a/src/client/views/CollectionLinearView.tsx b/src/client/views/CollectionLinearView.tsx index e8ef20899..c6602b9cb 100644 --- a/src/client/views/CollectionLinearView.tsx +++ b/src/client/views/CollectionLinearView.tsx @@ -1,21 +1,16 @@ import { action, IReactionDisposer, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Doc, HeightSym, WidthSym, DocListCast } from '../../new_fields/Doc'; -import { ObjectField } from '../../new_fields/ObjectField'; +import { Doc, HeightSym, WidthSym } from '../../new_fields/Doc'; import { makeInterface } from '../../new_fields/Schema'; -import { ScriptField } from '../../new_fields/ScriptField'; import { BoolCast, NumCast, StrCast } from '../../new_fields/Types'; import { emptyFunction, returnEmptyString, returnOne, returnTrue, Utils } from '../../Utils'; -import { Docs } from '../documents/Documents'; import { DragManager } from '../util/DragManager'; import { Transform } from '../util/Transform'; import "./CollectionLinearView.scss"; import { CollectionViewType } from './collections/CollectionBaseView'; import { CollectionSubView } from './collections/CollectionSubView'; import { documentSchema, DocumentView } from './nodes/DocumentView'; -import { translate } from 'googleapis/build/src/apis/translate'; -import { DocumentType } from '../documents/DocumentTypes'; type LinearDocument = makeInterface<[typeof documentSchema,]>; diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 1f9bdaac4..2f93d9584 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -55,14 +55,14 @@ interface DocAnnotatableProps { Document: Doc; DataDoc?: Doc; fieldKey: string; - fieldExt: string; whenActiveChanged: (isActive: boolean) => void; isSelected: () => boolean; renderDepth: number; } -export function DocAnnotatableComponent

(schemaCtor: (doc: Doc) => T) { +export function DocAnnotatableComponent

(schemaCtor: (doc: Doc) => T, fieldExt: string) { class Component extends React.Component

{ _isChildActive = false; + _fieldExt = fieldExt; //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then @computed get Document(): T { @@ -70,13 +70,14 @@ export function DocAnnotatableComponent

(schema } @computed get dataDoc() { return (this.props.DataDoc && this.props.Document.isTemplateField ? this.props.DataDoc : Doc.GetProto(this.props.Document)) as Doc; } @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); } + @computed get fieldExt() { return this._fieldExt; } @action.bound removeDocument(doc: Doc): boolean { Doc.GetProto(doc).annotationOn = undefined; - let value = Cast(this.extensionDoc[this.props.fieldExt], listSpec(Doc), []); + let value = this.extensionDoc && Cast(this.extensionDoc[this._fieldExt], listSpec(Doc), []); let index = value ? Doc.IndexOf(doc, value.map(d => d as Doc), true) : -1; - return index !== -1 && value.splice(index, 1) ? true : false; + return index !== -1 && value && value.splice(index, 1) ? true : false; } // if the moved document is already in this overlay collection nothing needs to be done. // otherwise, if the document can be removed from where it was, it will then be added to this document's overlay collection. @@ -87,7 +88,7 @@ export function DocAnnotatableComponent

(schema @action.bound addDocument(doc: Doc): boolean { Doc.GetProto(doc).annotationOn = this.props.Document; - return Doc.AddDocToList(this.extensionDoc, this.props.fieldExt, doc); + return this.extensionDoc && Doc.AddDocToList(this.extensionDoc, this._fieldExt, doc) ? true : false; } whenActiveChanged = (isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 4c2b6f262..68efcb000 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -478,7 +478,6 @@ export class MainView extends React.Component { Document={CurrentUserUtils.UserDocument.expandingButtons} DataDoc={undefined} fieldKey={"data"} - fieldExt={""} select={emptyFunction} chromeCollapsed={true} active={returnFalse} diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 79c032723..54a36f691 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -144,7 +144,6 @@ export class CollectionSchemaCell extends React.Component { Document: this.props.rowProps.original, DataDoc: this.props.rowProps.original, fieldKey: this.props.rowProps.column.id as string, - fieldExt: "", ruleProvider: undefined, ContainingCollectionView: this.props.CollectionView, ContainingCollectionDoc: this.props.CollectionView && this.props.CollectionView.props.Document, diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 43147ed20..7f16fe9e0 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -41,6 +41,7 @@ export interface SubCollectionViewProps extends CollectionViewProps { ruleProvider: Doc | undefined; children?: never | (() => JSX.Element[]) | React.ReactNode; isAnnotationOverlay?: boolean; + fieldExt: string; } export function CollectionSubView(schemaCtor: (doc: Doc) => T) { @@ -78,7 +79,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { // to its children which may be templates. // The name of the data field comes from fieldExt if it's an extension, or fieldKey otherwise. @computed get dataField() { - return this.props.fieldExt ? this.extensionDoc[this.props.fieldExt] : this.dataDoc[this.props.fieldKey]; + return this.props.fieldExt ? (this.extensionDoc ? this.extensionDoc[this.props.fieldExt] : undefined) : this.dataDoc[this.props.fieldKey]; } get childLayoutPairs() { diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 74a388425..e425ea66a 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -32,7 +32,7 @@ library.add(faTh, faTree, faSquare, faProjectDiagram, faSignature, faThList, faF @observer export class CollectionView extends React.Component { - public static LayoutString(fieldStr: string = "data", fieldExt: string = "") { return FieldView.LayoutString(CollectionView, fieldStr, fieldExt); } + public static LayoutString(fieldStr: string = "data") { return FieldView.LayoutString(CollectionView, fieldStr); } private _reactionDisposer: IReactionDisposer | undefined; @observable private _isLightboxOpen = false; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 33d6b1358..2e534b6b2 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -685,9 +685,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { getContainerTransform={this.getContainerTransform} getTransform={this.getTransform} isAnnotationOverlay={this.isAnnotationOverlay}> - - {this.childViews} - + {!this.extensionDoc ? (null) : + + {this.childViews} + } diff --git a/src/client/views/nodes/DocuLinkBox.tsx b/src/client/views/nodes/DocuLinkBox.tsx index 3294a5aa2..22e44948a 100644 --- a/src/client/views/nodes/DocuLinkBox.tsx +++ b/src/client/views/nodes/DocuLinkBox.tsx @@ -18,7 +18,7 @@ const DocLinkDocument = makeInterface(documentSchema); @observer export class DocuLinkBox extends DocComponent(DocLinkDocument) { - public static LayoutString(fieldKey: string, fieldExt?: string) { return FieldView.LayoutString(DocuLinkBox, fieldKey, fieldExt); } + public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DocuLinkBox, fieldKey); } _downx = 0; _downy = 0; @observable _x = 0; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 089ec77ba..9e36f0811 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -660,7 +660,7 @@ export class DocumentView extends DocComponent(Docu ); const titleView = (!showTitle ? (null) : diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 3b9627efc..7d69b5b51 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -24,7 +24,6 @@ import { ScriptField } from "../../../new_fields/ScriptField"; // export interface FieldViewProps { fieldKey: string; - fieldExt: string; fitToBox?: boolean; ContainingCollectionView: Opt; ContainingCollectionDoc: Opt; @@ -53,8 +52,8 @@ export interface FieldViewProps { @observer export class FieldView extends React.Component { - public static LayoutString(fieldType: { name: string }, fieldStr: string = "data", fieldExt: string = "") { - return `<${fieldType.name} {...props} fieldKey={"${fieldStr}"} fieldExt={"${fieldExt}"} />`; + public static LayoutString(fieldType: { name: string }, fieldStr: string = "data") { + return `<${fieldType.name} {...props} fieldKey={"${fieldStr}"}/>`; //"" } diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 020442bf3..b12ca60c9 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -727,8 +727,11 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe DocServer.GetRefField(pdfRegionId).then(pdfRegion => { if ((pdfDoc instanceof Doc) && (pdfRegion instanceof Doc)) { setTimeout(async () => { - let targetAnnotations = await DocListCastAsync(Doc.fieldExtensionDoc(pdfDoc, "data").annotations);// bcz: NO... this assumes the pdf is using its 'data' field. need to have the PDF's view handle updating its own annotations - targetAnnotations && targetAnnotations.push(pdfRegion); + const extension = Doc.fieldExtensionDoc(pdfDoc, "data"); + if (extension) { + let targetAnnotations = await DocListCastAsync(extension.annotations);// bcz: NO... this assumes the pdf is using its 'data' field. need to have the PDF's view handle updating its own annotations + targetAnnotations && targetAnnotations.push(pdfRegion); + } }); let link = DocUtils.MakeLink({ doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, { doc: pdfRegion, ctx: pdfDoc }, "note on " + pdfDoc.title, "pasted PDF link"); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index d80e222c2..540c1bae8 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -54,8 +54,8 @@ type ImageDocument = makeInterface<[typeof pageSchema, typeof documentSchema]>; const ImageDocument = makeInterface(pageSchema, documentSchema); @observer -export class ImageBox extends DocAnnotatableComponent(ImageDocument) { - public static LayoutString(fieldExt?: string) { return FieldView.LayoutString(ImageBox, "data", fieldExt); } +export class ImageBox extends DocAnnotatableComponent(ImageDocument, "annotations") { + public static LayoutString(fieldKey: string = "data") { return FieldView.LayoutString(ImageBox, fieldKey); } private _imgRef: React.RefObject = React.createRef(); private _dropDisposer?: DragManager.DragDropDisposer; @observable private _audioState = 0; @@ -330,7 +330,7 @@ export class ImageBox extends DocAnnotatableComponent { ContainingCollectionDoc: undefined, ruleProvider: undefined, fieldKey: this.props.keyName, - fieldExt: "", isSelected: returnFalse, select: emptyFunction, renderDepth: 1, diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 78858731f..dab602a29 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -26,8 +26,8 @@ type PdfDocument = makeInterface<[typeof documentSchema, typeof panZoomSchema, t const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema); @observer -export class PDFBox extends DocAnnotatableComponent(PdfDocument) { - public static LayoutString(fieldExt?: string) { return FieldView.LayoutString(PDFBox, "data", fieldExt); } +export class PDFBox extends DocAnnotatableComponent(PdfDocument, "annotations") { + public static LayoutString(fieldKey: string = "data") { return FieldView.LayoutString(PDFBox, fieldKey); } private _keyValue: string = ""; private _valueValue: string = ""; private _scriptValue: string = ""; diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 5e8154233..64871ef41 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -35,7 +35,7 @@ const VideoDocument = makeInterface(documentSchema, positionSchema, timeSchema); library.add(faVideo); @observer -export class VideoBox extends DocAnnotatableComponent(VideoDocument) { +export class VideoBox extends DocAnnotatableComponent(VideoDocument, "annotations") { static _youtubeIframeCounter: number = 0; private _reactionDisposer?: IReactionDisposer; private _youtubeReactionDisposer?: IReactionDisposer; @@ -49,7 +49,7 @@ export class VideoBox extends DocAnnotatableComponent; const WebDocument = makeInterface(documentSchema); @observer -export class WebBox extends DocAnnotatableComponent(WebDocument) { +export class WebBox extends DocAnnotatableComponent(WebDocument, "annotations") { - public static LayoutString(fieldExt?: string) { return FieldView.LayoutString(WebBox, "data", fieldExt); } + public static LayoutString(fieldKey: string = "data") { return FieldView.LayoutString(WebBox, fieldKey); } @observable private collapsed: boolean = true; @observable private url: string = ""; @@ -199,7 +199,7 @@ export class WebBox extends DocAnnotatableComponent (PdfDocument) { +export class PDFViewer extends DocAnnotatableComponent(PdfDocument, "annotations") { static _annotationStyle: any = addStyleSheet(); @observable private _pageSizes: { width: number, height: number }[] = []; @observable private _annotations: Doc[] = []; @@ -632,6 +632,7 @@ export class PDFViewer extends DocAnnotatableComponent)}

(this.Document.scrollHeight || this.Document.nativeHeight || 0)} PanelWidth={() => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : (this.Document.nativeWidth || 0)} diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index f60a2e720..c6f654c33 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -468,7 +468,7 @@ export namespace Doc { export function fieldExtensionDoc(doc: Doc, fieldKey: string) { let extension = doc[fieldKey + "_ext"] as Doc; (extension === undefined) && setTimeout(() => CreateDocumentExtensionForField(doc, fieldKey), 0); - return extension ? extension : doc; + return extension ? extension : undefined; } export function CreateDocumentExtensionForField(doc: Doc, fieldKey: string) { -- cgit v1.2.3-70-g09d2