From 2c04b0ae3689d931675151acbec24c88ea00daa1 Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Sat, 4 Jul 2020 02:01:32 +0800 Subject: transition speed + viewLinks --- src/client/views/collections/CollectionStackingView.tsx | 2 +- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 7bdf5e7df..8bd32b81f 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -184,7 +184,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) if (found) { const top = found.getBoundingClientRect().top; const localTop = this.props.ScreenToLocalTransform().transformPoint(0, top); - smoothScroll(500, this._mainCont!, localTop[1] + this._mainCont!.scrollTop); + smoothScroll(doc.presTransition ? Number(doc.presTransition) : 500, this._mainCont!, localTop[1] + this._mainCont!.scrollTop); } afterFocus && setTimeout(() => { if (afterFocus?.()) { } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 546a4307c..e2d4d4459 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -910,7 +910,8 @@ export class CollectionFreeFormView extends CollectionSubView Date: Wed, 15 Jul 2020 22:04:59 +0800 Subject: added progressivize features --- package-lock.json | 13 ++ package.json | 4 +- .../collectionFreeForm/CollectionFreeFormView.scss | 40 ++++- .../collectionFreeForm/CollectionFreeFormView.tsx | 40 ++++- .../views/nodes/CollectionFreeFormDocumentView.tsx | 9 +- src/client/views/nodes/PresBox.scss | 142 ++++++++++------ src/client/views/nodes/PresBox.tsx | 185 +++++++++++++++++---- .../views/presentationview/PresElementBox.tsx | 3 +- 8 files changed, 344 insertions(+), 92 deletions(-) (limited to 'src/client/views/collections') diff --git a/package-lock.json b/package-lock.json index ad181758c..1e8359fbf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14335,6 +14335,14 @@ "react-draggable": "^4.0.3" } }, + "react-reveal": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/react-reveal/-/react-reveal-1.2.2.tgz", + "integrity": "sha512-JCv3fAoU6Z+Lcd8U48bwzm4pMZ79qsedSXYwpwt6lJNtj/v5nKJYZZbw3yhaQPPgYePo3Y0NOCoYOq/jcsisuw==", + "requires": { + "prop-types": "^15.5.10" + } + }, "react-select": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/react-select/-/react-select-3.1.0.tgz", @@ -14800,6 +14808,11 @@ "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", "dev": true }, + "reveal.js": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/reveal.js/-/reveal.js-4.0.2.tgz", + "integrity": "sha512-LWZSUenufF1gpD7npxJ7KfoQQFKgc1D6XrLTFgKlwWNP1BQ74hT48KONFWMAw+8R/QUeaScCLCLrBVHDfFIEiw==" + }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", diff --git a/package.json b/package.json index 89af3b0b5..745f7d947 100644 --- a/package.json +++ b/package.json @@ -222,11 +222,13 @@ "react-jsx-parser": "^1.25.1", "react-measure": "^2.2.4", "react-resizable": "^1.10.1", + "react-reveal": "^1.2.2", "react-select": "^3.1.0", "react-table": "^6.11.5", "readline": "^1.3.0", "request": "^2.88.0", "request-promise": "^4.2.5", + "reveal.js": "^4.0.2", "rimraf": "^3.0.0", "serializr": "^1.5.4", "sharp": "^0.23.4", @@ -248,4 +250,4 @@ "xoauth2": "^1.2.0", "xregexp": "^4.3.0" } -} \ No newline at end of file +} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss index 92aee3776..fad90ca32 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss @@ -13,16 +13,54 @@ } .collectionfreeformview-viewdef { - > .collectionFreeFormDocumentView-container { + >.collectionFreeFormDocumentView-container { pointer-events: none; + .contentFittingDocumentDocumentView-previewDoc { pointer-events: all; } } + + svg.presPaths { + position: absolute; + z-index: 100000; + overflow: visible; + } + + svg.presPaths-hidden { + display: none; + } } .collectionfreeformview-none { touch-action: none; + + svg.presPaths { + position: absolute; + z-index: 100000; + overflow: visible; + } + + svg.presPaths-hidden { + display: none; + } +} + +.progressivizeButton { + position: absolute; + display: flex; + transform: translate(-105%, 0); + align-items: center; + border: black solid 1px; + border-radius: 3px; + justify-content: center; + width: 30; + height: 20; + background-color: #c8c8c8; +} + +.progressivizeButton:hover { + background-color: #aedef8; } .collectionFreeform-customText { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 98be2dc03..ded410a9c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,7 +1,7 @@ import { library } from "@fortawesome/fontawesome-svg-core"; import { faEye } from "@fortawesome/free-regular-svg-icons"; import { faBraille, faChalkboard, faCompass, faCompressArrowsAlt, faExpandArrowsAlt, faFileUpload, faPaintBrush, faTable, faUpload } from "@fortawesome/free-solid-svg-icons"; -import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx"; +import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, trace } from "mobx"; import { observer } from "mobx-react"; import { computedFn } from "mobx-utils"; import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../../fields/Doc"; @@ -46,6 +46,7 @@ import "./CollectionFreeFormView.scss"; import MarqueeOptionsMenu from "./MarqueeOptionsMenu"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); +import { PresBox } from "../../nodes/PresBox"; library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload); @@ -1350,6 +1351,8 @@ export class CollectionFreeFormView extends CollectionSubView @@ -1432,11 +1435,44 @@ interface CollectionFreeFormViewPannableContentsProps { viewDefDivClick?: ScriptField; children: () => JSX.Element[]; transition?: string; + presPaths?: boolean; + progressivize?: boolean; } @observer class CollectionFreeFormViewPannableContents extends React.Component{ + @computed get progressivize() { + if (this.props.progressivize) { + console.log("should render"); + return ( + <> + {PresBox.Instance.progressivizeChildDocs} + + ); + } + } + + @computed get presPaths() { + const presPaths = "presPaths" + (this.props.presPaths ? "" : "-hidden"); + if (this.props.presPaths) { + return ( + + + + + + + + + ; + {PresBox.Instance.paths} + + ); + } + } + render() { + trace(); const freeformclass = "collectionfreeformview" + (this.props.viewDefDivClick ? "-viewDef" : "-none"); const cenx = this.props.centeringShiftX(); const ceny = this.props.centeringShiftY(); @@ -1449,6 +1485,8 @@ class CollectionFreeFormViewPannableContents extends React.Component {this.props.children()} + {this.presPaths} + {this.progressivize} ; } } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index a3020f912..52a7d4ebf 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -15,6 +15,8 @@ import { numberRange } from "../../../Utils"; import { ComputedField } from "../../../fields/ScriptField"; import { listSpec } from "../../../fields/Schema"; import { DocumentType } from "../../documents/DocumentTypes"; +// @ts-ignore +import Zoom from 'react-reveal/Zoom'; 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; @@ -112,10 +114,15 @@ export class CollectionFreeFormDocumentView extends DocComponent { + if (!doc.appearFrame) doc.appearFrame = i; const curTimecode = progressivize ? i : timecode; const xlist = new List(numberRange(timecode + 1).map(i => undefined) as any as number[]); const ylist = new List(numberRange(timecode + 1).map(i => undefined) as any as number[]); - const olist = new List(numberRange(timecode + 1).map(t => progressivize && t < i ? 0 : 1)); + const olist = new List(numberRange(timecode + 1).map(t => progressivize && (t < NumCast(doc.appearFrame)) ? 0 : 1)); + const oarray = new List(); + oarray.fill(0, 0, NumCast(doc.appearFrame) - 1); + oarray.fill(1, NumCast(doc.appearFrame), timecode); + console.log(oarray); xlist[curTimecode] = NumCast(doc.x); ylist[curTimecode] = NumCast(doc.y); doc["x-indexed"] = xlist; diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss index 07e53fa94..4d1518b61 100644 --- a/src/client/views/nodes/PresBox.scss +++ b/src/client/views/nodes/PresBox.scss @@ -125,12 +125,14 @@ .toolbar-slider { position: relative; + align-self: center; + justify-self: left; -webkit-appearance: none; transform: rotateY(180deg); background-color: #40B3D8; - margin-top: 1px; + margin-top: 5px; width: 100%; - max-width: 100px; + max-width: 120px; height: 2.5px; left: 0px; } @@ -153,16 +155,19 @@ display: grid; justify-content: space-between; width: 100%; + height: max-content; + max-width: 120px; grid-template-columns: auto auto auto; - grid-template-rows: auto; + grid-template-rows: max-content; font-weight: 100; - margin-top: 5px; + /* margin-top: 5px; */ font-size: 8px; } .slider-value { - font-size: 10; - position: relative; + top: -20; + color: #2f86a2; + position: absolute; } .slider-value.none, @@ -197,29 +202,18 @@ .ribbon-final-box { align-self: flex-start; + justify-self: center; display: grid; grid-template-rows: auto auto; padding-left: 10px; padding-right: 10px; letter-spacing: normal; - width: max-content; + min-width: max-content; + width: 100%; font-size: 13; font-weight: 600; position: relative; - .selectedList { - display: block; - min-width: 50; - max-width: 120; - height: 70; - overflow-y: scroll; - - .selectedList-items { - font-size: 7; - font-weight: normal; - } - } - .ribbon-final-button { position: relative; @@ -241,41 +235,61 @@ } } + .selectedList { + display: block; + min-width: 50; + max-width: 120; + height: 70; + overflow-y: scroll; + + .selectedList-items { + font-size: 7; + font-weight: normal; + } + } + + .ribbon-button { + font-size: 10; + font-weight: 200; + height: 25; + border: solid 1px black; + display: flex; + border-radius: 10px; + margin-right: 5px; + width: max-content; + justify-content: center; + align-items: center; + padding-right: 10px; + padding-left: 10px; + } + + .ribbon-button.active { + background-color: #5B9FDD; + } + + .ribbon-button:hover { + background-color: lightgrey; + } + + svg.svg-inline--fa.fa-thumbtack.fa-w-12.toolbar-thumbtack { + right: 40; + position: absolute; + transform: rotate(45deg); + } + .ribbon-box { display: grid; grid-template-rows: max-content auto; + justify-self: center; padding-left: 10px; padding-right: 10px; letter-spacing: normal; - width: max-content; + width: 100%; font-weight: 600; position: relative; font-size: 13; border-right: solid 2px darkgrey; - .ribbon-button { - font-size: 10; - font-weight: 200; - height: 25; - border: solid 1px black; - display: flex; - border-radius: 10px; - margin-right: 5px; - width: max-content; - justify-content: center; - align-items: center; - padding-right: 10px; - padding-left: 10px; - } - - .ribbon-button.active { - background-color: #5B9FDD; - } - - .ribbon-button:hover { - background-color: lightgrey; - } - .presBox-dropdown:hover { border: solid 1px #378AD8; @@ -283,6 +297,7 @@ font-size: 10; display: block; padding-left: 5px; + padding-right: 5px; margin-top: 3; margin-bottom: 3; } @@ -303,6 +318,7 @@ left: -1px; z-index: 200; width: 85%; + min-width: max-content; display: block; background: #FFFFFF; border: 0.5px solid #979797; @@ -341,36 +357,58 @@ color: black; align-self: center; justify-self: center; + margin-right: 2px; } } } } .presBox-ribbon.active { - display: inline-flex; + display: grid; + grid-template-columns: auto auto auto auto auto; + grid-template-rows: 100%; height: 100px; padding-top: 5px; padding-bottom: 5px; border: solid 1px black; -} + ::-webkit-scrollbar { + -webkit-appearance: none; + height: 3px; + width: 8px; + } + ::-webkit-scrollbar-thumb { + border-radius: 2px; + background-color: rgb(101, 164, 220); + } +} + +.dropdown-play-button { + font-size: 10; + margin-left: 10; + margin-right: 10; + padding-top: 5px; + padding-bottom: 5px; + text-align: left; + justify-content: left; + border-bottom: solid 1px lightgrey; +} .dropdown-play { top: 32px; - transform: translate(-28%, 0px); - /* left: 0; */ display: none; border-radius: 5px; - width: 100px; - height: 100px; + width: max-content; + min-height: 20px; + height: max-content; z-index: 200; - background-color: black; + background-color: #323232; position: absolute; } .dropdown-play.active { - display: flex; + display: block; } .presBox-buttons { diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index abf97142e..5c21f6656 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -25,6 +25,8 @@ import { SearchUtil } from "../../util/SearchUtil"; import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView"; import { child } from "serializr"; + + type PresBoxSchema = makeInterface<[typeof documentSchema]>; const PresBoxDocument = makeInterface(documentSchema); @@ -232,7 +234,7 @@ export class PresBox extends ViewBoxBaseComponent //The function that starts or resets presentaton functionally, depending on status flag. @action - startOrResetPres = () => { + startOrResetPres = (startSlide: number) => { this.updateCurrentPresentation(); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); if (this._presTimer && this.layoutDoc.presStatus === "auto") { @@ -240,8 +242,8 @@ export class PresBox extends ViewBoxBaseComponent this.layoutDoc.presStatus = "manual"; } else { this.layoutDoc.presStatus = "auto"; - // this.startPresentation(0); - // this.gotoDocument(0, this.itemIndex); + this.startPresentation(startSlide); + this.gotoDocument(startSlide, this.itemIndex); this._presTimer = setInterval(() => { if (this.itemIndex + 1 < this.childDocs.length) this.next(); else { @@ -373,8 +375,10 @@ export class PresBox extends ViewBoxBaseComponent @computed get listOfSelected() { const list = this._selectedArray.map((doc: Doc, index: any) => { + const activeItem = Cast(doc, Doc, null); + const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); return ( -
{index + 1}. {doc.title}
+
{index + 1}. {targetDoc.title}
); }); return list; @@ -415,13 +419,27 @@ export class PresBox extends ViewBoxBaseComponent @action keyEvents = (e: KeyboardEvent) => { e.stopPropagation; + // switch(e.keyCode) { + // case 27: console.log("escape"); + // case 65 && (e.metaKey || e.altKey): + // } // Escape key if (e.keyCode === 27) { if (this.layoutDoc.presStatus === "edit") this._selectedArray = []; else this.layoutDoc.presStatus = "edit"; // Ctrl-A to select all } else if ((e.metaKey || e.altKey) && e.keyCode === 65) { - this._selectedArray = this.childDocs; + if (this.layoutDoc.presStatus === "edit") this._selectedArray = this.childDocs; + // left / a / up to go back + } else if (e.keyCode === 37 || 65 || 38) { + if (this.layoutDoc.presStatus !== "edit") this.back(); + // right / d / down to go to next + } else if (e.keyCode === 39 || 68 || 40) { + if (this.layoutDoc.presStatus !== "edit") this.next(); + // spacebar to 'present' or go to next slide + } else if (e.keyCode === 32) { + if (this.layoutDoc.presStatus !== "edit") this.next(); + else this.layoutDoc.presStatus = "manual"; } } @@ -432,6 +450,8 @@ export class PresBox extends ViewBoxBaseComponent @observable private moreInfoTools: boolean = false; @observable private playTools: boolean = false; + @observable private pathBoolean: boolean = false; + // For toggling transition toolbar @action toggleTransitionTools = () => { this.transitionTools = !this.transitionTools; @@ -491,26 +511,64 @@ export class PresBox extends ViewBoxBaseComponent @undoBatch @action - viewLinks = async () => { - let docToJump = this.childDocs[0]; - // console.log(SearchUtil.GetContextsOfDocument(presTargetDoc)); - // console.log(DocListCast(presTargetDoc.context)); - // console.log(DocumentManager.Instance.getAllDocumentViews(presTargetDoc)); + viewPaths = async () => { + const docToJump = this.childDocs[0]; const aliasOf = await DocCastAsync(docToJump.aliasOf); const srcContext = aliasOf && await DocCastAsync(aliasOf.context); - console.log(srcContext?.title); + if (this.pathBoolean) { + console.log("true"); + if (srcContext) { + this.togglePath(); + srcContext._fitToBox = false; + srcContext._viewType = "freeform"; + srcContext.presPathView = false; + } + } else { + console.log("false"); + if (srcContext) { + this.togglePath(); + srcContext._fitToBox = true; + srcContext._viewType = "freeform"; + srcContext.presPathView = true; + } + } + console.log("view paths"); const viewType = srcContext?._viewType; const fit = srcContext?._fitToBox; - if (srcContext) { - srcContext._fitToBox = true; - srcContext._viewType = "freeform"; - } // if (!DocumentManager.Instance.getDocumentView(curPres)) { // CollectionDockingView.AddRightSplit(curPres); // } } + @computed get paths() { + const paths = []; //List of all of the paths that need to be added + console.log(this.childDocs.length - 1); + for (let i = 0; i <= this.childDocs.length - 1; i++) { + const targetDoc = Cast(this.childDocs[i].presentationTargetDoc, Doc, null); + if (this.childDocs[i + 1] && targetDoc) { + const nextTargetDoc = Cast(this.childDocs[i + 1].presentationTargetDoc, Doc, null); + const n1x = NumCast(targetDoc.x) + (NumCast(targetDoc._width) / 2); + const n1y = NumCast(targetDoc.y) + (NumCast(targetDoc._height) / 2); + const n2x = NumCast(nextTargetDoc.x) + (NumCast(targetDoc._width) / 2); + const n2y = NumCast(nextTargetDoc.y) + (NumCast(targetDoc._height) / 2); + const pathPoints = n1x + "," + n1y + " " + n2x + "," + n2y; + paths.push(); + } + } + return paths; + } + + @action togglePath = () => this.pathBoolean = !this.pathBoolean; + /** * The function that is called on click to turn fading document after presented option on/off. * It also makes sure that the option swithches from hide-after to this one, since both @@ -572,13 +630,13 @@ export class PresBox extends ViewBoxBaseComponent
e.stopPropagation()}>
e.stopPropagation()} onClick={() => this.movementChanged('none')}>None
-
e.stopPropagation()} onClick={() => this.movementChanged('zoom')}>Zoom
-
e.stopPropagation()} onClick={() => this.movementChanged('nav')}>Navigate
+
e.stopPropagation()} onClick={() => this.movementChanged('zoom')}>Pan and Zoom
+
e.stopPropagation()} onClick={() => this.movementChanged('nav')}>Pan
-
{transitionSpeed}s
) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} />
+
{transitionSpeed}s
Slow
Medium
Fast
@@ -693,24 +751,48 @@ export class PresBox extends ViewBoxBaseComponent @computed get playDropdown() { return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> - +
this.startOrResetPres(this.itemIndex)}> + Start from current slide +
+
this.startOrResetPres(0)}> + Start from first slide +
); } + progressivizeOptions = (viewType: string) => { + const buttons = []; + buttons.push(
Progressivize child documents
); + buttons.push(
console.log("hide after")}>Internal navigation
); + if (viewType === "rtf") { + buttons.push(
console.log("hide after")}>Bullet points
); + } + return buttons; + } + + + @computed get progressivizeDropdown() { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - if (activeItem) { + const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + + if (activeItem && targetDoc) { return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
-
Progressivize Child Documents
+ {targetDoc.type} selected +
+
1. {targetDoc.title}
+
-
- Other progressivize features: -
Progressivize Text Bullet Points
-
Internal Navigation
+
+
+
Progressivize child documents
+
Edit
+
+
console.log("hide after")}>Internal navigation
@@ -718,20 +800,50 @@ export class PresBox extends ViewBoxBaseComponent } } + @action + editProgressivize = (e: React.MouseEvent) => { + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + targetDoc.currentFrame = targetDoc.lastFrame; + if (targetDoc?.editProgressivize) { + targetDoc.editProgressivize = false; + } else { + targetDoc.editProgressivize = true; + } + } + @action progressivize = (e: React.MouseEvent) => { e.stopPropagation(); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); activeItem.presProgressivize = !activeItem.presProgressivize; - const rootTarget = Cast(activeItem.presentationTargetDoc, Doc, null); - const docs = DocListCast(rootTarget[Doc.LayoutFieldKey(rootTarget)]); - if (this.rootDoc.presProgressivize) { - rootTarget.currentFrame = 0; + const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); + targetDoc.presProgressivize = !targetDoc.presProgressivize; + console.log(targetDoc.presProgressivize); + if (activeItem.presProgressivize) { + console.log("progressivize"); + targetDoc.currentFrame = 0; CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true); - rootTarget.lastFrame = docs.length - 1; + targetDoc.lastFrame = docs.length - 1; } } + @computed get progressivizeChildDocs() { + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); + const tags: JSX.Element[] = []; + docs.forEach((doc, index) => { + tags.push( +
{doc.appearFrame}
+ ); + }); + return tags; + } + + + @computed get moreInfoDropdown() { return (
); @@ -747,8 +859,8 @@ export class PresBox extends ViewBoxBaseComponent
-
-
+
+ {/*
*/}
@@ -762,6 +874,9 @@ export class PresBox extends ViewBoxBaseComponent
+
+ +
@@ -778,7 +893,7 @@ export class PresBox extends ViewBoxBaseComponent
- +
@@ -807,10 +922,10 @@ export class PresBox extends ViewBoxBaseComponent
-
+
this.startOrResetPres(0)}>   -
+
{ e.stopPropagation; this.togglePlay(); }} className="dropdown" icon={"angle-down"} /> {this.playDropdown}
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index f30ee2a5c..fc040f67b 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -230,7 +230,8 @@ export class PresElementBox extends ViewBoxBaseComponent e.stopPropagation()}> + // onPointerDown={e => e.stopPropagation()} + > {treecontainer ? (null) : <>
{`${this.indexInPres + 1}.`} -- cgit v1.2.3-70-g09d2 From ae47181bab9bdaa104dc417c4493bc1a0e52eea1 Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Fri, 17 Jul 2020 14:38:02 +0800 Subject: pres changes --- package-lock.json | 5 + package.json | 1 + .../collectionFreeForm/CollectionFreeFormView.tsx | 36 +++--- .../views/nodes/CollectionFreeFormDocumentView.tsx | 53 ++++++--- src/client/views/nodes/PresBox.scss | 28 +++++ src/client/views/nodes/PresBox.tsx | 129 ++++++++++++++++----- src/typings/index.d.ts | 5 +- tsconfig.json | 3 +- 8 files changed, 195 insertions(+), 65 deletions(-) (limited to 'src/client/views/collections') diff --git a/package-lock.json b/package-lock.json index 1e8359fbf..f0f40d4dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1205,6 +1205,11 @@ "@types/request": "*" } }, + "@types/reveal": { + "version": "3.3.33", + "resolved": "https://registry.npmjs.org/@types/reveal/-/reveal-3.3.33.tgz", + "integrity": "sha512-lKbezA9Oa5LfdSRwFDc/FHEGH4+FjiXh/a/PCSZAmN+KCeQJL/3ClOdAQwOxt3zdHc8XyioT+cNvIOletwRI7A==" + }, "@types/rimraf": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.4.tgz", diff --git a/package.json b/package.json index 745f7d947..eef6aae03 100644 --- a/package.json +++ b/package.json @@ -123,6 +123,7 @@ "@hig/theme-data": "^2.16.1", "@material-ui/core": "^4.11.0", "@types/google-maps": "^3.2.2", + "@types/reveal": "^3.3.33", "@types/webscopeio__react-textarea-autocomplete": "^4.6.1", "@webscopeio/react-textarea-autocomplete": "^4.7.0", "adm-zip": "^0.4.16", diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index ded410a9c..2b55008f4 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -48,6 +48,7 @@ import { MarqueeView } from "./MarqueeView"; import React = require("react"); import { PresBox } from "../../nodes/PresBox"; + library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload); export const panZoomSchema = createSchema({ @@ -1352,7 +1353,7 @@ export class CollectionFreeFormView extends CollectionSubView @@ -1436,21 +1437,21 @@ interface CollectionFreeFormViewPannableContentsProps { children: () => JSX.Element[]; transition?: string; presPaths?: boolean; - progressivize?: boolean; + // progressivize?: boolean; } @observer class CollectionFreeFormViewPannableContents extends React.Component{ - @computed get progressivize() { - if (this.props.progressivize) { - console.log("should render"); - return ( - <> - {PresBox.Instance.progressivizeChildDocs} - - ); - } - } + // @computed get progressivize() { + // if (this.props.progressivize) { + // console.log("should render"); + // return ( + // <> + // {PresBox.Instance.progressivizeChildDocs} + // + // ); + // } + // } @computed get presPaths() { const presPaths = "presPaths" + (this.props.presPaths ? "" : "-hidden"); @@ -1458,11 +1459,12 @@ class CollectionFreeFormViewPannableContents extends React.Component - - + + - - + + ; {PresBox.Instance.paths} @@ -1486,7 +1488,7 @@ class CollectionFreeFormViewPannableContents extends React.Component {this.props.children()} {this.presPaths} - {this.progressivize} + {/* {this.progressivize} */}
; } } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 52a7d4ebf..f797ffe8a 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -15,8 +15,9 @@ import { numberRange } from "../../../Utils"; import { ComputedField } from "../../../fields/ScriptField"; import { listSpec } from "../../../fields/Schema"; import { DocumentType } from "../../documents/DocumentTypes"; -// @ts-ignore -import Zoom from 'react-reveal/Zoom'; +import { Zoom, Fade, Flip, Rotate, Bounce, Roll, LightSpeed } from 'react-reveal'; +import { PresBox } from "./PresBox"; + 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; @@ -118,8 +119,10 @@ export class CollectionFreeFormDocumentView extends DocComponent(numberRange(timecode + 1).map(i => undefined) as any as number[]); const ylist = new List(numberRange(timecode + 1).map(i => undefined) as any as number[]); - const olist = new List(numberRange(timecode + 1).map(t => progressivize && (t < NumCast(doc.appearFrame)) ? 0 : 1)); - const oarray = new List(); + const olist = new List(numberRange(timecode + 1).map(t => progressivize && t < i ? 0 : 1)); + const oarray: number[] = []; + console.log(doc.title + "AF: " + doc.appearFrame); + console.log("timecode: " + timecode); oarray.fill(0, 0, NumCast(doc.appearFrame) - 1); oarray.fill(1, NumCast(doc.appearFrame), timecode); console.log(oarray); @@ -141,6 +144,35 @@ export class CollectionFreeFormDocumentView extends DocComponent; + if (this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc) { + switch (this.layoutDoc.presEffect) { + case "Zoom": return ({node}); break; + case "Fade": return ({node}); break; + case "Flip": return ({node}); break; + case "Rotate": return ({node}); break; + case "Bounce": return ({node}); break; + case "Roll": return ({node}); break; + case "LightSpeed": return ({node}); break; + case "None": return node; break; + default: return node; break; + } + } else { + return node; + } + } + contentScaling = () => this.nativeWidth > 0 && !this.props.fitToBox && !this.freezeDimensions ? this.width / this.nativeWidth : 1; panelWidth = () => (this.sizeProvider?.width || this.props.PanelWidth?.()); panelHeight = () => (this.sizeProvider?.height || this.props.PanelHeight?.()); @@ -171,6 +203,7 @@ export class CollectionFreeFormDocumentView extends DocComponent + {Doc.UserDoc().renderStyle !== "comic" ? (null) :
@@ -180,17 +213,7 @@ export class CollectionFreeFormDocumentView extends DocComponent} {!this.props.fitToBox ? - + <>{this.freeformNodeDiv} : ; @@ -226,6 +226,7 @@ export class PresBox extends ViewBoxBaseComponent this.navigateToElement(this.childDocs[index], fromDoc); this.hideIfNotPresented(index); this.showAfterPresented(index); + this.onHideDocumentUntilPressClick(); } }); @@ -237,6 +238,7 @@ export class PresBox extends ViewBoxBaseComponent startOrResetPres = (startSlide: number) => { this.updateCurrentPresentation(); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); if (this._presTimer && this.layoutDoc.presStatus === "auto") { clearInterval(this._presTimer); this.layoutDoc.presStatus = "manual"; @@ -250,7 +252,7 @@ export class PresBox extends ViewBoxBaseComponent clearInterval(this._presTimer); this.layoutDoc.presStatus = "manual"; } - }, activeItem.presDuration ? NumCast(activeItem.presDuration) : 2000); + }, targetDoc.presDuration ? NumCast(targetDoc.presDuration) + NumCast(targetDoc.presTransition) : 2000); // for (let i = this.itemIndex + 1; i <= this.childDocs.length; i++) { // if (this.itemIndex + 1 === this.childDocs.length) { // clearTimeout(this._presTimer); @@ -323,12 +325,15 @@ export class PresBox extends ViewBoxBaseComponent @undoBatch movementChanged = action((movement: string) => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); if (movement === 'zoom') { activeItem.presZoomButton = !activeItem.presZoomButton; activeItem.presNavButton = false; } else if (movement === 'nav') { activeItem.presZoomButton = false; activeItem.presNavButton = !activeItem.presNavButton; + } else if (movement === 'swap') { + targetDoc.presTransition = 0; } else { activeItem.presZoomButton = false; activeItem.presNavButton = false; @@ -443,13 +448,29 @@ export class PresBox extends ViewBoxBaseComponent } } + @action + onHideDocumentUntilPressClick = () => { + this.childDocs.forEach((doc, index) => { + const curDoc = Cast(doc, Doc, null); + const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null); + if (tagDoc.presEffect === 'None' || !tagDoc.presEffect) { + tagDoc.opacity = 1; + } else { + if (index <= this.itemIndex) { + tagDoc.opacity = 1; + } else { + tagDoc.opacity = 0; + } + } + }); + } + @observable private transitionTools: boolean = false; @observable private newDocumentTools: boolean = false; @observable private progressivizeTools: boolean = false; @observable private moreInfoTools: boolean = false; @observable private playTools: boolean = false; - @observable private pathBoolean: boolean = false; // For toggling transition toolbar @@ -556,11 +577,11 @@ export class PresBox extends ViewBoxBaseComponent paths.push(); } } @@ -608,15 +629,24 @@ export class PresBox extends ViewBoxBaseComponent if (targetDoc) targetDoc.presTransition = timeInMS; } + setDurationTime = (number: String) => { + const timeInMS = Number(number) * 1000; + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + if (targetDoc) targetDoc.presDuration = timeInMS; + } + @computed get transitionDropdown() { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); if (activeItem) { const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); - const transitionSpeed = targetDoc ? String(Number(targetDoc.presTransition) / 1000) : 0.5; - const visibilityTime = targetDoc ? String(Number(targetDoc.presTransition) / 1000) : 0.5; - const thumbLocation = String(-9.48 * Number(transitionSpeed) + 93); + const transitionSpeed = targetDoc.presTransition ? String(Number(targetDoc.presTransition) / 1000) : 0.5; + const duration = targetDoc.presDuration ? String(Number(targetDoc.presDuration) / 1000) : 2; + const transitionThumbLocation = String(-9.48 * Number(transitionSpeed) + 93); + const durationThumbLocation = String(9.48 * Number(duration)); const movement = activeItem.presZoomButton ? 'Zoom' : activeItem.presNavbutton ? 'Navigate' : 'None'; + const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None'; const visibility = activeItem.presFadeButton ? 'Fade' : activeItem.presHideTillShownButton ? 'Hide till shown' : activeItem.presHideAfter ? 'Hide on exit' : 'None'; return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> @@ -632,37 +662,30 @@ export class PresBox extends ViewBoxBaseComponent
e.stopPropagation()} onClick={() => this.movementChanged('none')}>None
e.stopPropagation()} onClick={() => this.movementChanged('zoom')}>Pan and Zoom
e.stopPropagation()} onClick={() => this.movementChanged('nav')}>Pan
+
e.stopPropagation()} onClick={() => this.movementChanged('swap')}>Swap
) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} />
-
{transitionSpeed}s
+
{transitionSpeed}s
Slow
Medium
Fast
- Visibility + Duration
e.stopPropagation()} - // onClick={() => this.dropdownToggle('Movement')} > - {visibility} - -
e.stopPropagation()}> -
e.stopPropagation()} onClick={() => this.visibilityChanged('none')}>None
-
e.stopPropagation()} onClick={() => this.visibilityChanged('fade')}>Fade on exit
-
e.stopPropagation()} onClick={() => this.visibilityChanged('hideAfter')}>Hide on exit
-
e.stopPropagation()} onClick={() => this.visibilityChanged('hideBefore')}>Hidden til presented
-
+ {duration} seconds
-
{transitionSpeed}s
- ) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} /> -
-
Slow
-
Medium
-
Fast
+ ) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} /> +
+
{duration}s
+
Short
+
+
Long
{/*
Fade After
*/} {/*
console.log("hide before")}>Hide Before
*/} @@ -674,12 +697,24 @@ export class PresBox extends ViewBoxBaseComponent onPointerDown={e => e.stopPropagation()} // onClick={() => this.dropdownToggle('Movement')} > - None + {effect}
e.stopPropagation()}> -
e.stopPropagation()}>None
+
e.stopPropagation()} onClick={() => targetDoc.presEffect = 'None'}>None
+
e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Fade'}>Fade In
+
e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Flip'}>Flip
+
e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Rotate'}>Rotate
+
e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Bounce'}>Bounce
+
e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Roll'}>Roll
+
+
targetDoc.presEffectDirection = 'left'}>
+
targetDoc.presEffectDirection = 'right'}>
+
targetDoc.presEffectDirection = 'top'}>
+
targetDoc.presEffectDirection = 'bottom'}>
+
targetDoc.presEffectDirection = false}>
+
{this._selectedArray.length} selected @@ -688,10 +723,10 @@ export class PresBox extends ViewBoxBaseComponent
-
+
this.applyTo(this._selectedArray)}> Apply to selected
-
+
this.applyTo(this.childDocs)}> Apply to all
@@ -700,6 +735,20 @@ export class PresBox extends ViewBoxBaseComponent } } + applyTo = (array: Doc[]) => { + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + array.forEach((doc, index) => { + const curDoc = Cast(doc, Doc, null); + const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null); + if (tagDoc && targetDoc) { + tagDoc.presTransition = targetDoc.presTransition; + tagDoc.presDuration = targetDoc.presDuration; + tagDoc.presEffect = targetDoc.presEffect; + } + }); + } + public inputRef = React.createRef(); @@ -846,7 +895,22 @@ export class PresBox extends ViewBoxBaseComponent @computed get moreInfoDropdown() { return (
); + } + + @computed get effectOpenBracket() { + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + if (targetDoc.presEffect && this.itemIndex) { + return ("<" + targetDoc.presEffect + "when=" + this.layoutDoc === PresBox.Instance.childDocs[this.itemIndex].presentationTargetDoc + ">"); + } else return; + } + @computed get effectCloseBracket() { + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + if (targetDoc.presEffect && this.itemIndex) { + return (""); + } else return; } @computed get toolbar() { @@ -895,8 +959,11 @@ export class PresBox extends ViewBoxBaseComponent
-
-
+ +

uppercase

+
+
+
diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts index 452882e09..799a3ee6f 100644 --- a/src/typings/index.d.ts +++ b/src/typings/index.d.ts @@ -6,7 +6,10 @@ declare module 'cors'; declare module 'webrtc-adapter'; declare module 'bezier-curve'; -declare module 'fit-curve' +declare module 'fit-curve'; +declare module 'reveal'; +declare module 'react-reveal'; +declare module 'react-reveal/makeCarousel'; declare module '@react-pdf/renderer' { diff --git a/tsconfig.json b/tsconfig.json index 803245ca6..b06cec79f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,7 +15,8 @@ "es2015" ], "typeRoots": [ - "node_modules/@types" + "node_modules/@types", + "./src/typings" ], "types": [ "youtube" -- cgit v1.2.3-70-g09d2 From ad6762c369fd0933326579707ecbc34fda42ab6c Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Mon, 20 Jul 2020 22:53:08 +0800 Subject: ui updates + progressivize features --- deploy/index.html | 1 + src/client/documents/Documents.ts | 3 + src/client/views/collections/CollectionMenu.scss | 60 +-- .../collectionFreeForm/CollectionFreeFormView.scss | 56 ++- .../collectionFreeForm/CollectionFreeFormView.tsx | 62 ++- .../views/nodes/CollectionFreeFormDocumentView.tsx | 34 +- src/client/views/nodes/PresBox.scss | 68 ++- src/client/views/nodes/PresBox.tsx | 504 +++++++++++++++------ .../views/presentationview/PresElementBox.scss | 40 +- .../views/presentationview/PresElementBox.tsx | 25 +- 10 files changed, 602 insertions(+), 251 deletions(-) (limited to 'src/client/views/collections') diff --git a/deploy/index.html b/deploy/index.html index 82e8c53a3..990ca510d 100644 --- a/deploy/index.html +++ b/deploy/index.html @@ -3,6 +3,7 @@ Dash Web + diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 080369afe..89a7c0f18 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -133,8 +133,11 @@ export interface DocumentOptions { currentFrame?: number; // the current frame of a frame-based collection (e.g., progressive slide) lastFrame?: number; // the last frame of a frame-based collection (e.g., progressive slide) activeFrame?: number; // the active frame of a document in a frame base collection + appearFrame?: number; // the frame in which the document appears presTransition?: number; //the time taken for the transition TO a document presDuration?: number; //the duration of the slide in presentation view + // xArray?: number[]; + // yArray?: number[]; borderRounding?: string; boxShadow?: string; dontRegisterChildViews?: boolean; diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index 348b9e6ea..929c22c35 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -312,44 +312,44 @@ align-items: center; .fwdKeyframe, - .numKeyframe, - .backKeyframe { - cursor: pointer; - position: absolute; - width: 20; - height: 30; - bottom: 0; - background: #121721; - display: flex; - align-items: center; - color: white; - } +.numKeyframe, +.backKeyframe { + cursor: pointer; + position: absolute; + width: 20; + height: 30; + bottom: 0; + background: #121721; + display: flex; + align-items: center; + color: white; +} - .backKeyframe { - left: 0; +.backKeyframe { + left: 0; - svg { - display: block; - margin: auto; - } + svg { + display: block; + margin: auto; } +} - .numKeyframe { - left: 20; - display: flex; - flex-direction: column; - padding: 5px; - } +.numKeyframe { + left: 20; + display: flex; + flex-direction: column; + padding: 5px; +} - .fwdKeyframe { - left: 40; +.fwdKeyframe { + left: 40; - svg { - display: block; - margin: auto; - } + svg { + display: block; + margin: auto; } } +} .collectionSchemaViewChrome-cont { display: flex; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss index fad90ca32..b50a93775 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss @@ -46,21 +46,69 @@ } } +.pathOrder { + position: absolute; + z-index: 200000; + + .pathOrder-frame { + position: absolute; + width: 40; + text-align: center; + font-size: 30; + background-color: #69a6db; + font-family: Roboto; + font-weight: 300; + } +} + .progressivizeButton { position: absolute; - display: flex; + display: grid; + grid-template-columns: auto 20px auto; transform: translate(-105%, 0); align-items: center; border: black solid 1px; border-radius: 3px; justify-content: center; - width: 30; + width: 40; + z-index: 30000; height: 20; - background-color: #c8c8c8; + overflow: hidden; + background-color: #d5dce2; + transition: all 1s; + + .progressivizeButton-prev:hover { + color: #5a9edd; + } + + .progressivizeButton-frame { + justify-self: center; + text-align: center; + width: 15px; + } + + .progressivizeButton-next:hover { + color: #5a9edd; + } +} + +.progressivizeMove-frame { + width: 40px; + border-radius: 2px; + z-index: 100000; + color: white; + text-align: center; + background-color: #5a9edd; + transform: translate(-105%, -110%); } .progressivizeButton:hover { - background-color: #aedef8; + box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.5); + + .progressivizeButton-frame { + background-color: #5a9edd; + color: white; + } } .collectionFreeform-customText { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 45c5c6a40..953b218b2 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1408,7 +1408,7 @@ export class CollectionFreeFormView extends CollectionSubView @@ -1493,44 +1493,56 @@ interface CollectionFreeFormViewPannableContentsProps { children: () => JSX.Element[]; transition?: string; presPaths?: boolean; - // progressivize?: boolean; + progressivize?: boolean; } @observer class CollectionFreeFormViewPannableContents extends React.Component{ - // @computed get progressivize() { - // if (this.props.progressivize) { - // console.log("should render"); - // return ( - // <> - // {PresBox.Instance.progressivizeChildDocs} - // - // ); - // } - // } + @computed get progressivize() { + if (this.props.progressivize) { + console.log("should render"); + return ( + <> + {PresBox.Instance.progressivizeChildDocs} + + ); + } + } @computed get presPaths() { const presPaths = "presPaths" + (this.props.presPaths ? "" : "-hidden"); if (this.props.presPaths) { return ( - - - - - - - - - ; + <> +
{PresBox.Instance.order}
+ + + + + + + + + + + + + + + + ; {PresBox.Instance.paths} - + + ); } } render() { - trace(); + // trace(); const freeformclass = "collectionfreeformview" + (this.props.viewDefDivClick ? "-viewDef" : "-none"); const cenx = this.props.centeringShiftX(); const ceny = this.props.centeringShiftY(); @@ -1544,7 +1556,7 @@ class CollectionFreeFormViewPannableContents extends React.Component {this.props.children()} {this.presPaths} - {/* {this.progressivize} */} + {this.progressivize}
; } } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index b975e24e2..2cf2ab35d 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -119,18 +119,23 @@ export class CollectionFreeFormDocumentView extends DocComponent(numberRange(timecode + 1).map(i => undefined) as any as number[]); const ylist = new List(numberRange(timecode + 1).map(i => undefined) as any as number[]); - const olist = new List(numberRange(timecode + 1).map(t => progressivize && t < i ? 0 : 1)); - const oarray: number[] = []; + const olist = new List(numberRange(timecode + 1).map(t => progressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1)); + let oarray: List; console.log(doc.title + "AF: " + doc.appearFrame); console.log("timecode: " + timecode); + oarray = olist; oarray.fill(0, 0, NumCast(doc.appearFrame) - 1); oarray.fill(1, NumCast(doc.appearFrame), timecode); + // oarray.fill(0, 0, NumCast(doc.appearFrame) - 1); + // oarray.fill(1, NumCast(doc.appearFrame), timecode); console.log(oarray); xlist[curTimecode] = NumCast(doc.x); ylist[curTimecode] = NumCast(doc.y); + doc.xArray = xlist; + doc.yArray = ylist; doc["x-indexed"] = xlist; doc["y-indexed"] = ylist; - doc["opacity-indexed"] = olist; + doc["opacity-indexed"] = oarray; doc.activeFrame = ComputedField.MakeFunction("self.context?.currentFrame||0"); doc.x = ComputedField.MakeInterpolated("x", "activeFrame"); doc.y = ComputedField.MakeInterpolated("y", "activeFrame"); @@ -157,14 +162,23 @@ export class CollectionFreeFormDocumentView extends DocComponent; if (this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc) { + const effectProps = { + left: this.layoutDoc.presEffectDirection === 'left', + right: this.layoutDoc.presEffectDirection === 'right', + top: this.layoutDoc.presEffectDirection === 'top', + bottom: this.layoutDoc.presEffectDirection === 'bottom', + opposite: true, + delay: this.layoutDoc.presTransition, + // when: this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc, + }; switch (this.layoutDoc.presEffect) { - case "Zoom": return ({node}); break; - case "Fade": return ({node}); break; - case "Flip": return ({node}); break; - case "Rotate": return ({node}); break; - case "Bounce": return ({node}); break; - case "Roll": return ({node}); break; - case "LightSpeed": return ({node}); break; + case "Zoom": return ({node}); break; + case "Fade": return ({node}); break; + case "Flip": return ({node}); break; + case "Rotate": return ({node}); break; + case "Bounce": return ({node}); break; + case "Roll": return ({node}); break; + case "LightSpeed": return ({node}); break; case "None": return node; break; default: return node; break; } diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss index bf31f71d2..45bb4293b 100644 --- a/src/client/views/nodes/PresBox.scss +++ b/src/client/views/nodes/PresBox.scss @@ -3,6 +3,7 @@ display: block; pointer-events: inherit; z-index: 2; + font-family: Roboto; box-shadow: #AAAAAA .2vw .2vw .4vw; width: 100%; min-width: 20px; @@ -16,7 +17,7 @@ position: relative; height: calc(100% - 25px); width: 100%; - margin-top: 10px; + margin-top: 3px; } .presBox-toolbar { @@ -39,12 +40,6 @@ display: flex; align-items: center; transition: 0.5s; - - @media only screen and (max-width: 400) { - .toolbar-buttonText { - display: none; - } - } } .toolbar-button.active { @@ -116,6 +111,7 @@ .presBox-ribbon { position: relative; display: none; + font-family: Roboto; background-color: white; color: black; width: 100%; @@ -123,6 +119,10 @@ z-index: 100; transition: 0.7s; + .ribbon-doubleButton { + display: inline-flex; + } + .toolbar-slider { position: relative; align-self: center; @@ -199,16 +199,56 @@ .ribbon-textInput { border-radius: 2px; - height: 25px; + height: 20px; font-size: 10; font-weight: 100; align-self: center; justify-self: center; padding-left: 10px; border: solid 1px black; + min-width: 80px; width: 100%; } + .ribbon-frameSelector { + border: black solid 1px; + width: 60px; + height: 20px; + display: grid; + grid-template-columns: auto 27px auto; + position: relative; + border-radius: 5px; + overflow: hidden; + align-items: center; + justify-self: left; + + .fwdKeyframe, + .backKeyframe { + cursor: pointer; + position: relative; + height: 100%; + background: #d5dce2; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + color: black; + } + + .numKeyframe { + font-size: 10; + font-weight: 600; + position: relative; + color: black; + display: flex; + width: 100%; + height: 100%; + text-align: center; + align-items: center; + justify-content: center; + } + } + .ribbon-final-box { align-self: flex-start; justify-self: center; @@ -279,10 +319,12 @@ .ribbon-button { font-size: 10; font-weight: 200; - height: 25; + height: 20; border: solid 1px black; display: flex; - border-radius: 10px; + margin-top: 5px; + margin-bottom: 5px; + border-radius: 5px; margin-right: 5px; width: max-content; justify-content: center; @@ -326,8 +368,8 @@ display: block; padding-left: 5px; padding-right: 5px; - margin-top: 3; - margin-bottom: 3; + padding-top: 3; + padding-bottom: 3; } .presBox-dropdownOption:hover { @@ -337,7 +379,7 @@ .presBox-dropdownOption.active { position: relative; - background-color: #9CE2F8; + background-color: #aedef8; } .presBox-dropdownOptions { diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index fc5e73c81..9b942c065 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -2,10 +2,10 @@ import React = require("react"); import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DocListCast, DocCastAsync } from "../../../fields/Doc"; +import { Doc, DocListCast, DocCastAsync, WidthSym } from "../../../fields/Doc"; import { InkTool } from "../../../fields/InkField"; import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types"; -import { returnFalse, returnOne } from "../../../Utils"; +import { returnFalse, returnOne, numberRange } from "../../../Utils"; import { documentSchema } from "../../../fields/documentSchemas"; import { DocumentManager } from "../../util/DocumentManager"; import { undoBatch } from "../../util/UndoManager"; @@ -25,6 +25,9 @@ import { SearchUtil } from "../../util/SearchUtil"; import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView"; import { child } from "serializr"; import { Zoom, Fade, Flip, Rotate, Bounce, Roll, LightSpeed } from 'react-reveal'; +import { List } from "../../../fields/List"; +import { Tooltip } from "@material-ui/core"; +import { CollectionFreeFormViewChrome } from "../collections/CollectionMenu"; type PresBoxSchema = makeInterface<[typeof documentSchema]>; @@ -60,11 +63,21 @@ export class PresBox extends ViewBoxBaseComponent this.rootDoc._forceRenderEngine = "timeline"; this.rootDoc._replacedChrome = "replaced"; this.layoutDoc.presStatus = "edit"; - document.addEventListener("keydown", this.keyEvents, false); + // document.addEventListener("keydown", this.keyEvents, false); } - componentWillUnmount() { - document.removeEventListener("keydown", this.keyEvents, false); + // componentWillUnmount() { + // document.removeEventListener("keydown", this.keyEvents, false); + // } + + onPointerOver = () => { + document.addEventListener("keydown", this.keyEvents, true); + // document.addEventListener("keydown", this.keyEvents, false); + } + + onPointerLeave = () => { + // document.removeEventListener("keydown", this.keyEvents, false); + document.removeEventListener("keydown", this.keyEvents, true); } updateCurrentPresentation = () => Doc.UserDoc().activePresentation = this.rootDoc; @@ -114,50 +127,77 @@ export class PresBox extends ViewBoxBaseComponent } } + + @action + onHideDocumentUntilPressClick = () => { + this.childDocs.forEach((doc, index) => { + const curDoc = Cast(doc, Doc, null); + const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null); + if (tagDoc.presEffect === 'None' || !tagDoc.presEffect) { + tagDoc.opacity = 1; + } else { + if (index <= this.itemIndex) { + tagDoc.opacity = 1; + } else { + tagDoc.opacity = 0; + } + } + }); + } + /** * This is the method that checks for the actions that need to be performed - * after the document has been presented, which involves 3 button options: + * before the document has been presented, which involves 3 button options: * Hide Until Presented, Hide After Presented, Fade After Presented */ - showAfterPresented = (index: number) => { + @action + hideDocumentInPres = () => { this.updateCurrentPresentation(); - this.childDocs.forEach((doc, ind) => { - const presTargetDoc = doc.presentationTargetDoc as Doc; - //the order of cases is aligned based on priority - if (doc.presHideTillShownButton && ind <= index) { - presTargetDoc.opacity = 1; - } - if (doc.presHideAfterButton && ind < index) { - presTargetDoc.opacity = 0; + this.childDocs.forEach((doc, i) => { + const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); + console.log("HB: " + doc.presHideTillShownButton); + console.log("HA: " + doc.presHideAfterButton); + if (doc.presHideTillShownButton) { + if (i < this.itemIndex) { + console.log(i + 1 + "hide before"); + tagDoc.opacity = 0; + console.log(tagDoc.opacity); + } else { + tagDoc.opacity = 1; + } } - if (doc.presFadeButton && ind < index) { - presTargetDoc.opacity = 0.5; + if (doc.presHideAfterButton) { + if (i > this.itemIndex) { + console.log(i + 1 + "hide after"); + tagDoc.opacity = 0; + console.log(tagDoc.opacity); + } else { + tagDoc.opacity = 1; + } } }); } /** * This is the method that checks for the actions that need to be performed - * before the document has been presented, which involves 3 button options: + * after the document has been presented, which involves 3 button options: * Hide Until Presented, Hide After Presented, Fade After Presented */ - hideIfNotPresented = (index: number) => { + showAfterPresented = (index: number) => { this.updateCurrentPresentation(); - this.childDocs.forEach((key, ind) => { + this.childDocs.forEach((doc, ind) => { + const presTargetDoc = doc.presentationTargetDoc as Doc; //the order of cases is aligned based on priority - const presTargetDoc = key.presentationTargetDoc as Doc; - if (key.hideAfterButton && ind >= index) { - presTargetDoc.opacity = 1; - } - if (key.fadeButton && ind >= index) { + if (doc.presHideTillShownButton && ind <= index) { presTargetDoc.opacity = 1; } - if (key.hideTillShownButton && ind > index) { + if (doc.presHideAfterButton && ind < index) { presTargetDoc.opacity = 0; } }); } + /** * This method makes sure that cursor navigates to the element that * has the option open and last in the group. If not in the group, and it has @@ -224,9 +264,10 @@ export class PresBox extends ViewBoxBaseComponent // this.startPresentation(index); // } this.navigateToElement(this.childDocs[index], fromDoc); - this.hideIfNotPresented(index); - this.showAfterPresented(index); - this.onHideDocumentUntilPressClick(); + // this.hideIfNotPresented(index); + // this.showAfterPresented(index); + this.hideDocumentInPres(); + // this.onHideDocumentUntilPressClick(); } }); @@ -340,24 +381,6 @@ export class PresBox extends ViewBoxBaseComponent } }); - @undoBatch - visibilityChanged = action((visibility: string) => { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - if (visibility === 'fade') { - activeItem.presFadeButton = !activeItem.presFadeButton; - } else if (visibility === 'hideBefore') { - activeItem.presHideTillShownButton = !activeItem.presHideTillShownButton; - activeItem.presHideAfterButton = false; - } else if (visibility === 'hideAfter') { - activeItem.presHideAfterButton = !activeItem.presHideAfterButton; - activeItem.presHideAfterButton = false; - } else { - activeItem.presHideAfterButton = false; - activeItem.presHideTillShownButton = false; - activeItem.presFadeButton = false; - } - }); - whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive)); addDocumentFilter = (doc: Doc | Doc[]) => { const docs = doc instanceof Doc ? [doc] : doc; @@ -433,39 +456,21 @@ export class PresBox extends ViewBoxBaseComponent if (this.layoutDoc.presStatus === "edit") this._selectedArray = []; else this.layoutDoc.presStatus = "edit"; // Ctrl-A to select all - } else if ((e.metaKey || e.altKey) && e.keyCode === 65) { + } if ((e.metaKey || e.altKey) && e.keyCode === 65) { if (this.layoutDoc.presStatus === "edit") this._selectedArray = this.childDocs; // left / a / up to go back - } else if (e.keyCode === 37 || 65 || 38) { + } if (e.keyCode === 37 || 65 || 38) { if (this.layoutDoc.presStatus !== "edit") this.back(); // right / d / down to go to next - } else if (e.keyCode === 39 || 68 || 40) { + } if (e.keyCode === 39 || 68 || 40) { if (this.layoutDoc.presStatus !== "edit") this.next(); // spacebar to 'present' or go to next slide - } else if (e.keyCode === 32) { + } if (e.keyCode === 32) { if (this.layoutDoc.presStatus !== "edit") this.next(); else this.layoutDoc.presStatus = "manual"; } } - @action - onHideDocumentUntilPressClick = () => { - this.childDocs.forEach((doc, index) => { - const curDoc = Cast(doc, Doc, null); - const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null); - if (tagDoc.presEffect === 'None' || !tagDoc.presEffect) { - tagDoc.opacity = 1; - } else { - if (index <= this.itemIndex) { - tagDoc.opacity = 1; - } else { - tagDoc.opacity = 0; - } - } - }); - } - - @observable private transitionTools: boolean = false; @observable private newDocumentTools: boolean = false; @observable private progressivizeTools: boolean = false; @@ -562,30 +567,60 @@ export class PresBox extends ViewBoxBaseComponent // } } + @computed get order() { + const order: JSX.Element[] = []; + this.childDocs.forEach((doc, index) => { + const targetDoc = Cast(doc.presentationTargetDoc, Doc, null); + order.push( +
+
{index + 1}
+
); + }); + return order; + } + @computed get paths() { - const paths = []; //List of all of the paths that need to be added + // const paths = []; //List of all of the paths that need to be added + let pathPoints = ""; console.log(this.childDocs.length - 1); - for (let i = 0; i <= this.childDocs.length - 1; i++) { - const targetDoc = Cast(this.childDocs[i].presentationTargetDoc, Doc, null); - if (this.childDocs[i + 1] && targetDoc) { - const nextTargetDoc = Cast(this.childDocs[i + 1].presentationTargetDoc, Doc, null); + this.childDocs.forEach((doc, index) => { + const targetDoc = Cast(doc.presentationTargetDoc, Doc, null); + if (targetDoc) { const n1x = NumCast(targetDoc.x) + (NumCast(targetDoc._width) / 2); const n1y = NumCast(targetDoc.y) + (NumCast(targetDoc._height) / 2); - const n2x = NumCast(nextTargetDoc.x) + (NumCast(targetDoc._width) / 2); - const n2y = NumCast(nextTargetDoc.y) + (NumCast(targetDoc._height) / 2); - const pathPoints = n1x + "," + n1y + " " + n2x + "," + n2y; - paths.push(); + // const n2x = NumCast(nextTargetDoc.x) + (NumCast(targetDoc._width) / 2); + // const n2y = NumCast(nextTargetDoc.y) + (NumCast(targetDoc._height) / 2); + if (index = 0) pathPoints = n1x + "," + n1y; + else pathPoints = pathPoints + " " + n1x + "," + n1y; + // const pathPoints = n1x + "," + n1y + " " + n2x + "," + n2y; + // else pathPoints = pathPoints + " " + n1x + "," + n1y; + // paths.push(); } - } - return paths; + }); + console.log(pathPoints); + // return paths; + return (); } @action togglePath = () => this.pathBoolean = !this.pathBoolean; @@ -638,16 +673,14 @@ export class PresBox extends ViewBoxBaseComponent @computed get transitionDropdown() { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - - if (activeItem) { - const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + if (activeItem && targetDoc) { const transitionSpeed = targetDoc.presTransition ? String(Number(targetDoc.presTransition) / 1000) : 0.5; const duration = targetDoc.presDuration ? String(Number(targetDoc.presDuration) / 1000) : 2; const transitionThumbLocation = String(-9.48 * Number(transitionSpeed) + 93); const durationThumbLocation = String(9.48 * Number(duration)); const movement = activeItem.presZoomButton ? 'Zoom' : activeItem.presNavbutton ? 'Navigate' : 'None'; const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None'; - const visibility = activeItem.presFadeButton ? 'Fade' : activeItem.presHideTillShownButton ? 'Hide till shown' : activeItem.presHideAfter ? 'Hide on exit' : 'None'; return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
@@ -669,16 +702,15 @@ export class PresBox extends ViewBoxBaseComponent
{transitionSpeed}s
Slow
-
Medium
+
Fast
- Duration -
e.stopPropagation()} - > - {duration} seconds + Visibility +
+
{"Hide before presented"}
}>
activeItem.presHideTillShownButton = !activeItem.presHideTillShownButton}>HB
+
{"Hide after presented"}
}>
activeItem.presHideAfterButton = !activeItem.presHideAfterButton}>HA
) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} />
@@ -709,11 +741,11 @@ export class PresBox extends ViewBoxBaseComponent
-
targetDoc.presEffectDirection = 'left'}>
-
targetDoc.presEffectDirection = 'right'}>
-
targetDoc.presEffectDirection = 'top'}>
-
targetDoc.presEffectDirection = 'bottom'}>
-
targetDoc.presEffectDirection = false}>
+
{"Enter from left"}
}>
targetDoc.presEffectDirection = 'left'}>
+
{"Enter from right"}
}>
targetDoc.presEffectDirection = 'right'}>
+
{"Enter from top"}
}>
targetDoc.presEffectDirection = 'top'}>
+
{"Enter from bottom"}
}>
targetDoc.presEffectDirection = 'bottom'}>
+
{"Enter from center"}
}>
targetDoc.presEffectDirection = false}>
@@ -782,9 +814,9 @@ export class PresBox extends ViewBoxBaseComponent
Choose type: -
-
{ type = "text"; }}>Text
-
{ type = "freeform"; }}>Freeform
+
+
{ type = "text"; })}>Text
+
{ type = "freeform"; })}>Freeform
@@ -810,17 +842,43 @@ export class PresBox extends ViewBoxBaseComponent ); } - progressivizeOptions = (viewType: string) => { - const buttons = []; - buttons.push(
Progressivize child documents
); - buttons.push(
console.log("hide after")}>Internal navigation
); - if (viewType === "rtf") { - buttons.push(
console.log("hide after")}>Bullet points
); + // progressivizeOptions = (viewType: string) => { + // const buttons = []; + // buttons.push(
Child documents
); + // buttons.push(
console.log("hide after")}>Internal zoom
); + // buttons.push(
console.log("hide after")}>Bullet points
); + // if (viewType === "rtf") { + // buttons.push(
console.log("hide after")}>Bullet points
); + // } + // return buttons; + // } + + @undoBatch + @action + nextKeyframe = (tagDoc: Doc): void => { + const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]); + const currentFrame = Cast(tagDoc.currentFrame, "number", null); + if (currentFrame === undefined) { + tagDoc.currentFrame = 0; + CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0); } - return buttons; + CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0); + tagDoc.currentFrame = Math.max(0, (currentFrame || 0) + 1); + tagDoc.lastFrame = Math.max(NumCast(tagDoc.currentFrame), NumCast(tagDoc.lastFrame)); } - + @undoBatch + @action + prevKeyframe = (tagDoc: Doc): void => { + const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]); + const currentFrame = Cast(tagDoc.currentFrame, "number", null); + if (currentFrame === undefined) { + tagDoc.currentFrame = 0; + CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0); + } + CollectionFreeFormDocumentView.gotoKeyframe(childDocs.slice()); + tagDoc.currentFrame = Math.max(0, (currentFrame || 0) - 1); + } @computed get progressivizeDropdown() { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); @@ -832,16 +890,38 @@ export class PresBox extends ViewBoxBaseComponent
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
{targetDoc.type} selected -
-
1. {targetDoc.title}
+
+
{targetDoc.title}
+
+
+
+
{ e.stopPropagation(); this.prevKeyframe(targetDoc); }}> + +
+
targetDoc.editing = !targetDoc.editing)} > + {NumCast(targetDoc.currentFrame)} +
+
{ e.stopPropagation(); this.nextKeyframe(targetDoc); }}> + +
+
+
{"Last frame"}
}>
{NumCast(targetDoc.lastFrame)}
-
-
Progressivize child documents
-
Edit
+
+
Child documents
+
Edit
+
+
+
Internal zoom
+
Edit
+
+
+
Text progressivize
+
Edit
-
console.log("hide after")}>Internal navigation
@@ -849,8 +929,38 @@ export class PresBox extends ViewBoxBaseComponent } } + //Progressivize Zoom @action - editProgressivize = (e: React.MouseEvent) => { + zoomProgressivize = (e: React.MouseEvent) => { + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + targetDoc.currentFrame = targetDoc.lastFrame; + if (targetDoc?.zoomProgressivize) { + targetDoc.zoomProgressivize = false; + } else { + targetDoc.zoomProgressivize = true; + } + } + + @action + progressivizeZoom = (e: React.MouseEvent) => { + e.stopPropagation(); + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + activeItem.zoomProgressivize = !activeItem.zoomProgressivize; + const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); + targetDoc.zoomProgressivize = !targetDoc.zoomProgressivize; + console.log(targetDoc.zoomProgressivize); + if (activeItem.zoomProgressivize) { + console.log("progressivize"); + targetDoc.currentFrame = 0; + CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true); + } + } + + //Progressivize Text nodes + @action + textProgressivize = (e: React.MouseEvent) => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); targetDoc.currentFrame = targetDoc.lastFrame; @@ -862,7 +972,7 @@ export class PresBox extends ViewBoxBaseComponent } @action - progressivize = (e: React.MouseEvent) => { + progressivizeText = (e: React.MouseEvent) => { e.stopPropagation(); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); activeItem.presProgressivize = !activeItem.presProgressivize; @@ -878,67 +988,163 @@ export class PresBox extends ViewBoxBaseComponent } } + //Progressivize Child Docs + @action + editProgressivize = (e: React.MouseEvent) => { + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + targetDoc.currentFrame = targetDoc.lastFrame; + if (targetDoc?.editProgressivize) { + targetDoc.editProgressivize = false; + } else { + targetDoc.editProgressivize = true; + } + } + + @action + progressivizeChild = (e: React.MouseEvent) => { + e.stopPropagation(); + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); + if (!activeItem.presProgressivize) { + activeItem.presProgressivize = true; + targetDoc.presProgressivize = true; + targetDoc.currentFrame = 0; + CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true); + targetDoc.lastFrame = docs.length - 1; + } else { + activeItem.presProgressivize = false; + targetDoc.presProgressivize = false; + docs.forEach((doc, index) => { + doc.appearFrame = 0; + }); + targetDoc.currentFrame = 0; + targetDoc.lastFrame = 0; + } + } + + @action + checkMovementLists = (doc: Doc, xlist: any, ylist: any) => { + const x: List = xlist; + const y: List = ylist; + const tags: JSX.Element[] = []; + let pathPoints = ""; //List of all of the paths that need to be added + // console.log(x); + // console.log(x.length); + // console.log(x[0]); + for (let i = 0; i < x.length - 1; i++) { + if (y[i] || x[i]) { + if (i === 0) pathPoints = (x[i] - 11) + "," + (y[i] + 33); + else pathPoints = pathPoints + " " + (x[i] - 11) + "," + (y[i] + 33); + tags.push(
{i}
); + } + } + tags.push(); + return tags; + } + + @observable + toggleDisplayMovement = (doc: Doc) => { + if (doc.displayMovement) doc.displayMovement = false; + else doc.displayMovement = true; + } + @computed get progressivizeChildDocs() { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); const tags: JSX.Element[] = []; docs.forEach((doc, index) => { + if (doc["x-indexed"] && doc["y-indexed"]) { + tags.push(
{this.checkMovementLists(doc, doc["x-indexed"], doc["y-indexed"])}
); + } tags.push( -
{doc.appearFrame}
- ); +
{ if (NumCast(targetDoc.currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0; }} onPointerOver={() => { if (NumCast(targetDoc.currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0.5; }} onClick={e => { this.toggleDisplayMovement(doc); e.stopPropagation(); }} style={{ backgroundColor: doc.displayMovement ? "#aedff8" : "#c8c8c8", top: NumCast(doc.y), left: NumCast(doc.x) }}> +
{ e.stopPropagation(); this.prevAppearFrame(doc, index); }} />
+
{doc.appearFrame}
+
{ e.stopPropagation(); this.nextAppearFrame(doc, index); }} />
+
); }); return tags; } - - - @computed get moreInfoDropdown() { - return (
); + @undoBatch + @action + nextAppearFrame = (doc: Doc, i: number): void => { + console.log("next"); + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + const appearFrame = Cast(doc.appearFrame, "number", null); + if (appearFrame === undefined) { + doc.appearFrame = 0; + } + doc.appearFrame = appearFrame + 1; + const olist = new List(numberRange(NumCast(targetDoc.lastFrame)).map(t => targetDoc.presProgressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1)); + doc["opacity-indexed"] = olist; + console.log(doc.appearFrame); } - @computed get effectOpenBracket() { + @undoBatch + @action + prevAppearFrame = (doc: Doc, i: number): void => { + console.log("prev"); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); - if (targetDoc.presEffect && this.itemIndex) { - return ("<" + targetDoc.presEffect + "when=" + this.layoutDoc === PresBox.Instance.childDocs[this.itemIndex].presentationTargetDoc + ">"); - } else return; + const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + const appearFrame = Cast(doc.appearFrame, "number", null); + if (appearFrame === undefined) { + doc.appearFrame = 0; + } + doc.appearFrame = Math.max(0, appearFrame - 1); + const olist = new List(numberRange(NumCast(targetDoc.lastFrame)).map(t => targetDoc.presProgressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1)); + doc["opacity-indexed"] = olist; + console.log(doc.appearFrame); } - @computed get effectCloseBracket() { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); - if (targetDoc.presEffect && this.itemIndex) { - return (""); - } else return; + @computed get moreInfoDropdown() { + return (
); } @computed get toolbar() { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - + const parent = document.getElementById('toolbarContainer'); + let width = 0; + if (parent) width = parent.offsetWidth; + console.log(width); if (activeItem) { return ( <> -
+
{"Add new slide"}
}>
-
+
-
+
{"View paths"}
}>
+ +
{/*
*/}
-
  Transitions
+
400 ? "block" : "none" }} className="toolbar-buttonText">  Transitions
-
  Progressivize
