aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Utils.ts9
-rw-r--r--src/client/documents/Documents.ts5
-rw-r--r--src/client/util/CurrentUserUtils.ts7
-rw-r--r--src/client/views/DocumentDecorations.tsx20
-rw-r--r--src/client/views/Main.tsx5
-rw-r--r--src/client/views/MarqueeAnnotator.tsx2
-rw-r--r--src/client/views/SidebarAnnos.tsx25
-rw-r--r--src/client/views/StyleProvider.tsx3
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx8
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx5
-rw-r--r--src/client/views/collections/TreeView.tsx33
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx6
-rw-r--r--src/client/views/nodes/DocumentView.tsx6
-rw-r--r--src/client/views/nodes/ImageBox.tsx4
-rw-r--r--src/client/views/nodes/WebBox.tsx11
-rw-r--r--src/client/views/nodes/button/FontIconBox.tsx15
-rw-r--r--src/client/views/nodes/formattedText/DashFieldView.tsx22
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx22
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx21
-rw-r--r--src/client/views/topbar/TopBar.tsx2
20 files changed, 145 insertions, 86 deletions
diff --git a/src/Utils.ts b/src/Utils.ts
index 9d3b9eb2b..22c8cb902 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -686,8 +686,9 @@ export function DashColor(color: string) {
try {
return color ? Color(color.toLowerCase()) : Color('transparent');
} catch (e) {
- console.log('COLOR error:', e);
- return Color('red');
+ if (color.includes('gradient')) console.log("using color 'white' in place of :" + color);
+ else console.log('COLOR error:', e);
+ return Color('white');
}
}
@@ -816,7 +817,7 @@ export function setupMoveUpEvents(
(target as any)._noClick = clickEvent(e, (target as any)._doubleTap);
}
document.removeEventListener('pointermove', _moveEvent);
- document.removeEventListener('pointerup', _upEvent);
+ document.removeEventListener('pointerup', _upEvent, true);
};
const _clickEvent = (e: MouseEvent): void => {
if ((target as any)._noClick) e.stopPropagation();
@@ -827,6 +828,6 @@ export function setupMoveUpEvents(
e.preventDefault();
}
document.addEventListener('pointermove', _moveEvent);
- document.addEventListener('pointerup', _upEvent);
+ document.addEventListener('pointerup', _upEvent, true);
document.addEventListener('click', _clickEvent, true);
}
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 3faa6e11d..debb11066 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -224,6 +224,7 @@ export class DocumentOptions {
contextMenuScripts?: List<ScriptField>;
contextMenuLabels?: List<string>;
contextMenuIcons?: List<string>;
+ allowClickBeforeDoubleClick?: boolean; // whether a click function can fire before the timeout for a double click has expired
dontUndo?: boolean; // whether button clicks should be undoable (this is set to true for Undo/Redo/and sidebar buttons that open the siebar panel)
description?: string; // added for links
layout?: string | Doc; // default layout string for a document
@@ -583,7 +584,7 @@ export namespace Docs {
DocumentType.FONTICON,
{
layout: { view: FontIconBox, dataField: defaultDataKey },
- options: { hideLinkButton: true, _width: 40, _height: 40, borderRounding: '100%', links: '@links(self)' },
+ options: { allowClickBeforeDoubleClick: true, hideLinkButton: true, _width: 40, _height: 40, borderRounding: '100%', links: '@links(self)' },
},
],
[
@@ -1808,7 +1809,7 @@ export namespace DocUtils {
_yMargin: noMargins ? 0 : undefined,
annotationOn,
docMaxAutoHeight: maxHeight,
- backgroundColor: backgroundColor,
+ backgroundColor,
_width: width || 200,
_height: 35,
x: x,
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index f678c8936..3d95cb947 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -612,6 +612,7 @@ export class CurrentUserUtils {
btnList: new List<string>(["Roboto", "Roboto Mono", "Nunito", "Times New Roman", "Arial", "Georgia", "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"]) },
{ title: "Size", toolTip: "Font size", width: 75, btnType: ButtonType.NumberButton, ignoreClick: true, scripts: {script: '{ return setFontSize(value, _readOnly_);}'}, numBtnMax: 200, numBtnMin: 0, numBtnType: NumButtonType.DropdownOptions },
{ title: "Color", toolTip: "Font color", btnType: ButtonType.ColorButton, icon: "font", ignoreClick: true, scripts: {script: '{ return setFontColor(value, _readOnly_);}'}},
+ { title: "Highlight",toolTip:"Font highlight", btnType: ButtonType.ColorButton, icon: "highlighter", ignoreClick: true, scripts: {script: '{ return setFontHighlight(value, _readOnly_);}'},funcs: {hidden: "IsNoviceMode()"} },
{ title: "Bold", toolTip: "Bold (Ctrl+B)", btnType: ButtonType.ToggleButton, icon: "bold", scripts: {onClick: '{ return toggleBold(_readOnly_); }'} },
{ title: "Italic", toolTip: "Italic (Ctrl+I)", btnType: ButtonType.ToggleButton, icon: "italic", scripts: {onClick: '{ return toggleItalic(_readOnly_);}'} },
{ title: "Under", toolTip: "Underline (Ctrl+U)", btnType: ButtonType.ToggleButton, icon: "underline", scripts: {onClick: '{ return toggleUnderline(_readOnly_);}'} },
@@ -635,9 +636,9 @@ export class CurrentUserUtils {
{ title: "Write", toolTip: "Write (Ctrl+Shift+P)", btnType: ButtonType.ToggleButton, icon: "pen", scripts: {onClick:'{ return setActiveTool("write", false, _readOnly_);}'} },
{ title: "Eraser", toolTip: "Eraser (Ctrl+E)", btnType: ButtonType.ToggleButton, icon: "eraser", scripts: {onClick:'{ return setActiveTool("eraser", false, _readOnly_);}' }},
// { title: "Highlighter", toolTip: "Highlighter (Ctrl+H)", btnType: ButtonType.ToggleButton, icon: "highlighter", scripts:{onClick: 'setActiveTool("highlighter")'} },
- { title: "Circle", toolTip: "Circle (double tap to lock mode)", btnType: ButtonType.ToggleButton, icon: "circle", scripts: {onClick:`{ return setActiveTool("${GestureUtils.Gestures.Circle}", false, _readOnly_);}`, onDoubleClick:`{ return setActiveTool("${GestureUtils.Gestures.Circle}", true, _readOnly_);}`} },
- { title: "Square", toolTip: "Square (double tap to lock mode)", btnType: ButtonType.ToggleButton, icon: "square", scripts: {onClick:`{ return setActiveTool("${GestureUtils.Gestures.Rectangle}", false, _readOnly_);}`, onDoubleClick:`{ return setActiveTool("${GestureUtils.Gestures.Rectangle}", true, _readOnly_);}`} },
- { title: "Line", toolTip: "Line (double tap to lock mode)", btnType: ButtonType.ToggleButton, icon: "minus", scripts: {onClick:`{ return setActiveTool("${GestureUtils.Gestures.Line}", false, _readOnly_);}`, onDoubleClick:`{ return setActiveTool("${GestureUtils.Gestures.Line}", true, _readOnly_);}`} },
+ { title: "Circle", toolTip: "Circle (double tap to lock mode)", btnType: ButtonType.ToggleButton, icon: "circle", scripts: {onClick:`{ return setActiveTool("${GestureUtils.Gestures.Circle}", false, _readOnly_);}`, onDoubleClick:`{ return setActiveTool("${GestureUtils.Gestures.Circle}", true, _readOnly_);}`} },
+ { title: "Square", toolTip: "Square (double tap to lock mode)", btnType: ButtonType.ToggleButton, icon: "square", scripts: {onClick:`{ return setActiveTool("${GestureUtils.Gestures.Rectangle}", false, _readOnly_);}`, onDoubleClick:`{ return setActiveTool("${GestureUtils.Gestures.Rectangle}", true, _readOnly_);}`} },
+ { title: "Line", toolTip: "Line (double tap to lock mode)", btnType: ButtonType.ToggleButton, icon: "minus", scripts: {onClick:`{ return setActiveTool("${GestureUtils.Gestures.Line}", false, _readOnly_);}`, onDoubleClick:`{ return setActiveTool("${GestureUtils.Gestures.Line}", true, _readOnly_);}`} },
{ title: "Mask", toolTip: "Mask", btnType: ButtonType.ToggleButton, icon: "user-circle", scripts: {onClick:'{ return setIsInkMask(_readOnly_);}'} },
{ title: "Fill", toolTip: "Fill color", btnType: ButtonType.ColorButton, icon: "fill-drip",ignoreClick: true, scripts: {script: '{ return setFillColor(value, _readOnly_);}'} },
{ title: "Width", toolTip: "Stroke width", btnType: ButtonType.NumberButton, ignoreClick: true, scripts: {script: '{ return setStrokeWidth(value, _readOnly_);}'}, numBtnType: NumButtonType.Slider, numBtnMin: 1},
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 41f4a17fb..21f63ada4 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -2,7 +2,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@material-ui/core';
import { IconButton } from 'browndash-components';
-import { action, computed, observable, reaction } from 'mobx';
+import { action, computed, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { FaUndo } from 'react-icons/fa';
import { DateField } from '../../fields/DateField';
@@ -182,7 +182,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
dragData.removeDocument = dragDocView.props.removeDocument;
dragData.isDocDecorationMove = true;
dragData.canEmbed = dragTitle;
- this._hidden = this.Interacting = true;
+ this._hidden = true;
DragManager.StartDocumentDrag(
SelectionManager.Views().map(dv => dv.ContentDiv!),
dragData,
@@ -191,7 +191,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
{
dragComplete: action(e => {
dragData.canEmbed && SelectionManager.DeselectAll();
- this._hidden = this.Interacting = false;
+ this._hidden = false;
}),
hideSource: true,
}
@@ -293,7 +293,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
*/
@action
onRadiusDown = (e: React.PointerEvent): void => {
- this._isRounding = true;
+ this._isRounding = DocumentDecorations.Instance.Interacting = true;
this._resizeUndo = UndoManager.StartBatch('DocDecs set radius');
// Call util move event function
setupMoveUpEvents(
@@ -316,10 +316,11 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
return false;
}, // moveEvent
action(e => {
- this._isRounding = false;
+ DocumentDecorations.Instance.Interacting = this._isRounding = false;
this._resizeUndo?.end();
}), // upEvent
- e => {} // clickEvent
+ e => {}, // clickEvent,
+ true
);
};
@@ -710,11 +711,14 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
return this._rotCenter;
}
+ @observable _showNothing = true;
+
render() {
const { b, r, x, y } = this.Bounds;
const bounds = { b, r, x, y };
- const seldocview = SelectionManager.Views().slice(-1)[0];
+ const seldocview = SelectionManager.Views().lastElement();
if (SnappingManager.GetIsDragging() || bounds.r - bounds.x < 1 || bounds.x === Number.MAX_VALUE || !seldocview || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) {
+ setTimeout(action(() => (this._showNothing = true)));
return null;
}
// hide the decorations if the parent chooses to hide it or if the document itself hides it
@@ -812,7 +816,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
</div>
);
return (
- <div className={`documentDecorations${colorScheme}`}>
+ <div className={`documentDecorations${colorScheme}`} style={{ opacity: this._showNothing ? 0.1 : undefined }} onPointerOver={action(e => (this._showNothing = false))}>
<div
className="documentDecorations-background"
style={{
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index e0b4c5159..6b18caed0 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -22,7 +22,8 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0 }; // bcz: not sure
(async () => {
MainView.Live = window.location.search.includes('live');
- ReactDOM.createRoot(document.getElementById('root')!).render(<FieldLoader />);
+ const root = ReactDOM.createRoot(document.getElementById('root')!);
+ root.render(<FieldLoader />);
window.location.search.includes('safe') && CollectionView.SetSafeMode(true);
const info = await CurrentUserUtils.loadCurrentUser();
if (info.email === 'guest') DocServer.Control.makeReadOnly();
@@ -47,6 +48,6 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0 }; // bcz: not sure
new LinkManager();
new TrackMovements();
new ReplayMovements();
- ReactDOM.createRoot(document.getElementById('root')!).render(<MainView />);
+ root.render(<MainView />);
}, 0);
})();
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index 5ab91dd70..3bdf65d01 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -49,7 +49,7 @@ export class MarqueeAnnotator extends React.Component<MarqueeAnnotatorProps> {
super(props);
AnchorMenu.Instance.OnCrop = (e: PointerEvent) => this.props.anchorMenuCrop?.(this.highlight('', true), true);
- AnchorMenu.Instance.OnClick = (e: PointerEvent) => this.props.anchorMenuClick?.()?.(this.highlight(this.props.highlightDragSrcColor ?? 'rgba(173, 216, 230, 0.75)', true));
+ AnchorMenu.Instance.OnClick = (e: PointerEvent) => this.props.anchorMenuClick?.()?.(this.highlight(this.props.highlightDragSrcColor ?? 'rgba(173, 216, 230, 0.75)', true, undefined, true));
AnchorMenu.Instance.OnAudio = unimplementedFunction;
AnchorMenu.Instance.Highlight = this.highlight;
AnchorMenu.Instance.GetAnchor = (savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => this.highlight('rgba(173, 216, 230, 0.75)', true, savedAnnotations, true);
diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index 6d06bbbf6..b9af28413 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -88,6 +88,7 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
};
});
+ if (!anchor.text) Doc.GetProto(anchor).text = '-selection-';
const textLines: any = [
{
type: 'paragraph',
@@ -121,16 +122,18 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
content: taggedContent,
};
if (taggedContent.length) textLines.push(metadatatext);
- Doc.GetProto(target).text = new RichTextField(
- JSON.stringify({
- doc: {
- type: 'doc',
- content: textLines,
- },
- selection: { type: 'text', anchor: 4, head: 4 }, // set selection to middle paragraph
- }),
- ''
- );
+ if (textLines.length) {
+ Doc.GetProto(target).text = new RichTextField(
+ JSON.stringify({
+ doc: {
+ type: 'doc',
+ content: textLines,
+ },
+ selection: { type: 'text', anchor: 4, head: 4 }, // set selection to middle paragraph
+ }),
+ ''
+ );
+ }
this.addDocument(target);
setTimeout(() => this._stackRef.current?.focusDocument(target, {}));
return target;
@@ -233,7 +236,7 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
isAnnotationOverlay={false}
select={emptyFunction}
NativeDimScaling={returnOne}
- childShowTitle={this.showTitle}
+ //childShowTitle={this.showTitle}
childDocumentsActive={this.props.isContentActive}
whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
childHideDecorationTitle={returnTrue}
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 3cb920ba0..817baeae6 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -19,6 +19,7 @@ import { SliderBox } from './nodes/SliderBox';
import './StyleProvider.scss';
import React = require('react');
import { Shadows } from 'browndash-components';
+import { SelectionManager } from '../util/SelectionManager';
export enum StyleProp {
TreeViewIcon = 'treeViewIcon',
@@ -116,7 +117,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
const excludeTypes = [DocumentType.FONTICON];
let highlighting = !props?.disableDocBrushing && highlightIndex && !excludeTypes.includes(doc.type as any) && doc._viewType !== CollectionViewType.Linear; // bcz: hack to turn off highlighting onsidebar panel documents. need to flag a document as not highlightable in a more direct way
if (highlighting && props?.focus !== emptyFunction && StrCast(doc.title) !== '[pres element template]') {
- return { highlightStyle, highlightColor, highlightIndex, highlightStroke: doc.type === DocumentType.INK };
+ return { highlightStyle, highlightColor: SelectionManager.Views().some(dv => dv.rootDoc === doc) ? 'black' : highlightColor, highlightIndex, highlightStroke: doc.type === DocumentType.INK };
}
}
return undefined;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 2f495d55c..6314b4529 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -129,6 +129,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
TraceMobx();
// appears that we are going to reset the _docXfs. TODO: what is Xfs?
this._docXfs.length = 0;
+ this._renderCount < docs.length && setTimeout(action(() => (this._renderCount = Math.min(docs.length, this._renderCount + 5))));
return docs.map((d, i) => {
const height = () => this.getDocHeight(d);
const width = () => this.getDocWidth(d);
@@ -139,7 +140,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
// So we're choosing whether we're going to render a column or a masonry doc
return (
<div className={`collectionStackingView-${this.isStackingView ? 'columnDoc' : 'masonryDoc'}`} key={d[Id]} style={style}>
- {this.getDisplayDoc(d, width)}
+ {this.getDisplayDoc(d, width, i)}
</div>
);
});
@@ -297,12 +298,13 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
};
isContentActive = () => (this.props.isSelected() || this.props.isContentActive() ? true : this.props.isSelected() === false || this.props.isContentActive() === false ? false : undefined);
+ @observable _renderCount = 5;
isChildContentActive = () =>
this.props.isDocumentActive?.() && (this.props.childDocumentsActive?.() || BoolCast(this.rootDoc.childDocumentsActive)) ? true : this.props.childDocumentsActive?.() === false || this.rootDoc.childDocumentsActive === false ? false : undefined;
isChildButtonContentActive = () => (this.props.childDocumentsActive?.() === false || this.rootDoc.childDocumentsActive === false ? false : undefined);
// this is what renders the document that you see on the screen
// called in Children: this actually adds a document to our children list
- getDisplayDoc(doc: Doc, width: () => number) {
+ getDisplayDoc(doc: Doc, width: () => number, count: number) {
const dataDoc = !doc.isTemplateDoc && !doc.isTemplateForField && !doc.PARAMS ? undefined : this.props.DataDoc;
const height = () => this.getDocHeight(doc);
@@ -310,7 +312,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
const stackedDocTransform = () => this.getDocTransform(doc, dref);
this._docXfs.push({ stackedDocTransform, width, height });
//DocumentView is how the node will be rendered
- return (
+ return count > this._renderCount ? null : (
<DocumentView
ref={r => (dref = r || undefined)}
Document={doc}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 1a265af4a..456f2a13d 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -259,11 +259,13 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: customFilters[i], icon: icons[i], label }));
};
headerFields = () => this.props.treeViewHideHeaderFields || BoolCast(this.doc.treeViewHideHeaderFields);
+ @observable _renderCount = 1;
@computed get treeViewElements() {
TraceMobx();
const dropAction = StrCast(this.doc.childDropAction) as dropActionType;
const addDoc = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => this.addDoc(doc, relativeTo, before);
const moveDoc = (d: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this.props.moveDocument?.(d, target, addDoc) || false;
+ if (this.treeChildren.length < this._renderCount) setTimeout(action(() => (this._renderCount = Math.min(this.treeChildren.length, this._renderCount + 20))));
return TreeView.GetChildElements(
this.treeChildren,
this,
@@ -296,7 +298,8 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
//TODO: [AL] add these
this.props.AddToMap,
this.props.RemFromMap,
- this.props.hierarchyIndex
+ this.props.hierarchyIndex,
+ this._renderCount
);
}
@computed get titleBar() {
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 2398d8f58..0d2968ba1 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -32,6 +32,7 @@ import { CollectionTreeView, TreeViewType } from './CollectionTreeView';
import { CollectionView } from './CollectionView';
import './TreeView.scss';
import React = require('react');
+import { render } from 'react-dom';
export interface TreeViewProps {
treeView: CollectionTreeView;
@@ -95,7 +96,7 @@ export class TreeView extends React.Component<TreeViewProps> {
private _header: React.RefObject<HTMLDivElement> = React.createRef();
private _tref = React.createRef<HTMLDivElement>();
@observable _docRef: Opt<DocumentView>;
- private _selDisposer: Opt<IReactionDisposer>;
+ private _disposers: { [name: string]: IReactionDisposer } = {};
private _editTitleScript: (() => ScriptField) | undefined;
private _openScript: (() => ScriptField) | undefined;
private _treedropDisposer?: DragManager.DragDropDisposer;
@@ -212,14 +213,14 @@ export class TreeView extends React.Component<TreeViewProps> {
};
@action setEditTitle = (docView?: DocumentView) => {
- this._selDisposer?.();
+ this._disposers.selection?.();
if (!docView) {
this._editTitle = false;
} else if (docView.isSelected()) {
const doc = docView.Document;
SelectionManager.SelectSchemaViewDoc(doc);
this._editTitle = true;
- this._selDisposer = reaction(
+ this._disposers.selection = reaction(
() => SelectionManager.SelectedSchemaDoc(),
seldoc => seldoc !== doc && this.setEditTitle(undefined)
);
@@ -259,7 +260,8 @@ export class TreeView extends React.Component<TreeViewProps> {
};
componentWillUnmount() {
- this._selDisposer?.();
+ this._renderTimer && clearTimeout(this._renderTimer);
+ Object.values(this._disposers).forEach(disposer => disposer?.());
this._treeEle && this.props.unobserveHeight(this._treeEle);
document.removeEventListener('pointermove', this.onDragMove, true);
document.removeEventListener('pointermove', this.onDragUp, true);
@@ -268,6 +270,10 @@ export class TreeView extends React.Component<TreeViewProps> {
}
componentDidUpdate() {
+ this._disposers.opening = reaction(
+ () => this.treeViewOpen,
+ open => !open && (this._renderCount = 20)
+ );
this.props.hierarchyIndex !== undefined && this.props.AddToMap?.(this.doc, this.props.hierarchyIndex);
}
@@ -512,6 +518,8 @@ export class TreeView extends React.Component<TreeViewProps> {
return rows;
}
+ _renderTimer: any;
+ @observable _renderCount = 1;
@computed get renderContent() {
TraceMobx();
const expandKey = this.treeViewExpandedView;
@@ -543,6 +551,14 @@ export class TreeView extends React.Component<TreeViewProps> {
const docs = expandKey === 'aliases' ? this.childAliases : expandKey === 'links' ? this.childLinks : expandKey === 'annotations' ? this.childAnnos : this.childDocs;
let downX = 0,
downY = 0;
+ if (docs?.length && this._renderCount < docs?.length) {
+ this._renderTimer && clearTimeout(this._renderTimer);
+ this._renderTimer = setTimeout(
+ action(() => {
+ this._renderCount = Math.min(docs!.length, this._renderCount + 20);
+ })
+ );
+ }
return (
<>
{!docs?.length || this.props.AddToMap /* hack to identify pres box trees */ ? null : (
@@ -599,7 +615,8 @@ export class TreeView extends React.Component<TreeViewProps> {
// TODO: [AL] add these
this.props.AddToMap,
this.props.RemFromMap,
- this.props.hierarchyIndex
+ this.props.hierarchyIndex,
+ this._renderCount
)}
</ul>
</>
@@ -651,7 +668,7 @@ export class TreeView extends React.Component<TreeViewProps> {
return (
<div
className={`bullet${this.props.treeView.outlineMode ? '-outline' : ''}`}
- key={'bullet'}
+ key="bullet"
title={this.childDocs?.length ? `click to see ${this.childDocs?.length} items` : 'view fields'}
onClick={this.bulletClick}
style={
@@ -1131,7 +1148,8 @@ export class TreeView extends React.Component<TreeViewProps> {
// TODO: [AL] add these
AddToMap?: (treeViewDoc: Doc, index: number[]) => Doc[],
RemFromMap?: (treeViewDoc: Doc, index: number[]) => Doc[],
- hierarchyIndex?: number[]
+ hierarchyIndex?: number[],
+ renderCount?: number
) {
const viewSpecScript = Cast(containerCollection.viewSpecScript, ScriptField);
if (viewSpecScript) {
@@ -1144,6 +1162,7 @@ export class TreeView extends React.Component<TreeViewProps> {
return docs
.filter(child => child instanceof Doc)
.map((child, i) => {
+ if (renderCount && i > renderCount) return null;
const pair = Doc.GetLayoutDataDocPair(containerCollection, dataDoc, child);
if (!pair.layout || pair.data instanceof Promise) {
return null;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index d6e95f97f..4d6e0dff2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -53,6 +53,7 @@ import { CollectionFreeFormRemoteCursors } from './CollectionFreeFormRemoteCurso
import './CollectionFreeFormView.scss';
import { MarqueeView } from './MarqueeView';
import React = require('react');
+import { DocumentDecorations } from '../../DocumentDecorations';
export type collectionFreeformViewProps = {
annotationLayerHostsContent?: boolean; // whether to force scaling of content (needed by ImageBox)
@@ -1305,7 +1306,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
pointerEvents = () => {
const engine = this.props.layoutEngine?.() || StrCast(this.props.Document._layoutEngine);
const pointerEvents =
- this.props.isContentActive() === false ? 'none' : this.props.childPointerEvents ?? (this.props.viewDefDivClick || (engine === computePassLayout.name && !this.props.isSelected(true)) ? 'none' : this.props.pointerEvents?.());
+ this.props.isContentActive() === false || DocumentDecorations.Instance.Interacting
+ ? 'none'
+ : this.props.childPointerEvents ?? (this.props.viewDefDivClick || (engine === computePassLayout.name && !this.props.isSelected(true)) ? 'none' : this.props.pointerEvents?.());
return pointerEvents;
};
getChildDocView(entry: PoolData) {
@@ -2287,6 +2290,7 @@ export function CollectionBrowseClick(dv: DocumentView, clientX: number, clientY
SelectionManager.DeselectAll();
dv.props.focus(dv.props.Document, {
willPanZoom: true,
+ zoomScale: 0.8,
afterFocus: async didMove => {
if (!didMove) {
const selfFfview = dv.ComponentView instanceof CollectionFreeFormView ? dv.ComponentView : undefined;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 36c0240f1..3d89566ee 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -664,7 +664,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
? this.props.select(false)
: '';
const clickFunc = () => (this.props.Document.dontUndo ? func() : UndoManager.RunInBatch(func, 'on click'));
- if (this.onDoubleClickHandler) {
+ if (this.onDoubleClickHandler && !this.props.Document.allowClickBeforeDoubleClick) {
runInAction(() => (this._pendingDoubleClick = true));
this._timeout = setTimeout(() => {
this._timeout = undefined;
@@ -780,7 +780,9 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
if (this.onPointerUpHandler?.script && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) {
this.onPointerUpHandler.script.run({ self: this.rootDoc, this: this.layoutDoc }, console.log);
} else {
- this._doubleTap = Date.now() - this._lastTap < 300 && e.button === 0 && Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2;
+ const now = Date.now();
+ console.log(now - this._lastTap);
+ this._doubleTap = now - this._lastTap < 600 && e.button === 0 && Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2;
// bcz: this is a placeholder. documents, when selected, should stopPropagation on doubleClicks if they want to keep the DocumentView from getting them
if (!this.props.isSelected(true) || ![DocumentType.PDF, DocumentType.RTF].includes(StrCast(this.rootDoc.type) as any)) this._lastTap = Date.now(); // don't want to process the start of a double tap if the doucment is selected
}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 540958941..c66f2a67b 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -383,7 +383,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
@computed get content() {
TraceMobx();
- const col = DashColor(this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor));
+ const backAlpha = DashColor(this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor)).alpha();
const srcpath = this.layoutDoc.hideImage ? '' : this.paths[0];
const fadepath = this.layoutDoc.hideImage ? '' : this.paths.lastElement();
const { nativeWidth, nativeHeight, nativeOrientation } = this.nativeSize;
@@ -403,7 +403,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
return (
<div className="imageBox-cont" key={this.layoutDoc[Id]} ref={this.createDropTarget} onPointerDown={this.marqueeDown}>
- <div className="imageBox-fader" style={{ opacity: col.alpha() }}>
+ <div className="imageBox-fader" style={{ opacity: backAlpha }}>
<img key="paths" src={srcpath} style={{ transform, transformOrigin }} draggable={false} width={nativeWidth} />
{fadepath === srcpath ? null : (
<div
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index c392f3577..5bbe521a7 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -257,6 +257,10 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
// this._iframe?.contentDocument?.removeEventListener("pointerup", this.iframeUp);
}
+ private _selectionText: string = '';
+ private _selectionContent: DocumentFragment | undefined;
+ selectionText = () => this._selectionText;
+ selectionContent = () => this._selectionContent;
@action
createTextAnnotation = (sel: Selection, selRange: Range | undefined) => {
if (this._mainCont.current && selRange) {
@@ -276,6 +280,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
}
//this._selectionText = selRange.cloneContents().textContent || "";
+ this._selectionContent = selRange?.cloneContents();
+ this._selectionText = this._selectionContent?.textContent || '';
// clear selection
if (sel.empty) sel.empty(); // Chrome
@@ -854,8 +860,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
return WebBox.sidebarResizerWidth + nativeDiff * (this.props.NativeDimScaling?.() || 1);
};
@computed get content() {
- const interactive =
- !this.props.docViewPath().lastElement()?.docView?._pendingDoubleClick && this.props.isContentActive() && this.props.pointerEvents?.() !== 'none' && Doc.ActiveTool === InkTool.None && !DocumentDecorations.Instance?.Interacting;
+ const interactive = !this.props.docViewPath().lastElement()?.docView?._pendingDoubleClick && this.props.isContentActive() && this.props.pointerEvents?.() !== 'none' && Doc.ActiveTool === InkTool.None;
return (
<div className={'webBox-cont' + (interactive ? '-interactive' : '')} onKeyDown={e => e.stopPropagation()} style={{ width: !this.layoutDoc.forceReflow ? NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth']) || `100%` : '100%' }}>
{this.urlContent}
@@ -1014,7 +1019,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
docView={this.props.docViewPath().lastElement()}
finishMarquee={this.finishMarquee}
savedAnnotations={this.savedAnnotationsCreator}
- selectionText={returnEmptyString}
+ selectionText={this.selectionText}
annotationLayer={this._annotationLayer.current}
mainCont={this._mainCont.current}
/>
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index 9d67283a0..b352f3790 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -136,7 +136,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
const setValue = (value: number) => UndoManager.RunInBatch(() => numScript?.script.run({ value, _readOnly_: false }), 'set num value');
// Script for checking the outcome of the toggle
- const checkResult: number = numScript?.script.run({ value: 0, _readOnly_: true }).result || 0;
+ const checkResult = Number(numScript?.script.run({ value: 0, _readOnly_: true }).result ?? 0).toPrecision(NumCast(this.dataDoc.numPrecision, 3));
const label = !FontIconBox.GetShowLabels() ? null : <div className="fontIconBox-label">{this.label}</div>;
@@ -150,7 +150,6 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
max={NumCast(this.rootDoc.numBtnMax, 100)}
value={checkResult}
className={'menu-slider'}
- id="slider"
onPointerDown={() => (this._batch = UndoManager.StartBatch('presDuration'))}
onPointerUp={() => this._batch?.end()}
onChange={e => {
@@ -642,13 +641,7 @@ ScriptingGlobals.add(function setFontHighlight(color?: string, checkResult?: boo
if (checkResult) {
return (selected ?? Doc.UserDoc())._fontHighlight;
}
- if (selected) {
- selected._fontColor = color;
- if (color) {
- editorView?.state && RichTextMenu.Instance.setHighlight(color, editorView, editorView?.dispatch);
- }
- }
- Doc.UserDoc()._fontHighlight = color;
+ color && RichTextMenu.Instance.setHighlight(color);
});
// toggle: Set overlay status of selected document
@@ -795,7 +788,7 @@ function setActiveTool(tool: InkTool | GestureUtils.Gestures, keepPrim: boolean,
GestureOverlay.Instance.KeepPrimitiveMode = keepPrim;
}
if (Object.values(GestureUtils.Gestures).includes(tool as any)) {
- if (GestureOverlay.Instance.InkShape === tool) {
+ if (GestureOverlay.Instance.InkShape === tool && !keepPrim) {
Doc.ActiveTool = InkTool.None;
GestureOverlay.Instance.InkShape = undefined;
} else {
@@ -804,7 +797,7 @@ function setActiveTool(tool: InkTool | GestureUtils.Gestures, keepPrim: boolean,
}
} else if (tool) {
// pen or eraser
- if (Doc.ActiveTool === tool && !GestureOverlay.Instance.InkShape) {
+ if (Doc.ActiveTool === tool && !GestureOverlay.Instance.InkShape && !keepPrim) {
Doc.ActiveTool = InkTool.None;
} else {
Doc.ActiveTool = tool as any;
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index 39005a18b..b33529aeb 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -18,12 +18,18 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { CollectionViewType } from '../../../documents/DocumentTypes';
import { NodeSelection } from 'prosemirror-state';
import { OpenWhere } from '../DocumentView';
+import { FormattedTextBoxComment } from './FormattedTextBoxComment';
export class DashFieldView {
dom: HTMLDivElement; // container for label and value
root: any;
+ node: any;
+ tbox: FormattedTextBox;
+ unclickable = () => !this.tbox.props.isSelected() && this.node.marks.some((m: any) => m.type === this.tbox.EditorView?.state.schema.marks.linkAnchor && m.attrs.noPreview);
constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) {
+ this.node = node;
+ this.tbox = tbox;
this.dom = document.createElement('div');
this.dom.style.width = node.attrs.width;
this.dom.style.height = node.attrs.height;
@@ -44,7 +50,18 @@ export class DashFieldView {
this.root = ReactDOM.createRoot(this.dom);
this.root.render(
- <DashFieldViewInternal node={node} getPos={getPos} fieldKey={node.attrs.fieldKey} docid={node.attrs.docid} width={node.attrs.width} height={node.attrs.height} hideKey={node.attrs.hideKey} editable={node.attrs.editable} tbox={tbox} />
+ <DashFieldViewInternal
+ node={node}
+ unclickable={this.unclickable}
+ getPos={getPos}
+ fieldKey={node.attrs.fieldKey}
+ docid={node.attrs.docid}
+ width={node.attrs.width}
+ height={node.attrs.height}
+ hideKey={node.attrs.hideKey}
+ editable={node.attrs.editable}
+ tbox={tbox}
+ />
);
}
destroy() {
@@ -68,6 +85,7 @@ interface IDashFieldViewInternal {
editable: boolean;
node: any;
getPos: any;
+ unclickable: () => boolean;
}
@observer
@@ -125,7 +143,7 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna
return (
<span
className="dashFieldView-fieldSpan"
- contentEditable={true}
+ contentEditable={!this.props.unclickable()}
style={{ display: strVal.length < 2 ? 'inline-block' : undefined }}
suppressContentEditableWarning={true}
defaultValue={strVal}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 49acd8a57..0ff09a0ca 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -81,7 +81,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
static _highlightStyleSheet: any = addStyleSheet();
static _bulletStyleSheet: any = addStyleSheet();
static _userStyleSheet: any = addStyleSheet();
- static _canAnnotate = true;
static _hadSelection: boolean = false;
private _sidebarRef = React.createRef<SidebarAnnos>();
private _ref: React.RefObject<HTMLDivElement> = React.createRef();
@@ -102,7 +101,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
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 = true;
@@ -118,7 +116,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
@computed get noSidebar() {
- return this.props.docViewPath?.()[this.props.docViewPath().length - 2]?.rootDoc.type === DocumentType.RTF || this.props.noSidebar || this.Document._noSidebar;
+ return this.props.docViewPath().lastElement()?.props.hideDecorationTitle || this.props.noSidebar || this.Document._noSidebar;
}
@computed get sidebarWidthPercent() {
return this._showSidebar ? '20%' : StrCast(this.layoutDoc._sidebarWidthPercent, '0%');
@@ -254,7 +252,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
});
};
AnchorMenu.Instance.Highlight = action((color: string, isLinkButton: boolean) => {
- this._editorView?.state && RichTextMenu.Instance.setHighlight(color, this._editorView, this._editorView?.dispatch);
+ this._editorView?.state && RichTextMenu.Instance.setHighlight(color);
return undefined;
});
AnchorMenu.Instance.onMakeAnchor = () => this.getAnchor(true);
@@ -788,7 +786,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
);
const uicontrols: ContextMenuProps[] = [];
- !Doc.noviceMode && uicontrols.push({ description: `${FormattedTextBox._canAnnotate ? "Don't" : ''} Show Menu on Selections`, 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: 'Show Highlights...', noexpand: true, subitems: highlighting, icon: 'hand-point-right' });
!Doc.noviceMode &&
@@ -1455,7 +1452,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
this._downX = e.clientX;
this._downY = e.clientY;
- this._downEvent = true;
FormattedTextBoxComment.textBox = this;
if (e.button === 0 && (this.props.rootSelected(true) || this.props.isSelected(true)) && !e.altKey && !e.ctrlKey && !e.metaKey) {
if (e.clientX < this.ProseRef!.getBoundingClientRect().right) {
@@ -1477,17 +1473,17 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
document.removeEventListener('pointermove', this.onSelectMove);
};
onPointerUp = (e: React.PointerEvent): void => {
- if (!this._editorView?.state.selection.empty && !(this._editorView?.state.selection instanceof NodeSelection) && FormattedTextBox._canAnnotate && !(e.nativeEvent as any).dash) this.setupAnchorMenu();
- if (!this._downEvent) return;
- this._downEvent = false;
- if (this._editorView?.state.selection.empty && this.props.isContentActive(true) && !(e.nativeEvent as any).dash) {
- const editor = this._editorView!;
+ const editor = this._editorView!;
+ const state = editor?.state;
+ if (!state || !editor) return;
+ if (!state.selection.empty && !(state.selection instanceof NodeSelection)) this.setupAnchorMenu();
+ else if (this.props.isContentActive(true)) {
const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY });
- !this.props.isSelected(true) && editor.dispatch(editor.state.tr.setSelection(new TextSelection(editor.state.doc.resolve(pcords?.pos || 0))));
+ !this.props.isSelected(true) && editor.dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(pcords?.pos || 0))));
let target = e.target as any; // hrefs are stored on the dataset of the <a> node that wraps the hyerlink <span>
while (target && !target.dataset?.targethrefs) target = target.parentElement;
FormattedTextBoxComment.update(this, editor, undefined, target?.dataset?.targethrefs, target?.dataset.linkdoc, target?.dataset.nopreview === 'true');
- if (pcords && pcords.inside > 0 && this._editorView.state.doc.nodeAt(pcords.inside)?.type === this._editorView.state.schema.nodes.dashDoc) {
+ if (pcords && pcords.inside > 0 && state.doc.nodeAt(pcords.inside)?.type === state.schema.nodes.dashDoc) {
return;
}
}
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index b70da2e5e..f0caa1f4f 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -54,7 +54,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
@observable private _activeFontColor: string = 'black';
@observable private showColorDropdown: boolean = false;
- @observable private activeHighlightColor: string = 'transparent';
+ @observable private _activeHighlightColor: string = 'transparent';
@observable private showHighlightDropdown: boolean = false;
@observable private currentLink: string | undefined = '';
@@ -89,6 +89,9 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
@computed get fontColor() {
return this._activeFontColor;
}
+ @computed get fontHighlight() {
+ return this._activeHighlightColor;
+ }
@computed get fontFamily() {
return this._activeFontFamily;
}
@@ -138,7 +141,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
this._activeFontFamily = !activeFamilies.length ? StrCast(this.TextView?.Document.fontFamily, StrCast(Doc.UserDoc().fontFamily, 'Arial')) : activeFamilies.length === 1 ? String(activeFamilies[0]) : 'various';
this._activeFontSize = !activeSizes.length ? StrCast(this.TextView?.Document.fontSize, StrCast(Doc.UserDoc().fontSize, '10px')) : activeSizes[0];
this._activeFontColor = !activeColors.length ? StrCast(this.TextView?.Document.fontColor, StrCast(Doc.UserDoc().fontColor, 'black')) : activeColors.length > 0 ? String(activeColors[0]) : '...';
- this.activeHighlightColor = !activeHighlights.length ? '' : activeHighlights.length > 0 ? String(activeHighlights[0]) : '...';
+ this._activeHighlightColor = !activeHighlights.length ? '' : activeHighlights.length > 0 ? String(activeHighlights[0]) : '...';
// update link in current selection
this.getTextLinkTargetTitle().then(targetTitle => this.setCurrentLink(targetTitle));
@@ -356,11 +359,13 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
this.updateMenu(this.view, undefined, this.props);
};
- setHighlight(color: String, view: EditorView, dispatch: any) {
- const highlightMark = view.state.schema.mark(view.state.schema.marks.marker, { highlight: color });
- if (view.state.selection.empty) return false;
- view.focus();
- this.setMark(highlightMark, view.state, dispatch, false);
+ setHighlight(color: string) {
+ if (this.view) {
+ const highlightMark = this.view.state.schema.mark(this.view.state.schema.marks.marker, { highlight: color });
+ this.setMark(highlightMark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(highlightMark)), true);
+ this.view.focus();
+ } else Doc.UserDoc()._fontHighlight = color;
+ this.updateMenu(this.view, undefined, this.props);
}
setColor(color: string) {
@@ -563,7 +568,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
}
@action setActiveHighlight(color: string) {
- this.activeHighlightColor = color;
+ this._activeHighlightColor = color;
}
@action setCurrentLink(link: string) {
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 7e728306c..f2e9be61d 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -54,7 +54,7 @@ export class TopBar extends React.Component {
<span style={{ color: Colors.LIGHT_BLUE, fontWeight: 500 }}>dash</span>
</div>
)}
- {Doc.ActiveDashboard && !Doc.noviceMode && (
+ {Doc.ActiveDashboard && (
<Button
text="Explore"
tooltip="Browsing mode for directly navigating to documents"