From 3c6e288fa031e8871618170d3b8d6db66dd3c66b Mon Sep 17 00:00:00 2001 From: Melissa Zhang Date: Sun, 17 May 2020 23:38:58 -0700 Subject: add 3D carousel view to code base --- src/client/views/collections/CollectionView.tsx | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 3b2e5e4fc..8d6866632 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -21,6 +21,7 @@ import { FieldView, FieldViewProps } from '../nodes/FieldView'; import { ScriptBox } from '../ScriptBox'; import { Touchable } from '../Touchable'; import { CollectionCarouselView } from './CollectionCarouselView'; +import { CollectionCarousel3DView } from './CollectionCarousel3DView'; import { CollectionDockingView } from "./CollectionDockingView"; import { AddCustomFreeFormLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines'; import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; @@ -63,6 +64,7 @@ export enum CollectionViewType { Multirow = "multirow", Time = "time", Carousel = "carousel", + Carousel3D = "3D carousel", Linear = "linear", Staff = "staff", Map = "map", @@ -183,6 +185,7 @@ export class CollectionView extends Touchable); } case CollectionViewType.Pile: { return (); } case CollectionViewType.Carousel: { return (); } + case CollectionViewType.Carousel3D: { return (); } case CollectionViewType.Stacking: { this.props.Document.singleColumn = true; return (); } case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (); } case CollectionViewType.Time: { return (); } @@ -222,6 +225,7 @@ export class CollectionView extends Touchable func(CollectionViewType.Multirow), icon: "columns" }); subItems.push({ description: "Masonry", event: () => func(CollectionViewType.Masonry), icon: "columns" }); subItems.push({ description: "Carousel", event: () => func(CollectionViewType.Carousel), icon: "columns" }); + subItems.push({ description: "3D Carousel", event: () => func(CollectionViewType.Carousel3D), icon: "columns" }); subItems.push({ description: "Pivot/Time", event: () => func(CollectionViewType.Time), icon: "columns" }); subItems.push({ description: "Map", event: () => func(CollectionViewType.Map), icon: "globe-americas" }); if (addExtras && this.props.Document._viewType === CollectionViewType.Freeform) { -- cgit v1.2.3-70-g09d2 From 05fe7bb89e51f3d8b643726f3283ba8adee740e4 Mon Sep 17 00:00:00 2001 From: Melissa Zhang Date: Thu, 4 Jun 2020 16:22:27 -0700 Subject: hover to show autoscroll button --- src/client/views/DocumentDecorations.tsx | 7 +- .../collections/CollectionCarousel3DView.scss | 49 ++++++++++-- .../views/collections/CollectionCarousel3DView.tsx | 86 +++++++++++++--------- src/client/views/collections/CollectionView.tsx | 2 +- 4 files changed, 100 insertions(+), 44 deletions(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 04f02c683..7cdf955a1 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -1,5 +1,5 @@ import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; -import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faTextHeight, faArrowAltCircleDown, faArrowAltCircleUp, faCheckCircle, faCloudUploadAlt, faLink, faShare, faStopCircle, faSyncAlt, faTag, faTimes } from '@fortawesome/free-solid-svg-icons'; +import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faTextHeight, faArrowAltCircleDown, faArrowAltCircleUp, faCheckCircle, faCloudUploadAlt, faLink, faShare, faStopCircle, faSyncAlt, faTag, faTimes, faAngleLeft, faAngleRight, faAngleDoubleLeft, faAngleDoubleRight, faPause } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; @@ -38,6 +38,11 @@ library.add(faCheckCircle); library.add(faCloudUploadAlt); library.add(faSyncAlt); library.add(faShare); +library.add(faAngleDoubleLeft); +library.add(faAngleDoubleRight); +library.add(faAngleLeft); +library.add(faAngleRight); +library.add(faPause); @observer export class DocumentDecorations extends React.Component<{}, { value: string }> { diff --git a/src/client/views/collections/CollectionCarousel3DView.scss b/src/client/views/collections/CollectionCarousel3DView.scss index d00a666f8..ff63f4116 100644 --- a/src/client/views/collections/CollectionCarousel3DView.scss +++ b/src/client/views/collections/CollectionCarousel3DView.scss @@ -1,4 +1,4 @@ -.collectionCarouselView-outer { +.collectionCarousel3DView-outer { height: 100%; position: relative; background-color: white; @@ -11,14 +11,14 @@ align-items: center; transition: transform 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955); - .collectionCarouselView-item, - .collectionCarouselView-item-active { + .collectionCarousel3DView-item, + .collectionCarousel3DView-item-active { flex: 1; transition: opacity 0.3s linear, transform 0.5s cubic-bezier(0.455, 0.03, 0.515, 0.955); pointer-events: none; } - .collectionCarouselView-item-active { + .collectionCarousel3DView-item-active { pointer-events: unset; } } @@ -46,7 +46,44 @@ } } -.carouselView-back, -.carouselView-forward { +.carousel3DView-back, +.carousel3DView-fwd, +.carousel3DView-back-scroll, +.carousel3DView-fwd-scroll { + position: absolute; + display: flex; + width: 30; + height: 30; + align-items: center; + border-radius: 5px; + justify-content: center; + background: rgba(255, 255, 255, 0.46); cursor: pointer; +} + +.carousel3DView-fwd { + top: 50%; + right: 0; +} + +.carousel3DView-back { + top: 50%; + left: 0; +} + +.carousel3DView-fwd-scroll { + top: calc(50% - 30px); + right: 0; +} + +.carousel3DView-back-scroll { + top: calc(50% - 30px); + left: 0; +} + +.carousel3DView-back:hover, +.carousel3DView-fwd:hover, +.carousel3DView-back-scroll:hover, +.carousel3DView-fwd-scroll:hover { + background: lightgray; } \ No newline at end of file diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index 2f161e255..1fa96df65 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -21,6 +21,10 @@ const Carousel3DDocument = makeInterface(documentSchema, collectionSchema); @observer export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocument) { + @computed get scrollSpeed() { + return this.layoutDoc._autoScrollSpeed ? NumCast(this.layoutDoc._autoScrollSpeed) : 1000; //default scroll speed + } + private _dropDisposer?: DragManager.DragDropDisposer; componentWillUnmount() { this._dropDisposer?.(); } @@ -74,43 +78,32 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume this.layoutDoc._itemIndex = (NumCast(this.layoutDoc._itemIndex) + direction + this.childLayoutPairs.length) % this.childLayoutPairs.length; } - startScroll = (direction: number) => { - this.layoutDoc.scrollInterval = 500; - this.interval = window.setInterval(() => { - this.changeSlide(direction); - }, this.layoutDoc.scrollInterval); + onArrowClick = (e: React.MouseEvent, direction: number) => { + e.stopPropagation(); + this.changeSlide(direction); } - timer?: number; interval?: number; - onArrowDown = (e: React.PointerEvent, direction: number) => { - e.stopPropagation; + startAutoScroll = (direction: number) => { + this.interval = window.setInterval(() => { + this.changeSlide(direction); + }, this.scrollSpeed); + } - const listener = () => { // is able to pass in the direction parameter and then correctly remove the listener - this.onArrowRelease(direction); - document.removeEventListener("pointerup", listener); - }; - document.addEventListener("pointerup", listener); + stopAutoScroll = () => { + window.clearInterval(this.interval); + this.interval = undefined; + } - this.layoutDoc.startScrollTimeout = 500; - this.timer = window.setTimeout(() => { // if arrow is held down long enough, activate automatic scrolling - window.clearTimeout(this.timer); - this.timer = undefined; - this.startScroll(direction); - }, this.layoutDoc.startScrollTimeout); + toggleAutoScroll = (direction: number) => { + this.layoutDoc.autoScrollOn = this.layoutDoc.autoScrollOn ? false : true; + this.layoutDoc.autoScrollOn ? this.startAutoScroll(direction) : this.stopAutoScroll(); } - onArrowRelease = (direction: number) => { - if (this.timer) { - this.changeSlide(direction); // if click wasn't long enough to activate autoscroll, only advance/go back 1 slide - window.clearTimeout(this.timer); - this.timer = undefined; - } + showAutoScrollButton = (direction: string) => { + // keep pause button visible while autoscroll is on, and don't show the other side's autoscroll button + !this.layoutDoc.autoScrollOn && (this.layoutDoc.showScrollButton = direction); - if (this.interval) { - window.clearInterval(this.interval); // stop scrolling - this.interval = undefined; - } } onContextMenu = (e: React.MouseEvent): void => { @@ -148,14 +141,35 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume } @computed get buttons() { - return <> -
this.onArrowDown(e, -1)}> - + if (!this.props.active()) return null; + return
this.showAutoScrollButton("none")}> +
this.onArrowClick(e, -1)} + onMouseEnter={() => this.showAutoScrollButton("back")}> +
-
this.onArrowDown(e, 1)}> - +
this.onArrowClick(e, 1)} + onMouseEnter={() => this.showAutoScrollButton("fwd")}> + +
+ {this.autoScrollButton} +
; + } + + @computed get autoScrollButton() { + const direction = this.layoutDoc.showScrollButton; + if (direction !== "back" && direction !== "fwd") return null; + + const offset = (direction === "back") ? -1 : 1; + return <> +
this.toggleAutoScroll(offset)}> + {this.layoutDoc.autoScrollOn ? + : + direction === "back" ? + : + }
; } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index a0f6ad9c7..82aa3dbd5 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -64,7 +64,7 @@ export enum CollectionViewType { Multirow = "multirow", Time = "time", Carousel = "carousel", - Carousel3D = "3D carousel", + Carousel3D = "3D Carousel", Linear = "linear", Staff = "staff", Map = "map", -- cgit v1.2.3-70-g09d2 From 3dab85351e1fe862a54294cec70e7139abea0d7d Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Mon, 15 Jun 2020 00:10:16 -0700 Subject: added ? to a lot of things --- .../views/collections/CollectionCarouselView.tsx | 2 +- .../views/collections/CollectionDockingView.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 18 +- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/ImageBox.tsx | 10 +- .../nodes/formattedText/FormattedTextBox.scss | 283 ++++++++++++++++++++- .../views/nodes/formattedText/FormattedTextBox.tsx | 4 +- src/mobile/MobileInterface.scss | 8 + src/mobile/MobileInterface.tsx | 10 +- src/server/index.ts | 1 + 10 files changed, 319 insertions(+), 21 deletions(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index f65a89422..bd0e4fc9a 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -87,7 +87,7 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument) onContextMenu = (e: React.MouseEvent): void => { // need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout if (!e.isPropagationStopped()) { - ContextMenu.Instance.addItem({ + ContextMenu.Instance?.addItem({ description: "Make Hero Image", event: () => { const index = NumCast(this.layoutDoc._itemIndex); (this.dataDoc || Doc.GetProto(this.props.Document)).hero = ObjectField.MakeCopy(this.childLayoutPairs[index].layout.data as ObjectField); diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 6f5a3dfe4..02ba45f9c 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -840,7 +840,7 @@ export class DockedFrameRenderer extends React.Component { parentActive={returnTrue} whenActiveChanged={emptyFunction} focus={emptyFunction} - backgroundColor={CollectionDockingView.Instance.props.backgroundColor} + backgroundColor={CollectionDockingView.Instance?.props.backgroundColor} addDocTab={this.addDocTab} pinToPres={DockedFrameRenderer.PinDoc} ContainingCollectionView={undefined} diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index a25a864af..00a1d27f0 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -213,12 +213,12 @@ export class CollectionView extends Touchable Doc, addExtras: boolean) { - const existingVm = ContextMenu.Instance.findByDescription(category); + const existingVm = ContextMenu.Instance?.findByDescription(category); const subItems = existingVm && "subitems" in existingVm ? existingVm.subitems : []; subItems.push({ description: "Freeform", event: () => func(CollectionViewType.Freeform), icon: "signature" }); if (addExtras && CollectionView._safeMode) { - ContextMenu.Instance.addItem({ description: "Test Freeform", event: () => func(CollectionViewType.Invalid), icon: "project-diagram" }); + ContextMenu.Instance?.addItem({ description: "Test Freeform", event: () => func(CollectionViewType.Invalid), icon: "project-diagram" }); } subItems.push({ description: "Schema", event: () => func(CollectionViewType.Schema), icon: "th-list" }); subItems.push({ description: "Tree", event: () => func(CollectionViewType.Tree), icon: "tree" }); @@ -235,7 +235,7 @@ export class CollectionView extends Touchable this._isLightboxOpen = true), icon: "eye" }); - !existingVm && ContextMenu.Instance.addItem({ description: category, subitems: subItems, icon: "eye" }); + !existingVm && ContextMenu.Instance?.addItem({ description: category, subitems: subItems, icon: "eye" }); } onContextMenu = (e: React.MouseEvent): void => { @@ -248,7 +248,7 @@ export class CollectionView extends Touchable this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" }); if (this.props.Document.childLayout instanceof Doc) { @@ -259,9 +259,9 @@ export class CollectionView extends Touchable this.props.Document.isInPlaceContainer = !this.props.Document.isInPlaceContainer, icon: "project-diagram" }); - !existing && ContextMenu.Instance.addItem({ description: "Options...", subitems: layoutItems, icon: "hand-point-right" }); + !existing && ContextMenu.Instance?.addItem({ description: "Options...", subitems: layoutItems, icon: "hand-point-right" }); - const existingOnClick = ContextMenu.Instance.findByDescription("OnClick..."); + const existingOnClick = ContextMenu.Instance?.findByDescription("OnClick..."); const onClicks = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : []; const funcs = [ { key: "onChildClick", name: "On Child Clicked" }, @@ -277,12 +277,12 @@ export class CollectionView extends Touchable this.props.Document[StrCast(childClick.targetScriptKey)] = ObjectField.MakeCopy(ScriptCast(childClick.data)), })); - !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); + !existingOnClick && ContextMenu.Instance?.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); - const more = ContextMenu.Instance.findByDescription("More..."); + const more = ContextMenu.Instance?.findByDescription("More..."); const moreItems = more && "subitems" in more ? more.subitems : []; moreItems.push({ description: "Export Image Hierarchy", icon: "columns", event: () => ImageUtils.ExportHierarchyToFileSystem(this.props.Document) }); - !more && ContextMenu.Instance.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); + !more && ContextMenu.Instance?.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); } } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 1d98a2628..66bc73617 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -138,7 +138,7 @@ export class DocumentView extends DocComponent(Docu document.removeEventListener("pointerup", this.onPointerUp); console.log(SelectionManager.SelectedDocuments()); console.log("START"); - if (RadialMenu.Instance._display === false) { + if (RadialMenu.Instance?._display === false) { this.addHoldMoveListeners(); this.addHoldEndListeners(); this.onRadialMenu(e, me); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index cabf30c13..73410e02f 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -174,19 +174,19 @@ export class ImageBox extends ViewBoxAnnotatableComponent.formattedTextBox-sidebar-handle { + right: 0; + left: unset; + } + + .formattedTextBox-sidebar, + .formattedTextBox-sidebar-inking { + border-left: dashed 1px black; + height: 100%; + display: inline-block; + position: absolute; + right: 0; + + .collectionfreeformview-container { + position: relative; + } + + >.formattedTextBox-sidebar-handle { + right: unset; + left: -5; + } + } + + .formattedTextBox-sidebar-inking { + pointer-events: all; + } + + .formattedTextBox-inner-rounded { + height: 70%; + width: 85%; + position: absolute; + overflow: auto; + top: 15%; + left: 10%; + } + + .formattedTextBox-inner-rounded, + .formattedTextBox-inner { + height: 100%; + white-space: pre-wrap; + hr { + display: block; + unicode-bidi: isolate; + margin-block-start: 0.5em; + margin-block-end: 0.5em; + margin-inline-start: auto; + margin-inline-end: auto; + overflow: hidden; + border-style: inset; + border-width: 1px; + } + } + + // .menuicon { + // display: inline-block; + // border-right: 1px solid rgba(0, 0, 0, 0.2); + // color: #888; + // line-height: 1; + // padding: 0 7px; + // margin: 1px; + // cursor: pointer; + // text-align: center; + // min-width: 1.4em; + // } + + .strong, + .heading { + font-weight: bold; + } + + .em { + font-style: italic; + } + + .userMarkOpen { + background: rgba(255, 255, 0, 0.267); + display: inline; + } + + .userMark { + background: rgba(255, 255, 0, 0.267); + font-size: 2px; + display: inline-grid; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 10px; + min-height: 10px; + text-align: center; + align-content: center; + } + + footnote { + display: inline-block; + position: relative; + cursor: pointer; + + div { + padding: 0 !important; + } + } + + footnote::after { + content: counter(prosemirror-footnote); + vertical-align: super; + font-size: 75%; + counter-increment: prosemirror-footnote; + } + + .ProseMirror { + counter-reset: prosemirror-footnote; + } + + .footnote-tooltip { + cursor: auto; + font-size: 75%; + position: absolute; + left: -30px; + top: calc(100% + 10px); + background: silver; + padding: 3px; + border-radius: 2px; + max-width: 100px; + min-width: 50px; + width: max-content; + } + + .prosemirror-attribution { + font-size: 8px; + } + + .footnote-tooltip::before { + border: 5px solid silver; + border-top-width: 0px; + border-left-color: transparent; + border-right-color: transparent; + position: absolute; + top: -5px; + left: 27px; + content: " "; + height: 0; + width: 0; + } + + + .formattedTextBox-inlineComment { + position: relative; + width: 40px; + height: 20px; + &::before { + content: "→"; + } + &:hover { + background: orange; + } + } + + .formattedTextBox-summarizer { + opacity: 0.5; + position: relative; + width: 40px; + height: 20px; + &::after { + content: "←"; + } + } + + .formattedTextBox-summarizer-collapsed { + opacity: 0.5; + position: relative; + width: 40px; + height: 20px; + &::after { + content: "..."; + } + } + + .ProseMirror { + touch-action: none; + span { + font-family: inherit; + } + + ol, ul { + counter-reset: deci1 0 multi1 0; + padding-left: 1em; + font-family: inherit; + } + ol { + margin-left: 1em; + font-family: inherit; + } + + .decimal1-ol { counter-reset: deci1; p {display: inline; font-family: inherit} margin-left: 0; } + .decimal2-ol { counter-reset: deci2; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 1em;} + .decimal3-ol { counter-reset: deci3; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 2em;} + .decimal4-ol { counter-reset: deci4; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 3em;} + .decimal5-ol { counter-reset: deci5; p {display: inline; font-family: inherit} font-size: smaller; } + .decimal6-ol { counter-reset: deci6; p {display: inline; font-family: inherit} font-size: smaller; } + .decimal7-ol { counter-reset: deci7; p {display: inline; font-family: inherit} font-size: smaller; } + + .multi1-ol { counter-reset: multi1; p {display: inline; font-family: inherit} margin-left: 0; padding-left: 1.2em } + .multi2-ol { counter-reset: multi2; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 1.4em;} + .multi3-ol { counter-reset: multi3; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 2em;} + .multi4-ol { counter-reset: multi4; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 3.4em;} + + .decimal1:before { transition: 0.5s;counter-increment: deci1; display: inline-block; margin-left: -1em; width: 1em; content: counter(deci1) ". "; } + .decimal2:before { transition: 0.5s;counter-increment: deci2; display: inline-block; margin-left: -2.1em; width: 2.1em; content: counter(deci1) "."counter(deci2) ". "; } + .decimal3:before { transition: 0.5s;counter-increment: deci3; display: inline-block; margin-left: -2.85em;width: 2.85em; content: counter(deci1) "."counter(deci2) "."counter(deci3) ". "; } + .decimal4:before { transition: 0.5s;counter-increment: deci4; display: inline-block; margin-left: -3.85em;width: 3.85em; content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) ". "; } + .decimal5:before { transition: 0.5s;counter-increment: deci5; display: inline-block; margin-left: -2em; width: 5em; content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) "."counter(deci5) ". "; } + .decimal6:before { transition: 0.5s;counter-increment: deci6; display: inline-block; margin-left: -2em; width: 6em; content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) "."counter(deci5) "."counter(deci6) ". "; } + .decimal7:before { transition: 0.5s;counter-increment: deci7; display: inline-block; margin-left: -2em; width: 7em; content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) "."counter(deci5) "."counter(deci6) "."counter(deci7) ". "; } + + .multi1:before { transition: 0.5s;counter-increment: multi1; display: inline-block; margin-left: -1em; width: 1.2em; content: counter(multi1, upper-alpha) ". "; } + .multi2:before { transition: 0.5s;counter-increment: multi2; display: inline-block; margin-left: -2em; width: 2em; content: counter(multi1, upper-alpha) "."counter(multi2, decimal) ". "; } + .multi3:before { transition: 0.5s;counter-increment: multi3; display: inline-block; margin-left: -2.85em; width:2.85em; content: counter(multi1, upper-alpha) "."counter(multi2, decimal) "."counter(multi3, lower-alpha) ". "; } + .multi4:before { transition: 0.5s;counter-increment: multi4; display: inline-block; margin-left: -4.2em; width: 4.2em; content: counter(multi1, upper-alpha) "."counter(multi2, decimal) "."counter(multi3, lower-alpha) "."counter(multi4, lower-roman) ". "; } + } +} diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 1fab54d7e..b0b648b66 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -188,7 +188,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } const state = this._editorView.state.apply(tx); - this._editorView.updateState(state); + this?._editorView?.updateState(state); (tx.storedMarks && !this._editorView.state.storedMarks) && (this._editorView.state.storedMarks = tx.storedMarks); const tsel = this._editorView.state.selection.$from; @@ -1213,7 +1213,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : ""; const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground; if (this.props.isSelected()) { - this._editorView && RichTextMenu.Instance.updateFromDash(this._editorView, undefined, this.props); + this._editorView && RichTextMenu.Instance?.updateFromDash(this._editorView, undefined, this.props); } else if (FormattedTextBoxComment.textBox === this) { FormattedTextBoxComment.Hide(); } diff --git a/src/mobile/MobileInterface.scss b/src/mobile/MobileInterface.scss index f75e60a37..215ce02e5 100644 --- a/src/mobile/MobileInterface.scss +++ b/src/mobile/MobileInterface.scss @@ -17,6 +17,14 @@ position: relative; touch-action: none; width: 100%; + + -webkit-touch-callout:none; + -webkit-user-select:none; + -khtml-user-select:none; + -moz-user-select:none; + -ms-user-select:none; + user-select:none; + -webkit-tap-highlight-color:rgba(0,0,0,0); } .mobileInterface-background { diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index 6cb8e3486..a2d3f63dc 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -39,6 +39,7 @@ import { SelectionManager } from "../client/util/SelectionManager"; import { SketchPicker } from "react-color"; import { ScriptField } from "../fields/ScriptField"; import InkOptionsMenu from "../client/views/collections/collectionFreeForm/InkOptionsMenu"; +import { RadialMenu } from "../client/views/nodes/RadialMenu"; library.add(faTasks, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus, faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard, @@ -96,6 +97,14 @@ export class MobileInterface extends React.Component { this._homeDoc._viewType === "stacking" ? this.menuListView = true : this.menuListView = false; Doc.SetSelectedTool(InkTool.None); this.switchCurrentView((userDoc: Doc) => this._homeDoc); + + document.removeEventListener("dblclick", this.onReactDoubleClick); + document.addEventListener("dblclick", this.onReactDoubleClick); + } + + onReactDoubleClick = (e: MouseEvent) => { + console.log("tapped"); + e.stopPropagation(); } @action @@ -896,7 +905,6 @@ export class MobileInterface extends React.Component { } else if (!this.imageUploadActive) { } - console.log("upload"); return (
diff --git a/src/server/index.ts b/src/server/index.ts index 590affd06..083173bb5 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -104,6 +104,7 @@ function routeSetter({ isRelease, addSupervisedRoute, logRegistrationOutcome }: const serve: PublicHandler = ({ req, res }) => { const detector = new mobileDetect(req.headers['user-agent'] || ""); const filename = detector.mobile() !== null ? 'mobile/image.html' : 'index.html'; + console.log(detector.is("iPhone")); res.sendFile(path.join(__dirname, '../../deploy/' + filename)); }; -- cgit v1.2.3-70-g09d2 From 738a56b3c18c06d8290346373eb60a125120caaf Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Thu, 18 Jun 2020 15:02:50 -0700 Subject: hopefully fixed new ink --- src/client/util/InteractionUtils.tsx | 4 +- src/client/views/InkingStroke.tsx | 4 +- .../views/collections/CollectionDockingView.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 4 +- .../views/collections/CollectionViewChromes.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 6 +-- src/client/views/nodes/DocumentView.tsx | 44 +++++++++++----------- src/mobile/MobileInterface.tsx | 16 +++++--- src/pen-gestures/ndollar.ts | 2 +- 9 files changed, 44 insertions(+), 40 deletions(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index aeb0f670d..3b42fcaee 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -96,9 +96,9 @@ export namespace InteractionUtils { } else if (points.length > 1 && points[points.length - 1].X === points[0].X && points[points.length - 1].Y === points[0].Y) { //pointer is up (first and last points are the same) - points.pop(); + //points.pop(); const newPoints = points.reduce((p, pts) => { p.push([pts.X, pts.Y]); return p; }, [] as number[][]); - + newPoints.pop(); const bezierCurves = fitCurve(newPoints, parseInt(bezier)); for (var i = 0; i < bezierCurves.length; i++) { for (var t = 0; t < 1; t += 0.01) { diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 7e3bd1c17..5129ef65d 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -68,8 +68,8 @@ export class InkingStroke extends ViewBoxBaseComponent { - ContextMenu.Instance.addItem({ description: "Analyze Stroke", event: this.analyzeStrokes, icon: "paint-brush" }); - ContextMenu.Instance.addItem({ description: "Make Mask", event: this.makeMask, icon: "paint-brush" }); + ContextMenu.Instance?.addItem({ description: "Analyze Stroke", event: this.analyzeStrokes, icon: "paint-brush" }); + ContextMenu.Instance?.addItem({ description: "Make Mask", event: this.makeMask, icon: "paint-brush" }); }} > diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index c2e297f61..657e2a08b 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -790,7 +790,7 @@ export class DockedFrameRenderer extends React.Component { if (this._mainCont && this._mainCont.children) { const { translateX, translateY } = Utils.GetScreenTransform(this._mainCont.children[0].firstChild as HTMLElement); const scale = Utils.GetScreenTransform(this._mainCont).scale; - return CollectionDockingView.Instance.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(1 / this.contentScaling() / scale); + return CollectionDockingView.Instance?.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(1 / this.contentScaling() / scale); } return Transform.Identity(); } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index a700d0dfb..0a84e6f72 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -283,10 +283,10 @@ export class CollectionView extends Touchable ImageUtils.ExportHierarchyToFileSystem(this.props.Document) }); - !more && ContextMenu.Instance.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); + !more && ContextMenu.Instance?.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); } } } diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 48810f1e9..ec908f034 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -300,7 +300,7 @@ export class CollectionViewBaseChrome extends React.Component { if (this.props.annotationsKey) return; - ContextMenu.Instance.addItem({ + ContextMenu.Instance?.addItem({ description: (this._timelineVisible ? "Close" : "Open") + " Animation Timeline", event: action(() => { this._timelineVisible = !this._timelineVisible; }), icon: this._timelineVisible ? faEyeSlash : faEye }); - const options = ContextMenu.Instance.findByDescription("Options..."); + const options = ContextMenu.Instance?.findByDescription("Options..."); const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : []; optionItems.push({ description: "reset view", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document[this.scaleFieldKey] = 1; }, icon: "compress-arrows-alt" }); @@ -1246,7 +1246,7 @@ export class CollectionFreeFormView extends CollectionSubView this.Document._LODdisable = !this.Document._LODdisable, icon: "table" }); - ContextMenu.Instance.addItem({ description: "Options...", subitems: optionItems, icon: "eye" }); + ContextMenu.Instance?.addItem({ description: "Options...", subitems: optionItems, icon: "eye" }); } @observable _timelineVisible = false; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index e027b6a0f..2f868d558 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -708,40 +708,40 @@ export class DocumentView extends DocComponent(Docu onContextMenu = async (e: React.MouseEvent | Touch): Promise => { // the touch onContextMenu is button 0, the pointer onContextMenu is button 2 if (!(e instanceof Touch)) { - if (e.button === 0 && !e.ctrlKey) { - e.preventDefault(); + if (e?.button === 0 && !e.ctrlKey) { + e?.preventDefault(); return; } - e.persist(); + e?.persist(); e?.stopPropagation(); - if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3 || - e.isDefaultPrevented()) { - e.preventDefault(); + if (Math.abs(this._downX - e?.clientX) > 3 || Math.abs(this._downY - e?.clientY) > 3 || + e?.isDefaultPrevented()) { + e?.preventDefault(); return; } - e.preventDefault(); + e?.preventDefault(); } const cm = ContextMenu.Instance; const customScripts = Cast(this.props.Document.contextMenuScripts, listSpec(ScriptField), []); Cast(this.props.Document.contextMenuLabels, listSpec("string"), []).forEach((label, i) => - cm.addItem({ description: label, event: () => customScripts[i]?.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" })); + cm?.addItem({ description: label, event: () => customScripts[i]?.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" })); this.props.contextMenuItems?.().forEach(item => - cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" })); + cm?.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" })); - let options = cm.findByDescription("Options..."); + let options = cm?.findByDescription("Options..."); const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : []; const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layoutKey)], Doc, null); optionItems.push({ description: "Open Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "layer-group" }); templateDoc && optionItems.push({ description: "Open Template ", event: () => this.props.addDocTab(templateDoc, "onRight"), icon: "eye" }); if (!options) { options = { description: "Options...", subitems: optionItems, icon: "compass" }; - cm.addItem(options); + cm?.addItem(options); } - const existingOnClick = cm.findByDescription("OnClick..."); + 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.props.Document.layoutKey}")`), icon: "window-restore" }); @@ -750,17 +750,17 @@ export class DocumentView extends DocComponent(Docu onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link on Right", event: this.toggleFollowOnRight, icon: "concierge-bell" }); onClicks.push({ description: this.Document.isLinkButton || this.Document.onClick ? "Remove Click Behavior" : "Follow Link", event: this.toggleLinkButtonBehavior, icon: "concierge-bell" }); 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...", subitems: onClicks, icon: "hand-point-right" }); + !existingOnClick && cm?.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); const funcs: ContextMenuProps[] = []; if (this.Document.onDragStart) { funcs.push({ description: "Drag an Alias", icon: "edit", event: () => this.Document.dragFactory && (this.Document.onDragStart = ScriptField.MakeFunction('getAlias(this.dragFactory)')) }); funcs.push({ description: "Drag a Copy", icon: "edit", event: () => this.Document.dragFactory && (this.Document.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)')) }); funcs.push({ description: "Drag Document", icon: "edit", event: () => this.Document.onDragStart = undefined }); - cm.addItem({ description: "OnDrag...", subitems: funcs, icon: "asterisk" }); + cm?.addItem({ description: "OnDrag...", subitems: funcs, icon: "asterisk" }); } - const more = cm.findByDescription("More..."); + const more = cm?.findByDescription("More..."); const moreItems = more && "subitems" in more ? more.subitems : []; if (!Doc.UserDoc().noviceMode) { moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" }); @@ -789,26 +789,26 @@ export class DocumentView extends DocComponent(Docu moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" }); 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...")!); + !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 help = cm?.findByDescription("Help..."); const helpItems: ContextMenuProps[] = help && "subitems" in help ? help.subitems : []; helpItems.push({ description: "Keyboard Shortcuts Ctrl+/", event: () => this.props.addDocTab(Docs.Create.PdfDocument("http://localhost:1050/assets/cheat-sheet.pdf", { _width: 300, _height: 300 }), "onRight"), icon: "keyboard" }); - cm.addItem({ description: "Help...", subitems: helpItems, icon: "question" }); + cm?.addItem({ description: "Help...", subitems: helpItems, icon: "question" }); - const existingAcls = cm.findByDescription("Privacy..."); + const existingAcls = cm?.findByDescription("Privacy..."); const aclItems: ContextMenuProps[] = existingAcls && "subitems" in existingAcls ? existingAcls.subitems : []; aclItems.push({ description: "Make Add Only", event: () => this.setAcl("addOnly"), icon: "concierge-bell" }); aclItems.push({ description: "Make Read Only", event: () => this.setAcl("readOnly"), icon: "concierge-bell" }); aclItems.push({ description: "Make Private", event: () => this.setAcl("ownerOnly"), icon: "concierge-bell" }); aclItems.push({ description: "Test Private", event: () => this.testAcl("ownerOnly"), icon: "concierge-bell" }); aclItems.push({ description: "Test Readonly", event: () => this.testAcl("readOnly"), icon: "concierge-bell" }); - !existingAcls && cm.addItem({ description: "Privacy...", subitems: aclItems, icon: "question" }); + !existingAcls && cm?.addItem({ description: "Privacy...", subitems: aclItems, icon: "question" }); // const recommender_subitems: ContextMenuProps[] = []; @@ -869,7 +869,7 @@ export class DocumentView extends DocComponent(Docu // DocumentViews should stop propagation of this event e.stopPropagation(); } - ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15); + ContextMenu.Instance?.displayMenu(e.pageX - 15, e.pageY - 15); !SelectionManager.IsSelected(this, true) && SelectionManager.SelectDoc(this, false); }); const path = this.props.LibraryPath.reduce((p: string, d: Doc) => p + "/" + (Doc.AreProtosEqual(d, (Doc.UserDoc()["tabs-button-library"] as Doc).sourcePanel as Doc) ? "" : d.title), ""); diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index 4000bee85..3a81e5de1 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -708,6 +708,10 @@ export class MobileInterface extends React.Component { e.stopPropagation(); } + uploadToCurrentCollection = (doc: Doc) => { + + } + render() { return (
@@ -717,13 +721,13 @@ export class MobileInterface extends React.Component {
{this.switchMenuView()} {this.inkMenu()} +
+ {this.pinToPresentation()} + {this.downloadDocument()} + {this.drawInk()} + {this.uploadAudioButton()} +
-
- {this.pinToPresentation()} - {this.downloadDocument()} - {this.drawInk()} - {this.uploadAudioButton()} -
{this.displayWorkspaces()} {this.renderDefaultContent()}
diff --git a/src/pen-gestures/ndollar.ts b/src/pen-gestures/ndollar.ts index 9d42035d1..ecd8df3e7 100644 --- a/src/pen-gestures/ndollar.ts +++ b/src/pen-gestures/ndollar.ts @@ -552,7 +552,7 @@ function Distance(p1: any, p2: any) // distance between two points } function CalcStartUnitVector(points: any, index: any) // start angle from points[0] to points[index] normalized as a unit vector { - const v = new Point(points[index].X - points[0].X, points[index].Y - points[0].Y); + const v = new Point(points[index]?.X - points[0]?.X, points[index]?.Y - points[0]?.Y); const len = Math.sqrt(v.X * v.X + v.Y * v.Y); return new Point(v.X / len, v.Y / len); } -- cgit v1.2.3-70-g09d2 From e8bac5f5e41524e1258d83a98fb440732190fda8 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 27 Jun 2020 20:02:34 -0400 Subject: made safe mode apply to all collections --- src/client/views/collections/CollectionView.tsx | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 508b9e5e7..5e3026979 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -105,15 +105,7 @@ export class CollectionView extends Touchable (this.props.isSelected(outsideReaction) || this.props.rootSelected(outsideReaction) || this.props.Document.forceActive || this._isChildActive || this.props.renderDepth === 0) ? true : false; -- cgit v1.2.3-70-g09d2 From b340defb4a4b8c5b7604099e7b0fb5b6846f70aa Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 27 Jun 2020 21:06:44 -0400 Subject: fixed safe mode & reverted to apply ontly to freeform and schema collections. --- src/client/views/Main.tsx | 2 ++ src/client/views/collections/CollectionView.tsx | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 6878658a8..77e37834d 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -6,12 +6,14 @@ import * as React from 'react'; import { DocServer } from "../DocServer"; import { AssignAllExtensions } from "../../extensions/General/Extensions"; import { Networking } from "../Network"; +import { CollectionView } from "./collections/CollectionView"; AssignAllExtensions(); export let resolvedPorts: { server: number, socket: number }; (async () => { + window.location.search.includes("safe") && CollectionView.SetSafeMode(true); const info = await CurrentUserUtils.loadCurrentUser(); resolvedPorts = JSON.parse(await Networking.FetchFromServer("/resolvedPorts")); DocServer.init(window.location.protocol, window.location.hostname, resolvedPorts.socket, info.email); diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 5e3026979..5f6e8c4a7 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -105,7 +105,15 @@ export class CollectionView extends Touchable (this.props.isSelected(outsideReaction) || this.props.rootSelected(outsideReaction) || this.props.Document.forceActive || this._isChildActive || this.props.renderDepth === 0) ? true : false; -- cgit v1.2.3-70-g09d2 From 790cc785a5cad47f0dd274c7f4773eff7d7d9c2e Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 28 Jun 2020 02:09:55 -0400 Subject: fixed selection of documents in nested collections with filter panel open --- src/client/views/collections/CollectionView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 5f6e8c4a7..469ae9f0e 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -191,7 +191,7 @@ export class CollectionView extends Touchable; } - screenToLocalTransform = () => this.props.ScreenToLocalTransform().scale(this.props.PanelWidth() / this.bodyPanelWidth()); + screenToLocalTransform = () => this.props.renderDepth ? this.props.ScreenToLocalTransform() : this.props.ScreenToLocalTransform().scale(this.props.PanelWidth() / this.bodyPanelWidth()); private SubViewHelper = (type: CollectionViewType, renderProps: CollectionRenderProps) => { const props: SubCollectionViewProps = { ...this.props, ...renderProps, ScreenToLocalTransform: this.screenToLocalTransform, CollectionView: this, annotationsKey: "" }; switch (type) { @@ -521,7 +521,7 @@ export class CollectionView extends Touchable {this.showIsTagged()} -
+
{this.collectionViewType !== undefined ? this.SubView(this.collectionViewType, props) : (null)}
{this.lightbox(DocListCast(this.props.Document[this.props.fieldKey]).filter(d => d.type === DocumentType.IMG).map(d => -- cgit v1.2.3-70-g09d2 From 83ce7f1ad7c2e1b691dbdc67408cee7c65d669b8 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 28 Jun 2020 10:25:27 -0400 Subject: from last --- src/client/views/collections/CollectionView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 469ae9f0e..e61ccf015 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -521,7 +521,7 @@ export class CollectionView extends Touchable {this.showIsTagged()} -
+
{this.collectionViewType !== undefined ? this.SubView(this.collectionViewType, props) : (null)}
{this.lightbox(DocListCast(this.props.Document[this.props.fieldKey]).filter(d => d.type === DocumentType.IMG).map(d => -- cgit v1.2.3-70-g09d2 From 2b9e542ea0e62b13e1f9e0b51f3cfb8e2ce8f78d Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 28 Jun 2020 11:55:49 -0400 Subject: slightly improved layout of workspace facet filter box --- src/client/util/SelectionManager.ts | 8 ++++++++ src/client/views/collections/CollectionTreeView.tsx | 2 +- src/client/views/collections/CollectionView.scss | 14 +++++++++----- src/client/views/collections/CollectionView.tsx | 5 +++-- src/fields/Doc.ts | 1 - 5 files changed, 21 insertions(+), 9 deletions(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index eb905d237..0f204bba4 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -3,6 +3,8 @@ import { Doc } from "../../fields/Doc"; import { DocumentView } from "../views/nodes/DocumentView"; import { computedFn } from "mobx-utils"; import { List } from "../../fields/List"; +import { Scripting } from "./Scripting"; +import { DocumentManager } from "./DocumentManager"; export namespace SelectionManager { @@ -86,3 +88,9 @@ export namespace SelectionManager { } } + +Scripting.addGlobal(function selectDoc(doc: any) { + const view = DocumentManager.Instance.getDocumentView(doc); + view && SelectionManager.SelectDoc(view, false); + //Doc.UserDoc().activeSelection = new List([doc]); +}); \ No newline at end of file diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 1088577d2..33e4acee5 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -124,7 +124,7 @@ class TreeView extends React.Component { constructor(props: any) { super(props); - this._editTitleScript = ScriptField.MakeFunction(`setInPlace(self, 'editTitle', '${this._uniqueId}')`); + this._editTitleScript = ScriptField.MakeScript(`{setInPlace(self, 'editTitle', '${this._uniqueId}'); selectDoc(self);} `); if (Doc.GetT(this.doc, "editTitle", "string", true) === "*") Doc.SetInPlace(this.doc, "editTitle", this._uniqueId, false); } diff --git a/src/client/views/collections/CollectionView.scss b/src/client/views/collections/CollectionView.scss index 7877fe155..b630f9cf8 100644 --- a/src/client/views/collections/CollectionView.scss +++ b/src/client/views/collections/CollectionView.scss @@ -11,16 +11,18 @@ height: 100%; overflow: hidden; // bcz: used to be 'auto' which would create scrollbars when there's a floating doc that's not visible. not sure if that's better, but the scrollbars are annoying... - .collectionTimeView-dragger { - background-color: lightgray; + .collectionView-filterDragger { + background-color: rgb(140, 139, 139); height: 40px; - width: 20px; + width: 10px; position: absolute; - border-radius: 10px; top: 55%; border: 1px black solid; + border-radius: 0; + border-top-left-radius: 20px; + border-bottom-left-radius: 20px; + border-right: unset; z-index: 2; - right: -10px; } .collectionTimeView-treeView { display: flex; @@ -30,6 +32,8 @@ position: absolute; right: 0; top: 0; + border-left: solid 1px; + z-index: 1; .collectionTimeView-addfacet { display: inline-block; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index e61ccf015..2aefb99f5 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -432,7 +432,7 @@ export class CollectionView extends Touchable { this._facetWidth = this.props.PanelWidth() - Math.max(this.props.ScreenToLocalTransform().transformPoint(e.clientX, 0)[0], 0); return false; - }), returnFalse, action(() => this._facetWidth = this.facetWidth() < 15 ? Math.min(this.props.PanelWidth() - 25, 200) : 0)); + }), returnFalse, action(() => 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) @@ -531,7 +531,8 @@ export class CollectionView extends Touchable +
} {this.facetWidth() < 10 ? (null) : this.filterView}
); diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 231ee88e3..dd7117594 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1159,7 +1159,6 @@ Scripting.addGlobal(function activePresentationItem() { const curPres = Doc.UserDoc().activePresentation as Doc; return curPres && DocListCast(curPres[Doc.LayoutFieldKey(curPres)])[NumCast(curPres._itemIndex)]; }); -Scripting.addGlobal(function selectDoc(doc: any) { Doc.UserDoc().activeSelection = new List([doc]); }); Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) { const docs = DocListCast(Doc.UserDoc().activeSelection). filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.DOCHOLDER && d.type !== DocumentType.KVP && -- cgit v1.2.3-70-g09d2 From 29f9cedd937697c56ce3b400931b26c82a23721d Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 29 Jun 2020 00:21:07 -0400 Subject: changed a lot of collection keys to start with "_" -- particularly for Stacking and Schema views. Also added filtering to facet filters. enabled facet filter for sidebar library. --- .../apis/google_docs/GooglePhotosClientUtils.ts | 1 - src/client/documents/Documents.ts | 40 +++++------ src/client/util/CurrentUserUtils.ts | 24 +++---- .../util/Import & Export/DirectoryImportBox.tsx | 2 +- src/client/views/MainView.tsx | 18 ++--- .../collections/CollectionMasonryViewFieldRow.tsx | 10 +-- .../views/collections/CollectionSchemaView.tsx | 16 +++-- .../views/collections/CollectionStackingView.tsx | 77 +++++++++++----------- .../CollectionStackingViewFieldColumn.tsx | 18 ++--- src/client/views/collections/CollectionSubView.tsx | 2 +- .../views/collections/CollectionTreeView.tsx | 4 +- src/client/views/collections/CollectionView.tsx | 8 +-- .../views/collections/CollectionViewChromes.tsx | 8 ++- .../collectionFreeForm/CollectionFreeFormView.tsx | 4 +- .../collections/collectionFreeForm/MarqueeView.tsx | 1 - src/client/views/nodes/KeyValueBox.tsx | 4 +- .../views/nodes/formattedText/DashFieldView.tsx | 4 +- .../views/nodes/formattedText/RichTextRules.ts | 4 +- src/client/views/pdf/PDFViewer.tsx | 2 +- src/fields/documentSchemas.ts | 10 ++- src/fields/util.ts | 2 +- src/scraping/buxton/scraper.py | 3 +- 22 files changed, 131 insertions(+), 131 deletions(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts index a604c7de1..13bfb3a91 100644 --- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts +++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts @@ -130,7 +130,6 @@ export namespace GooglePhotos { const uploads = await Transactions.WriteMediaItemsToServer(response); const children = uploads.map((upload: Transactions.UploadInformation) => { const document = Docs.Create.ImageDocument(Utils.fileUrl(upload.fileNames.clean)); - document.fillColumn = true; document.contentSize = upload.contentSize; return document; }); diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f71984ca6..b70971c2d 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -62,7 +62,7 @@ export interface DocumentOptions { _dimUnit?: string; // "px" or "*" (default = "*") _fitWidth?: boolean; _fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents - _LODdisable?: boolean; + _freeformLOD?: boolean; // whether to use LOD to render a freeform document _showTitleHover?: string; // _showTitle?: string; // which field to display in the title area. leave empty to have no title _showCaption?: string; // which field to display in the caption area. leave empty to have no caption @@ -99,7 +99,7 @@ export interface DocumentOptions { childLayoutTemplate?: Doc; // template for collection to use to render its children (see PresBox or Buxton layout in tree view) childLayoutString?: string; // template string for collection to use to render its children hideFilterView?: boolean; // whether to hide the filter popout on collections - hideHeadings?: boolean; // whether stacking view column headings should be hidden + _columnsHideIfEmpty?: boolean; // whether stacking view column headings should be hidden isTemplateForField?: string; // the field key for which the containing document is a rendering template isTemplateDoc?: boolean; targetScriptKey?: string; // where to write a template script (used by collections with click templates which need to target onClick, onDoubleClick, etc) @@ -119,7 +119,7 @@ export interface DocumentOptions { defaultBackgroundColor?: string; isBackground?: boolean; isLinkButton?: boolean; - columnWidth?: number; + _columnWidth?: number; _fontSize?: number; _fontFamily?: string; curPage?: number; @@ -137,7 +137,8 @@ export interface DocumentOptions { "onCheckedClick-rawScript"?: string; // onChecked script in raw text form "onCheckedClick-params"?: List; // parameter list for onChecked treeview functions _pivotField?: string; // field key used to determine headings for sections in stacking, masonry, pivot views - schemaColumns?: List; + _columnHeaders?: List; // headers for stacking views + _schemaHeaders?: List; // headers for schema view dockingConfig?: string; annotationOn?: Doc; removeDropProperties?: List; // list of properties that should be removed from a document when it is dropped. e.g., a creator button may be forceActive to allow it be dragged, but the forceActive property can be removed from the dropped document @@ -428,8 +429,7 @@ export namespace Docs { const parent = TreeDocument([loading], { title: "The Buxton Collection", _width: 400, - _height: 400, - _LODdisable: true + _height: 400 }); const parentProto = Doc.GetProto(parent); const { _socket } = DocServer; @@ -465,7 +465,7 @@ export namespace Docs { return imageDoc; }); // the main document we create - const doc = StackingDocument(deviceImages, { title, _LODdisable: true, hero: new ImageField(constructed[0].url) }); + const doc = StackingDocument(deviceImages, { title, hero: new ImageField(constructed[0].url) }); doc.nameAliases = new List([title.toLowerCase()]); // add the parsed attributes to this main document Doc.Get.FromJson({ data: device, appendToExisting: { targetDoc: Doc.GetProto(doc) } }); @@ -698,15 +698,15 @@ export namespace Docs { } export function FreeformDocument(documents: Array, options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Freeform }, id); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Freeform }, id); } export function PileDocument(documents: Array, options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", backgroundColor: "black", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Pile }, id); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", backgroundColor: "black", ...options, _viewType: CollectionViewType.Pile }, id); } export function LinearDocument(documents: Array, options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", backgroundColor: "black", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Linear }, id); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", backgroundColor: "black", ...options, _viewType: CollectionViewType.Linear }, id); } export function MapDocument(documents: Array, options: DocumentOptions = {}) { @@ -714,35 +714,35 @@ export namespace Docs { } export function CarouselDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Carousel }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Carousel }); } export function Carousel3DDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Carousel3D }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Carousel3D }); } - export function SchemaDocument(schemaColumns: SchemaHeaderField[], documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List(schemaColumns.length ? schemaColumns : [new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Schema }); + export function SchemaDocument(schemaHeaders: SchemaHeaderField[], documents: Array, options: DocumentOptions) { + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", _schemaHeaders: schemaHeaders.length ? new List(schemaHeaders) : undefined, ...options, _viewType: CollectionViewType.Schema }); } export function TreeDocument(documents: Array, options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Tree }, id); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Tree }, id); } export function StackingDocument(documents: Array, options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Stacking }, id); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Stacking }, id); } export function MulticolumnDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Multicolumn }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Multicolumn }); } export function MultirowDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Multirow }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Multirow }); } export function MasonryDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Masonry }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Masonry }); } export function LabelDocument(options?: DocumentOptions) { @@ -1054,7 +1054,7 @@ export namespace DocUtils { }); }); if (x !== undefined && y !== undefined) { - const newCollection = Docs.Create.PileDocument(docList, { title: "pileup", x: x - 55, y: y - 55, _width: 110, _height: 100, _LODdisable: true }); + const newCollection = Docs.Create.PileDocument(docList, { title: "pileup", x: x - 55, y: y - 55, _width: 110, _height: 100 }); newCollection.x = NumCast(newCollection.x) + NumCast(newCollection._width) / 2 - 55; newCollection.y = NumCast(newCollection.y) + NumCast(newCollection._height) / 2 - 55; newCollection._width = newCollection._height = 110; diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 2b0b2c738..d0ca0e57e 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -43,7 +43,7 @@ export class CurrentUserUtils { const queryTemplate = Docs.Create.MulticolumnDocument( [ Docs.Create.QueryDocument({ title: "query", _height: 200 }), - Docs.Create.FreeformDocument([], { title: "data", _height: 100, _LODdisable: true }) + Docs.Create.FreeformDocument([], { title: "data", _height: 100 }) ], { _width: 400, _height: 300, title: "queryView", _chromeStatus: "disabled", _xMargin: 3, _yMargin: 3, hideFilterView: true } ); @@ -136,9 +136,9 @@ export class CurrentUserUtils { if (doc["template-button-switch"] === undefined) { const { FreeformDocument, MulticolumnDocument, TextDocument } = Docs.Create; - const yes = FreeformDocument([], { title: "yes", _height: 35, _width: 50, _LODdisable: true, _dimUnit: DimUnit.Pixel, _dimMagnitude: 40 }); + const yes = FreeformDocument([], { title: "yes", _height: 35, _width: 50, _dimUnit: DimUnit.Pixel, _dimMagnitude: 40 }); const name = TextDocument("name", { title: "name", _height: 35, _width: 70, _dimMagnitude: 1 }); - const no = FreeformDocument([], { title: "no", _height: 100, _width: 100, _LODdisable: true }); + const no = FreeformDocument([], { title: "no", _height: 100, _width: 100 }); const labelTemplate = { doc: { type: "doc", content: [{ @@ -193,10 +193,10 @@ export class CurrentUserUtils { const shared = { _chromeStatus: "disabled", _autoHeight: true, _xMargin: 0 }; const detailViewOpts = { title: "detailView", _width: 300, _fontFamily: "Arial", _fontSize: 12 }; - const descriptionWrapperOpts = { title: "descriptions", _height: 300, columnWidth: -1, treeViewHideTitle: true, _pivotField: "title" }; + const descriptionWrapperOpts = { title: "descriptions", _height: 300, _columnWidth: -1, treeViewHideTitle: true, _pivotField: "title" }; const descriptionWrapper = MasonryDocument([details, short, long], { ...shared, ...descriptionWrapperOpts }); - descriptionWrapper.sectionHeaders = new List([ + descriptionWrapper._columnHeaders = new List([ new SchemaHeaderField("[A Short Description]", "dimGray", undefined, undefined, undefined, false), new SchemaHeaderField("[Long Description]", "dimGray", undefined, undefined, undefined, true), new SchemaHeaderField("[Details]", "dimGray", undefined, undefined, undefined, true), @@ -225,7 +225,7 @@ export class CurrentUserUtils { if (doc["template-buttons"] === undefined) { doc["template-buttons"] = new PrefetchProxy(Docs.Create.MasonryDocument(requiredTypes, { title: "Advanced Item Prototypes", _xMargin: 0, _showTitle: "title", - _autoHeight: true, _width: 500, columnWidth: 35, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", + _autoHeight: true, _width: 500, _columnWidth: 35, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), })); } else { @@ -358,11 +358,11 @@ export class CurrentUserUtils { }[] { if (doc.emptyPresentation === undefined) { doc.emptyPresentation = Docs.Create.PresDocument(new List(), - { title: "Presentation", _viewType: CollectionViewType.Stacking, targetDropAction: "alias", _LODdisable: true, _chromeStatus: "replaced", _showTitle: "title", boxShadow: "0 0" }); + { title: "Presentation", _viewType: CollectionViewType.Stacking, targetDropAction: "alias", _chromeStatus: "replaced", _showTitle: "title", boxShadow: "0 0" }); } if (doc.emptyCollection === undefined) { doc.emptyCollection = Docs.Create.FreeformDocument([], - { _nativeWidth: undefined, _nativeHeight: undefined, _LODdisable: true, _width: 150, _height: 100, title: "freeform" }); + { _nativeWidth: undefined, _nativeHeight: undefined, _width: 150, _height: 100, title: "freeform" }); } if (doc.emptyDocHolder === undefined) { doc.emptyDocHolder = Docs.Create.DocumentDocument( @@ -430,7 +430,7 @@ export class CurrentUserUtils { if (dragCreatorSet === undefined) { doc.myItemCreators = new PrefetchProxy(Docs.Create.MasonryDocument(creatorBtns, { title: "Basic Item Creators", _showTitle: "title", _xMargin: 0, - _autoHeight: true, _width: 500, columnWidth: 35, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", + _autoHeight: true, _width: 500, _columnWidth: 35, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), })); } else { @@ -493,7 +493,7 @@ export class CurrentUserUtils { static setupMobileDoc(userDoc: Doc) { return userDoc.activeMoble ?? Docs.Create.MasonryDocument(CurrentUserUtils.setupMobileButtons(userDoc), { - columnWidth: 100, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "buttons", _autoHeight: true, _yMargin: 5 + _columnWidth: 100, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "buttons", _autoHeight: true, _yMargin: 5 }); } @@ -655,7 +655,7 @@ export class CurrentUserUtils { // Finally, setup the list of buttons to display in the sidebar if (doc["tabs-buttons"] === undefined) { doc["tabs-buttons"] = new PrefetchProxy(Docs.Create.StackingDocument([searchBtn, libraryBtn, toolsBtn], { - _width: 500, _height: 80, boxShadow: "0 0", _pivotField: "title", hideHeadings: true, ignoreClick: true, _chromeStatus: "view-mode", + _width: 500, _height: 80, boxShadow: "0 0", _pivotField: "title", _columnsHideIfEmpty: true, ignoreClick: true, _chromeStatus: "view-mode", title: "sidebar btn row stack", backgroundColor: "dimGray", })); (toolsBtn.onClick as ScriptField).script.run({ this: toolsBtn }); @@ -704,7 +704,7 @@ export class CurrentUserUtils { if (doc.activePresentation === undefined) { doc.activePresentation = Docs.Create.PresDocument(new List(), { title: "Presentation", _viewType: CollectionViewType.Stacking, targetDropAction: "alias", - _LODdisable: true, _chromeStatus: "replaced", _showTitle: "title", boxShadow: "0 0" + _chromeStatus: "replaced", _showTitle: "title", boxShadow: "0 0" }); } } diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx index af6c57e68..77f13e9f4 100644 --- a/src/client/util/Import & Export/DirectoryImportBox.tsx +++ b/src/client/util/Import & Export/DirectoryImportBox.tsx @@ -161,7 +161,7 @@ export class DirectoryImportBox extends React.Component { importContainer = Docs.Create.SchemaDocument(headers, docs, options); } runInAction(() => this.phase = 'External: uploading files to Google Photos...'); - importContainer.singleColumn = false; + importContainer._columnsStack = false; await GooglePhotos.Export.CollectionToAlbum({ collection: importContainer }); Doc.AddDocToList(Doc.GetProto(parent.props.Document), "data", importContainer); !this.persistent && this.props.removeDocument && this.props.removeDocument(doc); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 68b81ab4f..8f5a31b6c 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -206,7 +206,6 @@ export class MainView extends React.Component { _width: this._panelWidth * .7, _height: this._panelHeight, title: "Collection " + workspaceCount, - _LODdisable: true }; const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); const workspaceDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [Doc.UserDoc().myCatalog as Doc] }], { title: `Workspace ${workspaceCount}` }, id, "row"); @@ -354,15 +353,6 @@ export class MainView extends React.Component { } } - @action - pointerOverDragger = () => { - // if (this.flyoutWidth === 0) { - // this.flyoutWidth = 250; - // this.sidebarButtonsDoc.columnWidth = this.flyoutWidth / 3 - 30; - // this._flyoutTranslate = false; - // } - } - @action pointerLeaveDragger = () => { if (!this._flyoutTranslate) { @@ -375,13 +365,13 @@ export class MainView extends React.Component { onPointerMove = (e: PointerEvent) => { this.flyoutWidth = Math.max(e.clientX, 0); Math.abs(this.flyoutWidth - this._flyoutSizeOnDown) > 6 && (this._canClick = false); - this.sidebarButtonsDoc.columnWidth = this.flyoutWidth / 3 - 30; + this.sidebarButtonsDoc._columnWidth = this.flyoutWidth / 3 - 30; } @action onPointerUp = (e: PointerEvent) => { if (Math.abs(e.clientX - this._flyoutSizeOnDown) < 4 && this._canClick) { this.flyoutWidth = this.flyoutWidth < 15 ? 250 : 0; - this.flyoutWidth && (this.sidebarButtonsDoc.columnWidth = this.flyoutWidth / 3 - 30); + this.flyoutWidth && (this.sidebarButtonsDoc._columnWidth = this.flyoutWidth / 3 - 30); } document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); @@ -470,7 +460,7 @@ export class MainView extends React.Component { }} >
-
{ MainView.Instance._flyoutTranslate = true; MainView.Instance.flyoutWidth = (MainView.Instance.flyoutWidth || 250); - MainView.Instance.sidebarButtonsDoc.columnWidth = MainView.Instance.flyoutWidth / 3 - 30; + MainView.Instance.sidebarButtonsDoc._columnWidth = MainView.Instance.flyoutWidth / 3 - 30; }); @computed get expandButton() { diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index e0b53e762..627b22417 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -111,8 +111,8 @@ export class CollectionMasonryViewFieldRow extends React.Component i.heading).indexOf(castedValue.toString()) > -1) { + if (this.props.parent.columnHeaders) { + if (this.props.parent.columnHeaders.map(i => i.heading).indexOf(castedValue.toString()) > -1) { return false; } } @@ -151,9 +151,9 @@ export class CollectionMasonryViewFieldRow extends React.Component d[key] = undefined); - if (this.props.parent.sectionHeaders && this.props.headingObject) { - const index = this.props.parent.sectionHeaders.indexOf(this.props.headingObject); - this.props.parent.sectionHeaders.splice(index, 1); + if (this.props.parent.columnHeaders && this.props.headingObject) { + const index = this.props.parent.columnHeaders.indexOf(this.props.headingObject); + this.props.parent.columnHeaders.splice(index, 1); } })); diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 56a2a517c..b780da97e 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -240,10 +240,10 @@ export class SchemaTable extends React.Component { @computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH - this.previewWidth(); } @computed get columns() { - return Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField), []); + return Cast(this.props.Document._schemaHeaders, listSpec(SchemaHeaderField), []); } set columns(columns: SchemaHeaderField[]) { - this.props.Document.schemaColumns = new List(columns); + this.props.Document._schemaHeaders = new List(columns); } @computed get childDocs() { @@ -375,10 +375,12 @@ export class SchemaTable extends React.Component { constructor(props: SchemaTableProps) { super(props); // convert old schema columns (list of strings) into new schema columns (list of schema header fields) - const oldSchemaColumns = Cast(this.props.Document.schemaColumns, listSpec("string"), []); - if (oldSchemaColumns && oldSchemaColumns.length && typeof oldSchemaColumns[0] !== "object") { - const newSchemaColumns = oldSchemaColumns.map(i => typeof i === "string" ? new SchemaHeaderField(i, "#f1efeb") : i); - this.props.Document.schemaColumns = new List(newSchemaColumns); + const oldSchemaHeaders = Cast(this.props.Document._schemaHeaders, listSpec("string"), []); + if (oldSchemaHeaders?.length && typeof oldSchemaHeaders[0] !== "object") { + const newSchemaHeaders = oldSchemaHeaders.map(i => typeof i === "string" ? new SchemaHeaderField(i, "#f1efeb") : i); + this.props.Document._schemaHeaders = new List(newSchemaHeaders); + } else if (this.props.Document._schemaHeaders === undefined) { + this.props.Document._schemaHeaders = new List([new SchemaHeaderField("title", "#f1efeb")]); } } @@ -740,7 +742,7 @@ export class SchemaTable extends React.Component { if(col === undefined) { return (doc as any)[key][row + ${row}]; } - return (doc as any)[key][row + ${row}][(doc as any).schemaColumns[col + ${col}].heading]; + return (doc as any)[key][row + ${row}][(doc as any)._schemaHeaders[col + ${col}].heading]; } return ${script}`; const compiled = CompileScript(script, { params: { this: Doc.name }, capturedVariables: { doc: this.props.Document, key: this.props.fieldKey }, typecheck: false, transformer: this.createTransformer(row, col) }); diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 4aab43b08..7bdf5e7df 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -43,27 +43,26 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) @observable _heightMap = new Map(); @observable _cursor: CursorProperty = "grab"; @observable _scroll = 0; // used to force the document decoration to update when scrolling - @computed get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); } - @computed get pivotField() { return StrCast(this.props.Document._pivotField); } + @computed get columnHeaders() { return Cast(this.layoutDoc._columnHeaders, listSpec(SchemaHeaderField)); } + @computed get pivotField() { return StrCast(this.layoutDoc._pivotField); } @computed get filteredChildren() { return this.childLayoutPairs.filter(pair => pair.layout instanceof Doc).map(pair => pair.layout); } - @computed get xMargin() { return NumCast(this.props.Document._xMargin, 2 * Math.min(this.gridGap, .05 * this.props.PanelWidth())); } - @computed get yMargin() { return Math.max(this.props.Document._showTitle && !this.props.Document._showTitleHover ? 30 : 0, NumCast(this.props.Document._yMargin, 0)); } // 2 * this.gridGap)); } - @computed get gridGap() { return NumCast(this.props.Document._gridGap, 10); } - @computed get isStackingView() { return BoolCast(this.props.Document.singleColumn, true); } + @computed get xMargin() { return NumCast(this.layoutDoc._xMargin, 2 * Math.min(this.gridGap, .05 * this.props.PanelWidth())); } + @computed get yMargin() { return Math.max(this.layoutDoc._showTitle && !this.layoutDoc._showTitleHover ? 30 : 0, NumCast(this.layoutDoc._yMargin, 0)); } // 2 * this.gridGap)); } + @computed get gridGap() { return NumCast(this.layoutDoc._gridGap, 10); } + @computed get isStackingView() { return BoolCast(this.layoutDoc._columnsStack, true); } @computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; } - @computed get showAddAGroup() { return (this.pivotField && (this.props.Document._chromeStatus !== 'view-mode' && this.props.Document._chromeStatus !== 'disabled')); } + @computed get showAddAGroup() { return (this.pivotField && (this.layoutDoc._chromeStatus !== 'view-mode' && this.layoutDoc._chromeStatus !== 'disabled')); } @computed get columnWidth() { - TraceMobx(); - return Math.min(this.props.PanelWidth() / (this.props as any).ContentScaling() - 2 * this.xMargin, - this.isStackingView ? Number.MAX_VALUE : this.props.Document.columnWidth === -1 ? this.props.PanelWidth() - 2 * this.xMargin : NumCast(this.props.Document.columnWidth, 250)); + return Math.min(this.props.PanelWidth() / this.props.ContentScaling() - 2 * this.xMargin, + this.isStackingView ? Number.MAX_VALUE : this.layoutDoc._columnWidth === -1 ? this.props.PanelWidth() - 2 * this.xMargin : NumCast(this.layoutDoc._columnWidth, 250)); } @computed get NodeWidth() { return this.props.PanelWidth() - this.gridGap; } constructor(props: any) { super(props); - if (this.sectionHeaders === undefined) { - this.props.Document.sectionHeaders = new List(); + if (this.columnHeaders === undefined) { + this.layoutDoc._columnHeaders = new List(); } } @@ -89,14 +88,14 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) } get Sections() { - if (!this.pivotField || this.sectionHeaders instanceof Promise) return new Map(); + if (!this.pivotField || this.columnHeaders instanceof Promise) return new Map(); - if (this.sectionHeaders === undefined) { - setTimeout(() => this.props.Document.sectionHeaders = new List(), 0); + if (this.columnHeaders === undefined) { + setTimeout(() => this.layoutDoc._columnHeaders = new List(), 0); return new Map(); } - const sectionHeaders = Array.from(this.sectionHeaders); - const fields = new Map(sectionHeaders.map(sh => [sh, []] as [SchemaHeaderField, []])); + const columnHeaders = Array.from(this.columnHeaders); + const fields = new Map(columnHeaders.map(sh => [sh, []] as [SchemaHeaderField, []])); let changed = false; this.filteredChildren.map(d => { const sectionValue = (d[this.pivotField] ? d[this.pivotField] : `NO ${this.pivotField.toUpperCase()} VALUE`) as object; @@ -105,26 +104,26 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) const castedSectionValue = !isNaN(parsed) ? parsed : sectionValue; // look for if header exists already - const existingHeader = sectionHeaders.find(sh => sh.heading === (castedSectionValue ? castedSectionValue.toString() : `NO ${this.pivotField.toUpperCase()} VALUE`)); + const existingHeader = columnHeaders.find(sh => sh.heading === (castedSectionValue ? castedSectionValue.toString() : `NO ${this.pivotField.toUpperCase()} VALUE`)); if (existingHeader) { fields.get(existingHeader)!.push(d); } else { const newSchemaHeader = new SchemaHeaderField(castedSectionValue ? castedSectionValue.toString() : `NO ${this.pivotField.toUpperCase()} VALUE`); fields.set(newSchemaHeader, [d]); - sectionHeaders.push(newSchemaHeader); + columnHeaders.push(newSchemaHeader); changed = true; } }); // remove all empty columns if hideHeadings is set - if (this.props.Document.hideHeadings) { + if (this.layoutDoc._columnsHideIfEmpty) { Array.from(fields.keys()).filter(key => !fields.get(key)!.length).map(header => { fields.delete(header); - sectionHeaders.splice(sectionHeaders.indexOf(header), 1); + columnHeaders.splice(columnHeaders.indexOf(header), 1); changed = true; }); } - changed && setTimeout(action(() => { if (this.sectionHeaders) { this.sectionHeaders.length = 0; this.sectionHeaders.push(...sectionHeaders); } }), 0); + changed && setTimeout(action(() => { if (this.columnHeaders) { this.columnHeaders.length = 0; this.columnHeaders.push(...columnHeaders); } }), 0); return fields; } @@ -136,7 +135,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) let wid = this.columnWidth / (this.isStackingView ? this.numGroupColumns : 1); if (!layoutDoc._fitWidth && nw && nh) { const aspect = nw && nh ? nh / nw : 1; - if (!(this.props.Document.fillColumn)) wid = Math.min(layoutDoc[WidthSym](), wid); + if (!(this.layoutDoc._columnsFill)) wid = Math.min(layoutDoc[WidthSym](), wid); return wid * aspect; } return layoutDoc._fitWidth ? wid * NumCast(layoutDoc.scrollHeight, nh) / (nw || 1) : layoutDoc[HeightSym](); @@ -147,7 +146,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) // reset section headers when a new filter is inputted this._pivotFieldDisposer = reaction( () => this.pivotField, - () => this.props.Document.sectionHeaders = new List() + () => this.layoutDoc._columnHeaders = new List() ); } componentWillUnmount() { @@ -211,7 +210,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) fitToBox={false} dontRegisterView={this.props.dontRegisterView} rootSelected={this.rootSelected} - dropAction={StrCast(this.props.Document.childDropAction) as dropActionType} + dropAction={StrCast(this.layoutDoc.childDropAction) as dropActionType} onClick={this.onChildClickHandler} onDoubleClick={this.onChildDoubleClickHandler} ScreenToLocalTransform={dxf} @@ -236,7 +235,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) if (!d) return 0; const layoutDoc = Doc.Layout(d, this.props.ChildLayoutTemplate?.()); const nw = NumCast(layoutDoc._nativeWidth); - return Math.min(nw && !this.props.Document.fillColumn ? d[WidthSym]() : Number.MAX_VALUE, this.columnWidth / this.numGroupColumns); + return Math.min(nw && !this.layoutDoc._columnsFill ? d[WidthSym]() : Number.MAX_VALUE, this.columnWidth / this.numGroupColumns); } getDocHeight(d?: Doc) { if (!d) return 0; @@ -246,7 +245,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) let wid = this.columnWidth / (this.isStackingView ? this.numGroupColumns : 1); if (!layoutDoc._fitWidth && nw && nh) { const aspect = nw && nh ? nh / nw : 1; - if (!(this.props.Document.fillColumn)) wid = Math.min(layoutDoc[WidthSym](), wid); + if (!(this.layoutDoc._columnsFill)) wid = Math.min(layoutDoc[WidthSym](), wid); return wid * aspect; } return layoutDoc._fitWidth ? !nh ? this.props.PanelHeight() - 2 * this.yMargin : @@ -259,7 +258,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) } @action onDividerMove = (e: PointerEvent, down: number[], delta: number[]) => { - this.layoutDoc.columnWidth = Math.max(10, this.columnWidth + delta[0]); + this.layoutDoc._columnWidth = Math.max(10, this.columnWidth + delta[0]); return false; } @@ -341,7 +340,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) this.refList.push(ref); const doc = this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc; this.observer = new _global.ResizeObserver(action((entries: any) => { - if (this.props.Document._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) { + if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) { Doc.Layout(doc)._height = Math.min(1200, Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", ""))))); } })); @@ -388,7 +387,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) this.refList.push(ref); const doc = this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc; this.observer = new _global.ResizeObserver(action((entries: any) => { - if (this.props.Document._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) { + if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) { Doc.Layout(doc)._height = this.refList.reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0); } })); @@ -411,9 +410,9 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) @action addGroup = (value: string) => { - if (value && this.sectionHeaders) { + if (value && this.columnHeaders) { const schemaHdrField = new SchemaHeaderField(value); - this.sectionHeaders.push(schemaHdrField); + this.columnHeaders.push(schemaHdrField); DocUtils.addFieldEnumerations(undefined, this.pivotField, [{ title: value, _backgroundColor: schemaHdrField.color }]); return true; } @@ -421,22 +420,22 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) } sortFunc = (a: [SchemaHeaderField, Doc[]], b: [SchemaHeaderField, Doc[]]): 1 | -1 => { - const descending = BoolCast(this.props.Document.stackingHeadersSortDescending); + const descending = StrCast(this.layoutDoc._columnsSort) === "descending"; const firstEntry = descending ? b : a; const secondEntry = descending ? a : b; return firstEntry[0].heading > secondEntry[0].heading ? 1 : -1; } onToggle = (checked: Boolean) => { - this.props.Document._chromeStatus = checked ? "collapsed" : "view-mode"; + this.layoutDoc._chromeStatus = checked ? "collapsed" : "view-mode"; } onContextMenu = (e: React.MouseEvent): void => { // need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout if (!e.isPropagationStopped()) { const subItems: ContextMenuProps[] = []; - subItems.push({ description: `${this.props.Document.fillColumn ? "Variable Size" : "Autosize"} Column`, event: () => this.props.Document.fillColumn = !this.props.Document.fillColumn, icon: "plus" }); - subItems.push({ description: `${this.Document._autoHeight ? "Variable Height" : "Auto Height"}`, event: () => this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight, icon: "plus" }); + subItems.push({ description: `${this.layoutDoc._columnsFill ? "Variable Size" : "Autosize"} Column`, event: () => this.layoutDoc._columnsFill = !this.layoutDoc._columnsFill, icon: "plus" }); + subItems.push({ description: `${this.layoutDoc._autoHeight ? "Variable Height" : "Auto Height"}`, event: () => this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight, icon: "plus" }); ContextMenu.Instance.addItem({ description: "Options...", subitems: subItems, icon: "eye" }); } } @@ -446,7 +445,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) let sections = [[undefined, this.filteredChildren] as [SchemaHeaderField | undefined, Doc[]]]; if (this.pivotField) { const entries = Array.from(this.Sections.entries()); - sections = entries.sort(this.sortFunc); + sections = this.layoutDoc._columnsSort ? entries.sort(this.sortFunc) : entries; } return sections.map((section, i) => this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1], i === 0)); } @@ -489,10 +488,10 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) style={{ width: !this.isStackingView ? "100%" : this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}>
} - {this.props.Document._chromeStatus !== 'disabled' && this.props.isSelected() ? : null} diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index b60ed853b..b147b089b 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -96,8 +96,8 @@ export class CollectionStackingViewFieldColumn extends React.Component i.heading).indexOf(castedValue.toString()) > -1) { + if (this.props.parent.columnHeaders) { + if (this.props.parent.columnHeaders.map(i => i.heading).indexOf(castedValue.toString()) > -1) { return false; } } @@ -148,9 +148,9 @@ export class CollectionStackingViewFieldColumn extends React.Component { const key = StrCast(this.props.parent.props.Document._pivotField); this.props.docList.forEach(d => d[key] = undefined); - if (this.props.parent.sectionHeaders && this.props.headingObject) { - const index = this.props.parent.sectionHeaders.indexOf(this.props.headingObject); - this.props.parent.sectionHeaders.splice(index, 1); + if (this.props.parent.columnHeaders && this.props.headingObject) { + const index = this.props.parent.columnHeaders.indexOf(this.props.headingObject); + this.props.parent.columnHeaders.splice(index, 1); } } @@ -168,7 +168,7 @@ export class CollectionStackingViewFieldColumn extends React.Component { const alias = Doc.MakeAlias(this.props.parent.props.Document); - alias._width = this.props.parent.props.PanelWidth() / (Cast(this.props.parent.props.Document.sectionHeaders, listSpec(SchemaHeaderField))?.length || 1); + alias._width = this.props.parent.props.PanelWidth() / (Cast(this.props.parent.columnHeaders, listSpec(SchemaHeaderField))?.length || 1); alias._pivotField = undefined; const key = StrCast(this.props.parent.props.Document._pivotField); let value = this.getValue(this._heading); @@ -259,8 +259,8 @@ export class CollectionStackingViewFieldColumn extends React.Component this.props.parent.props.addDocument(Docs.Create.FreeformDocument([], { _width: 200, _height: 200, _LODdisable: true })), icon: "compress-arrows-alt" }); - layoutItems.push({ description: ":carousel", event: () => this.props.parent.props.addDocument(Docs.Create.CarouselDocument([], { _width: 400, _height: 200, _LODdisable: true })), icon: "compress-arrows-alt" }); + layoutItems.push({ description: ":freeform", event: () => this.props.parent.props.addDocument(Docs.Create.FreeformDocument([], { _width: 200, _height: 200 })), icon: "compress-arrows-alt" }); + layoutItems.push({ description: ":carousel", event: () => this.props.parent.props.addDocument(Docs.Create.CarouselDocument([], { _width: 400, _height: 200 })), icon: "compress-arrows-alt" }); layoutItems.push({ description: ":columns", event: () => this.props.parent.props.addDocument(Docs.Create.MulticolumnDocument([], { _width: 200, _height: 200 })), icon: "compress-arrows-alt" }); layoutItems.push({ description: ":image", event: () => this.props.parent.props.addDocument(Docs.Create.ImageDocument("http://www.cs.brown.edu/~bcz/face.gif", { _width: 200, _height: 200 })), icon: "compress-arrows-alt" }); @@ -359,7 +359,7 @@ export class CollectionStackingViewFieldColumn extends React.Component - {this.props.parent.Document.hideHeadings ? (null) : headingView} + {this.props.parent.Document._columnsHideIfEmpty ? (null) : headingView} { this.collapsed ? (null) :
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 3a13ac822..49480e759 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -341,7 +341,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: const rect = "getBoundingClientRect" in focusNode ? focusNode.getBoundingClientRect() : focusNode?.parentElement.getBoundingClientRect(); const x = (rect?.x || 0); const y = NumCast(srcWeb._scrollTop) + (rect?.y || 0); - const anchor = Docs.Create.FreeformDocument([], { _LODdisable: true, _backgroundColor: "transparent", _width: 25, _height: 25, x, y, annotationOn: srcWeb }); + const anchor = Docs.Create.FreeformDocument([], { _backgroundColor: "transparent", _width: 25, _height: 25, x, y, annotationOn: srcWeb }); anchor.context = srcWeb; const key = Doc.LayoutFieldKey(srcWeb); Doc.AddDocToList(srcWeb, key + "-annotations", anchor); diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index d54f4d6e6..f6f6fb7cc 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -176,7 +176,7 @@ class TreeView extends React.Component { })} OnFillDown={undoBatch((value: string) => { Doc.SetInPlace(this.doc, key, value, false); - const doc = Docs.Create.FreeformDocument([], { title: "-", x: 0, y: 0, _width: 100, _height: 25, _LODdisable: true, templates: new List([Templates.Title.Layout]) }); + const doc = Docs.Create.FreeformDocument([], { title: "-", x: 0, y: 0, _width: 100, _height: 25, templates: new List([Templates.Title.Layout]) }); Doc.SetInPlace(this.doc, "editTitle", undefined, false); Doc.SetInPlace(doc, "editTitle", "*", false); return this.props.addDocument(doc); @@ -828,7 +828,7 @@ export class CollectionTreeView extends CollectionSubView Doc.SetInPlace(this.dataDoc, "title", value, false) || true)} OnFillDown={undoBatch((value: string) => { Doc.SetInPlace(this.dataDoc, "title", value, false); - const doc = Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, _width: 100, _height: 25, _LODdisable: true, templates: new List([Templates.Title.Layout]) }); + const doc = Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, _width: 100, _height: 25, templates: new List([Templates.Title.Layout]) }); Doc.SetInPlace(doc, "editTitle", "*", false); this.addDoc(doc, childDocs.length ? childDocs[0] : undefined, true); })} />} diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 5c87bc483..f2ffe7835 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -207,8 +207,8 @@ export class CollectionView extends Touchable); } case CollectionViewType.Carousel: { return (); } case CollectionViewType.Carousel3D: { return (); } - case CollectionViewType.Stacking: { this.props.Document.singleColumn = true; return (); } - case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (); } + case CollectionViewType.Stacking: { this.props.Document._columnsStack = true; return (); } + case CollectionViewType.Masonry: { this.props.Document._columnsStack = false; return (); } case CollectionViewType.Time: { return (); } case CollectionViewType.Map: return (); case CollectionViewType.Grid: return (); @@ -360,7 +360,7 @@ export class CollectionView extends Touchable(); this.childDocs.filter(child => child).forEach(child => Object.keys(Doc.GetProto(child)).forEach(key => facets.add(key))); Doc.AreProtosEqual(this.dataDoc, this.props.Document) && this.childDocs.filter(child => child).forEach(child => Object.keys(child).forEach(key => facets.add(key))); - return Array.from(facets); + return Array.from(facets).filter(f => !f.startsWith("_") && !["proto", "zIndex", "isPrototype", "context", "text-noTemplate"].includes(f)).sort(); } /** @@ -534,7 +534,7 @@ export class CollectionView extends Touchable } diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 276bccede..ab0df88f8 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -406,7 +406,7 @@ export class CollectionStackingViewChrome extends React.Component => { @@ -450,7 +450,11 @@ export class CollectionStackingViewChrome extends React.Component { this.props.CollectionView.props.Document.stackingHeadersSortDescending = !this.props.CollectionView.props.Document.stackingHeadersSortDescending; }; + @action toggleSort = () => { + this.props.CollectionView.props.Document._columnsSort = + this.props.CollectionView.props.Document._columnsSort === "descending" ? "ascending" : + this.props.CollectionView.props.Document._columnsSort === "ascending" ? undefined : "descending"; + }; @action resetValue = () => { this._currentKey = this.pivotField; }; render() { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 5135c4ae4..ba20e9830 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1226,7 +1226,7 @@ export class CollectionFreeFormView extends CollectionSubView this.Document._LODdisable = !this.Document._LODdisable, icon: "table" }); + optionItems.push({ description: `${this.Document._freeformLOD ? "Enable LOD" : "Disable LOD"}`, event: () => this.Document._freeformLOD = !this.Document._freeformLOD, icon: "table" }); optionItems.push({ description: "Import document", icon: "upload", event: ({ x, y }) => { const input = document.createElement("input"); @@ -1390,7 +1390,7 @@ export class CollectionFreeFormView extends CollectionSubView - {!this.Document._LODdisable && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ? + {this.Document._freeformLOD && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ? this.placeholder : this.marqueeView} diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 099859109..97ed74c10 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -352,7 +352,6 @@ export class MarqueeView extends React.Component d.context = newCollection); diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index d375466c9..b732f5f83 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -169,8 +169,8 @@ export class KeyValueBox extends React.Component { getTemplate = async () => { const parent = Docs.Create.StackingDocument([], { _width: 800, _height: 800, title: "Template" }); - parent.singleColumn = false; - parent.columnWidth = 100; + parent._columnsStack = false; + parent._columnWidth = 100; for (const row of this.rows.filter(row => row.isChecked)) { await this.createTemplateField(parent, row); row.uncheck(); diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx index 8c16f4a1a..8718bf329 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.tsx +++ b/src/client/views/nodes/formattedText/DashFieldView.tsx @@ -184,9 +184,9 @@ export class DashFieldViewInternal extends React.Component(); + alias._columnHeaders = list = new List(); } list.map(c => 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")); diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index ba3230801..6a85e3b7c 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -275,7 +275,7 @@ export class RichTextRules { if (!fieldKey) { if (docid) { DocServer.GetRefField(docid).then(docx => { - const target = ((docx instanceof Doc) && docx) || Docs.Create.FreeformDocument([], { title: docid, _width: 500, _height: 500, _LODdisable: true, }, docid); + const target = ((docx instanceof Doc) && docx) || Docs.Create.FreeformDocument([], { title: docid, _width: 500, _height: 500, }, docid); DocUtils.Publish(target, docid, returnFalse, returnFalse); DocUtils.MakeLink({ doc: this.Document }, { doc: target }, "portal to"); }); @@ -305,7 +305,7 @@ export class RichTextRules { if (!fieldKey && !docid) return state.tr; docid && DocServer.GetRefField(docid).then(docx => { if (!(docx instanceof Doc && docx)) { - const docx = Docs.Create.FreeformDocument([], { title: docid, _width: 500, _height: 500, _LODdisable: true }, docid); + const docx = Docs.Create.FreeformDocument([], { title: docid, _width: 500, _height: 500 }, docid); DocUtils.Publish(docx, docid, returnFalse, returnFalse); } }); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 5ed1e6239..372d01b9c 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -293,7 +293,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent