diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/PropertiesView.tsx | 14 | ||||
-rw-r--r-- | src/client/views/StyleProvider.tsx | 4 | ||||
-rw-r--r-- | src/client/views/collections/CollectionStackedTimeline.tsx | 33 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 32 | ||||
-rw-r--r-- | src/client/views/nodes/LinkDocPreview.tsx | 4 |
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; } |