From 188e1e57860f58e9ebe3536a0e1f7cd84ea0db80 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 18 Mar 2021 00:08:13 -0400 Subject: cleaned up link making. Documents don't add to the Undo stack when being created and Initializing is set. Links to text regions automatically update their link line endpoints even if autoMove isn't set. regularized initialization fields to avoid special cases about setting delegate keys without a leading "_" --- src/client/documents/Documents.ts | 227 ++++++++++++++++++-------------------- 1 file changed, 106 insertions(+), 121 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 8aa478cc1..24409933e 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -58,7 +58,6 @@ import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo"; import { DocumentType } from "./DocumentTypes"; import { EquationBox } from "../views/nodes/EquationBox"; import { FunctionPlotBox } from "../views/nodes/FunctionPlotBox"; -import { script } from "googleapis/build/src/apis/script"; import { CurrentUserUtils } from "../util/CurrentUserUtils"; const path = require('path'); @@ -93,7 +92,7 @@ type PEVt = PEInfo | "none" | "all"; type DROPt = DAInfo | dropActionType; export class DocumentOptions { system?: BOOLt = new BoolInfo("is this a system created/owned doc"); - dropAction?: DROPt = new DAInfo("what should happen to the source document when it's dropped onto this doc "); + _dropAction?: DROPt = new DAInfo("what should happen to this document when it's dropped somewhere else"); childDropAction?: DROPt = new DAInfo("what should happen to the source document when it's dropped onto a child of a collection "); targetDropAction?: DROPt = new DAInfo("what should happen to the source document when ??? "); color?: string; // foreground color data doc @@ -156,9 +155,11 @@ export class DocumentOptions { y?: number; z?: number; // whether document is in overlay (1) or not (0 or undefined) author?: string; - layoutKey?: string; + _layoutKey?: string; type?: string; title?: string; + "acl-Public"?: string; // public permissions + "_acl-Public"?: string; // public permissions version?: string; // version identifier for a document label?: string; hidden?: boolean; @@ -182,7 +183,7 @@ export class DocumentOptions { caption?: RichTextField; opacity?: number; defaultBackgroundColor?: string; - isLinkButton?: boolean; + _isLinkButton?: boolean; // marks a document as a button that will follow its primary link when clicked isFolder?: boolean; lastFrame?: number; // the last frame of a frame-based collection (e.g., progressive slide) activeFrame?: number; // the active frame of a document in a frame base collection @@ -206,9 +207,15 @@ export class DocumentOptions { dockingConfig?: string; annotationOn?: Doc; isPushpin?: boolean; - 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 + _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 iconShape?: string; // shapes of the fonticon border + layout_linkView?: Doc; // view template for a link document linkRelationship?: string; // type of relatinoship a link represents + linkDisplay?: boolean; // whether a link line should be dipslayed between the two link anchors + anchor1?: Doc; + anchor2?: Doc; + "anchor1-useLinkSmallAnchor"?: boolean; // whether anchor1 of a link should use a miniature anchor dot (as when the anchor is a text selection) + "anchor2-useLinkSmallAnchor"?: boolean; // whether anchor1 of a link should use a miniature anchor dot (as when the anchor is a text selection) ignoreClick?: boolean; onClick?: ScriptField; onDoubleClick?: ScriptField; @@ -304,31 +311,31 @@ export namespace Docs { const TemplateMap: TemplateMap = new Map([ [DocumentType.RTF, { layout: { view: FormattedTextBox, dataField: "text" }, - options: { _height: 150, _xMargin: 10, _yMargin: 10 } + options: { _height: 150, _xMargin: 10, _yMargin: 10, links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.SEARCH, { layout: { view: SearchBox, dataField: defaultDataKey }, - options: { _width: 400 } + options: { _width: 400, links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.FILTER, { layout: { view: FilterBox, dataField: defaultDataKey }, - options: { _width: 400 } + options: { _width: 400, links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.COLOR, { layout: { view: ColorBox, dataField: defaultDataKey }, - options: { _nativeWidth: 220, _nativeHeight: 300 } + options: { _nativeWidth: 220, _nativeHeight: 300, links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.IMG, { layout: { view: ImageBox, dataField: defaultDataKey }, - options: {} + options: { links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.WEB, { layout: { view: WebBox, dataField: defaultDataKey }, - options: { _height: 300, _fitWidth: true } + options: { _height: 300, _fitWidth: true, links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.COL, { layout: { view: CollectionView, dataField: defaultDataKey }, - options: { _panX: 0, _panY: 0, _viewScale: 1 } // , _width: 500, _height: 500 } + options: { _panX: 0, _panY: 0, _viewScale: 1, links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.KVP, { layout: { view: KeyValueBox, dataField: defaultDataKey }, @@ -336,15 +343,15 @@ export namespace Docs { }], [DocumentType.VID, { layout: { view: VideoBox, dataField: defaultDataKey }, - options: { _currentTimecode: 0 }, + options: { _currentTimecode: 0, links: ComputedField.MakeFunction("links(self)") as any }, }], [DocumentType.AUDIO, { layout: { view: AudioBox, dataField: defaultDataKey }, - options: { _height: 35, backgroundColor: "lightGray" } + options: { _height: 35, backgroundColor: "lightGray", links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.PDF, { layout: { view: PDFBox, dataField: defaultDataKey }, - options: { _curPage: 1, _fitWidth: true } + options: { _curPage: 1, _fitWidth: true, links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.IMPORT, { layout: { view: DirectoryImportBox, dataField: defaultDataKey }, @@ -352,7 +359,11 @@ export namespace Docs { }], [DocumentType.LINK, { layout: { view: LinkBox, dataField: defaultDataKey }, - options: { _height: 150, description: "" } + options: { + _height: 150, description: "", links: ComputedField.MakeFunction("links(self)") as any, + linkBoxExcludedKeys: new List(["treeViewExpandedView", "aliases", "treeViewHideTitle", "_removeDropProperties", + "linkBoxExcludedKeys", "treeViewOpen", "aliasNumber", "isPrototype", "creationDate", "author"]) + } }], [DocumentType.LINKDB, { data: new List(), @@ -365,53 +376,58 @@ export namespace Docs { options: { childDropAction: "alias", title: "Global Script Database" } }], [DocumentType.SCRIPTING, { - layout: { view: ScriptingBox, dataField: defaultDataKey } + layout: { view: ScriptingBox, dataField: defaultDataKey }, + options: { links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.YOUTUBE, { layout: { view: YoutubeBox, dataField: defaultDataKey } }], [DocumentType.LABEL, { layout: { view: LabelBox, dataField: defaultDataKey }, + options: { links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.EQUATION, { layout: { view: EquationBox, dataField: defaultDataKey }, + options: { links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.FUNCPLOT, { layout: { view: FunctionPlotBox, dataField: defaultDataKey }, + options: { links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.BUTTON, { layout: { view: LabelBox, dataField: "onClick" }, + options: { links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.SLIDER, { layout: { view: SliderBox, dataField: defaultDataKey }, + options: { links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.PRES, { layout: { view: PresBox, dataField: defaultDataKey }, - options: {} + options: { links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.FONTICON, { layout: { view: FontIconBox, dataField: defaultDataKey }, - options: { _width: 40, _height: 40, borderRounding: "100%" }, + options: { _width: 40, _height: 40, borderRounding: "100%", links: ComputedField.MakeFunction("links(self)") as any }, }], - // [DocumentType.RECOMMENDATION, { - // layout: { view: RecommendationsBox, dataField: defaultDataKey }, - // options: { _width: 200, _height: 200 }, - // }], [DocumentType.WEBCAM, { - layout: { view: DashWebRTCVideo, dataField: defaultDataKey } + layout: { view: DashWebRTCVideo, dataField: defaultDataKey }, + options: { links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.PRESELEMENT, { layout: { view: PresElementBox, dataField: defaultDataKey } }], [DocumentType.INK, { layout: { view: InkingStroke, dataField: defaultDataKey }, - options: { _fontFamily: "cursive", backgroundColor: "transparent" } + options: { _fontFamily: "cursive", backgroundColor: "transparent", links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.SCREENSHOT, { layout: { view: ScreenshotBox, dataField: defaultDataKey }, + options: { links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.COMPARISON, { layout: { view: ComparisonBox, dataField: defaultDataKey }, + options: { links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.GROUPDB, { data: new List(), @@ -419,10 +435,12 @@ export namespace Docs { options: { childDropAction: "alias", title: "Global Group Database" } }], [DocumentType.GROUP, { - layout: { view: EmptyBox, dataField: defaultDataKey } + layout: { view: EmptyBox, dataField: defaultDataKey }, + options: { links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.TEXTANCHOR, { - layout: { view: EmptyBox, dataField: defaultDataKey } + layout: { view: EmptyBox, dataField: defaultDataKey }, + options: { links: ComputedField.MakeFunction("links(self)") as any } }] ]); @@ -611,8 +629,6 @@ export namespace Docs { Scripting.addGlobal(Buxton); - const delegateKeys = ["x", "y", "system", "layoutKey", "dropAction", "lockedPosiiton", "childDropAction", "isLinkButton", "removeDropProperties", "treeViewOpen"]; - /** * This function receives the relevant document prototype and uses * it to create a new of that base-level prototype, or the @@ -632,59 +648,33 @@ export namespace Docs { * main document. */ export function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data", protoId?: string) { - const { omit: protoProps, extract: delegateProps } = OmitKeys(options, delegateKeys, "^_"); - - protoProps.system = delegateProps.system; - - if (!("author" in protoProps)) { - protoProps.author = Doc.CurrentUserEmail; - } - - if (!("creationDate" in protoProps)) { - protoProps.creationDate = new DateField; - protoProps[`${fieldKey}-lastModified`] = new DateField; - } - - protoProps.isPrototype = true; - - const dataDoc = MakeDataDelegate(proto, protoProps, data, fieldKey, protoId); - const viewDoc = Doc.MakeDelegate(dataDoc, delegId); - + const viewKeys = ["x", "y", "system"]; + const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, "^_"); + + dataProps.system = viewProps.system; + dataProps.isPrototype = true; + dataProps.author = Doc.CurrentUserEmail; + dataProps.creationDate = new DateField; + dataProps[`${fieldKey}-lastModified`] = new DateField; + dataProps["acl-Override"] = "None"; + dataProps["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add; + dataProps[fieldKey] = data; // so that the list of annotations is already initialised, prevents issues in addonly. // without this, if a doc has no annotations but the user has AddOnly privileges, they won't be able to add an annotation because they would have needed to create the field's list which they don't have permissions to do. + dataProps[fieldKey + "-annotations"] = new List(); + const dataDoc = Doc.assign(Doc.MakeDelegate(proto, protoId), dataProps as any, undefined, true); - dataDoc[fieldKey + "-annotations"] = new List(); - - proto.links = ComputedField.MakeFunction("links(self)"); - - viewDoc.author = Doc.CurrentUserEmail; - viewDoc.type !== DocumentType.LINK && viewDoc.type !== DocumentType.LABEL && DocUtils.MakeLinkToActiveAudio(viewDoc); - - viewDoc["acl-Public"] = dataDoc["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add; - viewDoc["acl-Override"] = dataDoc["acl-Override"] = "None"; + const viewDoc = Doc.MakeDelegate(dataDoc, delegId); + viewProps.author = Doc.CurrentUserEmail; + viewProps.type !== DocumentType.LINK && viewDoc.type !== DocumentType.LABEL && DocUtils.MakeLinkToActiveAudio(viewDoc); + viewProps["acl-Override"] = "None"; + viewProps["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add; + Doc.assign(viewDoc, viewProps, true, true); !Doc.IsSystem(dataDoc) && ![DocumentType.PDFANNO, DocumentType.KVP, DocumentType.LINK, DocumentType.LINKANCHOR, DocumentType.TEXTANCHOR].includes(proto.type as any) && - !dataDoc.isFolder && !protoProps.annotationOn && Doc.AddDocToList(Cast(Doc.UserDoc().myFileOrphans, Doc, null), "data", dataDoc); - - return Doc.assign(viewDoc, delegateProps, true); - } + !dataDoc.isFolder && !dataProps.annotationOn && Doc.AddDocToList(Cast(Doc.UserDoc().myFileOrphans, Doc, null), "data", dataDoc); - /** - * This function receives the relevant top level document prototype - * and models a new instance by delegating from it. - * - * Note that it stores the data it recieves at the delegate's data key, - * and applies any document options to this new delegate / instance. - * @param proto the prototype from which to model this new delegate - * @param options initial values to apply to this new delegate - * @param value the data to store in this new delegate - */ - function MakeDataDelegate(proto: Doc, options: DocumentOptions, value?: D, fieldKey: string = "data", id: string | undefined = undefined) { - const deleg = Doc.MakeDelegate(proto, id); - if (value !== undefined) { - deleg[fieldKey] = value; - } - return Doc.assign(deleg, options as any); + return viewDoc; } export function ImageDocument(url: string, options: DocumentOptions = {}) { @@ -763,24 +753,15 @@ export namespace Docs { } export function LinkDocument(source: { doc: Doc, ctx?: Doc }, target: { doc: Doc, ctx?: Doc }, options: DocumentOptions = {}, id?: string) { - const doc = InstanceFromProto(Prototypes.get(DocumentType.LINK), undefined, { - childDontRegisterViews: true, - isLinkButton: true, treeViewHideTitle: true, backgroundColor: "lightblue", // lightblue is default color for linking dot and link documents text comment area - treeViewExpandedView: "fields", removeDropProperties: new List(["_layerTags", "isLinkButton"]), ...options + const linkDoc = InstanceFromProto(Prototypes.get(DocumentType.LINK), undefined, { + childDontRegisterViews: true, treeViewOpen: true, anchor1: source.doc, anchor2: target.doc, + _isLinkButton: true, treeViewHideTitle: true, backgroundColor: "lightblue", // lightblue is default color for linking dot and link documents text comment area + treeViewExpandedView: "fields", _removeDropProperties: new List(["_layerTags", "isLinkButton"]), ...options }, id); - const linkDocProto = Doc.GetProto(doc); - linkDocProto.treeViewOpen = true;// setting this in the instance creator would set it on the view document. - linkDocProto.anchor1 = source.doc; - linkDocProto.anchor2 = target.doc; - - if (linkDocProto.linkBoxExcludedKeys === undefined) { - Cast(linkDocProto.proto, Doc, null).linkBoxExcludedKeys = new List(["treeViewExpandedView", "aliases", "treeViewHideTitle", "removeDropProperties", "linkBoxExcludedKeys", "treeViewOpen", "aliasNumber", "isPrototype", "creationDate", "author"]); - Cast(linkDocProto.proto, Doc, null).layoutKey = undefined; - } - LinkManager.Instance.addLink(doc); + LinkManager.Instance.addLink(linkDoc); - return doc; + return linkDoc; } export function InkDocument(color: string, tool: string, strokeWidth: string, strokeBezier: string, fillColor: string, arrowStart: string, arrowEnd: string, dash: string, points: { X: number, Y: number }[], options: DocumentOptions = {}) { @@ -1093,42 +1074,46 @@ export namespace DocUtils { if (!allowParCollectionLink && sv?.props.ContainingCollectionDoc === target.doc) return; if (target.doc === Doc.UserDoc()) return undefined; + const makeLink = action((linkDoc: Doc, showPopup?: number[]) => { + if (showPopup) { + LinkManager.currentLink = linkDoc; - const makeLink = action((linkDoc: Doc, showPopup: number[]) => { - LinkManager.currentLink = linkDoc; + TaskCompletionBox.textDisplayed = "Link Created"; + TaskCompletionBox.popupX = showPopup[0]; + TaskCompletionBox.popupY = showPopup[1] - 33; + TaskCompletionBox.taskCompleted = true; - TaskCompletionBox.textDisplayed = "Link Created"; - TaskCompletionBox.popupX = showPopup[0]; - TaskCompletionBox.popupY = showPopup[1] - 33; - TaskCompletionBox.taskCompleted = true; + LinkDescriptionPopup.popupX = showPopup[0]; + LinkDescriptionPopup.popupY = showPopup[1]; + LinkDescriptionPopup.descriptionPopup = true; - LinkDescriptionPopup.popupX = showPopup[0]; - LinkDescriptionPopup.popupY = showPopup[1]; - LinkDescriptionPopup.descriptionPopup = true; + const rect = document.body.getBoundingClientRect(); + if (LinkDescriptionPopup.popupX + 200 > rect.width) { + LinkDescriptionPopup.popupX -= 190; + TaskCompletionBox.popupX -= 40; + } + if (LinkDescriptionPopup.popupY + 100 > rect.height) { + LinkDescriptionPopup.popupY -= 40; + TaskCompletionBox.popupY -= 40; + } - const rect = document.body.getBoundingClientRect(); - if (LinkDescriptionPopup.popupX + 200 > rect.width) { - LinkDescriptionPopup.popupX -= 190; - TaskCompletionBox.popupX -= 40; - } - if (LinkDescriptionPopup.popupY + 100 > rect.height) { - LinkDescriptionPopup.popupY -= 40; - TaskCompletionBox.popupY -= 40; + setTimeout(action(() => TaskCompletionBox.taskCompleted = false), 2500); } - - setTimeout(action(() => TaskCompletionBox.taskCompleted = false), 2500); + return linkDoc; }); - const linkDoc = Docs.Create.LinkDocument(source, target, { linkRelationship, layoutKey: "layout_linkView", description }, id); - Doc.GetProto(linkDoc)["anchor1-useLinkSmallAnchor"] = source.doc.useLinkSmallAnchor; - Doc.GetProto(linkDoc)["anchor2-useLinkSmallAnchor"] = target.doc.useLinkSmallAnchor; - linkDoc.linkDisplay = true; - linkDoc.hidden = true; - Doc.GetProto(linkDoc)["acl-Public"] = linkDoc["acl-Public"] = SharingPermissions.Add; - linkDoc.layout_linkView = Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null); - Doc.GetProto(linkDoc).title = ComputedField.MakeFunction("generateLinkTitle(self)"); - showPopup && makeLink(linkDoc, showPopup); - return linkDoc; + return makeLink(Docs.Create.LinkDocument(source, target, { + title: ComputedField.MakeFunction("generateLinkTitle(self)") as any, + "anchor1-useLinkSmallAnchor": source.doc.useLinkSmallAnchor ? true : undefined, + "anchor2-useLinkSmallAnchor": target.doc.useLinkSmallAnchor ? true : undefined, + "acl-Public": SharingPermissions.Add, + "_acl-Public": SharingPermissions.Add, + layout_linkView: Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null), + linkDisplay: true, hidden: true, + linkRelationship, + _layoutKey: "layout_linkView", + description + }, id), showPopup); } export function DocumentFromField(target: Doc, fieldKey: string, proto?: Doc, options?: DocumentOptions): Doc | undefined { @@ -1357,7 +1342,7 @@ export namespace DocUtils { const pushpin = Docs.Create.FontIconDocument({ title: "pushpin", label: "", annotationOn: Cast(doc.annotationOn, Doc, null), isPushpin: true, icon: "map-pin", x: Cast(doc.x, "number", null), y: Cast(doc.y, "number", null), backgroundColor: "#ACCEF7", - _width: 15, _height: 15, _xPadding: 0, isLinkButton: true, _timecodeToShow: Cast(doc._timecodeToShow, "number", null) + _width: 15, _height: 15, _xPadding: 0, _isLinkButton: true, _timecodeToShow: Cast(doc._timecodeToShow, "number", null) }); Doc.AddDocToList(context, Doc.LayoutFieldKey(context) + "-annotations", pushpin); const pushpinLink = DocUtils.MakeLink({ doc: pushpin }, { doc: doc }, "pushpin", ""); -- cgit v1.2.3-70-g09d2 From 26fc8ca2af1697069eb9ba6128abd013550daf2e Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 18 Mar 2021 01:15:11 -0400 Subject: minor tweaks from last --- src/client/documents/Documents.ts | 85 +++++++--------------- .../views/nodes/formattedText/FormattedTextBox.tsx | 3 +- src/fields/util.ts | 8 +- 3 files changed, 36 insertions(+), 60 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 24409933e..332f7304b 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1,7 +1,7 @@ import { action, runInAction } from "mobx"; import { basename, extname } from "path"; import { DateField } from "../../fields/DateField"; -import { Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym } from "../../fields/Doc"; +import { Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym, Initializing } from "../../fields/Doc"; import { Id } from "../../fields/FieldSymbols"; import { HtmlField } from "../../fields/HtmlField"; import { InkField } from "../../fields/InkField"; @@ -193,6 +193,8 @@ export class DocumentOptions { presProgressivize?: boolean; borderRounding?: string; boxShadow?: string; + data?: any; + baseProto?: boolean; // is this a base prototoype dontRegisterView?: boolean; lookupField?: ScriptField; // script that returns the value of a field. This script is passed the rootDoc, layoutDoc, field, and container of the document. see PresBox. "onDoubleClick-rawScript"?: string; // onDoubleClick script in raw text form @@ -210,6 +212,7 @@ export class DocumentOptions { _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 iconShape?: string; // shapes of the fonticon border layout_linkView?: Doc; // view template for a link document + layout_keyValue?: string; // view tempalte for key value docs linkRelationship?: string; // type of relatinoship a link represents linkDisplay?: boolean; // whether a link line should be dipslayed between the two link anchors anchor1?: Doc; @@ -444,8 +447,6 @@ export namespace Docs { }] ]); - // All document prototypes are initialized with at least these values - const defaultOptions: DocumentOptions = { x: 0, y: 0, _width: 300 }; // bcz: do we really want to set anything here? could also try to set in render() methods for types that need a default const suffix = "Proto"; /** @@ -486,30 +487,22 @@ export namespace Docs { * @param type */ const PrototypeMap: PrototypeMap = new Map(); - export function get(type: DocumentType): Doc { - return PrototypeMap.get(type)!; - } + export function get(type: DocumentType): Doc { return PrototypeMap.get(type)!; } /** * A collection of all links in the database. Ideally, this would be a search, but for now all links are cached here. */ - export function MainLinkDocument() { - return Prototypes.get(DocumentType.LINKDB); - } + export function MainLinkDocument() { return Prototypes.get(DocumentType.LINKDB); } /** * A collection of all scripts in the database */ - export function MainScriptDocument() { - return Prototypes.get(DocumentType.SCRIPTDB); - } + export function MainScriptDocument() { return Prototypes.get(DocumentType.SCRIPTDB); } /** - * A collection of all groups in the database + * A collection of all user acl groups in the database */ - export function MainGroupDocument() { - return Prototypes.get(DocumentType.GROUPDB); - } + export function MainGroupDocument() { return Prototypes.get(DocumentType.GROUPDB); } /** * This is a convenience method that is used to initialize @@ -535,14 +528,12 @@ export namespace Docs { const title = prototypeId.toUpperCase().replace(upper, `_${upper}`); // synthesize the default options, the type and title from computed values and // whatever options pertain to this specific prototype - const options = { title, type, baseProto: true, ...defaultOptions, ...(template.options || {}) }; - options.layout = layout.view?.LayoutString(layout.dataField); - const doc = Doc.assign(new Doc(prototypeId, true), { system: true, layoutKey: "layout", ...options } as any); - doc.data = template.data; - doc.layout_keyValue = KeyValueBox.LayoutString(""); - return doc; + const options: DocumentOptions = { + system: true, _layoutKey: "layout", title, type, baseProto: true, x: 0, y: 0, _width: 300, ...(template.options || {}), + layout: layout.view?.LayoutString(layout.dataField), data: template.data, layout_keyValue: KeyValueBox.LayoutString("") + }; + return Doc.assign(new Doc(prototypeId, true), options as any, undefined, true); } - } /** @@ -648,7 +639,7 @@ export namespace Docs { * main document. */ export function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data", protoId?: string) { - const viewKeys = ["x", "y", "system"]; + const viewKeys = ["x", "y", "system"]; // keys that should be addded to the view document even though they don't begin with an "_" const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, "^_"); dataProps.system = viewProps.system; @@ -664,12 +655,11 @@ export namespace Docs { dataProps[fieldKey + "-annotations"] = new List(); const dataDoc = Doc.assign(Doc.MakeDelegate(proto, protoId), dataProps as any, undefined, true); - const viewDoc = Doc.MakeDelegate(dataDoc, delegId); viewProps.author = Doc.CurrentUserEmail; - viewProps.type !== DocumentType.LINK && viewDoc.type !== DocumentType.LABEL && DocUtils.MakeLinkToActiveAudio(viewDoc); viewProps["acl-Override"] = "None"; viewProps["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add; - Doc.assign(viewDoc, viewProps, true, true); + const viewDoc = Doc.assign(Doc.MakeDelegate(dataDoc, delegId), viewProps, true, true); + viewProps.type !== DocumentType.LINK && viewDoc.type !== DocumentType.LABEL && DocUtils.MakeLinkToActiveAudio(viewDoc); !Doc.IsSystem(dataDoc) && ![DocumentType.PDFANNO, DocumentType.KVP, DocumentType.LINK, DocumentType.LINKANCHOR, DocumentType.TEXTANCHOR].includes(proto.type as any) && !dataDoc.isFolder && !dataProps.annotationOn && Doc.AddDocToList(Cast(Doc.UserDoc().myFileOrphans, Doc, null), "data", dataDoc); @@ -679,22 +669,16 @@ export namespace Docs { export function ImageDocument(url: string, options: DocumentOptions = {}) { const imgField = new ImageField(new URL(url)); - const inst = InstanceFromProto(Prototypes.get(DocumentType.IMG), imgField, { title: path.basename(url), ...options }); - let target = imgField.url.href; - if (new RegExp(window.location.origin).test(target)) { - const extension = path.extname(target); - target = `${target.substring(0, target.length - extension.length)}_o${extension}`; - } - return inst; + return InstanceFromProto(Prototypes.get(DocumentType.IMG), imgField, { title: path.basename(url), ...options }); } + export function PresDocument(initial: List = new List(), options: DocumentOptions = {}) { return InstanceFromProto(Prototypes.get(DocumentType.PRES), initial, options); } export function ScriptingDocument(script: Opt, options: DocumentOptions = {}, fieldKey?: string) { - const res = InstanceFromProto(Prototypes.get(DocumentType.SCRIPTING), script, options); - fieldKey && res.proto instanceof Doc && (res.proto.layout = ScriptingBox.LayoutString(fieldKey)); - return res; + return InstanceFromProto(Prototypes.get(DocumentType.SCRIPTING), script, + { ...options, layout: fieldKey ? ScriptingBox.LayoutString(fieldKey) : undefined }); } export function VideoDocument(url: string, options: DocumentOptions = {}) { @@ -718,9 +702,8 @@ export namespace Docs { } export function AudioDocument(url: string, options: DocumentOptions = {}) { - const instance = InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(new URL(url)), { useLinkSmallAnchor: true, ...options }); // hideLinkButton: false, useLinkSmallAnchor: false, - Doc.GetProto(instance).backgroundColor = ComputedField.MakeFunction("this._audioState === 'playing' ? 'green':'gray'"); - return instance; + return InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(new URL(url)), + { useLinkSmallAnchor: true, ...options, backgroundColor: ComputedField.MakeFunction("this._audioState === 'playing' ? 'green':'gray'") as any }); // hideLinkButton: false, useLinkSmallAnchor: false, } export function SearchDocument(options: DocumentOptions = {}) { @@ -766,6 +749,7 @@ export namespace Docs { export function InkDocument(color: string, tool: string, strokeWidth: string, strokeBezier: string, fillColor: string, arrowStart: string, arrowEnd: string, dash: string, points: { X: number, Y: number }[], options: DocumentOptions = {}) { const I = new Doc(); + I[Initializing] = true; I.type = DocumentType.INK; I.layout = InkingStroke.LayoutString("data"); I.color = color; @@ -788,20 +772,16 @@ export namespace Docs { I.data = new InkField(points); I["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add; I["acl-Override"] = "None"; + I[Initializing] = false; return I; } export function PdfDocument(url: string, options: DocumentOptions = {}) { - const pdfProto = Prototypes.get(DocumentType.PDF); - pdfProto._fitWidth = true; // backward compatibility -- can be removed after db is reset - return InstanceFromProto(pdfProto, new PdfField(new URL(url)), { ...options }); + return InstanceFromProto(Prototypes.get(DocumentType.PDF), new PdfField(new URL(url)), { ...options }); } export function WebDocument(url: string, options: DocumentOptions = {}) { - const webProto = Prototypes.get(DocumentType.WEB); - webProto.scrollHeight = 100000; // backward compatibility -- can be removed after db is reset - webProto._fitWidth = true; // backward compatibility -- can be removed after db is reset - return InstanceFromProto(webProto, url ? new WebField(new URL(url)) : undefined, { _chromeStatus: url ? undefined : "enabled", _lockedTransform: true, ...options }); + return InstanceFromProto(Prototypes.get(DocumentType.WEB), url ? new WebField(new URL(url)) : undefined, { _chromeStatus: url ? undefined : "enabled", _lockedTransform: true, ...options }); } export function HtmlDocument(html: string, options: DocumentOptions = {}) { @@ -861,7 +841,6 @@ export namespace Docs { 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", ...options, _viewType: CollectionViewType.Masonry }); } @@ -879,11 +858,6 @@ export namespace Docs { } export function ButtonDocument(options?: DocumentOptions) { - // const btn = InstanceFromProto(Prototypes.get(DocumentType.BUTTON), undefined, { ...(options || {}), "onClick-rawScript": "-script-" }); - // btn.layoutKey = "layout_onClick"; - // btn.height = 250; - // btn.width = 200; - // btn.layout_onClick = ScriptingBox.LayoutString("onClick"); return InstanceFromProto(Prototypes.get(DocumentType.BUTTON), undefined, { ...(options || {}), "onClick-rawScript": "-script-" }); } @@ -891,7 +865,6 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.SLIDER), undefined, { ...(options || {}) }); } - export function FontIconDocument(options?: DocumentOptions) { return InstanceFromProto(Prototypes.get(DocumentType.FONTICON), undefined, { hideLinkButton: true, ...(options || {}) }); } @@ -904,11 +877,9 @@ export namespace Docs { } export function DockDocument(documents: Array, config: string, options: DocumentOptions, id?: string) { - const inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { freezeChildren: "remove|add", treeViewDefaultExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id); const tabs = TreeDocument(documents, { title: "On-Screen Tabs", freezeChildren: "remove|add", treeViewLockExpandedView: true, treeViewDefaultExpandedView: "data", _fitWidth: true, system: true }); const all = TreeDocument([], { title: "Off-Screen Tabs", freezeChildren: "add", treeViewLockExpandedView: true, treeViewDefaultExpandedView: "data", system: true }); - Doc.GetProto(inst).data = new List([tabs, all]); - return inst; + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", treeViewDefaultExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id); } export function DirectoryImportDocument(options: DocumentOptions = {}) { diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index d64db1ee1..d44867541 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -667,7 +667,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const splitter = state.schema.marks.splitter.create({ id: Utils.GenerateGuid() }); let tr = state.tr.addMark(sel.from, sel.to, splitter); if (sel.from !== sel.to) { - const anchor = anchorDoc ?? Docs.Create.TextanchorDocument(); + const anchor = anchorDoc ?? Docs.Create.TextanchorDocument({ title: this._editorView?.state.doc.textBetween(sel.from, sel.to) }); const href = targetHref ?? Utils.prepend("/doc/" + anchor[Id]); if (anchor !== anchorDoc) this.addDocument(anchor); tr.doc.nodesBetween(sel.from, sel.to, (node: any, pos: number, parent: any) => { @@ -681,7 +681,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this.dataDoc[ForceServerWrite] = this.dataDoc[UpdatingFromServer] = true; // need to allow permissions for adding links to readonly/augment only documents this._editorView!.dispatch(tr.removeMark(sel.from, sel.to, splitter)); this.dataDoc[UpdatingFromServer] = this.dataDoc[ForceServerWrite] = false; - Doc.GetProto(anchor).title = this._editorView?.state.doc.textBetween(sel.from, sel.to); return anchor; } return anchorDoc ?? this.rootDoc; diff --git a/src/fields/util.ts b/src/fields/util.ts index 36604c790..86f68ea6e 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -98,7 +98,10 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number } !receiver[Initializing] && (!receiver[UpdatingFromServer] || receiver[ForceServerWrite]) && UndoManager.AddEvent({ redo: () => receiver[prop] = value, - undo: () => receiver[prop] = curValue + undo: () => { + // console.log("Undo: " + prop + " = " + curValue); // bcz: uncomment to log undo + receiver[prop] = curValue + } }); return true; } @@ -380,6 +383,7 @@ export function updateFunction(target: any, prop: any, value: any, receiver: any lastValue = ObjectField.MakeCopy(receiver[prop]); }, undo: action(() => { + // console.log("undo $add: " + prop, diff.items) // bcz: uncomment to log undo diff.items.forEach((item: any) => { const ind = receiver[prop].indexOf(item.value ? item.value() : item); ind !== -1 && receiver[prop].splice(ind, 1); @@ -397,6 +401,7 @@ export function updateFunction(target: any, prop: any, value: any, receiver: any lastValue = ObjectField.MakeCopy(receiver[prop]); }), undo: () => { + // console.log("undo $rem: " + prop, diff.items) // bcz: uncomment to log undo diff.items.forEach((item: any) => { const ind = (prevValue as List).indexOf(item.value ? item.value() : item); ind !== -1 && receiver[prop].indexOf(item.value ? item.value() : item) === -1 && receiver[prop].splice(ind, 0, item); @@ -410,6 +415,7 @@ export function updateFunction(target: any, prop: any, value: any, receiver: any lastValue = ObjectField.MakeCopy(receiver[prop]); }, undo: () => { + // console.log("undo list: " + prop, receiver[prop]) // bcz: uncomment to log undo receiver[prop] = ObjectField.MakeCopy(prevValue as List); lastValue = ObjectField.MakeCopy(receiver[prop]); } -- cgit v1.2.3-70-g09d2 From ed83093961b7e19df4675c9e2cf0a78eae333614 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 18 Mar 2021 11:31:20 -0400 Subject: made linkanchorbuttons not show up next to pdf annos. gave pdfannos a baseProto. made textboxes dynamically remove hashtags when deleted from text. --- src/client/documents/Documents.ts | 7 +++++++ src/client/views/DocumentButtonBar.tsx | 22 +++++++++++++++++----- src/client/views/MarqueeAnnotator.tsx | 2 +- src/client/views/StyleProvider.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 4 ++-- .../views/nodes/formattedText/FormattedTextBox.tsx | 12 ++++++++++++ 6 files changed, 40 insertions(+), 9 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 332f7304b..a2850fd98 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -420,6 +420,10 @@ export namespace Docs { [DocumentType.PRESELEMENT, { layout: { view: PresElementBox, dataField: defaultDataKey } }], + [DocumentType.PDFANNO, { + layout: { view: CollectionView, dataField: defaultDataKey }, + options: { hideLinkButton: true } + }], [DocumentType.INK, { layout: { view: InkingStroke, dataField: defaultDataKey }, options: { _fontFamily: "cursive", backgroundColor: "transparent", links: ComputedField.MakeFunction("links(self)") as any } @@ -801,6 +805,9 @@ export namespace Docs { documents.map(d => d.context = inst); return inst; } + export function PdfAnnoDocument(documents: Array, options: DocumentOptions, id?: string) { + return InstanceFromProto(Prototypes.get(DocumentType.PDFANNO), 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", _noAutoscroll: true, ...options, _viewType: CollectionViewType.Pile }, id); diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 4a1ec4d6c..07b419e5f 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -184,6 +184,18 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV ; } @computed + get followLinkButton() { + const targetDoc = this.view0?.props.Document; + return !targetDoc ? (null) : {"follow primary link on click"}}> +
this.props.views().map(view => view?.docView?.toggleFollowLink(undefined, false, false)))}> + +
+
; + } + @computed get pinButton() { const targetDoc = this.view0?.props.Document; return !targetDoc ? (null) : (DocumentV const presPinWithViewIcon = ; const targetDoc = this.view0?.props.Document; return !targetDoc ? (null) :
{"Pin with current view"}
}> -
this.pinWithView(targetDoc)}> +
this.pinWithView(targetDoc)}> {presPinWithViewIcon}
; @@ -244,8 +254,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV const targetDoc = this.view0?.props.Document; return !targetDoc ? (null) :
{"Open Sharing Manager"}
}>
SharingManager.Instance.open(this.view0, targetDoc)}> - +
; } @@ -357,6 +366,9 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
{this.contextButton}
*/} + {!SelectionManager.Views()?.some(v => v.allLinks.length) ? (null) :
+ {this.followLinkButton} +
}
{this.pinButton}
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx index 2e50c9b6d..046f327fc 100644 --- a/src/client/views/MarqueeAnnotator.tsx +++ b/src/client/views/MarqueeAnnotator.tsx @@ -114,7 +114,7 @@ export class MarqueeAnnotator extends React.Component { return marqueeAnno; } - const textRegionAnno = Docs.Create.FreeformDocument([], { type: DocumentType.PDFANNO, annotationOn: this.props.rootDoc, title: "Selection on " + this.props.rootDoc.title, _width: 1, _height: 1 }); + const textRegionAnno = Docs.Create.PdfAnnoDocument([], { annotationOn: this.props.rootDoc, title: "Selection on " + this.props.rootDoc.title, _width: 1, _height: 1 }); let maxX = -Number.MAX_VALUE; let minY = Number.MAX_VALUE; const annoDocs: Doc[] = []; diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index d9ab0d397..5cbbcce79 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -74,7 +74,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt - {this.layoutDoc.hideAllLinks ? (null) : this.allAnchors} + {this.layoutDoc.hideAllLinks ? (null) : this.allLinkEndpoints} {this.hideLinkButton ? (null) : } @@ -808,7 +808,7 @@ export class DocumentViewInternal extends DocComponent { + if (node.type === schema.nodes.dashField && node.attrs.fieldKey.startsWith("#")) { + accumTags.push(node.attrs.fieldKey) + } + }); + const curTags = Object.keys(this.dataDoc).filter(key => key.startsWith("#")); + const added = accumTags.filter(tag => !curTags.includes(tag)); + const removed = curTags.filter(tag => !accumTags.includes(tag)); + removed.forEach(r => this.dataDoc[r] = undefined); + added.forEach(a => this.dataDoc[a] = a); + let unchanged = true; if (this._applyingChange !== this.fieldKey && removeSelection(json) !== removeSelection(curProto?.Data)) { this._applyingChange = this.fieldKey; -- cgit v1.2.3-70-g09d2 From f692e63595bf7492178cc55de41808595bbe73e2 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 18 Mar 2021 11:36:35 -0400 Subject: from last --- src/client/documents/Documents.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index a2850fd98..44747ebaf 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -422,7 +422,7 @@ export namespace Docs { }], [DocumentType.PDFANNO, { layout: { view: CollectionView, dataField: defaultDataKey }, - options: { hideLinkButton: true } + options: { links: ComputedField.MakeFunction("links(self)") as any, hideLinkButton: true } }], [DocumentType.INK, { layout: { view: InkingStroke, dataField: defaultDataKey }, -- cgit v1.2.3-70-g09d2 From ee53c138015fcf232e424b61a4a9e5521e49ada9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 18 Mar 2021 14:36:33 -0400 Subject: extended Doc.setFilter to allow replacing/appending a filter. fixed anchor unhighlighting in WebBox. reorged some properties on baseProtos (usLInkSmallAnchor etc) --- src/client/documents/Documents.ts | 6 ++--- src/client/util/DocumentManager.ts | 5 +++- src/client/views/DocComponent.tsx | 6 +++-- src/client/views/DocumentButtonBar.tsx | 2 +- src/client/views/StyleProvider.tsx | 2 +- .../views/collections/CollectionTimeView.tsx | 2 -- .../collectionFreeForm/CollectionFreeFormView.tsx | 10 ++------ src/client/views/nodes/FunctionPlotBox.tsx | 6 +---- src/client/views/nodes/PDFBox.tsx | 4 +-- src/client/views/nodes/WebBox.tsx | 30 ++++++++++++---------- src/client/views/pdf/PDFViewer.tsx | 4 +-- src/fields/Doc.ts | 7 +++-- 12 files changed, 38 insertions(+), 46 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 44747ebaf..89071f75b 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -411,7 +411,7 @@ export namespace Docs { }], [DocumentType.FONTICON, { layout: { view: FontIconBox, dataField: defaultDataKey }, - options: { _width: 40, _height: 40, borderRounding: "100%", links: ComputedField.MakeFunction("links(self)") as any }, + options: { hideLinkButton: true, _width: 40, _height: 40, borderRounding: "100%", links: ComputedField.MakeFunction("links(self)") as any }, }], [DocumentType.WEBCAM, { layout: { view: DashWebRTCVideo, dataField: defaultDataKey }, @@ -447,7 +447,7 @@ export namespace Docs { }], [DocumentType.TEXTANCHOR, { layout: { view: EmptyBox, dataField: defaultDataKey }, - options: { links: ComputedField.MakeFunction("links(self)") as any } + options: { links: ComputedField.MakeFunction("links(self)") as any, useSmallLinkButton: true, hideLinkButton: true } }] ]); @@ -873,7 +873,7 @@ export namespace Docs { } export function FontIconDocument(options?: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.FONTICON), undefined, { hideLinkButton: true, ...(options || {}) }); + return InstanceFromProto(Prototypes.get(DocumentType.FONTICON), undefined, { ...(options || {}) }); } export function FilterDocument(options?: DocumentOptions) { return InstanceFromProto(Prototypes.get(DocumentType.FILTER), undefined, { ...(options || {}) }); diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 8cb80ecf9..34ff03335 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -229,7 +229,10 @@ export class DocumentManager { } Scripting.addGlobal(function DocFocusOrOpen(doc: any) { const dv = DocumentManager.Instance.getDocumentView(doc); - if (dv && dv?.props.Document === doc) dv.props.focus(doc, { willZoom: true }); + if (dv && dv.props.Document === doc) { + dv.props.focus(doc, { willZoom: true }); + Doc.linkFollowHighlight(dv?.props.Document, false); + } else { const context = doc.context !== Doc.UserDoc().myFilesystem && Cast(doc.context, Doc, null); const showDoc = context || doc; diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 876fbac54..86396dc4d 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -203,8 +203,10 @@ export function ViewBoxAnnotatableComponent

this.props.whenActiveChanged(this._isChildActive = isActive)); active = (outsideReaction?: boolean) => (CurrentUserUtils.SelectedTool === InkTool.None && - (this.props.rootSelected(outsideReaction) || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0 || BoolCast((this.layoutDoc as any).forceActive)) ? true : false) - annotationsActive = (outsideReaction?: boolean) => (CurrentUserUtils.SelectedTool !== InkTool.None || (this.props.layerProvider?.(this.props.Document) === false && this.props.active()) || + (this.props.rootSelected(outsideReaction) || + this.props.Document.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false) + annotationsActive = (outsideReaction?: boolean) => (CurrentUserUtils.SelectedTool !== InkTool.None || + (this.props.layerProvider?.(this.props.Document) === false && this.props.active()) || (this.props.Document.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false) } return Component; diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 07b419e5f..e248ef39a 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -214,7 +214,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV if (targetDoc) { TabDocView.PinDoc(targetDoc); const activeDoc = PresBox.Instance.childDocs[PresBox.Instance.childDocs.length - 1]; - const scrollable: boolean = (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking); + const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(targetDoc.type as any) || targetDoc._viewType === CollectionViewType.Stacking; const pannable: boolean = ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG); if (scrollable) { const scroll = targetDoc._scrollTop; diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 5cbbcce79..1ee99817c 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -74,7 +74,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt doc) { getAnchor = () => { const anchor = Docs.Create.TextanchorDocument({ title: ComputedField.MakeFunction(`"${this.pivotField}"])`) as any, - useLinkSmallAnchor: true, - hideLinkButton: true, annotationOn: this.rootDoc }); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 57dba0f75..c82baf691 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -921,7 +921,7 @@ export class CollectionFreeFormView extends CollectionSubView { - const anchor = Docs.Create.TextanchorDocument({ - title: StrCast(this.layoutDoc._viewType), - useLinkSmallAnchor: true, - hideLinkButton: true, - annotationOn: this.rootDoc - }); + const anchor = Docs.Create.TextanchorDocument({ title: StrCast(this.layoutDoc._viewType), annotationOn: this.rootDoc }); const proto = Doc.GetProto(anchor); proto[ViewSpecPrefix + "_viewType"] = this.layoutDoc._viewType; proto.docFilters = ObjectField.MakeCopy(this.layoutDoc.docFilters as ObjectField) || new List([]); diff --git a/src/client/views/nodes/FunctionPlotBox.tsx b/src/client/views/nodes/FunctionPlotBox.tsx index e8bec9676..4be7d1c37 100644 --- a/src/client/views/nodes/FunctionPlotBox.tsx +++ b/src/client/views/nodes/FunctionPlotBox.tsx @@ -37,11 +37,7 @@ export class FunctionPlotBox extends ViewBoxBaseComponent this.createGraph()); } getAnchor = () => { - const anchor = Docs.Create.TextanchorDocument({ - useLinkSmallAnchor: true, - hideLinkButton: true, - annotationOn: this.rootDoc - }); + const anchor = Docs.Create.TextanchorDocument({ annotationOn: this.rootDoc }); anchor.xRange = new List(Array.from(this._plot.options.xAxis.domain)); anchor.yRange = new List(Array.from(this._plot.options.yAxis.domain)); return anchor; diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 0dbe0c917..d9c0fab02 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -101,8 +101,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent { const anchor = Docs.Create.TextanchorDocument({ title: StrCast(this.rootDoc.title + " " + this.layoutDoc._scrollTop), - useLinkSmallAnchor: true, - hideLinkButton: true, annotationOn: this.rootDoc, y: NumCast(this.layoutDoc._scrollTop), }); @@ -144,7 +142,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent { const active = StrListCast(this.rootDoc[this.sidebarKey() + "-docFilters"]).includes(`${tag}:${tag}:check`); return

Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey())}> + onClick={e => Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey(), e.shiftKey)}> {tag}
; } diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index ed412ad99..78bd6cbf6 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -205,8 +205,6 @@ export class WebBox extends ViewBoxAnnotatableComponent { const anchor = Docs.Create.TextanchorDocument({ title: StrCast(this.rootDoc.title + " " + this.layoutDoc._scrollTop), - useLinkSmallAnchor: true, - hideLinkButton: true, annotationOn: this.rootDoc, y: NumCast(this.layoutDoc._scrollTop), }); @@ -455,7 +453,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { const active = StrListCast(this.rootDoc[this.sidebarKey() + "-docFilters"]).includes(`${tag}:${tag}:check`); return
Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey())}> + onClick={e => Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey(), e.shiftKey)}> {tag}
; } @@ -541,7 +539,7 @@ export class WebBox extends ViewBoxAnnotatableComponent +
@@ -563,22 +561,26 @@ export class WebBox extends ViewBoxAnnotatableComponent {this.content} + CollectionView={undefined} + ScreenToLocalTransform={this.scrollXf} + renderDepth={this.props.renderDepth + 1} + scaling={returnOne} + //pointerEvents={this._isAnnotating || SnappingManager.GetIsDragging() ? "all" : "none"} + childPointerEvents={true} /> {this.annotationLayer}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 68b1452f8..0a46b2120 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -532,13 +532,13 @@ export class PDFViewer extends ViewBoxAnnotatableComponent + renderDepth={this.props.renderDepth + 1} + childPointerEvents={true} />
; } @computed get pdfViewerDiv() { diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 5bc770c15..953d96ffa 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -13,7 +13,6 @@ import { CollectionDockingView } from "../client/views/collections/CollectionDoc import { intersectRect, Utils } from "../Utils"; import { DateField } from "./DateField"; import { Copy, HandleUpdate, Id, OnUpdate, Parent, Self, SelfProxy, ToScriptString, ToString, Update } from "./FieldSymbols"; -import { InkTool } from "./InkField"; import { List } from "./List"; import { ObjectField } from "./ObjectField"; import { PrefetchProxy, ProxyField } from "./Proxy"; @@ -25,7 +24,6 @@ import { Cast, FieldValue, NumCast, StrCast, ToConstructor } from "./Types"; import { AudioField, ImageField, PdfField, VideoField, WebField } from "./URLField"; import { deleteProperty, GetEffectiveAcl, getField, getter, makeEditable, makeReadOnly, normalizeEmail, setter, SharingPermissions, updateFunction } from "./util"; import JSZip = require("jszip"); -import { prefix } from "@fortawesome/free-regular-svg-icons"; export namespace Field { export function toKeyValueString(doc: Doc, key: string): string { @@ -1069,9 +1067,9 @@ export namespace Doc { // filters document in a container collection: // all documents with the specified value for the specified key are included/excluded // based on the modifiers :"check", "x", undefined - export function setDocFilter(target: Opt, key: string, value: any, modifiers: "remove" | "match" | "check" | "x", toggle?: boolean, fieldSuffix?: string) { + export function setDocFilter(target: Opt, key: string, value: any, modifiers: "remove" | "match" | "check" | "x", toggle?: boolean, fieldPrefix?: string, append: boolean = true) { const container = target ?? CollectionDockingView.Instance.props.Document; - const filterField = "_" + (fieldSuffix ? fieldSuffix + "-" : "") + "docFilters"; + const filterField = "_" + (fieldPrefix ? fieldPrefix + "-" : "") + "docFilters"; const docFilters = Cast(container[filterField], listSpec("string"), []); runInAction(() => { for (let i = 0; i < docFilters.length; i++) { @@ -1089,6 +1087,7 @@ export namespace Doc { if (!docFilters.length && modifiers === "match" && value === undefined) { container[filterField] = undefined; } else if (modifiers !== "remove") { + !append && (docFilters.length = 0); docFilters.push(key + ":" + value + ":" + modifiers); container[filterField] = new List(docFilters); } -- cgit v1.2.3-70-g09d2 From 5845674720497f87c5ccada7a188817f3c912c6e Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 18 Mar 2021 15:42:13 -0400 Subject: preparing to break sidebar out into its own component --- src/client/documents/Documents.ts | 2 +- src/client/views/nodes/PDFBox.tsx | 52 ++++---- src/client/views/nodes/WebBox.tsx | 258 ++++++++++++++++++-------------------- 3 files changed, 152 insertions(+), 160 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 89071f75b..86ca50316 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -642,7 +642,7 @@ export namespace Docs { * only when creating a DockDocument from the current user's already existing * main document. */ - export function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data", protoId?: string) { + function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data", protoId?: string) { const viewKeys = ["x", "y", "system"]; // keys that should be addded to the view document even though they don't begin with an "_" const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, "^_"); diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index d9c0fab02..37341253d 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -38,7 +38,7 @@ const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema); export class PDFBox extends ViewBoxAnnotatableComponent(PdfDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PDFBox, fieldKey); } private _searchString: string = ""; - private _initialScale: number = 0; // the initial scale of the PDF when first rendered which determines whether the document will be live on startup or not. Getting bigger after startup won't make it automatically be live. + private _initialScrollTarget: Opt; private _displayPdfLive = false; // has this box ever had its contents activated -- if so, stop drawing the overlay title private _pdfViewer: PDFViewer | undefined; private _searchRef = React.createRef(); @@ -50,7 +50,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent; + componentWillUnmount() { this._selectReactionDisposer?.(); } + componentDidMount() { + this.props.setContentView?.(this); + this._selectReactionDisposer = reaction(() => this.props.isSelected(), + () => { + document.removeEventListener("keydown", this.onKeyDown); + this.props.isSelected(true) && document.addEventListener("keydown", this.onKeyDown); + }, { fireImmediately: true }); + } + scrollFocus = (doc: Doc, smooth: boolean) => { if (DocListCast(this.rootDoc[this.sidebarKey()]).includes(doc)) { if (this.layoutDoc["_" + this.sidebarKey() + "-docFilters"]) { @@ -95,7 +103,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent { @@ -107,15 +115,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent this.props.isSelected(), - () => { - document.removeEventListener("keydown", this.onKeyDown); - this.props.isSelected(true) && document.addEventListener("keydown", this.onKeyDown); - }, { fireImmediately: true }); - } @action loaded = (nw: number, nh: number, np: number) => { @@ -125,6 +124,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent this.fieldKey + "-sidebar"; sidebarFiltersHeight = () => 50; sidebarTransform = () => this.props.ScreenToLocalTransform().translate(Doc.NativeWidth(this.dataDoc), 0).scale(this.props.scaling?.() || 1); @@ -134,19 +134,19 @@ export class PDFBox extends ViewBoxAnnotatableComponent boolean) => this.moveDocument(doc, targetCollection, addDocument, this.sidebarKey()); sidebarRemDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, this.sidebarKey()); sidebarDocFilters = () => [...StrListCast(this.layoutDoc._docFilters), ...StrListCast(this.layoutDoc[this.sidebarKey() + "-docFilters"])]; - @computed get allTags() { + @computed get sidebarAllTags() { const keys = new Set(); DocListCast(this.rootDoc[this.sidebarKey()]).forEach(doc => SearchBox.documentKeys(doc).forEach(key => keys.add(key))); return Array.from(keys.keys()).filter(key => key[0]).filter(key => !key.startsWith("_") && (key[0] === "#" || key[0] === key[0].toUpperCase())).sort(); } - renderTag = (tag: string) => { - const active = StrListCast(this.rootDoc[this.sidebarKey() + "-docFilters"]).includes(`${tag}:${tag}:check`); - return
Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey(), e.shiftKey)}> - {tag} -
; - } @computed get sidebarOverlay() { + const renderTag = (tag: string) => { + const active = StrListCast(this.rootDoc[this.sidebarKey() + "-docFilters"]).includes(`${tag}:${tag}:check`); + return
Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey(), e.shiftKey)}> + {tag} +
; + } return !this.layoutDoc._showSidebar ? (null) :
- {this.allTags.map(tag => this.renderTag(tag))} + {this.sidebarAllTags.map(renderTag)}
; } @@ -217,9 +217,9 @@ export class PDFBox extends ViewBoxAnnotatableComponent { this._pdfViewer = pdfViewer; - if (this.initialScrollTarget) { - this.scrollFocus(this.initialScrollTarget, false); - this.initialScrollTarget = undefined; + if (this._initialScrollTarget) { + this.scrollFocus(this._initialScrollTarget, false); + this._initialScrollTarget = undefined; } } searchStringChanged = (e: React.ChangeEvent) => this._searchString = e.currentTarget.value; @@ -303,7 +303,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent target[tag] = tag); + this.sidebarAllTags.map(tag => target[tag] = tag); DocUtils.MakeLink({ doc: anchor }, { doc: target }, "inline markup", "annotation"); this.sidebarAddDocument(target); } diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 78bd6cbf6..df50f7b90 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -44,15 +44,15 @@ const WebDocument = makeInterface(documentSchema); @observer export class WebBox extends ViewBoxAnnotatableComponent(WebDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(WebBox, fieldKey); } + private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean) => void); private _mainCont: React.RefObject = React.createRef(); private _outerRef: React.RefObject = React.createRef(); private _disposers: { [name: string]: IReactionDisposer } = {}; private _annotationLayer: React.RefObject = React.createRef(); private _keyInput = React.createRef(); - @observable _scrollTimer: any; - @observable private _overlayAnnoInfo: Opt; private _initialScroll: Opt; - private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean) => void); + @observable private _scrollTimer: any; + @observable private _overlayAnnoInfo: Opt; @observable private _marqueeing: number[] | undefined; @observable private _url: string = "hello"; @observable private _isAnnotating = false; @@ -60,11 +60,13 @@ export class WebBox extends ViewBoxAnnotatableComponent(); @observable private _scrollHeight = 1500; @computed get scrollHeight() { return this._scrollHeight; } + @computed get allAnnotations() { return DocListCast(this.dataDoc[this.annotationKey]); } @computed get inlineTextAnnotations() { return this.allAnnotations.filter(a => a.textInlineAnnotations); } + @computed get webField() { return Cast(this.dataDoc[this.props.fieldKey], WebField)?.url; } constructor(props: any) { super(props); - if (this.dataDoc[this.fieldKey] instanceof WebField) { + if (this.webField) { Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(this.dataDoc) || 850); Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(this.dataDoc) || this.Document[HeightSym]() / this.Document[WidthSym]() * 850); } @@ -74,6 +76,58 @@ export class WebBox extends ViewBoxAnnotatableComponent this._url = this.webField?.toString() || ""); + + this._disposers.selection = reaction(() => this.props.isSelected(), + selected => !selected && setTimeout(() => { + Array.from(this._savedAnnotations.values()).forEach(v => v.forEach(a => a.remove())); + this._savedAnnotations.clear(); + })); + + if (this.webField?.href.indexOf("youtube") !== -1) { + const youtubeaspect = 400 / 315; + const nativeWidth = Doc.NativeWidth(this.layoutDoc); + const nativeHeight = Doc.NativeHeight(this.layoutDoc); + if (this.webField) { + if (!nativeWidth || !nativeHeight || Math.abs(nativeWidth / nativeHeight - youtubeaspect) > 0.05) { + if (!nativeWidth) Doc.SetNativeWidth(this.layoutDoc, 600); + Doc.SetNativeHeight(this.layoutDoc, (nativeWidth || 600) / youtubeaspect); + this.layoutDoc._height = this.layoutDoc[WidthSym]() / youtubeaspect; + } + } // else it's an HTMLfield + } else if (this.webField && !this.dataDoc.text) { + const result = await WebRequest.get(Utils.CorsProxy(this.webField.href)); + if (result) { + this.dataDoc.text = htmlToText.fromString(result.content); + } + } + + var quickScroll = true; + this._disposers.scrollReaction = reaction(() => NumCast(this.layoutDoc._scrollTop), + (scrollTop) => { + if (quickScroll) { + this._initialScroll = scrollTop; + } + else { + const viewTrans = StrCast(this.Document._viewTransition); + const durationMiliStr = viewTrans.match(/([0-9]*)ms/); + const durationSecStr = viewTrans.match(/([0-9.]*)s/); + const duration = durationMiliStr ? Number(durationMiliStr[1]) : durationSecStr ? Number(durationSecStr[1]) * 1000 : 0; + this.goTo(scrollTop, duration); + } + }, + { fireImmediately: true } + ); + quickScroll = false; + } + componentWillUnmount() { + Object.values(this._disposers).forEach(disposer => disposer?.()); + this._iframe?.removeEventListener('wheel', this.iframeWheel, true); + } + @action createTextAnnotation = (sel: Selection, selRange: Range) => { if (this._mainCont.current) { @@ -102,6 +156,32 @@ export class WebBox extends ViewBoxAnnotatableComponent this.urlEditor; // controls to be added to the top bar when a document of this type is selected + + scrollFocus = (doc: Doc, smooth: boolean) => { + if (doc !== this.rootDoc && this._outerRef.current) { + const scrollTo = doc.type === DocumentType.TEXTANCHOR ? NumCast(doc.y) : Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.layoutDoc._scrollTop), this.props.PanelHeight() / (this.props.scaling?.() || 1)); + if (scrollTo !== undefined) { + const focusSpeed = smooth ? 500 : 0; + this._initialScroll !== undefined && (this._initialScroll = scrollTo); + this.goTo(scrollTo, focusSpeed); + return focusSpeed; + } + } + this._initialScroll = NumCast(doc.y); + return 0; + } + + getAnchor = () => { + const anchor = Docs.Create.TextanchorDocument({ + title: StrCast(this.rootDoc.title + " " + this.layoutDoc._scrollTop), + annotationOn: this.rootDoc, + y: NumCast(this.layoutDoc._scrollTop), + }); + this.addDocument(anchor); + return anchor; + } + @action iframeUp = (e: PointerEvent) => { if (this._iframe?.contentWindow && this._iframe.contentDocument && !this._iframe.contentWindow.getSelection()?.isCollapsed) { @@ -151,8 +231,8 @@ export class WebBox extends ViewBoxAnnotatableComponent { + if (!this._scrollTimer) { + this._scrollTimer = setTimeout(action(() => this._scrollTimer = undefined), 250); // this turns events off on the iframe which allows scrolling to change direction smoothly + } + } + @action setDashScrollTop = (scrollTop: number, timeout: number = 250) => { const iframeHeight = Math.max(1000, this._scrollHeight - this.panelHeight()); @@ -177,90 +264,6 @@ export class WebBox extends ViewBoxAnnotatableComponent { - if (!this._scrollTimer) { - this._scrollTimer = setTimeout(action(() => this._scrollTimer = undefined), 250); // this turns events off on the iframe which allows scrolling to change direction smoothly - } - } - onWheel = (e: any) => { - e.stopPropagation(); - e.preventDefault(); - } - onScroll = (e: any) => this.setDashScrollTop(this._outerRef.current?.scrollTop || 0); - scrollFocus = (doc: Doc, smooth: boolean) => { - if (doc !== this.rootDoc && this._outerRef.current) { - const scrollTo = doc.type === DocumentType.TEXTANCHOR ? NumCast(doc.y) : Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.layoutDoc._scrollTop), this.props.PanelHeight() / (this.props.scaling?.() || 1)); - if (scrollTo !== undefined) { - const focusSpeed = smooth ? 500 : 0; - this._initialScroll !== undefined && (this._initialScroll = scrollTo); - this.goTo(scrollTo, focusSpeed); - return focusSpeed; - } - } - this._initialScroll = NumCast(doc.y); - return 0; - } - - getAnchor = () => { - const anchor = Docs.Create.TextanchorDocument({ - title: StrCast(this.rootDoc.title + " " + this.layoutDoc._scrollTop), - annotationOn: this.rootDoc, - y: NumCast(this.layoutDoc._scrollTop), - }); - this.addDocument(anchor); - return anchor; - } - - async componentDidMount() { - this.props.setContentView?.(this); // this tells the DocumentView that this AudioBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link. - - const urlField = Cast(this.dataDoc[this.props.fieldKey], WebField); - runInAction(() => this._url = urlField?.url.toString() || ""); - - this._disposers.selection = reaction(() => this.props.isSelected(), - selected => !selected && setTimeout(() => { - Array.from(this._savedAnnotations.values()).forEach(v => v.forEach(a => a.remove())); - this._savedAnnotations.clear(); - })); - - const field = Cast(this.rootDoc[this.props.fieldKey], WebField); - if (field?.url.href.indexOf("youtube") !== -1) { - const youtubeaspect = 400 / 315; - const nativeWidth = Doc.NativeWidth(this.layoutDoc); - const nativeHeight = Doc.NativeHeight(this.layoutDoc); - if (field) { - if (!nativeWidth || !nativeHeight || Math.abs(nativeWidth / nativeHeight - youtubeaspect) > 0.05) { - if (!nativeWidth) Doc.SetNativeWidth(this.layoutDoc, 600); - Doc.SetNativeHeight(this.layoutDoc, (nativeWidth || 600) / youtubeaspect); - this.layoutDoc._height = this.layoutDoc[WidthSym]() / youtubeaspect; - } - } // else it's an HTMLfield - } else if (field?.url && !this.dataDoc.text) { - const result = await WebRequest.get(Utils.CorsProxy(field.url.href)); - if (result) { - this.dataDoc.text = htmlToText.fromString(result.content); - } - } - - var quickScroll = true; - this._disposers.scrollReaction = reaction(() => NumCast(this.layoutDoc._scrollTop), - (scrollTop) => { - if (quickScroll) { - this._initialScroll = scrollTop; - } - else { - const viewTrans = StrCast(this.Document._viewTransition); - const durationMiliStr = viewTrans.match(/([0-9]*)ms/); - const durationSecStr = viewTrans.match(/([0-9.]*)s/); - const duration = durationMiliStr ? Number(durationMiliStr[1]) : durationSecStr ? Number(durationSecStr[1]) * 1000 : 0; - this.goTo(scrollTop, duration); - } - }, - { fireImmediately: true } - ); - quickScroll = false; - } goTo = (scrollTop: number, duration: number) => { if (this._outerRef.current) { @@ -275,11 +278,6 @@ export class WebBox extends ViewBoxAnnotatableComponent disposer?.()); - this._iframe?.removeEventListener('wheel', this.iframeWheel, true); - } - @action forward = () => { const future = Cast(this.dataDoc[this.fieldKey + "-future"], listSpec("string"), null); @@ -312,12 +310,13 @@ export class WebBox extends ViewBoxAnnotatableComponent { + submitURL = (newUrl?: string) => { + if (!newUrl) return; if (!newUrl.startsWith("http")) newUrl = "http://" + newUrl; try { const future = Cast(this.dataDoc[this.fieldKey + "-future"], listSpec("string"), null); const history = Cast(this.dataDoc[this.fieldKey + "-history"], listSpec("string"), null); - const url = Cast(this.dataDoc[this.fieldKey], WebField, null)?.url.toString(); + const url = this.webField?.toString(); if (url) { if (history === undefined) { this.dataDoc[this.fieldKey + "-history"] = new List([url]); @@ -336,7 +335,6 @@ export class WebBox extends ViewBoxAnnotatableComponent this.urlEditor; onWebUrlDrop = (e: React.DragEvent) => { const { dataTransfer } = e; const html = dataTransfer.getData("text/html"); @@ -371,12 +369,8 @@ export class WebBox extends ViewBoxAnnotatableComponent this.submitURL(this._keyInput.current!.value)} onDragOver={e => e.stopPropagation()} onDrop={this.onWebUrlDrop}> GO - - + + ); @@ -391,6 +385,19 @@ export class WebBox extends ViewBoxAnnotatableComponent { + if (!e.altKey && e.button === 0 && this.active(true)) { + this._marqueeing = [e.clientX, e.clientY]; + this.props.select(false); + } + } + @action finishMarquee = (x?: number, y?: number) => { + this._marqueeing = undefined; + this._isAnnotating = false; + x !== undefined && y !== undefined && this._setPreviewCursor?.(x, y, false); + } + @computed get urlContent() { const field = this.dataDoc[this.props.fieldKey]; @@ -424,7 +431,7 @@ export class WebBox extends ViewBoxAnnotatableComponent target[tag] = tag); + this.sidebarAllTags.map(tag => target[tag] = tag); DocUtils.MakeLink({ doc: anchor }, { doc: target }, "inline markup", "annotation"); this.sidebarAddDocument(target); } @@ -445,19 +452,19 @@ export class WebBox extends ViewBoxAnnotatableComponent boolean) => this.moveDocument(doc, targetCollection, addDocument, this.sidebarKey()); sidebarRemDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, this.sidebarKey()); sidebarDocFilters = () => [...StrListCast(this.layoutDoc._docFilters), ...StrListCast(this.layoutDoc[this.sidebarKey() + "-docFilters"])]; - @computed get allTags() { + @computed get sidebarAllTags() { const keys = new Set(); DocListCast(this.rootDoc[this.sidebarKey()]).forEach(doc => SearchBox.documentKeys(doc).forEach(key => keys.add(key))); return Array.from(keys.keys()).filter(key => key[0]).filter(key => !key.startsWith("_") && (key[0] === "#" || key[0] === key[0].toUpperCase())).sort(); } - renderTag = (tag: string) => { - const active = StrListCast(this.rootDoc[this.sidebarKey() + "-docFilters"]).includes(`${tag}:${tag}:check`); - return
Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey(), e.shiftKey)}> - {tag} -
; - } @computed get sidebarOverlay() { + const renderTag = (tag: string) => { + const active = StrListCast(this.rootDoc[this.sidebarKey() + "-docFilters"]).includes(`${tag}:${tag}:check`); + return
Doc.setDocFilter(this.rootDoc, tag, tag, "check", true, this.sidebarKey(), e.shiftKey)}> + {tag} +
; + } return !this.layoutDoc._showSidebar ? (null) :
- {this.allTags.map(tag => this.renderTag(tag))} + {this.sidebarAllTags.map(renderTag)}
; } - @computed - get content() { + @computed get content() { return
{this.urlContent}
; } - showInfo = action((anno: Opt) => this._overlayAnnoInfo = anno); - @computed get allAnnotations() { return DocListCast(this.dataDoc[this.annotationKey]); } @computed get annotationLayer() { TraceMobx(); return
@@ -518,20 +522,8 @@ export class WebBox extends ViewBoxAnnotatableComponent; } - @action - onMarqueeDown = (e: React.PointerEvent) => { - if (!e.altKey && e.button === 0 && this.active(true)) { - this._marqueeing = [e.clientX, e.clientY]; - this.props.select(false); - } - } + showInfo = action((anno: Opt) => this._overlayAnnoInfo = anno); setPreviewCursor = (func?: (x: number, y: number, drag: boolean) => void) => this._setPreviewCursor = func; - @action finishMarquee = (x?: number, y?: number) => { - this._marqueeing = undefined; - this._isAnnotating = false; - x !== undefined && y !== undefined && this._setPreviewCursor?.(x, y, false); - } - panelWidth = () => this.props.PanelWidth() / (this.props.scaling?.() || 1) - this.sidebarWidth(); // (this.Document.scrollHeight || Doc.NativeHeight(this.Document) || 0); panelHeight = () => this.props.PanelHeight() / (this.props.scaling?.() || 1); // () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document); scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._scrollTop)); @@ -551,8 +543,8 @@ export class WebBox extends ViewBoxAnnotatableComponent { e.stopPropagation(); e.preventDefault(); }} // block wheel events from propagating since they're handled by the iframe + onScroll={e => this.setDashScrollTop(this._outerRef.current?.scrollTop || 0)} onPointerDown={this.onMarqueeDown} >
Date: Thu, 18 Mar 2021 23:20:30 -0400 Subject: renamed pdfanno to htmlAnchor --- src/client/documents/DocumentTypes.ts | 2 +- src/client/documents/Documents.ts | 8 ++++---- src/client/views/MarqueeAnnotator.tsx | 2 +- src/client/views/pdf/Annotation.scss | 2 +- src/client/views/pdf/Annotation.tsx | 2 +- src/client/views/pdf/PDFViewer.tsx | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 851e78336..8565784b4 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -18,7 +18,7 @@ export enum DocumentType { LABEL = "label", // simple text label BUTTON = "button", // onClick button WEBCAM = "webcam", // webcam - PDFANNO = "pdfanno", // pdf text selection (could be just a collection?) + HTMLANCHOR = "htmlanchor", // text selection anchor in PDF/Web DATE = "date", // calendar view of a date SCRIPTING = "script", // script editor EQUATION = "equation", // equation editor diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 86ca50316..91369d325 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -420,7 +420,7 @@ export namespace Docs { [DocumentType.PRESELEMENT, { layout: { view: PresElementBox, dataField: defaultDataKey } }], - [DocumentType.PDFANNO, { + [DocumentType.HTMLANCHOR, { layout: { view: CollectionView, dataField: defaultDataKey }, options: { links: ComputedField.MakeFunction("links(self)") as any, hideLinkButton: true } }], @@ -665,7 +665,7 @@ export namespace Docs { const viewDoc = Doc.assign(Doc.MakeDelegate(dataDoc, delegId), viewProps, true, true); viewProps.type !== DocumentType.LINK && viewDoc.type !== DocumentType.LABEL && DocUtils.MakeLinkToActiveAudio(viewDoc); - !Doc.IsSystem(dataDoc) && ![DocumentType.PDFANNO, DocumentType.KVP, DocumentType.LINK, DocumentType.LINKANCHOR, DocumentType.TEXTANCHOR].includes(proto.type as any) && + !Doc.IsSystem(dataDoc) && ![DocumentType.HTMLANCHOR, DocumentType.KVP, DocumentType.LINK, DocumentType.LINKANCHOR, DocumentType.TEXTANCHOR].includes(proto.type as any) && !dataDoc.isFolder && !dataProps.annotationOn && Doc.AddDocToList(Cast(Doc.UserDoc().myFileOrphans, Doc, null), "data", dataDoc); return viewDoc; @@ -805,8 +805,8 @@ export namespace Docs { documents.map(d => d.context = inst); return inst; } - export function PdfAnnoDocument(documents: Array, options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.PDFANNO), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Freeform }, id); + export function HTMLAnchorDocument(documents: Array, options: DocumentOptions, id?: string) { + return InstanceFromProto(Prototypes.get(DocumentType.HTMLANCHOR), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Freeform }, id); } export function PileDocument(documents: Array, options: DocumentOptions, id?: string) { diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx index 046f327fc..d59ed7770 100644 --- a/src/client/views/MarqueeAnnotator.tsx +++ b/src/client/views/MarqueeAnnotator.tsx @@ -114,7 +114,7 @@ export class MarqueeAnnotator extends React.Component { return marqueeAnno; } - const textRegionAnno = Docs.Create.PdfAnnoDocument([], { annotationOn: this.props.rootDoc, title: "Selection on " + this.props.rootDoc.title, _width: 1, _height: 1 }); + const textRegionAnno = Docs.Create.HTMLAnchorDocument([], { annotationOn: this.props.rootDoc, title: "Selection on " + this.props.rootDoc.title, _width: 1, _height: 1 }); let maxX = -Number.MAX_VALUE; let minY = Number.MAX_VALUE; const annoDocs: Doc[] = []; diff --git a/src/client/views/pdf/Annotation.scss b/src/client/views/pdf/Annotation.scss index 8b242854d..e98f071c3 100644 --- a/src/client/views/pdf/Annotation.scss +++ b/src/client/views/pdf/Annotation.scss @@ -1,4 +1,4 @@ -.pdfAnnotation { +.htmlAnnotation { pointer-events: all; user-select: none; position: absolute; diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index 1e574b9c0..07b734405 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -89,7 +89,7 @@ class RegionAnnotation extends React.Component { } render() { - return (
this.props.showInfo(this.props.anno)} onPointerLeave={() => this.props.showInfo(undefined)} onPointerDown={this.onPointerDown} ref={this._mainCont} + return (
this.props.showInfo(this.props.anno)} onPointerLeave={() => this.props.showInfo(undefined)} onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ left: NumCast(this.props.document.x), top: NumCast(this.props.document.y), diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 163336e3e..84006f722 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -391,7 +391,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent v.forEach(a => a.remove())); this._savedAnnotations.clear(); - this._styleRule = addStyleSheetRule(PDFViewer._annotationStyle, "pdfAnnotation", { "pointer-events": "none" }); + this._styleRule = addStyleSheetRule(PDFViewer._annotationStyle, "htmlAnnotation", { "pointer-events": "none" }); document.addEventListener("pointerup", this.onSelectEnd); document.addEventListener("pointermove", this.onSelectMove); } -- cgit v1.2.3-70-g09d2 From e8ef90478cec13d45de0fe42e32a594e2630c47d Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 19 Mar 2021 10:35:57 -0400 Subject: fixing up some baseProto initialization. fixing stacking view with hidden docs. --- src/client/documents/Documents.ts | 56 +++++++++++----------- src/client/util/CurrentUserUtils.ts | 28 ++++++----- .../util/Import & Export/DirectoryImportBox.tsx | 1 + src/client/views/PropertiesButtons.tsx | 4 +- src/client/views/TemplateMenu.tsx | 2 +- .../views/collections/CollectionPileView.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/KeyValueBox.tsx | 2 +- 10 files changed, 54 insertions(+), 47 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 91369d325..f4657d824 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -338,11 +338,11 @@ export namespace Docs { }], [DocumentType.COL, { layout: { view: CollectionView, dataField: defaultDataKey }, - options: { _panX: 0, _panY: 0, _viewScale: 1, links: ComputedField.MakeFunction("links(self)") as any } + options: { _chromeStatus: "collapsed", _fitWidth: true, _panX: 0, _panY: 0, _viewScale: 1, links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.KVP, { layout: { view: KeyValueBox, dataField: defaultDataKey }, - options: { _height: 150 } + options: { _fitWidth: true, _height: 150 } }], [DocumentType.VID, { layout: { view: VideoBox, dataField: defaultDataKey }, @@ -363,7 +363,11 @@ export namespace Docs { [DocumentType.LINK, { layout: { view: LinkBox, dataField: defaultDataKey }, options: { - _height: 150, description: "", links: ComputedField.MakeFunction("links(self)") as any, + childDontRegisterViews: true, _isLinkButton: true, treeViewHideTitle: true, + treeViewOpen: true, _height: 150, description: "", + backgroundColor: "lightblue", // lightblue is default color for linking dot and link documents text comment area + treeViewExpandedView: "fields", _removeDropProperties: new List(["_layerTags", "isLinkButton"]), + links: ComputedField.MakeFunction("links(self)") as any, linkBoxExcludedKeys: new List(["treeViewExpandedView", "aliases", "treeViewHideTitle", "_removeDropProperties", "linkBoxExcludedKeys", "treeViewOpen", "aliasNumber", "isPrototype", "creationDate", "author"]) } @@ -434,7 +438,7 @@ export namespace Docs { }], [DocumentType.COMPARISON, { layout: { view: ComparisonBox, dataField: defaultDataKey }, - options: { links: ComputedField.MakeFunction("links(self)") as any } + options: { clipWidth: 50, backgroundColor: "gray", targetDropAction: "alias", links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.GROUPDB, { data: new List(), @@ -447,7 +451,7 @@ export namespace Docs { }], [DocumentType.TEXTANCHOR, { layout: { view: EmptyBox, dataField: defaultDataKey }, - options: { links: ComputedField.MakeFunction("links(self)") as any, useSmallLinkButton: true, hideLinkButton: true } + options: { targetDropAction: "move", links: ComputedField.MakeFunction("links(self)") as any, hideLinkButton: true } }] ]); @@ -702,12 +706,12 @@ export namespace Docs { } export function ComparisonDocument(options: DocumentOptions = { title: "Comparison Box" }) { - return InstanceFromProto(Prototypes.get(DocumentType.COMPARISON), "", { clipWidth: 50, backgroundColor: "gray", targetDropAction: "alias", ...options }); + return InstanceFromProto(Prototypes.get(DocumentType.COMPARISON), "", options); } export function AudioDocument(url: string, options: DocumentOptions = {}) { return InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(new URL(url)), - { useLinkSmallAnchor: true, ...options, backgroundColor: ComputedField.MakeFunction("this._audioState === 'playing' ? 'green':'gray'") as any }); // hideLinkButton: false, useLinkSmallAnchor: false, + { ...options, backgroundColor: ComputedField.MakeFunction("this._audioState === 'playing' ? 'green':'gray'") as any }); } export function SearchDocument(options: DocumentOptions = {}) { @@ -741,9 +745,7 @@ export namespace Docs { export function LinkDocument(source: { doc: Doc, ctx?: Doc }, target: { doc: Doc, ctx?: Doc }, options: DocumentOptions = {}, id?: string) { const linkDoc = InstanceFromProto(Prototypes.get(DocumentType.LINK), undefined, { - childDontRegisterViews: true, treeViewOpen: true, anchor1: source.doc, anchor2: target.doc, - _isLinkButton: true, treeViewHideTitle: true, backgroundColor: "lightblue", // lightblue is default color for linking dot and link documents text comment area - treeViewExpandedView: "fields", _removeDropProperties: new List(["_layerTags", "isLinkButton"]), ...options + anchor1: source.doc, anchor2: target.doc, ...options }, id); LinkManager.Instance.addLink(linkDoc); @@ -781,11 +783,11 @@ export namespace Docs { } export function PdfDocument(url: string, options: DocumentOptions = {}) { - return InstanceFromProto(Prototypes.get(DocumentType.PDF), new PdfField(new URL(url)), { ...options }); + return InstanceFromProto(Prototypes.get(DocumentType.PDF), new PdfField(new URL(url)), options); } export function WebDocument(url: string, options: DocumentOptions = {}) { - return InstanceFromProto(Prototypes.get(DocumentType.WEB), url ? new WebField(new URL(url)) : undefined, { _chromeStatus: url ? undefined : "enabled", _lockedTransform: true, ...options }); + return InstanceFromProto(Prototypes.get(DocumentType.WEB), url ? new WebField(new URL(url)) : undefined, options); } export function HtmlDocument(html: string, options: DocumentOptions = {}) { @@ -793,63 +795,63 @@ export namespace Docs { } export function KVPDocument(document: Doc, options: DocumentOptions = {}) { - return InstanceFromProto(Prototypes.get(DocumentType.KVP), document, { _fitWidth: true, title: document.title + ".kvp", ...options }); + return InstanceFromProto(Prototypes.get(DocumentType.KVP), document, { title: document.title + ".kvp", ...options }); } export function TextanchorDocument(options: DocumentOptions = {}, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.TEXTANCHOR), undefined, { targetDropAction: "move", ...options }, id); + return InstanceFromProto(Prototypes.get(DocumentType.TEXTANCHOR), undefined, options, id); } export function FreeformDocument(documents: Array, options: DocumentOptions, id?: string) { - const inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Freeform }, id); + const inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Freeform }, id); documents.map(d => d.context = inst); return inst; } export function HTMLAnchorDocument(documents: Array, options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.HTMLANCHOR), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Freeform }, id); + return InstanceFromProto(Prototypes.get(DocumentType.HTMLANCHOR), new List(documents), options, id); } export function PileDocument(documents: Array, options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", backgroundColor: "black", _noAutoscroll: true, ...options, _viewType: CollectionViewType.Pile }, id); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _noAutoscroll: true, ...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", ...options, _viewType: CollectionViewType.Linear }, id); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Linear }, id); } export function MapDocument(documents: Array, options: DocumentOptions = {}) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), options); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Map }); } export function CarouselDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", _fitWidth: true, ...options, _viewType: CollectionViewType.Carousel }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Carousel }); } export function Carousel3DDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", _fitWidth: true, ...options, _viewType: CollectionViewType.Carousel3D }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Carousel3D }); } export function SchemaDocument(schemaHeaders: SchemaHeaderField[], documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", _fitWidth: true, schemaHeaders: schemaHeaders.length ? new List(schemaHeaders) : undefined, ...options, _viewType: CollectionViewType.Schema }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaHeaders: new List(schemaHeaders), ...options, _viewType: CollectionViewType.Schema }); } export function TreeDocument(documents: Array, options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", _fitWidth: true, childDontRegisterViews: true, ...options, _viewType: CollectionViewType.Tree }, id); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { childDontRegisterViews: true, ...options, _viewType: CollectionViewType.Tree }, id); } export function StackingDocument(documents: Array, options: DocumentOptions, id?: string, protoId?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", _fitWidth: true, ...options, _viewType: CollectionViewType.Stacking }, id, undefined, protoId); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Stacking }, id, undefined, protoId); } export function MulticolumnDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Multicolumn }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Multicolumn }); } export function MultirowDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Multirow }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Multirow }); } export function MasonryDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Masonry }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Masonry }); } export function LabelDocument(options?: DocumentOptions) { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index d7ab3564c..fc70a6282 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -203,7 +203,7 @@ export class CurrentUserUtils { new SchemaHeaderField("[Long Description]", "dimGray", undefined, undefined, undefined, true), new SchemaHeaderField("[Details]", "dimGray", undefined, undefined, undefined, true), ]); - const detailView = Docs.Create.StackingDocument([carousel, descriptionWrapper], { ...shared, ...detailViewOpts, system: true }); + const detailView = Docs.Create.StackingDocument([carousel, descriptionWrapper], { ...shared, ...detailViewOpts, _chromeStatus: "", system: true }); detailView.isTemplateDoc = makeTemplate(detailView); details.title = "Details"; @@ -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", + title: "Advanced Item Prototypes", _xMargin: 0, _showTitle: "title", _chromeStatus: "", hidden: ComputedField.MakeFunction("IsNoviceMode()") as any, _stayInCollection: true, _hideContextMenu: true, _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 35, ignoreClick: true, _lockedPosition: true, @@ -492,13 +492,13 @@ export class CurrentUserUtils { _stayInCollection: true, dragFactory, clickFactory, - hidden: noviceMode ? ComputedField.MakeFunction("IsNoviceMode()") as any : undefined, + hidden: !noviceMode ? ComputedField.MakeFunction("IsNoviceMode()") as any : undefined, system: true, })); if (dragCreatorSet === undefined) { doc.myItemCreators = new PrefetchProxy(Docs.Create.MasonryDocument(creatorBtns, { - title: "Basic Item Creators", _showTitle: "title", _xMargin: 0, _stayInCollection: true, _hideContextMenu: true, + title: "Basic Item Creators", _showTitle: "title", _xMargin: 0, _stayInCollection: true, _hideContextMenu: true, _chromeStatus: "", _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 35, ignoreClick: true, _lockedPosition: true, dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), system: true })); @@ -559,6 +559,7 @@ export class CurrentUserUtils { doc.menuStack = new PrefetchProxy(Docs.Create.StackingDocument(menuBtns, { title: "menuItemPanel", childDropAction: "alias", + _chromeStatus: "", dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), backgroundColor: "black", ignoreClick: true, _gridGap: 0, @@ -596,7 +597,7 @@ export class CurrentUserUtils { // Sets up mobileMenu stacking document static setupMobileMenu() { const menu = new PrefetchProxy(Docs.Create.StackingDocument(this.setupMobileButtons(), { - _width: 980, ignoreClick: true, _lockedPosition: false, title: "home", _yMargin: 100, system: true + _width: 980, ignoreClick: true, _lockedPosition: false, title: "home", _yMargin: 100, system: true, _chromeStatus: "" })); return menu; } @@ -693,10 +694,10 @@ export class CurrentUserUtils { title: "Upload Images From the Web", _chromeStatus: "enabled", _lockedPosition: true, system: true }); const uploadDoc = Docs.Create.StackingDocument([], { - title: "Mobile Upload Collection", backgroundColor: "white", _lockedPosition: true, system: true + title: "Mobile Upload Collection", backgroundColor: "white", _lockedPosition: true, system: true, _chromeStatus: "" }); return Docs.Create.StackingDocument([webDoc, uploadDoc], { - _width: screen.width, _lockedPosition: true, title: "Upload", _autoHeight: true, _yMargin: 80, backgroundColor: "lightgray", system: true + _width: screen.width, _lockedPosition: true, title: "Upload", _autoHeight: true, _yMargin: 80, backgroundColor: "lightgray", system: true, _chromeStatus: "" }); } @@ -716,7 +717,8 @@ export class CurrentUserUtils { if (doc.myCreators === undefined) { doc.myCreators = new PrefetchProxy(Docs.Create.StackingDocument([creatorBtns, templateBtns], { title: "all Creators", _yMargin: 0, _autoHeight: true, _xMargin: 0, _fitWidth: true, - _width: 500, _height: 300, ignoreClick: true, _lockedPosition: true, system: true + _width: 500, _height: 300, ignoreClick: true, _lockedPosition: true, system: true, + _chromeStatus: "" })); } // setup a color picker @@ -729,7 +731,8 @@ export class CurrentUserUtils { if (doc.myTools === undefined) { const toolsStack = new PrefetchProxy(Docs.Create.StackingDocument([doc.myCreators as Doc, doc.myColorPicker as Doc], { - title: "My Tools", _width: 500, _yMargin: 20, ignoreClick: true, _lockedPosition: true, _forceActive: true, system: true, _stayInCollection: true, _hideContextMenu: true, + title: "My Tools", _width: 500, _yMargin: 20, ignoreClick: true, _lockedPosition: true, _forceActive: true, + system: true, _stayInCollection: true, _hideContextMenu: true, _chromeStatus: "" })) as any as Doc; doc.myTools = toolsStack; @@ -907,7 +910,8 @@ export class CurrentUserUtils { if (!sharedDocs) { sharedDocs = Docs.Create.StackingDocument([], { title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "none", childLimitHeight: 0, _yMargin: 50, _gridGap: 15, - _showTitle: "title", ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Add, "_acl-Public": SharingPermissions.Add + _showTitle: "title", ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Add, "_acl-Public": SharingPermissions.Add, + _chromeStatus: "" }, sharingDocumentId + "outer", sharingDocumentId); } if (sharedDocs instanceof Doc) { @@ -922,13 +926,13 @@ export class CurrentUserUtils { if (doc.myImportDocs === undefined) { doc.myImportDocs = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "My ImportDocuments", _forceActive: true, ignoreClick: true, _showTitle: "title", _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0, - childDropAction: "alias", _autoHeight: true, _yMargin: 50, _gridGap: 15, _lockedPosition: true, system: true + childDropAction: "alias", _autoHeight: true, _yMargin: 50, _gridGap: 15, _lockedPosition: true, system: true, _chromeStatus: "" })); } if (doc.myImportPanel === undefined) { const uploads = Cast(doc.myImportDocs, Doc, null); const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Import External document", _stayInCollection: true, _hideContextMenu: true, title: "Import", icon: "upload", system: true }); - doc.myImportPanel = new PrefetchProxy(Docs.Create.StackingDocument([newUpload, uploads], { title: "My ImportPanel", _yMargin: 20, ignoreClick: true, _stayInCollection: true, _hideContextMenu: true, _lockedPosition: true, system: true })); + doc.myImportPanel = new PrefetchProxy(Docs.Create.StackingDocument([newUpload, uploads], { title: "My ImportPanel", _yMargin: 20, ignoreClick: true, _chromeStatus: "", _stayInCollection: true, _hideContextMenu: true, _lockedPosition: true, system: true })); } } diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx index d9f010557..244e96599 100644 --- a/src/client/util/Import & Export/DirectoryImportBox.tsx +++ b/src/client/util/Import & Export/DirectoryImportBox.tsx @@ -145,6 +145,7 @@ export class DirectoryImportBox extends React.Component { title: `Import of ${directory}`, _width: 1105, _height: 500, + _chromeStatus: "", x: NumCast(doc.x), y: NumCast(doc.y) + offset }; diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 7a83295c7..9afcdc28d 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -32,7 +32,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { propertyToggleBtn = (label: string, property: string, tooltip: (on?: any) => string, icon: (on: boolean) => string, onClick?: (dv: Opt, doc: Doc, property: string) => void) => { const targetDoc = this.selectedDoc; - const onPropToggle = (dv: Opt, doc: Doc, prop: string) => (dv?.layoutDoc || doc)[prop] = (dv?.layoutDoc || doc)[prop] ? undefined : true; + const onPropToggle = (dv: Opt, doc: Doc, prop: string) => (dv?.layoutDoc || doc)[prop] = (dv?.layoutDoc || doc)[prop] ? false : true; return !targetDoc ? (null) : {tooltip(targetDoc?.[property])}
} placement="top">
@@ -74,7 +74,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { return this.propertyToggleBtn("Caption", "_showCaption", on => `${on ? "Hide" : "Show"} caption footer`, on => "closed-captioning", (dv, doc) => (dv?.rootDoc || doc)._showCaption = (dv?.rootDoc || doc)._showCaption === undefined ? "caption" : undefined); } @computed get chromeButton() { - return this.propertyToggleBtn("Controls", "_chromeStatus", on => `${on === "enabled" ? "Hide" : "Show"} editing UI`, on => "edit", (dv, doc) => (dv?.rootDoc || doc)._chromeStatus = (dv?.rootDoc || doc)._chromeStatus === undefined ? "enabled" : undefined); + return this.propertyToggleBtn("Controls", "_chromeStatus", on => `${on === "enabled" ? "Hide" : "Show"} editing UI`, on => "edit", (dv, doc) => (dv?.rootDoc || doc)._chromeStatus = !(dv?.rootDoc || doc)._chromeStatus ? "enabled" : ""); } @computed get titleButton() { return this.propertyToggleBtn("Title", "_showTitle", on => "Switch between title styles", on => "text-width", (dv, doc) => (dv?.rootDoc || doc)._showTitle = !(dv?.rootDoc || doc)._showTitle ? "title" : (dv?.rootDoc || doc)._showTitle === "title" ? "title:hover" : undefined); diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 23d8baeaf..3a329c7d9 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -81,7 +81,7 @@ export class TemplateMenu extends React.Component { @action toggleChrome = (): void => { this.props.docViews.map(dv => Doc.Layout(dv.layoutDoc)).forEach(layout => - layout._chromeStatus = (layout._chromeStatus ? undefined : StrCast(layout._replacedChrome, "enabled"))); + layout._chromeStatus = (layout._chromeStatus ? "" : StrCast(layout._replacedChrome, "enabled"))); } // todo: add brushes to brushMap to save with a style name diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx index 22b5c2b2a..7998b3277 100644 --- a/src/client/views/collections/CollectionPileView.tsx +++ b/src/client/views/collections/CollectionPileView.tsx @@ -21,7 +21,7 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { this.Document._pileLayoutEngine = "pass"; } this._originalChrome = StrCast(this.layoutDoc._chromeStatus); - this.layoutDoc._chromeStatus = undefined; + this.layoutDoc._chromeStatus = ""; } componentWillUnmount() { this.layoutDoc._chromeStatus = this._originalChrome; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 8128c18d7..2324c0eb4 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -74,7 +74,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: const { Document, DataDoc } = this.props; const validPairs = this.childDocs.map(doc => Doc.GetLayoutDataDocPair(Document, !this.props.isAnnotationOverlay ? DataDoc : undefined, doc)). filter(pair => { // filter out any documents that have a proto that we don't have permissions to (which we determine by not having any keys - return pair.layout && (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate));// Object.keys(pair.layout.proto).length)); + return pair.layout && !pair.layout.hidden && (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate));// Object.keys(pair.layout.proto).length)); }); return validPairs.map(({ data, layout }) => ({ data: data as Doc, layout: layout! })); // this mapping is a bit of a hack to coerce types } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index c82baf691..f0d99611a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1239,7 +1239,7 @@ export class CollectionFreeFormView extends CollectionSubView SharingManager.Instance.open(this.props.DocumentView()), icon: "users" }); if (!Doc.UserDoc().noviceMode) { moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" }); - moreItems.push({ description: `${this.Document._chromeStatus ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus ? undefined : "enabled"), icon: "project-diagram" }); + moreItems.push({ description: `${this.Document._chromeStatus ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus ? "" : "enabled"), icon: "project-diagram" }); if (Cast(Doc.GetProto(this.props.Document).data, listSpec(Doc))) { moreItems.push({ description: "Export to Google Photos Album", event: () => GooglePhotos.Export.CollectionToAlbum({ collection: this.props.Document }).then(console.log), icon: "caret-square-right" }); diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 383650e89..f27c2c6a7 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -163,7 +163,7 @@ export class KeyValueBox extends React.Component { } getTemplate = async () => { - const parent = Docs.Create.StackingDocument([], { _width: 800, _height: 800, title: "Template" }); + const parent = Docs.Create.StackingDocument([], { _width: 800, _height: 800, title: "Template", _chromeStatus: "" }); parent._columnWidth = 100; for (const row of this.rows.filter(row => row.isChecked)) { await this.createTemplateField(parent, row); -- cgit v1.2.3-70-g09d2 From 3e2709a68e32650074e2bbc9af89fa0d66536d77 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 19 Mar 2021 13:54:45 -0400 Subject: simplified chromeStatus to chromeHidden. fixed presBox item widths. fixed colorBox layout. --- src/client/documents/Documents.ts | 4 +- src/client/util/CurrentUserUtils.ts | 32 +++++------ .../util/Import & Export/DirectoryImportBox.tsx | 2 +- src/client/views/MainView.tsx | 4 +- src/client/views/PropertiesButtons.tsx | 5 +- src/client/views/SidebarAnnos.tsx | 1 - src/client/views/TemplateMenu.tsx | 7 +-- .../views/collections/CollectionCarousel3DView.tsx | 2 +- .../views/collections/CollectionCarouselView.tsx | 2 +- .../collections/CollectionMasonryViewFieldRow.tsx | 9 ++- .../views/collections/CollectionPileView.tsx | 10 ++-- .../views/collections/CollectionStackingView.tsx | 31 +++++------ .../CollectionStackingViewFieldColumn.tsx | 9 ++- .../views/collections/CollectionTimeView.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 1 + src/client/views/collections/SchemaTable.tsx | 3 +- src/client/views/nodes/ColorBox.scss | 1 - src/client/views/nodes/ColorBox.tsx | 65 ++++++++++------------ src/client/views/nodes/DocumentView.tsx | 16 +++--- src/client/views/nodes/KeyValueBox.tsx | 2 +- src/client/views/nodes/PresBox.tsx | 6 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 1 - src/fields/documentSchemas.ts | 2 - src/fields/util.ts | 6 -- 24 files changed, 98 insertions(+), 125 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f4657d824..366275b6e 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -119,7 +119,7 @@ export class DocumentOptions { _showCaption?: string; // which field to display in the caption area. leave empty to have no caption _scrollTop?: number; // scroll location for pdfs _noAutoscroll?: boolean;// whether collections autoscroll when this item is dragged - _chromeStatus?: string; + _chromeHidden?: boolean; // whether the editing chrome for a document is hidden _layerTags?: List; // layer tags a document has (used for tab filtering "layers" in document tab) _searchDoc?: boolean; // is this a search document (used to change UI for search results in schema view) _forceActive?: boolean; // flag to handle pointer events when not selected (or otherwise active) @@ -338,7 +338,7 @@ export namespace Docs { }], [DocumentType.COL, { layout: { view: CollectionView, dataField: defaultDataKey }, - options: { _chromeStatus: "collapsed", _fitWidth: true, _panX: 0, _panY: 0, _viewScale: 1, links: ComputedField.MakeFunction("links(self)") as any } + options: { _fitWidth: true, _panX: 0, _panY: 0, _viewScale: 1, links: ComputedField.MakeFunction("links(self)") as any } }], [DocumentType.KVP, { layout: { view: KeyValueBox, dataField: defaultDataKey }, diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index fc70a6282..05e560f51 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -203,7 +203,7 @@ export class CurrentUserUtils { new SchemaHeaderField("[Long Description]", "dimGray", undefined, undefined, undefined, true), new SchemaHeaderField("[Details]", "dimGray", undefined, undefined, undefined, true), ]); - const detailView = Docs.Create.StackingDocument([carousel, descriptionWrapper], { ...shared, ...detailViewOpts, _chromeStatus: "", system: true }); + const detailView = Docs.Create.StackingDocument([carousel, descriptionWrapper], { ...shared, ...detailViewOpts, _chromeHidden: true, system: true }); detailView.isTemplateDoc = makeTemplate(detailView); details.title = "Details"; @@ -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", _chromeStatus: "", + title: "Advanced Item Prototypes", _xMargin: 0, _showTitle: "title", _chromeHidden: true, hidden: ComputedField.MakeFunction("IsNoviceMode()") as any, _stayInCollection: true, _hideContextMenu: true, _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 35, ignoreClick: true, _lockedPosition: true, @@ -367,7 +367,7 @@ export class CurrentUserUtils { }[] { if (doc.emptyPresentation === undefined) { doc.emptyPresentation = Docs.Create.PresDocument(new List(), - { title: "Untitled Presentation", _viewType: CollectionViewType.Stacking, _fitWidth: true, _width: 400, _height: 500, targetDropAction: "alias", _chromeStatus: "replaced", boxShadow: "0 0", system: true, cloneFieldFilter: new List(["system"]) }); + { title: "Untitled Presentation", _viewType: CollectionViewType.Stacking, _fitWidth: true, _width: 400, _height: 500, targetDropAction: "alias", _chromeHidden: true, boxShadow: "0 0", system: true, cloneFieldFilter: new List(["system"]) }); ((doc.emptyPresentation as Doc).proto as Doc)["dragFactory-count"] = 0; } if (doc.emptyCollection === undefined) { @@ -498,7 +498,7 @@ export class CurrentUserUtils { if (dragCreatorSet === undefined) { doc.myItemCreators = new PrefetchProxy(Docs.Create.MasonryDocument(creatorBtns, { - title: "Basic Item Creators", _showTitle: "title", _xMargin: 0, _stayInCollection: true, _hideContextMenu: true, _chromeStatus: "", + title: "Basic Item Creators", _showTitle: "title", _xMargin: 0, _stayInCollection: true, _hideContextMenu: true, _chromeHidden: true, _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 35, ignoreClick: true, _lockedPosition: true, dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), system: true })); @@ -559,7 +559,7 @@ export class CurrentUserUtils { doc.menuStack = new PrefetchProxy(Docs.Create.StackingDocument(menuBtns, { title: "menuItemPanel", childDropAction: "alias", - _chromeStatus: "", + _chromeHidden: true, dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), backgroundColor: "black", ignoreClick: true, _gridGap: 0, @@ -597,7 +597,7 @@ export class CurrentUserUtils { // Sets up mobileMenu stacking document static setupMobileMenu() { const menu = new PrefetchProxy(Docs.Create.StackingDocument(this.setupMobileButtons(), { - _width: 980, ignoreClick: true, _lockedPosition: false, title: "home", _yMargin: 100, system: true, _chromeStatus: "" + _width: 980, ignoreClick: true, _lockedPosition: false, title: "home", _yMargin: 100, system: true, _chromeHidden: true, })); return menu; } @@ -691,13 +691,13 @@ export class CurrentUserUtils { static setupMobileUploadDoc(userDoc: Doc) { // const addButton = Docs.Create.FontIconDocument({ onDragStart: ScriptField.MakeScript('addWebToMobileUpload()'), title: "Add Web Doc to Upload Collection", icon: "plus", backgroundColor: "black" }) const webDoc = Docs.Create.WebDocument("https://www.britannica.com/biography/Miles-Davis", { - title: "Upload Images From the Web", _chromeStatus: "enabled", _lockedPosition: true, system: true + title: "Upload Images From the Web", _lockedPosition: true, system: true }); const uploadDoc = Docs.Create.StackingDocument([], { - title: "Mobile Upload Collection", backgroundColor: "white", _lockedPosition: true, system: true, _chromeStatus: "" + title: "Mobile Upload Collection", backgroundColor: "white", _lockedPosition: true, system: true, _chromeHidden: true, }); return Docs.Create.StackingDocument([webDoc, uploadDoc], { - _width: screen.width, _lockedPosition: true, title: "Upload", _autoHeight: true, _yMargin: 80, backgroundColor: "lightgray", system: true, _chromeStatus: "" + _width: screen.width, _lockedPosition: true, title: "Upload", _autoHeight: true, _yMargin: 80, backgroundColor: "lightgray", system: true, _chromeHidden: true, }); } @@ -717,14 +717,13 @@ export class CurrentUserUtils { if (doc.myCreators === undefined) { doc.myCreators = new PrefetchProxy(Docs.Create.StackingDocument([creatorBtns, templateBtns], { title: "all Creators", _yMargin: 0, _autoHeight: true, _xMargin: 0, _fitWidth: true, - _width: 500, _height: 300, ignoreClick: true, _lockedPosition: true, system: true, - _chromeStatus: "" + _width: 500, _height: 300, ignoreClick: true, _lockedPosition: true, system: true, _chromeHidden: true, })); } // setup a color picker if (doc.myColorPicker === undefined) { const color = Docs.Create.ColorDocument({ - title: "color picker", _width: 300, _dropAction: "alias", _hideContextMenu: true, _stayInCollection: true, _forceActive: true, _removeDropProperties: new List(["dropAction", "_stayInCollection", "_hideContextMenu", "forceActive"]), system: true + title: "color picker", _width: 220, _dropAction: "alias", _hideContextMenu: true, _stayInCollection: true, _forceActive: true, _removeDropProperties: new List(["dropAction", "_stayInCollection", "_hideContextMenu", "forceActive"]), system: true }); doc.myColorPicker = new PrefetchProxy(color); } @@ -732,7 +731,7 @@ export class CurrentUserUtils { if (doc.myTools === undefined) { const toolsStack = new PrefetchProxy(Docs.Create.StackingDocument([doc.myCreators as Doc, doc.myColorPicker as Doc], { title: "My Tools", _width: 500, _yMargin: 20, ignoreClick: true, _lockedPosition: true, _forceActive: true, - system: true, _stayInCollection: true, _hideContextMenu: true, _chromeStatus: "" + system: true, _stayInCollection: true, _hideContextMenu: true, _chromeHidden: true, })) as any as Doc; doc.myTools = toolsStack; @@ -910,8 +909,7 @@ export class CurrentUserUtils { if (!sharedDocs) { sharedDocs = Docs.Create.StackingDocument([], { title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "none", childLimitHeight: 0, _yMargin: 50, _gridGap: 15, - _showTitle: "title", ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Add, "_acl-Public": SharingPermissions.Add, - _chromeStatus: "" + _showTitle: "title", ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Add, "_acl-Public": SharingPermissions.Add, _chromeHidden: true, }, sharingDocumentId + "outer", sharingDocumentId); } if (sharedDocs instanceof Doc) { @@ -926,13 +924,13 @@ export class CurrentUserUtils { if (doc.myImportDocs === undefined) { doc.myImportDocs = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "My ImportDocuments", _forceActive: true, ignoreClick: true, _showTitle: "title", _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0, - childDropAction: "alias", _autoHeight: true, _yMargin: 50, _gridGap: 15, _lockedPosition: true, system: true, _chromeStatus: "" + childDropAction: "alias", _autoHeight: true, _yMargin: 50, _gridGap: 15, _lockedPosition: true, system: true, _chromeHidden: true, })); } if (doc.myImportPanel === undefined) { const uploads = Cast(doc.myImportDocs, Doc, null); const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Import External document", _stayInCollection: true, _hideContextMenu: true, title: "Import", icon: "upload", system: true }); - doc.myImportPanel = new PrefetchProxy(Docs.Create.StackingDocument([newUpload, uploads], { title: "My ImportPanel", _yMargin: 20, ignoreClick: true, _chromeStatus: "", _stayInCollection: true, _hideContextMenu: true, _lockedPosition: true, system: true })); + doc.myImportPanel = new PrefetchProxy(Docs.Create.StackingDocument([newUpload, uploads], { title: "My ImportPanel", _yMargin: 20, ignoreClick: true, _chromeHidden: true, _stayInCollection: true, _hideContextMenu: true, _lockedPosition: true, system: true })); } } diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx index 244e96599..925b74efa 100644 --- a/src/client/util/Import & Export/DirectoryImportBox.tsx +++ b/src/client/util/Import & Export/DirectoryImportBox.tsx @@ -145,7 +145,7 @@ export class DirectoryImportBox extends React.Component { title: `Import of ${directory}`, _width: 1105, _height: 500, - _chromeStatus: "", + _chromeHidden: true, x: NumCast(doc.x), y: NumCast(doc.y) + offset }; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index c59c67574..4444a3944 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -101,7 +101,7 @@ export class MainView extends React.Component { } new InkStrokeProperties(); this._sidebarContent.proto = undefined; - DocServer.setPlaygroundFields(["x", "y", "dataTransition", "_autoHeight", "_showSidebar", "_sidebarWidthPercent", "_width", "_height", "_viewTransition", "_panX", "_panY", "_viewScale", "_scrollTop", "hidden", "_curPage", "_viewType", "_chromeStatus"]); // can play with these fields on someone else's + DocServer.setPlaygroundFields(["x", "y", "dataTransition", "_autoHeight", "_showSidebar", "_sidebarWidthPercent", "_width", "_height", "_viewTransition", "_panX", "_panY", "_viewScale", "_scrollTop", "hidden", "_curPage", "_viewType", "_chromeHidden"]); // can play with these fields on someone else's DocServer.GetRefField("rtfProto").then(proto => (proto instanceof Doc) && reaction(() => StrCast(proto.BROADCAST_MESSAGE), msg => msg && alert(msg))); @@ -232,7 +232,7 @@ export class MainView extends React.Component { })); } const pres = Docs.Create.PresDocument(new List(), - { title: "Untitled Presentation", _viewType: CollectionViewType.Stacking, _width: 400, _height: 500, targetDropAction: "alias", _chromeStatus: "replaced", boxShadow: "0 0" }); + { title: "Untitled Presentation", _viewType: CollectionViewType.Stacking, _width: 400, _height: 500, targetDropAction: "alias", _chromeHidden: true, boxShadow: "0 0" }); CollectionDockingView.AddSplit(pres, "right"); this.userDoc.activePresentation = pres; Doc.AddDocToList(this.userDoc.myPresentations as Doc, "data", pres); diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 9afcdc28d..71f753d51 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -74,7 +74,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { return this.propertyToggleBtn("Caption", "_showCaption", on => `${on ? "Hide" : "Show"} caption footer`, on => "closed-captioning", (dv, doc) => (dv?.rootDoc || doc)._showCaption = (dv?.rootDoc || doc)._showCaption === undefined ? "caption" : undefined); } @computed get chromeButton() { - return this.propertyToggleBtn("Controls", "_chromeStatus", on => `${on === "enabled" ? "Hide" : "Show"} editing UI`, on => "edit", (dv, doc) => (dv?.rootDoc || doc)._chromeStatus = !(dv?.rootDoc || doc)._chromeStatus ? "enabled" : ""); + return this.propertyToggleBtn("Controls", "_chromeHidden", on => `${on ? "Show" : "Hide"} editing UI`, on => "edit", (dv, doc) => (dv?.rootDoc || doc)._chromeHidden = !(dv?.rootDoc || doc)._chromeHidden); } @computed get titleButton() { return this.propertyToggleBtn("Title", "_showTitle", on => "Switch between title styles", on => "text-width", (dv, doc) => (dv?.rootDoc || doc)._showTitle = !(dv?.rootDoc || doc)._showTitle ? "title" : (dv?.rootDoc || doc)._showTitle === "title" ? "title:hover" : undefined); @@ -165,8 +165,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { } @computed get onPerspectiveFlyout() { - const excludedViewTypes = Doc.UserDoc().noviceMode ? [CollectionViewType.Invalid, CollectionViewType.Docking, CollectionViewType.Pile, CollectionViewType.StackedTimeline, CollectionViewType.Stacking, CollectionViewType.Map, CollectionViewType.Linear] : - [CollectionViewType.Invalid, CollectionViewType.Docking, CollectionViewType.Pile, CollectionViewType.StackedTimeline, CollectionViewType.Linear]; + const excludedViewTypes = [CollectionViewType.Invalid, CollectionViewType.Docking, CollectionViewType.Pile, CollectionViewType.StackedTimeline, CollectionViewType.Linear]; const makeLabel = (value: string, label: string) =>
} - {/* {!this.chromeStatus || !this.props.isSelected() ? (null) : + {/* {this.chromeHidden || !this.props.isSelected() ? (null) : } */} diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 70ec1f925..caf4c59c1 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -32,7 +32,7 @@ interface CSVFieldColumnProps { docList: Doc[]; heading: string; pivotField: string; - chromeStatus: string; + chromeHidden?: boolean; columnHeaders: SchemaHeaderField[] | undefined; headingObject: SchemaHeaderField | undefined; yMargin: number; @@ -249,8 +249,7 @@ export class CollectionStackingViewFieldColumn extends React.Component
{/* the default bucket (no key value) has a tooltip that describes what it is. @@ -307,7 +306,7 @@ export class CollectionStackingViewFieldColumn extends React.Component {this.props.renderChildren(this.props.docList)}
- {(this.props.chromeStatus !== 'view-mode' && this.props.chromeStatus && type !== DocumentType.PRES) ? + {!this.props.chromeHidden && type !== DocumentType.PRES ?
doc) { } return
+ style={{ width: this.props.PanelWidth(), height: "100%" }}> {this.pivotKeyUI} {this.contents} {!this.props.isSelected() || !doTimeline ? (null) : <> diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 34fd20f1a..535bf539e 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -71,6 +71,7 @@ export interface CollectionViewProps extends FieldViewProps { // property overrides for child documents children?: never | (() => JSX.Element[]) | React.ReactNode; childDocuments?: Doc[]; // used to override the documents shown by the sub collection to an explicit list (see LinkBox) + childFitWidth?: () => boolean; childOpacity?: () => number; childHideTitle?: () => boolean; // whether to hide the documentdecorations title for children childHideDecorationTitle?: () => boolean; diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx index d26f53e28..4005c751e 100644 --- a/src/client/views/collections/SchemaTable.tsx +++ b/src/client/views/collections/SchemaTable.tsx @@ -559,8 +559,7 @@ export class SchemaTable extends React.Component { onPointerDown={this.props.onPointerDown} onClick={this.props.onClick} onWheel={e => this.props.active(true) && e.stopPropagation()} onDrop={e => this.props.onDrop(e, {})} onContextMenu={this.onContextMenu} > {this.reactTable} - {this.props.Document._chromeStatus ?
this.createRow()}>+ new
- : undefined} + {this.props.Document._chromeHidden ? undefined :
this.createRow()}>+ new
} {!this._showDoc ? (null) :
{ - const targetDoc = view.props.Document.dragFactory instanceof Doc ? view.props.Document.dragFactory : - view.props.Document.layout instanceof Doc ? view.props.Document.layout : - view.props.Document.isTemplateForField ? view.props.Document : Doc.GetProto(view.props.Document); - if (targetDoc) { - if (view.props.LayoutTemplate?.() || view.props.LayoutTemplateString) { // this situation typically occurs when you have a link dot - targetDoc.backgroundColor = Doc.UserDoc().backgroundColor; // bcz: don't know how to change the color of an inline template... - } - else if (RichTextMenu.Instance?.TextViewFieldKey && window.getSelection()?.toString() !== "") { - Doc.Layout(view.props.Document)[RichTextMenu.Instance.TextViewFieldKey + "-color"] = Doc.UserDoc().backgroundColor; - } else { - Doc.Layout(view.props.Document)._backgroundColor = Doc.UserDoc().backgroundColor; // '_backgroundColor' is template specific. 'backgroundColor' would apply to all templates, but has no UI at the moment - } + SelectionManager.Views().map(view => { + const targetDoc = view.props.Document.dragFactory instanceof Doc ? view.props.Document.dragFactory : + view.props.Document.layout instanceof Doc ? view.props.Document.layout : + view.props.Document.isTemplateForField ? view.props.Document : Doc.GetProto(view.props.Document); + if (targetDoc) { + if (view.props.LayoutTemplate?.() || view.props.LayoutTemplateString) { // this situation typically occurs when you have a link dot + targetDoc.backgroundColor = Doc.UserDoc().backgroundColor; // bcz: don't know how to change the color of an inline template... } - }); - } + else if (RichTextMenu.Instance?.TextViewFieldKey && window.getSelection()?.toString() !== "") { + Doc.Layout(view.props.Document)[RichTextMenu.Instance.TextViewFieldKey + "-color"] = Doc.UserDoc().backgroundColor; + } else { + Doc.Layout(view.props.Document)._backgroundColor = Doc.UserDoc().backgroundColor; // '_backgroundColor' is template specific. 'backgroundColor' would apply to all templates, but has no UI at the moment + } + } + }); } - constructor(props: any) { - super(props); - } render() { - const selDoc = SelectionManager.Views()?.[0]?.rootDoc; + const scaling = Math.min(this.layoutDoc.fitWidth ? 10000 : this.props.PanelHeight() / this.rootDoc[HeightSym](), this.props.PanelWidth() / this.rootDoc[WidthSym]()); return
e.button === 0 && !e.ctrlKey && e.stopPropagation()} onClick={e => { (e.nativeEvent as any).stuff = true; e.stopPropagation(); }} - style={{ width: `${100}%`, height: `${100}%` }} > + onPointerDown={e => e.button === 0 && !e.ctrlKey && e.stopPropagation()} onClick={e => e.stopPropagation()} + style={{ transform: `scale(${scaling})`, width: `${100 * scaling}%`, height: `${100 * scaling}%` }} > - + CurrentUserUtils.SelectedTool === InkTool.None && ColorBox.switchColor(c)} + color={StrCast(SelectionManager.Views()?.[0]?.rootDoc?._backgroundColor, ActiveInkColor())} + presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', + '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']} + /> -
-
{ActiveInkWidth() ?? 2}
- ) => { +
+
{ActiveInkWidth()}
+ ) => { SetActiveInkWidth(e.target.value); SelectionManager.Views().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeWidth = Number(e.target.value)); }} /> - {/*
{ActiveInkBezierApprox() ?? 2}
- ) => { - SetActiveBezierApprox(e.target.value); - SelectionManager.SelectedDocuments().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeBezier = e.target.value); - }} /> */} -
-
; } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index e15ade241..6d18f5f3e 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -101,6 +101,7 @@ export interface DocumentViewSharedProps { layerProvider: undefined | ((doc: Doc, assign?: boolean) => boolean); styleProvider: Opt; focus: DocFocusFunc; + fitWidth?: () => boolean; docFilters: () => string[]; docRangeFilters: () => string[]; searchFilterDocs: () => Doc[]; @@ -340,7 +341,7 @@ export class DocumentViewInternal extends DocComponent SharingManager.Instance.open(this.props.DocumentView()), icon: "users" }); if (!Doc.UserDoc().noviceMode) { moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" }); - moreItems.push({ description: `${this.Document._chromeStatus ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus ? "" : "enabled"), icon: "project-diagram" }); + moreItems.push({ description: `${this.Document._chromeHidden ? "Show" : "Hide"} Chrome`, event: () => this.Document._chromeHidden = !this.Document._chromeHidden, icon: "project-diagram" }); if (Cast(Doc.GetProto(this.props.Document).data, listSpec(Doc))) { moreItems.push({ description: "Export to Google Photos Album", event: () => GooglePhotos.Export.CollectionToAlbum({ collection: this.props.Document }).then(console.log), icon: "caret-square-right" }); @@ -994,6 +995,7 @@ export class DocumentView extends React.Component { get ComponentView() { return this.docView?._componentView; } get allLinks() { return this.docView?.allLinks || []; } get LayoutFieldKey() { return this.docView?.LayoutFieldKey || "layout"; } + get fitWidth() { return this.props.fitWidth?.() || this.layoutDoc.fitWidth; } @computed get docViewPath() { return this.props.docViewPath ? [...this.props.docViewPath(), this] : [this]; } @computed get layoutDoc() { return Doc.Layout(this.Document, this.props.LayoutTemplate?.()); } @@ -1005,13 +1007,13 @@ export class DocumentView extends React.Component { return this.docView?._componentView?.reverseNativeScaling?.() ? 0 : returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions)); } - @computed get shouldNotScale() { return (this.layoutDoc._fitWidth && !this.nativeWidth) || [CollectionViewType.Docking, CollectionViewType.Tree].includes(this.Document._viewType as any); } + @computed get shouldNotScale() { return (this.fitWidth && !this.nativeWidth) || [CollectionViewType.Docking, CollectionViewType.Tree].includes(this.Document._viewType as any); } @computed get effectiveNativeWidth() { return this.shouldNotScale ? 0 : (this.nativeWidth || NumCast(this.layoutDoc.width)); } @computed get effectiveNativeHeight() { return this.shouldNotScale ? 0 : (this.nativeHeight || NumCast(this.layoutDoc.height)); } @computed get nativeScaling() { if (this.shouldNotScale) return 1; const minTextScale = this.Document.type === DocumentType.RTF ? 0.1 : 0; - if (this.layoutDoc._fitWidth || this.props.PanelHeight() / this.effectiveNativeHeight > this.props.PanelWidth() / this.effectiveNativeWidth) { + if (this.fitWidth || this.props.PanelHeight() / this.effectiveNativeHeight > this.props.PanelWidth() / this.effectiveNativeWidth) { return Math.max(minTextScale, this.props.PanelWidth() / this.effectiveNativeWidth); // width-limited or fitWidth } return Math.max(minTextScale, this.props.PanelHeight() / this.effectiveNativeHeight); // height-limited or unscaled @@ -1027,7 +1029,7 @@ export class DocumentView extends React.Component { @computed get Xshift() { return this.effectiveNativeWidth ? (this.props.PanelWidth() - this.effectiveNativeWidth * this.nativeScaling) / 2 : 0; } @computed get Yshift() { return this.effectiveNativeWidth && this.effectiveNativeHeight && Math.abs(this.Xshift) < 0.001 ? (this.props.PanelHeight() - this.effectiveNativeHeight * this.nativeScaling) / 2 : 0; } @computed get centeringX() { return this.props.dontCenter?.includes("x") ? 0 : this.Xshift; } - @computed get centeringY() { return this.props.Document._fitWidth || this.props.dontCenter?.includes("y") ? 0 : this.Yshift; } + @computed get centeringY() { return this.fitWidth || this.props.dontCenter?.includes("y") ? 0 : this.Yshift; } toggleNativeDimensions = () => this.docView && Doc.toggleNativeDimensions(this.layoutDoc, this.docView.ContentScale, this.props.PanelWidth(), this.props.PanelHeight()); contentsActive = () => this.docView?.contentsActive(); @@ -1109,7 +1111,7 @@ export class DocumentView extends React.Component { position: this.props.Document.isInkMask ? "absolute" : undefined, transform: `translate(${this.centeringX}px, ${this.centeringY}px)`, width: xshift ?? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%`, - height: yshift ?? (this.props.Document._fitWidth ? `${this.panelHeight}px` : + height: yshift ?? (this.fitWidth ? `${this.panelHeight}px` : `${100 * this.effectiveNativeHeight / this.effectiveNativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%`), }}> { } getTemplate = async () => { - const parent = Docs.Create.StackingDocument([], { _width: 800, _height: 800, title: "Template", _chromeStatus: "" }); + const parent = Docs.Create.StackingDocument([], { _width: 800, _height: 800, title: "Template", _chromeHidden: true }); parent._columnWidth = 100; for (const row of this.rows.filter(row => row.isChecked)) { await this.createTemplateField(parent, row); diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 3c1fda465..88406b181 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -13,7 +13,7 @@ import { PrefetchProxy } from "../../../fields/Proxy"; import { listSpec, makeInterface } from "../../../fields/Schema"; import { ScriptField } from "../../../fields/ScriptField"; import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types"; -import { returnFalse, returnOne } from "../../../Utils"; +import { returnFalse, returnOne, returnTrue } from '../../../Utils'; import { Docs } from "../../documents/Documents"; import { DocumentType } from "../../documents/DocumentTypes"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; @@ -195,7 +195,6 @@ export class PresBox extends ViewBoxBaseComponent componentDidMount() { this.rootDoc.presBox = this.rootDoc; this.rootDoc._forceRenderEngine = "timeline"; - this.rootDoc._replacedChrome = "replaced"; this.layoutDoc.presStatus = PresStatus.Edit; this.layoutDoc._gridGap = 0; this.layoutDoc._yMargin = 0; @@ -2262,7 +2261,7 @@ export class PresBox extends ViewBoxBaseComponent const mode = StrCast(this.rootDoc._viewType) as CollectionViewType; const isMini: boolean = this.toolbarWidth <= 100; return ( -
+
{isMini ? (null) :