aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes
diff options
context:
space:
mode:
authorusodhi <61431818+usodhi@users.noreply.github.com>2021-03-10 11:57:30 -0500
committerusodhi <61431818+usodhi@users.noreply.github.com>2021-03-10 11:57:30 -0500
commit89b7b2ae27cbab6a7edd5fa3759949afe2cd2f71 (patch)
treee3d034d928a63f478ea705c083a3f74764e38d03 /src/client/views/nodes
parente7dd6dbdf8d01cef390ff65c0948e5e70ac232cf (diff)
parent80597c4780b1e8833d3742339836815d388356d2 (diff)
conflicts
Diffstat (limited to 'src/client/views/nodes')
-rw-r--r--src/client/views/nodes/DocHolderBox.scss15
-rw-r--r--src/client/views/nodes/DocHolderBox.tsx212
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx3
-rw-r--r--src/client/views/nodes/DocumentLinksButton.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx6
-rw-r--r--src/client/views/nodes/FilterBox.tsx56
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx190
7 files changed, 126 insertions, 358 deletions
diff --git a/src/client/views/nodes/DocHolderBox.scss b/src/client/views/nodes/DocHolderBox.scss
deleted file mode 100644
index 6a9ef0b6f..000000000
--- a/src/client/views/nodes/DocHolderBox.scss
+++ /dev/null
@@ -1,15 +0,0 @@
-.documentBox-container {
- width: 100%;
- height: 100%;
- pointer-events: all;
- position: absolute;
- .documentBox-lock {
- margin: auto;
- color: white;
- position: absolute;
- padding: 3px;
- }
- .contentFittingDocumentView {
- position: absolute;
- }
-} \ No newline at end of file
diff --git a/src/client/views/nodes/DocHolderBox.tsx b/src/client/views/nodes/DocHolderBox.tsx
deleted file mode 100644
index 765751a65..000000000
--- a/src/client/views/nodes/DocHolderBox.tsx
+++ /dev/null
@@ -1,212 +0,0 @@
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, IReactionDisposer, reaction } from "mobx";
-import { observer } from "mobx-react";
-import { Doc, Field } from "../../../fields/Doc";
-import { collectionSchema, documentSchema } from "../../../fields/documentSchemas";
-import { listSpec, makeInterface } from "../../../fields/Schema";
-import { ComputedField } from "../../../fields/ScriptField";
-import { Cast, NumCast, StrCast } from "../../../fields/Types";
-import { TraceMobx } from "../../../fields/util";
-import { returnFalse } from "../../../Utils";
-import { DocumentType } from "../../documents/DocumentTypes";
-import { DragManager } from "../../util/DragManager";
-import { undoBatch } from "../../util/UndoManager";
-import { ContextMenu } from "../ContextMenu";
-import { ContextMenuProps } from "../ContextMenuItem";
-import { ViewBoxAnnotatableComponent } from "../DocComponent";
-import { StyleProp } from "../StyleProvider";
-import "./DocHolderBox.scss";
-import { DocumentView } from "./DocumentView";
-import { FieldView, FieldViewProps } from "./FieldView";
-import React = require("react");
-
-type DocHolderBoxSchema = makeInterface<[typeof documentSchema, typeof collectionSchema]>;
-const DocHolderBoxDocument = makeInterface(documentSchema, collectionSchema);
-
-@observer
-export class DocHolderBox extends ViewBoxAnnotatableComponent<FieldViewProps, DocHolderBoxSchema>(DocHolderBoxDocument) {
- public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DocHolderBox, fieldKey); }
- _prevSelectionDisposer: IReactionDisposer | undefined;
- _dropDisposer?: DragManager.DragDropDisposer;
- _selections: Doc[] = [];
- _contRef = React.createRef<HTMLDivElement>();
- _curSelection = -1;
- componentDidMount() {
- this._prevSelectionDisposer = reaction(() => this.dataDoc[this.fieldKey], (data) => {
- if (data instanceof Doc && !this.isSelectionLocked()) {
- this._selections.indexOf(data) !== -1 && this._selections.splice(this._selections.indexOf(data), 1);
- this._selections.push(data);
- this._curSelection = this._selections.length - 1;
- }
- });
- }
- componentWillUnmount() {
- this._prevSelectionDisposer?.();
- }
- specificContextMenu = (e: React.MouseEvent): void => {
- const funcs: ContextMenuProps[] = [];
- funcs.push({ description: (this.isSelectionLocked() ? "Show" : "Lock") + " Selection", event: () => this.toggleLockSelection, icon: "expand-arrows-alt" });
- funcs.push({ description: (this.layoutDoc.excludeCollections ? "Include" : "Exclude") + " Collections", event: () => this.layoutDoc.excludeCollections = !this.layoutDoc.excludeCollections, icon: "expand-arrows-alt" });
- funcs.push({ description: `${this.layoutDoc.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.layoutDoc.forceActive = !this.layoutDoc.forceActive, icon: "project-diagram" });
- funcs.push({ description: `Show ${this.layoutDoc.childLayoutTemplateName !== "keyValue" ? "key values" : "contents"}`, event: () => this.layoutDoc.childLayoutString = this.layoutDoc.childLayoutString ? undefined : "<KeyValueBox {...props} />", icon: "project-diagram" });
-
- ContextMenu.Instance.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
- }
- lockSelection = () => {
- this.dataDoc[this.fieldKey] = this.dataDoc[this.fieldKey];
- }
- showSelection = () => {
- this.dataDoc[this.fieldKey] = ComputedField.MakeFunction(`selectedDocs(self,this.excludeCollections,[_last_])?.[0]`);
- }
- isSelectionLocked = () => {
- const kvpstring = Field.toKeyValueString(this.dataDoc, this.fieldKey);
- return !kvpstring || kvpstring.includes("DOC");
- }
- toggleLockSelection = () => {
- !this.isSelectionLocked() ? this.lockSelection() : this.showSelection();
- return true;
- }
- prevSelection = () => {
- this.lockSelection();
- if (this._curSelection > 0) {
- this.dataDoc[this.fieldKey] = this._selections[--this._curSelection];
- return true;
- }
- }
- nextSelection = () => {
- if (this._curSelection < this._selections.length - 1 && this._selections.length) {
- this.dataDoc[this.fieldKey] = this._selections[++this._curSelection];
- return true;
- }
- }
- onPointerDown = (e: React.PointerEvent) => {
- if (this.active() && e.button === 0 && !e.ctrlKey) {
- e.stopPropagation();
- }
- }
- onLockClick = (e: React.MouseEvent) => {
- this.toggleLockSelection();
- (e.nativeEvent as any).formattedHandled = true;
- e.stopPropagation();
- }
- get xPad() { return NumCast(this.rootDoc._xPadding); }
- get yPad() { return NumCast(this.rootDoc._yPadding); }
- onClick = (e: React.MouseEvent) => {
- let hitWidget: boolean | undefined = false;
- if (this._contRef.current!.getBoundingClientRect().top + this.yPad > e.clientY) hitWidget = (() => { this.props.select(false); return true; })();
- else if (this._contRef.current!.getBoundingClientRect().bottom - this.yPad < e.clientY) hitWidget = (() => { this.props.select(false); return true; })();
- else {
- if (this._contRef.current!.getBoundingClientRect().left + this.xPad > e.clientX) hitWidget = this.prevSelection();
- if (this._contRef.current!.getBoundingClientRect().right - this.xPad < e.clientX) hitWidget = this.nextSelection();
- }
- if (hitWidget) {
- (e.nativeEvent as any).formattedHandled = true;
- e.stopPropagation();
- }
- }
- pwidth = () => this.props.PanelWidth() - 2 * this.xPad;
- pheight = () => this.props.PanelHeight() - 2 * this.yPad;
- getTransform = () => this.props.ScreenToLocalTransform().translate(-this.xPad, -this.yPad);
- isActive = (outsideReaction: boolean) => this.active(outsideReaction) || this.props.renderDepth <= 1;
- layoutTemplateDoc = () => Cast(this.layoutDoc.childLayoutTemplate, Doc, null);
- get renderContents() {
- const containedDoc = Cast(this.dataDoc[this.fieldKey], Doc, null);
- const layoutTemplate = StrCast(this.layoutDoc.childLayoutString);
- const contents = !(containedDoc instanceof Doc) ||
- Cast(containedDoc[Doc.LayoutFieldKey(containedDoc)], listSpec(Doc), null)?.includes(this.rootDoc)
- ? (null) : this.layoutDoc.childLayoutString || this.layoutTemplateDoc() ?
- <DocumentView
- Document={containedDoc}
- DataDoc={undefined}
- docFilters={this.props.docFilters}
- docRangeFilters={this.props.docRangeFilters}
- searchFilterDocs={this.props.searchFilterDocs}
- ContainingCollectionView={this as any} // bcz: hack! need to pass a prop that can be used to select the container (ie, 'this') when the up selector in document decorations is clicked. currently, the up selector allows only a containing collection to be selected
- ContainingCollectionDoc={undefined}
- styleProvider={this.props.styleProvider}
- layerProvider={this.props.layerProvider}
- docViewPath={this.props.docViewPath}
- LayoutTemplateString={layoutTemplate}
- LayoutTemplate={this.layoutTemplateDoc}
- rootSelected={this.props.isSelected}
- addDocument={this.props.addDocument}
- moveDocument={this.props.moveDocument}
- removeDocument={this.props.removeDocument}
- addDocTab={this.props.addDocTab}
- pinToPres={this.props.pinToPres}
- ScreenToLocalTransform={this.getTransform}
- renderDepth={containedDoc.type !== DocumentType.DOCHOLDER && !this.props.renderDepth ? 0 : this.props.renderDepth + 1}
- PanelWidth={this.pwidth}
- PanelHeight={this.pheight}
- focus={this.props.focus}
- parentActive={this.isActive}
- dontRegisterView={true}
- whenActiveChanged={this.props.whenActiveChanged}
- bringToFront={returnFalse} /> :
- <DocumentView
- Document={containedDoc}
- DataDoc={undefined}
- docFilters={this.props.docFilters}
- docRangeFilters={this.props.docRangeFilters}
- searchFilterDocs={this.props.searchFilterDocs}
- ContainingCollectionView={this as any} // bcz: hack! need to pass a prop that can be used to select the container (ie, 'this') when the up selector in document decorations is clicked. currently, the up selector allows only a containing collection to be selected
- ContainingCollectionDoc={undefined}
- styleProvider={this.props.styleProvider}
- layerProvider={this.props.layerProvider}
- docViewPath={this.props.docViewPath}
- ignoreAutoHeight={true}
- LayoutTemplateString={layoutTemplate}
- LayoutTemplate={this.layoutTemplateDoc}
- rootSelected={this.props.isSelected}
- addDocument={this.props.addDocument}
- moveDocument={this.props.moveDocument}
- removeDocument={this.props.removeDocument}
- addDocTab={this.props.addDocTab}
- pinToPres={this.props.pinToPres}
- ScreenToLocalTransform={this.getTransform}
- renderDepth={containedDoc.type !== DocumentType.DOCHOLDER && !this.props.renderDepth ? 0 : this.props.renderDepth + 1}
- PanelWidth={this.pwidth}
- PanelHeight={this.pheight}
- focus={this.props.focus}
- parentActive={this.isActive}
- dontRegisterView={true}
- whenActiveChanged={this.props.whenActiveChanged}
- bringToFront={returnFalse}
- />;
- return contents;
- }
- render() {
- const containedDoc = Cast(this.dataDoc[this.fieldKey], Doc, null);
- TraceMobx();
- return !containedDoc ? (null) : <div className="documentBox-container" ref={this._contRef}
- onContextMenu={this.specificContextMenu}
- onPointerDown={this.onPointerDown} onClick={this.onClick}
- style={{
- background: this.props.styleProvider?.(containedDoc, this.props, StyleProp.BackgroundColor),
- border: `#00000021 solid ${this.xPad}px`,
- borderTop: `#0000005e solid ${this.yPad}px`,
- borderBottom: `#0000005e solid ${this.yPad}px`,
- }}>
- {this.renderContents}
- <div className="documentBox-lock" onClick={this.onLockClick} ref={this.createDropTarget}
- style={{ marginTop: - this.yPad, background: "black" }}>
- <FontAwesomeIcon icon={this.isSelectionLocked() ? "lock" : "unlock"} size="sm" />
- </div>
- </div >;
- }
-
- @undoBatch
- @action
- drop = (e: Event, de: DragManager.DropEvent) => {
- const docDragData = de.complete.docDragData;
- if (docDragData?.draggedDocuments[0].type === DocumentType.FONTICON) {
- const doc = Cast(docDragData.draggedDocuments[0].dragFactory, Doc, null);
- this.layoutDoc.childLayoutTemplate = doc;
- }
- }
- protected createDropTarget = (ele: HTMLDivElement) => {
- this._dropDisposer?.();
- ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.rootDoc));
- }
-
-}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 32542d056..2f7923574 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -16,7 +16,6 @@ import { FunctionPlotBox } from "./FunctionPlotBox";
import { SliderBox } from "./SliderBox";
import { LinkBox } from "./LinkBox";
import { ScriptingBox } from "./ScriptingBox";
-import { DocHolderBox } from "./DocHolderBox";
import { DocumentViewProps } from "./DocumentView";
import "./DocumentView.scss";
import { FontIconBox } from "./FontIconBox";
@@ -225,7 +224,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & Fo
FormattedTextBox, ImageBox, DirectoryImportBox, FontIconBox, LabelBox, EquationBox, SliderBox, FieldView,
CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox,
PDFBox, VideoBox, AudioBox, PresBox, YoutubeBox, PresElementBox, SearchBox, FilterBox, FunctionPlotBox,
- ColorBox, DashWebRTCVideo, LinkAnchorBox, InkingStroke, DocHolderBox, LinkBox, ScriptingBox,
+ ColorBox, DashWebRTCVideo, LinkAnchorBox, InkingStroke, LinkBox, ScriptingBox,
ScreenshotBox, HTMLtag, ComparisonBox
}}
bindings={bindings}
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 085ffae26..d62061aea 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -280,7 +280,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
TraceMobx();
const menuTitle = this.props.StartLink ? "Drag or tap to start link" : "Tap to complete link";
- const buttonTitle = "Tap to view links";
+ const buttonTitle = "Tap to view links; double tap to open link collection";
const title = this.props.InMenu ? menuTitle : buttonTitle;
return !Array.from(this.filteredLinks).length && !this.props.AlwaysOn ? (null) :
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 83022a759..ebc65002f 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -286,7 +286,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
handle1PointerMove = (e: TouchEvent, me: InteractionUtils.MultiTouchEvent<TouchEvent>) => {
- if ((e as any).formattedHandled) { e.stopPropagation; return; }
if (e.cancelBubble && this.active) {
this.removeMoveListeners();
}
@@ -475,7 +474,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
} else clickFunc();
} else if (this.Document["onClick-rawScript"] && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) {// bcz: hack? don't edit a script if you're clicking on a scripting box itself
this.props.addDocTab(DocUtils.makeCustomViewClicked(Doc.MakeAlias(this.props.Document), undefined, "onClick"), "add:right");
- } else if (this.allLinks && this.Document.isLinkButton && !e.shiftKey && !e.ctrlKey && !(e.nativeEvent as any).formattedHandled) {
+ } else if (this.allLinks && this.Document.isLinkButton && !e.shiftKey && !e.ctrlKey) {
this.allLinks.length && LinkManager.FollowLink(undefined, this.props.Document, this.props, e.altKey);
} else {
if ((this.layoutDoc.onDragStart || this.props.Document.rootDocument) && !(e.ctrlKey || e.button > 0)) { // onDragStart implies a button doc that we don't want to select when clicking. RootDocument & isTemplaetForField implies we're clicking on part of a template instance and we want to select the whole template, not the part
@@ -517,13 +516,10 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
document.removeEventListener("pointerup", this.onPointerUp);
document.addEventListener("pointermove", this.onPointerMove);
document.addEventListener("pointerup", this.onPointerUp);
-
- if ((e.nativeEvent as any).formattedHandled) { e.stopPropagation(); }
}
}
onPointerMove = (e: PointerEvent): void => {
- if ((e as any).formattedHandled) { e.stopPropagation(); return; }
if ((InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || Doc.GetSelectedTool() === InkTool.Highlighter || Doc.GetSelectedTool() === InkTool.Pen)) return;
if (e.cancelBubble && this.active) {
document.removeEventListener("pointermove", this.onPointerMove); // stop listening to pointerMove if something else has stopPropagated it (e.g., the MarqueeView)
diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx
index a4ae0b5a3..0f8dcad9d 100644
--- a/src/client/views/nodes/FilterBox.tsx
+++ b/src/client/views/nodes/FilterBox.tsx
@@ -1,8 +1,8 @@
import React = require("react");
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, observable, runInAction } from "mobx";
+import { computed, observable, action, trace, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { DataSym, Doc, DocListCast, DocListCastAsync, Field, Opt } from "../../../fields/Doc";
+import { DataSym, Doc, DocListCast, Field, Opt, DocListCastAsync } from "../../../fields/Doc";
import { documentSchema } from "../../../fields/documentSchemas";
import { List } from "../../../fields/List";
import { RichTextField } from "../../../fields/RichTextField";
@@ -19,8 +19,6 @@ import { SearchBox } from "../search/SearchBox";
import { FieldView, FieldViewProps } from './FieldView';
import './FilterBox.scss';
import { Scripting } from "../../util/Scripting";
-import { values } from "lodash";
-import { tokenToString } from "typescript";
import { SelectionManager } from "../../util/SelectionManager";
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
@@ -59,10 +57,20 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
return FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document;
}
+ @observable _loaded = false;
+ componentDidMount() {
+ reaction(() => DocListCastAsync(CollectionDockingView.Instance.props.Document.data),
+ async (activeTabsAsync) => {
+ const activeTabs = await activeTabsAsync;
+ activeTabs && (await SearchBox.foreachRecursiveDocAsync(activeTabs, emptyFunction));
+ runInAction(() => this._loaded = true);
+ }, { fireImmediately: true });
+ }
@computed get allDocs() {
+ trace();
const allDocs = new Set<Doc>();
const targetDoc = FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document;
- if (targetDoc) {
+ if (this._loaded && targetDoc) {
const activeTabs = DocListCast(targetDoc.data);
SearchBox.foreachRecursiveDoc(activeTabs, (doc: Doc) => allDocs.add(doc));
setTimeout(() => targetDoc.allDocuments = new List<Doc>(Array.from(allDocs)));
@@ -71,6 +79,7 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
}
@computed get _allFacets() {
+ trace();
const noviceReqFields = ["author", "tags", "text", "type"];
const noviceLayoutFields: string[] = [];//["_curPage"];
const noviceFields = [...noviceReqFields, ...noviceLayoutFields];
@@ -200,12 +209,12 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
const scriptText = `setDocFilter(this?.target, "${facetHeader}", text, "match")`;
newFacet.onTextChanged = ScriptField.MakeScript(scriptText, { this: Doc.name, text: "string" });
} else if (facetHeader !== "tags" && nonNumbers / facetValues.strings.length < .1) {
- newFacet = Docs.Create.SliderDocument({ title: facetHeader, _overflow: "visible", _height: 40, _stayInCollection: true, _hideContextMenu: true, treeViewExpandedView: "layout", treeViewOpen: true });
+ newFacet = Docs.Create.SliderDocument({ title: facetHeader, _overflow: "visible", _fitWidth: true, _height: 40, _stayInCollection: true, _hideContextMenu: true, treeViewExpandedView: "layout", treeViewOpen: true });
const newFacetField = Doc.LayoutFieldKey(newFacet);
const ranged = Doc.readDocRangeFilter(targetDoc, facetHeader);
Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox
- const extendedMinVal = minVal - Math.min(1, Math.abs(maxVal - minVal) * .05);
- const extendedMaxVal = maxVal + Math.min(1, Math.abs(maxVal - minVal) * .05);
+ const extendedMinVal = minVal - Math.min(1, Math.floor(Math.abs(maxVal - minVal) * .1));
+ const extendedMaxVal = maxVal + Math.min(1, Math.ceil(Math.abs(maxVal - minVal) * .05));
newFacet[newFacetField + "-min"] = ranged === undefined ? extendedMinVal : ranged[0];
newFacet[newFacetField + "-max"] = ranged === undefined ? extendedMaxVal : ranged[1];
Doc.GetProto(newFacet)[newFacetField + "-minThumb"] = extendedMinVal;
@@ -218,8 +227,8 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
newFacet.title = facetHeader;
newFacet.treeViewOpen = true;
newFacet.type = DocumentType.COL;
- const capturedVariables = { layoutDoc: targetDoc, system: true, _stayInCollection: true, _hideContextMenu: true, dataDoc: (targetDoc.data as any)[0][DataSym] };
- newFacet.data = ComputedField.MakeFunction(`readFacetData(layoutDoc, "${facetHeader}")`, {}, capturedVariables);
+ newFacet.target = targetDoc;
+ newFacet.data = ComputedField.MakeFunction(`readFacetData(self.target, "${facetHeader}")`);
}
newFacet && Doc.AddDocToList(this.dataDoc, this.props.fieldKey, newFacet);
}
@@ -345,6 +354,26 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
value={null}
closeMenuOnSelect={false}
/>
+ {/* @computed get flyoutpanel() {
+ return <div className="filterBox-flyout" style={{ width: `100%`, height: this.props.PanelHeight() - 30 }} onWheel={e => e.stopPropagation()}>
+ {this._allFacets.map(facet => <label className="filterBox-flyout-facet" key={`${facet}`} onClick={e => this.facetClick(facet)}>
+ <input type="checkbox" onChange={emptyFunction} checked={DocListCast(this.props.Document[this.props.fieldKey]).some(d => d.title === facet)} />
+ <span className="checkmark" />
+ {facet}
+ </label>)}
+ </div>;
+ }
+ render() {
+ const facetCollection = this.props.Document;
+
+ return this.props.dontRegisterView ? (null) : <div className="filterBox-treeView" style={{ width: "100%" }}>
+ <div className="filterBox-addFacet" style={{ width: "100%" }} onPointerDown={e => e.stopPropagation()}>
+ <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={this.flyoutpanel}>
+ <div className="filterBox-addFacetButton">
+ <FontAwesomeIcon icon={"edit"} size={"lg"} />
+ <span className="filterBox-span">Choose Facets</span>
+ </div>
+ </Flyout> */}
</div>
<div className="filterBox-tree" key="tree">
@@ -451,7 +480,7 @@ Scripting.addGlobal(function determineCheckedState(layoutDoc: Doc, facetHeader:
}
return undefined;
});
-Scripting.addGlobal(function readFacetData(layoutDoc: Doc, facetHeader: string) {
+Scripting.addGlobal(function readFacetData(targetDoc: Doc, facetHeader: string) {
const allCollectionDocs = DocListCast(CollectionDockingView.Instance?.props.Document.allDocuments);
const set = new Set<string>();
if (facetHeader === "tags") allCollectionDocs.forEach(child => Field.toString(child[facetHeader] as Field).split(":").forEach(key => set.add(key)));
@@ -464,7 +493,10 @@ Scripting.addGlobal(function readFacetData(layoutDoc: Doc, facetHeader: string)
const doc = new Doc();
doc.system = true;
doc.title = facetValue.toString();
- doc.treeViewChecked = ComputedField.MakeFunction("determineCheckedState(layoutDoc, facetHeader, facetValue)", {}, { layoutDoc, facetHeader, facetValue });
+ doc.target = targetDoc;
+ doc.facetHeader = facetHeader;
+ doc.facetValue = facetValue;
+ doc.treeViewChecked = ComputedField.MakeFunction("determineCheckedState(self.target, self.facetHeader, self.facetValue)");
return doc;
});
return new List<Doc>(facetValueDocSet);
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 0f669a544..ad11d55bf 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -15,7 +15,7 @@ import { DataSym, Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, Wid
import { documentSchema } from '../../../../fields/documentSchemas';
import applyDevTools = require("prosemirror-dev-tools");
import { removeMarkWithAttrs } from "./prosemirrorPatches";
-import { Id, Copy } from '../../../../fields/FieldSymbols';
+import { Id } from '../../../../fields/FieldSymbols';
import { InkTool } from '../../../../fields/InkField';
import { PrefetchProxy } from '../../../../fields/Proxy';
import { RichTextField } from "../../../../fields/RichTextField";
@@ -90,11 +90,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
public static get DefaultLayout() {
return Cast(Doc.UserDoc().defaultTextLayout, Doc, null) || StrCast(Doc.UserDoc().defaultTextLayout, null);
}
- public static CanAnnotate = true;
public static Instance: FormattedTextBox;
- public ProseRef?: HTMLDivElement;
- public get EditorView() { return this._editorView; }
- public get SidebarKey() { return this.fieldKey + "-sidebar"; }
+ public static LiveTextUndo: UndoManager.Batch | undefined;
+ static _highlights: string[] = ["Audio Tags", "Text from Others", "Todo Items", "Important Items", "Disagree Items", "Ignore Items"];
+ static _highlightStyleSheet: any = addStyleSheet();
+ static _bulletStyleSheet: any = addStyleSheet();
+ static _userStyleSheet: any = addStyleSheet();
+ static _canAnnotate = true;
+ static _hadSelection: boolean = false;
private _ref: React.RefObject<HTMLDivElement> = React.createRef();
private _scrollRef: React.RefObject<HTMLDivElement> = React.createRef();
private _editorView: Opt<EditorView>;
@@ -111,6 +114,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
private _focusSpeed: Opt<number>;
private _keymap: any = undefined;
private _rules: RichTextRules | undefined;
+ private _forceUncollapse = true; // if the cursor doesn't move between clicks, then the selection will disappear for some reason. This flags the 2nd click as happening on a selection which allows bullet points to toggle
+ private _forceDownNode: Node | undefined;
+ private _downEvent: any;
+ private _downX = 0;
+ private _downY = 0;
+ private _break = false;
+ public ProseRef?: HTMLDivElement;
+ public get EditorView() { return this._editorView; }
+ public get SidebarKey() { return this.fieldKey + "-sidebar"; }
@computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); }
@computed get sidebarColor() { return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "#e4e4e4")); }
@@ -121,10 +133,26 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
@computed get titleHeight() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin) || 0; }
@computed get _recording() { return this.dataDoc?.audioState === "recording"; }
set _recording(value) { this.dataDoc.audioState = value ? "recording" : undefined; }
+ @computed get config() {
+ this._keymap = buildKeymap(schema, this.props);
+ this._rules = new RichTextRules(this.props.Document, this);
+ return {
+ schema,
+ plugins: [
+ inputRules(this._rules.inpRules),
+ this.richTextMenuPlugin(),
+ history(),
+ keymap(this._keymap),
+ keymap(baseKeymap),
+ new Plugin({ props: { attributes: { class: "ProseMirror-example-setup-style" } } }),
+ new Plugin({ view(editorView) { return new FormattedTextBoxComment(editorView); } })
+ ]
+ };
+ }
public static FocusedBox: FormattedTextBox | undefined;
- public static SelectOnLoad = "";
public static PasteOnLoad: ClipboardEvent | undefined;
+ public static SelectOnLoad = "";
public static SelectOnLoadChar = "";
public static IsFragment(html: string) { return html.indexOf("data-pm-slice") !== -1; }
public static GetHref(html: string): string {
@@ -205,9 +233,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.rootDoc, this.getAnchor, targetCreator), e.pageX, e.pageY);
});
- const coordsT = this._editorView!.coordsAtPos(this._editorView!.state.selection.to);
const coordsB = this._editorView!.coordsAtPos(this._editorView!.state.selection.to);
- this.props.isSelected(true) && AnchorMenu.Instance.jumpTo(Math.min(coordsT.left, coordsB.left), Math.max(coordsT.bottom, coordsB.bottom));
+ this.props.isSelected(true) && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom);
}
dispatchTransaction = (tx: Transaction) => {
@@ -315,7 +342,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
// needs a better API for taking in a set of words with target documents instead of just one target
- public hyperlinkTerms = (terms: string[], target: Doc) => {
+ hyperlinkTerms = (terms: string[], target: Doc) => {
if (this._editorView && (this._editorView as any).docView && terms.some(t => t)) {
const res1 = terms.filter(t => t).map(term => this.findInNode(this._editorView!, this._editorView!.state.doc, term));
let tr = this._editorView.state.tr;
@@ -335,7 +362,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
this._editorView.dispatch(tr);
}
}
- public highlightSearchTerms = (terms: string[], backward: boolean) => {
+ highlightSearchTerms = (terms: string[], backward: boolean) => {
if (this._editorView && (this._editorView as any).docView && terms.some(t => t)) {
const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight);
const activeMark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight, { selected: true });
@@ -364,7 +391,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
}
- public unhighlightSearchTerms = () => {
+ unhighlightSearchTerms = () => {
if (window.screen.width < 600) null;
else if (this._editorView && (this._editorView as any).docView) {
const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight);
@@ -407,18 +434,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
// embed document when dragg marked as embed
} else if (de.embedKey) {
const target = dragData.droppedDocuments[0];
- // const link = DocUtils.MakeLink({ doc: this.dataDoc, ctx: this.props.ContainingCollectionDoc }, { doc: target }, "Embedded Doc:" + target.title);
- // if (link) {
target._fitToBox = true;
const node = schema.nodes.dashDoc.create({
width: target[WidthSym](), height: target[HeightSym](),
- title: "dashDoc", docid: target[Id],
+ title: "dashDoc",
+ docid: target[Id],
float: "right"
});
const view = this._editorView!;
view.dispatch(view.state.tr.insert(view.posAtCoords({ left: de.x, top: de.y })!.pos, node));
e.stopPropagation();
- // }
} // otherwise, fall through to outer collection to handle drop
}
}
@@ -467,7 +492,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
return ret;
}
- static _highlights: string[] = ["Audio Tags", "Text from Others", "Todo Items", "Important Items", "Disagree Items", "Ignore Items"];
updateHighlights = () => {
clearStyleSheetRules(FormattedTextBox._userStyleSheet);
if (FormattedTextBox._highlights.indexOf("Audio Tags") === -1) {
@@ -551,9 +575,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}, icon: "expand-arrows-alt"
}));
-
const uicontrols: ContextMenuProps[] = [];
- uicontrols.push({ description: `${FormattedTextBox.CanAnnotate ? "Hide" : "Show"} Annotation Bar`, event: () => FormattedTextBox.CanAnnotate = !FormattedTextBox.CanAnnotate, icon: "expand-arrows-alt" });
+ uicontrols.push({ description: `${FormattedTextBox._canAnnotate ? "Hide" : "Show"} Annotation Bar`, event: () => FormattedTextBox._canAnnotate = !FormattedTextBox._canAnnotate, icon: "expand-arrows-alt" });
uicontrols.push({ description: !this.Document._noSidebar ? "Hide Sidebar Handle" : "Show Sidebar Handle", event: () => this.layoutDoc._noSidebar = !this.layoutDoc._noSidebar, icon: "expand-arrows-alt" });
uicontrols.push({ description: `${this.layoutDoc._showAudio ? "Hide" : "Show"} Dictation Icon`, event: () => this.layoutDoc._showAudio = !this.layoutDoc._showAudio, icon: "expand-arrows-alt" });
uicontrols.push({ description: "Show Highlights...", noexpand: true, subitems: highlighting, icon: "hand-point-right" });
@@ -612,10 +635,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
if (results && [DictationManager.Controls.Infringed].includes(results)) {
DictationManager.Controls.stop();
}
- //this._editorView!.focus();
});
}
- stopDictation = (abort: boolean) => { DictationManager.Controls.stop(!abort); };
+ stopDictation = (abort: boolean) => DictationManager.Controls.stop(!abort);
setDictationContent = (value: string) => {
if (this._editorView) {
@@ -643,26 +665,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
}
- @computed get config() {
- this._keymap = buildKeymap(schema, this.props);
- this._rules = new RichTextRules(this.props.Document, this);
- return {
- schema,
- plugins: [
- inputRules(this._rules.inpRules),
- this.richTextMenuPlugin(),
- history(),
- keymap(this._keymap),
- keymap(baseKeymap),
- new Plugin({
- props: {
- attributes: { class: "ProseMirror-example-setup-style" }
- }
- }), new Plugin({ view(editorView) { return new FormattedTextBoxComment(editorView); } })
- ]
- };
- }
-
makeLinkAnchor(anchorDoc?: Doc, location?: string, targetHref?: string, title?: string) {
const state = this._editorView?.state;
if (state) {
@@ -692,10 +694,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
return anchorDoc ?? this.rootDoc;
}
- IsActive = () => {
- return this.active();//this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0;
- }
-
scrollFocus = (doc: Doc, smooth: boolean) => {
const anchorId = doc[Id];
const findAnchorFrag = (frag: Fragment, editor: EditorView) => {
@@ -753,7 +751,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
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.
- this.props.contentsActive?.(this.IsActive);
+ this.props.contentsActive?.(this.active);
this._cachedLinks = DocListCast(this.Document.links);
this._disposers.autoHeight = reaction(() => ({ scrollHeight: this.scrollHeight, autoHeight: this.autoHeight, width: NumCast(this.layoutDoc._width) }),
({ width, autoHeight, scrollHeight }) => width && autoHeight && this.resetNativeHeight(scrollHeight)
@@ -771,7 +769,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
instance => {
if (instance) {
this.pullFromGoogleDoc(this.checkState);
- this.dataDoc[GoogleRef] && this.dataDoc.unchanged && runInAction(() => instance.isAnimatingFetch = true);
+ this.dataDoc[GoogleRef] && this.dataDoc.googleDocUnchanged && runInAction(() => instance.isAnimatingFetch = true);
}
}
);
@@ -801,8 +799,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
() => {
if (!DocumentButtonBar.hasPulledHack) {
DocumentButtonBar.hasPulledHack = true;
- const unchanged = this.dataDoc.unchanged;
- this.pullFromGoogleDoc(unchanged ? this.checkState : this.updateState);
+ this.pullFromGoogleDoc(this.dataDoc.googleDocUnchanged ? this.checkState : this.updateState);
}
}
);
@@ -877,19 +874,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
const response = await GoogleApiClientUtils.Docs.write({ reference, content, mode });
response && (this.dataDoc[GoogleRef] = response.documentId);
const pushSuccess = response !== undefined && !("errors" in response);
- dataDoc.unchanged = pushSuccess;
+ dataDoc.googleDocUnchanged = pushSuccess;
DocumentButtonBar.Instance.startPushOutcome(pushSuccess);
}
};
const undo = () => {
- if (!exportState) {
- return;
- }
- const content: GoogleApiClientUtils.Docs.Content = {
- text: exportState.text,
- requests: []
- };
- if (reference && content) {
+ if (exportState && reference) {
+ const content: GoogleApiClientUtils.Docs.Content = {
+ text: exportState.text,
+ requests: []
+ };
GoogleApiClientUtils.Docs.write({ reference, content, mode });
}
};
@@ -922,7 +916,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}, 0);
dataDoc.title = exportState.title;
this.dataDoc["title-custom"] = true;
- dataDoc.unchanged = true;
+ dataDoc.googleDocUnchanged = true;
} else {
delete dataDoc[GoogleRef];
}
@@ -934,7 +928,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
const equalContent = isEqual(this._editorView.state.doc, exportState.state.doc);
const equalTitles = dataDoc.title === exportState.title;
const unchanged = equalContent && equalTitles;
- dataDoc.unchanged = unchanged;
+ dataDoc.googleDocUnchanged = unchanged;
DocumentButtonBar.Instance.setPullState(unchanged);
}
}
@@ -1094,7 +1088,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
selectAll(this._editorView!.state, this._editorView?.dispatch);
this.startUndoTypingBatch();
}
-
}
selectOnLoad && this._editorView!.focus();
// add user mark for any first character that was typed since the user mark that gets set in KeyPress won't have been called yet.
@@ -1112,11 +1105,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none");
}
- _downEvent: any;
- _downX = 0;
- _downY = 0;
- _break = false;
- _collapsed = false;
onPointerDown = (e: React.PointerEvent): void => {
if ((e.target as any).tagName === "AUDIOTAG") {
e.preventDefault();
@@ -1164,9 +1152,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
document.removeEventListener("pointerup", this.onSelectEnd);
document.removeEventListener("pointermove", this.onSelectMove);
}
-
onPointerUp = (e: React.PointerEvent): void => {
- if (!this._editorView?.state.selection.empty && FormattedTextBox.CanAnnotate) this.setupAnchorMenu();
+ if (!this._editorView?.state.selection.empty && FormattedTextBox._canAnnotate) this.setupAnchorMenu();
if (!this._downEvent) return;
this._downEvent = false;
if (!(e.nativeEvent as any).formattedHandled && this.active(true)) {
@@ -1183,13 +1170,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
e.stopPropagation();
}
}
-
@action
onDoubleClick = (e: React.MouseEvent): void => {
FormattedTextBoxComment.textBox = this;
if (e.button === 0 && this.props.isSelected(true) && !e.altKey && !e.ctrlKey && !e.metaKey) {
if (e.clientX < this.ProseRef!.getBoundingClientRect().right) { // stop propagation if not in sidebar
- e.stopPropagation(); // if the text box is selected, then it consumes all down events
+ e.stopPropagation(); // if the text box is selected, then it consumes all click events
}
}
if (e.button === 2 || (e.button === 0 && e.ctrlKey)) {
@@ -1203,7 +1189,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
e.stopPropagation();
}
}
-
@action
onFocused = (e: React.FocusEvent): void => {
FormattedTextBox.FocusedBox = this;
@@ -1230,17 +1215,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
}
onPointerWheel = (e: React.WheelEvent): void => {
- // if a text note is not selected and scrollable, this prevents us from being able to scroll and zoom out at the same time
+ // if a text note is selected and scrollable, stop event to prevent, say, outer collection from zooming.
if ((this.props.rootSelected(true) || this.props.isSelected(true)) || e.currentTarget.scrollHeight > e.currentTarget.clientHeight) {
e.stopPropagation();
}
}
-
- static _highlightStyleSheet: any = addStyleSheet();
- static _bulletStyleSheet: any = addStyleSheet();
- static _userStyleSheet: any = addStyleSheet();
- _forceUncollapse = true; // if the cursor doesn't move between clicks, then the selection will disappear for some reason. This flags the 2nd click as happening on a selection which allows bullet points to toggle
- _forceDownNode: Node | undefined;
onClick = (e: React.MouseEvent): void => {
if (Math.abs(e.clientX - this._downX) > 4 || Math.abs(e.clientY - this._downY) > 4) {
this._forceDownNode = undefined;
@@ -1276,7 +1255,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
this._forceUncollapse = !(this._editorView!.root as any).getSelection().isCollapsed;
this._forceDownNode = (this._editorView!.state.selection as NodeSelection)?.node;
}
-
// this hackiness handles clicking on the list item bullets to do expand/collapse. the bullets are ::before pseudo elements so there's no real way to hit test against them.
hitBulletTargets(x: number, y: number, collapse: boolean, highlightOnly: boolean, downNode: Node | undefined = undefined, selectOrderedList: boolean = false) {
this._forceUncollapse = false;
@@ -1302,8 +1280,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
if (selectOrderedList || (!collapse && listNode.attrs.visibility)) {
this._editorView.dispatch(this._editorView.state.tr.setSelection(new NodeSelection(selectOrderedList ? $olistPos! : listPos!)));
} else if (!listNode.attrs.visibility || downNode === listNode) {
- this._editorView.dispatch(this._editorView.state.tr.setNodeMarkup(clickPos.pos, listNode.type, { ...listNode.attrs, visibility: !listNode.attrs.visibility }));
- this._editorView.dispatch(this._editorView.state.tr.setSelection(TextSelection.create(this._editorView.state.doc, clickPos.pos)));
+ const tr = this._editorView.state.tr.setNodeMarkup(clickPos.pos, listNode.type, { ...listNode.attrs, visibility: !listNode.attrs.visibility });
+ this._editorView.dispatch(tr.setSelection(TextSelection.create(tr.doc, clickPos.pos)));
}
}
addStyleSheetRule(FormattedTextBox._bulletStyleSheet, olistNode.attrs.mapStyle + olistNode.attrs.bulletStyle + ":hover:before", { background: "lightgray" });
@@ -1321,30 +1299,25 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
view.root.removeEventListener("mouseup", originalUpHandler);
view.mouseDown.up = (e: MouseEvent) => {
!(e as any).formattedHandled && originalUpHandler(e);
- // e.stopPropagation();
(e as any).formattedHandled = true;
};
view.root.addEventListener("mouseup", view.mouseDown.up);
}
}
-
- public startUndoTypingBatch() {
+ startUndoTypingBatch() {
!this._undoTyping && (this._undoTyping = UndoManager.StartBatch("undoTyping"));
}
-
public endUndoTypingBatch() {
const wasUndoing = this._undoTyping;
this._undoTyping?.end();
this._undoTyping = undefined;
return wasUndoing;
}
- public static LiveTextUndo: UndoManager.Batch | undefined;
- public static HadSelection: boolean = false;
onBlur = (e: any) => {
if (RichTextMenu.Instance?.view === this._editorView && !this.props.isSelected(true)) {
RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined);
}
- FormattedTextBox.HadSelection = window.getSelection()?.toString() !== "";
+ FormattedTextBox._hadSelection = window.getSelection()?.toString() !== "";
this.endUndoTypingBatch();
FormattedTextBox.LiveTextUndo?.end();
@@ -1363,7 +1336,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
this._lastText = curText;
}
}
-
onKeyDown = (e: React.KeyboardEvent) => {
// single line text boxes need to pass through tab/enter/backspace so that their containers can respond (eg, an outline container)
if (this.rootDoc._singleLine && ((e.key === "Backspace" && !this.dataDoc[this.fieldKey]?.Text) || ["Tab", "Enter"].includes(e.key))) {
@@ -1385,36 +1357,33 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
this._rules!.EnteringStyle = false;
}
e.stopPropagation();
- if (e.key === "Escape") {
- this._editorView!.dispatch(state.tr.setSelection(TextSelection.create(state.doc, state.selection.from, state.selection.from)));
- (document.activeElement as any).blur?.();
- SelectionManager.DeselectAll();
- RichTextMenu.Instance.updateMenu(undefined, undefined, undefined);
- } else {
- if (e.key === "Tab" || e.key === "Enter") {
- if (e.key === "Enter") this.insertTime();
- e.preventDefault();
- }
- if (e.key === " " || this._lastTimedMark?.attrs.userid !== Doc.CurrentUserEmail) {
- const mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) });
- this._editorView!.dispatch(this._editorView!.state.tr.removeStoredMark(schema.marks.user_mark.create({})).addStoredMark(mark));
- }
- this.startUndoTypingBatch();
+ switch (e.key) {
+ case "Escape":
+ this._editorView!.dispatch(state.tr.setSelection(TextSelection.create(state.doc, state.selection.from, state.selection.from)));
+ (document.activeElement as any).blur?.();
+ SelectionManager.DeselectAll();
+ RichTextMenu.Instance.updateMenu(undefined, undefined, undefined);
+ return;
+ case "Enter": this.insertTime();
+ case "Tab": e.preventDefault(); break;
+ default: if (this._lastTimedMark?.attrs.userid === Doc.CurrentUserEmail) break;
+ case " ":
+ this._editorView!.dispatch(this._editorView!.state.tr.removeStoredMark(schema.marks.user_mark.create({}))
+ .addStoredMark(schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) })));
}
+ this.startUndoTypingBatch();
}
-
- ondrop = (eve: React.DragEvent) => {
+ ondrop = (e: React.DragEvent) => {
this._editorView!.dispatch(updateBullets(this._editorView!.state.tr, this._editorView!.state.schema));
- eve.stopPropagation(); // drag n drop of text within text note will generate a new note if not caughst, as will dragging in from outside of Dash.
+ e.stopPropagation(); // drag n drop of text within text note will generate a new note if not caughst, as will dragging in from outside of Dash.
}
- onScroll = (ev: React.UIEvent) => {
+ onScroll = (e: React.UIEvent) => {
if (!LinkDocPreview.LinkInfo && this._scrollRef.current) {
this._ignoreScroll = true;
this.layoutDoc._scrollTop = this._scrollRef.current.scrollTop;
this._ignoreScroll = false;
}
}
-
tryUpdateScrollHeight() {
const proseHeight = this.ProseRef?.scrollHeight || 0;
const scrollHeight = this.ProseRef && Math.min(NumCast(this.layoutDoc.docMaxAutoHeight, proseHeight), proseHeight);
@@ -1425,7 +1394,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
} else setTimeout(setScrollHeight, 10); // 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...
}
}
-
fitToBox = () => this.props.Document._fitToBox;
sidebarContentScaling = () => (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1);
sidebarAddDocument = (doc: Doc | Doc[]) => this.addDocument(doc, this.SidebarKey);
@@ -1442,7 +1410,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
@computed get sidebarHandle() {
const annotated = DocListCast(this.dataDoc[this.SidebarKey]).filter(d => d?.author).length;
- return <div className="formattedTextBox-sidebar-handle" onPointerDown={this.sidebarDown}
+ return (!annotated && !this.active()) ? (null) : <div className="formattedTextBox-sidebar-handle" onPointerDown={this.sidebarDown}
style={{
left: `max(0px, calc(100% - ${this.sidebarWidthPercent} ${this.sidebarWidth() ? "- 5px" : "- 10px"}))`,
background: this.props.styleProvider?.(this.props.Document, this.props, StyleProp.WidgetColor + (annotated ? ":annotated" : ""))
@@ -1489,7 +1457,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
const scale = this.props.hideOnLeave ? 1 : (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1);
const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
const interactive = (Doc.GetSelectedTool() === InkTool.None || SnappingManager.GetIsDragging()) && (this.layoutDoc.z || this.props.layerProvider?.(this.layoutDoc) !== false);
- if (!selected && FormattedTextBoxComment.textBox === this) setTimeout(() => FormattedTextBoxComment.Hide());
+ if (!selected && FormattedTextBoxComment.textBox === this) setTimeout(FormattedTextBoxComment.Hide);
const minimal = this.props.ignoreAutoHeight;
const margins = NumCast(this.layoutDoc._yMargin, this.props.yMargin || 0);
const selPad = Math.min(margins, 10);