aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/PropertiesView.tsx14
-rw-r--r--src/client/views/StyleProvider.tsx4
-rw-r--r--src/client/views/collections/CollectionStackedTimeline.tsx33
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx32
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx4
6 files changed, 45 insertions, 44 deletions
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index bc08e920a..905f9e2d0 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -1332,8 +1332,12 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
);
}
- @observable description = Field.toString(LinkManager.currentLink?.description as any as Field);
- @observable relationship = StrCast(LinkManager.currentLink?.linkRelationship);
+ @computed get description() {
+ return Field.toString(LinkManager.currentLink?.description as any as Field);
+ }
+ @computed get relationship() {
+ return StrCast(LinkManager.currentLink?.linkRelationship);
+ }
@observable private relationshipButtonColor: string = '';
// @action
@@ -1343,8 +1347,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@undoBatch
handleDescriptionChange = action((value: string) => {
if (LinkManager.currentLink && this.selectedDoc) {
- this.selectedDoc.description = value;
- this.description = value;
+ this.setDescripValue(value);
return true;
}
});
@@ -1352,8 +1355,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@undoBatch
handleLinkRelationshipChange = action((value: string) => {
if (LinkManager.currentLink && this.selectedDoc) {
- this.selectedDoc.linkRelationship = value;
- this.relationship = value;
+ this.setLinkRelationshipValue(value);
return true;
}
});
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index dc7a4e047..b77f01250 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -2,7 +2,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, runInAction } from 'mobx';
import { extname } from 'path';
-import { Doc, Opt } from '../../fields/Doc';
+import { Doc, DocListCast, Opt } from '../../fields/Doc';
import { BoolCast, Cast, DocCast, ImageCast, NumCast, StrCast } from '../../fields/Types';
import { DashColor, emptyFunction, lightOrDark } from '../../Utils';
import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
@@ -252,7 +252,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
case StyleProp.BoxShadow: {
if (!doc || opacity() === 0 || doc.noShadow) return undefined; // if it's not visible, then no shadow)
if (doc.boxShadow === 'standard') return Shadows.STANDARD_SHADOW;
- if (doc?.isLinkButton && ![DocumentType.LINK, DocumentType.INK].includes(doc.type as any)) return StrCast(doc?._linkButtonShadow, 'lightblue 0em 0em 1em');
+ if (doc?.isLinkButton && DocListCast(doc?.links).length && ![DocumentType.LINK, DocumentType.INK].includes(doc.type as any)) return StrCast(doc?._linkButtonShadow, 'lightblue 0em 0em 1em');
switch (doc?.type) {
case DocumentType.COL:
return StrCast(
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 39ae470b6..e9bf03208 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -8,6 +8,7 @@ import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
import { ComputedField, ScriptField } from '../../../fields/ScriptField';
import { Cast, NumCast } from '../../../fields/Types';
+import { ImageField } from '../../../fields/URLField';
import { emptyFunction, formatTime, OmitKeys, returnFalse, returnOne, returnTrue, setupMoveUpEvents, smoothScrollHorizontal, StopEvent } from '../../../Utils';
import { Docs } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
@@ -23,13 +24,10 @@ import { AudioWaveform } from '../AudioWaveform';
import { CollectionSubView } from '../collections/CollectionSubView';
import { Colors } from '../global/globalEnums';
import { LightboxView } from '../LightboxView';
-import { DocFocusFunc, DocFocusOptions, DocumentView, DocumentViewProps, DocumentViewSharedProps } from '../nodes/DocumentView';
+import { DocFocusFunc, DocFocusOptions, DocumentView, DocumentViewProps } from '../nodes/DocumentView';
import { LabelBox } from '../nodes/LabelBox';
-import './CollectionStackedTimeline.scss';
import { VideoBox } from '../nodes/VideoBox';
-import { ImageField } from '../../../fields/URLField';
-import { StyleProp } from '../StyleProvider';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import './CollectionStackedTimeline.scss';
export type CollectionStackedTimelineProps = {
Play: () => void;
@@ -610,7 +608,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
height={height}
toTimeline={this.toTimeline}
layoutDoc={this.layoutDoc}
- // isDocumentActive={this.props.childDocumentsActive ? this.props.isDocumentActive : this.isContentActive}
+ isDocumentActive={this.isContentActive}
currentTimecode={this.currentTimecode}
_timeline={this._timeline}
stackedTimeline={this}
@@ -702,7 +700,7 @@ interface StackedTimelineAnchorProps {
endTag: string;
renderDepth: number;
layoutDoc: Doc;
- isDocumentActive?: () => boolean;
+ isDocumentActive?: () => boolean | undefined;
ScreenToLocalTransform: () => Transform;
_timeline: HTMLDivElement | null;
focus: DocFocusFunc;
@@ -806,25 +804,6 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
return [resetTitle];
};
- innerStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string): any => {
- if (property === StyleProp.Decorations && doc && NumCast(doc.timecodeToHide) - NumCast(doc.timecodeToShow) < 0.0002) {
- return (
- <div className="styleProvider-lock">
- <FontAwesomeIcon
- icon={'camera'}
- style={{ color: 'red' }}
- onClick={e => {
- LinkFollower.FollowLink(undefined, doc, props as DocumentViewSharedProps, e.altKey);
- e.stopPropagation();
- }}
- size="lg"
- />
- </div>
- );
- }
- return this.props.styleProvider?.(doc, props, property);
- };
-
// renders anchor LabelBox
renderInner = computedFn(function (this: StackedTimelineAnchor, mark: Doc, script: undefined | (() => ScriptField), doublescript: undefined | (() => ScriptField), screenXf: () => Transform, width: () => number, height: () => number) {
const anchor = observable({ view: undefined as any });
@@ -841,7 +820,7 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
ref={action((r: DocumentView | null) => (anchor.view = r))}
Document={mark}
DataDoc={undefined}
- styleProvider={this.innerStyleProvider}
+ styleProvider={this.props.styleProvider}
renderDepth={this.props.renderDepth + 1}
LayoutTemplate={undefined}
LayoutTemplateString={LabelBox.LayoutStringWithTitle('data', this.computeTitle())}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index c57810a98..b85da2ce7 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -241,7 +241,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
const link = this.props.LinkDocs[0];
const { a, b, pt1norm, pt2norm, aActive, bActive, textX, textY, pt1, pt2 } = this.renderData;
- const linkRelationship = Field.toString(LinkManager.currentLink?.linkRelationship as any as Field); //get string representing relationship
+ const linkRelationship = Field.toString(link?.linkRelationship as any as Field); //get string representing relationship
const linkRelationshipList = Doc.UserDoc().linkRelationshipList as List<string>;
const linkColorList = Doc.UserDoc().linkColorList as List<string>;
const linkRelationshipSizes = Doc.UserDoc().linkRelationshipSizes as List<number>;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 4abfef563..778965553 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -239,9 +239,8 @@ export interface DocumentViewInternalProps extends DocumentViewProps {
@observer
export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps>() {
public static SelectAfterContextMenu = true; // whether a document should be selected after it's contextmenu is triggered.
- @observable _animateScaleTime: Opt<number>; // milliseconds for animating between views. defaults to 300 if not uset
- @observable _animateScalingTo = 0;
- @observable _pendingDoubleClick = false;
+ private _cursorTimer: NodeJS.Timeout | undefined;
+ private _longPress = false;
private _disposers: { [name: string]: IReactionDisposer } = {};
private _downX: number = 0;
private _downY: number = 0;
@@ -255,7 +254,12 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
private _dropDisposer?: DragManager.DragDropDisposer;
private _holdDisposer?: InteractionUtils.MultiTouchEventDisposer;
protected _multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
+
@observable _componentView: Opt<DocComponentView>; // needs to be accessed from DocumentView wrapper class
+ @observable _animateScaleTime: Opt<number>; // milliseconds for animating between views. defaults to 300 if not uset
+ @observable _animateScalingTo = 0;
+ @observable _pendingDoubleClick = false;
+ @observable _cursorPress = false;
private get topMost() {
return this.props.renderDepth === 0 && !LightboxView.LightboxDoc;
@@ -623,7 +627,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
SelectionManager.DeselectAll();
Doc.UnBrushDoc(this.props.Document);
}
- } else if (this.onClickHandler?.script && !isScriptBox()) {
+ } else if (!this._longPress && this.onClickHandler?.script && !isScriptBox()) {
// bcz: hack? don't execute script if you're clicking on a scripting box itself
const { clientX, clientY, shiftKey, altKey } = e;
const func = () =>
@@ -652,12 +656,12 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
clickFunc();
}, 350);
} else clickFunc();
- } else if (this.allLinks.length && this.Document.type !== DocumentType.LINK && !isScriptBox() && this.Document.isLinkButton && !e.shiftKey && !e.ctrlKey) {
+ } else if (!this._longPress && this.allLinks.length && this.Document.type !== DocumentType.LINK && !isScriptBox() && this.Document.isLinkButton && !e.shiftKey && !e.ctrlKey) {
SelectionManager.DeselectAll();
this.allLinks.length && LinkFollower.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
+ // onDragStart implies a button doc that we don't want to select when clicking. RootDocument & isTemplateForField implies we're clicking on part of a template instance and we want to select the whole template, not the part
stopPropagate = false; // don't stop propagation for field templates -- want the selection to propagate up to the root document of the template
} else {
runInAction(() => (this._pendingDoubleClick = true));
@@ -688,6 +692,13 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
return;
}
+ this._cursorTimer = setTimeout(
+ action(() => {
+ this._cursorPress = true;
+ this.props.select(false);
+ }),
+ 1000 // long press required duration
+ );
this._downX = e.clientX;
this._downY = e.clientY;
if ((Doc.ActiveTool === InkTool.None || this.props.addDocTab === returnFalse) && !(this.props.Document.rootDocument && !(e.ctrlKey || e.button > 0))) {
@@ -713,6 +724,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
};
+ @action
onPointerMove = (e: PointerEvent): void => {
if (e.cancelBubble) return;
if (InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || [InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) return;
@@ -722,6 +734,8 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler) && (e.buttons === 1 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE))) {
document.removeEventListener('pointermove', this.onPointerMove);
document.removeEventListener('pointerup', this.onPointerUp);
+ this._cursorTimer && clearTimeout(this._cursorTimer);
+ this._cursorPress = false;
this.startDragging(this._downX, this._downY, ((e.ctrlKey || e.altKey) && 'alias') || ((this.props.dropAction || this.Document.dropAction || undefined) as dropActionType));
}
}
@@ -736,8 +750,12 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
document.removeEventListener('pointerup', this.onPointerUp);
};
+ @action
onPointerUp = (e: PointerEvent): void => {
this.cleanupPointerEvents();
+ this._longPress = this._cursorPress;
+ this._cursorTimer && clearTimeout(this._cursorTimer);
+ this._cursorPress = false;
if (this.onPointerUpHandler?.script && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) {
this.onPointerUpHandler.script.run({ self: this.rootDoc, this: this.layoutDoc }, console.log);
@@ -1395,7 +1413,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
...style,
background: isButton || thumb ? undefined : this.backgroundColor,
opacity: this.opacity,
- cursor: Doc.ActiveTool === InkTool.None ? 'grab' : 'crosshair',
+ cursor: this._cursorPress ? 'wait' : Doc.ActiveTool === InkTool.None ? 'grab' : 'crosshair',
color: StrCast(this.layoutDoc.color, 'inherit'),
fontFamily: StrCast(this.Document._fontFamily, 'inherit'),
fontSize: Cast(this.Document._fontSize, 'string', null),
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 097035661..b2fdd93fc 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -17,6 +17,7 @@ import { Transform } from '../../util/Transform';
import { DocumentView, DocumentViewSharedProps, OpenWhere } from './DocumentView';
import './LinkDocPreview.scss';
import React = require('react');
+import { SelectionManager } from '../../util/SelectionManager';
interface LinkDocPreviewProps {
linkDoc?: Doc;
@@ -131,8 +132,9 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
returnFalse,
emptyFunction,
action(() => {
- LinkManager.currentLink = this._linkDoc === LinkManager.currentLink ? undefined : this._linkDoc;
+ LinkManager.currentLink = this._linkDoc;
LinkManager.currentLinkAnchor = this._linkSrc;
+ this.props.docProps.DocumentView?.().select(false);
if ((SettingsManager.propertiesWidth ?? 0) < 100) {
SettingsManager.propertiesWidth = 250;
}