+
400 ? "block" : "none" }} className="toolbar-buttonText">  Progressivize
-
+
@@ -977,7 +1183,7 @@ export class PresBox extends ViewBoxBaseComponent render() { this.childDocs.slice(); // needed to insure that the childDocs are loaded for looking up fields const mode = StrCast(this.rootDoc._viewType) as CollectionViewType; - return
+ return
) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} /> @@ -864,9 +902,22 @@ export class PresBox extends ViewBoxBaseComponent tagDoc.currentFrame = 0; CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0); } + let lastFrame: number = 0; + childDocs.forEach((doc) => { + if (NumCast(doc.appearFrame) > lastFrame) lastFrame = NumCast(doc.appearFrame); + }); CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0); tagDoc.currentFrame = Math.max(0, (currentFrame || 0) + 1); - tagDoc.lastFrame = Math.max(NumCast(tagDoc.currentFrame), NumCast(tagDoc.lastFrame)); + tagDoc.lastFrame = Math.max(NumCast(tagDoc.currentFrame), lastFrame); + if (tagDoc.zoomProgressivize) { + const resize = document.getElementById('resizable'); + if (resize) { + resize.style.width = this.checkList(tagDoc, tagDoc["width-indexed"]) + 'px'; + resize.style.height = this.checkList(tagDoc, tagDoc["height-indexed"]) + 'px'; + resize.style.top = this.checkList(tagDoc, tagDoc["top-indexed"]) + 'px'; + resize.style.left = this.checkList(tagDoc, tagDoc["left-indexed"]) + 'px'; + } + } } @undoBatch @@ -880,6 +931,15 @@ export class PresBox extends ViewBoxBaseComponent } CollectionFreeFormDocumentView.gotoKeyframe(childDocs.slice()); tagDoc.currentFrame = Math.max(0, (currentFrame || 0) - 1); + if (tagDoc.zoomProgressivize) { + const resize = document.getElementById('resizable'); + if (resize) { + resize.style.width = this.checkList(tagDoc, tagDoc["width-indexed"]) + 'px'; + resize.style.height = this.checkList(tagDoc, tagDoc["height-indexed"]) + 'px'; + resize.style.top = this.checkList(tagDoc, tagDoc["top-indexed"]) + 'px'; + resize.style.left = this.checkList(tagDoc, tagDoc["left-indexed"]) + 'px'; + } + } } @computed get progressivizeDropdown() { @@ -936,7 +996,6 @@ export class PresBox extends ViewBoxBaseComponent zoomProgressivize = (e: React.MouseEvent) => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); - targetDoc.currentFrame = targetDoc.lastFrame; if (targetDoc?.zoomProgressivize) { targetDoc.zoomProgressivize = false; } else { @@ -956,7 +1015,6 @@ export class PresBox extends ViewBoxBaseComponent if (activeItem.zoomProgressivize) { console.log("progressivize"); targetDoc.currentFrame = 0; - CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true); } } @@ -1050,6 +1108,7 @@ export class PresBox extends ViewBoxBaseComponent opacity: 1, stroke: "#000000", strokeWidth: 2, + strokeDasharray: '10 5', }} fill="none" />); @@ -1062,6 +1121,167 @@ export class PresBox extends ViewBoxBaseComponent else doc.displayMovement = true; } + private _isDraggingTL = false; + private _isDraggingTR = false; + private _isDraggingBR = false; + private _isDraggingBL = false; + private _isDragging = false; + + //Adds event listener so knows pointer is down and moving + onPointerMid = (e: React.PointerEvent): void => { + e.stopPropagation(); + e.preventDefault(); + this._isDragging = true; + document.removeEventListener("pointermove", this.onPointerMove); + document.addEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + document.addEventListener("pointerup", this.onPointerUp); + } + + //Adds event listener so knows pointer is down and moving + onPointerBR = (e: React.PointerEvent): void => { + e.stopPropagation(); + e.preventDefault(); + this._isDraggingBR = true; + document.removeEventListener("pointermove", this.onPointerMove); + document.addEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + document.addEventListener("pointerup", this.onPointerUp); + } + + //Adds event listener so knows pointer is down and moving + onPointerBL = (e: React.PointerEvent): void => { + e.stopPropagation(); + e.preventDefault(); + this._isDraggingBL = true; + document.removeEventListener("pointermove", this.onPointerMove); + document.addEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + document.addEventListener("pointerup", this.onPointerUp); + } + + //Adds event listener so knows pointer is down and moving + onPointerTR = (e: React.PointerEvent): void => { + e.stopPropagation(); + e.preventDefault(); + this._isDraggingTR = true; + document.removeEventListener("pointermove", this.onPointerMove); + document.addEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + document.addEventListener("pointerup", this.onPointerUp); + } + + //Adds event listener so knows pointer is down and moving + onPointerTL = (e: React.PointerEvent): void => { + e.stopPropagation(); + e.preventDefault(); + this._isDraggingTL = true; + document.removeEventListener("pointermove", this.onPointerMove); + document.addEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + document.addEventListener("pointerup", this.onPointerUp); + } + + //Removes all event listeners + onPointerUp = (e: PointerEvent): void => { + e.stopPropagation(); + e.preventDefault(); + this._isDraggingTL = false; + this._isDraggingTR = false; + this._isDraggingBL = false; + this._isDraggingBR = false; + this._isDragging = false; + document.removeEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + } + + //Adjusts the value in NodeStore + onPointerMove = (e: PointerEvent): void => { + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + e.stopPropagation(); + e.preventDefault(); + const doc = document.getElementById('resizable'); + if (doc) { + let height = doc.offsetHeight; + let width = doc.offsetWidth; + let top = doc.offsetTop; + let left = doc.offsetLeft; + //Bottom right + if (this._isDraggingBR) { + let newHeight = height += e.movementY; + doc.style.height = newHeight + 'px'; + let newWidth = width += e.movementX; + doc.style.width = newWidth + 'px'; + // Bottom left + } else if (this._isDraggingBL) { + let newHeight = height += e.movementY; + doc.style.height = newHeight + 'px'; + let newWidth = width -= e.movementX; + doc.style.width = newWidth + 'px'; + let newLeft = left += e.movementX; + doc.style.left = newLeft + 'px'; + // Top right + } else if (this._isDraggingTR) { + let newWidth = width += e.movementX; + doc.style.width = newWidth + 'px'; + let newHeight = height -= e.movementY; + doc.style.height = newHeight + 'px'; + let newTop = top += e.movementY; + doc.style.top = newTop + 'px'; + // Top left + } else if (this._isDraggingTL) { + const newWidth = width -= e.movementX; + doc.style.width = newWidth + 'px'; + const newHeight = height -= e.movementY; + doc.style.height = newHeight + 'px'; + const newTop = top += e.movementY; + doc.style.top = newTop + 'px'; + const newLeft = left += e.movementX; + doc.style.left = newLeft + 'px'; + } else if (this._isDragging) { + let newTop = top += e.movementY; + doc.style.top = newTop + 'px'; + let newLeft = left += e.movementX; + doc.style.left = newLeft + 'px'; + } + this.updateList(targetDoc, targetDoc["width-indexed"], width); + this.updateList(targetDoc, targetDoc["height-indexed"], height); + this.updateList(targetDoc, targetDoc["top-indexed"], top); + this.updateList(targetDoc, targetDoc["left-indexed"], left); + } + } + + @action + checkList = (doc: Doc, list: any): number => { + const x: List = list; + return x[NumCast(doc.currentFrame)]; + } + + @action + updateList = (doc: Doc, list: any, val: number) => { + const x: List = list; + x[NumCast(doc.currentFrame)] = val; + list = x; + } + + @computed get zoomProgressivizeContainer() { + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + CollectionFreeFormDocumentView.setupZoom(targetDoc, true); + + return ( +
+
+
+
+
+
+
+
+ ); + } + @computed get progressivizeChildDocs() { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); @@ -1117,12 +1337,16 @@ export class PresBox extends ViewBoxBaseComponent return (
); } + @observable + toolbarWidth = (): number => { + console.log(this.props.PanelWidth()); + const width = this.props.PanelWidth(); + return width; + } + + @computed get toolbar() { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const parent = document.getElementById('toolbarContainer'); - let width = 0; - if (parent) width = parent.offsetWidth; - console.log(width); if (activeItem) { return ( <> @@ -1133,22 +1357,22 @@ export class PresBox extends ViewBoxBaseComponent
{"View paths"}
}>
-
{this.expandBoolean ? "Minimize all" : "Expand all"}
}> -
{ this.toggleExpand(); this.childDocs.forEach((doc, ind) => { doc.presExpandInlineButton = !doc.presExpandInlineButton; }); }}> - +
{this.expandBoolean ? "Expand all" : "Minimize all"}
}> +
{ this.toggleExpand(); this.childDocs.forEach((doc, ind) => { if (this.expandBoolean) doc.presExpandInlineButton = false; else doc.presExpandInlineButton = true; }); }}> +
{/*
*/}
{"Transitions"}
}>
-
400 ? "block" : "none" }} className="toolbar-buttonText">  Transitions
+
380 ? "block" : "none" }} className="toolbar-buttonText">  Transitions
{"Progressivize"}
}>
-
400 ? "block" : "none" }} className="toolbar-buttonText">  Progressivize
+
380 ? "block" : "none" }} className="toolbar-buttonText">  Progressivize
@@ -1167,10 +1391,10 @@ export class PresBox extends ViewBoxBaseComponent } else { return ( <> -
+
{"Add new slide"}
}>
-
-
+
+
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss index 51ad6839c..c87a1583a 100644 --- a/src/client/views/presentationview/PresElementBox.scss +++ b/src/client/views/presentationview/PresElementBox.scss @@ -144,6 +144,9 @@ width: 20px; height: 20px; display: flex; + font-size: 75%; + background-color: black; + color: white; justify-content: center; align-items: center; } @@ -157,6 +160,9 @@ width: 20px; height: 20px; display: flex; + font-size: 75%; + background-color: black; + color: white; justify-content: center; align-items: center; } @@ -170,6 +176,8 @@ height: 20px; z-index: 200; display: flex; + background-color: black; + color: white; justify-content: center; align-items: center; } \ No newline at end of file diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 53d922cee..6c6bad06a 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -186,6 +186,7 @@ export class PresElementBox extends ViewBoxBaseComponent e.stopPropagation()} + onPointerDown={e => { + this.props.dropAction; + e.stopPropagation(); + }} > {treecontainer ? (null) : <>
@@ -258,8 +262,7 @@ export class PresElementBox extends ViewBoxBaseComponent
{"Movement speed"}
}>
{this.transition}
{"Duration of visibility"}
}>
{this.duration}
-
{"Remove from presentation"}
}>
-
{this.rootDoc.presExpandInlineButton ? "Expand" : "Minimize"}
}>
+
{this.rootDoc.presExpandInlineButton ? "Minimize" : "Expand"}
}>
{ e.stopPropagation(); this.presExpandDocumentClick(); }}> e.stopPropagation()} /> - +
}
diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts index 799a3ee6f..24b70057a 100644 --- a/src/typings/index.d.ts +++ b/src/typings/index.d.ts @@ -10,7 +10,7 @@ declare module 'fit-curve'; declare module 'reveal'; declare module 'react-reveal'; declare module 'react-reveal/makeCarousel'; - +declare module 'react-resizable-rotatable-draggable'; declare module '@react-pdf/renderer' { import * as React from 'react'; -- cgit v1.2.3-70-g09d2 From bdb52eb3090cae3f146a6777f18d53f54d1e1d0f Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Tue, 28 Jul 2020 23:48:12 +0800 Subject: scrollProgressivize + viewfinder --- src/client/util/DocumentManager.ts | 4 + src/client/views/.DS_Store | Bin 6148 -> 6148 bytes .../views/collections/CollectionDockingView.scss | 62 +++ .../views/collections/CollectionDockingView.tsx | 24 ++ .../collectionFreeForm/CollectionFreeFormView.tsx | 4 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 42 +- src/client/views/nodes/PresBox.scss | 118 +++++- src/client/views/nodes/PresBox.tsx | 436 +++++++++++++++------ .../views/presentationview/PresElementBox.tsx | 6 +- 9 files changed, 550 insertions(+), 146 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 237ea7675..d18eac374 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -127,6 +127,10 @@ export class DocumentManager { CollectionDockingView.AddRightSplit(doc); finished?.(); } + // static openInPlace = (doc: Doc, finished?: () => void) => { + // CollectionDockingView.AddTab(doc); + // finished?.(); + // } public jumpToDocument = async ( targetDoc: Doc, // document to display willZoom: boolean, // whether to zoom doc to take up most of screen diff --git a/src/client/views/.DS_Store b/src/client/views/.DS_Store index 3717a2923..3ce88292c 100644 Binary files a/src/client/views/.DS_Store and b/src/client/views/.DS_Store differ diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss index 1895c06a1..9b14df760 100644 --- a/src/client/views/collections/CollectionDockingView.scss +++ b/src/client/views/collections/CollectionDockingView.scss @@ -18,6 +18,68 @@ } } } + +.miniPres:hover { + opacity: 1; +} + +.miniPres { + position: absolute; + overflow: hidden; + right: 10; + top: 10; + opacity: 0.1; + transition: all 0.4s; + /* border: solid 1px; */ + color: white; + /* box-shadow: black 0.4vw 0.4vw 0.8vw; */ + + .miniPresOverlay { + display: grid; + grid-template-columns: auto auto auto auto auto auto auto auto; + grid-template-rows: 100%; + height: 100%; + justify-items: center; + align-items: center; + + .miniPres-button-text { + display: flex; + height: 30; + font-weight: 400; + min-width: 100%; + border-radius: 5px; + align-items: center; + justify-content: center; + transition: all 0.3s; + } + + .miniPres-divider { + width: 1px; + height: 80%; + border-right: solid 2px #5a5a5a; + } + + .miniPres-button { + display: flex; + height: 30; + min-width: 30; + border-radius: 100%; + align-items: center; + justify-content: center; + transition: all 0.3s; + } + + .miniPres-button:hover { + background-color: #5a5a5a; + } + + .miniPres-button-text:hover { + background-color: #5a5a5a; + } + } +} + + .lm_title { margin-top: 3px; border-radius: 5px; diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 53b2d5254..b82a33bd8 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -31,6 +31,8 @@ import { SnappingManager } from '../../util/SnappingManager'; import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; import { listSpec } from '../../../fields/Schema'; import { clamp } from 'lodash'; +import { PresBox } from '../nodes/PresBox'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; const _global = (window /* browser */ || global /* node */) as any; @observer @@ -838,6 +840,27 @@ export class DockedFrameRenderer extends React.Component { return false; }), emptyFunction, emptyFunction); } + getCurrentFrame = (): number => { + const presTargetDoc = Cast(PresBox.Instance.childDocs[PresBox.Instance.itemIndex].presentationTargetDoc, Doc, null); + const currentFrame = Cast(presTargetDoc.currentFrame, "number", null); + return currentFrame; + } + renderMiniPres() { + return
+
+
+
PresBox.Instance.startOrResetPres(PresBox.Instance.itemIndex)}>
+
+
+
Slide {PresBox.Instance.itemIndex + 1} / {PresBox.Instance.childDocs.length}
+ {/*
{this.getCurrentFrame}
*/} +
+
EXIT
+
+
; + } renderMiniMap() { return
{ ContainingCollectionView={undefined} ContainingCollectionDoc={undefined} /> {document._viewType === CollectionViewType.Freeform && !this._document?.hideMinimap ? this.renderMiniMap() : (null)} + {document._viewType === CollectionViewType.Freeform && this._document?.miniPres ? this.renderMiniPres() : (null)} ; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index e22b400c0..79540d19e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -214,7 +214,7 @@ export class CollectionFreeFormView extends CollectionSubView diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 480abdaed..5d1db6de2 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -76,22 +76,30 @@ export class CollectionFreeFormDocumentView extends DocComponent (i <= timecode && x !== undefined) || p === undefined ? x : p, undefined as any as number), + w: Cast(doc["w-indexed"], listSpec("number"), [NumCast(doc._width)]).reduce((p, x, i) => (i <= timecode && x !== undefined) || p === undefined ? x : p, undefined as any as number), x: Cast(doc["x-indexed"], listSpec("number"), [NumCast(doc.x)]).reduce((p, x, i) => (i <= timecode && x !== undefined) || p === undefined ? x : p, undefined as any as number), y: Cast(doc["y-indexed"], listSpec("number"), [NumCast(doc.y)]).reduce((p, y, i) => (i <= timecode && y !== undefined) || p === undefined ? y : p, undefined as any as number), opacity: Cast(doc["opacity-indexed"], listSpec("number"), [NumCast(doc.opacity, 1)]).reduce((p, o, i) => i <= timecode || p === undefined ? o : p, undefined as any as number), }); } - public static setValues(time: number, d: Doc, x?: number, y?: number, opacity?: number) { + public static setValues(time: number, d: Doc, x?: number, y?: number, h?: number, w?: number, opacity?: number) { const timecode = Math.round(time); + const hindexed = Cast(d["h-indexed"], listSpec("number"), []).slice(); + const windexed = Cast(d["w-indexed"], listSpec("number"), []).slice(); const xindexed = Cast(d["x-indexed"], listSpec("number"), []).slice(); const yindexed = Cast(d["y-indexed"], listSpec("number"), []).slice(); const oindexed = Cast(d["opacity-indexed"], listSpec("number"), []).slice(); xindexed[timecode] = x as any as number; yindexed[timecode] = y as any as number; + hindexed[timecode] = h as any as number; + windexed[timecode] = w as any as number; oindexed[timecode] = opacity as any as number; d["x-indexed"] = new List(xindexed); d["y-indexed"] = new List(yindexed); + d["h-indexed"] = new List(hindexed); + d["w-indexed"] = new List(windexed); d["opacity-indexed"] = new List(oindexed); } public static updateKeyframe(docs: Doc[], time: number) { @@ -99,7 +107,11 @@ export class CollectionFreeFormDocumentView extends DocComponent { const xindexed = Cast(doc['x-indexed'], listSpec("number"), null); const yindexed = Cast(doc['y-indexed'], listSpec("number"), null); + const hindexed = Cast(doc['h-indexed'], listSpec("number"), null); + const windexed = Cast(doc['w-indexed'], listSpec("number"), null); const opacityindexed = Cast(doc['opacity-indexed'], listSpec("number"), null); + hindexed?.length <= timecode + 1 && hindexed.push(undefined as any as number); + windexed?.length <= timecode + 1 && windexed.push(undefined as any as number); xindexed?.length <= timecode + 1 && xindexed.push(undefined as any as number); yindexed?.length <= timecode + 1 && yindexed.push(undefined as any as number); opacityindexed?.length <= timecode + 1 && opacityindexed.push(undefined as any as number); @@ -118,14 +130,24 @@ export class CollectionFreeFormDocumentView extends DocComponent(); const top = new List(); const left = new List(); + // width.push(100); + // height.push(100); + // top.push(0); + // left.push(0); width.push(NumCast(doc.width)); height.push(NumCast(doc.height)); top.push(NumCast(doc.height) / -2); left.push(NumCast(doc.width) / -2); - doc["width-indexed"] = width; - doc["height-indexed"] = height; - doc["top-indexed"] = top; - doc["left-indexed"] = left; + doc["viewfinder-width-indexed"] = width; + doc["viewfinder-height-indexed"] = height; + doc["viewfinder-top-indexed"] = top; + doc["viewfinder-left-indexed"] = left; + } + + public static setupScroll(doc: Doc, scrollProgressivize: boolean = false) { + const scrollList = new List(); + scrollList.push(NumCast(doc._scrollTop)); + doc["scroll-indexed"] = scrollList; } public static setupKeyframes(docs: Doc[], timecode: number, progressivize: boolean = false) { @@ -134,6 +156,8 @@ export class CollectionFreeFormDocumentView extends DocComponent(numberRange(timecode + 1).map(i => undefined) as any as number[]); const ylist = new List(numberRange(timecode + 1).map(i => undefined) as any as number[]); + const wlist = new List(numberRange(timecode + 1).map(i => undefined) as any as number[]); + const hlist = new List(numberRange(timecode + 1).map(i => undefined) as any as number[]); const olist = new List(numberRange(timecode + 1).map(t => progressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1)); let oarray: List; console.log(doc.title + "AF: " + doc.appearFrame); @@ -143,15 +167,21 @@ export class CollectionFreeFormDocumentView extends DocComponent; const PresBoxDocument = makeInterface(documentSchema); @@ -72,11 +72,9 @@ export class PresBox extends ViewBoxBaseComponent onPointerOver = () => { document.addEventListener("keydown", this.keyEvents, true); - // document.addEventListener("keydown", this.keyEvents, false); } onPointerLeave = () => { - // document.removeEventListener("keydown", this.keyEvents, false); document.removeEventListener("keydown", this.keyEvents, true); } @@ -96,18 +94,34 @@ export class PresBox extends ViewBoxBaseComponent presTargetDoc.currentFrame = curFrame + 1; if (presTargetDoc.zoomProgressivize) { const srcContext = Cast(presTargetDoc.context, Doc, null); - if (srcContext) { - srcContext._panX = this.checkList(presTargetDoc, presTargetDoc["left-indexed"]); - srcContext._panY = this.checkList(presTargetDoc, presTargetDoc["top-indexed"]); - srcContext._viewScale = this.checkList(presTargetDoc, presTargetDoc["width-indexed"]); - } - presTargetDoc._panY = this.checkList(presTargetDoc, presTargetDoc["left-indexed"]); - const resize = document.getElementById('resizable'); - if (resize) { - resize.style.width = this.checkList(presTargetDoc, presTargetDoc["width-indexed"]) + 'px'; - resize.style.height = this.checkList(presTargetDoc, presTargetDoc["height-indexed"]) + 'px'; - resize.style.top = this.checkList(presTargetDoc, presTargetDoc["top-indexed"]) + 'px'; - resize.style.left = this.checkList(presTargetDoc, presTargetDoc["left-indexed"]) + 'px'; + const srcDocView = DocumentManager.Instance.getDocumentView(srcContext); + if (srcContext && srcDocView) { + const layoutdoc = Doc.Layout(presTargetDoc); + const panelWidth: number = srcDocView.props.PanelWidth(); + const panelHeight: number = srcDocView.props.PanelHeight(); + console.log("srcDocView: " + srcDocView.props.PanelWidth()); + // console.log("layoutdoc._width: " + layoutdoc._width); + // console.log("srcContext._width: " + srcContext._width); + const newPanX = NumCast(presTargetDoc.x) + NumCast(layoutdoc._width) / 2; + const newPanY = NumCast(presTargetDoc.y) + NumCast(layoutdoc._height) / 2; + // const newPanX = NumCast(presTargetDoc.x) + panelWidth / 2; + // const newPanY = NumCast(presTargetDoc.y) + panelHeight / 2; + let newScale = 0.9 * Math.min(Number(panelWidth) / this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]), Number(panelHeight) / this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"])); + // srcContext._panX = newPanX + (NumCast(presTargetDoc._viewScale) * this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]) + NumCast(presTargetDoc._panX) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]) / 2)); + // srcContext._panY = newPanY + (NumCast(presTargetDoc._viewScale) * this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]) + NumCast(presTargetDoc._panY) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]) / 2)); + srcContext._panX = newPanX + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]) + NumCast(presTargetDoc._panX) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]) / 2)); + srcContext._panY = newPanY + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]) + NumCast(presTargetDoc._panY) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]) / 2)); + // srcContext._panX = newPanX + // srcContext._panY = newPanY + srcContext._viewScale = newScale; + console.log("X: " + srcContext._panX + ", Y: " + srcContext._panY + ", Scale: " + srcContext._viewScale); + const resize = document.getElementById('resizable'); + if (resize) { + resize.style.width = this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]) + 'px'; + resize.style.height = this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]) + 'px'; + resize.style.top = this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]) + 'px'; + resize.style.left = this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]) + 'px'; + } } } // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide @@ -322,8 +336,8 @@ export class PresBox extends ViewBoxBaseComponent this.updateCurrentPresentation(); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); - if (this._presTimer && this.layoutDoc.presStatus === "auto") { - clearInterval(this._presTimer); + if (this.layoutDoc.presStatus === "auto") { + if (this._presTimer) clearInterval(this._presTimer); this.layoutDoc.presStatus = "manual"; } else { this.layoutDoc.presStatus = "auto"; @@ -381,28 +395,48 @@ export class PresBox extends ViewBoxBaseComponent }); } - updateMinimize = action((e: React.ChangeEvent, mode: CollectionViewType) => { - if (BoolCast(this.layoutDoc.inOverlay) !== (mode === CollectionViewType.Invalid)) { - if (this.layoutDoc.inOverlay) { + updateMinimize = async () => { + const docToJump = this.childDocs[0]; + const aliasOf = await DocCastAsync(docToJump.aliasOf); + const srcContext = aliasOf && await DocCastAsync(aliasOf.context); + if (srcContext) { + if (srcContext.miniPres) { + document.removeEventListener("keydown", this.keyEvents, true); + srcContext.miniPres = false; Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc); CollectionDockingView.AddRightSplit(this.rootDoc); this.layoutDoc.inOverlay = false; } else { - const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); - this.rootDoc.x = pt[0];// 500;//e.clientX + 25; - this.rootDoc.y = pt[1];////e.clientY - 25; + document.addEventListener("keydown", this.keyEvents, true); + srcContext.miniPres = true; this.props.addDocTab?.(this.rootDoc, "close"); Doc.AddDocToList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc); } + + } - }); + // if (srcContext) { + // Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc); + // CollectionDockingView.AddRightSplit(this.rootDoc); + // this.layoutDoc.inOverlay = false; + // } + // else { + // const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); + // this.rootDoc.x = pt[0];// 500;//e.clientX + 25; + // this.rootDoc.y = pt[1];////e.clientY - 25; + // this.props.addDocTab?.(this.rootDoc, "close"); + // Doc.AddDocToList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc); + // } + // } + }; @undoBatch viewChanged = action((e: React.ChangeEvent) => { //@ts-ignore const viewType = e.target.selectedOptions[0].value as CollectionViewType; viewType === CollectionViewType.Stacking && (this.rootDoc._pivotField = undefined); // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here - this.updateMinimize(e, this.rootDoc._viewType = viewType); + // this.updateMinimize(this.rootDoc._viewType = viewType); + if (viewType === CollectionViewType.Stacking) this.rootDoc._gridGap = 5; }); @undoBatch @@ -411,19 +445,24 @@ export class PresBox extends ViewBoxBaseComponent const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); if (movement === 'zoom') { activeItem.presZoomButton = !activeItem.presZoomButton; - activeItem.presMovement = 'Zoom'; + if (activeItem.presZoomButton) activeItem.presMovement = 'Zoom'; + else activeItem.presMovement = 'None'; activeItem.presNavButton = false; } else if (movement === 'nav') { activeItem.presZoomButton = false; - activeItem.presMovement = 'Pan'; activeItem.presNavButton = !activeItem.presNavButton; + if (activeItem.presNavButton) activeItem.presMovement = 'Pan'; + else activeItem.presMovement = 'None'; } else if (movement === 'switch') { - activeItem.presMovement = 'Switch'; targetDoc.presTransition = 0; + activeItem.presSwitchButton = !activeItem.presSwitchButton; + if (activeItem.presSwitchButton) activeItem.presMovement = 'Switch'; + else activeItem.presMovement = 'None'; } else { activeItem.presMovement = 'None'; activeItem.presZoomButton = false; activeItem.presNavButton = false; + activeItem.presSwitchButton = false; } }); @@ -439,7 +478,7 @@ export class PresBox extends ViewBoxBaseComponent childLayoutTemplate = () => this.rootDoc._viewType !== CollectionViewType.Stacking ? undefined : this.presElement; removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc); getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight - panelHeight = () => this.props.PanelHeight() - 20; + panelHeight = () => this.props.PanelHeight() - 40; active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground) && (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false) @@ -465,9 +504,9 @@ export class PresBox extends ViewBoxBaseComponent //Regular click @action selectElement = (doc: Doc) => { - this._selectedArray = []; + // this._selectedArray = []; this.gotoDocument(this.childDocs.indexOf(doc), NumCast(this.itemIndex)); - this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]); + // this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]); console.log(this._selectedArray); } @@ -508,11 +547,11 @@ export class PresBox extends ViewBoxBaseComponent // Ctrl-A to select all } if ((e.metaKey || e.altKey) && e.keyCode === 65) { if (this.layoutDoc.presStatus === "edit") this._selectedArray = this.childDocs; - // left / a / up to go back - } if (e.keyCode === 37 || 65 || 38) { + // left(37) / a(65) / up(38) to go back + } if (e.keyCode === 37) { if (this.layoutDoc.presStatus !== "edit") this.back(); - // right / d / down to go to next - } if (e.keyCode === 39 || 68 || 40) { + // right (39) / d(68) / down(40) to go to next + } if (e.keyCode === 39) { if (this.layoutDoc.presStatus !== "edit") this.next(); // spacebar to 'present' or go to next slide } if (e.keyCode === 32) { @@ -526,6 +565,7 @@ export class PresBox extends ViewBoxBaseComponent @observable private progressivizeTools: boolean = false; @observable private moreInfoTools: boolean = false; @observable private playTools: boolean = false; + @observable private presentTools: boolean = false; @observable private pathBoolean: boolean = false; @observable private expandBoolean: boolean = false; @@ -548,6 +588,10 @@ export class PresBox extends ViewBoxBaseComponent // For toggling the tools for progressivize @action toggleProgressivize = () => { this.progressivizeTools = !this.progressivizeTools; + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + targetDoc.editZoomProgressivize = false; + targetDoc.editProgressivize = false; this.transitionTools = false; this.newDocumentTools = false; this.moreInfoTools = false; @@ -570,6 +614,16 @@ export class PresBox extends ViewBoxBaseComponent this.moreInfoTools = false; } + // For toggling the options when the user wants to select play + @action togglePresent = () => { + this.presentTools = !this.presentTools; + this.playTools = false; + this.transitionTools = false; + this.newDocumentTools = false; + this.progressivizeTools = false; + this.moreInfoTools = false; + } + @action toggleAllDropdowns() { this.transitionTools = false; this.newDocumentTools = false; @@ -659,11 +713,9 @@ export class PresBox extends ViewBoxBaseComponent strokeDasharray: '10 5', }} fill="none" - // markerStart="url(#square)" - // markerEnd="url(#arrow)" - marker-start="url(#markerSquare)" - marker-mid="url(#markerSquare)" - marker-end="url(#markerArrow)" + markerStart="url(#markerSquare)" + markerMid="url(#markerSquare)" + markerEnd="url(#markerArrow)" />); } @@ -725,6 +777,7 @@ export class PresBox extends ViewBoxBaseComponent const transitionThumbLocation = String(-9.48 * Number(transitionSpeed) + 93); const durationThumbLocation = String(9.48 * Number(duration)); const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None'; + activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : 'Zoom'; return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
@@ -742,8 +795,8 @@ export class PresBox extends ViewBoxBaseComponent
e.stopPropagation()} onClick={() => this.movementChanged('switch')}>Switch
- ) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} /> -
+ ) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} /> +
{transitionSpeed}s
Slow
@@ -784,7 +837,7 @@ export class PresBox extends ViewBoxBaseComponent
e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Roll'}>Roll
-
+
{"Enter from left"}
}>
targetDoc.presEffectDirection = 'left'}>
{"Enter from right"}
}>
targetDoc.presEffectDirection = 'right'}>
{"Enter from top"}
}>
targetDoc.presEffectDirection = 'top'}>
@@ -863,6 +916,24 @@ export class PresBox extends ViewBoxBaseComponent
{ type = "freeform"; })}>Freeform
+
+ Preset layouts: +
+
+
HEADER
+
Content goes here
+
+
+
HEADER
+
Some content
+
Some more content
+
+
+
HEADER
+
Content goes here
+
+
+
this.createNewSlide(title, type)}> Create New Slide @@ -877,10 +948,23 @@ export class PresBox extends ViewBoxBaseComponent return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
this.startOrResetPres(this.itemIndex)}> - Start from current slide + Present from current slide
this.startOrResetPres(0)}> - Start from first slide + Present from first slide +
+
+ ); + } + + @computed get presentDropdown() { + return ( +
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> +
+ Minimize +
+
this.startOrResetPres(0)}> + Sidebar view
); @@ -916,10 +1000,10 @@ export class PresBox extends ViewBoxBaseComponent if (tagDoc.zoomProgressivize) { const resize = document.getElementById('resizable'); if (resize) { - resize.style.width = this.checkList(tagDoc, tagDoc["width-indexed"]) + 'px'; - resize.style.height = this.checkList(tagDoc, tagDoc["height-indexed"]) + 'px'; - resize.style.top = this.checkList(tagDoc, tagDoc["top-indexed"]) + 'px'; - resize.style.left = this.checkList(tagDoc, tagDoc["left-indexed"]) + 'px'; + resize.style.width = this.checkList(tagDoc, tagDoc["viewfinder-width-indexed"]) + 'px'; + resize.style.height = this.checkList(tagDoc, tagDoc["viewfinder-height-indexed"]) + 'px'; + resize.style.top = this.checkList(tagDoc, tagDoc["viewfinder-top-indexed"]) + 'px'; + resize.style.left = this.checkList(tagDoc, tagDoc["viewfinder-left-indexed"]) + 'px'; } } } @@ -938,10 +1022,10 @@ export class PresBox extends ViewBoxBaseComponent if (tagDoc.zoomProgressivize) { const resize = document.getElementById('resizable'); if (resize) { - resize.style.width = this.checkList(tagDoc, tagDoc["width-indexed"]) + 'px'; - resize.style.height = this.checkList(tagDoc, tagDoc["height-indexed"]) + 'px'; - resize.style.top = this.checkList(tagDoc, tagDoc["top-indexed"]) + 'px'; - resize.style.left = this.checkList(tagDoc, tagDoc["left-indexed"]) + 'px'; + resize.style.width = this.checkList(tagDoc, tagDoc["viewfinder-width-indexed"]) + 'px'; + resize.style.height = this.checkList(tagDoc, tagDoc["viewfinder-height-indexed"]) + 'px'; + resize.style.top = this.checkList(tagDoc, tagDoc["viewfinder-top-indexed"]) + 'px'; + resize.style.left = this.checkList(tagDoc, tagDoc["viewfinder-left-indexed"]) + 'px'; } } } @@ -976,18 +1060,22 @@ export class PresBox extends ViewBoxBaseComponent
-
+
Child documents
Edit
-
-
Internal zoom
-
Edit
+
+
Internal zoom
+
Edit
-
+
Text progressivize
Edit
+
+
Scroll progressivize
+
Edit
+
@@ -995,30 +1083,59 @@ export class PresBox extends ViewBoxBaseComponent } } - //Progressivize Zoom + //Toggle whether the user edits or not + @action + editZoomProgressivize = (e: React.MouseEvent) => { + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + if (!targetDoc.editZoomProgressivize) { + targetDoc.editZoomProgressivize = true; + } else { + targetDoc.editZoomProgressivize = false; + } + } + + //Toggle whether the user edits or not @action - zoomProgressivize = (e: React.MouseEvent) => { + editScrollProgressivize = (e: React.MouseEvent) => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); - if (targetDoc?.zoomProgressivize) { - targetDoc.zoomProgressivize = false; + if (!targetDoc.editScrollProgressivize) { + targetDoc.editScrollProgressivize = true; } else { - targetDoc.zoomProgressivize = true; + targetDoc.editScrollProgressivize = false; } } + //Progressivize Zoom + @action + progressivizeScroll = (e: React.MouseEvent) => { + e.stopPropagation(); + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + activeItem.scrollProgressivize = !activeItem.scrollProgressivize; + const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + targetDoc.scrollProgressivize = !targetDoc.zoomProgressivize; + CollectionFreeFormDocumentView.setupScroll(targetDoc, true); + if (targetDoc.editScrollProgressivize) { + targetDoc.editScrollProgressivize = false; + targetDoc.currentFrame = 0; + targetDoc.lastFrame = 0; + } + } + + //Progressivize Zoom @action progressivizeZoom = (e: React.MouseEvent) => { e.stopPropagation(); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); activeItem.zoomProgressivize = !activeItem.zoomProgressivize; const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); - const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); targetDoc.zoomProgressivize = !targetDoc.zoomProgressivize; - console.log(targetDoc.zoomProgressivize); - if (activeItem.zoomProgressivize) { - console.log("progressivize"); + CollectionFreeFormDocumentView.setupZoom(targetDoc, true); + if (targetDoc.editZoomProgressivize) { + targetDoc.editZoomProgressivize = false; targetDoc.currentFrame = 0; + targetDoc.lastFrame = 0; } } @@ -1081,9 +1198,9 @@ export class PresBox extends ViewBoxBaseComponent targetDoc.editProgressivize = false; activeItem.presProgressivize = false; targetDoc.presProgressivize = false; - docs.forEach((doc, index) => { - doc.appearFrame = 0; - }); + // docs.forEach((doc, index) => { + // doc.appearFrame = 0; + // }); targetDoc.currentFrame = 0; targetDoc.lastFrame = 0; } @@ -1130,6 +1247,21 @@ export class PresBox extends ViewBoxBaseComponent private _isDraggingBR = false; private _isDraggingBL = false; private _isDragging = false; + // private _drag = ""; + + // onPointerDown = (e: React.PointerEvent): void => { + // e.stopPropagation(); + // e.preventDefault(); + // if (e.button === 0) { + // this._drag = e.currentTarget.id; + // console.log(this._drag); + // } + // document.removeEventListener("pointermove", this.onPointerMove); + // document.addEventListener("pointermove", this.onPointerMove); + // document.removeEventListener("pointerup", this.onPointerUp); + // document.addEventListener("pointerup", this.onPointerUp); + // } + //Adds event listener so knows pointer is down and moving onPointerMid = (e: React.PointerEvent): void => { @@ -1203,87 +1335,136 @@ export class PresBox extends ViewBoxBaseComponent onPointerMove = (e: PointerEvent): void => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + const tagDocView = DocumentManager.Instance.getDocumentView(targetDoc); e.stopPropagation(); e.preventDefault(); const doc = document.getElementById('resizable'); - if (doc) { + if (doc && tagDocView) { + console.log(tagDocView.props.ScreenToLocalTransform().Scale); let height = doc.offsetHeight; let width = doc.offsetWidth; let top = doc.offsetTop; let left = doc.offsetLeft; + // const newHeightB = height += (e.movementY * NumCast(targetDoc._viewScale)); + // const newHeightT = height -= (e.movementY * NumCast(targetDoc._viewScale)); + // const newWidthR = width += (e.movementX * NumCast(targetDoc._viewScale)); + // const newWidthL = width -= (e.movementX * NumCast(targetDoc._viewScale)); + // const newLeft = left += (e.movementX * NumCast(targetDoc._viewScale)); + // const newTop = top += (e.movementY * NumCast(targetDoc._viewScale)); + // switch (this._drag) { + // case "": break; + // case "resizer-br": + // doc.style.height = newHeightB + 'px'; + // doc.style.width = newWidthR + 'px'; + // break; + // case "resizer-bl": + // doc.style.height = newHeightB + 'px'; + // doc.style.width = newWidthL + 'px'; + // doc.style.left = newLeft + 'px'; + // break; + // case "resizer-tr": + // doc.style.width = newWidthR + 'px'; + // doc.style.height = newHeightT + 'px'; + // doc.style.top = newTop + 'px'; + // case "resizer-tl": + // doc.style.width = newWidthL + 'px'; + // doc.style.height = newHeightT + 'px'; + // doc.style.top = newTop + 'px'; + // doc.style.left = newLeft + 'px'; + // case "resizable": + // doc.style.top = newTop + 'px'; + // doc.style.left = newLeft + 'px'; + // } //Bottom right if (this._isDraggingBR) { - const newHeight = height += e.movementY; + const newHeight = height += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.height = newHeight + 'px'; - const newWidth = width += e.movementX; + const newWidth = width += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.width = newWidth + 'px'; // Bottom left } else if (this._isDraggingBL) { - const newHeight = height += e.movementY; + const newHeight = height += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.height = newHeight + 'px'; - const newWidth = width -= e.movementX; + const newWidth = width -= (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.width = newWidth + 'px'; - const newLeft = left += e.movementX; + const newLeft = left += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.left = newLeft + 'px'; // Top right } else if (this._isDraggingTR) { - const newWidth = width += e.movementX; + const newWidth = width += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.width = newWidth + 'px'; - const newHeight = height -= e.movementY; + const newHeight = height -= (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.height = newHeight + 'px'; - const newTop = top += e.movementY; + const newTop = top += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.top = newTop + 'px'; // Top left } else if (this._isDraggingTL) { - const newWidth = width -= e.movementX; + const newWidth = width -= (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.width = newWidth + 'px'; - const newHeight = height -= e.movementY; + const newHeight = height -= (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.height = newHeight + 'px'; - const newTop = top += e.movementY; + const newTop = top += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.top = newTop + 'px'; - const newLeft = left += e.movementX; + const newLeft = left += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.left = newLeft + 'px'; } else if (this._isDragging) { - const newTop = top += e.movementY; + const newTop = top += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.top = newTop + 'px'; - const newLeft = left += e.movementX; + const newLeft = left += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale); doc.style.left = newLeft + 'px'; } - this.updateList(targetDoc, targetDoc["width-indexed"], width); - this.updateList(targetDoc, targetDoc["height-indexed"], height); - this.updateList(targetDoc, targetDoc["top-indexed"], top); - this.updateList(targetDoc, targetDoc["left-indexed"], left); + this.updateList(targetDoc, targetDoc["viewfinder-width-indexed"], width); + this.updateList(targetDoc, targetDoc["viewfinder-height-indexed"], height); + this.updateList(targetDoc, targetDoc["viewfinder-top-indexed"], top); + this.updateList(targetDoc, targetDoc["viewfinder-left-indexed"], left); } } @action checkList = (doc: Doc, list: any): number => { const x: List = list; - return x[NumCast(doc.currentFrame)]; + if (x && x.length >= NumCast(doc.currentFrame) + 1) { + return x[NumCast(doc.currentFrame)]; + } else { + x.length = NumCast(doc.currentFrame) + 1; + x[NumCast(doc.currentFrame)] = x[NumCast(doc.currentFrame) - 1]; + return x[NumCast(doc.currentFrame)]; + } + } @action updateList = (doc: Doc, list: any, val: number) => { const x: List = list; - x[NumCast(doc.currentFrame)] = val; - list = x; + if (x && x.length >= NumCast(doc.currentFrame) + 1) { + x[NumCast(doc.currentFrame)] = val; + list = x; + } else { + x.length = NumCast(doc.currentFrame) + 1; + x[NumCast(doc.currentFrame)] = val; + list = x; + } + } + // scale: NumCast(targetDoc._viewScale), @computed get zoomProgressivizeContainer() { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); - CollectionFreeFormDocumentView.setupZoom(targetDoc, true); - - return ( -
-
-
-
-
-
-
-
- ); + if (targetDoc.editZoomProgressivize) { + return ( + <> +
+
+
+
+
+
+
+
+ + ); + } else return null; } @computed get progressivizeChildDocs() { @@ -1341,9 +1522,8 @@ export class PresBox extends ViewBoxBaseComponent return (
); } - @observable - toolbarWidth = (): number => { - console.log(this.props.PanelWidth()); + @computed + get toolbarWidth(): number { const width = this.props.PanelWidth(); return width; } @@ -1361,8 +1541,8 @@ export class PresBox extends ViewBoxBaseComponent
{"View paths"}
}>
-
{this.expandBoolean ? "Expand all" : "Minimize all"}
}> -
{ this.toggleExpand(); this.childDocs.forEach((doc, ind) => { if (this.expandBoolean) doc.presExpandInlineButton = false; else doc.presExpandInlineButton = true; }); }}> +
{this.expandBoolean ? "Minimize all" : "Expand all"}
}> +
{ this.toggleExpand(); this.childDocs.forEach((doc, ind) => { if (this.expandBoolean) doc.presExpandInlineButton = true; else doc.presExpandInlineButton = false; }); }}>
@@ -1370,13 +1550,13 @@ export class PresBox extends ViewBoxBaseComponent
{"Transitions"}
}>
-
380 ? "block" : "none" }} className="toolbar-buttonText">  Transitions
+
430 ? "block" : "none" }} className="toolbar-buttonText">  Transitions
{"Progressivize"}
}>
-
380 ? "block" : "none" }} className="toolbar-buttonText">  Progressivize
+
430 ? "block" : "none" }} className="toolbar-buttonText">  Progressivize
@@ -1401,9 +1581,6 @@ export class PresBox extends ViewBoxBaseComponent
- -

