diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/collections/CollectionSchemaView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionStackingView.tsx | 7 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentContentsView.tsx | 29 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 33 |
4 files changed, 41 insertions, 30 deletions
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index b54e8aff0..148711c97 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -405,6 +405,7 @@ interface CollectionSchemaPreviewProps { renderDepth: number; width: () => number; height: () => number; + showOverlays?: (doc: Doc) => { title?: boolean, caption?: boolean }; CollectionView?: CollectionView | CollectionPDFView | CollectionVideoView; getTransform: () => Transform; addDocument: (document: Doc, allowDuplicates?: boolean) => boolean; @@ -488,6 +489,7 @@ export class CollectionSchemaPreview extends React.Component<CollectionSchemaPre fitToBox={this.props.fitToBox} renderDepth={this.props.renderDepth + 1} selectOnLoad={false} + showOverlays={this.props.showOverlays} addDocument={this.props.addDocument} removeDocument={this.props.removeDocument} moveDocument={this.props.moveDocument} diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index aea74321e..e6a3e8b68 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -12,6 +12,7 @@ import "./CollectionStackingView.scss"; import { CollectionSubView } from "./CollectionSubView"; import { undoBatch } from "../../util/UndoManager"; import { DragManager } from "../../util/DragManager"; +import { DocTypes } from "../../documents/Documents"; @observer export class CollectionStackingView extends CollectionSubView(doc => doc) { @@ -61,6 +62,10 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { this.createDropTarget(ele!); } + overlays = (doc: Doc) => { + return doc.type === DocTypes.IMG ? { title: true, caption: true } : {} + } + @computed get singleColumnChildren() { return this.filteredChildren.map((d, i) => { @@ -75,6 +80,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { <CollectionSchemaPreview Document={layoutDoc} DataDocument={d !== this.props.DataDoc ? this.props.DataDoc : undefined} + showOverlays={this.overlays} renderDepth={this.props.renderDepth} width={width} height={height} @@ -122,6 +128,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { addDocument={this.props.addDocument} moveDocument={this.props.moveDocument} removeDocument={this.props.removeDocument} + showOverlays={this.overlays} getTransform={dxf} width={width} height={height} diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index eb786d537..ed6b224a7 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -89,34 +89,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & { return new List<string>(); } @computed get finalLayout() { - const baseLayout = this.props.layoutKey === "overlayLayout" ? "<div/>" : this.layout; - let base = baseLayout; - let layout = baseLayout; - - // bcz: templates are intended only for a document's primary layout or overlay (not background). However, - // a DocumentContentsView is used to render annotation overlays, so we detect that here - // by checking the layoutKey. This should probably be moved into - // a prop so that the overlay can explicitly turn off templates. - if ((this.props.layoutKey === "overlayLayout" && StrCast(this.props.Document.layout).indexOf("CollectionView") !== -1) || - (this.props.layoutKey === "layout" && StrCast(this.props.Document.layout).indexOf("CollectionView") === -1) || - (this.props.layoutKey === "layout" && NumCast(this.props.Document.viewType)) !== CollectionViewType.Freeform) { - this.templates.forEach(template => { - let self = this; - // this scales constants in the markup by the scaling applied to the document, but caps the constants to be smaller - // than the width/height of the containing document - function convertConstantsToNative(match: string, offset: number, x: string) { - let px = Number(match.replace("px", "")); - return `${Math.min(NumCast(self.props.Document.height, 0), - Math.min(NumCast(self.props.Document.width, 0), - px * self.props.ScreenToLocalTransform().Scale))}px`; - } - // let nativizedTemplate = template.replace(/([0-9]+)px/g, convertConstantsToNative); - // layout = nativizedTemplate.replace("{layout}", base); - layout = template.replace("{layout}", base); - base = layout; - }); - } - return layout; + return this.props.layoutKey === "overlayLayout" ? "<div/>" : this.layout; } render() { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 430409ee3..5385238f0 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -8,7 +8,7 @@ import { ObjectField } from "../../../new_fields/ObjectField"; import { createSchema, makeInterface, listSpec } from "../../../new_fields/Schema"; import { BoolCast, Cast, FieldValue, StrCast, NumCast, PromiseValue } from "../../../new_fields/Types"; import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; -import { emptyFunction, Utils } from "../../../Utils"; +import { emptyFunction, Utils, returnFalse, returnTrue } from "../../../Utils"; import { DocServer } from "../../DocServer"; import { Docs, DocUtils } from "../../documents/Documents"; import { DocumentManager } from "../../util/DocumentManager"; @@ -34,6 +34,7 @@ import { ContextMenuProps } from '../ContextMenuItem'; import { list, object, createSimpleSchema } from 'serializr'; import { LinkManager } from '../../util/LinkManager'; import { RouteStore } from '../../../server/RouteStore'; +import { FormattedTextBox } from './FormattedTextBox'; const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? library.add(fa.faTrash); @@ -78,6 +79,7 @@ export interface DocumentViewProps { moveDocument?: (doc: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean; ScreenToLocalTransform: () => Transform; renderDepth: number; + showOverlays?: (doc: Doc) => { title?: boolean, caption?: boolean }; ContentScaling: () => number; PanelWidth: () => number; PanelHeight: () => number; @@ -593,6 +595,15 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu let foregroundColor = StrCast(this.props.Document.layout instanceof Doc ? this.props.Document.layout.color : this.props.Document.color); var nativeWidth = this.nativeWidth > 0 ? `${this.nativeWidth}px` : "100%"; var nativeHeight = BoolCast(this.props.Document.ignoreAspect) ? this.props.PanelHeight() / this.props.ContentScaling() : this.nativeHeight > 0 ? `${this.nativeHeight}px` : "100%"; + let showTitle = this.props.showOverlays && this.props.showOverlays(this.props.Document).title; + let showCaption = this.props.showOverlays && this.props.showOverlays(this.props.Document).caption; + let templates = Cast(this.props.Document.templates, listSpec("string")); + if (templates instanceof List) { + templates.map(str => { + if (str.indexOf("{props.Document.title}") !== -1) showTitle = true; + if (str.indexOf("fieldKey={\"caption\"}") !== -1) showCaption = true; + }); + } return ( <div className={`documentView-node${this.topMost ? "-topmost" : ""}`} ref={this._mainCont} @@ -614,7 +625,25 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu onDrop={this.onDrop} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave} > - {this.contents} + {!showTitle && !showCaption ? this.contents : + <div style={{ position: "absolute", display: "inline-block", width: "100%", height: "100%", pointerEvents: "none" }}> + {!showTitle ? (null) : + <div style={{ + position: "absolute", top: 0, textAlign: "center", textOverflow: "ellipsis", whiteSpace: "pre", + overflow: "hidden", width: `${100 * this.props.ContentScaling()}%`, height: 25, background: "rgba(0, 0, 0, .4)", color: "white", + transformOrigin: "top left", transform: `scale(${1 / this.props.ContentScaling()})` + }}> + <span>{this.props.Document.title}</span> + </div> + } + {!showCaption ? (null) : + <div style={{ position: "absolute", bottom: 0, transformOrigin: "bottom left", width: `${100 * this.props.ContentScaling()}%`, transform: `scale(${1 / this.props.ContentScaling()})` }}> + <FormattedTextBox {...this.props} DataDoc={this.dataDoc} active={returnTrue} isSelected={this.isSelected} focus={emptyFunction} select={this.select} selectOnLoad={this.props.selectOnLoad} fieldExt={""} hideOnLeave={true} fieldKey={"caption"} /> + </div> + } + {this.contents} + </div> + } </div> ); } |