From b235c94614141752c98d24a395682a02297d9e6a Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 13 Apr 2020 11:15:59 -0400 Subject: cleaned up rootSelected() to work with templates. adjusted nudge to favor moving documents over panning collection --- .../views/nodes/CollectionFreeFormDocumentView.tsx | 4 ++-- src/client/views/nodes/DocumentView.tsx | 16 +++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 3503af442..e7cb2c015 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -60,8 +60,8 @@ export class CollectionFreeFormDocumentView extends DocComponent { - this.layoutDoc.x = NumCast(this.layoutDoc.x) + x; - this.layoutDoc.y = NumCast(this.layoutDoc.y) + y; + this.props.Document.x = NumCast(this.props.Document.x) + x; + this.props.Document.y = NumCast(this.props.Document.y) + y; } contentScaling = () => this.nativeWidth > 0 && !this.props.fitToBox && !this.freezeDimensions ? this.width / this.nativeWidth : 1; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 3784c5c9c..cc3c39154 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -289,13 +289,15 @@ export class DocumentView extends DocComponent(Docu let preventDefault = true; this.props.Document.isBackground === undefined && this.props.bringToFront(this.props.Document); if (this._doubleTap && this.props.renderDepth && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click - const fullScreenAlias = Doc.MakeAlias(this.props.Document); - if (StrCast(fullScreenAlias.layoutKey) !== "layout_fullScreen" && fullScreenAlias.layout_fullScreen) { - fullScreenAlias.layoutKey = "layout_fullScreen"; + if (!(e.nativeEvent as any).formattedHandled) { + const fullScreenAlias = Doc.MakeAlias(this.props.Document); + if (StrCast(fullScreenAlias.layoutKey) !== "layout_fullScreen" && fullScreenAlias.layout_fullScreen) { + fullScreenAlias.layoutKey = "layout_fullScreen"; + } + UndoManager.RunInBatch(() => this.props.addDocTab(fullScreenAlias, "inTab"), "double tap"); + SelectionManager.DeselectAll(); + Doc.UnBrushDoc(this.props.Document); } - UndoManager.RunInBatch(() => this.props.addDocTab(fullScreenAlias, "inTab"), "double tap"); - SelectionManager.DeselectAll(); - Doc.UnBrushDoc(this.props.Document); } else if (this.onClickHandler?.script) { SelectionManager.DeselectAll(); const func = () => this.onClickHandler.script.run({ @@ -978,7 +980,7 @@ export class DocumentView extends DocComponent(Docu return typeof fallback === "string" ? fallback : "layout"; } rootSelected = (outsideReaction?: boolean) => { - return this.isSelected(outsideReaction) || (this.props.Document.forceActive && this.props.rootSelected?.(outsideReaction) ? true : false); + return this.isSelected(outsideReaction) || (this.rootDoc && this.props.rootSelected?.(outsideReaction)); } childScaling = () => (this.layoutDoc._fitWidth ? this.props.PanelWidth() / this.nativeWidth : this.props.ContentScaling()); panelWidth = () => this.props.PanelWidth(); -- cgit v1.2.3-70-g09d2 From 516e59e0ff68fc812ab46f431afd2ef733c8a093 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 13 Apr 2020 16:09:29 -0400 Subject: fixed some map api issues. fixed image box rotations. --- maps.env | 1 + package-lock.json | 49 +++++------------ package.json | 2 +- src/client/documents/Documents.ts | 12 +--- src/client/views/nodes/ImageBox.tsx | 23 +++----- .../authentication/models/current_user_utils.ts | 2 +- webpack.config.js | 64 +++++++++++----------- 7 files changed, 60 insertions(+), 93 deletions(-) create mode 100644 maps.env (limited to 'src/client/views/nodes') diff --git a/maps.env b/maps.env new file mode 100644 index 000000000..2b3b203e7 --- /dev/null +++ b/maps.env @@ -0,0 +1 @@ +DASH_GOOGLE_MAPS_API_KEY=AIzaSyAdJkThRhSivFE-O1I6RHSmRBWGstLY_sI \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f40dc7b0f..11eaaddd6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -764,7 +764,7 @@ }, "@types/passport": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.0.tgz", "integrity": "sha512-Pf39AYKf8q+YoONym3150cEwfUD66dtwHJWvbeOzKxnA0GZZ/vAXhNWv9vMhKyRQBQZiQyWQnhYBEBlKW6G8wg==", "requires": { "@types/express": "*" @@ -5629,8 +5629,7 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true, - "optional": true + "bundled": true }, "aproba": { "version": "1.2.0", @@ -5648,13 +5647,11 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true, - "optional": true + "bundled": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5667,18 +5664,15 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "concat-map": { "version": "0.0.1", - "bundled": true, - "optional": true + "bundled": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "core-util-is": { "version": "1.0.2", @@ -5781,8 +5775,7 @@ }, "inherits": { "version": "2.0.4", - "bundled": true, - "optional": true + "bundled": true }, "ini": { "version": "1.3.5", @@ -5792,7 +5785,6 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5805,20 +5797,17 @@ "minimatch": { "version": "3.0.4", "bundled": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true, - "optional": true + "bundled": true }, "minipass": { "version": "2.9.0", "bundled": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5835,7 +5824,6 @@ "mkdirp": { "version": "0.5.1", "bundled": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -5916,8 +5904,7 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, - "optional": true + "bundled": true }, "object-assign": { "version": "4.1.1", @@ -5927,7 +5914,6 @@ "once": { "version": "1.4.0", "bundled": true, - "optional": true, "requires": { "wrappy": "1" } @@ -6003,8 +5989,7 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true, - "optional": true + "bundled": true }, "safer-buffer": { "version": "2.1.2", @@ -6034,7 +6019,6 @@ "string-width": { "version": "1.0.2", "bundled": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6052,7 +6036,6 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -6091,13 +6074,11 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, - "optional": true + "bundled": true }, "yallist": { "version": "3.1.1", - "bundled": true, - "optional": true + "bundled": true } } }, @@ -14414,7 +14395,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { "core-util-is": "~1.0.0", @@ -16028,7 +16009,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -18341,7 +18322,7 @@ }, "wrap-ansi": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "requires": { "string-width": "^1.0.1", diff --git a/package.json b/package.json index c742857ad..cc33e1b0b 100644 --- a/package.json +++ b/package.json @@ -260,4 +260,4 @@ "xoauth2": "^1.2.0", "youtube": "^0.1.0" } -} \ No newline at end of file +} diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 43e379125..3f46c4013 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -51,6 +51,7 @@ import { LinkBox } from "../views/nodes/LinkBox"; import { ScreenshotBox } from "../views/nodes/ScreenshotBox"; import CollectionMapView from "../views/collections/CollectionMapView"; import LocationField, { LocationData } from "../../new_fields/LocationField"; +import { action } from "mobx"; const requestImageSize = require('../util/request-image-size'); const path = require('path'); @@ -496,17 +497,6 @@ export namespace Docs { const extension = path.extname(target); target = `${target.substring(0, target.length - extension.length)}_o${extension}`; } - requestImageSize(Utils.CorsProxy(target)) - .then((size: any) => { - const aspect = size.height / size.width; - if (!inst._nativeWidth) { - inst._nativeWidth = size.width; - } - inst._nativeHeight = NumCast(inst._nativeWidth) * aspect; - inst._height = NumCast(inst._width) * aspect; - }) - .catch((err: any) => console.log(err)); - // } return inst; } export function PresDocument(initial: List = new List(), options: DocumentOptions = {}) { diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index de1640027..815a3f7b2 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -257,18 +257,16 @@ export class ImageBox extends ViewBoxAnnotatableComponent 0.05) { if (!this.layoutDoc.isTemplateDoc || this.dataDoc !== this.layoutDoc) { - requestImageSize(imgPath).then((inquiredSize: any) => { + requestImageSize(imgPath).then(action((inquiredSize: any) => { const rotation = NumCast(this.dataDoc[this.fieldKey + "-rotation"]) % 180; const rotatedNativeSize = rotation === 90 || rotation === 270 ? { height: inquiredSize.width, width: inquiredSize.height } : inquiredSize; const rotatedAspect = rotatedNativeSize.height / rotatedNativeSize.width; - setTimeout(action(() => { - if (this.layoutDoc[WidthSym]() && (!cachedNativeSize.width || !cachedNativeSize.height || Math.abs(1 - docAspect / rotatedAspect) > 0.1)) { - this.layoutDoc._height = this.layoutDoc[WidthSym]() * rotatedAspect; - this.dataDoc[this.fieldKey + "-nativeWidth"] = this.layoutDoc._nativeWidth = rotatedNativeSize.width; - this.dataDoc[this.fieldKey + "-nativeHeight"] = this.layoutDoc._nativeHeight = rotatedNativeSize.height; - } - }), 0); - }).catch((err: any) => console.log(err)); + if (this.layoutDoc[WidthSym]() && (!cachedNativeSize.width || !cachedNativeSize.height || Math.abs(1 - docAspect / rotatedAspect) > 0.1)) { + this.layoutDoc._height = this.layoutDoc[WidthSym]() * rotatedAspect; + this.dataDoc[this.fieldKey + "-nativeWidth"] = this.layoutDoc._nativeWidth = this.layoutDoc._width; + this.dataDoc[this.fieldKey + "-nativeHeight"] = this.layoutDoc._nativeHeight = this.layoutDoc._height; + } + })).catch(console.log); } else if (Math.abs(1 - docAspect / cachedAspect) > 0.1) { this.layoutDoc._width = this.layoutDoc[WidthSym]() || cachedNativeSize.width; this.layoutDoc._height = this.layoutDoc[WidthSym]() * cachedAspect; @@ -388,17 +386,14 @@ export class ImageBox extends ViewBoxAnnotatableComponent
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index 5408440e7..5e806d2d2 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -73,7 +73,7 @@ export class CurrentUserUtils { { title: "collection", icon: "folder", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: emptyCollection }, { title: "preview", icon: "expand", ignoreClick: true, drag: 'Docs.Create.DocumentDocument(ComputedField.MakeFunction("selectedDocs(this,this.excludeCollections,[_last_])?.[0]"), { _width: 250, _height: 250, title: "container" })' }, { title: "web page", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.WebDocument("https://en.wikipedia.org/wiki/Hedgehog", {_width: 300, _height: 300, title: "New Webpage" })' }, - { title: "cat image", icon: "cat", ignoreClick: true, drag: 'Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { _width: 200, title: "an image of a cat" })' }, + { title: "cat image", icon: "cat", ignoreClick: true, drag: 'Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { _width: 250, _nativeWidth:250, title: "an image of a cat" })' }, { title: "screenshot", icon: "photo-video", ignoreClick: true, drag: 'Docs.Create.ScreenshotDocument("", { _width: 400, _height: 200, title: "screen snapshot" })' }, { title: "webcam", icon: "video", ignoreClick: true, drag: 'Docs.Create.WebCamDocument("", { _width: 400, _height: 400, title: "a test cam" })' }, { title: "record", icon: "microphone", ignoreClick: true, drag: `Docs.Create.AudioDocument("${nullAudio}", { _width: 200, title: "ready to record audio" })` }, diff --git a/webpack.config.js b/webpack.config.js index 6265883fd..1027f29a6 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -20,7 +20,7 @@ const dotenv = require('dotenv'); function transferEnvironmentVariables() { const prefix = "_CLIENT_"; - const env = dotenv.config().parsed; + const env = dotenv.config({ debug: true }).parsed; if (env) { plugins.push(new webpack.DefinePlugin(Object.keys(env).reduce((mapping, envKey) => { if (envKey.startsWith(prefix)) { @@ -64,42 +64,42 @@ module.exports = { }, module: { rules: [{ - test: [/\.tsx?$/], - use: [{ - loader: 'ts-loader', - options: { - transpileOnly: true - } - }] + test: [/\.tsx?$/], + use: [{ + loader: 'ts-loader', + options: { + transpileOnly: true + } + }] + }, + { + test: /\.scss|css$/, + use: [{ + loader: "style-loader" }, { - test: /\.scss|css$/, - use: [{ - loader: "style-loader" - }, - { - loader: "css-loader" - }, - { - loader: "sass-loader" - } - ] + loader: "css-loader" }, { - test: /\.(jpg|png|pdf)$/, - use: [{ - loader: 'file-loader' - }] - }, - { - test: /\.(png|jpg|gif)$/i, - use: [{ - loader: 'url-loader', - options: { - limit: 8192 - } - }] + loader: "sass-loader" } + ] + }, + { + test: /\.(jpg|png|pdf)$/, + use: [{ + loader: 'file-loader' + }] + }, + { + test: /\.(png|jpg|gif)$/i, + use: [{ + loader: 'url-loader', + options: { + limit: 8192 + } + }] + } ] }, plugins, -- cgit v1.2.3-70-g09d2 From 130e26103461f23a2d8b57ea2eef6b17eefb8f8e Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 13 Apr 2020 21:46:20 -0400 Subject: updated childDetailedView stuff for pivot view --- src/client/views/TemplateMenu.tsx | 4 ++-- src/client/views/collections/CollectionTimeView.tsx | 10 ++++++---- src/client/views/collections/CollectionTreeView.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 4 ++-- src/client/views/collections/CollectionViewChromes.tsx | 4 ++-- src/client/views/nodes/DocumentView.tsx | 8 ++++---- src/new_fields/Doc.ts | 8 -------- src/new_fields/documentSchemas.ts | 2 +- 8 files changed, 18 insertions(+), 24 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 4d7f1e443..b76137f06 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -167,8 +167,8 @@ export class TemplateMenu extends React.Component { } } -Scripting.addGlobal(function switchView(doc: Doc, template: Doc) { - if (template.dragFactory) { +Scripting.addGlobal(function switchView(doc: Doc, template: Doc | undefined) { + if (template?.dragFactory) { template = Cast(template.dragFactory, Doc, null); } const templateTitle = StrCast(template?.title); diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index 53de2fbbe..31b720b81 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -5,7 +5,7 @@ import { List } from "../../../new_fields/List"; import { ObjectField } from "../../../new_fields/ObjectField"; import { RichTextField } from "../../../new_fields/RichTextField"; import { ComputedField, ScriptField } from "../../../new_fields/ScriptField"; -import { NumCast, StrCast, BoolCast } from "../../../new_fields/Types"; +import { NumCast, StrCast, BoolCast, Cast } from "../../../new_fields/Types"; import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../../Utils"; import { Scripting } from "../../util/Scripting"; import { ContextMenu } from "../ContextMenu"; @@ -19,6 +19,7 @@ const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; import React = require("react"); +import { DocumentView } from "../nodes/DocumentView"; @observer export class CollectionTimeView extends CollectionSubView(doc => doc) { @@ -28,14 +29,15 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) { componentWillUnmount() { this.props.Document.onChildClick = undefined; } - componentDidMount() { - const childDetailed = this.props.Document.childDetailed; // bcz: needs to be here to make sure the childDetailed layout template has been loaded when the first item is clicked; - const childText = "const alias = getAlias(this); Doc.ApplyTemplateTo(thisContainer.childDetailed, alias, 'layout_detailView'); alias.layoutKey='layout_detailedView'; alias.dropAction='alias'; alias.removeDropProperties=new List(['dropAction']); useRightSplit(alias, shiftKey); "; + async componentDidMount() { + const childText = "const alias = getAlias(this); switchView(alias, thisContainer.childDetailView); alias.dropAction='alias'; alias.removeDropProperties=new List(['dropAction']); useRightSplit(alias, shiftKey); "; this.props.Document.onChildClick = ScriptField.MakeScript(childText, { this: Doc.name, heading: "string", thisContainer: Doc.name, shiftKey: "boolean" }); this.props.Document._fitToBox = true; if (!this.props.Document.onViewDefClick) { this.props.Document.onViewDefDivClick = ScriptField.MakeScript("pivotColumnClick(this,payload)", { payload: "any" }); } + this.props.Document.childDetailView = Cast(this.props.Document.childDetailView, Doc, null) ||// bcz: needs to be here to make sure the childDetailView layout template has been loaded when the first item is clicked; + DocumentView.findTemplate("detailView", StrCast(this.props.Document.type), ""); } layoutEngine = () => this._layoutEngine; diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 23fb259fc..b96ee4bc4 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -754,7 +754,7 @@ export class CollectionTreeView extends CollectionSubView(Document, undefined as })); Document.childLayout = heroView; - Document.childDetailed = detailView; + Document.childDetailView = detailView; Document._viewType = CollectionViewType.Time; Document._forceActive = true; Document._pivotField = "company"; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 8cc5146d5..f94277862 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -232,8 +232,8 @@ export class CollectionView extends Touchable { if (this.props.Document.childLayout instanceof Doc) { layoutItems.push({ description: "View Child Layout", event: () => this.props.addDocTab(this.props.Document.childLayout as Doc, "onRight"), icon: "project-diagram" }); } - if (this.props.Document.childDetailed instanceof Doc) { - layoutItems.push({ description: "View Child Detailed Layout", event: () => this.props.addDocTab(this.props.Document.childDetailed as Doc, "onRight"), icon: "project-diagram" }); + if (this.props.Document.childDetailView instanceof Doc) { + layoutItems.push({ description: "View Child Detailed Layout", event: () => this.props.addDocTab(this.props.Document.childDetailView as Doc, "onRight"), icon: "project-diagram" }); } layoutItems.push({ description: `${this.props.Document.isInPlaceContainer ? "Unset" : "Set"} inPlace Container`, event: () => this.props.Document.isInPlaceContainer = !this.props.Document.isInPlaceContainer, icon: "project-diagram" }); diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index ba95dce00..e494c337a 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -48,8 +48,8 @@ export class CollectionViewBaseChrome extends React.Component click item view", - script: "this.target.childDetailed = getDocTemplate(this.source?.[0])", - immediate: (source: Doc[]) => this.target.childDetailed = Doc.getDocTemplate(source?.[0]), + script: "this.target.childDetailView = getDocTemplate(this.source?.[0])", + immediate: (source: Doc[]) => this.target.childDetailView = Doc.getDocTemplate(source?.[0]), initialize: emptyFunction, }; _contentCommand = { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index cc3c39154..5b6478e66 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -541,7 +541,7 @@ export class DocumentView extends DocComponent(Docu deleteClicked = (): void => { SelectionManager.DeselectAll(); this.props.removeDocument?.(this.props.Document); } // applies a custom template to a document. the template is identified by it's short name (e.g, slideView not layout_slideView) - static makeCustomViewClicked = (doc: Doc, creator: (documents: Array, options: DocumentOptions, id?: string) => Doc, templateSignature: string = "custom", docLayoutTemplate?: Doc) => { + static makeCustomViewClicked = (doc: Doc, creator: Opt<(documents: Array, options: DocumentOptions, id?: string) => Doc>, templateSignature: string = "custom", docLayoutTemplate?: Doc) => { const batch = UndoManager.StartBatch("makeCustomViewClicked"); runInAction(() => { doc.layoutKey = "layout_" + templateSignature; @@ -563,7 +563,7 @@ export class DocumentView extends DocComponent(Docu !docLayoutTemplate && allTemplates.forEach(tempDoc => StrCast(tempDoc.title) === templateName && (docLayoutTemplate = tempDoc)); return docLayoutTemplate; } - static createCustomView = (doc: Doc, creator: (documents: Array, options: DocumentOptions, id?: string) => Doc, templateSignature: string = "custom", docLayoutTemplate?: Doc) => { + static createCustomView = (doc: Doc, creator: Opt<(documents: Array, options: DocumentOptions, id?: string) => Doc>, templateSignature: string = "custom", docLayoutTemplate?: Doc) => { const templateName = templateSignature.replace(/\(.*\)/, ""); docLayoutTemplate = docLayoutTemplate || DocumentView.findTemplate(templateName, StrCast(doc.type), templateSignature); @@ -584,10 +584,10 @@ export class DocumentView extends DocComponent(Docu } else if (doc.data instanceof ImageField) { fieldTemplate = Docs.Create.ImageDocument("http://www.cs.brown.edu", options); } - const docTemplate = docLayoutTemplate || creator(fieldTemplate ? [fieldTemplate] : [], { title: customName + "(" + doc.title + ")", isTemplateDoc: true, _width: _width + 20, _height: Math.max(100, _height + 45) }); + const docTemplate = docLayoutTemplate || creator?.(fieldTemplate ? [fieldTemplate] : [], { title: customName + "(" + doc.title + ")", isTemplateDoc: true, _width: _width + 20, _height: Math.max(100, _height + 45) }); fieldTemplate && Doc.MakeMetadataFieldTemplate(fieldTemplate, Doc.GetProto(docTemplate)); - Doc.ApplyTemplateTo(docTemplate, doc, customName, undefined); + docTemplate && Doc.ApplyTemplateTo(docTemplate, doc, customName, undefined); } @undoBatch diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 92abb7a71..bcf0d1aec 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -603,14 +603,6 @@ export namespace Doc { return undefined; } export function ApplyTemplateTo(templateDoc: Doc, target: Doc, targetKey: string, titleTarget: string | undefined) { - if (!templateDoc) { - target.layout = undefined; - target._nativeWidth = undefined; - target._nativeHeight = undefined; - target.type = undefined; - return; - } - if (!Doc.AreProtosEqual(target[targetKey] as Doc, templateDoc)) { if (target.resolvedDataDoc) { target[targetKey] = new PrefetchProxy(templateDoc); diff --git a/src/new_fields/documentSchemas.ts b/src/new_fields/documentSchemas.ts index b11941f40..bc63e9df8 100644 --- a/src/new_fields/documentSchemas.ts +++ b/src/new_fields/documentSchemas.ts @@ -74,7 +74,7 @@ export const positionSchema = createSchema({ export const collectionSchema = createSchema({ childLayout: Doc, // layout template for children of a collecion - childDetailed: Doc, // layout template to apply to a child when its clicked on in a collection and opened (requires onChildClick or other script to use this field) + childDetailView: Doc, // layout template to apply to a child when its clicked on in a collection and opened (requires onChildClick or other script to use this field) onChildClick: ScriptField, // script to run for each child when its clicked onCheckedClick: ScriptField, // script to run when a checkbox is clicked next to a child in a tree view }); -- cgit v1.2.3-70-g09d2 From dc985718e92f79290ee0609f6ac247829e46e86a Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 13 Apr 2020 21:50:00 -0400 Subject: switched labelBox to use onClick- prefix instead of fieldKey. switched to paramsDoc instead of dataDoc to better work with templates --- src/client/views/nodes/LabelBox.tsx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index 9b063e2aa..391e359cc 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -36,12 +36,13 @@ export class LabelBox extends ViewBoxBaseComponent { const funcs: ContextMenuProps[] = []; funcs.push({ description: "Clear Script Params", event: () => { - const params = Cast(this.dataDoc[this.fieldKey + "-paramFieldKeys"], listSpec("string"), []); - params?.map(p => this.dataDoc[p] = undefined); + const params = Cast(this.paramsDoc["onClick-paramFieldKeys"], listSpec("string"), []); + params?.map(p => this.paramsDoc[p] = undefined); }, icon: "trash" }); @@ -52,19 +53,19 @@ export class LabelBox extends ViewBoxBaseComponent { const docDragData = de.complete.docDragData; - const params = Cast(this.dataDoc[this.fieldKey + "-paramFieldKeys"], listSpec("string"), []); - const missingParams = params?.filter(p => this.dataDoc[p] === undefined); + const params = Cast(this.paramsDoc["onClick-paramFieldKeys"], listSpec("string"), []); + const missingParams = params?.filter(p => !this.paramsDoc[p]); if (docDragData && missingParams?.includes((e.target as any).textContent)) { - this.dataDoc[(e.target as any).textContent] = new List(docDragData.droppedDocuments.map((d, i) => + this.paramsDoc[(e.target as any).textContent] = new List(docDragData.droppedDocuments.map((d, i) => d.onDragStart ? docDragData.draggedDocuments[i] : d)); e.stopPropagation(); } } // (!missingParams || !missingParams.length ? "" : "(" + missingParams.map(m => m + ":").join(" ") + ")") render() { - const params = Cast(this.dataDoc[this.fieldKey + "-paramFieldKeys"], listSpec("string"), []); - const missingParams = params?.filter(p => this.dataDoc[p] === undefined); - params?.map(p => DocListCast(this.dataDoc[p])); // bcz: really hacky form of prefetching ... + const params = Cast(this.paramsDoc["onClick-paramFieldKeys"], listSpec("string"), []); + const missingParams = params?.filter(p => !this.paramsDoc[p]); + params?.map(p => DocListCast(this.paramsDoc[p])); // bcz: really hacky form of prefetching ... return (
-- cgit v1.2.3-70-g09d2 From 26893de4b384678041523a0bbf71f895ad1cd2b7 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Apr 2020 10:50:15 -0400 Subject: added map undo batches. fixed marker flicker on drag. split up code. --- src/client/views/collections/CollectionMapView.tsx | 111 ++++++++++----------- src/client/views/nodes/DocumentView.tsx | 2 +- 2 files changed, 55 insertions(+), 58 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/collections/CollectionMapView.tsx b/src/client/views/collections/CollectionMapView.tsx index 5d0b0c982..fced52275 100644 --- a/src/client/views/collections/CollectionMapView.tsx +++ b/src/client/views/collections/CollectionMapView.tsx @@ -10,8 +10,8 @@ import "./CollectionMapView.scss"; import { CollectionSubView } from "./CollectionSubView"; import React = require("react"); import { DocumentManager } from "../../util/DocumentManager"; -import { UndoManager } from "../../util/UndoManager"; -import { IReactionDisposer, reaction, action } from "mobx"; +import { UndoManager, undoBatch } from "../../util/UndoManager"; +import { IReactionDisposer, reaction, action, computed } from "mobx"; import requestPromise = require("request-promise"); type MapSchema = makeInterface<[typeof documentSchema]>; @@ -28,7 +28,13 @@ const base = "https://maps.googleapis.com/maps/api/geocode/json?"; @observer class CollectionMapView extends CollectionSubView & { google: any }>(MapSchema) { - private mapRef = React.createRef(); + // private mapRef = React.createRef(); + // private get map() { + // return (this.mapRef.current as any).map; + // } + + private _cancelAddrReq = new Map(); + private _cancelLocReq = new Map(); private addressUpdaters: IReactionDisposer[] = []; private latlngUpdaters: IReactionDisposer[] = []; @@ -42,62 +48,62 @@ class CollectionMapView extends CollectionSubView & return undefined; } - renderMarker(layout: Doc, icon: Opt) { + markerClick = action(async (layout: Doc, location: LocationData) => { + //this.map.panTo(location); + const batch = UndoManager.StartBatch("marker click"); + this.layoutDoc[this.props.fieldKey + "-mapCenter-lat"] = location.lat; + this.layoutDoc[this.props.fieldKey + "-mapCenter-lng"] = location.lng; + location.zoom && (this.layoutDoc[this.props.fieldKey + "-mapCenter-zoom"] = location.zoom); + if (layout.isLinkButton && DocListCast(layout.links).length) { + await DocumentManager.Instance.FollowLink(undefined, layout, (doc: Doc, where: string, finished?: () => void) => { + this.props.addDocTab(doc, where); + finished?.(); + }, false, this.props.ContainingCollectionDoc, batch.end, undefined); + } else { + ScriptCast(layout.onClick)?.script.run({ this: layout, self: Cast(layout.rootDocument, Doc, null) || layout }); + batch.end(); + } + }); + + renderMarkerIcon(layout: Doc) { + const iconUrl = StrCast(this.props.Document.mapIconUrl, null); + if (iconUrl) { + const iconWidth = NumCast(layout["mapLocation-iconWidth"], 45); + const iconHeight = NumCast(layout["mapLocation-iconHeight"], 45); + const iconSize = new google.maps.Size(iconWidth, iconHeight); + return { + size: iconSize, + scaledSize: iconSize, + url: iconUrl + }; + } + } + renderMarker(layout: Doc) { const location = this.getLocation(layout, "mapLocation"); return !location ? (null) : { - this.map.panTo(location); - this.layoutDoc[this.props.fieldKey + "-mapCenter-lat"] = location.lat; - this.layoutDoc[this.props.fieldKey + "-mapCenter-lng"] = location.lng; - location.zoom && (this.layoutDoc[this.props.fieldKey + "-mapCenter-zoom"] = location.zoom); - if (layout.isLinkButton && DocListCast(layout.links).length) { - const batch = UndoManager.StartBatch("follow link click"); - await DocumentManager.Instance.FollowLink(undefined, layout, (doc: Doc, where: string, finished?: () => void) => { - this.props.addDocTab(doc, where); - finished?.(); - }, false, this.props.ContainingCollectionDoc, batch.end, undefined); - } else { - ScriptCast(layout.onClick)?.script.run({ this: layout, self: Cast(layout.rootDocument, Doc, null) || layout }); - } - }} - icon={icon} + position={location} + onClick={() => this.markerClick(layout, location)} + icon={this.renderMarkerIcon(layout)} />; } - _cancelAddrReq = new Map(); - _cancelLocReq = new Map(); - private get contents() { + @computed get contents() { this.addressUpdaters.forEach(disposer => disposer()); this.addressUpdaters = []; this.latlngUpdaters.forEach(disposer => disposer()); this.latlngUpdaters = []; - return this.childLayoutPairs.map(({ layout, data }) => { - let icon: Opt, iconUrl: Opt; - if ((iconUrl = StrCast(this.props.Document.mapIconUrl, null))) { - const iconWidth = NumCast(layout["mapLocation-iconWidth"], 45); - const iconHeight = NumCast(layout["mapLocation-iconHeight"], 45); - const iconSize = new google.maps.Size(iconWidth, iconHeight); - icon = { - size: iconSize, - scaledSize: iconSize, - url: iconUrl - }; - } + return this.childLayoutPairs.map(({ layout }) => { this.addressUpdaters.push(reaction( - () => ({ - lat: NumCast(layout["mapLocation-lat"]), - lng: NumCast(layout["mapLocation-lng"]) - }), + () => ({ lat: layout["mapLocation-lat"], lng: layout["mapLocation-lng"] }), ({ lat, lng }) => { if (this._cancelLocReq.get(layout[Id])) { this._cancelLocReq.set(layout[Id], false); } else if (lat !== undefined && lng !== undefined) { - const target = `${base}latlng=${lat},${lng}&key=${process.env.GOOGLE_MAPS_GEO!}`; + const target = `${base}latlng=${NumCast(lat)},${NumCast(lng)}&key=${process.env.GOOGLE_MAPS_GEO!}`; requestPromise.get(target).then(res => { const formatted_address = JSON.parse(res).results[0].formatted_address || ""; if (formatted_address !== layout["mapLocation-address"]) { @@ -132,14 +138,9 @@ class CollectionMapView extends CollectionSubView & } } )); - return this.renderMarker(layout, icon); + return this.renderMarker(layout); }); } - - private get map() { - return (this.mapRef.current as any).map; - } - render() { const { childLayoutPairs } = this; const { Document } = this.props; @@ -156,16 +157,15 @@ class CollectionMapView extends CollectionSubView & onWheel={e => e.stopPropagation()} onPointerDown={e => (e.button === 0 && !e.ctrlKey) && e.stopPropagation()} > { - const { center } = this.map; - Document[this.props.fieldKey + "-mapCenter-lat"] = center.lat(); - Document[this.props.fieldKey + "-mapCenter-lng"] = center.lng(); - }} + onDragend={undoBatch(action((e: any, map: any) => { + Document[this.props.fieldKey + "-mapCenter-lat"] = map.center.lat(); + Document[this.props.fieldKey + "-mapCenter-lng"] = map.center.lng(); + }))} > {this.contents} @@ -174,8 +174,5 @@ class CollectionMapView extends CollectionSubView & } -const LoadingContainer = () => { - return
; -}; - +const LoadingContainer = () =>
; export default GoogleApiWrapper({ apiKey: process.env.GOOGLE_MAPS!, LoadingContainer })(CollectionMapView) as any; \ No newline at end of file diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 5b6478e66..0ef7ece9c 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -586,7 +586,7 @@ export class DocumentView extends DocComponent(Docu } const docTemplate = docLayoutTemplate || creator?.(fieldTemplate ? [fieldTemplate] : [], { title: customName + "(" + doc.title + ")", isTemplateDoc: true, _width: _width + 20, _height: Math.max(100, _height + 45) }); - fieldTemplate && Doc.MakeMetadataFieldTemplate(fieldTemplate, Doc.GetProto(docTemplate)); + fieldTemplate && Doc.MakeMetadataFieldTemplate(fieldTemplate, docTemplate ? Doc.GetProto(docTemplate) : docTemplate); docTemplate && Doc.ApplyTemplateTo(docTemplate, doc, customName, undefined); } -- cgit v1.2.3-70-g09d2 From 1745feaae5fbf5d794c8d692bd3f6b8eacd3d7fc Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Apr 2020 19:01:58 -0400 Subject: fixed editing button click scripts --- src/client/views/nodes/DocumentView.tsx | 10 ++++++---- src/client/views/nodes/ScriptingBox.tsx | 5 +++-- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 0ef7ece9c..cb7811fbb 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -298,7 +298,7 @@ export class DocumentView extends DocComponent(Docu SelectionManager.DeselectAll(); Doc.UnBrushDoc(this.props.Document); } - } else if (this.onClickHandler?.script) { + } else if (this.onClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself SelectionManager.DeselectAll(); const func = () => this.onClickHandler.script.run({ this: this.layoutDoc, @@ -308,8 +308,9 @@ export class DocumentView extends DocComponent(Docu if (this.props.Document !== Doc.UserDoc().undoBtn && this.props.Document !== Doc.UserDoc().redoBtn) { UndoManager.RunInBatch(func, "on click"); } else func(); - } else if (this.Document["onClick-rawScript"]) { - UndoManager.RunInBatch(() => ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", e.clientX, e.clientY), "on button click"); + } else if (this.Document["onClick-rawScript"] && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) {// bcz: hack? don't edit a script if you're clicking on a scripting box itself + UndoManager.RunInBatch(() => DocumentView.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"); + //ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", e.clientX, e.clientY), "on button click"); } else if (this.Document.isLinkButton) { DocListCast(this.props.Document.links).length && this.followLinkClick(e.altKey, e.ctrlKey, e.shiftKey); } else { @@ -556,7 +557,8 @@ export class DocumentView extends DocComponent(Docu const iconViews = DocListCast(Cast(Doc.UserDoc().iconViews, Doc, null)?.data); const templBtns = DocListCast(Cast(Doc.UserDoc().templateButtons, Doc, null)?.data); const noteTypes = DocListCast(Cast(Doc.UserDoc().noteTypes, Doc, null)?.data); - const allTemplates = iconViews.concat(templBtns).concat(noteTypes).map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc); + const clickFuncs = DocListCast(Cast(Doc.UserDoc().clickFuncs, Doc, null)?.data); + const allTemplates = iconViews.concat(templBtns).concat(noteTypes).concat(clickFuncs).map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc); // bcz: this is hacky -- want to have different templates be applied depending on the "type" of a document. but type is not reliable and there could be other types of template searches so this should be generalized // first try to find a template that matches the specific document type (_). otherwise, fallback to a general match on !docLayoutTemplate && allTemplates.forEach(tempDoc => StrCast(tempDoc.title) === type + "_" + templateName && (docLayoutTemplate = tempDoc)); diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx index 8a1d270b3..a257898ab 100644 --- a/src/client/views/nodes/ScriptingBox.tsx +++ b/src/client/views/nodes/ScriptingBox.tsx @@ -75,9 +75,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent; return (
this.props.isSelected(true) && e.stopPropagation()} onWheel={e => this.props.isSelected(true) && e.stopPropagation()}> -
+
this.props.isSelected(true) && e.stopPropagation()} >