uppercase

-
@@ -1425,22 +1602,29 @@ export class PresBox extends ViewBoxBaseComponent onPointerDown={e => e.stopPropagation()} onChange={this.viewChanged} value={mode}> - + {/* */} - + {/* */}
-
this.startOrResetPres(0)}> -   - -
- { e.stopPropagation; this.togglePlay(); }} className="dropdown" icon={"angle-down"} /> - {this.playDropdown} -
-
this.layoutDoc.presStatus = "manual"}> - Present -
+ +
this.startOrResetPres(0)}> +   + +
+
{ e.stopPropagation; this.togglePlay(); }}> + + {this.playDropdown} +
+
+ +
this.layoutDoc.presStatus = "manual"}>   Present
+
{ e.stopPropagation; this.togglePresent(); }}> + + {this.presentDropdown} +
+
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 6c6bad06a..4d1195808 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -260,11 +260,11 @@ export class PresElementBox extends ViewBoxBaseComponent {`${this.targetDoc?.title}`}
-
{"Movement speed"}
}>
{this.transition}
-
{"Duration of visibility"}
}>
{this.duration}
+
{"Movement speed"}
}>
300 ? "block" : "none" }}>{this.transition}
+
{"Duration of visibility"}
}>
300 ? "block" : "none" }}>{this.duration}
{"Remove from presentation"}
}>
e.stopPropagation()} + // onPointerDown={e => e.stopPropagation()} onClick={e => { this.props.removeDocument?.(this.rootDoc); e.stopPropagation(); -- cgit v1.2.3-70-g09d2 From af592ffc89be5f7026f38ddec89956de9c001ed3 Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Sun, 2 Aug 2020 04:42:36 +0800 Subject: drag actions inc. multiple documents (fixed for all stacking collections) --- .../views/collections/CollectionStackingView.tsx | 24 +++- .../CollectionStackingViewFieldColumn.tsx | 4 +- .../views/collections/CollectionTreeView.tsx | 1 + src/client/views/nodes/PresBox.tsx | 131 ++++++++++++++++----- .../views/presentationview/PresElementBox.tsx | 52 +++++++- 5 files changed, 170 insertions(+), 42 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index c56ac9f77..dc6354383 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -286,14 +286,26 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) } }); if (super.onInternalDrop(e, de)) { - const newDoc = de.complete.docDragData.droppedDocuments[0]; + const newDocs = de.complete.docDragData.droppedDocuments; const docs = this.childDocList; if (docs) { - if (targInd === -1) targInd = docs.length; - else targInd = docs.indexOf(this.filteredChildren[targInd]); - const srcInd = docs.indexOf(newDoc); - docs.splice(srcInd, 1); - docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, newDoc); + newDocs.map((doc, i) => { + if (i === 0) { + if (targInd === -1) targInd = docs.length; + else targInd = docs.indexOf(this.filteredChildren[targInd]); + const srcInd = docs.indexOf(doc); + docs.splice(srcInd, 1); + docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, doc); + } else { + if (targInd === -1) targInd = docs.length; + else targInd = docs.indexOf(this.filteredChildren[targInd]); + const srcInd = docs.indexOf(doc); + const firstInd = docs.indexOf(newDocs[0]); + docs.splice(srcInd, 1); + // docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, doc); + docs.splice(firstInd + 1, 0, doc); + } + }); } } } diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 76af70cd1..890ab588c 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -350,7 +350,7 @@ export class CollectionStackingViewFieldColumn extends React.Component : (null); for (let i = 0; i < cols; i++) templatecols += `${style.columnWidth / style.numGroupColumns}px `; const chromeStatus = this.props.parent.props.Document._chromeStatus; - + const type = this.props.parent.props.Document.type; return <> {this.props.parent.Document._columnsHideIfEmpty ? (null) : headingView} { @@ -370,7 +370,7 @@ export class CollectionStackingViewFieldColumn extends React.Component - {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled') ? + {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled' && type !== 'presentation') ?
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 651357e5d..dd823f5d5 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -130,6 +130,7 @@ class TreeView extends React.Component { } protected createTreeDropTarget = (ele: HTMLDivElement) => { + console.log("ele"); this._treedropDisposer?.(); ele && (this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this), undefined, this.preTreeDrop.bind(this)), this.doc); } diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index b5f3fc204..28e340cf1 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -4,8 +4,8 @@ import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import { Doc, DocListCast, DocCastAsync, WidthSym } from "../../../fields/Doc"; import { InkTool } from "../../../fields/InkField"; -import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types"; -import { returnFalse, returnOne, numberRange } from "../../../Utils"; +import { BoolCast, Cast, NumCast, StrCast, ScriptCast } from "../../../fields/Types"; +import { returnFalse, returnOne, numberRange, setupMoveUpEvents, emptyFunction, returnTrue } from "../../../Utils"; import { documentSchema } from "../../../fields/documentSchemas"; import { DocumentManager } from "../../util/DocumentManager"; import { undoBatch } from "../../util/UndoManager"; @@ -15,7 +15,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import "./PresBox.scss"; import { ViewBoxBaseComponent } from "../DocComponent"; import { makeInterface, listSpec } from "../../../fields/Schema"; -import { Docs } from "../../documents/Documents"; +import { Docs, DocUtils } from "../../documents/Documents"; import { PrefetchProxy } from "../../../fields/Proxy"; import { ScriptField } from "../../../fields/ScriptField"; import { Scripting } from "../../util/Scripting"; @@ -29,6 +29,7 @@ import { Tooltip } from "@material-ui/core"; import { CollectionFreeFormViewChrome } from "../collections/CollectionMenu"; import { conformsTo } from "lodash"; import { translate } from "googleapis/build/src/apis/translate"; +import { DragManager, dropActionType } from "../../util/DragManager"; type PresBoxSchema = makeInterface<[typeof documentSchema]>; const PresBoxDocument = makeInterface(documentSchema); @@ -36,6 +37,7 @@ const PresBoxDocument = makeInterface(documentSchema); @observer export class PresBox extends ViewBoxBaseComponent(PresBoxDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresBox, fieldKey); } + private treedropDisposer?: DragManager.DragDropDisposer; static Instance: PresBox; @observable _isChildActive = false; @computed get childDocs() { return DocListCast(this.dataDoc[this.fieldKey]); } @@ -67,9 +69,9 @@ export class PresBox extends ViewBoxBaseComponent // document.addEventListener("keydown", this.keyEvents, false); } - // componentWillUnmount() { - // document.removeEventListener("keydown", this.keyEvents, false); - // } + componentWillUnmount() { + this.treedropDisposer?.(); + } onPointerOver = () => { document.addEventListener("keydown", this.keyEvents, true); @@ -236,21 +238,21 @@ export class PresBox extends ViewBoxBaseComponent * has the option open and last in the group. If not in the group, and it has * the option open, navigates to that element. */ - navigateToElement = (curDoc: Doc) => { + navigateToElement = async (curDoc: Doc) => { const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); - const srcContext = Cast(targetDoc.context, Doc, null); - const presCollection = Cast(this.rootDoc.presCollection, Doc, null); - const collectionDocView = DocumentManager.Instance.getDocumentView(presCollection); + const srcContext = await DocCastAsync(targetDoc.context); + const presCollection = Cast(this.layoutDoc.presCollection, Doc, null); + const collectionDocView = presCollection ? DocumentManager.Instance.getDocumentView(presCollection) : undefined; if (this.itemIndex >= 0) { if (targetDoc) { if (srcContext) this.layoutDoc.presCollection = srcContext; } else if (targetDoc) this.layoutDoc.presCollection = targetDoc; } - console.log("NC: " + srcContext.title); - console.log("PC: " + presCollection.title); + if (srcContext) console.log("NC: " + srcContext.title); + if (presCollection) console.log("PC: " + presCollection.title); if (collectionDocView) { - if (srcContext !== presCollection) { + if (srcContext && srcContext !== presCollection) { console.log("Case 1: new srcContext inside of current collection so add a new tab to the current pres collection"); console.log(collectionDocView); collectionDocView.props.addDocTab(srcContext, "inPlace"); @@ -270,14 +272,14 @@ export class PresBox extends ViewBoxBaseComponent if (docToJump === curDoc) { //checking if curDoc has navigation open if (curDoc.presNavButton && targetDoc) { - DocumentManager.Instance.jumpToDocument(targetDoc, false, undefined, srcContext); + await DocumentManager.Instance.jumpToDocument(targetDoc, false, undefined, srcContext); } else if (curDoc.presZoomButton && targetDoc) { //awaiting jump so that new scale can be found, since jumping is async - DocumentManager.Instance.jumpToDocument(targetDoc, true, undefined, srcContext); + await DocumentManager.Instance.jumpToDocument(targetDoc, true, undefined, srcContext); } } else { //awaiting jump so that new scale can be found, since jumping is async - targetDoc && DocumentManager.Instance.jumpToDocument(targetDoc, willZoom, undefined, srcContext); + targetDoc && await DocumentManager.Instance.jumpToDocument(targetDoc, willZoom, undefined, srcContext); } } @@ -424,9 +426,15 @@ export class PresBox extends ViewBoxBaseComponent whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive)); addDocumentFilter = (doc: Doc | Doc[]) => { const docs = doc instanceof Doc ? [doc] : doc; - docs.forEach(doc => { - doc.aliasOf instanceof Doc && (doc.presentationTargetDoc = doc.aliasOf); - !this.childDocs.includes(doc) && (doc.presZoomButton = true); + docs.forEach((doc, i) => { + if (this.childDocs.includes(doc)) { + console.log(docs.length); + console.log(i + 1); + if (docs.length === i + 1) return false; + } else { + doc.aliasOf instanceof Doc && (doc.presentationTargetDoc = doc.aliasOf); + !this.childDocs.includes(doc) && (doc.presZoomButton = true); + } }); return true; } @@ -439,6 +447,7 @@ export class PresBox extends ViewBoxBaseComponent // KEYS @observable _selectedArray: Doc[] = []; + @observable _eleArray: HTMLElement[] = []; @computed get listOfSelected() { const list = this._selectedArray.map((doc: Doc, index: any) => { @@ -462,18 +471,20 @@ export class PresBox extends ViewBoxBaseComponent //Command click @action - multiSelect = (doc: Doc) => { + multiSelect = (doc: Doc, ref: HTMLElement) => { this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]); + this._eleArray.push(ref); } //Shift click @action - shiftSelect = (doc: Doc) => { + shiftSelect = (doc: Doc, ref: HTMLElement) => { this._selectedArray = []; const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); if (activeItem) { for (let i = Math.min(this.itemIndex, this.childDocs.indexOf(doc)); i <= Math.max(this.itemIndex, this.childDocs.indexOf(doc)); i++) { this._selectedArray.push(this.childDocs[i]); + this._eleArray.push(ref); } } } @@ -1552,9 +1563,68 @@ export class PresBox extends ViewBoxBaseComponent } } + private _itemRef: React.RefObject = React.createRef(); + + + protected createPresDropTarget = (ele: HTMLDivElement) => { + console.log("created?"); + this.treedropDisposer?.(); + ele && (this.treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc, this.onInternalPreDrop.bind(this))); + if (ele) { + console.log("ele: " + ele.className) + } + } + + protected onInternalPreDrop(e: Event, de: DragManager.DropEvent, targetAction: dropActionType) { + console.log("preDrop?") + if (de.complete.docDragData) { + // if targetDropAction is, say 'alias', but we're just dragging within a collection, we want to ignore the targetAction. + // otherwise, the targetAction should become the actual action (which can still be overridden by the userDropAction -eg, shift/ctrl keys) + if (targetAction && !de.complete.docDragData.draggedDocuments.some(d => d.context === this.props.Document && this.childDocs.includes(d))) { + de.complete.docDragData.dropAction = targetAction; + } + e.stopPropagation(); + } + } + + @action + protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean { + console.log("drop in pres") + const docDragData = de.complete.docDragData; + ScriptCast(this.props.Document.dropConverter)?.script.run({ dragData: docDragData }); + if (docDragData && this.props.addDocument) { + console.log("docDragData && this.props.addDocument"); + let added = false; + const dropaction = docDragData.dropAction || docDragData.userDropAction; + if (dropaction && dropaction !== "move") { + console.log("dropaction && dropaction !== move"); + added = this.props.addDocument(docDragData.droppedDocuments); + } else if (docDragData.moveDocument) { + console.log("docDragData.moveDocument"); + const movedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] === d); + const addedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] !== d); + const res = addedDocs.length ? this.props.addDocument(addedDocs) : true; + if (movedDocs.length) { + const canAdd = this.props.Document._viewType === CollectionViewType.Pile || de.embedKey || + Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.props.Document); + added = docDragData.moveDocument(movedDocs, this.props.Document, canAdd ? this.props.addDocument : returnFalse); + } else added = res; + } else { + console.log("else"); + added = this.props.addDocument(docDragData.droppedDocuments); + } + added && e.stopPropagation(); + return added; + } + return false; + } + render() { this.childDocs.slice(); // needed to insure that the childDocs are loaded for looking up fields const mode = StrCast(this.rootDoc._viewType) as CollectionViewType; + // const addDocument = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => { + // return add(doc, relativeTo ? relativeTo : docs[i], before !== undefined ? before : false); + // }; return
+ Select Document + +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
Edit onClick Script
+
; + } + + @computed + get googlePhotosButton() { + const targetDoc = this.selectedDoc; + return !targetDoc ? (null) :
{"Export to Google Photos"}
}> +
{ + if (this.selectedDocumentView) { + GooglePhotos.Export.CollectionToAlbum({ collection: this.selectedDocumentView.Document }).then(console.log); + } + }}> + {} +
+
; + } + + @computed + get clustersButton() { + const targetDoc = this.selectedDoc; + return !targetDoc ? (null) :
{this.selectedDoc?.useClusters ? "Stop Showing Clusters" : "Show Clusters"}
}> +
+ {} +
+
; + } + + @action @undoBatch + changeFitToBox = () => { + this.selectedDoc && (this.selectedDoc._fitToBox = !this.selectedDoc._fitToBox); + } + + @action @undoBatch + changeClusters = () => { + this.selectedDoc && (this.selectedDoc.useClusters = !this.selectedDoc.useClusters); + } + + @computed + get fitContentButton() { + const targetDoc = this.selectedDoc; + return !targetDoc ? (null) :
{this.selectedDoc?._fitToBox ? "Stop Fitting Content" : "Fit Content"}
}> +
+ {} +
+
; + } + + // @computed + // get importButton() { + // const targetDoc = this.selectedDoc; + // return !targetDoc ? (null) :
{"Import a Document"}
}> + //
{ + // if (this.selectedDocumentView) { + // CollectionFreeFormView.importDocument(100, 100); + // } + // }}> + // {} + //
+ //
; + // } + + + render() { + if (!this.selectedDoc) return (null); + + const isText = this.selectedDoc[Doc.LayoutFieldKey(this.selectedDoc)] instanceof RichTextField; + const considerPull = isText && this.considerGoogleDocsPull; + const considerPush = isText && this.considerGoogleDocsPush; + const isImage = this.selectedDoc[Doc.LayoutFieldKey(this.selectedDoc)] instanceof ImageField; + const isCollection = this.selectedDoc.type === DocumentType.COL ? true : false; + const isFreeForm = this.selectedDoc._viewType === "freeform" ? true : false; + + return
+
+ {this.templateButton} +
+ {/*
+ {this.metadataButton} +
*/} +
+ {this.pinButton} +
+
+ {this.copyButton} +
+
+ {this.lockButton} +
+
+ {this.downloadButton} +
+
+
+
+ {this.deleteButton} +
+
+ {this.onClickButton} +
+
+ {this.sharingButton} +
+
+ {this.considerGoogleDocsPush} +
+
+ {this.considerGoogleDocsPull} +
+
+ {this.googlePhotosButton} +
+ {/*
+ {this.importButton} +
*/} + +
+ {this.clustersButton} +
+ +
+ {this.fitContentButton} +
+ +
+
; + } +} diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss index 9b14df760..6d93b2ba8 100644 --- a/src/client/views/collections/CollectionDockingView.scss +++ b/src/client/views/collections/CollectionDockingView.scss @@ -12,6 +12,7 @@ width: 100%; height: 100%; position: absolute; + .miniThumb { background: #25252525; position: absolute; @@ -89,6 +90,7 @@ transform: translate(0px, -3px); cursor: grab; } + .lm_title.focus-visible { cursor: text; } @@ -96,23 +98,25 @@ .lm_title_wrap { overflow: hidden; height: 19px; - margin-top: -3px; - display:inline-block; + margin-top: -2px; + display: inline-block; } + .lm_active .lm_title { border: solid 1px lightgray; } + .lm_header .lm_tab .lm_close_tab { position: absolute; text-align: center; } .lm_header .lm_tab { - padding-right : 20px; + padding-right: 20px; } .lm_popout { - display:none; + display: none; } .messageCounter { @@ -135,6 +139,7 @@ position: absolute; top: 0; left: 0; + // overflow: hidden; // bcz: menus don't show up when this is on (e.g., the parentSelectorMenu) .collectionDockingView-gear { padding-left: 5px; @@ -142,7 +147,10 @@ width: 18px; display: inline-block; margin: auto; + + display: none; } + .collectionDockingView-dragAsDocument { touch-action: none; position: absolute; diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index f658e9816..d685fac4e 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -1,9 +1,8 @@ import 'golden-layout/src/css/goldenlayout-base.css'; import 'golden-layout/src/css/goldenlayout-dark-theme.css'; -import { action, computed, Lambda, observable, reaction, runInAction, trace } from "mobx"; +import { action, computed, Lambda, observable, reaction, runInAction, trace, IReactionDisposer } from "mobx"; import { observer } from "mobx-react"; import * as ReactDOM from 'react-dom'; -import Measure from "react-measure"; import * as GoldenLayout from "../../../client/goldenLayout"; import { DateField } from '../../../fields/DateField'; import { Doc, DocListCast, Field, Opt, DataSym } from "../../../fields/Doc"; @@ -507,7 +506,6 @@ export class CollectionDockingView extends React.Component`; tab.titleElement[0].onclick = (e: any) => tab.titleElement[0].focus(); tab.titleElement[0].onchange = (e: any) => { tab.titleElement[0].size = e.currentTarget.value.length + 1; @@ -522,6 +520,10 @@ export class CollectionDockingView extends React.Component { + const view = DocumentManager.Instance.getDocumentView(doc); + view && SelectionManager.SelectDoc(view, false); + }; // shifts the focus to this tab when another tab is dragged over it tab.element[0].onmouseenter = (e: any) => { if (!this._isPointerDown || !SnappingManager.GetIsDragging()) return; @@ -676,10 +678,15 @@ export class DockedFrameRenderer extends React.Component { @observable private _panelHeight = 0; @observable private _document: Opt; @observable private _isActive: boolean = false; + _tabReaction: IReactionDisposer | undefined; get _stack(): any { return (this.props as any).glContainer.parent.parent; } + get _tab(): any { + const tab = (this.props as any).glContainer.tab.element[0] as HTMLElement; + return tab.getElementsByClassName("lm_title")?.[0]; + } constructor(props: any) { super(props); DocServer.GetRefField(this.props.documentId).then(action((f: Opt) => this._document = f as Doc)); @@ -740,9 +747,16 @@ export class DockedFrameRenderer extends React.Component { this.props.glContainer.layoutManager.on("activeContentItemChanged", this.onActiveContentItemChanged); this.props.glContainer.on("tab", this.onActiveContentItemChanged); this.onActiveContentItemChanged(); + this._tabReaction = reaction(() => ({ views: SelectionManager.SelectedDocuments(), color: StrCast(this._document?._backgroundColor, "white") }), + (data) => { + const selected = data.views.some(v => Doc.AreProtosEqual(v.props.Document, this._document)); + this._tab.style.backgroundColor = selected ? data.color : ""; + } + ); } componentWillUnmount() { + this._tabReaction?.(); this.props.glContainer.layoutManager.off("activeContentItemChanged", this.onActiveContentItemChanged); this.props.glContainer.off("tab", this.onActiveContentItemChanged); } diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 0ca86172f..fdd1b4e81 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -25,6 +25,8 @@ import { SelectionManager } from "../../util/SelectionManager"; import { DocumentView } from "../nodes/DocumentView"; import { ColorState } from "react-color"; import { ObjectField } from "../../../fields/ObjectField"; +import RichTextMenu from "../nodes/formattedText/RichTextMenu"; +import { RichTextField } from "../../../fields/RichTextField"; import { ScriptField } from "../../../fields/ScriptField"; import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { DocUtils } from "../../documents/Documents"; @@ -47,7 +49,7 @@ export default class CollectionMenu extends AntimodeMenu { componentDidMount() { reaction(() => SelectionManager.SelectedDocuments().length && SelectionManager.SelectedDocuments()[0], - (doc) => doc && this.SetSelection(doc)) + (doc) => doc && this.SetSelection(doc)); } @action @@ -160,7 +162,8 @@ export class CollectionViewBaseChrome extends React.Component { button['target-docFilters'] = this.target._docFilters instanceof ObjectField ? ObjectField.MakeCopy(this.target._docFilters as any as ObjectField) : ""; }, }; - _freeform_commands = [this._viewCommand, this._saveFilterCommand, this._fitContentCommand, this._clusterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand]; + @computed get _freeform_commands() { return Doc.UserDoc().noviceMode ? [this._viewCommand, this._saveFilterCommand] : [this._viewCommand, this._saveFilterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand]; } + _stacking_commands = [this._contentCommand, this._templateCommand]; _masonry_commands = [this._contentCommand, this._templateCommand]; _schema_commands = [this._templateCommand, this._narrativeCommand]; @@ -308,18 +311,32 @@ export class CollectionViewBaseChrome extends React.Component; } + @computed get selectedDocumentView() { + if (SelectionManager.SelectedDocuments().length) { + return SelectionManager.SelectedDocuments()[0]; + } else { return undefined; } + } + @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; } + @computed get isText() { + if (this.selectedDoc) { + return this.selectedDoc[Doc.LayoutFieldKey(this.selectedDoc)] instanceof RichTextField; + } + else return false; + } + render() { return (
- {this.props.type === CollectionViewType.Invalid || this.props.type === CollectionViewType.Docking ? (null) : this.viewModes} - {this.props.type === CollectionViewType.Docking ? (null) : this.templateChrome} -
+ {this.props.type === CollectionViewType.Invalid || + this.props.type === CollectionViewType.Docking || this.isText ? (null) : this.viewModes} + {this.props.type === CollectionViewType.Docking || this.isText ? (null) : this.templateChrome} + {/*
-
+
*/} {this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? (null) : ; + // return ; + return null; } render() { return !this.props.docView.layoutDoc ? (null) :
- {this.props.docView.props.renderDepth !== 0 ? (null) : + {this.props.docView.props.renderDepth !== 0 || this.isText ? (null) :
} -
+ {!!!this.isText ?
-
-
: null} + {!!!this.isText ?
this.document.editing = !this.document.editing)} > {NumCast(this.document.currentFrame)} -
-
+
: null} + {!!!this.isText ?
-
+
: null} - {!this.props.isOverlay || this.document.type !== DocumentType.WEB ? (null) : + {!this.props.isOverlay || this.document.type !== DocumentType.WEB || this.isText ? (null) : } - {!this.props.isOverlay || this.props.docView.layoutDoc.isAnnotating ? + {(!this.props.isOverlay || this.props.docView.layoutDoc.isAnnotating) && !this.isText ? <> {this.drawButtons} {this.widthPicker} @@ -566,6 +602,7 @@ export class CollectionFreeFormViewChrome extends React.Component : (null) } + {this.isText ? : null}
; } } diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 5553bbbb7..f67e049fd 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -253,7 +253,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
this.typesDropdownChange(!this._openTypes)}> - +
{this._openTypes ? allColumnTypes : justColType}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 425dc90e4..a104ac011 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -227,6 +227,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) addDocTab={this.addDocTab} bringToFront={returnFalse} ContentScaling={returnOne} + scriptContext={this.props.scriptContext} pinToPres={this.props.pinToPres} />; } diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 26d2ee8a3..68c233a16 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -351,7 +351,7 @@ export class CollectionStackingViewFieldColumn extends React.Component +
(schemaCtor: (doc: Doc) => T, moreProps?: const reg = new RegExp(Utils.prepend(""), "g"); const modHtml = srcUrl ? html.replace(reg, srcUrl) : html; const htmlDoc = Docs.Create.HtmlDocument(modHtml, { ...options, title: "-web page-", _width: 300, _height: 300 }); - Doc.GetProto(htmlDoc)["data-text"] = Doc.GetProto(htmlDoc)["text"] = text; + Doc.GetProto(htmlDoc)["data-text"] = Doc.GetProto(htmlDoc).text = text; this.props.addDocument(htmlDoc); if (srcWeb) { const focusNode = (SelectionManager.SelectedDocuments()[0].ContentDiv?.getElementsByTagName("iframe")[0].contentDocument?.getSelection()?.focusNode as any); diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index b8996c178..e5c4b9187 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -90,7 +90,10 @@ class TreeView extends React.Component { get displayName() { return "TreeView(" + this.doc.title + ")"; } // this makes mobx trace() statements more descriptive get defaultExpandedView() { return this.childDocs ? this.fieldKey : StrCast(this.doc.defaultExpandedView, this.noviceMode ? "layout" : "fields"); } @observable _overrideTreeViewOpen = false; // override of the treeViewOpen field allowing the display state to be independent of the document's state - set treeViewOpen(c: boolean) { if (this.props.treeViewPreventOpen) this._overrideTreeViewOpen = c; else this.doc.treeViewOpen = this._overrideTreeViewOpen = c; } + set treeViewOpen(c: boolean) { + if (this.props.treeViewPreventOpen) this._overrideTreeViewOpen = c; + else this.doc.treeViewOpen = this._overrideTreeViewOpen = c; + } @computed get treeViewOpen() { return (!this.props.treeViewPreventOpen && !this.doc.treeViewPreventOpen && BoolCast(this.doc.treeViewOpen)) || this._overrideTreeViewOpen; } @computed get treeViewExpandedView() { return StrCast(this.doc.treeViewExpandedView, this.defaultExpandedView); } @computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.containingCollection.maxEmbedHeight, 200); } @@ -101,7 +104,7 @@ class TreeView extends React.Component { const layout = Doc.LayoutField(this.doc) instanceof Doc ? Doc.LayoutField(this.doc) as Doc : undefined; return ((this.props.dataDoc ? DocListCast(this.props.dataDoc[field]) : undefined) || // if there's a data doc for an expanded template, use it's data field (layout ? DocListCast(layout[field]) : undefined) || // else if there's a layout doc, display it's fields - DocListCast(this.doc[field])) as Doc[]; // otherwise use the document's data field + DocListCast(this.doc[field])); // otherwise use the document's data field } @computed get childDocs() { return this.childDocList(this.fieldKey); } @computed get childLinks() { return this.childDocList("links"); } diff --git a/src/client/views/collections/CollectionView.scss b/src/client/views/collections/CollectionView.scss index b630f9cf8..a5aef86de 100644 --- a/src/client/views/collections/CollectionView.scss +++ b/src/client/views/collections/CollectionView.scss @@ -24,6 +24,7 @@ border-right: unset; z-index: 2; } + .collectionTimeView-treeView { display: flex; flex-direction: column; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 7e7ea6786..62e8dc26a 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -78,6 +78,7 @@ export interface CollectionViewCustomProps { childLayoutTemplate?: () => Opt; // specify a layout Doc template to use for children of the collection childLayoutString?: string; // specify a layout string to use for children of the collection childOpacity?: () => number; + hideFilter?: true; } export interface CollectionRenderProps { @@ -309,7 +310,7 @@ export class CollectionView extends Touchable this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" }); + !Doc.UserDoc().noviceMode ? optionItems.splice(0, 0, { description: `${this.props.Document.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" }) : null; if (this.props.Document.childLayout instanceof Doc) { optionItems.push({ description: "View Child Layout", event: () => this.props.addDocTab(this.props.Document.childLayout as Doc, "onRight"), icon: "project-diagram" }); } @@ -368,7 +369,7 @@ export class CollectionView extends Touchable this.props.PanelWidth() - this.facetWidth(); + bodyPanelWidth = () => this.props.PanelWidth(); facetWidth = () => Math.max(0, Math.min(this.props.PanelWidth() - 25, this._facetWidth)); @computed get dataDoc() { @@ -490,6 +491,7 @@ export class CollectionView extends Touchable this._facetWidth = this.facetWidth() < 15 ? Math.min(this.props.PanelWidth() - 25, 200) : 0), false); } + filterBackground = () => "rgba(105, 105, 105, 0.432)"; get ignoreFields() { return ["_docFilters", "_docRangeFilters"]; } // this makes the tree view collection ignore these filters (otherwise, the filters would filter themselves) @computed get scriptField() { @@ -559,6 +561,7 @@ export class CollectionView extends Touchable
; } + childLayoutTemplate = () => this.props.childLayoutTemplate?.() || Cast(this.props.Document.childLayoutTemplate, Doc, null); childLayoutString = this.props.childLayoutString || StrCast(this.props.Document.childLayoutString); @@ -588,11 +591,11 @@ export class CollectionView extends Touchable } - {this.facetWidth() < 10 ? (null) : this.filterView} + {this.facetWidth() < 10 ? (null) : this.filterView} */}
); } } diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx index 8c0b8de9d..532dd6abc 100644 --- a/src/client/views/collections/ParentDocumentSelector.tsx +++ b/src/client/views/collections/ParentDocumentSelector.tsx @@ -42,14 +42,14 @@ export class SelectorContextMenu extends React.Component { async fetchDocuments() { const aliases = (await SearchUtil.GetAliasesOfDocument(this.props.Document)); const containerProtoSets = await Promise.all(aliases.map(async alias => - await Promise.all((await SearchUtil.Search("", true, { fq: `data_l:"${alias[Id]}"` })).docs))); + ((await SearchUtil.Search("", true, { fq: `data_l:"${alias[Id]}"` })).docs))); const containerProtos = containerProtoSets.reduce((p, set) => { set.map(s => p.add(s)); return p; }, new Set()); const containerSets = await Promise.all(Array.from(containerProtos.keys()).map(async container => { - return (await SearchUtil.GetAliasesOfDocument(container)); + return (SearchUtil.GetAliasesOfDocument(container)); })); const containers = containerSets.reduce((p, set) => { set.map(s => p.add(s)); return p; }, new Set()); const doclayoutSets = await Promise.all(Array.from(containers.keys()).map(async (dp) => { - return (await SearchUtil.GetAliasesOfDocument(dp)); + return (SearchUtil.GetAliasesOfDocument(dp)); })); const doclayouts = Array.from(doclayoutSets.reduce((p, set) => { set.map(s => p.add(s)); return p; }, new Set()).keys()); runInAction(() => { diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx index cde795098..7e2840c2c 100644 --- a/src/client/views/collections/SchemaTable.tsx +++ b/src/client/views/collections/SchemaTable.tsx @@ -148,7 +148,7 @@ export class SchemaTable extends React.Component { } @action - changeTitleMode = () => this._showTitleDropdown = !this._showTitleDropdown; + changeTitleMode = () => this._showTitleDropdown = !this._showTitleDropdown @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); } @computed get tableColumns(): Column[] { @@ -208,7 +208,7 @@ export class SchemaTable extends React.Component { }}> {col.heading}
; - const sortIcon = col.desc === undefined ? "circle" : col.desc === true ? "caret-down" : "caret-up"; + const sortIcon = col.desc === undefined ? "caret-right" : col.desc === true ? "caret-down" : "caret-up"; const header =
{ {keysDropdown}
this.changeSorting(col)} - style={{ paddingRight: "6px", display: "inline" }}> + style={{ paddingRight: "6px", marginLeft: "4px", display: "inline" }}>
this.props.openHeader(col, e.clientX, e.clientY)} style={{ float: "right", paddingRight: "6px" }}> - +
; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 151acb64d..109808956 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1145,7 +1145,7 @@ export class CollectionFreeFormView extends CollectionSubView { TraceMobx(); return this.doLayoutComputation }, + this._layoutComputeReaction = reaction(() => this.doLayoutComputation, (elements) => this._layoutElements = elements || [], { fireImmediately: true, name: "doLayout" }); @@ -1240,13 +1240,15 @@ export class CollectionFreeFormView extends CollectionSubView { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document[this.scaleFieldKey] = 1; }, icon: "compress-arrows-alt" }); appearanceItems.push({ description: `${this.fitToContent ? "Make Zoomable" : "Scale to Window"}`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" }); - appearanceItems.push({ description: "Arrange contents in grid", event: this.layoutDocsInGrid, icon: "table" }); + !Doc.UserDoc().noviceMode ? appearanceItems.push({ description: "Arrange contents in grid", event: this.layoutDocsInGrid, icon: "table" }) : null; !appearance && ContextMenu.Instance.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" }); const viewctrls = ContextMenu.Instance.findByDescription("UI Controls..."); const viewCtrlItems = viewctrls && "subitems" in viewctrls ? viewctrls.subitems : []; - viewCtrlItems.push({ description: (Doc.UserDoc().showSnapLines ? "Hide" : "Show") + " Snap Lines", event: () => Doc.UserDoc().showSnapLines = !Doc.UserDoc().showSnapLines, icon: "compress-arrows-alt" }); - viewCtrlItems.push({ description: (this.Document.useClusters ? "Hide" : "Show") + " Clusters", event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" }); + + + !Doc.UserDoc().noviceMode ? viewCtrlItems.push({ description: (Doc.UserDoc().showSnapLines ? "Hide" : "Show") + " Snap Lines", event: () => Doc.UserDoc().showSnapLines = !Doc.UserDoc().showSnapLines, icon: "compress-arrows-alt" }) : null; + !Doc.UserDoc().noviceMode ? viewCtrlItems.push({ description: (this.Document.useClusters ? "Hide" : "Show") + " Clusters", event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" }) : null; !viewctrls && ContextMenu.Instance.addItem({ description: "UI Controls...", subitems: viewCtrlItems, icon: "eye" }); const options = ContextMenu.Instance.findByDescription("Options..."); @@ -1291,7 +1293,7 @@ export class CollectionFreeFormView extends CollectionSubView { SearchUtil.Search(`{!join from=id to=proto_i}id:link*`, true, {}).then(docs => { docs.docs.forEach(d => LinkManager.Instance.addLink(d)); - }) + }); }, 2000); // need to give solr some time to update so that this query will find any link docs we've added. } } diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx index ddc282e57..6263be261 100644 --- a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx +++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx @@ -13,7 +13,6 @@ import AntimodeMenu from "../../AntimodeMenu"; import "./FormatShapePane.scss"; import { undoBatch } from "../../../util/UndoManager"; import { ColorState, SketchPicker } from 'react-color'; -import { DocumentView } from "../../../views/nodes/DocumentView" @observer export default class FormatShapePane extends AntimodeMenu { @@ -124,12 +123,12 @@ export default class FormatShapePane extends AntimodeMenu { console.log(ink); if (ink) { const newPoints: { X: number, Y: number }[] = []; - for (var j = 0; j < ink.length; j++) { + ink.forEach(i => { // (new x — oldx) + (oldxpoint * newWidt)/oldWidth - const newX = (doc.x - oldX) + (ink[j].X * doc._width) / oldWidth; - const newY = (doc.y - oldY) + (ink[j].Y * doc._height) / oldHeight; + const newX = ((doc.x || 0) - oldX) + (i.X * (doc._width || 0)) / oldWidth; + const newY = ((doc.y || 0) - oldY) + (i.Y * (doc._height || 0)) / oldHeight; newPoints.push({ X: newX, Y: newY }); - } + }); doc.data = new InkField(newPoints); } } @@ -148,12 +147,12 @@ export default class FormatShapePane extends AntimodeMenu { console.log(ink); if (ink) { const newPoints: { X: number, Y: number }[] = []; - for (var j = 0; j < ink.length; j++) { + ink.forEach(i => { // (new x — oldx) + (oldxpoint * newWidt)/oldWidth - const newX = (doc.x - oldX) + (ink[j].X * doc._width) / oldWidth; - const newY = (doc.y - oldY) + (ink[j].Y * doc._height) / oldHeight; + const newX = ((doc.x || 0) - oldX) + (i.X * (doc._width || 0)) / oldWidth; + const newY = ((doc.y || 0) - oldY) + (i.Y * (doc._height || 0)) / oldHeight; newPoints.push({ X: newX, Y: newY }); - } + }); doc.data = new InkField(newPoints); } } @@ -191,11 +190,11 @@ export default class FormatShapePane extends AntimodeMenu { if (ink) { const newPoints: { X: number, Y: number }[] = []; - for (var i = 0; i < ink.length; i++) { - const newX = Math.cos(angle) * (ink[i].X - _centerPoints[index].X) - Math.sin(angle) * (ink[i].Y - _centerPoints[index].Y) + _centerPoints[index].X; - const newY = Math.sin(angle) * (ink[i].X - _centerPoints[index].X) + Math.cos(angle) * (ink[i].Y - _centerPoints[index].Y) + _centerPoints[index].Y; + ink.forEach(i => { + const newX = Math.cos(angle) * (i.X - _centerPoints[index].X) - Math.sin(angle) * (i.Y - _centerPoints[index].Y) + _centerPoints[index].X; + const newY = Math.sin(angle) * (i.X - _centerPoints[index].X) + Math.cos(angle) * (i.Y - _centerPoints[index].Y) + _centerPoints[index].Y; newPoints.push({ X: newX, Y: newY }); - } + }); doc.data = new InkField(newPoints); const xs = newPoints.map(p => p.X); const ys = newPoints.map(p => p.Y); @@ -395,12 +394,12 @@ export default class FormatShapePane extends AntimodeMenu { @computed get widInput() { return this.inputBox("wid", this.shapeWid, (val: string) => this.shapeWid = val); } @computed get rotInput() { return this.inputBoxDuo("rot", this.shapeRot, (val: string) => { this.rotate(Number(val) - Number(this.shapeRot)); this.shapeRot = val; return true; }, "∠:", "rot", this.shapeRot, (val: string) => this.shapeRot = val, ""); } - @computed get XpsInput() { return this.inputBoxDuo("Xps", this.shapeXps, (val: string) => this.shapeXps = val, "X:", "Yps", this.shapeYps, (val: string) => this.shapeYps = val, "Y:"); } @computed get YpsInput() { return this.inputBox("Yps", this.shapeYps, (val: string) => this.shapeYps = val); } @computed get controlPoints() { return this.controlPointsButton(); } @computed get lockRatio() { return this.lockRatioButton(); } @computed get rotate90() { return this.rotate90Button(); } + @computed get XpsInput() { return this.inputBoxDuo("Xps", this.shapeXps, (val: string) => this.shapeXps = val, "X:", "Yps", this.shapeYps, (val: string) => this.shapeYps = val, "Y:"); } @computed get propertyGroupItems() { diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss new file mode 100644 index 000000000..74f32275a --- /dev/null +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss @@ -0,0 +1,620 @@ +.propertiesView { + + background-color: rgb(205, 205, 205); + height: 100%; + font-family: "Noto Sans"; + cursor: auto; + + overflow-x: visible; + overflow-y: visible; + + .propertiesView-title { + background-color: rgb(159, 159, 159); + text-align: center; + padding-top: 12px; + padding-bottom: 12px; + display: flex; + font-size: 18px; + font-weight: bold; + justify-content: center; + + .propertiesView-title-icon { + width: 20px; + height: 20px; + padding-left: 38px; + margin-top: -5px; + right: 19; + position: absolute; + + &:hover { + color: grey; + cursor: pointer; + } + + } + + } + + .propertiesView-name { + border-bottom: 1px solid black; + padding: 8.5px; + font-size: 12.5px; + + &:hover { + cursor: pointer; + } + } + + .propertiesView-settings { + border-bottom: 1px solid black; + //padding: 8.5px; + font-size: 12.5px; + font-weight: bold; + + .propertiesView-settings-title { + font-weight: bold; + font-size: 12.5px; + padding: 4px; + display: flex; + color: white; + padding-left: 8px; + background-color: rgb(51, 51, 51); + + .propertiesView-settings-title-icon { + float: right; + right: 0; + position: absolute; + margin-left: 2px; + margin-right: 9px; + + &:hover { + cursor: pointer; + } + } + } + + .propertiesView-settings-content { + margin-left: 12px; + padding-bottom: 10px; + padding-top: 8px; + } + + } + + .propertiesView-sharing { + border-bottom: 1px solid black; + //padding: 8.5px; + + .propertiesView-sharing-title { + font-weight: bold; + font-size: 12.5px; + padding: 4px; + display: flex; + color: white; + padding-left: 8px; + background-color: rgb(51, 51, 51); + + .propertiesView-sharing-title-icon { + float: right; + right: 0; + position: absolute; + margin-left: 2px; + margin-right: 9px; + + &:hover { + cursor: pointer; + } + } + } + + .propertiesView-sharing-content { + font-size: 10px; + padding: 10px; + margin-left: 5px; + } + } + + .propertiesView-appearance { + border-bottom: 1px solid black; + //padding: 8.5px; + + .propertiesView-appearance-title { + font-weight: bold; + font-size: 12.5px; + padding: 4px; + display: flex; + color: white; + padding-left: 8px; + background-color: rgb(51, 51, 51); + + .propertiesView-appearance-title-icon { + float: right; + right: 0; + position: absolute; + margin-left: 2px; + margin-right: 9px; + + &:hover { + cursor: pointer; + } + } + } + + .propertiesView-appearance-content { + font-size: 10px; + padding: 10px; + margin-left: 5px; + } + } + + .propertiesView-transform { + border-bottom: 1px solid black; + //padding: 8.5px; + + .propertiesView-transform-title { + font-weight: bold; + font-size: 12.5px; + padding: 4px; + display: flex; + color: white; + padding-left: 8px; + background-color: rgb(51, 51, 51); + + .propertiesView-transform-title-icon { + float: right; + right: 0; + position: absolute; + margin-left: 2px; + margin-right: 9px; + + &:hover { + cursor: pointer; + } + } + } + + .propertiesView-transform-content { + font-size: 10px; + padding: 10px; + margin-left: 5px; + } + } + + .notify-button { + padding: 2px; + width: 12px; + height: 12px; + background-color: black; + border-radius: 10px; + padding-left: 2px; + padding-right: 2px; + margin-top: 2px; + margin-left: 3px; + + .notify-button-icon { + width: 6px; + height: 6.5px; + margin-left: .5px; + } + + &:hover { + background-color: rgb(158, 158, 158); + cursor: pointer; + } + } + + .expansion-button-icon { + width: 11px; + height: 11px; + color: black; + margin-left: 27px; + + &:hover { + color: rgb(131, 131, 131); + cursor: pointer; + } + } + + .propertiesView-sharingTable { + + border: 1px solid black; + padding: 5px; + border-radius: 6px; + /* width: 170px; */ + margin-right: 10px; + background-color: #ececec; + max-height: 130px; + overflow-y: scroll; + + .propertiesView-sharingTable-item { + + display: flex; + padding: 3px; + align-items: center; + border-bottom: 0.5px solid grey; + + &:hover .propertiesView-sharingTable-item-name { + overflow-x: unset; + white-space: unset; + overflow-wrap: break-word; + } + + .propertiesView-sharingTable-item-name { + font-weight: bold; + width: 80px; + overflow-x: hidden; + display: inline-block; + text-overflow: ellipsis; + white-space: nowrap; + } + + .propertiesView-sharingTable-item-permission { + display: flex; + right: 34; + float: right; + position: absolute; + + .permissions-select { + z-index: 1; + border: none; + background-color: inherit; + width: 75px; + text-align: justify; // for Edge + text-align-last: end; + + &:hover { + cursor: pointer; + } + } + } + + &:last-child { + border-bottom: none; + } + } + } + + .propertiesView-fields { + border-bottom: 1px solid black; + //padding: 8.5px; + + .propertiesView-fields-title { + font-weight: bold; + font-size: 12.5px; + padding: 4px; + display: flex; + color: white; + padding-left: 8px; + background-color: rgb(51, 51, 51); + + .propertiesView-fields-title-name { + font-size: 12.5px; + font-weight: bold; + white-space: nowrap; + width: 35px; + display: flex; + } + + .propertiesView-fields-title-icon { + float: right; + right: 0; + position: absolute; + margin-left: 2px; + margin-right: 9px; + + &:hover { + cursor: pointer; + } + } + } + + .propertiesView-fields-checkbox { + float: right; + height: 20px; + margin-top: -9px; + + .propertiesView-fields-checkbox-text { + font-size: 7px; + margin-top: -10px; + margin-left: 6px; + } + } + + .propertiesView-fields-content { + font-size: 10px; + margin-left: 2px; + padding: 10px; + + &:hover { + cursor: pointer; + } + } + } + + .field { + display: flex; + font-size: 7px; + background-color: #e8e8e8; + padding-right: 3px; + border: 0.5px solid grey; + border-radius: 5px; + padding-left: 3px; + } + + .uneditable-field { + display: flex; + overflow-y: visible; + margin-bottom: 2px; + + &:hover { + cursor: auto; + } + } + + .propertiesView-layout { + + .propertiesView-layout-title { + font-weight: bold; + font-size: 12.5px; + padding: 4px; + display: flex; + color: white; + padding-left: 8px; + background-color: rgb(51, 51, 51); + + .propertiesView-layout-title-icon { + float: right; + right: 0; + position: absolute; + margin-left: 2px; + margin-right: 9px; + + &:hover { + cursor: pointer; + } + } + } + + .propertiesView-layout-content { + overflow: hidden; + padding: 10px; + } + + } +} + +.inking-button { + + display: flex; + + .inking-button-points { + background-color: #333333; + padding: 7px; + border-radius: 7px; + margin-right: 32px; + width: 32; + height: 32; + padding-top: 9px; + margin-left: 18px; + + &:hover { + background: rgb(131, 131, 131); + transform: scale(1.05); + cursor: pointer; + } + } + + .inking-button-lock { + background-color: #333333; + padding: 7px; + border-radius: 7px; + margin-right: 32px; + width: 32; + height: 32; + padding-top: 9px; + padding-left: 10px; + + &:hover { + background: rgb(131, 131, 131); + transform: scale(1.05); + cursor: pointer; + } + } + + .inking-button-rotate { + background-color: #333333; + padding: 7px; + border-radius: 7px; + width: 32; + height: 32; + padding-top: 9px; + padding-left: 10px; + + &:hover { + background: rgb(131, 131, 131); + transform: scale(1.05); + cursor: pointer; + } + } +} + +.inputBox-duo { + display: flex; +} + +.inputBox { + + margin-top: 10px; + display: flex; + height: 19px; + margin-right: 15px; + + .inputBox-title { + font-size: 12px; + padding-right: 5px; + } + + .inputBox-input { + font-size: 10px; + width: 50px; + margin-right: 1px; + border-radius: 3px; + + &:hover { + cursor: pointer; + } + } + + .inputBox-button { + + .inputBox-button-up { + background-color: #333333; + height: 9px; + padding-left: 3px; + padding-right: 3px; + padding-top: 1px; + padding-bottom: 1px; + border-radius: 1.5px; + + &:hover { + background: rgb(131, 131, 131); + transform: scale(1.05); + cursor: pointer; + } + } + + .inputBox-button-down { + background-color: #333333; + height: 9px; + padding-left: 3px; + padding-right: 3px; + padding-top: 1px; + padding-bottom: 1px; + border-radius: 1.5px; + + &:hover { + background: rgb(131, 131, 131); + transform: scale(1.05); + cursor: pointer; + } + } + + } +} + +.color-palette { + width: 160px; + height: 360; +} + +.strokeAndFill { + display: flex; + margin-top: 10px; + + .fill { + margin-right: 40px; + display: flex; + padding-bottom: 7px; + margin-left: 35px; + + .fill-title { + font-size: 12px; + margin-right: 2px; + } + + .fill-button { + padding-top: 2px; + margin-top: -1px; + } + } + + .stroke { + display: flex; + + .stroke-title { + font-size: 12px; + } + + .stroke-button { + padding-top: 2px; + margin-left: 2px; + margin-top: -1px; + } + } +} + +.widthAndDash { + + .width { + .width-top { + display: flex; + + .width-title { + font-size: 12; + margin-right: 20px; + margin-left: 35px; + text-align: center; + } + + .width-input { + margin-right: 30px; + margin-top: -10px; + } + } + + .width-range { + margin-right: 1px; + margin-bottom: 6; + } + } + + .arrows { + + display: flex; + margin-bottom: 3px; + + .arrows-head { + + display: flex; + margin-right: 35px; + + .arrows-head-title { + font-size: 10; + } + + .arrows-head-input { + margin-left: 6px; + margin-top: 2px; + } + } + + .arrows-tail { + display: flex; + + .arrows-tail-title { + font-size: 10; + } + + .arrows-tail-input { + margin-left: 6px; + margin-top: 2px; + } + } + } + + .dashed { + + display: flex; + margin-left: 74px; + margin-bottom: 6px; + + .dashed-title { + font-size: 10; + } + + .dashed-input { + margin-left: 6px; + margin-top: 2px; + } + } +} \ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx new file mode 100644 index 000000000..35c7fd425 --- /dev/null +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx @@ -0,0 +1,858 @@ +import React = require("react"); +import { observer } from "mobx-react"; +import "./PropertiesView.scss"; +import { observable, action, computed, runInAction } from "mobx"; +import { Doc, Field, DocListCast, WidthSym, HeightSym, AclSym, AclPrivate, AclReadonly, AclAddonly, AclEdit, AclAdmin, Opt } from "../../../../fields/Doc"; +import { DocumentView } from "../../nodes/DocumentView"; +import { ComputedField } from "../../../../fields/ScriptField"; +import { EditableView } from "../../EditableView"; +import { KeyValueBox } from "../../nodes/KeyValueBox"; +import { Cast, NumCast, StrCast } from "../../../../fields/Types"; +import { listSpec } from "../../../../fields/Schema"; +import { ContentFittingDocumentView } from "../../nodes/ContentFittingDocumentView"; +import { returnFalse, returnOne, emptyFunction, emptyPath, returnTrue, returnZero, returnEmptyFilter, Utils } from "../../../../Utils"; +import { Id } from "../../../../fields/FieldSymbols"; +import { Transform } from "../../../util/Transform"; +import { PropertiesButtons } from "../../PropertiesButtons"; +import { SelectionManager } from "../../../util/SelectionManager"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Tooltip, Checkbox, Divider } from "@material-ui/core"; +import SharingManager from "../../../util/SharingManager"; +import { DocumentType } from "../../../documents/DocumentTypes"; +import FormatShapePane from "./FormatShapePane"; +import { SharingPermissions, GetEffectiveAcl } from "../../../../fields/util"; +import { InkField } from "../../../../fields/InkField"; +import { undoBatch } from "../../../util/UndoManager"; +import { ColorState, SketchPicker } from "react-color"; +import AntimodeMenu from "../../AntimodeMenu"; +import "./FormatShapePane.scss"; +import { discovery_v1 } from "googleapis"; +import { PresBox } from "../../nodes/PresBox"; +import { DocumentManager } from "../../../util/DocumentManager"; + + +interface PropertiesViewProps { + width: number; + height: number; + renderDepth: number; + ScreenToLocalTransform: () => Transform; + onDown: (event: any) => void; +} + +@observer +export class PropertiesView extends React.Component { + + @computed get MAX_EMBED_HEIGHT() { return 200; } + + @computed get selectedDocumentView() { + if (SelectionManager.SelectedDocuments().length) { + return SelectionManager.SelectedDocuments()[0]; + } else if (PresBox.Instance) { + const presSlide = PresBox.Instance._selectedArray[0]; + const view = DocumentManager.Instance.getDocumentView(presSlide); + if (view) return view; + } else { return undefined; } + } + @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; } + @computed get dataDoc() { return this.selectedDocumentView?.dataDoc; } + + @observable layoutFields: boolean = false; + + @observable openActions: boolean = true; + @observable openSharing: boolean = true; + @observable openFields: boolean = true; + @observable openLayout: boolean = true; + @observable openAppearance: boolean = true; + @observable openTransform: boolean = true; + + @computed get isInk() { return this.selectedDoc?.type === DocumentType.INK; } + + @action + rtfWidth = () => { + if (this.selectedDoc) { + return Math.min(this.selectedDoc?.[WidthSym](), this.props.width - 20); + } else { + return 0; + } + } + @action + rtfHeight = () => { + if (this.selectedDoc) { + return this.rtfWidth() <= this.selectedDoc?.[WidthSym]() ? Math.min(this.selectedDoc?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT; + } else { + return 0; + } + } + + @action + docWidth = () => { + if (this.selectedDoc) { + const layoutDoc = this.selectedDoc; + const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]()); + if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.width - 20)); + return NumCast(layoutDoc._nativeWidth) ? Math.min(layoutDoc[WidthSym](), this.props.width - 20) : this.props.width - 20; + } else { + return 0; + } + } + + @action + docHeight = () => { + if (this.selectedDoc && this.dataDoc) { + const layoutDoc = this.selectedDoc; + return Math.max(70, Math.min(this.MAX_EMBED_HEIGHT, (() => { + const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]()); + if (aspect) return this.docWidth() * aspect; + return layoutDoc._fitWidth ? (!this.dataDoc._nativeHeight ? NumCast(this.props.height) : + Math.min(this.docWidth() * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc._nativeHeight)) / NumCast(layoutDoc._nativeWidth, + NumCast(this.props.height)))) : + NumCast(layoutDoc._height) ? NumCast(layoutDoc._height) : 50; + })())); + } else { + return 0; + } + } + + @computed get expandedField() { + if (this.dataDoc && this.selectedDoc) { + const ids: { [key: string]: string } = {}; + const doc = this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc; + doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key)); + const rows: JSX.Element[] = []; + for (const key of Object.keys(ids).slice().sort()) { + const contents = doc[key]; + if (key[0] === "#") { + rows.push(
+ {key} +   +
); + } else { + let contentElement: (JSX.Element | null)[] | JSX.Element = []; + contentElement = Field.toKeyValueString(doc, key)} + SetValue={(value: string) => KeyValueBox.SetField(doc, key, value, true)} + />; + rows.push(
+ {key + ":"} +   + {contentElement} +
); + } + } + rows.push(
+ ""} + SetValue={this.setKeyValue} /> +
); + return rows; + } + } + + @computed get noviceFields() { + if (this.dataDoc && this.selectedDoc) { + const ids: { [key: string]: string } = {}; + const doc = this.dataDoc; + doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key)); + const rows: JSX.Element[] = []; + for (const key of Object.keys(ids).slice().sort()) { + if (key[0] === key[0].toUpperCase() || key[0] === "#" || key === "author" || key === "creationDate" || key.indexOf("lastModified") !== -1) { + const contents = doc[key]; + if (key[0] === "#") { + rows.push(
+ {key} +   +
); + } else { + const value = Field.toString(contents as Field); + if (key === "author" || key === "creationDate" || key.indexOf("lastModified") !== -1) { + rows.push(
+ {key + ": "} +
{value}
+
); + } else { + let contentElement: (JSX.Element | null)[] | JSX.Element = []; + contentElement = Field.toKeyValueString(doc, key)} + SetValue={(value: string) => KeyValueBox.SetField(doc, key, value, true)} + />; + + rows.push(
+ {key + ":"} +   + {contentElement} +
); + } + } + } + } + rows.push(
+ ""} + SetValue={this.setKeyValue} /> +
); + return rows; + } + } + + + setKeyValue = (value: string) => { + if (this.selectedDoc && this.dataDoc) { + const doc = this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc; + if (value.indexOf(":") !== -1) { + const newVal = value[0].toUpperCase() + value.substring(1, value.length); + KeyValueBox.SetField(doc, newVal.substring(0, newVal.indexOf(":")), newVal.substring(newVal.indexOf(":") + 1, newVal.length), true); + return true; + } else if (value[0] === "#") { + const newVal = value + `:'${value}'`; + KeyValueBox.SetField(doc, newVal.substring(0, newVal.indexOf(":")), newVal.substring(newVal.indexOf(":") + 1, newVal.length), true); + return true; + } + } + return false; + } + + @computed get layoutPreview() { + if (this.selectedDoc) { + const layoutDoc = Doc.Layout(this.selectedDoc); + const panelHeight = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : this.docHeight; + const panelWidth = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : this.docWidth; + return
+ "lightgrey"} + fitToBox={false} + FreezeDimensions={true} + NativeWidth={layoutDoc.type === + StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : returnZero} + NativeHeight={layoutDoc.type === + StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : returnZero} + PanelWidth={panelWidth} + PanelHeight={panelHeight} + focus={returnFalse} + ScreenToLocalTransform={this.props.ScreenToLocalTransform} + docFilters={returnEmptyFilter} + ContainingCollectionDoc={undefined} + ContainingCollectionView={undefined} + addDocument={returnFalse} + moveDocument={undefined} + removeDocument={returnFalse} + parentActive={() => false} + whenActiveChanged={emptyFunction} + addDocTab={returnFalse} + pinToPres={emptyFunction} + bringToFront={returnFalse} + ContentScaling={returnOne} + dontRegisterView={true} + /> +
; + } else { + return null; + } + } + + getPermissionsSelect(user: string) { + return ; + } + + @computed get notifyIcon() { + return
Notify with message
}> +
+ +
+
; + } + + @computed get expansionIcon() { + return
{"Show more permissions"}
}> +
{ + if (this.selectedDocumentView) { + SharingManager.Instance.open(this.selectedDocumentView); + } + }}> + +
+
; + } + + sharingItem(name: string, effectiveAcl: symbol, permission?: string) { + return
+
{name}
+ {name !== "Me" ? this.notifyIcon : null} +
+ {effectiveAcl === AclAdmin && permission !== "Owner" ? this.getPermissionsSelect(name) : permission} + {permission === "Owner" ? this.expansionIcon : null} +
+
; + } + + @computed get sharingTable() { + const AclMap = new Map([ + [AclPrivate, SharingPermissions.None], + [AclReadonly, SharingPermissions.View], + [AclAddonly, SharingPermissions.Add], + [AclEdit, SharingPermissions.Edit], + [AclAdmin, SharingPermissions.Admin] + ]); + + const effectiveAcl = GetEffectiveAcl(this.selectedDoc!); + const tableEntries = []; + + if (this.selectedDoc![AclSym]) { + for (const [key, value] of Object.entries(this.selectedDoc![AclSym])) { + const name = key.substring(4).replace("_", "."); + if (name !== Doc.CurrentUserEmail && name !== this.selectedDoc!.author) tableEntries.push(this.sharingItem(name, effectiveAcl, AclMap.get(value)!)); + } + } + + tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === this.selectedDoc!.author ? "Owner" : StrCast(this.selectedDoc![`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`]))); + if (Doc.CurrentUserEmail !== this.selectedDoc!.author) tableEntries.unshift(this.sharingItem(StrCast(this.selectedDoc!.author), effectiveAcl, "Owner")); + + return
+ {tableEntries} +
; + } + + @computed get fieldsCheckbox() { + return ; + } + + @action + toggleCheckbox = () => { + this.layoutFields = !this.layoutFields; + } + + @computed get editableTitle() { + return StrCast(this.selectedDoc?.title)} + SetValue={this.setTitle} />; + } + + @action + setTitle = (value: string) => { + if (this.dataDoc) { + this.selectedDoc && (this.selectedDoc.title = value); + KeyValueBox.SetField(this.dataDoc, "title", value, true); + return true; + } + return false; + } + + + + + + + + + + @undoBatch + @action + rotate = (angle: number) => { + const _centerPoints: { X: number, Y: number }[] = []; + if (this.selectedDoc) { + const doc = this.selectedDoc; + if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { + const ink = Cast(doc.data, InkField)?.inkData; + if (ink) { + const xs = ink.map(p => p.X); + const ys = ink.map(p => p.Y); + const left = Math.min(...xs); + const top = Math.min(...ys); + const right = Math.max(...xs); + const bottom = Math.max(...ys); + _centerPoints.push({ X: left, Y: top }); + } + } + + var index = 0; + if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { + doc.rotation = Number(doc.rotation) + Number(angle); + const ink = Cast(doc.data, InkField)?.inkData; + if (ink) { + + const newPoints: { X: number, Y: number }[] = []; + for (var i = 0; i < ink.length; i++) { + const newX = Math.cos(angle) * (ink[i].X - _centerPoints[index].X) - Math.sin(angle) * (ink[i].Y - _centerPoints[index].Y) + _centerPoints[index].X; + const newY = Math.sin(angle) * (ink[i].X - _centerPoints[index].X) + Math.cos(angle) * (ink[i].Y - _centerPoints[index].Y) + _centerPoints[index].Y; + newPoints.push({ X: newX, Y: newY }); + } + doc.data = new InkField(newPoints); + const xs = newPoints.map(p => p.X); + const ys = newPoints.map(p => p.Y); + const left = Math.min(...xs); + const top = Math.min(...ys); + const right = Math.max(...xs); + const bottom = Math.max(...ys); + + doc._height = (bottom - top); + doc._width = (right - left); + } + index++; + } + } + } + + @observable _controlBtn: boolean = false; + @observable _lock: boolean = false; + + @computed + get controlPointsButton() { + return
+
{"Edit points"}
}> +
this._controlBtn = !this._controlBtn)} style={{ backgroundColor: this._controlBtn ? "black" : "" }}> + +
+
+
{this._lock ? "Unlock points" : "Lock points"}
}> +
this._lock = !this._lock)} > + +
+
+
{"Rotate 90˚"}
}> +
this.rotate(Math.PI / 2))}> + +
+
+
; + } + + inputBox = (key: string, value: any, setter: (val: string) => {}, title: string) => { + return
+
{title}
+ setter(e.target.value)} /> +
+
this.upDownButtons("up", key)))} > + +
+
this.upDownButtons("down", key)))} > + +
+
+
; + } + + inputBoxDuo = (key: string, value: any, setter: (val: string) => {}, title1: string, key2: string, value2: any, setter2: (val: string) => {}, title2: string) => { + return
+ {this.inputBox(key, value, setter, title1)} + {title2 === "" ? (null) : this.inputBox(key2, value2, setter2, title2)} +
; + } + + @action + upDownButtons = (dirs: string, field: string) => { + switch (field) { + case "rot": this.rotate((dirs === "up" ? .1 : -.1)); break; + // case "rot": this.selectedInk?.forEach(i => i.rootDoc.rotation = NumCast(i.rootDoc.rotation) + (dirs === "up" ? 0.1 : -0.1)); break; + case "Xps": this.selectedDoc && (this.selectedDoc.x = NumCast(this.selectedDoc?.x) + (dirs === "up" ? 10 : -10)); break; + case "Yps": this.selectedDoc && (this.selectedDoc.y = NumCast(this.selectedDoc?.y) + (dirs === "up" ? 10 : -10)); break; + case "stk": this.selectedDoc && (this.selectedDoc.strokeWidth = NumCast(this.selectedDoc?.strokeWidth) + (dirs === "up" ? .1 : -.1)); break; + case "wid": + const oldWidth = NumCast(this.selectedDoc?._width); + const oldHeight = NumCast(this.selectedDoc?._height); + const oldX = NumCast(this.selectedDoc?.x); + const oldY = NumCast(this.selectedDoc?.y); + this.selectedDoc && (this.selectedDoc._width = oldWidth + (dirs === "up" ? 10 : - 10)); + this._lock && this.selectedDoc && (this.selectedDoc._height = (NumCast(this.selectedDoc?._width) / oldWidth * NumCast(this.selectedDoc?._height))); + const doc = this.selectedDoc; + if (doc?.type === DocumentType.INK && doc.x && doc.y && doc._height && doc._width) { + console.log(doc.x, doc.y, doc._height, doc._width); + const ink = Cast(doc.data, InkField)?.inkData; + console.log(ink); + if (ink) { + const newPoints: { X: number, Y: number }[] = []; + for (var j = 0; j < ink.length; j++) { + // (new x — oldx) + (oldxpoint * newWidt)/oldWidth + const newX = (NumCast(doc.x) - oldX) + (ink[j].X * NumCast(doc._width)) / oldWidth; + const newY = (NumCast(doc.y) - oldY) + (ink[j].Y * NumCast(doc._height)) / oldHeight; + newPoints.push({ X: newX, Y: newY }); + } + doc.data = new InkField(newPoints); + } + } + break; + case "hgt": + const oWidth = NumCast(this.selectedDoc?._width); + const oHeight = NumCast(this.selectedDoc?._height); + const oX = NumCast(this.selectedDoc?.x); + const oY = NumCast(this.selectedDoc?.y); + this.selectedDoc && (this.selectedDoc._height = oHeight + (dirs === "up" ? 10 : - 10)); + this._lock && this.selectedDoc && (this.selectedDoc._width = (NumCast(this.selectedDoc?._height) / oHeight * NumCast(this.selectedDoc?._width))); + const docu = this.selectedDoc; + if (docu?.type === DocumentType.INK && docu.x && docu.y && docu._height && docu._width) { + console.log(docu.x, docu.y, docu._height, docu._width); + const ink = Cast(docu.data, InkField)?.inkData; + console.log(ink); + if (ink) { + const newPoints: { X: number, Y: number }[] = []; + for (var j = 0; j < ink.length; j++) { + // (new x — oldx) + (oldxpoint * newWidt)/oldWidth + const newX = (NumCast(docu.x) - oX) + (ink[j].X * NumCast(docu._width)) / oWidth; + const newY = (NumCast(docu.y) - oY) + (ink[j].Y * NumCast(docu._height)) / oHeight; + newPoints.push({ X: newX, Y: newY }); + } + docu.data = new InkField(newPoints); + } + } + break; + } + } + + getField(key: string) { + //if (this.selectedDoc) { + return Field.toString(this.selectedDoc[key] as Field); + // } else { + // return undefined as Opt; + // } + } + + @computed get shapeXps() { return this.getField("x"); } + @computed get shapeYps() { return this.getField("y"); } + @computed get shapeRot() { return this.getField("rotation"); } + @computed get shapeHgt() { return this.getField("_height"); } + @computed get shapeWid() { return this.getField("_width"); } + set shapeXps(value) { this.selectedDoc && (this.selectedDoc.x = Number(value)); } + set shapeYps(value) { this.selectedDoc && (this.selectedDoc.y = Number(value)); } + set shapeRot(value) { this.selectedDoc && (this.selectedDoc.rotation = Number(value)); } + set shapeWid(value) { + const oldWidth = NumCast(this.selectedDoc?._width); + this.selectedDoc && (this.selectedDoc._width = Number(value)); + this._lock && this.selectedDoc && (this.selectedDoc._height = (NumCast(this.selectedDoc?._width) * NumCast(this.selectedDoc?._height)) / oldWidth); + } + set shapeHgt(value) { + const oldHeight = NumCast(this.selectedDoc?._height); + this.selectedDoc && (this.selectedDoc._height = Number(value)); + this._lock && this.selectedDoc && (this.selectedDoc._width = (NumCast(this.selectedDoc?._height) * NumCast(this.selectedDoc?._width)) / oldHeight); + } + + @computed get hgtInput() { return this.inputBoxDuo("hgt", this.shapeHgt, (val: string) => this.shapeHgt = val, "H:", "wid", this.shapeWid, (val: string) => this.shapeWid = val, "W:"); } + @computed get XpsInput() { return this.inputBoxDuo("Xps", this.shapeXps, (val: string) => this.shapeXps = val, "X:", "Yps", this.shapeYps, (val: string) => this.shapeYps = val, "Y:"); } + @computed get rotInput() { return this.inputBoxDuo("rot", this.shapeRot, (val: string) => { this.rotate(Number(val) - Number(this.shapeRot)); this.shapeRot = val; return true; }, "∠:", "rot", this.shapeRot, (val: string) => this.shapeRot = val, ""); } + + @observable private _fillBtn = false; + @observable private _lineBtn = false; + + private _lastFill = "#D0021B"; + private _lastLine = "#D0021B"; + private _lastDash: any = "2"; + + @computed get colorFil() { const ccol = this.getField("fillColor") || ""; ccol && (this._lastFill = ccol); return ccol; } + @computed get colorStk() { const ccol = this.getField("color") || ""; ccol && (this._lastLine = ccol); return ccol; } + set colorFil(value) { value && (this._lastFill = value); this.selectedDoc && (this.selectedDoc.fillColor = value ? value : undefined); } + set colorStk(value) { value && (this._lastLine = value); this.selectedDoc && (this.selectedDoc.color = value ? value : undefined); } + + colorButton(value: string, setter: () => {}) { + return
setter()))}> +
+ {value === "" || value === "transparent" ?

: ""} +
; + } + + @undoBatch + @action + switchStk = (color: ColorState) => { + const val = String(color.hex); + this.colorStk = val; + return true; + } + @undoBatch + @action + switchFil = (color: ColorState) => { + const val = String(color.hex); + this.colorFil = val; + return true; + } + + colorPicker(setter: (color: string) => {}, type: string) { + return ; + } + + @computed get fillButton() { return this.colorButton(this.colorFil, () => { this._fillBtn = !this._fillBtn; this._lineBtn = false; return true; }); } + @computed get lineButton() { return this.colorButton(this.colorStk, () => { this._lineBtn = !this._lineBtn; this._fillBtn = false; return true; }); } + + @computed get fillPicker() { return this.colorPicker((color: string) => this.colorFil = color, "fil"); } + @computed get linePicker() { return this.colorPicker((color: string) => this.colorStk = color, "stk"); } + + @computed get strokeAndFill() { + return
+
+
+
Fill:
+
{this.fillButton}
+
+
+
Stroke:
+
{this.lineButton}
+
+
+ {this._fillBtn ? this.fillPicker : ""} + {this._lineBtn ? this.linePicker : ""} +
; + } + + @computed get solidStk() { return this.selectedDoc?.color && (!this.selectedDoc?.strokeDash || this.selectedDoc?.strokeDash === "0") ? true : false; } + @computed get dashdStk() { return this.selectedDoc?.strokeDash || ""; } + @computed get unStrokd() { return this.selectedDoc?.color ? true : false; } + @computed get widthStk() { return this.getField("strokeWidth") || "1"; } + @computed get markHead() { return this.getField("strokeStartMarker") || ""; } + @computed get markTail() { return this.getField("strokeEndMarker") || ""; } + set solidStk(value) { this.dashdStk = ""; this.unStrokd = !value; } + set dashdStk(value) { + value && (this._lastDash = value) && (this.unStrokd = false); + this.selectedDoc && (this.selectedDoc.strokeDash = value ? this._lastDash : undefined); + } + set widthStk(value) { this.selectedDoc && (this.selectedDoc.strokeWidth = Number(value)); } + set unStrokd(value) { this.colorStk = value ? "" : this._lastLine; } + set markHead(value) { this.selectedDoc && (this.selectedDoc.strokeStartMarker = value); } + set markTail(value) { this.selectedDoc && (this.selectedDoc.strokeEndMarker = value); } + + + @computed get stkInput() { return this.regInput("stk", this.widthStk, (val: string) => this.widthStk = val); } + + + regInput = (key: string, value: any, setter: (val: string) => {}) => { + return
+ setter(e.target.value)} /> +
+
this.upDownButtons("up", key)))} > + +
+
this.upDownButtons("down", key)))} > + +
+
+
; + } + + @computed get widthAndDash() { + return
+
+
+
Width:
+
{this.stkInput}
+
+ this.widthStk = e.target.value))} /> +
+ +
+
+
Arrow Head:
+ this.markHead = this.markHead ? "" : "arrow"))} /> +
+
+
Arrow End:
+ this.markTail = this.markTail ? "" : "arrow"))} /> +
+
+
+
Dash:
+ +
+
; + } + + @undoBatch @action + changeDash = () => { + const dash = this.dashdStk; + if (dash === "2") { + this.dashdStk = "0"; + } else { + this.dashdStk = "2"; + } + } + + @computed get appearanceEditor() { + return
+ {this.widthAndDash} + {this.strokeAndFill} +
; + } + + @computed get transformEditor() { + return
+ {this.controlPointsButton} + {this.hgtInput} + {this.XpsInput} + {this.rotInput} +
; + } + + render() { + + if (!this.selectedDoc) { + return
+
+ No Document Selected +
; + } + + const novice = Doc.UserDoc().noviceMode; + + return
+
+ Properties +
+ +
+
+
+ {this.editableTitle} +
+
+
runInAction(() => { this.openActions = !this.openActions; })} + style={{ backgroundColor: this.openActions ? "black" : "" }}> + Actions +
+ +
+
+ {this.openActions ?
+ +
: null} +
+
+
runInAction(() => { this.openSharing = !this.openSharing; })} + style={{ backgroundColor: this.openSharing ? "black" : "" }}> + Sharing {"&"} Permissions +
+ +
+
+ {this.openSharing ?
+ {this.sharingTable} +
: null} +
+ + + + + {this.isInk ?
+
runInAction(() => { this.openAppearance = !this.openAppearance; })} + style={{ backgroundColor: this.openAppearance ? "black" : "" }}> + Appearance +
+ +
+
+ {this.openAppearance ?
+ {this.appearanceEditor} +
: null} +
: null} + + {this.isInk ?
+
runInAction(() => { this.openTransform = !this.openTransform; })} + style={{ backgroundColor: this.openTransform ? "black" : "" }}> + Transform +
+ +
+
+ {this.openTransform ?
+ {this.transformEditor} +
: null} +
: null} + + + + + +
+
runInAction(() => { this.openFields = !this.openFields; })} + style={{ backgroundColor: this.openFields ? "black" : "" }}> +
+ Fields {"&"} Tags +
+ +
+
+
+ {!novice && this.openFields ?
+ {this.fieldsCheckbox} +
Layout
+
: null} + {this.openFields ? +
+ {novice ? this.noviceFields : this.expandedField} +
: null} +
+
+
runInAction(() => { this.openLayout = !this.openLayout; })} + style={{ backgroundColor: this.openLayout ? "black" : "" }}> + Layout +
runInAction(() => { this.openLayout = !this.openLayout; })}> + +
+
+ {this.openLayout ?
{this.layoutPreview}
: null} +
+
; + } +} \ No newline at end of file diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index d1c839c3b..0aabf5319 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -182,7 +182,7 @@ export class LinkMenuItem extends React.Component { switch (this.props.destinationDoc.type) { case DocumentType.IMG: destinationIcon = "image"; break; case DocumentType.COMPARISON: destinationIcon = "columns"; break; - case DocumentType.RTF: destinationIcon = "font"; break; + case DocumentType.RTF: destinationIcon = "sticky-note"; break; case DocumentType.COL: destinationIcon = "folder"; break; case DocumentType.WEB: destinationIcon = "globe-asia"; break; case DocumentType.SCREENSHOT: destinationIcon = "photo-video"; break; @@ -196,6 +196,7 @@ export class LinkMenuItem extends React.Component { case DocumentType.DOCHOLDER: destinationIcon = "expand"; break; case DocumentType.VID: destinationIcon = "video"; break; case DocumentType.INK: destinationIcon = "pen-nib"; break; + case DocumentType.PDF: destinationIcon = "file"; break; default: destinationIcon = "question"; break; } diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index 6081def5d..f7e253f42 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -78,6 +78,9 @@ export class ContentFittingDocumentView extends React.Component 0.001 ? "auto" : this.props.PanelWidth(), height: Math.abs(this.centeringOffset) > 0.0001 ? "auto" : this.props.PanelHeight(), diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index e8173d103..e3f258b8d 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -18,6 +18,7 @@ import { DocHolderBox } from "./DocHolderBox"; import { DocumentViewProps } from "./DocumentView"; import "./DocumentView.scss"; import { FontIconBox } from "./FontIconBox"; +import { MenuIconBox } from "./MenuIconBox"; import { FieldView, FieldViewProps } from "./FieldView"; import { FormattedTextBox } from "./formattedText/FormattedTextBox"; import { ImageBox } from "./ImageBox"; @@ -189,7 +190,7 @@ export class DocumentContentsView extends React.Component + {/* {this.props.InMenu ? this.props.StartLink ? : + : links.length} */} + {this.props.InMenu ? this.props.StartLink ? : - : links.length} + link : links.length}
{DocumentLinksButton.StartLink && this.props.InMenu && !!!this.props.StartLink && DocumentLinksButton.StartLink !== this.props.View ?
(Docu } onClick = action((e: React.MouseEvent | React.PointerEvent) => { - if (!e.nativeEvent.cancelBubble && !this.Document.ignoreClick && + if (!e.nativeEvent.cancelBubble && !this.Document.ignoreClick && this.props.renderDepth >= 0 && (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) { let stopPropagate = true; let preventDefault = true; @@ -319,10 +321,11 @@ export class DocumentView extends DocComponent(Docu const func = () => this.onClickHandler.script.run({ this: this.layoutDoc, self: this.rootDoc, + scriptContext: this.props.scriptContext, thisContainer: this.props.ContainingCollectionDoc, shiftKey: e.shiftKey }, console.log); - if (this.props.Document !== Doc.UserDoc()["dockedBtn-undo"] && this.props.Document !== Doc.UserDoc()["dockedBtn-redo"]) { + if (!Doc.AreProtosEqual(this.props.Document, Doc.UserDoc()["dockedBtn-undo"] as Doc) && !Doc.AreProtosEqual(this.props.Document, Doc.UserDoc()["dockedBtn-redo"] as Doc)) { UndoManager.RunInBatch(func, "on click"); } else func(); } 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 @@ -584,6 +587,18 @@ export class DocumentView extends DocComponent(Docu } } + + @undoBatch + noOnClick = (): void => { + this.Document.ignoreClick = false; + this.Document.isLinkButton = false; + } + + @undoBatch + toggleDetail = (): void => { + this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`); + } + @undoBatch @action drop = async (e: Event, de: DragManager.DropEvent) => { if (this.props.Document === Doc.UserDoc().activeWorkspace) { @@ -660,6 +675,14 @@ export class DocumentView extends DocComponent(Docu } } + @action + onCopy = () => { + const copy = Doc.MakeCopy(this.props.Document, true); + copy.x = NumCast(this.props.Document.x) + NumCast(this.props.Document._width); + copy.y = NumCast(this.props.Document.y) + 30; + this.props.addDocument?.(copy); + } + @action onContextMenu = async (e: React.MouseEvent | Touch): Promise => { // the touch onContextMenu is button 0, the pointer onContextMenu is button 2 @@ -704,14 +727,14 @@ export class DocumentView extends DocComponent(Docu const existingOnClick = cm.findByDescription("OnClick..."); const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : []; onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" }); - onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`), icon: "window-restore" }); + onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`), icon: "concierge-bell" }); onClicks.push({ description: this.Document.ignoreClick ? "Select" : "Do Nothing", event: () => this.Document.ignoreClick = !this.Document.ignoreClick, icon: this.Document.ignoreClick ? "unlock" : "lock" }); - onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link in Place", event: () => this.toggleFollowLink("inPlace", true, false), icon: "concierge-bell" }); - !this.Document.isLinkButton && onClicks.push({ description: "Follow Link on Right", event: () => this.toggleFollowLink("onRight", false, false), icon: "concierge-bell" }); - onClicks.push({ description: this.Document.isLinkButton || this.onClickHandler ? "Remove Click Behavior" : "Follow Link", event: () => this.toggleFollowLink(undefined, false, false), icon: "concierge-bell" }); - onClicks.push({ description: (this.Document.isPushpin ? "Remove" : "Make") + " Pushpin", event: () => this.toggleFollowLink(undefined, false, true), icon: "snowflake" }); - onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "edit" }); - !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, addDivider: true, subitems: onClicks, icon: "hand-point-right" }); + onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link in Place", event: () => this.toggleFollowLink("inPlace", true, false), icon: "link" }); + !this.Document.isLinkButton && onClicks.push({ description: "Follow Link on Right", event: () => this.toggleFollowLink("onRight", false, false), icon: "link" }); + onClicks.push({ description: this.Document.isLinkButton || this.onClickHandler ? "Remove Click Behavior" : "Follow Link", event: () => this.toggleFollowLink(undefined, false, false), icon: "link" }); + onClicks.push({ description: (this.Document.isPushpin ? "Remove" : "Make") + " Pushpin", event: () => this.toggleFollowLink(undefined, false, true), icon: "map-pin" }); + onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "terminal" }); + !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, addDivider: true, subitems: onClicks, icon: "mouse-pointer" }); const funcs: ContextMenuProps[] = []; if (this.layoutDoc.onDragStart) { @@ -724,6 +747,9 @@ export class DocumentView extends DocComponent(Docu const more = cm.findByDescription("More..."); const moreItems = more && "subitems" in more ? more.subitems : []; moreItems.push({ description: "Download document", icon: "download", event: async () => Doc.Zip(this.props.Document) }); + moreItems.push({ description: "Share", event: () => SharingManager.Instance.open(this), icon: "users" }); + //moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" }); + moreItems.push({ description: "Create an Alias", event: () => this.onCopy(), icon: "copy" }); if (!Doc.UserDoc().noviceMode) { moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" }); moreItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" }); @@ -735,16 +761,18 @@ export class DocumentView extends DocComponent(Docu } moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" }); } + //GetEffectiveAcl(this.props.Document) === AclEdit && moreItems.push({ description: "Delete", event: this.deleteClicked, icon: "trash" }); + const effectiveAcl = GetEffectiveAcl(this.props.Document); (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) && moreItems.push({ description: "Delete", event: this.deleteClicked, icon: "trash" }); - moreItems.push({ description: "Share", event: () => SharingManager.Instance.open(this), icon: "external-link-alt" }); + !more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); cm.moveAfter(cm.findByDescription("More...")!, cm.findByDescription("OnClick...")!); const help = cm.findByDescription("Help..."); const helpItems: ContextMenuProps[] = help && "subitems" in help ? help.subitems : []; + !Doc.UserDoc().novice && helpItems.push({ description: "Show Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "layer-group" }); helpItems.push({ description: "Text Shortcuts Ctrl+/", event: () => this.props.addDocTab(Docs.Create.PdfDocument(Utils.prepend("/assets/cheat-sheet.pdf"), { _width: 300, _height: 300 }), "onRight"), icon: "keyboard" }); - helpItems.push({ description: "Show Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "layer-group" }); helpItems.push({ description: "Print Document in Console", event: () => console.log(this.props.Document), icon: "hand-point-right" }); cm.addItem({ description: "Help...", noexpand: true, subitems: helpItems, icon: "question" }); @@ -786,8 +814,9 @@ export class DocumentView extends DocComponent(Docu childScaling = () => (this.layoutDoc._fitWidth ? this.props.PanelWidth() / this.nativeWidth : this.props.ContentScaling()); @computed.struct get linkOffset() { return [-15, 0]; } @computed get contents() { + const pos = this.props.relative ? "relative " : "absolute"; TraceMobx(); - return (
+ return (
(Docu ChromeHeight={this.chromeHeight} isSelected={this.isSelected} select={this.select} + scriptContext={this.props.scriptContext} onClick={this.onClickFunc} layoutKey={this.finalLayoutKey} /> {this.layoutDoc.hideAllLinks ? (null) : this.allAnchors} @@ -877,8 +907,12 @@ export class DocumentView extends DocComponent(Docu } @computed get innards() { TraceMobx(); + const pos = this.props.relative ? "relative" : undefined; if (this.props.treeViewDoc && !this.props.LayoutTemplateString?.includes("LinkAnchorBox")) { // this happens when the document is a tree view label (but not an anchor dot) - return
+ return
{StrCast(this.props.Document.title)} {this.allAnchors}
; @@ -1003,7 +1037,7 @@ export class DocumentView extends DocComponent(Docu background: finalColor, opacity: finalOpacity, fontFamily: StrCast(this.Document._fontFamily, "inherit"), - fontSize: Cast(this.Document._fontSize, "string", null) + fontSize: Cast(this.Document._fontSize, "string", null), }}> {this.onClickHandler && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ? <> {this.innards} diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 5d5bc1d73..1b4151bd8 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -61,6 +61,7 @@ export interface FieldViewProps { color?: string; xMargin?: number; yMargin?: number; + scriptContext?: any; } @observer diff --git a/src/client/views/nodes/FontIconBox.scss b/src/client/views/nodes/FontIconBox.scss index 5b85d8b0b..69c835318 100644 --- a/src/client/views/nodes/FontIconBox.scss +++ b/src/client/views/nodes/FontIconBox.scss @@ -16,7 +16,7 @@ position: absolute; text-align: center; font-size: 8px; - margin-top:4px; + //margin-top:4px; letter-spacing: normal; left: 0; overflow: hidden; diff --git a/src/client/views/nodes/MenuIconBox.scss b/src/client/views/nodes/MenuIconBox.scss new file mode 100644 index 000000000..1b72f5a8f --- /dev/null +++ b/src/client/views/nodes/MenuIconBox.scss @@ -0,0 +1,49 @@ +.menuButton { + //padding: 7px; + padding-left: 7px; + width: 100%; + width: 60px; + height: 70px; + + .menuButton-wrap { + width: 45px; + /* padding: 5px; */ + touch-action: none; + background: black; + transform-origin: top left; + /* margin-bottom: 5px; */ + margin-top: 5px; + margin-right: 25px; + border-radius: 8px; + + &:hover { + background: rgb(61, 61, 61); + cursor: pointer; + } + } + + .menuButton-label { + color: white; + margin-right: 4px; + border-radius: 8px; + width: 42px; + position: relative; + text-align: center; + font-size: 8px; + margin-top: 1px; + letter-spacing: normal; + padding: 3px; + background-color: inherit; + } + + .menuButton-icon { + width: auto; + height: 35px; + padding: 5px; + } + + svg { + width: 95% !important; + height: 95%; + } +} \ No newline at end of file diff --git a/src/client/views/nodes/MenuIconBox.tsx b/src/client/views/nodes/MenuIconBox.tsx new file mode 100644 index 000000000..0aa7b327e --- /dev/null +++ b/src/client/views/nodes/MenuIconBox.tsx @@ -0,0 +1,33 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { createSchema, makeInterface } from '../../../fields/Schema'; +import { StrCast } from '../../../fields/Types'; +import { DocComponent } from '../DocComponent'; +import { FieldView, FieldViewProps } from './FieldView'; +import './MenuIconBox.scss'; +const MenuIconSchema = createSchema({ + icon: "string" +}); + +type MenuIconDocument = makeInterface<[typeof MenuIconSchema]>; +const MenuIconDocument = makeInterface(MenuIconSchema); +@observer +export class MenuIconBox extends DocComponent(MenuIconDocument) { + public static LayoutString(fieldKey: string) { return FieldView.LayoutString(MenuIconBox, fieldKey); } + _ref: React.RefObject = React.createRef(); + + render() { + + const color = this.props.backgroundColor?.(this.props.Document) === "lightgrey" ? "black" : "white"; + const menuBTN =
+
+ +
{this.dataDoc.title}
+
+
; + + return menuBTN; + } +} \ No newline at end of file diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index c04c6c409..97f223c02 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -32,6 +32,7 @@ import { conformsTo } from "lodash"; import { translate } from "googleapis/build/src/apis/translate"; import { DragManager, dropActionType } from "../../util/DragManager"; import { actionAsync } from "mobx-utils"; +import { SelectionManager } from "../../util/SelectionManager"; type PresBoxSchema = makeInterface<[typeof documentSchema]>; const PresBoxDocument = makeInterface(documentSchema); @@ -260,7 +261,7 @@ export class PresBox extends ViewBoxBaseComponent const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); const srcContext = await DocCastAsync(targetDoc.context); const presCollection = Cast(this.layoutDoc.presCollection, Doc, null); - const collectionDocView = presCollection ? DocumentManager.Instance.getDocumentView(presCollection) : undefined; + const collectionDocView = presCollection ? await DocumentManager.Instance.getDocumentView(presCollection) : undefined; if (this.itemIndex >= 0) { if (targetDoc) { if (srcContext) this.layoutDoc.presCollection = srcContext; @@ -496,6 +497,8 @@ export class PresBox extends ViewBoxBaseComponent selectElement = (doc: Doc) => { // this._selectedArray = []; this.gotoDocument(this.childDocs.indexOf(doc), NumCast(this.itemIndex)); + const view = DocumentManager.Instance.getDocumentView(doc); + view && SelectionManager.SelectDoc(view, false); // this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]); // console.log(this._selectedArray); } @@ -504,8 +507,9 @@ export class PresBox extends ViewBoxBaseComponent @action multiSelect = (doc: Doc, ref: HTMLElement) => { this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]); - const ele = ref.getElementsByClassName("stacking"); this._eleArray.push(ref); + const view = DocumentManager.Instance.getDocumentView(doc); + view && SelectionManager.SelectDoc(view, true); } //Shift click @@ -517,6 +521,8 @@ export class PresBox extends ViewBoxBaseComponent for (let i = Math.min(this.itemIndex, this.childDocs.indexOf(doc)); i <= Math.max(this.itemIndex, this.childDocs.indexOf(doc)); i++) { this._selectedArray.push(this.childDocs[i]); this._eleArray.push(ref); + const view = DocumentManager.Instance.getDocumentView(doc); + view && SelectionManager.SelectDoc(view, true); } } } diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx index 958a37568..8ae71c035 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.tsx +++ b/src/client/views/nodes/formattedText/DashFieldView.tsx @@ -190,7 +190,7 @@ export class DashFieldViewInternal extends React.Component c.heading).indexOf(this._fieldKey) === -1 && list.push(new SchemaHeaderField(this._fieldKey, "#f1efeb")); list.map(c => c.heading).indexOf("text") === -1 && list.push(new SchemaHeaderField("text", "#f1efeb")); - alias._pivotField = this._fieldKey; + alias._pivotField = this._fieldKey.startsWith("#") ? "#" : this._fieldKey; this.props.tbox.props.addDocTab(alias, "onRight"); } } diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 627c6e363..fc65f34eb 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1267,7 +1267,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this.doLinkOnDeselect(); // move the richtextmenu offscreen - if (!RichTextMenu.Instance.Pinned) RichTextMenu.Instance.delayHide(); + //if (!RichTextMenu.Instance.Pinned) RichTextMenu.Instance.delayHide(); } _lastTimedMark: Mark | undefined = undefined; @@ -1346,7 +1346,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp @computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); } render() { TraceMobx(); - const scale = this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1); + const scale = this.props.hideOnLeave ? 1 : this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1); const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : ""; const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground; setTimeout(() => this._editorView && RichTextMenu.Instance.updateFromDash(this._editorView, undefined, this.props), this.props.isSelected() ? 10 : 0); // need to make sure that we update a text box that is selected after updating the one that was deselected diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 7ccbfa051..f76707a79 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -77,7 +77,8 @@ export default class RichTextMenu extends AntimodeMenu { super(props); RichTextMenu.Instance = this; this._canFade = false; - this.Pinned = BoolCast(Doc.UserDoc()["menuRichText-pinned"]); + //this.Pinned = BoolCast(Doc.UserDoc()["menuRichText-pinned"]); + this.Pinned = true; this.fontSizeOptions = [ { mark: schema.marks.pFontSize.create({ fontSize: 7 }), title: "Set font size", label: "7pt", command: this.changeFontSize }, @@ -529,7 +530,7 @@ export default class RichTextMenu extends AntimodeMenu { indentParagraph(state: EditorState, dispatch: any) { var tr = state.tr; - let headin = false; + const heading = false; state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos, parent, index) => { if (node.type === schema.nodes.paragraph || node.type === schema.nodes.heading) { const nodeval = node.attrs.indent ? Number(node.attrs.indent) : undefined; @@ -539,7 +540,7 @@ export default class RichTextMenu extends AntimodeMenu { } return true; }); - !headin && dispatch?.(tr); + !heading && dispatch?.(tr); return true; } @@ -920,16 +921,22 @@ export default class RichTextMenu extends AntimodeMenu { render() { TraceMobx(); const row1 =
{[ - !this.collapsed ? this.getDragger() : (null), - !this.Pinned ? (null) :
{[ - this.createButton("bold", "Bold", this.boldActive, toggleMark(schema.marks.strong)), - this.createButton("italic", "Italic", this.italicsActive, toggleMark(schema.marks.em)), - this.createButton("underline", "Underline", this.underlineActive, toggleMark(schema.marks.underline)), - this.createButton("strikethrough", "Strikethrough", this.strikethroughActive, toggleMark(schema.marks.strikethrough)), - this.createButton("superscript", "Superscript", this.superscriptActive, toggleMark(schema.marks.superscript)), - this.createButton("subscript", "Subscript", this.subscriptActive, toggleMark(schema.marks.subscript)), -
- ]}
, + //!this.collapsed ? this.getDragger() : (null), + // !this.Pinned ? (null) :
{[ + // this.createButton("bold", "Bold", this.boldActive, toggleMark(schema.marks.strong)), + // this.createButton("italic", "Italic", this.italicsActive, toggleMark(schema.marks.em)), + // this.createButton("underline", "Underline", this.underlineActive, toggleMark(schema.marks.underline)), + // this.createButton("strikethrough", "Strikethrough", this.strikethroughActive, toggleMark(schema.marks.strikethrough)), + // this.createButton("superscript", "Superscript", this.superscriptActive, toggleMark(schema.marks.superscript)), + // this.createButton("subscript", "Subscript", this.subscriptActive, toggleMark(schema.marks.subscript)), + //
+ // ]}
, + this.createButton("bold", "Bold", this.boldActive, toggleMark(schema.marks.strong)), + this.createButton("italic", "Italic", this.italicsActive, toggleMark(schema.marks.em)), + this.createButton("underline", "Underline", this.underlineActive, toggleMark(schema.marks.underline)), + this.createButton("strikethrough", "Strikethrough", this.strikethroughActive, toggleMark(schema.marks.strikethrough)), + this.createButton("superscript", "Superscript", this.superscriptActive, toggleMark(schema.marks.superscript)), + this.createButton("subscript", "Subscript", this.subscriptActive, toggleMark(schema.marks.subscript)), this.createColorButton(), this.createHighlighterButton(), this.createLinkButton(), @@ -957,16 +964,16 @@ export default class RichTextMenu extends AntimodeMenu { this.createButton("minus", "Horizontal Rule", undefined, this.insertHorizontalRule),
,]}
-
- {/*
+ {/*
+ {
-
*/} +
} -
+
*/}
; return ( diff --git a/src/client/views/nodes/formattedText/nodes_rts.ts b/src/client/views/nodes/formattedText/nodes_rts.ts index 0eca6d753..1616500f6 100644 --- a/src/client/views/nodes/formattedText/nodes_rts.ts +++ b/src/client/views/nodes/formattedText/nodes_rts.ts @@ -79,14 +79,14 @@ export const nodes: { [index: string]: NodeSpec } = { { tag: "h5", attrs: { level: 5 } }, { tag: "h6", attrs: { level: 6 } }], toDOM(node) { - var dom = toParagraphDOM(node) as any; - var level = node.attrs.level || 1; + const dom = toParagraphDOM(node) as any; + const level = node.attrs.level || 1; dom[0] = 'h' + level; return dom; }, getAttrs(dom: any) { - var attrs = getParagraphNodeAttrs(dom) as any; - var level = Number(dom.nodeName.substring(1)) || 1; + const attrs = getParagraphNodeAttrs(dom) as any; + const level = Number(dom.nodeName.substring(1)) || 1; attrs.level = level; return attrs; } diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 43e74ff61..85fc63074 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -528,10 +528,10 @@ export namespace Doc { const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key])); const field = ProxyField.WithoutProxy(() => doc[key]); const copyObjectField = async (field: ObjectField) => { - const list = await Cast(doc[key], listSpec(Doc)); + const list = Cast(doc[key], listSpec(Doc)); const docs = list && (await DocListCastAsync(list))?.filter(d => d instanceof Doc); if (docs !== undefined && docs.length) { - const clones = await Promise.all(docs.map(async d => await Doc.makeClone(d as Doc, cloneMap, rtfs, exclusions, dontCreate))); + const clones = await Promise.all(docs.map(async d => Doc.makeClone(d, cloneMap, rtfs, exclusions, dontCreate))); !dontCreate && assignKey(new List(clones)); } else if (doc[key] instanceof Doc) { assignKey(key.includes("layout[") ? undefined : key.startsWith("layout") ? doc[key] as Doc : await Doc.makeClone(doc[key] as Doc, cloneMap, rtfs, exclusions, dontCreate)); // reference documents except copy documents that are expanded teplate fields @@ -625,7 +625,7 @@ export namespace Doc { Array.from(map.entries()).forEach(f => docs[f[0]] = f[1]); const docString = JSON.stringify({ id: doc[Id], docs }, replacer); - var zip = new JSZip(); + const zip = new JSZip(); zip.file(doc.title + ".json", docString); diff --git a/src/server/ActionUtilities.ts b/src/server/ActionUtilities.ts index 60f66c878..fd9bc0c83 100644 --- a/src/server/ActionUtilities.ts +++ b/src/server/ActionUtilities.ts @@ -1,11 +1,11 @@ -import { readFile, writeFile, exists, mkdir, unlink, createWriteStream } from 'fs'; -import { ExecOptions } from 'shelljs'; import { exec } from 'child_process'; -import * as path from 'path'; -import * as rimraf from "rimraf"; -import { yellow, Color } from 'colors'; +import { Color, yellow } from 'colors'; +import { createWriteStream, exists, mkdir, readFile, unlink, writeFile } from 'fs'; import * as nodemailer from "nodemailer"; import { MailOptions } from "nodemailer/lib/json-transport"; +import * as path from 'path'; +import * as rimraf from "rimraf"; +import { ExecOptions } from 'shelljs'; import Mail = require('nodemailer/lib/mailer'); const projectRoot = path.resolve(__dirname, "../../"); diff --git a/src/server/ApiManagers/UtilManager.ts b/src/server/ApiManagers/UtilManager.ts index e2cd88726..e657866ce 100644 --- a/src/server/ApiManagers/UtilManager.ts +++ b/src/server/ApiManagers/UtilManager.ts @@ -6,7 +6,6 @@ import { exec } from 'child_process'; // const recommender = new Recommender(); // recommender.testModel(); -import executeImport from "../../scraping/buxton/final/BuxtonImporter"; export default class UtilManager extends ApiManager { diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts index 2bf4c1956..890fb6f6d 100644 --- a/src/server/DashUploadUtils.ts +++ b/src/server/DashUploadUtils.ts @@ -1,23 +1,22 @@ -import { unlinkSync, createWriteStream, readFileSync, rename, writeFile, existsSync } from 'fs'; -import { Utils } from '../Utils'; -import * as path from 'path'; -import * as sharp from 'sharp'; -import request = require('request-promise'); +import { red } from 'colors'; import { ExifImage } from 'exif'; -import { Opt } from '../fields/Doc'; -import { AcceptibleMedia, Upload } from './SharedMediaTypes'; -import { filesDirectory, publicDirectory } from '.'; import { File } from 'formidable'; +import { createWriteStream, existsSync, readFileSync, rename, unlinkSync, writeFile } from 'fs'; +import * as path from 'path'; import { basename } from "path"; -import { createIfNotExists } from './ActionUtilities'; +import * as sharp from 'sharp'; +import { Stream } from 'stream'; +import { filesDirectory, publicDirectory } from '.'; +import { Opt } from '../fields/Doc'; import { ParsedPDF } from "../server/PdfTypes"; +import { Utils } from '../Utils'; +import { createIfNotExists } from './ActionUtilities'; +import { clientPathToFile, Directory, pathToDirectory, serverPathToFile } from './ApiManagers/UploadManager'; +import { resolvedServerUrl } from "./server_Initialization"; +import { AcceptibleMedia, Upload } from './SharedMediaTypes'; +import request = require('request-promise'); const parse = require('pdf-parse'); -import { Directory, serverPathToFile, clientPathToFile, pathToDirectory } from './ApiManagers/UploadManager'; -import { red } from 'colors'; -import { Stream } from 'stream'; -import { resolvedPorts } from './server_Initialization'; const requestImageSize = require("../client/util/request-image-size"); -import { resolvedServerUrl } from "./server_Initialization"; export enum SizeSuffix { Small = "_s", diff --git a/src/server/GarbageCollector.ts b/src/server/GarbageCollector.ts index 24745cbb4..a9a3b0481 100644 --- a/src/server/GarbageCollector.ts +++ b/src/server/GarbageCollector.ts @@ -1,9 +1,9 @@ -import { Database } from './database'; - -import * as path from 'path'; import * as fs from 'fs'; +import * as path from 'path'; +import { Database } from './database'; import { Search } from './Search'; + function addDoc(doc: any, ids: string[], files: { [name: string]: string[] }) { for (const key in doc) { if (!doc.hasOwnProperty(key)) { diff --git a/src/server/MemoryDatabase.ts b/src/server/MemoryDatabase.ts index 1f1d702d9..7f477327e 100644 --- a/src/server/MemoryDatabase.ts +++ b/src/server/MemoryDatabase.ts @@ -1,6 +1,7 @@ -import { IDatabase, DocumentsCollection } from './IDatabase'; -import { Transferable } from './Message'; +import { DH_CHECK_P_NOT_SAFE_PRIME } from 'constants'; import * as mongodb from 'mongodb'; +import { DocumentsCollection, IDatabase } from './IDatabase'; +import { Transferable } from './Message'; export class MemoryDatabase implements IDatabase { diff --git a/src/server/Message.ts b/src/server/Message.ts index ff0381fd3..59b24cd82 100644 --- a/src/server/Message.ts +++ b/src/server/Message.ts @@ -1,6 +1,6 @@ -import { Utils } from "../Utils"; import { Point } from "../pen-gestures/ndollar"; import { AnalysisResult, ImportResults } from "../scraping/buxton/final/BuxtonImporter"; +import { Utils } from "../Utils"; export class Message { private _name: string; diff --git a/src/server/ProcessFactory.ts b/src/server/ProcessFactory.ts index acb8b3a99..63682368f 100644 --- a/src/server/ProcessFactory.ts +++ b/src/server/ProcessFactory.ts @@ -1,8 +1,8 @@ -import { existsSync, mkdirSync } from "fs"; -import { pathFromRoot, fileDescriptorFromStream } from './ActionUtilities'; -import rimraf = require("rimraf"); import { ChildProcess, spawn, StdioOptions } from "child_process"; +import { existsSync, mkdirSync } from "fs"; import { Stream } from "stream"; +import { fileDescriptorFromStream, pathFromRoot } from './ActionUtilities'; +import rimraf = require("rimraf"); export namespace ProcessFactory { diff --git a/src/server/Recommender.ts b/src/server/Recommender.ts deleted file mode 100644 index 935ec3871..000000000 --- a/src/server/Recommender.ts +++ /dev/null @@ -1,133 +0,0 @@ -// //import { Doc } from "../fields/Doc"; -// //import { StrCast } from "../fields/Types"; -// //import { List } from "../fields/List"; -// //import { CognitiveServices } from "../client/cognitive_services/CognitiveServices"; - -// // var w2v = require('word2vec'); -// var assert = require('assert'); -// var arxivapi = require('arxiv-api-node'); -// import requestPromise = require("request-promise"); -// import * as use from '@tensorflow-models/universal-sentence-encoder'; -// import { Tensor } from "@tensorflow/tfjs-core/dist/tensor"; -// require('@tensorflow/tfjs-node'); - -// //http://gnuwin32.sourceforge.net/packages/make.htm - -// export class Recommender { - -// private _model: any; -// static Instance: Recommender; -// private dimension: number = 0; -// private choice: string = ""; // Tensorflow or Word2Vec - -// constructor() { -// Recommender.Instance = this; -// } - -// /*** -// * Loads pre-trained model from TF -// */ - -// public async loadTFModel() { -// let self = this; -// return new Promise(res => { -// use.load().then(model => { -// self.choice = "TF"; -// self._model = model; -// self.dimension = 512; -// res(model); -// }); -// } - -// ); -// } - -// /*** -// * Loads pre-trained model from word2vec -// */ - -// // private loadModel(): Promise { -// // let self = this; -// // return new Promise(res => { -// // w2v.loadModel("./node_modules/word2vec/examples/fixtures/vectors.txt", function (err: any, model: any) { -// // self.choice = "WV"; -// // self._model = model; -// // self.dimension = model.size; -// // res(model); -// // }); -// // }); -// // } - -// /*** -// * Testing -// */ - -// public async testModel() { -// if (!this._model) { -// await this.loadTFModel(); -// } -// if (this._model) { -// if (this.choice === "WV") { -// let similarity = this._model.similarity('father', 'mother'); -// } -// else if (this.choice === "TF") { -// const model = this._model as use.UniversalSentenceEncoder; -// // Embed an array of sentences. -// const sentences = [ -// 'Hello.', -// 'How are you?' -// ]; -// const embeddings = await this.vectorize(sentences); -// if (embeddings) embeddings.print(true /*verbose*/); -// // model.embed(sentences).then(embeddings => { -// // // `embeddings` is a 2D tensor consisting of the 512-dimensional embeddings for each sentence. -// // // So in this example `embeddings` has the shape [2, 512]. -// // embeddings.print(true /* verbose */); -// // }); -// } -// } -// else { -// console.log("model not found :("); -// } -// } - -// /*** -// * Uses model to convert words to vectors -// */ - -// public async vectorize(text: string[]): Promise { -// if (!this._model) { -// await this.loadTFModel(); -// } -// if (this._model) { -// if (this.choice === "WV") { -// let word_vecs = this._model.getVectors(text); -// return word_vecs; -// } -// else if (this.choice === "TF") { -// const model = this._model as use.UniversalSentenceEncoder; -// return new Promise(res => { -// model.embed(text).then(embeddings => { -// res(embeddings); -// }); -// }); - -// } -// } -// } - -// // public async trainModel() { -// // w2v.word2vec("./node_modules/word2vec/examples/eng_news-typical_2016_1M-sentences.txt", './node_modules/word2vec/examples/my_phrases.txt', { -// // cbow: 1, -// // size: 200, -// // window: 8, -// // negative: 25, -// // hs: 0, -// // sample: 1e-4, -// // threads: 20, -// // iter: 200, -// // minCount: 2 -// // }); -// // } - -// } diff --git a/src/server/RouteManager.ts b/src/server/RouteManager.ts index 1a2340afc..78b75d6be 100644 --- a/src/server/RouteManager.ts +++ b/src/server/RouteManager.ts @@ -1,8 +1,8 @@ -import RouteSubscriber from "./RouteSubscriber"; -import { DashUserModel } from "./authentication/DashUserModel"; -import { Request, Response, Express } from 'express'; -import { cyan, red, green } from 'colors'; +import { cyan, green, red } from 'colors'; +import { Express, Request, Response } from 'express'; import { AdminPriviliges } from "."; +import { DashUserModel } from "./authentication/DashUserModel"; +import RouteSubscriber from "./RouteSubscriber"; export enum Method { GET, diff --git a/src/server/Search.ts b/src/server/Search.ts index 21064e520..decd1f5b1 100644 --- a/src/server/Search.ts +++ b/src/server/Search.ts @@ -1,5 +1,5 @@ -import * as rp from 'request-promise'; import { red } from 'colors'; +import * as rp from 'request-promise'; const pathTo = (relative: string) => `http://localhost:8983/solr/dash/${relative}`; diff --git a/src/server/database.ts b/src/server/database.ts index 2372cbcf2..b7aa77f5d 100644 --- a/src/server/database.ts +++ b/src/server/database.ts @@ -1,11 +1,11 @@ import * as mongodb from 'mongodb'; -import { Transferable } from './Message'; +import * as mongoose from 'mongoose'; import { Opt } from '../fields/Doc'; -import { Utils, emptyFunction } from '../Utils'; +import { emptyFunction, Utils } from '../Utils'; import { GoogleApiServerUtils } from './apis/google/GoogleApiServerUtils'; -import { IDatabase, DocumentsCollection } from './IDatabase'; +import { DocumentsCollection, IDatabase } from './IDatabase'; import { MemoryDatabase } from './MemoryDatabase'; -import * as mongoose from 'mongoose'; +import { Transferable } from './Message'; import { Upload } from './SharedMediaTypes'; export namespace Database { diff --git a/src/server/downsize.ts b/src/server/downsize.ts index 5cd709fa3..382994e2d 100644 --- a/src/server/downsize.ts +++ b/src/server/downsize.ts @@ -1,5 +1,5 @@ -import * as sharp from 'sharp'; import * as fs from 'fs'; +import * as sharp from 'sharp'; const folder = "./src/server/public/files/"; const pngTypes = ["png", "PNG"]; diff --git a/src/server/index.ts b/src/server/index.ts index 9af4b00bc..9185e3c5e 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -1,29 +1,29 @@ require('dotenv').config(); -import { GoogleApiServerUtils } from "./apis/google/GoogleApiServerUtils"; +import { yellow } from "colors"; import * as mobileDetect from 'mobile-detect'; import * as path from 'path'; -import { Database } from './database'; -import { DashUploadUtils } from './DashUploadUtils'; -import RouteSubscriber from './RouteSubscriber'; -import initializeServer, { resolvedPorts } from './server_Initialization'; -import RouteManager, { Method, _success, _permission_denied, _error, _invalid, PublicHandler } from './RouteManager'; import * as qs from 'query-string'; -import UtilManager from './ApiManagers/UtilManager'; -import { SearchManager } from './ApiManagers/SearchManager'; -import UserManager from './ApiManagers/UserManager'; -import DownloadManager from './ApiManagers/DownloadManager'; -import { GoogleCredentialsLoader, SSL } from './apis/google/CredentialsLoader'; -import DeleteManager from "./ApiManagers/DeleteManager"; -import PDFManager from "./ApiManagers/PDFManager"; -import UploadManager from "./ApiManagers/UploadManager"; import { log_execution } from "./ActionUtilities"; +import DeleteManager from "./ApiManagers/DeleteManager"; +import DownloadManager from './ApiManagers/DownloadManager'; import GeneralGoogleManager from "./ApiManagers/GeneralGoogleManager"; -import HypothesisManager from "./ApiManagers/HypothesisManager"; import GooglePhotosManager from "./ApiManagers/GooglePhotosManager"; -import { Logger } from "./ProcessFactory"; -import { yellow } from "colors"; +import HypothesisManager from "./ApiManagers/HypothesisManager"; +import PDFManager from "./ApiManagers/PDFManager"; +import { SearchManager } from './ApiManagers/SearchManager'; import SessionManager from "./ApiManagers/SessionManager"; +import UploadManager from "./ApiManagers/UploadManager"; +import UserManager from './ApiManagers/UserManager'; +import UtilManager from './ApiManagers/UtilManager'; +import { GoogleCredentialsLoader, SSL } from './apis/google/CredentialsLoader'; +import { GoogleApiServerUtils } from "./apis/google/GoogleApiServerUtils"; import { AppliedSessionAgent } from "./DashSession/Session/agents/applied_session_agent"; +import { DashUploadUtils } from './DashUploadUtils'; +import { Database } from './database'; +import { Logger } from "./ProcessFactory"; +import RouteManager, { Method, PublicHandler } from './RouteManager'; +import RouteSubscriber from './RouteSubscriber'; +import initializeServer, { resolvedPorts } from './server_Initialization'; export const AdminPriviliges: Map = new Map(); export const onWindows = process.platform === "win32"; diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts index 744d4547b..e40f2b8e5 100644 --- a/src/server/server_Initialization.ts +++ b/src/server/server_Initialization.ts @@ -1,31 +1,31 @@ +import * as bodyParser from 'body-parser'; +import { blue, yellow } from 'colors'; +import * as cookieParser from 'cookie-parser'; +import * as cors from "cors"; import * as express from 'express'; -import * as expressValidator from 'express-validator'; import * as session from 'express-session'; +import * as expressValidator from 'express-validator'; +import * as fs from 'fs'; +import { Server as HttpServer } from "http"; +import { createServer, Server as HttpsServer } from "https"; import * as passport from 'passport'; -import * as bodyParser from 'body-parser'; -import * as cookieParser from 'cookie-parser'; -import expressFlash = require('express-flash'); -import flash = require('connect-flash'); -import { Database } from './database'; -import { getForgot, getLogin, getLogout, getReset, getSignup, postForgot, postLogin, postReset, postSignup } from './authentication/AuthenticationManager'; -const MongoStore = require('connect-mongo')(session); -import RouteManager from './RouteManager'; -import { WebSocket } from './websocket'; +import * as request from 'request'; import * as webpack from 'webpack'; -const config = require('../../webpack.config'); -const compiler = webpack(config); import * as wdm from 'webpack-dev-middleware'; import * as whm from 'webpack-hot-middleware'; -import * as fs from 'fs'; -import * as request from 'request'; -import RouteSubscriber from './RouteSubscriber'; import { publicDirectory } from '.'; import { logPort } from './ActionUtilities'; -import { blue, yellow } from 'colors'; -import * as cors from "cors"; -import { createServer, Server as HttpsServer } from "https"; -import { Server as HttpServer } from "http"; import { SSL } from './apis/google/CredentialsLoader'; +import { getForgot, getLogin, getLogout, getReset, getSignup, postForgot, postLogin, postReset, postSignup } from './authentication/AuthenticationManager'; +import { Database } from './database'; +import RouteManager from './RouteManager'; +import RouteSubscriber from './RouteSubscriber'; +import { WebSocket } from './websocket'; +import expressFlash = require('express-flash'); +import flash = require('connect-flash'); +const MongoStore = require('connect-mongo')(session); +const config = require('../../webpack.config'); +const compiler = webpack(config); /* RouteSetter is a wrapper around the server that prevents the server from being exposed. */ diff --git a/src/server/websocket.ts b/src/server/websocket.ts index f63a35e43..d5f89a750 100644 --- a/src/server/websocket.ts +++ b/src/server/websocket.ts @@ -1,21 +1,20 @@ -import * as fs from 'fs'; -import { logPort } from './ActionUtilities'; -import { Utils } from "../Utils"; -import { MessageStore, Transferable, Types, Diff, YoutubeQueryInput, YoutubeQueryTypes, GestureContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent, MobileDocumentUploadContent, RoomMessage } from "./Message"; -import { Client } from "./Client"; -import { Socket } from "socket.io"; -import { Database } from "./database"; -import { Search } from "./Search"; -import * as sio from 'socket.io'; -import YoutubeApi from "./apis/youtube/youtubeApiSample"; -import { GoogleCredentialsLoader, SSL } from "./apis/google/CredentialsLoader"; -import { timeMap } from "./ApiManagers/UserManager"; import { green } from "colors"; +import * as express from "express"; +import { createServer, Server } from "https"; import { networkInterfaces } from "os"; +import * as sio from 'socket.io'; +import { Socket } from "socket.io"; import executeImport from "../scraping/buxton/final/BuxtonImporter"; +import { Utils } from "../Utils"; +import { logPort } from './ActionUtilities'; +import { timeMap } from "./ApiManagers/UserManager"; +import { GoogleCredentialsLoader, SSL } from "./apis/google/CredentialsLoader"; +import YoutubeApi from "./apis/youtube/youtubeApiSample"; +import { Client } from "./Client"; +import { Database } from "./database"; import { DocumentsCollection } from "./IDatabase"; -import { createServer, Server } from "https"; -import * as express from "express"; +import { Diff, GestureContent, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, Transferable, Types, UpdateMobileInkOverlayPositionContent, YoutubeQueryInput, YoutubeQueryTypes } from "./Message"; +import { Search } from "./Search"; import { resolvedPorts } from './server_Initialization'; export namespace WebSocket { -- cgit v1.2.3-70-g09d2 From f4c14a48f91ec95b900bb1e25452d18971ff21a8 Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Mon, 3 Aug 2020 23:14:20 +0800 Subject: works with selection manager (PropertiesView) --- .../collectionFreeForm/PropertiesView.scss | 42 +++++++++++----------- .../collectionFreeForm/PropertiesView.tsx | 21 +++++++---- src/client/views/nodes/PresBox.scss | 2 +- src/client/views/nodes/PresBox.tsx | 2 +- .../views/presentationview/PresElementBox.tsx | 2 +- 5 files changed, 39 insertions(+), 30 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss index 6283a6669..2cdaa25ee 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss @@ -543,6 +543,27 @@ } } +.propertiesView-presSelected { + border-top: solid 1px darkgrey; + width: 100%; + padding-top: 5px; + font-family: Roboto; + font-weight: 500; + display: inline-flex; + + .propertiesView-selectedList { + border-left: solid 1px darkgrey; + margin-left: 10px; + padding-left: 5px; + + .selectedList-items { + font-size: 12; + font-weight: 300; + margin-top: 1; + } + } +} + .widthAndDash { .width { @@ -617,25 +638,4 @@ margin-top: 2px; } } - - .propertiesView-presSelected { - border-top: solid 1px darkgrey; - width: 100%; - padding-top: 5px; - font-family: Roboto; - font-weight: 500; - display: inline-flex; - - .propertiesView-selectedList { - border-left: solid 1px darkgrey; - margin-left: 10px; - padding-left: 5px; - - .selectedList-items { - font-size: 12; - font-weight: 300; - margin-top: 1; - } - } - } } \ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx index ce8baf559..88d585596 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx @@ -47,9 +47,14 @@ export class PropertiesView extends React.Component { @computed get selectedDocumentView() { if (SelectionManager.SelectedDocuments().length) { return SelectionManager.SelectedDocuments()[0]; - } else { console.log(undefined); return undefined; } + } else if (PresBox.Instance._selectedArray.length >= 1) { + return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc); + } else { return undefined; } + } + @computed get isPres(): boolean { + if (this.selectedDoc?.type === DocumentType.PRES) return true; + return false; } - @computed get isPres() { return this.selectedDoc?.type === DocumentType.PRES } @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; } @computed get dataDoc() { return this.selectedDocumentView?.dataDoc; } @@ -748,10 +753,14 @@ export class PropertiesView extends React.Component { render() { if (!this.selectedDoc) { - return
-
- No Document Selected -
; + console.log("!selectedDoc") + if (this.isPres === false) { + console.log("!isPres") + return
+
+ No Document Selected +
; + } } const novice = Doc.UserDoc().noviceMode; diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss index e5878708f..83e7152a8 100644 --- a/src/client/views/nodes/PresBox.scss +++ b/src/client/views/nodes/PresBox.scss @@ -143,7 +143,7 @@ display: grid; justify-content: flex-start; align-items: center; - grid-template-columns: repeat(auto-fit, 50px); + grid-template-columns: repeat(auto-fit, 70px); } .ribbon-property { diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 618161e97..496d4666e 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -832,7 +832,7 @@ export class PresBox extends ViewBoxBaseComponent
Effect direction
-
+
{"Enter from left"}
}>
targetDoc.presEffectDirection = 'left'}>
{"Enter from right"}
}>
targetDoc.presEffectDirection = 'right'}>
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 85949c5a8..ce7a43315 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -278,7 +278,7 @@ export class PresElementBox extends ViewBoxBaseComponent Date: Tue, 4 Aug 2020 17:58:50 +0800 Subject: properties view for presentation --- .../collectionFreeForm/PropertiesView.scss | 4 +- src/client/views/nodes/PresBox.scss | 14 ++--- src/client/views/nodes/PresBox.tsx | 59 +++++++++++----------- .../views/presentationview/PresElementBox.tsx | 8 ++- 4 files changed, 44 insertions(+), 41 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss index 2cdaa25ee..f559b940c 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss @@ -5,8 +5,8 @@ font-family: "Noto Sans"; cursor: auto; - overflow-x: visible; - overflow-y: visible; + overflow-x: hidden; + overflow-y: scroll; .propertiesView-title { background-color: rgb(159, 159, 159); diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss index 83e7152a8..45c6d33b8 100644 --- a/src/client/views/nodes/PresBox.scss +++ b/src/client/views/nodes/PresBox.scss @@ -291,7 +291,7 @@ .ribbon-textInput { border-radius: 2px; - height: 30px; + height: 20px; font-size: 11.5; font-weight: 100; align-self: center; @@ -363,14 +363,14 @@ .ribbon-final-button { position: relative; - font-size: 11.5; + font-size: 11; font-weight: normal; letter-spacing: normal; display: flex; justify-content: center; align-items: center; margin-bottom: 5px; - height: 30px; + height: 25px; color: white; width: 100%; max-width: 120; @@ -382,14 +382,14 @@ .ribbon-final-button-hidden { position: relative; - font-size: 11.5; + font-size: 11; font-weight: normal; letter-spacing: normal; display: flex; justify-content: center; align-items: center; margin-bottom: 5px; - height: 30px; + height: 25px; color: lightgrey; width: 100%; max-width: 120; @@ -414,9 +414,9 @@ } .ribbon-button { - font-size: 11; + font-size: 10.5; font-weight: 200; - height: 30; + height: 20; background-color: #dedede; border: solid 1px black; display: flex; diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 496d4666e..0a73106a3 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -900,22 +900,16 @@ export class PresBox extends ViewBoxBaseComponent
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
{this.stringType} options -
-
Child documents
-
Edit
+
+
Start automatically
+
Start manually
-
-
Internal zoom
-
Viewfinder
-
Snapshot
-
-
-
Text progressivize
-
Edit
+
+
Open document
+
Open parent collection
-
-
Scroll progressivize
-
Edit
+
+
Store original website
@@ -928,28 +922,25 @@ export class PresBox extends ViewBoxBaseComponent return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> -
-
runInAction(() => { this.layout = 'blank' })} /> -
runInAction(() => { this.layout = 'title' })}> +
+
runInAction(() => { this.layout = 'blank'; this.createNewSlide(this.layout); })} /> +
runInAction(() => { this.layout = 'title'; this.createNewSlide(this.layout); })}>
Title
Subtitle
-
runInAction(() => { this.layout = 'header' })}> +
runInAction(() => { this.layout = 'header'; this.createNewSlide(this.layout); })}>
Section header
-
runInAction(() => { this.layout = 'content' })}> +
runInAction(() => { this.layout = 'content'; this.createNewSlide(this.layout); })}>
Title
Text goes here
-
runInAction(() => { this.layout = 'twoColumns' })}> +
runInAction(() => { this.layout = 'twoColumns'; this.createNewSlide(this.layout); })}>
Title
Column one text
Column two text
-
runInAction(() => { this.openLayouts = !this.openLayouts })}> - -
); @@ -1033,9 +1024,17 @@ export class PresBox extends ViewBoxBaseComponent } createTemplate = (layout: string, input?: string) => { + const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + let x = 0; + let y = 0; + if (activeItem && targetDoc) { + x = NumCast(targetDoc._x); + y = NumCast(targetDoc._y) + NumCast(targetDoc._height) + 20; + } let doc = undefined; const title = Docs.Create.TextDocument("Click to change title", { - title: "Slide title", _width: 380, _height: 60, x: 10, y: 58, _fontSize: "24pt" + title: "Slide title", _width: 380, _height: 60, x: 10, y: 58, _fontSize: "24pt", }); const subtitle = Docs.Create.TextDocument("Click to change subtitle", { title: "Slide subtitle", _width: 380, _height: 50, x: 10, y: 118, _fontSize: "16pt" @@ -1058,27 +1057,27 @@ export class PresBox extends ViewBoxBaseComponent switch (layout) { case 'blank': doc = Docs.Create.FreeformDocument([], { - title: input ? input : "Blank slide", _width: 400, _height: 225, _fitToBox: true + title: input ? input : "Blank slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y }); break; case 'title': doc = Docs.Create.FreeformDocument([title, subtitle], { - title: input ? input : "Title slide", _width: 400, _height: 225, _fitToBox: true + title: input ? input : "Title slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y }); break; case 'header': doc = Docs.Create.FreeformDocument([header], { - title: input ? input : "Section header", _width: 400, _height: 225, _fitToBox: true + title: input ? input : "Section header", _width: 400, _height: 225, _fitToBox: true, x: x, y: y }); break; case 'content': doc = Docs.Create.FreeformDocument([contentTitle, content], { - title: input ? input : "Title and content", _width: 400, _height: 225, _fitToBox: true + title: input ? input : "Title and content", _width: 400, _height: 225, _fitToBox: true, x: x, y: y }); break; case 'twoColumns': doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], { - title: input ? input : "Title and two columns", _width: 400, _height: 225, _fitToBox: true + title: input ? input : "Title and two columns", _width: 400, _height: 225, _fitToBox: true, x: x, y: y }); break; default: @@ -1218,7 +1217,7 @@ export class PresBox extends ViewBoxBaseComponent
Edit
-
+
Frames
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index ce7a43315..90eb8580e 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -251,6 +251,10 @@ export class PresElementBox extends ViewBoxBaseComponent doc)); // let value = this.getValue(this._heading); // value = typeof value === "string" ? `"${value}"` : value; + PresBox.Instance._dragArray.map(ele => { + ele.style.backgroundColor = "#d5dce2"; + ele.style.borderRadius = '5px'; + }); if (activeItem) { DragManager.StartDocumentDrag(PresBox.Instance._dragArray.map(ele => ele), dragData, e.clientX, e.clientY); activeItem.dragging = true; @@ -295,10 +299,10 @@ export class PresElementBox extends ViewBoxBaseComponent <> -
+
{`${this.indexInPres + 1}.`}
-
+
{`${this.targetDoc?.title}`}
{"Movement speed"}
}>
300 ? "block" : "none" }}>{this.transition}
-- cgit v1.2.3-70-g09d2 From 6ea1420c502f76a1c3219e0c34633575fb00ec98 Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Tue, 4 Aug 2020 18:06:29 +0800 Subject: props for prez --- .../collectionFreeForm/PropertiesView.tsx | 302 +++++++-------------- 1 file changed, 95 insertions(+), 207 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx index 88d585596..3e8404874 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx @@ -27,8 +27,6 @@ import { ColorState, SketchPicker } from "react-color"; import AntimodeMenu from "../../AntimodeMenu"; import "./FormatShapePane.scss"; import { discovery_v1 } from "googleapis"; -import { PresBox } from "../../nodes/PresBox"; -import { DocumentManager } from "../../../util/DocumentManager"; interface PropertiesViewProps { @@ -47,14 +45,8 @@ export class PropertiesView extends React.Component { @computed get selectedDocumentView() { if (SelectionManager.SelectedDocuments().length) { return SelectionManager.SelectedDocuments()[0]; - } else if (PresBox.Instance._selectedArray.length >= 1) { - return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc); } else { return undefined; } } - @computed get isPres(): boolean { - if (this.selectedDoc?.type === DocumentType.PRES) return true; - return false; - } @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; } @computed get dataDoc() { return this.selectedDocumentView?.dataDoc; } @@ -66,13 +58,6 @@ export class PropertiesView extends React.Component { @observable openLayout: boolean = true; @observable openAppearance: boolean = true; @observable openTransform: boolean = true; - //Pres Trails booleans: - @observable openAddSlide: boolean = true; - @observable openPresentationTools: boolean = true; - @observable openPresTransitions: boolean = true; - @observable openPresProgressivize: boolean = true; - @observable openSlideOptions: boolean = true; - @computed get isInk() { return this.selectedDoc?.type === DocumentType.INK; } @@ -220,7 +205,7 @@ export class PropertiesView extends React.Component { } } - + @undoBatch setKeyValue = (value: string) => { if (this.selectedDoc && this.dataDoc) { const doc = this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc; @@ -281,9 +266,14 @@ export class PropertiesView extends React.Component { } } + @undoBatch + changePermissions = (e: any, user: string) => { + SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, this.selectedDoc!); + } + getPermissionsSelect(user: string) { return
- -
this.startOrResetPres(0)}> -   - -
-
{ e.stopPropagation; this.togglePlay(); }}> - - {this.playDropdown} -
-
- +
this.layoutDoc.presStatus = "manual"}>   Present
{ e.stopPropagation; this.togglePresent(); }}> {this.presentDropdown}
-
- -
-
- -
-
this.layoutDoc.presStatus = "edit"}> - +
+ {/* +
this.startOrResetPres(0)}> +   + +
+
{ e.stopPropagation; this.togglePlay(); }}> + + {this.playDropdown} +
+
*/} +
+
this.startOrResetPres(this.itemIndex)}>
+
+
+
Slide {this.itemIndex + 1} / {this.childDocs.length}
+
+
this.layoutDoc.presStatus = "edit"}> + +
@@ -1809,14 +1730,4 @@ Scripting.addGlobal(function lookupPresBoxField(container: Doc, field: string, d if (field === '_itemIndex') return container._itemIndex; if (field === 'presBox') return container; return undefined; -}); - - - -// console.log("render = " + this.layoutDoc.title + " " + this.layoutDoc.presStatus); -// const presOrderedDocs = DocListCast(activeItem.presOrderedDocs); -// if (presOrderedDocs.length != this.childDocs.length || presOrderedDocs.some((pd, i) => pd !== this.childDocs[i])) { -// this.rootDoc.presOrderedDocs = new List(this.childDocs.slice()); -// } - - +}); \ No newline at end of file diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index fc65f34eb..76d23ddfe 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -536,6 +536,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp Doc.AddDocToList(Cast(Doc.UserDoc()["template-notes"], Doc, null), "data", this.rootDoc); }, icon: "eye" }); + appearanceItems.push({ description: "Create progressivized slide...", event: this.progressivizeText, icon: "desktop" }); cm.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" }); const options = cm.findByDescription("Options..."); @@ -547,6 +548,69 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this._downX = this._downY = Number.NaN; } + progressivizeText = () => { + const list = this.ProseRef?.getElementsByTagName("li"); + const mainBulletText: string[] = []; + const mainBulletList: Doc[] = []; + if (list) { + const newBullets: Doc[] = this.recursiveProgressivize(1, list); + mainBulletList.push.apply(mainBulletList, newBullets); + } + console.log(mainBulletList.length); + const title = Docs.Create.TextDocument(StrCast(this.rootDoc.title), { title: "Title", _width: 800, _height: 70, x: 20, y: -10, _fontSize: '20pt', backgroundColor: "rgba(0,0,0,0)", appearFrame: 0, _fontWeight: 700 }); + mainBulletList.push(title); + const doc = Docs.Create.FreeformDocument(mainBulletList, { + title: StrCast(this.rootDoc.title), + x: NumCast(this.props.Document.x), y: NumCast(this.props.Document.y) + NumCast(this.props.Document._height) + 10, + _width: 400, _height: 225, _fitToBox: true, + }); + this.props.addDocument?.(doc); + } + + recursiveProgressivize = (nestDepth: number, list: HTMLCollectionOf, d?: number, y?: number, before?: string): Doc[] => { + const mainBulletList: Doc[] = []; + let b = d ? d : 0; + let yLoc = y ? y : 0; + let nestCount = 0; + let count: string = before ? before : ''; + const fontSize: string = (16 - (nestDepth * 2)) + 'pt'; + const xLoc: number = (nestDepth * 20); + const width: number = 390 - xLoc; + const height: number = 55 - (nestDepth * 5); + for (let i = 0; i < list.length; i++) { + const mainBullets: number = Number(list[i].getAttribute("data-bulletstyle")); + if (mainBullets === nestDepth) { + if (list[i].childElementCount > 1) { + b++; + nestCount++; + count = before ? count + nestCount + "." : nestCount + "."; + yLoc += height; + const text = list[i].getElementsByTagName("p")[0].innerText; + const length = text.length; + console.log(yLoc); + const bullet1 = Docs.Create.TextDocument(count + " " + text, { title: "Slide text", _width: width, _height: height, x: xLoc, y: 10 + (yLoc), _fontSize: fontSize, backgroundColor: "rgba(0,0,0,0)", appearFrame: d ? d : b }); + mainBulletList.push(bullet1); + const newList = this.recursiveProgressivize(nestDepth + 1, list[i].getElementsByTagName("li"), b, yLoc, count); + mainBulletList.push.apply(mainBulletList, newList); + b += newList.length; + yLoc += newList.length * (55 - ((nestDepth + 1) * 5)); + } else { + b++; + nestCount++; + count = before ? count + nestCount + "." : nestCount + "."; + yLoc += height; + const text = list[i].innerText; + const length = text.length; + console.log(yLoc); + const bullet1 = Docs.Create.TextDocument(count + " " + text, { title: "Slide text", _width: width, _height: height, x: xLoc, y: 10 + (yLoc), _fontSize: fontSize, backgroundColor: "rgba(0,0,0,0)", appearFrame: d ? d : b }); + mainBulletList.push(bullet1); + } + } + } + console.log("b: " + b); + return mainBulletList; + } + recordDictation = () => { DictationManager.Controls.listen({ interimHandler: this.setCurrentBulletContent, @@ -1374,6 +1438,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp color: this.props.color ? this.props.color : StrCast(this.layoutDoc[this.props.fieldKey + "-color"], this.props.hideOnLeave ? "white" : "inherit"), pointerEvents: interactive ? undefined : "none", fontSize: Cast(this.layoutDoc._fontSize, "string", null), + fontWeight: Cast(this.layoutDoc._fontWeight, "number", null), fontFamily: StrCast(this.layoutDoc._fontFamily, "inherit"), transition: "opacity 1s" }} diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss index 159cb5f8a..fa70b2a41 100644 --- a/src/client/views/presentationview/PresElementBox.scss +++ b/src/client/views/presentationview/PresElementBox.scss @@ -2,7 +2,8 @@ display: grid; grid-template-columns: max-content max-content max-content; background-color: #d5dce2; - // box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.25); + font-family: Roboto; + letter-spacing: normal; position: relative; pointer-events: all; width: 100%; @@ -21,13 +22,30 @@ .presElementBox-highlight { position: absolute; - transform: translate(-100px, -6px); + transform: translate(-100px, -4px); z-index: -1; width: calc(100% + 200px); - height: calc(100% + 12px); + height: calc(100% + 8px); background-color: #AEDDF8; } + .presElementBox-highlightTop { + position: absolute; + transform: translate(-100px, -4px); + z-index: -1; + width: calc(100% + 200px); + height: calc(50% + 4px); + } + + .presElementBox-highlightBottom { + position: absolute; + transform: translate(-100px, 0px); + z-index: -1; + top: 50%; + width: calc(100% + 200px); + height: calc(50% + 4px); + } + .documentView-node { position: absolute; z-index: 1; @@ -79,8 +97,12 @@ .presElementBox-number { font-size: 12px; + width: 20; font-weight: 700; - left: -15; + text-align: right; + justify-content: center; + align-content: center; + left: -20; position: absolute; display: inline-block; overflow: hidden; @@ -110,9 +132,8 @@ font-size: 10; font-weight: 300; font-family: Roboto; - /* font-style: italic; */ + z-index: 300; letter-spacing: normal; - /* left: 10px; */ } .presElementBox-embedded { @@ -174,7 +195,7 @@ bottom: 3px; width: 20px; height: 20px; - z-index: 200; + z-index: 300; display: flex; background-color: black; color: white; diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index b3d8cca98..e035ed0b8 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -220,7 +220,7 @@ export class PresElementBox extends ViewBoxBaseComponent) => { + e.stopPropagation(); + e.preventDefault(); + DragManager.docsBeingDragged = []; + this._highlightTopRef.current!.style.borderBottom = "0px"; + this._highlightBottomRef.current!.style.borderBottom = "0px"; + } + startDrag = (e: PointerEvent, down: number[], delta: number[]) => { // const ele: HTMLElement[] = PresBox.Instance._eleArray.map(doc => doc); const activeItem = this.rootDoc; const dragData = new DragManager.DocumentDragData(PresBox.Instance.sortArray().map(doc => doc)); // let value = this.getValue(this._heading); // value = typeof value === "string" ? `"${value}"` : value; + let dragItem: HTMLElement[] = []; + PresBox.Instance._dragArray.map(ele => { + const drag = ele; + drag.style.backgroundColor = "#d5dce2"; + drag.style.borderRadius = '5px'; + dragItem.push(drag); + }); if (activeItem) { - DragManager.StartDocumentDrag(PresBox.Instance._dragArray.map(ele => ele), dragData, e.clientX, e.clientY); + DragManager.StartDocumentDrag(dragItem.map(ele => ele), dragData, e.clientX, e.clientY); activeItem.dragging = true; return true; } return false; } + private _highlightTopRef: React.RefObject = React.createRef(); + private _highlightBottomRef: React.RefObject = React.createRef(); + onPointerTop = (e: React.PointerEvent) => { + if (DragManager.docsBeingDragged.length > 0) { + this._highlightTopRef.current!.style.borderTop = "solid 2px #5B9FDD"; + } + } + + onPointerBottom = (e: React.PointerEvent) => { + if (DragManager.docsBeingDragged.length > 0) { + this._highlightBottomRef.current!.style.borderBottom = "solid 2px #5B9FDD"; + } + } + + onPointerLeave = (e: React.PointerEvent) => { + if (DragManager.docsBeingDragged.length > 0) { + this._highlightBottomRef.current!.style.borderBottom = "0px"; + this._highlightTopRef.current!.style.borderTop = "0px"; + } + } + render() { const treecontainer = this.props.ContainingCollectionDoc?._viewType === CollectionViewType.Tree; - const className = "presElementBox-item" + (this.itemIndex === this.indexInPres ? " presElementBox-active" : ""); + const className = "presElementBox-item" + (PresBox.Instance._selectedArray.includes(this.rootDoc) ? " presElementBox-active" : ""); const pbi = "presElementBox-interaction"; return !(this.rootDoc instanceof Doc) || this.targetDoc instanceof Promise ? (null) : (
<>
@@ -297,7 +334,7 @@ export class PresElementBox extends ViewBoxBaseComponent
{"Movement speed"}
}>
300 ? "block" : "none" }}>{this.transition}
-
{"Duration of visibility"}
}>
300 ? "block" : "none" }}>{this.duration}
+
{"Duration"}
}>
300 ? "block" : "none" }}>{this.duration}
{"Remove from presentation"}
}>
e.stopPropagation()} @@ -311,7 +348,9 @@ export class PresElementBox extends ViewBoxBaseComponent e.stopPropagation()} />
-
+
+
+
-- cgit v1.2.3-70-g09d2 From cc905d329c88d7bdf9b7324a4f02ab92906ba7c8 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 5 Aug 2020 22:20:49 -0400 Subject: cleanup of presentation code pre-merge. --- src/client/documents/Documents.ts | 4 -- src/client/util/CurrentUserUtils.ts | 8 ++-- src/client/views/InkingStroke.tsx | 6 +-- src/client/views/MainView.tsx | 2 +- .../CollectionStackingViewFieldColumn.tsx | 3 +- .../views/collections/CollectionTreeView.tsx | 1 - .../collectionFreeForm/PropertiesView.tsx | 4 +- src/client/views/nodes/AudioBox.tsx | 1 - .../views/nodes/CollectionFreeFormDocumentView.tsx | 11 +---- src/client/views/nodes/DocumentLinksButton.tsx | 2 +- src/client/views/nodes/PresBox.tsx | 49 ++++++++++------------ .../views/nodes/formattedText/FormattedTextBox.tsx | 17 ++++---- .../views/nodes/formattedText/RichTextMenu.tsx | 3 +- .../views/presentationview/PresElementBox.tsx | 2 +- 14 files changed, 46 insertions(+), 67 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 57fcf3a00..959aeac41 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -801,10 +801,6 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.FONTICON), undefined, { hideLinkButton: true, ...(options || {}) }); } - export function MenuIconDocument(options?: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.MENUICON), undefined, { hideLinkButton: true, ...(options || {}) }); - } - export function PresElementBoxDocument(options?: DocumentOptions) { return InstanceFromProto(Prototypes.get(DocumentType.PRESELEMENT), undefined, { ...(options || {}) }); } diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 8023df8b4..4e59434b5 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -546,7 +546,7 @@ export class CurrentUserUtils { btn.color = "white"; btn._backgroundColor = ""; })); - }) + }); }); return doc.menuStack as Doc; } @@ -763,13 +763,13 @@ export class CurrentUserUtils { } static setupSidebarContainer(doc: Doc) { - if (doc["sidebar"] === undefined) { + if (doc.sidebar === undefined) { const sidebarContainer = new Doc(); sidebarContainer._chromeStatus = "disabled"; sidebarContainer.onClick = ScriptField.MakeScript("freezeSidebar()"); - doc["sidebar"] = new PrefetchProxy(sidebarContainer); + doc.sidebar = new PrefetchProxy(sidebarContainer); } - return doc["sidebar"] as Doc; + return doc.sidebar as Doc; } // setup the list of sidebar mode buttons which determine what is displayed in the sidebar diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 6c5eda256..4a77728b6 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -115,9 +115,9 @@ export class InkingStroke extends ViewBoxBaseComponent= 4) { for (var i = 0; i <= data.length - 4; i += 4) { controlPoints.push({ X: data[i].X, Y: data[i].Y, I: i }); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 138ff226f..7f50dda72 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -80,7 +80,7 @@ export class MainView extends React.Component { @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeWorkspace, Doc)) : CurrentUserUtils.GuestWorkspace; } @computed public get mainFreeform(): Opt { return (docs => (docs && docs.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); } - @observable public sidebarContent: any = this.userDoc?.["sidebar"]; + @observable public sidebarContent: any = this.userDoc?.sidebar; @observable public panelContent: string = "none"; @observable public showProperties: boolean = false; public isPointerDown = false; diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 68c233a16..fbc4e1552 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -12,6 +12,7 @@ import { NumCast, StrCast, Cast } from "../../../fields/Types"; import { ImageField } from "../../../fields/URLField"; import { TraceMobx } from "../../../fields/util"; import { Docs, DocUtils } from "../../documents/Documents"; +import { DocumentType } from "../../documents/DocumentTypes"; import { DragManager } from "../../util/DragManager"; import { Transform } from "../../util/Transform"; import { undoBatch } from "../../util/UndoManager"; @@ -366,7 +367,7 @@ export class CollectionStackingViewFieldColumn extends React.Component - {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled' && type !== 'presentation') ? + {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled' && type !== DocumentType.PRES) ?
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 8ec855c7c..3c7471d7c 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -133,7 +133,6 @@ class TreeView extends React.Component { } protected createTreeDropTarget = (ele: HTMLDivElement) => { - console.log("ele"); this._treedropDisposer?.(); ele && (this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this), undefined, this.preTreeDrop.bind(this)), this.doc); } diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx index 2b0a00498..dcbf8e989 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx @@ -552,7 +552,7 @@ export class PropertiesView extends React.Component { getField(key: string) { //if (this.selectedDoc) { - return Field.toString(this.selectedDoc[key] as Field); + return Field.toString(this?.[key] as Field); // } else { // return undefined as Opt; // } @@ -698,7 +698,7 @@ export class PropertiesView extends React.Component { this.widthStk = e.target.value))} - onMouseDown={(e) => { this._widthUndo = UndoManager.StartBatch("width undo");; }} + onMouseDown={(e) => { this._widthUndo = UndoManager.StartBatch("width undo"); }} onMouseUp={(e) => { this._widthUndo?.end(); this._widthUndo = undefined; }} />
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index dba92faae..2396e6973 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -21,7 +21,6 @@ import { Docs, DocUtils } from "../../documents/Documents"; import { ComputedField } from "../../../fields/ScriptField"; import { Networking } from "../../Network"; import { LinkAnchorBox } from "./LinkAnchorBox"; -import { signedCookie } from "cookie-parser"; // testing testing diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 35ed6c5a5..42a42ddf1 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -18,8 +18,6 @@ import { DocumentType } from "../../documents/DocumentTypes"; import { Zoom, Fade, Flip, Rotate, Bounce, Roll, LightSpeed } from 'react-reveal'; import { PresBox } from "./PresBox"; import { InkingStroke } from "../InkingStroke"; -import { PDFViewer } from "../pdf/PDFViewer"; -import { PDFBox } from "./PDFBox"; 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; @@ -119,7 +117,6 @@ export class CollectionFreeFormDocumentView extends DocComponent(numberRange(timecode + 1).map(i => undefined) as any as number[]); const hlist = new List(numberRange(timecode + 1).map(i => undefined) as any as number[]); const olist = new List(numberRange(timecode + 1).map(t => progressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1)); - let oarray: List; - console.log(doc.title + "AF: " + doc.appearFrame); - console.log("timecode: " + timecode); - oarray = olist; + const oarray = olist; oarray.fill(0, 0, NumCast(doc.appearFrame) - 1); oarray.fill(1, NumCast(doc.appearFrame), timecode); // oarray.fill(0, 0, NumCast(doc.appearFrame) - 1); - // oarray.fill(1, NumCast(doc.appearFrame), timecode); - // console.log(oarray); + // oarray.fill(1, NumCast(doc.appearFrame), timecode);\ wlist[curTimecode] = NumCast(doc._width); hlist[curTimecode] = NumCast(doc._height); xlist[curTimecode] = NumCast(doc.x); diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 4713ce447..025669b41 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -125,7 +125,7 @@ export class DocumentLinksButton extends React.Component DocumentLinksButton.StartLink!._link = this.props.View._link = undefined), 0); LinkManager.currentLink = linkDoc; if (linkDoc) { diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 1caefdc57..ccf1fb8e3 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -129,7 +129,7 @@ export class PresBox extends ViewBoxBaseComponent const nextChildDocs = DocListCast(nextTagDoc[Doc.LayoutFieldKey(presTargetDoc)]); nextChildDocs.forEach((doc, i) => { doc.opacity = 1; - }) + }); } const nextSelected = this.itemIndex + 1; this.gotoDocument(nextSelected, this.itemIndex); @@ -158,28 +158,24 @@ export class PresBox extends ViewBoxBaseComponent const vfHeight: number = this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]); // Case 1: document that is not a Golden Layout tab if (srcContext) { - console.log("CASE 1"); const srcDocView = DocumentManager.Instance.getDocumentView(srcContext); if (srcDocView) { const layoutdoc = Doc.Layout(presTargetDoc); const panelWidth: number = srcDocView.props.PanelWidth(); const panelHeight: number = srcDocView.props.PanelHeight(); - console.log("srcDocView: " + srcDocView.props.PanelWidth()); const newPanX = NumCast(presTargetDoc.x) + NumCast(layoutdoc._width) / 2; const newPanY = NumCast(presTargetDoc.y) + NumCast(layoutdoc._height) / 2; - let newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight); + const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight); srcContext._panX = newPanX + (vfLeft + (vfWidth / 2)); srcContext._panY = newPanY + (vfTop + (vfHeight / 2)); srcContext._viewScale = newScale; - console.log("X: " + srcContext._panX + ", Y: " + srcContext._panY + ", Scale: " + srcContext._viewScale); } } // Case 2: document is the containing collection if (docView && !srcContext) { - console.log("CASE 2"); const panelWidth: number = docView.props.PanelWidth(); const panelHeight: number = docView.props.PanelHeight(); - let newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight); + const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight); presTargetDoc._panX = vfLeft + (vfWidth / 2); presTargetDoc._panY = vfTop + (vfWidth / 2); presTargetDoc._viewScale = newScale; @@ -791,7 +787,7 @@ export class PresBox extends ViewBoxBaseComponent
Start manually
-
{ activeItem.openDocument = !activeItem.openDocument }}>Open document
+
activeItem.openDocument = !activeItem.openDocument}>Open document
Store original website
@@ -808,15 +804,15 @@ export class PresBox extends ViewBoxBaseComponent
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
-
runInAction(() => { this.layout = 'blank'; this.createNewSlide(this.layout); })} /> -
runInAction(() => { this.layout = 'title'; this.createNewSlide(this.layout); })}> +
{ this.layout = 'blank'; this.createNewSlide(this.layout); })} /> +
{ this.layout = 'title'; this.createNewSlide(this.layout); })}>
Title
Subtitle
-
runInAction(() => { this.layout = 'header'; this.createNewSlide(this.layout); })}> +
{ this.layout = 'header'; this.createNewSlide(this.layout); })}>
Section header
-
runInAction(() => { this.layout = 'content'; this.createNewSlide(this.layout); })}> +
{ this.layout = 'content'; this.createNewSlide(this.layout); })}>
Title
Text goes here
@@ -845,39 +841,39 @@ export class PresBox extends ViewBoxBaseComponent {/*
*/} { e.stopPropagation(); - runInAction(() => { (this.title = e.target.value) }); + runInAction(() => this.title = e.target.value); }}> {/*
*/}
Choose type:
-
runInAction(() => { this.addFreeform = !this.addFreeform })}>Text
-
runInAction(() => { this.addFreeform = !this.addFreeform })}>Freeform
+
this.addFreeform = !this.addFreeform)}>Text
+
this.addFreeform = !this.addFreeform)}>Freeform
Preset layouts:
-
runInAction(() => { this.layout = 'blank' })} /> -
runInAction(() => { this.layout = 'title' })}> +
this.layout = 'blank')} /> +
this.layout = 'title')}>
Title
Subtitle
-
runInAction(() => { this.layout = 'header' })}> +
this.layout = 'header')}>
Section header
-
runInAction(() => { this.layout = 'content' })}> +
this.layout = 'content')}>
Title
Text goes here
-
runInAction(() => { this.layout = 'twoColumns' })}> +
this.layout = 'twoColumns')}>
Title
Column one text
Column two text
-
runInAction(() => { this.openLayouts = !this.openLayouts })}> +
this.openLayouts = !this.openLayouts)}>
@@ -974,10 +970,10 @@ export class PresBox extends ViewBoxBaseComponent } // For toggling the options when the user wants to select play - @action togglePlay = () => { this.playTools = !this.playTools; } + @action togglePlay = () => { this.playTools = !this.playTools; }; // For toggling the options when the user wants to select play - @action togglePresent = () => { this.presentTools = !this.presentTools; } + @action togglePresent = () => { this.presentTools = !this.presentTools; }; // Case in which the document has keyframes to navigate to next key frame @undoBatch @@ -1381,9 +1377,7 @@ export class PresBox extends ViewBoxBaseComponent if (doc && tagDocView) { const scale = tagDocView.childScaling(); - console.log("childScaling: " + scale); const scale2 = tagDocView.props.ScreenToLocalTransform().Scale; - console.log("ScreenToLocal...Scale: " + scale2); let height = doc.offsetHeight; let width = doc.offsetWidth; let top = doc.offsetTop; @@ -1544,7 +1538,6 @@ export class PresBox extends ViewBoxBaseComponent @undoBatch @action prevAppearFrame = (doc: Doc, i: number): void => { - console.log("prev"); const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); const appearFrame = Cast(doc.appearFrame, "number", null); @@ -1595,7 +1588,7 @@ export class PresBox extends ViewBoxBaseComponent if (activeItem) { return ( <> -
{"Add new slide"}
}>
runInAction(() => { this.newDocumentTools = !this.newDocumentTools; })}> +
{"Add new slide"}
}>
this.newDocumentTools = !this.newDocumentTools)}>
@@ -1636,7 +1629,7 @@ export class PresBox extends ViewBoxBaseComponent } else { return ( <> -
{"Add new slide"}
}>
runInAction(() => { this.newDocumentTools = !this.newDocumentTools; })}> +
{"Add new slide"}
}>
this.newDocumentTools = !this.newDocumentTools)}>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 76d23ddfe..ab1de5529 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -577,20 +577,19 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const xLoc: number = (nestDepth * 20); const width: number = 390 - xLoc; const height: number = 55 - (nestDepth * 5); - for (let i = 0; i < list.length; i++) { - const mainBullets: number = Number(list[i].getAttribute("data-bulletstyle")); + Array.from(list).forEach(listItem => { + const mainBullets: number = Number(listItem.getAttribute("data-bulletstyle")); if (mainBullets === nestDepth) { - if (list[i].childElementCount > 1) { + if (listItem.childElementCount > 1) { b++; nestCount++; count = before ? count + nestCount + "." : nestCount + "."; yLoc += height; - const text = list[i].getElementsByTagName("p")[0].innerText; + const text = listItem.getElementsByTagName("p")[0].innerText; const length = text.length; - console.log(yLoc); const bullet1 = Docs.Create.TextDocument(count + " " + text, { title: "Slide text", _width: width, _height: height, x: xLoc, y: 10 + (yLoc), _fontSize: fontSize, backgroundColor: "rgba(0,0,0,0)", appearFrame: d ? d : b }); mainBulletList.push(bullet1); - const newList = this.recursiveProgressivize(nestDepth + 1, list[i].getElementsByTagName("li"), b, yLoc, count); + const newList = this.recursiveProgressivize(nestDepth + 1, listItem.getElementsByTagName("li"), b, yLoc, count); mainBulletList.push.apply(mainBulletList, newList); b += newList.length; yLoc += newList.length * (55 - ((nestDepth + 1) * 5)); @@ -599,15 +598,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp nestCount++; count = before ? count + nestCount + "." : nestCount + "."; yLoc += height; - const text = list[i].innerText; + const text = listItem.innerText; const length = text.length; - console.log(yLoc); const bullet1 = Docs.Create.TextDocument(count + " " + text, { title: "Slide text", _width: width, _height: height, x: xLoc, y: 10 + (yLoc), _fontSize: fontSize, backgroundColor: "rgba(0,0,0,0)", appearFrame: d ? d : b }); mainBulletList.push(bullet1); } } - } - console.log("b: " + b); + }); return mainBulletList; } diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 6e268be48..5af07c15d 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -903,8 +903,9 @@ export default class RichTextMenu extends AntimodeMenu { ref_node = pos.nodeBefore; } if (pos.nodeAfter !== null && pos.nodeAfter !== undefined) { - if (!pos.nodeBefore || this.view.state.selection.$from.pos !== this.view.state.selection.$to.pos) + if (!pos.nodeBefore || this.view.state.selection.$from.pos !== this.view.state.selection.$to.pos) { ref_node = pos.nodeAfter; + } } if (!ref_node && pos.pos > 0) { let skip = false; diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index e035ed0b8..11ffde9dd 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -259,7 +259,7 @@ export class PresElementBox extends ViewBoxBaseComponent doc)); // let value = this.getValue(this._heading); // value = typeof value === "string" ? `"${value}"` : value; - let dragItem: HTMLElement[] = []; + const dragItem: HTMLElement[] = []; PresBox.Instance._dragArray.map(ele => { const drag = ele; drag.style.backgroundColor = "#d5dce2"; -- cgit v1.2.3-70-g09d2 From 8b67afc6972cf81b306dea93a7ae87ef8d40d3eb Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 5 Aug 2020 22:36:02 -0400 Subject: fixed warnings --- src/client/views/collections/CollectionDockingView.tsx | 3 +-- src/client/views/collections/CollectionMenu.tsx | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 6d4a7f311..97c699091 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -896,8 +896,7 @@ export class DockedFrameRenderer extends React.Component { CollectionView={undefined} ContainingCollectionView={undefined} ContainingCollectionDoc={undefined} - ChildLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid havin to set stuff like this. - noOverlay={true} // don't render overlay Docs since they won't scale + ChildLayoutTemplate={this.childLayoutTemplate}// bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid havin to set stuff like this. active={returnTrue} select={emptyFunction} dropAction={undefined} diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 9ae72ba53..904592975 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -235,6 +235,7 @@ export class CollectionViewBaseChrome extends React.Component); case CollectionViewType.Stacking: return (); case CollectionViewType.Schema: return (); -- cgit v1.2.3-70-g09d2 From 1985e26afd1689a0e2880f5e8543fcd008f234d7 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 5 Aug 2020 22:42:38 -0400 Subject: restored noOverlay that go lost in the merge --- src/client/views/collections/CollectionDockingView.tsx | 3 ++- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 97c699091..6d4a7f311 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -896,7 +896,8 @@ export class DockedFrameRenderer extends React.Component { CollectionView={undefined} ContainingCollectionView={undefined} ContainingCollectionDoc={undefined} - ChildLayoutTemplate={this.childLayoutTemplate}// bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid havin to set stuff like this. + ChildLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid havin to set stuff like this. + noOverlay={true} // don't render overlay Docs since they won't scale active={returnTrue} select={emptyFunction} dropAction={undefined} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index f2ad0ba58..7f325182c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -78,6 +78,7 @@ export type collectionFreeformViewProps = { viewDefDivClick?: ScriptField; childPointerEvents?: boolean; scaleField?: string; + noOverlay?: boolean; // used to suppress docs in the overlay (z) layer (ie, for minimap since overlay doesn't scale) }; @observer @@ -1443,7 +1444,7 @@ export class CollectionFreeFormView extends CollectionSubView {this.Document._freeformLOD && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ? this.placeholder : this.marqueeView} - + {!this.props.noOverlay ? : (null)}
Date: Wed, 5 Aug 2020 22:50:38 -0400 Subject: readded Z test for applying layoutTempaltes in FreeFormView --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 7f325182c..ffeb3024d 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -956,8 +956,8 @@ export class CollectionFreeFormView extends CollectionSubView Date: Wed, 5 Aug 2020 23:18:27 -0400 Subject: added inking menu back for all docs. should really exclude documents from inking in a more fine grained way. --- src/client/views/collections/CollectionMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 904592975..53d2a136e 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -645,7 +645,7 @@ export class CollectionFreeFormViewChrome extends React.Component } - {(!this.props.isOverlay || this.props.docView.layoutDoc.isAnnotating) && !this.isText ? + {!this.isText ? <> {this.drawButtons} {this.widthPicker} -- cgit v1.2.3-70-g09d2