diff options
Diffstat (limited to 'src/client/views/nodes')
39 files changed, 716 insertions, 289 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..57f484214 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,53 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF } return undefined; } + + public static getValues(doc: Doc, time: number) { + return ({ + x: Cast(doc["x-indexed"], listSpec("number"), []).reduce((p, x, i) => (i <= time && x !== undefined) || p === undefined ? x : p, undefined as any as number), + y: Cast(doc["y-indexed"], listSpec("number"), []).reduce((p, y, i) => (i <= time && y !== undefined) || p === undefined ? y : p, undefined as any as number), + opacity: Cast(doc["opacity-indexed"], listSpec("number"), []).reduce((p, o, i) => i <= time || p === undefined ? o : p, undefined as any as number), + }); + } + + public static setValues(timecode: number, d: Doc, x?: number, y?: number, opacity?: number) { + Cast(d["x-indexed"], listSpec("number"), [])[timecode] = x as any as number; + Cast(d["y-indexed"], listSpec("number"), null)[timecode] = y as any as number; + Cast(d["opacity-indexed"], listSpec("number"), null)[timecode] = opacity as any as number; + } + public static updateKeyframe(docs: Doc[], timecode: number) { + 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 = undefined), 1010); + } + + public static gotoKeyframe(docs: Doc[]) { + docs.forEach(doc => doc.transition = "all 1s"); + setTimeout(() => docs.forEach(doc => doc.transition = undefined), 1010); + } + + public static setupKeyframes(docs: Doc[], timecode: number, collection: Doc) { + docs.forEach(doc => { + doc["x-indexed"] = new List<number>(numberRange(timecode).map(i => undefined) as any as number[]); + doc["y-indexed"] = new List<number>(numberRange(timecode).map(i => undefined) as any as number[]); + doc["opacity-indexed"] = new List<number>(numberRange(timecode).map(i => 0)); + (doc["x-indexed"] as any).push(NumCast(doc.x)); + (doc["y-indexed"] as any).push(NumCast(doc.y)); + (doc["opacity-indexed"] as any).push(NumCast(doc.opacity, 1)); + doc.displayTimecode = ComputedField.MakeFunction("collection ? collection.currentTimecode : 0", {}, { collection }); + doc.x = ComputedField.MakeInterpolated("x", "displayTimecode"); + doc.y = ComputedField.MakeInterpolated("y", "displayTimecode"); + doc.opacity = ComputedField.MakeInterpolated("opacity", "displayTimecode"); + }); + } + 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 +124,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 @@ -92,8 +146,15 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF height: this.height, zIndex: this.ZInd, 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 +163,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 f899b6bc8..6d53915ea 100644 --- a/src/client/views/nodes/ColorBox.tsx +++ b/src/client/views/nodes/ColorBox.tsx @@ -1,9 +1,9 @@ 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 { 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"; diff --git a/src/client/views/nodes/ComparisonBox.scss b/src/client/views/nodes/ComparisonBox.scss new file mode 100644 index 000000000..3d48d96e2 --- /dev/null +++ b/src/client/views/nodes/ComparisonBox.scss @@ -0,0 +1,90 @@ +.comparisonBox-interactive, .comparisonBox { + border-radius: inherit; + width: 100%; + height: 100%; + background-color: grey; + 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; + background-color: rgb(240, 240, 240); + } + } + + .slide-bar { + position: absolute; + height: 100%; + width: 3px; + display: inline-block; + background: gray; + cursor: ew-resize; + .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; + background-color: lightgray; + } + + .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; + .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..7a4d40db1 --- /dev/null +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -0,0 +1,152 @@ +import { library } from '@fortawesome/fontawesome-svg-core'; +import { faEye } from '@fortawesome/free-regular-svg-icons'; +import { faAsterisk, faBrain, faFileAudio, faImage, faPaintBrush, faTimes, faCloudUploadAlt } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { action, computed, observable, runInAction, Lambda } 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 } 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'; + +library.add(faImage, faEye as any, faPaintBrush, faBrain); +library.add(faFileAudio, faAsterisk); + +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) { + protected multiTouchDisposer?: import("../../util/InteractionUtils").InteractionUtils.MultiTouchEventDisposer | undefined; + + public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ComparisonBox, fieldKey); } + + private _beforeDropDisposer?: DragManager.DragDropDisposer; + private _afterDropDisposer?: DragManager.DragDropDisposer; + private resizeUpdater: Lambda | undefined; + + protected createDropTarget = (ele: HTMLDivElement | null, fieldKey: string) => { + if (ele) { + return DragManager.MakeDropTarget(ele, (event, dropEvent) => this.dropHandler(event, dropEvent, fieldKey), this.layoutDoc); + } + } + + @undoBatch + private dropHandler = (event: Event, dropEvent: DragManager.DropEvent, fieldKey: string) => { + event.stopPropagation(); + const droppedDocs = dropEvent.complete.docDragData?.droppedDocuments; + if (droppedDocs?.length) { + this.dataDoc[fieldKey] = droppedDocs[0]; + droppedDocs[0].isBackgound = true; + } + } + + componentWillMount() { + this.dataDoc.clipWidth = this.props.PanelWidth() / 2; + + //preserve before/after ratio during resizing + this.resizeUpdater = computed(() => this.props.PanelWidth()).observe(({ oldValue, newValue }) => + this.dataDoc.clipWidth = NumCast(this.dataDoc.clipWidth) / (oldValue || 0) * newValue + ); + } + + componentWillUnmount() { + this.resizeUpdater?.(); + } + + private registerSliding = (e: React.PointerEvent<HTMLDivElement>, targetWidth: number) => { + setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, action(() => { + this._animating = true; + this.dataDoc.clipWidth = targetWidth; + setTimeout(action(() => this._animating = false), 1000); + }), false); + } + + @action + private onPointerMove = ({ movementX }: PointerEvent) => { + const width = movementX * this.props.ScreenToLocalTransform().Scale + NumCast(this.dataDoc.clipWidth); + if (width && width > 5 && width < this.props.PanelWidth()) { + this.dataDoc.clipWidth = width; + } + return false; + } + + @undoBatch + clearDoc = (e: React.MouseEvent, fieldKey: string) => { + e.stopPropagation; + e.preventDefault; + delete this.dataDoc[fieldKey]; + } + + @observable _animating = false; + render() { + const beforeDoc = Cast(this.dataDoc.beforeDoc, Doc, null); + const afterDoc = Cast(this.dataDoc.afterDoc, Doc, null); + const clipWidth = NumCast(this.dataDoc.clipWidth); + return ( + <div className={`comparisonBox${this.active() || SnappingManager.GetIsDragging() ? "-interactive" : ""}`}> + <div className="afterBox-cont" key={"after"} onPointerDown={e => this.registerSliding(e, this.props.PanelWidth() - 5)} + ref={(ele) => { + this._afterDropDisposer?.(); + this._afterDropDisposer = this.createDropTarget(ele, "afterDoc"); + }}> + {afterDoc ? <> + <ContentFittingDocumentView {...this.props} + Document={afterDoc} + pointerEvents={false} + parentActive={this.props.active} + /> + <div className="clear-button after" onClick={e => this.clearDoc(e, "afterDoc")}> + <FontAwesomeIcon className="clear-button after" icon={faTimes} size="sm" /> + </div> + </> : + <div className="placeholder"> + <FontAwesomeIcon className="upload-icon" icon={faCloudUploadAlt} size="lg" /> + </div>} + </div> + <div className="clip-div" onPointerDown={e => this.registerSliding(e, 5)} style={{ width: clipWidth + "px", transition: this._animating ? "all 1s" : undefined }}> + {/* wraps around before image and slider bar */} + <div + className="beforeBox-cont" + key={"before"} + ref={(ele) => { + this._beforeDropDisposer?.(); + this._beforeDropDisposer = this.createDropTarget(ele, "beforeDoc"); + }} + style={{ width: this.props.PanelWidth() }}> + { + beforeDoc ? + <> + <ContentFittingDocumentView {...this.props} + Document={beforeDoc} + pointerEvents={false} + parentActive={this.props.active} /> + <div className="clear-button before" onClick={e => this.clearDoc(e, "beforeDoc")}> + <FontAwesomeIcon className="clear-button before" icon={faTimes} size="sm" /> + </div> + </> + : + <div className="placeholder"> + <FontAwesomeIcon className="upload-icon" icon={faCloudUploadAlt} size="lg" /> + </div> + } + </div> + </div> + + <div className="slide-bar" style={{ left: `calc(${NumCast(this.dataDoc.clipWidth) * 100 / this.props.PanelWidth()}% - 0.5px)` }}> + <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 2fc82e524..ef56e6fcd 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 } 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"; @@ -30,13 +30,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? @@ -194,7 +195,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & { CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, PresBox, YoutubeBox, PresElementBox, QueryBox, 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 d821bb8ac..993cabc36 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 } 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'; @@ -92,6 +91,7 @@ export interface DocumentViewProps { pinToPres: (document: Doc) => void; backgroundHalo?: () => boolean; backgroundColor?: (doc: Doc) => string | undefined; + opacity?: () => number | undefined; ChromeHeight?: () => number; dontRegisterView?: boolean; layoutKey?: string; @@ -682,12 +682,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu this.Document.lockedPosition = this.Document.lockedPosition ? undefined : true; } - @undoBatch - @action - toggleLockTransform = (): void => { - this.Document.lockedTransform = this.Document.lockedTransform ? undefined : true; - } - @action onContextMenu = async (e: React.MouseEvent | Touch): Promise<void> => { // the touch onContextMenu is button 0, the pointer onContextMenu is button 2 @@ -750,7 +744,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu const moreItems: ContextMenuProps[] = more && "subitems" in more ? more.subitems : []; 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) { @@ -764,10 +757,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; @@ -1118,7 +1113,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu render() { 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 +1152,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu 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,7 +1161,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 ? + {(this.Document.isBackground !== undefined || this.isSelected(false)) && (this.Document.type === DocumentType.COL || 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> 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 2ab0a416d..e9dc43bd8 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..77abfef1d 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'; 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..956d6556b 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'; diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index ac27640bd..ad9e49369 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -1,13 +1,11 @@ -import { library } from '@fortawesome/fontawesome-svg-core'; -import { faEdit } from '@fortawesome/free-regular-svg-icons'; import { action } 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 +14,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 42552ec73..aeb77a894 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,13 @@ 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.lastTimecode, "number", null); + const curFrame = NumCast(presTargetDoc.currentTimecode); + if (lastFrame !== undefined && curFrame < lastFrame) { + presTargetDoc.currentTimecode = curFrame + 1; + } + else if (this.childDocs[this.itemIndex + 1] !== undefined) { let nextSelected = this.itemIndex + 1; this.gotoDocument(nextSelected, this.itemIndex); @@ -188,11 +193,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.lastTimecode !== undefined) { + presTargetDoc.currentTimecode = 0; + } if (!this.layoutDoc.presStatus) { this.layoutDoc.presStatus = true; @@ -203,7 +212,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 +295,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,6 +330,7 @@ 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} @@ -333,5 +348,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/QueryBox.tsx b/src/client/views/nodes/QueryBox.tsx index 2a21a380d..0fff0b57f 100644 --- a/src/client/views/nodes/QueryBox.tsx +++ b/src/client/views/nodes/QueryBox.tsx @@ -1,15 +1,15 @@ import React = require("react"); import { IReactionDisposer } from "mobx"; import { observer } from "mobx-react"; -import { documentSchema } from "../../../new_fields/documentSchemas"; -import { Id } from '../../../new_fields/FieldSymbols'; -import { makeInterface, listSpec } from "../../../new_fields/Schema"; -import { StrCast, Cast } from "../../../new_fields/Types"; +import { documentSchema } from "../../../fields/documentSchemas"; +import { Id } from '../../../fields/FieldSymbols'; +import { makeInterface, listSpec } from "../../../fields/Schema"; +import { StrCast, Cast } from "../../../fields/Types"; import { ViewBoxAnnotatableComponent } from '../DocComponent'; import { SearchBox } from "../search/SearchBox"; import { FieldView, FieldViewProps } from './FieldView'; import "./QueryBox.scss"; -import { List } from "../../../new_fields/List"; +import { List } from "../../../fields/List"; import { SnappingManager } from "../../util/SnappingManager"; type QueryDocument = makeInterface<[typeof documentSchema]>; diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index a0ecc9ff5..5d4af2d77 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 } 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"; 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.tsx b/src/client/views/nodes/WebBox.tsx index 04878cf35..f80cea941 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,11 +97,13 @@ 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); @@ -110,16 +123,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 + 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 - setURL() { - const urlField: FieldResult<WebField> = Cast(this.dataDoc[this.props.fieldKey], WebField); - if (urlField) this._url = urlField.url.toString(); - else this._url = ""; + 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 +200,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 +220,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 +232,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 +241,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> @@ -308,6 +384,20 @@ 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 @@ -348,7 +438,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={{ @@ -356,18 +446,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 206c3db8c..b8fbe3420 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 } @@ -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; @@ -1223,14 +1224,14 @@ 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, diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index 07aecf148..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"; 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..2f7d23021 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; 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]; |
