aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/MainView.tsx2
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx1
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx6
-rw-r--r--src/client/views/nodes/AudioBox.tsx25
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx59
-rw-r--r--src/client/views/nodes/DocuLinkBox.tsx5
-rw-r--r--src/client/views/nodes/DocumentView.scss139
-rw-r--r--src/client/views/nodes/DocumentView.tsx112
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx2
-rw-r--r--src/client/views/nodes/ImageBox.tsx2
-rw-r--r--src/client/views/nodes/PDFBox.scss1
-rw-r--r--src/client/views/nodes/PDFBox.tsx57
-rw-r--r--src/client/views/pdf/PDFViewer.tsx23
13 files changed, 197 insertions, 237 deletions
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 180e02e7e..68f5d5446 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -38,6 +38,7 @@ import PDFMenu from './pdf/PDFMenu';
import { PreviewCursor } from './PreviewCursor';
import { Scripting } from '../util/Scripting';
import { LinkManager } from '../util/LinkManager';
+import { AudioBox } from './nodes/AudioBox';
@observer
export class MainView extends React.Component {
@@ -137,6 +138,7 @@ export class MainView extends React.Component {
globalPointerDown = action((e: PointerEvent) => {
this.isPointerDown = true;
+ AudioBox.AudioEnabled = true;
const targets = document.elementsFromPoint(e.x, e.y);
if (targets && targets.length && targets[0].className.toString().indexOf("contextMenu") === -1) {
ContextMenu.Instance.closeMenu();
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 7f0165ad4..37d897088 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -393,7 +393,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
let entries = Array.from(this.Sections.entries());
sections = entries.sort(this.sortFunc);
}
- console.log("NUM = " + this.numGroupColumns);
return (
<div className="collectionStackingMasonry-cont" >
<div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 47c355fc8..89cc69ccf 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -221,10 +221,10 @@ class TreeView extends React.Component<TreeViewProps> {
}
let movedDocs = (de.data.options === this.props.treeViewId ? de.data.draggedDocuments : de.data.droppedDocuments);
return (de.data.dropAction || de.data.userDropAction) ?
- de.data.droppedDocuments.reduce((added, d) => this.props.addDocument(d, undefined, before) || added, false)
+ de.data.droppedDocuments.reduce((added, d) => addDoc(d) || added, false)
: de.data.moveDocument ?
movedDocs.reduce((added, d) => de.data.moveDocument(d, undefined, addDoc) || added, false)
- : de.data.droppedDocuments.reduce((added, d) => this.props.addDocument(d, undefined, before), false);
+ : de.data.droppedDocuments.reduce((added, d) => addDoc(d), false);
}
return false;
}
@@ -474,7 +474,7 @@ class TreeView extends React.Component<TreeViewProps> {
let aspect = NumCast(childLayout.nativeWidth, 0) / NumCast(childLayout.nativeHeight, 0);
return aspect ? Math.min(childLayout[WidthSym](), rowWidth()) / aspect : childLayout[HeightSym]();
};
- return <TreeView
+ return !(child instanceof Doc) ? (null) : <TreeView
document={pair.layout}
dataDoc={pair.data}
containingCollection={containingCollection}
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 268255b46..86bd23b67 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -37,6 +37,7 @@ const AudioDocument = makeInterface(documentSchema, audioSchema);
@observer
export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocument>(AudioDocument) {
public static LayoutString(fieldKey: string) { return FieldView.LayoutString(AudioBox, fieldKey); }
+ public static Enabled = false;
_linkPlayDisposer: IReactionDisposer | undefined;
_reactionDisposer: IReactionDisposer | undefined;
@@ -98,7 +99,7 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
});
playFrom = (seekTimeInSeconds: number) => {
- if (this._ele) {
+ if (this._ele && AudioBox.Enabled) {
if (seekTimeInSeconds < 0) {
this.pause();
} else if (seekTimeInSeconds <= this._ele.duration) {
@@ -193,6 +194,7 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
setRef = (e: HTMLAudioElement | null) => {
e && e.addEventListener("timeupdate", this.timecodeChanged);
+ e && e.addEventListener("ended", this.pause);
this._ele = e;
}
@@ -242,16 +244,17 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
la2 = l.anchor1 as Doc;
linkTime = NumCast(l.anchor1Timecode);
}
- return !linkTime ? (null) : <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container"} style={{ left: `${linkTime / NumCast(this.dataDoc.duration, 1) * 100}%` }}>
- <div className={this.props.PanelHeight() < 32 ? "audioBox-linker-mini" : "audioBox-linker"} key={"linker" + i}>
- <DocumentView {...this.props} Document={l} layoutKey={Doc.LinkEndpoint(l, la2)}
- parentActive={returnTrue} bringToFront={emptyFunction} zoomToScale={emptyFunction} getScale={returnOne}
- backgroundColor={returnTransparent} />
- </div>
- <div key={i} className="audiobox-marker" onPointerEnter={() => Doc.linkFollowHighlight(la1)}
- onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { this.playFrom(linkTime); e.stopPropagation(); } }}
- onClick={e => { if (e.button === 0 && !e.ctrlKey) { this.pause(); e.stopPropagation(); } }} />
- </div>;
+ return !linkTime ? (null) :
+ <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container"} key={l[Id]} style={{ left: `${linkTime / NumCast(this.dataDoc.duration, 1) * 100}%` }}>
+ <div className={this.props.PanelHeight() < 32 ? "audioBox-linker-mini" : "audioBox-linker"} key={"linker" + i}>
+ <DocumentView {...this.props} Document={l} layoutKey={Doc.LinkEndpoint(l, la2)}
+ parentActive={returnTrue} bringToFront={emptyFunction} zoomToScale={emptyFunction} getScale={returnOne}
+ backgroundColor={returnTransparent} />
+ </div>
+ <div key={i} className="audiobox-marker" onPointerEnter={() => Doc.linkFollowHighlight(la1)}
+ onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { this.playFrom(linkTime); e.stopPropagation(); } }}
+ onClick={e => { if (e.button === 0 && !e.ctrlKey) { this.pause(); e.stopPropagation(); } }} />
+ </div>;
})}
<div className="audiobox-current" style={{ left: `${NumCast(this.Document.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} />
{this.audio}
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 58cb831f8..a035bdc3d 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,10 +1,9 @@
import { random } from "animejs";
-import { computed, IReactionDisposer, observable, reaction } from "mobx";
+import { computed, IReactionDisposer, observable, reaction, trace } from "mobx";
import { observer } from "mobx-react";
import { Doc, HeightSym, WidthSym } from "../../../new_fields/Doc";
import { listSpec } from "../../../new_fields/Schema";
import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { percent2frac } from "../../../Utils";
import { Transform } from "../../util/Transform";
import { DocComponent } from "../DocComponent";
import "./CollectionFreeFormDocumentView.scss";
@@ -71,12 +70,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
let ruleRounding = this.props.ruleProvider ? StrCast(this.props.ruleProvider["ruleRounding_" + this.Document.heading]) : undefined;
let ld = this.layoutDoc[StrCast(this.layoutDoc.layoutKey, "layout")] instanceof Doc ? this.layoutDoc[StrCast(this.layoutDoc.layoutKey, "layout")] as Doc : undefined;
let br = StrCast((ld || this.props.Document).borderRounding);
- br = !br && ruleRounding ? ruleRounding : br;
- if (br.endsWith("%")) {
- let nativeDim = Math.min(NumCast(this.layoutDoc.nativeWidth), NumCast(this.layoutDoc.nativeHeight));
- return percent2frac(br) * (nativeDim ? nativeDim : Math.min(this.props.PanelWidth(), this.props.PanelHeight()));
- }
- return undefined;
+ return !br && ruleRounding ? ruleRounding : br;
}
@computed
@@ -90,30 +84,29 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
finalPanelHeight = () => this.dataProvider ? this.dataProvider.height : this.panelHeight();
render() {
- return (
- <div className="collectionFreeFormDocumentView-container"
- style={{
- boxShadow:
- this.layoutDoc.opacity === 0 ? undefined : // if it's not visible, then no shadow
- this.layoutDoc.z ? `#9c9396 ${StrCast(this.layoutDoc.boxShadow, "10px 10px 0.9vw")}` : // if it's a floating doc, give it a big shadow
- this.clusterColor ? (`${this.clusterColor} ${StrCast(this.layoutDoc.boxShadow, `0vw 0vw ${(this.layoutDoc.isBackground ? 100 : 50) / this.props.ContentScaling()}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent
- this.layoutDoc.isBackground ? `1px 1px 1px ${this.clusterColor}` : // if it's a background & has a cluster color, make the shadow spread really big
- StrCast(this.layoutDoc.boxShadow, ""),
- borderRadius: this.borderRounding(),
- transform: this.transform,
- transition: this.Document.isAnimating !== undefined ? ".5s ease-in" : this.props.transition ? this.props.transition : this.dataProvider ? this.dataProvider.transition : StrCast(this.layoutDoc.transition),
- width: this.width,
- height: this.height,
- zIndex: this.Document.zIndex || 0,
- }} >
- <DocumentView {...this.props}
- ContentScaling={this.contentScaling}
- ScreenToLocalTransform={this.getTransform}
- backgroundColor={this.clusterColorFunc}
- PanelWidth={this.finalPanelWidth}
- PanelHeight={this.finalPanelHeight}
- />
- </div>
- );
+ trace();
+ return <div className="collectionFreeFormDocumentView-container"
+ style={{
+ boxShadow:
+ this.layoutDoc.opacity === 0 ? undefined : // if it's not visible, then no shadow
+ this.layoutDoc.z ? `#9c9396 ${StrCast(this.layoutDoc.boxShadow, "10px 10px 0.9vw")}` : // if it's a floating doc, give it a big shadow
+ this.clusterColor ? (`${this.clusterColor} ${StrCast(this.layoutDoc.boxShadow, `0vw 0vw ${(this.layoutDoc.isBackground ? 100 : 50) / this.props.ContentScaling()}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent
+ this.layoutDoc.isBackground ? `1px 1px 1px ${this.clusterColor}` : // if it's a background & has a cluster color, make the shadow spread really big
+ StrCast(this.layoutDoc.boxShadow, ""),
+ borderRadius: this.borderRounding(),
+ transform: this.transform,
+ transition: this.Document.isAnimating !== undefined ? ".5s ease-in" : this.props.transition ? this.props.transition : this.dataProvider ? this.dataProvider.transition : StrCast(this.layoutDoc.transition),
+ width: this.width,
+ height: this.height,
+ zIndex: this.Document.zIndex || 0,
+ }} >
+ <DocumentView {...this.props}
+ ContentScaling={this.contentScaling}
+ ScreenToLocalTransform={this.getTransform}
+ backgroundColor={this.clusterColorFunc}
+ PanelWidth={this.finalPanelWidth}
+ PanelHeight={this.finalPanelHeight}
+ />
+ </div>;
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/DocuLinkBox.tsx b/src/client/views/nodes/DocuLinkBox.tsx
index f4c7d43aa..d73407903 100644
--- a/src/client/views/nodes/DocuLinkBox.tsx
+++ b/src/client/views/nodes/DocuLinkBox.tsx
@@ -72,7 +72,10 @@ export class DocuLinkBox extends DocComponent<FieldViewProps, DocLinkSchema>(Doc
let y = NumCast(this.props.Document[this.props.fieldKey + "_y"], 100);
let x = NumCast(this.props.Document[this.props.fieldKey + "_x"], 100);
let c = StrCast(this.props.Document.backgroundColor, "lightblue");
- return <div className="docuLinkBox-cont" onPointerDown={this.onPointerDown} onClick={this.onClick} title={StrCast((this.props.Document[this.props.fieldKey === "anchor1" ? "anchor2" : "anchor1"]! as Doc).title)}
+ let anchor = this.props.fieldKey === "anchor1" ? "anchor2" : "anchor1";
+ let timecode = this.props.Document[anchor + "Timecode"];
+ let targetTitle = StrCast((this.props.Document[anchor]! as Doc).title) + (timecode !== undefined ? ":" + timecode : "");
+ return <div className="docuLinkBox-cont" onPointerDown={this.onPointerDown} onClick={this.onClick} title={targetTitle}
ref={this._ref} style={{
background: c, left: `calc(${x}% - 12.5px)`, top: `calc(${y}% - 12.5px)`,
transform: `scale(${hasAnchor ? 0.333 : 1 / this.props.ContentScaling()})`
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index a0bf74990..65df86d27 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -1,89 +1,82 @@
@import "../globalCssVariables";
.documentView-node, .documentView-node-topmost {
- position: inherit;
- top: 0;
- left:0;
- border-radius: inherit;
- transition : outline .3s linear;
- cursor: grab;
-
- // background: $light-color; //overflow: hidden;
- transform-origin: left top;
+ position: inherit;
+ top: 0;
+ left:0;
+ border-radius: inherit;
+ transition : outline .3s linear;
+ cursor: grab;
+
+ // background: $light-color; //overflow: hidden;
+ transform-origin: left top;
- &.minimized {
- width: 30px;
- height: 30px;
- }
+ &.minimized {
+ width: 30px;
+ height: 30px;
+ }
- .top {
- height: 20px;
- cursor: pointer;
- }
+ .top {
+ height: 20px;
+ cursor: pointer;
+ }
- .content {
- padding: 20px 20px;
- height: auto;
- box-sizing: border-box;
- }
+ .content {
+ padding: 20px 20px;
+ height: auto;
+ box-sizing: border-box;
+ }
- .scroll-box {
- overflow-y: scroll;
- height: calc(100% - 20px);
- }
+ .scroll-box {
+ overflow-y: scroll;
+ height: calc(100% - 20px);
+ }
- .documentView-overlays {
- border-radius: inherit;
- position: absolute;
- display: inline-block;
- width: 100%;
- height: 100%;
- pointer-events: none;
- .documentView-textOverlay {
- border-radius: inherit;
- width: 100%;
- display: inline-block;
+ .documentView-docuLinkWrapper {
+ pointer-events: none;
position: absolute;
+ transform-origin: top left;
+ width: 100%;
+ height: 100%;
}
- }
-}
+ .documentView-styleWrapper {
+ position: absolute;
+ display: inline-block;
+ width:100%;
+ height:100%;
+ pointer-events: none;
-.documentView-styleWrapper {
- position: absolute;
- display: inline-block;
- width:100%;
- height:100%;
- pointer-events: none;
+ .documentView-styleContentWrapper {
+ width:100%;
+ display: inline-block;
+ position: absolute;
+ }
+ .documentView-titleWrapper {
+ overflow:hidden;
+ color: white;
+ transform-origin: top left;
+ top: 0;
+ height: 25;
+ background: rgba(0, 0, 0, .4);
+ padding: 4px;
+ text-align: center;
+ text-overflow: ellipsis;
+ white-space: pre;
+ }
- .documentView-styleContentWrapper {
- width:100%;
- display: inline-block;
- position: absolute;
- }
- .documentView-titleWrapper {
- overflow:hidden;
- color: white;
- transform-origin: top left;
- top: 0;
- height: 25;
- background: rgba(0, 0, 0, .4);
- padding: 4px;
- text-align: center;
- text-overflow: ellipsis;
- white-space: pre;
- }
+ .documentView-searchHighlight {
+ position: absolute;
+ background: yellow;
+ bottom: -20px;
+ border-radius: 5px;
+ transform-origin: bottom left;
+ }
- .documentView-searchHighlight {
- position: absolute;
- background: yellow;
- bottom: -20px;
- border-radius: 5px;
- transform-origin: bottom left;
+ .documentView-captionWrapper {
+ position: absolute;
+ bottom: 0;
+ transform-origin: bottom left;
+ }
}
- .documentView-captionWrapper {
- position: absolute;
- bottom: 0;
- transform-origin: bottom left;
- }
} \ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 11066145b..c091f1260 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,6 +1,6 @@
import { library } from '@fortawesome/fontawesome-svg-core';
import * as fa from '@fortawesome/free-solid-svg-icons';
-import { action, computed, runInAction } from "mobx";
+import { action, computed, runInAction, trace } from "mobx";
import { observer } from "mobx-react";
import * as rp from "request-promise";
import { Doc, DocListCast, DocListCastAsync, Opt } from "../../../new_fields/Doc";
@@ -41,30 +41,10 @@ import { DocumentContentsView } from "./DocumentContentsView";
import "./DocumentView.scss";
import { FormattedTextBox } from './FormattedTextBox';
import React = require("react");
-import { link } from 'fs';
-
-library.add(fa.faEdit);
-library.add(fa.faTrash);
-library.add(fa.faShare);
-library.add(fa.faDownload);
-library.add(fa.faExpandArrowsAlt);
-library.add(fa.faCompressArrowsAlt);
-library.add(fa.faLayerGroup);
-library.add(fa.faExternalLinkAlt);
-library.add(fa.faAlignCenter);
-library.add(fa.faCaretSquareRight);
-library.add(fa.faSquare);
-library.add(fa.faConciergeBell);
-library.add(fa.faWindowRestore);
-library.add(fa.faFolder);
-library.add(fa.faMapPin);
-library.add(fa.faLink);
-library.add(fa.faFingerprint);
-library.add(fa.faCrosshairs);
-library.add(fa.faDesktop);
-library.add(fa.faUnlock);
-library.add(fa.faLock);
-library.add(fa.faLaptopCode, fa.faMale, fa.faCopy, fa.faHandPointRight, fa.faCompass, fa.faSnowflake, fa.faMicrophone);
+
+library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight,
+ fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale,
+ fa.faCopy, fa.faHandPointRight, fa.faCompass, fa.faSnowflake, fa.faMicrophone);
export interface DocumentViewProps {
ContainingCollectionView: Opt<CollectionView>;
@@ -599,6 +579,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
render() {
if (!this.props.Document) return (null);
+ trace();
const animDims = this.Document.animateToDimensions ? Array.from(this.Document.animateToDimensions) : undefined;
const ruleColor = this.props.ruleProvider ? StrCast(this.props.ruleProvider["ruleColor_" + this.Document.heading]) : undefined;
const ruleRounding = this.props.ruleProvider ? StrCast(this.props.ruleProvider["ruleRounding_" + this.Document.heading]) : undefined;
@@ -631,10 +612,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
</div>);
const titleView = (!showTitle ? (null) :
<div className="documentView-titleWrapper" style={{
+ width: `${100 * this.props.ContentScaling()}%`, transform: `scale(${1 / this.props.ContentScaling()})`,
position: showTextTitle ? "relative" : "absolute",
pointerEvents: SelectionManager.GetIsDragging() ? "none" : "all",
- width: `${100 * this.props.ContentScaling()}%`,
- transform: `scale(${1 / this.props.ContentScaling()})`
}}>
<EditableView
contents={this.Document[showTitle]}
@@ -649,48 +629,46 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
const highlightColors = ["transparent", "maroon", "maroon", "yellow", "magenta", "cyan", "orange"];
const highlightStyles = ["solid", "dashed", "solid", "solid", "solid", "solid", "solid", "solid"];
let highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc.viewType !== CollectionViewType.Linear;
- return (
- <div className={`documentView-node${this.topMost ? "-topmost" : ""}`}
- ref={this._mainCont}
- style={{
- transition: this.Document.isAnimating !== undefined ? ".5s linear" : StrCast(this.Document.transition),
- pointerEvents: this.Document.isBackground && !this.isSelected() ? "none" : "all",
- color: StrCast(this.Document.color),
- outline: highlighting && !borderRounding ? `${highlightColors[fullDegree]} ${highlightStyles[fullDegree]} ${localScale}px` : "solid 0px",
- border: highlighting && borderRounding ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined,
- background: this.layoutDoc.type === DocumentType.FONTICON || this.layoutDoc.viewType === CollectionViewType.Linear ? undefined : backgroundColor,
- width: animwidth,
- height: animheight,
- transform: `scale(${this.layoutDoc.fitWidth ? 1 : this.props.ContentScaling()})`,
- opacity: this.Document.opacity
- }}
- onDrop={this.onDrop} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick}
- onPointerEnter={() => Doc.BrushDoc(this.props.Document)} onPointerLeave={() => Doc.UnBrushDoc(this.props.Document)}
- >
- {this.Document.links && DocListCast(this.Document.links).filter((d) => !DocListCast(this.layoutDoc.hiddenLinks).some(hidden => Doc.AreProtosEqual(hidden, d))).filter(this.isNonTemporalLink).map((d, i) =>
- <div style={{ pointerEvents: "none", position: "absolute", transformOrigin: "top left", width: "100%", height: "100%", transform: `scale(${this.layoutDoc.fitWidth ? 1 : 1 / this.props.ContentScaling()})` }}>
- <DocumentView {...this.props} backgroundColor={returnTransparent} Document={d} removeDocument={undoBatch((doc: Doc) => Doc.AddDocToList(this.layoutDoc, "hiddenLinks", doc))} layoutKey={this.linkEndpoint(d)} />
- </div>)}
- {!showTitle && !showCaption ?
- this.Document.searchFields ?
- (<div className="documentView-searchWrapper">
- {this.contents}
- {searchHighlight}
- </div>)
- :
- this.contents
- :
- <div className="documentView-styleWrapper" >
- <div className="documentView-styleContentWrapper" style={{ height: showTextTitle ? "calc(100% - 29px)" : "100%", top: showTextTitle ? "29px" : undefined }}>
- {this.contents}
- </div>
- {titleView}
- {captionView}
+ return <div className={`documentView-node${this.topMost ? "-topmost" : ""}`}
+ ref={this._mainCont}
+ style={{
+ transition: this.Document.isAnimating !== undefined ? ".5s linear" : StrCast(this.Document.transition),
+ pointerEvents: this.Document.isBackground && !this.isSelected() ? "none" : "all",
+ color: StrCast(this.Document.color),
+ outline: highlighting && !borderRounding ? `${highlightColors[fullDegree]} ${highlightStyles[fullDegree]} ${localScale}px` : "solid 0px",
+ border: highlighting && borderRounding ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined,
+ background: this.layoutDoc.type === DocumentType.FONTICON || this.layoutDoc.viewType === CollectionViewType.Linear ? undefined : backgroundColor,
+ width: animwidth,
+ height: animheight,
+ transform: `scale(${this.layoutDoc.fitWidth ? 1 : this.props.ContentScaling()})`,
+ opacity: this.Document.opacity
+ }}
+ onDrop={this.onDrop} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick}
+ onPointerEnter={() => Doc.BrushDoc(this.props.Document)} onPointerLeave={() => Doc.UnBrushDoc(this.props.Document)}
+ >
+ {this.Document.links && DocListCast(this.Document.links).filter((d) => !DocListCast(this.layoutDoc.hiddenLinks).some(hidden => Doc.AreProtosEqual(hidden, d))).filter(this.isNonTemporalLink).map((d, i) =>
+ <div className="documentView-docuLinkWrapper" key={`${d[Id]}`} style={{ transform: `scale(${this.layoutDoc.fitWidth ? 1 : 1 / this.props.ContentScaling()})` }}>
+ <DocumentView {...this.props} Document={d} layoutKey={this.linkEndpoint(d)} backgroundColor={returnTransparent} removeDocument={undoBatch(doc => Doc.AddDocToList(this.layoutDoc, "hiddenLinks", doc))} />
+ </div>)}
+ {!showTitle && !showCaption ?
+ this.Document.searchFields ?
+ (<div className="documentView-searchWrapper">
+ {this.contents}
{searchHighlight}
+ </div>)
+ :
+ this.contents
+ :
+ <div className="documentView-styleWrapper" >
+ <div className="documentView-styleContentWrapper" style={{ height: showTextTitle ? "calc(100% - 29px)" : "100%", top: showTextTitle ? "29px" : undefined }}>
+ {this.contents}
</div>
- }
- </div>
- );
+ {titleView}
+ {captionView}
+ {searchHighlight}
+ </div>
+ }
+ </div>
}
}
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index cf55a10ba..037c92a62 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -1059,7 +1059,7 @@ export class FormattedTextBox extends DocExtendableComponent<(FieldViewProps & F
e.stopPropagation();
}} >
<FontAwesomeIcon className="formattedTExtBox-audioFont"
- style={{ color: this._recording ? "red" : "blue", opacity: this._recording ? 1 : 0.2 }} icon={"file-audio"} size="sm" />
+ style={{ color: this._recording ? "red" : "blue", opacity: this._recording ? 1 : 0.2 }} icon={"microphone"} size="sm" />
</div>
</div>
);
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 188440292..212c99f9d 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -323,7 +323,7 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
style={{ height: `calc(${.1 * nativeHeight / nativeWidth * 100}%)` }}
>
<FontAwesomeIcon className="imageBox-audioFont"
- style={{ color: [DocListCast(extensionDoc.audioAnnotations).length ? "blue" : "gray", "green", "red"][this._audioState] }} icon={faFileAudio} size="sm" />
+ style={{ color: [DocListCast(extensionDoc.audioAnnotations).length ? "blue" : "gray", "green", "red"][this._audioState] }} icon={!DocListCast(extensionDoc.audioAnnotations).length ? "microphone" : faFileAudio} size="sm" />
</div>
{this.considerGooglePhotosLink()}
<FaceRectangles document={extensionDoc} color={"#0000FF"} backgroundColor={"#0000FF"} />
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index 8bec4fbe3..963205206 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -7,6 +7,7 @@
overflow: hidden;
position:absolute;
cursor:auto;
+ transform-origin: top left;
}
.pdfBox-title-outer {
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 396a5356a..3baa6eb09 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -1,5 +1,5 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, observable, runInAction, reaction, IReactionDisposer } from 'mobx';
+import { action, observable, runInAction, reaction, IReactionDisposer, trace } from 'mobx';
import { observer } from "mobx-react";
import * as Pdfjs from "pdfjs-dist";
import "pdfjs-dist/web/pdf_viewer.css";
@@ -32,13 +32,14 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
private _valueValue: string = "";
private _scriptValue: string = "";
private _searchString: string = "";
+ private _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.
private _everActive = false; // has this box ever had its contents activated -- if so, stop drawing the overlay title
private _pdfViewer: PDFViewer | undefined;
- private _searchRef: React.RefObject<HTMLInputElement> = React.createRef();
- private _keyRef: React.RefObject<HTMLInputElement> = React.createRef();
- private _valueRef: React.RefObject<HTMLInputElement> = React.createRef();
- private _scriptRef: React.RefObject<HTMLInputElement> = React.createRef();
- private _selectReaction: IReactionDisposer | undefined;
+ private _searchRef = React.createRef<HTMLInputElement>();
+ private _keyRef = React.createRef<HTMLInputElement>();
+ private _valueRef = React.createRef<HTMLInputElement>();
+ private _scriptRef = React.createRef<HTMLInputElement>();
+ private _selectReactionDisposer: IReactionDisposer | undefined;
@observable private _searching: boolean = false;
@observable private _flyout: boolean = false;
@@ -46,21 +47,17 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
@observable private _pageControls = false;
componentWillUnmount() {
- this._selectReaction && this._selectReaction();
+ this._selectReactionDisposer && this._selectReactionDisposer();
}
componentDidMount() {
const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
if (pdfUrl instanceof PdfField) {
Pdfjs.getDocument(pdfUrl.url.pathname).promise.then(pdf => runInAction(() => this._pdf = pdf));
}
- this._selectReaction = reaction(() => this.props.isSelected(),
+ this._selectReactionDisposer = reaction(() => this.props.isSelected(),
() => {
- if (this.props.isSelected()) {
- document.removeEventListener("keydown", this.onKeyDown);
- document.addEventListener("keydown", this.onKeyDown);
- } else {
- document.removeEventListener("keydown", this.onKeyDown);
- }
+ document.removeEventListener("keydown", this.onKeyDown);
+ this.props.isSelected() && document.addEventListener("keydown", this.onKeyDown);
}, { fireImmediately: true });
}
@@ -75,8 +72,8 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
public prevAnnotation() { this._pdfViewer && this._pdfViewer.prevAnnotation(); }
public nextAnnotation() { this._pdfViewer && this._pdfViewer.nextAnnotation(); }
public backPage() { this._pdfViewer!.gotoPage((this.Document.curPage || 1) - 1); }
- public gotoPage = (p: number) => { this._pdfViewer!.gotoPage(p); };
public forwardPage() { this._pdfViewer!.gotoPage((this.Document.curPage || 1) + 1); }
+ public gotoPage = (p: number) => { this._pdfViewer!.gotoPage(p); };
@undoBatch
onKeyDown = action((e: KeyboardEvent) => {
@@ -86,12 +83,8 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
e.stopImmediatePropagation();
e.preventDefault();
}
- if (e.key === "PageDown" || e.key === "ArrowDown" || e.key === "ArrowRight") {
- this.forwardPage();
- }
- if (e.key === "PageUp" || e.key === "ArrowUp" || e.key === "ArrowLeft") {
- this.backPage();
- }
+ if (e.key === "PageDown" || e.key === "ArrowDown" || e.key === "ArrowRight") this.forwardPage();
+ if (e.key === "PageUp" || e.key === "ArrowUp" || e.key === "ArrowLeft") this.backPage();
});
@undoBatch
@@ -120,14 +113,12 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
settingsPanel() {
let pageBtns = <>
<button className="pdfBox-overlayButton-iconCont" key="back" title="Page Back"
- onPointerDown={(e) => e.stopPropagation()}
- onClick={() => this.backPage()}
+ onPointerDown={e => e.stopPropagation()} onClick={this.backPage}
style={{ left: 50, top: 5, height: "30px", position: "absolute", pointerEvents: "all" }}>
<FontAwesomeIcon style={{ color: "white" }} icon={"arrow-left"} size="sm" />
</button>
<button className="pdfBox-overlayButton-iconCont" key="fwd" title="Page Forward"
- onPointerDown={(e) => e.stopPropagation()}
- onClick={() => this.forwardPage()}
+ onPointerDown={e => e.stopPropagation()} onClick={this.forwardPage}
style={{ left: 80, top: 5, height: "30px", position: "absolute", pointerEvents: "all" }}>
<FontAwesomeIcon style={{ color: "white" }} icon={"arrow-right"} size="sm" />
</button>
@@ -137,15 +128,13 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
onPointerDown={e => e.stopPropagation()} style={{ display: this.active() ? "flex" : "none", position: "absolute", width: "100%", height: "100%", zIndex: 1, pointerEvents: "none" }}>
<div className="pdfBox-overlayCont" key="cont" onPointerDown={(e) => e.stopPropagation()} style={{ left: `${this._searching ? 0 : 100}%` }}>
<button className="pdfBox-overlayButton" title="Open Search Bar" />
- <input className="pdfBox-searchBar" placeholder="Search" ref={this._searchRef} onChange={this.searchStringChanged} onKeyDown={e => {
- e.keyCode === KeyCodes.ENTER && this.search(this._searchString, !e.shiftKey);
- }} />
+ <input className="pdfBox-searchBar" placeholder="Search" ref={this._searchRef} onChange={this.searchStringChanged} onKeyDown={e => e.keyCode === KeyCodes.ENTER && this.search(this._searchString, !e.shiftKey)} />
<button title="Search" onClick={e => this.search(this._searchString, !e.shiftKey)}>
<FontAwesomeIcon icon="search" size="sm" color="white" /></button>
- <button className="pdfBox-prevIcon " title="Previous Annotation" onClick={e => this.prevAnnotation()} >
+ <button className="pdfBox-prevIcon " title="Previous Annotation" onClick={this.prevAnnotation} >
<FontAwesomeIcon style={{ color: "white" }} icon={"arrow-up"} size="sm" />
</button>
- <button className="pdfBox-nextIcon" title="Next Annotation" onClick={e => this.nextAnnotation()} >
+ <button className="pdfBox-nextIcon" title="Next Annotation" onClick={this.nextAnnotation} >
<FontAwesomeIcon style={{ color: "white" }} icon={"arrow-down"} size="sm" />
</button>
</div>
@@ -200,8 +189,9 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
ContextMenu.Instance.addItem({ description: "Pdf Funcs...", subitems: funcs, icon: "asterisk" });
}
- _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() {
+ trace();
const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
let classname = "pdfBox-cont" + (this.active() ? "-interactive" : "");
let noPdf = !(pdfUrl instanceof PdfField) || !this._pdf;
@@ -214,11 +204,10 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
</div>
</div> :
<div className={classname} style={{
- transformOrigin: "top left",
width: this.props.Document.fitWidth ? `${100 / this.props.ContentScaling()}%` : undefined,
height: this.props.Document.fitWidth ? `${100 / this.props.ContentScaling()}%` : undefined,
transform: `scale(${this.props.Document.fitWidth ? this.props.ContentScaling() : 1})`
- }} onContextMenu={this.specificContextMenu} onPointerDown={(e: React.PointerEvent) => {
+ }} onContextMenu={this.specificContextMenu} onPointerDown={e => {
let hit = document.elementFromPoint(e.clientX, e.clientY);
if (hit && hit.localName === "span" && this.props.isSelected()) { // drag selecting text stops propagation
e.button === 0 && e.stopPropagation();
@@ -228,7 +217,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
setPdfViewer={this.setPdfViewer} ContainingCollectionView={this.props.ContainingCollectionView}
renderDepth={this.props.renderDepth} PanelHeight={this.props.PanelHeight} PanelWidth={this.props.PanelWidth}
Document={this.props.Document} DataDoc={this.dataDoc} ContentScaling={this.props.ContentScaling}
- addDocTab={this.props.addDocTab} GoToPage={this.gotoPage} focus={this.props.focus}
+ addDocTab={this.props.addDocTab} focus={this.props.focus}
pinToPres={this.props.pinToPres} addDocument={this.addDocument}
ScreenToLocalTransform={this.props.ScreenToLocalTransform} select={this.props.select}
isSelected={this.props.isSelected} whenActiveChanged={this.whenActiveChanged}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 51dc6e8d6..060ba8613 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -59,7 +59,6 @@ interface IViewerProps {
isSelected: () => boolean;
loaded: (nw: number, nh: number, np: number) => void;
active: () => boolean;
- GoToPage?: (n: number) => void;
addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean;
pinToPres: (document: Doc) => void;
addDocument?: (doc: Doc) => boolean;
@@ -220,7 +219,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
}
createPdfViewer() {
- if (!this._mainCont.current) {
+ if (!this._mainCont.current) { // bcz: I don't think this is ever triggered or needed
if (this._retries < 5) {
this._retries++;
setTimeout(() => this.createPdfViewer(), 1000);
@@ -235,9 +234,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
}));
document.addEventListener("pagerendered", action(() => this._showCover = this._showWaiting = false));
var pdfLinkService = new PDFJSViewer.PDFLinkService();
- let pdfFindController = new PDFJSViewer.PDFFindController({
- linkService: pdfLinkService,
- });
+ let pdfFindController = new PDFJSViewer.PDFFindController({ linkService: pdfLinkService });
this._pdfViewer = new PDFJSViewer.PDFViewer({
container: this._mainCont.current,
viewer: this._viewer.current,
@@ -626,6 +623,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
}
@computed get annotationLayer() {
+ trace();
return <div className="pdfViewer-annotationLayer" style={{ height: (this.Document.nativeHeight || 0) }} ref={this._annotationLayer}>
{this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map((anno, index) =>
<Annotation {...this.props} focus={this.props.focus} extensionDoc={this.extensionDoc!} anno={anno} key={`${anno[Id]}-annotation`} />)}
@@ -672,13 +670,14 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
marqueeing = () => this._marqueeing;
visibleHeight = () => this.props.PanelHeight() / this.props.ContentScaling() * 72 / 96;
render() {
- return !this.extensionDoc ? (null) : (<div className={"pdfViewer-viewer" + (this._zoomed !== 1 ? "-zoomed" : "")}
- onScroll={this.onScroll} onWheel={this.onZoomWheel} onPointerDown={this.onPointerDown} onClick={this.onClick} ref={this._mainCont}>
- {this.pdfViewerDiv}
- {this.annotationLayer}
- {this.standinViews}
- <PdfViewerMarquee isMarqueeing={this.marqueeing} width={this.marqueeWidth} height={this.marqueeHeight} x={this.marqueeX} y={this.marqueeY} />
- </div >);
+ trace();
+ return !this.extensionDoc ? (null) :
+ <div className={"pdfViewer-viewer" + (this._zoomed !== 1 ? "-zoomed" : "")} onScroll={this.onScroll} onWheel={this.onZoomWheel} onPointerDown={this.onPointerDown} onClick={this.onClick} ref={this._mainCont}>
+ {this.pdfViewerDiv}
+ {this.annotationLayer}
+ {this.standinViews}
+ <PdfViewerMarquee isMarqueeing={this.marqueeing} width={this.marqueeWidth} height={this.marqueeHeight} x={this.marqueeX} y={this.marqueeY} />
+ </div >;
}
}