aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/documents/Documents.ts1
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx3
-rw-r--r--src/client/views/nodes/PDFBox.tsx7
-rw-r--r--src/client/views/pdf/PDFViewer.scss50
-rw-r--r--src/client/views/pdf/PDFViewer.tsx158
-rw-r--r--src/fields/documentSchemas.ts1
6 files changed, 113 insertions, 107 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index dd3e13cfd..d9c2e0d8b 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -116,7 +116,6 @@ export class DocumentOptions {
_fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents
_lockedPosition?: boolean; // lock the x,y coordinates of the document so that it can't be dragged
_lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed
- _freeformLOD?: boolean; // whether to use LOD to render a freeform document
_isPushpin?: boolean; // whether document, when clicked, toggles display of its link target
_showTitle?: string; // field name to display in header (:hover is an optional suffix)
_showCaption?: string; // which field to display in the caption area. leave empty to have no caption
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 5b3a7db41..193750d8a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1558,7 +1558,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this.props.renderDepth && optionItems.push({ description: "Use Background Color as Default", event: () => Cast(Doc.UserDoc().emptyCollection, Doc, null)._backgroundColor = StrCast(this.layoutDoc._backgroundColor), icon: "palette" });
if (!Doc.UserDoc().noviceMode) {
optionItems.push({ description: (!Doc.NativeWidth(this.layoutDoc) || !Doc.NativeHeight(this.layoutDoc) ? "Freeze" : "Unfreeze") + " Aspect", event: this.toggleNativeDimensions, icon: "snowflake" });
- optionItems.push({ description: `${this.Document._freeformLOD ? "Enable LOD" : "Disable LOD"}`, event: () => this.Document._freeformLOD = !this.Document._freeformLOD, icon: "table" });
}
!options && ContextMenu.Instance.addItem({ description: "Options...", subitems: optionItems, icon: "eye" });
const mores = ContextMenu.Instance.findByDescription("More...");
@@ -1739,7 +1738,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
width: `${100 / (this.contentScaling || 1)}%`,
height: this.isAnnotationOverlay && this.Document.scrollHeight ? NumCast(this.Document.scrollHeight) : `${100 / (this.contentScaling || 1)}%`// : this.isAnnotationOverlay ? (this.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight()
}}>
- {this._firstRender || (this.Document._freeformLOD && !this.props.isContentActive() && !this.props.isAnnotationOverlay && this.props.renderDepth > 0) ?
+ {this._firstRender ?
this.placeholder : this.marqueeView}
{this.props.noOverlay ? (null) : <CollectionFreeFormOverlayView elements={this.elementFunc} />}
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 98c17ed23..e6e723ef1 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -65,9 +65,10 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
if (oldDiv.className === "pdfBox-ui" ||
- oldDiv.className.includes("pdfViewerDash-overlay")) {
+ oldDiv.className === "pdfViewerDash-overlay-inking") {
newDiv.style.display = "none";
}
+ if (newDiv && newDiv.style) newDiv.style.overflow = "hidden";
if (oldDiv instanceof HTMLCanvasElement) {
const canvas = oldDiv;
const img = document.createElement('img'); // create a Image Element
@@ -127,7 +128,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
htmlString,
anchw,
anchh,
- NumCast(region.y) * this.props.PanelHeight() / NumCast(this.rootDoc[this.fieldKey + "-nativeHeight"]),
+ NumCast(region.y) * this.props.PanelWidth() / NumCast(this.rootDoc[this.fieldKey + "-nativeWidth"]),
NumCast(region.x) * this.props.PanelWidth() / NumCast(this.rootDoc[this.fieldKey + "-nativeWidth"]),
4
).then
@@ -313,7 +314,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
</>;
const searchTitle = `${!this._searching ? "Open" : "Close"} Search Bar`;
const curPage = NumCast(this.Document._curPage) || 1;
- return !this.props.isContentActive() ? (null) :
+ return !this.props.isContentActive() || this._pdfViewer?.isAnnotating ? (null) :
<div className="pdfBox-ui" onKeyDown={e => [KeyCodes.BACKSPACE, KeyCodes.DELETE].includes(e.keyCode) ? e.stopPropagation() : true}
onPointerDown={e => e.stopPropagation()} style={{ display: this.props.isContentActive() ? "flex" : "none" }}>
<div className="pdfBox-overlayCont" onPointerDown={(e) => e.stopPropagation()} style={{ left: `${this._searching ? 0 : 100}%` }}>
diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss
index 390aed1e0..822af6a68 100644
--- a/src/client/views/pdf/PDFViewer.scss
+++ b/src/client/views/pdf/PDFViewer.scss
@@ -1,5 +1,3 @@
-
-
.pdfViewer-content {
height: 100%;
width: 100%;
@@ -8,33 +6,42 @@
top: 0;
left: 0;
}
-.pdfViewerDash, .pdfViewerDash-interactive {
+
+.pdfViewerDash,
+.pdfViewerDash-interactive {
position: absolute;
width: 100%;
height: 100%;
top: 0;
- left:0;
+ left: 0;
position: absolute;
overflow-y: auto;
overflow-x: hidden;
transform-origin: top left;
-
+
// .canvasWrapper {
// transform: scale(0.75);
// transform-origin: top left;
// }
.textLayer {
opacity: unset;
- mix-blend-mode: multiply;// bcz: makes text fuzzy!
+ mix-blend-mode: multiply; // bcz: makes text fuzzy!
+
span {
padding-right: 5px;
padding-bottom: 4px;
}
}
- .textLayer ::selection { background: #ACCEF7; } // should match the backgroundColor in createAnnotation()
+
+ .textLayer ::selection {
+ background: #ACCEF7;
+ }
+
+ // should match the backgroundColor in createAnnotation()
.textLayer .highlight {
background-color: yellow;
}
+
.textLayer .highlight.selected {
background-color: orange;
}
@@ -43,32 +50,32 @@
position: relative;
border: unset;
}
+
.pdfViewerDash-text-selected {
- // position: relative; // bcz: this breaks auto-scrolling using the inline search box
+ // position: relative; // bcz: this breaks auto-scrolling using the inline search box
z-index: -1;
- .textLayer{
- pointer-events: all;
- user-select: text;
+
+ .textLayer {
+ pointer-events: all;
+ user-select: text;
}
}
+
.pdfViewerDash-text {
transform-origin: top left;
+
.textLayer {
will-change: transform;
}
}
- .pdfViewerDash-overlay, .pdfViewerDash-overlay-inking {
+ .pdfViewerDash-overlay {
transform-origin: left top;
position: absolute;
top: 0px;
left: 0px;
display: inline-block;
- width:100%;
- pointer-events: all;
- }
- .pdfViewerDash-overlay {
- pointer-events: none;
+ width: 100%;
}
.pdfViewerDash-overlayAnno {
@@ -81,7 +88,7 @@
border-radius: 5px;
display: block;
}
-
+
.pdfViewerDash-annotationLayer {
position: absolute;
transform-origin: left top;
@@ -90,12 +97,13 @@
pointer-events: none;
mix-blend-mode: multiply; // bcz: makes text fuzzy!
}
+
.pdfViewerDash-waiting {
width: 70%;
height: 70%;
- margin : 15%;
+ margin: 15%;
transition: 0.4s opacity ease;
- opacity: 0.7;
+ opacity: 0.7;
position: absolute;
z-index: 10;
}
@@ -103,4 +111,4 @@
.pdfViewerDash-interactive {
pointer-events: all;
-} \ No newline at end of file
+} \ No newline at end of file
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 3c052d10b..38890410c 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -1,18 +1,16 @@
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx";
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, trace } from "mobx";
import { observer } from "mobx-react";
import * as Pdfjs from "pdfjs-dist";
import "pdfjs-dist/web/pdf_viewer.css";
-import { Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
+import { Doc, DocListCast, Field, HeightSym, Opt } from "../../../fields/Doc";
import { Id } from "../../../fields/FieldSymbols";
import { InkTool } from "../../../fields/InkField";
-import { Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types";
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
import { PdfField } from "../../../fields/URLField";
import { TraceMobx } from "../../../fields/util";
import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, OmitKeys, smoothScroll, Utils } from "../../../Utils";
import { DocUtils } from "../../documents/Documents";
-import { Networking } from "../../Network";
import { CurrentUserUtils } from "../../util/CurrentUserUtils";
-import { CompiledScript, CompileScript } from "../../util/Scripting";
import { SelectionManager } from "../../util/SelectionManager";
import { SharingManager } from "../../util/SharingManager";
import { SnappingManager } from "../../util/SnappingManager";
@@ -59,11 +57,9 @@ export class PDFViewer extends React.Component<IViewerProps> {
static _annotationStyle: any = addStyleSheet();
@observable private _pageSizes: { width: number, height: number }[] = [];
@observable private _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
- @observable private _script: CompiledScript = CompileScript("return true") as CompiledScript;
@observable private _marqueeing: number[] | undefined;
@observable private _textSelecting = true;
@observable private _showWaiting = true;
- @observable private _showCover = false;
@observable private _zoomed = 1;
@observable private _overlayAnnoInfo: Opt<Doc>;
@observable private Index: number = -1;
@@ -79,14 +75,13 @@ export class PDFViewer extends React.Component<IViewerProps> {
private _selectionText: string = "";
private _downX: number = 0;
private _downY: number = 0;
- private _coverPath: any;
private _lastSearch = false;
private _viewerIsSetup = false;
private _ignoreScroll = false;
private _initialScroll: Opt<number>;
private _forcedScroll = true;
-
+ @observable isAnnotating = false;
// key where data is stored
@computed get allAnnotations() {
return DocUtils.FilterDocs(DocListCast(this.props.dataDoc[this.props.fieldKey + "-annotations"]), this.props.docFilters(), this.props.docRangeFilters(), undefined);
@@ -108,13 +103,11 @@ export class PDFViewer extends React.Component<IViewerProps> {
if (pathComponents.length) {
params.subtree = `${pathComponents.join("/")}/`;
}
- this._coverPath = href.startsWith(window.location.origin) ? await Networking.PostToServer("/thumbnail", params) : { width: 100, height: 100, path: "" };
} else {
const params: any = {
coreFilename: relative.split("/")[relative.split("/").length - 1],
pageNum: Math.min(this.props.pdf.numPages, Math.max(1, NumCast(this.props.Document._curPage, 1))),
};
- this._coverPath = "http://cs.brown.edu/~bcz/face.gif";//href.startsWith(window.location.origin) ? await Networking.PostToServer("/thumbnail", params) : { width: 100, height: 100, path: "" };
}
runInAction(() => this._showWaiting = true);
this.props.startupLive && this.setupPdfJsViewer();
@@ -207,17 +200,6 @@ export class PDFViewer extends React.Component<IViewerProps> {
this.props.setPdfViewer(this);
await this.initialLoad();
- this._disposers.filterScript = reaction(
- () => ScriptCast(this.props.Document.filterScript),
- action(scriptField => {
- const oldScript = this._script.originalScript;
- this._script = scriptField?.script.compiled ? scriptField.script : CompileScript("return true") as CompiledScript;
- if (this._script.originalScript !== oldScript) {
- this.Index = -1;
- }
- }),
- { fireImmediately: true });
-
this.createPdfViewer();
}
@@ -232,7 +214,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
() => Math.abs(NumCast(this.props.Document._scrollTop)),
(pos) => {
if (!this._ignoreScroll) {
- (this._showCover || this._showWaiting) && this.setupPdfJsViewer();
+ this._showWaiting && this.setupPdfJsViewer();
const viewTrans = quickScroll ?? StrCast(this.props.Document._viewTransition);
const durationMiliStr = viewTrans.match(/([0-9]*)ms/);
const durationSecStr = viewTrans.match(/([0-9.]*)s/);
@@ -377,6 +359,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
this.props.select(false);
MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
this._marqueeing = [e.clientX, e.clientY];
+ this.isAnnotating = true;
if (e.target && ((e.target as any).className.includes("endOfContent") || ((e.target as any).parentElement.className !== "textLayer"))) {
this._textSelecting = false;
document.addEventListener("pointermove", this.onSelectMove); // need this to prevent document from being dragged if stopPropagation doesn't get called
@@ -393,6 +376,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
@action
finishMarquee = (x?: number, y?: number) => {
+ this.isAnnotating = false;
this._marqueeing = undefined;
this._textSelecting = true;
document.removeEventListener("pointermove", this.onSelectMove);
@@ -402,6 +386,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
@action
onSelectEnd = (e: PointerEvent): void => {
+ this.isAnnotating = false;
clearStyleSheetRules(PDFViewer._annotationStyle);
this.props.select(false);
document.removeEventListener("pointermove", this.onSelectMove);
@@ -459,20 +444,6 @@ export class PDFViewer extends React.Component<IViewerProps> {
setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean) => void) => this._setPreviewCursor = func;
- getCoverImage = () => {
- if (!this.props.Document[HeightSym]() || !Doc.NativeHeight(this.props.Document)) {
- setTimeout((() => {
- this.props.Document._height = this.props.Document[WidthSym]() * this._coverPath.height / this._coverPath.width;
- Doc.SetNativeWidth(this.props.Document, (Doc.NativeWidth(this.props.Document) || 0) * this._coverPath.height / this._coverPath.width);
- }).bind(this), 0);
- }
- const nativeWidth = Doc.NativeWidth(this.props.Document);
- const nativeHeight = Doc.NativeHeight(this.props.Document);
- const resolved = Utils.prepend(this._coverPath.path);
- return <img key={resolved} src={resolved} onError={action(() => this._coverPath.path = "http://www.cs.brown.edu/~bcz/face.gif")} onLoad={action(() => this._showWaiting = false)}
- style={{ position: "absolute", display: "inline-block", top: 0, left: 0, width: `${nativeWidth}px`, height: `${nativeHeight}px` }} />;
- }
-
@action
onZoomWheel = (e: React.WheelEvent) => {
if (this.props.isContentActive(true)) {
@@ -495,7 +466,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
}
@computed get overlayInfo() {
- return !this._overlayAnnoInfo || this._overlayAnnoInfo.author === Doc.CurrentUserEmail ? (null) :
+ return !this._overlayAnnoInfo ? (null) :
<div className="pdfViewerDash-overlayAnno" style={{ top: NumCast(this._overlayAnnoInfo.y), left: NumCast(this._overlayAnnoInfo.x) }}>
<div className="pdfViewerDash-overlayAnno" style={{ right: -50, background: SharingManager.Instance.users.find(users => users.user.email === this._overlayAnnoInfo!.author)?.userColor }}>
{this._overlayAnnoInfo.author + " " + Field.toString(this._overlayAnnoInfo.creationDate as Field)}
@@ -517,41 +488,76 @@ export class PDFViewer extends React.Component<IViewerProps> {
}
return this.props.styleProvider?.(doc, props, property);
}
+ renderAnnotations = (docFilters?: () => string[]) =>
+ <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
+ isAnnotationOverlay={true}
+ fieldKey={this.props.fieldKey + "-annotations"}
+ setPreviewCursor={this.setPreviewCursor}
+ PanelHeight={this.panelHeight}
+ PanelWidth={this.panelWidth}
+ dropAction={"alias"}
+ select={emptyFunction}
+ ContentScaling={this.contentZoom}
+ bringToFront={emptyFunction}
+ docFilters={docFilters || this.basicFilter}
+ styleProvider={this.childStyleProvider}
+ dontRenderDocuments={docFilters ? false : true}
+ CollectionView={undefined}
+ ScreenToLocalTransform={this.overlayTransform}
+ renderDepth={this.props.renderDepth + 1} />;
+
+ @computed get overlayLayerClickableAnnotations() {
+ return SnappingManager.GetIsDragging() ? (null) : this.renderAnnotations();
+ }
+ @computed get overlayLayerOpaqueAnnotations() {
+ trace();
+ return <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
+ isAnnotationOverlay={true}
+ fieldKey={this.props.fieldKey + "-annotations"}
+ setPreviewCursor={this.setPreviewCursor}
+ PanelHeight={this.panelHeight}
+ PanelWidth={this.panelWidth}
+ dropAction={"alias"}
+ select={emptyFunction}
+ ContentScaling={this.contentZoom}
+ bringToFront={emptyFunction}
+ docFilters={this.opaqueFilter}
+ styleProvider={this.childStyleProvider}
+ dontRenderDocuments={false}
+ CollectionView={undefined}
+ ScreenToLocalTransform={this.overlayTransform}
+ renderDepth={this.props.renderDepth + 1} />
+ }
+ @computed get overlayLayerTransparentAnnotations() {
+ trace();
+ return <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
+ isAnnotationOverlay={true}
+ fieldKey={this.props.fieldKey + "-annotations"}
+ setPreviewCursor={this.setPreviewCursor}
+ PanelHeight={this.panelHeight}
+ PanelWidth={this.panelWidth}
+ dropAction={"alias"}
+ select={emptyFunction}
+ ContentScaling={this.contentZoom}
+ bringToFront={emptyFunction}
+ docFilters={this.transparentFilter}
+ styleProvider={this.childStyleProvider}
+ dontRenderDocuments={false}
+ CollectionView={undefined}
+ ScreenToLocalTransform={this.overlayTransform}
+ renderDepth={this.props.renderDepth + 1} />
+ }
@computed get overlayLayer() {
- const renderAnnotations = (docFilters?: () => string[]) =>
- <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
- isAnnotationOverlay={true}
- fieldKey={this.props.fieldKey + "-annotations"}
- setPreviewCursor={this.setPreviewCursor}
- PanelHeight={this.panelHeight}
- PanelWidth={this.panelWidth}
- dropAction={"alias"}
- select={emptyFunction}
- ContentScaling={this.contentZoom}
- bringToFront={emptyFunction}
- docFilters={docFilters || this.basicFilter}
- styleProvider={this.childStyleProvider}
- dontRenderDocuments={docFilters ? false : true}
- CollectionView={undefined}
- ScreenToLocalTransform={this.overlayTransform}
- renderDepth={this.props.renderDepth + 1} />;
- return <div>
- <div className={`pdfViewerDash-overlay${CurrentUserUtils.SelectedTool !== InkTool.None || SnappingManager.GetIsDragging() ? "-inking" : ""}`}
- style={{
- pointerEvents: SnappingManager.GetIsDragging() ? "all" : undefined,
- mixBlendMode: "multiply",
- transform: `scale(${this._zoomed})`
- }}>
- {renderAnnotations(this.transparentFilter)}
+ return <div className="pdfViewerDash-overlay" style={{
+ transform: `scale(${this._zoomed})`,
+ pointerEvents: CurrentUserUtils.SelectedTool !== InkTool.None || SnappingManager.GetIsDragging() ? "all" : "none",
+ }} >
+ <div className="pdfViewerDash-overlay" key="muliplied" style={{ mixBlendMode: "multiply", }}>
+ {this.overlayLayerTransparentAnnotations}
</div>
- <div className={`pdfViewerDash-overlay${CurrentUserUtils.SelectedTool !== InkTool.None || SnappingManager.GetIsDragging() ? "-inking" : ""}`}
- style={{
- pointerEvents: SnappingManager.GetIsDragging() ? "all" : undefined,
- mixBlendMode: this.allAnnotations.some(anno => anno.mixBlendMode) ? "hard-light" : undefined,
- transform: `scale(${this._zoomed})`
- }}>
- {renderAnnotations(this.opaqueFilter)}
- {SnappingManager.GetIsDragging() ? (null) : renderAnnotations()}
+ <div className="pdfViewerDash-overlay" key="blended" style={{ mixBlendMode: this.allAnnotations.some(anno => anno.mixBlendMode) ? "hard-light" : undefined, }}>
+ {this.overlayLayerOpaqueAnnotations}
+ {this.overlayLayerClickableAnnotations}
</div>
</div>;
}
@@ -559,12 +565,6 @@ export class PDFViewer extends React.Component<IViewerProps> {
return <div className={"pdfViewerDash-text" + (this.props.pointerEvents !== "none" && this._textSelecting && this.props.isContentActive() ? "-selected" : "")} ref={this._viewer} />;
}
@computed get contentScaling() { return this.props.ContentScaling?.() || 1; }
- @computed get standinViews() {
- return <>
- {this._showCover ? this.getCoverImage() : (null)}
- {this._showWaiting ? <img className="pdfViewerDash-waiting" key="waiting" src={"/assets/loading.gif"} /> : (null)}
- </>;
- }
contentZoom = () => this._zoomed;
savedAnnotations = () => this._savedAnnotations;
render() {
@@ -581,7 +581,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
{this.annotationLayer}
{this.overlayLayer}
{this.overlayInfo}
- {this.standinViews}
+ {this._showWaiting ? <img className="pdfViewerDash-waiting" src={"/assets/loading.gif"} /> : (null)}
{!this._marqueeing || !this._mainCont.current || !this._annotationLayer.current ? (null) :
<MarqueeAnnotator rootDoc={this.props.rootDoc}
getPageFromScroll={this.getPageFromScroll}
@@ -594,7 +594,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
savedAnnotations={this.savedAnnotations}
annotationLayer={this._annotationLayer.current}
mainCont={this._mainCont.current}
- anchorMenuCrop={this.crop}
+ anchorMenuCrop={this._textSelecting ? undefined : this.crop}
/>}
</div>
</div>;
diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts
index 4d5ae1018..e532becb5 100644
--- a/src/fields/documentSchemas.ts
+++ b/src/fields/documentSchemas.ts
@@ -44,7 +44,6 @@ export const documentSchema = createSchema({
_showCaption: "string", // whether editable caption text is overlayed at the bottom of the document
_showTitle: "string", // the fieldkey(s) whose contents should be displayed at the top of the document. separate multiple keys with ";". Use :hover suffix to indicate title should be shown on hover
_showAudio: "boolean", // whether to show the audio record icon on documents
- _freeformLOD: "boolean", // whether to enable LOD switching for CollectionFreeFormViews
_pivotField: "string", // specifies which field key should be used as the timeline/pivot axis
_columnsFill: "boolean", // whether documents in a stacking view column should be sized to fill the column
_columnsSort: "string", // how a document should be sorted "ascending", "descending", undefined (none)