From f504934782b6458585148e3412b5fef975515931 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 23 Aug 2020 16:26:28 -0400 Subject: added settings for default text titles. fixed image audio annotatoins. fixed captions to not set title. added properties buttons for layout options and removed template layout button. fixed warnings. --- src/client/views/nodes/formattedText/FormattedTextBox.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.scss') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss index afdd8fea2..160f4ba72 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.scss +++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss @@ -32,8 +32,8 @@ .formattedTextBox-dictation { height: 12px; width: 10px; - top: 0px; - left: 0px; + bottom: 5px; + right: 8px; position: absolute; } } -- cgit v1.2.3-70-g09d2 From 93b72ab7818e48592e9d42d092fa91b4ebedd49e Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 12 Sep 2020 16:22:09 -0400 Subject: fixed sidebar views in text boxes to work in treeview outlines. fixed context menus to select docs again. fixed linkAnchors to show up when isLinkButton is true but doc is selcted. changed nudging to be ignore in annotation overlays --- src/client/util/SelectionManager.ts | 4 +- src/client/views/PreviewCursor.tsx | 2 +- .../views/collections/CollectionTreeView.scss | 19 ++++++++ .../views/collections/CollectionTreeView.tsx | 21 +++------ .../collectionFreeForm/CollectionFreeFormView.tsx | 7 +-- .../collections/collectionFreeForm/MarqueeView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 4 +- .../nodes/formattedText/FormattedTextBox.scss | 30 +++---------- .../views/nodes/formattedText/FormattedTextBox.tsx | 51 +++++++++++----------- 9 files changed, 68 insertions(+), 72 deletions(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.scss') diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 730db4f29..7795a4a59 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -73,8 +73,8 @@ export namespace SelectionManager { // computed functions, such as used in IsSelected generate errors if they're called outside of a // reaction context. Specifying the context with 'outsideReaction' allows an efficiency feature // to avoid unnecessary mobx invalidations when running inside a reaction. - export function IsSelected(doc: DocumentView, outsideReaction?: boolean): boolean { - return outsideReaction ? + export function IsSelected(doc: DocumentView | undefined, outsideReaction?: boolean): boolean { + return !doc ? false : outsideReaction ? manager.SelectedDocuments.get(doc) ? true : false : // get() accesses a hashtable -- setting anything in the hashtable generates a mobx invalidation for every get() computedFn(function isSelected(doc: DocumentView) { // wraapping get() in a computedFn only generates mobx() invalidations when the return value of the function for the specific get parameters has changed return manager.SelectedDocuments.get(doc) ? true : false; diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index 0a4d46c1f..7575aa430 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -22,7 +22,7 @@ export class PreviewCursor extends React.Component<{}> { static _getTransform: () => Transform; static _addDocument: (doc: Doc | Doc[]) => void; static _addLiveTextDoc: (doc: Doc) => void; - static _nudge: (x: number, y: number) => boolean; + static _nudge?: (x: number, y: number) => boolean; @observable static _clickPoint = [0, 0]; @observable public static Visible = false; constructor(props: any) { diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss index 09a46c30f..feeb04134 100644 --- a/src/client/views/collections/CollectionTreeView.scss +++ b/src/client/views/collections/CollectionTreeView.scss @@ -103,6 +103,15 @@ padding-bottom: 2px; } +.treeViewItem-container-active { + z-index: 100; + position: relative;; + .formattedTextbox-sidebar { + background-color: #ffff001f !important; + height: 500px !important; + } +} + .treeViewItem-openRight { display: none; height: 17px; @@ -128,6 +137,16 @@ border: transparent 1px solid; display: flex; align-items: center; + ::-webkit-scrollbar { + display: none; + } + .formattedTextBox-cont { + .formattedTextbox-sidebar { + overflow: visible !important; + border-left: unset; + } + overflow: visible !important; + } .editableView-container-editing-oneLine { min-width: 15px; diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 52e3c86b8..276e0b873 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -32,6 +32,7 @@ import { CurrentUserUtils } from '../../util/CurrentUserUtils'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { RichTextField } from '../../../fields/RichTextField'; import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; +import { DocumentManager } from '../../util/DocumentManager'; export interface TreeViewProps { document: Doc; @@ -176,7 +177,7 @@ class TreeView extends React.Component { } public static makeTextBullet() { - const bullet = Docs.Create.TextDocument("-text-", { title: "-title-", _viewType: CollectionViewType.Tree, hideLinkButton: true, treeViewOutlineMode: true, x: 0, y: 0, _xMargin: 0, _yMargin: 0, _autoHeight: true, _singleLine: true, _backgroundColor: "transparent", _width: 2000, _height: 10, templates: new List([Templates.Title.Layout]) }); + const bullet = Docs.Create.TextDocument("-text-", { title: "-title-", _viewType: CollectionViewType.Tree, hideLinkButton: true, treeViewOutlineMode: true, x: 0, y: 0, _xMargin: 0, _yMargin: 0, _autoHeight: true, _singleLine: true, _backgroundColor: "transparent", _width: 500, _height: 10, templates: new List([Templates.Title.Layout]) }); Doc.GetProto(bullet).layout = CollectionView.LayoutString("data"); Doc.GetProto(bullet).title = ComputedField.MakeFunction('self.text?.Text'); Doc.GetProto(bullet).data = new List([]); @@ -552,9 +553,10 @@ class TreeView extends React.Component { } } } else this._editMaxWidth = ""; + const selected = SelectionManager.IsSelected(DocumentManager.Instance.getFirstDocumentView(this.doc)); return this.doc.treeViewHideTitle || (this.outlineMode) ? !StrCast(Doc.LayoutField(this.doc)).includes("CollectionView") ? this.renderContent : -
this.props.active(true) && SelectionManager.DeselectAll()} +
this.props.active(true) && SelectionManager.DeselectAll()} onKeyDown={e => { e.stopPropagation(); e.key === "Backspace" && this.doc.text && !(this.doc.text as RichTextField)?.Text && UndoManager.RunInBatch(() => this.props.removeDoc?.(this.doc), "delete"); @@ -563,18 +565,9 @@ class TreeView extends React.Component { e.key === "Tab" && setTimeout(() => RichTextMenu.Instance.TextView?.EditorView?.focus(), 150); }} > -
{ - if (this.props.active(true)) { - e.stopPropagation(); - e.preventDefault(); - } - }} - onPointerDown={e => { - if (this.props.active(true)) { - e.stopPropagation(); - e.preventDefault(); - } - }} +
{ if (this.props.active(true)) { e.stopPropagation(); e.preventDefault(); } }} + onPointerDown={e => { if (this.props.active(true)) { e.stopPropagation(); e.preventDefault(); } }} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}> {this.outlineMode ? this.renderOutlineBullet : this.renderBullet}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 543798b7e..843314c03 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -792,7 +792,7 @@ export class CollectionFreeFormView extends CollectionSubView { - if (this.layoutDoc._lockedTransform || this.props.Document.inOverlay) return; + if (this.layoutDoc._lockedTransform || this.props.Document.inOverlay || this.props.Document.treeViewOutlineMode) return; if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming e.stopPropagation(); } @@ -1369,7 +1369,8 @@ export class CollectionFreeFormView extends CollectionSubView { - if (this.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform) { // bcz: this isn't ideal, but want to try it out... + if (this.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform || + this.props.ContainingCollectionDoc._panX !== undefined) { // bcz: this isn't ideal, but want to try it out... this.setPan(NumCast(this.layoutDoc._panX) + this.props.PanelWidth() / 2 * x / this.zoomScaling(), NumCast(this.layoutDoc._panY) + this.props.PanelHeight() / 2 * (-y) / this.zoomScaling(), "transform 500ms", true); this._nudgeTime = Date.now(); @@ -1381,7 +1382,7 @@ export class CollectionFreeFormView extends CollectionSubView void; addLiveTextDocument: (doc: Doc) => void; isSelected: () => boolean; - nudge: (x: number, y: number) => boolean; + nudge?: (x: number, y: number) => boolean; setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void; } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 147745d93..b372f3691 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -835,7 +835,7 @@ export class DocumentView extends DocComponent(Docu e?.stopPropagation(); // DocumentViews should stop propagation of this event } cm.displayMenu((e?.pageX || pageX || 0) - 15, (e?.pageY || pageY || 0) - 15); - this.isSelected(true) && SelectionManager.SelectDoc(this, false); + !this.isSelected(true) && SelectionManager.SelectDoc(this, false); }); } @@ -912,7 +912,7 @@ export class DocumentView extends DocComponent(Docu layoutKey={this.finalLayoutKey} /> {this.layoutDoc.hideAllLinks ? (null) : this.allAnchors} {/* {this.allAnchors} */} - {this.props.forcedBackgroundColor?.(this.Document) === "transparent" || this.layoutDoc.isLinkButton || (!this.isSelected() && this.layoutDoc.hideLinkButton) || this.props.dontRegisterView ? (null) : + {this.props.forcedBackgroundColor?.(this.Document) === "transparent" || (!this.isSelected() && (this.layoutDoc.isLinkButton || this.layoutDoc.hideLinkButton)) || this.props.dontRegisterView ? (null) : }
); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss index 160f4ba72..847b1bb30 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.scss +++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss @@ -45,10 +45,11 @@ width: 100%; height: 100%; } - + .formattedTextBox-sidebar-handle { position: absolute; - top: calc(50% - 17.5px); + top: 0; + //top: calc(50% - 17.5px); // use this to center vertically -- make sure it looks okay for slide views width: 10px; height: 35px; background: lightgray; @@ -56,11 +57,6 @@ cursor:grabbing; } -.formattedTextBox-cont>.formattedTextBox-sidebar-handle { - right: 0; - left: unset; -} - .formattedTextBox-sidebar, .formattedTextBox-sidebar-inking { border-left: dashed 1px black; @@ -73,11 +69,6 @@ .collectionfreeformview-container { position: relative; } - - >.formattedTextBox-sidebar-handle { - right: unset; - left: -5; - } } .formattedTextBox-sidebar-inking { @@ -396,10 +387,11 @@ footnote::after { width: 100%; height: 100%; } - + .formattedTextBox-sidebar-handle { position: absolute; - top: calc(50% - 17.5px); + top: 0; + //top: calc(50% - 17.5px); // use this to center vertically -- make sure it looks okay for slide views width: 10px; height: 35px; background: lightgray; @@ -407,11 +399,6 @@ footnote::after { cursor:grabbing; } - .formattedTextBox-cont>.formattedTextBox-sidebar-handle { - right: 0; - left: unset; - } - .formattedTextBox-sidebar, .formattedTextBox-sidebar-inking { border-left: dashed 1px black; @@ -423,11 +410,6 @@ footnote::after { .collectionfreeformview-container { position: relative; } - - >.formattedTextBox-sidebar-handle { - right: unset; - left: -5; - } } .formattedTextBox-sidebar-inking { diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 29d9283e7..a79e70017 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1500,7 +1500,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } - @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); } + @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "20%"); } sidebarWidth = () => Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth(); sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()) / this.props.ContentScaling(), 0); @computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); } @@ -1569,32 +1569,33 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp }} />
- {!this.layoutDoc._showSidebar ? (null) : this.sidebarWidthPercent === "0%" ? -
: + {!this.layoutDoc._showSidebar ? (null) : <>
- - -
-
} + {this.sidebarWidthPercent === "0%" ? (null) : + 1000 : this.props.PanelHeight} + PanelWidth={this.sidebarWidth} + scaleField={this.annotationKey + "-scale"} + annotationsKey={this.annotationKey} + isAnnotationOverlay={true} + focus={this.props.focus} + isSelected={this.props.isSelected} + select={emptyFunction} + active={this.annotationsActive} + ContentScaling={returnOne} + whenActiveChanged={this.whenActiveChanged} + removeDocument={this.removeDocument} + moveDocument={this.moveDocument} + addDocument={this.addDocument} + CollectionView={undefined} + ScreenToLocalTransform={this.sidebarScreenToLocal} + renderDepth={this.props.renderDepth + 1} + ContainingCollectionDoc={this.props.ContainingCollectionDoc} /> + } +
+ {this.props.isSelected() ?
: (null)} + } {!this.layoutDoc._showAudio ? (null) :
this._recording = !this._recording)} > Date: Sat, 12 Sep 2020 23:41:31 -0400 Subject: fixed stacking view selections to have the right bounding box. fixed text boxes to work with headerVIew template which has multiple text boxes in it. --- src/client/util/CurrentUserUtils.ts | 33 +++++++++++----------- src/client/util/DropConverter.ts | 2 +- src/client/views/Main.scss | 4 +++ src/client/views/collections/CollectionMenu.tsx | 2 +- .../views/collections/CollectionStackingView.tsx | 2 +- .../views/collections/CollectionTreeView.tsx | 2 +- src/client/views/globalCssVariables.scss | 4 --- .../nodes/formattedText/FormattedTextBox.scss | 5 ++-- .../views/nodes/formattedText/FormattedTextBox.tsx | 23 +++++++++------ .../formattedText/ProsemirrorExampleTransfer.ts | 2 +- 10 files changed, 43 insertions(+), 36 deletions(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.scss') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 365a0a409..a63a0ba08 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -47,7 +47,7 @@ export class CurrentUserUtils { @observable public static propertiesWidth: number = 0; - // sets up the default User Templates - slideView, queryView, descriptionView + // sets up the default User Templates - slideView, headerView static setupUserTemplateButtons(doc: Doc) { // Prototype for mobile button (not sure if 'Advanced Item Prototypes' is ideal location) if (doc["template-mobile-button"] === undefined) { @@ -85,29 +85,29 @@ export class CurrentUserUtils { }); } - if (doc["template-button-description"] === undefined) { - const descriptionTemplate = Doc.MakeDelegate(Docs.Create.TextDocument(" ", { title: "header", _height: 100, system: true }, "header")); // text needs to be a space to allow templateText to be created - descriptionTemplate.system = true; - descriptionTemplate[DataSym].layout = + if (doc["template-button-header"] === undefined) { + const headerTemplate = Doc.MakeDelegate(Docs.Create.TextDocument(" ", { title: "header", _autoHeight: true, system: true }, "header")); // text needs to be a space to allow templateText to be created + headerTemplate.system = true; + headerTemplate[DataSym].layout = "
" + - " " + + " " + " " + "
"; - (descriptionTemplate.proto as Doc).isTemplateDoc = makeTemplate(descriptionTemplate.proto as Doc, true, "descriptionView"); + (headerTemplate.proto as Doc).isTemplateDoc = makeTemplate(headerTemplate.proto as Doc, true, "headerView"); - doc["template-button-description"] = CurrentUserUtils.ficon({ + doc["template-button-header"] = CurrentUserUtils.ficon({ onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'), - dragFactory: new PrefetchProxy(descriptionTemplate) as any as Doc, - removeDropProperties: new List(["dropAction"]), title: "description view", icon: "window-maximize", system: true + dragFactory: new PrefetchProxy(headerTemplate) as any as Doc, + removeDropProperties: new List(["dropAction"]), title: "header view", icon: "window-maximize", system: true }); } if (doc["template-button-link"] === undefined) { // set _backgroundColor to transparent to prevent link dot from obscuring document it's attached to. - const linkTemplate = Doc.MakeDelegate(Docs.Create.TextDocument(" ", { title: "header", _height: 100, system: true }, "header")); // text needs to be a space to allow templateText to be created + const linkTemplate = Doc.MakeDelegate(Docs.Create.TextDocument(" ", { title: "header", _autoHeight: true, system: true }, "header")); // text needs to be a space to allow templateText to be created linkTemplate.system = true; Doc.GetProto(linkTemplate).layout = "
" + - " " + + " " + " " + "
"; (linkTemplate.proto as Doc).isTemplateDoc = makeTemplate(linkTemplate.proto as Doc, true, "linkView"); @@ -190,9 +190,9 @@ export class CurrentUserUtils { onChildDoubleClick: openInTarget, backgroundColor: "#9b9b9b3F", system: true }); - const details = TextDocument("", { title: "details", _height: 350, _autoHeight: true, system: true }); - const short = TextDocument("", { title: "shortDescription", treeViewOpen: true, treeViewExpandedView: "layout", _height: 100, _autoHeight: true, system: true }); - const long = TextDocument("", { title: "longDescription", treeViewOpen: false, treeViewExpandedView: "layout", _height: 350, _autoHeight: true, system: true }); + const details = TextDocument("", { title: "details", _height: 200, _autoHeight: true, system: true }); + const short = TextDocument("", { title: "shortDescription", treeViewOpen: true, treeViewExpandedView: "layout", _height: 75, _autoHeight: true, system: true }); + const long = TextDocument("", { title: "longDescription", treeViewOpen: false, treeViewExpandedView: "layout", _height: 150, _autoHeight: true, system: true }); const buxtonFieldKeys = ["year", "originalPrice", "degreesOfFreedom", "company", "attribute", "primaryKey", "secondaryKey", "dimensions"]; const detailedTemplate = { @@ -253,7 +253,7 @@ export class CurrentUserUtils { const requiredTypes = [ doc["template-button-slides"] as Doc, - doc["template-button-description"] as Doc, + doc["template-button-header"] as Doc, doc["template-mobile-button"] as Doc, doc["template-button-detail"] as Doc, doc["template-button-simple"] as Doc, @@ -468,7 +468,6 @@ export class CurrentUserUtils { { toolTip: "Tap to create an audio recorder in a new pane, drag for an audio recorder", title: "Audio", icon: "microphone", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyAudio as Doc, noviceMode: true }, { toolTip: "Tap to create a button in a new pane, drag for a button", title: "Button", icon: "bolt", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyButton as Doc, noviceMode: true }, { toolTip: "Tap to create a presentation in a new pane, drag for a presentation", title: "Trails", icon: "pres-trail", click: 'openOnRight(Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory))', drag: `Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory)`, dragFactory: doc.emptyPresentation as Doc, noviceMode: true }, - { toolTip: "Tap to create a search box in a new pane, drag for a search box", title: "Query", icon: "search", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptySearch as Doc }, { toolTip: "Tap to create a scripting box in a new pane, drag for a scripting box", title: "Script", icon: "terminal", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyScript as Doc }, { toolTip: "Tap to create a mobile view in a new pane, drag for a mobile view", title: "Phone", icon: "mobile", click: 'openOnRight(Doc.UserDoc().activeMobileMenu)', drag: 'this.dragFactory', dragFactory: doc.activeMobileMenu as Doc }, { toolTip: "Tap to create a document previewer in a new pane, drag for a document previewer", title: "Prev", icon: "expand", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyDocHolder as Doc }, diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts index f1848f7e5..49643b5bb 100644 --- a/src/client/util/DropConverter.ts +++ b/src/client/util/DropConverter.ts @@ -60,7 +60,7 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) { if (doc.type === DocumentType.FONTICON || StrCast(Doc.Layout(doc).layout).includes("FontIconBox")) { //dbox = Doc.MakeAlias(doc); // don't need to do anything if dropping an icon doc onto an icon bar since there should be no layout data for an icon } else if (!doc.onDragStart && !doc.isButtonBar) { - const layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc; + const layoutDoc = doc;// doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc; if (layoutDoc.type !== DocumentType.FONTICON) { !layoutDoc.isTemplateDoc && makeTemplate(layoutDoc); } diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss index 97ed0a901..b1ad4868c 100644 --- a/src/client/views/Main.scss +++ b/src/client/views/Main.scss @@ -1,6 +1,10 @@ @import "globalCssVariables"; @import "nodeModuleOverrides"; +:root { + --flyoutHandleWidth: 28px; + --menuPanelWidth: 60px; +} html, body { width: 100%; diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index a58edc604..3cc041e0b 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -533,7 +533,7 @@ export class CollectionFreeFormViewChrome extends React.Component this.Document._currentFrame === undefined ? this.props.childOpacity?.() : CollectionFreeFormDocumentView.getValues(doc, NumCast(this.Document._currentFrame))?.opacity; return { } public static makeTextBullet() { - const bullet = Docs.Create.TextDocument("-text-", { title: "-title-", _viewType: CollectionViewType.Tree, hideLinkButton: true, treeViewOutlineMode: true, x: 0, y: 0, _xMargin: 0, _yMargin: 0, _autoHeight: true, _singleLine: true, _backgroundColor: "transparent", _width: 500, _height: 10, templates: new List([Templates.Title.Layout]) }); + const bullet = Docs.Create.TextDocument("-text-", { title: "-title-", _viewType: CollectionViewType.Tree, hideLinkButton: true, _showSidebar: true, treeViewOutlineMode: true, x: 0, y: 0, _xMargin: 0, _yMargin: 0, _autoHeight: true, _singleLine: true, _backgroundColor: "transparent", _width: 1000, _height: 10, templates: new List([Templates.Title.Layout]) }); Doc.GetProto(bullet).layout = CollectionView.LayoutString("data"); Doc.GetProto(bullet).title = ComputedField.MakeFunction('self.text?.Text'); Doc.GetProto(bullet).data = new List([]); diff --git a/src/client/views/globalCssVariables.scss b/src/client/views/globalCssVariables.scss index d0c90edcb..1539d1399 100644 --- a/src/client/views/globalCssVariables.scss +++ b/src/client/views/globalCssVariables.scss @@ -38,10 +38,6 @@ $MINIMIZED_ICON_SIZE:25; $MAX_ROW_HEIGHT: 44px; $DFLT_IMAGE_NATIVE_DIM: 900px; $MENU_PANEL_WIDTH: 60px; -:root { - --flyoutHandleWidth: 28px; - --menuPanelWidth: 60px; -} :export { contextMenuZindex: $contextMenu-zindex; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss index 847b1bb30..43e64d2d2 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.scss +++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss @@ -43,7 +43,7 @@ overflow: auto; display: inline-block; width: 100%; - height: 100%; + height: unset; } .formattedTextBox-sidebar-handle { @@ -51,7 +51,8 @@ top: 0; //top: calc(50% - 17.5px); // use this to center vertically -- make sure it looks okay for slide views width: 10px; - height: 35px; + height: 100%; + max-height: 35px; background: lightgray; border-radius: 20px; cursor:grabbing; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index a79e70017..873d88f7e 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -64,6 +64,7 @@ export interface FormattedTextBoxProps { hideOnLeave?: boolean; // used by DocumentView for setting caption's hide on leave (bcz: would prefer to have caption-hideOnLeave field set or something similar) xMargin?: number; // used to override document's settings for xMargin --- see CollectionCarouselView yMargin?: number; + dontSelectOnLoad?: boolean; // suppress selecting the text box when loaded } export const GoogleRef = "googleDocId"; @@ -79,6 +80,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp public static Instance: FormattedTextBox; public ProseRef?: HTMLDivElement; public get EditorView() { return this._editorView; } + private _boxRef: React.RefObject = React.createRef(); private _ref: React.RefObject = React.createRef(); private _scrollRef: React.RefObject = React.createRef(); private _editorView: Opt; @@ -556,7 +558,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => { const bounds = this.CurrentDiv.getBoundingClientRect(); - this.layoutDoc._sidebarWidthPercent = "" + 100 * (1 - (e.clientX - bounds.left) / bounds.width) + "%"; + this.layoutDoc._sidebarWidthPercent = "" + 100 * Math.max(0, (1 - (e.clientX - bounds.left) / bounds.width)) + "%"; return false; } @undoBatch @@ -1144,7 +1146,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } const selectOnLoad = this.rootDoc[Id] === FormattedTextBox.SelectOnLoad; - if (selectOnLoad && !this.props.dontRegisterView) { + if (selectOnLoad && !this.props.dontRegisterView && !this.props.dontSelectOnLoad) { FormattedTextBox.SelectOnLoad = ""; this.props.select(false); if (FormattedTextBox.SelectOnLoadChar) { @@ -1314,7 +1316,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } if (!node && this.ProseRef) { const lastNode = this.ProseRef.children[this.ProseRef.children.length - 1].children[this.ProseRef.children[this.ProseRef.children.length - 1].children.length - 1]; // get the last prosemirror div - if (e.clientY > lastNode?.getBoundingClientRect().bottom) { // if we clicked below the last prosemirror div, then set the selection to be the end of the document + const boundsRect = lastNode?.getBoundingClientRect(); + if (e.clientX > boundsRect.left && e.clientX < boundsRect.right && + e.clientY > boundsRect.bottom) { // if we clicked below the last prosemirror div, then set the selection to be the end of the document + this._editorView?.focus(); this._editorView!.dispatch(this._editorView!.state.tr.setSelection(TextSelection.create(this._editorView!.state.doc, this._editorView!.state.doc.content.size))); } } else if ([this._editorView!.state.schema.nodes.ordered_list, this._editorView!.state.schema.nodes.listItem].includes(node?.type) && @@ -1473,7 +1478,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } @action tryUpdateHeight(limitHeight?: number) { - let scrollHeight = this._ref.current?.scrollHeight; + let scrollHeight = this.ProseRef?.scrollHeight || 0; if (this.props.renderDepth && this.layoutDoc._autoHeight && !this.props.ignoreAutoHeight && scrollHeight) { // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation scrollHeight = scrollHeight * NumCast(this.layoutDoc._viewScale, 1); if (limitHeight && scrollHeight > limitHeight) { @@ -1493,14 +1498,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp }, 10); } else { try { - this.layoutDoc._height = newHeight; + const boxHeight = Number(getComputedStyle(this._boxRef.current!).height.replace("px", "")); + const outer = this.rootDoc[HeightSym]() - boxHeight - (this.props.ChromeHeight ? this.props.ChromeHeight() : 0); + this.rootDoc._height = newHeight + outer; this.layoutDoc._nativeHeight = nh ? scrollHeight : undefined; } catch (e) { console.log("Error in tryUpdateHeight"); } } } } - @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "20%"); } + @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); } sidebarWidth = () => Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth(); sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()) / this.props.ContentScaling(), 0); @computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); } @@ -1516,7 +1523,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const selPad = this.props.isSelected() && !this.layoutDoc._singleLine ? -10 : 0; const selclass = this.props.isSelected() && !this.layoutDoc._singleLine ? "-selected" : ""; return ( -
}
- {this.props.isSelected() ?
: (null)} + {this.props.isSelected() ?
: (null)} } {!this.layoutDoc._showAudio ? (null) :
this._recording = !this._recording)} > diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts index 9895940d1..e77cc2692 100644 --- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts +++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts @@ -49,7 +49,7 @@ export function buildKeymap>(schema: S, props: any, mapKey /// bcz; Argh!! replace with an onEnter func that conditionally handles Enter const addTextBox = (below: boolean, force?: boolean) => { - if (props.LayoutTemplateString) return true; + if (props.Document.treeViewOutlineMode) return true; // bcz: Arghh .. need to determine if this is an treeViewOutlineBox in which case Enter's are ignored.. const layoutDoc = props.Document; const originalDoc = layoutDoc.rootDocument || layoutDoc; if (force || props.Document._singleLine) { -- cgit v1.2.3-70-g09d2 From 6c03a4ad74ca93311139e8fecda8a4793c103488 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 14 Sep 2020 22:17:54 -0400 Subject: updated header text view. fixed dragging tree view items to unregister listeners. fixed contextMenu icon selection to ignore dashFieldViews. fixed selectOnLoadChar to not apply when a childlayoutstring is specified. fixed dropping text box on item view to only use json parseable text. --- src/client/documents/Documents.ts | 1 + src/client/util/CurrentUserUtils.ts | 13 ++++++++-- src/client/views/DocumentButtonBar.tsx | 1 + src/client/views/PreviewCursor.tsx | 4 +-- src/client/views/collections/CollectionMenu.tsx | 6 +++-- .../views/collections/CollectionTreeView.tsx | 12 +++++++++ src/client/views/collections/TabDocView.tsx | 12 ++++++--- .../collectionFreeForm/CollectionFreeFormView.tsx | 4 +-- .../collections/collectionFreeForm/MarqueeView.tsx | 2 +- src/client/views/nodes/AudioBox.tsx | 4 +-- .../views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- src/client/views/nodes/ComparisonBox.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 6 ++--- .../nodes/formattedText/FormattedTextBox.scss | 5 +++- .../views/nodes/formattedText/FormattedTextBox.tsx | 29 +++++++++++++++------- 15 files changed, 73 insertions(+), 30 deletions(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.scss') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index d22e20101..0911f3e04 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -98,6 +98,7 @@ export interface DocumentOptions { layoutKey?: string; type?: string; title?: string; + version?: string; // version identifier for a document label?: string; hidden?: boolean; userDoc?: Doc; // the userDocument diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index b38cdabbc..6d4035b75 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -408,7 +408,7 @@ export class CurrentUserUtils { FormattedTextBox.SelectOnLoad = textDoc[Id]; doc.emptySlide = textDoc; } - if (doc.emptyHeader === undefined) { + if (doc.emptyHeader === undefined || (doc.emptyHeader as Doc).version !== "0") { const json = { doc: { type: "doc", @@ -428,7 +428,7 @@ export class CurrentUserUtils { selection: { type: "text", anchor: 1, head: 1 }, storedMarks: [] }; - const headerTemplate = Docs.Create.RTFDocument(new RichTextField(JSON.stringify(json), ""), { title: "header", target: doc, _headerHeight: 24, _headerFontSize: 9, _autoHeight: true, system: true, cloneFieldFilter: new List(["system"]) }, "header"); // text needs to be a space to allow templateText to be created + const headerTemplate = Docs.Create.RTFDocument(new RichTextField(JSON.stringify(json), ""), { title: "header", version: "0", target: doc, _height: 70, _headerHeight: 12, _headerFontSize: 9, _autoHeight: true, system: true, cloneFieldFilter: new List(["system"]) }, "header"); // text needs to be a space to allow templateText to be created headerTemplate[DataSym].layout = "
" + " " + @@ -1001,6 +1001,15 @@ export class CurrentUserUtils { doc["dockedBtn-undo"] && reaction(() => UndoManager.undoStack.slice(), () => Doc.GetProto(doc["dockedBtn-undo"] as Doc).opacity = UndoManager.CanUndo() ? 1 : 0.4, { fireImmediately: true }); doc["dockedBtn-redo"] && reaction(() => UndoManager.redoStack.slice(), () => Doc.GetProto(doc["dockedBtn-redo"] as Doc).opacity = UndoManager.CanRedo() ? 1 : 0.4, { fireImmediately: true }); + // uncomment this to setup a default note style that uses the custom header layout + PromiseValue(doc.emptyHeader).then(factory => { + if (Cast(doc.defaultTextLayout, Doc, null)?.version !== "0") { + const deleg = Doc.delegateDragFactory(factory as Doc); + deleg.title = "header"; + doc.defaultTextLayout = new PrefetchProxy(deleg); + Doc.AddDocToList(Cast(doc["template-notes"], Doc, null), "data", deleg); + } + }); return doc; } diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index e8b18fca4..7629ed173 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -298,6 +298,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV while (child.children.length) { const next = Array.from(child.children).find(c => typeof (c.className) === "string"); if (next?.className.includes("documentView-node")) break; + if (next?.className.includes("dashFieldView")) break; if (next) child = next; else break; } diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index 7575aa430..ee5a390a7 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -22,7 +22,7 @@ export class PreviewCursor extends React.Component<{}> { static _getTransform: () => Transform; static _addDocument: (doc: Doc | Doc[]) => void; static _addLiveTextDoc: (doc: Doc) => void; - static _nudge?: (x: number, y: number) => boolean; + static _nudge?: undefined | ((x: number, y: number) => boolean); @observable static _clickPoint = [0, 0]; @observable public static Visible = false; constructor(props: any) { @@ -158,7 +158,7 @@ export class PreviewCursor extends React.Component<{}> { addLiveText: (doc: Doc) => void, getTransform: () => Transform, addDocument: (doc: Doc | Doc[]) => boolean, - nudge: (nudgeX: number, nudgeY: number) => boolean) { + nudge: undefined | ((nudgeX: number, nudgeY: number) => boolean)) { this._clickPoint = [x, y]; this._onKeyPress = onKeyPress; this._addLiveTextDoc = addLiveText; diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 8342c5b12..9e67faed5 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -123,8 +123,10 @@ export class CollectionViewBaseChrome extends React.Component { - if (source.length === 1 && source[0].type === DocumentType.RTF && Cast(source[0].text, RichTextField, null)?.Text) { - Doc.SetInPlace(this.target, "childLayoutString", Cast(source[0].text, RichTextField, null)?.Text, false); + let formatStr = source.length && Cast(source[0].text, RichTextField, null)?.Text; + try { formatStr && JSON.parse(formatStr); } catch (e) { formatStr = ""; } + if (source.length === 1 && formatStr) { + Doc.SetInPlace(this.target, "childLayoutString", formatStr, false); } else if (source.length) { this.target.childLayoutTemplate = Doc.getDocTemplate(source?.[0]); } else { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 60ce7e001..463439762 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -145,15 +145,25 @@ class TreeView extends React.Component { } componentWillUnmount() { + console.log("DISMOUT" + this.doc.title); document.removeEventListener("pointermove", this.onDragMove, true); + document.removeEventListener("pointermove", this.onDragUp, true); } + onDragUp = (e: PointerEvent) => { + console.log("DUP" + this.doc.title); + document.removeEventListener("pointerup", this.onDragUp, true); + document.removeEventListener("pointermove", this.onDragMove, true); + } onPointerEnter = (e: React.PointerEvent): void => { this.props.active(true) && Doc.BrushDoc(this.dataDoc); if (e.buttons === 1 && SnappingManager.GetIsDragging()) { this._header!.current!.className = "treeViewItem-header"; document.removeEventListener("pointermove", this.onDragMove, true); document.addEventListener("pointermove", this.onDragMove, true); + document.removeEventListener("pointerup", this.onDragUp, true); + document.addEventListener("pointerup", this.onDragUp, true); + console.log("DSTART" + this.doc.title); } } onPointerLeave = (e: React.PointerEvent): void => { @@ -161,6 +171,8 @@ class TreeView extends React.Component { if (this._header?.current?.className !== "treeViewItem-header-editing") { this._header!.current!.className = "treeViewItem-header"; } + console.log("DLEAVE" + this.doc.title); + document.removeEventListener("pointerup", this.onDragUp, true); document.removeEventListener("pointermove", this.onDragMove, true); } onDragMove = (e: PointerEvent): void => { diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index f4fda67cd..62f6d50fc 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -28,6 +28,7 @@ import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormV import { CollectionViewType } from './CollectionView'; import React = require("react"); import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Tooltip } from '@material-ui/core'; const _global = (window /* browser */ || global /* node */) as any; interface TabDocViewProps { @@ -330,9 +331,12 @@ export class TabDocView extends React.Component { />
} -
e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this._document!.hideMinimap = !this._document!.hideMinimap; })} > - -
+ + {"toggle minimap"}
}> +
e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this._document!.hideMinimap = !this._document!.hideMinimap; })} > + +
+ ; } focusFunc = (doc: Doc, willZoom: boolean, scale?: number, afterFocus?: () => void) => afterFocus?.(); @@ -367,7 +371,7 @@ export class TabDocView extends React.Component { searchFilterDocs={CollectionDockingView.Instance.searchFilterDocs} ContainingCollectionView={undefined} ContainingCollectionDoc={undefined} /> - {this._document!._viewType !== CollectionViewType.Freeform ? (null) : this.renderMiniMap()} + {this._document._viewType !== CollectionViewType.Freeform ? (null) : this.renderMiniMap()} ; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 60e347786..ef58afeb5 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1116,8 +1116,8 @@ export class CollectionFreeFormView extends CollectionSubView SelectionManager.SelectDoc(DocumentManager.Instance.getDocumentView(slide)!, false)); e.stopPropagation(); } else if (!e.ctrlKey && !e.metaKey) { - FormattedTextBox.SelectOnLoadChar = FormattedTextBox.DefaultLayout ? e.key : ""; + FormattedTextBox.SelectOnLoadChar = FormattedTextBox.DefaultLayout && !this.props.ChildLayoutString ? e.key : ""; const tbox = Docs.Create.TextDocument("", { _width: 200, _height: 100, x: x, y: y, _autoHeight: true, _fontSize: StrCast(Doc.UserDoc().fontSize), _fontFamily: StrCast(Doc.UserDoc().fontFamily), diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 7658ee5cb..88f6a65be 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -535,7 +535,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent this.playLink(mark)} - pointerEvents={true} + pointerEvents={"all"} rootSelected={returnFalse} LayoutTemplate={undefined} ContainingCollectionDoc={this.props.Document} @@ -628,7 +628,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 3be32dce5..5df36435c 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -265,7 +265,7 @@ export class CollectionFreeFormDocumentView extends DocComponent {Doc.UserDoc().renderStyle !== "comic" ? (null) : diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index 616cddfcf..2af5b3182 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -74,7 +74,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent { return
e.stopPropagation()} // prevent triggering slider movement in registerSliding diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 771a8f526..15e571839 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -79,7 +79,7 @@ export interface DocumentViewProps { ContentScaling: () => number; PanelWidth: () => number; PanelHeight: () => number; - pointerEvents?: boolean; + pointerEvents?: string; focus: (doc: Doc, willZoom: boolean, scale?: number, afterFocus?: DocFocusFunc) => void; parentActive: (outsideReaction: boolean) => boolean; whenActiveChanged: (isActive: boolean) => void; @@ -960,7 +960,7 @@ export class DocumentView extends DocComponent(Docu dontRegisterView={false} forcedBackgroundColor={returnTransparent} removeDocument={this.hideLinkAnchor} - pointerEvents={false} + pointerEvents={"none"} LayoutTemplate={undefined} LayoutTemplateString={LinkAnchorBox.LayoutString(`anchor${Doc.LinkEndpoint(d, this.props.Document)}`)} />
); @@ -1017,7 +1017,7 @@ export class DocumentView extends DocComponent(Docu
; } @computed get ignorePointerEvents() { - return this.props.pointerEvents === false || + return this.props.pointerEvents === "none" || (SnappingManager.GetIsDragging() && this.Document["_isBackground-canClick"]) || (this.Document._isBackground && !this.isSelected() && !SnappingManager.GetIsDragging()) || (this.Document.type === DocumentType.INK && Doc.GetSelectedTool() !== InkTool.None); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss index 43e64d2d2..d1109b388 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.scss +++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss @@ -86,7 +86,9 @@ } .formattedTextBox-inner-rounded, .formattedTextBox-inner-rounded-selected, -.formattedTextBox-inner, .formattedTextBox-inner-selected { +.formattedTextBox-inner, +.formattedTextBox-inner-minimal, +.formattedTextBox-inner-selected { height: 100%; white-space: pre-wrap; .ProseMirror:hover { @@ -426,6 +428,7 @@ footnote::after { left: 10%; } + .formattedTextBox-inner-minimal, .formattedTextBox-inner-rounded, .formattedTextBox-inner { height: 100%; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index c6b4775c9..dc7d355b7 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -238,7 +238,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const tsel = this._editorView.state.selection.$from; tsel.marks().filter(m => m.type === this._editorView!.state.schema.marks.user_mark).map(m => AudioBox.SetScrubTime(Math.max(0, m.attrs.modified * 1000))); const curText = state.doc.textBetween(0, state.doc.content.size, " \n"); - const curTemp = Cast(this.layoutDoc[this.props.fieldKey], RichTextField); // the actual text in the text box + const curTemp = this.layoutDoc.resolvedDataDoc ? Cast(this.layoutDoc[this.props.fieldKey], RichTextField) : undefined; // the actual text in the text box const curProto = Cast(Cast(this.dataDoc.proto, Doc, null)?.[this.fieldKey], RichTextField, null); // the default text inherited from a prototype const curLayout = this.rootDoc !== this.layoutDoc ? Cast(this.layoutDoc[this.fieldKey], RichTextField, null) : undefined; // the default text stored in a layout template const json = JSON.stringify(state.toJSON()); @@ -247,7 +247,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const removeSelection = (json: string | undefined) => { return json?.indexOf("\"storedMarks\"") === -1 ? json?.replace(/"selection":.*/, "") : json?.replace(/"selection":"\"storedMarks\""/, "\"storedMarks\""); - } + }; if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) { if (!this._applyingChange && removeSelection(json) !== removeSelection(curProto?.Data)) { @@ -617,7 +617,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const appearanceItems = appearance && "subitems" in appearance ? appearance.subitems : []; appearanceItems.push({ description: "Change Perspective...", noexpand: true, subitems: changeItems, icon: "external-link-alt" }); // this.rootDoc.isTemplateDoc && appearanceItems.push({ description: "Make Default Layout", event: async () => Doc.UserDoc().defaultTextLayout = new PrefetchProxy(this.rootDoc), icon: "eye" }); - Doc.UserDoc().defaultTextLayout && appearanceItems.push({ description: "Reset default note style", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" }); + appearanceItems.push({ description: "Reset default note style", event: () => this.rootDoc.layoutKey = "layout", icon: "eye" }); appearanceItems.push({ description: "Make Default Layout", event: () => { if (!this.layoutDoc.isTemplateDoc) { @@ -1155,9 +1155,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp if (FormattedTextBox.SelectOnLoadChar && this._editorView) { const $from = this._editorView.state.selection.anchor ? this._editorView.state.doc.resolve(this._editorView.state.selection.anchor - 1) : undefined; const mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) }); - const curMarks = this._editorView!.state.storedMarks ?? $from?.marksAcross(this._editorView.state.selection.$head) ?? []; + const curMarks = this._editorView.state.storedMarks ?? $from?.marksAcross(this._editorView.state.selection.$head) ?? []; const storedMarks = [...curMarks.filter(m => m.type !== mark.type), mark]; - this._editorView.dispatch(this._editorView!.state.tr.setStoredMarks(storedMarks).insertText(FormattedTextBox.SelectOnLoadChar).setStoredMarks(storedMarks)); + this._editorView.dispatch(this._editorView.state.tr.setStoredMarks(storedMarks).insertText(FormattedTextBox.SelectOnLoadChar).setStoredMarks(storedMarks)); FormattedTextBox.SelectOnLoadChar = ""; } else if (curText?.Text) { selectAll(this._editorView!.state, this._editorView?.dispatch); @@ -1496,7 +1496,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const nh = this.layoutDoc.isTemplateForField ? 0 : NumCast(this.layoutDoc._nativeHeight, 0); const dh = NumCast(this.rootDoc._height, 0); const newHeight = Math.max(10, (nh ? dh / nh * scrollHeight : scrollHeight) + (this.props.ChromeHeight ? this.props.ChromeHeight() : 0)); - if (this.rootDoc !== this.layoutDoc.doc && !this.layoutDoc.resolvedDataDoc) { + if (!this.props.LayoutTemplateString && this.rootDoc !== this.layoutDoc.doc && !this.layoutDoc.resolvedDataDoc) { // if we have a template that hasn't been resolved yet, we can't set the height or we'd be setting it on the unresolved template. So set a timeout and hope its arrived... console.log("Delayed height adjustment..."); setTimeout(() => { @@ -1505,6 +1505,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp }, 10); } else { try { + // let ele = this._boxRef.current; + // while (ele && ele.className !== "documentView-contentsView") ele = ele.parentElement as any; + // if (ele) { + // const docHeight = Number(getComputedStyle(ele).height.replace("px", "")); + // const boxHeight = Number(getComputedStyle(this._boxRef.current!).height.replace("px", "")); + // const outer = docHeight - boxHeight - (this.props.ChromeHeight ? this.props.ChromeHeight() : 0); + // this.rootDoc._height = newHeight + outer; + // this.layoutDoc._nativeHeight = nh ? scrollHeight : undefined; + // } const boxHeight = Number(getComputedStyle(this._boxRef.current!).height.replace("px", "")); const outer = this.rootDoc[HeightSym]() - boxHeight - (this.props.ChromeHeight ? this.props.ChromeHeight() : 0); this.rootDoc._height = newHeight + outer; @@ -1527,7 +1536,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp if (!this.props.isSelected() && FormattedTextBoxComment.textBox === this) { setTimeout(() => FormattedTextBoxComment.Hide(), 0); } - const selPad = this.props.isSelected() && !this.layoutDoc._singleLine ? -10 : 0; + const minimal = this.props.ignoreAutoHeight; + const selPad = (this.props.isSelected() && !this.layoutDoc._singleLine) || minimal ? -10 : 0; const selclass = this.props.isSelected() && !this.layoutDoc._singleLine ? "-selected" : ""; return (
-
-- cgit v1.2.3-70-g09d2 From 1cb5ac5e07ad90589670a788e3144d9d9581a393 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 29 Sep 2020 15:03:16 -0400 Subject: made pdf/web anchors pushpins by default. can now remove docs you own from sidebars you don't. made formatted text boxes alway show sidebar handle when there's content. sidebar text has no padding by default. sidebar collection doesn't scroll when text overflows. added more playground fields --- src/client/documents/Documents.ts | 21 ++++++++++++ src/client/util/CurrentUserUtils.ts | 3 +- src/client/views/DocComponent.tsx | 3 +- src/client/views/MainView.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 1 + .../collectionFreeForm/CollectionFreeFormView.tsx | 6 ++++ .../collections/collectionFreeForm/MarqueeView.tsx | 2 +- src/client/views/nodes/FilterBox.tsx | 2 +- src/client/views/nodes/WebBox.tsx | 1 + .../nodes/formattedText/FormattedTextBox.scss | 18 +++++----- .../views/nodes/formattedText/FormattedTextBox.tsx | 40 ++++++++++++++++------ src/client/views/pdf/PDFViewer.tsx | 3 +- 12 files changed, 76 insertions(+), 26 deletions(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.scss') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 19f719c43..ad30e7d33 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -889,6 +889,27 @@ export namespace Docs { } export namespace DocUtils { + export function Excluded(d: Doc, docFilters: string[]) { + const filterFacets: { [key: string]: { [value: string]: string } } = {}; // maps each filter key to an object with value=>modifier fields + for (let i = 0; i < docFilters.length; i += 3) { + const [key, value, modifiers] = docFilters.slice(i, i + 3); + if (!filterFacets[key]) { + filterFacets[key] = {}; + } + filterFacets[key][value] = modifiers; + } + + if (d.z) return false; + for (const facetKey of Object.keys(filterFacets)) { + const facet = filterFacets[facetKey]; + const xs = Object.keys(facet).filter(value => facet[value] === "x"); + const failsNotEqualFacets = xs?.some(value => Doc.matchFieldValue(d, facetKey, value)); + if (failsNotEqualFacets) { + return true; + } + } + return false; + } export function FilterDocs(docs: Doc[], docFilters: string[], docRangeFilters: string[], viewSpecScript?: ScriptField) { const childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs; diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 342954a4e..3e76b189a 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1127,8 +1127,9 @@ export class CurrentUserUtils { CurrentUserUtils.openDashboard(userDoc, dashboardDoc); } - public static GetNewTextDoc(title: string, x: number, y: number, width?: number, height?: number) { + public static GetNewTextDoc(title: string, x: number, y: number, width?: number, height?: number, noMargins?: boolean) { const tbox = Docs.Create.TextDocument("", { + _xMargin: noMargins ? 0 : undefined, _yMargin: noMargins ? 0 : undefined, _width: width || 200, _height: height || 100, x: x, y: y, _autoHeight: true, _fontSize: StrCast(Doc.UserDoc().fontSize), _fontFamily: StrCast(Doc.UserDoc().fontFamily), title }); diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index b3c90a68f..893b74d75 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -123,7 +123,8 @@ export function ViewBoxAnnotatableComponent

doc.isPushpin = doc.annotationOn = undefined); const targetDataDoc = this.dataDoc; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 4299dba86..5469c2358 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -86,7 +86,7 @@ export class MainView extends React.Component { document.getElementById("root")?.addEventListener("scroll", e => ((ele) => ele.scrollLeft = ele.scrollTop = 0)(document.getElementById("root")!)); new InkStrokeProperties(); this._sidebarContent.proto = undefined; - DocServer.setPlaygroundFields(["dataTransition", "_viewTransition", "_panX", "_panY", "_viewScale", "_scrollY", "_scrollTop", "hidden", "_curPage", "_viewType", "_chromeStatus"]); // can play with these fields on someone else's + DocServer.setPlaygroundFields(["dataTransition", "_delayAutoHeight", "_autoHeight", "_showSidebar", "_sidebarWidthPercent", "_width", "_height", "_viewTransition", "_panX", "_panY", "_viewScale", "_scrollY", "_scrollTop", "hidden", "_curPage", "_viewType", "_chromeStatus"]); // 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))); diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 26fe00657..649b8c175 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -142,6 +142,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: const docsforFilter: Doc[] = []; childDocs.forEach((d) => { + if (DocUtils.Excluded(d, docFilters)) return; let notFiltered = d.z || ((!searchDocs.length || searchDocs.includes(d)) && ((!docFilters.length && !docRangeFilters.length) || DocUtils.FilterDocs([d], docFilters, docRangeFilters, viewSpecScript).length > 0)); const fieldKey = Doc.LayoutFieldKey(d); const annos = !Field.toString(Doc.LayoutField(d) as Field).includes("CollectionView"); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 967055638..a3f76839d 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1625,6 +1625,12 @@ class CollectionFreeFormViewPannableContents extends React.Component { + const target = e.target as any; + if (getComputedStyle(target.parentElement)?.overflow === "visible") { // if collection is visible, then scrolling will mess things up since there are no scroll bars + target.scrollTop = target.scrollLeft = 0; + } + }} style={{ transform: `translate(${cenx}px, ${ceny}px) scale(${zoom}) translate(${panx}px, ${pany}px)`, transition: this.props.transition, diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index e1ebb4eee..7c64fd429 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -141,7 +141,7 @@ export class MarqueeView extends React.Component(noviceFields); this.allDocs.forEach(doc => SearchBox.documentKeys(doc).filter(key => keys.add(key))); - return Array.from(keys.keys()).filter(key => key[0] === "#" || key.indexOf("lastModified") !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith("_") && !key.startsWith("acl")) || noviceFields.includes(key)).sort(); + return Array.from(keys.keys()).filter(key => key[0] === "#" || key.indexOf("lastModified") !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith("_")) || noviceFields.includes(key) || !Doc.UserDoc().noviceMode).sort(); } gatherFieldValues(dashboard: Doc, facetKey: string) { diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index a7b534956..421aac69f 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -508,6 +508,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, - action(() => { + () => setTimeout(action(() => { const prevWidth = this.sidebarWidth(); this.layoutDoc._showSidebar = ((this.layoutDoc._sidebarWidthPercent = StrCast(this.layoutDoc._sidebarWidthPercent, "0%") === "0%" ? "50%" : "0%")) !== "0%"; this.layoutDoc._width = this.layoutDoc._showSidebar ? NumCast(this.layoutDoc._width) * 2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth); - })); + })), false); } sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => { const bounds = this.CurrentDiv.getBoundingClientRect(); @@ -1524,6 +1524,25 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } + @computed get audioHandle() { + return !this.layoutDoc._showAudio ? (null) : +

this._recording = !this._recording)} > + +
; + } + + @computed get sidebarHandle() { + const annotated = DocListCast(this.dataDoc[this.annotationKey]).length; + return !this.props.isSelected() && !(annotated && !this.sidebarWidth()) ? (null) : +
{ + console.log(e); + }} + />; + } + @computed get sidebarCollection() { const fitToBox = this.props.Document._fitToBox; return !this.layoutDoc._showSidebar || this.sidebarWidthPercent === "0%" ? (null) : @@ -1531,6 +1550,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props)); // need to make sure that we update a text box that is selected after updating the one that was deselected if (!selected && FormattedTextBoxComment.textBox === this) { FormattedTextBoxComment.Hide(); } const minimal = this.props.ignoreAutoHeight; - const selPad = (selected && !this.layoutDoc._singleLine) || minimal ? -10 : 0; - const selclass = selected && !this.layoutDoc._singleLine ? "-selected" : ""; + const margins = NumCast(this.layoutDoc._yMargin, this.props.yMargin || 0); + const selPad = Math.min(margins, 10); + const padding = Math.max(margins + ((selected && !this.layoutDoc._singleLine) || minimal ? -selPad : 0), 0); + const selclass = selected && !this.layoutDoc._singleLine && margins >= 10 ? "-selected" : ""; return (
{this.sidebarCollection} - {selected ?
: (null)} - {!this.layoutDoc._showAudio ? (null) : -
this._recording = !this._recording)} > - -
} + {this.sidebarHandle} + {this.audioHandle}
); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index fb87da744..77dd40f2a 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -642,6 +642,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent