From 810f86195188503b04d64f9d58ea4dfc3a639398 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 22 Mar 2022 11:32:47 -0400 Subject: fixed temporal media merge that had reverted a lot of things. --- src/client/views/nodes/AudioBox.tsx | 9 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 17 +- src/client/views/nodes/ColorBox.tsx | 7 +- src/client/views/nodes/ComparisonBox.tsx | 9 +- src/client/views/nodes/DocumentIcon.tsx | 2 +- src/client/views/nodes/DocumentLinksButton.scss | 4 +- src/client/views/nodes/DocumentLinksButton.tsx | 24 +- src/client/views/nodes/DocumentView.scss | 5 +- src/client/views/nodes/DocumentView.tsx | 72 ++-- src/client/views/nodes/EquationBox.tsx | 11 +- src/client/views/nodes/FilterBox.tsx | 17 +- src/client/views/nodes/FunctionPlotBox.tsx | 2 +- src/client/views/nodes/ImageBox.tsx | 19 +- src/client/views/nodes/KeyValueBox.tsx | 2 +- src/client/views/nodes/LabelBox.tsx | 9 +- src/client/views/nodes/LinkAnchorBox.tsx | 6 +- src/client/views/nodes/LinkBox.tsx | 7 +- src/client/views/nodes/MapBox/MapBox.tsx | 9 +- src/client/views/nodes/PDFBox.scss | 1 + src/client/views/nodes/PDFBox.tsx | 64 ++-- src/client/views/nodes/ScreenshotBox.tsx | 14 +- src/client/views/nodes/ScriptingBox.tsx | 34 +- src/client/views/nodes/SliderBox.tsx | 15 +- src/client/views/nodes/VideoBox.tsx | 41 +-- src/client/views/nodes/WebBox.scss | 7 + src/client/views/nodes/WebBox.tsx | 176 +++++---- src/client/views/nodes/WebBoxRenderer.js | 395 +++++++++++++++++++++ src/client/views/nodes/button/ButtonScripts.ts | 6 +- src/client/views/nodes/button/FontIconBox.tsx | 199 +++++------ .../views/nodes/formattedText/FormattedTextBox.tsx | 27 +- .../formattedText/ProsemirrorExampleTransfer.ts | 24 +- .../views/nodes/formattedText/RichTextRules.ts | 26 +- src/client/views/nodes/trails/PresBox.tsx | 12 +- src/client/views/nodes/trails/PresElementBox.tsx | 29 +- 34 files changed, 819 insertions(+), 482 deletions(-) create mode 100644 src/client/views/nodes/WebBoxRenderer.js (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index f5de31fcb..be18cc1de 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -42,9 +42,6 @@ declare class MediaRecorder { constructor(e: any); // whatever MediaRecorder has } -type AudioDocument = makeInterface<[typeof documentSchema]>; -const AudioDocument = makeInterface(documentSchema); - enum media_state { PendingRecording = "pendingRecording", Recording = "recording", @@ -54,7 +51,7 @@ enum media_state { @observer -export class AudioBox extends ViewBoxAnnotatableComponent(AudioDocument) { +export class AudioBox extends ViewBoxAnnotatableComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(AudioBox, fieldKey); } public static Enabled = false; @@ -240,7 +237,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent { + console.log("Data available", e); const [{ result }] = await Networking.UploadFilesToServer(e.data); + console.log("Data result", result); if (!(result instanceof Error)) { this.props.Document[this.fieldKey] = new AudioField(result.accessPaths.agnostic.client); } @@ -660,4 +659,4 @@ export class AudioBox extends ViewBoxAnnotatableComponent; } -} \ No newline at end of file +} diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index fe34d6687..c2a526804 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -1,7 +1,6 @@ import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import { Doc, Opt } from "../../../fields/Doc"; -import { Document } from "../../../fields/documentSchemas"; import { List } from "../../../fields/List"; import { listSpec } from "../../../fields/Schema"; import { ComputedField } from "../../../fields/ScriptField"; @@ -23,25 +22,27 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { 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; layerProvider: ((doc: Doc, assign?: boolean) => boolean) | undefined; + renderCutoffProvider: (doc: Doc) => boolean; zIndex?: number; highlight?: boolean; jitterRotation: number; dataTransition?: string; replica: string; + renderIndex: number; CollectionFreeFormView: CollectionFreeFormView; } @observer -export class CollectionFreeFormDocumentView extends DocComponent(Document) { +export class CollectionFreeFormDocumentView extends DocComponent() { public static animFields = ["_height", "_width", "x", "y", "_scrollTop", "opacity"]; // fields that are configured to be animatable using animation frames @observable _animPos: number[] | undefined = undefined; @observable _contentView: DocumentView | undefined | null; get displayName() { return "CollectionFreeFormDocumentView(" + this.rootDoc.title + ")"; } // this makes mobx trace() statements more descriptive get maskCentering() { return this.props.Document.isInkMask ? InkingStroke.MaskDim / 2 : 0; } get transform() { return `translate(${this.X - this.maskCentering}px, ${this.Y - this.maskCentering}px) rotate(${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 ZInd() { return this.dataProvider ? this.dataProvider.zIndex : (this.Document.zIndex || 0); } + get X() { return this.dataProvider ? this.dataProvider.x : NumCast(this.Document.x); } + get Y() { return this.dataProvider ? this.dataProvider.y : NumCast(this.Document.y); } + get ZInd() { return this.dataProvider ? this.dataProvider.zIndex : NumCast(this.Document.zIndex); } get Opacity() { return this.dataProvider ? this.dataProvider.opacity : undefined; } get Highlight() { return this.dataProvider?.highlight; } @computed get dataProvider() { return this.props.dataProvider?.(this.props.Document, this.props.replica); } @@ -176,7 +177,11 @@ export class CollectionFreeFormDocumentView extends DocComponent - this._contentView = r)} /> + {this.props.renderCutoffProvider(this.props.Document) ? +
+ : + this._contentView = r)} /> + }
; } } diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx index 8da5cd1b1..d975baf9b 100644 --- a/src/client/views/nodes/ColorBox.tsx +++ b/src/client/views/nodes/ColorBox.tsx @@ -3,9 +3,7 @@ import { action } from "mobx"; import { observer } from "mobx-react"; import { ColorState, SketchPicker } from 'react-color'; import { Doc, HeightSym, WidthSym } from '../../../fields/Doc'; -import { documentSchema } from "../../../fields/documentSchemas"; import { InkTool } from "../../../fields/InkField"; -import { makeInterface } from "../../../fields/Schema"; import { StrCast } from "../../../fields/Types"; import { DocumentType } from "../../documents/DocumentTypes"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; @@ -17,11 +15,8 @@ import "./ColorBox.scss"; import { FieldView, FieldViewProps } from './FieldView'; import { RichTextMenu } from "./formattedText/RichTextMenu"; -type ColorDocument = makeInterface<[typeof documentSchema]>; -const ColorDocument = makeInterface(documentSchema); - @observer -export class ColorBox extends ViewBoxBaseComponent(ColorDocument) { +export class ColorBox extends ViewBoxBaseComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ColorBox, fieldKey); } @undoBatch diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index d47e8340c..cbc61ffdb 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -2,8 +2,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, observable } from 'mobx'; import { observer } from "mobx-react"; import { Doc, Opt } from '../../../fields/Doc'; -import { documentSchema } from '../../../fields/documentSchemas'; -import { createSchema, makeInterface } from '../../../fields/Schema'; import { Cast, NumCast, StrCast } from '../../../fields/Types'; import { emptyFunction, OmitKeys, returnFalse, setupMoveUpEvents } from '../../../Utils'; import { DragManager } from '../../util/DragManager'; @@ -15,15 +13,10 @@ import "./ComparisonBox.scss"; import { DocumentView, DocumentViewProps } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; import React = require("react"); -import { DocumentType } from '../../documents/DocumentTypes'; -export const comparisonSchema = createSchema({}); - -type ComparisonDocument = makeInterface<[typeof comparisonSchema, typeof documentSchema]>; -const ComparisonDocument = makeInterface(comparisonSchema, documentSchema); @observer -export class ComparisonBox extends ViewBoxAnnotatableComponent(ComparisonDocument) { +export class ComparisonBox extends ViewBoxAnnotatableComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ComparisonBox, fieldKey); } protected _multiTouchDisposer?: import("../../util/InteractionUtils").InteractionUtils.MultiTouchEventDisposer | undefined; private _disposers: (DragManager.DragDropDisposer | undefined)[] = [undefined, undefined]; diff --git a/src/client/views/nodes/DocumentIcon.tsx b/src/client/views/nodes/DocumentIcon.tsx index 123212608..433a0bf48 100644 --- a/src/client/views/nodes/DocumentIcon.tsx +++ b/src/client/views/nodes/DocumentIcon.tsx @@ -2,7 +2,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import { DocumentView } from "./DocumentView"; import { DocumentManager } from "../../util/DocumentManager"; -import { Transformer, Scripting, ts } from "../../util/Scripting"; +import { Transformer, ts } from "../../util/Scripting"; import { Field } from "../../../fields/Doc"; @observer diff --git a/src/client/views/nodes/DocumentLinksButton.scss b/src/client/views/nodes/DocumentLinksButton.scss index 228e1bdcb..9ab3171d3 100644 --- a/src/client/views/nodes/DocumentLinksButton.scss +++ b/src/client/views/nodes/DocumentLinksButton.scss @@ -1,6 +1,8 @@ @import "../global/globalCssVariables.scss"; - +.documentLinksButton-wrapper { + transform-origin: top left; +} .documentLinksButton-menu { width: 100%; height: 100%; diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 93cd02d93..7e6ca4248 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -20,6 +20,7 @@ import { DocumentView } from "./DocumentView"; import { LinkDescriptionPopup } from "./LinkDescriptionPopup"; import { TaskCompletionBox } from "./TaskCompletedBox"; import React = require("react"); +import { Transform } from "../../util/Transform"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; @@ -31,6 +32,7 @@ interface DocumentLinksButtonProps { AlwaysOn?: boolean; InMenu?: boolean; StartLink?: boolean; //whether the link HAS been started (i.e. now needs to be completed) + ContentScaling?: () => number; } @observer export class DocumentLinksButton extends React.Component { @@ -302,16 +304,16 @@ export class DocumentLinksButton extends React.Component{title}}> - {this.linkButtonInner} - - : - !DocumentLinksButton.LinkEditorDocView && !this.props.InMenu ? - {title}}> - {this.linkButtonInner} - - : this.linkButtonInner; + return (!Array.from(this.filteredLinks).length && !this.props.AlwaysOn) ? (null) : +
+ { + (this.props.InMenu && (DocumentLinksButton.StartLink || this.props.StartLink)) || + (!DocumentLinksButton.LinkEditorDocView && !this.props.InMenu) ? + {title}
}> + {this.linkButtonInner} + + : this.linkButtonInner + } + ; } } diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index 9fcd45e72..4565f8504 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -58,9 +58,10 @@ .documentView-audioBackground { display: inline-block; width: 10%; + height: 25; position: absolute; - top: 0px; - left: 0px; + top: 10px; + left: 10px; border-radius: 25px; background: white; opacity: 0.3; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 707c15bff..e7de87ea5 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1,3 +1,4 @@ +import { IconProp } from "@fortawesome/fontawesome-svg-core"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; @@ -9,11 +10,11 @@ import { List } from "../../../fields/List"; import { ObjectField } from "../../../fields/ObjectField"; import { listSpec } from "../../../fields/Schema"; import { ScriptField } from '../../../fields/ScriptField'; -import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types"; +import { BoolCast, Cast, ImageCast, NumCast, ScriptCast, StrCast } from "../../../fields/Types"; import { AudioField } from "../../../fields/URLField"; import { GetEffectiveAcl, SharingPermissions, TraceMobx } from '../../../fields/util'; import { MobileInterface } from '../../../mobile/MobileInterface'; -import { emptyFunction, hasDescendantTarget, OmitKeys, returnTrue, returnVal, Utils, lightOrDark, simulateMouseClick, returnEmptyString } from "../../../Utils"; +import { emptyFunction, hasDescendantTarget, lightOrDark, OmitKeys, returnEmptyString, returnTrue, returnVal, simulateMouseClick, Utils } from "../../../Utils"; import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; import { Docs, DocUtils } from "../../documents/Documents"; import { DocumentType } from '../../documents/DocumentTypes'; @@ -23,7 +24,7 @@ import { DocumentManager } from "../../util/DocumentManager"; import { DragManager, dropActionType } from "../../util/DragManager"; import { InteractionUtils } from '../../util/InteractionUtils'; import { LinkManager } from '../../util/LinkManager'; -import { Scripting } from '../../util/Scripting'; +import { ScriptingGlobals } from '../../util/ScriptingGlobals'; import { SelectionManager } from "../../util/SelectionManager"; import { SharingManager } from '../../util/SharingManager'; import { SnappingManager } from '../../util/SnappingManager'; @@ -48,8 +49,6 @@ import { RadialMenu } from './RadialMenu'; import { ScriptingBox } from "./ScriptingBox"; import { PresBox } from './trails/PresBox'; import React = require("react"); -import { IconProp } from "@fortawesome/fontawesome-svg-core"; -import { ColorScheme } from "../../util/SettingsManager"; const { Howl } = require('howler'); interface Window { @@ -110,6 +109,7 @@ export interface DocumentViewSharedProps { fitContentsToDoc?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _fitToBox property on a Document ContainingCollectionView: Opt; ContainingCollectionDoc: Opt; + thumbShown?: () => boolean; setContentView?: (view: DocComponentView) => any; CollectionFreeFormDocumentView?: () => CollectionFreeFormDocumentView; PanelWidth: () => number; @@ -179,11 +179,12 @@ export interface DocumentViewInternalProps extends DocumentViewProps { } @observer -export class DocumentViewInternal extends DocComponent(Document) { +export class DocumentViewInternal extends DocComponent() { public static SelectAfterContextMenu = true; // whether a document should be selected after it's contextmenu is triggered. @observable _animateScalingTo = 0; @observable _mediaState = 0; @observable _pendingDoubleClick = false; + private _disposers: { [name: string]: IReactionDisposer } = {}; private _downX: number = 0; private _downY: number = 0; private _firstX: number = -1; @@ -204,6 +205,7 @@ export class DocumentViewInternal extends DocComponent); } @computed get ContentScale() { return this.props.ContentScaling?.() || 1; } + @computed get thumb() { return ImageCast(this.layoutDoc["thumb-frozen"], ImageCast(this.layoutDoc.thumb))?.url.href.replace(".png", "_m.png"); } @computed get hidden() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Hidden); } @computed get opacity() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Opacity); } @computed get boxShadow() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BoxShadow); } @@ -239,6 +241,7 @@ export class DocumentViewInternal extends DocComponent disposer?.()); } handle1PointerHoldStart = (e: Event, me: InteractionUtils.MultiTouchEvent): any => { @@ -485,6 +488,7 @@ export class DocumentViewInternal extends DocComponent this.onClickHandler.script.run({ this: this.layoutDoc, self: this.rootDoc, + _readOnly_: false, scriptContext: this.props.scriptContext, thisContainer: this.props.ContainingCollectionDoc, documentView: this.props.DocumentView(), @@ -836,14 +840,13 @@ export class DocumentViewInternal extends DocComponent !this.props.isSelected() && LightboxView.LightboxDoc !== this.rootDoc && this.thumb && + !this._componentView?.isAnyChildContentActive?.() ? true : false; @computed get contents() { TraceMobx(); const audioView = !this.layoutDoc._showAudio ? (null) : -
+
@@ -853,8 +856,17 @@ export class DocumentViewInternal extends DocComponent - showTitle.split(";").length === 1 ? showTitle + "=" + Field.toString(targetDoc[showTitle.split(";")[0]] as any as Field) : "#" + showTitle} - SetValue={undoBatch(input => { + SetValue={undoBatch((input: string) => { if (input?.startsWith("#")) { if (this.props.showTitle) { this.rootDoc._showTitle = input?.substring(1) ? input.substring(1) : undefined; } else { Doc.UserDoc().showTitle = input?.substring(1) ? input.substring(1) : "creationDate"; } - return true; } else { - var value = input.replace(new RegExp(showTitle + "="), ""); + var value = input.replace(new RegExp(showTitle + "="), "") as string | number; if (showTitle !== "title" && Number(value).toString() === value) value = Number(value); if (showTitle.includes("Date") || showTitle === "author") return true; - return Doc.SetInPlace(targetDoc, showTitle, value, true) ? true : true; + Doc.SetInPlace(targetDoc, showTitle, value, true); } return true; })} @@ -1048,15 +1059,17 @@ export class DocumentViewInternal extends DocComponent; } + @observable _: string = ""; @computed get renderDoc() { TraceMobx(); - const isButton: boolean = this.props.Document.type === DocumentType.FONTICON; + const thumb = ImageCast(this.layoutDoc["thumb-frozen"], ImageCast(this.layoutDoc.thumb))?.url.href.replace(".png", "_m.png"); + const isButton = this.props.Document.type === DocumentType.FONTICON; if (!(this.props.Document instanceof Doc) || GetEffectiveAcl(this.props.Document[DataSym]) === AclPrivate || this.hidden) return null; return this.docContents ??
+ {this.innards} {this.onClickHandler && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ?
: (null)} {this.widgetDecorations ?? null} @@ -1143,7 +1157,7 @@ export class DocumentView extends React.Component { get LayoutFieldKey() { return this.docView?.LayoutFieldKey || "layout"; } get fitWidth() { return this.props.fitWidth?.(this.rootDoc) || this.layoutDoc.fitWidth; } - @computed get docViewPath() { return this.props.docViewPath ? [...this.props.docViewPath(), this] : [this]; } + @computed get docViewPath(): DocumentView[] { return this.props.docViewPath ? [...this.props.docViewPath(), this] : [this]; } @computed get layoutDoc() { return Doc.Layout(this.Document, this.props.LayoutTemplate?.()); } @computed get nativeWidth() { return this.docView?._componentView?.reverseNativeScaling?.() ? 0 : @@ -1281,7 +1295,7 @@ export class DocumentView extends React.Component { } } -Scripting.addGlobal(function toggleDetail(dv: DocumentView, detailLayoutKeySuffix: string) { +ScriptingGlobals.add(function toggleDetail(dv: DocumentView, detailLayoutKeySuffix: string) { if (dv.Document.layoutKey === "layout_" + detailLayoutKeySuffix) dv.switchViews(false, "layout"); else dv.switchViews(true, detailLayoutKeySuffix); }); \ No newline at end of file diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx index f1f802c13..c170f9867 100644 --- a/src/client/views/nodes/EquationBox.tsx +++ b/src/client/views/nodes/EquationBox.tsx @@ -3,25 +3,18 @@ import { action, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { WidthSym } from '../../../fields/Doc'; -import { documentSchema } from '../../../fields/documentSchemas'; import { Id } from '../../../fields/FieldSymbols'; -import { createSchema, makeInterface } from '../../../fields/Schema'; import { NumCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; import { Docs } from '../../documents/Documents'; import { ViewBoxBaseComponent } from '../DocComponent'; import { LightboxView } from '../LightboxView'; -import { FieldView, FieldViewProps } from './FieldView'; import './EquationBox.scss'; +import { FieldView, FieldViewProps } from './FieldView'; -const EquationSchema = createSchema({}); - -type EquationDocument = makeInterface<[typeof EquationSchema, typeof documentSchema]>; -const EquationDocument = makeInterface(EquationSchema, documentSchema); - @observer -export class EquationBox extends ViewBoxBaseComponent(EquationDocument) { +export class EquationBox extends ViewBoxBaseComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(EquationBox, fieldKey); } public static SelectOnLoad: string = ""; _ref: React.RefObject = React.createRef(); diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index fb8e89da9..ba65acee0 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -4,18 +4,17 @@ import { action, computed, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; import Select from "react-select"; import { Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt } from "../../../fields/Doc"; -import { documentSchema } from "../../../fields/documentSchemas"; import { List } from "../../../fields/List"; import { RichTextField } from "../../../fields/RichTextField"; -import { listSpec, makeInterface } from "../../../fields/Schema"; +import { listSpec } from "../../../fields/Schema"; import { ComputedField, ScriptField } from "../../../fields/ScriptField"; -import { Cast, StrCast, NumCast } from "../../../fields/Types"; +import { Cast, NumCast, StrCast } from "../../../fields/Types"; import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from "../../../Utils"; import { Docs } from "../../documents/Documents"; import { DocumentType } from "../../documents/DocumentTypes"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { UserOptions } from "../../util/GroupManager"; -import { Scripting } from "../../util/Scripting"; +import { ScriptingGlobals } from "../../util/ScriptingGlobals"; import { SelectionManager } from "../../util/SelectionManager"; import { CollectionTreeView } from "../collections/CollectionTreeView"; import { CollectionView } from "../collections/CollectionView"; @@ -30,11 +29,8 @@ const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; -type FilterBoxDocument = makeInterface<[typeof documentSchema]>; -const FilterBoxDocument = makeInterface(documentSchema); - @observer -export class FilterBox extends ViewBoxBaseComponent(FilterBoxDocument) { +export class FilterBox extends ViewBoxBaseComponent() { constructor(props: Readonly) { super(props); @@ -425,7 +421,6 @@ export class FilterBox extends ViewBoxBaseComponent(); const activeTabs = DocListCast(layoutDoc[childKey]); SearchBox.foreachRecursiveDoc(activeTabs, (depth: number, doc: Doc) => allCollectionDocs.add(doc)); diff --git a/src/client/views/nodes/FunctionPlotBox.tsx b/src/client/views/nodes/FunctionPlotBox.tsx index 5050fc2d2..3ab0a3ff2 100644 --- a/src/client/views/nodes/FunctionPlotBox.tsx +++ b/src/client/views/nodes/FunctionPlotBox.tsx @@ -19,7 +19,7 @@ type EquationDocument = makeInterface<[typeof EquationSchema, typeof documentSch const EquationDocument = makeInterface(EquationSchema, documentSchema); @observer -export class FunctionPlotBox extends ViewBoxBaseComponent(EquationDocument) { +export class FunctionPlotBox extends ViewBoxBaseComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FunctionPlotBox, fieldKey); } public static GraphCount = 0; _plot: any; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 89f70985c..0a4168698 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,12 +1,12 @@ -import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, trace } from 'mobx'; +import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from "mobx-react"; +import { extname } from 'path'; import { DataSym, Doc, DocListCast, WidthSym } from '../../../fields/Doc'; -import { documentSchema } from '../../../fields/documentSchemas'; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; import { List } from '../../../fields/List'; import { ObjectField } from '../../../fields/ObjectField'; -import { createSchema, makeInterface } from '../../../fields/Schema'; +import { createSchema } from '../../../fields/Schema'; import { ComputedField } from '../../../fields/ScriptField'; import { Cast, NumCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; @@ -29,16 +29,11 @@ import { FaceRectangles } from './FaceRectangles'; import { FieldView, FieldViewProps } from './FieldView'; import "./ImageBox.scss"; import React = require("react"); -import { SnappingManager } from '../../util/SnappingManager'; -const path = require('path'); export const pageSchema = createSchema({ googlePhotosUrl: "string", googlePhotosTags: "string" }); -type ImageDocument = makeInterface<[typeof pageSchema, typeof documentSchema]>; -const ImageDocument = makeInterface(pageSchema, documentSchema); - const uploadIcons = { idle: "downarrow.png", loading: "loading.gif", @@ -47,7 +42,7 @@ const uploadIcons = { }; @observer -export class ImageBox extends ViewBoxAnnotatableComponent(ImageDocument) { +export class ImageBox extends ViewBoxAnnotatableComponent() { protected _multiTouchDisposer?: import("../../util/InteractionUtils").InteractionUtils.MultiTouchEventDisposer | undefined; public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ImageBox, fieldKey); } private _imgRef: React.RefObject = React.createRef(); @@ -190,7 +185,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent -
+
{ value = eq ? value.substr(1) : value; const dubEq = value.startsWith(":=") ? "computed" : value.startsWith(";=") ? "script" : false; value = dubEq ? value.substr(2) : value; - const options: ScriptOptions = { addReturn: true, params: { this: "Doc", _last_: "any" }, editable: false }; + const options: ScriptOptions = { addReturn: true, params: { this: Doc.name, self: Doc.name, _last_: "any", _readOnly_: "boolean" }, editable: false }; if (dubEq) options.typecheck = false; const script = CompileScript(value, options); return !script.compiled ? undefined : { script, type: dubEq, onDelegate: eq }; diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index dae72bb78..0015f0b71 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -2,9 +2,8 @@ import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast } from '../../../fields/Doc'; -import { documentSchema } from '../../../fields/documentSchemas'; import { List } from '../../../fields/List'; -import { createSchema, listSpec, makeInterface } from '../../../fields/Schema'; +import { listSpec } from '../../../fields/Schema'; import { Cast, StrCast } from '../../../fields/Types'; import { DragManager } from '../../util/DragManager'; import { undoBatch } from '../../util/UndoManager'; @@ -16,17 +15,13 @@ import { FieldView, FieldViewProps } from './FieldView'; import BigText from './LabelBigText'; import './LabelBox.scss'; -const LabelSchema = createSchema({}); - -type LabelDocument = makeInterface<[typeof LabelSchema, typeof documentSchema]>; -const LabelDocument = makeInterface(LabelSchema, documentSchema); export interface LabelBoxProps { label?: string; } @observer -export class LabelBox extends ViewBoxBaseComponent<(FieldViewProps & LabelBoxProps), LabelDocument>(LabelDocument) { +export class LabelBox extends ViewBoxBaseComponent<(FieldViewProps & LabelBoxProps)>() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(LabelBox, fieldKey); } public static LayoutStringWithTitle(fieldType: { name: string }, fieldStr: string, label: string) { return `<${fieldType.name} fieldKey={'${fieldStr}'} label={'${label}'} {...props} />`; //e.g., "" diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index a7bfb93eb..437d29f39 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -2,8 +2,6 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, observable } from "mobx"; import { observer } from "mobx-react"; import { Doc } from "../../../fields/Doc"; -import { documentSchema } from "../../../fields/documentSchemas"; -import { makeInterface } from "../../../fields/Schema"; import { Cast, NumCast, StrCast } from "../../../fields/Types"; import { TraceMobx } from "../../../fields/util"; import { emptyFunction, setupMoveUpEvents, Utils } from '../../../Utils'; @@ -23,11 +21,9 @@ const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; -type LinkAnchorSchema = makeInterface<[typeof documentSchema]>; -const LinkAnchorDocument = makeInterface(documentSchema); @observer -export class LinkAnchorBox extends ViewBoxBaseComponent(LinkAnchorDocument) { +export class LinkAnchorBox extends ViewBoxBaseComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(LinkAnchorBox, fieldKey); } _doubleTap = false; _lastTap: number = 0; diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx index 879a63248..43f4b43fb 100644 --- a/src/client/views/nodes/LinkBox.tsx +++ b/src/client/views/nodes/LinkBox.tsx @@ -1,7 +1,5 @@ import React = require("react"); import { observer } from "mobx-react"; -import { documentSchema } from "../../../fields/documentSchemas"; -import { makeInterface } from "../../../fields/Schema"; import { emptyFunction, returnFalse } from "../../../Utils"; import { ViewBoxBaseComponent } from "../DocComponent"; import { StyleProp } from "../StyleProvider"; @@ -9,11 +7,8 @@ import { ComparisonBox } from "./ComparisonBox"; import { FieldView, FieldViewProps } from './FieldView'; import "./LinkBox.scss"; -type LinkDocument = makeInterface<[typeof documentSchema]>; -const LinkDocument = makeInterface(documentSchema); - @observer -export class LinkBox extends ViewBoxBaseComponent(LinkDocument) { +export class LinkBox extends ViewBoxBaseComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(LinkBox, fieldKey); } isContentActiveFunc = () => this.isContentActive(); render() { diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 50444c73a..aa2130af5 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -1,14 +1,11 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Autocomplete, GoogleMap, GoogleMapProps, Marker } from '@react-google-maps/api'; -import * as dotenv from 'dotenv'; import { action, computed, IReactionDisposer, observable, ObservableMap } from 'mobx'; import { observer } from "mobx-react"; import * as React from "react"; import { Doc, DocListCast, Opt, WidthSym } from '../../../../fields/Doc'; -import { documentSchema } from '../../../../fields/documentSchemas'; import { Id } from '../../../../fields/FieldSymbols'; import { InkTool } from '../../../../fields/InkField'; -import { makeInterface } from '../../../../fields/Schema'; import { NumCast, StrCast } from '../../../../fields/Types'; import { TraceMobx } from '../../../../fields/util'; import { emptyFunction, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../../Utils'; @@ -43,9 +40,6 @@ import { MapBoxInfoWindow } from './MapBoxInfoWindow'; // const _global = (window /* browser */ || global /* node */) as any; -type MapDocument = makeInterface<[typeof documentSchema]>; -const MapDocument = makeInterface(documentSchema); - const mapContainerStyle = { height: '100%', }; @@ -59,7 +53,6 @@ const mapOptions = { fullscreenControl: false, }; -dotenv.config({ path: __dirname + '/.env' }); const apiKey = process.env.GOOGLE_MAPS; const script = document.createElement('script'); @@ -93,7 +86,7 @@ const options = { } as google.maps.places.AutocompleteOptions; @observer -export class MapBox extends ViewBoxAnnotatableComponent, MapDocument>(MapDocument) { +export class MapBox extends ViewBoxAnnotatableComponent>() { private _dropDisposer?: DragManager.DragDropDisposer; private _disposers: { [name: string]: IReactionDisposer } = {}; diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss index f44355929..8a68f9647 100644 --- a/src/client/views/nodes/PDFBox.scss +++ b/src/client/views/nodes/PDFBox.scss @@ -248,6 +248,7 @@ .pdfBox-background { width: 100%; height: 100%; + cursor: ew-resize; background: lightGray; } diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index d54b65d92..9807cee7c 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -3,17 +3,14 @@ import { action, computed, IReactionDisposer, observable, reaction, runInAction import { observer } from "mobx-react"; import * as Pdfjs from "pdfjs-dist"; import "pdfjs-dist/web/pdf_viewer.css"; -import { Doc, DocListCast, Opt, WidthSym, StrListCast } from "../../../fields/Doc"; -import { documentSchema } from '../../../fields/documentSchemas'; -import { makeInterface, listSpec } from "../../../fields/Schema"; -import { Cast, NumCast, StrCast } from '../../../fields/Types'; +import { Doc, DocListCast, Opt, WidthSym } from "../../../fields/Doc"; +import { Cast, NumCast, StrCast, ImageCast } from '../../../fields/Types'; import { PdfField } from "../../../fields/URLField"; import { TraceMobx } from '../../../fields/util'; import { emptyFunction, returnOne, setupMoveUpEvents, Utils } from '../../../Utils'; import { Docs } from '../../documents/Documents'; import { KeyCodes } from '../../util/KeyCodes'; import { undoBatch } from '../../util/UndoManager'; -import { panZoomSchema } from '../collections/collectionFreeForm/CollectionFreeFormView'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from "../DocComponent"; @@ -22,18 +19,14 @@ import { AnchorMenu } from '../pdf/AnchorMenu'; import { PDFViewer } from "../pdf/PDFViewer"; import { SidebarAnnos } from '../SidebarAnnos'; import { FieldView, FieldViewProps } from './FieldView'; -import { pageSchema } from "./ImageBox"; import "./PDFBox.scss"; import React = require("react"); -import { CurrentUserUtils } from '../../util/CurrentUserUtils'; - -type PdfDocument = makeInterface<[typeof documentSchema, typeof panZoomSchema, typeof pageSchema]>; -const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema); @observer -export class PDFBox extends ViewBoxAnnotatableComponent(PdfDocument) { +export class PDFBox extends ViewBoxAnnotatableComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PDFBox, fieldKey); } public static openSidebarWidth = 250; + public static sidebarResizerWidth = 5; private _searchString: string = ""; private _initialScrollTarget: Opt; private _pdfViewer: PDFViewer | undefined; @@ -46,6 +39,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent this._pdf = PDFBox.pdfcache.get(this.pdfUrl!.url.href)); - else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href)) PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then(action(pdf => this._pdf = pdf)); + else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href)) PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then(action((pdf: any) => this._pdf = pdf)); } } @@ -80,7 +74,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent this._pdfViewer?.prevAnnotation(); public nextAnnotation = () => this._pdfViewer?.nextAnnotation(); - public backPage = () => { this.Document._curPage = (this.Document._curPage || 1) - 1; return true; }; - public forwardPage = () => { this.Document._curPage = (this.Document._curPage || 1) + 1; return true; }; + public backPage = () => { this.Document._curPage = (NumCast(this.Document._curPage) || 1) - 1; return true; }; + public forwardPage = () => { this.Document._curPage = (NumCast(this.Document._curPage) || 1) + 1; return true; }; public gotoPage = (p: number) => this.Document._curPage = p; @undoBatch @@ -142,15 +136,15 @@ export class PDFBox extends ViewBoxAnnotatableComponent { + sidebarBtnDown = (e: React.PointerEvent, onButton: boolean) => { // onButton determines whether the width of the pdf box changes, or just the ratio of the sidebar to the pdf setupMoveUpEvents(this, e, (e, down, delta) => { const localDelta = this.props.ScreenToLocalTransform().scale(this.props.scaling?.() || 1).transformDirection(delta[0], delta[1]); const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]); const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth); - const ratio = (curNativeWidth + localDelta[0] / (this.props.scaling?.() || 1)) / nativeWidth; + const ratio = (curNativeWidth + (onButton ? 1 : -1) * localDelta[0] / (this.props.scaling?.() || 1)) / nativeWidth; if (ratio >= 1) { this.layoutDoc.nativeWidth = nativeWidth * ratio; - this.layoutDoc._width = this.layoutDoc[WidthSym]() + localDelta[0]; + onButton && (this.layoutDoc._width = this.layoutDoc[WidthSym]() + localDelta[0]); this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth; } return false; @@ -160,16 +154,17 @@ export class PDFBox extends ViewBoxAnnotatableComponent = undefined; toggleSidebar = action((preview: boolean = false) => { const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]); - const ratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? PDFBox.openSidebarWidth : 0) + nativeWidth) / nativeWidth; + const sideratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? PDFBox.openSidebarWidth : 0) + nativeWidth) / nativeWidth; + const pdfratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? PDFBox.openSidebarWidth + PDFBox.sidebarResizerWidth : 0) + nativeWidth) / nativeWidth; const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth); if (preview) { - this._previewNativeWidth = nativeWidth * ratio; - this._previewWidth = this.layoutDoc[WidthSym]() * nativeWidth * ratio / curNativeWidth; + this._previewNativeWidth = nativeWidth * sideratio; + this._previewWidth = this.layoutDoc[WidthSym]() * nativeWidth * sideratio / curNativeWidth; this._showSidebar = true; } else { - this.layoutDoc.nativeWidth = nativeWidth * ratio; - this.layoutDoc._width = this.layoutDoc[WidthSym]() * nativeWidth * ratio / curNativeWidth; + this.layoutDoc.nativeWidth = nativeWidth * pdfratio; + this.layoutDoc._width = this.layoutDoc[WidthSym]() * nativeWidth * pdfratio / curNativeWidth; this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth; } }); @@ -185,7 +180,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent ; const searchTitle = `${!this._searching ? "Open" : "Close"} Search Bar`; - const curPage = this.Document._curPage || 1; + const curPage = NumCast(this.Document._curPage) || 1; return !this.props.isContentActive() ? (null) :
[KeyCodes.BACKSPACE, KeyCodes.DELETE].includes(e.keyCode) ? e.stopPropagation() : true} onPointerDown={e => e.stopPropagation()} style={{ display: this.props.isContentActive() ? "flex" : "none" }}> @@ -223,7 +218,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent + onPointerDown={e => this.sidebarBtnDown(e, true)} >
; @@ -253,18 +248,20 @@ export class PDFBox extends ViewBoxAnnotatableComponent 1; + isPdfContentActive = () => this.isAnyChildContentActive() || this.props.isSelected(); @computed get renderPdfView() { TraceMobx(); const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1; const scale = previewScale * (this.props.scaling?.() || 1); return
600) ? NumCast(this.Document._height) * this.props.PanelWidth() / NumCast(this.Document._width) : undefined }}> -
+
this.sidebarBtnDown(e, false)} />
(); - static pdfpromise = new Map>(); + static pdfpromise = new Map>(); render() { TraceMobx(); - if (this._pdf) return this.renderPdfView; + if (this._pdf) { + if (!this.props.thumbShown?.()) { + return this.renderPdfView; + } + return null; + } const href = this.pdfUrl?.url.href; if (href) { if (PDFBox.pdfcache.get(href)) setTimeout(action(() => this._pdf = PDFBox.pdfcache.get(href))); else { if (!PDFBox.pdfpromise.get(href)) PDFBox.pdfpromise.set(href, Pdfjs.getDocument(href).promise); - PDFBox.pdfpromise.get(href)?.then(action(pdf => PDFBox.pdfcache.set(href, this._pdf = pdf))); + PDFBox.pdfpromise.get(href)?.then(action((pdf: any) => PDFBox.pdfcache.set(href, this._pdf = pdf))); } } return this.renderTitleBox; diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 0c631e5f9..dbb567d3a 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -1,20 +1,17 @@ import React = require("react"); import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; // import { Canvas } from '@react-three/fiber'; -import { action, computed, observable, reaction, trace, runInAction } from "mobx"; +import { computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; // import { BufferAttribute, Camera, Vector2, Vector3 } from 'three'; import { DateField } from "../../../fields/DateField"; -import { Doc, WidthSym, HeightSym } from "../../../fields/Doc"; -import { documentSchema } from "../../../fields/documentSchemas"; +import { Doc, HeightSym, WidthSym } from "../../../fields/Doc"; import { Id } from "../../../fields/FieldSymbols"; -import { InkTool } from "../../../fields/InkField"; -import { makeInterface } from "../../../fields/Schema"; import { ComputedField } from "../../../fields/ScriptField"; import { Cast, NumCast } from "../../../fields/Types"; import { AudioField, VideoField } from "../../../fields/URLField"; import { TraceMobx } from "../../../fields/util"; -import { emptyFunction, numberRange, OmitKeys, returnFalse, returnOne, Utils } from "../../../Utils"; +import { emptyFunction, OmitKeys, returnFalse, returnOne } from "../../../Utils"; import { DocUtils } from "../../documents/Documents"; import { DocumentType } from "../../documents/DocumentTypes"; import { Networking } from "../../Network"; @@ -32,9 +29,6 @@ declare class MediaRecorder { constructor(e: any, options?: any); // whatever MediaRecorder has } -type ScreenshotDocument = makeInterface<[typeof documentSchema]>; -const ScreenshotDocument = makeInterface(documentSchema); - // interface VideoTileProps { // raised: { coord: Vector2, off: Vector3 }[]; // setRaised: (r: { coord: Vector2, off: Vector3 }[]) => void; @@ -112,7 +106,7 @@ const ScreenshotDocument = makeInterface(documentSchema); // } @observer -export class ScreenshotBox extends ViewBoxAnnotatableComponent(ScreenshotDocument) { +export class ScreenshotBox extends ViewBoxAnnotatableComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ScreenshotBox, fieldKey); } private _audioRec: any; private _videoRec: any; diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx index 183140cd7..366c3fc2f 100644 --- a/src/client/views/nodes/ScriptingBox.tsx +++ b/src/client/views/nodes/ScriptingBox.tsx @@ -1,18 +1,19 @@ import ReactTextareaAutocomplete from "@webscopeio/react-textarea-autocomplete"; import "@webscopeio/react-textarea-autocomplete/style.css"; -import { action, computed, observable, runInAction, trace } from "mobx"; +import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; import { Doc } from "../../../fields/Doc"; -import { documentSchema } from "../../../fields/documentSchemas"; import { List } from "../../../fields/List"; -import { createSchema, listSpec, makeInterface } from "../../../fields/Schema"; +import { listSpec } from "../../../fields/Schema"; import { ScriptField } from "../../../fields/ScriptField"; -import { Cast, NumCast, ScriptCast, StrCast, BoolCast } from "../../../fields/Types"; +import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types"; +import { TraceMobx } from "../../../fields/util"; import { returnEmptyString } from "../../../Utils"; import { DragManager } from "../../util/DragManager"; import { InteractionUtils } from "../../util/InteractionUtils"; -import { CompileScript, Scripting, ScriptParam } from "../../util/Scripting"; +import { CompileScript, ScriptParam } from "../../util/Scripting"; +import { ScriptingGlobals } from "../../util/ScriptingGlobals"; import { ScriptManager } from "../../util/ScriptManager"; import { ContextMenu } from "../ContextMenu"; import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from "../DocComponent"; @@ -21,15 +22,10 @@ import { FieldView, FieldViewProps } from "../nodes/FieldView"; import { OverlayView } from "../OverlayView"; import { DocumentIconContainer } from "./DocumentIcon"; import "./ScriptingBox.scss"; -import { TraceMobx } from "../../../fields/util"; const _global = (window /* browser */ || global /* node */) as any; -const ScriptingSchema = createSchema({}); -type ScriptingDocument = makeInterface<[typeof ScriptingSchema, typeof documentSchema]>; -const ScriptingDocument = makeInterface(ScriptingSchema, documentSchema); - @observer -export class ScriptingBox extends ViewBoxAnnotatableComponent(ScriptingDocument) { +export class ScriptingBox extends ViewBoxAnnotatableComponent() { private dropDisposer?: DragManager.DragDropDisposer; protected _multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer | undefined; @@ -42,9 +38,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent; } - renderFuncListElement(value: string) { - return
+ renderFuncListElement(value: string | object) { + return (typeof value !== "string") ? (null) :
{value}
diff --git a/src/client/views/nodes/SliderBox.tsx b/src/client/views/nodes/SliderBox.tsx index 92d1f7446..b96977f32 100644 --- a/src/client/views/nodes/SliderBox.tsx +++ b/src/client/views/nodes/SliderBox.tsx @@ -2,30 +2,19 @@ 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 '../../../fields/documentSchemas'; -import { createSchema, makeInterface } from '../../../fields/Schema'; import { NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; import { ViewBoxBaseComponent } from '../DocComponent'; import { ScriptBox } from '../ScriptBox'; +import { StyleProp } from '../StyleProvider'; import { FieldView, FieldViewProps } from './FieldView'; import { Handle, Tick, TooltipRail, Track } from './SliderBox-components'; import './SliderBox.scss'; -import { StyleProp } from '../StyleProvider'; - -const SliderSchema = createSchema({ - _sliderMin: "number", - _sliderMax: "number", - _sliderMinThumb: "number", - _sliderMaxThumb: "number", -}); -type SliderDocument = makeInterface<[typeof SliderSchema, typeof documentSchema]>; -const SliderDocument = makeInterface(SliderSchema, documentSchema); @observer -export class SliderBox extends ViewBoxBaseComponent(SliderDocument) { +export class SliderBox extends ViewBoxBaseComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(SliderBox, fieldKey); } get minThumbKey() { return this.fieldKey + "-minThumb"; } diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 9797178b2..913123cda 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -2,11 +2,10 @@ import React = require("react"); import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, untracked } from "mobx"; import { observer } from "mobx-react"; +import { basename } from "path"; import * as rp from 'request-promise'; import { Doc, DocListCast } from "../../../fields/Doc"; -import { documentSchema } from "../../../fields/documentSchemas"; import { InkTool } from "../../../fields/InkField"; -import { makeInterface } from "../../../fields/Schema"; import { Cast, NumCast, StrCast } from "../../../fields/Types"; import { AudioField, VideoField } from "../../../fields/URLField"; import { emptyFunction, formatTime, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, Utils } from "../../../Utils"; @@ -44,13 +43,8 @@ const path = require('path'); * Like images, users can zoom and pan and it has an overlay layer allowing for annotations on top of the video at different times */ - -type VideoDocument = makeInterface<[typeof documentSchema]>; -const VideoDocument = makeInterface(documentSchema); - - @observer -export class VideoBox extends ViewBoxAnnotatableComponent(VideoDocument) { +export class VideoBox extends ViewBoxAnnotatableComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(VideoBox, fieldKey); } static async convertDataUri(imageUri: string, returnedFilename: string) { try { @@ -129,7 +123,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent returnedFilename && this.createRealSummaryLink(returnedFilename, downX, downY)); } @@ -263,12 +258,12 @@ export class VideoBox extends ViewBoxAnnotatableComponent { const url = !imagePath.startsWith("/") ? Utils.CorsProxy(imagePath) : imagePath; - const width = this.layoutDoc._width || 1; - const height = this.layoutDoc._height || 0; + const width = NumCast(this.layoutDoc._width) || 1; + const height = NumCast(this.layoutDoc._height); const imageSummary = Docs.Create.ImageDocument(url, { _nativeWidth: Doc.NativeWidth(this.layoutDoc), _nativeHeight: Doc.NativeHeight(this.layoutDoc), - x: (this.layoutDoc.x || 0) + width, y: (this.layoutDoc.y || 0), _isLinkButton: true, - _width: 150, _height: height / width * 150, title: "--snapshot" + (this.layoutDoc._currentTimecode || 0) + " image-" + x: NumCast(this.layoutDoc.x) + width, y: NumCast(this.layoutDoc.y), _isLinkButton: true, + _width: 150, _height: height / width * 150, title: "--snapshot" + NumCast(this.layoutDoc._currentTimecode) + " image-" }); Doc.SetNativeWidth(Doc.GetProto(imageSummary), Doc.NativeWidth(this.layoutDoc)); Doc.SetNativeHeight(Doc.GetProto(imageSummary), Doc.NativeHeight(this.layoutDoc)); @@ -292,7 +287,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent this._fullScreen = vref.webkitDisplayingFullscreen); this._disposers.reactionDisposer?.(); - this._disposers.reactionDisposer = reaction(() => (this.layoutDoc._currentTimecode || 0), + this._disposers.reactionDisposer = reaction(() => NumCast(this.layoutDoc._currentTimecode), time => !this._playing && (vref.currentTime = time), { fireImmediately: true }); } } @@ -419,7 +414,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent { this._disposers.reactionDisposer?.(); this._disposers.youtubeReactionDisposer?.(); - this._disposers.reactionDisposer = reaction(() => this.layoutDoc._currentTimecode, () => !this._playing && this.Seek((this.layoutDoc._currentTimecode || 0))); + this._disposers.reactionDisposer = reaction(() => this.layoutDoc._currentTimecode, () => !this._playing && this.Seek(NumCast(this.layoutDoc._currentTimecode))); this._disposers.youtubeReactionDisposer = reaction( () => CurrentUserUtils.SelectedTool === InkTool.None && this.props.isSelected(true) && !SnappingManager.GetIsDragging() && !DocumentDecorations.Instance.Interacting, (interactive) => iframe.style.pointerEvents = interactive ? "all" : "none", { fireImmediately: true }); @@ -503,7 +498,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent Math.round((this.layoutDoc._currentTimecode || 0))); + const start = untracked(() => Math.round(NumCast(this.layoutDoc._currentTimecode))); return