aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/util/DragManager.ts19
-rw-r--r--src/client/views/InkingStroke.tsx2
-rw-r--r--src/client/views/MarqueeAnnotator.tsx2
-rw-r--r--src/client/views/collections/CollectionCarousel3DView.tsx1
-rw-r--r--src/client/views/collections/CollectionCarouselView.tsx3
-rw-r--r--src/client/views/collections/CollectionSubView.tsx1
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss9
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx75
-rw-r--r--src/client/views/collections/collectionSchema/SchemaTableCell.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx20
-rw-r--r--src/client/views/nodes/FieldView.tsx1
-rw-r--r--src/client/views/nodes/MapBox/MapAnchorMenu.tsx62
-rw-r--r--src/client/views/nodes/MapBox/MapBox.tsx36
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx10
-rw-r--r--src/client/views/pdf/AnchorMenu.tsx3
15 files changed, 121 insertions, 125 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index f86f9a3e5..4f30e92ce 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -4,7 +4,7 @@ import { Doc, Field, Opt, StrListCast } from '../../fields/Doc';
import { List } from '../../fields/List';
import { PrefetchProxy } from '../../fields/Proxy';
import { ScriptField } from '../../fields/ScriptField';
-import { ScriptCast, StrCast } from '../../fields/Types';
+import { BoolCast, ScriptCast, StrCast } from '../../fields/Types';
import { emptyFunction, Utils } from '../../Utils';
import { Docs, DocUtils } from '../documents/Documents';
import * as globalCssVariables from '../views/global/globalCssVariables.scss';
@@ -108,9 +108,11 @@ export namespace DragManager {
constructor(dragDoc: Doc[], dropAction?: dropActionType) {
this.draggedDocuments = dragDoc;
this.droppedDocuments = [];
+ this.draggedViews = [];
this.offset = [0, 0];
this.dropAction = dropAction;
}
+ draggedViews: DocumentView[];
draggedDocuments: Doc[];
droppedDocuments: Doc[];
treeViewDoc?: Doc;
@@ -189,6 +191,13 @@ export namespace DragManager {
// drag a document and drop it (or make an embed/copy on drop)
export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions, onDropCompleted?: (e?: DragCompleteEvent) => any) {
+ dragData.draggedViews.forEach(
+ action(view => {
+ const ffview = view.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView;
+ ffview && (ffview.GroupChildDrag = BoolCast(ffview.Document._isGroup));
+ ffview?.setupDragLines(false);
+ })
+ );
const addAudioTag = (dropDoc: any) => {
dropDoc && !dropDoc.author_date && (dropDoc.author_date = new DateField());
dropDoc instanceof Doc && DocUtils.MakeLinkToActiveAudio(() => dropDoc);
@@ -196,6 +205,14 @@ export namespace DragManager {
};
const finishDrag = async (e: DragCompleteEvent) => {
const docDragData = e.docDragData;
+ setTimeout(() =>
+ dragData.draggedViews.forEach(
+ action(view => {
+ const ffview = view.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView;
+ ffview && (ffview.GroupChildDrag = false);
+ })
+ )
+ );
onDropCompleted?.(e); // glr: optional additional function to be called - in this case with presentation trails
if (docDragData && !docDragData.droppedDocuments.length) {
docDragData.dropAction = dragData.userDropAction || dragData.dropAction;
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index f63a27426..9b52f5870 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -446,7 +446,6 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
mask,
highlightColor
);
- const fsize = +StrCast(this.props.Document._text_fontSize, '12px').replace('px', '');
// bootsrap 3 style sheet sets line height to be 20px for default 14 point font size.
// this attempts to figure out the lineHeight ratio by inquiring the body's lineHeight and dividing by the fontsize which should yield 1.428571429
// see: https://bibwild.wordpress.com/2019/06/10/bootstrap-3-to-4-changes-in-how-font-size-line-height-and-spacing-is-done-or-what-happened-to-line-height-computed/
@@ -493,7 +492,6 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
yPadding={10}
xPadding={10}
fieldKey="text"
- fontSize={fsize}
dontRegisterView={true}
noSidebar={true}
dontScale={true}
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index a958607de..0987b0867 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -211,7 +211,7 @@ export class MarqueeAnnotator extends React.Component<MarqueeAnnotatorProps> {
const effectiveAcl = GetEffectiveAcl(this.props.rootDoc[DocData]);
const annotationDoc = [AclAugment, AclSelfEdit, AclEdit, AclAdmin].includes(effectiveAcl) && this.makeAnnotationDocument(color, isLinkButton, savedAnnotations);
addAsAnnotation && !savedAnnotations && annotationDoc && this.props.addDocument(annotationDoc);
- return (annotationDoc as Doc) ?? undefined;
+ return annotationDoc as Doc;
};
public static previewNewAnnotation = action((savedAnnotations: ObservableMap<number, HTMLDivElement[]>, annotationLayer: HTMLDivElement, div: HTMLDivElement, page: number) => {
diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx
index 4bc72772a..a8d080953 100644
--- a/src/client/views/collections/CollectionCarousel3DView.tsx
+++ b/src/client/views/collections/CollectionCarousel3DView.tsx
@@ -28,7 +28,6 @@ export class CollectionCarousel3DView extends CollectionSubView() {
}
protected createDashEventsTarget = (ele: HTMLDivElement | null) => {
- //used for stacking and masonry view
this._dropDisposer?.();
if (ele) {
this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc);
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 040a584b8..33a92d406 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -21,7 +21,6 @@ export class CollectionCarouselView extends CollectionSubView() {
}
protected createDashEventsTarget = (ele: HTMLDivElement | null) => {
- //used for stacking and masonry view
this._dropDisposer?.();
if (ele) {
this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc);
@@ -86,7 +85,7 @@ export class CollectionCarouselView extends CollectionSubView() {
marginLeft: this.marginX,
width: `calc(100% - ${this.marginX * 2}px)`,
}}>
- <FormattedTextBox key={index} {...captionProps} allowScroll={true} fieldKey={show_captions} styleProvider={this.captionStyleProvider} Document={curDoc.layout} DataDoc={undefined} />
+ <FormattedTextBox key={index} {...captionProps} fieldKey={show_captions} styleProvider={this.captionStyleProvider} Document={curDoc.layout} DataDoc={undefined} />
</div>
</>
);
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 26272d2ee..158f9d8ee 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -31,7 +31,6 @@ export function CollectionSubView<X>(moreProps?: X) {
@observable _focusFilters: Opt<string[]>; // childFilters that are overridden when previewing a link to an anchor which has childFilters set on it
@observable _focusRangeFilters: Opt<string[]>; // childFiltersByRanges that are overridden when previewing a link to an anchor which has childFiltersByRanges set on it
protected createDashEventsTarget = (ele: HTMLDivElement | null) => {
- //used for stacking and masonry view
this.dropDisposer?.();
this.gestureDisposer?.();
this._multiTouchDisposer?.();
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index e4ae251c8..c90fdf013 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -11,6 +11,15 @@
touch-action: none;
border-radius: inherit;
}
+.collectionFreeForm-groupDropper {
+ width: 10000;
+ height: 10000;
+ left: -5000;
+ top: -5000;
+ position: absolute;
+ background: transparent;
+ pointer-events: all;
+}
.collectionfreeformview-grid {
transform-origin: top left;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index a64ccbb2c..676e96714 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -124,7 +124,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@observable _timelineRef = React.createRef<Timeline>();
@observable _marqueeRef: HTMLDivElement | null = null;
@observable _marqueeViewRef = React.createRef<MarqueeView>();
- @observable ChildDrag: DocumentView | undefined; // child document view being dragged. needed to update drop areas of groups when a group item is dragged.
+ @observable GroupChildDrag: boolean = false; // child document view being dragged. needed to update drop areas of groups when a group item is dragged.
@observable _brushedView = { width: 0, height: 0, panX: 0, panY: 0, opacity: 0 }; // highlighted region of freeform canvas used by presentations to indicate a region
constructor(props: any) {
@@ -342,7 +342,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@action
internalDocDrop(e: Event, de: DragManager.DropEvent, docDragData: DragManager.DocumentDragData, xp: number, yp: number) {
- if (!de.embedKey && !this.ChildDrag && this.rootDoc._isGroup) return false;
if (!super.onInternalDrop(e, de)) return false;
const refDoc = docDragData.droppedDocuments[0];
const [xpo, ypo] = this.getContainerTransform().transformPoint(de.x, de.y);
@@ -1763,17 +1762,24 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@undoBatch
toggleNativeDimensions = () => Doc.toggleNativeDimensions(this.layoutDoc, 1, this.nativeWidth, this.nativeHeight);
+ ///
+ /// resetView restores a freeform collection to unit scale and centered at (0,0) UNLESS
+ /// the view is a group, in which case this does nothing (since Groups calculate their own scale and center)
+ ///
+ @undoBatch
+ resetView = () => {
+ if (!this.props.Document._isGroup) {
+ this.props.Document[this.panXFieldKey] = this.props.Document[this.panYFieldKey] = 0;
+ this.props.Document[this.scaleFieldKey] = 1;
+ }
+ };
+
onContextMenu = (e: React.MouseEvent) => {
if (this.props.isAnnotationOverlay || !ContextMenu.Instance) return;
const appearance = ContextMenu.Instance.findByDescription('Appearance...');
const appearanceItems = appearance && 'subitems' in appearance ? appearance.subitems : [];
- !this.props.Document._isGroup &&
- appearanceItems.push({
- description: 'Reset View',
- event: () => CollectionFreeFormView.ResetView(this),
- icon: 'compress-arrows-alt',
- });
+ !this.props.Document._isGroup && appearanceItems.push({ description: 'Reset View', event: this.resetView, icon: 'compress-arrows-alt' });
!Doc.noviceMode &&
appearanceItems.push({
description: 'Toggle auto arrange',
@@ -1975,15 +1981,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
nativeDim = () => this.nativeDimScaling;
- private groupDropDisposer?: DragManager.DragDropDisposer;
- protected createGroupEventsTarget = (ele: HTMLDivElement) => {
- //used for stacking and masonry view
- this.groupDropDisposer?.();
- if (ele) {
- this.groupDropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc, this.onInternalPreDrop.bind(this));
- }
- };
-
@action
brushView = (viewport: { width: number; height: number; panX: number; panY: number }, transTime: number) => {
this._brushtimer1 && clearTimeout(this._brushtimer1);
@@ -2068,51 +2065,18 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
{/* // uncomment to show snap lines */}
<div className="snapLines" style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', pointerEvents: 'none' }}>
<svg style={{ width: '100%', height: '100%' }}>
- {this._hLines?.map(l => (
- <line x1="0" y1={l} x2="1000" y2={l} stroke="black" />
- ))}
- {this._vLines?.map(l => (
- <line y1="0" x1={l} y2="1000" x2={l} stroke="black" />
- ))}
+ {(this._hLines ?? [])
+ .map(l => <line x1="0" y1={l} x2="1000" y2={l} stroke="black" />) //
+ .concat((this._vLines ?? []).map(l => <line y1="0" x1={l} y2="1000" x2={l} stroke="black" />)) ?? []}
</svg>
</div>
- {this.props.Document._isGroup && SnappingManager.GetIsDragging() && this.ChildDrag ? (
- <div
- className="collectionFreeForm-groupDropper"
- ref={this.createGroupEventsTarget}
- style={{
- width: this.ChildDrag ? '10000' : '100%',
- height: this.ChildDrag ? '10000' : '100%',
- left: this.ChildDrag ? '-5000' : 0,
- top: this.ChildDrag ? '-5000' : 0,
- position: 'absolute',
- background: '#0009930',
- pointerEvents: 'all',
- }}
- />
- ) : null}
+ {this.GroupChildDrag ? <div className="collectionFreeForm-groupDropper" /> : null}
</>
)}
</div>
);
}
- /// resetView restores a freeform collection to unit scale and centered at (0,0) UNLESS
- // the view is a group, in which case this does nothing (since Groups calculate their own scale and center)
- static ResetView(view?: CollectionFreeFormView) {
- if (view) {
- if (view.props.Document._isGroup) return;
- view.props.Document[view.panXFieldKey] = view.props.Document[view.panYFieldKey] = 0;
- view.props.Document[view.scaleFieldKey] = 1;
- } else {
- SelectionManager.Docs()
- .filter(doc => !doc._isGroup)
- .forEach(doc => {
- doc._freeform_panX = doc._freeform_panY = 0;
- doc._freeform_scale = 1;
- });
- }
- }
}
interface CollectionFreeFormOverlayViewProps {
@@ -2358,6 +2322,3 @@ ScriptingGlobals.add(function bringToFront() {
ScriptingGlobals.add(function sendToBack(doc: Doc) {
SelectionManager.Views().forEach(view => view.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView.bringToFront(view.rootDoc, true));
});
-ScriptingGlobals.add(function resetView() {
- CollectionFreeFormView.ResetView();
-});
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index 4092d9722..9d5b533d1 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -272,7 +272,7 @@ export class SchemaRTFCell extends React.Component<SchemaTableCellProps> {
fieldProps.isContentActive = this.selectedFunc;
return (
<div className="schemaRTFCell" style={{ display: 'flex', fontStyle: this.selected ? undefined : 'italic', width: '100%', height: '100%', position: 'relative', color, textDecoration, cursor, pointerEvents }}>
- {this.selected ? <FormattedTextBox allowScroll={true} {...fieldProps} DataDoc={this.props.Document} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))}
+ {this.selected ? <FormattedTextBox {...fieldProps} DataDoc={this.props.Document} /> : (field => (field ? Field.toString(field) : ''))(FieldValue(fieldProps.Document[fieldProps.fieldKey]))}
</div>
);
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index ef96e64be..e4fc6c4a2 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -394,18 +394,15 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
dragData.treeViewDoc = this.props.treeViewDoc;
dragData.removeDocument = this.props.removeDocument;
dragData.moveDocument = this.props.moveDocument;
+ dragData.draggedViews = [this.props.DocumentView()];
dragData.canEmbed = this.rootDoc.dragAction ?? this.props.dragAction ? true : false;
- const ffview = this.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView;
- ffview && runInAction(() => (ffview.ChildDrag = this.props.DocumentView()));
DragManager.StartDocumentDrag(
selected.map(dv => dv.docView!._mainCont.current!),
dragData,
x,
y,
- { hideSource: hideSource || (!dropAction && !this.layoutDoc.onDragStart && !this.props.dontHideOnDrag) },
- () => setTimeout(action(() => ffview && (ffview.ChildDrag = undefined)))
+ { hideSource: hideSource || (!dropAction && !this.layoutDoc.onDragStart && !this.props.dontHideOnDrag) }
); // this needs to happen after the drop event is processed.
- ffview?.setupDragLines(false);
}
}
@@ -495,11 +492,10 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
const sendToBack = e.altKey;
this._singleClickFunc =
- clickFunc ??
- (() =>
- sendToBack
- ? this.props.DocumentView().props.CollectionFreeFormDocumentView?.().props.bringToFront(this.rootDoc, true)
- : this._componentView?.select?.(e.ctrlKey || e.metaKey, e.shiftKey) ?? this.props.select(e.ctrlKey || e.metaKey || e.shiftKey));
+ // prettier-ignore
+ clickFunc ?? (() => (sendToBack ? this.props.DocumentView().props.bringToFront(this.rootDoc, true) :
+ this._componentView?.select?.(e.ctrlKey || e.metaKey, e.shiftKey) ??
+ this.props.select(e.ctrlKey || e.metaKey || e.shiftKey)));
const waitFordblclick = this.props.waitForDoubleClickToClick?.() ?? this.Document.waitForDoubleClickToClick;
if ((clickFunc && waitFordblclick !== 'never') || waitFordblclick === 'always') {
this._doubleClickTimeout && clearTimeout(this._doubleClickTimeout);
@@ -1099,7 +1095,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
captionStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string) => this.props?.styleProvider?.(doc, props, property + ':caption');
@computed get innards() {
TraceMobx();
- const ffscale = () => this.props.DocumentView().props.CollectionFreeFormDocumentView?.().props.ScreenToLocalTransform().Scale || 1;
const showTitle = this.layout_showTitle?.split(':')[0];
const showTitleHover = this.layout_showTitle?.includes(':hover');
const captionView = !this.layout_showCaption ? null : (
@@ -1107,8 +1102,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
className="documentView-captionWrapper"
style={{
pointerEvents: this.rootDoc.ignoreClick ? 'none' : this.isContentActive() || this.props.isDocumentActive?.() ? 'all' : undefined,
- minWidth: 50 * ffscale(),
- maxHeight: `max(100%, ${20 * ffscale()}px)`,
background: StrCast(this.layoutDoc._backgroundColor, 'rgba(0,0,0,0.2)'),
color: lightOrDark(StrCast(this.layoutDoc._backgroundColor, 'black')),
}}>
@@ -1117,7 +1110,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
yPadding={10}
xPadding={10}
fieldKey={this.layout_showCaption}
- fontSize={12 * Math.max(1, (2 * ffscale()) / 3)}
styleProvider={this.captionStyleProvider}
dontRegisterView={true}
noSidebar={true}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 4ebf22ddf..f014f842e 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -34,7 +34,6 @@ export interface FieldViewProps extends DocumentViewSharedProps {
backgroundColor?: string;
treeViewDoc?: Doc;
color?: string;
- fontSize?: number;
height?: number;
width?: number;
noSidebar?: boolean;
diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
index f0827936b..7af4d9b59 100644
--- a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
+++ b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
@@ -1,41 +1,32 @@
import React = require('react');
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction } from 'mobx';
+import { IReactionDisposer, ObservableMap, reaction } from 'mobx';
import { observer } from 'mobx-react';
-import { ColorState } from 'react-color';
import { Doc, Opt } from '../../../../fields/Doc';
-import { returnFalse, setupMoveUpEvents, unimplementedFunction, Utils } from '../../../../Utils';
+import { returnFalse, setupMoveUpEvents, unimplementedFunction } from '../../../../Utils';
import { SelectionManager } from '../../../util/SelectionManager';
import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
-import { LinkPopup } from '../../linking/LinkPopup';
-import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT';
// import { GPTPopup, GPTPopupMode } from './../../GPTPopup/GPTPopup';
-import { EditorView } from 'prosemirror-view';
-import './MapAnchorMenu.scss';
-import { ColorPicker, Group, IconButton, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components';
-import { StrCast } from '../../../../fields/Types';
-import { DocumentType } from '../../../documents/DocumentTypes';
+import { IconButton } from 'browndash-components';
import { SettingsManager } from '../../../util/SettingsManager';
+import './MapAnchorMenu.scss';
@observer
export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
static Instance: MapAnchorMenu;
private _disposer: IReactionDisposer | undefined;
- private _disposer2: IReactionDisposer | undefined;
- private _commentCont = React.createRef<HTMLButtonElement>();
+ private _commentRef = React.createRef<HTMLDivElement>();
public onMakeAnchor: () => Opt<Doc> = () => undefined; // Method to get anchor from text search
public Center: () => void = unimplementedFunction;
- // public OnClick: (e: PointerEvent) => void = unimplementedFunction;
+ public OnClick: (e: PointerEvent) => void = unimplementedFunction;
// public OnAudio: (e: PointerEvent) => void = unimplementedFunction;
- // public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction;
- // public StartCropDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction;
+ public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction;
public Highlight: (color: string, isTargetToggler: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => Opt<Doc> = (color: string, isTargetToggler: boolean) => undefined;
public GetAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => undefined;
public Delete: () => void = unimplementedFunction;
- public LinkNote: () => void = unimplementedFunction;
// public MakeTargetToggle: () => void = unimplementedFunction;
// public ShowTargetTrail: () => void = unimplementedFunction;
public IsTargetToggler: () => boolean = returnFalse;
@@ -52,23 +43,12 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
componentWillUnmount() {
this._disposer?.();
- this._disposer2?.();
}
componentDidMount() {
- this._disposer2 = reaction(
- () => this._opacity,
- opacity => {
- if (!opacity) {
- }
- },
- { fireImmediately: true }
- );
this._disposer = reaction(
() => SelectionManager.Views().slice(),
- selected => {
- MapAnchorMenu.Instance.fadeOut(true);
- }
+ selected => MapAnchorMenu.Instance.fadeOut(true)
);
}
// audioDown = (e: React.PointerEvent) => {
@@ -87,6 +67,18 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
// e => this.OnCrop?.(e)
// );
// };
+ notePointerDown = (e: React.PointerEvent) => {
+ setupMoveUpEvents(
+ this,
+ e,
+ (e: PointerEvent) => {
+ this.StartDrag(e, this._commentRef.current!);
+ return true;
+ },
+ returnFalse,
+ e => this.OnClick(e)
+ );
+ };
static top = React.createRef<HTMLDivElement>();
// public get Top(){
@@ -105,12 +97,14 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
/>
}
{
- <IconButton
- tooltip="Link Note to Pin" //
- onPointerDown={this.LinkNote}
- icon={<FontAwesomeIcon icon="sticky-note" />}
- color={SettingsManager.userColor}
- />
+ <div ref={this._commentRef}>
+ <IconButton
+ tooltip="Link Note to Pin" //
+ onPointerDown={this.notePointerDown}
+ icon={<FontAwesomeIcon icon="sticky-note" />}
+ color={SettingsManager.userColor}
+ />
+ </div>
}
{
<IconButton
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index d7469e530..a419858fc 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -6,6 +6,7 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, DocListCast, Field, Opt } from '../../../../fields/Doc';
import { DocCss, Highlight, Width } from '../../../../fields/DocSymbols';
+import { Id } from '../../../../fields/FieldSymbols';
import { InkTool } from '../../../../fields/InkField';
import { DocCast, NumCast, StrCast } from '../../../../fields/Types';
import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../../Utils';
@@ -24,6 +25,7 @@ import { MarqueeAnnotator } from '../../MarqueeAnnotator';
import { SidebarAnnos } from '../../SidebarAnnos';
import { DocumentView } from '../DocumentView';
import { FieldView, FieldViewProps } from '../FieldView';
+import { FormattedTextBox } from '../formattedText/FormattedTextBox';
import { PinProps, PresBox } from '../trails';
import { MapAnchorMenu } from './MapAnchorMenu';
import './MapBox.scss';
@@ -215,6 +217,37 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this.layoutDoc._width = this.layoutDoc._layout_showSidebar ? NumCast(this.layoutDoc._width) * 1.2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth);
};
+ startAnchorDrag = (e: PointerEvent, ele: HTMLElement) => {
+ e.preventDefault();
+ e.stopPropagation();
+
+ const sourceAnchorCreator = action(() => {
+ const note = this.getAnchor(true);
+ if (note && this.selectedPin) {
+ note.latitude = this.selectedPin.latitude;
+ note.longitude = this.selectedPin.longitude;
+ note.map = this.selectedPin.map;
+ }
+ return note as Doc;
+ });
+
+ const targetCreator = (annotationOn: Doc | undefined) => {
+ const target = DocUtils.GetNewTextDoc('Note linked to ' + this.rootDoc.title, 0, 0, 100, 100, undefined, annotationOn, undefined, 'yellow');
+ FormattedTextBox.SelectOnLoad = target[Id];
+ return target;
+ };
+ const docView = this.props.DocumentView?.();
+ docView &&
+ DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(docView, sourceAnchorCreator, targetCreator), e.pageX, e.pageY, {
+ dragComplete: e => {
+ if (!e.aborted && e.annoDragData && e.annoDragData.linkSourceDoc && e.annoDragData.dropDocument && e.linkDocument) {
+ e.annoDragData.linkSourceDoc.followLinkToggle = e.annoDragData.dropDocument.annotationOn === this.props.Document;
+ e.annoDragData.linkSourceDoc.followLinkZoom = false;
+ }
+ },
+ });
+ };
+
createNoteAnnotation = () => {
const createFunc = undoable(
action(() => {
@@ -388,7 +421,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
MapAnchorMenu.Instance.Delete = this.deleteSelectedPin;
MapAnchorMenu.Instance.Center = this.centerOnSelectedPin;
- MapAnchorMenu.Instance.LinkNote = this.createNoteAnnotation;
+ MapAnchorMenu.Instance.OnClick = this.createNoteAnnotation;
+ MapAnchorMenu.Instance.StartDrag = this.startAnchorDrag;
const point = this._bingMap.current.tryLocationToPixel(new this.MicrosoftMaps.Location(this.selectedPin.latitude, this.selectedPin.longitude));
const x = point.x + (this.props.PanelWidth() - this.sidebarWidth()) / 2;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 6a92d09d9..90ebf5206 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -78,9 +78,7 @@ const translate = setCORS('http://cors-anywhere.herokuapp.com/');
export const GoogleRef = 'googleDocId';
type PullHandler = (exportState: Opt<GoogleApiClientUtils.Docs.ImportResult>, dataDoc: Doc) => void;
-export interface FormattedTextBoxProps {
- allowScroll?: boolean;
-}
+export interface FormattedTextBoxProps {}
@observer
export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps & FormattedTextBoxProps>() {
public static LayoutString(fieldStr: string) {
@@ -562,7 +560,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
drop = (e: Event, de: DragManager.DropEvent) => {
if (de.complete.annoDragData) {
de.complete.annoDragData.dropDocCreator = () => this.getAnchor(true);
- e.stopPropagation();
return true;
}
const dragData = de.complete.docDragData;
@@ -2067,10 +2064,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
// if scrollTop is 0, then don't let wheel trigger scroll on any container (which it would since onScroll won't be triggered on this)
- if (this.props.isContentActive() && !this.props.allowScroll) {
+ if (this.props.isContentActive()) {
// prevent default if selected || child is active but this doc isn't scrollable
if (
- (this._scrollRef.current?.scrollHeight ?? 0) <= Math.ceil(Number(this.layoutDoc._height)) && //
+ (this._scrollRef.current?.scrollHeight ?? 0) <= Math.ceil(this.props.PanelHeight()) && //
(this.props.isSelected() || this.isAnyChildContentActive())
) {
e.preventDefault();
@@ -2131,7 +2128,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
ref={this._ref}
style={{
cursor: this.props.isContentActive() ? 'text' : undefined,
- overflow: this.layout_autoHeight && this.props.CollectionFreeFormDocumentView?.() ? 'hidden' : undefined, //x this breaks viewing an layout_autoHeight doc in its own tab, or in the lightbox
height: this.props.height || (this.layout_autoHeight && this.props.renderDepth && !this.props.suppressSetHeight ? 'max-content' : undefined),
pointerEvents: Doc.ActiveTool === InkTool.None && !this.props.onBrowseClick?.() ? undefined : 'none',
}}
diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx
index 85c1cce8c..18cf633f4 100644
--- a/src/client/views/pdf/AnchorMenu.tsx
+++ b/src/client/views/pdf/AnchorMenu.tsx
@@ -5,16 +5,15 @@ import { action, computed, IReactionDisposer, observable, ObservableMap, reactio
import { observer } from 'mobx-react';
import { ColorState } from 'react-color';
import { Doc, Opt } from '../../../fields/Doc';
-import { StrCast } from '../../../fields/Types';
import { returnFalse, setupMoveUpEvents, unimplementedFunction, Utils } from '../../../Utils';
import { gptAPICall, GPTCallType } from '../../apis/gpt/GPT';
import { DocumentType } from '../../documents/DocumentTypes';
import { SelectionManager } from '../../util/SelectionManager';
+import { SettingsManager } from '../../util/SettingsManager';
import { AntimodeMenu, AntimodeMenuProps } from '../AntimodeMenu';
import { LinkPopup } from '../linking/LinkPopup';
import './AnchorMenu.scss';
import { GPTPopup, GPTPopupMode } from './GPTPopup/GPTPopup';
-import { SettingsManager } from '../../util/SettingsManager';
@observer
export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {