aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes')
-rw-r--r--src/client/views/nodes/AudioBox.tsx16
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx88
-rw-r--r--src/client/views/nodes/ColorBox.tsx12
-rw-r--r--src/client/views/nodes/ComparisonBox.scss93
-rw-r--r--src/client/views/nodes/ComparisonBox.tsx114
-rw-r--r--src/client/views/nodes/ContentFittingDocumentView.tsx6
-rw-r--r--src/client/views/nodes/DocHolderBox.tsx12
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx13
-rw-r--r--src/client/views/nodes/DocumentIcon.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.scss1
-rw-r--r--src/client/views/nodes/DocumentView.tsx74
-rw-r--r--src/client/views/nodes/FaceRectangles.tsx6
-rw-r--r--src/client/views/nodes/FieldView.tsx10
-rw-r--r--src/client/views/nodes/FontIconBox.tsx8
-rw-r--r--src/client/views/nodes/ImageBox.tsx27
-rw-r--r--src/client/views/nodes/KeyValueBox.tsx14
-rw-r--r--src/client/views/nodes/KeyValuePair.tsx6
-rw-r--r--src/client/views/nodes/LabelBox.tsx13
-rw-r--r--src/client/views/nodes/LinkAnchorBox.tsx12
-rw-r--r--src/client/views/nodes/LinkBox.tsx6
-rw-r--r--src/client/views/nodes/PDFBox.tsx12
-rw-r--r--src/client/views/nodes/PresBox.tsx47
-rw-r--r--src/client/views/nodes/ScreenshotBox.tsx19
-rw-r--r--src/client/views/nodes/ScriptingBox.tsx10
-rw-r--r--src/client/views/nodes/SliderBox.tsx8
-rw-r--r--src/client/views/nodes/VideoBox.tsx80
-rw-r--r--src/client/views/nodes/WebBox.scss52
-rw-r--r--src/client/views/nodes/WebBox.tsx229
-rw-r--r--src/client/views/nodes/formattedText/DashDocCommentView.tsx16
-rw-r--r--src/client/views/nodes/formattedText/DashDocView.tsx10
-rw-r--r--src/client/views/nodes/formattedText/DashFieldView.tsx12
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx48
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx8
-rw-r--r--src/client/views/nodes/formattedText/ImageResizeView.tsx2
-rw-r--r--src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts24
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx6
-rw-r--r--src/client/views/nodes/formattedText/RichTextRules.ts10
-rw-r--r--src/client/views/nodes/formattedText/RichTextSchema.tsx16
-rw-r--r--src/client/views/nodes/formattedText/marks_rts.ts2
39 files changed, 795 insertions, 349 deletions
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 1c5e13620..1a935d9b0 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -2,23 +2,23 @@ import React = require("react");
import { FieldViewProps, FieldView } from './FieldView';
import { observer } from "mobx-react";
import "./AudioBox.scss";
-import { Cast, DateCast, NumCast } from "../../../new_fields/Types";
-import { AudioField, nullAudio } from "../../../new_fields/URLField";
+import { Cast, DateCast, NumCast } from "../../../fields/Types";
+import { AudioField, nullAudio } from "../../../fields/URLField";
import { ViewBoxBaseComponent } from "../DocComponent";
-import { makeInterface, createSchema } from "../../../new_fields/Schema";
-import { documentSchema } from "../../../new_fields/documentSchemas";
+import { makeInterface, createSchema } from "../../../fields/Schema";
+import { documentSchema } from "../../../fields/documentSchemas";
import { Utils, returnTrue, emptyFunction, returnOne, returnTransparent, returnFalse, returnZero } from "../../../Utils";
import { runInAction, observable, reaction, IReactionDisposer, computed, action } from "mobx";
-import { DateField } from "../../../new_fields/DateField";
+import { DateField } from "../../../fields/DateField";
import { SelectionManager } from "../../util/SelectionManager";
-import { Doc, DocListCast } from "../../../new_fields/Doc";
+import { Doc, DocListCast } from "../../../fields/Doc";
import { ContextMenuProps } from "../ContextMenuItem";
import { ContextMenu } from "../ContextMenu";
-import { Id } from "../../../new_fields/FieldSymbols";
+import { Id } from "../../../fields/FieldSymbols";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { DocumentView } from "./DocumentView";
import { Docs, DocUtils } from "../../documents/Documents";
-import { ComputedField } from "../../../new_fields/ScriptField";
+import { ComputedField } from "../../../fields/ScriptField";
import { Networking } from "../../Network";
import { LinkAnchorBox } from "./LinkAnchorBox";
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index cdbe506a5..910aa744d 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,18 +1,22 @@
import { computed, IReactionDisposer, observable, reaction, trace } from "mobx";
import { observer } from "mobx-react";
-import { Doc, HeightSym, WidthSym } from "../../../new_fields/Doc";
-import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { Doc, HeightSym, WidthSym } from "../../../fields/Doc";
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
import { Transform } from "../../util/Transform";
import { DocComponent } from "../DocComponent";
import "./CollectionFreeFormDocumentView.scss";
import { DocumentView, DocumentViewProps } from "./DocumentView";
import React = require("react");
-import { Document } from "../../../new_fields/documentSchemas";
-import { TraceMobx } from "../../../new_fields/util";
+import { Document } from "../../../fields/documentSchemas";
+import { TraceMobx } from "../../../fields/util";
import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
+import { List } from "../../../fields/List";
+import { numberRange } from "../../../Utils";
+import { ComputedField } from "../../../fields/ScriptField";
+import { listSpec } from "../../../fields/Schema";
export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
- dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, highlight?: boolean, z: number, transition?: string } | undefined;
+ dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined;
sizeProvider?: (doc: Doc, replica: string) => { width: number, height: number } | undefined;
zIndex?: number;
highlight?: boolean;
@@ -31,10 +35,11 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
const rnd = seed / 233280;
return min + rnd * (max - min);
}
- get displayName() { return "CollectionFreeFormDocumentView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive
+ get displayName() { return "CollectionFreeFormDocumentView(" + this.rootDoc.title + ")"; } // this makes mobx trace() statements more descriptive
get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) rotate(${this.random(-1, 1) * this.props.jitterRotation}deg)`; }
get X() { return this.dataProvider ? this.dataProvider.x : (this.Document.x || 0); }
get Y() { return this.dataProvider ? this.dataProvider.y : (this.Document.y || 0); }
+ get Opacity() { return this.dataProvider ? this.dataProvider.opacity : Cast(this.layoutDoc.opacity, "number", null); }
get ZInd() { return this.dataProvider ? this.dataProvider.zIndex : (this.Document.zIndex || 0); }
get Highlight() { return this.dataProvider?.highlight; }
get width() { return this.props.sizeProvider && this.sizeProvider ? this.sizeProvider.width : this.layoutDoc[WidthSym](); }
@@ -62,6 +67,62 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
}
return undefined;
}
+
+ public static getValues(doc: Doc, time: number) {
+ const timecode = Math.round(time);
+ return ({
+ x: Cast(doc["x-indexed"], listSpec("number"), []).reduce((p, x, i) => (i <= timecode && x !== undefined) || p === undefined ? x : p, undefined as any as number),
+ y: Cast(doc["y-indexed"], listSpec("number"), []).reduce((p, y, i) => (i <= timecode && y !== undefined) || p === undefined ? y : p, undefined as any as number),
+ opacity: Cast(doc["opacity-indexed"], listSpec("number"), []).reduce((p, o, i) => i <= timecode || p === undefined ? o : p, undefined as any as number),
+ });
+ }
+
+ public static setValues(time: number, d: Doc, x?: number, y?: number, opacity?: number) {
+ const timecode = Math.round(time);
+ Cast(d["x-indexed"], listSpec("number"), [])[Math.max(0, timecode - 1)] = x as any as number;
+ Cast(d["y-indexed"], listSpec("number"), [])[Math.max(0, timecode - 1)] = y as any as number;
+ Cast(d["x-indexed"], listSpec("number"), [])[timecode] = x as any as number;
+ Cast(d["y-indexed"], listSpec("number"), [])[timecode] = y as any as number;
+ Cast(d["opacity-indexed"], listSpec("number"), null)[timecode] = opacity as any as number;
+ }
+ public static updateKeyframe(docs: Doc[], time: number) {
+ const timecode = Math.round(time);
+ docs.forEach(doc => {
+ const xindexed = Cast(doc['x-indexed'], listSpec("number"), null);
+ const yindexed = Cast(doc['y-indexed'], listSpec("number"), null);
+ const opacityindexed = Cast(doc['opacity-indexed'], listSpec("number"), null);
+ xindexed?.length <= timecode + 1 && xindexed.push(undefined as any as number);
+ yindexed?.length <= timecode + 1 && yindexed.push(undefined as any as number);
+ opacityindexed?.length <= timecode + 1 && opacityindexed.push(undefined as any as number);
+ doc.transition = "all 1s";
+ });
+ setTimeout(() => docs.forEach(doc => doc.transition = "inherit"), 1010);
+ }
+
+ public static gotoKeyframe(docs: Doc[]) {
+ docs.forEach(doc => doc.transition = "all 1s");
+ setTimeout(() => docs.forEach(doc => doc.transition = "inherit"), 1010);
+ }
+
+ public static setupKeyframes(docs: Doc[], timecode: number, progressivize: boolean = false) {
+ docs.forEach((doc, i) => {
+ const curTimecode = progressivize ? i : timecode;
+ const xlist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
+ const ylist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
+ const olist = new List<number>(numberRange(timecode + 1).map(t => progressivize && t < i ? 0 : 1));
+ xlist[Math.max(curTimecode - 1, 0)] = xlist[curTimecode] = NumCast(doc.x);
+ ylist[Math.max(curTimecode - 1, 0)] = ylist[curTimecode] = NumCast(doc.y);
+ doc["x-indexed"] = xlist;
+ doc["y-indexed"] = ylist;
+ doc["opacity-indexed"] = olist;
+ doc.activeFrame = ComputedField.MakeFunction("self.context ? (self.context.currentFrame||0) : 0");
+ doc.x = ComputedField.MakeInterpolated("x", "activeFrame");
+ doc.y = ComputedField.MakeInterpolated("y", "activeFrame");
+ doc.opacity = ComputedField.MakeInterpolated("opacity", "activeFrame");
+ doc.transition = "inherit";
+ });
+ }
+
nudge = (x: number, y: number) => {
this.props.Document.x = NumCast(this.props.Document.x) + x;
this.props.Document.y = NumCast(this.props.Document.y) + y;
@@ -72,14 +133,16 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
panelHeight = () => (this.sizeProvider?.height || this.props.PanelHeight?.());
getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y).scale(1 / this.contentScaling());
focusDoc = (doc: Doc) => this.props.focus(doc, false);
+ opacity = () => this.Opacity;
NativeWidth = () => this.nativeWidth;
NativeHeight = () => this.nativeHeight;
render() {
TraceMobx();
+ const backgroundColor = StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.Document.backgroundColor) || this.props.backgroundColor?.(this.Document);
return <div className="collectionFreeFormDocumentView-container"
style={{
boxShadow:
- this.layoutDoc.opacity === 0 ? undefined : // if it's not visible, then no shadow
+ this.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.props.backgroundHalo?.() ? (`${this.props.backgroundColor?.(this.props.Document)} ${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 ? undefined : // if it's a background & has a cluster color, make the shadow spread really big
@@ -91,9 +154,17 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
width: this.width,
height: this.height,
zIndex: this.ZInd,
+ mixBlendMode: StrCast(this.layoutDoc.mixBlendMode) as any,
display: this.ZInd === -99 ? "none" : undefined,
- pointerEvents: this.props.Document.isBackground ? "none" : this.props.pointerEvents ? "all" : undefined
+ pointerEvents: this.props.Document.isBackground || this.Opacity === 0 ? "none" : this.props.pointerEvents ? "all" : undefined
}} >
+ {Doc.UserDoc().renderStyle !== "comic" ? (null) :
+ <div style={{ width: "100%", height: "100%", position: "absolute" }}>
+ <svg style={{ transform: `scale(1,${this.props.PanelHeight() / this.props.PanelWidth()})`, transformOrigin: "top left", overflow: "visible" }} viewBox="0 0 12 14">
+ <path d="M 7 0 C 9 -1 13 1 12 4 C 11 10 13 12 10 12 C 6 12 7 13 2 12 Q -1 11 0 8 C 1 4 0 4 0 2 C 0 0 1 0 1 0 C 3 0 3 1 7 0"
+ style={{ stroke: "black", fill: backgroundColor, strokeWidth: 0.2 }} />
+ </svg>
+ </div>}
{!this.props.fitToBox ?
<DocumentView {...this.props}
@@ -102,6 +173,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
ContentScaling={this.contentScaling}
ScreenToLocalTransform={this.getTransform}
backgroundColor={this.props.backgroundColor}
+ opacity={this.opacity}
NativeHeight={this.NativeHeight}
NativeWidth={this.NativeWidth}
PanelWidth={this.panelWidth}
diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx
index 7ab6d99c2..6d53915ea 100644
--- a/src/client/views/nodes/ColorBox.tsx
+++ b/src/client/views/nodes/ColorBox.tsx
@@ -1,10 +1,10 @@
import React = require("react");
import { observer } from "mobx-react";
import { SketchPicker } from 'react-color';
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { makeInterface } from "../../../new_fields/Schema";
-import { StrCast } from "../../../new_fields/Types";
-import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { makeInterface } from "../../../fields/Schema";
+import { StrCast } from "../../../fields/Types";
+import { CurrentUserUtils } from "../../util/CurrentUserUtils";
import { SelectionManager } from "../../util/SelectionManager";
import { ViewBoxBaseComponent } from "../DocComponent";
import { InkingControl } from "../InkingControl";
@@ -27,6 +27,10 @@ export class ColorBox extends ViewBoxBaseComponent<FieldViewProps, ColorDocument
<SketchPicker onChange={InkingControl.Instance.switchColor} presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']}
color={StrCast(CurrentUserUtils.ActivePen ? CurrentUserUtils.ActivePen.backgroundColor : undefined,
StrCast(selDoc?._backgroundColor, StrCast(selDoc?.backgroundColor, "black")))} />
+ <div style={{ display: "grid", gridTemplateColumns: "20% 80%", paddingTop: "10px" }}>
+ <div>{InkingControl.Instance.selectedWidth ?? 2}</div>
+ <input type="range" value={InkingControl.Instance.selectedWidth ?? 2} defaultValue={2} min={1} max={100} onChange={(e: React.ChangeEvent<HTMLInputElement>) => InkingControl.Instance.switchWidth(e.target.value)} />
+ </div>
</div>;
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/ComparisonBox.scss b/src/client/views/nodes/ComparisonBox.scss
new file mode 100644
index 000000000..810a824cf
--- /dev/null
+++ b/src/client/views/nodes/ComparisonBox.scss
@@ -0,0 +1,93 @@
+.comparisonBox-interactive,
+.comparisonBox {
+ border-radius: inherit;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ z-index: 0;
+ pointer-events: none;
+
+ .clip-div {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ overflow: hidden;
+
+ .beforeBox-cont {
+ height: 100%;
+ overflow: hidden;
+ }
+ }
+
+ .slide-bar {
+ position: absolute;
+ height: 100%;
+ width: 3px;
+ display: inline-block;
+ background: white;
+
+ .slide-handle {
+ position: absolute;
+ display: none;
+ height: 20px;
+ width: 30px;
+ bottom: 0px;
+ left: -10.5px;
+
+ .left-handle,
+ .right-handle {
+ width: 15px;
+ }
+ }
+ }
+
+ .afterBox-cont {
+ position: absolute;
+ top: 0;
+ right: 0;
+ height: 100%;
+ width: 100%;
+ overflow: hidden;
+ }
+
+ .clear-button {
+ position: absolute;
+ top: 3px;
+ opacity: 0.8;
+ pointer-events: all;
+ cursor: pointer;
+ }
+
+ .clear-button.before {
+ left: 3px;
+ }
+
+ .clear-button.after {
+ right: 3px;
+ }
+
+ .placeholder {
+ width: 50%;
+ height: 50%;
+ margin-top: 25%;
+ margin-left: 25%;
+
+ .upload-icon {
+ width: 100%;
+ height: 100%;
+ opacity: 0.5;
+ }
+ }
+}
+
+.comparisonBox-interactive {
+ pointer-events: unset;
+ cursor: ew-resize;
+
+ .slide-bar {
+ .slide-handle {
+ display: flex;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
new file mode 100644
index 000000000..cce60628d
--- /dev/null
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -0,0 +1,114 @@
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { action, observable } from 'mobx';
+import { observer } from "mobx-react";
+import { Doc } from '../../../fields/Doc';
+import { documentSchema } from '../../../fields/documentSchemas';
+import { createSchema, makeInterface } from '../../../fields/Schema';
+import { NumCast, Cast, StrCast } from '../../../fields/Types';
+import { DragManager } from '../../util/DragManager';
+import { ViewBoxAnnotatableComponent } from '../DocComponent';
+import { FieldView, FieldViewProps } from './FieldView';
+import "./ComparisonBox.scss";
+import React = require("react");
+import { ContentFittingDocumentView } from './ContentFittingDocumentView';
+import { undoBatch } from '../../util/UndoManager';
+import { setupMoveUpEvents, emptyFunction } from '../../../Utils';
+import { SnappingManager } from '../../util/SnappingManager';
+import { DocumentViewProps } from './DocumentView';
+
+export const comparisonSchema = createSchema({});
+
+type ComparisonDocument = makeInterface<[typeof comparisonSchema, typeof documentSchema]>;
+const ComparisonDocument = makeInterface(comparisonSchema, documentSchema);
+
+@observer
+export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps, ComparisonDocument>(ComparisonDocument) {
+ public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ComparisonBox, fieldKey); }
+ protected multiTouchDisposer?: import("../../util/InteractionUtils").InteractionUtils.MultiTouchEventDisposer | undefined;
+ private _disposers: (DragManager.DragDropDisposer | undefined)[] = [undefined, undefined];
+
+ @observable _animating = "";
+
+ protected createDropTarget = (ele: HTMLDivElement | null, fieldKey: string, disposerId: number) => {
+ this._disposers[disposerId]?.();
+ if (ele) {
+ // create disposers identified by disposerId to remove drag & drop listeners
+ this._disposers[disposerId] = DragManager.MakeDropTarget(ele, (e, dropEvent) => this.dropHandler(e, dropEvent, fieldKey), this.layoutDoc);
+ }
+ }
+
+ @undoBatch
+ private dropHandler = (event: Event, dropEvent: DragManager.DropEvent, fieldKey: string) => {
+ event.stopPropagation(); // prevent parent Doc from registering new position so that it snaps back into place
+ const droppedDocs = dropEvent.complete.docDragData?.droppedDocuments;
+ if (droppedDocs?.length) {
+ this.dataDoc[fieldKey] = droppedDocs[0];
+ }
+ }
+
+ private registerSliding = (e: React.PointerEvent<HTMLDivElement>, targetWidth: number) => {
+ setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, action(() => {
+ // on click, animate slider movement to the targetWidth
+ this._animating = "all 1s";
+ this.layoutDoc._clipWidth = targetWidth * 100 / this.props.PanelWidth();
+ setTimeout(action(() => this._animating = ""), 1000);
+ }), false);
+ }
+
+ @action
+ private onPointerMove = ({ movementX }: PointerEvent) => {
+ const width = movementX * this.props.ScreenToLocalTransform().Scale + NumCast(this.layoutDoc._clipWidth) / 100 * this.props.PanelWidth();
+ if (width && width > 5 && width < this.props.PanelWidth()) {
+ this.layoutDoc._clipWidth = width * 100 / this.props.PanelWidth();
+ }
+ return false;
+ }
+
+ @undoBatch
+ clearDoc = (e: React.MouseEvent, fieldKey: string) => {
+ e.stopPropagation; // prevent click event action (slider movement) in registerSliding
+ delete this.dataDoc[fieldKey];
+ }
+
+ render() {
+ const clipWidth = NumCast(this.layoutDoc._clipWidth) + "%";
+ const childProps: DocumentViewProps = { ...this.props, pointerEvents: false, parentActive: this.props.active };
+ const clearButton = (which: string) => {
+ return <div className={`clear-button ${which}`}
+ onPointerDown={e => e.stopPropagation()} // prevent triggering slider movement in registerSliding
+ onClick={e => this.clearDoc(e, `${which}Doc`)}>
+ <FontAwesomeIcon className={`clear-button ${which}`} icon={"times"} size="sm" />
+ </div>;
+ };
+ const displayDoc = (which: string) => {
+ const whichDoc = Cast(this.dataDoc[`${which}Doc`], Doc, null);
+ return whichDoc ? <>
+ <ContentFittingDocumentView {...childProps} Document={whichDoc} />
+ {clearButton(which)}
+ </> : // placeholder image if doc is missing
+ <div className="placeholder">
+ <FontAwesomeIcon className="upload-icon" icon={"cloud-upload-alt"} size="lg" />
+ </div>;
+ };
+ const displayBox = (which: string, index: number, cover: number) => {
+ return <div className={`${which}Box-cont`} key={which} style={{ width: this.props.PanelWidth() }}
+ onPointerDown={e => this.registerSliding(e, cover)}
+ ref={ele => this.createDropTarget(ele, `${which}Doc`, index)} >
+ {displayDoc(which)}
+ </div>;
+ };
+
+ return (
+ <div className={`comparisonBox${this.active() || SnappingManager.GetIsDragging() ? "-interactive" : ""}` /* change className to easily disable/enable pointer events in CSS */}>
+ {displayBox("after", 1, this.props.PanelWidth() - 5)}
+ <div className="clip-div" style={{ width: clipWidth, transition: this._animating, background: StrCast(this.layoutDoc._backgroundColor, "gray") }}>
+ {displayBox("before", 0, 5)}
+ </div>
+
+ <div className="slide-bar" style={{ left: `calc(${clipWidth} - 0.5px)` }}
+ onPointerDown={e => this.registerSliding(e, this.props.PanelWidth() / 2)} /* if clicked, return slide-bar to center */ >
+ <div className="slide-handle" />
+ </div>
+ </div >);
+ }
+} \ No newline at end of file
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index 1c6250b94..a90b4668e 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -2,9 +2,9 @@ import React = require("react");
import { computed } from "mobx";
import { observer } from "mobx-react";
import "react-table/react-table.css";
-import { Doc, Opt, WidthSym, HeightSym } from "../../../new_fields/Doc";
-import { NumCast, StrCast, Cast } from "../../../new_fields/Types";
-import { TraceMobx } from "../../../new_fields/util";
+import { Doc, Opt, WidthSym, HeightSym } from "../../../fields/Doc";
+import { NumCast, StrCast, Cast } from "../../../fields/Types";
+import { TraceMobx } from "../../../fields/util";
import { emptyFunction, returnOne } from "../../../Utils";
import '../DocumentDecorations.scss';
import { DocumentView, DocumentViewProps } from "../nodes/DocumentView";
diff --git a/src/client/views/nodes/DocHolderBox.tsx b/src/client/views/nodes/DocHolderBox.tsx
index af8dc704c..0c5239d66 100644
--- a/src/client/views/nodes/DocHolderBox.tsx
+++ b/src/client/views/nodes/DocHolderBox.tsx
@@ -1,12 +1,12 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { action, IReactionDisposer, reaction } from "mobx";
import { observer } from "mobx-react";
-import { Doc, Field } from "../../../new_fields/Doc";
-import { collectionSchema, documentSchema } from "../../../new_fields/documentSchemas";
-import { makeInterface, listSpec } from "../../../new_fields/Schema";
-import { ComputedField } from "../../../new_fields/ScriptField";
-import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { TraceMobx } from "../../../new_fields/util";
+import { Doc, Field } from "../../../fields/Doc";
+import { collectionSchema, documentSchema } from "../../../fields/documentSchemas";
+import { makeInterface, listSpec } from "../../../fields/Schema";
+import { ComputedField } from "../../../fields/ScriptField";
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
+import { TraceMobx } from "../../../fields/util";
import { emptyPath, returnFalse, returnOne, returnZero } from "../../../Utils";
import { DocumentType } from "../../documents/DocumentTypes";
import { DragManager } from "../../util/DragManager";
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 729209fd7..03383882d 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -1,7 +1,7 @@
import { computed } from "mobx";
import { observer } from "mobx-react";
-import { Doc, Opt, Field } from "../../../new_fields/Doc";
-import { Cast, StrCast, NumCast } from "../../../new_fields/Types";
+import { Doc, Opt, Field, AclSym, AclPrivate } from "../../../fields/Doc";
+import { Cast, StrCast, NumCast } from "../../../fields/Types";
import { OmitKeys, Without, emptyPath } from "../../../Utils";
import DirectoryImportBox from "../../util/Import & Export/DirectoryImportBox";
import { CollectionDockingView } from "../collections/CollectionDockingView";
@@ -31,13 +31,14 @@ import { DashWebRTCVideo } from "../webcam/DashWebRTCVideo";
import { LinkAnchorBox } from "./LinkAnchorBox";
import { PresElementBox } from "../presentationview/PresElementBox";
import { ScreenshotBox } from "./ScreenshotBox";
+import { ComparisonBox } from "./ComparisonBox";
import { VideoBox } from "./VideoBox";
import { WebBox } from "./WebBox";
import { InkingStroke } from "../InkingStroke";
import React = require("react");
import { RecommendationsBox } from "../RecommendationsBox";
-import { TraceMobx } from "../../../new_fields/util";
-import { ScriptField } from "../../../new_fields/ScriptField";
+import { TraceMobx } from "../../../fields/util";
+import { ScriptField } from "../../../fields/ScriptField";
import XRegExp = require("xregexp");
const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
@@ -185,7 +186,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
const bindings = this.CreateBindings(onClick, onInput);
// layoutFrame = splits.length > 1 ? splits[0] + splits[1].replace(/{([^{}]|(?R))*}/, replacer4) : ""; // might have been more elegant if javascript supported recursive patterns
- return (this.props.renderDepth > 12 || !layoutFrame || !this.layoutDoc) ? (null) :
+ return (this.props.renderDepth > 12 || !layoutFrame || !this.layoutDoc || this.layoutDoc[AclSym] === AclPrivate) ? (null) :
<ObserverJsxParser
key={42}
blacklistedAttrs={[]}
@@ -195,7 +196,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox,
PDFBox, VideoBox, AudioBox, PresBox, YoutubeBox, PresElementBox, SearchBox, SearchItem,
ColorBox, DashWebRTCVideo, LinkAnchorBox, InkingStroke, DocHolderBox, LinkBox, ScriptingBox,
- RecommendationsBox, ScreenshotBox, HTMLtag
+ RecommendationsBox, ScreenshotBox, HTMLtag, ComparisonBox
}}
bindings={bindings}
jsx={layoutFrame}
diff --git a/src/client/views/nodes/DocumentIcon.tsx b/src/client/views/nodes/DocumentIcon.tsx
index f56f5e829..fb54f18e8 100644
--- a/src/client/views/nodes/DocumentIcon.tsx
+++ b/src/client/views/nodes/DocumentIcon.tsx
@@ -3,7 +3,7 @@ import * as React from "react";
import { DocumentView } from "./DocumentView";
import { DocumentManager } from "../../util/DocumentManager";
import { Transformer, Scripting, ts } from "../../util/Scripting";
-import { Field } from "../../../new_fields/Doc";
+import { Field } from "../../../fields/Doc";
@observer
export class DocumentIcon extends React.Component<{ view: DocumentView, index: number }> {
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index dea09cb30..b7726f7ba 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -94,6 +94,7 @@
text-align: center;
text-overflow: ellipsis;
white-space: pre;
+ position: absolute;
}
.documentView-titleWrapper-hover {
display:none;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 3d20148e7..b4757e0a4 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -4,16 +4,15 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
import * as rp from "request-promise";
-import { Doc, DocListCast, HeightSym, Opt, WidthSym, DataSym } from "../../../new_fields/Doc";
-import { Document } from '../../../new_fields/documentSchemas';
-import { Id } from '../../../new_fields/FieldSymbols';
-import { InkTool } from '../../../new_fields/InkField';
-import { listSpec } from "../../../new_fields/Schema";
-import { SchemaHeaderField } from '../../../new_fields/SchemaHeaderField';
-import { ScriptField } from '../../../new_fields/ScriptField';
-import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { ImageField } from '../../../new_fields/URLField';
-import { TraceMobx } from '../../../new_fields/util';
+import { Doc, DocListCast, HeightSym, Opt, WidthSym, DataSym, AclSym, AclReadonly, AclPrivate } from "../../../fields/Doc";
+import { Document } from '../../../fields/documentSchemas';
+import { Id } from '../../../fields/FieldSymbols';
+import { InkTool } from '../../../fields/InkField';
+import { listSpec } from "../../../fields/Schema";
+import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
+import { ScriptField } from '../../../fields/ScriptField';
+import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
+import { TraceMobx } from '../../../fields/util';
import { GestureUtils } from '../../../pen-gestures/GestureUtils';
import { emptyFunction, OmitKeys, returnOne, returnTransparent, Utils, emptyPath } from "../../../Utils";
import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils';
@@ -45,6 +44,7 @@ import "./DocumentView.scss";
import { LinkAnchorBox } from './LinkAnchorBox';
import { RadialMenu } from './RadialMenu';
import React = require("react");
+import { undo } from 'prosemirror-history';
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,
@@ -92,6 +92,7 @@ export interface DocumentViewProps {
pinToPres: (document: Doc) => void;
backgroundHalo?: () => boolean;
backgroundColor?: (doc: Doc) => string | undefined;
+ opacity?: () => number | undefined;
ChromeHeight?: () => number;
dontRegisterView?: boolean;
layoutKey?: string;
@@ -684,8 +685,13 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@undoBatch
@action
- toggleLockTransform = (): void => {
- this.Document.lockedTransform = this.Document.lockedTransform ? undefined : true;
+ setAcl = (acl: "readOnly" | "addOnly" | "ownerOnly") => {
+ this.layoutDoc.ACL = this.dataDoc.ACL = acl;
+ DocListCast(this.dataDoc[Doc.LayoutFieldKey(this.dataDoc)]).map(d => {
+ if (d.author === Doc.CurrentUserEmail) d.ACL = acl;
+ const data = d[DataSym];
+ if (data && data.author === Doc.CurrentUserEmail) data.ACL = acl;
+ });
}
@action
@@ -748,14 +754,16 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
const more = cm.findByDescription("More...");
const moreItems: ContextMenuProps[] = more && "subitems" in more ? more.subitems : [];
+ moreItems.push({ description: "Make Add Only", event: () => this.setAcl("addOnly"), icon: "concierge-bell" });
+ moreItems.push({ description: "Make Read Only", event: () => this.setAcl("readOnly"), icon: "concierge-bell" });
+ moreItems.push({ description: "Make Private", event: () => this.setAcl("ownerOnly"), icon: "concierge-bell" });
moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" });
moreItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" });
- moreItems.push({ description: this.Document.lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: BoolCast(this.Document.lockedTransform) ? "unlock" : "lock" });
moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" });
if (!ClientUtils.RELEASE) {
// let copies: ContextMenuProps[] = [];
- moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(this.props.Document[Id]), icon: "fingerprint" });
+ moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" });
// cm.addItem({ description: "Copy...", subitems: copies, icon: "copy" });
}
if (Cast(Doc.GetProto(this.props.Document).data, listSpec(Doc))) {
@@ -764,10 +772,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
moreItems.push({ description: "Write Back Link to Album", event: () => GooglePhotos.Transactions.AddTextEnrichment(this.props.Document), icon: "caret-square-right" });
}
moreItems.push({
- description: "Download document", icon: "download", event: async () =>
- console.log(JSON.parse(await rp.get(Utils.CorsProxy("http://localhost:8983/solr/dash/select"), {
+ description: "Download document", icon: "download", event: async () => {
+ const response = await rp.get(Utils.CorsProxy("http://localhost:8983/solr/dash/select"), {
qs: { q: 'world', fq: 'NOT baseProto_b:true AND NOT deleted:true', start: '0', rows: '100', hl: true, 'hl.fl': '*' }
- })))
+ });
+ console.log(response ? JSON.parse(response) : undefined);
+ }
// const a = document.createElement("a");
// const url = Utils.prepend(`/downloadId/${this.props.Document[Id]}`);
// a.href = url;
@@ -970,9 +980,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
return this.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false;
}
childScaling = () => (this.layoutDoc._fitWidth ? this.props.PanelWidth() / this.nativeWidth : this.props.ContentScaling());
- panelWidth = () => this.props.PanelWidth();
- panelHeight = () => this.props.PanelHeight();
- screenToLocalTransform = () => this.props.ScreenToLocalTransform();
@computed get contents() {
TraceMobx();
return (<>
@@ -993,10 +1000,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
addDocument={this.props.addDocument}
removeDocument={this.props.removeDocument}
moveDocument={this.props.moveDocument}
- ScreenToLocalTransform={this.screenToLocalTransform}
+ ScreenToLocalTransform={this.props.ScreenToLocalTransform}
renderDepth={this.props.renderDepth}
- PanelWidth={this.panelWidth}
- PanelHeight={this.panelHeight}
+ PanelWidth={this.props.PanelWidth}
+ PanelHeight={this.props.PanelHeight}
ignoreAutoHeight={this.props.ignoreAutoHeight}
focus={this.props.focus}
parentActive={this.props.parentActive}
@@ -1116,9 +1123,22 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}), 400);
});
+ renderLock() {
+ return (this.Document.isBackground !== undefined || this.isSelected(false)) &&
+ ((this.Document.type === DocumentType.COL && this.Document._viewType !== CollectionViewType.Pile) || this.Document.type === DocumentType.IMG) &&
+ this.props.renderDepth > 0 && this.props.PanelWidth() > 0 ?
+ <div className="documentView-lock" onClick={() => this.toggleBackground(true)}>
+ <FontAwesomeIcon icon={this.Document.isBackground ? "unlock" : "lock"} style={{ color: this.Document.isBackground ? "red" : undefined }} size="lg" />
+ </div>
+ : (null);
+ }
+
render() {
+ if (this.props.Document[AclSym] && this.props.Document[AclSym] === AclPrivate) return (null);
if (!(this.props.Document instanceof Doc)) return (null);
- const backgroundColor = StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.Document.backgroundColor) || this.props.backgroundColor?.(this.Document);
+ const backgroundColor = Doc.UserDoc().renderStyle === "comic" ? undefined : StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.Document.backgroundColor) || this.props.backgroundColor?.(this.Document);
+ const opacity = Cast(this.layoutDoc._opacity, "number", Cast(this.layoutDoc.opacity, "number", Cast(this.Document.opacity, "number", null)));
+ const finalOpacity = this.props.opacity ? this.props.opacity() : opacity;
const finalColor = this.layoutDoc.type === DocumentType.FONTICON || this.layoutDoc._viewType === CollectionViewType.Linear ? undefined : backgroundColor;
const fullDegree = Doc.isBrushedHighlightedDegree(this.props.Document);
const borderRounding = this.layoutDoc.borderRounding;
@@ -1155,7 +1175,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
border: this.layoutDoc.border ? StrCast(this.layoutDoc.border) : highlighting && borderRounding ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined,
boxShadow: this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" : undefined,
background: finalColor,
- opacity: this.Document.opacity,
+ opacity: finalOpacity,
fontFamily: StrCast(this.Document._fontFamily, "inherit"),
fontSize: Cast(this.Document._fontSize, "number", null)
}}>
@@ -1164,9 +1184,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
<div className="documentView-contentBlocker" />
</> :
this.innards}
- {(this.Document.isBackground !== undefined || this.isSelected(false)) && this.props.renderDepth > 0 && this.props.PanelWidth() > 0 ?
- <div className="documentView-lock" onClick={() => this.toggleBackground(true)}> <FontAwesomeIcon icon={this.Document.isBackground ? "unlock" : "lock"} size="lg" /> </div>
- : (null)}
+ {this.renderLock()}
</div>;
{ this._showKPQuery ? <KeyphraseQueryView keyphrases={this._queries}></KeyphraseQueryView> : undefined; }
}
diff --git a/src/client/views/nodes/FaceRectangles.tsx b/src/client/views/nodes/FaceRectangles.tsx
index 3c7f1f206..92ca276cb 100644
--- a/src/client/views/nodes/FaceRectangles.tsx
+++ b/src/client/views/nodes/FaceRectangles.tsx
@@ -1,8 +1,8 @@
import React = require("react");
-import { Doc, DocListCast } from "../../../new_fields/Doc";
-import { Cast, NumCast } from "../../../new_fields/Types";
+import { Doc, DocListCast } from "../../../fields/Doc";
+import { Cast, NumCast } from "../../../fields/Types";
import { observer } from "mobx-react";
-import { Id } from "../../../new_fields/FieldSymbols";
+import { Id } from "../../../fields/FieldSymbols";
import FaceRectangle from "./FaceRectangle";
interface FaceRectanglesProps {
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 9fba91fd8..cbb1b5b00 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -1,11 +1,11 @@
import React = require("react");
import { computed } from "mobx";
import { observer } from "mobx-react";
-import { DateField } from "../../../new_fields/DateField";
-import { Doc, FieldResult, Opt, Field } from "../../../new_fields/Doc";
-import { List } from "../../../new_fields/List";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { AudioField, VideoField } from "../../../new_fields/URLField";
+import { DateField } from "../../../fields/DateField";
+import { Doc, FieldResult, Opt, Field } from "../../../fields/Doc";
+import { List } from "../../../fields/List";
+import { ScriptField } from "../../../fields/ScriptField";
+import { AudioField, VideoField } from "../../../fields/URLField";
import { Transform } from "../../util/Transform";
import { CollectionView } from "../collections/CollectionView";
import { AudioBox } from "./AudioBox";
diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
index 0d597b3a8..cf0b16c7c 100644
--- a/src/client/views/nodes/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox.tsx
@@ -1,16 +1,16 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { createSchema, makeInterface } from '../../../new_fields/Schema';
+import { createSchema, makeInterface } from '../../../fields/Schema';
import { DocComponent } from '../DocComponent';
import './FontIconBox.scss';
import { FieldView, FieldViewProps } from './FieldView';
-import { StrCast, Cast } from '../../../new_fields/Types';
+import { StrCast, Cast } from '../../../fields/Types';
import { Utils } from "../../../Utils";
import { runInAction, observable, reaction, IReactionDisposer } from 'mobx';
-import { Doc } from '../../../new_fields/Doc';
+import { Doc } from '../../../fields/Doc';
import { ContextMenu } from '../ContextMenu';
-import { ScriptField } from '../../../new_fields/ScriptField';
+import { ScriptField } from '../../../fields/ScriptField';
const FontIconSchema = createSchema({
icon: "string"
});
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index aaebceaa2..6913dfbc7 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -4,22 +4,21 @@ import { faAsterisk, faBrain, faFileAudio, faImage, faPaintBrush } from '@fortaw
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, observable, runInAction } from 'mobx';
import { observer } from "mobx-react";
-import { DataSym, Doc, DocListCast, HeightSym, WidthSym } from '../../../new_fields/Doc';
-import { documentSchema } from '../../../new_fields/documentSchemas';
-import { Id } from '../../../new_fields/FieldSymbols';
-import { List } from '../../../new_fields/List';
-import { ObjectField } from '../../../new_fields/ObjectField';
-import { createSchema, listSpec, makeInterface } from '../../../new_fields/Schema';
-import { ComputedField } from '../../../new_fields/ScriptField';
-import { Cast, NumCast, StrCast } from '../../../new_fields/Types';
-import { AudioField, ImageField } from '../../../new_fields/URLField';
-import { TraceMobx } from '../../../new_fields/util';
+import { DataSym, Doc, DocListCast, HeightSym, WidthSym } from '../../../fields/Doc';
+import { documentSchema } from '../../../fields/documentSchemas';
+import { Id } from '../../../fields/FieldSymbols';
+import { List } from '../../../fields/List';
+import { ObjectField } from '../../../fields/ObjectField';
+import { createSchema, listSpec, makeInterface } from '../../../fields/Schema';
+import { ComputedField } from '../../../fields/ScriptField';
+import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { AudioField, ImageField } from '../../../fields/URLField';
+import { TraceMobx } from '../../../fields/util';
import { emptyFunction, returnOne, Utils, returnZero } from '../../../Utils';
import { CognitiveServices, Confidence, Service, Tag } from '../../cognitive_services/CognitiveServices';
import { Docs } from '../../documents/Documents';
import { Networking } from '../../Network';
import { DragManager } from '../../util/DragManager';
-import { SelectionManager } from '../../util/SelectionManager';
import { undoBatch } from '../../util/UndoManager';
import { ContextMenu } from "../../views/ContextMenu";
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
@@ -267,7 +266,11 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
if (!this.layoutDoc.isTemplateDoc || this.dataDoc !== this.layoutDoc) {
requestImageSize(imgPath).then(action((inquiredSize: any) => {
const rotation = NumCast(this.dataDoc[this.fieldKey + "-rotation"]) % 180;
- const rotatedNativeSize = rotation === 90 || rotation === 270 ? { height: inquiredSize.width, width: inquiredSize.height } : inquiredSize;
+ const rotatedNativeSize = { width: inquiredSize.width, height: inquiredSize.height };
+ if (inquiredSize.orientation === 6 || rotation === 90 || rotation === 270) {
+ rotatedNativeSize.width = inquiredSize.height;
+ rotatedNativeSize.height = inquiredSize.width;
+ }
const rotatedAspect = rotatedNativeSize.height / rotatedNativeSize.width;
if (this.layoutDoc[WidthSym]() && (!cachedNativeSize.width || !cachedNativeSize.height || Math.abs(1 - docAspect / rotatedAspect) > 0.1)) {
this.layoutDoc._height = this.layoutDoc[WidthSym]() * rotatedAspect;
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index 39d7109b1..e983852ea 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -1,13 +1,13 @@
import { action, computed, observable } from "mobx";
import { observer } from "mobx-react";
-import { Doc, Field, FieldResult } from "../../../new_fields/Doc";
-import { List } from "../../../new_fields/List";
-import { RichTextField } from "../../../new_fields/RichTextField";
-import { listSpec } from "../../../new_fields/Schema";
-import { ComputedField, ScriptField } from "../../../new_fields/ScriptField";
-import { Cast, FieldValue, NumCast } from "../../../new_fields/Types";
-import { ImageField } from "../../../new_fields/URLField";
+import { Doc, Field, FieldResult } from "../../../fields/Doc";
+import { List } from "../../../fields/List";
+import { RichTextField } from "../../../fields/RichTextField";
+import { listSpec } from "../../../fields/Schema";
+import { ComputedField, ScriptField } from "../../../fields/ScriptField";
+import { Cast, FieldValue, NumCast } from "../../../fields/Types";
+import { ImageField } from "../../../fields/URLField";
import { Docs } from "../../documents/Documents";
import { SetupDrag } from "../../util/DragManager";
import { CompiledScript, CompileScript, ScriptOptions } from "../../util/Scripting";
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 6dc4ae578..3cbe3e494 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -1,6 +1,6 @@
import { action, observable } from 'mobx';
import { observer } from "mobx-react";
-import { Doc, Field, Opt } from '../../../new_fields/Doc';
+import { Doc, Field, Opt } from '../../../fields/Doc';
import { emptyFunction, returnFalse, returnOne, returnZero } from '../../../Utils';
import { Docs } from '../../documents/Documents';
import { Transform } from '../../util/Transform';
@@ -99,9 +99,9 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
<div className="keyValuePair-td-key-container">
<button style={hover} className="keyValuePair-td-key-delete" onClick={undoBatch(() => {
if (Object.keys(props.Document).indexOf(props.fieldKey) !== -1) {
- props.Document[props.fieldKey] = undefined;
+ delete props.Document[props.fieldKey];
}
- else props.Document.proto![props.fieldKey] = undefined;
+ else delete props.Document.proto![props.fieldKey];
})}>
X
</button>
diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx
index 38558c43d..a0946e3a6 100644
--- a/src/client/views/nodes/LabelBox.tsx
+++ b/src/client/views/nodes/LabelBox.tsx
@@ -3,11 +3,11 @@ import { faEdit } from '@fortawesome/free-regular-svg-icons';
import { action, computed, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, DocListCast } from '../../../new_fields/Doc';
-import { documentSchema } from '../../../new_fields/documentSchemas';
-import { List } from '../../../new_fields/List';
-import { createSchema, listSpec, makeInterface } from '../../../new_fields/Schema';
-import { Cast, NumCast, StrCast } from '../../../new_fields/Types';
+import { Doc, DocListCast } from '../../../fields/Doc';
+import { documentSchema } from '../../../fields/documentSchemas';
+import { List } from '../../../fields/List';
+import { createSchema, listSpec, makeInterface } from '../../../fields/Schema';
+import { Cast, NumCast, StrCast } from '../../../fields/Types';
import { DragManager } from '../../util/DragManager';
import { undoBatch } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
@@ -16,9 +16,6 @@ import { ViewBoxBaseComponent } from '../DocComponent';
import { FieldView, FieldViewProps } from './FieldView';
import './LabelBox.scss';
-
-library.add(faEdit as any);
-
const LabelSchema = createSchema({});
type LabelDocument = makeInterface<[typeof LabelSchema, typeof documentSchema]>;
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx
index bc36e056e..83245a89c 100644
--- a/src/client/views/nodes/LinkAnchorBox.tsx
+++ b/src/client/views/nodes/LinkAnchorBox.tsx
@@ -1,9 +1,9 @@
import { action, observable } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DocListCast } from "../../../new_fields/Doc";
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { makeInterface } from "../../../new_fields/Schema";
-import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { Doc, DocListCast } from "../../../fields/Doc";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { makeInterface } from "../../../fields/Schema";
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
import { Utils, setupMoveUpEvents, emptyFunction } from '../../../Utils';
import { DocumentManager } from "../../util/DocumentManager";
import { DragManager } from "../../util/DragManager";
@@ -16,7 +16,7 @@ import { ContextMenu } from "../ContextMenu";
import { LinkEditor } from "../linking/LinkEditor";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { SelectionManager } from "../../util/SelectionManager";
-import { TraceMobx } from "../../../new_fields/util";
+import { TraceMobx } from "../../../fields/util";
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -72,7 +72,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps, LinkAnch
anchorContainerDoc && this.props.bringToFront(anchorContainerDoc, false);
if (anchorContainerDoc && !this.layoutDoc.onClick && !this._isOpen) {
this._timeout = setTimeout(action(() => {
- DocumentManager.Instance.FollowLink(this.rootDoc, anchorContainerDoc, document => this.props.addDocTab(document, StrCast(this.layoutDoc.linkOpenLocation, "inTab")), false);
+ DocumentManager.Instance.FollowLink(this.rootDoc, anchorContainerDoc, document => this.props.addDocTab(document, StrCast(this.layoutDoc.linkOpenLocation, e.altKey ? "inTab" : "onRight")), false);
this._editing = false;
}), 300 - (Date.now() - this._lastTap));
}
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 740f2ef04..3f942e87b 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -1,13 +1,13 @@
import React = require("react");
import { observer } from "mobx-react";
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { makeInterface, listSpec } from "../../../new_fields/Schema";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { makeInterface, listSpec } from "../../../fields/Schema";
import { returnFalse, returnZero } from "../../../Utils";
import { CollectionTreeView } from "../collections/CollectionTreeView";
import { ViewBoxBaseComponent } from "../DocComponent";
import { FieldView, FieldViewProps } from './FieldView';
import "./LinkBox.scss";
-import { Cast } from "../../../new_fields/Types";
+import { Cast } from "../../../fields/Types";
type LinkDocument = makeInterface<[typeof documentSchema]>;
const LinkDocument = makeInterface(documentSchema);
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 3712c648e..493f23dc4 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -3,11 +3,11 @@ import { action, observable, runInAction, reaction, IReactionDisposer, trace, un
import { observer } from "mobx-react";
import * as Pdfjs from "pdfjs-dist";
import "pdfjs-dist/web/pdf_viewer.css";
-import { Opt, WidthSym, Doc, HeightSym } from "../../../new_fields/Doc";
-import { makeInterface } from "../../../new_fields/Schema";
-import { ScriptField } from '../../../new_fields/ScriptField';
-import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { PdfField, URLField } from "../../../new_fields/URLField";
+import { Opt, WidthSym, Doc, HeightSym } from "../../../fields/Doc";
+import { makeInterface } from "../../../fields/Schema";
+import { ScriptField } from '../../../fields/ScriptField';
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
+import { PdfField, URLField } from "../../../fields/URLField";
import { Utils } from '../../../Utils';
import { undoBatch } from '../../util/UndoManager';
import { panZoomSchema } from '../collections/collectionFreeForm/CollectionFreeFormView';
@@ -20,7 +20,7 @@ import { pageSchema } from "./ImageBox";
import { KeyCodes } from '../../util/KeyCodes';
import "./PDFBox.scss";
import React = require("react");
-import { documentSchema } from '../../../new_fields/documentSchemas';
+import { documentSchema } from '../../../fields/documentSchemas';
type PdfDocument = makeInterface<[typeof documentSchema, typeof panZoomSchema, typeof pageSchema]>;
const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema);
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index e203c7efa..9f1e99c77 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -1,12 +1,12 @@
import React = require("react");
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
+import { action, computed, observable } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DocListCast, DocCastAsync } from "../../../new_fields/Doc";
-import { InkTool } from "../../../new_fields/InkField";
-import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { returnFalse } from "../../../Utils";
-import { documentSchema } from "../../../new_fields/documentSchemas";
+import { Doc, DocListCast, DocCastAsync } from "../../../fields/Doc";
+import { InkTool } from "../../../fields/InkField";
+import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
+import { returnFalse, returnOne } from "../../../Utils";
+import { documentSchema } from "../../../fields/documentSchemas";
import { DocumentManager } from "../../util/DocumentManager";
import { undoBatch } from "../../util/UndoManager";
import { CollectionDockingView } from "../collections/CollectionDockingView";
@@ -15,11 +15,10 @@ import { InkingControl } from "../InkingControl";
import { FieldView, FieldViewProps } from './FieldView';
import "./PresBox.scss";
import { ViewBoxBaseComponent } from "../DocComponent";
-import { makeInterface } from "../../../new_fields/Schema";
-import { List } from "../../../new_fields/List";
+import { makeInterface } from "../../../fields/Schema";
import { Docs } from "../../documents/Documents";
-import { PrefetchProxy } from "../../../new_fields/Proxy";
-import { ScriptField } from "../../../new_fields/ScriptField";
+import { PrefetchProxy } from "../../../fields/Proxy";
+import { ScriptField } from "../../../fields/ScriptField";
import { Scripting } from "../../util/Scripting";
type PresBoxSchema = makeInterface<[typeof documentSchema]>;
@@ -59,7 +58,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
@action
next = () => {
this.updateCurrentPresentation();
- if (this.childDocs[this.itemIndex + 1] !== undefined) {
+ const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null);
+ const lastFrame = Cast(presTargetDoc.lastFrame, "number", null);
+ const curFrame = NumCast(presTargetDoc.currentFrame);
+ if (lastFrame !== undefined && curFrame < lastFrame) {
+ presTargetDoc.transition = "all 1s";
+ setTimeout(() => presTargetDoc.transition = undefined, 1010);
+ presTargetDoc.currentFrame = curFrame + 1;
+ }
+ else if (this.childDocs[this.itemIndex + 1] !== undefined) {
let nextSelected = this.itemIndex + 1;
this.gotoDocument(nextSelected, this.itemIndex);
@@ -188,11 +195,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
//The function that is called when a document is clicked or reached through next or back.
//it'll also execute the necessary actions if presentation is playing.
- public gotoDocument = (index: number, fromDoc: number) => {
+ public gotoDocument = action((index: number, fromDoc: number) => {
this.updateCurrentPresentation();
Doc.UnBrushAllDocs();
if (index >= 0 && index < this.childDocs.length) {
this.rootDoc._itemIndex = index;
+ const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null);
+ if (presTargetDoc.lastFrame !== undefined) {
+ presTargetDoc.currentFrame = 0;
+ }
if (!this.layoutDoc.presStatus) {
this.layoutDoc.presStatus = true;
@@ -203,7 +214,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
this.hideIfNotPresented(index);
this.showAfterPresented(index);
}
- }
+ });
//The function that starts or resets presentaton functionally, depending on status flag.
startOrResetPres = () => {
@@ -286,7 +297,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
(this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
render() {
- this.rootDoc.presOrderedDocs = new List<Doc>(this.childDocs.map((child, i) => child));
+ // console.log("render = " + this.layoutDoc.title + " " + this.layoutDoc.presStatus);
+ // const presOrderedDocs = DocListCast(this.rootDoc.presOrderedDocs);
+ // if (presOrderedDocs.length != this.childDocs.length || presOrderedDocs.some((pd, i) => pd !== this.childDocs[i])) {
+ // this.rootDoc.presOrderedDocs = new List<Doc>(this.childDocs.slice());
+ // }
+ this.childDocs.slice(); // needed to insure that the childDocs are loaded for looking up fields
const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
return <div className="presBox-cont" style={{ minWidth: this.layoutDoc.inOverlay ? 240 : undefined }} >
<div className="presBox-buttons" style={{ display: this.rootDoc._chromeStatus === "disabled" ? "none" : undefined }}>
@@ -316,9 +332,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
PanelWidth={this.props.PanelWidth}
PanelHeight={this.panelHeight}
moveDocument={returnFalse}
+ childOpacity={returnOne}
childLayoutTemplate={this.childLayoutTemplate}
filterAddDocument={this.addDocumentFilter}
removeDocument={returnFalse}
+ dontRegisterView={true}
focus={this.selectElement}
ScreenToLocalTransform={this.getTransform} />
: (null)
@@ -332,5 +350,6 @@ Scripting.addGlobal(function lookupPresBoxField(container: Doc, field: string, d
if (field === 'presCollapsedHeight') return container._viewType === CollectionViewType.Stacking ? 50 : 46;
if (field === 'presStatus') return container.presStatus;
if (field === '_itemIndex') return container._itemIndex;
+ if (field === 'presBox') return container;
return undefined;
});
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index a0ecc9ff5..29e3c008a 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -5,10 +5,10 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { action, computed, IReactionDisposer, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
import * as rp from 'request-promise';
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { makeInterface } from "../../../new_fields/Schema";
-import { Cast, NumCast } from "../../../new_fields/Types";
-import { VideoField } from "../../../new_fields/URLField";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { makeInterface, listSpec } from "../../../fields/Schema";
+import { Cast, NumCast } from "../../../fields/Types";
+import { VideoField } from "../../../fields/URLField";
import { emptyFunction, returnFalse, returnOne, Utils, returnZero } from "../../../Utils";
import { Docs, DocUtils } from "../../documents/Documents";
import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
@@ -18,6 +18,8 @@ import { ViewBoxBaseComponent } from "../DocComponent";
import { InkingControl } from "../InkingControl";
import { FieldView, FieldViewProps } from './FieldView';
import "./ScreenshotBox.scss";
+import { Doc, WidthSym, HeightSym } from "../../../fields/Doc";
+import { OverlayView } from "../OverlayView";
const path = require('path');
type ScreenshotDocument = makeInterface<[typeof documentSchema]>;
@@ -72,7 +74,14 @@ export class ScreenshotBox extends ViewBoxBaseComponent<FieldViewProps, Screensh
x: NumCast(this.layoutDoc.x) + width, y: NumCast(this.layoutDoc.y),
_width: 150, _height: height / width * 150, title: "--screenshot--"
});
- this.props.addDocument?.(imageSummary);
+ if (!this.props.addDocument || this.props.addDocument === returnFalse) {
+ const spt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
+ imageSummary.x = spt[0];
+ imageSummary.y = spt[1];
+ Cast(Cast(Doc.UserDoc().myOverlayDocuments, Doc, null)?.data, listSpec(Doc), []).push(imageSummary);
+ } else {
+ this.props.addDocument?.(imageSummary);
+ }
}
}, 500);
});
diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx
index c607d6614..0944edf60 100644
--- a/src/client/views/nodes/ScriptingBox.tsx
+++ b/src/client/views/nodes/ScriptingBox.tsx
@@ -1,10 +1,10 @@
import { action, observable, computed } from "mobx";
import { observer } from "mobx-react";
import * as React from "react";
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { createSchema, makeInterface, listSpec } from "../../../new_fields/Schema";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { StrCast, ScriptCast, Cast } from "../../../new_fields/Types";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { createSchema, makeInterface, listSpec } from "../../../fields/Schema";
+import { ScriptField } from "../../../fields/ScriptField";
+import { StrCast, ScriptCast, Cast } from "../../../fields/Types";
import { InteractionUtils } from "../../util/InteractionUtils";
import { CompileScript, isCompileError, ScriptParam } from "../../util/Scripting";
import { ViewBoxAnnotatableComponent } from "../DocComponent";
@@ -13,7 +13,7 @@ import { FieldView, FieldViewProps } from "../nodes/FieldView";
import "./ScriptingBox.scss";
import { OverlayView } from "../OverlayView";
import { DocumentIconContainer } from "./DocumentIcon";
-import { List } from "../../../new_fields/List";
+import { List } from "../../../fields/List";
const ScriptingSchema = createSchema({});
type ScriptingDocument = makeInterface<[typeof ScriptingSchema, typeof documentSchema]>;
diff --git a/src/client/views/nodes/SliderBox.tsx b/src/client/views/nodes/SliderBox.tsx
index cb2526769..9a1aefba9 100644
--- a/src/client/views/nodes/SliderBox.tsx
+++ b/src/client/views/nodes/SliderBox.tsx
@@ -4,10 +4,10 @@ import { runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Handles, Rail, Slider, Ticks, Tracks } from 'react-compound-slider';
-import { documentSchema } from '../../../new_fields/documentSchemas';
-import { createSchema, makeInterface } from '../../../new_fields/Schema';
-import { ScriptField } from '../../../new_fields/ScriptField';
-import { Cast, NumCast, StrCast } from '../../../new_fields/Types';
+import { documentSchema } from '../../../fields/documentSchemas';
+import { createSchema, makeInterface } from '../../../fields/Schema';
+import { ScriptField } from '../../../fields/ScriptField';
+import { Cast, NumCast, StrCast } from '../../../fields/Types';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { ViewBoxBaseComponent } from '../DocComponent';
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 9602eac52..9d02239fc 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -1,16 +1,13 @@
import React = require("react");
-import { library } from "@fortawesome/fontawesome-svg-core";
-import { faVideo } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { action, computed, IReactionDisposer, observable, reaction, runInAction, untracked } from "mobx";
import { observer } from "mobx-react";
import * as rp from 'request-promise';
-import { Doc } from "../../../new_fields/Doc";
-import { InkTool } from "../../../new_fields/InkField";
-import { createSchema, makeInterface } from "../../../new_fields/Schema";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { Cast, StrCast } from "../../../new_fields/Types";
-import { VideoField } from "../../../new_fields/URLField";
+import { Doc } from "../../../fields/Doc";
+import { InkTool } from "../../../fields/InkField";
+import { createSchema, makeInterface } from "../../../fields/Schema";
+import { Cast, StrCast } from "../../../fields/Types";
+import { VideoField } from "../../../fields/URLField";
import { Utils, emptyFunction, returnOne, returnZero } from "../../../Utils";
import { Docs, DocUtils } from "../../documents/Documents";
import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
@@ -21,7 +18,8 @@ import { DocumentDecorations } from "../DocumentDecorations";
import { InkingControl } from "../InkingControl";
import { FieldView, FieldViewProps } from './FieldView';
import "./VideoBox.scss";
-import { documentSchema } from "../../../new_fields/documentSchemas";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { Networking } from "../../Network";
const path = require('path');
export const timeSchema = createSchema({
@@ -30,8 +28,6 @@ export const timeSchema = createSchema({
type VideoDocument = makeInterface<[typeof documentSchema, typeof timeSchema]>;
const VideoDocument = makeInterface(documentSchema, timeSchema);
-library.add(faVideo);
-
@observer
export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoDocument>(VideoDocument) {
static _youtubeIframeCounter: number = 0;
@@ -104,41 +100,59 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
canvas.height = 640 * (this.layoutDoc._nativeHeight || 0) / (this.layoutDoc._nativeWidth || 1);
const ctx = canvas.getContext('2d');//draw image to canvas. scale to target dimensions
if (ctx) {
- ctx.rect(0, 0, canvas.width, canvas.height);
- ctx.fillStyle = "blue";
- ctx.fill();
+ // ctx.rect(0, 0, canvas.width, canvas.height);
+ // ctx.fillStyle = "blue";
+ // ctx.fill();
this._videoRef && ctx.drawImage(this._videoRef, 0, 0, canvas.width, canvas.height);
}
- if (!this._videoRef) { // can't find a way to take snapshots of videos
- const b = Docs.Create.ButtonDocument({
+ if (!this._videoRef) {
+ const b = Docs.Create.LabelDocument({
x: (this.layoutDoc.x || 0) + width, y: (this.layoutDoc.y || 1),
- _width: 150, _height: 50, title: (this.layoutDoc.currentTimecode || 0).toString()
+ _width: 150, _height: 50, title: (this.layoutDoc.currentTimecode || 0).toString(),
+ });
+ b.isLinkButton = true;
+ this.props.addDocument?.(b);
+ DocUtils.MakeLink({ doc: b }, { doc: this.rootDoc }, "video snapshot");
+ Networking.PostToServer("/youtubeScreenshot", {
+ id: this.youtubeVideoId,
+ timecode: this.layoutDoc.currentTimecode
+ }).then(response => {
+ const resolved = response?.accessPaths?.agnostic?.client;
+ if (resolved) {
+ this.props.removeDocument?.(b);
+ this.createRealSummaryLink(resolved);
+ }
});
- b.onClick = ScriptField.MakeScript(`this.currentTimecode = ${(this.layoutDoc.currentTimecode || 0)}`);
} else {
//convert to desired file format
const dataUrl = canvas.toDataURL('image/png'); // can also use 'image/png'
// if you want to preview the captured image,
const filename = path.basename(encodeURIComponent("snapshot" + StrCast(this.rootDoc.title).replace(/\..*$/, "") + "_" + (this.layoutDoc.currentTimecode || 0).toString().replace(/\./, "_")));
- VideoBox.convertDataUri(dataUrl, filename).then(returnedFilename => {
+ VideoBox.convertDataUri(dataUrl, filename).then((returnedFilename: string) => {
if (returnedFilename) {
- const url = this.choosePath(Utils.prepend(returnedFilename));
- const imageSummary = Docs.Create.ImageDocument(url, {
- _nativeWidth: this.layoutDoc._nativeWidth, _nativeHeight: this.layoutDoc._nativeHeight,
- x: (this.layoutDoc.x || 0) + width, y: (this.layoutDoc.y || 0),
- _width: 150, _height: height / width * 150, title: "--snapshot" + (this.layoutDoc.currentTimecode || 0) + " image-"
- });
- Doc.GetProto(imageSummary)["data-nativeWidth"] = this.layoutDoc._nativeWidth;
- Doc.GetProto(imageSummary)["data-nativeHeight"] = this.layoutDoc._nativeHeight;
- imageSummary.isLinkButton = true;
- this.props.addDocument && this.props.addDocument(imageSummary);
- DocUtils.MakeLink({ doc: imageSummary }, { doc: this.rootDoc }, "video snapshot");
+ this.createRealSummaryLink(returnedFilename);
}
});
}
}
+ private createRealSummaryLink = (relative: string) => {
+ const url = this.choosePath(Utils.prepend(relative));
+ const width = (this.layoutDoc._width || 0);
+ const height = (this.layoutDoc._height || 0);
+ const imageSummary = Docs.Create.ImageDocument(url, {
+ _nativeWidth: this.layoutDoc._nativeWidth, _nativeHeight: this.layoutDoc._nativeHeight,
+ x: (this.layoutDoc.x || 0) + width, y: (this.layoutDoc.y || 0),
+ _width: 150, _height: height / width * 150, title: "--snapshot" + (this.layoutDoc.currentTimecode || 0) + " image-"
+ });
+ Doc.GetProto(imageSummary)["data-nativeWidth"] = this.layoutDoc._nativeWidth;
+ Doc.GetProto(imageSummary)["data-nativeHeight"] = this.layoutDoc._nativeHeight;
+ imageSummary.isLinkButton = true;
+ this.props.addDocument?.(imageSummary);
+ DocUtils.MakeLink({ doc: imageSummary }, { doc: this.rootDoc }, "video snapshot");
+ }
+
@action
updateTimecode = () => {
this.player && (this.layoutDoc.currentTimecode = this.player.currentTime);
@@ -162,8 +176,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
componentWillUnmount() {
this.Pause();
- this._reactionDisposer && this._reactionDisposer();
- this._youtubeReactionDisposer && this._youtubeReactionDisposer();
+ this._reactionDisposer?.();
+ this._youtubeReactionDisposer?.();
}
@action
@@ -337,7 +351,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
}
@action.bound
- addDocumentWithTimestamp(doc: Doc|Doc[]): boolean {
+ addDocumentWithTimestamp(doc: Doc | Doc[]): boolean {
const docs = doc instanceof Doc ? [doc] : doc;
docs.forEach(doc => {
const curTime = (this.layoutDoc.currentTimecode || -1);
diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss
index 4c05d4627..4623444b9 100644
--- a/src/client/views/nodes/WebBox.scss
+++ b/src/client/views/nodes/WebBox.scss
@@ -5,6 +5,36 @@
transform-origin: top left;
width: 100%;
height: 100%;
+
+ .webBox-htmlSpan {
+ position: absolute;
+ top: 0;
+ left: 0;
+ }
+ .webBox-cont {
+ pointer-events: none;
+ }
+ .webBox-cont, .webBox-cont-interactive {
+ padding: 0vw;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ transform-origin: top left;
+ overflow: auto;
+ .webBox-iframe {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ top:0;
+ }
+ }
+ .webBox-cont-interactive {
+ span {
+ user-select: text !important;
+ }
+ }
.webBox-outerContent {
width: 100%;
height: 100%;
@@ -20,29 +50,7 @@
display:none;
}
}
-.webBox-cont {
- padding: 0vw;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- transform-origin: top left;
- overflow: auto;
- pointer-events: none;
-}
-
-.webBox-cont-interactive {
- span {
- user-select: text !important;
- }
-}
-#webBox-htmlSpan {
- position: absolute;
- top: 0;
- left: 0;
-}
.webBox-overlay {
width: 100%;
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 384a6e8a5..c4ab3c9e2 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1,14 +1,14 @@
import { library } from "@fortawesome/fontawesome-svg-core";
import { faStickyNote, faPen, faMousePointer } from '@fortawesome/free-solid-svg-icons';
-import { action, computed, observable, trace, IReactionDisposer, reaction } from "mobx";
+import { action, computed, observable, trace, IReactionDisposer, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { Doc, FieldResult } from "../../../new_fields/Doc";
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { HtmlField } from "../../../new_fields/HtmlField";
-import { InkTool } from "../../../new_fields/InkField";
-import { makeInterface } from "../../../new_fields/Schema";
-import { Cast, NumCast, BoolCast, StrCast } from "../../../new_fields/Types";
-import { WebField } from "../../../new_fields/URLField";
+import { Doc, FieldResult, DocListCast } from "../../../fields/Doc";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { HtmlField } from "../../../fields/HtmlField";
+import { InkTool } from "../../../fields/InkField";
+import { makeInterface, listSpec } from "../../../fields/Schema";
+import { Cast, NumCast, BoolCast, StrCast } from "../../../fields/Types";
+import { WebField } from "../../../fields/URLField";
import { Utils, returnOne, emptyFunction, returnZero } from "../../../Utils";
import { Docs } from "../../documents/Documents";
import { DragManager } from "../../util/DragManager";
@@ -22,6 +22,10 @@ import React = require("react");
import * as WebRequest from 'web-request';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
+import { ContextMenu } from "../ContextMenu";
+import { ContextMenuProps } from "../ContextMenuItem";
+import { undoBatch } from "../../util/UndoManager";
+import { List } from "../../../fields/List";
const htmlToText = require("html-to-text");
library.add(faStickyNote);
@@ -33,7 +37,7 @@ const WebDocument = makeInterface(documentSchema);
export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocument>(WebDocument) {
public static LayoutString(fieldKey: string) { return FieldView.LayoutString(WebBox, fieldKey); }
- get _collapsed() { return StrCast(this.layoutDoc._chromeStatus) === "disabled"; }
+ get _collapsed() { return StrCast(this.layoutDoc._chromeStatus) !== "enabled"; }
set _collapsed(value) { this.layoutDoc._chromeStatus = !value ? "enabled" : "disabled"; }
@observable private _url: string = "hello";
@observable private _pressX: number = 0;
@@ -48,19 +52,26 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean) => void);
iframeLoaded = action((e: any) => {
- if (this._iframeRef.current?.contentDocument) {
- this._iframeRef.current.contentDocument.addEventListener('pointerdown', this.iframedown, false);
- this._iframeRef.current.contentDocument.addEventListener('scroll', this.iframeScrolled, false);
- this.layoutDoc.scrollHeight = this._iframeRef.current.contentDocument.children?.[0].scrollHeight || 1000;
- this._iframeRef.current.contentDocument.children[0].scrollTop = NumCast(this.layoutDoc.scrollTop);
+ const iframe = this._iframeRef.current;
+ if (iframe && iframe.contentDocument) {
+ iframe.setAttribute("enable-annotation", "true");
+ iframe.contentDocument.addEventListener('pointerdown', this.iframedown, false);
+ iframe.contentDocument.addEventListener('scroll', this.iframeScrolled, false);
+ this.layoutDoc.scrollHeight = iframe.contentDocument.children?.[0].scrollHeight || 1000;
+ iframe.contentDocument.children[0].scrollTop = NumCast(this.layoutDoc.scrollTop);
+ iframe.contentDocument.children[0].scrollLeft = NumCast(this.layoutDoc.scrollLeft);
}
this._reactionDisposer?.();
- this._reactionDisposer = reaction(() => this.layoutDoc.scrollY,
- (scrollY) => {
- if (scrollY !== undefined) {
- this._outerRef.current!.scrollTop = scrollY;
+ this._reactionDisposer = reaction(() => ({ y: this.layoutDoc.scrollY, x: this.layoutDoc.scrollX }),
+ ({ x, y }) => {
+ if (y !== undefined) {
+ this._outerRef.current!.scrollTop = y;
this.layoutDoc.scrollY = undefined;
}
+ if (x !== undefined) {
+ this._outerRef.current!.scrollLeft = x;
+ this.layoutDoc.scrollX = undefined;
+ }
},
{ fireImmediately: true }
);
@@ -70,14 +81,14 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
this._setPreviewCursor?.(e.screenX, e.screenY, false);
}
iframeScrolled = (e: any) => {
- const scroll = e.target?.children?.[0].scrollTop;
- this.layoutDoc.scrollTop = this._outerRef.current!.scrollTop = scroll;
+ const scrollTop = e.target?.children?.[0].scrollTop;
+ const scrollLeft = e.target?.children?.[0].scrollLeft;
+ this.layoutDoc.scrollTop = this._outerRef.current!.scrollTop = scrollTop;
+ this.layoutDoc.scrollLeft = this._outerRef.current!.scrollLeft = scrollLeft;
}
async componentDidMount() {
-
- this.setURL();
-
- this._iframeRef.current!.setAttribute("enable-annotation", "true");
+ const urlField = Cast(this.dataDoc[this.props.fieldKey], WebField);
+ runInAction(() => this._url = urlField?.url.toString() || "");
document.addEventListener("pointerup", this.onLongPressUp);
document.addEventListener("pointermove", this.onLongPressMove);
@@ -86,14 +97,18 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
const youtubeaspect = 400 / 315;
const nativeWidth = NumCast(this.layoutDoc._nativeWidth);
const nativeHeight = NumCast(this.layoutDoc._nativeHeight);
- if (!nativeWidth || !nativeHeight || Math.abs(nativeWidth / nativeHeight - youtubeaspect) > 0.05) {
- if (!nativeWidth) this.layoutDoc._nativeWidth = 600;
- this.layoutDoc._nativeHeight = NumCast(this.layoutDoc._nativeWidth) / youtubeaspect;
- this.layoutDoc._height = NumCast(this.layoutDoc._width) / youtubeaspect;
- }
+ if (field) {
+ if (!nativeWidth || !nativeHeight || Math.abs(nativeWidth / nativeHeight - youtubeaspect) > 0.05) {
+ if (!nativeWidth) this.layoutDoc._nativeWidth = 600;
+ this.layoutDoc._nativeHeight = NumCast(this.layoutDoc._nativeWidth) / youtubeaspect;
+ this.layoutDoc._height = NumCast(this.layoutDoc._width) / youtubeaspect;
+ }
+ } // else it's an HTMLfield
} else if (field?.url) {
const result = await WebRequest.get(Utils.CorsProxy(field.url.href));
- this.dataDoc.text = htmlToText.fromString(result.content);
+ if (result) {
+ this.dataDoc.text = htmlToText.fromString(result.content);
+ }
}
}
@@ -101,8 +116,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
this._reactionDisposer?.();
document.removeEventListener("pointerup", this.onLongPressUp);
document.removeEventListener("pointermove", this.onLongPressMove);
- this._iframeRef.current!.contentDocument?.removeEventListener('pointerdown', this.iframedown);
- this._iframeRef.current!.contentDocument?.removeEventListener('scroll', this.iframeScrolled);
+ this._iframeRef.current?.contentDocument?.removeEventListener('pointerdown', this.iframedown);
+ this._iframeRef.current?.contentDocument?.removeEventListener('scroll', this.iframeScrolled);
}
@action
@@ -110,16 +125,73 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
this._url = e.target.value;
}
+ onUrlDragover = (e: React.DragEvent) => {
+ e.preventDefault();
+ }
@action
- submitURL = () => {
- this.dataDoc[this.props.fieldKey] = new WebField(new URL(this._url));
+ onUrlDrop = (e: React.DragEvent) => {
+ const { dataTransfer } = e;
+ const html = dataTransfer.getData("text/html");
+ const uri = dataTransfer.getData("text/uri-list");
+ const url = uri || html || this._url;
+ this._url = url.startsWith(window.location.origin) ?
+ url.replace(window.location.origin, this._url.match(/http[s]?:\/\/[^\/]*/)?.[0] || "") : url;
+ this.submitURL();
+ e.stopPropagation();
+ }
+
+ @action
+ forward = () => {
+ const future = Cast(this.dataDoc[this.fieldKey + "-future"], listSpec("string"), null);
+ const history = Cast(this.dataDoc[this.fieldKey + "-history"], listSpec("string"), null);
+ if (future.length) {
+ history.push(this._url);
+ this.dataDoc[this.annotationKey + "-" + this.urlHash(this._url)] = new List<Doc>(DocListCast(this.dataDoc[this.annotationKey]));
+ this.dataDoc[this.fieldKey] = new WebField(new URL(this._url = future.pop()!));
+ this.dataDoc[this.annotationKey] = new List<Doc>(DocListCast(this.dataDoc[this.annotationKey + "-" + this.urlHash(this._url)]));
+ }
}
@action
- setURL() {
- const urlField: FieldResult<WebField> = Cast(this.dataDoc[this.props.fieldKey], WebField);
- if (urlField) this._url = urlField.url.toString();
- else this._url = "";
+ back = () => {
+ const future = Cast(this.dataDoc[this.fieldKey + "-future"], listSpec("string"), null);
+ const history = Cast(this.dataDoc[this.fieldKey + "-history"], listSpec("string"), null);
+ if (history.length) {
+ if (future === undefined) this.dataDoc[this.fieldKey + "-future"] = new List<string>([this._url]);
+ else future.push(this._url);
+ this.dataDoc[this.annotationKey + "-" + this.urlHash(this._url)] = new List<Doc>(DocListCast(this.dataDoc[this.annotationKey]));
+ this.dataDoc[this.fieldKey] = new WebField(new URL(this._url = history.pop()!));
+ this.dataDoc[this.annotationKey] = new List<Doc>(DocListCast(this.dataDoc[this.annotationKey + "-" + this.urlHash(this._url)]));
+ }
+ }
+
+ urlHash(s: string) {
+ return s.split('').reduce((a: any, b: any) => { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0);
+ }
+ @action
+ submitURL = () => {
+ if (!this._url.startsWith("http")) this._url = "http://" + this._url;
+ try {
+ const URLy = new URL(this._url);
+ const future = Cast(this.dataDoc[this.fieldKey + "-future"], listSpec("string"), null);
+ const history = Cast(this.dataDoc[this.fieldKey + "-history"], listSpec("string"), null);
+ const annos = DocListCast(this.dataDoc[this.annotationKey]);
+ const url = Cast(this.dataDoc[this.fieldKey], WebField, null)?.url.toString();
+ if (url) {
+ if (history === undefined) {
+ this.dataDoc[this.fieldKey + "-history"] = new List<string>([url]);
+
+ } else {
+ history.push(url);
+ }
+ future && (future.length = 0);
+ this.dataDoc[this.annotationKey + "-" + this.urlHash(url)] = new List<Doc>(annos);
+ }
+ this.dataDoc[this.fieldKey] = new WebField(URLy);
+ this.dataDoc[this.annotationKey] = new List<Doc>([]);
+ } catch (e) {
+ console.log("Error in URL :" + this._url);
+ }
}
onValueKeyDown = async (e: React.KeyboardEvent) => {
@@ -130,19 +202,14 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
}
toggleAnnotationMode = () => {
- if (!this.layoutDoc.isAnnotating) {
- this.layoutDoc.lockedTransform = false;
- this.layoutDoc.isAnnotating = true;
- }
- else {
- this.layoutDoc.lockedTransform = true;
- this.layoutDoc.isAnnotating = false;
- }
+ this.layoutDoc.isAnnotating = !this.layoutDoc.isAnnotating;
}
urlEditor() {
return (
- <div className="webBox-urlEditor" style={{ top: this._collapsed ? -70 : 0 }}>
+ <div className="webBox-urlEditor"
+ onDrop={this.onUrlDrop}
+ onDragOver={this.onUrlDragover} style={{ top: this._collapsed ? -70 : 0 }}>
<div className="urlEditor">
<div className="editorBase">
<button className="editor-collapse"
@@ -155,7 +222,9 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
title="Collapse Url Editor" onClick={this.toggleCollapse}>
<FontAwesomeIcon icon="caret-up" size="2x" />
</button>
- <div className="webBox-buttons" style={{ display: this._collapsed ? "none" : "flex" }}>
+ <div className="webBox-buttons"
+ onDrop={this.onUrlDrop}
+ onDragOver={this.onUrlDragover} style={{ display: this._collapsed ? "none" : "flex" }}>
<div className="webBox-freeze" title={"Annotate"} style={{ background: this.layoutDoc.isAnnotating ? "lightBlue" : "gray" }} onClick={this.toggleAnnotationMode} >
<FontAwesomeIcon icon={faPen} size={"2x"} />
</div>
@@ -165,6 +234,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
<input className="webpage-urlInput"
placeholder="ENTER URL"
value={this._url}
+ onDrop={this.onUrlDrop}
+ onDragOver={this.onUrlDragover}
onChange={this.onURLChange}
onKeyDown={this.onValueKeyDown}
/>
@@ -172,10 +243,17 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
- minWidth: "100px",
+ maxWidth: "120px",
}}>
- <button className="submitUrl" onClick={this.submitURL}>
- SUBMIT
+ <button className="submitUrl" onClick={this.submitURL}
+ onDragOver={this.onUrlDragover} onDrop={this.onUrlDrop}>
+ GO
+ </button>
+ <button className="submitUrl" onClick={this.back}>
+ <FontAwesomeIcon icon="caret-left" size="lg"></FontAwesomeIcon>
+ </button>
+ <button className="submitUrl" onClick={this.forward}>
+ <FontAwesomeIcon icon="caret-right" size="lg"></FontAwesomeIcon>
</button>
</div>
</div>
@@ -309,19 +387,39 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
}
+ @undoBatch
+ @action
+ toggleNativeDimensions = () => {
+ Doc.toggleNativeDimensions(this.layoutDoc, this.props.ContentScaling(), this.props.NativeWidth(), this.props.NativeHeight());
+ }
+ specificContextMenu = (e: React.MouseEvent): void => {
+ const cm = ContextMenu.Instance;
+ const funcs: ContextMenuProps[] = [];
+ funcs.push({ description: (!this.layoutDoc._nativeWidth || !this.layoutDoc._nativeHeight ? "Freeze" : "Unfreeze") + " Aspect", event: this.toggleNativeDimensions, icon: "snowflake" });
+ cm.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
+
+ }
+
+ //const href = "https://brown365-my.sharepoint.com/personal/bcz_ad_brown_edu/_layouts/15/Doc.aspx?sourcedoc={31aa3178-4c21-4474-b367-877d0a7135e4}&action=embedview&wdStartOn=1";
+
@computed
- get content() {
+ get urlContent() {
+
const field = this.dataDoc[this.props.fieldKey];
let view;
if (field instanceof HtmlField) {
- view = <span id="webBox-htmlSpan" dangerouslySetInnerHTML={{ __html: field.html }} />;
+ view = <span className="webBox-htmlSpan" dangerouslySetInnerHTML={{ __html: field.html }} />;
} else if (field instanceof WebField) {
const url = this.layoutDoc.UseCors ? Utils.CorsProxy(field.url.href) : field.url.href;
- view = <iframe ref={this._iframeRef} onLoad={this.iframeLoaded} src={url} style={{ position: "absolute", width: "100%", height: "100%", top: 0 }} />;
+ view = <iframe className="webBox-iframe" enable-annotation={true} ref={this._iframeRef} src={url} onLoad={this.iframeLoaded} />;
} else {
- view = <iframe ref={this._iframeRef} src={"https://crossorigin.me/https://cs.brown.edu"} style={{ position: "absolute", width: "100%", height: "100%", top: 0 }} />;
+ view = <iframe className="webBox-iframe" enable-annotation={true} ref={this._iframeRef} src={"https://crossorigin.me/https://cs.brown.edu"} />;
}
-
+ return view;
+ }
+ @computed
+ get content() {
+ const view = this.urlContent;
const decInteracting = DocumentDecorations.Instance?.Interacting;
const frozen = !this.props.isSelected() || decInteracting;
@@ -342,7 +440,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
{this.urlEditor()}
</>);
}
- scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.props.Document.scrollTop));
+ scrollXf = () => this.props.ScreenToLocalTransform().translate(NumCast(this.layoutDoc.scrollLeft), NumCast(this.layoutDoc.scrollTop));
render() {
return (<div className={`webBox-container`}
style={{
@@ -350,18 +448,27 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
width: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}%` : "100%",
height: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}%` : "100%",
pointerEvents: this.layoutDoc.isBackground ? "none" : undefined
- }} >
+ }}
+ onContextMenu={this.specificContextMenu}>
+ <base target="_blank" />
{this.content}
<div className={"webBox-outerContent"} ref={this._outerRef}
style={{ pointerEvents: this.layoutDoc.isAnnotating && !this.layoutDoc.isBackground ? "all" : "none" }}
onWheel={e => e.stopPropagation()}
onScroll={e => {
- if (this._iframeRef.current!.contentDocument!.children[0].scrollTop !== this._outerRef.current!.scrollTop) {
- this._iframeRef.current!.contentDocument!.children[0].scrollTop = this._outerRef.current!.scrollTop;
+ const iframe = this._iframeRef?.current?.contentDocument;
+ const outerFrame = this._outerRef.current;
+ if (iframe && outerFrame) {
+ if (iframe.children[0].scrollTop !== outerFrame.scrollTop) {
+ iframe.children[0].scrollTop = outerFrame.scrollTop;
+ }
+ if (iframe.children[0].scrollLeft !== outerFrame.scrollLeft) {
+ iframe.children[0].scrollLeft = outerFrame.scrollLeft;
+ }
}
//this._outerRef.current!.scrollTop !== this._scrollTop && (this._outerRef.current!.scrollTop = this._scrollTop)
}}>
- <div className={"webBox-innerContent"} style={{ height: NumCast(this.layoutDoc.scrollHeight) }}>
+ <div className={"webBox-innerContent"} style={{ height: NumCast(this.layoutDoc.scrollHeight), width: 4000 }}>
<CollectionFreeFormView {...this.props}
PanelHeight={this.props.PanelHeight}
PanelWidth={this.props.PanelWidth}
diff --git a/src/client/views/nodes/formattedText/DashDocCommentView.tsx b/src/client/views/nodes/formattedText/DashDocCommentView.tsx
index d94fe7fc6..d56b87ae5 100644
--- a/src/client/views/nodes/formattedText/DashDocCommentView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocCommentView.tsx
@@ -8,14 +8,14 @@ import { EditorState, NodeSelection, Plugin, TextSelection } from "prosemirror-s
import { StepMap } from "prosemirror-transform";
import { EditorView } from "prosemirror-view";
import * as ReactDOM from 'react-dom';
-import { Doc, DocListCast, Field, HeightSym, WidthSym } from "../../../../new_fields/Doc";
-import { Id } from "../../../../new_fields/FieldSymbols";
-import { List } from "../../../../new_fields/List";
-import { ObjectField } from "../../../../new_fields/ObjectField";
-import { listSpec } from "../../../../new_fields/Schema";
-import { SchemaHeaderField } from "../../../../new_fields/SchemaHeaderField";
-import { ComputedField } from "../../../../new_fields/ScriptField";
-import { BoolCast, Cast, NumCast, StrCast } from "../../../../new_fields/Types";
+import { Doc, DocListCast, Field, HeightSym, WidthSym } from "../../../../fields/Doc";
+import { Id } from "../../../../fields/FieldSymbols";
+import { List } from "../../../../fields/List";
+import { ObjectField } from "../../../../fields/ObjectField";
+import { listSpec } from "../../../../fields/Schema";
+import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField";
+import { ComputedField } from "../../../../fields/ScriptField";
+import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types";
import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils, returnZero } from "../../../../Utils";
import { DocServer } from "../../../DocServer";
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 7130fee2b..05e6a5959 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -1,10 +1,10 @@
import { IReactionDisposer, reaction } from "mobx";
import { NodeSelection } from "prosemirror-state";
-import { Doc, HeightSym, WidthSym } from "../../../../new_fields/Doc";
-import { Id } from "../../../../new_fields/FieldSymbols";
-import { ObjectField } from "../../../../new_fields/ObjectField";
-import { ComputedField } from "../../../../new_fields/ScriptField";
-import { BoolCast, Cast, NumCast, StrCast } from "../../../../new_fields/Types";
+import { Doc, HeightSym, WidthSym } from "../../../../fields/Doc";
+import { Id } from "../../../../fields/FieldSymbols";
+import { ObjectField } from "../../../../fields/ObjectField";
+import { ComputedField } from "../../../../fields/ScriptField";
+import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types";
import { emptyFunction, returnEmptyString, returnFalse, Utils, returnZero } from "../../../../Utils";
import { DocServer } from "../../../DocServer";
import { Docs } from "../../../documents/Documents";
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index 3c6841f08..d05e8f1ea 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -1,10 +1,10 @@
import { IReactionDisposer, observable, runInAction, computed, action } from "mobx";
-import { Doc, DocListCast, Field } from "../../../../new_fields/Doc";
-import { List } from "../../../../new_fields/List";
-import { listSpec } from "../../../../new_fields/Schema";
-import { SchemaHeaderField } from "../../../../new_fields/SchemaHeaderField";
-import { ComputedField } from "../../../../new_fields/ScriptField";
-import { Cast, StrCast } from "../../../../new_fields/Types";
+import { Doc, DocListCast, Field } from "../../../../fields/Doc";
+import { List } from "../../../../fields/List";
+import { listSpec } from "../../../../fields/Schema";
+import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField";
+import { ComputedField } from "../../../../fields/ScriptField";
+import { Cast, StrCast } from "../../../../fields/Types";
import { DocServer } from "../../../DocServer";
import { CollectionViewType } from "../../collections/CollectionView";
import { FormattedTextBox } from "./FormattedTextBox";
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 23bf86a32..fc131cd38 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -12,17 +12,17 @@ import { Fragment, Mark, Node, Slice } from "prosemirror-model";
import { EditorState, NodeSelection, Plugin, TextSelection, Transaction } from "prosemirror-state";
import { ReplaceStep } from 'prosemirror-transform';
import { EditorView } from "prosemirror-view";
-import { DateField } from '../../../../new_fields/DateField';
-import { DataSym, Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym } from "../../../../new_fields/Doc";
-import { documentSchema } from '../../../../new_fields/documentSchemas';
-import { Id } from '../../../../new_fields/FieldSymbols';
-import { InkTool } from '../../../../new_fields/InkField';
-import { PrefetchProxy } from '../../../../new_fields/Proxy';
-import { RichTextField } from "../../../../new_fields/RichTextField";
-import { RichTextUtils } from '../../../../new_fields/RichTextUtils';
-import { createSchema, makeInterface } from "../../../../new_fields/Schema";
-import { Cast, DateCast, NumCast, StrCast } from "../../../../new_fields/Types";
-import { TraceMobx } from '../../../../new_fields/util';
+import { DateField } from '../../../../fields/DateField';
+import { DataSym, Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym } from "../../../../fields/Doc";
+import { documentSchema } from '../../../../fields/documentSchemas';
+import { Id } from '../../../../fields/FieldSymbols';
+import { InkTool } from '../../../../fields/InkField';
+import { PrefetchProxy } from '../../../../fields/Proxy';
+import { RichTextField } from "../../../../fields/RichTextField";
+import { RichTextUtils } from '../../../../fields/RichTextUtils';
+import { createSchema, makeInterface } from "../../../../fields/Schema";
+import { Cast, DateCast, NumCast, StrCast } from "../../../../fields/Types";
+import { TraceMobx } from '../../../../fields/util';
import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, numberRange, returnOne, returnZero, Utils, setupMoveUpEvents } from '../../../../Utils';
import { GoogleApiClientUtils, Pulls, Pushes } from '../../../apis/google_docs/GoogleApiClientUtils';
import { DocServer } from "../../../DocServer";
@@ -58,7 +58,7 @@ import { FieldView, FieldViewProps } from "../FieldView";
import "./FormattedTextBox.scss";
import { FormattedTextBoxComment, formattedTextBoxCommentPlugin } from './FormattedTextBoxComment';
import React = require("react");
-import { ScriptField } from '../../../../new_fields/ScriptField';
+import { ScriptField } from '../../../../fields/ScriptField';
import GoogleAuthenticationManager from '../../../apis/GoogleAuthenticationManager';
library.add(faEdit);
@@ -206,6 +206,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
if ((!curTemp && !curProto) || curText || curLayout?.Data.includes("dash")) { // if no template, or there's text that didn't come from the layout template, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended)
if (json !== curLayout?.Data) {
!curText && tx.storedMarks?.map(m => m.type.name === "pFontSize" && (Doc.UserDoc().fontSize = this.layoutDoc._fontSize = m.attrs.fontSize));
+ !curText && tx.storedMarks?.map(m => m.type.name === "pFontFamily" && (Doc.UserDoc().fontFamily = this.layoutDoc._fontFamily = m.attrs.fontFamily));
this.dataDoc[this.props.fieldKey] = new RichTextField(json, curText);
this.dataDoc[this.props.fieldKey + "-noTemplate"] = (curTemp?.Text || "") !== curText; // mark the data field as being split from the template if it has been edited
}
@@ -868,7 +869,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
const marks = [...node.marks];
const linkIndex = marks.findIndex(mark => mark.type.name === "link");
- const link = view.state.schema.mark(view.state.schema.marks.link, { href: `http://localhost:1050/doc/${linkId}`, location: "onRight", title: title, docref: true });
+ const link = view.state.schema.mark(view.state.schema.marks.link, { href: Utils.prepend(`/doc/${linkId}`), location: "onRight", title: title, docref: true });
marks.splice(linkIndex === -1 ? 0 : linkIndex, 1, link);
return node.mark(marks);
}
@@ -1178,7 +1179,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
@action
tryUpdateHeight(limitHeight?: number) {
let scrollHeight = this._ref.current?.scrollHeight;
- if (this.layoutDoc._autoHeight && !this.props.ignoreAutoHeight && scrollHeight) { // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation
+ if (this.props.renderDepth && this.layoutDoc._autoHeight && !this.props.ignoreAutoHeight && scrollHeight) { // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation
scrollHeight = scrollHeight * NumCast(this.layoutDoc.scale, 1);
if (limitHeight && scrollHeight > limitHeight) {
scrollHeight = limitHeight;
@@ -1210,16 +1211,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
@computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); }
render() {
TraceMobx();
- const style: { [key: string]: any } = {};
const scale = this.props.ContentScaling() * NumCast(this.layoutDoc.scale, 1);
- const divKeys = ["width", "height", "background"];
- const replacer = (match: any, expr: string, offset: any, string: any) => { // bcz: this executes a script to convert a propery expression string: { script } into a value
- return ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ self: this.rootDoc, this: this.layoutDoc }).result as string || "";
- };
- divKeys.map((prop: string) => {
- const p = (this.props as any)[prop] as string;
- p && (style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer));
- });
const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
const interactive = InkingControl.Instance.selectedTool || this.layoutDoc.isBackground;
if (this.props.isSelected()) {
@@ -1232,19 +1224,19 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
transform: `scale(${scale})`,
transformOrigin: "top left",
width: `${100 / scale}%`,
- height: `${100 / scale}%`,
+ height: `calc(${100 / scale}% - ${this.props.ChromeHeight?.() || 0}px)`,
+ ...this.styleFromLayoutString(scale)
}}>
<div className={`formattedTextBox-cont`} ref={this._ref}
style={{
width: "100%",
- height: this.props.height ? this.props.height : this.layoutDoc._autoHeight && this.props.renderDepth ? "max-content" : `calc(100% - ${this.props.ChromeHeight?.() || 0}px`,
- background: this.props.background ? this.props.background : StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], this.props.hideOnLeave ? "rgba(0,0,0 ,0.4)" : ""),
+ height: this.props.height ? this.props.height : this.layoutDoc._autoHeight && this.props.renderDepth ? "max-content" : undefined,
+ background: Doc.UserDoc().renderStyle === "comic" ? "transparent" : this.props.background ? this.props.background : StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], this.props.hideOnLeave ? "rgba(0,0,0 ,0.4)" : ""),
opacity: this.props.hideOnLeave ? (this._entered ? 1 : 0.1) : 1,
color: this.props.color ? this.props.color : StrCast(this.layoutDoc[this.props.fieldKey + "-color"], this.props.hideOnLeave ? "white" : "inherit"),
pointerEvents: interactive ? "none" : undefined,
fontSize: Cast(this.layoutDoc._fontSize, "number", null),
- fontFamily: StrCast(this.layoutDoc._fontFamily, "inherit"),
- ...style
+ fontFamily: StrCast(this.layoutDoc._fontFamily, "inherit")
}}
onContextMenu={this.specificContextMenu}
onKeyDown={this.onKeyPress}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index a33717855..d47ae63af 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -2,8 +2,8 @@ import { Mark, ResolvedPos } from "prosemirror-model";
import { EditorState, Plugin } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
import * as ReactDOM from 'react-dom';
-import { Doc, DocCastAsync } from "../../../../new_fields/Doc";
-import { Cast, FieldValue, NumCast } from "../../../../new_fields/Types";
+import { Doc, DocCastAsync } from "../../../../fields/Doc";
+import { Cast, FieldValue, NumCast } from "../../../../fields/Types";
import { emptyFunction, returnEmptyString, returnFalse, Utils, emptyPath, returnZero, returnOne } from "../../../../Utils";
import { DocServer } from "../../../DocServer";
import { DocumentManager } from "../../../util/DocumentManager";
@@ -211,8 +211,8 @@ export class FormattedTextBoxComment {
NativeWidth={returnZero}
NativeHeight={returnZero}
/>, FormattedTextBoxComment.tooltipText);
- FormattedTextBoxComment.tooltip.style.width = NumCast(target.width) ? `${NumCast(target.width)}` : "100%";
- FormattedTextBoxComment.tooltip.style.height = NumCast(target.height) ? `${NumCast(target.height)}` : "100%";
+ FormattedTextBoxComment.tooltip.style.width = NumCast(target._width) ? `${NumCast(target._width)}` : "100%";
+ FormattedTextBoxComment.tooltip.style.height = NumCast(target._height) ? `${NumCast(target._height)}` : "100%";
}
// let ext = (target && target.type !== DocumentType.PDFANNO && Doc.fieldExtensionDoc(target, "data")) || target; // try guessing that the target doc's data is in the 'data' field. probably need an 'overviewLayout' and then just display the target Document ....
// let text = ext && StrCast(ext.text);
diff --git a/src/client/views/nodes/formattedText/ImageResizeView.tsx b/src/client/views/nodes/formattedText/ImageResizeView.tsx
index 8f98da0fd..401ecd7e6 100644
--- a/src/client/views/nodes/formattedText/ImageResizeView.tsx
+++ b/src/client/views/nodes/formattedText/ImageResizeView.tsx
@@ -1,5 +1,5 @@
import { NodeSelection } from "prosemirror-state";
-import { Doc } from "../../../../new_fields/Doc";
+import { Doc } from "../../../../fields/Doc";
import { DocServer } from "../../../DocServer";
import { DocumentManager } from "../../../util/DocumentManager";
import React = require("react");
diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
index a0b02880e..0e3e7f91e 100644
--- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
+++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
@@ -7,10 +7,10 @@ import { splitListItem, wrapInList, } from "prosemirror-schema-list";
import { EditorState, Transaction, TextSelection } from "prosemirror-state";
import { SelectionManager } from "../../../util/SelectionManager";
import { Docs } from "../../../documents/Documents";
-import { NumCast, BoolCast, Cast, StrCast } from "../../../../new_fields/Types";
-import { Doc } from "../../../../new_fields/Doc";
+import { NumCast, BoolCast, Cast, StrCast } from "../../../../fields/Types";
+import { Doc } from "../../../../fields/Doc";
import { FormattedTextBox } from "./FormattedTextBox";
-import { Id } from "../../../../new_fields/FieldSymbols";
+import { Id } from "../../../../fields/FieldSymbols";
const mac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false;
@@ -154,15 +154,12 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, props: any
const originalDoc = layoutDoc.rootDocument || layoutDoc;
if (originalDoc instanceof Doc) {
const layoutKey = StrCast(originalDoc.layoutKey);
- const newDoc = Docs.Create.TextDocument("", {
- layout: Cast(originalDoc.layout, Doc, null) || FormattedTextBox.DefaultLayout,
- layoutKey,
- _singleLine: BoolCast(originalDoc._singleLine),
- x: NumCast(originalDoc.x), y: NumCast(originalDoc.y) + NumCast(originalDoc._height) + 10, _width: NumCast(layoutDoc._width), _height: NumCast(layoutDoc._height)
- });
+ const newDoc = Doc.MakeCopy(originalDoc, true);
+ newDoc.y = NumCast(originalDoc.y) + NumCast(originalDoc._height) + 10;
if (layoutKey !== "layout" && originalDoc[layoutKey] instanceof Doc) {
newDoc[layoutKey] = originalDoc[layoutKey];
}
+ Doc.GetProto(newDoc).text = undefined;
FormattedTextBox.SelectOnLoad = newDoc[Id];
props.addDocument(newDoc);
}
@@ -178,15 +175,12 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, props: any
const originalDoc = layoutDoc.rootDocument || layoutDoc;
if (force || props.Document._singleLine) {
const layoutKey = StrCast(originalDoc.layoutKey);
- const newDoc = Docs.Create.TextDocument("", {
- layout: Cast(originalDoc.layout, Doc, null) || FormattedTextBox.DefaultLayout,
- layoutKey,
- _singleLine: BoolCast(originalDoc._singleLine),
- x: NumCast(originalDoc.x) + NumCast(originalDoc._width) + 10, y: NumCast(originalDoc.y), _width: NumCast(layoutDoc._width), _height: NumCast(layoutDoc._height)
- });
+ const newDoc = Doc.MakeCopy(originalDoc, true);
+ newDoc.x = NumCast(originalDoc.x) + NumCast(originalDoc._width) + 10;
if (layoutKey !== "layout" && originalDoc[layoutKey] instanceof Doc) {
newDoc[layoutKey] = originalDoc[layoutKey];
}
+ Doc.GetProto(newDoc).text = undefined;
FormattedTextBox.SelectOnLoad = newDoc[Id];
props.addDocument(newDoc);
return true;
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 170a39801..fd1b26208 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -11,14 +11,14 @@ import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
import { faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSubscript, faSuperscript, faIndent, faEyeDropper, faCaretDown, faPalette, faHighlighter, faLink, faPaintRoller, faSleigh } from "@fortawesome/free-solid-svg-icons";
import { updateBullets } from "./ProsemirrorExampleTransfer";
import { FieldViewProps } from "../FieldView";
-import { Cast, StrCast } from "../../../../new_fields/Types";
+import { Cast, StrCast } from "../../../../fields/Types";
import { FormattedTextBoxProps } from "./FormattedTextBox";
import { unimplementedFunction, Utils } from "../../../../Utils";
import { wrapInList } from "prosemirror-schema-list";
-import { PastelSchemaPalette, DarkPastelSchemaPalette } from '../../../../new_fields/SchemaHeaderField';
+import { PastelSchemaPalette, DarkPastelSchemaPalette } from '../../../../fields/SchemaHeaderField';
import "./RichTextMenu.scss";
import { DocServer } from "../../../DocServer";
-import { Doc } from "../../../../new_fields/Doc";
+import { Doc } from "../../../../fields/Doc";
import { SelectionManager } from "../../../util/SelectionManager";
import { LinkManager } from "../../../util/LinkManager";
const { toggleMark, setBlockType } = require("prosemirror-commands");
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts
index 0ba591fec..fbd6c87bb 100644
--- a/src/client/views/nodes/formattedText/RichTextRules.ts
+++ b/src/client/views/nodes/formattedText/RichTextRules.ts
@@ -1,9 +1,9 @@
import { ellipsis, emDash, InputRule, smartQuotes, textblockTypeInputRule } from "prosemirror-inputrules";
import { NodeSelection, TextSelection } from "prosemirror-state";
-import { DataSym, Doc } from "../../../../new_fields/Doc";
-import { Id } from "../../../../new_fields/FieldSymbols";
-import { ComputedField } from "../../../../new_fields/ScriptField";
-import { Cast, NumCast } from "../../../../new_fields/Types";
+import { DataSym, Doc } from "../../../../fields/Doc";
+import { Id } from "../../../../fields/FieldSymbols";
+import { ComputedField } from "../../../../fields/ScriptField";
+import { Cast, NumCast } from "../../../../fields/Types";
import { returnFalse, Utils } from "../../../../Utils";
import { DocServer } from "../../../DocServer";
import { Docs, DocUtils } from "../../../documents/Documents";
@@ -11,7 +11,7 @@ import { FormattedTextBox } from "./FormattedTextBox";
import { wrappingInputRule } from "./prosemirrorPatches";
import RichTextMenu from "./RichTextMenu";
import { schema } from "./schema_rts";
-import { List } from "../../../../new_fields/List";
+import { List } from "../../../../fields/List";
export class RichTextRules {
public Document: Doc;
diff --git a/src/client/views/nodes/formattedText/RichTextSchema.tsx b/src/client/views/nodes/formattedText/RichTextSchema.tsx
index 7edd191cf..91280dea4 100644
--- a/src/client/views/nodes/formattedText/RichTextSchema.tsx
+++ b/src/client/views/nodes/formattedText/RichTextSchema.tsx
@@ -8,14 +8,14 @@ import { EditorState, NodeSelection, Plugin, TextSelection } from "prosemirror-s
import { StepMap } from "prosemirror-transform";
import { EditorView } from "prosemirror-view";
import * as ReactDOM from 'react-dom';
-import { Doc, DocListCast, Field, HeightSym, WidthSym } from "../../../../new_fields/Doc";
-import { Id } from "../../../../new_fields/FieldSymbols";
-import { List } from "../../../../new_fields/List";
-import { ObjectField } from "../../../../new_fields/ObjectField";
-import { listSpec } from "../../../../new_fields/Schema";
-import { SchemaHeaderField } from "../../../../new_fields/SchemaHeaderField";
-import { ComputedField } from "../../../../new_fields/ScriptField";
-import { BoolCast, Cast, NumCast, StrCast, FieldValue } from "../../../../new_fields/Types";
+import { Doc, DocListCast, Field, HeightSym, WidthSym } from "../../../../fields/Doc";
+import { Id } from "../../../../fields/FieldSymbols";
+import { List } from "../../../../fields/List";
+import { ObjectField } from "../../../../fields/ObjectField";
+import { listSpec } from "../../../../fields/Schema";
+import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField";
+import { ComputedField } from "../../../../fields/ScriptField";
+import { BoolCast, Cast, NumCast, StrCast, FieldValue } from "../../../../fields/Types";
import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils, returnZero } from "../../../../Utils";
import { DocServer } from "../../../DocServer";
import { Docs } from "../../../documents/Documents";
diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts
index 46bf481fb..ebaa23e99 100644
--- a/src/client/views/nodes/formattedText/marks_rts.ts
+++ b/src/client/views/nodes/formattedText/marks_rts.ts
@@ -1,6 +1,6 @@
import React = require("react");
import { DOMOutputSpecArray, Fragment, MarkSpec, Node, NodeSpec, Schema, Slice } from "prosemirror-model";
-import { Doc } from "../../../../new_fields/Doc";
+import { Doc } from "../../../../fields/Doc";
const emDOM: DOMOutputSpecArray = ["em", 0];