aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2021-09-17 14:07:09 -0400
committerbobzel <zzzman@gmail.com>2021-09-17 14:07:09 -0400
commitf097eefd91614d4efa2a89b3d8c7d1071d6c0b6f (patch)
tree817227c736afbfc38c0da81add1ae9b2a4704a31 /src
parenta75ccf3bd6c0029116d46436bd5a9d956b6e04e7 (diff)
added 'unset' docFilters. changed link doc views to use comparison box with title/caption. fixed linkEditor to write to data doc. generalized comparisonBox rendering to use parameterized fields. fixed pdf/web to honor pointerEvents none prop and fixed textAnnotations to get rendered once as an Annotation. moved filterIcon stuff into DocumentView
Diffstat (limited to 'src')
-rw-r--r--src/Utils.ts4
-rw-r--r--src/client/DocServer.ts2
-rw-r--r--src/client/documents/Documents.ts17
-rw-r--r--src/client/views/collections/CollectionView.tsx12
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx6
-rw-r--r--src/client/views/linking/LinkEditor.tsx11
-rw-r--r--src/client/views/nodes/ComparisonBox.tsx8
-rw-r--r--src/client/views/nodes/DocumentView.tsx19
-rw-r--r--src/client/views/nodes/LinkBox.tsx19
-rw-r--r--src/client/views/nodes/LinkDescriptionPopup.tsx7
-rw-r--r--src/client/views/nodes/PDFBox.tsx9
-rw-r--r--src/client/views/nodes/WebBox.tsx14
-rw-r--r--src/client/views/pdf/Annotation.scss3
-rw-r--r--src/client/views/pdf/PDFViewer.tsx13
-rw-r--r--src/fields/Doc.ts2
15 files changed, 80 insertions, 66 deletions
diff --git a/src/Utils.ts b/src/Utils.ts
index 6eacd8296..e11f1154e 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -125,7 +125,9 @@ export namespace Utils {
// bcz: isTransparent(__value__) is a hack. it would be nice to have acual functions be parsed, but now Doc.matchFieldValue is hardwired to recognize just this one
return `backgroundColor:${isTransparentFunctionHack},${noRecursionHack}:x`;// bcz: hack. noRecursion should probably be either another ':' delimited field, or it should be a modifier to the comparision (eg., check, x, etc) field
}
-
+ export function PropUnsetFilter(prop: string) {
+ return `${prop}:any,${noRecursionHack}:unset`;
+ }
export function toRGBAstr(col: { r: number, g: number, b: number, a?: number }) {
return "rgba(" + col.r + "," + col.g + "," + col.b + (col.a !== undefined ? "," + col.a : "") + ")";
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index e498a7cca..3b376a0e7 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -241,6 +241,7 @@ export namespace DocServer {
// the field has been returned from the server
const getSerializedField = Utils.EmitCallback(_socket, MessageStore.GetRefField, id);
+ console.log(id)
// when the serialized RefField has been received, go head and begin deserializing it into an object.
// Here, once deserialized, we also invoke .proto to 'load' the document's prototype, which ensures that all
// future .proto calls on the Doc won't have to go farther than the cache to get their actual value.
@@ -264,6 +265,7 @@ export namespace DocServer {
} else {
delete _cache[id];
}
+ console.log(id, field);
return field;
// either way, overwrite or delete any promises cached at this id (that we inserted as flags
// to indicate that the field was in the process of being fetched). Now everything
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index f50f306a3..e8185400e 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -962,13 +962,17 @@ export namespace DocUtils {
// metadata facets that exist
const exists = Object.keys(facet).filter(value => facet[value] === "exists");
+ // metadata facets that exist
+ const unsets = Object.keys(facet).filter(value => facet[value] === "unset");
+
// facets that have an x next to them
const xs = Object.keys(facet).filter(value => facet[value] === "x");
- if (!exists.length && !xs.length && !checks.length && !matches.length) return true;
+ if (!unsets.length && !exists.length && !xs.length && !checks.length && !matches.length) return true;
const failsNotEqualFacets = !xs.length ? false : xs.some(value => Doc.matchFieldValue(d, facetKey, value));
const satisfiesCheckFacets = !checks.length ? true : checks.some(value => Doc.matchFieldValue(d, facetKey, value));
const satisfiesExistsFacets = !exists.length ? true : exists.some(value => d[facetKey] !== undefined);
+ const satisfiesUnsetsFacets = !unsets.length ? true : unsets.some(value => d[facetKey] === undefined);
const satisfiesMatchFacets = !matches.length ? true : matches.some(value => {
if (facetKey.startsWith("*")) { // fields starting with a '*' are used to match families of related fields. ie, *lastModified will match text-lastModified, data-lastModified, etc
const allKeys = Array.from(Object.keys(d));
@@ -980,11 +984,11 @@ export namespace DocUtils {
});
// if we're ORing them together, the default return is false, and we return true for a doc if it satisfies any one set of criteria
if ((parentCollection?.currentFilter as Doc)?.filterBoolean === "OR") {
- if (satisfiesExistsFacets && satisfiesCheckFacets && !failsNotEqualFacets && satisfiesMatchFacets) return true;
+ if (satisfiesUnsetsFacets && satisfiesExistsFacets && satisfiesCheckFacets && !failsNotEqualFacets && satisfiesMatchFacets) return true;
}
// if we're ANDing them together, the default return is true, and we return false for a doc if it doesn't satisfy any set of criteria
else {
- if (!satisfiesExistsFacets || !satisfiesCheckFacets || failsNotEqualFacets || (matches.length && !satisfiesMatchFacets)) return false;
+ if (!satisfiesUnsetsFacets || !satisfiesExistsFacets || !satisfiesCheckFacets || failsNotEqualFacets || (matches.length && !satisfiesMatchFacets)) return false;
}
}
@@ -1088,10 +1092,11 @@ export namespace DocUtils {
"anchor2-useLinkSmallAnchor": target.doc.useLinkSmallAnchor ? true : undefined,
"acl-Public": SharingPermissions.Augment,
"_acl-Public": SharingPermissions.Augment,
- layout_linkView: Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null),
- linkDisplay: true, hidden: true,
+ linkDisplay: true,
+ hidden: true,
linkRelationship,
- _layoutKey: "layout_linkView",
+ _showCaption: "description",
+ _showTitle: "linkRelationship",
description
}, id), showPopup);
}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 5c9c8063b..38e027fb3 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -246,12 +246,6 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
childLayoutTemplate = () => this.props.childLayoutTemplate?.() || Cast(this.rootDoc.childLayoutTemplate, Doc, null);
@computed get childLayoutString() { return StrCast(this.rootDoc.childLayoutString); }
- /**
- * Shows the filter icon if it's a user-created collection which isn't a dashboard and has some docFilters applied on it or on the current dashboard.
- */
- @computed get showFilterIcon() {
- return this.props.Document.viewType !== CollectionViewType.Docking && !Doc.IsSystem(this.props.Document) && this._subView?.IsFiltered();
- }
@observable _subView: any = undefined;
@@ -280,12 +274,6 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
style={{ pointerEvents: this.props.layerProvider?.(this.rootDoc) === false ? "none" : undefined }}>
{this.showIsTagged()}
{this.collectionViewType !== undefined ? this.SubView(this.collectionViewType, props) : (null)}
- {this.showFilterIcon ?
- <FontAwesomeIcon icon={"filter"} size="lg"
- style={{ position: 'absolute', top: '1%', right: '1%', cursor: "pointer", padding: 1, color: this.showFilterIcon === "hasFilter" ? '#18c718bd' : "orange", zIndex: 1 }}
- onPointerDown={action(e => { this.props.select(false); CurrentUserUtils.propertiesWidth = 250; e.stopPropagation(); })}
- />
- : (null)}
</div>);
}
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index 3b3e069d8..2cb487588 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -1,6 +1,6 @@
import { action, computed, IReactionDisposer, observable, reaction } from "mobx";
import { observer } from "mobx-react";
-import { Doc } from "../../../../fields/Doc";
+import { Doc, Field } from "../../../../fields/Doc";
import { Id } from "../../../../fields/FieldSymbols";
import { List } from "../../../../fields/List";
import { NumCast, StrCast } from "../../../../fields/Types";
@@ -180,7 +180,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
if (!this.renderData) return (null);
const { a, b, pt1norm, pt2norm, aActive, bActive, textX, textY, pt1, pt2 } = this.renderData;
LinkManager.currentLink = this.props.LinkDocs[0];
- const linkRelationship = StrCast(LinkManager.currentLink?.linkRelationship); //get string representing relationship
+ const linkRelationship = Field.toString(LinkManager.currentLink?.linkRelationship as any as Field); //get string representing relationship
const linkRelationshipList = Doc.UserDoc().linkRelationshipList as List<string>;
const linkColorList = Doc.UserDoc().linkColorList as List<string>;
//access stroke color using index of the relationship in the color list (default black)
@@ -189,7 +189,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
<path className="collectionfreeformlinkview-linkLine" style={{ opacity: this._opacity, strokeDasharray: "2 2", stroke: strokeColor }}
d={`M ${pt1[0]} ${pt1[1]} C ${pt1[0] + pt1norm[0]} ${pt1[1] + pt1norm[1]}, ${pt2[0] + pt2norm[0]} ${pt2[1] + pt2norm[1]}, ${pt2[0]} ${pt2[1]}`} />
{textX === undefined ? (null) : <text className="collectionfreeformlinkview-linkText" x={textX} y={textY} onPointerDown={this.pointerDown} >
- {StrCast(this.props.LinkDocs[0].description)}
+ {Field.toString(this.props.LinkDocs[0].description as any as Field)}
</text>}
</>);
}
diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx
index 240a71c3e..219f7d3a2 100644
--- a/src/client/views/linking/LinkEditor.tsx
+++ b/src/client/views/linking/LinkEditor.tsx
@@ -2,13 +2,14 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Tooltip } from "@material-ui/core";
import { action, computed, observable } from "mobx";
import { observer } from "mobx-react";
-import { Doc, StrListCast } from "../../../fields/Doc";
-import { DateCast, StrCast } from "../../../fields/Types";
+import { Doc, StrListCast, Field } from "../../../fields/Doc";
+import { DateCast, StrCast, Cast } from "../../../fields/Types";
import { LinkManager } from "../../util/LinkManager";
import { undoBatch } from "../../util/UndoManager";
import './LinkEditor.scss';
import { LinkRelationshipSearch } from "./LinkRelationshipSearch";
import React = require("react");
+import { ToString } from "../../../fields/FieldSymbols";
interface LinkEditorProps {
@@ -20,7 +21,7 @@ interface LinkEditorProps {
@observer
export class LinkEditor extends React.Component<LinkEditorProps> {
- @observable description = StrCast(LinkManager.currentLink?.description);
+ @observable description = Field.toString(LinkManager.currentLink?.description as any as Field);
@observable relationship = StrCast(LinkManager.currentLink?.linkRelationship);
@observable openDropdown: boolean = false;
@observable showInfo: boolean = false;
@@ -41,7 +42,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
@undoBatch
setRelationshipValue = action((value: string) => {
if (LinkManager.currentLink) {
- LinkManager.currentLink.linkRelationship = value;
+ Doc.GetProto(LinkManager.currentLink).linkRelationship = value;
const linkRelationshipList = StrListCast(Doc.UserDoc().linkRelationshipList);
const linkColorList = StrListCast(Doc.UserDoc().linkColorList);
// if the relationship does not exist in the list, add it and a corresponding unique randomly generated color
@@ -79,7 +80,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
@undoBatch
setDescripValue = action((value: string) => {
if (LinkManager.currentLink) {
- LinkManager.currentLink.description = value;
+ Doc.GetProto(LinkManager.currentLink).description = value;
this.buttonColor = "rgb(62, 133, 55)";
setTimeout(action(() => this.buttonColor = ""), 750);
return true;
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index 6708a08ee..72c7e4f45 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -15,6 +15,7 @@ import "./ComparisonBox.scss";
import { DocumentView, DocumentViewProps } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
import React = require("react");
+import { DocumentType } from '../../documents/DocumentTypes';
export const comparisonSchema = createSchema({});
@@ -87,7 +88,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
</div>;
};
const displayDoc = (which: string) => {
- const whichDoc = Cast(this.dataDoc[`compareBox-${which}`], Doc, null);
+ var whichDoc = Cast(this.dataDoc[which], Doc, null);
+ if (whichDoc.type === DocumentType.MARKER) whichDoc = Cast(whichDoc.annotationOn, Doc, null);
return whichDoc ? <>
<DocumentView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
isContentActive={returnFalse}
@@ -112,9 +114,9 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
return (
<div className={`comparisonBox${this.props.isContentActive() || SnappingManager.GetIsDragging() ? "-interactive" : ""}` /* change className to easily disable/enable pointer events in CSS */}>
- {displayBox("after", 1, this.props.PanelWidth() - 3)}
+ {displayBox(this.fieldKey === "data" ? "compareBox-after" : `${this.fieldKey}2`, 1, this.props.PanelWidth() - 3)}
<div className="clip-div" style={{ width: clipWidth, transition: this._animating, background: StrCast(this.layoutDoc._backgroundColor, "gray") }}>
- {displayBox("before", 0, 0)}
+ {displayBox(this.fieldKey === "data" ? "compareBox-before" : `${this.fieldKey}1`, 0, 0)}
</div>
<div className="slide-bar" style={{ left: `calc(${clipWidth} - 0.5px)`, cursor: NumCast(this.layoutDoc._clipWidth) < 5 ? "e-resize" : NumCast(this.layoutDoc._clipWidth) / 100 > (this.props.PanelWidth() - 5) / this.props.PanelWidth() ? "w-resize" : undefined }}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 46a8b6629..35249c7f4 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -13,7 +13,7 @@ import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Ty
import { AudioField } from "../../../fields/URLField";
import { GetEffectiveAcl, SharingPermissions, TraceMobx } from '../../../fields/util';
import { MobileInterface } from '../../../mobile/MobileInterface';
-import { emptyFunction, hasDescendantTarget, OmitKeys, returnTrue, returnVal, Utils, lightOrDark, simulateMouseClick } from "../../../Utils";
+import { emptyFunction, hasDescendantTarget, OmitKeys, returnTrue, returnVal, Utils, lightOrDark, simulateMouseClick, returnEmptyString } from "../../../Utils";
import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils';
import { Docs, DocUtils } from "../../documents/Documents";
import { DocumentType } from '../../documents/DocumentTypes';
@@ -802,6 +802,12 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
cm.displayMenu((e?.pageX || pageX || 0) - 15, (e?.pageY || pageY || 0) - 15);
}
+ collectionFilters = () => StrListCast(this.props.Document._docFilters);
+ collectionRangeDocFilters = () => StrListCast(this.props.Document._docRangeFilters);
+ @computed get showFilterIcon() {
+ return this.collectionFilters().length || this.collectionRangeDocFilters().length ? "hasFilter" :
+ this.props.docFilters?.().filter(f => Utils.IsRecursiveFilter(f)).length || this.props.docRangeFilters().length ? "inheritsFilter" : undefined
+ }
rootSelected = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false;
panelHeight = () => this.props.PanelHeight() - this.headerMargin;
screenToLocal = () => this.props.ScreenToLocalTransform().translate(0, -this.headerMargin);
@@ -832,7 +838,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
</div>;
return <div className="documentView-contentsView"
style={{
- pointerEvents: this.rootDoc.type !== DocumentType.INK && ((this.props.contentPointerEvents as any) || (this.isContentActive())) ? "all" : "none",
+ pointerEvents: this.props.pointerEvents as any ? this.props.pointerEvents as any : (this.rootDoc.type !== DocumentType.INK && ((this.props.contentPointerEvents as any) || (this.isContentActive())) ? "all" : "none"),
height: this.headerMargin ? `calc(100% - ${this.headerMargin}px)` : undefined,
}}>
<DocumentContentsView key={1} {...this.props}
@@ -869,6 +875,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
anchorPanelHeight = () => this.props.PanelHeight() || 1;
anchorStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string): any => {
switch (property) {
+ case StyleProp.ShowTitle: return "";
case StyleProp.PointerEvents: return "none";
case StyleProp.LinkSource: return this.props.Document;// pass the LinkSource to the LinkAnchorBox
default: return this.props.styleProvider?.(doc, props, property);
@@ -901,6 +908,8 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
PanelWidth={this.anchorPanelWidth}
PanelHeight={this.anchorPanelHeight}
dontRegisterView={false}
+ showTitle={returnEmptyString}
+ hideCaptions={true}
fitWidth={returnTrue}
styleProvider={this.anchorStyleProvider}
removeDocument={this.hideLinkAnchor}
@@ -1087,6 +1096,12 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
</div>
</>
}
+ {this.showFilterIcon ?
+ <FontAwesomeIcon icon={"filter"} size="lg"
+ style={{ position: 'absolute', top: '1%', right: '1%', cursor: "pointer", padding: 1, color: this.showFilterIcon === "hasFilter" ? '#18c718bd' : "orange", zIndex: 1 }}
+ onPointerDown={action(e => { this.props.select(false); CurrentUserUtils.propertiesWidth = 250; e.stopPropagation(); })}
+ />
+ : (null)}
</div>;
}
}
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 55ea45bb8..b82d16677 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -2,10 +2,10 @@ import React = require("react");
import { observer } from "mobx-react";
import { documentSchema } from "../../../fields/documentSchemas";
import { makeInterface } from "../../../fields/Schema";
-import { returnFalse } from "../../../Utils";
-import { CollectionTreeView } from "../collections/CollectionTreeView";
+import { emptyFunction, returnFalse } from "../../../Utils";
import { ViewBoxBaseComponent } from "../DocComponent";
import { StyleProp } from "../StyleProvider";
+import { ComparisonBox } from "./ComparisonBox";
import { FieldView, FieldViewProps } from './FieldView';
import "./LinkBox.scss";
@@ -20,22 +20,15 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps, LinkDocument>(
if (this.dataDoc.treeViewOpen === undefined) setTimeout(() => this.dataDoc.treeViewOpen = true);
return <div className={`linkBox-container${this.isContentActive() ? "-interactive" : ""}`}
style={{ background: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor) }} >
- <CollectionTreeView {...this.props}
- childDocuments={[this.dataDoc]}
- treeViewOpen={true}
- treeViewExpandedView={"fields"}
- treeViewHideTitle={true}
- treeViewSkipFields={["treeViewExpandedView", "aliases", "_removeDropProperties",
- "treeViewOpen", "aliasNumber", "isPrototype", "creationDate", "author"]}
+ <ComparisonBox {...this.props}
+ fieldKey="anchor"
+ setHeight={emptyFunction}
dontRegisterView={true}
renderDepth={this.props.renderDepth + 1}
- CollectionView={undefined}
- isAnyChildContentActive={returnFalse}
isContentActive={this.isContentActiveFunc}
addDocument={returnFalse}
removeDocument={returnFalse}
- moveDocument={returnFalse}>
- </CollectionTreeView>
+ moveDocument={returnFalse} />
</div>;
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx
index b62a4dd56..a9d33f161 100644
--- a/src/client/views/nodes/LinkDescriptionPopup.tsx
+++ b/src/client/views/nodes/LinkDescriptionPopup.tsx
@@ -1,8 +1,9 @@
import React = require("react");
+import { action, observable } from "mobx";
import { observer } from "mobx-react";
-import "./LinkDescriptionPopup.scss";
-import { observable, action } from "mobx";
+import { Doc } from "../../../fields/Doc";
import { LinkManager } from "../../util/LinkManager";
+import "./LinkDescriptionPopup.scss";
import { TaskCompletionBox } from "./TaskCompletedBox";
@@ -25,7 +26,7 @@ export class LinkDescriptionPopup extends React.Component<{}> {
onDismiss = (add: boolean) => {
LinkDescriptionPopup.descriptionPopup = false;
if (add) {
- LinkManager.currentLink && (LinkManager.currentLink.description = this.description);
+ LinkManager.currentLink && (Doc.GetProto(LinkManager.currentLink).description = this.description);
}
}
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index f0a502e31..30b4dc92a 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -3,9 +3,9 @@ import { action, computed, IReactionDisposer, observable, reaction, runInAction
import { observer } from "mobx-react";
import * as Pdfjs from "pdfjs-dist";
import "pdfjs-dist/web/pdf_viewer.css";
-import { Doc, DocListCast, Opt, WidthSym } from "../../../fields/Doc";
+import { Doc, DocListCast, Opt, WidthSym, StrListCast } from "../../../fields/Doc";
import { documentSchema } from '../../../fields/documentSchemas';
-import { makeInterface } from "../../../fields/Schema";
+import { makeInterface, listSpec } from "../../../fields/Schema";
import { Cast, NumCast, StrCast } from '../../../fields/Types';
import { PdfField } from "../../../fields/URLField";
import { TraceMobx } from '../../../fields/util';
@@ -25,6 +25,7 @@ import { FieldView, FieldViewProps } from './FieldView';
import { pageSchema } from "./ImageBox";
import "./PDFBox.scss";
import React = require("react");
+import { CurrentUserUtils } from '../../util/CurrentUserUtils';
type PdfDocument = makeInterface<[typeof documentSchema, typeof panZoomSchema, typeof pageSchema]>;
const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema);
@@ -249,9 +250,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@observable _showSidebar = false;
@computed get SidebarShown() { return this._showSidebar || this.layoutDoc._showSidebar ? true : false; }
- contentScaling = () => {
- return 1;
- }
+ contentScaling = () => 1;
@computed get renderPdfView() {
TraceMobx();
const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1;
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 6a20ca14a..60a83d612 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -532,7 +532,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
NumCast(this.layoutDoc.nativeWidth)
@computed get content() {
- return <div className={"webBox-cont" + (!this.props.docViewPath().lastElement()?.docView?._pendingDoubleClick && this.props.isContentActive() && CurrentUserUtils.SelectedTool === InkTool.None && !DocumentDecorations.Instance?.Interacting ? "-interactive" : "")}
+ const interactive = !this.props.docViewPath().lastElement()?.docView?._pendingDoubleClick && this.props.isContentActive() && this.props.pointerEvents !== "none" && CurrentUserUtils.SelectedTool === InkTool.None && !DocumentDecorations.Instance?.Interacting;
+ return <div className={"webBox-cont" + (interactive ? "-interactive" : "")}
style={{ width: !this.layoutDoc.allowReflow ? NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]) || `100%` : "100%", }}>
{this.urlContent}
</div>;
@@ -575,10 +576,11 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
panelHeight = () => this.props.PanelHeight() / (this.props.scaling?.() || 1); // () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document);
scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._scrollTop));
anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick;
- transparentFilter = () => [...this.props.docFilters(), Utils.IsTransparentFilter()];
- opaqueFilter = () => [...this.props.docFilters(), Utils.IsOpaqueFilter()];
+ basicFilter = () => [...this.props.docFilters(), Utils.PropUnsetFilter("textInlineAnnotations")];
+ transparentFilter = () => [Utils.IsTransparentFilter(), ...this.basicFilter()];
+ opaqueFilter = () => [Utils.IsOpaqueFilter(), ...this.basicFilter()];
render() {
- const pointerEvents = this.props.layerProvider?.(this.layoutDoc) === false ? "none" : undefined;
+ const pointerEvents = this.props.layerProvider?.(this.layoutDoc) === false ? "none" : this.props.pointerEvents ? this.props.pointerEvents as any : undefined;
const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1;
const scale = previewScale * (this.props.scaling?.() || 1);
const renderAnnotations = (docFilters?: () => string[]) =>
@@ -593,7 +595,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
ScreenToLocalTransform={this.scrollXf}
scaling={returnOne}
dropAction={"alias"}
- docFilters={docFilters || this.props.docFilters}
+ docFilters={docFilters || this.basicFilter}
dontRenderDocuments={docFilters ? false : true}
select={emptyFunction}
ContentScaling={returnOne}
@@ -606,7 +608,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
pointerEvents={CurrentUserUtils.SelectedTool !== InkTool.None || this._isAnnotating || SnappingManager.GetIsDragging() ? "all" : "none"} />;
return (
<div className="webBox" ref={this._mainCont}
- style={{ pointerEvents: this.props.isContentActive() && !MarqueeOptionsMenu.Instance.isShown() ? "all" : SnappingManager.GetIsDragging() ? undefined : "none" }} >
+ style={{ pointerEvents: this.props.isContentActive() && this.props.pointerEvents !== "none" && !MarqueeOptionsMenu.Instance.isShown() ? "all" : SnappingManager.GetIsDragging() ? undefined : "none" }} >
<div className={`webBox-container`} style={{ pointerEvents }} onContextMenu={this.specificContextMenu}>
<base target="_blank" />
<div className={"webBox-outerContent"} ref={this._outerRef}
diff --git a/src/client/views/pdf/Annotation.scss b/src/client/views/pdf/Annotation.scss
index e98f071c3..1de60ffed 100644
--- a/src/client/views/pdf/Annotation.scss
+++ b/src/client/views/pdf/Annotation.scss
@@ -4,4 +4,7 @@
position: absolute;
background-color: rgba(146, 245, 95, 0.467);
transition: opacity 0.5s;
+ &:hover {
+ cursor: pointer;
+ }
} \ No newline at end of file
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 7aa18e46f..78adedf5b 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -179,7 +179,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
let focusSpeed: Opt<number>;
if (doc !== this.props.rootDoc && mainCont) {
const windowHeight = this.props.PanelHeight() / (this.props.scaling?.() || 1);
- const scrollTo = Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.props.layoutDoc._scrollTop), windowHeight, .1 * windowHeight);
+ const scrollTo = doc.unrendered ? NumCast(doc.y) : Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.props.layoutDoc._scrollTop), windowHeight, .1 * windowHeight);
if (scrollTo !== undefined) {
focusSpeed = 500;
@@ -502,8 +502,9 @@ export class PDFViewer extends React.Component<IViewerProps> {
overlayTransform = () => this.scrollXf().scale(1 / this._zoomed);
panelWidth = () => this.props.PanelWidth() / (this.props.scaling?.() || 1); // (this.Document.scrollHeight || Doc.NativeHeight(this.Document) || 0);
panelHeight = () => this.props.PanelHeight() / (this.props.scaling?.() || 1); // () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document);
- transparentFilter = () => [...this.props.docFilters(), Utils.IsTransparentFilter()];
- opaqueFilter = () => [...this.props.docFilters(), Utils.IsOpaqueFilter()];
+ basicFilter = () => [...this.props.docFilters(), Utils.PropUnsetFilter("textInlineAnnotations")];
+ transparentFilter = () => [Utils.IsTransparentFilter(), ...this.basicFilter()];
+ opaqueFilter = () => [Utils.IsOpaqueFilter(), ...this.basicFilter()];
@computed get overlayLayer() {
const renderAnnotations = (docFilters?: () => string[]) =>
<CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
@@ -516,7 +517,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
select={emptyFunction}
ContentScaling={this.contentZoom}
bringToFront={emptyFunction}
- docFilters={docFilters || this.props.docFilters}
+ docFilters={docFilters || this.basicFilter}
dontRenderDocuments={docFilters ? false : true}
CollectionView={undefined}
ScreenToLocalTransform={this.overlayTransform}
@@ -543,7 +544,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
</div>;
}
@computed get pdfViewerDiv() {
- return <div className={"pdfViewerDash-text" + (this._textSelecting && (this.props.isSelected() || this.props.isContentActive()) ? "-selected" : "")} ref={this._viewer} />;
+ return <div className={"pdfViewerDash-text" + (this.props.pointerEvents !== "none" && this._textSelecting && (this.props.isSelected() || this.props.isContentActive()) ? "-selected" : "")} ref={this._viewer} />;
}
@computed get contentScaling() { return this.props.ContentScaling?.() || 1; }
@computed get standinViews() {
@@ -556,7 +557,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
render() {
TraceMobx();
return <div className="pdfViewer-content">
- <div className={`pdfViewerDash${this.props.isContentActive() ? "-interactive" : ""}`} ref={this._mainCont}
+ <div className={`pdfViewerDash${this.props.isContentActive() && this.props.pointerEvents !== "none" ? "-interactive" : ""}`} ref={this._mainCont}
onScroll={this.onScroll} onWheel={this.onZoomWheel} onPointerDown={this.onPointerDown} onClick={this.onClick}
style={{
overflowX: this._zoomed !== 1 ? "scroll" : undefined,
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 4d040f3bc..57bd0f46f 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1136,7 +1136,7 @@ export namespace Doc {
// filters document in a container collection:
// all documents with the specified value for the specified key are included/excluded
// based on the modifiers :"check", "x", undefined
- export function setDocFilter(container: Opt<Doc>, key: string, value: any, modifiers: "remove" | "match" | "check" | "x" | "exists", toggle?: boolean, fieldSuffix?: string, append: boolean = true) {
+ export function setDocFilter(container: Opt<Doc>, key: string, value: any, modifiers: "remove" | "match" | "check" | "x" | "exists" | "unset", toggle?: boolean, fieldSuffix?: string, append: boolean = true) {
if (!container) return;
const filterField = "_" + (fieldSuffix ? fieldSuffix + "-" : "") + "docFilters";
const docFilters = Cast(container[filterField], listSpec("string"), []);